Messages in this thread Patch in this message |  | | Date | Wed, 11 Sep 2002 00:22:17 -0500 | From | Oliver Xymoron <> | Subject | [PATCH 9/11] Entropy fixes - refactor reseeding |
| |
Factor pool reseeding out of normal entropy transfer. This allows different pools to have different policy on how to reseed.
This patch also makes random_read actually use the entropy count in the secondary pool rather than tracking off the primary.
diff -urN clean/drivers/char/random.c patched/drivers/char/random.c --- clean/drivers/char/random.c 2002-09-10 23:32:04.000000000 -0500 +++ patched/drivers/char/random.c 2002-09-10 23:34:28.000000000 -0500 @@ -886,7 +886,6 @@ *********************************************************************/ #define EXTRACT_ENTROPY_USER 1 -#define EXTRACT_ENTROPY_SECONDARY 2 #define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE) #define SEC_XFER_SIZE (TMP_BUF_SIZE*4) @@ -928,10 +927,6 @@ * number of bytes that are actually obtained. If the EXTRACT_ENTROPY_USER * flag is given, then the buf pointer is assumed to be in user space. * - * If the EXTRACT_ENTROPY_SECONDARY flag is given, then we are actually - * extracting entropy from the secondary pool, and can refill from the - * primary pool if needed. - * * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words. */ static ssize_t extract_entropy(struct entropy_store *r, void * buf, @@ -945,9 +940,6 @@ if (r->entropy_count > r->poolinfo.POOLBITS) r->entropy_count = r->poolinfo.POOLBITS; - if (flags & EXTRACT_ENTROPY_SECONDARY) - xfer_secondary_pool(r, nbytes); - DEBUG_ENT("%s has %d bits, want %d bits\n", r == sec_random_state ? "secondary" : r == random_state ? "primary" : "unknown", @@ -1029,6 +1021,18 @@ return ret; } +/* Reseed pool with pull bits from input pool, provided input pool has + * more than thresh bits available. Pull should be sufficient for a + * "catastrophic reseed" - enough to make the destination pool + * unguessable should it be compromised + */ +void reseed_pool(struct entropy_store *r, int thresh, int pull) +{ + if (r->entropy_count < 8 && + random_state->entropy_count > thresh) + xfer_secondary_pool(r, pull/8); +} + /* * This function is the exported kernel interface. It returns some * number of good random numbers, suitable for seeding TCP sequence @@ -1036,14 +1040,16 @@ */ 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 + if (!sec_random_state) + { printk(KERN_NOTICE "get_random_bytes called before " "random driver initialization\n"); + return; + } + + reseed_pool(sec_random_state, + random_read_wakeup_thresh, random_read_wakeup_thresh); + extract_entropy(sec_random_state, (char *) buf, nbytes, 0); } /********************************************************************* @@ -1107,14 +1113,19 @@ return 0; add_wait_queue(&random_read_wait, &wait); + while (nbytes > 0) { set_current_state(TASK_INTERRUPTIBLE); + reseed_pool(sec_random_state, + random_read_wakeup_thresh, + random_read_wakeup_thresh); + n = nbytes; if (n > SEC_XFER_SIZE) n = SEC_XFER_SIZE; - if (n > random_state->entropy_count / 8) - n = random_state->entropy_count / 8; + if (n > sec_random_state->entropy_count / 8) + n = sec_random_state->entropy_count / 8; if (n == 0) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; @@ -1133,8 +1144,8 @@ sec_random_state->entropy_count); n = extract_entropy(sec_random_state, buf, n, - EXTRACT_ENTROPY_USER | - EXTRACT_ENTROPY_SECONDARY); + EXTRACT_ENTROPY_USER); + if (n < 0) { retval = n; break; @@ -1162,9 +1173,11 @@ urandom_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) { + reseed_pool(sec_random_state, + random_read_wakeup_thresh, random_read_wakeup_thresh); + return extract_entropy(sec_random_state, buf, nbytes, - EXTRACT_ENTROPY_USER | - EXTRACT_ENTROPY_SECONDARY); + EXTRACT_ENTROPY_USER); } static unsigned int
-- "Love the dolphins," she advised him. "Write by W.A.S.T.E.." - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |