1/* 2 * Copyright (c) 1999,2000,2004 Damien Miller <djm@mindrot.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "includes.h" 18 19#include <sys/types.h> 20 21#include <string.h> 22#include <stdlib.h> 23#include <stdarg.h> 24 25#include "log.h" 26 27#ifndef HAVE_ARC4RANDOM 28 29#ifdef __APPLE_CRYPTO__ 30#include "ossl-rand.h" 31#include "ossl-rc4.h" 32#include "ossl-err.h" 33#else 34#include <openssl/rand.h> 35#include <openssl/rc4.h> 36#include <openssl/err.h> 37#endif 38 39/* Size of key to use */ 40#define SEED_SIZE 20 41 42/* Number of bytes to reseed after */ 43#define REKEY_BYTES (1 << 24) 44 45static int rc4_ready = 0; 46static RC4_KEY rc4; 47 48unsigned int 49arc4random(void) 50{ 51 unsigned int r = 0; 52 static int first_time = 1; 53 54 if (rc4_ready <= 0) { 55 if (first_time) 56 seed_rng(); 57 first_time = 0; 58 arc4random_stir(); 59 } 60 61 RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); 62 63 rc4_ready -= sizeof(r); 64 65 return(r); 66} 67 68void 69arc4random_stir(void) 70{ 71 unsigned char rand_buf[SEED_SIZE]; 72 int i; 73 74 memset(&rc4, 0, sizeof(rc4)); 75 if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) 76 fatal("Couldn't obtain random bytes (error %ld)", 77 ERR_get_error()); 78 RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); 79 80 /* 81 * Discard early keystream, as per recommendations in: 82 * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps 83 */ 84 for(i = 0; i <= 256; i += sizeof(rand_buf)) 85 RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); 86 87 memset(rand_buf, 0, sizeof(rand_buf)); 88 89 rc4_ready = REKEY_BYTES; 90} 91#endif /* !HAVE_ARC4RANDOM */ 92 93#ifndef HAVE_ARC4RANDOM_BUF 94void 95arc4random_buf(void *_buf, size_t n) 96{ 97 size_t i; 98 u_int32_t r = 0; 99 char *buf = (char *)_buf; 100 101 for (i = 0; i < n; i++) { 102 if (i % 4 == 0) 103 r = arc4random(); 104 buf[i] = r & 0xff; 105 r >>= 8; 106 } 107 i = r = 0; 108} 109#endif /* !HAVE_ARC4RANDOM_BUF */ 110 111#ifndef HAVE_ARC4RANDOM_UNIFORM 112/* 113 * Calculate a uniformly distributed random number less than upper_bound 114 * avoiding "modulo bias". 115 * 116 * Uniformity is achieved by generating new random numbers until the one 117 * returned is outside the range [0, 2**32 % upper_bound). This 118 * guarantees the selected random number will be inside 119 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) 120 * after reduction modulo upper_bound. 121 */ 122u_int32_t 123arc4random_uniform(u_int32_t upper_bound) 124{ 125 u_int32_t r, min; 126 127 if (upper_bound < 2) 128 return 0; 129 130#if (ULONG_MAX > 0xffffffffUL) 131 min = 0x100000000UL % upper_bound; 132#else 133 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ 134 if (upper_bound > 0x80000000) 135 min = 1 + ~upper_bound; /* 2**32 - upper_bound */ 136 else { 137 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ 138 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; 139 } 140#endif 141 142 /* 143 * This could theoretically loop forever but each retry has 144 * p > 0.5 (worst case, usually far better) of selecting a 145 * number inside the range we need, so it should rarely need 146 * to re-roll. 147 */ 148 for (;;) { 149 r = arc4random(); 150 if (r >= min) 151 break; 152 } 153 154 return r % upper_bound; 155} 156#endif /* !HAVE_ARC4RANDOM_UNIFORM */ 157