linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/14]  Add support for NIST P521 to ecdsa and ecdh
@ 2024-02-15 23:13 Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits Stefan Berger
                   ` (14 more replies)
  0 siblings, 15 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:13 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

This series of patches adds support for the NIST P521 curve to ecdsa and
ecdh. Test cases for NIST P521 are added to both modules.

An issue with the current code in ecdsa and ecdh is that it assumes that
input arrays providing key coordinates for example, are arrays of digits
(a 'digit' is a 'u64'). This works well for all currently supported
curves, such as NIST P192/256/384, but does not work for NIST P521 where
coordinates are 8 digits + 2 bytes long. So some of the changes deal with
converting byte arrays to digits and digits to byte arrays.


Regards,
   Stefan

v2:
 - Reformulated some patch descriptions
 - Fixed issue detected by krobot
 - Some other small changes to the code

Stefan Berger (14):
  crypto: ecdsa - Convert byte arrays with key coordinates to digits
  crypto: ecdsa - Adjust tests on length of key parameters
  crypto: ecdsa - Extend res.x mod n calculation for NIST P521
  crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
  crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
  crypto: ecc - Add NIST P521 curve parameters
  crypto: ecdsa - Register NIST P521 and extend test suite
  x509: Add OID for NIST P521 and extend parser for it
  crypto: ecdh - Use properly formatted digits to check for valid key
  crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte
    array
  crypto: Add nbits field to ecc_curve structure
  crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's
    nbytes
  crypto: ecdh - Use functions to copy digits from and to byte array
  crypto: ecdh - Add support for NIST P521 and add test case

 crypto/asymmetric_keys/x509_cert_parser.c |   3 +
 crypto/ecc.c                              |  71 +++++--
 crypto/ecc_curve_defs.h                   |  45 +++++
 crypto/ecdh.c                             |  59 +++++-
 crypto/ecdsa.c                            |  48 ++++-
 crypto/testmgr.c                          |  14 ++
 crypto/testmgr.h                          | 225 ++++++++++++++++++++++
 include/crypto/ecc_curve.h                |   3 +
 include/crypto/ecdh.h                     |   1 +
 include/crypto/internal/ecc.h             |  61 +++++-
 include/linux/oid_registry.h              |   1 +
 11 files changed, 495 insertions(+), 36 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 02/14] crypto: ecdsa - Adjust tests on length of key parameters Stefan Berger
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

For NIST P192/256/384 the public key's x and y parameters could be copied
directly from a given array since both parameters filled 'ndigits' of
digits (a 'digit' is a u64). For support of NIST P521 the key parameters
first have to be copied into a temporary byte array with leading zeros
and can then be copied into the final digit array using ecc_swap_digits.

Implement ecc_digits_from_bytes to convert a byte array into an array of
digits and use this function in ecdsa_set_pub_key where an input byte array
needs to be converted into digits.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecdsa.c                | 14 +++++++++-----
 include/crypto/internal/ecc.h | 19 +++++++++++++++++++
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index fbd76498aba8..ba8fb76fd165 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx)
 static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen)
 {
 	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+	unsigned int digitlen, ndigits;
 	const unsigned char *d = key;
-	const u64 *digits = (const u64 *)&d[1];
-	unsigned int ndigits;
 	int ret;
 
 	ret = ecdsa_ecc_ctx_reset(ctx);
@@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig
 		return -EINVAL;
 
 	keylen--;
-	ndigits = (keylen >> 1) / sizeof(u64);
+	digitlen = keylen >> 1;
+
+	ndigits = digitlen / sizeof(u64);
 	if (ndigits != ctx->curve->g.ndigits)
 		return -EINVAL;
 
-	ecc_swap_digits(digits, ctx->pub_key.x, ndigits);
-	ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits);
+	d++;
+
+	ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits);
+	ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits);
+
 	ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
 
 	ctx->pub_key_set = ret == 0;
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 4f6c1a68882f..bee3329af7de 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -56,6 +56,25 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
 		out[i] = get_unaligned_be64(&src[ndigits - 1 - i]);
 }
 
+/**
+ * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array
+ * @in:       Input byte array
+ * @nbytes    Size of input byte array
+ * @out       Output digits array
+ * @ndigits:  Number of digits to create from byte array
+ */
+static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
+					 u64 *out, unsigned int ndigits)
+{
+	unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+	u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT];
+	unsigned int o = sz - nbytes;
+
+	memset(tmp, 0, o);
+	memcpy(&tmp[o], in, nbytes);
+	ecc_swap_digits(tmp, out, ndigits);
+}
+
 /**
  * ecc_is_key_valid() - Validate a given ECDH private key
  *
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 02/14] crypto: ecdsa - Adjust tests on length of key parameters
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 03/14] crypto: ecdsa - Extend res.x mod n calculation for NIST P521 Stefan Berger
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

In preparation for support of NIST P521, adjust the basic tests on the
length of the provided key parameters to only ensure that the length of the
x plus y coordinates parameter array is not an odd number and that each
coordinate fits into an array of 'ndigits' digits. Mathematical tests on
the key's parameters are then done in ecc_is_pubkey_valid_full rejecting
invalid keys.

The change is necessary since NIST P521 keys do not have keys with
coordinates that each fully require 'full' digits (= u64), unlike
NIST P192/256/384 that all require multiple 'full' digits.

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

diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index ba8fb76fd165..64e1e69d53ba 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -230,7 +230,7 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig
 	if (ret < 0)
 		return ret;
 
-	if (keylen < 1 || (((keylen - 1) >> 1) % sizeof(u64)) != 0)
+	if (keylen < 1 || ((keylen - 1) & 1) != 0)
 		return -EINVAL;
 	/* we only accept uncompressed format indicated by '4' */
 	if (d[0] != 4)
@@ -239,7 +239,7 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig
 	keylen--;
 	digitlen = keylen >> 1;
 
-	ndigits = digitlen / sizeof(u64);
+	ndigits = DIV_ROUND_UP(digitlen, sizeof(u64));
 	if (ndigits != ctx->curve->g.ndigits)
 		return -EINVAL;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 03/14] crypto: ecdsa - Extend res.x mod n calculation for NIST P521
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 02/14] crypto: ecdsa - Adjust tests on length of key parameters Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 04/14] crypto: ecc - Implement vli_mmod_fast_521 for NIST p521 Stefan Berger
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

res.x has been calculated by ecc_point_mult_shamir, which uses
'mod curve_prime'. The curve_prime 'p' is typically larger than the
curve_order 'n' and therefore it is possible that p > res.x >= n.

If res.x >= n then res.x mod n can be calculated by iteratively sub-
tracting n from res.x until n > res.x. For NIST P192/256/384 this can be
done in a single subtraction. This can also be done in a single
subtraction for NIST P521.

The mathematical reason why a single subtraction is sufficient is
due to the values of 'p' and 'n' of the NIST curves where the following
holds true:

   note: max(res.x) = p - 1

   max(res.x) - n < n
       p - 1  - n < n
       p - 1      < 2n  => true for the NIST curves

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecdsa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index 64e1e69d53ba..1814f009f971 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -122,7 +122,7 @@ static int _ecdsa_verify(struct ecc_ctx *ctx, const u64 *hash, const u64 *r, con
 
 	/* res.x = res.x mod n (if res.x > order) */
 	if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1))
-		/* faster alternative for NIST p384, p256 & p192 */
+		/* faster alternative for NIST p521, p384, p256 & p192 */
 		vli_sub(res.x, res.x, curve->n, ndigits);
 
 	if (!vli_cmp(res.x, r, ndigits))
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 04/14] crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (2 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 03/14] crypto: ecdsa - Extend res.x mod n calculation for NIST P521 Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 05/14] crypto: ecc - For NIST P521 use vli_num_bits to get number of bits Stefan Berger
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Implement vli_mmod_fast_521 following the description for how to calculate
the modulus for NIST P521 in the NIST publication "Recommendations for
Discrete Logarithm-Based Cryptography: Elliptic Curve Domain Parameters"
section G.1.4.

NIST p521 requires 9 64bit digits, so increase the ECC_MAX_DIGITS so that
arrays fit the larger numbers.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc.c                  | 31 +++++++++++++++++++++++++++++++
 include/crypto/internal/ecc.h |  2 +-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index f53fb4d6af99..ea7b28b5e00e 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -902,6 +902,31 @@ static void vli_mmod_fast_384(u64 *result, const u64 *product,
 #undef AND64H
 #undef AND64L
 
+/* Computes result = product % curve_prime
+ * from "Recommendations for Discrete Logarithm-Based Cryptography:
+ *       Elliptic Curve Domain Parameters" G.1.4
+ */
+static void vli_mmod_fast_521(u64 *result, const u64 *product,
+				const u64 *curve_prime, u64 *tmp)
+{
+	const unsigned int ndigits = 9;
+	size_t i;
+
+	for (i = 0; i < ndigits; i++)
+		tmp[i] = product[i];
+	tmp[8] &= 0x1ff;
+
+	vli_set(result, tmp, ndigits);
+
+
+	for (i = 0; i < ndigits; i++)
+		tmp[i] = (product[8 + i] >> 9) | (product[9 + i] << 55);
+	tmp[8] &= 0x1ff;
+
+	vli_mod_add(result, result, tmp, curve_prime, ndigits);
+}
+
+
 /* Computes result = product % curve_prime for different curve_primes.
  *
  * Note that curve_primes are distinguished just by heuristic check and
@@ -941,6 +966,12 @@ static bool vli_mmod_fast(u64 *result, u64 *product,
 	case 6:
 		vli_mmod_fast_384(result, product, curve_prime, tmp);
 		break;
+	case 9:
+		if (!strcmp(curve->name, "nist_521")) {
+			vli_mmod_fast_521(result, product, curve_prime, tmp);
+			break;
+		}
+		fallthrough;
 	default:
 		pr_err_ratelimited("ecc: unsupported digits size!\n");
 		return false;
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index bee3329af7de..b8ca5023b3b5 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -33,7 +33,7 @@
 #define ECC_CURVE_NIST_P192_DIGITS  3
 #define ECC_CURVE_NIST_P256_DIGITS  4
 #define ECC_CURVE_NIST_P384_DIGITS  6
-#define ECC_MAX_DIGITS              (512 / 64) /* due to ecrdsa */
+#define ECC_MAX_DIGITS              (576 / 64) /* due to NIST P521 */
 
 #define ECC_DIGITS_TO_BYTES_SHIFT 3
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 05/14] crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (3 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 04/14] crypto: ecc - Implement vli_mmod_fast_521 for NIST p521 Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters Stefan Berger
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

In ecc_point_mult use vli_num_bits to determine the number of bits when
using NIST P521. The change is required specifically for NIST P521 to
pass mathematical tests on the public key.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index ea7b28b5e00e..0734cea284a4 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1326,7 +1326,10 @@ static void ecc_point_mult(struct ecc_point *result,
 	carry = vli_add(sk[0], scalar, curve->n, ndigits);
 	vli_add(sk[1], sk[0], curve->n, ndigits);
 	scalar = sk[!carry];
-	num_bits = sizeof(u64) * ndigits * 8 + 1;
+	if (ndigits == 9 && !strcmp(curve->name, "nist_521"))
+		num_bits = vli_num_bits(scalar, ndigits);
+	else
+		num_bits = sizeof(u64) * ndigits * 8 + 1;
 
 	vli_set(rx[1], point->x, ndigits);
 	vli_set(ry[1], point->y, ndigits);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (4 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 05/14] crypto: ecc - For NIST P521 use vli_num_bits to get number of bits Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-16 18:48   ` Elliott, Robert (Servers)
  2024-02-15 23:14 ` [PATCH v2 07/14] crypto: ecdsa - Register NIST P521 and extend test suite Stefan Berger
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Add the parameters for the NIST P521 curve and define a new curve ID
for it. Make the curve available in ecc_get_curve.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc.c            |  2 ++
 crypto/ecc_curve_defs.h | 44 +++++++++++++++++++++++++++++++++++++++++
 include/crypto/ecdh.h   |  1 +
 3 files changed, 47 insertions(+)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 0734cea284a4..73fbbfc8d69c 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -60,6 +60,8 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
 		return &nist_p256;
 	case ECC_CURVE_NIST_P384:
 		return &nist_p384;
+	case ECC_CURVE_NIST_P521:
+		return &nist_p521;
 	default:
 		return NULL;
 	}
diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index 9719934c9428..93a47a5d460a 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -86,6 +86,50 @@ static struct ecc_curve nist_p384 = {
 	.b = nist_p384_b
 };
 
+/* NIST P-521 */
+static u64 nist_p521_g_x[] = { 0xf97e7e31c2e5bd66ull, 0x3348b3c1856a429bull,
+				0xfe1dc127a2ffa8deull, 0xa14b5e77efe75928ull,
+				0xf828af606b4d3dbaull, 0x9c648139053fb521ull,
+				0x9e3ecb662395b442ull, 0x858e06b70404e9cdull,
+				0xc6ull };
+static u64 nist_p521_g_y[] = { 0x88be94769fd16650ull, 0x353c7086a272c240ull,
+				0xc550b9013fad0761ull, 0x97ee72995ef42640ull,
+				0x17afbd17273e662cull, 0x98f54449579b4468ull,
+				0x5c8a5fb42c7d1bd9ull, 0x39296a789a3bc004ull,
+				0x118ull };
+static u64 nist_p521_p[] = { 0xffffffffffffffffull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0x1ffull };
+static u64 nist_p521_n[] = { 0xbb6fb71e91386409ull, 0x3bb5c9b8899c47aeull,
+				0x7fcc0148f709a5d0ull, 0x51868783bf2f966bull,
+				0xfffffffffffffffaull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0x1ffull };
+static u64 nist_p521_a[] = { 0xfffffffffffffffcull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0xffffffffffffffffull, 0xffffffffffffffffull,
+				0x1ffull };
+static u64 nist_p521_b[] = { 0xef451fd46b503f00ull, 0x3573df883d2c34f1ull,
+				0x1652c0bd3bb1bf07ull, 0x56193951ec7e937bull,
+				0xb8b489918ef109e1ull, 0xa2da725b99b315f3ull,
+				0x929a21a0b68540eeull, 0x953eb9618e1c9a1full,
+				0x051ull };
+static struct ecc_curve nist_p521 = {
+	.name = "nist_521",
+	.g = {
+		.x = nist_p521_g_x,
+		.y = nist_p521_g_y,
+		.ndigits = 9,
+	},
+	.p = nist_p521_p,
+	.n = nist_p521_n,
+	.a = nist_p521_a,
+	.b = nist_p521_b
+};
+
 /* curve25519 */
 static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000,
 				0x0000000000000000, 0x0000000000000000 };
diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h
index a9f98078d29c..9784ecdd2fb4 100644
--- a/include/crypto/ecdh.h
+++ b/include/crypto/ecdh.h
@@ -26,6 +26,7 @@
 #define ECC_CURVE_NIST_P192	0x0001
 #define ECC_CURVE_NIST_P256	0x0002
 #define ECC_CURVE_NIST_P384	0x0003
+#define ECC_CURVE_NIST_P521	0x0004
 
 /**
  * struct ecdh - define an ECDH private key
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 07/14] crypto: ecdsa - Register NIST P521 and extend test suite
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (5 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 08/14] x509: Add OID for NIST P521 and extend parser for it Stefan Berger
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Register NIST P521 as an akcipher and extend the testmgr with
NIST P521-specific test vectors.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecdsa.c   |  30 ++++++++++
 crypto/testmgr.c |   7 +++
 crypto/testmgr.h | 146 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)

diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index 1814f009f971..faa55c692d2a 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -269,6 +269,28 @@ static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm)
 	return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 }
 
+static int ecdsa_nist_p521_init_tfm(struct crypto_akcipher *tfm)
+{
+	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P521);
+}
+
+static struct akcipher_alg ecdsa_nist_p521 = {
+	.verify = ecdsa_verify,
+	.set_pub_key = ecdsa_set_pub_key,
+	.max_size = ecdsa_max_size,
+	.init = ecdsa_nist_p521_init_tfm,
+	.exit = ecdsa_exit_tfm,
+	.base = {
+		.cra_name = "ecdsa-nist-p521",
+		.cra_driver_name = "ecdsa-nist-p521-generic",
+		.cra_priority = 100,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct ecc_ctx),
+	},
+};
+
 static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
 {
 	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
@@ -352,8 +374,15 @@ static int __init ecdsa_init(void)
 	if (ret)
 		goto nist_p384_error;
 
+	ret = crypto_register_akcipher(&ecdsa_nist_p521);
+	if (ret)
+		goto nist_p521_error;
+
 	return 0;
 
+nist_p521_error:
+	crypto_unregister_akcipher(&ecdsa_nist_p384);
+
 nist_p384_error:
 	crypto_unregister_akcipher(&ecdsa_nist_p256);
 
@@ -369,6 +398,7 @@ static void __exit ecdsa_exit(void)
 		crypto_unregister_akcipher(&ecdsa_nist_p192);
 	crypto_unregister_akcipher(&ecdsa_nist_p256);
 	crypto_unregister_akcipher(&ecdsa_nist_p384);
+	crypto_unregister_akcipher(&ecdsa_nist_p521);
 }
 
 subsys_initcall(ecdsa_init);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 3dddd288ca02..00f5a6cf341a 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5097,6 +5097,13 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.akcipher = __VECS(ecdsa_nist_p384_tv_template)
 		}
+	}, {
+		.alg = "ecdsa-nist-p521",
+		.test = alg_test_akcipher,
+		.fips_allowed = 1,
+		.suite = {
+			.akcipher = __VECS(ecdsa_nist_p521_tv_template)
+		}
 	}, {
 		.alg = "ecrdsa",
 		.test = alg_test_akcipher,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 986f331a5fc2..9bde04be8df9 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -991,6 +991,152 @@ static const struct akcipher_testvec ecdsa_nist_p384_tv_template[] = {
 	},
 };
 
+static const struct akcipher_testvec ecdsa_nist_p521_tv_template[] = {
+	{
+	.key = /* secp521r1(sha224) */
+	"\x04\x01\x4f\x43\x18\xb6\xa9\xc9\x5d\x68\xd3\xa9\x42\xf8\x98\xc0"
+	"\xd2\xd1\xa9\x50\x3b\xe8\xc4\x40\xe6\x11\x78\x88\x4b\xbd\x76\xa7"
+	"\x9a\xe0\xdd\x31\xa4\x67\x78\x45\x33\x9e\x8c\xd1\xc7\x44\xac\x61"
+	"\x68\xc8\x04\xe7\x5c\x79\xb1\xf1\x41\x0c\x71\xc0\x53\xa8\xbc\xfb"
+	"\xf5\xca\xd4\x01\x40\xfd\xa3\x45\xda\x08\xe0\xb4\xcb\x28\x3b\x0a"
+	"\x02\x35\x5f\x02\x9f\x3f\xcd\xef\x08\x22\x40\x97\x74\x65\xb7\x76"
+	"\x85\xc7\xc0\x5c\xfb\x81\xe1\xa5\xde\x0c\x4e\x8b\x12\x31\xb6\x47"
+	"\xed\x37\x0f\x99\x3f\x26\xba\xa3\x8e\xff\x79\x34\x7c\x3a\xfe\x1f"
+	"\x3b\x83\x82\x2f\x14",
+	.key_len = 133,
+	.params =
+	"\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+	"\x00\x23",
+	.param_len = 18,
+	.m =
+	"\xa2\x3a\x6a\x8c\x7b\x3c\xf2\x51\xf8\xbe\x5f\x4f\x3b\x15\x05\xc4"
+	"\xb5\xbc\x19\xe7\x21\x85\xe9\x23\x06\x33\x62\xfb",
+	.m_size = 28,
+	.algo = OID_id_ecdsa_with_sha224,
+	.c =
+	"\x30\x81\x86\x02\x41\x01\xd6\x43\xe7\xff\x42\xb2\xba\x74\x35\xf6"
+	"\xdc\x6d\x02\x7b\x22\xac\xe2\xef\x07\x92\xee\x60\x94\x06\xf8\x3f"
+	"\x59\x0f\x74\xf0\x3f\xd8\x18\xc6\x37\x8a\xcb\xa7\xd8\x7d\x98\x85"
+	"\x29\x88\xff\x0b\x94\x94\x6c\xa6\x9b\x89\x8b\x1e\xfd\x09\x46\x6b"
+	"\xc7\xaf\x7a\xb9\x19\x0a\x02\x41\x3a\x26\x0d\x55\xcd\x23\x1e\x7d"
+	"\xa0\x5e\xf9\x88\xf3\xd2\x32\x90\x57\x0f\xf8\x65\x97\x6b\x09\x4d"
+	"\x22\x26\x0b\x5f\x49\x32\x6b\x91\x99\x30\x90\x0f\x1c\x8f\x78\xd3"
+	"\x9f\x0e\x64\xcc\xc4\xe8\x43\xd9\x0e\x1c\xad\x22\xda\x82\x00\x35"
+	"\xa3\x50\xb1\xa5\x98\x92\x2a\xa5\x52",
+	.c_size = 137,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	},
+	{
+	.key = /* secp521r1(sha256) */
+	"\x04\x01\x05\x3a\x6b\x3b\x5a\x0f\xa7\xb9\xb7\x32\x53\x4e\xe2\xae"
+	"\x0a\x52\xc5\xda\xdd\x5a\x79\x1c\x30\x2d\x33\x07\x79\xd5\x70\x14"
+	"\x61\x0c\xec\x26\x4d\xd8\x35\x57\x04\x1d\x88\x33\x4d\xce\x05\x36"
+	"\xa5\xaf\x56\x84\xfa\x0b\x9e\xff\x7b\x30\x4b\x92\x1d\x06\xf8\x81"
+	"\x24\x1e\x51\x00\x09\x21\x51\xf7\x46\x0a\x77\xdb\xb5\x0c\xe7\x9c"
+	"\xff\x27\x3c\x02\x71\xd7\x85\x36\xf1\xaa\x11\x59\xd8\xb8\xdc\x09"
+	"\xdc\x6d\x5a\x6f\x63\x07\x6c\xe1\xe5\x4d\x6e\x0f\x6e\xfb\x7c\x05"
+	"\x8a\xe9\x53\xa8\xcf\xce\x43\x0e\x82\x20\x86\xbc\x88\x9c\xb7\xe3"
+	"\xe6\x77\x1e\x1f\x8a",
+	.key_len = 133,
+	.params =
+	"\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+	"\x00\x23",
+	.param_len = 18,
+	.m =
+	"\xcc\x97\x73\x0c\x73\xa2\x53\x2b\xfa\xd7\x83\x1d\x0c\x72\x1b\x39"
+	"\x80\x71\x8d\xdd\xc5\x9b\xff\x55\x32\x98\x25\xa2\x58\x2e\xb7\x73",
+	.m_size = 32,
+	.algo = OID_id_ecdsa_with_sha256,
+	.c =
+	"\x30\x81\x88\x02\x42\x00\xcd\xa5\x5f\x57\x52\x27\x78\x3a\xb5\x06"
+	"\x0f\xfd\x83\xfc\x0e\xd9\xce\x50\x9f\x7d\x1f\xca\x8b\xa8\x2d\x56"
+	"\x3c\xf6\xf0\xd8\xe1\xb7\x5d\x95\x35\x6f\x02\x0e\xaf\xe1\x4c\xae"
+	"\xce\x54\x76\x9a\xc2\x8f\xb8\x38\x1f\x46\x0b\x04\x64\x34\x79\xde"
+	"\x7e\xd7\x59\x10\xe9\xd9\xd5\x02\x42\x01\xcf\x50\x85\x38\xf9\x15"
+	"\x83\x18\x04\x6b\x35\xae\x65\xb5\x99\x12\x0a\xa9\x79\x24\xb9\x37"
+	"\x35\xdd\xa0\xe0\x87\x2c\x44\x4b\x5a\xee\xaf\xfa\x10\xdd\x9b\xfb"
+	"\x36\x1a\x31\x03\x42\x02\x5f\x50\xf0\xa2\x0d\x1c\x57\x56\x8f\x12"
+	"\xb7\x1d\x91\x55\x38\xb6\xf6\x34\x65\xc7\xbd",
+	.c_size = 139,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	},
+	{
+	.key = /* secp521r1(sha384) */
+	"\x04\x00\x2e\xd6\x21\x04\x75\xc3\xdc\x7d\xff\x0e\xf3\x70\x25\x2b"
+	"\xad\x72\xfc\x5a\x91\xf1\xd5\x9c\x64\xf3\x1f\x47\x11\x10\x62\x33"
+	"\xfd\x2e\xe8\x32\xca\x9e\x6f\x0a\x4c\x5b\x35\x9a\x46\xc5\xe7\xd4"
+	"\x38\xda\xb2\xf0\xf4\x87\xf3\x86\xf4\xea\x70\xad\x1e\xd4\x78\x8c"
+	"\x36\x18\x17\x00\xa2\xa0\x34\x1b\x2e\x6a\xdf\x06\xd6\x99\x2d\x47"
+	"\x50\x92\x1a\x8a\x72\x9c\x23\x44\xfa\xa7\xa9\xed\xa6\xef\x26\x14"
+	"\xb3\x9d\xfe\x5e\xa3\x8c\xd8\x29\xf8\xdf\xad\xa6\xab\xfc\xdd\x46"
+	"\x22\x6e\xd7\x35\xc7\x23\xb7\x13\xae\xb6\x34\xff\xd7\x80\xe5\x39"
+	"\xb3\x3b\x5b\x1b\x94",
+	.key_len = 133,
+	.params =
+	"\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+	"\x00\x23",
+	.param_len = 18,
+	.m =
+	"\x36\x98\xd6\x82\xfa\xad\xed\x3c\xb9\x40\xb6\x4d\x9e\xb7\x04\x26"
+	"\xad\x72\x34\x44\xd2\x81\xb4\x9b\xbe\x01\x04\x7a\xd8\x50\xf8\x59"
+	"\xba\xad\x23\x85\x6b\x59\xbe\xfb\xf6\x86\xd4\x67\xa8\x43\x28\x76",
+	.m_size = 48,
+	.algo = OID_id_ecdsa_with_sha384,
+	.c =
+	"\x30\x81\x88\x02\x42\x00\x93\x96\x76\x3c\x27\xea\xaa\x9c\x26\xec"
+	"\x51\xdc\xe8\x35\x5e\xae\x16\xf2\x4b\x64\x98\xf7\xec\xda\xc7\x7e"
+	"\x42\x71\x86\x57\x2d\xf1\x7d\xe4\xdf\x9b\x7d\x9e\x47\xca\x33\x32"
+	"\x76\x06\xd0\xf9\xc0\xe4\xe6\x84\x59\xfd\x1a\xc4\x40\xdd\x43\xb8"
+	"\x6a\xdd\xfb\xe6\x63\x4e\x28\x02\x42\x00\xff\xc3\x6a\x87\x6e\xb5"
+	"\x13\x1f\x20\x55\xce\x37\x97\xc9\x05\x51\xe5\xe4\x3c\xbc\x93\x65"
+	"\x57\x1c\x30\xda\xa7\xcd\x26\x28\x76\x3b\x52\xdf\xc4\xc0\xdb\x54"
+	"\xdb\x8a\x0d\x6a\xc3\xf3\x7a\xd1\xfa\xe7\xa7\xe5\x5a\x94\x56\xcf"
+	"\x8f\xb4\x22\xc6\x4f\xab\x2b\x62\xc1\x42\xb1",
+	.c_size = 139,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	},
+	{
+	.key = /* secp521r1(sha512) */
+	"\x04\x00\xc7\x65\xee\x0b\x86\x7d\x8f\x02\xf1\x74\x5b\xb0\x4c\x3f"
+	"\xa6\x35\x60\x9f\x55\x23\x11\xcc\xdf\xb8\x42\x99\xee\x6c\x96\x6a"
+	"\x27\xa2\x56\xb2\x2b\x03\xad\x0f\xe7\x97\xde\x09\x5d\xb4\xc5\x5f"
+	"\xbd\x87\x37\xbf\x5a\x16\x35\x56\x08\xfd\x6f\x06\x1a\x1c\x84\xee"
+	"\xc3\x64\xb3\x00\x9e\xbd\x6e\x60\x76\xee\x69\xfd\x3a\xb8\xcd\x7e"
+	"\x91\x68\x53\x57\x44\x13\x2e\x77\x09\x2a\xbe\x48\xbd\x91\xd8\xf6"
+	"\x21\x16\x53\x99\xd5\xf0\x40\xad\xa6\xf8\x58\x26\xb6\x9a\xf8\x77"
+	"\xfe\x3a\x05\x1a\xdb\xa9\x0f\xc0\x6c\x76\x30\x8c\xd8\xde\x44\xae"
+	"\xd0\x17\xdf\x49\x6a",
+	.key_len = 133,
+	.params =
+	"\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+	"\x00\x23",
+	.param_len = 18,
+	.m =
+	"\x5c\xa6\xbc\x79\xb8\xa0\x1e\x11\x83\xf7\xe9\x05\xdf\xba\xf7\x69"
+	"\x97\x22\x32\xe4\x94\x7c\x65\xbd\x74\xc6\x9a\x8b\xbd\x0d\xdc\xed"
+	"\xf5\x9c\xeb\xe1\xc5\x68\x40\xf2\xc7\x04\xde\x9e\x0d\x76\xc5\xa3"
+	"\xf9\x3c\x6c\x98\x08\x31\xbd\x39\xe8\x42\x7f\x80\x39\x6f\xfe\x68",
+	.m_size = 64,
+	.algo = OID_id_ecdsa_with_sha512,
+	.c =
+	"\x30\x81\x88\x02\x42\x01\x5c\x71\x86\x96\xac\x21\x33\x7e\x4e\xaa"
+	"\x86\xec\xa8\x05\x03\x52\x56\x63\x0e\x02\xcc\x94\xa9\x05\xb9\xfb"
+	"\x62\x1e\x42\x03\x6c\x74\x8a\x1f\x12\x3e\xb7\x7e\x51\xff\x7f\x27"
+	"\x93\xe8\x6c\x49\x7d\x28\xfc\x80\xa6\x13\xfc\xb6\x90\xf7\xbb\x28"
+	"\xb5\x04\xb0\xb6\x33\x1c\x7e\x02\x42\x01\x70\x43\x52\x1d\xe3\xc6"
+	"\xbd\x5a\x40\x95\x35\x89\x4f\x41\x5f\x9e\x19\x88\x05\x3e\x43\x39"
+	"\x01\xbd\xb7\x7a\x76\x37\x51\x47\x49\x98\x12\x71\xd0\xe9\xca\xa7"
+	"\xc0\xcb\xaa\x00\x55\xbb\x6a\xb4\x73\x00\xd2\x72\x74\x13\x63\x39"
+	"\xa6\xe5\x25\x46\x1e\x77\x44\x78\xe0\xd1\x04",
+	.c_size = 139,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	},
+};
+
 /*
  * EC-RDSA test vectors are generated by gost-engine.
  */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 08/14] x509: Add OID for NIST P521 and extend parser for it
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (6 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 07/14] crypto: ecdsa - Register NIST P521 and extend test suite Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 09/14] crypto: ecdh - Use properly formatted digits to check for valid key Stefan Berger
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger, David Howells

Prepare the x509 parser to accept NIST P521 certificates and add the
OID for ansip521r1, which is the identifier for NIST P521.

Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/asymmetric_keys/x509_cert_parser.c | 3 +++
 include/linux/oid_registry.h              | 1 +
 2 files changed, 4 insertions(+)

diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 487204d39426..99f809b7910b 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -538,6 +538,9 @@ int x509_extract_key_data(void *context, size_t hdrlen,
 		case OID_id_ansip384r1:
 			ctx->cert->pub->pkey_algo = "ecdsa-nist-p384";
 			break;
+		case OID_id_ansip521r1:
+			ctx->cert->pub->pkey_algo = "ecdsa-nist-p521";
+			break;
 		default:
 			return -ENOPKG;
 		}
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index 3921fbed0b28..af16d96fbbf2 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -65,6 +65,7 @@ enum OID {
 	OID_Scram,			/* 1.3.6.1.5.5.14 */
 	OID_certAuthInfoAccess,		/* 1.3.6.1.5.5.7.1.1 */
 	OID_id_ansip384r1,		/* 1.3.132.0.34 */
+	OID_id_ansip521r1,		/* 1.3.132.0.35 */
 	OID_sha256,			/* 2.16.840.1.101.3.4.2.1 */
 	OID_sha384,			/* 2.16.840.1.101.3.4.2.2 */
 	OID_sha512,			/* 2.16.840.1.101.3.4.2.3 */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 09/14] crypto: ecdh - Use properly formatted digits to check for valid key
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (7 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 08/14] x509: Add OID for NIST P521 and extend parser for it Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 10/14] crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte array Stefan Berger
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

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


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 10/14] crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte array
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (8 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 09/14] crypto: ecdh - Use properly formatted digits to check for valid key Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 11/14] crypto: Add nbits field to ecc_curve structure Stefan Berger
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Implement ecc_digits_to_bytes to convert an array of digits into an
nbytes-sized byte array.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 include/crypto/internal/ecc.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index b8ca5023b3b5..6229aa3f3218 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -75,6 +75,24 @@ static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
 	ecc_swap_digits(tmp, out, ndigits);
 }
 
+/**
+ * ecc_digits_to_bytes() - Copy digits into a byte array of size nbytes
+ * @in:      Input digits array
+ * @ndigits: Number of digits in input digits array
+ * @out:     Output byte array
+ * @nbytes:  Number of bytes to copy into byte array
+ */
+static inline void ecc_digits_to_bytes(const u64 *in, unsigned int ndigits,
+				       u8 *out, unsigned int nbytes)
+{
+	unsigned int sz = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+	u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT];
+	unsigned int o = sz - nbytes;
+
+	ecc_swap_digits(in, (u64 *)tmp, ndigits);
+	memcpy(out, &tmp[o], nbytes);
+}
+
 /**
  * ecc_is_key_valid() - Validate a given ECDH private key
  *
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 11/14] crypto: Add nbits field to ecc_curve structure
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (9 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 10/14] crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte array Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 12/14] crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's nbytes Stefan Berger
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Add the number of bits a curve has to the ecc_curve definition. This field
only needs to be set for curves that don't fill up all bytes in their
digits, such as NIST P521 which has only 9 bits in the most significant
digit. This field will be used to determine the number of bytes a curve
requires for its key coordinates for example.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc_curve_defs.h    | 1 +
 include/crypto/ecc_curve.h | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index 93a47a5d460a..09a221657c31 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -119,6 +119,7 @@ static u64 nist_p521_b[] = { 0xef451fd46b503f00ull, 0x3573df883d2c34f1ull,
 				0x051ull };
 static struct ecc_curve nist_p521 = {
 	.name = "nist_521",
+	.nbits = 521,
 	.g = {
 		.x = nist_p521_g_x,
 		.y = nist_p521_g_y,
diff --git a/include/crypto/ecc_curve.h b/include/crypto/ecc_curve.h
index 70964781eb68..337a44956926 100644
--- a/include/crypto/ecc_curve.h
+++ b/include/crypto/ecc_curve.h
@@ -23,6 +23,8 @@ struct ecc_point {
  * struct ecc_curve - definition of elliptic curve
  *
  * @name:	Short name of the curve.
+ * @nbits:      Curves that do not use all bits in their ndigits must specify
+ *              their number of bits here, otherwise can leave at 0.
  * @g:		Generator point of the curve.
  * @p:		Prime number, if Barrett's reduction is used for this curve
  *		pre-calculated value 'mu' is appended to the @p after ndigits.
@@ -34,6 +36,7 @@ struct ecc_point {
  */
 struct ecc_curve {
 	char *name;
+	unsigned int nbits;
 	struct ecc_point g;
 	u64 *p;
 	u64 *n;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 12/14] crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's nbytes
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (10 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 11/14] crypto: Add nbits field to ecc_curve structure Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 13/14] crypto: ecdh - Use functions to copy digits from and to byte array Stefan Berger
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Implement ecc_curve_get_nbytes to get a curve's number of bytes (nbytes).
The number of bytes can be derived from the nbits field of a curve, if
set, otherwise from the ndigits field.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc.c                  |  6 ++----
 include/crypto/internal/ecc.h | 11 +++++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index 73fbbfc8d69c..f643719450b8 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1478,10 +1478,8 @@ static int __ecc_is_key_valid(const struct ecc_curve *curve,
 int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits,
 		     const u64 *private_key, unsigned int private_key_len)
 {
-	int nbytes;
 	const struct ecc_curve *curve = ecc_get_curve(curve_id);
-
-	nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+	int nbytes = ecc_curve_get_nbytes(curve);
 
 	if (private_key_len != nbytes)
 		return -EINVAL;
@@ -1506,7 +1504,7 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
 {
 	const struct ecc_curve *curve = ecc_get_curve(curve_id);
 	u64 priv[ECC_MAX_DIGITS];
-	unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+	unsigned int nbytes = ecc_curve_get_nbytes(curve);
 	unsigned int nbits = vli_num_bits(curve->n, ndigits);
 	int err;
 
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 6229aa3f3218..5d485d3221d3 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -93,6 +93,17 @@ static inline void ecc_digits_to_bytes(const u64 *in, unsigned int ndigits,
 	memcpy(out, &tmp[o], nbytes);
 }
 
+/**
+ * ecc_curve_get_nbytes() - Get the number of bytes the curve requires
+ * @curve:   The curve
+ */
+static inline unsigned int ecc_curve_get_nbytes(const struct ecc_curve *curve)
+{
+	if (curve->nbits)
+		return DIV_ROUND_UP(curve->nbits, 8);
+	return curve->g.ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+}
+
 /**
  * ecc_is_key_valid() - Validate a given ECDH private key
  *
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 13/14] crypto: ecdh - Use functions to copy digits from and to byte array
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (11 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 12/14] crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's nbytes Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-15 23:14 ` [PATCH v2 14/14] crypto: ecdh - Add support for NIST P521 and add test case Stefan Berger
  2024-02-16 19:27 ` [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Simo Sorce
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

All curves supported so far provide full 64bit digit arrays to convert
coordinates from and to. For NIST P521 only 8 digits and 2 bytes will be
given per coordinate so that conversion from 9 digits does not work since
some bytes are missing. Therefore, regard the input (output)
arrays as byte arrays that need to be converted to digits (from digits).
Use ecc_digits_from_bytes to convert a byte array to digits and
ecc_digits_to_bytes to convert digits to a byte array.

crypt_ecdh_shared_secret creates 'rand_z' from 'nbytes' of random bytes.
Also convert this array to fill a byte array with 'nbytes' of random bytes
and create the rand_z digits from the byte array. The most significant
digit of rand_z needs to be adjusted to mask out unnecessary bits beyond
the 521 bits of NIST P521. Therefore, apply the appropriate mask to the
most significant digit keeping only the 9 most significant bits.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecc.c                  | 27 +++++++++++++++------------
 crypto/ecdh.c                 | 26 +++++++++++++++-----------
 include/crypto/internal/ecc.h | 10 +++++++---
 3 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index f643719450b8..ced77eb6e533 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1542,7 +1542,8 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey)
 EXPORT_SYMBOL(ecc_gen_privkey);
 
 int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
-		     const u64 *private_key, u64 *public_key)
+		     const u64 *private_key, u8 *public_key,
+		     unsigned int nbytes)
 {
 	int ret = 0;
 	struct ecc_point *pk;
@@ -1570,8 +1571,8 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
 		goto err_free_point;
 	}
 
-	ecc_swap_digits(pk->x, public_key, ndigits);
-	ecc_swap_digits(pk->y, &public_key[ndigits], ndigits);
+	ecc_digits_to_bytes(pk->x, ndigits, public_key, nbytes);
+	ecc_digits_to_bytes(pk->y, ndigits, &public_key[nbytes], nbytes);
 
 err_free_point:
 	ecc_free_point(pk);
@@ -1641,14 +1642,14 @@ int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
 EXPORT_SYMBOL(ecc_is_pubkey_valid_full);
 
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-			      const u64 *private_key, const u64 *public_key,
-			      u64 *secret)
+			      const u64 *private_key, const u8 *public_key,
+			      unsigned int nbytes, u8 *secret, u64 msd_mask)
 {
 	int ret = 0;
 	struct ecc_point *product, *pk;
 	u64 priv[ECC_MAX_DIGITS];
 	u64 rand_z[ECC_MAX_DIGITS];
-	unsigned int nbytes;
+	u8 tmp[ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT];
 	const struct ecc_curve *curve = ecc_get_curve(curve_id);
 
 	if (!private_key || !public_key || !curve ||
@@ -1657,9 +1658,10 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
 		goto out;
 	}
 
-	nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
-
-	get_random_bytes(rand_z, nbytes);
+	get_random_bytes(tmp, nbytes);
+	ecc_digits_from_bytes(tmp, nbytes, rand_z, ndigits);
+	if (msd_mask)
+		rand_z[ndigits - 1] &= msd_mask;
 
 	pk = ecc_alloc_point(ndigits);
 	if (!pk) {
@@ -1667,8 +1669,9 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
 		goto out;
 	}
 
-	ecc_swap_digits(public_key, pk->x, ndigits);
-	ecc_swap_digits(&public_key[ndigits], pk->y, ndigits);
+	ecc_digits_from_bytes(public_key, nbytes, pk->x, ndigits);
+	ecc_digits_from_bytes(&public_key[nbytes], nbytes, pk->y, ndigits);
+
 	ret = ecc_is_pubkey_valid_partial(curve, pk);
 	if (ret)
 		goto err_alloc_product;
@@ -1688,7 +1691,7 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
 		goto err_validity;
 	}
 
-	ecc_swap_digits(product->x, secret, ndigits);
+	ecc_digits_to_bytes(product->x, ndigits, secret, nbytes);
 
 err_validity:
 	memzero_explicit(priv, sizeof(priv));
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index f187365db7b6..e64133428552 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -15,6 +15,8 @@
 struct ecdh_ctx {
 	unsigned int curve_id;
 	unsigned int ndigits;
+	unsigned int nbytes;
+	u64 msd_mask;
 	u64 private_key[ECC_MAX_DIGITS];
 };
 
@@ -28,7 +30,6 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
 {
 	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 ||
@@ -39,10 +40,8 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
 		return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
 				       ctx->private_key);
 
-	nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
-
-	memcpy(ctx->private_key, params.key, nbytes);
-	ecc_swap_digits(ctx->private_key, priv, ctx->ndigits);
+	ecc_digits_from_bytes(params.key, ctx->nbytes, priv, ctx->ndigits);
+	ecc_swap_digits(priv, ctx->private_key, ctx->ndigits);
 
 	if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
 			     priv, params.key_size) < 0) {
@@ -56,13 +55,13 @@ static int ecdh_compute_value(struct kpp_request *req)
 {
 	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
 	struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
-	u64 *public_key;
-	u64 *shared_secret = NULL;
+	unsigned int nbytes = ctx->nbytes;
+	u8 *public_key;
+	u8 *shared_secret = NULL;
 	void *buf;
-	size_t copied, nbytes, public_key_sz;
+	size_t copied, public_key_sz;
 	int ret = -ENOMEM;
 
-	nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 	/* Public part is a point thus it has both coordinates */
 	public_key_sz = 2 * nbytes;
 
@@ -91,12 +90,14 @@ static int ecdh_compute_value(struct kpp_request *req)
 
 		ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits,
 						ctx->private_key, public_key,
-						shared_secret);
+						nbytes, shared_secret,
+						ctx->msd_mask);
 
 		buf = shared_secret;
 	} else {
 		ret = ecc_make_pub_key(ctx->curve_id, ctx->ndigits,
-				       ctx->private_key, public_key);
+				       ctx->private_key, public_key,
+				       nbytes);
 		buf = public_key;
 		nbytes = public_key_sz;
 	}
@@ -134,6 +135,7 @@ static int ecdh_nist_p192_init_tfm(struct crypto_kpp *tfm)
 
 	ctx->curve_id = ECC_CURVE_NIST_P192;
 	ctx->ndigits = ECC_CURVE_NIST_P192_DIGITS;
+	ctx->nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 
 	return 0;
 }
@@ -159,6 +161,7 @@ static int ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm)
 
 	ctx->curve_id = ECC_CURVE_NIST_P256;
 	ctx->ndigits = ECC_CURVE_NIST_P256_DIGITS;
+	ctx->nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 
 	return 0;
 }
@@ -184,6 +187,7 @@ static int ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm)
 
 	ctx->curve_id = ECC_CURVE_NIST_P384;
 	ctx->ndigits = ECC_CURVE_NIST_P384_DIGITS;
+	ctx->nbytes = ctx->ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
 
 	return 0;
 }
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 5d485d3221d3..328a82bd35c8 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -138,12 +138,14 @@ int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey);
  * @ndigits:		curve's number of digits
  * @private_key:	pregenerated private key for the given curve
  * @public_key:		buffer for storing the generated public key
+ * @nbytes:		number of bytes per coordinate of public key
  *
  * Returns 0 if the public key was generated successfully, a negative value
  * if an error occurred.
  */
 int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
-		     const u64 *private_key, u64 *public_key);
+		     const u64 *private_key, u8 *public_key,
+		     unsigned int nbytes);
 
 /**
  * crypto_ecdh_shared_secret() - Compute a shared secret
@@ -152,7 +154,9 @@ int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
  * @ndigits:		curve's number of digits
  * @private_key:	private key of part A
  * @public_key:		public key of counterpart B
+ * @nbytes:		number of bytes per coordinate of public key
  * @secret:		buffer for storing the calculated shared secret
+ * @msd_mask:		optional mask to apply to the most significant digit
  *
  * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret
  * before using it for symmetric encryption or HMAC.
@@ -161,8 +165,8 @@ int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits,
  * if an error occurred.
  */
 int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
-			      const u64 *private_key, const u64 *public_key,
-			      u64 *secret);
+			      const u64 *private_key, const u8 *public_key,
+			      unsigned int nbytes, u8 *secret, u64 msd_mask);
 
 /**
  * ecc_is_pubkey_valid_partial() - Partial public key validation
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 14/14] crypto: ecdh - Add support for NIST P521 and add test case
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (12 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 13/14] crypto: ecdh - Use functions to copy digits from and to byte array Stefan Berger
@ 2024-02-15 23:14 ` Stefan Berger
  2024-02-16 19:27 ` [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Simo Sorce
  14 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-15 23:14 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre, Stefan Berger

Implement ecdh support with NIST P521 and add a test case from RFC5903.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 crypto/ecdh.c                 | 34 +++++++++++++++
 crypto/testmgr.c              |  7 ++++
 crypto/testmgr.h              | 79 +++++++++++++++++++++++++++++++++++
 include/crypto/internal/ecc.h |  1 +
 4 files changed, 121 insertions(+)

diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index e64133428552..be87832e172e 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -207,6 +207,32 @@ static struct kpp_alg ecdh_nist_p384 = {
 	},
 };
 
+static int ecdh_nist_p521_init_tfm(struct crypto_kpp *tfm)
+{
+	struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
+
+	ctx->curve_id = ECC_CURVE_NIST_P521;
+	ctx->ndigits = ECC_CURVE_NIST_P521_DIGITS;
+	ctx->nbytes = DIV_ROUND_UP(521, 8);
+	ctx->msd_mask = 0x1ff;
+
+	return 0;
+}
+static struct kpp_alg ecdh_nist_p521 = {
+	.set_secret = ecdh_set_secret,
+	.generate_public_key = ecdh_compute_value,
+	.compute_shared_secret = ecdh_compute_value,
+	.max_size = ecdh_max_size,
+	.init = ecdh_nist_p521_init_tfm,
+	.base = {
+		.cra_name = "ecdh-nist-p521",
+		.cra_driver_name = "ecdh-nist-p521-generic",
+		.cra_priority = 100,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct ecdh_ctx),
+	},
+};
+
 static bool ecdh_nist_p192_registered;
 
 static int __init ecdh_init(void)
@@ -225,8 +251,15 @@ static int __init ecdh_init(void)
 	if (ret)
 		goto nist_p384_error;
 
+	ret = crypto_register_kpp(&ecdh_nist_p521);
+	if (ret)
+		goto nist_p521_error;
+
 	return 0;
 
+nist_p521_error:
+	crypto_unregister_kpp(&ecdh_nist_p384);
+
 nist_p384_error:
 	crypto_unregister_kpp(&ecdh_nist_p256);
 
@@ -242,6 +275,7 @@ static void __exit ecdh_exit(void)
 		crypto_unregister_kpp(&ecdh_nist_p192);
 	crypto_unregister_kpp(&ecdh_nist_p256);
 	crypto_unregister_kpp(&ecdh_nist_p384);
+	crypto_unregister_kpp(&ecdh_nist_p521);
 }
 
 subsys_initcall(ecdh_init);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 00f5a6cf341a..91f39f5a438b 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5077,6 +5077,13 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.kpp = __VECS(ecdh_p384_tv_template)
 		}
+	}, {
+		.alg = "ecdh-nist-p521",
+		.test = alg_test_kpp,
+		.fips_allowed = 1,
+		.suite = {
+			.kpp = __VECS(ecdh_p521_tv_template)
+		}
 	}, {
 		.alg = "ecdsa-nist-p192",
 		.test = alg_test_akcipher,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 9bde04be8df9..dc9a2b30b5fd 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -4468,6 +4468,85 @@ static const struct kpp_testvec ecdh_p384_tv_template[] = {
 	}
 };
 
+/*
+ * NIST P521 test vectors from RFC5903
+ */
+static const struct kpp_testvec ecdh_p521_tv_template[] = {
+	{
+	.secret =
+#ifdef __LITTLE_ENDIAN
+	"\x02\x00" /* type */
+	"\x48\x00" /* len */
+	"\x42\x00" /* key_size */
+#else
+	"\x00\x02" /* type */
+	"\x00\x48" /* len */
+	"\x00\x42" /* key_size */
+#endif
+	"\x00\x37\xAD\xE9\x31\x9A\x89\xF4"
+	"\xDA\xBD\xB3\xEF\x41\x1A\xAC\xCC"
+	"\xA5\x12\x3C\x61\xAC\xAB\x57\xB5"
+	"\x39\x3D\xCE\x47\x60\x81\x72\xA0"
+	"\x95\xAA\x85\xA3\x0F\xE1\xC2\x95"
+	"\x2C\x67\x71\xD9\x37\xBA\x97\x77"
+	"\xF5\x95\x7B\x26\x39\xBA\xB0\x72"
+	"\x46\x2F\x68\xC2\x7A\x57\x38\x2D"
+	"\x4A\x52",
+	.b_public =
+	"\x00\xD0\xB3\x97\x5A\xC4\xB7\x99"
+	"\xF5\xBE\xA1\x6D\x5E\x13\xE9\xAF"
+	"\x97\x1D\x5E\x9B\x98\x4C\x9F\x39"
+	"\x72\x8B\x5E\x57\x39\x73\x5A\x21"
+	"\x9B\x97\xC3\x56\x43\x6A\xDC\x6E"
+	"\x95\xBB\x03\x52\xF6\xBE\x64\xA6"
+	"\xC2\x91\x2D\x4E\xF2\xD0\x43\x3C"
+	"\xED\x2B\x61\x71\x64\x00\x12\xD9"
+	"\x46\x0F"
+	"\x01\x5C\x68\x22\x63\x83\x95\x6E"
+	"\x3B\xD0\x66\xE7\x97\xB6\x23\xC2"
+	"\x7C\xE0\xEA\xC2\xF5\x51\xA1\x0C"
+	"\x2C\x72\x4D\x98\x52\x07\x7B\x87"
+	"\x22\x0B\x65\x36\xC5\xC4\x08\xA1"
+	"\xD2\xAE\xBB\x8E\x86\xD6\x78\xAE"
+	"\x49\xCB\x57\x09\x1F\x47\x32\x29"
+	"\x65\x79\xAB\x44\xFC\xD1\x7F\x0F"
+	"\xC5\x6A",
+	.expected_a_public =
+	"\x00\x15\x41\x7E\x84\xDB\xF2\x8C"
+	"\x0A\xD3\xC2\x78\x71\x33\x49\xDC"
+	"\x7D\xF1\x53\xC8\x97\xA1\x89\x1B"
+	"\xD9\x8B\xAB\x43\x57\xC9\xEC\xBE"
+	"\xE1\xE3\xBF\x42\xE0\x0B\x8E\x38"
+	"\x0A\xEA\xE5\x7C\x2D\x10\x75\x64"
+	"\x94\x18\x85\x94\x2A\xF5\xA7\xF4"
+	"\x60\x17\x23\xC4\x19\x5D\x17\x6C"
+	"\xED\x3E"
+	"\x01\x7C\xAE\x20\xB6\x64\x1D\x2E"
+	"\xEB\x69\x57\x86\xD8\xC9\x46\x14"
+	"\x62\x39\xD0\x99\xE1\x8E\x1D\x5A"
+	"\x51\x4C\x73\x9D\x7C\xB4\xA1\x0A"
+	"\xD8\xA7\x88\x01\x5A\xC4\x05\xD7"
+	"\x79\x9D\xC7\x5E\x7B\x7D\x5B\x6C"
+	"\xF2\x26\x1A\x6A\x7F\x15\x07\x43"
+	"\x8B\xF0\x1B\xEB\x6C\xA3\x92\x6F"
+	"\x95\x82",
+	.expected_ss =
+	"\x01\x14\x4C\x7D\x79\xAE\x69\x56"
+	"\xBC\x8E\xDB\x8E\x7C\x78\x7C\x45"
+	"\x21\xCB\x08\x6F\xA6\x44\x07\xF9"
+	"\x78\x94\xE5\xE6\xB2\xD7\x9B\x04"
+	"\xD1\x42\x7E\x73\xCA\x4B\xAA\x24"
+	"\x0A\x34\x78\x68\x59\x81\x0C\x06"
+	"\xB3\xC7\x15\xA3\xA8\xCC\x31\x51"
+	"\xF2\xBE\xE4\x17\x99\x6D\x19\xF3"
+	"\xDD\xEA",
+	.secret_size = 72,
+	.b_public_size = 132,
+	.expected_a_public_size = 132,
+	.expected_ss_size = 66
+	}
+};
+
 /*
  * MD4 test vectors from RFC1320
  */
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 328a82bd35c8..a04b313f2871 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -33,6 +33,7 @@
 #define ECC_CURVE_NIST_P192_DIGITS  3
 #define ECC_CURVE_NIST_P256_DIGITS  4
 #define ECC_CURVE_NIST_P384_DIGITS  6
+#define ECC_CURVE_NIST_P521_DIGITS  9
 #define ECC_MAX_DIGITS              (576 / 64) /* due to NIST P521 */
 
 #define ECC_DIGITS_TO_BYTES_SHIFT 3
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* RE: [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters
  2024-02-15 23:14 ` [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters Stefan Berger
@ 2024-02-16 18:48   ` Elliott, Robert (Servers)
  2024-02-16 19:03     ` Stefan Berger
  0 siblings, 1 reply; 21+ messages in thread
From: Elliott, Robert (Servers) @ 2024-02-16 18:48 UTC (permalink / raw)
  To: Stefan Berger, keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre

> -----Original Message-----
> From: Stefan Berger <stefanb@linux.ibm.com>
> Sent: Thursday, February 15, 2024 5:14 PM
> Subject: [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters
> 
> Add the parameters for the NIST P521 curve and define a new curve ID
> for it. Make the curve available in ecc_get_curve.
> 
...
> diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
...
> +static struct ecc_curve nist_p521 = {
> +	.name = "nist_521",

Are the name fields in the ecc_curve structures used anywhere or
exposed to userspace?

It'd be nice if the strings for the nist_p192, nist_p256, and nist_p384 
structures and this new nist_p521 structure included "p" before
the number, better matching all the code and the NIST FIPS 186-4 names:
    .name = "nist_p192"
    .name = "nist_p256"
    .name = "nist_p384"
    .name = "nist_p521"



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters
  2024-02-16 18:48   ` Elliott, Robert (Servers)
@ 2024-02-16 19:03     ` Stefan Berger
  0 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-16 19:03 UTC (permalink / raw)
  To: Elliott, Robert (Servers), keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre



On 2/16/24 13:48, Elliott, Robert (Servers) wrote:
>> -----Original Message-----
>> From: Stefan Berger <stefanb@linux.ibm.com>
>> Sent: Thursday, February 15, 2024 5:14 PM
>> Subject: [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters
>>
>> Add the parameters for the NIST P521 curve and define a new curve ID
>> for it. Make the curve available in ecc_get_curve.
>>
> ...
>> diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
> ...
>> +static struct ecc_curve nist_p521 = {
>> +	.name = "nist_521",
> 
> Are the name fields in the ecc_curve structures used anywhere or
> exposed to userspace?
> 
> It'd be nice if the strings for the nist_p192, nist_p256, and nist_p384
> structures and this new nist_p521 structure included "p" before
> the number, better matching all the code and the NIST FIPS 186-4 names:
>      .name = "nist_p192"
>      .name = "nist_p256"
>      .name = "nist_p384"
>      .name = "nist_p521"
> 
> 

This is what is exposed:

$ cat /proc/crypto | grep nist
name         : ecdh-nist-p384
driver       : ecdh-nist-p384-generic
name         : ecdh-nist-p256
driver       : ecdh-nist-p256-generic
name         : ecdh-nist-p192
driver       : ecdh-nist-p192-generic
name         : ecdsa-nist-p384
driver       : ecdsa-nist-p384-generic
name         : ecdsa-nist-p256
driver       : ecdsa-nist-p256-generic
name         : ecdsa-nist-p192
driver       : ecdsa-nist-p192-generic

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 00/14]  Add support for NIST P521 to ecdsa and ecdh
  2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
                   ` (13 preceding siblings ...)
  2024-02-15 23:14 ` [PATCH v2 14/14] crypto: ecdh - Add support for NIST P521 and add test case Stefan Berger
@ 2024-02-16 19:27 ` Simo Sorce
  2024-02-16 19:32   ` Stefan Berger
  14 siblings, 1 reply; 21+ messages in thread
From: Simo Sorce @ 2024-02-16 19:27 UTC (permalink / raw)
  To: Stefan Berger, keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre

On Thu, 2024-02-15 at 18:13 -0500, Stefan Berger wrote:
> This series of patches adds support for the NIST P521 curve to ecdsa and
> ecdh. Test cases for NIST P521 are added to both modules.
> 
> An issue with the current code in ecdsa and ecdh is that it assumes that
> input arrays providing key coordinates for example, are arrays of digits
> (a 'digit' is a 'u64'). This works well for all currently supported
> curves, such as NIST P192/256/384, but does not work for NIST P521 where
> coordinates are 8 digits + 2 bytes long. So some of the changes deal with
> converting byte arrays to digits and digits to byte arrays.
> 
> 
> Regards,
>    Stefan
> 
> v2:
>  - Reformulated some patch descriptions
>  - Fixed issue detected by krobot
>  - Some other small changes to the code
> 
> Stefan Berger (14):
>   crypto: ecdsa - Convert byte arrays with key coordinates to digits
>   crypto: ecdsa - Adjust tests on length of key parameters
>   crypto: ecdsa - Extend res.x mod n calculation for NIST P521
>   crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
>   crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
>   crypto: ecc - Add NIST P521 curve parameters
>   crypto: ecdsa - Register NIST P521 and extend test suite
>   x509: Add OID for NIST P521 and extend parser for it
>   crypto: ecdh - Use properly formatted digits to check for valid key
>   crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte
>     array
>   crypto: Add nbits field to ecc_curve structure
>   crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's
>     nbytes
>   crypto: ecdh - Use functions to copy digits from and to byte array
>   crypto: ecdh - Add support for NIST P521 and add test case
> 
>  crypto/asymmetric_keys/x509_cert_parser.c |   3 +
>  crypto/ecc.c                              |  71 +++++--
>  crypto/ecc_curve_defs.h                   |  45 +++++
>  crypto/ecdh.c                             |  59 +++++-
>  crypto/ecdsa.c                            |  48 ++++-
>  crypto/testmgr.c                          |  14 ++
>  crypto/testmgr.h                          | 225 ++++++++++++++++++++++
>  include/crypto/ecc_curve.h                |   3 +
>  include/crypto/ecdh.h                     |   1 +
>  include/crypto/internal/ecc.h             |  61 +++++-
>  include/linux/oid_registry.h              |   1 +
>  11 files changed, 495 insertions(+), 36 deletions(-)

Hi Stefan,
what kind of side-channel testing was performed on this code?
And what is the use case you are adding it for?

Thanks,
Simo.

-- 
Simo Sorce
Distinguished Engineer
RHEL Crypto Team
Red Hat, Inc









^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh
  2024-02-16 19:27 ` [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Simo Sorce
@ 2024-02-16 19:32   ` Stefan Berger
  2024-02-16 19:40     ` Simo Sorce
  0 siblings, 1 reply; 21+ messages in thread
From: Stefan Berger @ 2024-02-16 19:32 UTC (permalink / raw)
  To: Simo Sorce, keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre



On 2/16/24 14:27, Simo Sorce wrote:
> On Thu, 2024-02-15 at 18:13 -0500, Stefan Berger wrote:
>> This series of patches adds support for the NIST P521 curve to ecdsa and
>> ecdh. Test cases for NIST P521 are added to both modules.
>>
>> An issue with the current code in ecdsa and ecdh is that it assumes that
>> input arrays providing key coordinates for example, are arrays of digits
>> (a 'digit' is a 'u64'). This works well for all currently supported
>> curves, such as NIST P192/256/384, but does not work for NIST P521 where
>> coordinates are 8 digits + 2 bytes long. So some of the changes deal with
>> converting byte arrays to digits and digits to byte arrays.
>>
>>
>> Regards,
>>     Stefan
>>
>> v2:
>>   - Reformulated some patch descriptions
>>   - Fixed issue detected by krobot
>>   - Some other small changes to the code
>>
>> Stefan Berger (14):
>>    crypto: ecdsa - Convert byte arrays with key coordinates to digits
>>    crypto: ecdsa - Adjust tests on length of key parameters
>>    crypto: ecdsa - Extend res.x mod n calculation for NIST P521
>>    crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
>>    crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
>>    crypto: ecc - Add NIST P521 curve parameters
>>    crypto: ecdsa - Register NIST P521 and extend test suite
>>    x509: Add OID for NIST P521 and extend parser for it
>>    crypto: ecdh - Use properly formatted digits to check for valid key
>>    crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte
>>      array
>>    crypto: Add nbits field to ecc_curve structure
>>    crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's
>>      nbytes
>>    crypto: ecdh - Use functions to copy digits from and to byte array
>>    crypto: ecdh - Add support for NIST P521 and add test case
>>
>>   crypto/asymmetric_keys/x509_cert_parser.c |   3 +
>>   crypto/ecc.c                              |  71 +++++--
>>   crypto/ecc_curve_defs.h                   |  45 +++++
>>   crypto/ecdh.c                             |  59 +++++-
>>   crypto/ecdsa.c                            |  48 ++++-
>>   crypto/testmgr.c                          |  14 ++
>>   crypto/testmgr.h                          | 225 ++++++++++++++++++++++
>>   include/crypto/ecc_curve.h                |   3 +
>>   include/crypto/ecdh.h                     |   1 +
>>   include/crypto/internal/ecc.h             |  61 +++++-
>>   include/linux/oid_registry.h              |   1 +
>>   11 files changed, 495 insertions(+), 36 deletions(-)
> 
> Hi Stefan,
> what kind of side-channel testing was performed on this code?
> And what is the use case you are adding it for?

We're using public keys for signature verification. I am not aware that
public key usage is critical to side channels.

The use case for adding it is primarily driven by closing a gap to 
complete the support for the common ECDSA NIST curves.

     Stefan

> 
> Thanks,
> Simo.
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh
  2024-02-16 19:32   ` Stefan Berger
@ 2024-02-16 19:40     ` Simo Sorce
  2024-02-19 14:40       ` Stefan Berger
  0 siblings, 1 reply; 21+ messages in thread
From: Simo Sorce @ 2024-02-16 19:40 UTC (permalink / raw)
  To: Stefan Berger, keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre

On Fri, 2024-02-16 at 14:32 -0500, Stefan Berger wrote:
> 
> On 2/16/24 14:27, Simo Sorce wrote:
> > On Thu, 2024-02-15 at 18:13 -0500, Stefan Berger wrote:
> > > This series of patches adds support for the NIST P521 curve to ecdsa and
> > > ecdh. Test cases for NIST P521 are added to both modules.
> > > 
> > > An issue with the current code in ecdsa and ecdh is that it assumes that
> > > input arrays providing key coordinates for example, are arrays of digits
> > > (a 'digit' is a 'u64'). This works well for all currently supported
> > > curves, such as NIST P192/256/384, but does not work for NIST P521 where
> > > coordinates are 8 digits + 2 bytes long. So some of the changes deal with
> > > converting byte arrays to digits and digits to byte arrays.
> > > 
> > > 
> > > Regards,
> > >     Stefan
> > > 
> > > v2:
> > >   - Reformulated some patch descriptions
> > >   - Fixed issue detected by krobot
> > >   - Some other small changes to the code
> > > 
> > > Stefan Berger (14):
> > >    crypto: ecdsa - Convert byte arrays with key coordinates to digits
> > >    crypto: ecdsa - Adjust tests on length of key parameters
> > >    crypto: ecdsa - Extend res.x mod n calculation for NIST P521
> > >    crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
> > >    crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
> > >    crypto: ecc - Add NIST P521 curve parameters
> > >    crypto: ecdsa - Register NIST P521 and extend test suite
> > >    x509: Add OID for NIST P521 and extend parser for it
> > >    crypto: ecdh - Use properly formatted digits to check for valid key
> > >    crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte
> > >      array
> > >    crypto: Add nbits field to ecc_curve structure
> > >    crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's
> > >      nbytes
> > >    crypto: ecdh - Use functions to copy digits from and to byte array
> > >    crypto: ecdh - Add support for NIST P521 and add test case
> > > 
> > >   crypto/asymmetric_keys/x509_cert_parser.c |   3 +
> > >   crypto/ecc.c                              |  71 +++++--
> > >   crypto/ecc_curve_defs.h                   |  45 +++++
> > >   crypto/ecdh.c                             |  59 +++++-
> > >   crypto/ecdsa.c                            |  48 ++++-
> > >   crypto/testmgr.c                          |  14 ++
> > >   crypto/testmgr.h                          | 225 ++++++++++++++++++++++
> > >   include/crypto/ecc_curve.h                |   3 +
> > >   include/crypto/ecdh.h                     |   1 +
> > >   include/crypto/internal/ecc.h             |  61 +++++-
> > >   include/linux/oid_registry.h              |   1 +
> > >   11 files changed, 495 insertions(+), 36 deletions(-)
> > 
> > Hi Stefan,
> > what kind of side-channel testing was performed on this code?
> > And what is the use case you are adding it for?
> 
> We're using public keys for signature verification. I am not aware that
> public key usage is critical to side channels.
> 
> The use case for adding it is primarily driven by closing a gap to 
> complete the support for the common ECDSA NIST curves.

Is there an assumption the ECDH code uses exclusively ephemeral keys?

Simo.

-- 
Simo Sorce
Distinguished Engineer
RHEL Crypto Team
Red Hat, Inc









^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh
  2024-02-16 19:40     ` Simo Sorce
@ 2024-02-19 14:40       ` Stefan Berger
  0 siblings, 0 replies; 21+ messages in thread
From: Stefan Berger @ 2024-02-19 14:40 UTC (permalink / raw)
  To: Simo Sorce, keyrings, linux-crypto, herbert, davem
  Cc: linux-kernel, saulo.alessandre



On 2/16/24 14:40, Simo Sorce wrote:
> On Fri, 2024-02-16 at 14:32 -0500, Stefan Berger wrote:
>>
>> On 2/16/24 14:27, Simo Sorce wrote:
>>> On Thu, 2024-02-15 at 18:13 -0500, Stefan Berger wrote:
>>>> This series of patches adds support for the NIST P521 curve to ecdsa and
>>>> ecdh. Test cases for NIST P521 are added to both modules.
>>>>
>>>> An issue with the current code in ecdsa and ecdh is that it assumes that
>>>> input arrays providing key coordinates for example, are arrays of digits
>>>> (a 'digit' is a 'u64'). This works well for all currently supported
>>>> curves, such as NIST P192/256/384, but does not work for NIST P521 where
>>>> coordinates are 8 digits + 2 bytes long. So some of the changes deal with
>>>> converting byte arrays to digits and digits to byte arrays.
>>>>
>>>>
>>>> Regards,
>>>>      Stefan
>>>>
>>>> v2:
>>>>    - Reformulated some patch descriptions
>>>>    - Fixed issue detected by krobot
>>>>    - Some other small changes to the code
>>>>
>>>> Stefan Berger (14):
>>>>     crypto: ecdsa - Convert byte arrays with key coordinates to digits
>>>>     crypto: ecdsa - Adjust tests on length of key parameters
>>>>     crypto: ecdsa - Extend res.x mod n calculation for NIST P521
>>>>     crypto: ecc - Implement vli_mmod_fast_521 for NIST p521
>>>>     crypto: ecc - For NIST P521 use vli_num_bits to get number of bits
>>>>     crypto: ecc - Add NIST P521 curve parameters
>>>>     crypto: ecdsa - Register NIST P521 and extend test suite
>>>>     x509: Add OID for NIST P521 and extend parser for it
>>>>     crypto: ecdh - Use properly formatted digits to check for valid key
>>>>     crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte
>>>>       array
>>>>     crypto: Add nbits field to ecc_curve structure
>>>>     crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's
>>>>       nbytes
>>>>     crypto: ecdh - Use functions to copy digits from and to byte array
>>>>     crypto: ecdh - Add support for NIST P521 and add test case
>>>>
>>>>    crypto/asymmetric_keys/x509_cert_parser.c |   3 +
>>>>    crypto/ecc.c                              |  71 +++++--
>>>>    crypto/ecc_curve_defs.h                   |  45 +++++
>>>>    crypto/ecdh.c                             |  59 +++++-
>>>>    crypto/ecdsa.c                            |  48 ++++-
>>>>    crypto/testmgr.c                          |  14 ++
>>>>    crypto/testmgr.h                          | 225 ++++++++++++++++++++++
>>>>    include/crypto/ecc_curve.h                |   3 +
>>>>    include/crypto/ecdh.h                     |   1 +
>>>>    include/crypto/internal/ecc.h             |  61 +++++-
>>>>    include/linux/oid_registry.h              |   1 +
>>>>    11 files changed, 495 insertions(+), 36 deletions(-)
>>>
>>> Hi Stefan,
>>> what kind of side-channel testing was performed on this code?
>>> And what is the use case you are adding it for?
>>
>> We're using public keys for signature verification. I am not aware that
>> public key usage is critical to side channels.
>>
>> The use case for adding it is primarily driven by closing a gap to
>> complete the support for the common ECDSA NIST curves.
> 
> Is there an assumption the ECDH code uses exclusively ephemeral keys?
> 
It can use both, provided keys and ephemeral keys. I think at this point 
it's best to drop ecdh support from this series.

    Stefan

> Simo.
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2024-02-19 14:40 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-15 23:13 [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Stefan Berger
2024-02-15 23:14 ` [PATCH v2 01/14] crypto: ecdsa - Convert byte arrays with key coordinates to digits Stefan Berger
2024-02-15 23:14 ` [PATCH v2 02/14] crypto: ecdsa - Adjust tests on length of key parameters Stefan Berger
2024-02-15 23:14 ` [PATCH v2 03/14] crypto: ecdsa - Extend res.x mod n calculation for NIST P521 Stefan Berger
2024-02-15 23:14 ` [PATCH v2 04/14] crypto: ecc - Implement vli_mmod_fast_521 for NIST p521 Stefan Berger
2024-02-15 23:14 ` [PATCH v2 05/14] crypto: ecc - For NIST P521 use vli_num_bits to get number of bits Stefan Berger
2024-02-15 23:14 ` [PATCH v2 06/14] crypto: ecc - Add NIST P521 curve parameters Stefan Berger
2024-02-16 18:48   ` Elliott, Robert (Servers)
2024-02-16 19:03     ` Stefan Berger
2024-02-15 23:14 ` [PATCH v2 07/14] crypto: ecdsa - Register NIST P521 and extend test suite Stefan Berger
2024-02-15 23:14 ` [PATCH v2 08/14] x509: Add OID for NIST P521 and extend parser for it Stefan Berger
2024-02-15 23:14 ` [PATCH v2 09/14] crypto: ecdh - Use properly formatted digits to check for valid key Stefan Berger
2024-02-15 23:14 ` [PATCH v2 10/14] crypto: ecc - Implement ecc_digits_to_bytes to convert digits to byte array Stefan Berger
2024-02-15 23:14 ` [PATCH v2 11/14] crypto: Add nbits field to ecc_curve structure Stefan Berger
2024-02-15 23:14 ` [PATCH v2 12/14] crypto: ecc - Implement and use ecc_curve_get_nbytes to get curve's nbytes Stefan Berger
2024-02-15 23:14 ` [PATCH v2 13/14] crypto: ecdh - Use functions to copy digits from and to byte array Stefan Berger
2024-02-15 23:14 ` [PATCH v2 14/14] crypto: ecdh - Add support for NIST P521 and add test case Stefan Berger
2024-02-16 19:27 ` [PATCH v2 00/14] Add support for NIST P521 to ecdsa and ecdh Simo Sorce
2024-02-16 19:32   ` Stefan Berger
2024-02-16 19:40     ` Simo Sorce
2024-02-19 14:40       ` Stefan Berger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).