summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Silbersack <silby@FreeBSD.org>2001-09-01 22:26:04 +0000
committerMike Silbersack <silby@FreeBSD.org>2001-09-01 22:26:04 +0000
commit2b51a47fe6a895db725974ac382e901b80e86d0e (patch)
tree17bf967c509b1f557597e805ffe96c8d6c13bbb0 /sys
parent3e598215bd1cf6105befd32b95c2d3cef7148464 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/libkern/arc4random.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/libkern/arc4random.c b/sys/libkern/arc4random.c
index 4eefb6910727..293f23b5c017 100644
--- a/sys/libkern/arc4random.c
+++ b/sys/libkern/arc4random.c
@@ -11,15 +11,20 @@
*/
#include <sys/libkern.h>
+#include <sys/time.h>
+#include <sys/random.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;
-extern u_int read_random (void *, u_int);
+static u_int8_t arc4_randbyte(void);
static __inline void
arc4_swap(u_int8_t *a, u_int8_t *b)
@@ -40,7 +45,9 @@ arc4_randomstir (void)
u_int8_t key[256];
int r, n;
- r = read_random(key, sizeof(key));
+ /* Reseed from random device. This technically isn't
+ reseeding, as we're not throwing away the old state. */
+ r = read_random_unlimited(key, ARC4_KEYBYTES);
/* if r == 0 || -1, just use what was on the stack */
if (r > 0)
{
@@ -53,6 +60,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;
}
/*
@@ -69,6 +81,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();
}
/*
@@ -92,14 +113,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();