[Cryptography] RNG design principles

Ard Biesheuvel ard.biesheuvel at gmail.com
Sun Nov 27 11:55:24 EST 2016

2016-11-27 15:08 GMT+01:00 John Denker <jsd at av8n.com>:
> On 11/27/2016 05:18 AM, Ard Biesheuvel wrote:
>> OK, so bottom line is that GRUB needs to install the RNG seed config table if
>> - a randomseed env var is present (and it probably needs to clear it as well)
>> - (on x86) the firmware implements EFI_RNG_PROTOCOL
> I agree with that in spirit.  This seems like great progress.
> Here are some possible refinements:
> 1) There should be a grub command, such as "randomize", on a
>  par with other grub commands such as "initrd" or "uppermem" :
>    https://www.gnu.org/software/grub/manual/grub.html#Command_002dline-and-menu-entry-commands

Yes, a command would make sense, but given that 'kernel' and 'initrd'
take file paths, perhaps it makes sense to read the seed from a file
directly rather than from the environment? E.g., /etc/random.seed,
with root only read/write permissions.

> 2) GRUB needs to install the RNG seed config table if *either*
>   a) a random seed is provided via the randomize command, or
>   b) a random seed is available via EFI_RNG_PROTOCOL, or both.
>  If both sources are available, grub should hash them together.
>  The randomize command may be given more than once, with
>  cumulative effect.
> 3) As a corollary of item (1), a grub environment variable can
>  be used as the argument to the randomize command.  However
>  the point is that the argument can be something else, perhaps
>  randomness from dice rolls, typed in by the user, interactively.

I think a user should be able to issue that command from the GRUB
shell once basic support for it is implemented.

> 4) We hope that the environment variable will get updated with
>  new randomness before the next boot.  More specifically, it should
>  be updated as soon as possible after booting up (to keep the old
>  value away from prying eyes) and updated *again* as late as possible
>  before shutdown (to keep the new value away from prying eyes).


> 5) Ordinarily the grub environment variable should *not* be cleared.
>  Rationale:  Consider the case where the system crashes and reboots
>  before the seed (stored in the grub environment) can be updated.
>  Reusing a seed is suboptimal, but it's waaaay better than nothing.
>  In particular, the hash of a stored seed with the real time clock
>  is not too bad, and is waaaay better than either one separately.

That presumes knowledge of/access to the real time clock. In general,
we have very little guaranteed sources like that, even less so on
ARM/arm64 (which has much more variation than x86, which is in
practice more a platform [PC] than an architecture) But indeed,
reusing the seed should be preferred over not using any seed. If we
take the seed from a file directly, I don't think we will typically be
able to modify arbitrary files anyway.

> 6) In the case where the boot firmware does not know about EFI
>  configuration tables, but the kernel does, grub can create a table
>  ab_initio and pass it to the kernel.

If the boot firmware is UEFI, it knows about configuration tables. If
it doesn't, then there is no point in using this mechanism: we cannot
impersonate a UEFI system.

> 7) A question:  In the EFI configuration table, is there any way
>  to distinguish "hard" randomness (such as might come from a HRNG)
>  versus pseudo randomness?  In other words, when the system makes
>  use of this randomness, how much "credit" should be added to
>  /dev/random?

The current struct that carries the entropy has a size field only
(apart from the actual bits) but we could easily update that to
include a lower bound on the entropy. It actually makes sense with
regard to the ARM/arm64 seeding from the EFI_RNG_PROTOCOL, because I
currently don't distinguish between the raw protocol (which is spec'ed
to provide entropy suitable for seeding a DRBG) and various other
defined DRBD protocols. [Note that the current implementation does not
increase the entropy estimate when consuming the seed, even if it
comes from the raw protocol]

> On 11/27/2016 06:00 AM, Ralf Senderek wrote:
>>> Both "grub.cfg" and "grubenv" are traditionally world-readable because
>>> they are not perceived as containing secret information.
> That's fixable.  There's not much need for it to be world-readable,
> since the contents are usually boring.  Most people don't even know
> it exists.  Also, it would be easy to write an expurgated version,
> world-readable, containing everything except the secrets, if there
> were any need for it.  This is roughly analogous to /etc/passwd and
> /etc/shadow.

As I stated above, I think using a separate file altogether is a better idea.

>>> is a better way to secure
>>> the secret seed than to store it in the file system?
> It needs to be secure.  Putting it outside the filesystem is an
> odd way to make it secure.  If the existing permissions system
> is not good enough, we have already forfeited the game, in ways
> unrelated to randomness.  The permissions system is easier to
> use than whatever tools would be used to store stuff outside
> the filesystem.  In either case, attention to detail is required.
> Similarly, the grub environment system already exists, with a
> logical design, documentation, et cetera.
> If/when anybody has a specific suggestion for where to store the
> seed, we should definitely look at it.  But until then, the
> grub environment seems good enough, and incomparably better
> than what we have now.

More information about the cryptography mailing list