Hi,
Le jeudi 09 août 2018 à 12:40 -0700, Eric Biggers a écrit :
> From: Eric Biggers <[email protected]>
> Subject: [PATCH] crypto: chacha20 - Fix keystream alignment for
> chacha20_block() (again)
>
> In commit 9f480faec58cd6 ("crypto: chacha20 - Fix keystream alignment
> for chacha20_block()") I had missed that chacha20_block() can end up
> being called on the buffer passed to get_random_bytes(), which can have
> any alignment. So, while my commit didn't break anything since
> chacha20_block() has actually always had a u32-alignment requirement for
> the output, it didn't fully solve the alignment problems.
>
> Revert my solution and just update chacha20_block() to use
> put_unaligned_le32(), so the output buffer doesn't have to be aligned.
>
> This is simpler, and on many CPUs it's the same speed.
>
> Reported-by: Stephan Müller <[email protected]>
> Signed-off-by: Eric Biggers <[email protected]>
> ---
> crypto/chacha20_generic.c | 7 ++++---
> drivers/char/random.c | 24 ++++++++++++------------
> include/crypto/chacha20.h | 3 +--
> lib/chacha20.c | 6 +++---
> 4 files changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/char/random.c b/drivers/char/random.c
> index bd449ad52442..b8f4345a50f4 100644
> --- a/drivers/char/random.c
> +++ b/drivers/char/random.c
> @@ -433,9 +433,9 @@ static int crng_init_cnt = 0;
> static unsigned long crng_global_init_time = 0;
> #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
> static void _extract_crng(struct crng_state *crng,
> - __u32 out[CHACHA20_BLOCK_WORDS]);
> + __u8 out[CHACHA20_BLOCK_SIZE]);
> static void _crng_backtrack_protect(struct crng_state *crng,
> - __u32 tmp[CHACHA20_BLOCK_WORDS], int used);
> + __u8 tmp[CHACHA20_BLOCK_SIZE], int used);
> static void process_random_ready_list(void);
> static void _get_random_bytes(void *buf, int nbytes);
>
[...]
> @@ -994,7 +994,7 @@ static void extract_crng(__u32 out[CHACHA20_BLOCK_WORDS])
> * enough) to mutate the CRNG key to provide backtracking protection.
> */
> static void _crng_backtrack_protect(struct crng_state *crng,
> - __u32 tmp[CHACHA20_BLOCK_WORDS], int used)
> + __u8 tmp[CHACHA20_BLOCK_SIZE], int used)
> {
> unsigned long flags;
> __u32 *s, *d;
> @@ -1006,14 +1006,14 @@ static void _crng_backtrack_protect(struct crng_state
> *crng,
> used = 0;
> }
> spin_lock_irqsave(&crng->lock, flags);
> - s = &tmp[used / sizeof(__u32)];
> + s = (__u32 *) &tmp[used];
tmp is __8* while s is __u32*, that sounds like an alignment issue ...
> d = &crng->state[4];
> for (i=0; i < 8; i++)
> *d++ ^= *s++;
... when s is dereferenced
> spin_unlock_irqrestore(&crng->lock, flags);
> }
>
Regards.
--
Yann Droneaud
OPTEYA