diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2011-01-07 23:13:49 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2011-01-07 23:13:49 +0000 |
commit | e39ad44ca931953c1004f94eb5b89ad7e2f59df0 (patch) | |
tree | deb115c996b5afbd7f320091d636eab4ba65c0d0 | |
parent | 288eb9bdabfd29a4643657cee203bd87068d9425 (diff) |
some minor improvements to rnd.
1. only support pool words == 2048.
2. define the amount of key we use.
3. define the amount of rc4 we skip.
4. use arc4random_buf instead of reimplementing inline.
5. bzero some more "secrets".
ok deraadt djm
-rw-r--r-- | sys/dev/rnd.c | 89 | ||||
-rw-r--r-- | sys/dev/rndvar.h | 4 |
2 files changed, 29 insertions, 64 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c index 17e8cd05409..9bdee5f3f18 100644 --- a/sys/dev/rnd.c +++ b/sys/dev/rnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rnd.c,v 1.126 2011/01/07 04:56:51 deraadt Exp $ */ +/* $OpenBSD: rnd.c,v 1.127 2011/01/07 23:13:48 tedu Exp $ */ /* * Copyright (c) 2011 Theo de Raadt. @@ -181,47 +181,13 @@ * The reultant polynomial is: * 2^POOLWORDS + 2^POOL_TAP1 + 2^POOL_TAP2 + 2^POOL_TAP3 + 2^POOL_TAP4 + 1 */ -#define POOLBITS (POOLWORDS*32) +#define POOLWORDS 2048 #define POOLBYTES (POOLWORDS*4) #define POOLMASK (POOLWORDS - 1) -#if POOLWORDS == 2048 #define POOL_TAP1 1638 #define POOL_TAP2 1231 #define POOL_TAP3 819 #define POOL_TAP4 411 -#elif POOLWORDS == 1024 /* also (819, 616, 410, 207, 2) */ -#define POOL_TAP1 817 -#define POOL_TAP2 615 -#define POOL_TAP3 412 -#define POOL_TAP4 204 -#elif POOLWORDS == 512 /* also (409,307,206,102,2), (409,309,205,103,2) */ -#define POOL_TAP1 411 -#define POOL_TAP2 308 -#define POOL_TAP3 208 -#define POOL_TAP4 104 -#elif POOLWORDS == 256 -#define POOL_TAP1 205 -#define POOL_TAP2 155 -#define POOL_TAP3 101 -#define POOL_TAP4 52 -#elif POOLWORDS == 128 /* also (103, 78, 51, 27, 2) */ -#define POOL_TAP1 103 -#define POOL_TAP2 76 -#define POOL_TAP3 51 -#define POOL_TAP4 25 -#elif POOLWORDS == 64 -#define POOL_TAP1 52 -#define POOL_TAP2 39 -#define POOL_TAP3 26 -#define POOL_TAP4 14 -#elif POOLWORDS == 32 -#define POOL_TAP1 26 -#define POOL_TAP2 20 -#define POOL_TAP3 14 -#define POOL_TAP4 7 -#else -#error No primitive polynomial available for chosen POOLWORDS -#endif struct mutex entropylock = MUTEX_INITIALIZER(IPL_HIGH); @@ -544,17 +510,24 @@ extract_entropy(u_int8_t *buf, int nbytes) } /* + * Bytes of key material for each rc4 instance. + */ +#define ARC4_KEY_BYTES 64 + +/* * Maximum number of bytes to serve directly from the main arc4random * pool. Larger requests are served from discrete arc4 instances keyed - * from the main pool. + * from the main pool. Must be larger than ARC4_KEY_BYTES. */ #define ARC4_MAIN_MAX_BYTES 2048 /* - * Key size (in bytes) for arc4 instances setup to serve requests larger - * than ARC4_MAIN_MAX_BYTES. + * Throw away the first N words of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. (N = 256 in our case.) */ -#define ARC4_SUB_KEY_BYTES (256 / 8) +#define ARC4_STATE 256 +#define ARC4_PARANOIA 4 struct mutex rndlock = MUTEX_INITIALIZER(IPL_HIGH); struct rc4_ctx arc4random_state; @@ -583,16 +556,13 @@ arc4random(void) static void arc4random_buf_large(void *buf, size_t n) { - u_char lbuf[ARC4_SUB_KEY_BYTES]; + u_char lbuf[ARC4_KEY_BYTES]; struct rc4_ctx lctx; - mtx_enter(&rndlock); - rc4_getbytes(&arc4random_state, lbuf, sizeof(lbuf)); - rndstats.arc4_reads += n; - mtx_leave(&rndlock); + arc4random_buf(lbuf, sizeof(lbuf)); rc4_keysetup(&lctx, lbuf, sizeof(lbuf)); - rc4_skip(&lctx, 256 * 4); + rc4_skip(&lctx, ARC4_STATE * ARC4_PARANOIA); rc4_getbytes(&lctx, (u_char *)buf, n); bzero(lbuf, sizeof(lbuf)); bzero(&lctx, sizeof(lctx)); @@ -667,7 +637,7 @@ arc4_init(void *v, void *w) { struct rc4_ctx new_ctx; struct timespec ts; - u_int8_t buf[64], *p; + u_int8_t buf[ARC4_KEY_BYTES], *p; int i; /* @@ -682,18 +652,16 @@ arc4_init(void *v, void *w) buf[i] ^= p[i]; rc4_keysetup(&new_ctx, buf, sizeof(buf)); - /* - * Throw away the first N words of output, as suggested in the - * paper "Weaknesses in the Key Scheduling Algorithm of RC4" - * by Fluher, Mantin, and Shamir. (N = 256 in our case.) - */ - rc4_skip(&new_ctx, 256 * 4); + rc4_skip(&new_ctx, ARC4_STATE * ARC4_PARANOIA); mtx_enter(&rndlock); bcopy(&new_ctx, &arc4random_state, sizeof(new_ctx)); rndstats.rnd_used += sizeof(buf) * 8; rndstats.arc4_nstirs++; mtx_leave(&rndlock); + + bzero(buf, sizeof(buf)); + bzero(&new_ctx, sizeof(new_ctx)); } /* @@ -741,7 +709,7 @@ randomclose(dev_t dev, int flag, int mode, struct proc *p) int randomread(dev_t dev, struct uio *uio, int ioflag) { - u_char lbuf[ARC4_SUB_KEY_BYTES]; + u_char lbuf[ARC4_KEY_BYTES]; struct rc4_ctx lctx; size_t total = uio->uio_resid; u_char *buf; @@ -752,13 +720,10 @@ randomread(dev_t dev, struct uio *uio, int ioflag) buf = malloc(2 * PAGE_SIZE, M_TEMP, M_WAITOK); if (total > ARC4_MAIN_MAX_BYTES) { - mtx_enter(&rndlock); - rc4_getbytes(&arc4random_state, lbuf, sizeof(lbuf)); - rndstats.arc4_reads += sizeof(lbuf); - mtx_leave(&rndlock); - + arc4random_buf(lbuf, sizeof(lbuf)); rc4_keysetup(&lctx, lbuf, sizeof(lbuf)); - rc4_skip(&lctx, 256 * 4); + rc4_skip(&lctx, ARC4_STATE * ARC4_PARANOIA); + bzero(lbuf, sizeof(lbuf)); myctx = 1; } @@ -773,7 +738,9 @@ randomread(dev_t dev, struct uio *uio, int ioflag) if (ret == 0 && uio->uio_resid > 0) yield(); } - + if (myctx) + bzero(&lctx, sizeof(lctx)); + bzero(buf, 2 * PAGE_SIZE); free(buf, M_TEMP); return ret; } diff --git a/sys/dev/rndvar.h b/sys/dev/rndvar.h index 0c62a5bd033..34f62d70ffa 100644 --- a/sys/dev/rndvar.h +++ b/sys/dev/rndvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rndvar.h,v 1.27 2011/01/07 04:56:52 deraadt Exp $ */ +/* $OpenBSD: rndvar.h,v 1.28 2011/01/07 23:13:48 tedu Exp $ */ /* * Copyright (c) 1996,2000 Michael Shalayeff. @@ -31,8 +31,6 @@ #ifndef __RNDVAR_H__ #define __RNDVAR_H__ -#define POOLWORDS 2048 /* Power of 2 - note that this is 32-bit words */ - #define RND_SRC_TRUE 0 #define RND_SRC_TIMER 1 #define RND_SRC_MOUSE 2 |