mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
9592eef7c1
When RDRAND was introduced, there was much discussion on whether it should be trusted and how the kernel should handle that. Initially, two mechanisms cropped up, CONFIG_ARCH_RANDOM, a compile time switch, and "nordrand", a boot-time switch. Later the thinking evolved. With a properly designed RNG, using RDRAND values alone won't harm anything, even if the outputs are malicious. Rather, the issue is whether those values are being *trusted* to be good or not. And so a new set of options were introduced as the real ones that people use -- CONFIG_RANDOM_TRUST_CPU and "random.trust_cpu". With these options, RDRAND is used, but it's not always credited. So in the worst case, it does nothing, and in the best case, maybe it helps. Along the way, CONFIG_ARCH_RANDOM's meaning got sort of pulled into the center and became something certain platforms force-select. The old options don't really help with much, and it's a bit odd to have special handling for these instructions when the kernel can deal fine with the existence or untrusted existence or broken existence or non-existence of that CPU capability. Simplify the situation by removing CONFIG_ARCH_RANDOM and using the ordinary asm-generic fallback pattern instead, keeping the two options that are actually used. For now it leaves "nordrand" for now, as the removal of that will take a different route. Acked-by: Michael Ellerman <mpe@ellerman.id.au> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Borislav Petkov <bp@suse.de> Acked-by: Heiko Carstens <hca@linux.ibm.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
140 lines
3.8 KiB
C
140 lines
3.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef _LINUX_RANDOM_H
|
|
#define _LINUX_RANDOM_H
|
|
|
|
#include <linux/bug.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/list.h>
|
|
#include <linux/once.h>
|
|
|
|
#include <uapi/linux/random.h>
|
|
|
|
struct notifier_block;
|
|
|
|
void add_device_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;
|
|
void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy);
|
|
|
|
#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
|
|
static inline void add_latent_entropy(void)
|
|
{
|
|
add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
|
|
}
|
|
#else
|
|
static inline void add_latent_entropy(void) { }
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_VMGENID)
|
|
void add_vmfork_randomness(const void *unique_vm_id, size_t len);
|
|
int register_random_vmfork_notifier(struct notifier_block *nb);
|
|
int unregister_random_vmfork_notifier(struct notifier_block *nb);
|
|
#else
|
|
static inline int register_random_vmfork_notifier(struct notifier_block *nb) { return 0; }
|
|
static inline int unregister_random_vmfork_notifier(struct notifier_block *nb) { return 0; }
|
|
#endif
|
|
|
|
void get_random_bytes(void *buf, size_t len);
|
|
u32 get_random_u32(void);
|
|
u64 get_random_u64(void);
|
|
static inline unsigned int get_random_int(void)
|
|
{
|
|
return get_random_u32();
|
|
}
|
|
static inline unsigned long get_random_long(void)
|
|
{
|
|
#if BITS_PER_LONG == 64
|
|
return get_random_u64();
|
|
#else
|
|
return get_random_u32();
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* On 64-bit architectures, protect against non-terminated C string overflows
|
|
* by zeroing out the first byte of the canary; this leaves 56 bits of entropy.
|
|
*/
|
|
#ifdef CONFIG_64BIT
|
|
# ifdef __LITTLE_ENDIAN
|
|
# define CANARY_MASK 0xffffffffffffff00UL
|
|
# else /* big endian, 64 bits: */
|
|
# define CANARY_MASK 0x00ffffffffffffffUL
|
|
# endif
|
|
#else /* 32 bits: */
|
|
# define CANARY_MASK 0xffffffffUL
|
|
#endif
|
|
|
|
static inline unsigned long get_random_canary(void)
|
|
{
|
|
return get_random_long() & CANARY_MASK;
|
|
}
|
|
|
|
int __init random_init(const char *command_line);
|
|
bool rng_is_initialized(void);
|
|
int wait_for_random_bytes(void);
|
|
|
|
/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
|
|
* Returns the result of the call to wait_for_random_bytes. */
|
|
static inline int get_random_bytes_wait(void *buf, size_t nbytes)
|
|
{
|
|
int ret = wait_for_random_bytes();
|
|
get_random_bytes(buf, nbytes);
|
|
return ret;
|
|
}
|
|
|
|
#define declare_get_random_var_wait(name, ret_type) \
|
|
static inline int get_random_ ## name ## _wait(ret_type *out) { \
|
|
int ret = wait_for_random_bytes(); \
|
|
if (unlikely(ret)) \
|
|
return ret; \
|
|
*out = get_random_ ## name(); \
|
|
return 0; \
|
|
}
|
|
declare_get_random_var_wait(u32, u32)
|
|
declare_get_random_var_wait(u64, u32)
|
|
declare_get_random_var_wait(int, unsigned int)
|
|
declare_get_random_var_wait(long, unsigned long)
|
|
#undef declare_get_random_var
|
|
|
|
/*
|
|
* This is designed to be standalone for just prandom
|
|
* users, but for now we include it from <linux/random.h>
|
|
* for legacy reasons.
|
|
*/
|
|
#include <linux/prandom.h>
|
|
|
|
#include <asm/archrandom.h>
|
|
|
|
/*
|
|
* Called from the boot CPU during startup; not valid to call once
|
|
* secondary CPUs are up and preemption is possible.
|
|
*/
|
|
#ifndef arch_get_random_seed_long_early
|
|
static inline bool __init arch_get_random_seed_long_early(unsigned long *v)
|
|
{
|
|
WARN_ON(system_state != SYSTEM_BOOTING);
|
|
return arch_get_random_seed_long(v);
|
|
}
|
|
#endif
|
|
|
|
#ifndef arch_get_random_long_early
|
|
static inline bool __init arch_get_random_long_early(unsigned long *v)
|
|
{
|
|
WARN_ON(system_state != SYSTEM_BOOTING);
|
|
return arch_get_random_long(v);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_SMP
|
|
int random_prepare_cpu(unsigned int cpu);
|
|
int random_online_cpu(unsigned int cpu);
|
|
#endif
|
|
|
|
#ifndef MODULE
|
|
extern const struct file_operations random_fops, urandom_fops;
|
|
#endif
|
|
|
|
#endif /* _LINUX_RANDOM_H */
|