summaryrefslogtreecommitdiff
path: root/sys/libkern/arc4random.c
diff options
context:
space:
mode:
authorMike Silbersack <silby@FreeBSD.org>2001-08-30 01:15:25 +0000
committerMike Silbersack <silby@FreeBSD.org>2001-08-30 01:15:25 +0000
commit3a7810bc39bcf802c5cd2c95364a2b0bb8744356 (patch)
tree6cdce0a5cf12b3da20c60659909b262ba323a4e3 /sys/libkern/arc4random.c
parent595aba526e9b45d802eaf0d6bef17a9a639b9b53 (diff)
downloadsrc-test2-3a7810bc39bcf802c5cd2c95364a2b0bb8744356.tar.gz
src-test2-3a7810bc39bcf802c5cd2c95364a2b0bb8744356.zip
Notes
Diffstat (limited to 'sys/libkern/arc4random.c')
-rw-r--r--sys/libkern/arc4random.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/sys/libkern/arc4random.c b/sys/libkern/arc4random.c
index 477c74269971..71616dc21d05 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();