xref: /freebsd/sys/compat/linuxkpi/common/include/linux/random.h (revision f29e915bc0d216a87f222a208caeb2172c93e4ea)
18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky  * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky  * Copyright (c) 2010 Panasas, Inc.
5d8571d3eSHans Petter Selasky  * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky  * All rights reserved.
71dcd1a53SBjoern A. Zeeb  * Copyright 2023 The FreeBSD Foundation
81dcd1a53SBjoern A. Zeeb  *
91dcd1a53SBjoern A. Zeeb  * Portions of this software was developed by Björn Zeeb
101dcd1a53SBjoern A. Zeeb  * under sponsorship from the FreeBSD Foundation.
118d59ecb2SHans Petter Selasky  *
128d59ecb2SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
138d59ecb2SHans Petter Selasky  * modification, are permitted provided that the following conditions
148d59ecb2SHans Petter Selasky  * are met:
158d59ecb2SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
168d59ecb2SHans Petter Selasky  *    notice unmodified, this list of conditions, and the following
178d59ecb2SHans Petter Selasky  *    disclaimer.
188d59ecb2SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
198d59ecb2SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
208d59ecb2SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
218d59ecb2SHans Petter Selasky  *
228d59ecb2SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
238d59ecb2SHans Petter Selasky  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
248d59ecb2SHans Petter Selasky  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
258d59ecb2SHans Petter Selasky  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
268d59ecb2SHans Petter Selasky  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
278d59ecb2SHans Petter Selasky  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
288d59ecb2SHans Petter Selasky  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
298d59ecb2SHans Petter Selasky  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
308d59ecb2SHans Petter Selasky  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
318d59ecb2SHans Petter Selasky  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
328d59ecb2SHans Petter Selasky  */
33bf4e2e5bSMark Johnston 
34307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_LINUX_RANDOM_H_
35307f78f3SVladimir Kondratyev #define	_LINUXKPI_LINUX_RANDOM_H_
368d59ecb2SHans Petter Selasky 
37408c514fSNeel Chauhan #include <linux/types.h>
388d59ecb2SHans Petter Selasky #include <sys/random.h>
39d8571d3eSHans Petter Selasky #include <sys/libkern.h>
408d59ecb2SHans Petter Selasky 
418d59ecb2SHans Petter Selasky static inline void
get_random_bytes(void * buf,int nbytes)428d59ecb2SHans Petter Selasky get_random_bytes(void *buf, int nbytes)
438d59ecb2SHans Petter Selasky {
44bf4e2e5bSMark Johnston 
45a8a16c71SConrad Meyer 	arc4random_buf(buf, nbytes);
468d59ecb2SHans Petter Selasky }
478d59ecb2SHans Petter Selasky 
48bf4e2e5bSMark Johnston static inline u_int
get_random_int(void)49bf4e2e5bSMark Johnston get_random_int(void)
50bf4e2e5bSMark Johnston {
51bf4e2e5bSMark Johnston 	u_int val;
52bf4e2e5bSMark Johnston 
53bf4e2e5bSMark Johnston 	get_random_bytes(&val, sizeof(val));
54bf4e2e5bSMark Johnston 	return (val);
55bf4e2e5bSMark Johnston }
56bf4e2e5bSMark Johnston 
57*f29e915bSBjoern A. Zeeb static inline uint8_t
get_random_u8(void)58*f29e915bSBjoern A. Zeeb get_random_u8(void)
59*f29e915bSBjoern A. Zeeb {
60*f29e915bSBjoern A. Zeeb 	uint8_t val;
61*f29e915bSBjoern A. Zeeb 
62*f29e915bSBjoern A. Zeeb 	get_random_bytes(&val, sizeof(val));
63*f29e915bSBjoern A. Zeeb 	return (val);
64*f29e915bSBjoern A. Zeeb }
65*f29e915bSBjoern A. Zeeb 
661dcd1a53SBjoern A. Zeeb #define	get_random_u32() get_random_int()
671dcd1a53SBjoern A. Zeeb 
681dcd1a53SBjoern A. Zeeb /*
691dcd1a53SBjoern A. Zeeb  * See "Fast Random Integer Generation in an Interval" by Daniel Lemire
701dcd1a53SBjoern A. Zeeb  * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights.
711dcd1a53SBjoern A. Zeeb  */
721dcd1a53SBjoern A. Zeeb static inline uint32_t
get_random_u32_inclusive(uint32_t floor,uint32_t ceil)731dcd1a53SBjoern A. Zeeb get_random_u32_inclusive(uint32_t floor, uint32_t ceil)
741dcd1a53SBjoern A. Zeeb {
751dcd1a53SBjoern A. Zeeb 	uint64_t x;
761dcd1a53SBjoern A. Zeeb 	uint32_t t, v;
771dcd1a53SBjoern A. Zeeb 
781dcd1a53SBjoern A. Zeeb 	MPASS(ceil >= floor);
791dcd1a53SBjoern A. Zeeb 
801dcd1a53SBjoern A. Zeeb 	v = get_random_u32();
811dcd1a53SBjoern A. Zeeb 	t = ceil - floor + 1;
821dcd1a53SBjoern A. Zeeb 	x = (uint64_t)t * v;
831dcd1a53SBjoern A. Zeeb 	while (x < t)
841dcd1a53SBjoern A. Zeeb 		x = (uint64_t)t * get_random_u32();
851dcd1a53SBjoern A. Zeeb 	v = x >> 32;
861dcd1a53SBjoern A. Zeeb 
871dcd1a53SBjoern A. Zeeb 	return (floor + v);
881dcd1a53SBjoern A. Zeeb }
891dcd1a53SBjoern A. Zeeb 
90bf4e2e5bSMark Johnston static inline u_long
get_random_long(void)91bf4e2e5bSMark Johnston get_random_long(void)
92bf4e2e5bSMark Johnston {
93bf4e2e5bSMark Johnston 	u_long val;
94bf4e2e5bSMark Johnston 
95bf4e2e5bSMark Johnston 	get_random_bytes(&val, sizeof(val));
96bf4e2e5bSMark Johnston 	return (val);
97bf4e2e5bSMark Johnston }
98bf4e2e5bSMark Johnston 
997f88d742SVladimir Kondratyev static inline uint64_t
get_random_u64(void)1007f88d742SVladimir Kondratyev get_random_u64(void)
1017f88d742SVladimir Kondratyev {
1027f88d742SVladimir Kondratyev 	uint64_t val;
1037f88d742SVladimir Kondratyev 
1047f88d742SVladimir Kondratyev 	get_random_bytes(&val, sizeof(val));
1057f88d742SVladimir Kondratyev 	return (val);
1067f88d742SVladimir Kondratyev }
1077f88d742SVladimir Kondratyev 
1089289c1f6SVladimir Kondratyev static inline uint32_t
get_random_u32_below(uint32_t max)1099289c1f6SVladimir Kondratyev get_random_u32_below(uint32_t max)
1109289c1f6SVladimir Kondratyev {
1119289c1f6SVladimir Kondratyev 	return (arc4random_uniform(max));
1129289c1f6SVladimir Kondratyev }
1139289c1f6SVladimir Kondratyev 
11410096cb6SBjoern A. Zeeb static __inline uint32_t
prandom_u32(void)11510096cb6SBjoern A. Zeeb prandom_u32(void)
11610096cb6SBjoern A. Zeeb {
11710096cb6SBjoern A. Zeeb 	uint32_t val;
11810096cb6SBjoern A. Zeeb 
11910096cb6SBjoern A. Zeeb 	get_random_bytes(&val, sizeof(val));
12010096cb6SBjoern A. Zeeb 	return (val);
12110096cb6SBjoern A. Zeeb }
12210096cb6SBjoern A. Zeeb 
123af300929SEmmanuel Vadot static inline u32
prandom_u32_max(u32 max)124af300929SEmmanuel Vadot prandom_u32_max(u32 max)
125af300929SEmmanuel Vadot {
126af300929SEmmanuel Vadot 	return (arc4random_uniform(max));
127af300929SEmmanuel Vadot }
128af300929SEmmanuel Vadot 
129307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_RANDOM_H_ */
130