diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-12-30 22:05:46 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-12-30 22:05:46 +0000 |
commit | f86a8cbba3c4969f3c12fc7107790af4c8538407 (patch) | |
tree | d12c623f16af62df387ee10053b17dcf3fe946a5 /sys | |
parent | 8c03186080334cb4ae3bca67a6c18764699270d8 (diff) |
be more cynical about boot-time entropy, and fold time and entropy data in.
ok djm
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/rnd.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index b93907b69a3..ecddb9ae8f8 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.113 2010/12/29 20:11:17 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.114 2010/12/30 22:05:45 deraadt Exp $ */ /* * rnd.c -- A strong random number generator @@ -176,6 +176,7 @@ #include <sys/conf.h> #include <sys/disk.h> #include <sys/limits.h> +#include <sys/time.h> #include <sys/ioctl.h> #include <sys/malloc.h> #include <sys/fcntl.h> @@ -505,7 +506,7 @@ enqueue_randomness(int state, int val) { struct timer_rand_state *p; struct rand_event *rep; - struct timespec tv; + struct timespec ts; u_int time, nbits; #ifdef DIAGNOSTIC @@ -529,8 +530,8 @@ enqueue_randomness(int state, int val) return; } - nanotime(&tv); - time = (tv.tv_nsec >> 10) + (tv.tv_sec << 20); + nanotime(&ts); + time = (ts.tv_nsec >> 10) + (ts.tv_sec << 20); nbits = 0; /* @@ -605,7 +606,7 @@ enqueue_randomness(int state, int val) rep->re_state = p; rep->re_nbits = nbits; - rep->re_time = tv.tv_nsec ^ (tv.tv_sec << 20); + rep->re_time = ts.tv_nsec ^ (ts.tv_sec << 20); rep->re_val = val; rndstats.rnd_enqs++; @@ -684,19 +685,29 @@ int arc4random_initialized; static void arc4_stir(void) { - u_int8_t buf[256]; - int len; + struct timespec ts; + u_int8_t buf[256], *p; + int i; + + /* + * Use MD5 PRNG data and a system timespec; early in the boot + * process this is the best we can do -- some architectures do + * not collect entropy very well during this time, but may have + * clock information which is better than nothing. + */ + extract_entropy((u_int8_t *)buf, sizeof buf); + nanotime(&ts); + for (p = (u_int8_t *)&ts, i = 0; i < sizeof(ts); i++) + buf[i] ^= p[i]; - nanotime((struct timespec *) buf); - len = sizeof(buf) - sizeof(struct timespec); - extract_entropy((u_int8_t *)(buf + sizeof (struct timespec)), len); - len += sizeof(struct timespec); mtx_enter(&rndlock); + rndstats.rnd_used += sizeof(buf) * 8; + if (rndstats.arc4_nstirs > 0) rc4_crypt(&arc4random_state, buf, buf, sizeof(buf)); rc4_keysetup(&arc4random_state, buf, sizeof(buf)); - rndstats.arc4_stirs += len; + rndstats.arc4_stirs += sizeof(buf); rndstats.arc4_nstirs++; /* @@ -1016,7 +1027,7 @@ randomwrite(dev_t dev, struct uio *uio, int flags) if (ret) break; while (n % sizeof(u_int32_t)) - ((u_int8_t *) buf)[n++] = 0; + ((u_int8_t *)buf)[n++] = 0; add_entropy_words(buf, n / 4); newdata = 1; } |