diff options
-rw-r--r-- | src/lib/libc/stdlib/random.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index 5ce7c90ee9..787581fe58 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c | |||
@@ -32,10 +32,11 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #if defined(LIBC_SCCS) && !defined(lint) | 34 | #if defined(LIBC_SCCS) && !defined(lint) |
35 | static char *rcsid = "$OpenBSD: random.c,v 1.9 2000/04/04 14:27:00 millert Exp $"; | 35 | static char *rcsid = "$OpenBSD: random.c,v 1.10 2002/12/06 17:43:34 millert Exp $"; |
36 | #endif /* LIBC_SCCS and not lint */ | 36 | #endif /* LIBC_SCCS and not lint */ |
37 | 37 | ||
38 | #include <sys/types.h> | 38 | #include <sys/param.h> |
39 | #include <sys/sysctl.h> | ||
39 | #include <sys/time.h> | 40 | #include <sys/time.h> |
40 | #include <fcntl.h> | 41 | #include <fcntl.h> |
41 | #include <stdio.h> | 42 | #include <stdio.h> |
@@ -237,7 +238,7 @@ srandom(x) | |||
237 | void | 238 | void |
238 | srandomdev() | 239 | srandomdev() |
239 | { | 240 | { |
240 | int fd; | 241 | int fd, i, mib[2], n; |
241 | size_t len; | 242 | size_t len; |
242 | 243 | ||
243 | if (rand_type == TYPE_0) | 244 | if (rand_type == TYPE_0) |
@@ -245,19 +246,35 @@ srandomdev() | |||
245 | else | 246 | else |
246 | len = rand_deg * sizeof(state[0]); | 247 | len = rand_deg * sizeof(state[0]); |
247 | 248 | ||
249 | /* | ||
250 | * To get seed data, first try reading from /dev/arandom. | ||
251 | * If that fails, try the KERN_ARND sysctl() (one int at a time). | ||
252 | * As a last resort, call srandom(). | ||
253 | */ | ||
248 | if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 && | 254 | if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 && |
249 | read(fd, (void *) state, len) == (ssize_t) len) { | 255 | read(fd, (void *) state, len) == (ssize_t) len) { |
250 | close(fd); | 256 | close(fd); |
251 | } else { | 257 | } else { |
252 | struct timeval tv; | ||
253 | u_int junk; | ||
254 | |||
255 | /* XXX - this could be better */ | ||
256 | gettimeofday(&tv, NULL); | ||
257 | srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk); | ||
258 | if (fd != -1) | 258 | if (fd != -1) |
259 | close(fd); | 259 | close(fd); |
260 | return; | 260 | mib[0] = CTL_KERN; |
261 | mib[1] = KERN_ARND; | ||
262 | n = len / sizeof(int); | ||
263 | len = sizeof(int); | ||
264 | for (i = 0; i < n; i++) { | ||
265 | if (sysctl(mib, 2, (char *)((int *)state + i), &len, | ||
266 | NULL, 0) == -1) | ||
267 | break; | ||
268 | } | ||
269 | if (i != n) { | ||
270 | struct timeval tv; | ||
271 | u_int junk; | ||
272 | |||
273 | /* XXX - this could be better */ | ||
274 | gettimeofday(&tv, NULL); | ||
275 | srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk); | ||
276 | return; | ||
277 | } | ||
261 | } | 278 | } |
262 | 279 | ||
263 | if (rand_type != TYPE_0) { | 280 | if (rand_type != TYPE_0) { |