mbox series

[U-Boot,RFC,0/3] collect entropy, populate /chosen/rng-seed

Message ID 20190918220140.838-1-rasmus.villemoes@prevas.dk
Headers show
Series collect entropy, populate /chosen/rng-seed | expand

Message

Rasmus Villemoes Sept. 18, 2019, 10:01 p.m. UTC
[This is very much an early Request For Comments - it builds and shows
a sketch of what I have in mind, but has not really been tested. The
rest of the cover letter is copied from patch 3.]

A recurring theme on LKML is the boot process deadlocking due to some
process blocking waiting for random numbers, while the kernel's
Cryptographic Random Number Generator (crng) is not initalized yet,
but that very blocking means no activity happens that would generate
the entropy necessary to finalize seeding the crng.

This is not a problem on boards that have a good hwrng (when the
kernel is configured to trust it), whether in the CPU or in a TPM or
elsewhere. However, that's far from all boards out there.

Moreover, when booting with an initrd, all the "disk activity" that
would otherwise generate some timing variances has already been done
by U-boot. Hence it makes sense to try to collect that entropy in
U-boot and pass it on to the kernel. On the kernel side, support for
that has just landed in master (commit 428826f5358c "fdt: add support
for rng-seed").

By itself, this does not help with the initialization of the crng,
since the kernel only considers the rng-seed "trustworthy" if
CONFIG_RANDOM_TRUST_BOOTLOADER is set (it is always fed into the crng,
but entropy is only accounted when that config option is set).

This adds some basic infrastructure for collecting entropy in U-boot,
and then it's up to the BSP developer to decide if
CONFIG_RANDOM_TRUST_BOOTLOADER should be enabled in the kernel.

If this is accepted, I think we should add entropy() calls before and
after most disk and network activities. Moreover, at least some boards
seem to have a rather reliable source of randomness in the contents of
RAM after a cold boot [*], so I imagine exposing the entropy_mix()
either via a command "entropy <addr> <len>" that can be run during a
boot script, or perhaps to be done automatically (and as early as
possible to reduce risk of "tainting") via some CONFIG_ENTROPY_RAM_{ADDR,LEN}.

There's probably good sources of entropy to be had from the SPL phase,
but I couldn't find a good way of passing that on other than by
putting the sha256_context inside global_data, which would bloat that
by over 100 bytes.

[*] Looking at a slightly arbitrary place in the middle of physical
memory I got these

40d07670: 34081000 400a8020 00002040 20024400    ...4 ..@@ ...D.
40d07670: 343c1000 640a9120 00036040 6006e400    ..<4 ..d@`.....`
40d07670: 353c1040 600a9120 00026041 6246e400    @.<5 ..`A`....Fb
40d07670: 34281000 600a9100 00026040 2046e400    ..(4...`@`....F

So some bits are always the same, but there's quite a few that flip
randomly between boots - so mixing in a MB or two seems that it should
provide plenty of real entropy.

Rasmus Villemoes (3):
  u-boot/sha256.h: add SHA256_INIT macro
  u-boot/sha256.h: include linux/types.h
  add infrastructure for collecting entropy

 common/fdt_support.c    | 12 ++++++++
 include/common.h        |  3 ++
 include/entropy.h       | 42 +++++++++++++++++++++++++++
 include/u-boot/sha256.h | 13 +++++++++
 lib/Kconfig             | 10 +++++++
 lib/Makefile            |  1 +
 lib/entropy.c           | 63 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 144 insertions(+)
 create mode 100644 include/entropy.h
 create mode 100644 lib/entropy.c