summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2020-11-24 11:47:19 +0100
committerHerbert Xu <herbert@gondor.apana.org.au>2020-12-04 18:13:13 +1100
commit8319c80ab523e5735c07bb0da3bae7a93997c61e (patch)
tree789feca3be5b6e997c000435fa0e75faa0f74415
parenta8f0e3a397cd601adc3844d7f56a1ac53da66bda (diff)
downloadlinux-crypto-8319c80ab523e5735c07bb0da3bae7a93997c61e.tar.gz
linux-crypto-8319c80ab523e5735c07bb0da3bae7a93997c61e.zip
crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
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>
-rw-r--r--crypto/ecdh.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index b0232d6a..d56b8603 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -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;
}