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
41static inline void
42get_random_bytes(void *buf, int nbytes)
43{
44
45	arc4random_buf(buf, nbytes);
46}
47
48static inline u_int
49get_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 */
63static inline uint32_t
64get_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
81static inline u_long
82get_random_long(void)
83{
84	u_long val;
85
86	get_random_bytes(&val, sizeof(val));
87	return (val);
88}
89
90static inline uint64_t
91get_random_u64(void)
92{
93	uint64_t val;
94
95	get_random_bytes(&val, sizeof(val));
96	return (val);
97}
98
99static inline uint32_t
100get_random_u32_below(uint32_t max)
101{
102	return (arc4random_uniform(max));
103}
104
105static __inline uint32_t
106prandom_u32(void)
107{
108	uint32_t val;
109
110	get_random_bytes(&val, sizeof(val));
111	return (val);
112}
113
114static inline u32
115prandom_u32_max(u32 max)
116{
117	return (arc4random_uniform(max));
118}
119
120#endif /* _LINUXKPI_LINUX_RANDOM_H_ */
121