1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 2 /* 3 * include/linux/prandom.h 3 * include/linux/prandom.h 4 * 4 * 5 * Include file for the fast pseudo-random 32- 5 * Include file for the fast pseudo-random 32-bit 6 * generation. 6 * generation. 7 */ 7 */ 8 #ifndef _LINUX_PRANDOM_H 8 #ifndef _LINUX_PRANDOM_H 9 #define _LINUX_PRANDOM_H 9 #define _LINUX_PRANDOM_H 10 10 11 #include <linux/types.h> 11 #include <linux/types.h> 12 #include <linux/once.h> !! 12 #include <linux/percpu.h> 13 #include <linux/random.h> !! 13 >> 14 u32 prandom_u32(void); >> 15 void prandom_bytes(void *buf, size_t nbytes); >> 16 void prandom_seed(u32 seed); >> 17 void prandom_reseed_late(void); >> 18 >> 19 #if BITS_PER_LONG == 64 >> 20 /* >> 21 * The core SipHash round function. Each line can be executed in >> 22 * parallel given enough CPU resources. >> 23 */ >> 24 #define PRND_SIPROUND(v0, v1, v2, v3) ( \ >> 25 v0 += v1, v1 = rol64(v1, 13), v2 += v3, v3 = rol64(v3, 16), \ >> 26 v1 ^= v0, v0 = rol64(v0, 32), v3 ^= v2, \ >> 27 v0 += v3, v3 = rol64(v3, 21), v2 += v1, v1 = rol64(v1, 17), \ >> 28 v3 ^= v0, v1 ^= v2, v2 = rol64(v2, 32) \ >> 29 ) >> 30 >> 31 #define PRND_K0 (0x736f6d6570736575 ^ 0x6c7967656e657261) >> 32 #define PRND_K1 (0x646f72616e646f6d ^ 0x7465646279746573) >> 33 >> 34 #elif BITS_PER_LONG == 32 >> 35 /* >> 36 * On 32-bit machines, we use HSipHash, a reduced-width version of SipHash. >> 37 * This is weaker, but 32-bit machines are not used for high-traffic >> 38 * applications, so there is less output for an attacker to analyze. >> 39 */ >> 40 #define PRND_SIPROUND(v0, v1, v2, v3) ( \ >> 41 v0 += v1, v1 = rol32(v1, 5), v2 += v3, v3 = rol32(v3, 8), \ >> 42 v1 ^= v0, v0 = rol32(v0, 16), v3 ^= v2, \ >> 43 v0 += v3, v3 = rol32(v3, 7), v2 += v1, v1 = rol32(v1, 13), \ >> 44 v3 ^= v0, v1 ^= v2, v2 = rol32(v2, 16) \ >> 45 ) >> 46 #define PRND_K0 0x6c796765 >> 47 #define PRND_K1 0x74656462 >> 48 >> 49 #else >> 50 #error Unsupported BITS_PER_LONG >> 51 #endif 14 52 15 struct rnd_state { 53 struct rnd_state { 16 __u32 s1, s2, s3, s4; 54 __u32 s1, s2, s3, s4; 17 }; 55 }; 18 56 19 u32 prandom_u32_state(struct rnd_state *state) 57 u32 prandom_u32_state(struct rnd_state *state); 20 void prandom_bytes_state(struct rnd_state *sta 58 void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); 21 void prandom_seed_full_state(struct rnd_state 59 void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); 22 60 23 #define prandom_init_once(pcpu_state) 61 #define prandom_init_once(pcpu_state) \ 24 DO_ONCE(prandom_seed_full_state, (pcpu 62 DO_ONCE(prandom_seed_full_state, (pcpu_state)) 25 63 >> 64 /** >> 65 * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro) >> 66 * @ep_ro: right open interval endpoint >> 67 * >> 68 * Returns a pseudo-random number that is in interval [0, ep_ro). Note >> 69 * that the result depends on PRNG being well distributed in [0, ~0U] >> 70 * u32 space. Here we use maximally equidistributed combined Tausworthe >> 71 * generator, that is, prandom_u32(). This is useful when requesting a >> 72 * random index of an array containing ep_ro elements, for example. >> 73 * >> 74 * Returns: pseudo-random number in interval [0, ep_ro) >> 75 */ >> 76 static inline u32 prandom_u32_max(u32 ep_ro) >> 77 { >> 78 return (u32)(((u64) prandom_u32() * ep_ro) >> 32); >> 79 } >> 80 26 /* 81 /* 27 * Handle minimum values for seeds 82 * Handle minimum values for seeds 28 */ 83 */ 29 static inline u32 __seed(u32 x, u32 m) 84 static inline u32 __seed(u32 x, u32 m) 30 { 85 { 31 return (x < m) ? x + m : x; 86 return (x < m) ? x + m : x; 32 } 87 } 33 88 34 /** 89 /** 35 * prandom_seed_state - set seed for prandom_u 90 * prandom_seed_state - set seed for prandom_u32_state(). 36 * @state: pointer to state structure to recei 91 * @state: pointer to state structure to receive the seed. 37 * @seed: arbitrary 64-bit value to use as a s 92 * @seed: arbitrary 64-bit value to use as a seed. 38 */ 93 */ 39 static inline void prandom_seed_state(struct r 94 static inline void prandom_seed_state(struct rnd_state *state, u64 seed) 40 { 95 { 41 u32 i = ((seed >> 32) ^ (seed << 10) ^ !! 96 u32 i = (seed >> 32) ^ (seed << 10) ^ seed; 42 97 43 state->s1 = __seed(i, 2U); 98 state->s1 = __seed(i, 2U); 44 state->s2 = __seed(i, 8U); 99 state->s2 = __seed(i, 8U); 45 state->s3 = __seed(i, 16U); 100 state->s3 = __seed(i, 16U); 46 state->s4 = __seed(i, 128U); 101 state->s4 = __seed(i, 128U); 47 } 102 } 48 103 49 /* Pseudo random number generator from numeric 104 /* Pseudo random number generator from numerical recipes. */ 50 static inline u32 next_pseudo_random32(u32 see 105 static inline u32 next_pseudo_random32(u32 seed) 51 { 106 { 52 return seed * 1664525 + 1013904223; 107 return seed * 1664525 + 1013904223; 53 } 108 } 54 109 55 #endif 110 #endif 56 111
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.