2019-09-27 15:59:54

by Linus Torvalds

[permalink] [raw]
Subject: Re: Linux 5.3-rc8

On Fri, Sep 27, 2019 at 6:57 AM Lennart Poettering <[email protected]> wrote:
>
> Doing the random seed in the boot loader is nice for two reasons:
>
> 1. It runs very very early, so that the OS can come up with fully
> initialized entropy right from the beginning.

Oh, that part I love.

But I don't believe in your second case:

> 2. The boot loader generally has found some disk to read the kernel from,
> i.e. has a place where stuff can be stored and which can be updated
> (most modern boot loaders can write to disk these days, and so can
> EFI). Thus, it can derive a new random seed from a stored seed on disk
> and pass it to the OS *AND* update it right away on disk ensuring that
> it is never reused again.

No. This is absolutely no different at all from user space doing it
early with a file.

All the same "golden image" issues exist, and in general the less the
boot loader writes to disk, the better.

Plus it doesn't actually work anyway in the one situation where people
_really_ want it - embedded devices, where the kernel image is quite
possibly in read-only flash that needs major setup for updates.

PLUS.

Your "it can update it right away on disk" is just crazy talk. With
WHAT? It has no randomness to play with, and it doesn't have time to
do jitter entropy stuff.

So all it can do is a really bad job at taking the previous random
seed, doing some transformation on it, and add a little bit of
whatever system randomness it can find. None of which is any better
than what the kernel can do.

End result: you'd need to have the kernel update whatever bootloader
data later on, and I'm not seeing that happening. Afaik the current
bootloader interface has no way to specify how to update it when you
actually have better randomness.

> NVRAM backing EFI vars sucks. Nothing you want to update on every
> cycle. It's OK to update during OS installation, but during every
> single boot? I'd rather not.

I do agree that EFI nvram isn't wonderful, but hopefully nonvolatile
storage is improving, and it's conceptually the right thing.

Linus


2019-09-29 09:05:57

by Lennart Poettering

[permalink] [raw]
Subject: Re: Linux 5.3-rc8

On Fr, 27.09.19 08:58, Linus Torvalds ([email protected]) wrote:

> On Fri, Sep 27, 2019 at 6:57 AM Lennart Poettering <[email protected]> wrote:
> >
> > Doing the random seed in the boot loader is nice for two reasons:
> >
> > 1. It runs very very early, so that the OS can come up with fully
> > initialized entropy right from the beginning.
>
> Oh, that part I love.
>
> But I don't believe in your second case:
>
> > 2. The boot loader generally has found some disk to read the kernel from,
> > i.e. has a place where stuff can be stored and which can be updated
> > (most modern boot loaders can write to disk these days, and so can
> > EFI). Thus, it can derive a new random seed from a stored seed on disk
> > and pass it to the OS *AND* update it right away on disk ensuring that
> > it is never reused again.
>
> No. This is absolutely no different at all from user space doing it
> early with a file.
>
> All the same "golden image" issues exist, and in general the less the
> boot loader writes to disk, the better.
>
> Plus it doesn't actually work anyway in the one situation where people
> _really_ want it - embedded devices, where the kernel image is quite
> possibly in read-only flash that needs major setup for updates.
>
> PLUS.
>
> Your "it can update it right away on disk" is just crazy talk. With
> WHAT? It has no randomness to play with, and it doesn't have time to
> do jitter entropy stuff.

So these two issues are addressed by the logic implemented in sd-boot
(systemd's boot loader) like this:

The old seed is read off the ESP seed file. We then calculate two hash
sums in counter mode from it (SHA256), one we pass to the OS as seed
to initialize the random pool from. The other we use to update the ESP
seed file with. Unless you are capable of breaking SHA256 this means
the seed passed to the OS and the new seed stored on disk are derived
from the same seed but in a way you cannot determine one if you
managed to learn the other. Moreover, on each boot you are guaranteed
to get two new seeds, each time, and you cannot derive the sums used
on previous boots from those. This means we are robust towards
potential seed reuse when turning the system forcibly off during boot.

Now, what's still missing in the above is protection against "golden
image" issues, as you correctly pointed out. To deal with that the
SHA256 sums are not just hashed from the old seed and the counter, but
also include a system specific "system token" (you may also call it
"salt") which is stored in an EFI variable, persistently, which was
created once, during system installation. This hence gives you the
behaviour your are looking for, using the NVRAM like you suggested,
but we don't need to write the EFI vars all the time, as instead we
update the seed file stored in the ESP each time, and updating the ESP
should be safer and less problematic (i.e. if everything is done right
it's a single sector write).

To make this safer, on EFI firmwares that support the RNG protocol we
also include some data derived from that in the hash, just for good
measure. To sumarize:

NEWDISKSEED = SHA256(OLDDISKSEED || SYSTEMTOKEN || EFIRNGVAL || "1")
SEEDFORLINUX = SHA256(OLDDISKSEED || SYSTEMTOKEN || EFIRNGVAL || "2")

(and no, this is not a crypto scheme I designed, but something
Dr. Bertram Poettering (my brother, a cryptographer) suggested)

> So all it can do is a really bad job at taking the previous random
> seed, doing some transformation on it, and add a little bit of
> whatever system randomness it can find. None of which is any better
> than what the kernel can do.

Well, the kernel cannot hash and rewrite the old seed file early enough,
it's that simple. It can do that only when /var becomes writable,
i.e. very late during boot, much later than when we need entropy
for. The boot loader on the hand, can hash and rewrite the old seed
file even before the kernel initializes, and that's the big benefit!

> End result: you'd need to have the kernel update whatever bootloader
> data later on, and I'm not seeing that happening. Afaik the current
> bootloader interface has no way to specify how to update it when you
> actually have better randomness.

So, you could, but don't have to update the ESP random seed file from
the OS too, every now and then, but the security of the model dos not
rely on that.

(And yes, the above doesn't help if you have a fully R/O medium, but
those tend to be embedded devices, and I am much less concerned about
those, the designers really can deal with the RNG seed issues
themselves, and maybe provide some hw to do it; it's the generic user
PCs that we should be concerned about, and for those the above should
generally work)

Lennart

--
Lennart Poettering, Berlin