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 static inline uint8_t
get_random_u8(void)58 get_random_u8(void)
59 {
60 uint8_t val;
61
62 get_random_bytes(&val, sizeof(val));
63 return (val);
64 }
65
66 #define get_random_u32() get_random_int()
67
68 /*
69 * See "Fast Random Integer Generation in an Interval" by Daniel Lemire
70 * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights.
71 */
72 static inline uint32_t
get_random_u32_inclusive(uint32_t floor,uint32_t ceil)73 get_random_u32_inclusive(uint32_t floor, uint32_t ceil)
74 {
75 uint64_t x;
76 uint32_t t, v;
77
78 MPASS(ceil >= floor);
79
80 v = get_random_u32();
81 t = ceil - floor + 1;
82 x = (uint64_t)t * v;
83 while (x < t)
84 x = (uint64_t)t * get_random_u32();
85 v = x >> 32;
86
87 return (floor + v);
88 }
89
90 static inline u_long
get_random_long(void)91 get_random_long(void)
92 {
93 u_long val;
94
95 get_random_bytes(&val, sizeof(val));
96 return (val);
97 }
98
99 static inline uint64_t
get_random_u64(void)100 get_random_u64(void)
101 {
102 uint64_t val;
103
104 get_random_bytes(&val, sizeof(val));
105 return (val);
106 }
107
108 static inline uint32_t
get_random_u32_below(uint32_t max)109 get_random_u32_below(uint32_t max)
110 {
111 return (arc4random_uniform(max));
112 }
113
114 static __inline uint32_t
prandom_u32(void)115 prandom_u32(void)
116 {
117 uint32_t val;
118
119 get_random_bytes(&val, sizeof(val));
120 return (val);
121 }
122
123 static inline u32
prandom_u32_max(u32 max)124 prandom_u32_max(u32 max)
125 {
126 return (arc4random_uniform(max));
127 }
128
129 #endif /* _LINUXKPI_LINUX_RANDOM_H_ */
130