Skip to content

Commit 2ee25b6

Browse files
committed
random: avoid superfluous call to RDRAND in CRNG extraction
RDRAND is not fast. RDRAND is actually quite slow. We've known this for a while, which is why functions like get_random_u{32,64} were converted to use batching of our ChaCha-based CRNG instead. Yet CRNG extraction still includes a call to RDRAND, in the hot path of every call to get_random_bytes(), /dev/urandom, and getrandom(2). This call to RDRAND here seems quite superfluous. CRNG is already extracting things based on a 256-bit key, based on good entropy, which is then reseeded periodically, updated, backtrack-mutated, and so forth. The CRNG extraction construction is something that we're already relying on to be secure and solid. If it's not, that's a serious problem, and it's unlikely that mixing in a measly 32 bits from RDRAND is going to alleviate things. And in the case where the CRNG doesn't have enough entropy yet, we're already initializing the ChaCha key row with RDRAND in crng_init_try_arch_early(). Removing the call to RDRAND improves performance on an i7-11850H by 370%. In other words, the vast majority of the work done by extract_crng() prior to this commit was devoted to fetching 32 bits of RDRAND. Reviewed-by: Theodore Ts'o <[email protected]> Acked-by: Ard Biesheuvel <[email protected]> Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent 96562f2 commit 2ee25b6

File tree

1 file changed

+1
-3
lines changed

1 file changed

+1
-3
lines changed

drivers/char/random.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
10231023
static void _extract_crng(struct crng_state *crng,
10241024
__u8 out[CHACHA_BLOCK_SIZE])
10251025
{
1026-
unsigned long v, flags, init_time;
1026+
unsigned long flags, init_time;
10271027

10281028
if (crng_ready()) {
10291029
init_time = READ_ONCE(crng->init_time);
@@ -1033,8 +1033,6 @@ static void _extract_crng(struct crng_state *crng,
10331033
&input_pool : NULL);
10341034
}
10351035
spin_lock_irqsave(&crng->lock, flags);
1036-
if (arch_get_random_long(&v))
1037-
crng->state[14] ^= v;
10381036
chacha20_block(&crng->state[0], out);
10391037
if (crng->state[12] == 0)
10401038
crng->state[13]++;

0 commit comments

Comments
 (0)