diff options
author | ache <ache@FreeBSD.org> | 2008-07-21 21:57:30 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2008-07-21 21:57:30 +0000 |
commit | c65a53e7022c74b7a49ad2ece2d40b552dee6201 (patch) | |
tree | efbd48a1a9ddc4f9754556ac9041c589ad69bb8b /lib | |
parent | 52a393acadb5f26325eb0916c7e62876f726d8c4 (diff) | |
download | FreeBSD-src-c65a53e7022c74b7a49ad2ece2d40b552dee6201.zip FreeBSD-src-c65a53e7022c74b7a49ad2ece2d40b552dee6201.tar.gz |
1) Use __packed attr on rdat structure to make it exact 128 bytes.
2) Use gettimeofday() and getpid() only if reading from /dev/urandom
fails or impossible.
3) Discard N bytes on very first initialization only (i.e. don't
discard on re-stir).
4) Reduce N from 1024 to 512 as really suggested in the
"(Not So) Random Shuffles of RC4" paper:
http://research.microsoft.com/users/mironov/papers/rc4full.pdf
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/arc4random.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index 69dae4b..68d727d 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -106,34 +106,41 @@ arc4_addrandom(u_char *dat, int datlen) static void arc4_stir(void) { - int fd, n; + int fd, n, done; struct { struct timeval tv; pid_t pid; u_int8_t rnd[128 - sizeof(struct timeval) - sizeof(pid_t)]; - } rdat; + } __packed 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)); + if (_read(fd, &rdat, sizeof(rdat)) == sizeof(rdat)) + done = 1; (void)_close(fd); } - /* fd < 0? Ah, what the heck. We'll just take whatever was on the + /* !done? Ah, what the heck. We'll just take whatever was on the * stack... */ + if (!done) { + gettimeofday(&rdat.tv, NULL); + rdat.pid = getpid(); + } arc4_addrandom((u_char *)&rdat, sizeof(rdat)); /* * Throw away the first N bytes of output, as suggested in the * paper "Weaknesses in the Key Scheduling Algorithm of RC4" - * by Fluher, Mantin, and Shamir. N=1024 is based on + * by Fluher, Mantin, and Shamir. N=512 is based on * suggestions in the paper "(Not So) Random Shuffles of RC4" * by Ilya Mironov. */ - for (n = 0; n < 1024; n++) - (void)arc4_getbyte(); + if (rs_initialized != 1) { + for (n = 0; n < 512; n++) + (void)arc4_getbyte(); + rs_initialized = 1; + } arc4_count = 1600000; } @@ -170,7 +177,7 @@ arc4_check_init(void) { if (!rs_initialized) { arc4_init(); - rs_initialized = 1; + rs_initialized = 2; } } |