[openssl-dev] Improving OpenSSL default RNG

Kurt Roeckx kurt at roeckx.be
Fri Oct 23 18:57:10 UTC 2015


On Fri, Oct 23, 2015 at 03:22:39PM +0200, Alessandro Ghedini wrote:
> Hello everyone,
> 
> (sorry for the wall of text...)
> 
> one of the things that both BoringSSL and LibreSSL have in common is the
> replacement of OpenSSL's default RNG RAND_SSLeay() with a simpler and saner
> alternative. Given RAND_SSLeay() complexity I think it'd be worth to at least
> consider possible alternatives for OpenSSL.

I think at least a few of us want to see something changed, but
I'm not sure what direction it's going to go.

> 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 problem with only relying on /dev/urandom on Linux is that
it can give you data without having had enough entropy feed in it
first.  At least getrandom() will fix that, but that's only in the
kernel since 3.17 and a lot of people still don't have that.  But
maybe most people will actually have it on systems that are going
to run 1.1.

This is of course not a new problem, we also already have that
now.

I think some people have concerns about only relying on the OSs
RNG and instead want to get a high entropy seed from it and use
that to feed our own RNG.  We might use a better (by whatever
definition) algorithm than the kernel is using.

Only using /dev/urandom might result in people complaining that we
start to drain their available entropy.  I don't know enough about
the Linux kernel's implementation of the RNG, but their
calculation just seems wrong to me.

> Incidentally, BoringSSL added a whole new API for thread-local storage which
> OpenSSL could adopt given that e.g. the ASYNC support could benefit from it
> (there are other interesting bits in BoringSSL, like the new threading API that
> could also be adopted by OpenSSL).

Threads, and so thread-local storage, is all very OS specific.
And I'm afraid we don't have that on all platforms we still want
to support.  But I think that belongs in a different discussion.

> 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).

An other issue is that /dev/urandom might not be available in a
chroot or when you run out of file descriptor.  The chroot is at
least something the LibreSSL seems to be running in to, but is
nothing we can really do about on all OSs.

> 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.

I think the arc4random() thing is such a misleading name since it
doesn't have anything to do with (A)RC4 anymore.  I'm also not
sure that the implementation with ChaCha20 is the best way to go,
you could also go for something like Fortuna, or stay with
whatever we use now.

We currently don't reseed, and I have no idea what amount of data
we should be able to safely extract from it now, I think it's
rather large, but reseeding should never hurt.



Kurt



More information about the openssl-dev mailing list