1*7dae1524Sriastradh /* $NetBSD: arc4random.c,v 1.38 2024/08/29 13:39:42 riastradh Exp $ */ 2e68f73c3Sitojun 30e26ad08Sriastradh /*- 40e26ad08Sriastradh * Copyright (c) 2014 The NetBSD Foundation, Inc. 50e26ad08Sriastradh * All rights reserved. 6e68f73c3Sitojun * 70e26ad08Sriastradh * This code is derived from software contributed to The NetBSD Foundation 80e26ad08Sriastradh * by Taylor R. Campbell. 90e26ad08Sriastradh * 100e26ad08Sriastradh * Redistribution and use in source and binary forms, with or without 110e26ad08Sriastradh * modification, are permitted provided that the following conditions 120e26ad08Sriastradh * are met: 130e26ad08Sriastradh * 1. Redistributions of source code must retain the above copyright 140e26ad08Sriastradh * notice, this list of conditions and the following disclaimer. 150e26ad08Sriastradh * 2. Redistributions in binary form must reproduce the above copyright 160e26ad08Sriastradh * notice, this list of conditions and the following disclaimer in the 170e26ad08Sriastradh * documentation and/or other materials provided with the distribution. 180e26ad08Sriastradh * 190e26ad08Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 200e26ad08Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 210e26ad08Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220e26ad08Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 230e26ad08Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 240e26ad08Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 250e26ad08Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 260e26ad08Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 270e26ad08Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 280e26ad08Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 290e26ad08Sriastradh * POSSIBILITY OF SUCH DAMAGE. 30e68f73c3Sitojun */ 31e68f73c3Sitojun 32e68f73c3Sitojun /* 330e26ad08Sriastradh * Legacy arc4random(3) API from OpenBSD reimplemented using the 340e26ad08Sriastradh * ChaCha20 PRF, with per-thread state. 35e68f73c3Sitojun * 360e26ad08Sriastradh * Security model: 370e26ad08Sriastradh * - An attacker who sees some outputs cannot predict past or future 380e26ad08Sriastradh * outputs. 390e26ad08Sriastradh * - An attacker who sees the PRNG state cannot predict past outputs. 400e26ad08Sriastradh * - An attacker who sees a child's PRNG state cannot predict past or 410e26ad08Sriastradh * future outputs in the parent, or in other children. 42e68f73c3Sitojun * 430e26ad08Sriastradh * The arc4random(3) API may abort the process if: 440e26ad08Sriastradh * 450e26ad08Sriastradh * (a) the crypto self-test fails, 460e26ad08Sriastradh * (b) pthread_atfork or thr_keycreate fail, or 470e26ad08Sriastradh * (c) sysctl(KERN_ARND) fails when reseeding the PRNG. 480e26ad08Sriastradh * 490e26ad08Sriastradh * The crypto self-test, pthread_atfork, and thr_keycreate occur only 500e26ad08Sriastradh * once, on the first use of any of the arc4random(3) API. KERN_ARND 510e26ad08Sriastradh * is unlikely to fail later unless the kernel is seriously broken. 52e68f73c3Sitojun */ 53e68f73c3Sitojun 5488c3eadbSlukem #include <sys/cdefs.h> 55*7dae1524Sriastradh __RCSID("$NetBSD: arc4random.c,v 1.38 2024/08/29 13:39:42 riastradh Exp $"); 5688c3eadbSlukem 57fd5cb0acSkleink #include "namespace.h" 586e07f2d4Stls #include "reentrant.h" 590e26ad08Sriastradh 600e26ad08Sriastradh #include <sys/bitops.h> 610e26ad08Sriastradh #include <sys/endian.h> 620e26ad08Sriastradh #include <sys/errno.h> 630e26ad08Sriastradh #include <sys/mman.h> 64e68f73c3Sitojun #include <sys/sysctl.h> 65e68f73c3Sitojun 660e26ad08Sriastradh #include <assert.h> 670e26ad08Sriastradh #include <sha2.h> 682cb0850bSriastradh #include <stdatomic.h> 690e26ad08Sriastradh #include <stdbool.h> 700e26ad08Sriastradh #include <stdint.h> 710e26ad08Sriastradh #include <stdlib.h> 720e26ad08Sriastradh #include <string.h> 730e26ad08Sriastradh #include <unistd.h> 740e26ad08Sriastradh 750d283a3aSriastradh #include "arc4random.h" 760d283a3aSriastradh #include "reentrant.h" 770d283a3aSriastradh 78fd5cb0acSkleink #ifdef __weak_alias 79fd5cb0acSkleink __weak_alias(arc4random,_arc4random) 80e2ff5b6fSdsl __weak_alias(arc4random_addrandom,_arc4random_addrandom) 81e2ff5b6fSdsl __weak_alias(arc4random_buf,_arc4random_buf) 82e2ff5b6fSdsl __weak_alias(arc4random_stir,_arc4random_stir) 83e2ff5b6fSdsl __weak_alias(arc4random_uniform,_arc4random_uniform) 84fd5cb0acSkleink #endif 85fd5cb0acSkleink 861ae59401Sroy /* 870e26ad08Sriastradh * For standard ChaCha, use le32dec/le32enc. We don't need that for 880e26ad08Sriastradh * the purposes of a nondeterministic random number generator -- we 890e26ad08Sriastradh * don't need to be bit-for-bit compatible over any wire. 901ae59401Sroy */ 91d390b20fSdsl 92a52c0478Schristos static inline uint32_t 930e26ad08Sriastradh crypto_le32dec(const void *p) 94e68f73c3Sitojun { 950e26ad08Sriastradh uint32_t v; 96c7009a57Sroy 970e26ad08Sriastradh (void)memcpy(&v, p, sizeof v); 980e26ad08Sriastradh 990e26ad08Sriastradh return v; 100e68f73c3Sitojun } 101e68f73c3Sitojun 1020e26ad08Sriastradh static inline void 1030e26ad08Sriastradh crypto_le32enc(void *p, uint32_t v) 1046e07f2d4Stls { 105c7009a57Sroy 1060e26ad08Sriastradh (void)memcpy(p, &v, sizeof v); 107e68f73c3Sitojun } 108e68f73c3Sitojun 1090e26ad08Sriastradh /* ChaCha core */ 1100e26ad08Sriastradh 1110e26ad08Sriastradh #define crypto_core_OUTPUTBYTES 64 1120e26ad08Sriastradh #define crypto_core_INPUTBYTES 16 1130e26ad08Sriastradh #define crypto_core_KEYBYTES 32 1140e26ad08Sriastradh #define crypto_core_CONSTBYTES 16 1150e26ad08Sriastradh 116d8688883Sriastradh #define crypto_core_ROUNDS 20 1170e26ad08Sriastradh 1180e26ad08Sriastradh static uint32_t 1190e26ad08Sriastradh rotate(uint32_t u, unsigned c) 1206e07f2d4Stls { 121c7009a57Sroy 1220e26ad08Sriastradh return (u << c) | (u >> (32 - c)); 1236e07f2d4Stls } 1246e07f2d4Stls 1250e26ad08Sriastradh #define QUARTERROUND(a, b, c, d) do { \ 1260e26ad08Sriastradh (a) += (b); (d) ^= (a); (d) = rotate((d), 16); \ 1270e26ad08Sriastradh (c) += (d); (b) ^= (c); (b) = rotate((b), 12); \ 1280e26ad08Sriastradh (a) += (b); (d) ^= (a); (d) = rotate((d), 8); \ 1290e26ad08Sriastradh (c) += (d); (b) ^= (c); (b) = rotate((b), 7); \ 130388550b0Srillig } while (0) 1310e26ad08Sriastradh 132ace5b9b5Schristos static const uint8_t crypto_core_constant32[16] = "expand 32-byte k"; 1330e26ad08Sriastradh 1340e26ad08Sriastradh static void 1350e26ad08Sriastradh crypto_core(uint8_t *out, const uint8_t *in, const uint8_t *k, 1360e26ad08Sriastradh const uint8_t *c) 1370e26ad08Sriastradh { 1380e26ad08Sriastradh uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15; 1390e26ad08Sriastradh uint32_t j0,j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15; 1400e26ad08Sriastradh int i; 1410e26ad08Sriastradh 1420e26ad08Sriastradh j0 = x0 = crypto_le32dec(c + 0); 1430e26ad08Sriastradh j1 = x1 = crypto_le32dec(c + 4); 1440e26ad08Sriastradh j2 = x2 = crypto_le32dec(c + 8); 1450e26ad08Sriastradh j3 = x3 = crypto_le32dec(c + 12); 1460e26ad08Sriastradh j4 = x4 = crypto_le32dec(k + 0); 1470e26ad08Sriastradh j5 = x5 = crypto_le32dec(k + 4); 1480e26ad08Sriastradh j6 = x6 = crypto_le32dec(k + 8); 1490e26ad08Sriastradh j7 = x7 = crypto_le32dec(k + 12); 1500e26ad08Sriastradh j8 = x8 = crypto_le32dec(k + 16); 1510e26ad08Sriastradh j9 = x9 = crypto_le32dec(k + 20); 1520e26ad08Sriastradh j10 = x10 = crypto_le32dec(k + 24); 1530e26ad08Sriastradh j11 = x11 = crypto_le32dec(k + 28); 1540e26ad08Sriastradh j12 = x12 = crypto_le32dec(in + 0); 1550e26ad08Sriastradh j13 = x13 = crypto_le32dec(in + 4); 1560e26ad08Sriastradh j14 = x14 = crypto_le32dec(in + 8); 1570e26ad08Sriastradh j15 = x15 = crypto_le32dec(in + 12); 1580e26ad08Sriastradh 1590e26ad08Sriastradh for (i = crypto_core_ROUNDS; i > 0; i -= 2) { 1600e26ad08Sriastradh QUARTERROUND( x0, x4, x8,x12); 1610e26ad08Sriastradh QUARTERROUND( x1, x5, x9,x13); 1620e26ad08Sriastradh QUARTERROUND( x2, x6,x10,x14); 1630e26ad08Sriastradh QUARTERROUND( x3, x7,x11,x15); 1640e26ad08Sriastradh QUARTERROUND( x0, x5,x10,x15); 1650e26ad08Sriastradh QUARTERROUND( x1, x6,x11,x12); 1660e26ad08Sriastradh QUARTERROUND( x2, x7, x8,x13); 1670e26ad08Sriastradh QUARTERROUND( x3, x4, x9,x14); 1680e26ad08Sriastradh } 1690e26ad08Sriastradh 1700e26ad08Sriastradh crypto_le32enc(out + 0, x0 + j0); 1710e26ad08Sriastradh crypto_le32enc(out + 4, x1 + j1); 1720e26ad08Sriastradh crypto_le32enc(out + 8, x2 + j2); 1730e26ad08Sriastradh crypto_le32enc(out + 12, x3 + j3); 1740e26ad08Sriastradh crypto_le32enc(out + 16, x4 + j4); 1750e26ad08Sriastradh crypto_le32enc(out + 20, x5 + j5); 1760e26ad08Sriastradh crypto_le32enc(out + 24, x6 + j6); 1770e26ad08Sriastradh crypto_le32enc(out + 28, x7 + j7); 1780e26ad08Sriastradh crypto_le32enc(out + 32, x8 + j8); 1790e26ad08Sriastradh crypto_le32enc(out + 36, x9 + j9); 1800e26ad08Sriastradh crypto_le32enc(out + 40, x10 + j10); 1810e26ad08Sriastradh crypto_le32enc(out + 44, x11 + j11); 1820e26ad08Sriastradh crypto_le32enc(out + 48, x12 + j12); 1830e26ad08Sriastradh crypto_le32enc(out + 52, x13 + j13); 1840e26ad08Sriastradh crypto_le32enc(out + 56, x14 + j14); 1850e26ad08Sriastradh crypto_le32enc(out + 60, x15 + j15); 1860e26ad08Sriastradh } 1870e26ad08Sriastradh 1880e26ad08Sriastradh /* ChaCha self-test */ 1890e26ad08Sriastradh 1900e26ad08Sriastradh #ifdef _DIAGNOSTIC 1910e26ad08Sriastradh 1920e26ad08Sriastradh /* 1930e26ad08Sriastradh * Test vector for ChaCha20 from 1940e26ad08Sriastradh * <http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-00>, 1950e26ad08Sriastradh * test vectors for ChaCha12 and ChaCha8 and for big-endian machines 1960e26ad08Sriastradh * generated by the same crypto_core code with crypto_core_ROUNDS and 1970e26ad08Sriastradh * crypto_le32enc/dec varied. 1980e26ad08Sriastradh */ 1990e26ad08Sriastradh 2000e26ad08Sriastradh static const uint8_t crypto_core_selftest_vector[64] = { 2010e26ad08Sriastradh #if _BYTE_ORDER == _LITTLE_ENDIAN 2020e26ad08Sriastradh # if crypto_core_ROUNDS == 8 2030e26ad08Sriastradh 0x3e,0x00,0xef,0x2f,0x89,0x5f,0x40,0xd6, 2040e26ad08Sriastradh 0x7f,0x5b,0xb8,0xe8,0x1f,0x09,0xa5,0xa1, 2050e26ad08Sriastradh 0x2c,0x84,0x0e,0xc3,0xce,0x9a,0x7f,0x3b, 2060e26ad08Sriastradh 0x18,0x1b,0xe1,0x88,0xef,0x71,0x1a,0x1e, 2070e26ad08Sriastradh 0x98,0x4c,0xe1,0x72,0xb9,0x21,0x6f,0x41, 2080e26ad08Sriastradh 0x9f,0x44,0x53,0x67,0x45,0x6d,0x56,0x19, 2090e26ad08Sriastradh 0x31,0x4a,0x42,0xa3,0xda,0x86,0xb0,0x01, 2100e26ad08Sriastradh 0x38,0x7b,0xfd,0xb8,0x0e,0x0c,0xfe,0x42, 2110e26ad08Sriastradh # elif crypto_core_ROUNDS == 12 2120e26ad08Sriastradh 0x9b,0xf4,0x9a,0x6a,0x07,0x55,0xf9,0x53, 2130e26ad08Sriastradh 0x81,0x1f,0xce,0x12,0x5f,0x26,0x83,0xd5, 2140e26ad08Sriastradh 0x04,0x29,0xc3,0xbb,0x49,0xe0,0x74,0x14, 2150e26ad08Sriastradh 0x7e,0x00,0x89,0xa5,0x2e,0xae,0x15,0x5f, 2160e26ad08Sriastradh 0x05,0x64,0xf8,0x79,0xd2,0x7a,0xe3,0xc0, 2170e26ad08Sriastradh 0x2c,0xe8,0x28,0x34,0xac,0xfa,0x8c,0x79, 2180e26ad08Sriastradh 0x3a,0x62,0x9f,0x2c,0xa0,0xde,0x69,0x19, 2190e26ad08Sriastradh 0x61,0x0b,0xe8,0x2f,0x41,0x13,0x26,0xbe, 2200e26ad08Sriastradh # elif crypto_core_ROUNDS == 20 2210e26ad08Sriastradh 0x76,0xb8,0xe0,0xad,0xa0,0xf1,0x3d,0x90, 2220e26ad08Sriastradh 0x40,0x5d,0x6a,0xe5,0x53,0x86,0xbd,0x28, 2230e26ad08Sriastradh 0xbd,0xd2,0x19,0xb8,0xa0,0x8d,0xed,0x1a, 2240e26ad08Sriastradh 0xa8,0x36,0xef,0xcc,0x8b,0x77,0x0d,0xc7, 2250e26ad08Sriastradh 0xda,0x41,0x59,0x7c,0x51,0x57,0x48,0x8d, 2260e26ad08Sriastradh 0x77,0x24,0xe0,0x3f,0xb8,0xd8,0x4a,0x37, 2270e26ad08Sriastradh 0x6a,0x43,0xb8,0xf4,0x15,0x18,0xa1,0x1c, 2280e26ad08Sriastradh 0xc3,0x87,0xb6,0x69,0xb2,0xee,0x65,0x86, 2290e26ad08Sriastradh # else 2300e26ad08Sriastradh # error crypto_core_ROUNDS must be 8, 12, or 20. 2310e26ad08Sriastradh # endif 2320e26ad08Sriastradh #elif _BYTE_ORDER == _BIG_ENDIAN 2330e26ad08Sriastradh # if crypto_core_ROUNDS == 8 2340e26ad08Sriastradh 0x9a,0x13,0x07,0xe3,0x38,0x18,0x9e,0x99, 2350e26ad08Sriastradh 0x15,0x37,0x16,0x4d,0x04,0xe6,0x48,0x9a, 2360e26ad08Sriastradh 0x07,0xd6,0xe8,0x7a,0x02,0xf9,0xf5,0xc7, 2370e26ad08Sriastradh 0x3f,0xa9,0xc2,0x0a,0xe1,0xc6,0x62,0xea, 2380e26ad08Sriastradh 0x80,0xaf,0xb6,0x51,0xca,0x52,0x43,0x87, 2390e26ad08Sriastradh 0xe3,0xa6,0xa6,0x61,0x11,0xf5,0xe6,0xcf, 2400e26ad08Sriastradh 0x09,0x0f,0xdc,0x9d,0xc3,0xc3,0xbb,0x43, 2410e26ad08Sriastradh 0xd7,0xfa,0x70,0x42,0xbf,0xa5,0xee,0xa2, 2420e26ad08Sriastradh # elif crypto_core_ROUNDS == 12 2430e26ad08Sriastradh 0xcf,0x6c,0x16,0x48,0xbf,0xf4,0xba,0x85, 2440e26ad08Sriastradh 0x32,0x69,0xd3,0x98,0xc8,0x7d,0xcd,0x3f, 2450e26ad08Sriastradh 0xdc,0x76,0x6b,0xa2,0x7b,0xcb,0x17,0x4d, 2460e26ad08Sriastradh 0x05,0xda,0xdd,0xd8,0x62,0x54,0xbf,0xe0, 2470e26ad08Sriastradh 0x65,0xed,0x0e,0xf4,0x01,0x7e,0x3c,0x05, 2480e26ad08Sriastradh 0x35,0xb2,0x7a,0x60,0xf3,0x8f,0x12,0x33, 2490e26ad08Sriastradh 0x24,0x60,0xcd,0x85,0xfe,0x4c,0xf3,0x39, 2500e26ad08Sriastradh 0xb1,0x0e,0x3e,0xe0,0xba,0xa6,0x2f,0xa9, 2510e26ad08Sriastradh # elif crypto_core_ROUNDS == 20 2520e26ad08Sriastradh 0x83,0x8b,0xf8,0x75,0xf7,0xde,0x9d,0x8c, 2530e26ad08Sriastradh 0x33,0x14,0x72,0x28,0xd1,0xbe,0x88,0xe5, 2540e26ad08Sriastradh 0x94,0xb5,0xed,0xb8,0x56,0xb5,0x9e,0x0c, 2550e26ad08Sriastradh 0x64,0x6a,0xaf,0xd9,0xa7,0x49,0x10,0x59, 2560e26ad08Sriastradh 0xba,0x3a,0x82,0xf8,0x4a,0x70,0x9c,0x00, 2570e26ad08Sriastradh 0x82,0x2c,0xae,0xc6,0xd7,0x1c,0x2e,0xda, 2580e26ad08Sriastradh 0x2a,0xfb,0x61,0x70,0x2b,0xd1,0xbf,0x8b, 2590e26ad08Sriastradh 0x95,0xbc,0x23,0xb6,0x4b,0x60,0x02,0xec, 2600e26ad08Sriastradh # else 2610e26ad08Sriastradh # error crypto_core_ROUNDS must be 8, 12, or 20. 2620e26ad08Sriastradh # endif 2630e26ad08Sriastradh #else 2640e26ad08Sriastradh # error Byte order must be little-endian or big-endian. 2650e26ad08Sriastradh #endif 2660e26ad08Sriastradh }; 2670e26ad08Sriastradh 2680e26ad08Sriastradh static int 2690e26ad08Sriastradh crypto_core_selftest(void) 2700e26ad08Sriastradh { 2710e26ad08Sriastradh const uint8_t nonce[crypto_core_INPUTBYTES] = {0}; 2720e26ad08Sriastradh const uint8_t key[crypto_core_KEYBYTES] = {0}; 2730e26ad08Sriastradh uint8_t block[64]; 2740e26ad08Sriastradh unsigned i; 2750e26ad08Sriastradh 2760e26ad08Sriastradh crypto_core(block, nonce, key, crypto_core_constant32); 2770e26ad08Sriastradh for (i = 0; i < 64; i++) { 2780e26ad08Sriastradh if (block[i] != crypto_core_selftest_vector[i]) 2790e26ad08Sriastradh return EIO; 2800e26ad08Sriastradh } 2810e26ad08Sriastradh 2820e26ad08Sriastradh return 0; 2830e26ad08Sriastradh } 2840e26ad08Sriastradh 2850e26ad08Sriastradh #else /* !_DIAGNOSTIC */ 2860e26ad08Sriastradh 2870e26ad08Sriastradh static int 2880e26ad08Sriastradh crypto_core_selftest(void) 2890e26ad08Sriastradh { 2900e26ad08Sriastradh 2910e26ad08Sriastradh return 0; 2920e26ad08Sriastradh } 2930e26ad08Sriastradh 2940e26ad08Sriastradh #endif 2950e26ad08Sriastradh 2960e26ad08Sriastradh /* PRNG */ 2970e26ad08Sriastradh 2980e26ad08Sriastradh /* 2990e26ad08Sriastradh * For a state s, rather than use ChaCha20 as a stream cipher to 3000e26ad08Sriastradh * generate the concatenation ChaCha20_s(0) || ChaCha20_s(1) || ..., we 3010e26ad08Sriastradh * split ChaCha20_s(0) into s' || x and yield x for the first request, 3020e26ad08Sriastradh * split ChaCha20_s'(0) into s'' || y and yield y for the second 3030e26ad08Sriastradh * request, &c. This provides backtracking resistance: an attacker who 3040e26ad08Sriastradh * finds s'' can't recover s' or x. 3050e26ad08Sriastradh */ 3060e26ad08Sriastradh 3070e26ad08Sriastradh #define crypto_prng_SEEDBYTES crypto_core_KEYBYTES 3080e26ad08Sriastradh #define crypto_prng_MAXOUTPUTBYTES \ 3090e26ad08Sriastradh (crypto_core_OUTPUTBYTES - crypto_prng_SEEDBYTES) 3100e26ad08Sriastradh 3110d283a3aSriastradh __CTASSERT(sizeof(struct crypto_prng) == crypto_prng_SEEDBYTES); 3120e26ad08Sriastradh 3130e26ad08Sriastradh static void 3140e26ad08Sriastradh crypto_prng_seed(struct crypto_prng *prng, const void *seed) 3150e26ad08Sriastradh { 3160e26ad08Sriastradh 3170e26ad08Sriastradh (void)memcpy(prng->state, seed, crypto_prng_SEEDBYTES); 3180e26ad08Sriastradh } 3190e26ad08Sriastradh 3200e26ad08Sriastradh static void 3210e26ad08Sriastradh crypto_prng_buf(struct crypto_prng *prng, void *buf, size_t n) 3220e26ad08Sriastradh { 3230e26ad08Sriastradh const uint8_t nonce[crypto_core_INPUTBYTES] = {0}; 3240e26ad08Sriastradh uint8_t output[crypto_core_OUTPUTBYTES]; 3250e26ad08Sriastradh 3260e26ad08Sriastradh _DIAGASSERT(n <= crypto_prng_MAXOUTPUTBYTES); 3270e26ad08Sriastradh __CTASSERT(sizeof prng->state + crypto_prng_MAXOUTPUTBYTES 3280e26ad08Sriastradh <= sizeof output); 3290e26ad08Sriastradh 3300e26ad08Sriastradh crypto_core(output, nonce, prng->state, crypto_core_constant32); 3310e26ad08Sriastradh (void)memcpy(prng->state, output, sizeof prng->state); 3320e26ad08Sriastradh (void)memcpy(buf, output + sizeof prng->state, n); 3330e26ad08Sriastradh (void)explicit_memset(output, 0, sizeof output); 3340e26ad08Sriastradh } 3350e26ad08Sriastradh 3360e26ad08Sriastradh /* One-time stream: expand short single-use secret into long secret */ 3370e26ad08Sriastradh 3380e26ad08Sriastradh #define crypto_onetimestream_SEEDBYTES crypto_core_KEYBYTES 3390e26ad08Sriastradh 3400e26ad08Sriastradh static void 3410e26ad08Sriastradh crypto_onetimestream(const void *seed, void *buf, size_t n) 3420e26ad08Sriastradh { 3430e26ad08Sriastradh uint32_t nonce[crypto_core_INPUTBYTES / sizeof(uint32_t)] = {0}; 3440e26ad08Sriastradh uint8_t block[crypto_core_OUTPUTBYTES]; 3450e26ad08Sriastradh uint8_t *p8, *p32; 34626ba8048Schristos const uint8_t *nonce8 = (const uint8_t *)(void *)nonce; 3470e26ad08Sriastradh size_t ni, nb, nf; 3480e26ad08Sriastradh 3490e26ad08Sriastradh /* 3500e26ad08Sriastradh * Guarantee we can generate up to n bytes. We have 3510e26ad08Sriastradh * 2^(8*INPUTBYTES) possible inputs yielding output of 3520e26ad08Sriastradh * OUTPUTBYTES*2^(8*INPUTBYTES) bytes. It suffices to require 3530e26ad08Sriastradh * that sizeof n > (1/CHAR_BIT) log_2 n be less than 3540e26ad08Sriastradh * (1/CHAR_BIT) log_2 of the total output stream length. We 3550e26ad08Sriastradh * have 3560e26ad08Sriastradh * 3570e26ad08Sriastradh * log_2 (o 2^(8 i)) = log_2 o + log_2 2^(8 i) 3580e26ad08Sriastradh * = log_2 o + 8 i. 3590e26ad08Sriastradh */ 360accd2f26Schristos #ifndef __lint__ 361accd2f26Schristos __CTASSERT(CHAR_BIT * sizeof n <= (ilog2(crypto_core_OUTPUTBYTES) + 362bec9c2feSriastradh 8 * crypto_core_INPUTBYTES)); 363accd2f26Schristos #endif 3640e26ad08Sriastradh 3650e26ad08Sriastradh p8 = buf; 3660e26ad08Sriastradh p32 = (uint8_t *)roundup2((uintptr_t)p8, 4); 3670e26ad08Sriastradh ni = p32 - p8; 3680e26ad08Sriastradh if (n < ni) 3690e26ad08Sriastradh ni = n; 3700e26ad08Sriastradh nb = (n - ni) / sizeof block; 3710e26ad08Sriastradh nf = (n - ni) % sizeof block; 3720e26ad08Sriastradh 3730e26ad08Sriastradh _DIAGASSERT(((uintptr_t)p32 & 3) == 0); 3740e26ad08Sriastradh _DIAGASSERT(ni <= n); 3750e26ad08Sriastradh _DIAGASSERT(nb <= (n / sizeof block)); 3760e26ad08Sriastradh _DIAGASSERT(nf <= n); 3770e26ad08Sriastradh _DIAGASSERT(n == (ni + (nb * sizeof block) + nf)); 3780e26ad08Sriastradh _DIAGASSERT(ni < 4); 3790e26ad08Sriastradh _DIAGASSERT(nf < sizeof block); 3800e26ad08Sriastradh 3810e26ad08Sriastradh if (ni) { 3820e26ad08Sriastradh crypto_core(block, nonce8, seed, crypto_core_constant32); 3830e26ad08Sriastradh nonce[0]++; 3840e26ad08Sriastradh (void)memcpy(p8, block, ni); 3850e26ad08Sriastradh } 3860e26ad08Sriastradh while (nb--) { 3870e26ad08Sriastradh crypto_core(p32, nonce8, seed, crypto_core_constant32); 3880e26ad08Sriastradh if (++nonce[0] == 0) 3890e26ad08Sriastradh nonce[1]++; 3900e26ad08Sriastradh p32 += crypto_core_OUTPUTBYTES; 3910e26ad08Sriastradh } 3920e26ad08Sriastradh if (nf) { 3930e26ad08Sriastradh crypto_core(block, nonce8, seed, crypto_core_constant32); 3940e26ad08Sriastradh if (++nonce[0] == 0) 3950e26ad08Sriastradh nonce[1]++; 3960e26ad08Sriastradh (void)memcpy(p32, block, nf); 3970e26ad08Sriastradh } 3980e26ad08Sriastradh 3990e26ad08Sriastradh if (ni | nf) 4000e26ad08Sriastradh (void)explicit_memset(block, 0, sizeof block); 4010e26ad08Sriastradh } 4020e26ad08Sriastradh 4032cb0850bSriastradh /* 4042cb0850bSriastradh * entropy_epoch() 4052cb0850bSriastradh * 4062cb0850bSriastradh * Return the current entropy epoch, from the sysctl node 4072cb0850bSriastradh * kern.entropy.epoch. 4082cb0850bSriastradh * 4092cb0850bSriastradh * The entropy epoch is never zero. Initially, or on error, it is 4102cb0850bSriastradh * (unsigned)-1. It may wrap around but it skips (unsigned)-1 and 4112cb0850bSriastradh * 0 when it does. Changes happen less than once per second, so 4122cb0850bSriastradh * wraparound will only affect systems after 136 years of uptime. 4132cb0850bSriastradh * 4142cb0850bSriastradh * XXX This should get it from a page shared read-only by kernel 4152cb0850bSriastradh * with userland, but until we implement such a mechanism, this 4162cb0850bSriastradh * sysctl -- incurring the cost of a syscall -- will have to 4172cb0850bSriastradh * serve. 4182cb0850bSriastradh */ 4192cb0850bSriastradh static unsigned 4202cb0850bSriastradh entropy_epoch(void) 4212cb0850bSriastradh { 4222cb0850bSriastradh static atomic_int mib0[3]; 4232cb0850bSriastradh static atomic_bool initialized = false; 4242cb0850bSriastradh int mib[3]; 425*7dae1524Sriastradh unsigned epoch = (unsigned)-1; 4262cb0850bSriastradh size_t epochlen = sizeof(epoch); 4272cb0850bSriastradh 4282cb0850bSriastradh /* 4292cb0850bSriastradh * Resolve kern.entropy.epoch if we haven't already. Cache it 4302cb0850bSriastradh * for the next caller. Initialization is idempotent, so it's 4312cb0850bSriastradh * OK if two threads do it at once. 4322cb0850bSriastradh */ 4332cb0850bSriastradh if (atomic_load_explicit(&initialized, memory_order_acquire)) { 4342cb0850bSriastradh mib[0] = atomic_load_explicit(&mib0[0], memory_order_relaxed); 4352cb0850bSriastradh mib[1] = atomic_load_explicit(&mib0[1], memory_order_relaxed); 4362cb0850bSriastradh mib[2] = atomic_load_explicit(&mib0[2], memory_order_relaxed); 4372cb0850bSriastradh } else { 4382cb0850bSriastradh size_t nmib = __arraycount(mib); 4392cb0850bSriastradh 4402cb0850bSriastradh if (sysctlnametomib("kern.entropy.epoch", mib, &nmib) == -1) 441*7dae1524Sriastradh return (unsigned)-1; 4422cb0850bSriastradh if (nmib != __arraycount(mib)) 443*7dae1524Sriastradh return (unsigned)-1; 4442cb0850bSriastradh atomic_store_explicit(&mib0[0], mib[0], memory_order_relaxed); 4452cb0850bSriastradh atomic_store_explicit(&mib0[1], mib[1], memory_order_relaxed); 4462cb0850bSriastradh atomic_store_explicit(&mib0[2], mib[2], memory_order_relaxed); 4472cb0850bSriastradh atomic_store_explicit(&initialized, true, 4482cb0850bSriastradh memory_order_release); 4492cb0850bSriastradh } 4502cb0850bSriastradh 4512cb0850bSriastradh if (sysctl(mib, __arraycount(mib), &epoch, &epochlen, NULL, 0) == -1) 452*7dae1524Sriastradh return (unsigned)-1; 4532cb0850bSriastradh if (epochlen != sizeof(epoch)) 454*7dae1524Sriastradh return (unsigned)-1; 4552cb0850bSriastradh 4562cb0850bSriastradh return epoch; 4572cb0850bSriastradh } 4582cb0850bSriastradh 4590e26ad08Sriastradh /* arc4random state: per-thread, per-process (zeroed in child on fork) */ 4600e26ad08Sriastradh 4610e26ad08Sriastradh static void 4620e26ad08Sriastradh arc4random_prng_addrandom(struct arc4random_prng *prng, const void *data, 4630e26ad08Sriastradh size_t datalen) 4640e26ad08Sriastradh { 4650e26ad08Sriastradh const int mib[] = { CTL_KERN, KERN_ARND }; 4660e26ad08Sriastradh SHA256_CTX ctx; 4670e26ad08Sriastradh uint8_t buf[crypto_prng_SEEDBYTES]; 4680e26ad08Sriastradh size_t buflen = sizeof buf; 4692cb0850bSriastradh unsigned epoch = entropy_epoch(); 4700e26ad08Sriastradh 4710e26ad08Sriastradh __CTASSERT(sizeof buf == SHA256_DIGEST_LENGTH); 4720e26ad08Sriastradh 4730e26ad08Sriastradh SHA256_Init(&ctx); 4740e26ad08Sriastradh 4750e26ad08Sriastradh crypto_prng_buf(&prng->arc4_prng, buf, sizeof buf); 4760e26ad08Sriastradh SHA256_Update(&ctx, buf, sizeof buf); 4770e26ad08Sriastradh 47826ba8048Schristos if (sysctl(mib, (u_int)__arraycount(mib), buf, &buflen, NULL, 0) == -1) 4790e26ad08Sriastradh abort(); 4800e26ad08Sriastradh if (buflen != sizeof buf) 4810e26ad08Sriastradh abort(); 4820e26ad08Sriastradh SHA256_Update(&ctx, buf, sizeof buf); 4830e26ad08Sriastradh 4840e26ad08Sriastradh if (data != NULL) 4850e26ad08Sriastradh SHA256_Update(&ctx, data, datalen); 4860e26ad08Sriastradh 4870e26ad08Sriastradh SHA256_Final(buf, &ctx); 4880e26ad08Sriastradh (void)explicit_memset(&ctx, 0, sizeof ctx); 4890e26ad08Sriastradh 4900e26ad08Sriastradh /* reseed(SHA256(prng() || sysctl(KERN_ARND) || data)) */ 4910e26ad08Sriastradh crypto_prng_seed(&prng->arc4_prng, buf); 4920e26ad08Sriastradh (void)explicit_memset(buf, 0, sizeof buf); 4932cb0850bSriastradh prng->arc4_epoch = epoch; 4940e26ad08Sriastradh } 4950e26ad08Sriastradh 4960e26ad08Sriastradh #ifdef _REENTRANT 4970e26ad08Sriastradh static struct arc4random_prng * 4980e26ad08Sriastradh arc4random_prng_create(void) 4990e26ad08Sriastradh { 5000e26ad08Sriastradh struct arc4random_prng *prng; 5010e26ad08Sriastradh const size_t size = roundup(sizeof(*prng), sysconf(_SC_PAGESIZE)); 5020e26ad08Sriastradh 503bec9c2feSriastradh prng = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 504bec9c2feSriastradh 0); 5050e26ad08Sriastradh if (prng == MAP_FAILED) 5060e26ad08Sriastradh goto fail0; 5070e26ad08Sriastradh if (minherit(prng, size, MAP_INHERIT_ZERO) == -1) 5080e26ad08Sriastradh goto fail1; 5090e26ad08Sriastradh 5100e26ad08Sriastradh return prng; 5110e26ad08Sriastradh 5120e26ad08Sriastradh fail1: (void)munmap(prng, size); 5130e26ad08Sriastradh fail0: return NULL; 5140e26ad08Sriastradh } 5150e26ad08Sriastradh #endif 5160e26ad08Sriastradh 5170e26ad08Sriastradh #ifdef _REENTRANT 5180e26ad08Sriastradh static void 5190e26ad08Sriastradh arc4random_prng_destroy(struct arc4random_prng *prng) 5200e26ad08Sriastradh { 5210e26ad08Sriastradh const size_t size = roundup(sizeof(*prng), sysconf(_SC_PAGESIZE)); 5220e26ad08Sriastradh 5230e26ad08Sriastradh (void)explicit_memset(prng, 0, sizeof(*prng)); 5240e26ad08Sriastradh (void)munmap(prng, size); 5250e26ad08Sriastradh } 5260e26ad08Sriastradh #endif 5270e26ad08Sriastradh 5280e26ad08Sriastradh /* Library state */ 5290e26ad08Sriastradh 5300d283a3aSriastradh struct arc4random_global_state arc4random_global = { 5310e26ad08Sriastradh #ifdef _REENTRANT 5320e26ad08Sriastradh .lock = MUTEX_INITIALIZER, 5330e26ad08Sriastradh #endif 5340e26ad08Sriastradh .initialized = false, 5350e26ad08Sriastradh }; 5360e26ad08Sriastradh 5370e26ad08Sriastradh static void 5380e26ad08Sriastradh arc4random_atfork_prepare(void) 5390e26ad08Sriastradh { 5400e26ad08Sriastradh 5410e26ad08Sriastradh mutex_lock(&arc4random_global.lock); 5420e26ad08Sriastradh (void)explicit_memset(&arc4random_global.prng, 0, 5430e26ad08Sriastradh sizeof arc4random_global.prng); 5440e26ad08Sriastradh } 5450e26ad08Sriastradh 5460e26ad08Sriastradh static void 5470e26ad08Sriastradh arc4random_atfork_parent(void) 5480e26ad08Sriastradh { 5490e26ad08Sriastradh 5500e26ad08Sriastradh mutex_unlock(&arc4random_global.lock); 5510e26ad08Sriastradh } 5520e26ad08Sriastradh 5530e26ad08Sriastradh static void 5540e26ad08Sriastradh arc4random_atfork_child(void) 5550e26ad08Sriastradh { 5560e26ad08Sriastradh 5570e26ad08Sriastradh mutex_unlock(&arc4random_global.lock); 5580e26ad08Sriastradh } 5590e26ad08Sriastradh 5600e26ad08Sriastradh #ifdef _REENTRANT 5610e26ad08Sriastradh static void 5620e26ad08Sriastradh arc4random_tsd_destructor(void *p) 5630e26ad08Sriastradh { 5640e26ad08Sriastradh struct arc4random_prng *const prng = p; 5650e26ad08Sriastradh 5660e26ad08Sriastradh arc4random_prng_destroy(prng); 5670e26ad08Sriastradh } 5680e26ad08Sriastradh #endif 5690e26ad08Sriastradh 5700e26ad08Sriastradh static void 5710e26ad08Sriastradh arc4random_initialize(void) 5720e26ad08Sriastradh { 5730e26ad08Sriastradh 5740e26ad08Sriastradh mutex_lock(&arc4random_global.lock); 5750e26ad08Sriastradh if (!arc4random_global.initialized) { 5760e26ad08Sriastradh if (crypto_core_selftest() != 0) 5770e26ad08Sriastradh abort(); 5780e26ad08Sriastradh if (pthread_atfork(&arc4random_atfork_prepare, 5790e26ad08Sriastradh &arc4random_atfork_parent, &arc4random_atfork_child) 5800e26ad08Sriastradh != 0) 5810e26ad08Sriastradh abort(); 5820e26ad08Sriastradh #ifdef _REENTRANT 5830e26ad08Sriastradh if (thr_keycreate(&arc4random_global.thread_key, 5840e26ad08Sriastradh &arc4random_tsd_destructor) != 0) 5850e26ad08Sriastradh abort(); 5860e26ad08Sriastradh #endif 5870e26ad08Sriastradh arc4random_global.initialized = true; 5880e26ad08Sriastradh } 5890e26ad08Sriastradh mutex_unlock(&arc4random_global.lock); 5900e26ad08Sriastradh } 5910e26ad08Sriastradh 5920e26ad08Sriastradh static struct arc4random_prng * 5930e26ad08Sriastradh arc4random_prng_get(void) 5940e26ad08Sriastradh { 5950e26ad08Sriastradh struct arc4random_prng *prng = NULL; 5960e26ad08Sriastradh 5970e26ad08Sriastradh /* Make sure the library is initialized. */ 5980e26ad08Sriastradh if (__predict_false(!arc4random_global.initialized)) 5990e26ad08Sriastradh arc4random_initialize(); 6000e26ad08Sriastradh 6010e26ad08Sriastradh #ifdef _REENTRANT 6020e26ad08Sriastradh /* Get or create the per-thread PRNG state. */ 6030e26ad08Sriastradh prng = thr_getspecific(arc4random_global.thread_key); 6040e26ad08Sriastradh if (__predict_false(prng == NULL)) { 6050e26ad08Sriastradh prng = arc4random_prng_create(); 6060e26ad08Sriastradh thr_setspecific(arc4random_global.thread_key, prng); 6070e26ad08Sriastradh } 6080e26ad08Sriastradh #endif 6090e26ad08Sriastradh 6100e26ad08Sriastradh /* If we can't create it, fall back to the global PRNG. */ 6110e26ad08Sriastradh if (__predict_false(prng == NULL)) { 6120e26ad08Sriastradh mutex_lock(&arc4random_global.lock); 6130e26ad08Sriastradh prng = &arc4random_global.prng; 6140e26ad08Sriastradh } 6150e26ad08Sriastradh 6160e26ad08Sriastradh /* Guarantee the PRNG is seeded. */ 6172cb0850bSriastradh if (__predict_false(prng->arc4_epoch != entropy_epoch())) 6180e26ad08Sriastradh arc4random_prng_addrandom(prng, NULL, 0); 6190e26ad08Sriastradh 6200e26ad08Sriastradh return prng; 6210e26ad08Sriastradh } 6220e26ad08Sriastradh 6230e26ad08Sriastradh static void 6240e26ad08Sriastradh arc4random_prng_put(struct arc4random_prng *prng) 6250e26ad08Sriastradh { 6260e26ad08Sriastradh 6270e26ad08Sriastradh /* If we had fallen back to the global PRNG, unlock it. */ 6280e26ad08Sriastradh if (__predict_false(prng == &arc4random_global.prng)) 6290e26ad08Sriastradh mutex_unlock(&arc4random_global.lock); 6300e26ad08Sriastradh } 6310e26ad08Sriastradh 6320e26ad08Sriastradh /* Public API */ 6330e26ad08Sriastradh 634a52c0478Schristos uint32_t 635a52c0478Schristos arc4random(void) 636e68f73c3Sitojun { 6370e26ad08Sriastradh struct arc4random_prng *prng; 6386e07f2d4Stls uint32_t v; 639e68f73c3Sitojun 6400e26ad08Sriastradh prng = arc4random_prng_get(); 6410e26ad08Sriastradh crypto_prng_buf(&prng->arc4_prng, &v, sizeof v); 6420e26ad08Sriastradh arc4random_prng_put(prng); 6430e26ad08Sriastradh 644ad728d47Sdsl return v; 645a52c0478Schristos } 646a52c0478Schristos 6476e07f2d4Stls void 6486e07f2d4Stls arc4random_buf(void *buf, size_t len) 6496e07f2d4Stls { 6500e26ad08Sriastradh struct arc4random_prng *prng; 651ad728d47Sdsl 6520e26ad08Sriastradh if (len <= crypto_prng_MAXOUTPUTBYTES) { 6530e26ad08Sriastradh prng = arc4random_prng_get(); 6540e26ad08Sriastradh crypto_prng_buf(&prng->arc4_prng, buf, len); 6550e26ad08Sriastradh arc4random_prng_put(prng); 6560e26ad08Sriastradh } else { 6570e26ad08Sriastradh uint8_t seed[crypto_onetimestream_SEEDBYTES]; 658ad728d47Sdsl 6590e26ad08Sriastradh prng = arc4random_prng_get(); 6600e26ad08Sriastradh crypto_prng_buf(&prng->arc4_prng, seed, sizeof seed); 6610e26ad08Sriastradh arc4random_prng_put(prng); 6626f85c323Sdsl 6630e26ad08Sriastradh crypto_onetimestream(seed, buf, len); 6640e26ad08Sriastradh (void)explicit_memset(seed, 0, sizeof seed); 6650e26ad08Sriastradh } 6666e07f2d4Stls } 6676e07f2d4Stls 668ad728d47Sdsl uint32_t 6690e26ad08Sriastradh arc4random_uniform(uint32_t bound) 670a52c0478Schristos { 6710e26ad08Sriastradh struct arc4random_prng *prng; 6720e26ad08Sriastradh uint32_t minimum, r; 673ad728d47Sdsl 674a52c0478Schristos /* 6750e26ad08Sriastradh * We want a uniform random choice in [0, n), and arc4random() 6760e26ad08Sriastradh * makes a uniform random choice in [0, 2^32). If we reduce 6770e26ad08Sriastradh * that modulo n, values in [0, 2^32 mod n) will be represented 6780e26ad08Sriastradh * slightly more than values in [2^32 mod n, n). Instead we 6790e26ad08Sriastradh * choose only from [2^32 mod n, 2^32) by rejecting samples in 6800e26ad08Sriastradh * [0, 2^32 mod n), to avoid counting the extra representative 6810e26ad08Sriastradh * of [0, 2^32 mod n). To compute 2^32 mod n, note that 6820e26ad08Sriastradh * 6830e26ad08Sriastradh * 2^32 mod n = 2^32 mod n - 0 6840e26ad08Sriastradh * = 2^32 mod n - n mod n 6850e26ad08Sriastradh * = (2^32 - n) mod n, 6860e26ad08Sriastradh * 6870e26ad08Sriastradh * the last of which is what we compute in 32-bit arithmetic. 688a52c0478Schristos */ 6890e26ad08Sriastradh minimum = (-bound % bound); 690a52c0478Schristos 6910e26ad08Sriastradh prng = arc4random_prng_get(); 6920e26ad08Sriastradh do crypto_prng_buf(&prng->arc4_prng, &r, sizeof r); 6930e26ad08Sriastradh while (__predict_false(r < minimum)); 6940e26ad08Sriastradh arc4random_prng_put(prng); 6950e26ad08Sriastradh 6960e26ad08Sriastradh return (r % bound); 697a52c0478Schristos } 6980e26ad08Sriastradh 6990e26ad08Sriastradh void 7000e26ad08Sriastradh arc4random_stir(void) 7010e26ad08Sriastradh { 7020e26ad08Sriastradh struct arc4random_prng *prng; 7030e26ad08Sriastradh 7040e26ad08Sriastradh prng = arc4random_prng_get(); 7050e26ad08Sriastradh arc4random_prng_addrandom(prng, NULL, 0); 7060e26ad08Sriastradh arc4random_prng_put(prng); 7070e26ad08Sriastradh } 7080e26ad08Sriastradh 7090e26ad08Sriastradh /* 7100e26ad08Sriastradh * Silly signature here is for hysterical raisins. Should instead be 7110e26ad08Sriastradh * const void *data and size_t datalen. 7120e26ad08Sriastradh */ 7130e26ad08Sriastradh void 7140e26ad08Sriastradh arc4random_addrandom(u_char *data, int datalen) 7150e26ad08Sriastradh { 7160e26ad08Sriastradh struct arc4random_prng *prng; 7170e26ad08Sriastradh 7180e26ad08Sriastradh _DIAGASSERT(0 <= datalen); 7190e26ad08Sriastradh 7200e26ad08Sriastradh prng = arc4random_prng_get(); 7210e26ad08Sriastradh arc4random_prng_addrandom(prng, data, datalen); 7220e26ad08Sriastradh arc4random_prng_put(prng); 7230e26ad08Sriastradh } 7240e26ad08Sriastradh 7250e26ad08Sriastradh #ifdef _ARC4RANDOM_TEST 7260e26ad08Sriastradh 7270e26ad08Sriastradh #include <sys/wait.h> 7280e26ad08Sriastradh 7290e26ad08Sriastradh #include <err.h> 7300e26ad08Sriastradh #include <stdio.h> 7310e26ad08Sriastradh 7320e26ad08Sriastradh int 7330e26ad08Sriastradh main(int argc __unused, char **argv __unused) 7340e26ad08Sriastradh { 7350e26ad08Sriastradh unsigned char gubbish[] = "random gubbish"; 7360e26ad08Sriastradh const uint8_t zero64[64] = {0}; 7370e26ad08Sriastradh uint8_t buf[2048]; 7380e26ad08Sriastradh unsigned i, a, n; 7390e26ad08Sriastradh 7400e26ad08Sriastradh /* Test arc4random: should not be deterministic. */ 7410e26ad08Sriastradh if (printf("arc4random: %08"PRIx32"\n", arc4random()) < 0) 7420e26ad08Sriastradh err(1, "printf"); 7430e26ad08Sriastradh 7440e26ad08Sriastradh /* Test stirring: should definitely not be deterministic. */ 7450e26ad08Sriastradh arc4random_stir(); 7460e26ad08Sriastradh 7470e26ad08Sriastradh /* Test small buffer. */ 7480e26ad08Sriastradh arc4random_buf(buf, 8); 7490e26ad08Sriastradh if (printf("arc4randombuf small:") < 0) 7500e26ad08Sriastradh err(1, "printf"); 7510e26ad08Sriastradh for (i = 0; i < 8; i++) 7520e26ad08Sriastradh if (printf(" %02x", buf[i]) < 0) 7530e26ad08Sriastradh err(1, "printf"); 7540e26ad08Sriastradh if (printf("\n") < 0) 7550e26ad08Sriastradh err(1, "printf"); 7560e26ad08Sriastradh 7570e26ad08Sriastradh /* Test addrandom: should not make the rest deterministic. */ 7580e26ad08Sriastradh arc4random_addrandom(gubbish, sizeof gubbish); 7590e26ad08Sriastradh 7600e26ad08Sriastradh /* Test large buffer. */ 7610e26ad08Sriastradh arc4random_buf(buf, sizeof buf); 7620e26ad08Sriastradh if (printf("arc4randombuf_large:") < 0) 7630e26ad08Sriastradh err(1, "printf"); 7640e26ad08Sriastradh for (i = 0; i < sizeof buf; i++) 7650e26ad08Sriastradh if (printf(" %02x", buf[i]) < 0) 7660e26ad08Sriastradh err(1, "printf"); 7670e26ad08Sriastradh if (printf("\n") < 0) 7680e26ad08Sriastradh err(1, "printf"); 7690e26ad08Sriastradh 7700e26ad08Sriastradh /* Test misaligned small and large. */ 7710e26ad08Sriastradh for (a = 0; a < 64; a++) { 7720e26ad08Sriastradh for (n = a; n < sizeof buf; n++) { 7730e26ad08Sriastradh (void)memset(buf, 0, sizeof buf); 7740e26ad08Sriastradh arc4random_buf(buf, n - a); 7750e26ad08Sriastradh if (memcmp(buf + n - a, zero64, a) != 0) 7760e26ad08Sriastradh errx(1, "arc4random buffer overflow 0"); 7770e26ad08Sriastradh 7780e26ad08Sriastradh (void)memset(buf, 0, sizeof buf); 7790e26ad08Sriastradh arc4random_buf(buf + a, n - a); 7800e26ad08Sriastradh if (memcmp(buf, zero64, a) != 0) 7810e26ad08Sriastradh errx(1, "arc4random buffer overflow 1"); 7820e26ad08Sriastradh 7830e26ad08Sriastradh if ((2*a) <= n) { 7840e26ad08Sriastradh (void)memset(buf, 0, sizeof buf); 7850e26ad08Sriastradh arc4random_buf(buf + a, n - a - a); 7860e26ad08Sriastradh if (memcmp(buf + n - a, zero64, a) != 0) 7870e26ad08Sriastradh errx(1, 7880e26ad08Sriastradh "arc4random buffer overflow 2"); 7890e26ad08Sriastradh } 7900e26ad08Sriastradh } 7910e26ad08Sriastradh } 7920e26ad08Sriastradh 7930e26ad08Sriastradh /* Test fork-safety. */ 7940e26ad08Sriastradh { 7950e26ad08Sriastradh pid_t pid, rpid; 7960e26ad08Sriastradh int status; 7970e26ad08Sriastradh 7980e26ad08Sriastradh pid = fork(); 7990e26ad08Sriastradh switch (pid) { 8000e26ad08Sriastradh case -1: 8010e26ad08Sriastradh err(1, "fork"); 802d48e1013Sriastradh case 0: { 803d48e1013Sriastradh /* 804d48e1013Sriastradh * Verify the epoch has been set to zero by fork. 805d48e1013Sriastradh */ 806d48e1013Sriastradh struct arc4random_prng *prng = NULL; 807d48e1013Sriastradh #ifdef _REENTRANT 808d48e1013Sriastradh prng = thr_getspecific(arc4random_global.thread_key); 809d48e1013Sriastradh #endif 810d48e1013Sriastradh if (prng == NULL) 811d48e1013Sriastradh prng = &arc4random_global.prng; 812d48e1013Sriastradh _exit(prng->arc4_epoch != 0); 813d48e1013Sriastradh } 8140e26ad08Sriastradh default: 8150e26ad08Sriastradh rpid = waitpid(pid, &status, 0); 8160e26ad08Sriastradh if (rpid == -1) 8170e26ad08Sriastradh err(1, "waitpid"); 8180e26ad08Sriastradh if (rpid != pid) 8190e26ad08Sriastradh errx(1, "waitpid returned wrong pid" 8200e26ad08Sriastradh ": %"PRIdMAX" != %"PRIdMAX, 8210e26ad08Sriastradh (intmax_t)rpid, 8220e26ad08Sriastradh (intmax_t)pid); 8230e26ad08Sriastradh if (WIFEXITED(status)) { 8240e26ad08Sriastradh if (WEXITSTATUS(status) != 0) 8250e26ad08Sriastradh errx(1, "child exited with %d", 8260e26ad08Sriastradh WEXITSTATUS(status)); 8270e26ad08Sriastradh } else if (WIFSIGNALED(status)) { 8280e26ad08Sriastradh errx(1, "child terminated on signal %d", 8290e26ad08Sriastradh WTERMSIG(status)); 8300e26ad08Sriastradh } else { 8310e26ad08Sriastradh errx(1, "child died mysteriously: %d", status); 8320e26ad08Sriastradh } 8330e26ad08Sriastradh } 8340e26ad08Sriastradh } 8350e26ad08Sriastradh 8360e26ad08Sriastradh /* XXX Test multithreaded fork safety...? */ 8370e26ad08Sriastradh 8380e26ad08Sriastradh return 0; 8390e26ad08Sriastradh } 8400e26ad08Sriastradh #endif 841