diff mbox series

[v2,09/14] crypto: ecdh - Use properly formatted digits to check for valid key

Message ID 20240215231414.3857320-10-stefanb@linux.ibm.com (mailing list archive)
State Superseded
Delegated to: Herbert Xu
Headers show
Series Add support for NIST P521 to ecdsa and ecdh | expand

Commit Message

Stefan Berger Feb. 15, 2024, 11:14 p.m. UTC
ecc_is_key_valid expects a key with the most significant digit in the last
entry of the digit array. Currently a reverse key is passed to
ecc_is_key_valid that then passes the rather simple test checking whether
the private key is in range [2, n-3]. For all current ecdh-supported
curves (NIST P192/256/384) the 'n' parameter is a rather large number,
therefore easily passing this test. Fix the format of the digit by using
ecc_digits_from_bytes to create a temporary private key and pass it to
the test function. Keep the swapped key in ctx->private_key.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecdh.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 80afee3234fb..f187365db7b6 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -27,6 +27,8 @@  static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
 			   unsigned int len)
 {
 	struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
+	u64 priv[ECC_MAX_DIGITS];
+	unsigned int nbytes;
 	struct ecdh params;
 
 	if (crypto_ecdh_decode_key(buf, len, &params) < 0 ||
@@ -37,10 +39,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);
 
-	memcpy(ctx->private_key, params.key, params.key_size);
+	nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+
+	memcpy(ctx->private_key, params.key, nbytes);
+	ecc_swap_digits(ctx->private_key, priv, ctx->ndigits);
 
 	if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
-			     ctx->private_key, params.key_size) < 0) {
+			     priv, params.key_size) < 0) {
 		memzero_explicit(ctx->private_key, params.key_size);
 		return -EINVAL;
 	}