diff --git a/src/include/stdlib.h b/src/include/stdlib.h index afd027aa..51f8a267 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdlib.h,v 1.11 1999/11/27 13:20:25 espie Exp $ */ +/* $OpenBSD: stdlib.h,v 1.12 2000/04/03 23:23:48 millert Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /*- @@ -179,6 +179,7 @@ long random __P((void)); char *realpath __P((const char *, char *)); char *setstate __P((const char *)); void srandom __P((unsigned int)); +void srandomdev __P((void)); int putenv __P((const char *)); int setenv __P((const char *, const char *, int)); diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3 index 9558a672..260c2398 100644 --- a/src/lib/libc/stdlib/random.3 +++ b/src/lib/libc/stdlib/random.3 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: random.3,v 1.10 2000/01/19 05:25:43 pjanzen Exp $ +.\" $OpenBSD: random.3,v 1.11 2000/04/03 23:23:48 millert Exp $ .\" .Dd April 19, 1991 .Dt RANDOM 3 @@ -37,6 +37,7 @@ .Sh NAME .Nm random , .Nm srandom , +.Nm srandomdev , .Nm initstate , .Nm setstate .Nd better random number generator; routines for changing generators @@ -46,6 +47,8 @@ .Fn random void .Ft void .Fn srandom "unsigned int seed" +.Ft void +.Fn srandomdev void .Ft char * .Fn initstate "unsigned int seed" "char *state" "size_t n" .Ft char * @@ -92,6 +95,19 @@ with as the seed. .Pp The +.Fn srandomdev +routine initialize a state array using the +.Xr arandom 4 +random number device which returns good random numbers, +suitable for cryptographic use. +Note that this particular seeding procedure can generate +states which are impossible to reproduce by calling +.Fn srandom +with any value, since the succeeding terms in the +state buffer are no longer derived from the LC algorithm applied to +a fixed seed. +.Pp +The .Fn initstate routine allows a state array, passed in as an argument, to be initialized for future use. The size of the state array (in bytes) is used by @@ -153,7 +169,8 @@ messages are printed on the standard error output. .Sh SEE ALSO .Xr arc4random 3 , .Xr drand48 3 , -.Xr rand 3 +.Xr rand 3 , +.Xr random 4 , .Sh STANDARDS The .Fn random , @@ -163,6 +180,10 @@ and .Fn setstate functions conform to .St -xpg4.2 . +.Pp +The +.Fn srandomdev +function is an extension. .Sh HISTORY These functions appeared in diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index 79344f30..7c6e5f7e 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c @@ -32,11 +32,15 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: random.c,v 1.6 1998/02/07 02:16:25 millert Exp $"; +static char *rcsid = "$OpenBSD: random.c,v 1.7 2000/04/03 23:23:48 millert Exp $"; #endif /* LIBC_SCCS and not lint */ +#include +#include +#include #include #include +#include /* * random.c: @@ -219,6 +223,47 @@ srandom(x) } } +/* + * srandomdev: + * + * Many programs choose the seed value in a totally predictable manner. + * This often causes problems. We seed the generator using the much more + * secure arandom(4) interface. Note that this particular seeding + * procedure can generate states which are impossible to reproduce by + * calling srandom() with any value, since the succeeding terms in the + * state buffer are no longer derived from the LC algorithm applied to + * a fixed seed. + */ +void +srandomdev() +{ + int fd; + size_t len; + + if (rand_type == TYPE_0) + len = sizeof(state[0]); + else + len = rand_deg * sizeof(state[0]); + + if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 && + read(fd, (void *) state, len) == (ssize_t) len) { + close(fd); + } else { + struct timeval tv; + u_int junk; + + /* XXX - this could be better */ + gettimeofday(&tv, NULL); + srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk); + return; + } + + if (rand_type != TYPE_0) { + fptr = &state[rand_sep]; + rptr = &state[0]; + } +} + /* * initstate: *