diff options
author | dan <dan@FreeBSD.org> | 1999-11-28 23:39:49 +0000 |
---|---|---|
committer | dan <dan@FreeBSD.org> | 1999-11-28 23:39:49 +0000 |
commit | 08f9eb57a7ba4ae109192467aa38a0628b044a92 (patch) | |
tree | d1c5a3b153429abe0b7013eaca72178ebea4b49b /sys/libkern | |
parent | 6c73ef33e3ddc45ff955bdce14f81f2496609a4a (diff) | |
download | FreeBSD-src-08f9eb57a7ba4ae109192467aa38a0628b044a92.zip FreeBSD-src-08f9eb57a7ba4ae109192467aa38a0628b044a92.tar.gz |
Address the concerns of the ``randomness'' of the initial PRNG. Now, we
use bits from /dev/random to stir the S-box. Also add an internal counter to
keep the S-box stirred on a regular basis.
Reviewed by: msmith
Diffstat (limited to 'sys/libkern')
-rw-r--r-- | sys/libkern/arc4random.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/sys/libkern/arc4random.c b/sys/libkern/arc4random.c index 3c4c06b..b6d9070 100644 --- a/sys/libkern/arc4random.c +++ b/sys/libkern/arc4random.c @@ -11,12 +11,16 @@ */ #include <sys/libkern.h> -#include <sys/time.h> + +#define ARC4_MAXRUNS 64 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]; +extern u_int read_random (void *, u_int); + static __inline void arc4_swap(u_int8_t *a, u_int8_t *b) { @@ -28,29 +32,38 @@ arc4_swap(u_int8_t *a, u_int8_t *b) } /* - * Initialize our S-box to its beginning defaults. + * Stir our S-box. */ static void -arc4_init(void) +arc4_randomstir (void) { - struct timespec ts; u_int8_t key[256]; - int n; + int r, n; - for (n = 0; n < 256; n++) - arc4_sbox[n] = (u_int8_t) n; + r = read_random(key, sizeof(key)); + for (n = r; n < sizeof(key); n++) + key[n] = key[n % r]; - nanotime(&ts); - srandom(ts.tv_sec ^ ts.tv_nsec); - for (n = 0; n < 256; n++) - key[n] = random() % 256; - - arc4_i = arc4_j = 0; for (n = 0; n < 256; n++) { - arc4_j = arc4_j + arc4_sbox[n] + key[n]; + arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256; arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]); } +} + +/* + * Initialize our S-box to its beginning defaults. + */ +static void +arc4_init(void) +{ + int n; + + arc4_i = arc4_j = 0; + for (n = 0; n < 256; n++) + arc4_sbox[n] = (u_int8_t) n; + + arc4_randomstir(); arc4_initialized = 1; } @@ -79,6 +92,11 @@ arc4random(void) /* Initialize array if needed. */ if (!arc4_initialized) arc4_init(); + if (++arc4_numruns > ARC4_MAXRUNS) + { + arc4_randomstir(); + arc4_numruns = 0; + } ret = arc4_randbyte(); ret |= arc4_randbyte() << 8; |