From 6712a3afabdcfd1e795f2b52f7bdda7000c54e57 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 21 Oct 2017 17:02:09 +0200 Subject: [PATCH 1/5] Remove `Copy` trait from ChaCha --- src/prng/chacha.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/prng/chacha.rs b/src/prng/chacha.rs index f6559afe6e6..9c5bf5fc846 100644 --- a/src/prng/chacha.rs +++ b/src/prng/chacha.rs @@ -29,20 +29,13 @@ const CHACHA_ROUNDS: u32 = 20; // Cryptographically secure from 8 upwards as of /// /// [1]: D. J. Bernstein, [*ChaCha, a variant of /// Salsa20*](http://cr.yp.to/chacha.html) -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] pub struct ChaChaRng { buffer: [w32; STATE_WORDS], // Internal buffer of output state: [w32; STATE_WORDS], // Initial state index: usize, // Index into state } -static EMPTY: ChaChaRng = ChaChaRng { - buffer: [w(0); STATE_WORDS], - state: [w(0); STATE_WORDS], - index: STATE_WORDS -}; - - macro_rules! quarter_round{ ($a: expr, $b: expr, $c: expr, $d: expr) => {{ $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left(16)); @@ -102,7 +95,11 @@ impl ChaChaRng { /// - 2917185654 /// - 2419978656 pub fn new_unseeded() -> ChaChaRng { - let mut rng = EMPTY; + let mut rng = ChaChaRng { + buffer: [w(0); STATE_WORDS], + state: [w(0); STATE_WORDS], + index: STATE_WORDS + }; rng.init(&[0; KEY_WORDS]); rng } @@ -265,7 +262,11 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng { /// Only up to 8 words are used; if less than 8 /// words are used, the remaining are set to zero. fn from_seed(seed: &'a [u32]) -> ChaChaRng { - let mut rng = EMPTY; + let mut rng = ChaChaRng { + buffer: [w(0); STATE_WORDS], + state: [w(0); STATE_WORDS], + index: STATE_WORDS + }; rng.init(&[0u32; KEY_WORDS]); // set key in place { From e513aaa8e2d93357aab0fac5982af24eb62dbb72 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 21 Oct 2017 18:56:15 +0200 Subject: [PATCH 2/5] Custom Debug implementation for ChaCha and Xorshift So the internal state is never exposed (may be security-sensitive) --- src/prng/chacha.rs | 10 +++++++++- src/prng/isaac.rs | 1 + src/prng/isaac64.rs | 1 + src/prng/xorshift.rs | 11 +++++++++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/prng/chacha.rs b/src/prng/chacha.rs index 9c5bf5fc846..d066e652c29 100644 --- a/src/prng/chacha.rs +++ b/src/prng/chacha.rs @@ -11,6 +11,7 @@ //! The ChaCha random number generator. use core::num::Wrapping as w; +use core::fmt; use {Rng, CryptoRng, SeedFromRng, SeedableRng, Error}; #[allow(bad_style)] @@ -29,13 +30,20 @@ const CHACHA_ROUNDS: u32 = 20; // Cryptographically secure from 8 upwards as of /// /// [1]: D. J. Bernstein, [*ChaCha, a variant of /// Salsa20*](http://cr.yp.to/chacha.html) -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct ChaChaRng { buffer: [w32; STATE_WORDS], // Internal buffer of output state: [w32; STATE_WORDS], // Initial state index: usize, // Index into state } +// Custom Debug implementation that does not expose the internal state +impl fmt::Debug for ChaChaRng { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "ChaChaRng {{}}") + } +} + macro_rules! quarter_round{ ($a: expr, $b: expr, $c: expr, $d: expr) => {{ $a = $a + $b; $d = $d ^ $a; $d = w($d.0.rotate_left(16)); diff --git a/src/prng/isaac.rs b/src/prng/isaac.rs index fa2aa0de99e..9e5ab2d91e9 100644 --- a/src/prng/isaac.rs +++ b/src/prng/isaac.rs @@ -110,6 +110,7 @@ impl Clone for IsaacRng { } } +// Custom Debug implementation that does not expose the internal state impl fmt::Debug for IsaacRng { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "IsaacRng {{}}") diff --git a/src/prng/isaac64.rs b/src/prng/isaac64.rs index 403572d9157..26daa705ea6 100644 --- a/src/prng/isaac64.rs +++ b/src/prng/isaac64.rs @@ -94,6 +94,7 @@ impl Clone for Isaac64Rng { } } +// Custom Debug implementation that does not expose the internal state impl fmt::Debug for Isaac64Rng { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Isaac64Rng {{}}") diff --git a/src/prng/xorshift.rs b/src/prng/xorshift.rs index 031fd4b843c..a1455cea270 100644 --- a/src/prng/xorshift.rs +++ b/src/prng/xorshift.rs @@ -11,6 +11,7 @@ //! Xorshift generators use core::num::Wrapping as w; +use core::fmt; use {Rng, SeedFromRng, SeedableRng, Error}; /// An Xorshift[1] random number @@ -23,8 +24,7 @@ use {Rng, SeedFromRng, SeedableRng, Error}; /// [1]: Marsaglia, George (July 2003). ["Xorshift /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of /// Statistical Software*. Vol. 8 (Issue 14). -#[allow(missing_copy_implementations)] -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct XorShiftRng { x: w, y: w, @@ -32,6 +32,13 @@ pub struct XorShiftRng { w: w, } +// Custom Debug implementation that does not expose the internal state +impl fmt::Debug for XorShiftRng { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "XorShiftRng {{}}") + } +} + impl XorShiftRng { /// Creates a new XorShiftRng instance which is not seeded. /// From fdf401723396013e08f202a9f2678d9ea88a9e2b Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 21 Oct 2017 17:20:07 +0200 Subject: [PATCH 3/5] Implement Debug for TreadRng --- src/thread_local.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/thread_local.rs b/src/thread_local.rs index 819fe1cb844..0d7348ec244 100644 --- a/src/thread_local.rs +++ b/src/thread_local.rs @@ -21,8 +21,7 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 32_768; type ReseedingStdRng = ReseedingRng; /// The thread-local RNG. -#[derive(Clone)] -#[allow(missing_debug_implementations)] +#[derive(Clone, Debug)] pub struct ThreadRng { rng: Rc>, } From 37f745068f277e9db35c3a463f2b877aca396723 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 21 Oct 2017 17:22:04 +0200 Subject: [PATCH 4/5] Remove Debug bound from ReadRng --- src/read.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/read.rs b/src/read.rs index 6eaaaedadc8..30da8d88331 100644 --- a/src/read.rs +++ b/src/read.rs @@ -10,7 +10,6 @@ //! A wrapper around any Read to treat it as an RNG. -use std::fmt::Debug; use std::io; use std::io::Read; @@ -35,11 +34,12 @@ use {Rng, Error, ErrorKind}; /// println!("{:x}", distributions::uniform::(&mut rng)); /// ``` #[derive(Debug)] -pub struct ReadRng { +// Do not derive Clone, because it could share the underlying reader +pub struct ReadRng { reader: R } -impl ReadRng { +impl ReadRng { /// Create a new `ReadRng` from a `Read`. pub fn new(r: R) -> ReadRng { ReadRng { @@ -48,7 +48,7 @@ impl ReadRng { } } -impl Rng for ReadRng { +impl Rng for ReadRng { fn next_u32(&mut self) -> u32 { ::rand_core::impls::next_u32_via_fill(self) } From b5556c6a845141ed8b590eb2355a112f98e3181a Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 21 Oct 2017 17:50:27 +0200 Subject: [PATCH 5/5] Make `OsRng` Debug use `imp::OsRng` Debug --- src/os.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/os.rs b/src/os.rs index e15f218210c..1b8f791fcbd 100644 --- a/src/os.rs +++ b/src/os.rs @@ -18,7 +18,9 @@ use {Rng, Error}; // TODO: replace many of the panics below with Result error handling /// A random number generator that retrieves randomness straight from -/// the operating system. Platform sources: +/// the operating system. +/// +/// Platform sources: /// /// - Unix-like systems (Linux, Android, Mac OSX): read directly from /// `/dev/urandom`, or from `getrandom(2)` system call if available. @@ -37,6 +39,12 @@ use {Rng, Error}; /// in-depth discussion. pub struct OsRng(imp::OsRng); +impl fmt::Debug for OsRng { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + impl OsRng { /// Create a new `OsRng`. pub fn new() -> Result { @@ -69,12 +77,6 @@ impl Rng for OsRng { } } -impl fmt::Debug for OsRng { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "OsRng {{}}") - } -} - // Specialisation of `ReadRng` for our purposes #[derive(Debug)] struct ReadRng (R);