|
Petr Tesarik |
1b908a |
From: =?UTF-8?q?Stephan=20M=C3=BCller?= <smueller@chronox.de>
|
|
Petr Tesarik |
1b908a |
Date: Mon, 20 Jul 2020 19:09:23 +0200
|
|
Petr Tesarik |
1b908a |
Subject: crypto: ecc - SP800-56A rev 3 local public key validation
|
|
Petr Tesarik |
1b908a |
Git-commit: 6914dd53eb7af7cbc66edf7992d600b1e952c40d
|
|
Petr Tesarik |
1b908a |
Patch-mainline: v5.9-rc1
|
|
Petr Tesarik |
1b908a |
References: bsc#1175718
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
After the generation of a local public key, SP800-56A rev 3 section
|
|
Petr Tesarik |
1b908a |
5.6.2.1.3 mandates a validation of that key with a full validation
|
|
Petr Tesarik |
1b908a |
compliant to section 5.6.2.3.3.
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
Only if the full validation passes, the key is allowed to be used.
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
The patch adds the full key validation compliant to 5.6.2.3.3 and
|
|
Petr Tesarik |
1b908a |
performs the required check on the generated public key.
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
Signed-off-by: Stephan Mueller <smueller@chronox.de>
|
|
Petr Tesarik |
1b908a |
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
|
Petr Tesarik |
1b908a |
[ ptesarik: The export is needed only to share the routines with ecrdsa.
|
|
Petr Tesarik |
1b908a |
SLE15 does not have the ecrdsa module, so the added function should be
|
|
Petr Tesarik |
1b908a |
local to crypto/ecc.c. ]
|
|
Petr Tesarik |
1b908a |
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
|
Petr Tesarik |
1b908a |
---
|
|
Petr Tesarik |
1b908a |
crypto/ecc.c | 34 +++++++++++++++++++++++++++++++++-
|
|
Petr Tesarik |
1b908a |
1 file changed, 33 insertions(+), 1 deletion(-)
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
--- a/crypto/ecc.c
|
|
Petr Tesarik |
1b908a |
+++ b/crypto/ecc.c
|
|
Petr Tesarik |
1b908a |
@@ -42,6 +42,9 @@ typedef struct {
|
|
Petr Tesarik |
1b908a |
u64 m_high;
|
|
Petr Tesarik |
1b908a |
} uint128_t;
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
+static int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
|
|
Petr Tesarik |
1b908a |
+ struct ecc_point *pk);
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
|
|
Petr Tesarik |
1b908a |
{
|
|
Petr Tesarik |
1b908a |
switch (curve_id) {
|
|
Petr Tesarik |
1b908a |
@@ -1404,7 +1407,9 @@ int ecc_make_pub_key(unsigned int curve_
|
|
Petr Tesarik |
1b908a |
}
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
ecc_point_mult(pk, &curve->g, priv, NULL, curve, ndigits);
|
|
Petr Tesarik |
1b908a |
- if (ecc_point_is_zero(pk)) {
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ /* SP800-56A rev 3 5.6.2.1.3 key check */
|
|
Petr Tesarik |
1b908a |
+ if (ecc_is_pubkey_valid_full(curve, pk)) {
|
|
Petr Tesarik |
1b908a |
ret = -EAGAIN;
|
|
Petr Tesarik |
1b908a |
goto err_free_point;
|
|
Petr Tesarik |
1b908a |
}
|
|
Petr Tesarik |
1b908a |
@@ -1452,6 +1457,33 @@ int ecc_is_pubkey_valid_partial(const st
|
|
Petr Tesarik |
1b908a |
}
|
|
Petr Tesarik |
1b908a |
EXPORT_SYMBOL(ecc_is_pubkey_valid_partial);
|
|
Petr Tesarik |
1b908a |
|
|
Petr Tesarik |
1b908a |
+/* SP800-56A section 5.6.2.3.3 full verification */
|
|
Petr Tesarik |
1b908a |
+static int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
|
|
Petr Tesarik |
1b908a |
+ struct ecc_point *pk)
|
|
Petr Tesarik |
1b908a |
+{
|
|
Petr Tesarik |
1b908a |
+ struct ecc_point *nQ;
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ /* Checks 1 through 3 */
|
|
Petr Tesarik |
1b908a |
+ int ret = ecc_is_pubkey_valid_partial(curve, pk);
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ if (ret)
|
|
Petr Tesarik |
1b908a |
+ return ret;
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ /* Check 4: Verify that nQ is the zero point. */
|
|
Petr Tesarik |
1b908a |
+ nQ = ecc_alloc_point(pk->ndigits);
|
|
Petr Tesarik |
1b908a |
+ if (!nQ)
|
|
Petr Tesarik |
1b908a |
+ return -ENOMEM;
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ ecc_point_mult(nQ, pk, curve->n, NULL, curve, pk->ndigits);
|
|
Petr Tesarik |
1b908a |
+ if (!ecc_point_is_zero(nQ))
|
|
Petr Tesarik |
1b908a |
+ ret = -EINVAL;
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ ecc_free_point(nQ);
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
+ return ret;
|
|
Petr Tesarik |
1b908a |
+}
|
|
Petr Tesarik |
1b908a |
+EXPORT_SYMBOL(ecc_is_pubkey_valid_full);
|
|
Petr Tesarik |
1b908a |
+
|
|
Petr Tesarik |
1b908a |
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
|
|
Petr Tesarik |
1b908a |
const u64 *private_key, const u64 *public_key,
|
|
Petr Tesarik |
1b908a |
u64 *secret)
|