]> git.sesse.net Git - bcachefs-tools-debian/blob - include/linux/random.h
rust: bump rpassword to v7.x
[bcachefs-tools-debian] / include / linux / random.h
1 /*
2  * include/linux/random.h
3  *
4  * Include file for the random number generator.
5  */
6 #ifndef _LINUX_RANDOM_H
7 #define _LINUX_RANDOM_H
8
9 #include <unistd.h>
10 #include <sys/syscall.h>
11 #include <linux/bug.h>
12 #include <linux/log2.h>
13
14 #ifdef SYS_getrandom
15 static inline int getrandom(void *buf, size_t buflen, unsigned int flags)
16 {
17          return syscall(SYS_getrandom, buf, buflen, flags);
18 }
19 #else
20 extern int urandom_fd;
21
22 static inline int getrandom(void *buf, size_t buflen, unsigned int flags)
23 {
24         return read(urandom_fd, buf, buflen);
25 }
26 #endif
27
28 static inline void get_random_bytes(void *buf, int nbytes)
29 {
30         BUG_ON(getrandom(buf, nbytes, 0) != nbytes);
31 }
32
33 #define get_random_type(type)                           \
34 static inline type get_random_##type(void)              \
35 {                                                       \
36         type v;                                         \
37                                                         \
38         get_random_bytes(&v, sizeof(v));                \
39         return v;                                       \
40 }
41
42 get_random_type(int);
43 get_random_type(long);
44 get_random_type(u8);
45 get_random_type(u16);
46 get_random_type(u32);
47 get_random_type(u64);
48
49 static inline u32 get_random_u32_below(u32 ceil)
50 {
51         if (ceil <= 1)
52                 return 0;
53         for (;;) {
54                 if (ceil <= 1U << 8) {
55                         u32 mult = ceil * get_random_u8();
56                         if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil))
57                                 return mult >> 8;
58                 } else if (ceil <= 1U << 16) {
59                         u32 mult = ceil * get_random_u16();
60                         if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil))
61                                 return mult >> 16;
62                 } else {
63                         u64 mult = (u64)ceil * get_random_u32();
64                         if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil))
65                                 return mult >> 32;
66                 }
67         }
68 }
69
70 #endif /* _LINUX_RANDOM_H */