linux-kernel.vger.kernel.org archive mirror
 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 26/41] random: implement support for evaluating larger fast_pool entropies
Date: Mon, 21 Sep 2020 09:58:42 +0200	[thread overview]
Message-ID: <20200921075857.4424-27-nstange@suse.de> (raw)
In-Reply-To: <20200921075857.4424-1-nstange@suse.de>

The fast_pools, mixed into from add_interrupt_randomness(), are 128 bits
wide and get awarded at most an entropy value as low as one bit in total.

An upcoming patch will significantly increase the estimated entropy per
event and this will make the fast_pools to receive much larger values
of successively mixed in event entropy.

In analogy to the reasoning in commit 30e37ec516ae ("random: account for
entropy loss due to overwrites"), probabilistic collisions will have to get
accounted for when calculating the total fast_pool entropy.

From said commit, the final fast_pool entropy equals

  e = pool_size * (1 - exp(-num_events * entropy_per_event / pool_size))

Where pool_size is 128 bits in this case and
num_events * entropy_per_event equals the sum of all estimated entropy from
the IRQ events previously mixed in.

Disclaimer: I'm cargo-culting here. That probabilisic overwrites are in
fact an issue sounds plausible after having read e.g. "Balls into Bins" by
M.Raab and A. Steger. But I haven't managed to derive this equation by
myself, nor have I found it in any literature.

Anyway, implement the new fast_pool_entropy() for evaluating the equation
given above by means of a suitable approximation.

add_interrupt_randomness() empties its fast_pool into the global input_pool
whenever the number of accumulated events has reached a threshold of 64
and the input_pool's ->lock is uncontended. Thus, the number of IRQ events
accumulated at the fast_pool can be assumed to be unlikely to exceed
larger factors of 64. The maximum estimate supported for per-IRQ entropy
will be 1 bit and thus, this sets an upper bound on the range where the
approximation is supposed to work well.

At the same time, estimates for the per-IRQ entropy as low as 1/64 bits
should be supported and the approximation should not be too coarse in these
lower regions in order to avoid excessive loss when entropy is likely a
scarce resource anyway.

Apply a piecewise linear approximation to the fast_pool entropy, with
the lengths of the resp. intervals getting doubled with increasing input
values. That is, let the first interval cover 32 bits worth of input
entropy, the next one 64 bits and stop after a final one of length
128 bits. Any input entropy beyond 32 + 64 + 128 bits gets discarded in
order to limit the computations done from interrupt context, but as
outlined above, this is unlikely to matter in practice. The shorter
intervals for the regions of smaller values will improve the accuracy of
the approximation in these areas, i.e. for small estimates for the per-IRQ
entropy.

Note that the new fast_pool_entropy() is not being used anywhere yet, it
will be wired up in an upcoming commit.

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

diff --git a/drivers/char/random.c b/drivers/char/random.c
index a985ceb22c7c..ac36c56dd135 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1547,6 +1547,58 @@ static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
 	return *ptr;
 }
 
+/*
+ * Calculate the entropy of a fast_pool after num_events IRQ events of
+ * assessed entropy 2^-event_entropy_shift each have been mixed in.
+ */
+static unsigned int fast_pool_entropy(unsigned int num_events,
+				      int event_entropy_shift)
+{
+	unsigned int result, cur, interval_len;
+
+	/*
+	 * Assume that each event fed into the fast_pool
+	 * carries h = 2^-event_entropy_shift bits of entropy.
+	 * In analogy to how entropy deltas are calculated
+	 * in pool_entropy_delta() for the struct entropy_store
+	 * input_pool, a fast_pool which received num_events
+	 * of total entropy num_events * h will contain
+	 * p * (1 - exp(-num_events * h / p)
+	 * bits of entropy, where p equals the poolsize of 128 bits.
+	 *
+	 * Note that most of the time num_events will be ~64, c.f.
+	 * add_interrupt_randomness.  Approximate the resulting
+	 * fast_pool entropy in a piecewise linear manner from below:
+	 * from 0 to 32, from 32 to 96 and from 96 to 224.
+	 * Event entropy above 224 gets simply discarded. For p = 128,
+	 * the calculated fast_pool entropy is ~226 at
+	 * num_events * h == 32, ~540 at 96 and ~846 at 224, all given
+	 * in units of 2^-ENTROPY_SHIFT.
+	 */
+	BUILD_BUG_ON(sizeof(((struct fast_pool *)NULL)->pool) != 16);
+	BUILD_BUG_ON(ENTROPY_SHIFT != 3);
+
+	/* Interval from 0 to 32. */
+	interval_len = 32 << event_entropy_shift;
+	cur = min_t(unsigned int, num_events, interval_len);
+	result = (226 * cur) >> 5; /* shift is for /32 */
+	num_events -= cur;
+
+	/* Interval of length 64 from 32 to 96. */
+	interval_len <<= 1;
+	cur = min_t(unsigned int, num_events, interval_len);
+	result += ((540 - 226) * cur) >> 6; /* shift is for /64 */
+	num_events -= cur;
+
+	/* Interval of length 128 from 96 to 224. */
+	interval_len <<= 1;
+	cur = min_t(unsigned int, num_events, interval_len);
+	result += ((846 - 540) * cur) >> 7; /* shift is for /128 */
+
+	/* Return value is in units of 2^-ENTROPY_SHIFT. */
+	return result >> event_entropy_shift;
+}
+
 void add_interrupt_randomness(int irq, int irq_flags)
 {
 	struct entropy_store	*r;
-- 
2.26.2


  parent reply	other threads:[~2020-09-21  7:59 UTC|newest]

Thread overview: 84+ 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  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 ` Nicolai Stange [this message]
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 ` [RFC PATCH 41/41] random: lower per-IRQ entropy estimate upon health test failure Nicolai Stange
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-27-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).