summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-12-06 17:43:35 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-12-06 17:43:35 +0000
commit3eecdfe454d22c8c3904b9b14d21337af4094935 (patch)
treef4c7e44f5bbe2c49b98cbdaded28a2aed693b16c /lib
parent73f269fce8cd33d237ab27ab4af3f81e0df49635 (diff)
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdlib/random.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c
index 5ce7c90ee9c..787581fe58b 100644
--- a/lib/libc/stdlib/random.c
+++ b/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 <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
@@ -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) {