NetBSD recently changed to a /dev/urandom implementation which keys a stream generator per-open rather than one that draws bits directly from the kernel entropy pool. When we did this we added a number of extra warnings that are triggered by applications consuming large amounts of entropy.
Shortly thereafter, we noticed that OpenSSH sshd uses a great deal of entropy indeed, though it does not directly access /dev/urandom nor does it directly call the OpenSSL RAND API. The root cause of this behavior is that sshd re-execs itself for each new connection, which then causes OpenSSL to reinitialize the SSLeay entropy gathering functions that are in crypto/rand/md_rand.c. They in turn call RAND_poll() in crypto/rand/rand_unix.c, and for each call to RAND_poll, OpenSSL opens /dev/urandom, reads 256 bits, and closes /dev/urandom. While considering ways for OpenSSH to be somewhat stingier with random bits from the kernel, I noticed two rather dubious things about the md_rand.c/rand_unix.c code: * First, there is an #ifdef OpenBSD block which replaces the entirety of RAND_poll() with calls to arc4random(). I can only assume this was done when someone running OpenBSD noticed the same problem with excessive entropy consumption from /dev/urandom that I have just noticed on NetBSD. Unless I misunderstand, this means that all the key material for the new FIPS-compliant CTR_DRBG is in fact being supplied by an instance of RC4! That seems extremely questionable at best. * Second, I believe the interaction of the "initialized" and "ok" tests in ssleay_rand_bytes() in md_rand.c is not right, because it prevents an application from seeding the generator with entropy of its own choice rather than having it autopmatically seeded by RAND_poll(). I think the block: if (!initialized) { RAND_poll(); initialized = 1; } Should be removed. I think that the RAND_poll() call should be moved to the "if (!ok)" block just below, instead. As I read the code, this would allow an application to seed the generator with entropy via RAND_seed(), RAND_add(), or RAND_load_file() and avoid the /dev/urandom use. With this change I could make OpenSSH sshd pass entropy from parent to child when re-executing itself, which would be a huge improvement to entropy consumption on many server systems and would also probably allow removal of the awful arc4random() hack mentioned above, while achieving what I think was probably its original design goal. Opinions? Thor ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org