When applied along with revisions 1.10 and 1.11 of libc/gen/arc4random.c,
these patches should stop the excessive entropy consumption observed with
OpenSSH on current and NetBSD 6-branch systems.
I note that the cause of the problem is complex and somewhat amusing.
Let's start from this question: why on earth are there calls to
arc4random_stir() in unexpected places all over the OpenSSH sources?
Before and after every fork, after exec, in the key generation routines --
in places where there are no calls to arc4random() itself and where one
would hope there never had been (particularly for key generation!).
The reason turns out to be that, at some point, OpenSSL (not OpenSSH)
was patched for OpenBSD to make it use libc arc4random() as the source
of startup key material for its own RNG. In an application like OpenSSH
that does not use the SSL parts of the library and does not call RAND_seed(),
that is the *only* key material for the generator.
I can only guess this was done because OpenSSL was "using too much entropy"
from /dev/random or /dev/urandom. But the result was that programs like
OpenSSH, which call OpenSSL crypto functions in both halves after fork(),
would get the exact same bytes back from the generator (same primes for
ephemeral RSA or DH keys, same... *shudder*). The pervasive calls to
arc4random_stir() paper over this problem.
This hack was not applied for NetBSD so OpenSSL continued to draw down
new entropy after every fork-exec OpenSSH performed: one per connection,
at least. That's a lot of entropy.
The attached patch adjusts OpenSSL so its generator can be explicitly
fed enough entropy at startup that it won't try to autokey itself, and
adjusts OpenSSH so that it keeps an fd open to /dev/urandom and explicitly
draws bits as needed. /dev/urandom will never return the same bits
twice, so this is always safe; on systems like NetBSD where the urandom
implementation keys a stream generator per open, it is also very efficient.
Description: Text document