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

Commit c13b9c36 authored by Mark Rutland's avatar Mark Rutland Committed by Greg Kroah-Hartman
Browse files

random: split primary/secondary crng init paths



commit 5cbe0f13b51ac2fb2fd55902cff8d0077fc084c0 upstream.

Currently crng_initialize() is used for both the primary CRNG and
secondary CRNGs. While we wish to share common logic, we need to do a
number of additional things for the primary CRNG, and this would be
easier to deal with were these handled in separate functions.

This patch splits crng_initialize() into crng_initialize_primary() and
crng_initialize_secondary(), with common logic factored out into a
crng_init_try_arch() helper.

There should be no functional change as a result of this patch.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20200210130015.17664-2-mark.rutland@arm.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c070b07a
Loading
Loading
Loading
Loading
+22 −12
Original line number Diff line number Diff line
@@ -782,27 +782,37 @@ static int __init parse_trust_cpu(char *arg)
}
early_param("random.trust_cpu", parse_trust_cpu);

static void crng_initialize(struct crng_state *crng)
static bool crng_init_try_arch(struct crng_state *crng)
{
	int		i;
	int		arch_init = 1;
	bool		arch_init = true;
	unsigned long	rv;

	memcpy(&crng->state[0], "expand 32-byte k", 16);
	if (crng == &primary_crng)
		_extract_entropy(&input_pool, &crng->state[4],
				 sizeof(__u32) * 12, 0);
	else
		_get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
	for (i = 4; i < 16; i++) {
		if (!arch_get_random_seed_long(&rv) &&
		    !arch_get_random_long(&rv)) {
			rv = random_get_entropy();
			arch_init = 0;
			arch_init = false;
		}
		crng->state[i] ^= rv;
	}
	if (trust_cpu && arch_init && crng == &primary_crng) {

	return arch_init;
}

static void crng_initialize_secondary(struct crng_state *crng)
{
	memcpy(&crng->state[0], "expand 32-byte k", 16);
	_get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
	crng_init_try_arch(crng);
	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
}

static void __init crng_initialize_primary(struct crng_state *crng)
{
	memcpy(&crng->state[0], "expand 32-byte k", 16);
	_extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0);
	if (crng_init_try_arch(crng) && trust_cpu) {
		invalidate_batched_entropy();
		numa_crng_init();
		crng_init = 2;
@@ -853,7 +863,7 @@ static void do_numa_crng_init(struct work_struct *work)
		crng = kmalloc_node(sizeof(struct crng_state),
				    GFP_KERNEL | __GFP_NOFAIL, i);
		spin_lock_init(&crng->lock);
		crng_initialize(crng);
		crng_initialize_secondary(crng);
		pool[i] = crng;
	}
	/* pairs with READ_ONCE() in select_crng() */
@@ -1793,7 +1803,7 @@ int __init rand_initialize(void)
	init_std_data(&input_pool);
	if (crng_need_final_init)
		crng_finalize_init(&primary_crng);
	crng_initialize(&primary_crng);
	crng_initialize_primary(&primary_crng);
	crng_global_init_time = jiffies;
	if (ratelimit_disable) {
		urandom_warning.interval = 0;