random: credit architectural init the exact amount
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 12 May 2022 13:32:26 +0000 (15:32 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 18 May 2022 13:53:53 +0000 (15:53 +0200)
RDRAND and RDSEED can fail sometimes, which is fine. We currently
initialize the RNG with 512 bits of RDRAND/RDSEED. We only need 256 bits
of those to succeed in order to initialize the RNG. Instead of the
current "all or nothing" approach, actually credit these contributions
the amount that is actually contributed.

Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
drivers/char/random.c

index 95982dc08669c76001b388c490442e0e024993f1..29062595b6102c2f9670d4610bbfd22c515d0df0 100644 (file)
@@ -927,9 +927,8 @@ static struct notifier_block pm_notifier = { .notifier_call = random_pm_notifica
  */
 int __init random_init(const char *command_line)
 {
-       size_t i;
        ktime_t now = ktime_get_real();
-       bool arch_init = true;
+       unsigned int i, arch_bytes;
        unsigned long rv;
 
 #if defined(LATENT_ENTROPY_PLUGIN)
@@ -937,11 +936,12 @@ int __init random_init(const char *command_line)
        _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
 #endif
 
-       for (i = 0; i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
+       for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
+            i < BLAKE2S_BLOCK_SIZE; i += sizeof(rv)) {
                if (!arch_get_random_seed_long_early(&rv) &&
                    !arch_get_random_long_early(&rv)) {
                        rv = random_get_entropy();
-                       arch_init = false;
+                       arch_bytes -= sizeof(rv);
                }
                _mix_pool_bytes(&rv, sizeof(rv));
        }
@@ -952,8 +952,8 @@ int __init random_init(const char *command_line)
 
        if (crng_ready())
                crng_reseed();
-       else if (arch_init && trust_cpu)
-               credit_init_bits(BLAKE2S_BLOCK_SIZE * 8);
+       else if (trust_cpu)
+               credit_init_bits(arch_bytes * 8);
 
        WARN_ON(register_pm_notifier(&pm_notifier));