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