diff options
author | silby <silby@FreeBSD.org> | 2001-08-30 01:15:25 +0000 |
---|---|---|
committer | silby <silby@FreeBSD.org> | 2001-08-30 01:15:25 +0000 |
commit | b4c97b92690a22af4509abe0deac1b4a4e3e6330 (patch) | |
tree | 6cdce0a5cf12b3da20c60659909b262ba323a4e3 /sys/libkern | |
parent | 437849a8f7c4696581b75fb67b899965955d2f6d (diff) | |
download | FreeBSD-src-b4c97b92690a22af4509abe0deac1b4a4e3e6330.zip FreeBSD-src-b4c97b92690a22af4509abe0deac1b4a4e3e6330.tar.gz |
Minor improvements to arc4random():
- Decrease reseeding interval from every 64 to every 16384 runs
to reduce entropy usage.
- Add time based reseeding. (Every 5 minutes.)
- Throw away the first 256 words of output as suggested in
"Weaknesses in the Key Scheduling Algorithm of RC4."
Reviewed by: Mark Murray
MFC After: jkh says ok
Diffstat (limited to 'sys/libkern')
-rw-r--r-- | sys/libkern/arc4random.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/sys/libkern/arc4random.c b/sys/libkern/arc4random.c index 477c742..71616dc 100644 --- a/sys/libkern/arc4random.c +++ b/sys/libkern/arc4random.c @@ -13,13 +13,19 @@ #include <sys/types.h> #include <sys/random.h> #include <sys/libkern.h> +#include <sys/time.h> -#define ARC4_MAXRUNS 64 +#define ARC4_MAXRUNS 16384 +#define ARC4_RESEED_SECONDS 300 +#define ARC4_KEYBYTES 32 /* 256 bit key */ static u_int8_t arc4_i, arc4_j; static int arc4_initialized = 0; static int arc4_numruns = 0; static u_int8_t arc4_sbox[256]; +static struct timeval arc4_tv_nextreseed; + +static u_int8_t arc4_randbyte(void); static __inline void arc4_swap(u_int8_t *a, u_int8_t *b) @@ -43,7 +49,7 @@ arc4_randomstir (void) /* XXX read_random() returns unsafe numbers if the entropy * devce is not loaded - MarkM */ - r = read_random(key, sizeof(key)); + r = read_random(key, ARC4_KEYBYTES); /* if r == 0 || -1, just use what was on the stack */ if (r > 0) { @@ -56,6 +62,11 @@ arc4_randomstir (void) arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256; arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]); } + + /* Reset for next reseed cycle. */ + getmicrotime(&arc4_tv_nextreseed); + arc4_tv_nextreseed.tv_sec += ARC4_RESEED_SECONDS; + arc4_numruns = 0; } /* @@ -72,6 +83,15 @@ arc4_init(void) arc4_randomstir(); arc4_initialized = 1; + + /* Now, throw away the first N words out output, as suggested + * in the paper "Weaknesses in the Key Scheduling Algorithm + * of RC4" by Fluher, Mantin, and Shamir. + * + * (N = 256 in our case.) + */ + for (n = 0; n < 256*4; n++) + arc4_randbyte(); } /* @@ -95,14 +115,19 @@ u_int32_t arc4random(void) { u_int32_t ret; + struct timeval tv_now; /* Initialize array if needed. */ if (!arc4_initialized) arc4_init(); - if (++arc4_numruns > ARC4_MAXRUNS) + + /* Get current time. */ + getmicrotime(&tv_now); + + if ((++arc4_numruns > ARC4_MAXRUNS) || + (tv_now.tv_sec > arc4_tv_nextreseed.tv_sec)) { arc4_randomstir(); - arc4_numruns = 0; } ret = arc4_randbyte(); |