diff options
| author | Daniel Mueller <deso@posteo.net> | 2020-01-02 08:32:06 -0800 | 
|---|---|---|
| committer | Daniel Mueller <deso@posteo.net> | 2020-01-02 08:32:06 -0800 | 
| commit | fd091b04316db9dc5fafadbd6bdbe60b127408a9 (patch) | |
| tree | f202270f7ae5cedc513be03833a26148d9b5e219 /rand/src/rngs/adapter | |
| parent | 8161cdb26f98e65b39c603ddf7a614cc87c77a1c (diff) | |
| download | nitrocli-fd091b04316db9dc5fafadbd6bdbe60b127408a9.tar.gz nitrocli-fd091b04316db9dc5fafadbd6bdbe60b127408a9.tar.bz2  | |
Update nitrokey crate to 0.4.0
This change finally updates the version of the nitrokey crate that we
consume to 0.4.0. Along with that we update rand_core, one of its
dependencies, to 0.5.1. Further more we add cfg-if in version 0.1.10 and
getrandom in version 0.1.13, both of which are now new (non-development)
dependencies.
Import subrepo nitrokey/:nitrokey at e81057037e9b4f370b64c0a030a725bc6bdfb870
Import subrepo cfg-if/:cfg-if at 4484a6faf816ff8058088ad857b0c6bb2f4b02b2
Import subrepo getrandom/:getrandom at d661aa7e1b8cc80b47dabe3d2135b3b47d2858af
Import subrepo rand/:rand at d877ed528248b52d947e0484364a4e1ae59ca502
Diffstat (limited to 'rand/src/rngs/adapter')
| -rw-r--r-- | rand/src/rngs/adapter/mod.rs | 4 | ||||
| -rw-r--r-- | rand/src/rngs/adapter/read.rs | 53 | ||||
| -rw-r--r-- | rand/src/rngs/adapter/reseeding.rs | 89 | 
3 files changed, 72 insertions, 74 deletions
diff --git a/rand/src/rngs/adapter/mod.rs b/rand/src/rngs/adapter/mod.rs index 60b832e..659ff26 100644 --- a/rand/src/rngs/adapter/mod.rs +++ b/rand/src/rngs/adapter/mod.rs @@ -8,8 +8,8 @@  //! Wrappers / adapters forming RNGs -#[cfg(feature="std")] #[doc(hidden)] pub mod read; +#[cfg(feature="std")] mod read;  mod reseeding; -#[cfg(feature="std")] pub use self::read::ReadRng; +#[cfg(feature="std")] pub use self::read::{ReadRng, ReadError};  pub use self::reseeding::ReseedingRng; diff --git a/rand/src/rngs/adapter/read.rs b/rand/src/rngs/adapter/read.rs index 30b6de6..901462e 100644 --- a/rand/src/rngs/adapter/read.rs +++ b/rand/src/rngs/adapter/read.rs @@ -10,12 +10,13 @@  //! A wrapper around any Read to treat it as an RNG.  use std::io::Read; +use std::fmt; -use rand_core::{RngCore, Error, ErrorKind, impls}; +use rand_core::{RngCore, Error, impls};  /// An RNG that reads random bytes straight from any type supporting -/// `std::io::Read`, for example files. +/// [`std::io::Read`], for example files.  ///  /// This will work best with an infinite reader, but that is not required.  /// @@ -24,10 +25,10 @@ use rand_core::{RngCore, Error, ErrorKind, impls};  ///  /// # Panics  /// -/// `ReadRng` uses `std::io::read_exact`, which retries on interrupts. All other -/// errors from the underlying reader, including when it does not have enough -/// data, will only be reported through [`try_fill_bytes`]. The other -/// [`RngCore`] methods will panic in case of an error. +/// `ReadRng` uses [`std::io::Read::read_exact`], which retries on interrupts. +/// All other errors from the underlying reader, including when it does not +/// have enough data, will only be reported through [`try_fill_bytes`]. +/// The other [`RngCore`] methods will panic in case of an error.  ///  /// # Example  /// @@ -40,9 +41,8 @@ use rand_core::{RngCore, Error, ErrorKind, impls};  /// println!("{:x}", rng.gen::<u32>());  /// ```  /// -/// [`OsRng`]: ../struct.OsRng.html -/// [`RngCore`]: ../../trait.RngCore.html -/// [`try_fill_bytes`]: ../../trait.RngCore.html#method.tymethod.try_fill_bytes +/// [`OsRng`]: crate::rngs::OsRng +/// [`try_fill_bytes`]: RngCore::try_fill_bytes  #[derive(Debug)]  pub struct ReadRng<R> {      reader: R @@ -72,24 +72,33 @@ impl<R: Read> RngCore for ReadRng<R> {      }      fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { -        if dest.len() == 0 { return Ok(()); } +        if dest.is_empty() { return Ok(()); }          // Use `std::io::read_exact`, which retries on `ErrorKind::Interrupted`. -        self.reader.read_exact(dest).map_err(|err| { -            match err.kind() { -                ::std::io::ErrorKind::UnexpectedEof => Error::with_cause( -                    ErrorKind::Unavailable, -                    "not enough bytes available, reached end of source", err), -                _ => Error::with_cause(ErrorKind::Unavailable, -                    "error reading from Read source", err) -            } -        }) +        self.reader.read_exact(dest).map_err(|e| Error::new(ReadError(e)))      }  } +/// `ReadRng` error type +#[derive(Debug)] +pub struct ReadError(std::io::Error); + +impl fmt::Display for ReadError { +    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +        write!(f, "ReadError: {}", self.0) +    } +} + +impl std::error::Error for ReadError { +    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { +        Some(&self.0) +    } +} + +  #[cfg(test)]  mod test {      use super::ReadRng; -    use {RngCore, ErrorKind}; +    use crate::RngCore;      #[test]      fn test_reader_rng_u64() { @@ -132,6 +141,8 @@ mod test {          let mut rng = ReadRng::new(&v[..]); -        assert!(rng.try_fill_bytes(&mut w).err().unwrap().kind == ErrorKind::Unavailable); +        let result = rng.try_fill_bytes(&mut w); +        assert!(result.is_err()); +        println!("Error: {}", result.unwrap_err());      }  } diff --git a/rand/src/rngs/adapter/reseeding.rs b/rand/src/rngs/adapter/reseeding.rs index 016afab..ec88efe 100644 --- a/rand/src/rngs/adapter/reseeding.rs +++ b/rand/src/rngs/adapter/reseeding.rs @@ -12,7 +12,7 @@  use core::mem::size_of; -use rand_core::{RngCore, CryptoRng, SeedableRng, Error, ErrorKind}; +use rand_core::{RngCore, CryptoRng, SeedableRng, Error};  use rand_core::block::{BlockRngCore, BlockRng};  /// A wrapper around any PRNG that implements [`BlockRngCore`], that adds the @@ -24,7 +24,7 @@ use rand_core::block::{BlockRngCore, BlockRng};  /// - After `clone()`, the clone will be reseeded on first use.  /// - After a process is forked, the RNG in the child process is reseeded within  ///   the next few generated values, depending on the block size of the -///   underlying PRNG. For [`ChaChaCore`] and [`Hc128Core`] this is a maximum of +///   underlying PRNG. For ChaCha and Hc128 this is a maximum of  ///   15 `u32` values before reseeding.  /// - After the PRNG has generated a configurable number of random bytes.  /// @@ -57,33 +57,24 @@ use rand_core::block::{BlockRngCore, BlockRng};  /// # Example  ///  /// ``` -/// # extern crate rand; -/// # extern crate rand_chacha; -/// # fn main() {  /// use rand::prelude::*; -/// use rand_chacha::ChaChaCore; // Internal part of ChaChaRng that +/// use rand_chacha::ChaCha20Core; // Internal part of ChaChaRng that  ///                              // implements BlockRngCore  /// use rand::rngs::OsRng;  /// use rand::rngs::adapter::ReseedingRng;  /// -/// let prng = ChaChaCore::from_entropy(); -// FIXME: it is better to use EntropyRng as reseeder, but that doesn't implement -// clone yet. -/// let reseeder = OsRng::new().unwrap(); -/// let mut reseeding_rng = ReseedingRng::new(prng, 0, reseeder); +/// let prng = ChaCha20Core::from_entropy(); +/// let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);  ///  /// println!("{}", reseeding_rng.gen::<u64>());  ///  /// let mut cloned_rng = reseeding_rng.clone();  /// assert!(reseeding_rng.gen::<u64>() != cloned_rng.gen::<u64>()); -/// # }  /// ```  /// -/// [`ChaChaCore`]: ../../../rand_chacha/struct.ChaChaCore.html -/// [`Hc128Core`]: ../../../rand_hc/struct.Hc128Core.html -/// [`BlockRngCore`]: ../../../rand_core/block/trait.BlockRngCore.html -/// [`ReseedingRng::new`]: struct.ReseedingRng.html#method.new -/// [`reseed()`]: struct.ReseedingRng.html#method.reseed +/// [`BlockRngCore`]: rand_core::block::BlockRngCore +/// [`ReseedingRng::new`]: ReseedingRng::new +/// [`reseed()`]: ReseedingRng::reseed  #[derive(Debug)]  pub struct ReseedingRng<R, Rsdr>(BlockRng<ReseedingCore<R, Rsdr>>)  where R: BlockRngCore + SeedableRng, @@ -234,6 +225,7 @@ where R: BlockRngCore + SeedableRng,                             results: &mut <Self as BlockRngCore>::Results,                             global_fork_counter: usize)      { +        #![allow(clippy::if_same_then_else)]  // false positive          if self.is_forked(global_fork_counter) {              info!("Fork detected, reseeding RNG");          } else { @@ -243,21 +235,13 @@ where R: BlockRngCore + SeedableRng,          let num_bytes =              results.as_ref().len() * size_of::<<R as BlockRngCore>::Item>(); -        let threshold = if let Err(e) = self.reseed() { -            let delay = match e.kind { -                ErrorKind::Transient => num_bytes as i64, -                kind @ _ if kind.should_retry() => self.threshold >> 8, -                _ => self.threshold, -            }; -            warn!("Reseeding RNG delayed reseeding by {} bytes due to \ -                   error from source: {}", delay, e); -            delay -        } else { -            self.fork_counter = global_fork_counter; -            self.threshold -        }; +        if let Err(e) = self.reseed() { +            warn!("Reseeding RNG failed: {}", e); +            let _ = e; +        } +        self.fork_counter = global_fork_counter; -        self.bytes_until_reseed = threshold - num_bytes as i64; +        self.bytes_until_reseed = self.threshold - num_bytes as i64;          self.inner.generate(results);      }  } @@ -282,12 +266,11 @@ where R: BlockRngCore + SeedableRng + CryptoRng,        Rsdr: RngCore + CryptoRng {} -#[cfg(all(feature="std", unix, not(target_os="emscripten")))] +#[cfg(all(unix, not(target_os="emscripten")))]  mod fork { -    extern crate libc; - -    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; -    use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT}; +    use core::sync::atomic::{AtomicUsize, AtomicBool, Ordering}; +    #[allow(deprecated)]  // Required for compatibility with Rust < 1.24. +    use core::sync::atomic::{ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};      // Fork protection      // @@ -301,12 +284,14 @@ mod fork {      // don't update `fork_counter`, so a reseed is attempted as soon as      // possible. +    #[allow(deprecated)]      static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;      pub fn get_fork_counter() -> usize {          RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)      } +    #[allow(deprecated)]      static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;      extern fn fork_handler() { @@ -316,14 +301,14 @@ mod fork {      }      pub fn register_fork_handler() { -        if FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) == false { +        if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {              unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };              FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);          }      }  } -#[cfg(not(all(feature="std", unix, not(target_os="emscripten"))))] +#[cfg(not(all(unix, not(target_os="emscripten"))))]  mod fork {      pub fn get_fork_counter() -> usize { 0 }      pub fn register_fork_handler() {} @@ -332,25 +317,27 @@ mod fork {  #[cfg(test)]  mod test { -    use {Rng, SeedableRng}; -    use rand_chacha::ChaChaCore; -    use rngs::mock::StepRng; +    use crate::{Rng, SeedableRng}; +    use crate::rngs::std::Core; +    use crate::rngs::mock::StepRng;      use super::ReseedingRng;      #[test]      fn test_reseeding() {          let mut zero = StepRng::new(0, 0); -        let rng = ChaChaCore::from_rng(&mut zero).unwrap(); -        let mut reseeding = ReseedingRng::new(rng, 32*4, zero); - -        // Currently we only support for arrays up to length 32. -        // TODO: cannot generate seq via Rng::gen because it uses different alg -        let mut buf = [0u32; 32]; // Needs to be a multiple of the RNGs result -                                  // size to test exactly. -        reseeding.fill(&mut buf); +        let rng = Core::from_rng(&mut zero).unwrap(); +        let thresh = 1; // reseed every time the buffer is exhausted +        let mut reseeding = ReseedingRng::new(rng, thresh, zero); + +        // RNG buffer size is [u32; 64] +        // Debug is only implemented up to length 32 so use two arrays +        let mut buf = ([0u32; 32], [0u32; 32]); +        reseeding.fill(&mut buf.0); +        reseeding.fill(&mut buf.1);          let seq = buf;          for _ in 0..10 { -            reseeding.fill(&mut buf); +            reseeding.fill(&mut buf.0); +            reseeding.fill(&mut buf.1);              assert_eq!(buf, seq);          }      } @@ -358,7 +345,7 @@ mod test {      #[test]      fn test_clone_reseeding() {          let mut zero = StepRng::new(0, 0); -        let rng = ChaChaCore::from_rng(&mut zero).unwrap(); +        let rng = Core::from_rng(&mut zero).unwrap();          let mut rng1 = ReseedingRng::new(rng, 32*4, zero);          let first: u32 = rng1.gen();  | 
