From 22eaf3990b1256b50ba4c135ae8390acf5495542 Mon Sep 17 00:00:00 2001 From: millert <> Date: Fri, 6 Dec 2002 17:43:34 +0000 Subject: [PATCH] In srandomdev(), if we can't access /dev/arandom, use the sysctl() instead. We don't want to use the sysctl() by default since we are reading more than just a few bytes of entropy when setting up the state. --- src/lib/libc/stdlib/random.c | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index 5ce7c90e..787581fe 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c @@ -32,10 +32,11 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: random.c,v 1.9 2000/04/04 14:27:00 millert Exp $"; +static char *rcsid = "$OpenBSD: random.c,v 1.10 2002/12/06 17:43:34 millert Exp $"; #endif /* LIBC_SCCS and not lint */ -#include +#include +#include #include #include #include @@ -237,7 +238,7 @@ srandom(x) void srandomdev() { - int fd; + int fd, i, mib[2], n; size_t len; if (rand_type == TYPE_0) @@ -245,19 +246,35 @@ srandomdev() else len = rand_deg * sizeof(state[0]); + /* + * To get seed data, first try reading from /dev/arandom. + * If that fails, try the KERN_ARND sysctl() (one int at a time). + * As a last resort, call srandom(). + */ 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); if (fd != -1) close(fd); - return; + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + n = len / sizeof(int); + len = sizeof(int); + for (i = 0; i < n; i++) { + if (sysctl(mib, 2, (char *)((int *)state + i), &len, + NULL, 0) == -1) + break; + } + if (i != n) { + 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) {