/dev/random: Use separate entropy store for /dev/urandom
PATCH 3/4 /dev/random: Use separate entropy store for /dev/urandom
This patch adds a separate pool for use with /dev/urandom. This prevents a /dev/urandom read from being able to completely drain the entropy in the /dev/random pool, and also makes it much more difficult for an attacker to carry out a state extension attack.
patch-random-3-urandom-pool
random.c +27 -9
@@ -401,6 +401,7 @@*/ static struct entropy_store *random_state;/* The default global store */ static struct entropy_store *sec_random_state;/* secondary store */ +static struct entropy_store *urandom_state;/* For urandom */ static DECLARE_WAIT_QUEUE_HEAD (random_read_wait);static DECLARE_WAIT_QUEUE_HEAD (random_write_wait);
@@ -1474,14 +1475,21 @@*/ void get_random_bytes (void *buf,int nbytes) { -if (sec_random_state) -extract_entropy (sec_random_state, (char *) buf, nbytes, -EXTRACT_ENTROPY_SECONDARY ); -else if (random_state) -extract_entropy (random_state, (char *) buf, nbytes,0 ); -else +struct entropy_store *r = urandom_state; +int flags =EXTRACT_ENTROPY_SECONDARY ; + +if (!r) + r = sec_random_state; +if (!r) { + r = random_state; + flags =0 ; + } +if (!r) {printk (KERN_NOTICE "get_random_bytes called before " "random driver initialization\n" ); +return ; + } +extract_entropy (r, (char *) buf, nbytes, flags); }EXPORT_SYMBOL (get_random_bytes);
@@ -1532,8 +1540,12 @@if (create_entropy_store (SECONDARY_POOL_SIZE ,"secondary" , &sec_random_state)) goto err; +if (create_entropy_store (SECONDARY_POOL_SIZE ,"urandom" , + &urandom_state)) + goto err;clear_entropy_store (random_state);clear_entropy_store (sec_random_state); +clear_entropy_store (urandom_state);init_std_data (random_state);#ifdef CONFIG_SYSCTL sysctl_init_random (random_state);
@@ -1667,9 +1679,15 @@ urandom_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) { - return extract_entropy(sec_random_state, buf, nbytes, - EXTRACT_ENTROPY_USER | -EXTRACT_ENTROPY_SECONDARY ); + int flags = EXTRACT_ENTROPY_USER; +unsigned long cpuflags; + +spin_lock_irqsave (&random_state->lock, cpuflags); +if (random_state->entropy_count > random_state->poolinfo.POOLBITS) + flags |=EXTRACT_ENTROPY_SECONDARY ; +spin_unlock_irqrestore (&random_state->lock, cpuflags); + +return extract_entropy (urandom_state, buf, nbytes, flags); } static unsigned int
Quoted 5 lines · Theodore Ts'o
This patch adds a separate pool for use with
/dev/urandom. This prevents a/dev/urandomread from being able to completely drain the entropy in the/dev/randompool, and also makes it much more difficult for an attacker to carry out a state extension attack.
My version of this went a step further. We want to at all times ensure that there's enough data to do a full catastrophic reseed in the blocking pool, so we have to assure we're never drawing below that point when doing reads for urandom.
Signature · 1 line
Mathematics is the supreme nostalgia of our time.