lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu,  8 Feb 2024 17:18:35 -0500
From: Stefan Berger <stefanb@...ux.ibm.com>
To: keyrings@...r.kernel.org, linux-crypto@...r.kernel.org,
        herbert@...dor.apana.org.au, davem@...emloft.net
Cc: linux-kernel@...r.kernel.org, saulo.alessandre@....jus.br,
        Stefan Berger <stefanb@...ux.ibm.com>
Subject: [PATCH 09/14] crypto: ecdh - Use properly formatted digits to check for valid key

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 that rather simple test checking whether
the private key is in range [2, n-3]. For all current ecdh-supported
curves (NIST P192/256/384) n is a rather large number, therefore easily
passing this test. However, this will not work for NIST P521 anymore but
the properly prepared array of digits will need to be passed. Therefore,
use ecc_digits_from_array to create the digits array from the byte array
and pass the result to this test function. Use a swapped key in
ctx->private_key.

Note: The ctx->private_key is currently (unnecessarily) swapped and will
be swapped into proper order in ecc_make_pub_key and
crypto_ecdh_shared_secret before usage. Also the key generated in
ecc_gen_privkey, that is assigned to ctx->private_key, is currently
swapped. The above mention 'swap' and the ones mention here could likely
all be removed.

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

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index 80afee3234fb..83029233c03e 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;
+
+	ecc_digits_from_array(params.key, nbytes, priv, ctx->ndigits);
+	ecc_swap_digits(priv, ctx->private_key, 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;
 	}
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