It is required by SP800-90C that only SP800-90B compliant entropy sources may be used for seeding DRBGs. Don't award any entropy to arch_get_random_long() if fips_enabled is true. Don't award any entropy to arch_get_random_seed_long() if fips_enabled && !arch_has_sp800_90b_random_seed(). This is achieved by making min_crng_reseed_pool_entropy() return the full minimum seed size if fips_enabled && !arch_has_sp800_90b_random_seed() is true. This prevents crng_reseed() from attempting to make up for any lack of entropy in the input_pool by reading from the architectural RNG. Make crng_reseed() bail out in FIPS mode if the input_pool provides insufficient entropy and any of the arch_get_random_seed_long() invocations fails: there's no statement regarding SP900-90B compliance of arch_get_random_long() and so it can't be used as a backup. Signed-off-by: Nicolai Stange <nstange@xxxxxxx> --- drivers/char/random.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 7712b4464ef5..aaddee4e4ab1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1195,9 +1195,13 @@ static int min_crng_reseed_pool_entropy(void) * up to one half of the minimum entropy needed for * reseeding. That way it won't dominate the entropy * collected by other means at input_pool. + * If in FIPS mode, restrict this to SP900-90B compliant + * architectural RNGs. */ - if (arch_has_random() || arch_has_random_seed()) + if (arch_has_sp800_90b_random_seed() || + (!fips_enabled && (arch_has_random() || arch_has_random_seed()))) { return 8; + } return 16; } @@ -1233,7 +1237,8 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) for (i = 0; i < 8; i++) { unsigned long rv; if (!arch_get_random_seed_long(&rv) && - !arch_get_random_long(&rv)) { + ((arch_randomness_required && fips_enabled) || + !arch_get_random_long(&rv))) { if (arch_randomness_required) { /* * The input_pool failed to provide -- 2.26.2