xref: /minix/external/bsd/bind/dist/lib/isc/entropy.c (revision 00b67f09)
1 /*	$NetBSD: entropy.c,v 1.5 2014/12/10 04:37:59 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2007, 2009, 2010, 2014  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 2000-2003  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: entropy.c,v 1.22 2010/08/10 23:48:19 tbox Exp  */
21 
22 /*! \file
23  * \brief
24  * This is the system independent part of the entropy module.  It is
25  * compiled via inclusion from the relevant OS source file, ie,
26  * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c.
27  *
28  * \author Much of this code is modeled after the NetBSD /dev/random implementation,
29  * written by Michael Graff <explorer@netbsd.org>.
30  */
31 
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 
36 #include <isc/buffer.h>
37 #include <isc/entropy.h>
38 #include <isc/keyboard.h>
39 #include <isc/list.h>
40 #include <isc/magic.h>
41 #include <isc/mem.h>
42 #include <isc/msgs.h>
43 #include <isc/mutex.h>
44 #include <isc/platform.h>
45 #include <isc/region.h>
46 #include <isc/sha1.h>
47 #include <isc/string.h>
48 #include <isc/time.h>
49 #include <isc/util.h>
50 
51 #ifdef PKCS11CRYPTO
52 #include <pk11/pk11.h>
53 #endif
54 
55 #define ENTROPY_MAGIC		ISC_MAGIC('E', 'n', 't', 'e')
56 #define SOURCE_MAGIC		ISC_MAGIC('E', 'n', 't', 's')
57 
58 #define VALID_ENTROPY(e)	ISC_MAGIC_VALID(e, ENTROPY_MAGIC)
59 #define VALID_SOURCE(s)		ISC_MAGIC_VALID(s, SOURCE_MAGIC)
60 
61 /***
62  *** "constants."  Do not change these unless you _really_ know what
63  *** you are doing.
64  ***/
65 
66 /*%
67  * Size of entropy pool in 32-bit words.  This _MUST_ be a power of 2.
68  */
69 #define RND_POOLWORDS	128
70 /*% Pool in bytes. */
71 #define RND_POOLBYTES	(RND_POOLWORDS * 4)
72 /*% Pool in bits. */
73 #define RND_POOLBITS	(RND_POOLWORDS * 32)
74 
75 /*%
76  * Number of bytes returned per hash.  This must be true:
77  *	threshold * 2 <= digest_size_in_bytes
78  */
79 #define RND_ENTROPY_THRESHOLD	10
80 #define THRESHOLD_BITS		(RND_ENTROPY_THRESHOLD * 8)
81 
82 /*%
83  * Size of the input event queue in samples.
84  */
85 #define RND_EVENTQSIZE	32
86 
87 /*%
88  * The number of times we'll "reseed" for pseudorandom seeds.  This is an
89  * extremely weak pseudorandom seed.  If the caller is using lots of
90  * pseudorandom data and they cannot provide a stronger random source,
91  * there is little we can do other than hope they're smart enough to
92  * call _adddata() with something better than we can come up with.
93  */
94 #define RND_INITIALIZE	128
95 
96 /*% Entropy Pool */
97 typedef struct {
98 	isc_uint32_t	cursor;		/*%< current add point in the pool */
99 	isc_uint32_t	entropy;	/*%< current entropy estimate in bits */
100 	isc_uint32_t	pseudo;		/*%< bits extracted in pseudorandom */
101 	isc_uint32_t	rotate;		/*%< how many bits to rotate by */
102 	isc_uint32_t	pool[RND_POOLWORDS];	/*%< random pool data */
103 } isc_entropypool_t;
104 
105 struct isc_entropy {
106 	unsigned int			magic;
107 	isc_mem_t		       *mctx;
108 	isc_mutex_t			lock;
109 	unsigned int			refcnt;
110 	isc_uint32_t			initialized;
111 	isc_uint32_t			initcount;
112 	isc_entropypool_t		pool;
113 	unsigned int			nsources;
114 	isc_entropysource_t	       *nextsource;
115 	ISC_LIST(isc_entropysource_t)	sources;
116 };
117 
118 /*% Sample Queue */
119 typedef struct {
120 	isc_uint32_t	last_time;	/*%< last time recorded */
121 	isc_uint32_t	last_delta;	/*%< last delta value */
122 	isc_uint32_t	last_delta2;	/*%< last delta2 value */
123 	isc_uint32_t	nsamples;	/*%< number of samples filled in */
124 	isc_uint32_t   *samples;	/*%< the samples */
125 	isc_uint32_t   *extra;		/*%< extra samples added in */
126 } sample_queue_t;
127 
128 typedef struct {
129 	sample_queue_t	samplequeue;
130 } isc_entropysamplesource_t;
131 
132 typedef struct {
133 	isc_boolean_t		start_called;
134 	isc_entropystart_t	startfunc;
135 	isc_entropyget_t	getfunc;
136 	isc_entropystop_t	stopfunc;
137 	void		       *arg;
138 	sample_queue_t		samplequeue;
139 } isc_cbsource_t;
140 
141 typedef struct {
142 	FILESOURCE_HANDLE_TYPE handle;
143 } isc_entropyfilesource_t;
144 
145 struct isc_entropysource {
146 	unsigned int	magic;
147 	unsigned int	type;
148 	isc_entropy_t  *ent;
149 	isc_uint32_t	total;		/*%< entropy from this source */
150 	ISC_LINK(isc_entropysource_t)	link;
151 	char		name[32];
152 	isc_boolean_t	bad;
153 	isc_boolean_t	warn_keyboard;
154 	isc_keyboard_t	kbd;
155 	union {
156 		isc_entropysamplesource_t	sample;
157 		isc_entropyfilesource_t		file;
158 		isc_cbsource_t			callback;
159 		isc_entropyusocketsource_t	usocket;
160 	} sources;
161 };
162 
163 #define ENTROPY_SOURCETYPE_SAMPLE	1	/*%< Type is a sample source */
164 #define ENTROPY_SOURCETYPE_FILE		2	/*%< Type is a file source */
165 #define ENTROPY_SOURCETYPE_CALLBACK	3	/*%< Type is a callback source */
166 #define ENTROPY_SOURCETYPE_USOCKET	4	/*%< Type is a Unix socket source */
167 
168 /*@{*/
169 /*%
170  * The random pool "taps"
171  */
172 #define TAP1	99
173 #define TAP2	59
174 #define TAP3	31
175 #define TAP4	 9
176 #define TAP5	 7
177 /*@}*/
178 
179 /*@{*/
180 /*%
181  * Declarations for function provided by the system dependent sources that
182  * include this file.
183  */
184 static void
185 fillpool(isc_entropy_t *, unsigned int, isc_boolean_t);
186 
187 static int
188 wait_for_sources(isc_entropy_t *);
189 
190 static void
191 destroyfilesource(isc_entropyfilesource_t *source);
192 
193 static void
194 destroyusocketsource(isc_entropyusocketsource_t *source);
195 
196 /*@}*/
197 
198 static void
samplequeue_release(isc_entropy_t * ent,sample_queue_t * sq)199 samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) {
200 	REQUIRE(sq->samples != NULL);
201 	REQUIRE(sq->extra != NULL);
202 
203 	isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4);
204 	isc_mem_put(ent->mctx, sq->extra, RND_EVENTQSIZE * 4);
205 	sq->samples = NULL;
206 	sq->extra = NULL;
207 }
208 
209 static isc_result_t
samplesource_allocate(isc_entropy_t * ent,sample_queue_t * sq)210 samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) {
211 	sq->samples = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4);
212 	if (sq->samples == NULL)
213 		return (ISC_R_NOMEMORY);
214 
215 	sq->extra = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4);
216 	if (sq->extra == NULL) {
217 		isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4);
218 		sq->samples = NULL;
219 		return (ISC_R_NOMEMORY);
220 	}
221 
222 	sq->nsamples = 0;
223 
224 	return (ISC_R_SUCCESS);
225 }
226 
227 /*%
228  * Add in entropy, even when the value we're adding in could be
229  * very large.
230  */
231 static inline void
add_entropy(isc_entropy_t * ent,isc_uint32_t entropy)232 add_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
233 	/* clamp input.  Yes, this must be done. */
234 	entropy = ISC_MIN(entropy, RND_POOLBITS);
235 	/* Add in the entropy we already have. */
236 	entropy += ent->pool.entropy;
237 	/* Clamp. */
238 	ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS);
239 }
240 
241 /*%
242  * Decrement the amount of entropy the pool has.
243  */
244 static inline void
subtract_entropy(isc_entropy_t * ent,isc_uint32_t entropy)245 subtract_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
246 	entropy = ISC_MIN(entropy, ent->pool.entropy);
247 	ent->pool.entropy -= entropy;
248 }
249 
250 /*!
251  * Add in entropy, even when the value we're adding in could be
252  * very large.
253  */
254 static inline void
add_pseudo(isc_entropy_t * ent,isc_uint32_t pseudo)255 add_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
256 	/* clamp input.  Yes, this must be done. */
257 	pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
258 	/* Add in the pseudo we already have. */
259 	pseudo += ent->pool.pseudo;
260 	/* Clamp. */
261 	ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
262 }
263 
264 /*!
265  * Decrement the amount of pseudo the pool has.
266  */
267 static inline void
subtract_pseudo(isc_entropy_t * ent,isc_uint32_t pseudo)268 subtract_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
269 	pseudo = ISC_MIN(pseudo, ent->pool.pseudo);
270 	ent->pool.pseudo -= pseudo;
271 }
272 
273 /*!
274  * Add one word to the pool, rotating the input as needed.
275  */
276 static inline void
entropypool_add_word(isc_entropypool_t * rp,isc_uint32_t val)277 entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) {
278 	/*
279 	 * Steal some values out of the pool, and xor them into the
280 	 * word we were given.
281 	 *
282 	 * Mix the new value into the pool using xor.  This will
283 	 * prevent the actual values from being known to the caller
284 	 * since the previous values are assumed to be unknown as well.
285 	 */
286 	val ^= rp->pool[(rp->cursor + TAP1) & (RND_POOLWORDS - 1)];
287 	val ^= rp->pool[(rp->cursor + TAP2) & (RND_POOLWORDS - 1)];
288 	val ^= rp->pool[(rp->cursor + TAP3) & (RND_POOLWORDS - 1)];
289 	val ^= rp->pool[(rp->cursor + TAP4) & (RND_POOLWORDS - 1)];
290 	val ^= rp->pool[(rp->cursor + TAP5) & (RND_POOLWORDS - 1)];
291 	if (rp->rotate == 0)
292 		rp->pool[rp->cursor++] ^= val;
293 	else
294 		rp->pool[rp->cursor++] ^=
295 		  ((val << rp->rotate) | (val >> (32 - rp->rotate)));
296 
297 	/*
298 	 * If we have looped around the pool, increment the rotate
299 	 * variable so the next value will get xored in rotated to
300 	 * a different position.
301 	 * Increment by a value that is relatively prime to the word size
302 	 * to try to spread the bits throughout the pool quickly when the
303 	 * pool is empty.
304 	 */
305 	if (rp->cursor == RND_POOLWORDS) {
306 		rp->cursor = 0;
307 		rp->rotate = (rp->rotate + 7) & 31;
308 	}
309 }
310 
311 /*!
312  * Add a buffer's worth of data to the pool.
313  *
314  * Requires that the lock is held on the entropy pool.
315  */
316 static void
entropypool_adddata(isc_entropy_t * ent,void * p,unsigned int len,isc_uint32_t entropy)317 entropypool_adddata(isc_entropy_t *ent, void *p, unsigned int len,
318 		    isc_uint32_t entropy)
319 {
320 	isc_uint32_t val;
321 	unsigned long addr;
322 	isc_uint8_t *buf;
323 
324 	addr = (unsigned long)p;
325 	buf = p;
326 
327 	if ((addr & 0x03U) != 0U) {
328 		val = 0;
329 		switch (len) {
330 		case 3:
331 			val = *buf++;
332 			len--;
333 		case 2:
334 			val = val << 8 | *buf++;
335 			len--;
336 		case 1:
337 			val = val << 8 | *buf++;
338 			len--;
339 		}
340 
341 		entropypool_add_word(&ent->pool, val);
342 	}
343 
344 	for (; len > 3; len -= 4) {
345 		val = *((isc_uint32_t *)buf);
346 
347 		entropypool_add_word(&ent->pool, val);
348 		buf += 4;
349 	}
350 
351 	if (len != 0) {
352 		val = 0;
353 		switch (len) {
354 		case 3:
355 			val = *buf++;
356 		case 2:
357 			val = val << 8 | *buf++;
358 		case 1:
359 			val = val << 8 | *buf++;
360 		}
361 
362 		entropypool_add_word(&ent->pool, val);
363 	}
364 
365 	add_entropy(ent, entropy);
366 	subtract_pseudo(ent, entropy);
367 }
368 
369 static inline void
reseed(isc_entropy_t * ent)370 reseed(isc_entropy_t *ent) {
371 	isc_time_t t;
372 	pid_t pid;
373 
374 	if (ent->initcount == 0) {
375 		pid = getpid();
376 		entropypool_adddata(ent, &pid, sizeof(pid), 0);
377 		pid = getppid();
378 		entropypool_adddata(ent, &pid, sizeof(pid), 0);
379 	}
380 
381 	/*!
382 	 * After we've reseeded 100 times, only add new timing info every
383 	 * 50 requests.  This will keep us from using lots and lots of
384 	 * CPU just to return bad pseudorandom data anyway.
385 	 */
386 	if (ent->initcount > 100)
387 		if ((ent->initcount % 50) != 0)
388 			return;
389 
390 	TIME_NOW(&t);
391 	entropypool_adddata(ent, &t, sizeof(t), 0);
392 	ent->initcount++;
393 }
394 
395 static inline unsigned int
estimate_entropy(sample_queue_t * sq,isc_uint32_t t)396 estimate_entropy(sample_queue_t *sq, isc_uint32_t t) {
397 	isc_int32_t		delta;
398 	isc_int32_t		delta2;
399 	isc_int32_t		delta3;
400 
401 	/*!
402 	 * If the time counter has overflowed, calculate the real difference.
403 	 * If it has not, it is simpler.
404 	 */
405 	if (t < sq->last_time)
406 		delta = UINT_MAX - sq->last_time + t;
407 	else
408 		delta = sq->last_time - t;
409 
410 	if (delta < 0)
411 		delta = -delta;
412 
413 	/*
414 	 * Calculate the second and third order differentials
415 	 */
416 	delta2 = sq->last_delta - delta;
417 	if (delta2 < 0)
418 		delta2 = -delta2;
419 
420 	delta3 = sq->last_delta2 - delta2;
421 	if (delta3 < 0)
422 		delta3 = -delta3;
423 
424 	sq->last_time = t;
425 	sq->last_delta = delta;
426 	sq->last_delta2 = delta2;
427 
428 	/*
429 	 * If any delta is 0, we got no entropy.  If all are non-zero, we
430 	 * might have something.
431 	 */
432 	if (delta == 0 || delta2 == 0 || delta3 == 0)
433 		return 0;
434 
435 	/*
436 	 * We could find the smallest delta and claim we got log2(delta)
437 	 * bits, but for now return that we found 1 bit.
438 	 */
439 	return 1;
440 }
441 
442 static unsigned int
crunchsamples(isc_entropy_t * ent,sample_queue_t * sq)443 crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) {
444 	unsigned int ns;
445 	unsigned int added;
446 
447 	if (sq->nsamples < 6)
448 		return (0);
449 
450 	added = 0;
451 	sq->last_time = sq->samples[0];
452 	sq->last_delta = 0;
453 	sq->last_delta2 = 0;
454 
455 	/*
456 	 * Prime the values by adding in the first 4 samples in.  This
457 	 * should completely initialize the delta calculations.
458 	 */
459 	for (ns = 0; ns < 4; ns++)
460 		(void)estimate_entropy(sq, sq->samples[ns]);
461 
462 	for (ns = 4; ns < sq->nsamples; ns++)
463 		added += estimate_entropy(sq, sq->samples[ns]);
464 
465 	entropypool_adddata(ent, sq->samples, sq->nsamples * 4, added);
466 	entropypool_adddata(ent, sq->extra, sq->nsamples * 4, 0);
467 
468 	/*
469 	 * Move the last 4 samples into the first 4 positions, and start
470 	 * adding new samples from that point.
471 	 */
472 	for (ns = 0; ns < 4; ns++) {
473 		sq->samples[ns] = sq->samples[sq->nsamples - 4 + ns];
474 		sq->extra[ns] = sq->extra[sq->nsamples - 4 + ns];
475 	}
476 
477 	sq->nsamples = 4;
478 
479 	return (added);
480 }
481 
482 static unsigned int
get_from_callback(isc_entropysource_t * source,unsigned int desired,isc_boolean_t blocking)483 get_from_callback(isc_entropysource_t *source, unsigned int desired,
484 		  isc_boolean_t blocking)
485 {
486 	isc_entropy_t *ent = source->ent;
487 	isc_cbsource_t *cbs = &source->sources.callback;
488 	unsigned int added;
489 	unsigned int got;
490 	isc_result_t result;
491 
492 	if (desired == 0)
493 		return (0);
494 
495 	if (source->bad)
496 		return (0);
497 
498 	if (!cbs->start_called && cbs->startfunc != NULL) {
499 		result = cbs->startfunc(source, cbs->arg, blocking);
500 		if (result != ISC_R_SUCCESS)
501 			return (0);
502 		cbs->start_called = ISC_TRUE;
503 	}
504 
505 	added = 0;
506 	result = ISC_R_SUCCESS;
507 	while (desired > 0 && result == ISC_R_SUCCESS) {
508 		result = cbs->getfunc(source, cbs->arg, blocking);
509 		if (result == ISC_R_QUEUEFULL) {
510 			got = crunchsamples(ent, &cbs->samplequeue);
511 			added += got;
512 			desired -= ISC_MIN(got, desired);
513 			result = ISC_R_SUCCESS;
514 		} else if (result != ISC_R_SUCCESS &&
515 			   result != ISC_R_NOTBLOCKING)
516 			source->bad = ISC_TRUE;
517 
518 	}
519 
520 	return (added);
521 }
522 
523 /*
524  * Extract some number of bytes from the random pool, decreasing the
525  * estimate of randomness as each byte is extracted.
526  *
527  * Do this by stiring the pool and returning a part of hash as randomness.
528  * Note that no secrets are given away here since parts of the hash are
529  * xored together before returned.
530  *
531  * Honor the request from the caller to only return good data, any data,
532  * etc.
533  */
534 isc_result_t
isc_entropy_getdata(isc_entropy_t * ent,void * data,unsigned int length,unsigned int * returned,unsigned int flags)535 isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
536 		    unsigned int *returned, unsigned int flags)
537 {
538 	unsigned int i;
539 	isc_sha1_t hash;
540 	unsigned char digest[ISC_SHA1_DIGESTLENGTH];
541 	isc_uint32_t remain, deltae, count, total;
542 	isc_uint8_t *buf;
543 	isc_boolean_t goodonly, partial, blocking;
544 
545 	REQUIRE(VALID_ENTROPY(ent));
546 	REQUIRE(data != NULL);
547 	REQUIRE(length > 0);
548 
549 	goodonly = ISC_TF((flags & ISC_ENTROPY_GOODONLY) != 0);
550 	partial = ISC_TF((flags & ISC_ENTROPY_PARTIAL) != 0);
551 	blocking = ISC_TF((flags & ISC_ENTROPY_BLOCKING) != 0);
552 
553 	REQUIRE(!partial || returned != NULL);
554 
555 	LOCK(&ent->lock);
556 
557 	remain = length;
558 	buf = data;
559 	total = 0;
560 	while (remain != 0) {
561 		count = ISC_MIN(remain, RND_ENTROPY_THRESHOLD);
562 
563 		/*
564 		 * If we are extracting good data only, make certain we
565 		 * have enough data in our pool for this pass.  If we don't,
566 		 * get some, and fail if we can't, and partial returns
567 		 * are not ok.
568 		 */
569 		if (goodonly) {
570 			unsigned int fillcount;
571 
572 			fillcount = ISC_MAX(remain * 8, count * 8);
573 
574 			/*
575 			 * If, however, we have at least THRESHOLD_BITS
576 			 * of entropy in the pool, don't block here.  It is
577 			 * better to drain the pool once in a while and
578 			 * then refill it than it is to constantly keep the
579 			 * pool full.
580 			 */
581 			if (ent->pool.entropy >= THRESHOLD_BITS)
582 				fillpool(ent, fillcount, ISC_FALSE);
583 			else
584 				fillpool(ent, fillcount, blocking);
585 
586 			/*
587 			 * Verify that we got enough entropy to do one
588 			 * extraction.  If we didn't, bail.
589 			 */
590 			if (ent->pool.entropy < THRESHOLD_BITS) {
591 				if (!partial)
592 					goto zeroize;
593 				else
594 					goto partial_output;
595 			}
596 		} else {
597 			/*
598 			 * If we've extracted half our pool size in bits
599 			 * since the last refresh, try to refresh here.
600 			 */
601 			if (ent->initialized < THRESHOLD_BITS)
602 				fillpool(ent, THRESHOLD_BITS, blocking);
603 			else
604 				fillpool(ent, 0, ISC_FALSE);
605 
606 			/*
607 			 * If we've not initialized with enough good random
608 			 * data, seed with our crappy code.
609 			 */
610 			if (ent->initialized < THRESHOLD_BITS)
611 				reseed(ent);
612 		}
613 
614 		isc_sha1_init(&hash);
615 		isc_sha1_update(&hash, (void *)(ent->pool.pool),
616 				RND_POOLBYTES);
617 		isc_sha1_final(&hash, digest);
618 
619 		/*
620 		 * Stir the extracted data (all of it) back into the pool.
621 		 */
622 		entropypool_adddata(ent, digest, ISC_SHA1_DIGESTLENGTH, 0);
623 
624 		for (i = 0; i < count; i++)
625 			buf[i] = digest[i] ^ digest[i + RND_ENTROPY_THRESHOLD];
626 
627 		buf += count;
628 		remain -= count;
629 
630 		deltae = count * 8;
631 		deltae = ISC_MIN(deltae, ent->pool.entropy);
632 		total += deltae;
633 		subtract_entropy(ent, deltae);
634 		add_pseudo(ent, count * 8);
635 	}
636 
637  partial_output:
638 	memset(digest, 0, sizeof(digest));
639 
640 	if (returned != NULL)
641 		*returned = (length - remain);
642 
643 	UNLOCK(&ent->lock);
644 
645 	return (ISC_R_SUCCESS);
646 
647  zeroize:
648 	/* put the entropy we almost extracted back */
649 	add_entropy(ent, total);
650 	memset(data, 0, length);
651 	memset(digest, 0, sizeof(digest));
652 	if (returned != NULL)
653 		*returned = 0;
654 
655 	UNLOCK(&ent->lock);
656 
657 	return (ISC_R_NOENTROPY);
658 }
659 
660 static void
isc_entropypool_init(isc_entropypool_t * pool)661 isc_entropypool_init(isc_entropypool_t *pool) {
662 	pool->cursor = RND_POOLWORDS - 1;
663 	pool->entropy = 0;
664 	pool->pseudo = 0;
665 	pool->rotate = 0;
666 	memset(pool->pool, 0, RND_POOLBYTES);
667 }
668 
669 static void
isc_entropypool_invalidate(isc_entropypool_t * pool)670 isc_entropypool_invalidate(isc_entropypool_t *pool) {
671 	pool->cursor = 0;
672 	pool->entropy = 0;
673 	pool->pseudo = 0;
674 	pool->rotate = 0;
675 	memset(pool->pool, 0, RND_POOLBYTES);
676 }
677 
678 isc_result_t
isc_entropy_create(isc_mem_t * mctx,isc_entropy_t ** entp)679 isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
680 	isc_result_t result;
681 	isc_entropy_t *ent;
682 
683 	REQUIRE(mctx != NULL);
684 	REQUIRE(entp != NULL && *entp == NULL);
685 
686 	ent = isc_mem_get(mctx, sizeof(isc_entropy_t));
687 	if (ent == NULL)
688 		return (ISC_R_NOMEMORY);
689 
690 	/*
691 	 * We need a lock.
692 	 */
693 	result = isc_mutex_init(&ent->lock);
694 	if (result != ISC_R_SUCCESS)
695 		goto errout;
696 
697 	/*
698 	 * From here down, no failures will/can occur.
699 	 */
700 	ISC_LIST_INIT(ent->sources);
701 	ent->nextsource = NULL;
702 	ent->nsources = 0;
703 	ent->mctx = NULL;
704 	isc_mem_attach(mctx, &ent->mctx);
705 	ent->refcnt = 1;
706 	ent->initialized = 0;
707 	ent->initcount = 0;
708 	ent->magic = ENTROPY_MAGIC;
709 
710 	isc_entropypool_init(&ent->pool);
711 
712 	*entp = ent;
713 	return (ISC_R_SUCCESS);
714 
715  errout:
716 	isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
717 
718 	return (result);
719 }
720 
721 /*!
722  * Requires "ent" be locked.
723  */
724 static void
destroysource(isc_entropysource_t ** sourcep)725 destroysource(isc_entropysource_t **sourcep) {
726 	isc_entropysource_t *source;
727 	isc_entropy_t *ent;
728 	isc_cbsource_t *cbs;
729 
730 	source = *sourcep;
731 	*sourcep = NULL;
732 	ent = source->ent;
733 
734 	ISC_LIST_UNLINK(ent->sources, source, link);
735 	ent->nextsource = NULL;
736 	REQUIRE(ent->nsources > 0);
737 	ent->nsources--;
738 
739 	switch (source->type) {
740 	case ENTROPY_SOURCETYPE_FILE:
741 		if (! source->bad)
742 			destroyfilesource(&source->sources.file);
743 		break;
744 	case ENTROPY_SOURCETYPE_USOCKET:
745 		if (! source->bad)
746 			destroyusocketsource(&source->sources.usocket);
747 		break;
748 	case ENTROPY_SOURCETYPE_SAMPLE:
749 		samplequeue_release(ent, &source->sources.sample.samplequeue);
750 		break;
751 	case ENTROPY_SOURCETYPE_CALLBACK:
752 		cbs = &source->sources.callback;
753 		if (cbs->start_called && cbs->stopfunc != NULL) {
754 			cbs->stopfunc(source, cbs->arg);
755 			cbs->start_called = ISC_FALSE;
756 		}
757 		samplequeue_release(ent, &cbs->samplequeue);
758 		break;
759 	}
760 
761 	memset(source, 0, sizeof(isc_entropysource_t));
762 
763 	isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
764 }
765 
766 static inline isc_boolean_t
destroy_check(isc_entropy_t * ent)767 destroy_check(isc_entropy_t *ent) {
768 	isc_entropysource_t *source;
769 
770 	if (ent->refcnt > 0)
771 		return (ISC_FALSE);
772 
773 	source = ISC_LIST_HEAD(ent->sources);
774 	while (source != NULL) {
775 		switch (source->type) {
776 		case ENTROPY_SOURCETYPE_FILE:
777 		case ENTROPY_SOURCETYPE_USOCKET:
778 			break;
779 		default:
780 			return (ISC_FALSE);
781 		}
782 		source = ISC_LIST_NEXT(source, link);
783 	}
784 
785 	return (ISC_TRUE);
786 }
787 
788 static void
destroy(isc_entropy_t ** entp)789 destroy(isc_entropy_t **entp) {
790 	isc_entropy_t *ent;
791 	isc_entropysource_t *source;
792 	isc_mem_t *mctx;
793 
794 	REQUIRE(entp != NULL && *entp != NULL);
795 	ent = *entp;
796 	*entp = NULL;
797 
798 	LOCK(&ent->lock);
799 
800 	REQUIRE(ent->refcnt == 0);
801 
802 	/*
803 	 * Here, detach non-sample sources.
804 	 */
805 	source = ISC_LIST_HEAD(ent->sources);
806 	while (source != NULL) {
807 		switch(source->type) {
808 		case ENTROPY_SOURCETYPE_FILE:
809 		case ENTROPY_SOURCETYPE_USOCKET:
810 			destroysource(&source);
811 			break;
812 		}
813 		source = ISC_LIST_HEAD(ent->sources);
814 	}
815 
816 	/*
817 	 * If there are other types of sources, we've found a bug.
818 	 */
819 	REQUIRE(ISC_LIST_EMPTY(ent->sources));
820 
821 	mctx = ent->mctx;
822 
823 	isc_entropypool_invalidate(&ent->pool);
824 
825 	UNLOCK(&ent->lock);
826 
827 	DESTROYLOCK(&ent->lock);
828 
829 	memset(ent, 0, sizeof(isc_entropy_t));
830 	isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
831 	isc_mem_detach(&mctx);
832 }
833 
834 void
isc_entropy_destroysource(isc_entropysource_t ** sourcep)835 isc_entropy_destroysource(isc_entropysource_t **sourcep) {
836 	isc_entropysource_t *source;
837 	isc_entropy_t *ent;
838 	isc_boolean_t killit;
839 
840 	REQUIRE(sourcep != NULL);
841 	REQUIRE(VALID_SOURCE(*sourcep));
842 
843 	source = *sourcep;
844 	*sourcep = NULL;
845 
846 	ent = source->ent;
847 	REQUIRE(VALID_ENTROPY(ent));
848 
849 	LOCK(&ent->lock);
850 
851 	destroysource(&source);
852 
853 	killit = destroy_check(ent);
854 
855 	UNLOCK(&ent->lock);
856 
857 	if (killit)
858 		destroy(&ent);
859 }
860 
861 isc_result_t
isc_entropy_createcallbacksource(isc_entropy_t * ent,isc_entropystart_t start,isc_entropyget_t get,isc_entropystop_t stop,void * arg,isc_entropysource_t ** sourcep)862 isc_entropy_createcallbacksource(isc_entropy_t *ent,
863 				 isc_entropystart_t start,
864 				 isc_entropyget_t get,
865 				 isc_entropystop_t stop,
866 				 void *arg,
867 				 isc_entropysource_t **sourcep)
868 {
869 	isc_result_t result;
870 	isc_entropysource_t *source;
871 	isc_cbsource_t *cbs;
872 
873 	REQUIRE(VALID_ENTROPY(ent));
874 	REQUIRE(get != NULL);
875 	REQUIRE(sourcep != NULL && *sourcep == NULL);
876 
877 	LOCK(&ent->lock);
878 
879 	source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
880 	if (source == NULL) {
881 		result = ISC_R_NOMEMORY;
882 		goto errout;
883 	}
884 	source->bad = ISC_FALSE;
885 
886 	cbs = &source->sources.callback;
887 
888 	result = samplesource_allocate(ent, &cbs->samplequeue);
889 	if (result != ISC_R_SUCCESS)
890 		goto errout;
891 
892 	cbs->start_called = ISC_FALSE;
893 	cbs->startfunc = start;
894 	cbs->getfunc = get;
895 	cbs->stopfunc = stop;
896 	cbs->arg = arg;
897 
898 	/*
899 	 * From here down, no failures can occur.
900 	 */
901 	source->magic = SOURCE_MAGIC;
902 	source->type = ENTROPY_SOURCETYPE_CALLBACK;
903 	source->ent = ent;
904 	source->total = 0;
905 	memset(source->name, 0, sizeof(source->name));
906 	ISC_LINK_INIT(source, link);
907 
908 	/*
909 	 * Hook it into the entropy system.
910 	 */
911 	ISC_LIST_APPEND(ent->sources, source, link);
912 	ent->nsources++;
913 
914 	*sourcep = source;
915 
916 	UNLOCK(&ent->lock);
917 	return (ISC_R_SUCCESS);
918 
919  errout:
920 	if (source != NULL)
921 		isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
922 
923 	UNLOCK(&ent->lock);
924 
925 	return (result);
926 }
927 
928 void
isc_entropy_stopcallbacksources(isc_entropy_t * ent)929 isc_entropy_stopcallbacksources(isc_entropy_t *ent) {
930 	isc_entropysource_t *source;
931 	isc_cbsource_t *cbs;
932 
933 	REQUIRE(VALID_ENTROPY(ent));
934 
935 	LOCK(&ent->lock);
936 
937 	source = ISC_LIST_HEAD(ent->sources);
938 	while (source != NULL) {
939 		if (source->type == ENTROPY_SOURCETYPE_CALLBACK) {
940 			cbs = &source->sources.callback;
941 			if (cbs->start_called && cbs->stopfunc != NULL) {
942 				cbs->stopfunc(source, cbs->arg);
943 				cbs->start_called = ISC_FALSE;
944 			}
945 		}
946 
947 		source = ISC_LIST_NEXT(source, link);
948 	}
949 
950 	UNLOCK(&ent->lock);
951 }
952 
953 isc_result_t
isc_entropy_createsamplesource(isc_entropy_t * ent,isc_entropysource_t ** sourcep)954 isc_entropy_createsamplesource(isc_entropy_t *ent,
955 			       isc_entropysource_t **sourcep)
956 {
957 	isc_result_t result;
958 	isc_entropysource_t *source;
959 	sample_queue_t *sq;
960 
961 	REQUIRE(VALID_ENTROPY(ent));
962 	REQUIRE(sourcep != NULL && *sourcep == NULL);
963 
964 	LOCK(&ent->lock);
965 
966 	source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
967 	if (source == NULL) {
968 		result = ISC_R_NOMEMORY;
969 		goto errout;
970 	}
971 
972 	sq = &source->sources.sample.samplequeue;
973 	result = samplesource_allocate(ent, sq);
974 	if (result != ISC_R_SUCCESS)
975 		goto errout;
976 
977 	/*
978 	 * From here down, no failures can occur.
979 	 */
980 	source->magic = SOURCE_MAGIC;
981 	source->type = ENTROPY_SOURCETYPE_SAMPLE;
982 	source->ent = ent;
983 	source->total = 0;
984 	memset(source->name, 0, sizeof(source->name));
985 	ISC_LINK_INIT(source, link);
986 
987 	/*
988 	 * Hook it into the entropy system.
989 	 */
990 	ISC_LIST_APPEND(ent->sources, source, link);
991 	ent->nsources++;
992 
993 	*sourcep = source;
994 
995 	UNLOCK(&ent->lock);
996 	return (ISC_R_SUCCESS);
997 
998  errout:
999 	if (source != NULL)
1000 		isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
1001 
1002 	UNLOCK(&ent->lock);
1003 
1004 	return (result);
1005 }
1006 
1007 /*!
1008  * Add a sample, and return ISC_R_SUCCESS if the queue has become full,
1009  * ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the
1010  * queue was full when this function was called.
1011  */
1012 static isc_result_t
addsample(sample_queue_t * sq,isc_uint32_t sample,isc_uint32_t extra)1013 addsample(sample_queue_t *sq, isc_uint32_t sample, isc_uint32_t extra) {
1014 	if (sq->nsamples >= RND_EVENTQSIZE)
1015 		return (ISC_R_NOMORE);
1016 
1017 	sq->samples[sq->nsamples] = sample;
1018 	sq->extra[sq->nsamples] = extra;
1019 	sq->nsamples++;
1020 
1021 	if (sq->nsamples >= RND_EVENTQSIZE)
1022 		return (ISC_R_QUEUEFULL);
1023 
1024 	return (ISC_R_SUCCESS);
1025 }
1026 
1027 isc_result_t
isc_entropy_addsample(isc_entropysource_t * source,isc_uint32_t sample,isc_uint32_t extra)1028 isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
1029 		      isc_uint32_t extra)
1030 {
1031 	isc_entropy_t *ent;
1032 	sample_queue_t *sq;
1033 	unsigned int entropy;
1034 	isc_result_t result;
1035 
1036 	REQUIRE(VALID_SOURCE(source));
1037 
1038 	ent = source->ent;
1039 
1040 	LOCK(&ent->lock);
1041 
1042 	sq = &source->sources.sample.samplequeue;
1043 	result = addsample(sq, sample, extra);
1044 	if (result == ISC_R_QUEUEFULL) {
1045 		entropy = crunchsamples(ent, sq);
1046 		add_entropy(ent, entropy);
1047 	}
1048 
1049 	UNLOCK(&ent->lock);
1050 
1051 	return (result);
1052 }
1053 
1054 isc_result_t
isc_entropy_addcallbacksample(isc_entropysource_t * source,isc_uint32_t sample,isc_uint32_t extra)1055 isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
1056 			      isc_uint32_t extra)
1057 {
1058 	sample_queue_t *sq;
1059 	isc_result_t result;
1060 
1061 	REQUIRE(VALID_SOURCE(source));
1062 	REQUIRE(source->type == ENTROPY_SOURCETYPE_CALLBACK);
1063 
1064 	sq = &source->sources.callback.samplequeue;
1065 	result = addsample(sq, sample, extra);
1066 
1067 	return (result);
1068 }
1069 
1070 void
isc_entropy_putdata(isc_entropy_t * ent,void * data,unsigned int length,isc_uint32_t entropy)1071 isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
1072 		    isc_uint32_t entropy)
1073 {
1074 	REQUIRE(VALID_ENTROPY(ent));
1075 
1076 	LOCK(&ent->lock);
1077 
1078 	entropypool_adddata(ent, data, length, entropy);
1079 
1080 	if (ent->initialized < THRESHOLD_BITS)
1081 		ent->initialized = THRESHOLD_BITS;
1082 
1083 	UNLOCK(&ent->lock);
1084 }
1085 
1086 static void
dumpstats(isc_entropy_t * ent,FILE * out)1087 dumpstats(isc_entropy_t *ent, FILE *out) {
1088 	fprintf(out,
1089 		isc_msgcat_get(isc_msgcat, ISC_MSGSET_ENTROPY,
1090 			       ISC_MSG_ENTROPYSTATS,
1091 			       "Entropy pool %p:  refcnt %u cursor %u,"
1092 			       " rotate %u entropy %u pseudo %u nsources %u"
1093 			       " nextsource %p initialized %u initcount %u\n"),
1094 		ent, ent->refcnt,
1095 		ent->pool.cursor, ent->pool.rotate,
1096 		ent->pool.entropy, ent->pool.pseudo,
1097 		ent->nsources, ent->nextsource, ent->initialized,
1098 		ent->initcount);
1099 }
1100 
1101 /*
1102  * This function ignores locking.  Use at your own risk.
1103  */
1104 void
isc_entropy_stats(isc_entropy_t * ent,FILE * out)1105 isc_entropy_stats(isc_entropy_t *ent, FILE *out) {
1106 	REQUIRE(VALID_ENTROPY(ent));
1107 
1108 	LOCK(&ent->lock);
1109 	dumpstats(ent, out);
1110 	UNLOCK(&ent->lock);
1111 }
1112 
1113 unsigned int
isc_entropy_status(isc_entropy_t * ent)1114 isc_entropy_status(isc_entropy_t *ent) {
1115 	unsigned int estimate;
1116 
1117 	LOCK(&ent->lock);
1118 	estimate = ent->pool.entropy;
1119 	UNLOCK(&ent->lock);
1120 
1121 	return estimate;
1122 }
1123 
1124 void
isc_entropy_attach(isc_entropy_t * ent,isc_entropy_t ** entp)1125 isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) {
1126 	REQUIRE(VALID_ENTROPY(ent));
1127 	REQUIRE(entp != NULL && *entp == NULL);
1128 
1129 	LOCK(&ent->lock);
1130 
1131 	ent->refcnt++;
1132 	*entp = ent;
1133 
1134 	UNLOCK(&ent->lock);
1135 }
1136 
1137 void
isc_entropy_detach(isc_entropy_t ** entp)1138 isc_entropy_detach(isc_entropy_t **entp) {
1139 	isc_entropy_t *ent;
1140 	isc_boolean_t killit;
1141 
1142 	REQUIRE(entp != NULL && VALID_ENTROPY(*entp));
1143 	ent = *entp;
1144 	*entp = NULL;
1145 
1146 	LOCK(&ent->lock);
1147 
1148 	REQUIRE(ent->refcnt > 0);
1149 	ent->refcnt--;
1150 
1151 	killit = destroy_check(ent);
1152 
1153 	UNLOCK(&ent->lock);
1154 
1155 	if (killit)
1156 		destroy(&ent);
1157 }
1158 
1159 static isc_result_t
kbdstart(isc_entropysource_t * source,void * arg,isc_boolean_t blocking)1160 kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
1161 	/*
1162 	 * The intent of "first" is to provide a warning message only once
1163 	 * during the run of a program that might try to gather keyboard
1164 	 * entropy multiple times.
1165 	 */
1166 	static isc_boolean_t first = ISC_TRUE;
1167 
1168 	UNUSED(arg);
1169 
1170 	if (! blocking)
1171 		return (ISC_R_NOENTROPY);
1172 
1173 	if (first) {
1174 		if (source->warn_keyboard)
1175 			fprintf(stderr, "You must use the keyboard to create "
1176 				"entropy, since your system is lacking\n"
1177 				"/dev/random (or equivalent)\n\n");
1178 		first = ISC_FALSE;
1179 	}
1180 	fprintf(stderr, "start typing:\n");
1181 
1182 	return (isc_keyboard_open(&source->kbd));
1183 }
1184 
1185 static void
kbdstop(isc_entropysource_t * source,void * arg)1186 kbdstop(isc_entropysource_t *source, void *arg) {
1187 
1188 	UNUSED(arg);
1189 
1190 	if (! isc_keyboard_canceled(&source->kbd))
1191 		fprintf(stderr, "stop typing.\r\n");
1192 
1193 	(void)isc_keyboard_close(&source->kbd, 3);
1194 }
1195 
1196 static isc_result_t
kbdget(isc_entropysource_t * source,void * arg,isc_boolean_t blocking)1197 kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
1198 	isc_result_t result;
1199 	isc_time_t t;
1200 	isc_uint32_t sample;
1201 	isc_uint32_t extra;
1202 	unsigned char c;
1203 
1204 	UNUSED(arg);
1205 
1206 	if (!blocking)
1207 		return (ISC_R_NOTBLOCKING);
1208 
1209 	result = isc_keyboard_getchar(&source->kbd, &c);
1210 	if (result != ISC_R_SUCCESS)
1211 		return (result);
1212 
1213 	TIME_NOW(&t);
1214 
1215 	sample = isc_time_nanoseconds(&t);
1216 	extra = c;
1217 
1218 	result = isc_entropy_addcallbacksample(source, sample, extra);
1219 	if (result != ISC_R_SUCCESS) {
1220 		fprintf(stderr, "\r\n");
1221 		return (result);
1222 	}
1223 
1224 	fprintf(stderr, ".");
1225 	fflush(stderr);
1226 
1227 	return (result);
1228 }
1229 
1230 isc_result_t
isc_entropy_usebestsource(isc_entropy_t * ectx,isc_entropysource_t ** source,const char * randomfile,int use_keyboard)1231 isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
1232 			  const char *randomfile, int use_keyboard)
1233 {
1234 	isc_result_t result;
1235 	isc_result_t final_result = ISC_R_NOENTROPY;
1236 	isc_boolean_t userfile = ISC_TRUE;
1237 
1238 	REQUIRE(VALID_ENTROPY(ectx));
1239 	REQUIRE(source != NULL && *source == NULL);
1240 	REQUIRE(use_keyboard == ISC_ENTROPY_KEYBOARDYES ||
1241 		use_keyboard == ISC_ENTROPY_KEYBOARDNO  ||
1242 		use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE);
1243 
1244 #ifdef PKCS11CRYPTO
1245 	if (randomfile != NULL)
1246 		pk11_rand_seed_fromfile(randomfile);
1247 #endif
1248 
1249 #ifdef PATH_RANDOMDEV
1250 	if (randomfile == NULL) {
1251 		randomfile = PATH_RANDOMDEV;
1252 		userfile = ISC_FALSE;
1253 	}
1254 #endif
1255 
1256 	if (randomfile != NULL && use_keyboard != ISC_ENTROPY_KEYBOARDYES) {
1257 		result = isc_entropy_createfilesource(ectx, randomfile);
1258 		if (result == ISC_R_SUCCESS &&
1259 		    use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE)
1260 			use_keyboard = ISC_ENTROPY_KEYBOARDNO;
1261 		if (result != ISC_R_SUCCESS && userfile)
1262 			return (result);
1263 
1264 		final_result = result;
1265 	}
1266 
1267 	if (use_keyboard != ISC_ENTROPY_KEYBOARDNO) {
1268 		result = isc_entropy_createcallbacksource(ectx, kbdstart,
1269 							  kbdget, kbdstop,
1270 							  NULL, source);
1271 		if (result == ISC_R_SUCCESS)
1272 			(*source)->warn_keyboard =
1273 				ISC_TF(use_keyboard ==
1274 				       ISC_ENTROPY_KEYBOARDMAYBE);
1275 
1276 		if (final_result != ISC_R_SUCCESS)
1277 			final_result = result;
1278 	}
1279 
1280 	/*
1281 	 * final_result is ISC_R_SUCCESS if at least one source of entropy
1282 	 * could be started, otherwise it is the error from the most recently
1283 	 * failed operation (or ISC_R_NOENTROPY if PATH_RANDOMDEV is not
1284 	 * defined and use_keyboard is ISC_ENTROPY_KEYBOARDNO).
1285 	 */
1286 	return (final_result);
1287 }
1288