Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * include/linux/prandom.h
0004  *
0005  * Include file for the fast pseudo-random 32-bit
0006  * generation.
0007  */
0008 #ifndef _LINUX_PRANDOM_H
0009 #define _LINUX_PRANDOM_H
0010 
0011 #include <linux/types.h>
0012 #include <linux/percpu.h>
0013 #include <linux/random.h>
0014 
0015 static inline u32 prandom_u32(void)
0016 {
0017     return get_random_u32();
0018 }
0019 
0020 static inline void prandom_bytes(void *buf, size_t nbytes)
0021 {
0022     return get_random_bytes(buf, nbytes);
0023 }
0024 
0025 struct rnd_state {
0026     __u32 s1, s2, s3, s4;
0027 };
0028 
0029 u32 prandom_u32_state(struct rnd_state *state);
0030 void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes);
0031 void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state);
0032 
0033 #define prandom_init_once(pcpu_state)           \
0034     DO_ONCE(prandom_seed_full_state, (pcpu_state))
0035 
0036 /**
0037  * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro)
0038  * @ep_ro: right open interval endpoint
0039  *
0040  * Returns a pseudo-random number that is in interval [0, ep_ro). Note
0041  * that the result depends on PRNG being well distributed in [0, ~0U]
0042  * u32 space. Here we use maximally equidistributed combined Tausworthe
0043  * generator, that is, prandom_u32(). This is useful when requesting a
0044  * random index of an array containing ep_ro elements, for example.
0045  *
0046  * Returns: pseudo-random number in interval [0, ep_ro)
0047  */
0048 static inline u32 prandom_u32_max(u32 ep_ro)
0049 {
0050     return (u32)(((u64) prandom_u32() * ep_ro) >> 32);
0051 }
0052 
0053 /*
0054  * Handle minimum values for seeds
0055  */
0056 static inline u32 __seed(u32 x, u32 m)
0057 {
0058     return (x < m) ? x + m : x;
0059 }
0060 
0061 /**
0062  * prandom_seed_state - set seed for prandom_u32_state().
0063  * @state: pointer to state structure to receive the seed.
0064  * @seed: arbitrary 64-bit value to use as a seed.
0065  */
0066 static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
0067 {
0068     u32 i = ((seed >> 32) ^ (seed << 10) ^ seed) & 0xffffffffUL;
0069 
0070     state->s1 = __seed(i,   2U);
0071     state->s2 = __seed(i,   8U);
0072     state->s3 = __seed(i,  16U);
0073     state->s4 = __seed(i, 128U);
0074 }
0075 
0076 /* Pseudo random number generator from numerical recipes. */
0077 static inline u32 next_pseudo_random32(u32 seed)
0078 {
0079     return seed * 1664525 + 1013904223;
0080 }
0081 
0082 #endif