Skip to content

Commit

Permalink
ReseedingRng: tweak doc and log messages
Browse files Browse the repository at this point in the history
  • Loading branch information
dhardy committed Feb 5, 2018
1 parent f7f6468 commit ff1bd8b
Showing 1 changed file with 28 additions and 28 deletions.
56 changes: 28 additions & 28 deletions src/reseeding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use {Rng, SeedableRng, Error, ErrorKind};
/// limited number of bytes they can output, or at least not a limit reachable
/// in any practical way. There is no such thing as 'running out of entropy'.
///
/// Some small non-cryptographic PRNG's can have very small periods of for
/// Some small non-cryptographic PRNGs can have very small periods, for
/// example less than 2<sup>64</sup>. Would reseeding help to ensure that you do
/// not wrap around at the end of the period? A period of 2<sup>64</sup> still
/// takes several centuries of CPU-years on current hardware. Reseeding will
Expand All @@ -31,30 +31,29 @@ use {Rng, SeedableRng, Error, ErrorKind};
/// # When should you use `ReseedingRng`?
///
/// - Reseeding can be seen as some form of 'security in depth'. Even if in the
/// future there is found a cryptographic weakness in the used CSPRNG,
/// future a cryptographic weakness is found in the CSPRNG being used,
/// occasionally reseeding should make exploiting it much more difficult or
/// even impossible.
/// - It can be used as a poor man's cryptography (not recommended, just use a
/// good CSPRNG). Previous implementations of `thread_rng` for example used
/// `ReseedingRng` with the ISAAC RNG. That algorithm, although seemingly
/// strong, does not come with a security proof and does not meet the current
/// standards for a cryptographically secure PRNG. By reseeding it very
/// frequently (every 32 MiB) it seems safe to assume there is no attack that
/// can operate on the tiny window between reseeds.
/// `ReseedingRng` with the ISAAC RNG. That algorithm, although apparently
/// strong and with no known attack, does not come with any proof of security
/// and does not meet the current standards for a cryptographically secure
/// PRNG. By reseeding it frequently (every 32 MiB) it seems safe to assume
/// there is no attack that can operate on the tiny window between reseeds.
///
/// # Error handling
///
/// If reseeding fails, `try_fill_bytes` is the only `Rng` method to report it.
/// For all other methods `ReseedingRng` wil not panic, but try to handle the
/// error intelligently. And if nothing helps, continue without reseeding.
/// For all other `Rng` methods, `ReseedingRng` will not panic but try to
/// handle the error intelligently; if handling the source error fails these
/// methods will continue generating data from the wrapped PRNG without
/// reseeding.
///
/// It is usually best to use the infallible methods `next_u32`, `next_u64` and
/// `fill_bytes` because they can make use of this error handeling strategy.
///
/// Use `try_fill_bytes` and possible `try_reseed` if you want to handle
/// reseeding errors explicitly. All reseeding errors will either be
/// `ErrorKind::Transient` or `ErrorKind::NotReady`, and contain the original
/// error as cause.
/// `fill_bytes` because they can make use of this error handling strategy.
/// Use `try_fill_bytes` and possibly `try_reseed` if you want to handle
/// reseeding errors explicitly.
#[derive(Debug)]
pub struct ReseedingRng<R, Rsdr> {
rng: R,
Expand All @@ -81,19 +80,19 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
}
}

/// Reseed the internal RNG.
///
/// On error, this will try to intelligently handle reseeding. If the error
/// kind indicates retrying might help, it will immidiately retry a couple
/// of times. If the error kind indicates the seeding RNG is not ready, it
/// will retry after a while, after `threshold / 256` generated bytes.
/// Reseed the internal PRNG.
///
/// If the seeding RNG has an other error or a permanently failure, it will
/// completely skip reseeding. Only after generating `threshold` bytes it
/// will retry again.
/// This will try to work around errors in the RNG used for reseeding
/// intelligently. If the error kind indicates retrying might help, it will
/// immediately retry a couple of times. If the error kind indicates the
/// seeding RNG is not ready, it will retry later, after `threshold / 256`
/// generated bytes. On other errors in the source RNG, this will skip
/// reseeding and continue using the internal PRNG, until another
/// `threshold` bytes have been generated (at which point it will try
/// reseeding again).
#[inline(never)]
pub fn reseed(&mut self) {
trace!("Reseeding RNG after {} generated bytes",
trace!("Reseeding RNG after generating {} bytes",
self.threshold - self.bytes_until_reseed);
self.bytes_until_reseed = self.threshold;
let mut err_count = 0;
Expand All @@ -103,14 +102,14 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
let kind = e.kind();
if kind.should_wait() {
self.bytes_until_reseed = self.threshold >> 8;
info!("Reseeding delayed, retrying after {} generated bytes",
warn!("Reseeding RNG delayed for {} bytes",
self.bytes_until_reseed);
} else if kind.should_retry() {
err_count += 1;
// Retry immediately for 5 times (arbitrary limit)
if err_count <= 5 { continue; }
}
info!("Reseeding failed, RNG remains unchanged. Error: {}", e);
warn!("Reseeding RNG failed; continuing without reseeding. Error: {:?}", e);
}
break; // Successfully reseeded, delayed, or given up.
}
Expand All @@ -121,7 +120,8 @@ impl<R: Rng+SeedableRng, Rsdr: Rng> ReseedingRng<R, Rsdr> {
///
/// If reseeding fails, return an error with the original cause. Note that
/// if the cause has a permanent failure, we report a transient error and
/// skip reseeding.
/// skip reseeding; this means that only two error kinds can be reported
/// from this method: `ErrorKind::Transient` and `ErrorKind::NotReady`.
#[inline(never)]
pub fn try_reseed(&mut self) -> Result<(), Error> {
trace!("Reseeding RNG after {} generated bytes",
Expand Down

0 comments on commit ff1bd8b

Please sign in to comment.