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