Tue Apr 14 14:11:51 2015 UTC ()
Centralize bookkeeping of rnd_initial_entropy.

It is not adjusted everywhere it should be, although the only places
it perhaps formally ought to be are places with questionable entropy
estimates in the first place.


(riastradh)
diff -r1.60 -r1.61 src/sys/kern/kern_rndq.c

cvs diff -r1.60 -r1.61 src/sys/kern/Attic/kern_rndq.c (expand / switch to unified diff)

--- src/sys/kern/Attic/kern_rndq.c 2015/04/14 13:57:35 1.60
+++ src/sys/kern/Attic/kern_rndq.c 2015/04/14 14:11:51 1.61
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_rndq.c,v 1.60 2015/04/14 13:57:35 riastradh Exp $ */ 1/* $NetBSD: kern_rndq.c,v 1.61 2015/04/14 14:11:51 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon. 8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
9 * This code uses ideas and algorithms from the Linux driver written by 9 * This code uses ideas and algorithms from the Linux driver written by
10 * Ted Ts'o. 10 * Ted Ts'o.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.60 2015/04/14 13:57:35 riastradh Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.61 2015/04/14 14:11:51 riastradh Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/atomic.h> 38#include <sys/atomic.h>
39#include <sys/ioctl.h> 39#include <sys/ioctl.h>
40#include <sys/fcntl.h> 40#include <sys/fcntl.h>
41#include <sys/select.h> 41#include <sys/select.h>
42#include <sys/poll.h> 42#include <sys/poll.h>
43#include <sys/kmem.h> 43#include <sys/kmem.h>
44#include <sys/mutex.h> 44#include <sys/mutex.h>
45#include <sys/proc.h> 45#include <sys/proc.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/conf.h> 47#include <sys/conf.h>
48#include <sys/systm.h> 48#include <sys/systm.h>
@@ -280,45 +280,26 @@ rnd_getmore(size_t byteswanted) @@ -280,45 +280,26 @@ rnd_getmore(size_t byteswanted)
280 rnd_printf_verbose("rnd: asking source %s for %zu bytes\n", 280 rnd_printf_verbose("rnd: asking source %s for %zu bytes\n",
281 rs->name, byteswanted); 281 rs->name, byteswanted);
282 } 282 }
283 mutex_spin_exit(&rnd_global.lock); 283 mutex_spin_exit(&rnd_global.lock);
284} 284}
285 285
286/* 286/*
287 * Check to see if there are readers waiting on us. If so, kick them. 287 * Check to see if there are readers waiting on us. If so, kick them.
288 */ 288 */
289static void 289static void
290rnd_wakeup_readers(void) 290rnd_wakeup_readers(void)
291{ 291{
292 292
293 /* 
294 * XXX This bookkeeping shouldn't be here -- this is not where 
295 * the rnd_initial_entropy state change actually happens. 
296 */ 
297 mutex_spin_enter(&rnd_global.lock); 
298 const size_t entropy_count = rndpool_get_entropy_count(&rnd_global.pool); 
299 if (entropy_count < RND_ENTROPY_THRESHOLD * 8) { 
300 mutex_spin_exit(&rnd_global.lock); 
301 return; 
302 } else { 
303#ifdef RND_VERBOSE 
304 if (__predict_false(!rnd_initial_entropy)) 
305 rnd_printf_verbose("rnd: have initial entropy (%zu)\n", 
306 entropy_count); 
307#endif 
308 rnd_initial_entropy = 1; 
309 } 
310 mutex_spin_exit(&rnd_global.lock); 
311 
312 rndsinks_distribute(); 293 rndsinks_distribute();
313} 294}
314 295
315/* 296/*
316 * Use the timing/value of the event to estimate the entropy gathered. 297 * Use the timing/value of the event to estimate the entropy gathered.
317 * If all the differentials (first, second, and third) are non-zero, return 298 * If all the differentials (first, second, and third) are non-zero, return
318 * non-zero. If any of these are zero, return zero. 299 * non-zero. If any of these are zero, return zero.
319 */ 300 */
320static inline uint32_t 301static inline uint32_t
321rnd_delta_estimate(rnd_delta_t *d, uint32_t v, int32_t delta) 302rnd_delta_estimate(rnd_delta_t *d, uint32_t v, int32_t delta)
322{ 303{
323 int32_t delta2, delta3; 304 int32_t delta2, delta3;
324 305
@@ -473,26 +454,47 @@ rnd_skew_intr(void *arg) @@ -473,26 +454,47 @@ rnd_skew_intr(void *arg)
473 if (RND_ENABLED(&rnd_skew.source)) { 454 if (RND_ENABLED(&rnd_skew.source)) {
474 if (flipflop) { 455 if (flipflop) {
475 rnd_add_uint32(&rnd_skew.source, rnd_counter()); 456 rnd_add_uint32(&rnd_skew.source, rnd_counter());
476 callout_schedule(&rnd_skew.callout, hz / 10); 457 callout_schedule(&rnd_skew.callout, hz / 10);
477 } else { 458 } else {
478 callout_schedule(&rnd_skew.callout, 1); 459 callout_schedule(&rnd_skew.callout, 1);
479 } 460 }
480 } 461 }
481 mutex_spin_exit(&rnd_skew.lock); 462 mutex_spin_exit(&rnd_skew.lock);
482} 463}
483#endif 464#endif
484 465
485/* 466/*
 467 * Entropy was just added to the pool. If we crossed the threshold for
 468 * the first time, set rnd_initial_entropy = 1.
 469 */
 470static void
 471rnd_entropy_added(void)
 472{
 473 uint32_t pool_entropy;
 474
 475 KASSERT(mutex_owned(&rnd_global.lock));
 476
 477 if (__predict_true(rnd_initial_entropy))
 478 return;
 479 pool_entropy = rndpool_get_entropy_count(&rnd_global.pool);
 480 if (pool_entropy > RND_ENTROPY_THRESHOLD * NBBY) {
 481 rnd_printf_verbose("rnd: have initial entropy (%zu)\n",
 482 pool_entropy);
 483 rnd_initial_entropy = 1;
 484 }
 485}
 486
 487/*
486 * initialize the global random pool for our use. 488 * initialize the global random pool for our use.
487 * rnd_init() must be called very early on in the boot process, so 489 * rnd_init() must be called very early on in the boot process, so
488 * the pool is ready for other devices to attach as sources. 490 * the pool is ready for other devices to attach as sources.
489 */ 491 */
490void 492void
491rnd_init(void) 493rnd_init(void)
492{ 494{
493 uint32_t c; 495 uint32_t c;
494 496
495 if (rnd_ready) 497 if (rnd_ready)
496 return; 498 return;
497 499
498 /* 500 /*
@@ -556,31 +558,28 @@ rnd_init(void) @@ -556,31 +558,28 @@ rnd_init(void)
556 rnd_attach_source(&rnd_skew.source, "callout", RND_TYPE_SKEW, 558 rnd_attach_source(&rnd_skew.source, "callout", RND_TYPE_SKEW,
557 RND_FLAG_COLLECT_VALUE|RND_FLAG_ESTIMATE_VALUE| 559 RND_FLAG_COLLECT_VALUE|RND_FLAG_ESTIMATE_VALUE|
558 RND_FLAG_HASCB|RND_FLAG_HASENABLE); 560 RND_FLAG_HASCB|RND_FLAG_HASENABLE);
559 rnd_skew_intr(NULL); 561 rnd_skew_intr(NULL);
560#endif 562#endif
561 563
562 rnd_printf_verbose("rnd: initialised (%u)%s", RND_POOLBITS, 564 rnd_printf_verbose("rnd: initialised (%u)%s", RND_POOLBITS,
563 c ? " with counter\n" : "\n"); 565 c ? " with counter\n" : "\n");
564 if (boot_rsp != NULL) { 566 if (boot_rsp != NULL) {
565 mutex_spin_enter(&rnd_global.lock); 567 mutex_spin_enter(&rnd_global.lock);
566 rndpool_add_data(&rnd_global.pool, boot_rsp->data, 568 rndpool_add_data(&rnd_global.pool, boot_rsp->data,
567 sizeof(boot_rsp->data), 569 sizeof(boot_rsp->data),
568 MIN(boot_rsp->entropy, RND_POOLBITS / 2)); 570 MIN(boot_rsp->entropy, RND_POOLBITS / 2));
569 if (rndpool_get_entropy_count(&rnd_global.pool) > 571 rnd_entropy_added();
570 RND_ENTROPY_THRESHOLD * 8) { 572 mutex_spin_exit(&rnd_global.lock);
571 rnd_initial_entropy = 1; 
572 } 
573 mutex_spin_exit(&rnd_global.lock); 
574 rnd_printf("rnd: seeded with %d bits\n", 573 rnd_printf("rnd: seeded with %d bits\n",
575 MIN(boot_rsp->entropy, RND_POOLBITS / 2)); 574 MIN(boot_rsp->entropy, RND_POOLBITS / 2));
576 memset(boot_rsp, 0, sizeof(*boot_rsp)); 575 memset(boot_rsp, 0, sizeof(*boot_rsp));
577 } 576 }
578 rnd_attach_source(&rnd_printf_source, "printf", RND_TYPE_UNKNOWN, 577 rnd_attach_source(&rnd_printf_source, "printf", RND_TYPE_UNKNOWN,
579 RND_FLAG_NO_ESTIMATE); 578 RND_FLAG_NO_ESTIMATE);
580 rnd_attach_source(&rnd_autoconf_source, "autoconf", 579 rnd_attach_source(&rnd_autoconf_source, "autoconf",
581 RND_TYPE_UNKNOWN, 580 RND_TYPE_UNKNOWN,
582 RND_FLAG_COLLECT_TIME|RND_FLAG_ESTIMATE_TIME); 581 RND_FLAG_COLLECT_TIME|RND_FLAG_ESTIMATE_TIME);
583 rnd_ready = 1; 582 rnd_ready = 1;
584} 583}
585 584
586static rnd_sample_t * 585static rnd_sample_t *
@@ -1085,26 +1084,27 @@ rnd_process_events(void) @@ -1085,26 +1084,27 @@ rnd_process_events(void)
1085 } 1084 }
1086 if (source->flags & RND_FLAG_COLLECT_TIME) { 1085 if (source->flags & RND_FLAG_COLLECT_TIME) {
1087 rndpool_add_data(&rnd_global.pool, sample->ts, 1086 rndpool_add_data(&rnd_global.pool, sample->ts,
1088 sample_count * 1087 sample_count *
1089 sizeof(sample->ts[1]), 1088 sizeof(sample->ts[1]),
1090 0); 1089 0);
1091 } 1090 }
1092 1091
1093 pool_entropy += entropy; 1092 pool_entropy += entropy;
1094 source->total += sample->entropy; 1093 source->total += sample->entropy;
1095skip: SIMPLEQ_INSERT_TAIL(&df_samples, sample, next); 1094skip: SIMPLEQ_INSERT_TAIL(&df_samples, sample, next);
1096 } 1095 }
1097 rndpool_set_entropy_count(&rnd_global.pool, pool_entropy); 1096 rndpool_set_entropy_count(&rnd_global.pool, pool_entropy);
 1097 rnd_entropy_added();
1098 mutex_spin_exit(&rnd_global.lock); 1098 mutex_spin_exit(&rnd_global.lock);
1099 1099
1100 /* 1100 /*
1101 * If we filled the pool past the threshold, wake anyone 1101 * If we filled the pool past the threshold, wake anyone
1102 * waiting for entropy. Otherwise, ask all the entropy sources 1102 * waiting for entropy. Otherwise, ask all the entropy sources
1103 * for more. 1103 * for more.
1104 */ 1104 */
1105 if (pool_entropy > RND_ENTROPY_THRESHOLD * 8) { 1105 if (pool_entropy > RND_ENTROPY_THRESHOLD * 8) {
1106 wake++; 1106 wake++;
1107 } else { 1107 } else {
1108 rnd_getmore(howmany((RND_POOLBITS - pool_entropy), NBBY)); 1108 rnd_getmore(howmany((RND_POOLBITS - pool_entropy), NBBY));
1109 rnd_printf_verbose("rnd: empty, asking for %d bytes\n", 1109 rnd_printf_verbose("rnd: empty, asking for %d bytes\n",
1110 (int)(howmany((RND_POOLBITS - pool_entropy), NBBY))); 1110 (int)(howmany((RND_POOLBITS - pool_entropy), NBBY)));
@@ -1597,26 +1597,27 @@ rnd_system_ioctl(struct file *fp, u_long @@ -1597,26 +1597,27 @@ rnd_system_ioctl(struct file *fp, u_long
1597 * do not flood the pool with entropy such that 1597 * do not flood the pool with entropy such that
1598 * new samples are discarded henceforth. 1598 * new samples are discarded henceforth.
1599 */ 1599 */
1600 estimate = MIN((rnddata->len * NBBY) / 2, 1600 estimate = MIN((rnddata->len * NBBY) / 2,
1601 MIN(rnddata->entropy, 1601 MIN(rnddata->entropy,
1602 RND_POOLBITS / 2)); 1602 RND_POOLBITS / 2));
1603 } else { 1603 } else {
1604 estimate = 0; 1604 estimate = 0;
1605 } 1605 }
1606 1606
1607 mutex_spin_enter(&rnd_global.lock); 1607 mutex_spin_enter(&rnd_global.lock);
1608 rndpool_add_data(&rnd_global.pool, rnddata->data, 1608 rndpool_add_data(&rnd_global.pool, rnddata->data,
1609 rnddata->len, estimate); 1609 rnddata->len, estimate);
 1610 rnd_entropy_added();
1610 mutex_spin_exit(&rnd_global.lock); 1611 mutex_spin_exit(&rnd_global.lock);
1611 1612
1612 rnd_wakeup_readers(); 1613 rnd_wakeup_readers();
1613 } else { 1614 } else {
1614 rnd_printf_verbose("rnd" 1615 rnd_printf_verbose("rnd"
1615 ": already seeded by boot loader\n"); 1616 ": already seeded by boot loader\n");
1616 } 1617 }
1617 break; 1618 break;
1618 1619
1619 default: 1620 default:
1620 return ENOTTY; 1621 return ENOTTY;
1621 } 1622 }
1622 1623