Messages in this thread | | | Date | Sun, 20 Feb 2022 20:34:19 -0800 | From | Eric Biggers <> | Subject | Re: [PATCH v2 01/10] random: introduce drain_entropy() helper to declutter crng_reseed() |
| |
On Sat, Feb 12, 2022 at 01:23:09PM +0100, Jason A. Donenfeld wrote: > In preparation for separating responsibilities, break out the entropy > count management part of crng_reseed() into its own function. > > No functional changes. > > Cc: Theodore Ts'o <tytso@mit.edu> > Cc: Dominik Brodowski <linux@dominikbrodowski.net> > Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> > --- > drivers/char/random.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/drivers/char/random.c b/drivers/char/random.c > index 44a20a1a1b3a..436b146b33be 100644 > --- a/drivers/char/random.c > +++ b/drivers/char/random.c > @@ -260,6 +260,7 @@ static struct { > }; > > static void extract_entropy(void *buf, size_t nbytes); > +static bool drain_entropy(void *buf, size_t nbytes); > > static void crng_reseed(void); > > @@ -453,22 +454,13 @@ static void crng_slow_load(const void *cp, size_t len) > static void crng_reseed(void) > { > unsigned long flags; > - int entropy_count; > unsigned long next_gen; > u8 key[CHACHA_KEY_SIZE]; > bool finalize_init = false; > > - /* First we make sure we have POOL_MIN_BITS of entropy in the pool, > - * and then we drain all of it. Only then can we extract a new key. > - */ > - do { > - entropy_count = READ_ONCE(input_pool.entropy_count); > - if (entropy_count < POOL_MIN_BITS) > - return; > - } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count); > - extract_entropy(key, sizeof(key)); > - wake_up_interruptible(&random_write_wait); > - kill_fasync(&fasync, SIGIO, POLL_OUT); > + /* Only reseed if we can, to prevent brute forcing a small amount of new bits. */ > + if (!drain_entropy(key, sizeof(key))) > + return; > > /* We copy the new key into the base_crng, overwriting the old one, > * and update the generation counter. We avoid hitting ULONG_MAX, > @@ -893,6 +885,25 @@ static void extract_entropy(void *buf, size_t nbytes) > memzero_explicit(&block, sizeof(block)); > } > > +/* > + * First we make sure we have POOL_MIN_BITS of entropy in the pool, > + * and then we drain all of it. Only then can we extract a new key > + * with extract_entropy(). > + */ > +static bool drain_entropy(void *buf, size_t nbytes) > +{ > + unsigned int entropy_count; > + do { > + entropy_count = READ_ONCE(input_pool.entropy_count); > + if (entropy_count < POOL_MIN_BITS) > + return false; > + } while (cmpxchg(&input_pool.entropy_count, entropy_count, 0) != entropy_count); > + extract_entropy(buf, nbytes); > + wake_up_interruptible(&random_write_wait); > + kill_fasync(&fasync, SIGIO, POLL_OUT); > + return true; > +}
Looks good, but perhaps the comment should clarify that drain_entropy() doesn't destroy the entropy in the pool, but rather just extracts it and zeroes out the entropy counter?
- Eric
| |