random: Ingest extra fast entropy when !seeded
We periodically ingest entropy from pollable entropy sources, but only 8 bytes at a time and only occasionally enough to feed all of Fortuna's pools once per second. This can result in Fortuna remaining unseeded for a nontrivial amount of time when there is no entropy passed in from the boot loader, even if RDRAND is available to quickly provide a large amount of entropy. Detect in random_sources_feed if we are not yet seeded, and increase the amount of immediate entropy harvesting we perform, in order to "fill" Fortuna's entropy pools and avoid having random: randomdev_wait_until_seeded unblock wait stall the boot process when entropy is available. This speeds up the FreeBSD boot in the Firecracker VM by 2.3 seconds. Approved by: csprng (delphij) Sponsored by: https://www.patreon.com/cperciva Differential Revision: https://reviews.freebsd.org/D35802
This commit is contained in:
parent
102f31bf36
commit
0811ce5723
@ -254,6 +254,28 @@ random_sources_feed(void)
|
||||
*/
|
||||
npools = howmany(p_random_alg_context->ra_poolcount, RANDOM_KTHREAD_HZ);
|
||||
|
||||
/*-
|
||||
* If we're not seeded yet, attempt to perform a "full seed", filling
|
||||
* all of the PRNG's pools with entropy; if there is enough entropy
|
||||
* available from "fast" entropy sources this will allow us to finish
|
||||
* seeding and unblock the boot process immediately rather than being
|
||||
* stuck for a few seconds with random_kthread gradually collecting a
|
||||
* small chunk of entropy every 1 / RANDOM_KTHREAD_HZ seconds.
|
||||
*
|
||||
* The value 64 below is RANDOM_FORTUNA_DEFPOOLSIZE, i.e. chosen to
|
||||
* fill Fortuna's pools in the default configuration. With another
|
||||
* PRNG or smaller pools for Fortuna, we might collect more entropy
|
||||
* than needed to fill the pools, but this is harmless; alternatively,
|
||||
* a different PRNG, larger pools, or fast entropy sources which are
|
||||
* not able to provide as much entropy as we request may result in the
|
||||
* not being fully seeded (and thus remaining blocked) but in that
|
||||
* case we will return here after 1 / RANDOM_KTHREAD_HZ seconds and
|
||||
* try again for a large amount of entropy.
|
||||
*/
|
||||
if (!p_random_alg_context->ra_seeded())
|
||||
npools = howmany(p_random_alg_context->ra_poolcount * 64,
|
||||
sizeof(entropy));
|
||||
|
||||
/*
|
||||
* Step over all of live entropy sources, and feed their output
|
||||
* to the system-wide RNG.
|
||||
|
Loading…
Reference in New Issue
Block a user