Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

random: initialize ChaCha20 constants with correct endianness

On big endian CPUs, the ChaCha20-based CRNG is using the wrong
endianness for the ChaCha20 constants.

This doesn't matter cryptographically, but technically it means it's not
ChaCha20 anymore. Fix it to always use the standard constants.

Cc: linux-crypto@vger.kernel.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Theodore Ts'o <tytso@mit.edu>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Eric Biggers and committed by
Herbert Xu
a181e0fd 30d0f6a9

+9 -4
+2 -2
drivers/char/random.c
··· 819 819 820 820 static void __maybe_unused crng_initialize_secondary(struct crng_state *crng) 821 821 { 822 - memcpy(&crng->state[0], "expand 32-byte k", 16); 822 + chacha_init_consts(crng->state); 823 823 _get_random_bytes(&crng->state[4], sizeof(__u32) * 12); 824 824 crng_init_try_arch(crng); 825 825 crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; ··· 827 827 828 828 static void __init crng_initialize_primary(struct crng_state *crng) 829 829 { 830 - memcpy(&crng->state[0], "expand 32-byte k", 16); 830 + chacha_init_consts(crng->state); 831 831 _extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0); 832 832 if (crng_init_try_arch_early(crng) && trust_cpu) { 833 833 invalidate_batched_entropy();
+7 -2
include/crypto/chacha.h
··· 47 47 hchacha_block_generic(state, out, nrounds); 48 48 } 49 49 50 - void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv); 51 - static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv) 50 + static inline void chacha_init_consts(u32 *state) 52 51 { 53 52 state[0] = 0x61707865; /* "expa" */ 54 53 state[1] = 0x3320646e; /* "nd 3" */ 55 54 state[2] = 0x79622d32; /* "2-by" */ 56 55 state[3] = 0x6b206574; /* "te k" */ 56 + } 57 + 58 + void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv); 59 + static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv) 60 + { 61 + chacha_init_consts(state); 57 62 state[4] = key[0]; 58 63 state[5] = key[1]; 59 64 state[6] = key[2];