arc4random.c 12 KB

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