diff mbox series

crypto: ecdh - avoid unaligned accesses in ecdh_set_secret()

Message ID 20201124104719.13415-1-ardb@kernel.org
State Accepted
Commit 17858b140bf49961b71d4e73f1c3ea9bc8e7dda0
Headers show
Series crypto: ecdh - avoid unaligned accesses in ecdh_set_secret() | expand

Commit Message

Ard Biesheuvel Nov. 24, 2020, 10:47 a.m. UTC
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>
---
 crypto/ecdh.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Herbert Xu Dec. 4, 2020, 7:15 a.m. UTC | #1
On Tue, Nov 24, 2020 at 11:47:19AM +0100, Ard Biesheuvel wrote:
> 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>

> ---

>  crypto/ecdh.c | 9 +++++----

>  1 file changed, 5 insertions(+), 4 deletions(-)


Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
diff mbox series

Patch

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;
 }