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 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 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 571dcd1a53SBjoern A. Zeeb #define get_random_u32() get_random_int() 581dcd1a53SBjoern A. Zeeb 591dcd1a53SBjoern A. Zeeb /* 601dcd1a53SBjoern A. Zeeb * See "Fast Random Integer Generation in an Interval" by Daniel Lemire 611dcd1a53SBjoern A. Zeeb * [https://arxiv.org/pdf/1805.10941.pdf] for implementation insights. 621dcd1a53SBjoern A. Zeeb */ 631dcd1a53SBjoern A. Zeeb static inline uint32_t 641dcd1a53SBjoern A. Zeeb get_random_u32_inclusive(uint32_t floor, uint32_t ceil) 651dcd1a53SBjoern A. Zeeb { 661dcd1a53SBjoern A. Zeeb uint64_t x; 671dcd1a53SBjoern A. Zeeb uint32_t t, v; 681dcd1a53SBjoern A. Zeeb 691dcd1a53SBjoern A. Zeeb MPASS(ceil >= floor); 701dcd1a53SBjoern A. Zeeb 711dcd1a53SBjoern A. Zeeb v = get_random_u32(); 721dcd1a53SBjoern A. Zeeb t = ceil - floor + 1; 731dcd1a53SBjoern A. Zeeb x = (uint64_t)t * v; 741dcd1a53SBjoern A. Zeeb while (x < t) 751dcd1a53SBjoern A. Zeeb x = (uint64_t)t * get_random_u32(); 761dcd1a53SBjoern A. Zeeb v = x >> 32; 771dcd1a53SBjoern A. Zeeb 781dcd1a53SBjoern A. Zeeb return (floor + v); 791dcd1a53SBjoern A. Zeeb } 801dcd1a53SBjoern A. Zeeb 81bf4e2e5bSMark Johnston static inline u_long 82bf4e2e5bSMark Johnston get_random_long(void) 83bf4e2e5bSMark Johnston { 84bf4e2e5bSMark Johnston u_long val; 85bf4e2e5bSMark Johnston 86bf4e2e5bSMark Johnston get_random_bytes(&val, sizeof(val)); 87bf4e2e5bSMark Johnston return (val); 88bf4e2e5bSMark Johnston } 89bf4e2e5bSMark Johnston 90*7f88d742SVladimir Kondratyev static inline uint64_t 91*7f88d742SVladimir Kondratyev get_random_u64(void) 92*7f88d742SVladimir Kondratyev { 93*7f88d742SVladimir Kondratyev uint64_t val; 94*7f88d742SVladimir Kondratyev 95*7f88d742SVladimir Kondratyev get_random_bytes(&val, sizeof(val)); 96*7f88d742SVladimir Kondratyev return (val); 97*7f88d742SVladimir Kondratyev } 98*7f88d742SVladimir Kondratyev 9910096cb6SBjoern A. Zeeb static __inline uint32_t 10010096cb6SBjoern A. Zeeb prandom_u32(void) 10110096cb6SBjoern A. Zeeb { 10210096cb6SBjoern A. Zeeb uint32_t val; 10310096cb6SBjoern A. Zeeb 10410096cb6SBjoern A. Zeeb get_random_bytes(&val, sizeof(val)); 10510096cb6SBjoern A. Zeeb return (val); 10610096cb6SBjoern A. Zeeb } 10710096cb6SBjoern A. Zeeb 108af300929SEmmanuel Vadot static inline u32 109af300929SEmmanuel Vadot prandom_u32_max(u32 max) 110af300929SEmmanuel Vadot { 111af300929SEmmanuel Vadot return (arc4random_uniform(max)); 112af300929SEmmanuel Vadot } 113af300929SEmmanuel Vadot 114307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_RANDOM_H_ */ 115