• Eric Biggers's avatar
    crypto: x86/poly1305 - fix overflow during partial reduction · 4de25ac0
    Eric Biggers authored
    commit 678cce4019d746da6c680c48ba9e6d417803e127 upstream.
    The x86_64 implementation of Poly1305 produces the wrong result on some
    inputs because poly1305_4block_avx2() incorrectly assumes that when
    partially reducing the accumulator, the bits carried from limb 'd4' to
    limb 'h0' fit in a 32-bit integer.  This is true for poly1305-generic
    which processes only one block at a time.  However, it's not true for
    the AVX2 implementation, which processes 4 blocks at a time and
    therefore can produce intermediate limbs about 4x larger.
    Fix it by making the relevant calculations use 64-bit arithmetic rather
    than 32-bit.  Note that most of the carries already used 64-bit
    arithmetic, but the d4 -> h0 carry was different for some reason.
    To be safe I also made the same change to the corresponding SSE2 code,
    though that only operates on 1 or 2 blocks at a time.  I don't think
    it's really needed for poly1305_block_sse2(), but it doesn't hurt
    because it's already x86_64 code.  It *might* be needed for
    poly1305_2block_sse2(), but overflows aren't easy to reproduce there.
    This bug was originally detected by my patches that improve testmgr to
    fuzz algorithms against their generic implementation.  But also add a
    test vector which reproduces it directly (in the AVX2 case).
    Fixes: b1ccc8f4 ("crypto: poly1305 - Add a four block AVX2 variant for x86_64")
    Fixes: c70f4abe ("crypto: poly1305 - Add a SSE2 SIMD variant for x86_64")
    Cc: <stable@vger.kernel.org> # v4.3+
    Cc: Martin Willi <martin@strongswan.org>
    Cc: Jason A. Donenfeld <Jason@zx2c4.com>
    Signed-off-by: 's avatarEric Biggers <ebiggers@google.com>
    Reviewed-by: 's avatarMartin Willi <martin@strongswan.org>
    Signed-off-by: 's avatarHerbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>