diff options
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r-- | lib/libc/stdlib/random.3 | 25 | ||||
-rw-r--r-- | lib/libc/stdlib/random.c | 47 |
2 files changed, 69 insertions, 3 deletions
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3 index 9558a672eb6..260c2398164 100644 --- a/lib/libc/stdlib/random.3 +++ b/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/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c index 79344f30f16..7c6e5f7eb92 100644 --- a/lib/libc/stdlib/random.c +++ b/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 <sys/types.h> +#include <sys/time.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> /* * random.c: @@ -220,6 +224,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: * * Initialize the state information in the given array of n bytes for future |