xref: /aosp_15_r20/external/libevent/evutil_rand.c (revision 663afb9b963571284e0f0a60f257164ab54f64bf)
1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
3*663afb9bSAndroid Build Coastguard Worker  *
4*663afb9bSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
5*663afb9bSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
6*663afb9bSAndroid Build Coastguard Worker  * are met:
7*663afb9bSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
8*663afb9bSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
9*663afb9bSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
10*663afb9bSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
11*663afb9bSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
12*663afb9bSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
13*663afb9bSAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
14*663afb9bSAndroid Build Coastguard Worker  *
15*663afb9bSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*663afb9bSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*663afb9bSAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*663afb9bSAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19*663afb9bSAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*663afb9bSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*663afb9bSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*663afb9bSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*663afb9bSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*663afb9bSAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*663afb9bSAndroid Build Coastguard Worker  */
26*663afb9bSAndroid Build Coastguard Worker 
27*663afb9bSAndroid Build Coastguard Worker /* This file has our secure PRNG code.  On platforms that have arc4random(),
28*663afb9bSAndroid Build Coastguard Worker  * we just use that.  Otherwise, we include arc4random.c as a bunch of static
29*663afb9bSAndroid Build Coastguard Worker  * functions, and wrap it lightly.  We don't expose the arc4random*() APIs
30*663afb9bSAndroid Build Coastguard Worker  * because A) they aren't in our namespace, and B) it's not nice to name your
31*663afb9bSAndroid Build Coastguard Worker  * APIs after their implementations.  We keep them in a separate file
32*663afb9bSAndroid Build Coastguard Worker  * so that other people can rip it out and use it for whatever.
33*663afb9bSAndroid Build Coastguard Worker  */
34*663afb9bSAndroid Build Coastguard Worker 
35*663afb9bSAndroid Build Coastguard Worker #include "event2/event-config.h"
36*663afb9bSAndroid Build Coastguard Worker #include "evconfig-private.h"
37*663afb9bSAndroid Build Coastguard Worker 
38*663afb9bSAndroid Build Coastguard Worker #include <limits.h>
39*663afb9bSAndroid Build Coastguard Worker 
40*663afb9bSAndroid Build Coastguard Worker #include "util-internal.h"
41*663afb9bSAndroid Build Coastguard Worker #include "evthread-internal.h"
42*663afb9bSAndroid Build Coastguard Worker 
43*663afb9bSAndroid Build Coastguard Worker #ifdef EVENT__HAVE_ARC4RANDOM
44*663afb9bSAndroid Build Coastguard Worker #include <stdlib.h>
45*663afb9bSAndroid Build Coastguard Worker #include <string.h>
46*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_set_urandom_device_file(char * fname)47*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_set_urandom_device_file(char *fname)
48*663afb9bSAndroid Build Coastguard Worker {
49*663afb9bSAndroid Build Coastguard Worker 	(void) fname;
50*663afb9bSAndroid Build Coastguard Worker 	return -1;
51*663afb9bSAndroid Build Coastguard Worker }
52*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_init(void)53*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_init(void)
54*663afb9bSAndroid Build Coastguard Worker {
55*663afb9bSAndroid Build Coastguard Worker 	/* call arc4random() now to force it to self-initialize */
56*663afb9bSAndroid Build Coastguard Worker 	(void) arc4random();
57*663afb9bSAndroid Build Coastguard Worker 	return 0;
58*663afb9bSAndroid Build Coastguard Worker }
59*663afb9bSAndroid Build Coastguard Worker #ifndef EVENT__DISABLE_THREAD_SUPPORT
60*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_global_setup_locks_(const int enable_locks)61*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_global_setup_locks_(const int enable_locks)
62*663afb9bSAndroid Build Coastguard Worker {
63*663afb9bSAndroid Build Coastguard Worker 	return 0;
64*663afb9bSAndroid Build Coastguard Worker }
65*663afb9bSAndroid Build Coastguard Worker #endif
66*663afb9bSAndroid Build Coastguard Worker static void
evutil_free_secure_rng_globals_locks(void)67*663afb9bSAndroid Build Coastguard Worker evutil_free_secure_rng_globals_locks(void)
68*663afb9bSAndroid Build Coastguard Worker {
69*663afb9bSAndroid Build Coastguard Worker }
70*663afb9bSAndroid Build Coastguard Worker 
71*663afb9bSAndroid Build Coastguard Worker static void
ev_arc4random_buf(void * buf,size_t n)72*663afb9bSAndroid Build Coastguard Worker ev_arc4random_buf(void *buf, size_t n)
73*663afb9bSAndroid Build Coastguard Worker {
74*663afb9bSAndroid Build Coastguard Worker #if defined(EVENT__HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
75*663afb9bSAndroid Build Coastguard Worker 	arc4random_buf(buf, n);
76*663afb9bSAndroid Build Coastguard Worker 	return;
77*663afb9bSAndroid Build Coastguard Worker #else
78*663afb9bSAndroid Build Coastguard Worker 	unsigned char *b = buf;
79*663afb9bSAndroid Build Coastguard Worker 
80*663afb9bSAndroid Build Coastguard Worker #if defined(EVENT__HAVE_ARC4RANDOM_BUF)
81*663afb9bSAndroid Build Coastguard Worker 	/* OSX 10.7 introducd arc4random_buf, so if you build your program
82*663afb9bSAndroid Build Coastguard Worker 	 * there, you'll get surprised when older versions of OSX fail to run.
83*663afb9bSAndroid Build Coastguard Worker 	 * To solve this, we can check whether the function pointer is set,
84*663afb9bSAndroid Build Coastguard Worker 	 * and fall back otherwise.  (OSX does this using some linker
85*663afb9bSAndroid Build Coastguard Worker 	 * trickery.)
86*663afb9bSAndroid Build Coastguard Worker 	 */
87*663afb9bSAndroid Build Coastguard Worker 	{
88*663afb9bSAndroid Build Coastguard Worker 		void (*tptr)(void *,size_t) =
89*663afb9bSAndroid Build Coastguard Worker 		    (void (*)(void*,size_t))arc4random_buf;
90*663afb9bSAndroid Build Coastguard Worker 		if (tptr != NULL) {
91*663afb9bSAndroid Build Coastguard Worker 			arc4random_buf(buf, n);
92*663afb9bSAndroid Build Coastguard Worker 			return;
93*663afb9bSAndroid Build Coastguard Worker 		}
94*663afb9bSAndroid Build Coastguard Worker 	}
95*663afb9bSAndroid Build Coastguard Worker #endif
96*663afb9bSAndroid Build Coastguard Worker 	/* Make sure that we start out with b at a 4-byte alignment; plenty
97*663afb9bSAndroid Build Coastguard Worker 	 * of CPUs care about this for 32-bit access. */
98*663afb9bSAndroid Build Coastguard Worker 	if (n >= 4 && ((ev_uintptr_t)b) & 3) {
99*663afb9bSAndroid Build Coastguard Worker 		ev_uint32_t u = arc4random();
100*663afb9bSAndroid Build Coastguard Worker 		int n_bytes = 4 - (((ev_uintptr_t)b) & 3);
101*663afb9bSAndroid Build Coastguard Worker 		memcpy(b, &u, n_bytes);
102*663afb9bSAndroid Build Coastguard Worker 		b += n_bytes;
103*663afb9bSAndroid Build Coastguard Worker 		n -= n_bytes;
104*663afb9bSAndroid Build Coastguard Worker 	}
105*663afb9bSAndroid Build Coastguard Worker 	while (n >= 4) {
106*663afb9bSAndroid Build Coastguard Worker 		*(ev_uint32_t*)b = arc4random();
107*663afb9bSAndroid Build Coastguard Worker 		b += 4;
108*663afb9bSAndroid Build Coastguard Worker 		n -= 4;
109*663afb9bSAndroid Build Coastguard Worker 	}
110*663afb9bSAndroid Build Coastguard Worker 	if (n) {
111*663afb9bSAndroid Build Coastguard Worker 		ev_uint32_t u = arc4random();
112*663afb9bSAndroid Build Coastguard Worker 		memcpy(b, &u, n);
113*663afb9bSAndroid Build Coastguard Worker 	}
114*663afb9bSAndroid Build Coastguard Worker #endif
115*663afb9bSAndroid Build Coastguard Worker }
116*663afb9bSAndroid Build Coastguard Worker 
117*663afb9bSAndroid Build Coastguard Worker #else /* !EVENT__HAVE_ARC4RANDOM { */
118*663afb9bSAndroid Build Coastguard Worker 
119*663afb9bSAndroid Build Coastguard Worker #ifdef EVENT__ssize_t
120*663afb9bSAndroid Build Coastguard Worker #define ssize_t EVENT__ssize_t
121*663afb9bSAndroid Build Coastguard Worker #endif
122*663afb9bSAndroid Build Coastguard Worker #define ARC4RANDOM_EXPORT static
123*663afb9bSAndroid Build Coastguard Worker #define ARC4_LOCK_() EVLOCK_LOCK(arc4rand_lock, 0)
124*663afb9bSAndroid Build Coastguard Worker #define ARC4_UNLOCK_() EVLOCK_UNLOCK(arc4rand_lock, 0)
125*663afb9bSAndroid Build Coastguard Worker #ifndef EVENT__DISABLE_THREAD_SUPPORT
126*663afb9bSAndroid Build Coastguard Worker static void *arc4rand_lock;
127*663afb9bSAndroid Build Coastguard Worker #endif
128*663afb9bSAndroid Build Coastguard Worker 
129*663afb9bSAndroid Build Coastguard Worker #define ARC4RANDOM_UINT32 ev_uint32_t
130*663afb9bSAndroid Build Coastguard Worker #define ARC4RANDOM_NOSTIR
131*663afb9bSAndroid Build Coastguard Worker #define ARC4RANDOM_NORANDOM
132*663afb9bSAndroid Build Coastguard Worker #define ARC4RANDOM_NOUNIFORM
133*663afb9bSAndroid Build Coastguard Worker 
134*663afb9bSAndroid Build Coastguard Worker #include "./arc4random.c"
135*663afb9bSAndroid Build Coastguard Worker 
136*663afb9bSAndroid Build Coastguard Worker #ifndef EVENT__DISABLE_THREAD_SUPPORT
137*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_global_setup_locks_(const int enable_locks)138*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_global_setup_locks_(const int enable_locks)
139*663afb9bSAndroid Build Coastguard Worker {
140*663afb9bSAndroid Build Coastguard Worker 	EVTHREAD_SETUP_GLOBAL_LOCK(arc4rand_lock, 0);
141*663afb9bSAndroid Build Coastguard Worker 	return 0;
142*663afb9bSAndroid Build Coastguard Worker }
143*663afb9bSAndroid Build Coastguard Worker #endif
144*663afb9bSAndroid Build Coastguard Worker 
145*663afb9bSAndroid Build Coastguard Worker static void
evutil_free_secure_rng_globals_locks(void)146*663afb9bSAndroid Build Coastguard Worker evutil_free_secure_rng_globals_locks(void)
147*663afb9bSAndroid Build Coastguard Worker {
148*663afb9bSAndroid Build Coastguard Worker #ifndef EVENT__DISABLE_THREAD_SUPPORT
149*663afb9bSAndroid Build Coastguard Worker 	if (arc4rand_lock != NULL) {
150*663afb9bSAndroid Build Coastguard Worker 		EVTHREAD_FREE_LOCK(arc4rand_lock, 0);
151*663afb9bSAndroid Build Coastguard Worker 		arc4rand_lock = NULL;
152*663afb9bSAndroid Build Coastguard Worker 	}
153*663afb9bSAndroid Build Coastguard Worker #endif
154*663afb9bSAndroid Build Coastguard Worker 	return;
155*663afb9bSAndroid Build Coastguard Worker }
156*663afb9bSAndroid Build Coastguard Worker 
157*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_set_urandom_device_file(char * fname)158*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_set_urandom_device_file(char *fname)
159*663afb9bSAndroid Build Coastguard Worker {
160*663afb9bSAndroid Build Coastguard Worker #ifdef TRY_SEED_URANDOM
161*663afb9bSAndroid Build Coastguard Worker 	ARC4_LOCK_();
162*663afb9bSAndroid Build Coastguard Worker 	arc4random_urandom_filename = fname;
163*663afb9bSAndroid Build Coastguard Worker 	ARC4_UNLOCK_();
164*663afb9bSAndroid Build Coastguard Worker #endif
165*663afb9bSAndroid Build Coastguard Worker 	return 0;
166*663afb9bSAndroid Build Coastguard Worker }
167*663afb9bSAndroid Build Coastguard Worker 
168*663afb9bSAndroid Build Coastguard Worker int
evutil_secure_rng_init(void)169*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_init(void)
170*663afb9bSAndroid Build Coastguard Worker {
171*663afb9bSAndroid Build Coastguard Worker 	int val;
172*663afb9bSAndroid Build Coastguard Worker 
173*663afb9bSAndroid Build Coastguard Worker 	ARC4_LOCK_();
174*663afb9bSAndroid Build Coastguard Worker 	val = (!arc4_stir()) ? 0 : -1;
175*663afb9bSAndroid Build Coastguard Worker 	ARC4_UNLOCK_();
176*663afb9bSAndroid Build Coastguard Worker 	return val;
177*663afb9bSAndroid Build Coastguard Worker }
178*663afb9bSAndroid Build Coastguard Worker 
179*663afb9bSAndroid Build Coastguard Worker static void
ev_arc4random_buf(void * buf,size_t n)180*663afb9bSAndroid Build Coastguard Worker ev_arc4random_buf(void *buf, size_t n)
181*663afb9bSAndroid Build Coastguard Worker {
182*663afb9bSAndroid Build Coastguard Worker 	arc4random_buf(buf, n);
183*663afb9bSAndroid Build Coastguard Worker }
184*663afb9bSAndroid Build Coastguard Worker 
185*663afb9bSAndroid Build Coastguard Worker #endif /* } !EVENT__HAVE_ARC4RANDOM */
186*663afb9bSAndroid Build Coastguard Worker 
187*663afb9bSAndroid Build Coastguard Worker void
evutil_secure_rng_get_bytes(void * buf,size_t n)188*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_get_bytes(void *buf, size_t n)
189*663afb9bSAndroid Build Coastguard Worker {
190*663afb9bSAndroid Build Coastguard Worker 	ev_arc4random_buf(buf, n);
191*663afb9bSAndroid Build Coastguard Worker }
192*663afb9bSAndroid Build Coastguard Worker 
193*663afb9bSAndroid Build Coastguard Worker #if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM)
194*663afb9bSAndroid Build Coastguard Worker void
evutil_secure_rng_add_bytes(const char * buf,size_t n)195*663afb9bSAndroid Build Coastguard Worker evutil_secure_rng_add_bytes(const char *buf, size_t n)
196*663afb9bSAndroid Build Coastguard Worker {
197*663afb9bSAndroid Build Coastguard Worker 	arc4random_addrandom((unsigned char*)buf,
198*663afb9bSAndroid Build Coastguard Worker 	    n>(size_t)INT_MAX ? INT_MAX : (int)n);
199*663afb9bSAndroid Build Coastguard Worker }
200*663afb9bSAndroid Build Coastguard Worker #endif
201*663afb9bSAndroid Build Coastguard Worker 
202*663afb9bSAndroid Build Coastguard Worker void
evutil_free_secure_rng_globals_(void)203*663afb9bSAndroid Build Coastguard Worker evutil_free_secure_rng_globals_(void)
204*663afb9bSAndroid Build Coastguard Worker {
205*663afb9bSAndroid Build Coastguard Worker     evutil_free_secure_rng_globals_locks();
206*663afb9bSAndroid Build Coastguard Worker }
207