diff options
author | ache <ache@FreeBSD.org> | 2008-08-03 20:15:22 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2008-08-03 20:15:22 +0000 |
commit | 3fa9cc2a95b84ebd2674a4a3a5c5507b42aadc36 (patch) | |
tree | 3b31f0bead4fa6111aea396e32a24a186c9551c2 | |
parent | b6a62e0a11ac0c1d7169a8277b0f6dbd5cd84899 (diff) | |
download | FreeBSD-src-3fa9cc2a95b84ebd2674a4a3a5c5507b42aadc36.zip FreeBSD-src-3fa9cc2a95b84ebd2674a4a3a5c5507b42aadc36.tar.gz |
Restored from previous backing out (because that is OpenBSD way, so
assumed to be reviewd by them):
Stir directly from the kernel PRNG, without taking less random pid & time
bytes too (when it is possible).
The difference with OpenBSD code is that they have KERN_ARND sysctl for
that task, while we need to read /dev/random
-rw-r--r-- | lib/libc/gen/arc4random.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index c4733e5..d702e34 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -55,6 +55,7 @@ struct arc4_stream { static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; #define RANDOMDEV "/dev/urandom" +#define KEYSIZE 128 #define THREAD_LOCK() \ do { \ if (__isthreaded) \ @@ -106,24 +107,27 @@ arc4_addrandom(u_char *dat, int datlen) static void arc4_stir(void) { - int fd, n; + int done, fd, n; struct { - struct timeval tv; - pid_t pid; - u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)]; - } rdat; + struct timeval tv; + pid_t pid; + u_int8_t rnd[KEYSIZE]; + } rdat; - gettimeofday(&rdat.tv, NULL); - rdat.pid = getpid(); fd = _open(RANDOMDEV, O_RDONLY, 0); + done = 0; if (fd >= 0) { - (void) _read(fd, rdat.rnd, sizeof(rdat.rnd)); - _close(fd); + if (_read(fd, &rdat, KEYSIZE) == KEYSIZE) + done = 1; + (void)_close(fd); } - /* fd < 0? Ah, what the heck. We'll just take whatever was on the - * stack... */ + if (!done) { + (void)gettimeofday(&rdat.tv, NULL); + rdat.pid = getpid(); + /* We'll just take whatever was on the stack too... */ + } - arc4_addrandom((void *) &rdat, sizeof(rdat)); + arc4_addrandom((u_char *)&rdat, KEYSIZE); /* * Throw away the first N bytes of output, as suggested in the |