xref: /netbsd-src/lib/libc/gen/arc4random.c (revision 7dae152421c4b79dc6a9c39dec55fec7551999c2)
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