Seems the attachment was stripped, probably an anti spam measure. So, I'll just put the text here. >From 8be9a727727b2a264e55abe8faefb0e5d29b6fd6 Mon Sep 17 00:00:00 2001 From: Fedora Kernel Team <kernel-team@xxxxxxxxxxxxxxxxx> Date: Sun, 20 Aug 2017 12:16:14 -0700 Subject: [PATCH] use input entropy to reseed crng based on timer and input entropy pool level --- drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 8ad9270..07da211 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -315,6 +315,13 @@ static int random_read_wakeup_bits = 64; static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS; /* + * The minimum number of seconds between urandom pool reseeding. We + * do this to limit the amount of entropy that can be drained from the + * input pool even if there are heavy demands on /dev/urandom. + */ +static int random_min_urandom_seed = 60; + +/* * Originally, we used a primitive polynomial of degree .poolwords * over GF(2). The taps for various sizes are defined below. They * were chosen to be evenly spaced except for the last tap, which is 1 @@ -399,6 +406,8 @@ static struct poolinfo { #endif }; +#define CRNG_RESEED_INTERVAL (random_min_urandom_seed*HZ) + /* * Static global variables */ @@ -472,6 +481,7 @@ static ssize_t _extract_entropy(struct entropy_store *r, void *buf, size_t nbytes, int fips); static void crng_reseed(struct crng_state *crng, struct entropy_store *r); +static void crng_entropy_reseed(struct crng_state *crng, struct entropy_store *r); static void push_to_pool(struct work_struct *work); static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; @@ -702,13 +712,23 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) r->entropy_total, _RET_IP_); if (r == &input_pool) { - int entropy_bits = entropy_count >> ENTROPY_SHIFT; - - if (crng_init < 2 && entropy_bits >= 128) { - crng_reseed(&primary_crng, r); - entropy_bits = r->entropy_count >> ENTROPY_SHIFT; + int entropy_bits; + if (crng_init < 2) + { entropy_bits = entropy_count >> ENTROPY_SHIFT; + if (entropy_bits >= 128) + { crng_reseed(&primary_crng, r); + entropy_bits = r->entropy_count >> ENTROPY_SHIFT; + } + } + else if (crng_init == 2) + { if (r->entropy_count >= 4000) + { struct crng_state *crng = &primary_crng; + if (time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) + { crng_entropy_reseed(crng, r); + entropy_bits = r->entropy_count - 256; + } + } } - /* should we wake readers? */ if (entropy_bits >= random_read_wakeup_bits) { wake_up_interruptible(&random_read_wait); @@ -721,7 +741,6 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) r->initialized && r->entropy_total >= 2*random_read_wakeup_bits) { struct entropy_store *other = &blocking_pool; - if (other->entropy_count <= 3 * other->poolinfo->poolfracbits / 4) { schedule_work(&other->push_work); @@ -751,8 +770,6 @@ static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) * *********************************************************************/ -#define CRNG_RESEED_INTERVAL (300*HZ) - static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); #ifdef CONFIG_NUMA @@ -851,6 +868,32 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) } } +static void crng_entropy_reseed(struct crng_state *crng, struct entropy_store *r) +{ + unsigned long flags; + int i, num; + union { + __u8 block[CHACHA20_BLOCK_SIZE]; + __u32 key[8]; + } buf; + + if (r) { + num = extract_entropy(r, &buf, 32, 16, 0); + if (num == 0) + return; + } + spin_lock_irqsave(&primary_crng.lock, flags); + for (i = 0; i < 8; i++) { + crng->state[i+4] ^= buf.key[i]; + } + memzero_explicit(&buf, sizeof(buf)); + crng->init_time = jiffies; + spin_unlock_irqrestore(&primary_crng.lock, flags); + if (crng == &primary_crng && crng_init == 2) { + pr_notice("random: crng entropy reseed done\n"); + } +} + static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA20_BLOCK_SIZE]) { @@ -1942,7 +1985,6 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, static int min_read_thresh = 8, min_write_thresh; static int max_read_thresh = OUTPUT_POOL_WORDS * 32; static int max_write_thresh = INPUT_POOL_WORDS * 32; -static int random_min_urandom_seed = 60; static char sysctl_bootid[16]; /* -- 2.9.5 _______________________________________________ kernel mailing list -- kernel@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx