12b15cb3dSCy Schubert /* Portable arc4random.c based on arc4random.c from OpenBSD.
22b15cb3dSCy Schubert * Portable version by Chris Davis, adapted for Libevent by Nick Mathewson
32b15cb3dSCy Schubert * Copyright (c) 2010 Chris Davis, Niels Provos, and Nick Mathewson
42b15cb3dSCy Schubert * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson
52b15cb3dSCy Schubert *
62b15cb3dSCy Schubert * Note that in Libevent, this file isn't compiled directly. Instead,
72b15cb3dSCy Schubert * it's included from evutil_rand.c
82b15cb3dSCy Schubert */
92b15cb3dSCy Schubert
102b15cb3dSCy Schubert /*
112b15cb3dSCy Schubert * Copyright (c) 1996, David Mazieres <dm@uun.org>
122b15cb3dSCy Schubert * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
132b15cb3dSCy Schubert *
142b15cb3dSCy Schubert * Permission to use, copy, modify, and distribute this software for any
152b15cb3dSCy Schubert * purpose with or without fee is hereby granted, provided that the above
162b15cb3dSCy Schubert * copyright notice and this permission notice appear in all copies.
172b15cb3dSCy Schubert *
182b15cb3dSCy Schubert * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
192b15cb3dSCy Schubert * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
202b15cb3dSCy Schubert * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
212b15cb3dSCy Schubert * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
222b15cb3dSCy Schubert * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
232b15cb3dSCy Schubert * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
242b15cb3dSCy Schubert * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
252b15cb3dSCy Schubert */
262b15cb3dSCy Schubert
272b15cb3dSCy Schubert /*
282b15cb3dSCy Schubert * Arc4 random number generator for OpenBSD.
292b15cb3dSCy Schubert *
302b15cb3dSCy Schubert * This code is derived from section 17.1 of Applied Cryptography,
312b15cb3dSCy Schubert * second edition, which describes a stream cipher allegedly
322b15cb3dSCy Schubert * compatible with RSA Labs "RC4" cipher (the actual description of
332b15cb3dSCy Schubert * which is a trade secret). The same algorithm is used as a stream
342b15cb3dSCy Schubert * cipher called "arcfour" in Tatu Ylonen's ssh package.
352b15cb3dSCy Schubert *
362b15cb3dSCy Schubert * Here the stream cipher has been modified always to include the time
372b15cb3dSCy Schubert * when initializing the state. That makes it impossible to
382b15cb3dSCy Schubert * regenerate the same random sequence twice, so this can't be used
392b15cb3dSCy Schubert * for encryption, but will generate good random numbers.
402b15cb3dSCy Schubert *
412b15cb3dSCy Schubert * RC4 is a registered trademark of RSA Laboratories.
422b15cb3dSCy Schubert */
432b15cb3dSCy Schubert
442b15cb3dSCy Schubert #ifndef ARC4RANDOM_EXPORT
452b15cb3dSCy Schubert #define ARC4RANDOM_EXPORT
462b15cb3dSCy Schubert #endif
472b15cb3dSCy Schubert
482b15cb3dSCy Schubert #ifndef ARC4RANDOM_UINT32
492b15cb3dSCy Schubert #define ARC4RANDOM_UINT32 uint32_t
502b15cb3dSCy Schubert #endif
512b15cb3dSCy Schubert
522b15cb3dSCy Schubert #ifndef ARC4RANDOM_NO_INCLUDES
532b15cb3dSCy Schubert #include "evconfig-private.h"
542b15cb3dSCy Schubert #ifdef _WIN32
552b15cb3dSCy Schubert #include <wincrypt.h>
562b15cb3dSCy Schubert #include <process.h>
57*a466cc55SCy Schubert #include <winerror.h>
582b15cb3dSCy Schubert #else
592b15cb3dSCy Schubert #include <fcntl.h>
602b15cb3dSCy Schubert #include <unistd.h>
612b15cb3dSCy Schubert #include <sys/param.h>
622b15cb3dSCy Schubert #include <sys/time.h>
632b15cb3dSCy Schubert #ifdef EVENT__HAVE_SYS_SYSCTL_H
642b15cb3dSCy Schubert #include <sys/sysctl.h>
652b15cb3dSCy Schubert #endif
66*a466cc55SCy Schubert #ifdef EVENT__HAVE_SYS_RANDOM_H
67*a466cc55SCy Schubert #include <sys/random.h>
68*a466cc55SCy Schubert #endif
692b15cb3dSCy Schubert #endif
702b15cb3dSCy Schubert #include <limits.h>
712b15cb3dSCy Schubert #include <stdlib.h>
722b15cb3dSCy Schubert #include <string.h>
732b15cb3dSCy Schubert #endif
742b15cb3dSCy Schubert
752b15cb3dSCy Schubert /* Add platform entropy 32 bytes (256 bits) at a time. */
762b15cb3dSCy Schubert #define ADD_ENTROPY 32
772b15cb3dSCy Schubert
782b15cb3dSCy Schubert /* Re-seed from the platform RNG after generating this many bytes. */
792b15cb3dSCy Schubert #define BYTES_BEFORE_RESEED 1600000
802b15cb3dSCy Schubert
812b15cb3dSCy Schubert struct arc4_stream {
822b15cb3dSCy Schubert unsigned char i;
832b15cb3dSCy Schubert unsigned char j;
842b15cb3dSCy Schubert unsigned char s[256];
852b15cb3dSCy Schubert };
862b15cb3dSCy Schubert
872b15cb3dSCy Schubert #ifdef _WIN32
882b15cb3dSCy Schubert #define getpid _getpid
892b15cb3dSCy Schubert #define pid_t int
902b15cb3dSCy Schubert #endif
912b15cb3dSCy Schubert
922b15cb3dSCy Schubert static int rs_initialized;
932b15cb3dSCy Schubert static struct arc4_stream rs;
942b15cb3dSCy Schubert static pid_t arc4_stir_pid;
952b15cb3dSCy Schubert static int arc4_count;
962b15cb3dSCy Schubert
972b15cb3dSCy Schubert static inline unsigned char arc4_getbyte(void);
982b15cb3dSCy Schubert
992b15cb3dSCy Schubert static inline void
arc4_init(void)1002b15cb3dSCy Schubert arc4_init(void)
1012b15cb3dSCy Schubert {
1022b15cb3dSCy Schubert int n;
1032b15cb3dSCy Schubert
1042b15cb3dSCy Schubert for (n = 0; n < 256; n++)
1052b15cb3dSCy Schubert rs.s[n] = n;
1062b15cb3dSCy Schubert rs.i = 0;
1072b15cb3dSCy Schubert rs.j = 0;
1082b15cb3dSCy Schubert }
1092b15cb3dSCy Schubert
1102b15cb3dSCy Schubert static inline void
arc4_addrandom(const unsigned char * dat,int datlen)1112b15cb3dSCy Schubert arc4_addrandom(const unsigned char *dat, int datlen)
1122b15cb3dSCy Schubert {
1132b15cb3dSCy Schubert int n;
1142b15cb3dSCy Schubert unsigned char si;
1152b15cb3dSCy Schubert
1162b15cb3dSCy Schubert rs.i--;
1172b15cb3dSCy Schubert for (n = 0; n < 256; n++) {
1182b15cb3dSCy Schubert rs.i = (rs.i + 1);
1192b15cb3dSCy Schubert si = rs.s[rs.i];
1202b15cb3dSCy Schubert rs.j = (rs.j + si + dat[n % datlen]);
1212b15cb3dSCy Schubert rs.s[rs.i] = rs.s[rs.j];
1222b15cb3dSCy Schubert rs.s[rs.j] = si;
1232b15cb3dSCy Schubert }
1242b15cb3dSCy Schubert rs.j = rs.i;
1252b15cb3dSCy Schubert }
1262b15cb3dSCy Schubert
1272b15cb3dSCy Schubert #ifndef _WIN32
1282b15cb3dSCy Schubert static ssize_t
read_all(int fd,unsigned char * buf,size_t count)1292b15cb3dSCy Schubert read_all(int fd, unsigned char *buf, size_t count)
1302b15cb3dSCy Schubert {
1312b15cb3dSCy Schubert size_t numread = 0;
1322b15cb3dSCy Schubert ssize_t result;
1332b15cb3dSCy Schubert
1342b15cb3dSCy Schubert while (numread < count) {
1352b15cb3dSCy Schubert result = read(fd, buf+numread, count-numread);
1362b15cb3dSCy Schubert if (result<0)
1372b15cb3dSCy Schubert return -1;
1382b15cb3dSCy Schubert else if (result == 0)
1392b15cb3dSCy Schubert break;
1402b15cb3dSCy Schubert numread += result;
1412b15cb3dSCy Schubert }
1422b15cb3dSCy Schubert
1432b15cb3dSCy Schubert return (ssize_t)numread;
1442b15cb3dSCy Schubert }
1452b15cb3dSCy Schubert #endif
1462b15cb3dSCy Schubert
1472b15cb3dSCy Schubert #ifdef _WIN32
1482b15cb3dSCy Schubert #define TRY_SEED_WIN32
1492b15cb3dSCy Schubert static int
arc4_seed_win32(void)1502b15cb3dSCy Schubert arc4_seed_win32(void)
1512b15cb3dSCy Schubert {
1522b15cb3dSCy Schubert /* This is adapted from Tor's crypto_seed_rng() */
1532b15cb3dSCy Schubert static int provider_set = 0;
1542b15cb3dSCy Schubert static HCRYPTPROV provider;
1552b15cb3dSCy Schubert unsigned char buf[ADD_ENTROPY];
1562b15cb3dSCy Schubert
1572b15cb3dSCy Schubert if (!provider_set) {
1582b15cb3dSCy Schubert if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
1592b15cb3dSCy Schubert CRYPT_VERIFYCONTEXT)) {
1602b15cb3dSCy Schubert if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
1612b15cb3dSCy Schubert return -1;
1622b15cb3dSCy Schubert }
1632b15cb3dSCy Schubert provider_set = 1;
1642b15cb3dSCy Schubert }
1652b15cb3dSCy Schubert if (!CryptGenRandom(provider, sizeof(buf), buf))
1662b15cb3dSCy Schubert return -1;
1672b15cb3dSCy Schubert arc4_addrandom(buf, sizeof(buf));
1682b15cb3dSCy Schubert evutil_memclear_(buf, sizeof(buf));
1692b15cb3dSCy Schubert return 0;
1702b15cb3dSCy Schubert }
1712b15cb3dSCy Schubert #endif
1722b15cb3dSCy Schubert
173*a466cc55SCy Schubert #if defined(EVENT__HAVE_GETRANDOM)
174*a466cc55SCy Schubert #define TRY_SEED_GETRANDOM
1752b15cb3dSCy Schubert static int
arc4_seed_getrandom(void)176*a466cc55SCy Schubert arc4_seed_getrandom(void)
1772b15cb3dSCy Schubert {
1782b15cb3dSCy Schubert unsigned char buf[ADD_ENTROPY];
1792b15cb3dSCy Schubert size_t len, n;
1802b15cb3dSCy Schubert unsigned i;
1812b15cb3dSCy Schubert int any_set;
1822b15cb3dSCy Schubert
1832b15cb3dSCy Schubert memset(buf, 0, sizeof(buf));
1842b15cb3dSCy Schubert
1852b15cb3dSCy Schubert for (len = 0; len < sizeof(buf); len += n) {
1862b15cb3dSCy Schubert n = sizeof(buf) - len;
1872b15cb3dSCy Schubert
188*a466cc55SCy Schubert if (0 == getrandom(&buf[len], n, 0))
1892b15cb3dSCy Schubert return -1;
1902b15cb3dSCy Schubert }
1912b15cb3dSCy Schubert /* make sure that the buffer actually got set. */
1922b15cb3dSCy Schubert for (i=0,any_set=0; i<sizeof(buf); ++i) {
1932b15cb3dSCy Schubert any_set |= buf[i];
1942b15cb3dSCy Schubert }
1952b15cb3dSCy Schubert if (!any_set)
1962b15cb3dSCy Schubert return -1;
1972b15cb3dSCy Schubert
1982b15cb3dSCy Schubert arc4_addrandom(buf, sizeof(buf));
1992b15cb3dSCy Schubert evutil_memclear_(buf, sizeof(buf));
2002b15cb3dSCy Schubert return 0;
2012b15cb3dSCy Schubert }
202*a466cc55SCy Schubert #endif /* EVENT__HAVE_GETRANDOM */
2032b15cb3dSCy Schubert
204*a466cc55SCy Schubert #if defined(EVENT__HAVE_SYS_SYSCTL_H) && defined(EVENT__HAVE_SYSCTL)
2052b15cb3dSCy Schubert #if EVENT__HAVE_DECL_CTL_KERN && EVENT__HAVE_DECL_KERN_ARND
2062b15cb3dSCy Schubert #define TRY_SEED_SYSCTL_BSD
2072b15cb3dSCy Schubert static int
arc4_seed_sysctl_bsd(void)2082b15cb3dSCy Schubert arc4_seed_sysctl_bsd(void)
2092b15cb3dSCy Schubert {
2102b15cb3dSCy Schubert /* Based on code from William Ahern and from OpenBSD, this function
2112b15cb3dSCy Schubert * tries to use the KERN_ARND syscall to get entropy from the kernel.
2122b15cb3dSCy Schubert * This can work even if /dev/urandom is inaccessible for some reason
2132b15cb3dSCy Schubert * (e.g., we're running in a chroot). */
2142b15cb3dSCy Schubert int mib[] = { CTL_KERN, KERN_ARND };
2152b15cb3dSCy Schubert unsigned char buf[ADD_ENTROPY];
2162b15cb3dSCy Schubert size_t len, n;
2172b15cb3dSCy Schubert int i, any_set;
2182b15cb3dSCy Schubert
2192b15cb3dSCy Schubert memset(buf, 0, sizeof(buf));
2202b15cb3dSCy Schubert
2212b15cb3dSCy Schubert len = sizeof(buf);
2222b15cb3dSCy Schubert if (sysctl(mib, 2, buf, &len, NULL, 0) == -1) {
2232b15cb3dSCy Schubert for (len = 0; len < sizeof(buf); len += sizeof(unsigned)) {
2242b15cb3dSCy Schubert n = sizeof(unsigned);
2252b15cb3dSCy Schubert if (n + len > sizeof(buf))
2262b15cb3dSCy Schubert n = len - sizeof(buf);
2272b15cb3dSCy Schubert if (sysctl(mib, 2, &buf[len], &n, NULL, 0) == -1)
2282b15cb3dSCy Schubert return -1;
2292b15cb3dSCy Schubert }
2302b15cb3dSCy Schubert }
2312b15cb3dSCy Schubert /* make sure that the buffer actually got set. */
2322b15cb3dSCy Schubert for (i=any_set=0; i<sizeof(buf); ++i) {
2332b15cb3dSCy Schubert any_set |= buf[i];
2342b15cb3dSCy Schubert }
2352b15cb3dSCy Schubert if (!any_set)
2362b15cb3dSCy Schubert return -1;
2372b15cb3dSCy Schubert
2382b15cb3dSCy Schubert arc4_addrandom(buf, sizeof(buf));
2392b15cb3dSCy Schubert evutil_memclear_(buf, sizeof(buf));
2402b15cb3dSCy Schubert return 0;
2412b15cb3dSCy Schubert }
2422b15cb3dSCy Schubert #endif
2432b15cb3dSCy Schubert #endif /* defined(EVENT__HAVE_SYS_SYSCTL_H) */
2442b15cb3dSCy Schubert
2452b15cb3dSCy Schubert #ifdef __linux__
2462b15cb3dSCy Schubert #define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
2472b15cb3dSCy Schubert static int
arc4_seed_proc_sys_kernel_random_uuid(void)2482b15cb3dSCy Schubert arc4_seed_proc_sys_kernel_random_uuid(void)
2492b15cb3dSCy Schubert {
2502b15cb3dSCy Schubert /* Occasionally, somebody will make /proc/sys accessible in a chroot,
2512b15cb3dSCy Schubert * but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid.
2522b15cb3dSCy Schubert * Its format is stupid, so we need to decode it from hex.
2532b15cb3dSCy Schubert */
2542b15cb3dSCy Schubert int fd;
2552b15cb3dSCy Schubert char buf[128];
2562b15cb3dSCy Schubert unsigned char entropy[64];
2572b15cb3dSCy Schubert int bytes, n, i, nybbles;
2582b15cb3dSCy Schubert for (bytes = 0; bytes<ADD_ENTROPY; ) {
2592b15cb3dSCy Schubert fd = evutil_open_closeonexec_("/proc/sys/kernel/random/uuid", O_RDONLY, 0);
2602b15cb3dSCy Schubert if (fd < 0)
2612b15cb3dSCy Schubert return -1;
2622b15cb3dSCy Schubert n = read(fd, buf, sizeof(buf));
2632b15cb3dSCy Schubert close(fd);
2642b15cb3dSCy Schubert if (n<=0)
2652b15cb3dSCy Schubert return -1;
2662b15cb3dSCy Schubert memset(entropy, 0, sizeof(entropy));
2672b15cb3dSCy Schubert for (i=nybbles=0; i<n; ++i) {
2682b15cb3dSCy Schubert if (EVUTIL_ISXDIGIT_(buf[i])) {
2692b15cb3dSCy Schubert int nyb = evutil_hex_char_to_int_(buf[i]);
2702b15cb3dSCy Schubert if (nybbles & 1) {
2712b15cb3dSCy Schubert entropy[nybbles/2] |= nyb;
2722b15cb3dSCy Schubert } else {
2732b15cb3dSCy Schubert entropy[nybbles/2] |= nyb<<4;
2742b15cb3dSCy Schubert }
2752b15cb3dSCy Schubert ++nybbles;
2762b15cb3dSCy Schubert }
2772b15cb3dSCy Schubert }
2782b15cb3dSCy Schubert if (nybbles < 2)
2792b15cb3dSCy Schubert return -1;
2802b15cb3dSCy Schubert arc4_addrandom(entropy, nybbles/2);
2812b15cb3dSCy Schubert bytes += nybbles/2;
2822b15cb3dSCy Schubert }
2832b15cb3dSCy Schubert evutil_memclear_(entropy, sizeof(entropy));
2842b15cb3dSCy Schubert evutil_memclear_(buf, sizeof(buf));
2852b15cb3dSCy Schubert return 0;
2862b15cb3dSCy Schubert }
2872b15cb3dSCy Schubert #endif
2882b15cb3dSCy Schubert
2892b15cb3dSCy Schubert #ifndef _WIN32
2902b15cb3dSCy Schubert #define TRY_SEED_URANDOM
2912b15cb3dSCy Schubert static char *arc4random_urandom_filename = NULL;
2922b15cb3dSCy Schubert
arc4_seed_urandom_helper_(const char * fname)2932b15cb3dSCy Schubert static int arc4_seed_urandom_helper_(const char *fname)
2942b15cb3dSCy Schubert {
2952b15cb3dSCy Schubert unsigned char buf[ADD_ENTROPY];
2962b15cb3dSCy Schubert int fd;
2972b15cb3dSCy Schubert size_t n;
2982b15cb3dSCy Schubert
2992b15cb3dSCy Schubert fd = evutil_open_closeonexec_(fname, O_RDONLY, 0);
3002b15cb3dSCy Schubert if (fd<0)
3012b15cb3dSCy Schubert return -1;
3022b15cb3dSCy Schubert n = read_all(fd, buf, sizeof(buf));
3032b15cb3dSCy Schubert close(fd);
3042b15cb3dSCy Schubert if (n != sizeof(buf))
3052b15cb3dSCy Schubert return -1;
3062b15cb3dSCy Schubert arc4_addrandom(buf, sizeof(buf));
3072b15cb3dSCy Schubert evutil_memclear_(buf, sizeof(buf));
3082b15cb3dSCy Schubert return 0;
3092b15cb3dSCy Schubert }
3102b15cb3dSCy Schubert
3112b15cb3dSCy Schubert static int
arc4_seed_urandom(void)3122b15cb3dSCy Schubert arc4_seed_urandom(void)
3132b15cb3dSCy Schubert {
3142b15cb3dSCy Schubert /* This is adapted from Tor's crypto_seed_rng() */
3152b15cb3dSCy Schubert static const char *filenames[] = {
3162b15cb3dSCy Schubert "/dev/srandom", "/dev/urandom", "/dev/random", NULL
3172b15cb3dSCy Schubert };
3182b15cb3dSCy Schubert int i;
3192b15cb3dSCy Schubert if (arc4random_urandom_filename)
3202b15cb3dSCy Schubert return arc4_seed_urandom_helper_(arc4random_urandom_filename);
3212b15cb3dSCy Schubert
3222b15cb3dSCy Schubert for (i = 0; filenames[i]; ++i) {
3232b15cb3dSCy Schubert if (arc4_seed_urandom_helper_(filenames[i]) == 0) {
3242b15cb3dSCy Schubert return 0;
3252b15cb3dSCy Schubert }
3262b15cb3dSCy Schubert }
3272b15cb3dSCy Schubert
3282b15cb3dSCy Schubert return -1;
3292b15cb3dSCy Schubert }
3302b15cb3dSCy Schubert #endif
3312b15cb3dSCy Schubert
3322b15cb3dSCy Schubert static int
arc4_seed(void)3332b15cb3dSCy Schubert arc4_seed(void)
3342b15cb3dSCy Schubert {
3352b15cb3dSCy Schubert int ok = 0;
3362b15cb3dSCy Schubert /* We try every method that might work, and don't give up even if one
3372b15cb3dSCy Schubert * does seem to work. There's no real harm in over-seeding, and if
3382b15cb3dSCy Schubert * one of these sources turns out to be broken, that would be bad. */
3392b15cb3dSCy Schubert #ifdef TRY_SEED_WIN32
3402b15cb3dSCy Schubert if (0 == arc4_seed_win32())
3412b15cb3dSCy Schubert ok = 1;
3422b15cb3dSCy Schubert #endif
343*a466cc55SCy Schubert #ifdef TRY_SEED_GETRANDOM
344*a466cc55SCy Schubert if (0 == arc4_seed_getrandom())
345*a466cc55SCy Schubert ok = 1;
346*a466cc55SCy Schubert #endif
3472b15cb3dSCy Schubert #ifdef TRY_SEED_URANDOM
3482b15cb3dSCy Schubert if (0 == arc4_seed_urandom())
3492b15cb3dSCy Schubert ok = 1;
3502b15cb3dSCy Schubert #endif
3512b15cb3dSCy Schubert #ifdef TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID
3522b15cb3dSCy Schubert if (arc4random_urandom_filename == NULL &&
3532b15cb3dSCy Schubert 0 == arc4_seed_proc_sys_kernel_random_uuid())
3542b15cb3dSCy Schubert ok = 1;
3552b15cb3dSCy Schubert #endif
3562b15cb3dSCy Schubert #ifdef TRY_SEED_SYSCTL_BSD
3572b15cb3dSCy Schubert if (0 == arc4_seed_sysctl_bsd())
3582b15cb3dSCy Schubert ok = 1;
3592b15cb3dSCy Schubert #endif
3602b15cb3dSCy Schubert return ok ? 0 : -1;
3612b15cb3dSCy Schubert }
3622b15cb3dSCy Schubert
3632b15cb3dSCy Schubert static int
arc4_stir(void)3642b15cb3dSCy Schubert arc4_stir(void)
3652b15cb3dSCy Schubert {
3662b15cb3dSCy Schubert int i;
3672b15cb3dSCy Schubert
3682b15cb3dSCy Schubert if (!rs_initialized) {
3692b15cb3dSCy Schubert arc4_init();
3702b15cb3dSCy Schubert rs_initialized = 1;
3712b15cb3dSCy Schubert }
3722b15cb3dSCy Schubert
373*a466cc55SCy Schubert if (0 != arc4_seed())
3742b15cb3dSCy Schubert return -1;
3752b15cb3dSCy Schubert
3762b15cb3dSCy Schubert /*
3772b15cb3dSCy Schubert * Discard early keystream, as per recommendations in
3782b15cb3dSCy Schubert * "Weaknesses in the Key Scheduling Algorithm of RC4" by
3792b15cb3dSCy Schubert * Scott Fluhrer, Itsik Mantin, and Adi Shamir.
3802b15cb3dSCy Schubert * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
3812b15cb3dSCy Schubert *
3822b15cb3dSCy Schubert * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that
3832b15cb3dSCy Schubert * we drop at least 2*256 bytes, with 12*256 as a conservative
3842b15cb3dSCy Schubert * value.
3852b15cb3dSCy Schubert *
3862b15cb3dSCy Schubert * RFC4345 says to drop 6*256.
3872b15cb3dSCy Schubert *
3882b15cb3dSCy Schubert * At least some versions of this code drop 4*256, in a mistaken
3892b15cb3dSCy Schubert * belief that "words" in the Fluhrer/Mantin/Shamir paper refers
3902b15cb3dSCy Schubert * to processor words.
3912b15cb3dSCy Schubert *
3922b15cb3dSCy Schubert * We add another sect to the cargo cult, and choose 12*256.
3932b15cb3dSCy Schubert */
3942b15cb3dSCy Schubert for (i = 0; i < 12*256; i++)
3952b15cb3dSCy Schubert (void)arc4_getbyte();
3962b15cb3dSCy Schubert
3972b15cb3dSCy Schubert arc4_count = BYTES_BEFORE_RESEED;
3982b15cb3dSCy Schubert
3992b15cb3dSCy Schubert return 0;
4002b15cb3dSCy Schubert }
4012b15cb3dSCy Schubert
4022b15cb3dSCy Schubert
4032b15cb3dSCy Schubert static void
arc4_stir_if_needed(void)4042b15cb3dSCy Schubert arc4_stir_if_needed(void)
4052b15cb3dSCy Schubert {
4062b15cb3dSCy Schubert pid_t pid = getpid();
4072b15cb3dSCy Schubert
4082b15cb3dSCy Schubert if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid)
4092b15cb3dSCy Schubert {
4102b15cb3dSCy Schubert arc4_stir_pid = pid;
4112b15cb3dSCy Schubert arc4_stir();
4122b15cb3dSCy Schubert }
4132b15cb3dSCy Schubert }
4142b15cb3dSCy Schubert
4152b15cb3dSCy Schubert static inline unsigned char
arc4_getbyte(void)4162b15cb3dSCy Schubert arc4_getbyte(void)
4172b15cb3dSCy Schubert {
4182b15cb3dSCy Schubert unsigned char si, sj;
4192b15cb3dSCy Schubert
4202b15cb3dSCy Schubert rs.i = (rs.i + 1);
4212b15cb3dSCy Schubert si = rs.s[rs.i];
4222b15cb3dSCy Schubert rs.j = (rs.j + si);
4232b15cb3dSCy Schubert sj = rs.s[rs.j];
4242b15cb3dSCy Schubert rs.s[rs.i] = sj;
4252b15cb3dSCy Schubert rs.s[rs.j] = si;
4262b15cb3dSCy Schubert return (rs.s[(si + sj) & 0xff]);
4272b15cb3dSCy Schubert }
4282b15cb3dSCy Schubert
4292b15cb3dSCy Schubert static inline unsigned int
arc4_getword(void)4302b15cb3dSCy Schubert arc4_getword(void)
4312b15cb3dSCy Schubert {
4322b15cb3dSCy Schubert unsigned int val;
4332b15cb3dSCy Schubert
4342b15cb3dSCy Schubert val = arc4_getbyte() << 24;
4352b15cb3dSCy Schubert val |= arc4_getbyte() << 16;
4362b15cb3dSCy Schubert val |= arc4_getbyte() << 8;
4372b15cb3dSCy Schubert val |= arc4_getbyte();
4382b15cb3dSCy Schubert
4392b15cb3dSCy Schubert return val;
4402b15cb3dSCy Schubert }
4412b15cb3dSCy Schubert
4422b15cb3dSCy Schubert #ifndef ARC4RANDOM_NOSTIR
4432b15cb3dSCy Schubert ARC4RANDOM_EXPORT int
arc4random_stir(void)4442b15cb3dSCy Schubert arc4random_stir(void)
4452b15cb3dSCy Schubert {
4462b15cb3dSCy Schubert int val;
4472b15cb3dSCy Schubert ARC4_LOCK_();
4482b15cb3dSCy Schubert val = arc4_stir();
4492b15cb3dSCy Schubert ARC4_UNLOCK_();
4502b15cb3dSCy Schubert return val;
4512b15cb3dSCy Schubert }
4522b15cb3dSCy Schubert #endif
4532b15cb3dSCy Schubert
4542b15cb3dSCy Schubert #ifndef ARC4RANDOM_NOADDRANDOM
4552b15cb3dSCy Schubert ARC4RANDOM_EXPORT void
arc4random_addrandom(const unsigned char * dat,int datlen)4562b15cb3dSCy Schubert arc4random_addrandom(const unsigned char *dat, int datlen)
4572b15cb3dSCy Schubert {
4582b15cb3dSCy Schubert int j;
4592b15cb3dSCy Schubert ARC4_LOCK_();
4602b15cb3dSCy Schubert if (!rs_initialized)
4612b15cb3dSCy Schubert arc4_stir();
4622b15cb3dSCy Schubert for (j = 0; j < datlen; j += 256) {
4632b15cb3dSCy Schubert /* arc4_addrandom() ignores all but the first 256 bytes of
4642b15cb3dSCy Schubert * its input. We want to make sure to look at ALL the
4652b15cb3dSCy Schubert * data in 'dat', just in case the user is doing something
4662b15cb3dSCy Schubert * crazy like passing us all the files in /var/log. */
4672b15cb3dSCy Schubert arc4_addrandom(dat + j, datlen - j);
4682b15cb3dSCy Schubert }
4692b15cb3dSCy Schubert ARC4_UNLOCK_();
4702b15cb3dSCy Schubert }
4712b15cb3dSCy Schubert #endif
4722b15cb3dSCy Schubert
4732b15cb3dSCy Schubert #ifndef ARC4RANDOM_NORANDOM
4742b15cb3dSCy Schubert ARC4RANDOM_EXPORT ARC4RANDOM_UINT32
arc4random(void)4752b15cb3dSCy Schubert arc4random(void)
4762b15cb3dSCy Schubert {
4772b15cb3dSCy Schubert ARC4RANDOM_UINT32 val;
4782b15cb3dSCy Schubert ARC4_LOCK_();
4792b15cb3dSCy Schubert arc4_count -= 4;
4802b15cb3dSCy Schubert arc4_stir_if_needed();
4812b15cb3dSCy Schubert val = arc4_getword();
4822b15cb3dSCy Schubert ARC4_UNLOCK_();
4832b15cb3dSCy Schubert return val;
4842b15cb3dSCy Schubert }
4852b15cb3dSCy Schubert #endif
4862b15cb3dSCy Schubert
4872b15cb3dSCy Schubert ARC4RANDOM_EXPORT void
arc4random_buf(void * buf_,size_t n)4882b15cb3dSCy Schubert arc4random_buf(void *buf_, size_t n)
4892b15cb3dSCy Schubert {
4902b15cb3dSCy Schubert unsigned char *buf = buf_;
4912b15cb3dSCy Schubert ARC4_LOCK_();
4922b15cb3dSCy Schubert arc4_stir_if_needed();
4932b15cb3dSCy Schubert while (n--) {
4942b15cb3dSCy Schubert if (--arc4_count <= 0)
4952b15cb3dSCy Schubert arc4_stir();
4962b15cb3dSCy Schubert buf[n] = arc4_getbyte();
4972b15cb3dSCy Schubert }
4982b15cb3dSCy Schubert ARC4_UNLOCK_();
4992b15cb3dSCy Schubert }
5002b15cb3dSCy Schubert
5012b15cb3dSCy Schubert #ifndef ARC4RANDOM_NOUNIFORM
5022b15cb3dSCy Schubert /*
5032b15cb3dSCy Schubert * Calculate a uniformly distributed random number less than upper_bound
5042b15cb3dSCy Schubert * avoiding "modulo bias".
5052b15cb3dSCy Schubert *
5062b15cb3dSCy Schubert * Uniformity is achieved by generating new random numbers until the one
5072b15cb3dSCy Schubert * returned is outside the range [0, 2**32 % upper_bound). This
5082b15cb3dSCy Schubert * guarantees the selected random number will be inside
5092b15cb3dSCy Schubert * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
5102b15cb3dSCy Schubert * after reduction modulo upper_bound.
5112b15cb3dSCy Schubert */
5122b15cb3dSCy Schubert ARC4RANDOM_EXPORT unsigned int
arc4random_uniform(unsigned int upper_bound)5132b15cb3dSCy Schubert arc4random_uniform(unsigned int upper_bound)
5142b15cb3dSCy Schubert {
5152b15cb3dSCy Schubert ARC4RANDOM_UINT32 r, min;
5162b15cb3dSCy Schubert
5172b15cb3dSCy Schubert if (upper_bound < 2)
5182b15cb3dSCy Schubert return 0;
5192b15cb3dSCy Schubert
5202b15cb3dSCy Schubert #if (UINT_MAX > 0xffffffffUL)
5212b15cb3dSCy Schubert min = 0x100000000UL % upper_bound;
5222b15cb3dSCy Schubert #else
5232b15cb3dSCy Schubert /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
5242b15cb3dSCy Schubert if (upper_bound > 0x80000000)
5252b15cb3dSCy Schubert min = 1 + ~upper_bound; /* 2**32 - upper_bound */
5262b15cb3dSCy Schubert else {
5272b15cb3dSCy Schubert /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
5282b15cb3dSCy Schubert min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
5292b15cb3dSCy Schubert }
5302b15cb3dSCy Schubert #endif
5312b15cb3dSCy Schubert
5322b15cb3dSCy Schubert /*
5332b15cb3dSCy Schubert * This could theoretically loop forever but each retry has
5342b15cb3dSCy Schubert * p > 0.5 (worst case, usually far better) of selecting a
5352b15cb3dSCy Schubert * number inside the range we need, so it should rarely need
5362b15cb3dSCy Schubert * to re-roll.
5372b15cb3dSCy Schubert */
5382b15cb3dSCy Schubert for (;;) {
5392b15cb3dSCy Schubert r = arc4random();
5402b15cb3dSCy Schubert if (r >= min)
5412b15cb3dSCy Schubert break;
5422b15cb3dSCy Schubert }
5432b15cb3dSCy Schubert
5442b15cb3dSCy Schubert return r % upper_bound;
5452b15cb3dSCy Schubert }
5462b15cb3dSCy Schubert #endif
547