ipc/chromium/src/third_party/libevent/arc4random.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/third_party/libevent/arc4random.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,539 @@
     1.4 +/* Portable arc4random.c based on arc4random.c from OpenBSD.
     1.5 + * Portable version by Chris Davis, adapted for Libevent by Nick Mathewson
     1.6 + * Copyright (c) 2010 Chris Davis, Niels Provos, and Nick Mathewson
     1.7 + * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson
     1.8 + *
     1.9 + * Note that in Libevent, this file isn't compiled directly.  Instead,
    1.10 + * it's included from evutil_rand.c
    1.11 + */
    1.12 +
    1.13 +/*
    1.14 + * Copyright (c) 1996, David Mazieres <dm@uun.org>
    1.15 + * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
    1.16 + *
    1.17 + * Permission to use, copy, modify, and distribute this software for any
    1.18 + * purpose with or without fee is hereby granted, provided that the above
    1.19 + * copyright notice and this permission notice appear in all copies.
    1.20 + *
    1.21 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    1.22 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    1.23 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    1.24 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    1.25 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    1.26 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    1.27 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    1.28 + */
    1.29 +
    1.30 +/*
    1.31 + * Arc4 random number generator for OpenBSD.
    1.32 + *
    1.33 + * This code is derived from section 17.1 of Applied Cryptography,
    1.34 + * second edition, which describes a stream cipher allegedly
    1.35 + * compatible with RSA Labs "RC4" cipher (the actual description of
    1.36 + * which is a trade secret).  The same algorithm is used as a stream
    1.37 + * cipher called "arcfour" in Tatu Ylonen's ssh package.
    1.38 + *
    1.39 + * Here the stream cipher has been modified always to include the time
    1.40 + * when initializing the state.  That makes it impossible to
    1.41 + * regenerate the same random sequence twice, so this can't be used
    1.42 + * for encryption, but will generate good random numbers.
    1.43 + *
    1.44 + * RC4 is a registered trademark of RSA Laboratories.
    1.45 + */
    1.46 +
    1.47 +#ifndef ARC4RANDOM_EXPORT
    1.48 +#define ARC4RANDOM_EXPORT
    1.49 +#endif
    1.50 +
    1.51 +#ifndef ARC4RANDOM_UINT32
    1.52 +#define ARC4RANDOM_UINT32 uint32_t
    1.53 +#endif
    1.54 +
    1.55 +#ifndef ARC4RANDOM_NO_INCLUDES
    1.56 +#ifdef WIN32
    1.57 +#include <wincrypt.h>
    1.58 +#include <process.h>
    1.59 +#else
    1.60 +#include <fcntl.h>
    1.61 +#include <unistd.h>
    1.62 +#include <sys/param.h>
    1.63 +#include <sys/time.h>
    1.64 +#ifdef _EVENT_HAVE_SYS_SYSCTL_H
    1.65 +#include <sys/sysctl.h>
    1.66 +#endif
    1.67 +#endif
    1.68 +#include <limits.h>
    1.69 +#include <stdlib.h>
    1.70 +#include <string.h>
    1.71 +#endif
    1.72 +
    1.73 +/* Add platform entropy 32 bytes (256 bits) at a time. */
    1.74 +#define ADD_ENTROPY 32
    1.75 +
    1.76 +/* Re-seed from the platform RNG after generating this many bytes. */
    1.77 +#define BYTES_BEFORE_RESEED 1600000
    1.78 +
    1.79 +struct arc4_stream {
    1.80 +	unsigned char i;
    1.81 +	unsigned char j;
    1.82 +	unsigned char s[256];
    1.83 +};
    1.84 +
    1.85 +#ifdef WIN32
    1.86 +#define getpid _getpid
    1.87 +#define pid_t int
    1.88 +#endif
    1.89 +
    1.90 +static int rs_initialized;
    1.91 +static struct arc4_stream rs;
    1.92 +static pid_t arc4_stir_pid;
    1.93 +static int arc4_count;
    1.94 +static int arc4_seeded_ok;
    1.95 +
    1.96 +static inline unsigned char arc4_getbyte(void);
    1.97 +
    1.98 +static inline void
    1.99 +arc4_init(void)
   1.100 +{
   1.101 +	int     n;
   1.102 +
   1.103 +	for (n = 0; n < 256; n++)
   1.104 +		rs.s[n] = n;
   1.105 +	rs.i = 0;
   1.106 +	rs.j = 0;
   1.107 +}
   1.108 +
   1.109 +static inline void
   1.110 +arc4_addrandom(const unsigned char *dat, int datlen)
   1.111 +{
   1.112 +	int     n;
   1.113 +	unsigned char si;
   1.114 +
   1.115 +	rs.i--;
   1.116 +	for (n = 0; n < 256; n++) {
   1.117 +		rs.i = (rs.i + 1);
   1.118 +		si = rs.s[rs.i];
   1.119 +		rs.j = (rs.j + si + dat[n % datlen]);
   1.120 +		rs.s[rs.i] = rs.s[rs.j];
   1.121 +		rs.s[rs.j] = si;
   1.122 +	}
   1.123 +	rs.j = rs.i;
   1.124 +}
   1.125 +
   1.126 +#ifndef WIN32
   1.127 +static ssize_t
   1.128 +read_all(int fd, unsigned char *buf, size_t count)
   1.129 +{
   1.130 +	size_t numread = 0;
   1.131 +	ssize_t result;
   1.132 +
   1.133 +	while (numread < count) {
   1.134 +		result = read(fd, buf+numread, count-numread);
   1.135 +		if (result<0)
   1.136 +			return -1;
   1.137 +		else if (result == 0)
   1.138 +			break;
   1.139 +		numread += result;
   1.140 +	}
   1.141 +
   1.142 +	return (ssize_t)numread;
   1.143 +}
   1.144 +#endif
   1.145 +
   1.146 +#ifdef WIN32
   1.147 +#define TRY_SEED_WIN32
   1.148 +static int
   1.149 +arc4_seed_win32(void)
   1.150 +{
   1.151 +	/* This is adapted from Tor's crypto_seed_rng() */
   1.152 +	static int provider_set = 0;
   1.153 +	static HCRYPTPROV provider;
   1.154 +	unsigned char buf[ADD_ENTROPY];
   1.155 +
   1.156 +	if (!provider_set) {
   1.157 +		if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
   1.158 +		    CRYPT_VERIFYCONTEXT)) {
   1.159 +			if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
   1.160 +				return -1;
   1.161 +		}
   1.162 +		provider_set = 1;
   1.163 +	}
   1.164 +	if (!CryptGenRandom(provider, sizeof(buf), buf))
   1.165 +		return -1;
   1.166 +	arc4_addrandom(buf, sizeof(buf));
   1.167 +	memset(buf, 0, sizeof(buf));
   1.168 +	arc4_seeded_ok = 1;
   1.169 +	return 0;
   1.170 +}
   1.171 +#endif
   1.172 +
   1.173 +#if defined(_EVENT_HAVE_SYS_SYSCTL_H) && defined(_EVENT_HAVE_SYSCTL)
   1.174 +#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_RANDOM && _EVENT_HAVE_DECL_RANDOM_UUID
   1.175 +#define TRY_SEED_SYSCTL_LINUX
   1.176 +static int
   1.177 +arc4_seed_sysctl_linux(void)
   1.178 +{
   1.179 +	/* Based on code by William Ahern, this function tries to use the
   1.180 +	 * RANDOM_UUID sysctl to get entropy from the kernel.  This can work
   1.181 +	 * even if /dev/urandom is inaccessible for some reason (e.g., we're
   1.182 +	 * running in a chroot). */
   1.183 +	int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
   1.184 +	unsigned char buf[ADD_ENTROPY];
   1.185 +	size_t len, n;
   1.186 +	unsigned i;
   1.187 +	int any_set;
   1.188 +
   1.189 +	memset(buf, 0, sizeof(buf));
   1.190 +
   1.191 +	for (len = 0; len < sizeof(buf); len += n) {
   1.192 +		n = sizeof(buf) - len;
   1.193 +
   1.194 +		if (0 != sysctl(mib, 3, &buf[len], &n, NULL, 0))
   1.195 +			return -1;
   1.196 +	}
   1.197 +	/* make sure that the buffer actually got set. */
   1.198 +	for (i=0,any_set=0; i<sizeof(buf); ++i) {
   1.199 +		any_set |= buf[i];
   1.200 +	}
   1.201 +	if (!any_set)
   1.202 +		return -1;
   1.203 +
   1.204 +	arc4_addrandom(buf, sizeof(buf));
   1.205 +	memset(buf, 0, sizeof(buf));
   1.206 +	arc4_seeded_ok = 1;
   1.207 +	return 0;
   1.208 +}
   1.209 +#endif
   1.210 +
   1.211 +#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_ARND
   1.212 +#define TRY_SEED_SYSCTL_BSD
   1.213 +static int
   1.214 +arc4_seed_sysctl_bsd(void)
   1.215 +{
   1.216 +	/* Based on code from William Ahern and from OpenBSD, this function
   1.217 +	 * tries to use the KERN_ARND syscall to get entropy from the kernel.
   1.218 +	 * This can work even if /dev/urandom is inaccessible for some reason
   1.219 +	 * (e.g., we're running in a chroot). */
   1.220 +	int mib[] = { CTL_KERN, KERN_ARND };
   1.221 +	unsigned char buf[ADD_ENTROPY];
   1.222 +	size_t len, n;
   1.223 +	int i, any_set;
   1.224 +
   1.225 +	memset(buf, 0, sizeof(buf));
   1.226 +
   1.227 +	len = sizeof(buf);
   1.228 +	if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
   1.229 +		for (len = 0; len < sizeof(buf); len += sizeof(unsigned)) {
   1.230 +			n = sizeof(unsigned);
   1.231 +			if (n + len > sizeof(buf))
   1.232 +			    n = len - sizeof(buf);
   1.233 +			if (sysctl(mib, 2, &buf[len], &n, NULL, 0) == -1)
   1.234 +				return -1;
   1.235 +		}
   1.236 +	}
   1.237 +	/* make sure that the buffer actually got set. */
   1.238 +	for (i=any_set=0; i<sizeof(buf); ++i) {
   1.239 +		any_set |= buf[i];
   1.240 +	}
   1.241 +	if (!any_set)
   1.242 +		return -1;
   1.243 +
   1.244 +	arc4_addrandom(buf, sizeof(buf));
   1.245 +	memset(buf, 0, sizeof(buf));
   1.246 +	arc4_seeded_ok = 1;
   1.247 +	return 0;
   1.248 +}
   1.249 +#endif
   1.250 +#endif /* defined(_EVENT_HAVE_SYS_SYSCTL_H) */
   1.251 +
   1.252 +#ifdef __linux__
   1.253 +#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
   1.254 +static int
   1.255 +arc4_seed_proc_sys_kernel_random_uuid(void)
   1.256 +{
   1.257 +	/* Occasionally, somebody will make /proc/sys accessible in a chroot,
   1.258 +	 * but not /dev/urandom.  Let's try /proc/sys/kernel/random/uuid.
   1.259 +	 * Its format is stupid, so we need to decode it from hex.
   1.260 +	 */
   1.261 +	int fd;
   1.262 +	char buf[128];
   1.263 +	unsigned char entropy[64];
   1.264 +	int bytes, n, i, nybbles;
   1.265 +	for (bytes = 0; bytes<ADD_ENTROPY; ) {
   1.266 +		fd = evutil_open_closeonexec("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
   1.267 +		if (fd < 0)
   1.268 +			return -1;
   1.269 +		n = read(fd, buf, sizeof(buf));
   1.270 +		close(fd);
   1.271 +		if (n<=0)
   1.272 +			return -1;
   1.273 +		memset(entropy, 0, sizeof(entropy));
   1.274 +		for (i=nybbles=0; i<n; ++i) {
   1.275 +			if (EVUTIL_ISXDIGIT(buf[i])) {
   1.276 +				int nyb = evutil_hex_char_to_int(buf[i]);
   1.277 +				if (nybbles & 1) {
   1.278 +					entropy[nybbles/2] |= nyb;
   1.279 +				} else {
   1.280 +					entropy[nybbles/2] |= nyb<<4;
   1.281 +				}
   1.282 +				++nybbles;
   1.283 +			}
   1.284 +		}
   1.285 +		if (nybbles < 2)
   1.286 +			return -1;
   1.287 +		arc4_addrandom(entropy, nybbles/2);
   1.288 +		bytes += nybbles/2;
   1.289 +	}
   1.290 +	memset(entropy, 0, sizeof(entropy));
   1.291 +	memset(buf, 0, sizeof(buf));
   1.292 +	return 0;
   1.293 +}
   1.294 +#endif
   1.295 +
   1.296 +#ifndef WIN32
   1.297 +#define TRY_SEED_URANDOM
   1.298 +static int
   1.299 +arc4_seed_urandom(void)
   1.300 +{
   1.301 +	/* This is adapted from Tor's crypto_seed_rng() */
   1.302 +	static const char *filenames[] = {
   1.303 +		"/dev/srandom", "/dev/urandom", "/dev/random", NULL
   1.304 +	};
   1.305 +	unsigned char buf[ADD_ENTROPY];
   1.306 +	int fd, i;
   1.307 +	size_t n;
   1.308 +
   1.309 +	for (i = 0; filenames[i]; ++i) {
   1.310 +		fd = evutil_open_closeonexec(filenames[i], O_RDONLY, 0);
   1.311 +		if (fd<0)
   1.312 +			continue;
   1.313 +		n = read_all(fd, buf, sizeof(buf));
   1.314 +		close(fd);
   1.315 +		if (n != sizeof(buf))
   1.316 +			return -1;
   1.317 +		arc4_addrandom(buf, sizeof(buf));
   1.318 +		memset(buf, 0, sizeof(buf));
   1.319 +		arc4_seeded_ok = 1;
   1.320 +		return 0;
   1.321 +	}
   1.322 +
   1.323 +	return -1;
   1.324 +}
   1.325 +#endif
   1.326 +
   1.327 +static int
   1.328 +arc4_seed(void)
   1.329 +{
   1.330 +	int ok = 0;
   1.331 +	/* We try every method that might work, and don't give up even if one
   1.332 +	 * does seem to work.  There's no real harm in over-seeding, and if
   1.333 +	 * one of these sources turns out to be broken, that would be bad. */
   1.334 +#ifdef TRY_SEED_WIN32
   1.335 +	if (0 == arc4_seed_win32())
   1.336 +		ok = 1;
   1.337 +#endif
   1.338 +#ifdef TRY_SEED_URANDOM
   1.339 +	if (0 == arc4_seed_urandom())
   1.340 +		ok = 1;
   1.341 +#endif
   1.342 +#ifdef TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
   1.343 +	if (0 == arc4_seed_proc_sys_kernel_random_uuid())
   1.344 +		ok = 1;
   1.345 +#endif
   1.346 +#ifdef TRY_SEED_SYSCTL_LINUX
   1.347 +	/* Apparently Linux is deprecating sysctl, and spewing warning
   1.348 +	 * messages when you try to use it. */
   1.349 +	if (!ok && 0 == arc4_seed_sysctl_linux())
   1.350 +		ok = 1;
   1.351 +#endif
   1.352 +#ifdef TRY_SEED_SYSCTL_BSD
   1.353 +	if (0 == arc4_seed_sysctl_bsd())
   1.354 +		ok = 1;
   1.355 +#endif
   1.356 +	return ok ? 0 : -1;
   1.357 +}
   1.358 +
   1.359 +static int
   1.360 +arc4_stir(void)
   1.361 +{
   1.362 +	int     i;
   1.363 +
   1.364 +	if (!rs_initialized) {
   1.365 +		arc4_init();
   1.366 +		rs_initialized = 1;
   1.367 +	}
   1.368 +
   1.369 +	arc4_seed();
   1.370 +	if (!arc4_seeded_ok)
   1.371 +		return -1;
   1.372 +
   1.373 +	/*
   1.374 +	 * Discard early keystream, as per recommendations in
   1.375 +	 * "Weaknesses in the Key Scheduling Algorithm of RC4" by
   1.376 +	 * Scott Fluhrer, Itsik Mantin, and Adi Shamir.
   1.377 +	 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
   1.378 +	 *
   1.379 +	 * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that
   1.380 +	 * we drop at least 2*256 bytes, with 12*256 as a conservative
   1.381 +	 * value.
   1.382 +	 *
   1.383 +	 * RFC4345 says to drop 6*256.
   1.384 +	 *
   1.385 +	 * At least some versions of this code drop 4*256, in a mistaken
   1.386 +	 * belief that "words" in the Fluhrer/Mantin/Shamir paper refers
   1.387 +	 * to processor words.
   1.388 +	 *
   1.389 +	 * We add another sect to the cargo cult, and choose 12*256.
   1.390 +	 */
   1.391 +	for (i = 0; i < 12*256; i++)
   1.392 +		(void)arc4_getbyte();
   1.393 +	arc4_count = BYTES_BEFORE_RESEED;
   1.394 +
   1.395 +	return 0;
   1.396 +}
   1.397 +
   1.398 +
   1.399 +static void
   1.400 +arc4_stir_if_needed(void)
   1.401 +{
   1.402 +	pid_t pid = getpid();
   1.403 +
   1.404 +	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid)
   1.405 +	{
   1.406 +		arc4_stir_pid = pid;
   1.407 +		arc4_stir();
   1.408 +	}
   1.409 +}
   1.410 +
   1.411 +static inline unsigned char
   1.412 +arc4_getbyte(void)
   1.413 +{
   1.414 +	unsigned char si, sj;
   1.415 +
   1.416 +	rs.i = (rs.i + 1);
   1.417 +	si = rs.s[rs.i];
   1.418 +	rs.j = (rs.j + si);
   1.419 +	sj = rs.s[rs.j];
   1.420 +	rs.s[rs.i] = sj;
   1.421 +	rs.s[rs.j] = si;
   1.422 +	return (rs.s[(si + sj) & 0xff]);
   1.423 +}
   1.424 +
   1.425 +static inline unsigned int
   1.426 +arc4_getword(void)
   1.427 +{
   1.428 +	unsigned int val;
   1.429 +
   1.430 +	val = arc4_getbyte() << 24;
   1.431 +	val |= arc4_getbyte() << 16;
   1.432 +	val |= arc4_getbyte() << 8;
   1.433 +	val |= arc4_getbyte();
   1.434 +
   1.435 +	return val;
   1.436 +}
   1.437 +
   1.438 +#ifndef ARC4RANDOM_NOSTIR
   1.439 +ARC4RANDOM_EXPORT int
   1.440 +arc4random_stir(void)
   1.441 +{
   1.442 +	int val;
   1.443 +	_ARC4_LOCK();
   1.444 +	val = arc4_stir();
   1.445 +	_ARC4_UNLOCK();
   1.446 +	return val;
   1.447 +}
   1.448 +#endif
   1.449 +
   1.450 +#ifndef ARC4RANDOM_NOADDRANDOM
   1.451 +ARC4RANDOM_EXPORT void
   1.452 +arc4random_addrandom(const unsigned char *dat, int datlen)
   1.453 +{
   1.454 +	int j;
   1.455 +	_ARC4_LOCK();
   1.456 +	if (!rs_initialized)
   1.457 +		arc4_stir();
   1.458 +	for (j = 0; j < datlen; j += 256) {
   1.459 +		/* arc4_addrandom() ignores all but the first 256 bytes of
   1.460 +		 * its input.  We want to make sure to look at ALL the
   1.461 +		 * data in 'dat', just in case the user is doing something
   1.462 +		 * crazy like passing us all the files in /var/log. */
   1.463 +		arc4_addrandom(dat + j, datlen - j);
   1.464 +	}
   1.465 +	_ARC4_UNLOCK();
   1.466 +}
   1.467 +#endif
   1.468 +
   1.469 +#ifndef ARC4RANDOM_NORANDOM
   1.470 +ARC4RANDOM_EXPORT ARC4RANDOM_UINT32
   1.471 +arc4random(void)
   1.472 +{
   1.473 +	ARC4RANDOM_UINT32 val;
   1.474 +	_ARC4_LOCK();
   1.475 +	arc4_count -= 4;
   1.476 +	arc4_stir_if_needed();
   1.477 +	val = arc4_getword();
   1.478 +	_ARC4_UNLOCK();
   1.479 +	return val;
   1.480 +}
   1.481 +#endif
   1.482 +
   1.483 +ARC4RANDOM_EXPORT void
   1.484 +arc4random_buf(void *_buf, size_t n)
   1.485 +{
   1.486 +	unsigned char *buf = _buf;
   1.487 +	_ARC4_LOCK();
   1.488 +	arc4_stir_if_needed();
   1.489 +	while (n--) {
   1.490 +		if (--arc4_count <= 0)
   1.491 +			arc4_stir();
   1.492 +		buf[n] = arc4_getbyte();
   1.493 +	}
   1.494 +	_ARC4_UNLOCK();
   1.495 +}
   1.496 +
   1.497 +#ifndef ARC4RANDOM_NOUNIFORM
   1.498 +/*
   1.499 + * Calculate a uniformly distributed random number less than upper_bound
   1.500 + * avoiding "modulo bias".
   1.501 + *
   1.502 + * Uniformity is achieved by generating new random numbers until the one
   1.503 + * returned is outside the range [0, 2**32 % upper_bound).  This
   1.504 + * guarantees the selected random number will be inside
   1.505 + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
   1.506 + * after reduction modulo upper_bound.
   1.507 + */
   1.508 +ARC4RANDOM_EXPORT unsigned int
   1.509 +arc4random_uniform(unsigned int upper_bound)
   1.510 +{
   1.511 +	ARC4RANDOM_UINT32 r, min;
   1.512 +
   1.513 +	if (upper_bound < 2)
   1.514 +		return 0;
   1.515 +
   1.516 +#if (UINT_MAX > 0xffffffffUL)
   1.517 +	min = 0x100000000UL % upper_bound;
   1.518 +#else
   1.519 +	/* Calculate (2**32 % upper_bound) avoiding 64-bit math */
   1.520 +	if (upper_bound > 0x80000000)
   1.521 +		min = 1 + ~upper_bound;		/* 2**32 - upper_bound */
   1.522 +	else {
   1.523 +		/* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
   1.524 +		min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
   1.525 +	}
   1.526 +#endif
   1.527 +
   1.528 +	/*
   1.529 +	 * This could theoretically loop forever but each retry has
   1.530 +	 * p > 0.5 (worst case, usually far better) of selecting a
   1.531 +	 * number inside the range we need, so it should rarely need
   1.532 +	 * to re-roll.
   1.533 +	 */
   1.534 +	for (;;) {
   1.535 +		r = arc4random();
   1.536 +		if (r >= min)
   1.537 +			break;
   1.538 +	}
   1.539 +
   1.540 +	return r % upper_bound;
   1.541 +}
   1.542 +#endif

mercurial