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

Changed files
+70 -61
drivers
include
lib
tools
testing
selftests
wireguard
+30 -18
drivers/char/Kconfig
··· 429 429 driver include crash and makedumpfile. 430 430 431 431 config RANDOM_TRUST_CPU 432 - bool "Trust the CPU manufacturer to initialize Linux's CRNG" 432 + bool "Initialize RNG using CPU RNG instructions" 433 + default y 433 434 depends on ARCH_RANDOM 434 - default n 435 435 help 436 - Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or 437 - RDRAND, IBM for the S390 and Power PC architectures) is trustworthy 438 - for the purposes of initializing Linux's CRNG. Since this is not 439 - something that can be independently audited, this amounts to trusting 440 - that CPU manufacturer (perhaps with the insistence or mandate 441 - of a Nation State's intelligence or law enforcement agencies) 442 - has not installed a hidden back door to compromise the CPU's 443 - random number generation facilities. This can also be configured 444 - at boot with "random.trust_cpu=on/off". 436 + Initialize the RNG using random numbers supplied by the CPU's 437 + RNG instructions (e.g. RDRAND), if supported and available. These 438 + random numbers are never used directly, but are rather hashed into 439 + the main input pool, and this happens regardless of whether or not 440 + this option is enabled. Instead, this option controls whether the 441 + they are credited and hence can initialize the RNG. Additionally, 442 + other sources of randomness are always used, regardless of this 443 + setting. Enabling this implies trusting that the CPU can supply high 444 + quality and non-backdoored random numbers. 445 + 446 + Say Y here unless you have reason to mistrust your CPU or believe 447 + its RNG facilities may be faulty. This may also be configured at 448 + boot time with "random.trust_cpu=on/off". 445 449 446 450 config RANDOM_TRUST_BOOTLOADER 447 - bool "Trust the bootloader to initialize Linux's CRNG" 451 + bool "Initialize RNG using bootloader-supplied seed" 452 + default y 448 453 help 449 - Some bootloaders can provide entropy to increase the kernel's initial 450 - device randomness. Say Y here to assume the entropy provided by the 451 - booloader is trustworthy so it will be added to the kernel's entropy 452 - pool. Otherwise, say N here so it will be regarded as device input that 453 - only mixes the entropy pool. This can also be configured at boot with 454 - "random.trust_bootloader=on/off". 454 + Initialize the RNG using a seed supplied by the bootloader or boot 455 + environment (e.g. EFI or a bootloader-generated device tree). This 456 + seed is not used directly, but is rather hashed into the main input 457 + pool, and this happens regardless of whether or not this option is 458 + enabled. Instead, this option controls whether the seed is credited 459 + and hence can initialize the RNG. Additionally, other sources of 460 + randomness are always used, regardless of this setting. Enabling 461 + this implies trusting that the bootloader can supply high quality and 462 + non-backdoored seeds. 463 + 464 + Say Y here unless you have reason to mistrust your bootloader or 465 + believe its RNG facilities may be faulty. This may also be configured 466 + at boot time with "random.trust_bootloader=on/off". 455 467 456 468 endmenu
+17 -22
drivers/char/random.c
··· 650 650 651 651 if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { 652 652 crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */ 653 - execute_in_process_context(crng_set_ready, &set_ready); 653 + if (static_key_initialized) 654 + execute_in_process_context(crng_set_ready, &set_ready); 654 655 wake_up_interruptible(&crng_init_wait); 655 656 kill_fasync(&fasync, SIGIO, POLL_IN); 656 657 pr_notice("crng init done\n"); ··· 725 724 * 726 725 **********************************************************************/ 727 726 728 - static bool used_arch_random; 729 - static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); 730 - static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); 727 + static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); 728 + static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); 731 729 static int __init parse_trust_cpu(char *arg) 732 730 { 733 731 return kstrtobool(arg, &trust_cpu); ··· 776 776 int __init random_init(const char *command_line) 777 777 { 778 778 ktime_t now = ktime_get_real(); 779 - unsigned int i, arch_bytes; 779 + unsigned int i, arch_bits; 780 780 unsigned long entropy; 781 781 782 782 #if defined(LATENT_ENTROPY_PLUGIN) ··· 784 784 _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed)); 785 785 #endif 786 786 787 - for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE; 787 + for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8; 788 788 i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) { 789 789 if (!arch_get_random_seed_long_early(&entropy) && 790 790 !arch_get_random_long_early(&entropy)) { 791 791 entropy = random_get_entropy(); 792 - arch_bytes -= sizeof(entropy); 792 + arch_bits -= sizeof(entropy) * 8; 793 793 } 794 794 _mix_pool_bytes(&entropy, sizeof(entropy)); 795 795 } ··· 798 798 _mix_pool_bytes(command_line, strlen(command_line)); 799 799 add_latent_entropy(); 800 800 801 + /* 802 + * If we were initialized by the bootloader before jump labels are 803 + * initialized, then we should enable the static branch here, where 804 + * it's guaranteed that jump labels have been initialized. 805 + */ 806 + if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY) 807 + crng_set_ready(NULL); 808 + 801 809 if (crng_ready()) 802 810 crng_reseed(); 803 811 else if (trust_cpu) 804 - credit_init_bits(arch_bytes * 8); 805 - used_arch_random = arch_bytes * 8 >= POOL_READY_BITS; 812 + _credit_init_bits(arch_bits); 806 813 807 814 WARN_ON(register_pm_notifier(&pm_notifier)); 808 815 809 816 WARN(!random_get_entropy(), "Missing cycle counter and fallback timer; RNG " 810 817 "entropy collection will consequently suffer."); 811 818 return 0; 812 - } 813 - 814 - /* 815 - * Returns whether arch randomness has been mixed into the initial 816 - * state of the RNG, regardless of whether or not that randomness 817 - * was credited. Knowing this is only good for a very limited set 818 - * of uses, such as early init printk pointer obfuscation. 819 - */ 820 - bool rng_has_arch_random(void) 821 - { 822 - return used_arch_random; 823 819 } 824 820 825 821 /* ··· 861 865 * Handle random seed passed by bootloader, and credit it if 862 866 * CONFIG_RANDOM_TRUST_BOOTLOADER is set. 863 867 */ 864 - void __cold add_bootloader_randomness(const void *buf, size_t len) 868 + void __init add_bootloader_randomness(const void *buf, size_t len) 865 869 { 866 870 mix_pool_bytes(buf, len); 867 871 if (trust_bootloader) 868 872 credit_init_bits(len * 8); 869 873 } 870 - EXPORT_SYMBOL_GPL(add_bootloader_randomness); 871 874 872 875 #if IS_ENABLED(CONFIG_VMGENID) 873 876 static BLOCKING_NOTIFIER_HEAD(vmfork_chain);
+1 -1
include/linux/crc-itu-t.h
··· 4 4 * 5 5 * Implements the standard CRC ITU-T V.41: 6 6 * Width 16 7 - * Poly 0x1021 (x^16 + x^12 + x^15 + 1) 7 + * Poly 0x1021 (x^16 + x^12 + x^5 + 1) 8 8 * Init 0 9 9 */ 10 10
+1 -2
include/linux/random.h
··· 13 13 struct notifier_block; 14 14 15 15 void add_device_randomness(const void *buf, size_t len); 16 - void add_bootloader_randomness(const void *buf, size_t len); 16 + void __init add_bootloader_randomness(const void *buf, size_t len); 17 17 void add_input_randomness(unsigned int type, unsigned int code, 18 18 unsigned int value) __latent_entropy; 19 19 void add_interrupt_randomness(int irq) __latent_entropy; ··· 74 74 75 75 int __init random_init(const char *command_line); 76 76 bool rng_is_initialized(void); 77 - bool rng_has_arch_random(void); 78 77 int wait_for_random_bytes(void); 79 78 80 79 /* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
+1 -1
lib/crc-itu-t.c
··· 7 7 #include <linux/module.h> 8 8 #include <linux/crc-itu-t.h> 9 9 10 - /** CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^15 + 1) */ 10 + /* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */ 11 11 const u16 crc_itu_t_table[256] = { 12 12 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 13 13 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+1 -2
lib/vsprintf.c
··· 769 769 static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); 770 770 unsigned long flags; 771 771 772 - if (!system_unbound_wq || 773 - (!rng_is_initialized() && !rng_has_arch_random()) || 772 + if (!system_unbound_wq || !rng_is_initialized() || 774 773 !spin_trylock_irqsave(&filling, flags)) 775 774 return -EAGAIN; 776 775
+13 -15
tools/testing/selftests/wireguard/qemu/Makefile
··· 64 64 ifeq ($(HOST_ARCH),$(ARCH)) 65 65 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm 66 66 else 67 - QEMU_MACHINE := -cpu cortex-a53 -machine virt 68 - CFLAGS += -march=armv8-a -mtune=cortex-a53 67 + QEMU_MACHINE := -cpu max -machine virt 68 + CFLAGS += -march=armv8-a 69 69 endif 70 70 else ifeq ($(ARCH),aarch64_be) 71 71 CHOST := aarch64_be-linux-musl ··· 76 76 ifeq ($(HOST_ARCH),$(ARCH)) 77 77 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm 78 78 else 79 - QEMU_MACHINE := -cpu cortex-a53 -machine virt 80 - CFLAGS += -march=armv8-a -mtune=cortex-a53 79 + QEMU_MACHINE := -cpu max -machine virt 80 + CFLAGS += -march=armv8-a 81 81 endif 82 82 else ifeq ($(ARCH),arm) 83 83 CHOST := arm-linux-musleabi ··· 88 88 ifeq ($(HOST_ARCH),$(ARCH)) 89 89 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm 90 90 else 91 - QEMU_MACHINE := -cpu cortex-a15 -machine virt 92 - CFLAGS += -march=armv7-a -mtune=cortex-a15 -mabi=aapcs-linux 91 + QEMU_MACHINE := -cpu max -machine virt 92 + CFLAGS += -march=armv7-a -mabi=aapcs-linux 93 93 endif 94 94 else ifeq ($(ARCH),armeb) 95 95 CHOST := armeb-linux-musleabi ··· 100 100 ifeq ($(HOST_ARCH),$(ARCH)) 101 101 QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm 102 102 else 103 - QEMU_MACHINE := -cpu cortex-a15 -machine virt 104 - CFLAGS += -march=armv7-a -mabi=aapcs-linux # We don't pass -mtune=cortex-a15 due to a compiler bug on big endian. 103 + QEMU_MACHINE := -cpu max -machine virt 104 + CFLAGS += -march=armv7-a -mabi=aapcs-linux 105 105 LDFLAGS += -Wl,--be8 106 106 endif 107 107 else ifeq ($(ARCH),x86_64) ··· 112 112 ifeq ($(HOST_ARCH),$(ARCH)) 113 113 QEMU_MACHINE := -cpu host -machine q35,accel=kvm 114 114 else 115 - QEMU_MACHINE := -cpu Skylake-Server -machine q35 116 - CFLAGS += -march=skylake-avx512 115 + QEMU_MACHINE := -cpu max -machine q35 117 116 endif 118 117 else ifeq ($(ARCH),i686) 119 118 CHOST := i686-linux-musl ··· 122 123 ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH)) 123 124 QEMU_MACHINE := -cpu host -machine q35,accel=kvm 124 125 else 125 - QEMU_MACHINE := -cpu coreduo -machine q35 126 - CFLAGS += -march=prescott 126 + QEMU_MACHINE := -cpu max -machine q35 127 127 endif 128 128 else ifeq ($(ARCH),mips64) 129 129 CHOST := mips64-linux-musl ··· 180 182 ifeq ($(HOST_ARCH),$(ARCH)) 181 183 QEMU_MACHINE := -cpu host,accel=kvm -machine pseries 182 184 else 183 - QEMU_MACHINE := -machine pseries 185 + QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng 184 186 endif 185 187 else ifeq ($(ARCH),powerpc64le) 186 188 CHOST := powerpc64le-linux-musl ··· 190 192 ifeq ($(HOST_ARCH),$(ARCH)) 191 193 QEMU_MACHINE := -cpu host,accel=kvm -machine pseries 192 194 else 193 - QEMU_MACHINE := -machine pseries 195 + QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng 194 196 endif 195 197 else ifeq ($(ARCH),powerpc) 196 198 CHOST := powerpc-linux-musl ··· 245 247 ifeq ($(HOST_ARCH),$(ARCH)) 246 248 QEMU_MACHINE := -cpu host,accel=kvm -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) 247 249 else 248 - QEMU_MACHINE := -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) 250 + QEMU_MACHINE := -cpu max -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) 249 251 endif 250 252 else 251 253 $(error I only build: x86_64, i686, arm, armeb, aarch64, aarch64_be, mips, mipsel, mips64, mips64el, powerpc64, powerpc64le, powerpc, m68k, riscv64, riscv32, s390x)
+3
tools/testing/selftests/wireguard/qemu/init.c
··· 21 21 #include <sys/utsname.h> 22 22 #include <sys/sendfile.h> 23 23 #include <sys/sysmacros.h> 24 + #include <sys/random.h> 24 25 #include <linux/random.h> 25 26 #include <linux/version.h> 26 27 ··· 59 58 { 60 59 int bits = 256, fd; 61 60 61 + if (!getrandom(NULL, 0, GRND_NONBLOCK)) 62 + return; 62 63 pretty_message("[+] Fake seeding RNG..."); 63 64 fd = open("/dev/random", O_WRONLY); 64 65 if (fd < 0)
+3
tools/testing/selftests/wireguard/qemu/kernel.config
··· 31 31 CONFIG_BINFMT_ELF=y 32 32 CONFIG_BINFMT_SCRIPT=y 33 33 CONFIG_VDSO=y 34 + CONFIG_STRICT_KERNEL_RWX=y 34 35 CONFIG_VIRTUALIZATION=y 35 36 CONFIG_HYPERVISOR_GUEST=y 36 37 CONFIG_PARAVIRT=y ··· 66 65 CONFIG_PROC_SYSCTL=y 67 66 CONFIG_SYSFS=y 68 67 CONFIG_TMPFS=y 68 + CONFIG_RANDOM_TRUST_CPU=y 69 + CONFIG_RANDOM_TRUST_BOOTLOADER=y 69 70 CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 70 71 CONFIG_LOG_BUF_SHIFT=18 71 72 CONFIG_PRINTK_TIME=y