1e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Portable arc4random.c based on arc4random.c from OpenBSD.
2e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Portable version by Chris Davis, adapted for Libevent by Nick Mathewson
3e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Copyright (c) 2010 Chris Davis, Niels Provos, and Nick Mathewson
4e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson
5e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
6e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Note that in Libevent, this file isn't compiled directly.  Instead,
7e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * it's included from evutil_rand.c
8e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
9e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
10e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/*
11e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Copyright (c) 1996, David Mazieres <dm@uun.org>
12e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
13e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
14e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Permission to use, copy, modify, and distribute this software for any
15e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * purpose with or without fee is hereby granted, provided that the above
16e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * copyright notice and this permission notice appear in all copies.
17e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
18e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
19e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
20e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
21e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
24e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
26e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
27e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/*
28e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Arc4 random number generator for OpenBSD.
29e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
30e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * This code is derived from section 17.1 of Applied Cryptography,
31e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * second edition, which describes a stream cipher allegedly
32e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * compatible with RSA Labs "RC4" cipher (the actual description of
33e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * which is a trade secret).  The same algorithm is used as a stream
34e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * cipher called "arcfour" in Tatu Ylonen's ssh package.
35e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
36e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Here the stream cipher has been modified always to include the time
37e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * when initializing the state.  That makes it impossible to
38e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * regenerate the same random sequence twice, so this can't be used
39e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * for encryption, but will generate good random numbers.
40e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
41e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * RC4 is a registered trademark of RSA Laboratories.
42e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
43e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
44e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_EXPORT
45e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define ARC4RANDOM_EXPORT
46e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
47e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
48e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_UINT32
49e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define ARC4RANDOM_UINT32 uint32_t
50e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
51e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
52e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_NO_INCLUDES
53e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef WIN32
54e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <wincrypt.h>
55e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <process.h>
56e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
57e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <fcntl.h>
58e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <unistd.h>
59e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <sys/param.h>
60e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <sys/time.h>
61e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef _EVENT_HAVE_SYS_SYSCTL_H
62e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <sys/sysctl.h>
63e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
64e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
65e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <limits.h>
66e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <stdlib.h>
67e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#include <string.h>
68e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
69e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
70e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Add platform entropy 32 bytes (256 bits) at a time. */
71e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define ADD_ENTROPY 32
72e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
73e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/* Re-seed from the platform RNG after generating this many bytes. */
74e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define BYTES_BEFORE_RESEED 1600000
75e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
76e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystruct arc4_stream {
77e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char i;
78e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char j;
79e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char s[256];
80e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley};
81e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
82e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef WIN32
83e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define getpid _getpid
84e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define pid_t int
85e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
86e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
87e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int rs_initialized;
88e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic struct arc4_stream rs;
89e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic pid_t arc4_stir_pid;
90e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int arc4_count;
91e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int arc4_seeded_ok;
92e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
93e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline unsigned char arc4_getbyte(void);
94e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
95e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline void
96e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_init(void)
97e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
98e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int     n;
99e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
100e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (n = 0; n < 256; n++)
101e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs.s[n] = n;
102e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.i = 0;
103e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.j = 0;
104e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
105e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
106e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline void
107e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_addrandom(const unsigned char *dat, int datlen)
108e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
109e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int     n;
110e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char si;
111e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
112e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.i--;
113e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (n = 0; n < 256; n++) {
114e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs.i = (rs.i + 1);
115e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		si = rs.s[rs.i];
116e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs.j = (rs.j + si + dat[n % datlen]);
117e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs.s[rs.i] = rs.s[rs.j];
118e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs.s[rs.j] = si;
119e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
120e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.j = rs.i;
121e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
122e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
123e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef WIN32
124e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic ssize_t
125e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyread_all(int fd, unsigned char *buf, size_t count)
126e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
127e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size_t numread = 0;
128e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ssize_t result;
129e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
130e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (numread < count) {
131e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		result = read(fd, buf+numread, count-numread);
132e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (result<0)
133e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
134e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		else if (result == 0)
135e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			break;
136e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		numread += result;
137e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
138e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
139e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return (ssize_t)numread;
140e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
141e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
142e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
143e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef WIN32
144e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define TRY_SEED_WIN32
145e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
146e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed_win32(void)
147e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
148e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* This is adapted from Tor's crypto_seed_rng() */
149e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	static int provider_set = 0;
150e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	static HCRYPTPROV provider;
151e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char buf[ADD_ENTROPY];
152e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
153e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!provider_set) {
154e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
155e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		    CRYPT_VERIFYCONTEXT)) {
156e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
157e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return -1;
158e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
159e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		provider_set = 1;
160e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
161e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!CryptGenRandom(provider, sizeof(buf), buf))
162e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
163e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_addrandom(buf, sizeof(buf));
164e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(buf, sizeof(buf));
165e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seeded_ok = 1;
166e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
167e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
168e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
169e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
170e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if defined(_EVENT_HAVE_SYS_SYSCTL_H) && defined(_EVENT_HAVE_SYSCTL)
171e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_RANDOM && _EVENT_HAVE_DECL_RANDOM_UUID
172e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define TRY_SEED_SYSCTL_LINUX
173e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
174e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed_sysctl_linux(void)
175e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
176e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Based on code by William Ahern, this function tries to use the
177e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * RANDOM_UUID sysctl to get entropy from the kernel.  This can work
178e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * even if /dev/urandom is inaccessible for some reason (e.g., we're
179e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * running in a chroot). */
180e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
181e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char buf[ADD_ENTROPY];
182e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size_t len, n;
183e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned i;
184e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int any_set;
185e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
186e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(buf, 0, sizeof(buf));
187e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
188e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (len = 0; len < sizeof(buf); len += n) {
189e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		n = sizeof(buf) - len;
190e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
191e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (0 != sysctl(mib, 3, &buf[len], &n, NULL, 0))
192e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
193e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
194e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* make sure that the buffer actually got set. */
195e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (i=0,any_set=0; i<sizeof(buf); ++i) {
196e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		any_set |= buf[i];
197e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
198e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!any_set)
199e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
200e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
201e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_addrandom(buf, sizeof(buf));
202e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(buf, sizeof(buf));
203e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seeded_ok = 1;
204e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
205e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
206e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
207e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
208e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if _EVENT_HAVE_DECL_CTL_KERN && _EVENT_HAVE_DECL_KERN_ARND
209e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define TRY_SEED_SYSCTL_BSD
210e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
211e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed_sysctl_bsd(void)
212e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
213e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Based on code from William Ahern and from OpenBSD, this function
214e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * tries to use the KERN_ARND syscall to get entropy from the kernel.
215e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * This can work even if /dev/urandom is inaccessible for some reason
216e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * (e.g., we're running in a chroot). */
217e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int mib[] = { CTL_KERN, KERN_ARND };
218e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char buf[ADD_ENTROPY];
219e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size_t len, n;
220e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int i, any_set;
221e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
222e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	memset(buf, 0, sizeof(buf));
223e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
224e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	len = sizeof(buf);
225e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
226e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		for (len = 0; len < sizeof(buf); len += sizeof(unsigned)) {
227e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			n = sizeof(unsigned);
228e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (n + len > sizeof(buf))
229e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			    n = len - sizeof(buf);
230e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (sysctl(mib, 2, &buf[len], &n, NULL, 0) == -1)
231e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				return -1;
232e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
233e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
234e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* make sure that the buffer actually got set. */
235e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (i=any_set=0; i<sizeof(buf); ++i) {
236e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		any_set |= buf[i];
237e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
238e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!any_set)
239e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
240e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
241e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_addrandom(buf, sizeof(buf));
242e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(buf, sizeof(buf));
243e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seeded_ok = 1;
244e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
245e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
246e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
247e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif /* defined(_EVENT_HAVE_SYS_SYSCTL_H) */
248e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
249e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef __linux__
250e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
251e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
252e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed_proc_sys_kernel_random_uuid(void)
253e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
254e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Occasionally, somebody will make /proc/sys accessible in a chroot,
255e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * but not /dev/urandom.  Let's try /proc/sys/kernel/random/uuid.
256e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * Its format is stupid, so we need to decode it from hex.
257e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
258e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int fd;
259e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	char buf[128];
260e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char entropy[64];
261e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int bytes, n, i, nybbles;
262e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (bytes = 0; bytes<ADD_ENTROPY; ) {
263e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		fd = evutil_open_closeonexec("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
264e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (fd < 0)
265e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
266e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		n = read(fd, buf, sizeof(buf));
267e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		close(fd);
268e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (n<=0)
269e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
270e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		memset(entropy, 0, sizeof(entropy));
271e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		for (i=nybbles=0; i<n; ++i) {
272e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			if (EVUTIL_ISXDIGIT(buf[i])) {
273e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				int nyb = evutil_hex_char_to_int(buf[i]);
274e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				if (nybbles & 1) {
275e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					entropy[nybbles/2] |= nyb;
276e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				} else {
277e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley					entropy[nybbles/2] |= nyb<<4;
278e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				}
279e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley				++nybbles;
280e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			}
281e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
282e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (nybbles < 2)
283e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return -1;
284e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_addrandom(entropy, nybbles/2);
285e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		bytes += nybbles/2;
286e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
287e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(entropy, sizeof(entropy));
288e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(buf, sizeof(buf));
289e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seeded_ok = 1;
290e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
291e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
292e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
293e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
294e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef WIN32
295e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#define TRY_SEED_URANDOM
296e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic char *arc4random_urandom_filename = NULL;
297e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
298e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int arc4_seed_urandom_helper_(const char *fname)
299e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
300e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char buf[ADD_ENTROPY];
301e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int fd;
302e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	size_t n;
303e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
304e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	fd = evutil_open_closeonexec(fname, O_RDONLY, 0);
305e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (fd<0)
306e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
307e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	n = read_all(fd, buf, sizeof(buf));
308e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	close(fd);
309e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (n != sizeof(buf))
310e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
311e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_addrandom(buf, sizeof(buf));
312e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	evutil_memclear_(buf, sizeof(buf));
313e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seeded_ok = 1;
314e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
315e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
316e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
317e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
318e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed_urandom(void)
319e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
320e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* This is adapted from Tor's crypto_seed_rng() */
321e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	static const char *filenames[] = {
322e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		"/dev/srandom", "/dev/urandom", "/dev/random", NULL
323e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	};
324e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int i;
325e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (arc4random_urandom_filename)
326e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return arc4_seed_urandom_helper_(arc4random_urandom_filename);
327e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
328e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (i = 0; filenames[i]; ++i) {
329e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (arc4_seed_urandom_helper_(filenames[i]) == 0) {
330e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			return 0;
331e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		}
332e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
333e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
334e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return -1;
335e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
336e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
337e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
338e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
339e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_seed(void)
340e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
341e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int ok = 0;
342e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* We try every method that might work, and don't give up even if one
343e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * does seem to work.  There's no real harm in over-seeding, and if
344e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * one of these sources turns out to be broken, that would be bad. */
345e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef TRY_SEED_WIN32
346e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (0 == arc4_seed_win32())
347e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ok = 1;
348e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
349e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef TRY_SEED_URANDOM
350e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (0 == arc4_seed_urandom())
351e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ok = 1;
352e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
353e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
354e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (arc4random_urandom_filename == NULL &&
355e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	    0 == arc4_seed_proc_sys_kernel_random_uuid())
356e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ok = 1;
357e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
358e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef TRY_SEED_SYSCTL_LINUX
359e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Apparently Linux is deprecating sysctl, and spewing warning
360e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * messages when you try to use it. */
361e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!ok && 0 == arc4_seed_sysctl_linux())
362e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ok = 1;
363e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
364e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifdef TRY_SEED_SYSCTL_BSD
365e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (0 == arc4_seed_sysctl_bsd())
366e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		ok = 1;
367e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
368e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return ok ? 0 : -1;
369e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
370e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
371e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic int
372e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_stir(void)
373e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
374e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int     i;
375e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
376e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!rs_initialized) {
377e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_init();
378e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		rs_initialized = 1;
379e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
380e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
381e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_seed();
382e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!arc4_seeded_ok)
383e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return -1;
384e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
385e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/*
386e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * Discard early keystream, as per recommendations in
387e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * "Weaknesses in the Key Scheduling Algorithm of RC4" by
388e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * Scott Fluhrer, Itsik Mantin, and Adi Shamir.
389e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
390e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
391e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that
392e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * we drop at least 2*256 bytes, with 12*256 as a conservative
393e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * value.
394e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
395e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * RFC4345 says to drop 6*256.
396e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
397e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * At least some versions of this code drop 4*256, in a mistaken
398e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * belief that "words" in the Fluhrer/Mantin/Shamir paper refers
399e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * to processor words.
400e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 *
401e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * We add another sect to the cargo cult, and choose 12*256.
402e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
403e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (i = 0; i < 12*256; i++)
404e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		(void)arc4_getbyte();
405e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
406e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_count = BYTES_BEFORE_RESEED;
407e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
408e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return 0;
409e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
410e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
411e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
412e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic void
413e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_stir_if_needed(void)
414e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
415e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	pid_t pid = getpid();
416e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
417e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid)
418e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	{
419e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_stir_pid = pid;
420e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_stir();
421e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
422e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
423e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
424e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline unsigned char
425e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_getbyte(void)
426e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
427e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char si, sj;
428e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
429e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.i = (rs.i + 1);
430e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	si = rs.s[rs.i];
431e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.j = (rs.j + si);
432e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	sj = rs.s[rs.j];
433e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.s[rs.i] = sj;
434e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	rs.s[rs.j] = si;
435e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return (rs.s[(si + sj) & 0xff]);
436e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
437e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
438e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileystatic inline unsigned int
439e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4_getword(void)
440e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
441e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned int val;
442e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
443e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val = arc4_getbyte() << 24;
444e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val |= arc4_getbyte() << 16;
445e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val |= arc4_getbyte() << 8;
446e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val |= arc4_getbyte();
447e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
448e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return val;
449e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
450e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
451e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_NOSTIR
452e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyARC4RANDOM_EXPORT int
453e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4random_stir(void)
454e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
455e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int val;
456e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_LOCK();
457e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val = arc4_stir();
458e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_UNLOCK();
459e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return val;
460e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
461e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
462e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
463e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_NOADDRANDOM
464e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyARC4RANDOM_EXPORT void
465e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4random_addrandom(const unsigned char *dat, int datlen)
466e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
467e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	int j;
468e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_LOCK();
469e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (!rs_initialized)
470e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_stir();
471e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (j = 0; j < datlen; j += 256) {
472e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* arc4_addrandom() ignores all but the first 256 bytes of
473e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		 * its input.  We want to make sure to look at ALL the
474e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		 * data in 'dat', just in case the user is doing something
475e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		 * crazy like passing us all the files in /var/log. */
476e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		arc4_addrandom(dat + j, datlen - j);
477e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
478e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_UNLOCK();
479e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
480e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
481e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
482e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_NORANDOM
483e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyARC4RANDOM_EXPORT ARC4RANDOM_UINT32
484e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4random(void)
485e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
486e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ARC4RANDOM_UINT32 val;
487e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_LOCK();
488e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_count -= 4;
489e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_stir_if_needed();
490e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	val = arc4_getword();
491e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_UNLOCK();
492e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return val;
493e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
494e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
495e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
496e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyARC4RANDOM_EXPORT void
497e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4random_buf(void *_buf, size_t n)
498e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
499e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	unsigned char *buf = _buf;
500e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_LOCK();
501e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	arc4_stir_if_needed();
502e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	while (n--) {
503e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (--arc4_count <= 0)
504e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			arc4_stir();
505e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		buf[n] = arc4_getbyte();
506e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
507e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	_ARC4_UNLOCK();
508e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
509e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
510e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#ifndef ARC4RANDOM_NOUNIFORM
511e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley/*
512e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Calculate a uniformly distributed random number less than upper_bound
513e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * avoiding "modulo bias".
514e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley *
515e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * Uniformity is achieved by generating new random numbers until the one
516e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * returned is outside the range [0, 2**32 % upper_bound).  This
517e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * guarantees the selected random number will be inside
518e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
519e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley * after reduction modulo upper_bound.
520e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley */
521e867981d427db5e0b860d67485838e1f9e8c37daChristopher WileyARC4RANDOM_EXPORT unsigned int
522e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wileyarc4random_uniform(unsigned int upper_bound)
523e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley{
524e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	ARC4RANDOM_UINT32 r, min;
525e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
526e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (upper_bound < 2)
527e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		return 0;
528e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
529e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#if (UINT_MAX > 0xffffffffUL)
530e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	min = 0x100000000UL % upper_bound;
531e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#else
532e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/* Calculate (2**32 % upper_bound) avoiding 64-bit math */
533e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	if (upper_bound > 0x80000000)
534e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		min = 1 + ~upper_bound;		/* 2**32 - upper_bound */
535e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	else {
536e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		/* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
537e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
538e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
539e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
540e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
541e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	/*
542e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * This could theoretically loop forever but each retry has
543e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * p > 0.5 (worst case, usually far better) of selecting a
544e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * number inside the range we need, so it should rarely need
545e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 * to re-roll.
546e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	 */
547e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	for (;;) {
548e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		r = arc4random();
549e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley		if (r >= min)
550e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley			break;
551e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	}
552e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley
553e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley	return r % upper_bound;
554e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley}
555e867981d427db5e0b860d67485838e1f9e8c37daChristopher Wiley#endif
556