Re: Linux messages full of `random: get_random_u32 called from`

From: Trent Piepho
Date: Mon May 21 2018 - 13:45:13 EST


On Fri, 2018-05-18 at 19:22 -0400, Theodore Y. Ts'o wrote:
> On Fri, May 18, 2018 at 10:56:18PM +0000, Trent Piepho wrote:
> >
> > Let's look at what we're doing after this fix:
> > Want non-cryptographic random data for UUID, ask kernel for it.
> > Kernel has non-cryptographic random data, won't give it to us.
> > Wait one second for cryptographic random data, which we didn't need.
> > Give up and create our own random data, which is non-cryptographic and
> > even worse than what the kernel could have given us from the start.
> >
> > util-linux falls back to rand() seeded with the pid, uid, tv_sec, and
> > tv_usec from gettimeofday(). Pretty bad on an embedded system with no
> > RTC and worse than what the kernel in crng_init 1 state can give us.
>
> So what util-linux's libuuid could do is fall back to using
> /dev/urandom instead. Whether or not you retry for a second before
> you fall back to /dev/urandom really depends on how important the
> second U in UUID ("unique") is to you. If you use lower quality
> randomness, you can potentially risk getting non-unique UUID's.

Does it really matter how long one waits? The fact that there is a
fallback that can be used would seem to provide a guarantee of
randomness/uniquness only as good as that fallback.

And here is the fallback, https://github.com/karelzak/util-linux/blob/m
aster/lib/randutils.c#L64

It doesn't seem all that great. Can we say that the kernel, e.g.
urandom, can always provide random data at least as good as the above
without blocking? If the kernel is always as good or better, then
what's the point of having the inferior fallback?

> If you don't worry leaking your computer's identity and the time when
> the UUID was generated, the application could also use the time-based
> UUID's. There are privacy implications for doing so, it's not

libuuid will still ask for random data to initialize its clock file:

https://github.com/karelzak/util-linux/blob/master/libuuid/src/gen_uuid
.c#L281


> > It would seem to be a fact that there will be users of non-
> > cryptographic random data in early boot. What is the best practice for
> > that? To fall back to each user trying "to find randomly-looking
> > things on an 1990s Unix." That doesn't seem good to me. But what's
> > the better way?
>
> We could add a new flag to getrandom(2), but application authors can
> just as easily fall back to using /dev/urandom. The real concern I

I wouldn't say just as easily. It's a more complex code path,
documented across multiple man pages and requires certain file system
access that getrandom() doesn't. But it's certainly readily
achievable, so maybe that's good enough. I think a flag to getrandom
would result in fewer mistakes in userspace code.

> have is application authors that actually *really* need cryptographic
> randomness, but they're too lazy to figure out a way to defer key
> generation until the last possible moment.

Would it be safe to say the the randutils code in util-linux would be
better off falling back to /dev/urandom instead of what it does?

If authors that really need cryptographic data use random_get_bytes()
or uuid_generate(), they'll get code that automatically falls back to
gettimeofday(). And probably not even know it.

I get your concern about lazy authors using an API that isn't
appropriate for their use case.

But we have this api already, in util-linux and code copied/inspired by
it, and it seems there are use cases where it is appropriate. If we
make it better(*), then does the risk of it being used where it
shouldn't go up?

(*) Better: use the best available random data that can be provided
without blocking.


> There are other things we can do to add support in the bootloader to
> read an entropy state file and inject it into the kernel alongside the
> initrd and boot command line. But that doesn't completely solve the
> problem; you still have to deal with the "frest from the factory,

This is problematic on a number of embedded platforms.

The bootloader might have no writable persistent storage to read/write
this entropy from. This requires drivers for the storage hardware,
ability to deal with the storage being in an inconsistent state, and
security of the storage. Assuming hardware for writable storage even
exists.

So if I want u-boot to read/write an encrypted and authenticated flash
file system, there is a lot of code to put in the bootloader! And now
we have to worry about that being exploited. Maybe this means the
bootloader needs an encryption key that it didn't previous need have
access to.

Some systems have a limit on bootloader size and RAM. Cyclone 5 is
64kB, which pretty much requires a two stage bootloader. Arria 10 has
256kB and boots in a single stage, but bootloader features are quite
limited. On imx23, it's possible to boot directly into linux with no
bootloader at all. The cpu's rom can initialize the hardware enough to
run linux just from info in the mxs boot image format.