diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/stdlib/rand.3 | 13 | ||||
-rw-r--r-- | lib/libc/stdlib/rand.c | 34 |
2 files changed, 46 insertions, 1 deletions
diff --git a/lib/libc/stdlib/rand.3 b/lib/libc/stdlib/rand.3 index b47ff67..67955d9 100644 --- a/lib/libc/stdlib/rand.3 +++ b/lib/libc/stdlib/rand.3 @@ -42,6 +42,7 @@ .Sh NAME .Nm rand , .Nm srand , +.Nm sranddev , .Nm rand_r .Nd bad random number generator .Sh LIBRARY @@ -50,6 +51,8 @@ .Fd #include <stdlib.h> .Ft void .Fn srand "unsigned seed" +.Ft void +.Fn sranddev void .Ft int .Fn rand void .Ft int @@ -83,6 +86,13 @@ If no value is provided, the functions are automatically seeded with a value of 1. .Pp +The +.Fn sranddev +routine initialize a seed using +.Xr urandom 4 +random number device which returns good random numbers, +suitable for cryptographic use. +.Pp .Fn rand_r provides the same functionality as .Fn rand . @@ -90,7 +100,8 @@ A pointer to the context value .Fa ctx must be supplied by the caller. .Sh SEE ALSO -.Xr random 3 +.Xr random 3 , +.Xr urandom 4 .Sh STANDARDS The .Fn rand diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index 70285bd..8de8ead 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -39,8 +39,11 @@ static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; #endif /* LIBC_SCCS and not lint */ +#include <sys/time.h> /* for sranddev() */ #include <sys/types.h> +#include <fcntl.h> /* for sranddev() */ #include <stdlib.h> +#include <unistd.h> /* for sranddev() */ #ifdef TEST #include <stdio.h> @@ -101,6 +104,37 @@ u_int seed; next = seed; } + +/* + * sranddev: + * + * Many programs choose the seed value in a totally predictable manner. + * This often causes problems. We seed the generator using the much more + * secure urandom(4) interface. + */ +void +sranddev() +{ + int fd, done; + + done = 0; + fd = _open("/dev/urandom", O_RDONLY, 0); + if (fd >= 0) { + if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) + done = 1; + _close(fd); + } + + if (!done) { + struct timeval tv; + unsigned long junk; + + gettimeofday(&tv, NULL); + next = getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk; + } +} + + #ifdef TEST main() |