summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2020-11-24 11:47:19 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-12-30 11:54:10 +0100
commitc49bfdb521017bdabd9dc5420afbfd688e8f300f (patch)
treef122de361bfc1dba97d9c7bce56fb1b77264055a /crypto
parentfef8633a85fb6d8f11535057808e87d71e1e51a6 (diff)
downloadlinux-stable-c49bfdb521017bdabd9dc5420afbfd688e8f300f.tar.gz
linux-stable-c49bfdb521017bdabd9dc5420afbfd688e8f300f.tar.bz2
linux-stable-c49bfdb521017bdabd9dc5420afbfd688e8f300f.zip
crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()
commit 17858b140bf49961b71d4e73f1c3ea9bc8e7dda0 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/ecdh.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index b0232d6ab4ce..d56b8603dec9 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;
}