From 986ad2f782cf944990e4eda8bf88ea1821233302 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 11 Dec 2018 23:50:45 +0100 Subject: Add nitrokey as a dependency to nitrocli The nitrokey crate provides a simple interface to the Nitrokey Storage and the Nitrokey Pro based on the libnitrokey library developed by Nitrokey UG. The low-level bindings to this library are available in the nitrokey-sys crate. This patch adds version v0.2.1 of the nitrokey crate as a dependency for nitrocli. It includes the indirect dependencies nitrokey-sys (version 3.4.1) and rand (version 0.4.3). Import subrepo nitrokey/:nitrokey at 2eccc96ceec2282b868891befe9cda7f941fbe7b Import subrepo nitrokey-sys/:nitrokey-sys at f1a11ebf72610fb9cf80ac7f9f147b4ba1a5336f Import subrepo rand/:rand at d7d5da49daf7ceb3e5940072940d495cced3a1b3 --- rand/src/read.rs | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 rand/src/read.rs (limited to 'rand/src/read.rs') diff --git a/rand/src/read.rs b/rand/src/read.rs new file mode 100644 index 0000000..c7351b7 --- /dev/null +++ b/rand/src/read.rs @@ -0,0 +1,123 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A wrapper around any Read to treat it as an RNG. + +use std::io::{self, Read}; +use std::mem; +use Rng; + +/// An RNG that reads random bytes straight from a `Read`. This will +/// work best with an infinite reader, but this is not required. +/// +/// # Panics +/// +/// It will panic if it there is insufficient data to fulfill a request. +/// +/// # Example +/// +/// ```rust +/// use rand::{read, Rng}; +/// +/// let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; +/// let mut rng = read::ReadRng::new(&data[..]); +/// println!("{:x}", rng.gen::()); +/// ``` +#[derive(Debug)] +pub struct ReadRng { + reader: R +} + +impl ReadRng { + /// Create a new `ReadRng` from a `Read`. + pub fn new(r: R) -> ReadRng { + ReadRng { + reader: r + } + } +} + +impl Rng for ReadRng { + fn next_u32(&mut self) -> u32 { + // This is designed for speed: reading a LE integer on a LE + // platform just involves blitting the bytes into the memory + // of the u32, similarly for BE on BE; avoiding byteswapping. + let mut buf = [0; 4]; + fill(&mut self.reader, &mut buf).unwrap(); + unsafe { *(buf.as_ptr() as *const u32) } + } + fn next_u64(&mut self) -> u64 { + // see above for explanation. + let mut buf = [0; 8]; + fill(&mut self.reader, &mut buf).unwrap(); + unsafe { *(buf.as_ptr() as *const u64) } + } + fn fill_bytes(&mut self, v: &mut [u8]) { + if v.len() == 0 { return } + fill(&mut self.reader, v).unwrap(); + } +} + +fn fill(r: &mut Read, mut buf: &mut [u8]) -> io::Result<()> { + while buf.len() > 0 { + match try!(r.read(buf)) { + 0 => return Err(io::Error::new(io::ErrorKind::Other, + "end of file reached")), + n => buf = &mut mem::replace(&mut buf, &mut [])[n..], + } + } + Ok(()) +} + +#[cfg(test)] +mod test { + use super::ReadRng; + use Rng; + + #[test] + fn test_reader_rng_u64() { + // transmute from the target to avoid endianness concerns. + let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1, + 0 , 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3]; + let mut rng = ReadRng::new(&v[..]); + + assert_eq!(rng.next_u64(), 1_u64.to_be()); + assert_eq!(rng.next_u64(), 2_u64.to_be()); + assert_eq!(rng.next_u64(), 3_u64.to_be()); + } + #[test] + fn test_reader_rng_u32() { + let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3]; + let mut rng = ReadRng::new(&v[..]); + + assert_eq!(rng.next_u32(), 1_u32.to_be()); + assert_eq!(rng.next_u32(), 2_u32.to_be()); + assert_eq!(rng.next_u32(), 3_u32.to_be()); + } + #[test] + fn test_reader_rng_fill_bytes() { + let v = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let mut w = [0u8; 8]; + + let mut rng = ReadRng::new(&v[..]); + rng.fill_bytes(&mut w); + + assert!(v == w); + } + + #[test] + #[should_panic] + fn test_reader_rng_insufficient_bytes() { + let mut rng = ReadRng::new(&[][..]); + let mut v = [0u8; 3]; + rng.fill_bytes(&mut v); + } +} -- cgit v1.2.1