@@ -722,7 +722,8 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits)
if (r == &input_pool) {
int entropy_bits = entropy_count >> ENTROPY_SHIFT;
- if (crng_init < 2 && entropy_bits >= 128)
+ if (crng_init < 2 && entropy_bits >= 128 &&
+ crng_global_init_time > 0)
crng_reseed(&primary_crng, r);
}
}
@@ -1763,8 +1764,8 @@ static void __init init_std_data(struct entropy_store *r)
}
/*
- * Note that setup_arch() may call add_device_randomness()
- * long before we get here. This allows seeding of the pools
+ * add_device_randomness() or add_bootloader_randomness() may be
+ * called long before we get here. This allows seeding of the pools
* with some platform dependent data very early in the boot
* process. But it limits our options here. We must use
* statically allocated structures that already have all
@@ -2291,15 +2292,29 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
/* Handle random seed passed by bootloader.
- * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
- * it would be regarded as device data.
+ * If the seed is trustworthy, its entropy will be credited.
* The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
*/
void add_bootloader_randomness(const void *buf, unsigned int size)
{
- if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
- add_hwgenerator_randomness(buf, size, size * 8);
- else
- add_device_randomness(buf, size);
+ unsigned long time = random_get_entropy() ^ jiffies;
+ unsigned long flags;
+
+ if (!crng_ready() && size) {
+#ifdef CONFIG_RANDOM_TRUST_BOOTLOADER
+ crng_fast_load(buf, size);
+#else
+ crng_slow_load(buf, size);
+#endif /* CONFIG_RANDOM_TRUST_BOOTLOADER */
+ }
+
+ spin_lock_irqsave(&input_pool.lock, flags);
+ _mix_pool_bytes(&input_pool, buf, size);
+ _mix_pool_bytes(&input_pool, &time, sizeof(time));
+ spin_unlock_irqrestore(&input_pool.lock, flags);
+
+#ifdef CONFIG_RANDOM_TRUST_BOOTLOADER
+ credit_entropy_bits(&input_pool, size * 8);
+#endif
}
EXPORT_SYMBOL_GPL(add_bootloader_randomness);