On Thu, Feb 17, 2022 at 05:28:48PM +0100, Jason A. Donenfeld wrote: > This topic has come up countless times, and usually doesn't go anywhere. > This time I thought I'd bring it up with a slightly narrower focus, > updated for some developments over the last three years: we finally can > make /dev/urandom always secure, in light of the fact that our RNG is > now always seeded. > > Ever since Linus' 50ee7529ec45 ("random: try to actively add entropy > rather than passively wait for it"), the RNG does a haveged-style jitter > dance around the scheduler, in order to produce entropy (and credit it) > for the case when we're stuck in wait_for_random_bytes(). How ever you > feel about the Linus Jitter Dance is beside the point: it's been there > for three years and usually gets the RNG initialized in a second or so. > > As a matter of fact, this is what happens currently when people use > getrandom(). It's already there and working, and most people have been > using it for years without realizing. > > So, given that the kernel has grown this mechanism for seeding itself > from nothing, and that this procedure happens pretty fast, maybe there's > no point any longer in having /dev/urandom give insecure bytes. In the > past we didn't want the boot process to deadlock, which was > understandable. But now, in the worst case, a second goes by, and the > problem is resolved. It seems like maybe we're finally at a point when > we can get rid of the infamous "urandom read hole". > > The one slight drawback is that the Linus Jitter Dance relies on random_ > get_entropy() being implemented. The first lines of try_to_generate_ > entropy() are: > > stack.now = random_get_entropy(); > if (stack.now == random_get_entropy()) > return; > > On most platforms, random_get_entropy() is simply aliased to get_cycles(). > The number of machines without a cycle counter or some other > implementation of random_get_entropy() in 2022, which can also run a > mainline kernel, and at the same time have a both broken and out of date > userspace that relies on /dev/urandom never blocking at boot is thought > to be exceedingly low. And to be clear: those museum pieces without > cycle counters will continue to run Linux just fine, and even > /dev/urandom will be operable just like before; the RNG just needs to be > seeded first through the usual means, which should already be the case > now. > > On systems that really do want unseeded randomness, we already offer > getrandom(GRND_INSECURE), which is in use by, e.g., systemd for seeding > their hash tables at boot. Nothing in this commit would affect > GRND_INSECURE, and it remains the means of getting those types of random > numbers. > > This patch goes a long way toward eliminating a long overdue userspace > crypto footgun. After several decades of endless user confusion, we will > finally be able to say, "use any single one of our random interfaces and > you'll be fine. They're all the same. It doesn't matter." And that, I > think, is really something. Finally all of those blog posts and > disagreeing forums and contradictory articles will all become correct > about whatever they happened to recommend, and along with it, a whole > class of vulnerabilities eliminated. > > With very minimal downside, we're finally in a position where we can > make this change. > > Cc: Dinh Nguyen <dinguyen@xxxxxxxxxx> > Cc: Nick Hu <nickhu@xxxxxxxxxxxxx> > Cc: Max Filippov <jcmvbkbc@xxxxxxxxx> > Cc: Palmer Dabbelt <palmer@xxxxxxxxxxx> > Cc: David S. Miller <davem@xxxxxxxxxxxxx> > Cc: Yoshinori Sato <ysato@xxxxxxxxxxxxxxxxxxxx> > Cc: Michal Simek <monstr@xxxxxxxxx> > Cc: Borislav Petkov <bp@xxxxxxxxx> > Cc: Guo Ren <guoren@xxxxxxxxxx> > Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> > Cc: Joshua Kinard <kumba@xxxxxxxxxx> > Cc: David Laight <David.Laight@xxxxxxxxxx> > Cc: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx> > Cc: Eric Biggers <ebiggers@xxxxxxxxxx> > Cc: Ard Biesheuvel <ardb@xxxxxxxxxx> > Cc: Arnd Bergmann <arnd@xxxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Andy Lutomirski <luto@xxxxxxxxxx> > Cc: Kees Cook <keescook@xxxxxxxxxxxx> > Cc: Lennart Poettering <mzxreary@xxxxxxxxxxx> > Cc: Konstantin Ryabitsev <konstantin@xxxxxxxxxxxxxxxxxxx> > Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > Cc: Theodore Ts'o <tytso@xxxxxxx> > Signed-off-by: Jason A. Donenfeld <Jason@xxxxxxxxx> > --- > Having learned that MIPS32 isn't affected by this (initially my largest > worry), and then heartened today upon reading LWN's summary of our > previous discussion ("it would seem there are no huge barriers to > removing the final distinction between /dev/random and /dev/urandom"), I > figured I'd go ahead and submit a v1 of this. It seems at least worth > trying and seeing if somebody arrives with legitimate complaints. To > that end I've also widened the CC list quite a bit. > > Changes v0->v1: > - We no longer touch GRND_INSECURE at all, in anyway. Lennart (and to an > extent, Andy) pointed out that getting insecure numbers immediately at > boot is still something that has legitimate use cases, so this patch > no longer touches that code. > > drivers/char/mem.c | 2 +- > drivers/char/random.c | 51 ++++++------------------------------------ > include/linux/random.h | 2 +- > 3 files changed, 9 insertions(+), 46 deletions(-) > Just a small nit: the comments above rng_is_initialized() and wait_for_random_bytes() still imply that /dev/urandom is nonblocking. - Eric