All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolai Stange <nstange@suse.de>
To: "Theodore Y. Ts'o" <tytso@mit.edu>
Cc: linux-crypto@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"Alexander E. Patrakov" <patrakov@gmail.com>,
	"Ahmed S. Darwish" <darwish.07@gmail.com>,
	"Willy Tarreau" <w@1wt.eu>,
	"Matthew Garrett" <mjg59@srcf.ucam.org>,
	"Vito Caputo" <vcaputo@pengaru.com>,
	"Andreas Dilger" <adilger.kernel@dilger.ca>,
	"Jan Kara" <jack@suse.cz>, "Ray Strode" <rstrode@redhat.com>,
	"William Jon McCann" <mccann@jhu.edu>,
	zhangjs <zachary@baishancloud.com>,
	"Andy Lutomirski" <luto@kernel.org>,
	"Florian Weimer" <fweimer@redhat.com>,
	"Lennart Poettering" <mzxreary@0pointer.de>,
	"Peter Matthias" <matthias.peter@bsi.bund.de>,
	"Marcelo Henrique Cerri" <marcelo.cerri@canonical.com>,
	"Roman Drahtmueller" <draht@schaltsekun.de>,
	"Neil Horman" <nhorman@redhat.com>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	"Julia Lawall" <julia.lawall@inria.fr>,
	"Dan Carpenter" <dan.carpenter@oracle.com>,
	"Andy Lavr" <andy.lavr@gmail.com>,
	"Eric Biggers" <ebiggers@kernel.org>,
	"Jason A. Donenfeld" <Jason@zx2c4.com>,
	"Stephan Müller" <smueller@chronox.de>,
	"Torsten Duwe" <duwe@suse.de>, "Petr Tesarik" <ptesarik@suse.cz>,
	"Nicolai Stange" <nstange@suse.de>
Subject: [RFC PATCH 41/41] random: lower per-IRQ entropy estimate upon health test failure
Date: Mon, 21 Sep 2020 09:58:57 +0200	[thread overview]
Message-ID: <20200921075857.4424-42-nstange@suse.de> (raw)
In-Reply-To: <20200921075857.4424-1-nstange@suse.de>

Currently, if fips_enabled is set, a per-IRQ min-entropy estimate of
either 1 bit or 1/8 bit is assumed, depending on whether a high resolution
get_cycles() is available or not. The statistical NIST SP800-90B startup
health tests are run on a certain amount of noise samples and are intended
to reject in case this hypothesis turns out to be wrong, i.e. if the
actual min-entropy is smaller. As long as the startup tests haven't
finished, entropy dispatch and thus, the initial crng seeding, is
inhibited. On test failure, the startup tests would restart themselves
from the beginning.

It follows that in case a system's actual per-IRQ min-entropy is smaller
than the more or less arbitrarily assessed 1 bit or 1/8 bit resp., there
will be a good chance that the initial crng seed will never complete.
AFAICT, such a situation could potentially prevent certain userspace
daemons like OpenSSH from loading.

In order to still be able to make any progress, make
add_interrupt_randomness() lower the per-IRQ min-entropy by one half upon
each health test failure, but only until the minimum supported value of
1/64 bits has been reached. Note that health test failures will cause a
restart of the startup health tests already and thus, a certain number of
additional noise samples resp. IRQ events will have to get examined by the
health tests before the initial crng seeding can take place. This number
of fresh events required is reciprocal to the estimated per-IRQ
min-entropy H: for the Adaptive Proportion Test (APT) it equals ~128 / H.
It follows that this patch won't be of much help for embedded systems or
VMs with poor IRQ rates at boot time, at least not without manual
intervention. But there aren't many options left when fips_enabled is set.

With respect to NIST SP800-90B conformance, this patch enters kind of a
gray area: NIST SP800-90B has no notion of such a dynamically adjusted
min-entropy estimate. Instead, it is assumed that some fixed value has been
estimated based on general principles and subsequently validated in the
course of the certification process. However, I would argue that if a
system had successfully passed certification for 1 bit or 1/8 bit resp. of
estimated min-entropy per sample, it would automatically be approved for
all smaller values as well. Had we started out with such a lower value
passing the health tests from the beginning, the latter would never have
complained in the first place and the system would have come up just fine.

Finally, note that all statistical tests have a non-zero probability of
false positives and so do the NIST SP800-90B health tests. In order to not
keep the estimated per-IRQ entropy at a smaller level than necessary for
forever after spurious health test failures, make
add_interrupt_randomness() attempt to double it again after a certain
number of successful health test passes at the degraded entropy level have
been completed. This threshold should not be too small in order to avoid
excessive entropy accounting loss due to continuously alternating between
a too large per-IRQ entropy estimate and the next smaller value. For now,
choose a value of five as a compromise between quick recovery and limiting
said accounting loss.

