lkml.org 
[lkml]   [2019]   [Jul]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.2 263/413] crypto: ghash - fix unaligned memory access in ghash_setkey()
    Date
    From: Eric Biggers <ebiggers@google.com>

    commit 5c6bc4dfa515738149998bb0db2481a4fdead979 upstream.

    Changing ghash_mod_init() to be subsys_initcall made it start running
    before the alignment fault handler has been installed on ARM. In kernel
    builds where the keys in the ghash test vectors happened to be
    misaligned in the kernel image, this exposed the longstanding bug that
    ghash_setkey() is incorrectly casting the key buffer (which can have any
    alignment) to be128 for passing to gf128mul_init_4k_lle().

    Fix this by memcpy()ing the key to a temporary buffer.

    Don't fix it by setting an alignmask on the algorithm instead because
    that would unnecessarily force alignment of the data too.

    Fixes: 2cdc6899a88e ("crypto: ghash - Add GHASH digest algorithm for GCM")
    Reported-by: Peter Robinson <pbrobinson@gmail.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Eric Biggers <ebiggers@google.com>
    Tested-by: Peter Robinson <pbrobinson@gmail.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    crypto/ghash-generic.c | 8 +++++++-
    1 file changed, 7 insertions(+), 1 deletion(-)

    --- a/crypto/ghash-generic.c
    +++ b/crypto/ghash-generic.c
    @@ -31,6 +31,7 @@ static int ghash_setkey(struct crypto_sh
    const u8 *key, unsigned int keylen)
    {
    struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
    + be128 k;

    if (keylen != GHASH_BLOCK_SIZE) {
    crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
    @@ -39,7 +40,12 @@ static int ghash_setkey(struct crypto_sh

    if (ctx->gf128)
    gf128mul_free_4k(ctx->gf128);
    - ctx->gf128 = gf128mul_init_4k_lle((be128 *)key);
    +
    + BUILD_BUG_ON(sizeof(k) != GHASH_BLOCK_SIZE);
    + memcpy(&k, key, GHASH_BLOCK_SIZE); /* avoid violating alignment rules */
    + ctx->gf128 = gf128mul_init_4k_lle(&k);
    + memzero_explicit(&k, GHASH_BLOCK_SIZE);
    +
    if (!ctx->gf128)
    return -ENOMEM;


    \
     
     \ /
      Last update: 2019-07-24 21:36    [W:2.677 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site