[openssl-dev] Improving OpenSSL default RNG

Alessandro Ghedini alessandro at ghedini.me
Fri Oct 23 14:00:51 UTC 2015


On Fri, Oct 23, 2015 at 03:38:51pm +0200, Tomas Mraz wrote:
> On Pá, 2015-10-23 at 15:22 +0200, Alessandro Ghedini wrote:
> ...
> > BoringSSL started using the system RNG (e.g. /dev/urandom) for every call to
> > RAND_bytes(). Additionally, if the RDRAND instruction is available, the output
> > of RDRAND is mixed with the output of the system RNG using ChaCha20. This uses
> > thread-local storage to keep the global RNG state.
> ...
> > The BoringSSL method is very simple but it needs a read from /dev/urandom for
> > every call to RAND_bytes() which can be slow (though, BoringSSL's RAND_bytes()
> > seems to implement some sort of buffering for /dev/urandom so the cost may be
> > lower).
> > 
> > On the other hand, LibreSSL replaced the whole RAND_* API with calls to
> > OpenBSD's arc4random(). This is a nice and simple scheme that uses ChaCha20 to
> > mix the internal RNG state, which is regularly reseeded from the system RNG.
> > The core logic of this (excluding ChaCha20 and platform-specific bits) is
> > implemented in less than 200 lines of code and, at least in theory, it's the
> > one that provides the best performance/simplicity trade-off (ChaCha20 can be
> > pretty fast even for non-asm platform-generic implementations).
> > 
> > Both of these methods are robust and mostly platform-indipendent (e.g. none of
> > them uses the system time, PID or uninitilized buffers to seed the RNG state)
> > and have simple implementations, so I think OpenSSL can benefit a lot from
> > adopting one of them. The astute readers may point out that OpenSSL doesn't
> > support ChaCha20 yet, but that's hopefully coming soon.
> 
> How these libraries handle generation of random numbers after the
> fork()? The mixing in of the system time & PID before pulling bytes from
> RNG prevents sharing two identical streams of random numbers among
> forked processes. If there is a buffering of data pulled from the kernel
> RNG it is not sufficient to just say that all the data are pulled from
> the kernel and thus unique.

So, it seems that BoringSSL's /dev/urandom buffering is disabled by default and
needs to be explicitly enabled by calling RAND_enable_fork_unsafe_buffering().

arc4random() detects forks by registering a pthread_atfork() handler and/or by
checking changes in getpid() output before returning any randomness. When a
fork is detected, the internal state is automatically re-seeded with the system
RNG.

Cheers
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://mta.openssl.org/pipermail/openssl-dev/attachments/20151023/fc6aaefa/attachment.sig>


More information about the openssl-dev mailing list