Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e575837 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Greg Kroah-Hartman
Browse files

random: ensure early RDSEED goes through mixer on init



commit a02cf3d0dd77244fd5333ac48d78871de459ae6d upstream.

Continuing the reasoning of "random: use RDSEED instead of RDRAND in
entropy extraction" from this series, at init time we also don't want to
be xoring RDSEED directly into the crng. Instead it's safer to put it
into our entropy collector and then re-extract it, so that it goes
through a hash function with preimage resistance. As a matter of hygiene,
we also order these now so that the RDSEED byte are hashed in first,
followed by the bytes that are likely more predictable (e.g. utsname()).

Cc: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
Reviewed-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6bc282be
Loading
Loading
Loading
Loading
+5 −11
Original line number Original line Diff line number Diff line
@@ -1260,24 +1260,18 @@ int __init rand_initialize(void)
	bool arch_init = true;
	bool arch_init = true;
	unsigned long rv;
	unsigned long rv;


	mix_pool_bytes(&now, sizeof(now));
	for (i = BLAKE2S_BLOCK_SIZE; i > 0; i -= sizeof(rv)) {
	for (i = BLAKE2S_BLOCK_SIZE; i > 0; i -= sizeof(rv)) {
		if (!arch_get_random_seed_long(&rv) &&
		    !arch_get_random_long(&rv))
			rv = random_get_entropy();
		mix_pool_bytes(&rv, sizeof(rv));
	}
	mix_pool_bytes(utsname(), sizeof(*(utsname())));

	extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
	for (i = 4; i < 16; i++) {
		if (!arch_get_random_seed_long_early(&rv) &&
		if (!arch_get_random_seed_long_early(&rv) &&
		    !arch_get_random_long_early(&rv)) {
		    !arch_get_random_long_early(&rv)) {
			rv = random_get_entropy();
			rv = random_get_entropy();
			arch_init = false;
			arch_init = false;
		}
		}
		primary_crng.state[i] ^= rv;
		mix_pool_bytes(&rv, sizeof(rv));
	}
	}
	mix_pool_bytes(&now, sizeof(now));
	mix_pool_bytes(utsname(), sizeof(*(utsname())));

	extract_entropy(&primary_crng.state[4], sizeof(u32) * 12);
	if (arch_init && trust_cpu && crng_init < 2) {
	if (arch_init && trust_cpu && crng_init < 2) {
		invalidate_batched_entropy();
		invalidate_batched_entropy();
		crng_init = 2;
		crng_init = 2;