| From foo@baz Thu Jun 16 06:59:24 PM CEST 2022 |
| From: "Jason A. Donenfeld" <Jason@zx2c4.com> |
| Date: Tue, 8 Feb 2022 13:00:11 +0100 |
| Subject: random: do not xor RDRAND when writing into /dev/random |
| |
| From: "Jason A. Donenfeld" <Jason@zx2c4.com> |
| |
| commit 91c2afca290ed3034841c8c8532e69ed9e16cf34 upstream. |
| |
| Continuing the reasoning of "random: ensure early RDSEED goes through |
| mixer on init", we don't want RDRAND interacting with anything without |
| going through the mixer function, as a backdoored CPU could presumably |
| cancel out data during an xor, which it'd have a harder time doing when |
| being forced through a cryptographic hash function. There's actually no |
| need at all to be calling RDRAND in write_pool(), because before we |
| extract from the pool, we always do so with 32 bytes of RDSEED hashed in |
| at that stage. Xoring at this stage is needless and introduces a minor |
| liability. |
| |
| Cc: Theodore Ts'o <tytso@mit.edu> |
| Reviewed-by: Dominik Brodowski <linux@dominikbrodowski.net> |
| Reviewed-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/char/random.c | 14 ++------------ |
| 1 file changed, 2 insertions(+), 12 deletions(-) |
| |
| --- a/drivers/char/random.c |
| +++ b/drivers/char/random.c |
| @@ -1357,25 +1357,15 @@ static unsigned int random_poll(struct f |
| static int write_pool(const char __user *buffer, size_t count) |
| { |
| size_t bytes; |
| - u32 t, buf[16]; |
| + u8 buf[BLAKE2S_BLOCK_SIZE]; |
| const char __user *p = buffer; |
| |
| while (count > 0) { |
| - int b, i = 0; |
| - |
| bytes = min(count, sizeof(buf)); |
| - if (copy_from_user(&buf, p, bytes)) |
| + if (copy_from_user(buf, p, bytes)) |
| return -EFAULT; |
| - |
| - for (b = bytes; b > 0; b -= sizeof(u32), i++) { |
| - if (!arch_get_random_int(&t)) |
| - break; |
| - buf[i] ^= t; |
| - } |
| - |
| count -= bytes; |
| p += bytes; |
| - |
| mix_pool_bytes(buf, bytes); |
| cond_resched(); |
| } |