From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: tytso@mit.edu, linux@dominikbrodowski.net, ebiggers@kernel.org,
"Jason A. Donenfeld" <Jason@zx2c4.com>,
Eric Biggers <ebiggers@google.com>
Subject: [PATCH v2 1/9] random: use RDSEED instead of RDRAND in entropy extraction
Date: Wed, 9 Feb 2022 02:19:11 +0100 [thread overview]
Message-ID: <20220209011919.493762-2-Jason@zx2c4.com> (raw)
In-Reply-To: <20220209011919.493762-1-Jason@zx2c4.com>
When /dev/random was directly connected with entropy extraction, without
any expansion stage, extract_buf() was called for every 10 bytes of data
read from /dev/random. For that reason, RDRAND was used rather than
RDSEED. At the same time, crng_reseed() was still only called every 5
minutes, so there RDSEED made sense.
Those olden days were also a time when the entropy collector did not use
a cryptographic hash function, which meant most bets were off in terms
of real preimage resistance. For that reason too it didn't matter
_that_ much whether RDSEED was mixed in before or after entropy
extraction; both choices were sort of bad.
But now we have a cryptographic hash function at work, and with that we
get real preimage resistance. We also now only call extract_entropy()
every 5 minutes, rather than every 10 bytes. This allows us to do two
important things.
First, we can switch to using RDSEED in extract_entropy(), as Dominik
suggested. Second, we can ensure that RDSEED input always goes into the
cryptographic hash function with other things before being used
directly. This eliminates a category of attacks in which the CPU knows
the current state of the crng and knows that we're going to xor RDSEED
into it, and so it computes a malicious RDSEED. By going through our
hash function, it would require the CPU to compute a preimage on the
fly, which isn't going to happen.
Cc: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Eric Biggers <ebiggers@google.com>
Suggested-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
drivers/char/random.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 22d12213d548..ce3c019e5f5f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -722,13 +722,8 @@ static void crng_reseed(struct crng_state *crng)
CHACHA_KEY_SIZE);
}
spin_lock_irqsave(&crng->lock, flags);
- for (i = 0; i < 8; i++) {
- unsigned long rv;
- if (!arch_get_random_seed_long(&rv) &&
- !arch_get_random_long(&rv))
- rv = random_get_entropy();
- crng->state[i + 4] ^= buf.key[i] ^ rv;
- }
+ for (i = 0; i < 8; i++)
+ crng->state[i + 4] ^= buf.key[i];
memzero_explicit(&buf, sizeof(buf));
WRITE_ONCE(crng->init_time, jiffies);
spin_unlock_irqrestore(&crng->lock, flags);
@@ -1064,16 +1059,17 @@ static void extract_entropy(void *buf, size_t nbytes)
unsigned long flags;
u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE];
struct {
- unsigned long rdrand[32 / sizeof(long)];
+ unsigned long rdseed[32 / sizeof(long)];
size_t counter;
} block;
size_t i;
trace_extract_entropy(nbytes, input_pool.entropy_count);
- for (i = 0; i < ARRAY_SIZE(block.rdrand); ++i) {
- if (!arch_get_random_long(&block.rdrand[i]))
- block.rdrand[i] = random_get_entropy();
+ for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) {
+ if (!arch_get_random_seed_long(&block.rdseed[i]) &&
+ !arch_get_random_long(&block.rdseed[i]))
+ block.rdseed[i] = random_get_entropy();
}
spin_lock_irqsave(&input_pool.lock, flags);
@@ -1081,7 +1077,7 @@ static void extract_entropy(void *buf, size_t nbytes)
/* seed = HASHPRF(last_key, entropy_input) */
blake2s_final(&input_pool.hash, seed);
- /* next_key = HASHPRF(seed, RDRAND || 0) */
+ /* next_key = HASHPRF(seed, RDSEED || 0) */
block.counter = 0;
blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed));
blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key));
@@ -1091,7 +1087,7 @@ static void extract_entropy(void *buf, size_t nbytes)
while (nbytes) {
i = min_t(size_t, nbytes, BLAKE2S_HASH_SIZE);
- /* output = HASHPRF(seed, RDRAND || ++counter) */
+ /* output = HASHPRF(seed, RDSEED || ++counter) */
++block.counter;
blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed));
nbytes -= i;
--
2.35.0
next prev parent reply other threads:[~2022-02-09 2:39 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-09 1:19 [PATCH v2 0/9] random: cleanups around per-cpu crng & rdrand Jason A. Donenfeld
2022-02-09 1:19 ` Jason A. Donenfeld [this message]
2022-02-09 6:18 ` [PATCH v2 1/9] random: use RDSEED instead of RDRAND in entropy extraction Dominik Brodowski
2022-02-09 1:19 ` [PATCH v2 2/9] random: get rid of secondary crngs Jason A. Donenfeld
2022-02-09 8:22 ` Dominik Brodowski
2022-02-09 10:26 ` Jason A. Donenfeld
2022-02-21 2:38 ` Eric Biggers
2022-02-09 1:19 ` [PATCH v2 3/9] random: inline leaves of rand_initialize() Jason A. Donenfeld
2022-02-09 8:22 ` Dominik Brodowski
2022-02-09 10:27 ` Jason A. Donenfeld
2022-02-09 1:19 ` [PATCH v2 4/9] random: ensure early RDSEED goes through mixer on init Jason A. Donenfeld
2022-02-09 8:23 ` Dominik Brodowski
2022-02-09 10:37 ` Jason A. Donenfeld
2022-02-09 1:19 ` [PATCH v2 5/9] random: do not xor RDRAND when writing into /dev/random Jason A. Donenfeld
2022-02-09 8:28 ` Dominik Brodowski
2022-02-09 10:40 ` Jason A. Donenfeld
2022-02-09 1:19 ` [PATCH v2 6/9] random: absorb fast pool into input pool after fast load Jason A. Donenfeld
2022-02-09 8:29 ` Dominik Brodowski
2022-02-09 10:45 ` Jason A. Donenfeld
2022-02-15 21:13 ` [PATCH v3] " Jason A. Donenfeld
2022-02-21 2:47 ` Eric Biggers
2022-02-21 14:57 ` Jason A. Donenfeld
2022-02-21 14:58 ` [PATCH v4] " Jason A. Donenfeld
2022-02-21 19:08 ` Eric Biggers
2022-02-09 1:19 ` [PATCH v2 7/9] random: use simpler fast key erasure flow on per-cpu keys Jason A. Donenfeld
2022-02-09 8:30 ` Dominik Brodowski
2022-02-09 10:54 ` Jason A. Donenfeld
2022-02-14 18:46 ` [PATCH v3] " Jason A. Donenfeld
2022-02-16 23:21 ` [PATCH v4] " Jason A. Donenfeld
2022-02-21 3:37 ` Eric Biggers
2022-02-21 14:42 ` Jason A. Donenfeld
2022-02-09 1:19 ` [PATCH v2 8/9] random: use hash function for crng_slow_load() Jason A. Donenfeld
2022-02-09 8:30 ` Dominik Brodowski
2022-02-21 3:40 ` Eric Biggers
2022-02-09 1:19 ` [PATCH v2 9/9] random: remove outdated INT_MAX >> 6 check in urandom_read() Jason A. Donenfeld
2022-02-21 3:56 ` 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=20220209011919.493762-2-Jason@zx2c4.com \
--to=jason@zx2c4.com \
--cc=ebiggers@google.com \
--cc=ebiggers@kernel.org \
--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