diff options
Diffstat (limited to 'usr.sbin/bind/lib/isc/random.c')
| -rw-r--r-- | usr.sbin/bind/lib/isc/random.c | 87 |
1 files changed, 35 insertions, 52 deletions
diff --git a/usr.sbin/bind/lib/isc/random.c b/usr.sbin/bind/lib/isc/random.c index 8730d5213e9..1199c5eb766 100644 --- a/usr.sbin/bind/lib/isc/random.c +++ b/usr.sbin/bind/lib/isc/random.c @@ -1,9 +1,8 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2013, 2014, 2016 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. - * Copyright (C) 2008 Damien Miller * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * @@ -16,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: random.c,v 1.21.18.2 2005/04/29 00:16:48 marka Exp $ */ +/* $Id: random.c,v 1.10 2019/12/16 16:16:26 deraadt Exp $ */ /*! \file */ @@ -44,14 +43,14 @@ initialize_rand(void) { #ifndef HAVE_ARC4RANDOM unsigned int pid = getpid(); - + /* * The low bits of pid generally change faster. * Xor them with the high bits of time which change slowly. */ pid = ((pid << 16) & 0xffff0000) | ((pid >> 16) & 0xffff); - srand(time(NULL) ^ pid); + srand((unsigned)time(NULL) ^ pid); #endif } @@ -68,6 +67,21 @@ isc_random_seed(isc_uint32_t seed) #ifndef HAVE_ARC4RANDOM srand(seed); +#elif defined(HAVE_ARC4RANDOM_STIR) + /* Formally not necessary... */ + UNUSED(seed); + arc4random_stir(); +#elif defined(HAVE_ARC4RANDOM_ADDRANDOM) + arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); +#else + /* + * If arc4random() is available and no corresponding seeding + * function arc4random_addrandom() is available, no seeding is + * done on such platforms (e.g., OpenBSD 5.5). This is because + * the OS itself is supposed to seed the RNG and it is assumed + * that no explicit seeding is required. + */ + UNUSED(seed); #endif } @@ -83,61 +97,30 @@ isc_random_get(isc_uint32_t *val) * rand()'s lower bits are not random. * rand()'s upper bit is zero. */ +#if RAND_MAX >= 0xfffff + /* We have at least 20 bits. Use lower 16 excluding lower most 4 */ *val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000); +#elif RAND_MAX >= 0x7fff + /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */ + *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) | + ((rand() << 18) & 0xffc00000); #else - *val = arc4random(); +#error RAND_MAX is too small #endif -} - -isc_uint32_t -isc_random_uniform(isc_uint32_t upper_bound) -{ - isc_uint32_t r, min; - - /* - * Uniformity is achieved by generating new random numbers until - * the one returned is outside the range [0, 2**32 % upper_bound). - * This guarantees the selected random number will be inside - * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) - * after reduction modulo upper_bound. - */ - - if (upper_bound < 2) - return 0; - -#if (ULONG_MAX > 0xffffffffUL) - min = 0x100000000UL % upper_bound; #else - /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ - if (upper_bound > 0x80000000) - min = 1 + ~upper_bound; /* 2**32 - upper_bound */ - else { - /* (2**32 - x) % x == 2**32 % x when x <= 2**31 */ - min = ((0xffffffff - upper_bound) + 1) % upper_bound; - } + *val = arc4random(); #endif - - /* - * This could theoretically loop forever doing this, but each retry - * has p > 0.5 (worst case, usually far better) of selecting a - * number inside the range we need, so it should rarely need to - * re-roll. - */ - for (;;) { - isc_random_get(&r); - if (r >= min) - break; - } - - return r % upper_bound; } isc_uint32_t isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) { - REQUIRE(jitter < max); + isc_uint32_t rnd; + + REQUIRE(jitter < max || (jitter == 0 && max == 0)); + if (jitter == 0) return (max); - else - return max - isc_random_uniform(jitter); -} + isc_random_get(&rnd); + return (max - rnd % jitter); +} |
