xref: /openbmc/linux/include/linux/random.h (revision 6bb20c15)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
26071a6c0SJason A. Donenfeld 
31da177e4SLinus Torvalds #ifndef _LINUX_RANDOM_H
41da177e4SLinus Torvalds #define _LINUX_RANDOM_H
51da177e4SLinus Torvalds 
6253d3194SMark Rutland #include <linux/bug.h>
7253d3194SMark Rutland #include <linux/kernel.h>
8205a525cSHerbert Xu #include <linux/list.h>
9897ece56SDaniel Borkmann 
10607ca46eSDavid Howells #include <uapi/linux/random.h>
111da177e4SLinus Torvalds 
125acd3548SJason A. Donenfeld struct notifier_block;
13205a525cSHerbert Xu 
14a1940263SJason A. Donenfeld void add_device_randomness(const void *buf, size_t len);
1539e0f991SJason A. Donenfeld void __init add_bootloader_randomness(const void *buf, size_t len);
167782cfecSJason A. Donenfeld void add_input_randomness(unsigned int type, unsigned int code,
170766f788SEmese Revfy 			  unsigned int value) __latent_entropy;
187782cfecSJason A. Donenfeld void add_interrupt_randomness(int irq) __latent_entropy;
19db516da9SJason A. Donenfeld void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy, bool sleep_after);
202f14062bSJason A. Donenfeld 
add_latent_entropy(void)212f14062bSJason A. Donenfeld static inline void add_latent_entropy(void)
222f14062bSJason A. Donenfeld {
23d7bf7f3bSJason A. Donenfeld #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
242f14062bSJason A. Donenfeld 	add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
252f14062bSJason A. Donenfeld #else
26d7bf7f3bSJason A. Donenfeld 	add_device_randomness(NULL, 0);
272f14062bSJason A. Donenfeld #endif
28d7bf7f3bSJason A. Donenfeld }
292f14062bSJason A. Donenfeld 
30a4107d34SJason A. Donenfeld #if IS_ENABLED(CONFIG_VMGENID)
31a1940263SJason A. Donenfeld void add_vmfork_randomness(const void *unique_vm_id, size_t len);
327782cfecSJason A. Donenfeld int register_random_vmfork_notifier(struct notifier_block *nb);
337782cfecSJason A. Donenfeld int unregister_random_vmfork_notifier(struct notifier_block *nb);
34f3c2682bSJason A. Donenfeld #else
register_random_vmfork_notifier(struct notifier_block * nb)35f3c2682bSJason A. Donenfeld static inline int register_random_vmfork_notifier(struct notifier_block *nb) { return 0; }
unregister_random_vmfork_notifier(struct notifier_block * nb)36f3c2682bSJason A. Donenfeld static inline int unregister_random_vmfork_notifier(struct notifier_block *nb) { return 0; }
37a4107d34SJason A. Donenfeld #endif
381da177e4SLinus Torvalds 
39a1940263SJason A. Donenfeld void get_random_bytes(void *buf, size_t len);
40585cd5feSJason A. Donenfeld u8 get_random_u8(void);
41585cd5feSJason A. Donenfeld u16 get_random_u16(void);
42c440408cSJason A. Donenfeld u32 get_random_u32(void);
43c440408cSJason A. Donenfeld u64 get_random_u64(void);
get_random_long(void)44c440408cSJason A. Donenfeld static inline unsigned long get_random_long(void)
45c440408cSJason A. Donenfeld {
46c440408cSJason A. Donenfeld #if BITS_PER_LONG == 64
47c440408cSJason A. Donenfeld 	return get_random_u64();
48c440408cSJason A. Donenfeld #else
49c440408cSJason A. Donenfeld 	return get_random_u32();
50c440408cSJason A. Donenfeld #endif
51c440408cSJason A. Donenfeld }
52c440408cSJason A. Donenfeld 
53e9a688bcSJason A. Donenfeld u32 __get_random_u32_below(u32 ceil);
54e9a688bcSJason A. Donenfeld 
55e9a688bcSJason A. Donenfeld /*
56e9a688bcSJason A. Donenfeld  * Returns a random integer in the interval [0, ceil), with uniform
57e9a688bcSJason A. Donenfeld  * distribution, suitable for all uses. Fastest when ceil is a constant, but
58e9a688bcSJason A. Donenfeld  * still fast for variable ceil as well.
59e9a688bcSJason A. Donenfeld  */
get_random_u32_below(u32 ceil)60e9a688bcSJason A. Donenfeld static inline u32 get_random_u32_below(u32 ceil)
61e9a688bcSJason A. Donenfeld {
62e9a688bcSJason A. Donenfeld 	if (!__builtin_constant_p(ceil))
63e9a688bcSJason A. Donenfeld 		return __get_random_u32_below(ceil);
64e9a688bcSJason A. Donenfeld 
65e9a688bcSJason A. Donenfeld 	/*
66e9a688bcSJason A. Donenfeld 	 * For the fast path, below, all operations on ceil are precomputed by
67e9a688bcSJason A. Donenfeld 	 * the compiler, so this incurs no overhead for checking pow2, doing
68e9a688bcSJason A. Donenfeld 	 * divisions, or branching based on integer size. The resultant
69e9a688bcSJason A. Donenfeld 	 * algorithm does traditional reciprocal multiplication (typically
70e9a688bcSJason A. Donenfeld 	 * optimized by the compiler into shifts and adds), rejecting samples
71e9a688bcSJason A. Donenfeld 	 * whose lower half would indicate a range indivisible by ceil.
72e9a688bcSJason A. Donenfeld 	 */
73e9a688bcSJason A. Donenfeld 	BUILD_BUG_ON_MSG(!ceil, "get_random_u32_below() must take ceil > 0");
74e9a688bcSJason A. Donenfeld 	if (ceil <= 1)
75e9a688bcSJason A. Donenfeld 		return 0;
76e9a688bcSJason A. Donenfeld 	for (;;) {
77e9a688bcSJason A. Donenfeld 		if (ceil <= 1U << 8) {
78e9a688bcSJason A. Donenfeld 			u32 mult = ceil * get_random_u8();
79e9a688bcSJason A. Donenfeld 			if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil))
80e9a688bcSJason A. Donenfeld 				return mult >> 8;
81e9a688bcSJason A. Donenfeld 		} else if (ceil <= 1U << 16) {
82e9a688bcSJason A. Donenfeld 			u32 mult = ceil * get_random_u16();
83e9a688bcSJason A. Donenfeld 			if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil))
84e9a688bcSJason A. Donenfeld 				return mult >> 16;
85e9a688bcSJason A. Donenfeld 		} else {
86e9a688bcSJason A. Donenfeld 			u64 mult = (u64)ceil * get_random_u32();
87e9a688bcSJason A. Donenfeld 			if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil))
88e9a688bcSJason A. Donenfeld 				return mult >> 32;
89e9a688bcSJason A. Donenfeld 		}
90e9a688bcSJason A. Donenfeld 	}
91e9a688bcSJason A. Donenfeld }
92e9a688bcSJason A. Donenfeld 
93022c2040SRik van Riel /*
947f576b25SJason A. Donenfeld  * Returns a random integer in the interval (floor, U32_MAX], with uniform
957f576b25SJason A. Donenfeld  * distribution, suitable for all uses. Fastest when floor is a constant, but
967f576b25SJason A. Donenfeld  * still fast for variable floor as well.
977f576b25SJason A. Donenfeld  */
get_random_u32_above(u32 floor)987f576b25SJason A. Donenfeld static inline u32 get_random_u32_above(u32 floor)
997f576b25SJason A. Donenfeld {
1007f576b25SJason A. Donenfeld 	BUILD_BUG_ON_MSG(__builtin_constant_p(floor) && floor == U32_MAX,
1017f576b25SJason A. Donenfeld 			 "get_random_u32_above() must take floor < U32_MAX");
1027f576b25SJason A. Donenfeld 	return floor + 1 + get_random_u32_below(U32_MAX - floor);
1037f576b25SJason A. Donenfeld }
1047f576b25SJason A. Donenfeld 
1057f576b25SJason A. Donenfeld /*
1067f576b25SJason A. Donenfeld  * Returns a random integer in the interval [floor, ceil], with uniform
1077f576b25SJason A. Donenfeld  * distribution, suitable for all uses. Fastest when floor and ceil are
1087f576b25SJason A. Donenfeld  * constant, but still fast for variable floor and ceil as well.
1097f576b25SJason A. Donenfeld  */
get_random_u32_inclusive(u32 floor,u32 ceil)1107f576b25SJason A. Donenfeld static inline u32 get_random_u32_inclusive(u32 floor, u32 ceil)
1117f576b25SJason A. Donenfeld {
1127f576b25SJason A. Donenfeld 	BUILD_BUG_ON_MSG(__builtin_constant_p(floor) && __builtin_constant_p(ceil) &&
1137f576b25SJason A. Donenfeld 			 (floor > ceil || ceil - floor == U32_MAX),
1147f576b25SJason A. Donenfeld 			 "get_random_u32_inclusive() must take floor <= ceil");
1157f576b25SJason A. Donenfeld 	return floor + get_random_u32_below(ceil - floor + 1);
1167f576b25SJason A. Donenfeld }
1177f576b25SJason A. Donenfeld 
118f6238499SJason A. Donenfeld void __init random_init_early(const char *command_line);
119f6238499SJason A. Donenfeld void __init random_init(void);
1207782cfecSJason A. Donenfeld bool rng_is_initialized(void);
1217782cfecSJason A. Donenfeld int wait_for_random_bytes(void);
122*bbc7e1beSJason A. Donenfeld int execute_with_initialized_rng(struct notifier_block *nb);
1237782cfecSJason A. Donenfeld 
124da9ba564SJason A. Donenfeld /* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes).
125da9ba564SJason A. Donenfeld  * Returns the result of the call to wait_for_random_bytes. */
get_random_bytes_wait(void * buf,size_t nbytes)12604ec96b7SJason A. Donenfeld static inline int get_random_bytes_wait(void *buf, size_t nbytes)
127da9ba564SJason A. Donenfeld {
128da9ba564SJason A. Donenfeld 	int ret = wait_for_random_bytes();
129da9ba564SJason A. Donenfeld 	get_random_bytes(buf, nbytes);
13025e3fca4SJason A. Donenfeld 	return ret;
131da9ba564SJason A. Donenfeld }
132da9ba564SJason A. Donenfeld 
1337c3a8a1dSJason A. Donenfeld #define declare_get_random_var_wait(name, ret_type) \
1347c3a8a1dSJason A. Donenfeld 	static inline int get_random_ ## name ## _wait(ret_type *out) { \
135da9ba564SJason A. Donenfeld 		int ret = wait_for_random_bytes(); \
136da9ba564SJason A. Donenfeld 		if (unlikely(ret)) \
137da9ba564SJason A. Donenfeld 			return ret; \
1387c3a8a1dSJason A. Donenfeld 		*out = get_random_ ## name(); \
139da9ba564SJason A. Donenfeld 		return 0; \
140da9ba564SJason A. Donenfeld 	}
141a890d1c6SJason A. Donenfeld declare_get_random_var_wait(u8, u8)
142a890d1c6SJason A. Donenfeld declare_get_random_var_wait(u16, u16)
1437c3a8a1dSJason A. Donenfeld declare_get_random_var_wait(u32, u32)
1447c3a8a1dSJason A. Donenfeld declare_get_random_var_wait(u64, u32)
1457c3a8a1dSJason A. Donenfeld declare_get_random_var_wait(long, unsigned long)
146da9ba564SJason A. Donenfeld #undef declare_get_random_var
147da9ba564SJason A. Donenfeld 
1485960164fSJoe Eykholt /*
149c0842fbcSLinus Torvalds  * This is designed to be standalone for just prandom
150c0842fbcSLinus Torvalds  * users, but for now we include it from <linux/random.h>
151c0842fbcSLinus Torvalds  * for legacy reasons.
1525960164fSJoe Eykholt  */
153c0842fbcSLinus Torvalds #include <linux/prandom.h>
1545960164fSJoe Eykholt 
1553191dd5aSJason A. Donenfeld #ifdef CONFIG_SMP
1567782cfecSJason A. Donenfeld int random_prepare_cpu(unsigned int cpu);
1577782cfecSJason A. Donenfeld int random_online_cpu(unsigned int cpu);
1587782cfecSJason A. Donenfeld #endif
1597782cfecSJason A. Donenfeld 
1607782cfecSJason A. Donenfeld #ifndef MODULE
1617782cfecSJason A. Donenfeld extern const struct file_operations random_fops, urandom_fops;
1623191dd5aSJason A. Donenfeld #endif
1633191dd5aSJason A. Donenfeld 
1641da177e4SLinus Torvalds #endif /* _LINUX_RANDOM_H */
165