Commit 3cae0d84 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'random-5.19-rc2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random

Pull random number generator fixes from Jason Donenfeld:

 - A fix for a 5.19 regression for a case in which early device tree
   initializes the RNG, which flips a static branch.

   On most plaforms, jump labels aren't initialized until much later, so
   this caused splats. On a few mailing list threads, we cooked up easy
   fixes for arm64, arm32, and risc-v. But then things looked slightly
   more involved for xtensa, powerpc, arc, and mips. And at that point,
   when we're patching 7 architectures in a place before the console is
   even available, it seems like the cost/risk just wasn't worth it.

   So random.c works around it now by checking the already exported
   `static_key_initialized` boolean, as though somebody already ran into
   this issue in the past. I'm not super jazzed about that; it'd be
   prettier to not have to complicate downstream code. But I suppose
   it's practical.

 - A few small code nits and adding a missing __init annotation.

 - A change to the default config values to use the cpu and bootloader's
   seeds for initializing the RNG earlier.

   This brings them into line with what all the distros do (Fedora/RHEL,
   Debian, Ubuntu, Gentoo, Arch, NixOS, Alpine, SUSE, and Void... at
   least), and moreover will now give us test coverage in various test
   beds that might have caught the above device tree bug earlier.

 - A change to WireGuard CI's configuration to increase test coverage
   around the RNG.

 - A documentation comment fix to unrelated maintainerless CRC code that
   I was asked to take, I guess because it has to do with polynomials
   (which the RNG thankfully no longer uses).

* tag 'random-5.19-rc2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random:
  wireguard: selftests: use maximum cpu features and allow rng seeding
  random: remove rng_has_arch_random()
  random: credit cpu and bootloader seeds by default
  random: do not use jump labels before they are initialized
  random: account for arch randomness in bits
  random: mark bootloader randomness code as __init
  random: avoid checking crng_ready() twice in random_init()
  crc-itu-t: fix typo in CRC ITU-T polynomial comment
parents 7a68065e 17b0128a
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -429,28 +429,40 @@ config ADI
	  driver include crash and makedumpfile.

config RANDOM_TRUST_CPU
	bool "Trust the CPU manufacturer to initialize Linux's CRNG"
	bool "Initialize RNG using CPU RNG instructions"
	default y
	depends on ARCH_RANDOM
	default n
	help
	Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or
	RDRAND, IBM for the S390 and Power PC architectures) is trustworthy
	for the purposes of initializing Linux's CRNG.  Since this is not
	something that can be independently audited, this amounts to trusting
	that CPU manufacturer (perhaps with the insistence or mandate
	of a Nation State's intelligence or law enforcement agencies)
	has not installed a hidden back door to compromise the CPU's
	random number generation facilities. This can also be configured
	at boot with "random.trust_cpu=on/off".
	  Initialize the RNG using random numbers supplied by the CPU's
	  RNG instructions (e.g. RDRAND), if supported and available. These
	  random numbers are never used directly, but are rather hashed into
	  the main input pool, and this happens regardless of whether or not
	  this option is enabled. Instead, this option controls whether the
	  they are credited and hence can initialize the RNG. Additionally,
	  other sources of randomness are always used, regardless of this
	  setting.  Enabling this implies trusting that the CPU can supply high
	  quality and non-backdoored random numbers.

	  Say Y here unless you have reason to mistrust your CPU or believe
	  its RNG facilities may be faulty. This may also be configured at
	  boot time with "random.trust_cpu=on/off".

config RANDOM_TRUST_BOOTLOADER
	bool "Trust the bootloader to initialize Linux's CRNG"
	help
	Some bootloaders can provide entropy to increase the kernel's initial
	device randomness. Say Y here to assume the entropy provided by the
	booloader is trustworthy so it will be added to the kernel's entropy
	pool. Otherwise, say N here so it will be regarded as device input that
	only mixes the entropy pool. This can also be configured at boot with
	"random.trust_bootloader=on/off".
	bool "Initialize RNG using bootloader-supplied seed"
	default y
	help
	  Initialize the RNG using a seed supplied by the bootloader or boot
	  environment (e.g. EFI or a bootloader-generated device tree). This
	  seed is not used directly, but is rather hashed into the main input
	  pool, and this happens regardless of whether or not this option is
	  enabled. Instead, this option controls whether the seed is credited
	  and hence can initialize the RNG. Additionally, other sources of
	  randomness are always used, regardless of this setting. Enabling
	  this implies trusting that the bootloader can supply high quality and
	  non-backdoored seeds.

	  Say Y here unless you have reason to mistrust your bootloader or
	  believe its RNG facilities may be faulty. This may also be configured
	  at boot time with "random.trust_bootloader=on/off".

endmenu
+17 −22
Original line number Diff line number Diff line
@@ -650,6 +650,7 @@ static void __cold _credit_init_bits(size_t bits)

	if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
		crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */
		if (static_key_initialized)
			execute_in_process_context(crng_set_ready, &set_ready);
		wake_up_interruptible(&crng_init_wait);
		kill_fasync(&fasync, SIGIO, POLL_IN);
@@ -724,9 +725,8 @@ static void __cold _credit_init_bits(size_t bits)
 *
 **********************************************************************/

static bool used_arch_random;
static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER);
static int __init parse_trust_cpu(char *arg)
{
	return kstrtobool(arg, &trust_cpu);
@@ -776,7 +776,7 @@ 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_bytes;
	unsigned int i, arch_bits;
	unsigned long entropy;

#if defined(LATENT_ENTROPY_PLUGIN)
@@ -784,12 +784,12 @@ int __init random_init(const char *command_line)
	_mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed));
