The startup health tests to be executed at boot as required by NIST 800-90B consist of running the contiuous health tests, i.e. the Adaptive Proportion Test (APT) and the Repetition Count Test (RCT), until a certain amount of noise samples have been examined. In case of test failure during this period, the startup tests would get restarted by means of reinitializing the fast_pool's ->warmup member with the original number of total samples to examine during startup. A future patch will enable dynamically switching from the initial H=1 or 1/8 per-IRQ min-entropy estimates to lower values upon health test failures in order to keep those systems going where these more or less arbitrary per-IRQ entropy estimates turn out to simply be wrong. It is certainly desirable to restart the startup health tests upon such a switch. In order to keep the upcoming code comprehensible, move the startup test restart logic from health_test_process() into add_interrupt_randomness(). For simplicity, make add_interrupt_randomness() trigger a startup test on each health test failure. Note that there's a change in behaviour: up to now, only the bootime startup tests would have restarted themselves upon failure, whereas now even a failure of the continuous health tests can potentially trigger a startup test long after boot. Note that as it currently stands, rerunning the full startup tests after the crng has received its initial seed has the only effect to inhibit entropy dispatch for a while and thus, to potentially delay those best effort crng reseeds during runtime. As reseeds never reduce a crng state's entropy, this behaviour is admittedly questionable. However, further patches introducing forced reseeds might perhaps become necessary in the future, c.f. the specification of "reseed_interval" in NIST SP800-90A. Thus, it's better to keep the startup health test restart logic consistent for now. Signed-off-by: Nicolai Stange <nstange@xxxxxxx> --- drivers/char/random.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 86dd87588b1b..bb79dcb96882 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1098,8 +1098,6 @@ health_test_process(struct health_test *h, unsigned int event_entropy_shift, * Something is really off, get_cycles() has become * (or always been) a constant. */ - if (h->warmup) - health_test_reset(h, event_entropy_shift); return health_discard; } @@ -1110,8 +1108,6 @@ health_test_process(struct health_test *h, unsigned int event_entropy_shift, */ apt = health_test_apt(h, event_entropy_shift, sample_delta); if (unlikely(h->warmup) && --h->warmup) { - if (apt == health_discard) - health_test_reset(h, event_entropy_shift); /* * Don't allow the caller to dispatch until warmup * has completed. @@ -1928,6 +1924,14 @@ void add_interrupt_randomness(int irq, int irq_flags) health_test_process(&fast_pool->health, fast_pool->event_entropy_shift, cycles); + if (unlikely(health_result == health_discard)) { + /* + * Oops, something's odd. Restart the startup + * tests. + */ + health_test_reset(&fast_pool->health, + fast_pool->event_entropy_shift); + } } if (unlikely(crng_init == 0)) { -- 2.26.2