summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2002-12-06 17:43:34 +0000
committermillert <>2002-12-06 17:43:34 +0000
commit27ad3c1b70e1ff5a88d4f7761f12549dd24f8d39 (patch)
treef5e9f90389333ae8839fd2681418027236bc0eef
parent25071cb01d98bb08f0c7db1ead925c76f842e478 (diff)
downloadopenbsd-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.
-rw-r--r--src/lib/libc/stdlib/random.c37
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)
35static char *rcsid = "$OpenBSD: random.c,v 1.9 2000/04/04 14:27:00 millert Exp $"; 35static 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)
237void 238void
238srandomdev() 239srandomdev()
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) {