Re: [PATCH v24 00/12] /dev/random - a new approach with full SP800-90B compliance

Stephan Müller
2019-11-12T23:05:03Z

Am Dienstag, 12. November 2019, 16:33:59 CET schrieb Andy Lutomirski:

Hi Andy,

> On Mon, Nov 11, 2019 at 11:13 AM Stephan Müller <smueller@chronox.de> wrote:
> > The following patch set provides a different approach to /dev/random which
> > is called Linux Random Number Generator (LRNG) to collect entropy within
> > the Linux kernel. The main improvements compared to the existing
> > /dev/random is to provide sufficient entropy during boot time as well as
> > in virtual environments and when using SSDs. A secondary design goal is
> > to limit the impact of the entropy collection on massive parallel systems
> > and also allow the use accelerated cryptographic primitives. Also, all
> > steps of the entropic data processing are testable.
>
> This is very nice!
>
> > The LRNG patch set allows a user to select use of the existing /dev/random
> > or the LRNG during compile time. As the LRNG provides API and ABI
> > compatible interfaces to the existing /dev/random implementation, the
> > user can freely chose the RNG implementation without affecting kernel or
> > user space operations.
> >
> > This patch set provides early boot-time entropy which implies that no
> > additional flags to the getrandom(2) system call discussed recently on
> > the LKML is considered to be necessary.
>
> I'm uneasy about this. I fully believe that, *on x86*, this works.
> But on embedded systems with in-order CPUs, a single clock, and very
> lightweight boot processes, most or all of boot might be too
> deterministic for this to work.

I agree that in such cases, my LRNG getrandom(2) would also block until the
LRNG thinks it collected 256 bits of entropy. However, I am under the
impression that the LRNG collects that entropy faster that the existing /dev/
random implementation, even in this case.

Nicolai is copied on this thread. He promised to have the LRNG tested on such
a minimalistic system that you describe. I hope he could contribute some
numbers from that test helping us to understand how much of a problem we face.
>
> I have a somewhat competing patch set here:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/log/?h=random
> /kill-it
>
> (Ignore the "horrible test hack" and the debugfs part.)
>
> The basic summary is that I change /dev/random so that it becomes
> functionally identical to getrandom(..., 0) -- in other words, it
> blocks until the CRNG is initialized but is then identical to
> /dev/urandom.

This would be equal to the LRNG code without compiling the TRNG.

> And I add getrandom(...., GRND_INSECURE) that is
> functionally identical to the existing /dev/urandom: it always returns
> *something* immediately, but it may or may not actually be
> cryptographically random or even random at all depending on system
> details.

Ok, if it is suggested that getrandom(2) should also have a mode to behave
exactly like /dev/urandom by not waiting until it is fully seeded, I am happy
to add that.
>
> In other words, my series simplifies the ABI that we support. Right
> now, we have three ways to ask for random numbers with different
> semantics and we need to have to RNGs in the kernel at all time. With
> my changes, we have only two ways to ask for random numbers, and the
> /dev/random pool is entirely gone.

Again, I do not want to stand in the way of changing the ABI if this is the
agreed way. All I want to say is that the LRNG seemingly is initialized much
faster than the existing /dev/random. If this is not fast enough for some
embedded environments, I would not want to stand in the way to make their life
easier.
>
> Would you be amenable to merging this into your series (i.e. either
> merging the code or just the ideas)?

Absolutely. I would be happy to do that.

Allow me to pull your code (I am currently behind a slow line) and review it
to see how best to integrate it.

> This would let you get rid of
> things like the compile-time selection of the blocking TRNG, since the
> blocking TRNG would be entirely gone.

Hm, I am not so sure we should do that.

Allow me to explain: I am also collaborating on the European side with the
German BSI. They love /dev/random as it is a "NTG.1" RNG based on their AIS 31
standard.

In order to seed a deterministic RNG (like OpenSSL, GnuTLS, etc. which are all
defined to be "DRG.3" or "DRG.2"), BSI mandates that the seed source is an
NTG.1.

By getting rid of the TRNG entirely and having /dev/random entirely behaving
like /dev/urandom or getrandom(2) without the GRND_RANDOM flag, the kernel
would "only" provide a "DRG.3" type RNG. This type of RNG would be disallowed
to seed another "DRG.3" or "DRG.2".

In plain English that means that for BSI's requirements, if the TRNG is gone
there would be no native seed source on Linux any more that can satisfy the
requirement. This is the ultimate reason why I made the TRNG compile-time
selectable: to support embedded systems but also support use cases like the
BSI case.

Please consider that I maintain a study over the last years for BSI trying to
ensure that the NTG.1 property is always met [1] [2]. The sole purpose of that
study is around this NTG.1.
>
> Or do you think that a kernel-provided blocking TRNG is a genuinely
> useful thing to keep around?

Yes, as I hope I explained it appropriately above, there are standardization
requirements that need the TRNG.

PS: When I was forwarding Linus' email on eliminating the blocking_pool to
BSI, I saw unhappy faces. :-)

I would like to help both sides here.

[1] https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Studies/
LinuxRNG/NTG1_Kerneltabelle_EN.pdf?__blob=publicationFile&v=3

[2] https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/Studies/
LinuxRNG/NTG1_Kerneltabelle_EN.pdf?__blob=publicationFile&v=3

Ciao
Stephan