Re: Linux 5.3-rc8

From: Willy Tarreau
Date: Mon Sep 16 2019 - 02:13:37 EST


On Sun, Sep 15, 2019 at 10:02:02PM -0700, Linus Torvalds wrote:
> On Sun, Sep 15, 2019 at 9:30 PM Willy Tarreau <w@xxxxxx> wrote:
> >
> > I'd be in favor of adding in the man page something like "this
> > random source is only suitable for applications which will not be
> > harmed by getting a predictable value on output, and as such it is
> > not suitable for generation of system keys or passwords, please
> > use GRND_RANDOM for this".
>
> The problem with GRND_RANDOM is that it also ends up extracting
> entropy, and has absolutely horrendous performance behavior. It's why
> hardly anybody uses /dev/random.
>
> Which nobody should really ever do. I don't understand why people want
> that thing, considering that the second law of thermodynamics really
> pretty much applies. If you can crack the cryptographic hashes well
> enough to break them despite reseeding etc, people will have much more
> serious issues than the entropy accounting.

That's exactly what I was thinking about a few minutes ago and which
drove me back to mutt :-)

> So the problem with getrandom() is that it only offered two flags, and
> to make things worse they were the wrong ones.
(...)
> - GRND_RANDOM | GRND_NONBLOCK - don't use
>
> This won't block, but it will decrease the blocking pool entropy.
>
> It might be an acceptable "get me a truly secure ring with reliable
> performance", but when it fails, you're going to be unhappy, and there
> is no obvious fallback.
>
> So three out of four flag combinations end up being mostly "don't
> use", and the fourth one isn't what you'd normally want (which is just
> plain /dev/urandom semantics).

I'm seeing it from a different angle. I now understand better why
getrandom() absolutely wants to have an initialized pool, it's to
encourage private key producers to use a secure, infinite source of
randomness. Something that neither /dev/random nor /dev/urandom
reliably provide. Unfortunately it does it by changing how urandom
works while it ought to have done it as the replacement of /dev/random.

The 3 random generation behaviors we currently support are :

- /dev/random: only returns safe random (blocks), AND depletes entropy.
getrandom(GRND_RANDOM) does the same.
- /dev/urandom: returns whatever (never blocks), inexhaustible
- getrandom(0): returns safe random (blocks), inexhaustible

Historically we used to want to rely on /dev/random for SSH keys and
certificates. It's arguable that with the massive increase of crypto
usage, what used to be done only once in a system's life happens a
bit more often and using /dev/random here can sometimes become a
problem because it harms the whole system (thus why I said I think that
we could almost require CAP_something to access it). Applications
falling back to /dev/urandom obviously resulted in the massive mess
we've seen years ago, even if it apparently solved the problem for
their users. Thus getrandom(0) does make sense, but not as an
alternative to urandom but to random, since it returns randoms safe
for use for long lived keys.

Couldn't we simply change the way things work ? Make GRND_RANDOM *not*
deplate entropy, and document it as the only safe source, and make the
default call return the same as /dev/urandom ? We can then use your
timeout mechanism for the first one (which is not supposed to be called
often and would be more accepted with a moderately long delay).

Applications need to evolve as well. It's fine to use libraries to do
whatever you need for you but ultimately the lib exports a function for
a generic use case and doesn't know how to best adapt to the use case.
Typically I would expect an SSH/HTTP daemon running in a recovery
initramfs to produce unsafe randoms so that I can connect there without
having to dance around it. However the self-signed cert produced there
must not be saved, just like the SSH host key. But this means that the
application (here the ssh-keygen or openssl) also need to be taught to
purposely produce insecure keys when explicitly instructed to do so.
Otherwise we know what will happen in the long term, since history
repeats itself as long as the conditions are not changed :-/

Willy