• Eric Biggers's avatar
    crypto: chacha-generic - fix use as arm64 no-NEON fallback · 713d486a
    Eric Biggers authored
    commit 7aceaaef upstream.
    
    The arm64 implementations of ChaCha and XChaCha are failing the extra
    crypto self-tests following my patches to test the !may_use_simd() code
    paths, which previously were untested.  The problem is as follows:
    
    When !may_use_simd(), the arm64 NEON implementations fall back to the
    generic implementation, which uses the skcipher_walk API to iterate
    through the src/dst scatterlists.  Due to how the skcipher_walk API
    works, walk.stride is set from the skcipher_alg actually being used,
    which in this case is the arm64 NEON algorithm.  Thus walk.stride is
    5*CHACHA_BLOCK_SIZE, not CHACHA_BLOCK_SIZE.
    
    This unnecessarily large stride shouldn't cause an actual problem.
    However, the generic implementation computes round_down(nbytes,
    walk.stride).  round_down() assumes the round amount is a power of 2,
    which 5*CHACHA_BLOCK_SIZE is not, so it gives the wrong result.
    
    This causes the following case in skcipher_walk_done() to be hit,
    causing a WARN() and failing the encryption operation:
    
    	if (WARN_ON(err)) {
    		/* unexpected case; didn't process all bytes */
    		err = -EINVAL;
    		goto finish;
    	}
    
    Fix it by rounding down to CHACHA_BLOCK_SIZE instead of walk.stride.
    
    (Or we could replace round_down() with rounddown(), but that would add a
    slow division operation every time, which I think we should avoid.)
    
    Fixes: 2fe55987 ("crypto: arm64/chacha - use combined SIMD/ALU routine for more speed")
    Cc: <stable@vger.kernel.org> # v5.0+
    Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
    Reviewed-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    713d486a
chacha_generic.c 6 KB