So, introduce a new member ->good_tests to struct fast_pool for keeping
track of the number of successfult health test passes. Make
add_interrupt_randomness() increment it upon successful healh test
completion and reset it to zero on failures. Make
add_interrupt_randomness() double the current min-entropy estimate and
restart the startup health in case ->good_tests is > 4 and the entropy
had previously been lowered.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 drivers/char/random.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index bb79dcb96882..24c09ba9d7d0 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1126,6 +1126,7 @@ struct fast_pool {
 	bool		dispatch_needed : 1;
 	bool		discard_needed : 1;
 	int		event_entropy_shift;
+	unsigned int		good_tests;
 	struct queued_entropy	q;
 	struct health_test	health;
 };
@@ -1926,9 +1927,13 @@ void add_interrupt_randomness(int irq, int irq_flags)
 					    cycles);
 		if (unlikely(health_result == health_discard)) {
 			/*
-			 * Oops, something's odd. Restart the startup
-			 * tests.
+			 * Oops, something's odd. Lower the entropy
+			 * estimate and restart the startup tests.
 			 */
+			fast_pool->event_entropy_shift =
+				min_t(unsigned int,
+				      fast_pool->event_entropy_shift + 1, 6);
+			fast_pool->good_tests = 0;
 			health_test_reset(&fast_pool->health,
 					  fast_pool->event_entropy_shift);
 		}
@@ -1951,6 +1956,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
 		 * entropy discard request?
 		 */
 		fast_pool->dispatch_needed = !fast_pool->discard_needed;
+		fast_pool->good_tests++;
 		break;
 
 	case health_discard:
@@ -2005,6 +2011,21 @@ void add_interrupt_randomness(int irq, int irq_flags)
 	if (fast_pool->dispatch_needed || health_result == health_none) {
 		reseed = __dispatch_queued_entropy_fast(r, q);
 		fast_pool->dispatch_needed = false;
+
+		/*
+		 * In case the estimated per-IRQ min-entropy had to be
+		 * lowered due to health test failure, but the lower
+		 * value has proven to withstand the tests for some
+		 * time now, try to give the next better value another
+		 * shot.
+		 */
+		if (unlikely((fast_pool->event_entropy_shift >
+			      min_irq_event_entropy_shift())) &&
+		    fast_pool->good_tests > 4) {
+			fast_pool->event_entropy_shift--;
+			health_test_reset(&fast_pool->health,
+					  fast_pool->event_entropy_shift);
+		}
 	} else if (fast_pool->discard_needed) {
 		int dummy;
 
-- 
2.26.2


  parent reply	other threads:[~2020-09-21  8:01 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-21  7:58 [DISCUSSION PATCH 00/41] random: possible ways towards NIST SP800-90B compliance Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 01/41] random: remove dead code in credit_entropy_bits() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 02/41] random: remove dead code for nbits < 0 " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 03/41] random: prune dead assignment to entropy_bits " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 04/41] random: drop 'reserved' parameter from extract_entropy() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 05/41] random: don't reset entropy to zero on overflow Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 06/41] random: factor the exponential approximation in credit_entropy_bits() out Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 07/41] random: let pool_entropy_delta() take nbits in units of 2^-ENTROPY_SHIFT Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 08/41] random: introduce __credit_entropy_bits_fast() for hot paths Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 09/41] random: protect ->entropy_count with the pool spinlock Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 10/41] random: implement support for delayed entropy dispatching Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 11/41] random: convert add_timer_randomness() to queued_entropy API Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 12/41] random: convert add_interrupt_randomness() " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 13/41] random: convert try_to_generate_entropy() " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 14/41] random: drop __credit_entropy_bits_fast() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 15/41] random: convert add_hwgenerator_randomness() to queued_entropy API Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 16/41] random: convert random_ioctl() " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 17/41] random: drop credit_entropy_bits() and credit_entropy_bits_safe() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 18/41] random: move arch_get_random_seed() calls in crng_reseed() into own loop Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 19/41] random: reintroduce arch_has_random() + arch_has_random_seed() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 20/41] random: provide min_crng_reseed_pool_entropy() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 21/41] random: don't invoke arch_get_random_long() from add_interrupt_randomness() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 22/41] random: introduce arch_has_sp800_90b_random_seed() Nicolai Stange
