Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ae48b7e

Browse files
dhardypitdicker
authored andcommittedFeb 17, 2018
ReseedingRng: tweak doc and log messages
1 parent 8450ad5 commit ae48b7e

File tree

2 files changed

+30
-30
lines changed

2 files changed

+30
-30
lines changed
 

‎src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@
257257
#[cfg(feature = "log")] #[macro_use] extern crate log;
258258
#[cfg(not(feature = "log"))] macro_rules! trace { ($($x:tt)*) => () }
259259
#[cfg(not(feature = "log"))] macro_rules! debug { ($($x:tt)*) => () }
260-
#[cfg(not(feature = "log"))] macro_rules! info { ($($x:tt)*) => () }
261-
#[cfg(all(feature="std", not(feature = "log")))] macro_rules! warn { ($($x:tt)*) => () }
260+
#[cfg(all(feature="std", not(feature = "log")))] macro_rules! info { ($($x:tt)*) => () }
261+
#[cfg(not(feature = "log"))] macro_rules! warn { ($($x:tt)*) => () }
262262
#[cfg(all(feature="std", not(feature = "log")))] macro_rules! error { ($($x:tt)*) => () }
263263

264264

‎src/reseeding.rs

+28-28
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use {Rng, SeedableRng, Error, ErrorKind};
2020
/// limited number of bytes they can output, or at least not a limit reachable
2121
/// in any practical way. There is no such thing as 'running out of entropy'.
2222
///
23-
/// Some small non-cryptographic PRNG's can have very small periods of for
23+
/// Some small non-cryptographic PRNGs can have very small periods, for
2424
/// example less than 2<sup>64</sup>. Would reseeding help to ensure that you do
2525
/// not wrap around at the end of the period? A period of 2<sup>64</sup> still
2626
/// takes several centuries of CPU-years on current hardware. Reseeding will
@@ -31,30 +31,29 @@ use {Rng, SeedableRng, Error, ErrorKind};
3131
/// # When should you use `ReseedingRng`?
3232
///
3333
/// - Reseeding can be seen as some form of 'security in depth'. Even if in the
34-
/// future there is found a cryptographic weakness in the used CSPRNG,
34+
/// future a cryptographic weakness is found in the CSPRNG being used,
3535
/// occasionally reseeding should make exploiting it much more difficult or
3636
/// even impossible.
3737
/// - It can be used as a poor man's cryptography (not recommended, just use a
3838
/// good CSPRNG). Previous implementations of `thread_rng` for example used
39-
/// `ReseedingRng` with the ISAAC RNG. That algorithm, although seemingly
40-
/// strong, does not come with a security proof and does not meet the current
41-
/// standards for a cryptographically secure PRNG. By reseeding it very
42-
/// frequently (every 32 MiB) it seems safe to assume there is no attack that
43-
/// can operate on the tiny window between reseeds.
39+
/// `ReseedingRng` with the ISAAC RNG. That algorithm, although apparently
40+
/// strong and with no known attack, does not come with any proof of security
41+
/// and does not meet the current standards for a cryptographically secure
42+
/// PRNG. By reseeding it frequently (every 32 MiB) it seems safe to assume
43+
/// there is no attack that can operate on the tiny window between reseeds.
4444
///
4545
/// # Error handling
4646
///
4747
/// If reseeding fails, `try_fill_bytes` is the only `Rng` method to report it.
48-
/// For all other methods `ReseedingRng` wil not panic, but try to handle the
49-
/// error intelligently. And if nothing helps, continue without reseeding.
48+
/// For all other `Rng` methods, `ReseedingRng` will not panic but try to
49+
/// handle the error intelligently; if handling the source error fails these
50+
/// methods will continue generating data from the wrapped PRNG without
51+
/// reseeding.
5052
///
5153
/// It is usually best to use the infallible methods `next_u32`, `next_u64` and
52-
/// `fill_bytes` because they can make use of this error handeling strategy.
53-
///
54-
/// Use `try_fill_bytes` and possible `try_reseed` if you want to handle
55-
/// reseeding errors explicitly. All reseeding errors will either be
56-
/// `ErrorKind::Transient` or `ErrorKind::NotReady`, and contain the original
57-
/// error as cause.
54+
/// `fill_bytes` because they can make use of this error handling strategy.
55+
/// Use `try_fill_bytes` and possibly `try_reseed` if you want to handle
56+
/// reseeding errors explicitly.
5857
#[derive(Debug)]
5958
pub struct ReseedingRng<R, Rsdr> {
6059
rng: R,
@@ -81,19 +80,19 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
8180
}
8281
}
8382

84-
/// Reseed the internal RNG.
85-
///
86-
/// On error, this will try to intelligently handle reseeding. If the error
87-
/// kind indicates retrying might help, it will immidiately retry a couple
88-
/// of times. If the error kind indicates the seeding RNG is not ready, it
89-
/// will retry after a while, after `threshold / 256` generated bytes.
83+
/// Reseed the internal PRNG.
9084
///
91-
/// If the seeding RNG has an other error or a permanently failure, it will
92-
/// completely skip reseeding. Only after generating `threshold` bytes it
93-
/// will retry again.
85+
/// This will try to work around errors in the RNG used for reseeding
86+
/// intelligently. If the error kind indicates retrying might help, it will
87+
/// immediately retry a couple of times. If the error kind indicates the
88+
/// seeding RNG is not ready, it will retry later, after `threshold / 256`
89+
/// generated bytes. On other errors in the source RNG, this will skip
90+
/// reseeding and continue using the internal PRNG, until another
91+
/// `threshold` bytes have been generated (at which point it will try
92+
/// reseeding again).
9493
#[inline(never)]
9594
pub fn reseed(&mut self) {
96-
trace!("Reseeding RNG after {} generated bytes",
95+
trace!("Reseeding RNG after generating {} bytes",
9796
self.threshold - self.bytes_until_reseed);
9897
self.bytes_until_reseed = self.threshold;
9998
let mut err_count = 0;
@@ -103,14 +102,14 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
103102
let kind = e.kind();
104103
if kind.should_wait() {
105104
self.bytes_until_reseed = self.threshold >> 8;
106-
info!("Reseeding delayed, retrying after {} generated bytes",
105+
warn!("Reseeding RNG delayed for {} bytes",
107106
self.bytes_until_reseed);
108107
} else if kind.should_retry() {
109108
err_count += 1;
110109
// Retry immediately for 5 times (arbitrary limit)
111110
if err_count <= 5 { continue; }
112111
}
113-
info!("Reseeding failed, RNG remains unchanged. Error: {}", e);
112+
warn!("Reseeding RNG failed; continuing without reseeding. Error: {:?}", e);
114113
}
115114
break; // Successfully reseeded, delayed, or given up.
116115
}
@@ -121,7 +120,8 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
121120
///
122121
/// If reseeding fails, return an error with the original cause. Note that
123122
/// if the cause has a permanent failure, we report a transient error and
124-
/// skip reseeding.
123+
/// skip reseeding; this means that only two error kinds can be reported
124+
/// from this method: `ErrorKind::Transient` and `ErrorKind::NotReady`.
125125
#[inline(never)]
126126
pub fn try_reseed(&mut self) -> Result<(), Error> {
127127
trace!("Reseeding RNG after {} generated bytes",

0 commit comments

Comments
 (0)