#endif

	for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE;
	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_bytes -= sizeof(entropy);
			arch_bits -= sizeof(entropy) * 8;
		}
		_mix_pool_bytes(&entropy, sizeof(entropy));
	}
@@ -798,11 +798,18 @@ int __init random_init(const char *command_line)
	_mix_pool_bytes(command_line, strlen(command_line));
	add_latent_entropy();

	/*
	 * If we were initialized by the bootloader before jump labels are
	 * initialized, then we should enable the static branch here, where
	 * it's guaranteed that jump labels have been initialized.
	 */
	if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY)
		crng_set_ready(NULL);

	if (crng_ready())
		crng_reseed();
	else if (trust_cpu)
		credit_init_bits(arch_bytes * 8);
	used_arch_random = arch_bytes * 8 >= POOL_READY_BITS;
		_credit_init_bits(arch_bits);

	WARN_ON(register_pm_notifier(&pm_notifier));

@@ -811,17 +818,6 @@ int __init random_init(const char *command_line)
	return 0;
}

/*
 * Returns whether arch randomness has been mixed into the initial
 * state of the RNG, regardless of whether or not that randomness
 * was credited. Knowing this is only good for a very limited set
 * of uses, such as early init printk pointer obfuscation.
 */
bool rng_has_arch_random(void)
{
	return used_arch_random;
}

/*
 * Add device- or boot-specific data to the input pool to help
 * initialize it.
@@ -865,13 +861,12 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
 * Handle random seed passed by bootloader, and credit it if
 * CONFIG_RANDOM_TRUST_BOOTLOADER is set.
 */
void __cold add_bootloader_randomness(const void *buf, size_t len)
void __init add_bootloader_randomness(const void *buf, size_t len)
{
	mix_pool_bytes(buf, len);
	if (trust_bootloader)
		credit_init_bits(len * 8);
}
EXPORT_SYMBOL_GPL(add_bootloader_randomness);

#if IS_ENABLED(CONFIG_VMGENID)
static BLOCKING_NOTIFIER_HEAD(vmfork_chain);
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 *
 * Implements the standard CRC ITU-T V.41:
 *   Width 16
 *   Poly  0x1021 (x^16 + x^12 + x^15 + 1)
 *   Poly  0x1021 (x^16 + x^12 + x^5 + 1)
 *   Init  0
 */

+1 −2
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
struct notifier_block;

void add_device_randomness(const void *buf, size_t len);
void add_bootloader_randomness(const void *buf, size_t len);
void __init add_bootloader_randomness(const void *buf, size_t len);
void add_input_randomness(unsigned int type, unsigned int code,
			  unsigned int value) __latent_entropy;
void add_interrupt_randomness(int irq) __latent_entropy;
@@ -74,7 +74,6 @@ static inline unsigned long get_random_canary(void)

int __init random_init(const char *command_line);
bool rng_is_initialized(void);
bool rng_has_arch_random(void);
int wait_for_random_bytes(void);

/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
#include <linux/module.h>
#include <linux/crc-itu-t.h>

/** CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^15 + 1) */
/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */
const u16 crc_itu_t_table[256] = {
	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
Loading