Re: random: ensure use of aligned buffers with ChaCha20

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Le jeudi 09 août 2018 à 12:40 -0700, Eric Biggers a écrit :
> From: Eric Biggers <ebiggers@xxxxxxxxxx>
> 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 <smueller@xxxxxxxxxx>
> Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx>
> ---
>  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





[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux