From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>,
Theodore Ts'o <tytso@mit.edu>,
Dominik Brodowski <linux@dominikbrodowski.net>
Subject: [PATCH v2] random: reseed more often immediately after booting
Date: Wed, 9 Mar 2022 12:18:50 -0700 [thread overview]
Message-ID: <20220309191850.1508953-1-Jason@zx2c4.com> (raw)
In-Reply-To: <20220309152653.1244096-1-Jason@zx2c4.com>
In order to chip away at the "premature first" problem, we augment our
existing entropy accounting with increased reseedings at boot. The idea
is that at boot, we're getting entropy from various places, and we're
not very sure which of early boot entropy is good and which isn't. Even
when we're crediting the entropy, we're still not totally certain that
it's any good. Since boot is the one time (aside from a compromise) that
we have zero entropy, it's important that we shephard entropy into the
crng fairly often. At the same time, we don't want a "premature next"
problem, whereby an attacker can brute force individual bits of added
entropy. In lieu of going full-on Fortuna (for now), we can pick a
simpler strategy of just reseeding more often during the first 5 minutes
after boot. This is still bounded by the 256-bit entropy credit
requirement, so we'll skip a reseeding if we haven't reached that, but
in case entropy /is/ coming in, this ensures that it makes its way into
the crng rather rapidly during these early stages. For this we start at
5 seconds after boot, and double that interval until it's more than 5
minutes. After that, we then move to our normal schedule of reseeding
not more than once per 5 minutes.
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
Changes v1->v2:
- Simplified arithmetic, prevented overflow.
drivers/char/random.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0ceda9a12bfe..8c08186205f4 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -333,6 +333,27 @@ static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
memzero_explicit(first_block, sizeof(first_block));
}
+/*
+ * Return whether the crng seed is considered to be sufficiently
+ * old that a reseeding might be attempted. This is the case 5,
+ * 10, 20, 40, 80, and 160 seconds after boot, and after if the
+ * last reseeding was CRNG_RESEED_INTERVAL ago.
+ */
+static bool crng_has_old_seed(void)
+{
+ static unsigned int next_init_secs = 5;
+
+ if (unlikely(next_init_secs < CRNG_RESEED_INTERVAL / HZ)) {
+ unsigned int uptime = min_t(u64, INT_MAX, ktime_get_seconds());
+ if (uptime >= READ_ONCE(next_init_secs)) {
+ WRITE_ONCE(next_init_secs, 5U << fls(uptime / 5));
+ return true;
+ }
+ return false;
+ }
+ return time_after(jiffies, READ_ONCE(base_crng.birth) + CRNG_RESEED_INTERVAL);
+}
+
/*
* This function returns a ChaCha state that you may use for generating
* random data. It also returns up to 32 bytes on its own of random data
@@ -366,10 +387,10 @@ static void crng_make_state(u32 chacha_state[CHACHA_STATE_WORDS],
}
/*
- * If the base_crng is more than 5 minutes old, we reseed, which
- * in turn bumps the generation counter that we check below.
+ * If the base_crng is old enough, we try to reseed, which in turn
+ * bumps the generation counter that we check below.
*/
- if (unlikely(time_after(jiffies, READ_ONCE(base_crng.birth) + CRNG_RESEED_INTERVAL)))
+ if (unlikely(crng_has_old_seed()))
crng_reseed(false);
local_lock_irqsave(&crngs.lock, flags);
--
2.35.1
next prev parent reply other threads:[~2022-03-09 19:19 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-09 15:26 [PATCH] " Jason A. Donenfeld
2022-03-09 19:18 ` Jason A. Donenfeld [this message]
2022-03-10 4:57 ` [PATCH v2] " Eric Biggers
2022-03-10 20:59 ` Jason A. Donenfeld
2022-03-10 21:10 ` Jason A. Donenfeld
2022-03-12 19:44 ` Eric Biggers
2022-03-13 0:35 ` Jason A. Donenfeld
2022-03-13 1:00 ` Eric Biggers
2022-03-13 1:29 ` Jason A. Donenfeld
2022-03-13 1:41 ` [PATCH v4] " Jason A. Donenfeld
2022-03-13 3:39 ` Eric Biggers
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=20220309191850.1508953-1-Jason@zx2c4.com \
--to=jason@zx2c4.com \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=tytso@mit.edu \
/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
all inboxes | Powered by JetHome®