Random number generator fixes for Linux 5.19-rc2.
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEq5lC5tSkz8NBJiCnSfxwEqXeA64FAmKktaEACgkQSfxwEqXe A65Q+RAAkyLfX6kxQlTZbglTTiapbGwpk7+VhM0pJfc3guXhIe8kNZ5cX/mfkGeZ f/ebUmWSJhqaNz1OIZeBZQ98ESwh8imfWaxWDkqsFh4c+hGsSp2xwIszMn3Hg+7L Sm/0Q71eZaSnRBGxWRVBbz3tTppUBS4nJxvFj8iM3jWWUffZa0m/w1lMvqc8kNJu kM1ONqb+CEuHOJyltUaH2qEXD6fQE3IOpPdC6PdsFqFX8qLN/pwZO6tpY8tYPt3j AUubp8F3eR4Y7WcmMi1b7BmiRgg47jdsS18aqRSH8CuYvIBbXHNM+tuK54zh/888 d+s9Bj6ALR4z1/a8HXqtudCazYU+1VozWxVIELcpDWTX4wKgqVZ0HLEz7sAEfCgV wSIcIY8TRJlOTL43KenbJqbyIOsvAidqWEYz5ogF9WYUlaD82s2j8pUMj4wQoD5w VJqF2CaoewU0BOGK7rZFnElN5rPlfEJtNBZQOEo16BzA2tXilPgRFoOmKs9TMRQo dGotfp62rUuS14b9x7zc9be0QmtnmwxQKO9U6SRVd5X2HXU/E5PsqTsbt0PKlSbA qemw2CehPB+uFs0cqbbeI5VBpVnPQJkaflTfOVr04h7623KJ5Pnblv7/8iSedOOh L4ACxPO5I5MrM8rJAR4g85SYVg3A/HaTufA5XtR5QB/qmEaErXg= =1Lf0 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
3cae0d8475
@ -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"
|
||||
bool "Initialize RNG using bootloader-supplied seed"
|
||||
default y
|
||||
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".
|
||||
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
|
||||
|
@ -650,7 +650,8 @@ 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. */
|
||||
execute_in_process_context(crng_set_ready, &set_ready);
|
||||
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);
|
||||
pr_notice("crng init done\n");
|
||||
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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).
|
||||
|
@ -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,
|
||||
|
@ -769,8 +769,7 @@ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
|
||||
static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
|
||||
unsigned long flags;
|
||||
|
||||
if (!system_unbound_wq ||
|
||||
(!rng_is_initialized() && !rng_has_arch_random()) ||
|
||||
if (!system_unbound_wq || !rng_is_initialized() ||
|
||||
!spin_trylock_irqsave(&filling, flags))
|
||||
return -EAGAIN;
|
||||
|
||||
|
@ -64,8 +64,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu cortex-a53 -machine virt
|
||||
CFLAGS += -march=armv8-a -mtune=cortex-a53
|
||||
QEMU_MACHINE := -cpu max -machine virt
|
||||
CFLAGS += -march=armv8-a
|
||||
endif
|
||||
else ifeq ($(ARCH),aarch64_be)
|
||||
CHOST := aarch64_be-linux-musl
|
||||
@ -76,8 +76,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu cortex-a53 -machine virt
|
||||
CFLAGS += -march=armv8-a -mtune=cortex-a53
|
||||
QEMU_MACHINE := -cpu max -machine virt
|
||||
CFLAGS += -march=armv8-a
|
||||
endif
|
||||
else ifeq ($(ARCH),arm)
|
||||
CHOST := arm-linux-musleabi
|
||||
@ -88,8 +88,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu cortex-a15 -machine virt
|
||||
CFLAGS += -march=armv7-a -mtune=cortex-a15 -mabi=aapcs-linux
|
||||
QEMU_MACHINE := -cpu max -machine virt
|
||||
CFLAGS += -march=armv7-a -mabi=aapcs-linux
|
||||
endif
|
||||
else ifeq ($(ARCH),armeb)
|
||||
CHOST := armeb-linux-musleabi
|
||||
@ -100,8 +100,8 @@ QEMU_VPORT_RESULT := virtio-serial-device
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu cortex-a15 -machine virt
|
||||
CFLAGS += -march=armv7-a -mabi=aapcs-linux # We don't pass -mtune=cortex-a15 due to a compiler bug on big endian.
|
||||
QEMU_MACHINE := -cpu max -machine virt
|
||||
CFLAGS += -march=armv7-a -mabi=aapcs-linux
|
||||
LDFLAGS += -Wl,--be8
|
||||
endif
|
||||
else ifeq ($(ARCH),x86_64)
|
||||
@ -112,8 +112,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine q35,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu Skylake-Server -machine q35
|
||||
CFLAGS += -march=skylake-avx512
|
||||
QEMU_MACHINE := -cpu max -machine q35
|
||||
endif
|
||||
else ifeq ($(ARCH),i686)
|
||||
CHOST := i686-linux-musl
|
||||
@ -123,8 +122,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage
|
||||
ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host -machine q35,accel=kvm
|
||||
else
|
||||
QEMU_MACHINE := -cpu coreduo -machine q35
|
||||
CFLAGS += -march=prescott
|
||||
QEMU_MACHINE := -cpu max -machine q35
|
||||
endif
|
||||
else ifeq ($(ARCH),mips64)
|
||||
CHOST := mips64-linux-musl
|
||||
@ -182,7 +180,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
|
||||
else
|
||||
QEMU_MACHINE := -machine pseries
|
||||
QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
|
||||
endif
|
||||
else ifeq ($(ARCH),powerpc64le)
|
||||
CHOST := powerpc64le-linux-musl
|
||||
@ -192,7 +190,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host,accel=kvm -machine pseries
|
||||
else
|
||||
QEMU_MACHINE := -machine pseries
|
||||
QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng
|
||||
endif
|
||||
else ifeq ($(ARCH),powerpc)
|
||||
CHOST := powerpc-linux-musl
|
||||
@ -247,7 +245,7 @@ QEMU_VPORT_RESULT := virtio-serial-ccw
|
||||
ifeq ($(HOST_ARCH),$(ARCH))
|
||||
QEMU_MACHINE := -cpu host,accel=kvm -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
|
||||
else
|
||||
QEMU_MACHINE := -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
|
||||
QEMU_MACHINE := -cpu max -machine s390-ccw-virtio -append $(KERNEL_CMDLINE)
|
||||
endif
|
||||
else
|
||||
$(error I only build: x86_64, i686, arm, armeb, aarch64, aarch64_be, mips, mipsel, mips64, mips64el, powerpc64, powerpc64le, powerpc, m68k, riscv64, riscv32, s390x)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/random.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
@ -58,6 +59,8 @@ static void seed_rng(void)
|
||||
{
|
||||
int bits = 256, fd;
|
||||
|
||||
if (!getrandom(NULL, 0, GRND_NONBLOCK))
|
||||
return;
|
||||
pretty_message("[+] Fake seeding RNG...");
|
||||
fd = open("/dev/random", O_WRONLY);
|
||||
if (fd < 0)
|
||||
|
@ -31,6 +31,7 @@ CONFIG_TTY=y
|
||||
CONFIG_BINFMT_ELF=y
|
||||
CONFIG_BINFMT_SCRIPT=y
|
||||
CONFIG_VDSO=y
|
||||
CONFIG_STRICT_KERNEL_RWX=y
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_HYPERVISOR_GUEST=y
|
||||
CONFIG_PARAVIRT=y
|
||||
@ -65,6 +66,8 @@ CONFIG_PROC_FS=y
|
||||
CONFIG_PROC_SYSCTL=y
|
||||
CONFIG_SYSFS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_RANDOM_TRUST_CPU=y
|
||||
CONFIG_RANDOM_TRUST_BOOTLOADER=y
|
||||
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
|
||||
CONFIG_LOG_BUF_SHIFT=18
|
||||
CONFIG_PRINTK_TIME=y
|
||||
|
Loading…
Reference in New Issue
Block a user