diff options
| author | millert <> | 2002-12-06 17:43:34 +0000 |
|---|---|---|
| committer | millert <> | 2002-12-06 17:43:34 +0000 |
| commit | 27ad3c1b70e1ff5a88d4f7761f12549dd24f8d39 (patch) | |
| tree | f5e9f90389333ae8839fd2681418027236bc0eef /src/lib/libc/stdlib/random.c | |
| parent | 25071cb01d98bb08f0c7db1ead925c76f842e478 (diff) | |
| download | openbsd-27ad3c1b70e1ff5a88d4f7761f12549dd24f8d39.tar.gz openbsd-27ad3c1b70e1ff5a88d4f7761f12549dd24f8d39.tar.bz2 openbsd-27ad3c1b70e1ff5a88d4f7761f12549dd24f8d39.zip | |
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 '')
| -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) { |
