]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
authorArd Biesheuvel <ardb@kernel.org>
Tue, 24 Nov 2020 10:47:19 +0000 (11:47 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 4 Dec 2020 07:13:13 +0000 (18:13 +1100)
ecdh_set_secret() casts a void* pointer to a const u64* in order to
feed it into ecc_is_key_valid(). This is not generally permitted by
the C standard, and leads to actual misalignment faults on ARMv6
cores. In some cases, these are fixed up in software, but this still
leads to performance hits that are entirely avoidable.

So let's copy the key into the ctx buffer first, which we will do
anyway in the common case, and which guarantees correct alignment.

Cc: <stable@vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/ecdh.c

index b0232d6ab4ce708ea7abf5326cbbf2e4e201857b..d56b8603dec95a9fca11c4fb2c5dafdf4f5d2fcf 100644 (file)
@@ -53,12 +53,13 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
                return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
                                       ctx->private_key);
 
-       if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
-                            (const u64 *)params.key, params.key_size) < 0)
-               return -EINVAL;
-
        memcpy(ctx->private_key, params.key, params.key_size);
 
+       if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
+                            ctx->private_key, params.key_size) < 0) {
+               memzero_explicit(ctx->private_key, params.key_size);
+               return -EINVAL;
+       }
        return 0;
 }