2020-09-21 12:18   ` kernel test robot
2020-09-21  7:58 ` [RFC PATCH 23/41] random: don't award entropy to non-SP800-90B arch RNGs in FIPS mode Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 24/41] init: call time_init() before rand_initialize() Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 25/41] random: probe cycle counter resolution at initialization Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 26/41] random: implement support for evaluating larger fast_pool entropies Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 27/41] random: increase per-IRQ event entropy estimate if in FIPS mode Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 28/41] random: don't award entropy to disk + input events " Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 29/41] random: move definition of struct queued_entropy and related API upwards Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 30/41] random: add a queued_entropy instance to struct fast_pool Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 31/41] random: introduce struct health_test + health_test_reset() placeholders Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 32/41] random: introduce health test stub and wire it up Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 33/41] random: make health_test_process() maintain the get_cycles() delta Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 34/41] random: implement the "Adaptive Proportion" NIST SP800-90B health test Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 35/41] random: improve the APT's statistical power Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 36/41] random: optimize the APT's presearch Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 37/41] random: implement the "Repetition Count" NIST SP800-90B health test Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 38/41] random: enable NIST SP800-90B startup tests Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 39/41] random: make the startup tests include muliple APT invocations Nicolai Stange
2020-09-21  7:58 ` [RFC PATCH 40/41] random: trigger startup health test on any failure of the health tests Nicolai Stange
2020-09-21  7:58 ` Nicolai Stange [this message]
2020-09-21  8:09 ` [DISCUSSION PATCH 00/41] random: possible ways towards NIST SP800-90B compliance Jason A. Donenfeld
2020-09-21  8:40 ` Stephan Mueller
2020-09-22 13:23   ` Torsten Duwe
2020-09-22 16:21     ` Greg Kroah-Hartman
2020-09-22 17:48       ` Torsten Duwe
2020-10-02 12:38 ` Torsten Duwe
2020-10-02 13:15   ` Willy Tarreau
2020-10-02 13:33     ` Greg Kroah-Hartman
2020-10-02 14:05       ` Torsten Duwe
2020-10-02 13:56     ` Stephan Mueller
2020-10-16 17:26       ` Torsten Duwe
2020-10-19 19:28         ` [PATCH v36 00/13] /dev/random - a new approach Stephan Müller
2020-10-19 19:30           ` [PATCH v36 01/13] Linux Random Number Generator Stephan Müller
2020-10-19 19:31           ` [PATCH v36 02/13] LRNG - allocate one DRNG instance per NUMA node Stephan Müller
2020-10-19 19:32           ` [PATCH v36 03/13] LRNG - sysctls and /proc interface Stephan Müller
2020-10-19 19:32           ` [PATCH v36 04/13] LRNG - add switchable DRNG support Stephan Müller
2020-10-19 19:33           ` [PATCH v36 05/13] LRNG - add common generic hash support Stephan Müller
2020-10-19 19:34           ` [PATCH v36 06/13] crypto: DRBG - externalize DRBG functions for LRNG Stephan Müller
2020-10-19 19:34           ` [PATCH v36 07/13] LRNG - add SP800-90A DRBG extension Stephan Müller
2020-10-19 19:35           ` [PATCH v36 08/13] LRNG - add kernel crypto API PRNG extension Stephan Müller
2020-10-19 19:35           ` [PATCH v36 09/13] crypto: provide access to a static Jitter RNG state Stephan Müller
2020-10-19 19:36           ` [PATCH v36 10/13] LRNG - add Jitter RNG fast noise source Stephan Müller
2020-10-19 19:37           ` [PATCH v36 11/13] LRNG - add SP800-90B compliant health tests Stephan Müller
2020-10-19 19:37           ` [PATCH v36 12/13] LRNG - add interface for gathering of raw entropy Stephan Müller
2020-10-19 19:38           ` [PATCH v36 13/13] LRNG - add power-on and runtime self-tests Stephan Müller
2020-10-28 17:51           ` [PATCH v36 00/13] /dev/random - a new approach Torsten Duwe
2020-10-28 18:07             ` Greg Kroah-Hartman
2020-11-02 13:44               ` Torsten Duwe
2020-11-04 14:26                 ` Marcelo Henrique Cerri
2020-11-17 14:01                 ` Torsten Duwe
2020-11-10 10:22           ` Stephan Mueller
2020-10-02 13:35   ` [DISCUSSION PATCH 00/41] random: possible ways towards NIST SP800-90B compliance Van Leeuwen, Pascal
2020-10-02 14:04     ` Greg Kroah-Hartman
2020-10-02 14:34       ` Van Leeuwen, Pascal
2020-10-02 15:13         ` Greg Kroah-Hartman
2020-10-02 15:39           ` Van Leeuwen, Pascal
2020-10-02 16:30             ` Randy Dunlap
2020-10-02 18:14             ` Theodore Y. Ts'o
2020-10-02 19:09               ` Van Leeuwen, Pascal
2020-10-07  4:24   ` Eric Biggers
2020-10-07  5:52     ` Stephan Mueller
2020-10-07 10:38     ` Nicolai Stange

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200921075857.4424-42-nstange@suse.de \
    --to=nstange@suse.de \
    --cc=Jason@zx2c4.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=andy.lavr@gmail.com \
    --cc=arnd@arndb.de \
    --cc=dan.carpenter@oracle.com \
    --cc=darwish.07@gmail.com \
    --cc=draht@schaltsekun.de \
    --cc=duwe@suse.de \
    --cc=ebiederm@xmission.com \
    --cc=ebiggers@kernel.org \
    --cc=fweimer@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=julia.lawall@inria.fr \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=marcelo.cerri@canonical.com \
    --cc=matthias.peter@bsi.bund.de \
    --cc=mccann@jhu.edu \
    --cc=mjg59@srcf.ucam.org \
    --cc=mzxreary@0pointer.de \
    --cc=nhorman@redhat.com \
    --cc=patrakov@gmail.com \
    --cc=ptesarik@suse.cz \
    --cc=rdunlap@infradead.org \
    --cc=rstrode@redhat.com \
    --cc=smueller@chronox.de \
    --cc=tytso@mit.edu \
    --cc=vcaputo@pengaru.com \
    --cc=w@1wt.eu \
    --cc=zachary@baishancloud.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.