xref: /openbsd/sys/dev/rnd.c (revision 4fb9ab68)
1 /*	$OpenBSD: rnd.c,v 1.228 2024/06/14 10:17:05 claudio Exp $	*/
2 
3 /*
4  * Copyright (c) 2011,2020 Theo de Raadt.
5  * Copyright (c) 2008 Damien Miller.
6  * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
7  * Copyright (c) 2013 Markus Friedl.
8  * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, and the entire permission notice in its entirety,
16  *    including the disclaimer of warranties.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. The name of the author may not be used to endorse or promote
21  *    products derived from this software without specific prior
22  *    written permission.
23  *
24  * ALTERNATIVELY, this product may be distributed under the terms of
25  * the GNU Public License, in which case the provisions of the GPL are
26  * required INSTEAD OF the above restrictions.  (This clause is
27  * necessary due to a potential bad interaction between the GPL and
28  * the restrictions contained in a BSD-style copyright.)
29  *
30  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
31  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
34  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
40  * OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 /*
44  * The bootblocks pre-fill the kernel .openbsd.randomdata section with seed
45  * material (on-disk from previous boot, hopefully mixed with a hardware rng).
46  * The first arc4random(9) call initializes this seed material as a chacha
47  * state.  Calls can be done early in kernel bootstrap code -- early use is
48  * encouraged.
49  *
50  * After the kernel timeout subsystem is initialized, random_start() prepares
51  * the entropy collection mechanism enqueue_randomness() and timeout-driven
52  * mixing into the chacha state.  The first submissions come from device
53  * probes, later on interrupt-time submissions are more common.  Entropy
54  * data (and timing information) get mixed over the entropy input ring
55  * rnd_event_space[] -- the goal is to collect damage.
56  *
57  * Based upon timeouts, a selection of the entropy ring rnd_event_space[]
58  * CRC bit-distributed and XOR mixed into entropy_pool[].
59  *
60  * From time to time, entropy_pool[] is SHA512-whitened, mixed with time
61  * information again, XOR'd with the inner and outer states of the existing
62  * chacha state, to create a new chacha state.
63  *
64  * During early boot (until cold=0), enqueue operations are immediately
65  * dequeued, and mixed into the chacha.
66  */
67 
68 #include <sys/param.h>
69 #include <sys/event.h>
70 #include <sys/ioctl.h>
71 #include <sys/malloc.h>
72 #include <sys/timeout.h>
73 #include <sys/atomic.h>
74 #include <sys/task.h>
75 #include <sys/msgbuf.h>
76 #include <sys/mount.h>
77 #include <sys/syscallargs.h>
78 
79 #include <crypto/sha2.h>
80 
81 #define KEYSTREAM_ONLY
82 #include <crypto/chacha_private.h>
83 
84 #include <uvm/uvm_extern.h>
85 
86 /*
87  * For the purposes of better mixing, we use the CRC-32 polynomial as
88  * well to make a twisted Generalized Feedback Shift Register
89  *
90  * (See M. Matsumoto & Y. Kurita, 1992.  Twisted GFSR generators.  ACM
91  * Transactions on Modeling and Computer Simulation 2(3):179-194.
92  * Also see M. Matsumoto & Y. Kurita, 1994.  Twisted GFSR generators
93  * II.  ACM Transactions on Modeling and Computer Simulation 4:254-266)
94  */
95 
96 /*
97  * Stirring polynomial over GF(2). Used in add_entropy_words() below.
98  *
99  * The polynomial terms are chosen to be evenly spaced (minimum RMS
100  * distance from evenly spaced; except for the last tap, which is 1 to
101  * get the twisting happening as fast as possible.
102  *
103  * The resultant polynomial is:
104  *   2^POOLWORDS + 2^POOL_TAP1 + 2^POOL_TAP2 + 2^POOL_TAP3 + 2^POOL_TAP4 + 1
105  */
106 #define POOLWORDS	2048
107 #define POOLBYTES	(POOLWORDS*4)
108 #define POOLMASK	(POOLWORDS - 1)
109 #define	POOL_TAP1	1638
110 #define	POOL_TAP2	1231
111 #define	POOL_TAP3	819
112 #define	POOL_TAP4	411
113 
114 /*
115  * Raw entropy collection from device drivers; at interrupt context or not.
116  * enqueue_randomness() is used to submit data into the entropy input ring.
117  */
118 
119 #define QEVLEN	128		 /* must be a power of 2 */
120 #define QEVCONSUME 8		 /* how many events to consume a time */
121 
122 #define KEYSZ	32
123 #define IVSZ	8
124 #define BLOCKSZ	64
125 #define RSBUFSZ	(16*BLOCKSZ)
126 #define EBUFSIZE KEYSZ + IVSZ
127 
128 struct rand_event {
129 	u_int	re_time;
130 	u_int	re_val;
131 } rnd_event_space[QEVLEN];
132 
133 u_int	rnd_event_cons;
134 u_int	rnd_event_prod;
135 int	rnd_cold = 1;
136 int	rnd_slowextract = 1;
137 
138 void	rnd_reinit(void *v);		/* timeout to start reinit */
139 void	rnd_init(void *);			/* actually do the reinit */
140 
141 static u_int32_t entropy_pool[POOLWORDS];
142 u_int32_t entropy_pool0[POOLWORDS] __attribute__((section(".openbsd.randomdata")));
143 
144 void	dequeue_randomness(void *);
145 void	add_entropy_words(const u_int32_t *, u_int);
146 void	extract_entropy(u_int8_t *)
147     __attribute__((__bounded__(__minbytes__,1,EBUFSIZE)));
148 
149 struct timeout rnd_timeout = TIMEOUT_INITIALIZER(dequeue_randomness, NULL);
150 
151 int	filt_randomread(struct knote *, long);
152 void	filt_randomdetach(struct knote *);
153 int	filt_randomwrite(struct knote *, long);
154 
155 static void _rs_seed(u_char *, size_t);
156 static void _rs_clearseed(const void *p, size_t s);
157 
158 const struct filterops randomread_filtops = {
159 	.f_flags	= FILTEROP_ISFD,
160 	.f_attach	= NULL,
161 	.f_detach	= filt_randomdetach,
162 	.f_event	= filt_randomread,
163 };
164 
165 const struct filterops randomwrite_filtops = {
166 	.f_flags	= FILTEROP_ISFD,
167 	.f_attach	= NULL,
168 	.f_detach	= filt_randomdetach,
169 	.f_event	= filt_randomwrite,
170 };
171 
172 /*
173  * This function mixes entropy and timing into the entropy input ring.
174  */
175 static void
176 add_event_data(u_int val)
177 {
178 	struct rand_event *rep;
179 	int e;
180 
181 	e = (atomic_inc_int_nv(&rnd_event_prod) - 1) & (QEVLEN-1);
182 	rep = &rnd_event_space[e];
183 	rep->re_time += cpu_rnd_messybits();
184 	rep->re_val += val;
185 }
186 
187 void
188 enqueue_randomness(u_int val)
189 {
190 	add_event_data(val);
191 
192 	if (rnd_cold) {
193 		dequeue_randomness(NULL);
194 		rnd_init(NULL);
195 		if (!cold)
196 			rnd_cold = 0;
197 	} else if (!timeout_pending(&rnd_timeout) &&
198 	    (rnd_event_prod - rnd_event_cons) > QEVCONSUME) {
199 		rnd_slowextract = min(rnd_slowextract * 2, 5000);
200 		timeout_add_msec(&rnd_timeout, rnd_slowextract * 10);
201 	}
202 }
203 
204 /*
205  * This function merges entropy ring information into the buffer using
206  * a polynomial to spread the bits.
207  */
208 void
209 add_entropy_words(const u_int32_t *buf, u_int n)
210 {
211 	/* derived from IEEE 802.3 CRC-32 */
212 	static const u_int32_t twist_table[8] = {
213 		0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
214 		0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
215 	};
216 	static u_int	entropy_add_ptr;
217 	static u_char	entropy_input_rotate;
218 
219 	for (; n--; buf++) {
220 		u_int32_t w = (*buf << entropy_input_rotate) |
221 		    (*buf >> ((32 - entropy_input_rotate) & 31));
222 		u_int i = entropy_add_ptr =
223 		    (entropy_add_ptr - 1) & POOLMASK;
224 		/*
225 		 * Normally, we add 7 bits of rotation to the pool.
226 		 * At the beginning of the pool, add an extra 7 bits
227 		 * rotation, so that successive passes spread the
228 		 * input bits across the pool evenly.
229 		 */
230 		entropy_input_rotate =
231 		    (entropy_input_rotate + (i ? 7 : 14)) & 31;
232 
233 		/* XOR pool contents corresponding to polynomial terms */
234 		w ^= entropy_pool[(i + POOL_TAP1) & POOLMASK] ^
235 		     entropy_pool[(i + POOL_TAP2) & POOLMASK] ^
236 		     entropy_pool[(i + POOL_TAP3) & POOLMASK] ^
237 		     entropy_pool[(i + POOL_TAP4) & POOLMASK] ^
238 		     entropy_pool[(i + 1) & POOLMASK] ^
239 		     entropy_pool[i]; /* + 2^POOLWORDS */
240 
241 		entropy_pool[i] = (w >> 3) ^ twist_table[w & 7];
242 	}
243 }
244 
245 /*
246  * Pulls entropy out of the queue and merges it into the pool with the
247  * CRC.  This takes a mix of fresh entries from the producer end of the
248  * queue and entries from the consumer end of the queue which are
249  * likely to have collected more damage.
250  */
251 void
252 dequeue_randomness(void *v)
253 {
254 	u_int32_t buf[2];
255 	u_int startp, startc, i;
256 
257 	/* Some very new damage */
258 	startp = rnd_event_prod - QEVCONSUME;
259 	for (i = 0; i < QEVCONSUME; i++) {
260 		u_int e = (startp + i) & (QEVLEN-1);
261 
262 		buf[0] = rnd_event_space[e].re_time;
263 		buf[1] = rnd_event_space[e].re_val;
264 		add_entropy_words(buf, 2);
265 	}
266 	/* and some probably more damaged */
267 	startc = atomic_add_int_nv(&rnd_event_cons, QEVCONSUME) - QEVCONSUME;
268 	for (i = 0; i < QEVCONSUME; i++) {
269 		u_int e = (startc + i) & (QEVLEN-1);
270 
271 		buf[0] = rnd_event_space[e].re_time;
272 		buf[1] = rnd_event_space[e].re_val;
273 		add_entropy_words(buf, 2);
274 	}
275 }
276 
277 /*
278  * Grabs a chunk from the entropy_pool[] and slams it through SHA512 when
279  * requested.
280  */
281 void
282 extract_entropy(u_int8_t *buf)
283 {
284 	static u_int32_t extract_pool[POOLWORDS];
285 	u_char digest[SHA512_DIGEST_LENGTH];
286 	SHA2_CTX shactx;
287 
288 #if SHA512_DIGEST_LENGTH < EBUFSIZE
289 #error "need more bigger hash output"
290 #endif
291 
292 	/*
293 	 * INTENTIONALLY not protected by any lock.  Races during
294 	 * memcpy() result in acceptable input data; races during
295 	 * SHA512Update() would create nasty data dependencies.  We
296 	 * do not rely on this as a benefit, but if it happens, cool.
297 	 */
298 	memcpy(extract_pool, entropy_pool, sizeof(extract_pool));
299 
300 	/* Hash the pool to get the output */
301 	SHA512Init(&shactx);
302 	SHA512Update(&shactx, (u_int8_t *)extract_pool, sizeof(extract_pool));
303 	SHA512Final(digest, &shactx);
304 
305 	/* Copy data to destination buffer */
306 	memcpy(buf, digest, EBUFSIZE);
307 
308 	/*
309 	 * Modify pool so next hash will produce different results.
310 	 */
311 	add_event_data(extract_pool[0]);
312 	dequeue_randomness(NULL);
313 
314 	/* Wipe data from memory */
315 	explicit_bzero(extract_pool, sizeof(extract_pool));
316 	explicit_bzero(digest, sizeof(digest));
317 }
318 
319 /* random keystream by ChaCha */
320 
321 struct mutex rndlock = MUTEX_INITIALIZER(IPL_HIGH);
322 struct timeout rndreinit_timeout = TIMEOUT_INITIALIZER(rnd_reinit, NULL);
323 struct task rnd_task = TASK_INITIALIZER(rnd_init, NULL);
324 
325 static chacha_ctx rs;		/* chacha context for random keystream */
326 /* keystream blocks (also chacha seed from boot) */
327 static u_char rs_buf[RSBUFSZ];
328 u_char rs_buf0[RSBUFSZ] __attribute__((section(".openbsd.randomdata")));
329 static size_t rs_have;		/* valid bytes at end of rs_buf */
330 static size_t rs_count;		/* bytes till reseed */
331 
332 void
333 suspend_randomness(void)
334 {
335 	struct timespec ts;
336 
337 	getnanotime(&ts);
338 	enqueue_randomness(ts.tv_sec);
339 	enqueue_randomness(ts.tv_nsec);
340 
341 	dequeue_randomness(NULL);
342 	rs_count = 0;
343 	arc4random_buf(entropy_pool, sizeof(entropy_pool));
344 }
345 
346 void
347 resume_randomness(char *buf, size_t buflen)
348 {
349 	struct timespec ts;
350 
351 	if (buf && buflen)
352 		_rs_seed(buf, buflen);
353 	getnanotime(&ts);
354 	enqueue_randomness(ts.tv_sec);
355 	enqueue_randomness(ts.tv_nsec);
356 
357 	dequeue_randomness(NULL);
358 	rs_count = 0;
359 }
360 
361 static inline void _rs_rekey(u_char *dat, size_t datlen);
362 
363 static inline void
364 _rs_init(u_char *buf, size_t n)
365 {
366 	KASSERT(n >= KEYSZ + IVSZ);
367 	chacha_keysetup(&rs, buf, KEYSZ * 8);
368 	chacha_ivsetup(&rs, buf + KEYSZ, NULL);
369 }
370 
371 static void
372 _rs_seed(u_char *buf, size_t n)
373 {
374 	_rs_rekey(buf, n);
375 
376 	/* invalidate rs_buf */
377 	rs_have = 0;
378 	memset(rs_buf, 0, sizeof(rs_buf));
379 
380 	rs_count = 1600000;
381 }
382 
383 static void
384 _rs_stir(int do_lock)
385 {
386 	struct timespec ts;
387 	u_int8_t buf[EBUFSIZE], *p;
388 	int i;
389 
390 	/*
391 	 * Use SHA512 PRNG data and a system timespec; early in the boot
392 	 * process this is the best we can do -- some architectures do
393 	 * not collect entropy very well during this time, but may have
394 	 * clock information which is better than nothing.
395 	 */
396 	extract_entropy(buf);
397 
398 	nanotime(&ts);
399 	for (p = (u_int8_t *)&ts, i = 0; i < sizeof(ts); i++)
400 		buf[i] ^= p[i];
401 
402 	if (do_lock)
403 		mtx_enter(&rndlock);
404 	_rs_seed(buf, sizeof(buf));
405 	if (do_lock)
406 		mtx_leave(&rndlock);
407 	explicit_bzero(buf, sizeof(buf));
408 
409 	/* encourage fast-dequeue again */
410 	rnd_slowextract = 1;
411 }
412 
413 static inline void
414 _rs_stir_if_needed(size_t len)
415 {
416 	static int rs_initialized;
417 
418 	if (!rs_initialized) {
419 		memcpy(entropy_pool, entropy_pool0, sizeof(entropy_pool));
420 		memcpy(rs_buf, rs_buf0, sizeof(rs_buf));
421 		/* seeds cannot be cleaned yet, random_start() will do so */
422 		_rs_init(rs_buf, KEYSZ + IVSZ);
423 		rs_count = 1024 * 1024 * 1024;	/* until main() runs */
424 		rs_initialized = 1;
425 	} else if (rs_count <= len)
426 		_rs_stir(0);
427 	else
428 		rs_count -= len;
429 }
430 
431 static void
432 _rs_clearseed(const void *p, size_t s)
433 {
434 	struct kmem_dyn_mode kd_avoidalias;
435 	vaddr_t va = trunc_page((vaddr_t)p);
436 	vsize_t off = (vaddr_t)p - va;
437 	vsize_t len;
438 	vaddr_t rwva;
439 	paddr_t pa;
440 
441 	while (s > 0) {
442 		pmap_extract(pmap_kernel(), va, &pa);
443 
444 		memset(&kd_avoidalias, 0, sizeof(kd_avoidalias));
445 		kd_avoidalias.kd_prefer = pa;
446 		kd_avoidalias.kd_waitok = 1;
447 		rwva = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none,
448 		    &kd_avoidalias);
449 		if (!rwva)
450 			panic("_rs_clearseed");
451 
452 		pmap_kenter_pa(rwva, pa, PROT_READ | PROT_WRITE);
453 		pmap_update(pmap_kernel());
454 
455 		len = MIN(s, PAGE_SIZE - off);
456 		explicit_bzero((void *)(rwva + off), len);
457 
458 		pmap_kremove(rwva, PAGE_SIZE);
459 		km_free((void *)rwva, PAGE_SIZE, &kv_any, &kp_none);
460 
461 		va += PAGE_SIZE;
462 		s -= len;
463 		off = 0;
464 	}
465 }
466 
467 static inline void
468 _rs_rekey(u_char *dat, size_t datlen)
469 {
470 #ifndef KEYSTREAM_ONLY
471 	memset(rs_buf, 0, sizeof(rs_buf));
472 #endif
473 	/* fill rs_buf with the keystream */
474 	chacha_encrypt_bytes(&rs, rs_buf, rs_buf, sizeof(rs_buf));
475 	/* mix in optional user provided data */
476 	if (dat) {
477 		size_t i, m;
478 
479 		m = MIN(datlen, KEYSZ + IVSZ);
480 		for (i = 0; i < m; i++)
481 			rs_buf[i] ^= dat[i];
482 	}
483 	/* immediately reinit for backtracking resistance */
484 	_rs_init(rs_buf, KEYSZ + IVSZ);
485 	memset(rs_buf, 0, KEYSZ + IVSZ);
486 	rs_have = sizeof(rs_buf) - KEYSZ - IVSZ;
487 }
488 
489 static inline void
490 _rs_random_buf(void *_buf, size_t n)
491 {
492 	u_char *buf = (u_char *)_buf;
493 	size_t m;
494 
495 	_rs_stir_if_needed(n);
496 	while (n > 0) {
497 		if (rs_have > 0) {
498 			m = MIN(n, rs_have);
499 			memcpy(buf, rs_buf + sizeof(rs_buf) - rs_have, m);
500 			memset(rs_buf + sizeof(rs_buf) - rs_have, 0, m);
501 			buf += m;
502 			n -= m;
503 			rs_have -= m;
504 		}
505 		if (rs_have == 0)
506 			_rs_rekey(NULL, 0);
507 	}
508 }
509 
510 static inline void
511 _rs_random_u32(u_int32_t *val)
512 {
513 	_rs_stir_if_needed(sizeof(*val));
514 	if (rs_have < sizeof(*val))
515 		_rs_rekey(NULL, 0);
516 	memcpy(val, rs_buf + sizeof(rs_buf) - rs_have, sizeof(*val));
517 	memset(rs_buf + sizeof(rs_buf) - rs_have, 0, sizeof(*val));
518 	rs_have -= sizeof(*val);
519 }
520 
521 /* Return one word of randomness from a ChaCha20 generator */
522 u_int32_t
523 arc4random(void)
524 {
525 	u_int32_t ret;
526 
527 	mtx_enter(&rndlock);
528 	_rs_random_u32(&ret);
529 	mtx_leave(&rndlock);
530 	return ret;
531 }
532 
533 /*
534  * Fill a buffer of arbitrary length with ChaCha20-derived randomness.
535  */
536 void
537 arc4random_buf(void *buf, size_t n)
538 {
539 	mtx_enter(&rndlock);
540 	_rs_random_buf(buf, n);
541 	mtx_leave(&rndlock);
542 }
543 
544 /*
545  * Allocate a new ChaCha20 context for the caller to use.
546  */
547 struct arc4random_ctx *
548 arc4random_ctx_new(void)
549 {
550 	char keybuf[KEYSZ + IVSZ];
551 
552 	chacha_ctx *ctx = malloc(sizeof(chacha_ctx), M_TEMP, M_WAITOK);
553 	arc4random_buf(keybuf, KEYSZ + IVSZ);
554 	chacha_keysetup(ctx, keybuf, KEYSZ * 8);
555 	chacha_ivsetup(ctx, keybuf + KEYSZ, NULL);
556 	explicit_bzero(keybuf, sizeof(keybuf));
557 	return (struct arc4random_ctx *)ctx;
558 }
559 
560 /*
561  * Free a ChaCha20 context created by arc4random_ctx_new()
562  */
563 void
564 arc4random_ctx_free(struct arc4random_ctx *ctx)
565 {
566 	explicit_bzero(ctx, sizeof(chacha_ctx));
567 	free(ctx, M_TEMP, sizeof(chacha_ctx));
568 }
569 
570 /*
571  * Use a given ChaCha20 context to fill a buffer
572  */
573 void
574 arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n)
575 {
576 #ifndef KEYSTREAM_ONLY
577 	memset(buf, 0, n);
578 #endif
579 	chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n);
580 }
581 
582 /*
583  * Calculate a uniformly distributed random number less than upper_bound
584  * avoiding "modulo bias".
585  *
586  * Uniformity is achieved by generating new random numbers until the one
587  * returned is outside the range [0, 2**32 % upper_bound).  This
588  * guarantees the selected random number will be inside
589  * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
590  * after reduction modulo upper_bound.
591  */
592 u_int32_t
593 arc4random_uniform(u_int32_t upper_bound)
594 {
595 	u_int32_t r, min;
596 
597 	if (upper_bound < 2)
598 		return 0;
599 
600 	/* 2**32 % x == (2**32 - x) % x */
601 	min = -upper_bound % upper_bound;
602 
603 	/*
604 	 * This could theoretically loop forever but each retry has
605 	 * p > 0.5 (worst case, usually far better) of selecting a
606 	 * number inside the range we need, so it should rarely need
607 	 * to re-roll.
608 	 */
609 	for (;;) {
610 		r = arc4random();
611 		if (r >= min)
612 			break;
613 	}
614 
615 	return r % upper_bound;
616 }
617 
618 void
619 rnd_init(void *null)
620 {
621 	_rs_stir(1);
622 }
623 
624 /*
625  * Called by timeout to mark arc4 for stirring,
626  */
627 void
628 rnd_reinit(void *v)
629 {
630 	task_add(systq, &rnd_task);
631 	/* 10 minutes, per dm@'s suggestion */
632 	timeout_add_sec(&rndreinit_timeout, 10 * 60);
633 }
634 
635 /*
636  * Start periodic services inside the random subsystem, which pull
637  * entropy forward, hash it, and re-seed the random stream as needed.
638  */
639 void
640 random_start(int goodseed)
641 {
642 	extern char etext[];
643 
644 #if !defined(NO_PROPOLICE)
645 	extern long __guard_local;
646 
647 	if (__guard_local == 0)
648 		printf("warning: no entropy supplied by boot loader\n");
649 #endif
650 
651 	_rs_clearseed(entropy_pool0, sizeof(entropy_pool0));
652 	_rs_clearseed(rs_buf0, sizeof(rs_buf0));
653 
654 	/* Message buffer may contain data from previous boot */
655 	if (msgbufp->msg_magic == MSG_MAGIC)
656 		add_entropy_words((u_int32_t *)msgbufp->msg_bufc,
657 		    msgbufp->msg_bufs / sizeof(u_int32_t));
658 	add_entropy_words((u_int32_t *)etext - 32*1024,
659 	    8192/sizeof(u_int32_t));
660 
661 	dequeue_randomness(NULL);
662 	rnd_init(NULL);
663 	rnd_reinit(NULL);
664 
665 	if (goodseed)
666 		printf("random: good seed from bootblocks\n");
667 	else {
668 		/* XXX kernel should work harder here */
669 		printf("random: boothowto does not indicate good seed\n");
670 	}
671 }
672 
673 int
674 randomopen(dev_t dev, int flag, int mode, struct proc *p)
675 {
676 	return 0;
677 }
678 
679 int
680 randomclose(dev_t dev, int flag, int mode, struct proc *p)
681 {
682 	return 0;
683 }
684 
685 /*
686  * Maximum number of bytes to serve directly from the main ChaCha
687  * pool. Larger requests are served from a discrete ChaCha instance keyed
688  * from the main pool.
689  */
690 #define RND_MAIN_MAX_BYTES	2048
691 
692 int
693 randomread(dev_t dev, struct uio *uio, int ioflag)
694 {
695 	struct arc4random_ctx *lctx = NULL;
696 	size_t		total = uio->uio_resid;
697 	u_char		*buf;
698 	int		ret = 0;
699 
700 	if (uio->uio_resid == 0)
701 		return 0;
702 
703 	buf = malloc(POOLBYTES, M_TEMP, M_WAITOK);
704 	if (total > RND_MAIN_MAX_BYTES)
705 		lctx = arc4random_ctx_new();
706 
707 	while (ret == 0 && uio->uio_resid > 0) {
708 		size_t	n = ulmin(POOLBYTES, uio->uio_resid);
709 
710 		if (lctx != NULL)
711 			arc4random_ctx_buf(lctx, buf, n);
712 		else
713 			arc4random_buf(buf, n);
714 		ret = uiomove(buf, n, uio);
715 		if (ret == 0 && uio->uio_resid > 0)
716 			yield();
717 	}
718 	if (lctx != NULL)
719 		arc4random_ctx_free(lctx);
720 	explicit_bzero(buf, POOLBYTES);
721 	free(buf, M_TEMP, POOLBYTES);
722 	return ret;
723 }
724 
725 int
726 randomwrite(dev_t dev, struct uio *uio, int flags)
727 {
728 	int		ret = 0, newdata = 0;
729 	u_int32_t	*buf;
730 
731 	if (uio->uio_resid == 0)
732 		return 0;
733 
734 	buf = malloc(POOLBYTES, M_TEMP, M_WAITOK);
735 
736 	while (ret == 0 && uio->uio_resid > 0) {
737 		size_t	n = ulmin(POOLBYTES, uio->uio_resid);
738 
739 		ret = uiomove(buf, n, uio);
740 		if (ret != 0)
741 			break;
742 		while (n % sizeof(u_int32_t))
743 			((u_int8_t *)buf)[n++] = 0;
744 		add_entropy_words(buf, n / 4);
745 		if (uio->uio_resid > 0)
746 			yield();
747 		newdata = 1;
748 	}
749 
750 	if (newdata)
751 		rnd_init(NULL);
752 
753 	explicit_bzero(buf, POOLBYTES);
754 	free(buf, M_TEMP, POOLBYTES);
755 	return ret;
756 }
757 
758 int
759 randomkqfilter(dev_t dev, struct knote *kn)
760 {
761 	switch (kn->kn_filter) {
762 	case EVFILT_READ:
763 		kn->kn_fop = &randomread_filtops;
764 		break;
765 	case EVFILT_WRITE:
766 		kn->kn_fop = &randomwrite_filtops;
767 		break;
768 	default:
769 		return (EINVAL);
770 	}
771 
772 	return (0);
773 }
774 
775 void
776 filt_randomdetach(struct knote *kn)
777 {
778 }
779 
780 int
781 filt_randomread(struct knote *kn, long hint)
782 {
783 	kn->kn_data = RND_MAIN_MAX_BYTES;
784 	return (1);
785 }
786 
787 int
788 filt_randomwrite(struct knote *kn, long hint)
789 {
790 	kn->kn_data = POOLBYTES;
791 	return (1);
792 }
793 
794 int
795 randomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
796 {
797 	switch (cmd) {
798 	case FIOASYNC:
799 		/* No async flag in softc so this is a no-op. */
800 		break;
801 	case FIONBIO:
802 		/* Handled in the upper FS layer. */
803 		break;
804 	default:
805 		return ENOTTY;
806 	}
807 	return 0;
808 }
809 
810 int
811 sys_getentropy(struct proc *p, void *v, register_t *retval)
812 {
813 	struct sys_getentropy_args /* {
814 		syscallarg(void *) buf;
815 		syscallarg(size_t) nbyte;
816 	} */ *uap = v;
817 	char buf[256];
818 	int error;
819 
820 	if (SCARG(uap, nbyte) > sizeof(buf))
821 		return (EIO);
822 	arc4random_buf(buf, SCARG(uap, nbyte));
823 	if ((error = copyout(buf, SCARG(uap, buf), SCARG(uap, nbyte))) != 0)
824 		return (error);
825 	explicit_bzero(buf, sizeof(buf));
826 	*retval = 0;
827 	return (0);
828 }
829