summaryrefslogtreecommitdiff
path: root/drivers/char/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/random.c')
-rw-r--r--drivers/char/random.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0c6568ae5f68..7bf11fa66265 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -596,12 +596,20 @@ static void extract_entropy(void *buf, size_t len)
unsigned long rdseed[32 / sizeof(long)];
size_t counter;
} block;
- size_t i;
+ size_t i, longs;
- for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
- if (!arch_get_random_seed_long(&block.rdseed[i]) &&
- !arch_get_random_long(&block.rdseed[i]))
- block.rdseed[i] = random_get_entropy();
+ for (i = 0; i < ARRAY_SIZE(block.rdseed);) {
+ longs = arch_get_random_seed_longs(&block.rdseed[i], ARRAY_SIZE(block.rdseed) - i);
+ if (longs) {
+ i += longs;
+ continue;
+ }
+ longs = arch_get_random_longs(&block.rdseed[i], ARRAY_SIZE(block.rdseed) - i);
+ if (longs) {
+ i += longs;
+ continue;
+ }
+ block.rdseed[i++] = random_get_entropy();
}
spin_lock_irqsave(&input_pool.lock, flags);
@@ -776,22 +784,31 @@ static struct notifier_block pm_notifier = { .notifier_call = random_pm_notifica
int __init random_init(const char *command_line)
{
ktime_t now = ktime_get_real();
- unsigned int i, arch_bits;
- unsigned long entropy;
+ size_t i, longs, arch_bits;
+ unsigned long entropy[BLAKE2S_BLOCK_SIZE / sizeof(long)];
#if defined(LATENT_ENTROPY_PLUGIN)
static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy;
_mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
#endif
- for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8;
- i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) {
- if (!arch_get_random_seed_long_early(&entropy) &&
- !arch_get_random_long_early(&entropy)) {
- entropy = random_get_entropy();
- arch_bits -= sizeof(entropy) * 8;
+ for (i = 0, arch_bits = sizeof(entropy) * 8; i < ARRAY_SIZE(entropy);) {
+ longs = arch_get_random_seed_longs(entropy, ARRAY_SIZE(entropy) - i);
+ if (longs) {
+ _mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ i += longs;
+ continue;
}
- _mix_pool_bytes(&entropy, sizeof(entropy));
+ longs = arch_get_random_longs(entropy, ARRAY_SIZE(entropy) - i);
+ if (longs) {
+ _mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ i += longs;
+ continue;
+ }
+ entropy[0] = random_get_entropy();
+ _mix_pool_bytes(entropy, sizeof(*entropy));
+ arch_bits -= sizeof(*entropy) * 8;
+ ++i;
}
_mix_pool_bytes(&now, sizeof(now));
_mix_pool_bytes(utsname(), sizeof(*(utsname())));