[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
|
|
Subscribe / Log in / New account

Initializing the entropy pool using RDRAND and friends

By Jake Edge
July 24, 2018

Random number generation in the kernel has garnered a lot of attention over the years. The tensions between the need for cryptographic-strength random numbers versus getting strong random numbers more quickly—along with the need to avoid regressions—has led to something of a patchwork of APIs. While it is widely agreed that waiting for a properly initialized random number generator (RNG) before producing random numbers is the proper course, opinions differ on what "properly" means exactly. Beyond that, waiting, especially early in the boot process, can be problematic as well. One solution would be to trust the RNG instructions provided by most modern processors, but that comes with worries of its own.

Theodore Ts'o posted a patch on July 17 to add a kernel configuration option that would explicitly trust the CPU vendor's hardware RNG (e.g. the RDRAND instruction for x86). Kernels built with RANDOM_TRUST_CPU will immediately initialize the random number pool using the architecture's facility, without waiting for enough entropy to accumulate from other sources; this means that the getrandom() system call will not block. Waiting for systems to gather enough entropy has been a problem in the past, especially for virtual machines and embedded systems where such entropy can be difficult to find.

Currently, the kernel uses CPU-provided random number instructions as part of the process of mixing data into the entropy pool, without crediting any entropy to it; the patch would go further than that. Instead of waiting for enough entropy to be gathered at boot time, it would simply initialize the pool from the output of RDRAND (or other similar instructions). As Ts'o put it in the patch: "I'm not sure Linux distro's will thank us for this. The problem is trusting the CPU [manufacturer] can be an emotional / political issue."

There are some who would rather these hardware RNG instructions not be used at all for kernel random numbers. But blocking in getrandom() can lead to user space being unable to get random numbers as quickly as needed. By providing a configuration option, the kernel developers neatly avoid making a decision on whether to trust these hardware RNG instructions, but that leaves the decision to the distributions:

Even if I were convinced that Intel hadn't backdoored RDRAND (or an NSA agent backdoored RDRAND for them) such that the NSA had a NOBUS (nobody but us) capability to crack RDRAND generated numbers, if we made a change to unconditionally trust RDRAND, then I didn't want the upstream kernel developers to have to answer the question, "why are you willing to trust Intel, but you aren't willing to trust a company owned and controlled by a PLA [People's Liberation Army] general?" (Or a company owned and controlled by one of Putin's Oligarchs, if that makes you feel better.)

With this patch, we don't put ourselves in this position --- but we do put the Linux distro's in this position [instead]. The upside is it gives the choice to each person building their own Linux kernel to decide whether trusting RDRAND is worth it to avoid hangs due to userspace trying to get cryptographic-grade entropy early in the boot process.

Sandy Harris wondered if there should be a value associated with the option, which would say how many bits of entropy the user thinks should be credited per 32-bit value from the hardware RNG. But Ts'o pointed out that his patch (which has a code diff roughly the same size as the text for its configuration option) does not mess with the entropy estimation. In any case, he is skeptical that kind of knob would truly be useful:

In practice I doubt most people would be able to deal with a numerical dial, and I'm trying to [encourage] people to use getrandom(2). I view /dev/random as a legacy interface, and for most people a CRNG [Cryptographic-strength RNG] is quite sufficient. For those people who are super paranoid and want a "true random number generator" (and the meaning of that is hazy) because a CRNG is Not Enough, my recommendation these days is that they get something like an open hardware RNG solution, such as ChaosKey from Altus Metrum.

Other external hardware RNG devices were also mentioned as possibilities in the thread.

In case distributors choose to enable this in their kernels, Yann Droneaud would like to see a kernel command-line option to disable it. That would likely make it easier for distributions to build kernels with it enabled since their users would have a way to override it without building their own kernel. Ts'o did not reply to that particular request directly, but his patch is meant as an RFC, so perhaps we will see that in the next version. In response to Droneaud, he did elaborate, including some thoughts on threat models:

The trust model that we're using is this. The presumption is that (at least for US-based CPU [manufacturers]) the amount of effort needed to add a [blatant] backdoor to, say, the instruction scheduler and register management file is such that it couldn't be done by a single engineer, or even a very small set of engineers. Enough people would need to know about it, or would be able to figure out something untowards was happening, or it would be obvious through various regression tests, that it would be obvious if there was a generic back door in the CPU itself. This is a good thing, because ultimately we *have* to trust the general purpose CPU. If the CPU is actively conspiring against you, there really is no hope.

However, the RDRAND unit is a small, self-contained thing, which is *documented* to use an AES whitener (e.g., it does an AES encryption as its last step). So presumably, a change to make the RDRAND unit effectively be:

	AES_ENCRYPT(NSA_KEY, COUNTER++)
Is much easier to hide or introduce.

Laura Abbott was set to test the patch on a Fedora Rawhide kernel, but found that the hang at boot time waiting for random numbers had been fixed some other way. But she did think the option was a good idea:

That said, I do think this is a beneficial option to have available because it actually fixes the underlying problem instead of hoping nobody else decides to block early in the bootup process.

It is a simple change, though likely somewhat controversial—for distributions anyway. Another approach might be to simply change the kernel to always allow boot-time selection of whether to trust the CPU's hardware RNG. Defaulting that to "do not trust" would effectively leave things as they are today, but give users a way to decide for themselves—and take distributions off the hot seat if one truly exists.


Index entries for this article
KernelRandom numbers
KernelSecurity/Random number generation
SecurityLinux kernel/Random number generation
SecurityRandom number generation


to post comments

Initializing the entropy pool using RDRAND and friends

Posted Jul 24, 2018 18:44 UTC (Tue) by josh (subscriber, #17465) [Link] (9 responses)

Along the same lines, it'd be interesting to see a patch that makes getrandom into a VDSO call that can optionally just call RDRAND *directly* and never even enter the kernel.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 7:14 UTC (Wed) by mb (subscriber, #50428) [Link] (8 responses)

RDRAND does not seem to be privileged. You can just use it in your application.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 7:35 UTC (Wed) by josh (subscriber, #17465) [Link]

It isn't, but it'd be nice to have a compatible solution that works on systems with or without it, and just uses it for acceleration if available.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 8:18 UTC (Wed) by gioele (subscriber, #61675) [Link] (6 responses)

> RDRAND does not seem to be privileged. You can just use it in your application.

It's not that easy. An application that uses the output of RDRAND without mixing it with other sources of randomness is insecure.

https://www.freebsd.org/news/status/report-2013-09-devsum...
https://news.ycombinator.com/item?id=6336505 (tytso)
http://comments.gmane.org/gmane.comp.security.cryptograph...

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 11:58 UTC (Wed) by azumanga (subscriber, #90158) [Link] (5 responses)

None of the comments you link to seem to back up your claim. A bunch of people seem to be paranoid that Intel might be willing to throw away all good will they will ever have, to introduce a back door that will be found one day, in RDRAND. That seems like extreme paranoia to me, against the genuine problem of many machines today not producing good enough random numbers at startup.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 13:23 UTC (Wed) by excors (subscriber, #95769) [Link] (1 responses)

There's also a significant difference between "insecure" and "secure if (and only if) you trust Intel". Even if you don't trust Intel, you shouldn't ignore that distinction.

And if you don't trust Intel, XORing the output of RDRAND with other random data won't save you. https://www.alchemistowl.org/pocorgtfo/pocorgtfo03.pdf (warning: large PDF) chapter 6 shows how a CPU (or CPU emulator in their case) could backdoor /dev/urandom by making RDRAND detect the data that the kernel is going to XOR it with, then have RDRAND return that data XOR some target string, so the final output from /dev/urandom is simply that target string. And of course a CPU backdoor could do the same even to code that *doesn't* use RDRAND, with just a little more effort to detect where to insert its malicious behaviour. You can't get away from the need to trust your hardware.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 14:05 UTC (Wed) by farnz (subscriber, #17727) [Link]

Of course, as Ted T'so has already said, there are degrees of trust in Intel. Changing the AES whitener in RDRAND to be non-random is plausibly simple enough that you only need to compromise one to five individuals (as the final behaviour is not "weird" - it's expected behaviour that happens to be compromised) in order to have control of RDRAND's output; changing the CPU to detect the kernel data as per the "PoC || GTFO" paper requires you to comprise dozens to hundreds of individuals, so that the "weird" behaviour is not noticed during validation.

So, you can trust that a mass compromise of Intel is not going to happen, while still being concerned that two or three individuals are working against you.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 17:27 UTC (Wed) by felixfix (subscriber, #242) [Link] (2 responses)

Was it Ritchie, Thompson, Kernigan, or someone else who posited a C compiler which recognized when it was compiling itself and inserted the self-recognition code along with backdoor code?

At some point you either seal yourself inside a room with no outside contact, or you start taking risks that have very little probability of ever happening.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 18:17 UTC (Wed) by josh (subscriber, #17465) [Link] (1 responses)

That was Reflections on Trusting Trust by Ken Thompson.

Reflections on Trusting Trust

Posted Jul 27, 2018 14:55 UTC (Fri) by david.a.wheeler (subscriber, #72896) [Link]

"Reflections on trusting trust" by Ken Thompson, Communications of the ACM CACM Homepage, Volume 27 Issue 8, Aug 1984, Pages 761-763. This is the first published demonstration of the attack (the attack itself was identified in an earlier Multics paper). Copies of Thompson's paper are available at:
https://dl.acm.org/citation.cfm?id=358210
https://web.archive.org/web/20150309043401/cm.bell-labs.c...
https://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-th...

However, it is *NOT* turtles all the way down. My PhD dissertation is on a countermesaure called "Diverse Double-Compiling" (DDC). More info available here: https://www.dwheeler.com/trusting-trust/

Initializing the entropy pool using RDRAND and friends

Posted Jul 24, 2018 21:54 UTC (Tue) by judas_iscariote (guest, #47386) [Link]

A kernel parameter that allows me to not even start /sbin/init until the rng is seeded or one that does what ted's RANDOM_TRUST_CPU is enough for me. a kernel configuration option unfortunately is useless for people that do not build their own kernel.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 0:35 UTC (Wed) by xtifr (guest, #143) [Link] (6 responses)

Yeah, count me as another vote for runtime/boottime selection, rather than compile time. The distros will thank you, the *users* will thank you--just about everyone except the person who actually has to write the code will thank you. :)

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 7:27 UTC (Wed) by simcop2387 (subscriber, #101710) [Link] (5 responses)

The only problem with this is that it means that it could be changed by an evil maid. I think it should be a choice, forced permanent into the kernel (on or off) or as a kernel command line parameter if you've got a way to trust the bootloader (though if you don't trust the bootloader....)

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 8:00 UTC (Wed) by nilsmeyer (guest, #122604) [Link] (1 responses)

One could add a compile-time option to ignore the kernel command line option ;) Isn't it conceivable though that the evil maid just replaces your kernel?

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 13:18 UTC (Wed) by mjthayer (guest, #39183) [Link]

> One could add a compile-time option to ignore the kernel command line option ;) Isn't it conceivable though that the evil maid just replaces your kernel?

Perhaps some clever person can find a way to tie the desired state of the option to kernel lockdown.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 8:50 UTC (Wed) by smurf (subscriber, #17840) [Link] (2 responses)

Well, the kernel PRNG doesn't just forward the hardware RNG to userspace, it's hashed. Since AFAIK nobody has ever found a repeated kernel RNG stream, there's no wall clock inside the CPU, and the hash function hasn't been compromised (otherwise we'd be in deep shit anyway), frankly I fail to see what the paranoia is all about.

Initializing the entropy pool using RDRAND and friends

Posted Jul 26, 2018 19:21 UTC (Thu) by Otus (subscriber, #67685) [Link]

> the hash function hasn't been compromised (otherwise we'd be in deep shit anyway)

SHA1 *has* been compromised. Just not in a way that would help attack its use here.

Initializing the entropy pool using RDRAND and friends

Posted Aug 2, 2018 4:50 UTC (Thu) by njs (subscriber, #40338) [Link]

If there were, say, 2**64 different possible RDRAND streams, then that'd be large enough that people would be unlikely to notice a duplicate without extensive effort, but still entirely possible for someone like the NSA to precompute all the hashed getrandom() output streams.

Initializing the entropy pool using RDRAND and friends

Posted Jul 25, 2018 13:55 UTC (Wed) by naptastic (guest, #60139) [Link]

From the linked email by Eugen Leitl:

> Linus decided to include a patch from Intel to allow their unauditable RdRand to bypass the entropy pool over my strenuous objections.

I want to make sure I understand the implications of this correctly.

What are the circumstances (if any) in which Intel's RNG will be passed back to userspace unaltered? Is there a way I can make sure my system _always_ combines multiple sources of entropy? Is there a way I can completely remove RdRand from the equation? I'm not saying I necessarily want to, I'm just trying to make sure my understanding is correct.

Thanks!

Initializing the entropy pool using RDRAND and friends

Posted Jul 27, 2018 15:48 UTC (Fri) by imMute (guest, #96323) [Link]

From the article:

>There are some who would rather these hardware RNG instructions not be used at all for kernel random numbers.

From the linked email:

>It's worth noting that the maintainer of record (me) for the Linux RNG quit the project about two years ago precisely because Linus decided to include a patch from Intel to allow their unauditable RdRand to bypass the entropy pool over my strenuous objections.

The LWN article implies that someone is objecting to using RDRAND at all (even if mixed in with other sources). The linked complaint is about using *only* RDRAND ("allow ... RdRand to bypass the entropy pool"). Seems a bit disingenuous for LWN to word it the way they did...


Copyright © 2018, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds