From bc6847e225787089acd45f959d7b2ec99fb65183 Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Mon, 21 Jul 2008 13:52:06 +0000 Subject: [PATCH] Implement arc4random_buf() function Obtained from: OpenBSD --- lib/libc/gen/arc4random.3 | 15 ++++++++++++--- lib/libc/gen/arc4random.c | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/libc/gen/arc4random.3 b/lib/libc/gen/arc4random.3 index 27c6fd16c987..5af38ce78ee4 100644 --- a/lib/libc/gen/arc4random.3 +++ b/lib/libc/gen/arc4random.3 @@ -35,6 +35,7 @@ .Os .Sh NAME .Nm arc4random , +.Nm arc4random_buf , .Nm arc4random_stir , .Nm arc4random_addrandom .Nd arc4 random number generator @@ -45,6 +46,8 @@ .Ft u_int32_t .Fn arc4random "void" .Ft void +.Fn arc4random_buf "void *buf" "size_t nbytes" +.Ft void .Fn arc4random_stir "void" .Ft void .Fn arc4random_addrandom "unsigned char *dat" "int datlen" @@ -68,6 +71,13 @@ and therefore has twice the range of and .Xr random 3 . .Pp +.Fn arc4random_buf +function fills the region +.Fa buf +of length +.Fa nbytes +with ARC4-derived random data. +.Pp The .Fn arc4random_stir function reads data from @@ -78,10 +88,9 @@ and uses it to permute the S-Boxes via There is no need to call .Fn arc4random_stir before using -.Fn arc4random , -since .Fn arc4random -automatically initializes itself. +functions family, since +they automatically initialize themselves. .Sh EXAMPLES The following produces a drop-in replacement for the traditional .Fn rand diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index 6aa232389726..7c11da262580 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -164,7 +164,7 @@ arc4_check_init(void) } } -static void +static inline void arc4_check_stir(void) { if (!rs_stired || arc4_count <= 0) { @@ -208,6 +208,21 @@ arc4random(void) return (rnd); } +void +arc4random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + + THREAD_LOCK(); + arc4_check_init(); + while (n--) { + arc4_check_stir(); + buf[n] = arc4_getbyte(&rs); + arc4_count--; + } + THREAD_UNLOCK(); +} + #if 0 /*-------- Test code for i386 --------*/ #include