1 /*-
2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
6 * All rights reserved.
7 * Copyright 2023 The FreeBSD Foundation
8 *
9 * Portions of this software was developed by Björn Zeeb
10 * under sponsorship from the FreeBSD Foundation.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice unmodified, this list of conditions, and the following
17 * disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef _LINUXKPI_LINUX_RANDOM_H_
35 #define _LINUXKPI_LINUX_RANDOM_H_
36
37 #include <linux/types.h>
38 #include <sys/random.h>
39 #include <sys/libkern.h>
40
41 static inline void
get_random_bytes(void * buf,int nbytes)42 get_random_bytes(void *buf, int nbytes)
43 {
44
45 arc4random_buf(buf, nbytes);
46 }
47
48 static inline u_int
get_random_int(void)49 get_random_int(void)
50 {
51 u_int val;
52
53 get_random_bytes(&val, sizeof(val));
54 return (val);
55 }
56
57 #define get_random_u32() get_random_int()
58
59 /*
60 * See "Fast Random Integer Generation in an Interval" by Daniel Lemire
61 * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights.
62 */
63 static inline uint32_t
get_random_u32_inclusive(uint32_t floor,uint32_t ceil)64 get_random_u32_inclusive(uint32_t floor, uint32_t ceil)
65 {
66 uint64_t x;
67 uint32_t t, v;
68
69 MPASS(ceil >= floor);
70
71 v = get_random_u32();
72 t = ceil - floor + 1;
73 x = (uint64_t)t * v;
74 while (x < t)
75 x = (uint64_t)t * get_random_u32();
76 v = x >> 32;
77
78 return (floor + v);
79 }
80
81 static inline u_long
get_random_long(void)82 get_random_long(void)
83 {
84 u_long val;
85
86 get_random_bytes(&val, sizeof(val));
87 return (val);
88 }
89
90 static inline uint64_t
get_random_u64(void)91 get_random_u64(void)
92 {
93 uint64_t val;
94
95 get_random_bytes(&val, sizeof(val));
96 return (val);
97 }
98
99 static inline uint32_t
get_random_u32_below(uint32_t max)100 get_random_u32_below(uint32_t max)
101 {
102 return (arc4random_uniform(max));
103 }
104
105 static __inline uint32_t
prandom_u32(void)106 prandom_u32(void)
107 {
108 uint32_t val;
109
110 get_random_bytes(&val, sizeof(val));
111 return (val);
112 }
113
114 static inline u32
prandom_u32_max(u32 max)115 prandom_u32_max(u32 max)
116 {
117 return (arc4random_uniform(max));
118 }
119
120 #endif /* _LINUXKPI_LINUX_RANDOM_H_ */
121