linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] crypto: add eddsa support for x509
@ 2021-05-12 14:04 Hongbo Li
  2021-05-12 14:04 ` [PATCH 1/7] crypto: fix a memory leak in sm2 Hongbo Li
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel, Hongbo Li

From: Hongbo Li <herberthbli@tencent.com>

This series of patches add support for x509 cert signed by eddsa,
which is described in RFC8032 [1], currently ed25519 only.

According to RFC8032 section 4 [2], there're two variants: PureEdDSA and
HashEdDSA. These patches support PureEdDSA which named Ed25519.

Patch1 fix a memory leak bug in sm2.

Patch2 fix a mpi_resize bug, this bug will cause eddsa verification failed.

Patch3 exports some mpi common functions.

Patch4 makes x509 layer support eddsa.

Patch5 moves some common code in sm2 to separate files. These code is also
       used by eddsa.

Patch6 is the implementation of eddsa verification according to RFC8032
       section 5.1.7 [3].

Patch7 adds test vector for eddsa.

Test by the following script:

keyctl newring test @u

while :; do
    certfile="cert.der"

    openssl req \
            -x509 \
            -newkey ED25519 \
            -keyout key.pem \
            -days 365 \
            -subj '/CN=test' \
            -nodes \
            -outform der \
            -out ${certfile} 2>/dev/null

    exp=0
    id=$(keyctl padd asymmetric testkey %keyring:test < "${certfile}")
    rc=$?
    if [ $rc -ne $exp ]; then
        case "$exp" in
            0) echo "Error: Could not load ed25519 certificate $certfile!";
        esac
        exit 1
    else
        case "$rc" in
            0) printf "load ed25519 cert keyid: %-10s\n" $id;
        esac
    fi
done

Best Regards

Hongbo

[1] https://datatracker.ietf.org/doc/html/rfc8032
[2] https://datatracker.ietf.org/doc/html/rfc8032#section-4
[3] https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.7

Hongbo Li (7):
  crypto: fix a memory leak in sm2
  lib/mpi: use kcalloc in mpi_resize
  lib/mpi: export some common function
  x509: add support for eddsa
  crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h
  crypto: support ed25519 x509 cert
  crypto: add eddsa test vector

 crypto/Kconfig                            |  15 ++++
 crypto/Makefile                           |   4 +
 crypto/asymmetric_keys/public_key.c       |  73 +++++++++++++--
 crypto/asymmetric_keys/x509_cert_parser.c |  14 ++-
 crypto/asymmetric_keys/x509_public_key.c  |   4 +-
 crypto/sm2.c                              | 104 +---------------------
 crypto/testmgr.c                          |   6 ++
 crypto/testmgr.h                          |  32 +++++++
 include/linux/oid_registry.h              |   1 +
 lib/mpi/mpi-add.c                         |   4 +-
 lib/mpi/mpiutil.c                         |   2 +-
 11 files changed, 146 insertions(+), 113 deletions(-)

-- 
2.27.0


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

* [PATCH 1/7] crypto: fix a memory leak in sm2
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-14  4:52   ` Tianjia Zhang
  2021-05-12 14:04 ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize Hongbo Li
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

SM2 module alloc ec->Q in sm2_set_pub_key(), when doing alg test in
test_akcipher_one(), it will set public key for every test vector,
and don't free ec->Q. This will cause a memory leak.

This patch alloc ec->Q in sm2_ec_ctx_init().

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/sm2.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/crypto/sm2.c b/crypto/sm2.c
index b21addc..db8a4a2 100644
--- a/crypto/sm2.c
+++ b/crypto/sm2.c
@@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
 		goto free;
 
 	rc = -ENOMEM;
+
+	ec->Q = mpi_point_new(0);
+	if (!ec->Q)
+		goto free;
+
 	/* mpi_ec_setup_elliptic_curve */
 	ec->G = mpi_point_new(0);
-	if (!ec->G)
+	if (!ec->G) {
+		mpi_point_release(ec->Q);
 		goto free;
+	}
 
 	mpi_set(ec->G->x, x);
 	mpi_set(ec->G->y, y);
@@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
 	rc = -EINVAL;
 	ec->n = mpi_scanval(ecp->n);
 	if (!ec->n) {
+		mpi_point_release(ec->Q);
 		mpi_point_release(ec->G);
 		goto free;
 	}
@@ -386,27 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm,
 	MPI a;
 	int rc;
 
-	ec->Q = mpi_point_new(0);
-	if (!ec->Q)
-		return -ENOMEM;
-
 	/* include the uncompressed flag '0x04' */
-	rc = -ENOMEM;
 	a = mpi_read_raw_data(key, keylen);
 	if (!a)
-		goto error;
+		return -ENOMEM;
 
 	mpi_normalize(a);
 	rc = sm2_ecc_os2ec(ec->Q, a);
 	mpi_free(a);
-	if (rc)
-		goto error;
-
-	return 0;
 
-error:
-	mpi_point_release(ec->Q);
-	ec->Q = NULL;
 	return rc;
 }
 
-- 
1.8.3.1


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

* [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
  2021-05-12 14:04 ` [PATCH 1/7] crypto: fix a memory leak in sm2 Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 19:07   ` Eric Biggers
  2021-05-12 14:04 ` [PATCH 3/7] lib/mpi: export some common function Hongbo Li
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

We should set the additional space to 0 in mpi_resize().
So use kcalloc() instead of kmalloc_array().

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 lib/mpi/mpiutil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c
index 3c63710..e6c4b31 100644
--- a/lib/mpi/mpiutil.c
+++ b/lib/mpi/mpiutil.c
@@ -148,7 +148,7 @@ int mpi_resize(MPI a, unsigned nlimbs)
 		return 0;	/* no need to do it */
 
 	if (a->d) {
-		p = kmalloc_array(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);
+		p = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);
 		if (!p)
 			return -ENOMEM;
 		memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
-- 
1.8.3.1


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

* [PATCH 3/7] lib/mpi: export some common function
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
  2021-05-12 14:04 ` [PATCH 1/7] crypto: fix a memory leak in sm2 Hongbo Li
  2021-05-12 14:04 ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 14:04 ` [PATCH 4/7] x509: add support for eddsa Hongbo Li
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

Export mpi_add_ui() and mpi_sub() that are used by the following
eddsa patch.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 lib/mpi/mpi-add.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/mpi/mpi-add.c b/lib/mpi/mpi-add.c
index 2cdae54..d34c6c1 100644
--- a/lib/mpi/mpi-add.c
+++ b/lib/mpi/mpi-add.c
@@ -62,7 +62,7 @@ void mpi_add_ui(MPI w, MPI u, unsigned long v)
 	w->nlimbs = wsize;
 	w->sign   = wsign;
 }
-
+EXPORT_SYMBOL_GPL(mpi_add_ui);
 
 void mpi_add(MPI w, MPI u, MPI v)
 {
@@ -138,7 +138,7 @@ void mpi_sub(MPI w, MPI u, MPI v)
 	mpi_add(w, u, vv);
 	mpi_free(vv);
 }
-
+EXPORT_SYMBOL_GPL(mpi_sub);
 
 void mpi_addm(MPI w, MPI u, MPI v, MPI m)
 {
-- 
1.8.3.1


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

* [PATCH 4/7] x509: add support for eddsa
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
                   ` (2 preceding siblings ...)
  2021-05-12 14:04 ` [PATCH 3/7] lib/mpi: export some common function Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 14:04 ` [PATCH 5/7] crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h Hongbo Li
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

This patch make x509 support eddsa(currently ed25519). According to
RFC8032 section 5.1.7[1], the digest is not on the original message,
but on a special formated message string:
	SHA512(dom2(F, C) || R || A || PH(M))

[1]: https://tools.ietf.org/html/rfc8032#section-5.1.7

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/asymmetric_keys/public_key.c       | 73 +++++++++++++++++++++++++++----
 crypto/asymmetric_keys/x509_cert_parser.c | 14 +++++-
 crypto/asymmetric_keys/x509_public_key.c  |  4 +-
 include/linux/oid_registry.h              |  1 +
 4 files changed, 82 insertions(+), 10 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 4fefb21..c1236a8 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -251,8 +251,8 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
 }
 
 #if IS_REACHABLE(CONFIG_CRYPTO_SM2)
-static int cert_sig_digest_update(const struct public_key_signature *sig,
-				  struct crypto_akcipher *tfm_pkey)
+static int sm2_cert_sig_digest_update(const struct public_key_signature *sig,
+				      struct crypto_akcipher *tfm_pkey)
 {
 	struct crypto_shash *tfm;
 	struct shash_desc *desc;
@@ -297,7 +297,7 @@ static int cert_sig_digest_update(const struct public_key_signature *sig,
 	return ret;
 }
 #else
-static inline int cert_sig_digest_update(
+static inline int sm2_cert_sig_digest_update(
 	const struct public_key_signature *sig,
 	struct crypto_akcipher *tfm_pkey)
 {
@@ -305,6 +305,58 @@ static inline int cert_sig_digest_update(
 }
 #endif /* ! IS_REACHABLE(CONFIG_CRYPTO_SM2) */
 
+static int eddsa_cert_sig_digest_update(const struct public_key *pub,
+					const struct public_key_signature *sig)
+{
+	struct crypto_shash *tfm = NULL;
+	struct shash_desc *desc = NULL;
+	int key_size, ret = 0;
+
+	if (strcmp(pub->pkey_algo, "eddsa-25519"))
+		return -ENOPKG;
+
+	tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
+	if (IS_ERR(tfm))
+		return PTR_ERR(tfm);
+
+	desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	desc->tfm = tfm;
+
+	/* RFC8032 section 5.1.7
+	 * step 2. SHA512(dom2(F, C) || R || A || PH(M))
+	 */
+	key_size = 32;
+	if (sig->s_size != key_size * 2 ||
+	    pub->keylen != key_size) {
+		ret = -EINVAL;
+		goto free;
+	}
+
+	ret = crypto_shash_init(desc);
+	if (ret < 0)
+		goto free;
+
+	ret = crypto_shash_update(desc, sig->s, key_size);
+	if (ret < 0)
+		goto free;
+
+	ret = crypto_shash_update(desc, pub->key, key_size);
+	if (ret < 0)
+		goto free;
+
+	ret = crypto_shash_finup(desc, sig->data, sig->data_size, sig->digest);
+
+free:
+	kfree(desc);
+	crypto_free_shash(tfm);
+	return ret;
+}
+
 /*
  * Verify a signature using a public key.
  */
@@ -358,11 +410,16 @@ int public_key_verify_signature(const struct public_key *pkey,
 	if (ret)
 		goto error_free_key;
 
-	if (sig->pkey_algo && strcmp(sig->pkey_algo, "sm2") == 0 &&
-	    sig->data_size) {
-		ret = cert_sig_digest_update(sig, tfm);
-		if (ret)
-			goto error_free_key;
+	if (sig->pkey_algo && sig->data_size) {
+		if (strcmp(sig->pkey_algo, "sm2") == 0) {
+			ret = sm2_cert_sig_digest_update(sig, tfm);
+			if (ret)
+				goto error_free_key;
+		} else if (strcmp(sig->pkey_algo, "eddsa") == 0) {
+			ret = eddsa_cert_sig_digest_update(pkey, sig);
+			if (ret)
+				goto error_free_key;
+		}
 	}
 
 	sg_init_table(src_sg, 2);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 6d00309..3f60c57 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -258,6 +258,9 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 	case OID_SM2_with_SM3:
 		ctx->cert->sig->hash_algo = "sm3";
 		goto sm2;
+	case OID_ed25519:
+		ctx->cert->sig->hash_algo = "sha512";
+		goto eddsa;
 	}
 
 rsa_pkcs1:
@@ -280,6 +283,11 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
 	ctx->cert->sig->encoding = "x962";
 	ctx->algo_oid = ctx->last_oid;
 	return 0;
+eddsa:
+	ctx->cert->sig->pkey_algo = "eddsa";
+	ctx->cert->sig->encoding = "raw";
+	ctx->algo_oid = ctx->last_oid;
+	return 0;
 }
 
 /*
@@ -302,7 +310,8 @@ int x509_note_signature(void *context, size_t hdrlen,
 	if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
 	    strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
 	    strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0 ||
-	    strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0) {
+	    strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0 ||
+	    strcmp(ctx->cert->sig->pkey_algo, "eddsa") == 0) {
 		/* Discard the BIT STRING metadata */
 		if (vlen < 1 || *(const u8 *)value != 0)
 			return -EBADMSG;
@@ -517,6 +526,9 @@ int x509_extract_key_data(void *context, size_t hdrlen,
 			return -ENOPKG;
 		}
 		break;
+	case OID_ed25519:
+		ctx->cert->pub->pkey_algo = "eddsa-25519";
+		break;
 	default:
 		return -ENOPKG;
 	}
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 3d45161..a8fd368 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -131,7 +131,9 @@ int x509_check_for_self_signed(struct x509_certificate *cert)
 	ret = -EKEYREJECTED;
 	if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0 &&
 	    (strncmp(cert->pub->pkey_algo, "ecdsa-", 6) != 0 ||
-	     strcmp(cert->sig->pkey_algo, "ecdsa") != 0))
+	     strcmp(cert->sig->pkey_algo, "ecdsa") != 0) &&
+	    (strncmp(cert->pub->pkey_algo, "eddsa-", 6) != 0 ||
+	     strcmp(cert->sig->pkey_algo, "eddsa") != 0))
 		goto out;
 
 	ret = public_key_verify_signature(cert->pub, cert->sig);
diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h
index cc64d94..d84bb86 100644
--- a/include/linux/oid_registry.h
+++ b/include/linux/oid_registry.h
@@ -64,6 +64,7 @@ enum OID {
 
 	OID_certAuthInfoAccess,		/* 1.3.6.1.5.5.7.1.1 */
 	OID_sha1,			/* 1.3.14.3.2.26 */
+	OID_ed25519,			/* 1.3.101.112 */
 	OID_id_ansip384r1,		/* 1.3.132.0.34 */
 	OID_sha256,			/* 2.16.840.1.101.3.4.2.1 */
 	OID_sha384,			/* 2.16.840.1.101.3.4.2.2 */
-- 
1.8.3.1


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

* [PATCH 5/7] crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
                   ` (3 preceding siblings ...)
  2021-05-12 14:04 ` [PATCH 4/7] x509: add support for eddsa Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 14:04 ` [PATCH 6/7] crypto: ed25519 cert verification Hongbo Li
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

Some structs and functions in sm2 are common codes, and could be
used by the following eddsa patch. So move them to common files:
ec_mpi.c and ec_mpi.h.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/Kconfig  |  4 +++
 crypto/Makefile |  1 +
 crypto/ec_mpi.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++
 crypto/ec_mpi.h | 37 ++++++++++++++++++++++
 crypto/sm2.c    | 98 ++-------------------------------------------------------
 5 files changed, 127 insertions(+), 95 deletions(-)
 create mode 100644 crypto/ec_mpi.c
 create mode 100644 crypto/ec_mpi.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4a0d187..75ae7d3 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -265,6 +265,9 @@ config CRYPTO_ECRDSA
 	  standard algorithms (called GOST algorithms). Only signature verification
 	  is implemented.
 
+config CRYPTO_EC_MPI
+	tristate
+
 config CRYPTO_SM2
 	tristate "SM2 algorithm"
 	select CRYPTO_SM3
@@ -272,6 +275,7 @@ config CRYPTO_SM2
 	select CRYPTO_MANAGER
 	select MPILIB
 	select ASN1
+	select CRYPTO_EC_MPI
 	help
 	  Generic implementation of the SM2 public key algorithm. It was
 	  published by State Encryption Management Bureau, China.
diff --git a/crypto/Makefile b/crypto/Makefile
index 10526d4..8afb393 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -177,6 +177,7 @@ obj-$(CONFIG_CRYPTO_OFB) += ofb.o
 obj-$(CONFIG_CRYPTO_ECC) += ecc.o
 obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
 obj-$(CONFIG_CRYPTO_CURVE25519) += curve25519-generic.o
+obj-$(CONFIG_CRYPTO_EC_MPI) += ec_mpi.o
 
 ecdh_generic-y += ecdh.o
 ecdh_generic-y += ecdh_helper.o
diff --git a/crypto/ec_mpi.c b/crypto/ec_mpi.c
new file mode 100644
index 0000000..a537e6f
--- /dev/null
+++ b/crypto/ec_mpi.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EC MPI common functions.
+ *
+ * Copyright (c) 2020, Alibaba Group.
+ * Authors: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include "ec_mpi.h"
+
+int ec_mpi_ctx_init(struct mpi_ec_ctx *ec, const struct ecc_domain_parms *ecp)
+{
+	MPI p, a, b;
+	MPI x, y;
+	int rc = -EINVAL;
+
+	p = mpi_scanval(ecp->p);
+	a = mpi_scanval(ecp->a);
+	b = mpi_scanval(ecp->b);
+	if (!p || !a || !b)
+		goto free_p;
+
+	x = mpi_scanval(ecp->g_x);
+	y = mpi_scanval(ecp->g_y);
+	if (!x || !y)
+		goto free;
+
+	rc = -ENOMEM;
+
+	ec->Q = mpi_point_new(0);
+	if (!ec->Q)
+		goto free;
+
+	/* mpi_ec_setup_elliptic_curve */
+	ec->G = mpi_point_new(0);
+	if (!ec->G) {
+		mpi_point_release(ec->Q);
+		goto free;
+	}
+
+	mpi_set(ec->G->x, x);
+	mpi_set(ec->G->y, y);
+	mpi_set_ui(ec->G->z, 1);
+
+	rc = -EINVAL;
+	ec->n = mpi_scanval(ecp->n);
+	if (!ec->n) {
+		mpi_point_release(ec->Q);
+		mpi_point_release(ec->G);
+		goto free;
+	}
+
+	ec->h = ecp->h;
+	ec->name = ecp->desc;
+	mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b);
+
+	rc = 0;
+
+free:
+	mpi_free(x);
+	mpi_free(y);
+free_p:
+	mpi_free(p);
+	mpi_free(a);
+	mpi_free(b);
+
+	return rc;
+}
+EXPORT_SYMBOL(ec_mpi_ctx_init);
+
+void ec_mpi_ctx_deinit(struct mpi_ec_ctx *ec)
+{
+	mpi_ec_deinit(ec);
+
+	memset(ec, 0, sizeof(*ec));
+}
+EXPORT_SYMBOL(ec_mpi_ctx_deinit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>");
diff --git a/crypto/ec_mpi.h b/crypto/ec_mpi.h
new file mode 100644
index 0000000..e1f6d3aa
--- /dev/null
+++ b/crypto/ec_mpi.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * EC MPI common structs.
+ *
+ * Copyright (c) 2020, Alibaba Group.
+ * Authors: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#include <linux/mpi.h>
+
+struct ecc_domain_parms {
+	const char *desc;           /* Description of the curve.  */
+	unsigned int nbits;         /* Number of bits.  */
+	unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */
+
+	/* The model describing this curve.  This is mainly used to select
+	 * the group equation.
+	 */
+	enum gcry_mpi_ec_models model;
+
+	/* The actual ECC dialect used.  This is used for curve specific
+	 * optimizations and to select encodings etc.
+	 */
+	enum ecc_dialects dialect;
+
+	const char *p;              /* The prime defining the field.  */
+	const char *a, *b;          /* The coefficients.  For Twisted Edwards
+				     * Curves b is used for d.  For Montgomery
+				     * Curves (a,b) has ((A-2)/4,B^-1).
+				     */
+	const char *n;              /* The order of the base point.  */
+	const char *g_x, *g_y;      /* Base point.  */
+	unsigned int h;             /* Cofactor.  */
+};
+
+int ec_mpi_ctx_init(struct mpi_ec_ctx *ec, const struct ecc_domain_parms *ecp);
+void ec_mpi_ctx_deinit(struct mpi_ec_ctx *ec);
diff --git a/crypto/sm2.c b/crypto/sm2.c
index db8a4a2..ea1676b 100644
--- a/crypto/sm2.c
+++ b/crypto/sm2.c
@@ -9,42 +9,17 @@
  */
 
 #include <linux/module.h>
-#include <linux/mpi.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/akcipher.h>
 #include <crypto/hash.h>
 #include <crypto/sm3_base.h>
 #include <crypto/rng.h>
 #include <crypto/sm2.h>
+#include "ec_mpi.h"
 #include "sm2signature.asn1.h"
 
 #define MPI_NBYTES(m)   ((mpi_get_nbits(m) + 7) / 8)
 
-struct ecc_domain_parms {
-	const char *desc;           /* Description of the curve.  */
-	unsigned int nbits;         /* Number of bits.  */
-	unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */
-
-	/* The model describing this curve.  This is mainly used to select
-	 * the group equation.
-	 */
-	enum gcry_mpi_ec_models model;
-
-	/* The actual ECC dialect used.  This is used for curve specific
-	 * optimizations and to select encodings etc.
-	 */
-	enum ecc_dialects dialect;
-
-	const char *p;              /* The prime defining the field.  */
-	const char *a, *b;          /* The coefficients.  For Twisted Edwards
-				     * Curves b is used for d.  For Montgomery
-				     * Curves (a,b) has ((A-2)/4,B^-1).
-				     */
-	const char *n;              /* The order of the base point.  */
-	const char *g_x, *g_y;      /* Base point.  */
-	unsigned int h;             /* Cofactor.  */
-};
-
 static const struct ecc_domain_parms sm2_ecp = {
 	.desc = "sm2p256v1",
 	.nbits = 256,
@@ -60,73 +35,6 @@ struct ecc_domain_parms {
 	.h = 1
 };
 
-static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
-{
-	const struct ecc_domain_parms *ecp = &sm2_ecp;
-	MPI p, a, b;
-	MPI x, y;
-	int rc = -EINVAL;
-
-	p = mpi_scanval(ecp->p);
-	a = mpi_scanval(ecp->a);
-	b = mpi_scanval(ecp->b);
-	if (!p || !a || !b)
-		goto free_p;
-
-	x = mpi_scanval(ecp->g_x);
-	y = mpi_scanval(ecp->g_y);
-	if (!x || !y)
-		goto free;
-
-	rc = -ENOMEM;
-
-	ec->Q = mpi_point_new(0);
-	if (!ec->Q)
-		goto free;
-
-	/* mpi_ec_setup_elliptic_curve */
-	ec->G = mpi_point_new(0);
-	if (!ec->G) {
-		mpi_point_release(ec->Q);
-		goto free;
-	}
-
-	mpi_set(ec->G->x, x);
-	mpi_set(ec->G->y, y);
-	mpi_set_ui(ec->G->z, 1);
-
-	rc = -EINVAL;
-	ec->n = mpi_scanval(ecp->n);
-	if (!ec->n) {
-		mpi_point_release(ec->Q);
-		mpi_point_release(ec->G);
-		goto free;
-	}
-
-	ec->h = ecp->h;
-	ec->name = ecp->desc;
-	mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b);
-
-	rc = 0;
-
-free:
-	mpi_free(x);
-	mpi_free(y);
-free_p:
-	mpi_free(p);
-	mpi_free(a);
-	mpi_free(b);
-
-	return rc;
-}
-
-static void sm2_ec_ctx_deinit(struct mpi_ec_ctx *ec)
-{
-	mpi_ec_deinit(ec);
-
-	memset(ec, 0, sizeof(*ec));
-}
-
 /* RESULT must have been initialized and is set on success to the
  * point given by VALUE.
  */
@@ -416,14 +324,14 @@ static int sm2_init_tfm(struct crypto_akcipher *tfm)
 {
 	struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
 
-	return sm2_ec_ctx_init(ec);
+	return ec_mpi_ctx_init(ec, &sm2_ecp);
 }
 
 static void sm2_exit_tfm(struct crypto_akcipher *tfm)
 {
 	struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
 
-	sm2_ec_ctx_deinit(ec);
+	ec_mpi_ctx_deinit(ec);
 }
 
 static struct akcipher_alg sm2 = {
-- 
1.8.3.1


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

* [PATCH 6/7] crypto: ed25519 cert verification
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
                   ` (4 preceding siblings ...)
  2021-05-12 14:04 ` [PATCH 5/7] crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 18:39   ` kernel test robot
  2021-05-12 14:04 ` [PATCH 7/7] crypto: add eddsa test vector Hongbo Li
  2021-05-12 19:11 ` [PATCH 0/7] crypto: add eddsa support for x509 Eric Biggers
  7 siblings, 1 reply; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

This patch adds the support of eddsa(currently ed25519) which is described
in RFC8032 section 5.1.7 [1].

[1]: https://tools.ietf.org/html/rfc8032#section-5.1.7

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/Kconfig  |  11 ++
 crypto/Makefile |   3 +
 crypto/eddsa.c  | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 340 insertions(+)
 create mode 100644 crypto/eddsa.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 75ae7d3..6463c85 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -268,6 +268,17 @@ config CRYPTO_ECRDSA
 config CRYPTO_EC_MPI
 	tristate
 
+config CRYPTO_EDDSA
+	tristate "EDDSA (ed25519) algorithm"
+	select CRYPTO_ECC
+	select CRYPTO_EC_MPI
+	select CRYPTO_AKCIPHER
+	select ASN1
+	help
+	  Edwards-curve Digital Signature Algorithm (ed25519) is a variant
+	  of Schnorr's signature system with (possibly twisted) Edwards curves.
+	  Only signature verification is implemented.
+
 config CRYPTO_SM2
 	tristate "SM2 algorithm"
 	select CRYPTO_SM3
diff --git a/crypto/Makefile b/crypto/Makefile
index 8afb393..2bbdfad 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -56,6 +56,9 @@ ecdsa_generic-y += ecdsa.o
 ecdsa_generic-y += ecdsasignature.asn1.o
 obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o
 
+eddsa_generic-y += eddsa.o
+obj-$(CONFIG_CRYPTO_EDDSA) += eddsa_generic.o
+
 crypto_acompress-y := acompress.o
 crypto_acompress-y += scompress.o
 obj-$(CONFIG_CRYPTO_ACOMP2) += crypto_acompress.o
diff --git a/crypto/eddsa.c b/crypto/eddsa.c
new file mode 100644
index 0000000..06e86be
--- /dev/null
+++ b/crypto/eddsa.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EDDSA generic algorithm.
+ *
+ * Copyright (c) 2021 Hongbo Li <herberthbli@tencent.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/mpi.h>
+#include <linux/module.h>
+#include <linux/oid_registry.h>
+#include <crypto/hash.h>
+#include <crypto/sha2.h>
+#include <crypto/ecdh.h>
+#include <crypto/curve25519.h>
+#include <crypto/internal/akcipher.h>
+#include "ec_mpi.h"
+
+struct eddsa_ctx {
+	enum OID algo_oid;
+	struct mpi_ec_ctx ec_ctx;
+};
+
+static MPI p58;
+static MPI seven;
+static MPI m1;
+
+static const struct ecc_domain_parms ed25519_domain_params = {
+	.desc = "ed25519",
+	.nbits = 256,
+	.fips = 0,
+	.model = MPI_EC_EDWARDS,
+	.dialect = ECC_DIALECT_ED25519,
+	.p = "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+	.a = "-0x01",
+	.b = "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
+	.n = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+	.g_x = "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
+	.g_y = "0x6666666666666666666666666666666666666666666666666666666666666658",
+	.h = 8,
+};
+
+static void reverse_buffer(u8 *buffer, u32 length)
+{
+	u32 tmp, i;
+
+	for (i = 0; i < length / 2; i++) {
+		tmp = buffer[i];
+		buffer[i] = buffer[length - 1 - i];
+		buffer[length - 1 - i] = tmp;
+	}
+}
+
+static int eddsa_encode_x_y(MPI x, MPI y, u8 *buf, u32 key_size)
+{
+	memcpy(buf, y->d, key_size);
+	if (mpi_test_bit(x, 0))
+		buf[key_size - 1] |= 0x80;
+
+	return 0;
+}
+
+int ecc_eddsa_encodepoint(MPI_POINT point, struct mpi_ec_ctx *ec,
+			  MPI x, MPI y, u8 *buf, u32 key_size)
+{
+	if (mpi_ec_get_affine(x, y, point, ec))
+		return -EINVAL;
+
+	return eddsa_encode_x_y(x, y, buf, key_size);
+}
+
+/* Recover X from Y and SIGN (which actually is a parity bit).  */
+static int eddsa_recover_x(MPI x, MPI y, int sign, struct mpi_ec_ctx *ec)
+{
+	MPI u, v, v3, t;
+	int ret = 0;
+
+	if (ec->dialect != ECC_DIALECT_ED25519)
+		return -ENOPKG;
+
+	u = mpi_new(0);
+	v = mpi_new(0);
+	v3 = mpi_new(0);
+	t = mpi_new(0);
+
+	/* Compute u and v */
+	/* u = y^2 */
+	mpi_mulm(u, y, y, ec->p);
+	/* v = b*y^2 */
+	mpi_mulm(v, ec->b, u, ec->p);
+	/* u = y^2-1 */
+	mpi_sub_ui(u, u, 1);
+	/* v = b*y^2+1 */
+	mpi_add_ui(v, v, 1);
+
+	/* Compute sqrt(u/v) */
+	/* v3 = v^3 */
+	mpi_powm(v3, v, mpi_const(MPI_C_THREE), ec->p);
+	/* t = v3 * v3 * u * v = u * v^7 */
+	mpi_powm(t, v, seven, ec->p);
+	mpi_mulm(t, t, u, ec->p);
+	/* t = t^((p-5)/8) = (u * v^7)^((p-5)/8)  */
+	mpi_powm(t, t, p58, ec->p);
+	/* x = t * u * v^3 = (u * v^3) * (u * v^7)^((p-5)/8) */
+	mpi_mulm(t, t, u, ec->p);
+	mpi_mulm(x, t, v3, ec->p);
+
+	/* Adjust if needed. */
+	/* t = v * x^2 */
+	mpi_mulm(t, x, x, ec->p);
+	mpi_mulm(t, t, v, ec->p);
+	/* -t == u ? x = x * sqrt(-1) */
+	mpi_sub(t, ec->p, t);
+	if (!mpi_cmp(t, u)) {
+		mpi_mulm(x, x, m1, ec->p);
+		/* t = v * x^2 */
+		mpi_mulm(t, x, x, ec->p);
+		mpi_mulm(t, t, v, ec->p);
+		/* -t == u ? x = x * sqrt(-1) */
+		mpi_sub(t, ec->p, t);
+		if (!mpi_cmp(t, u))
+			ret = -EINVAL;
+	}
+
+	/* Choose the desired square root according to parity */
+	if (mpi_test_bit(x, 0) != !!sign)
+		mpi_sub(x, ec->p, x);
+
+	mpi_free(t);
+	mpi_free(v3);
+	mpi_free(v);
+	mpi_free(u);
+
+	return ret;
+}
+
+static int ecc_eddsa_decodepoint(const u8 *pk, int key_size,
+				 struct mpi_ec_ctx *ec, MPI_POINT result)
+{
+	MPI y;
+	u8 *rawmpi;
+	int sign, ret = 0;
+
+	rawmpi = kmalloc(key_size, GFP_KERNEL);
+	if (!rawmpi)
+		return -ENOMEM;
+	memcpy(rawmpi, pk, key_size);
+	reverse_buffer(rawmpi, key_size);
+
+	sign = !!(rawmpi[0] & 0x80);
+	rawmpi[0] &= 0x7f;
+
+	y = mpi_read_raw_data(rawmpi, key_size);
+	if (!y) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	mpi_normalize(y);
+	mpi_set(result->y, y);
+	mpi_free(y);
+
+	ret = eddsa_recover_x(result->x, result->y, sign, ec);
+	mpi_set_ui(result->z, 1);
+out:
+	kfree(rawmpi);
+	return ret;
+}
+
+int eddsa_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct mpi_ec_ctx *ec = &ctx->ec_ctx;
+	struct gcry_mpi_point sb, ka;
+	MPI s = NULL;
+	MPI k = NULL;
+	u8 sig[CURVE25519_KEY_SIZE * 2], digest[SHA512_DIGEST_SIZE];
+	u8 *buf;
+	u32 key_size;
+	int ret = 0;
+
+	if (ctx->algo_oid != OID_ed25519)
+		return -ENOPKG;
+
+	key_size = CURVE25519_KEY_SIZE;
+
+	if (!ec->Q || req->src_len != key_size * 2)
+		return -EINVAL;
+
+	sg_copy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len),
+			  sig, req->src_len);
+
+	sg_pcopy_to_buffer(req->src,
+			   sg_nents_for_len(req->src,
+					    req->src_len + req->dst_len),
+			   digest, req->dst_len, req->src_len);
+
+	reverse_buffer(digest, SHA512_DIGEST_SIZE);
+	k = mpi_read_raw_data(digest, SHA512_DIGEST_SIZE);
+
+	reverse_buffer(sig + key_size, key_size);
+	s = mpi_read_raw_data(sig + key_size, key_size);
+
+	mpi_point_init(&sb);
+	mpi_point_init(&ka);
+
+	mpi_ec_mul_point(&sb, s, ec->G, ec);
+	mpi_ec_mul_point(&ka, k, ec->Q, ec);
+	mpi_sub(ka.x, ec->p, ka.x);
+	mpi_ec_add_points(&sb, &sb, &ka, ec);
+
+	buf = kmalloc(key_size, GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = ecc_eddsa_encodepoint(&sb, ec, s, k, buf, key_size);
+	if (ret)
+		goto out;
+
+	if (memcmp(buf, sig, key_size))
+		ret = -EKEYREJECTED;
+
+out:
+	mpi_point_free_parts(&sb);
+	mpi_point_free_parts(&ka);
+	mpi_free(k);
+	mpi_free(s);
+	kfree(buf);
+	return ret;
+}
+
+static int eddsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+			     unsigned int keylen)
+{
+	struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct mpi_ec_ctx *ec = &ctx->ec_ctx;
+	const u8 *pk = key;
+
+	if (ctx->algo_oid != OID_ed25519)
+		return -ENOPKG;
+
+	if (keylen != CURVE25519_KEY_SIZE)
+		return -EINVAL;
+
+	return ecc_eddsa_decodepoint(pk, keylen, ec, ec->Q);
+}
+
+u32 eddsa_max_size(struct crypto_akcipher *tfm)
+{
+	struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	if (ctx->algo_oid == OID_ed25519)
+		return CURVE25519_KEY_SIZE;
+
+	return 0;
+}
+
+static int eddsa_25519_init_tfm(struct crypto_akcipher *tfm)
+{
+	struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	ctx->algo_oid = OID_ed25519;
+	p58 = mpi_scanval("0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD");
+	if (!p58)
+		return -ENOMEM;
+
+	m1 = mpi_scanval("2B8324804FC1DF0B2B4D00993DFBD7A72F431806AD2FE478C4EE1B274A0EA0B0");
+	if (!m1)
+		return -ENOMEM;
+
+	seven = mpi_set_ui(NULL, 7);
+
+	return ec_mpi_ctx_init(&ctx->ec_ctx, &ed25519_domain_params);
+}
+
+static void eddsa_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	ec_mpi_ctx_deinit(&ctx->ec_ctx);
+	mpi_free(p58);
+	mpi_free(seven);
+	mpi_free(m1);
+}
+
+
+static struct akcipher_alg eddsa_25519 = {
+	.verify = eddsa_verify,
+	.set_pub_key = eddsa_set_pub_key,
+	.max_size = eddsa_max_size,
+	.init = eddsa_25519_init_tfm,
+	.exit = eddsa_exit_tfm,
+	.base = {
+		.cra_name = "eddsa-25519",
+		.cra_driver_name = "eddsa-25519-generic",
+		.cra_priority = 100,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct eddsa_ctx),
+	},
+};
+
+static int eddsa_mod_init(void)
+{
+	return crypto_register_akcipher(&eddsa_25519);
+}
+
+static void eddsa_mod_exit(void)
+{
+	crypto_unregister_akcipher(&eddsa_25519);
+}
+
+module_init(eddsa_mod_init);
+module_exit(eddsa_mod_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Hongbo Li <herberthbli@tencent.com>");
+MODULE_ALIAS_CRYPTO("eddsa");
+MODULE_ALIAS_CRYPTO("eddsa-generic");
+MODULE_DESCRIPTION("EDDSA generic algorithm");
-- 
1.8.3.1


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

* [PATCH 7/7] crypto: add eddsa test vector
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
                   ` (5 preceding siblings ...)
  2021-05-12 14:04 ` [PATCH 6/7] crypto: ed25519 cert verification Hongbo Li
@ 2021-05-12 14:04 ` Hongbo Li
  2021-05-12 19:11 ` [PATCH 0/7] crypto: add eddsa support for x509 Eric Biggers
  7 siblings, 0 replies; 17+ messages in thread
From: Hongbo Li @ 2021-05-12 14:04 UTC (permalink / raw)
  To: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli
  Cc: linux-kernel

From: Hongbo Li <herberthbli@tencent.com>

This patch adds the test vector for ed25519.

Signed-off-by: Hongbo Li <herberthbli@tencent.com>
---
 crypto/testmgr.c |  6 ++++++
 crypto/testmgr.h | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 10c5b3b..498d186 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4939,6 +4939,12 @@ static int alg_test_null(const struct alg_test_desc *desc,
 			.akcipher = __VECS(ecrdsa_tv_template)
 		}
 	}, {
+		.alg = "eddsa-25519",
+		.test = alg_test_akcipher,
+		.suite = {
+			.akcipher = __VECS(eddsa_25519_tv_template)
+		}
+	}, {
 		.alg = "essiv(authenc(hmac(sha256),cbc(aes)),sha256)",
 		.test = alg_test_aead,
 		.fips_allowed = 1,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 34e4a3d..11807a3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -1145,6 +1145,38 @@ struct kpp_testvec {
 };
 
 /*
+ * EDDSA test vectors.
+ * From RFC8032 section 7.1
+ */
+static const struct akcipher_testvec eddsa_25519_tv_template[] = {
+	{
+	.key =
+	"\x3d\x40\x17\xc3\xe8\x43\x89\x5a\x92\xb7\x0a\xa7\x4d\x1b\x7e\xbc"
+	"\x9c\x98\x2c\xcf\x2e\xc4\x96\x8c\xc0\xcd\x55\xf1\x2a\xf4\x66\x0c",
+	.key_len = 32,
+	/*
+	 * RFC8032 section 5.1.7. m is SHA512(dom2(F, C) || R || A || PH(M))
+	 * M is 0x72
+	 */
+	.m =
+	"\xa2\x71\xdf\x0d\x2b\x0d\x03\xbd\x17\xb4\xed\x9a\x4b\x6a\xfd\xdf"
+	"\x2e\x73\x28\x7f\xd6\x30\xf1\xa1\x37\xd8\x7c\xe8\x73\xa5\x91\xcc"
+	"\x31\xb6\xdd\x85\x2a\x98\xb5\xdd\x12\x26\xfe\x99\x3d\x82\x28\x27"
+	"\x8c\xeb\xa2\x1f\x80\xb8\xfc\x95\x98\x6a\x70\xd7\x1e\xdf\x3f\xaf",
+	.m_size = 64,
+	.c =
+	"\x92\xa0\x09\xa9\xf0\xd4\xca\xb8\x72\x0e\x82\x0b\x5f\x64\x25\x40"
+	"\xa2\xb2\x7b\x54\x16\x50\x3f\x8f\xb3\x76\x22\x23\xeb\xdb\x69\xda"
+	"\x08\x5a\xc1\xe4\x3e\x15\x99\x6e\x45\x8f\x36\x13\xd0\xf1\x1d\x8c"
+	"\x38\x7b\x2e\xae\xb4\x30\x2a\xee\xb0\x0d\x29\x16\x12\xbb\x0c\x00",
+	.c_size = 64,
+	.algo = OID_ed25519,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	}
+};
+
+/*
  * PKCS#1 RSA test vectors. Obtained from CAVS testing.
  */
 static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = {
-- 
1.8.3.1


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

* Re: [PATCH 6/7] crypto: ed25519 cert verification
  2021-05-12 14:04 ` [PATCH 6/7] crypto: ed25519 cert verification Hongbo Li
@ 2021-05-12 18:39   ` kernel test robot
  0 siblings, 0 replies; 17+ messages in thread
From: kernel test robot @ 2021-05-12 18:39 UTC (permalink / raw)
  To: Hongbo Li, keyrings, linux-crypto, herbert, dhowells, jarkko,
	tianjia.zhang, herberthbli
  Cc: kbuild-all, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 7917 bytes --]

Hi Hongbo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on cryptodev/master]
[also build test WARNING on crypto/master linus/master v5.13-rc1 next-20210512]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Hongbo-Li/crypto-add-eddsa-support-for-x509/20210512-220722
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f9de73b89d39483afde4fc9ba079b66dee2f05ab
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Hongbo-Li/crypto-add-eddsa-support-for-x509/20210512-220722
        git checkout f9de73b89d39483afde4fc9ba079b66dee2f05ab
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> crypto/eddsa.c:67:5: warning: no previous prototype for 'ecc_eddsa_encodepoint' [-Wmissing-prototypes]
      67 | int ecc_eddsa_encodepoint(MPI_POINT point, struct mpi_ec_ctx *ec,
         |     ^~~~~~~~~~~~~~~~~~~~~
>> crypto/eddsa.c:174:5: warning: no previous prototype for 'eddsa_verify' [-Wmissing-prototypes]
     174 | int eddsa_verify(struct akcipher_request *req)
         |     ^~~~~~~~~~~~
>> crypto/eddsa.c:255:5: warning: no previous prototype for 'eddsa_max_size' [-Wmissing-prototypes]
     255 | u32 eddsa_max_size(struct crypto_akcipher *tfm)
         |     ^~~~~~~~~~~~~~


vim +/ecc_eddsa_encodepoint +67 crypto/eddsa.c

    66	
  > 67	int ecc_eddsa_encodepoint(MPI_POINT point, struct mpi_ec_ctx *ec,
    68				  MPI x, MPI y, u8 *buf, u32 key_size)
    69	{
    70		if (mpi_ec_get_affine(x, y, point, ec))
    71			return -EINVAL;
    72	
    73		return eddsa_encode_x_y(x, y, buf, key_size);
    74	}
    75	
    76	/* Recover X from Y and SIGN (which actually is a parity bit).  */
    77	static int eddsa_recover_x(MPI x, MPI y, int sign, struct mpi_ec_ctx *ec)
    78	{
    79		MPI u, v, v3, t;
    80		int ret = 0;
    81	
    82		if (ec->dialect != ECC_DIALECT_ED25519)
    83			return -ENOPKG;
    84	
    85		u = mpi_new(0);
    86		v = mpi_new(0);
    87		v3 = mpi_new(0);
    88		t = mpi_new(0);
    89	
    90		/* Compute u and v */
    91		/* u = y^2 */
    92		mpi_mulm(u, y, y, ec->p);
    93		/* v = b*y^2 */
    94		mpi_mulm(v, ec->b, u, ec->p);
    95		/* u = y^2-1 */
    96		mpi_sub_ui(u, u, 1);
    97		/* v = b*y^2+1 */
    98		mpi_add_ui(v, v, 1);
    99	
   100		/* Compute sqrt(u/v) */
   101		/* v3 = v^3 */
   102		mpi_powm(v3, v, mpi_const(MPI_C_THREE), ec->p);
   103		/* t = v3 * v3 * u * v = u * v^7 */
   104		mpi_powm(t, v, seven, ec->p);
   105		mpi_mulm(t, t, u, ec->p);
   106		/* t = t^((p-5)/8) = (u * v^7)^((p-5)/8)  */
   107		mpi_powm(t, t, p58, ec->p);
   108		/* x = t * u * v^3 = (u * v^3) * (u * v^7)^((p-5)/8) */
   109		mpi_mulm(t, t, u, ec->p);
   110		mpi_mulm(x, t, v3, ec->p);
   111	
   112		/* Adjust if needed. */
   113		/* t = v * x^2 */
   114		mpi_mulm(t, x, x, ec->p);
   115		mpi_mulm(t, t, v, ec->p);
   116		/* -t == u ? x = x * sqrt(-1) */
   117		mpi_sub(t, ec->p, t);
   118		if (!mpi_cmp(t, u)) {
   119			mpi_mulm(x, x, m1, ec->p);
   120			/* t = v * x^2 */
   121			mpi_mulm(t, x, x, ec->p);
   122			mpi_mulm(t, t, v, ec->p);
   123			/* -t == u ? x = x * sqrt(-1) */
   124			mpi_sub(t, ec->p, t);
   125			if (!mpi_cmp(t, u))
   126				ret = -EINVAL;
   127		}
   128	
   129		/* Choose the desired square root according to parity */
   130		if (mpi_test_bit(x, 0) != !!sign)
   131			mpi_sub(x, ec->p, x);
   132	
   133		mpi_free(t);
   134		mpi_free(v3);
   135		mpi_free(v);
   136		mpi_free(u);
   137	
   138		return ret;
   139	}
   140	
   141	static int ecc_eddsa_decodepoint(const u8 *pk, int key_size,
   142					 struct mpi_ec_ctx *ec, MPI_POINT result)
   143	{
   144		MPI y;
   145		u8 *rawmpi;
   146		int sign, ret = 0;
   147	
   148		rawmpi = kmalloc(key_size, GFP_KERNEL);
   149		if (!rawmpi)
   150			return -ENOMEM;
   151		memcpy(rawmpi, pk, key_size);
   152		reverse_buffer(rawmpi, key_size);
   153	
   154		sign = !!(rawmpi[0] & 0x80);
   155		rawmpi[0] &= 0x7f;
   156	
   157		y = mpi_read_raw_data(rawmpi, key_size);
   158		if (!y) {
   159			ret = -EINVAL;
   160			goto out;
   161		}
   162	
   163		mpi_normalize(y);
   164		mpi_set(result->y, y);
   165		mpi_free(y);
   166	
   167		ret = eddsa_recover_x(result->x, result->y, sign, ec);
   168		mpi_set_ui(result->z, 1);
   169	out:
   170		kfree(rawmpi);
   171		return ret;
   172	}
   173	
 > 174	int eddsa_verify(struct akcipher_request *req)
   175	{
   176		struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
   177		struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
   178		struct mpi_ec_ctx *ec = &ctx->ec_ctx;
   179		struct gcry_mpi_point sb, ka;
   180		MPI s = NULL;
   181		MPI k = NULL;
   182		u8 sig[CURVE25519_KEY_SIZE * 2], digest[SHA512_DIGEST_SIZE];
   183		u8 *buf;
   184		u32 key_size;
   185		int ret = 0;
   186	
   187		if (ctx->algo_oid != OID_ed25519)
   188			return -ENOPKG;
   189	
   190		key_size = CURVE25519_KEY_SIZE;
   191	
   192		if (!ec->Q || req->src_len != key_size * 2)
   193			return -EINVAL;
   194	
   195		sg_copy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len),
   196				  sig, req->src_len);
   197	
   198		sg_pcopy_to_buffer(req->src,
   199				   sg_nents_for_len(req->src,
   200						    req->src_len + req->dst_len),
   201				   digest, req->dst_len, req->src_len);
   202	
   203		reverse_buffer(digest, SHA512_DIGEST_SIZE);
   204		k = mpi_read_raw_data(digest, SHA512_DIGEST_SIZE);
   205	
   206		reverse_buffer(sig + key_size, key_size);
   207		s = mpi_read_raw_data(sig + key_size, key_size);
   208	
   209		mpi_point_init(&sb);
   210		mpi_point_init(&ka);
   211	
   212		mpi_ec_mul_point(&sb, s, ec->G, ec);
   213		mpi_ec_mul_point(&ka, k, ec->Q, ec);
   214		mpi_sub(ka.x, ec->p, ka.x);
   215		mpi_ec_add_points(&sb, &sb, &ka, ec);
   216	
   217		buf = kmalloc(key_size, GFP_KERNEL);
   218		if (!buf) {
   219			ret = -ENOMEM;
   220			goto out;
   221		}
   222	
   223		ret = ecc_eddsa_encodepoint(&sb, ec, s, k, buf, key_size);
   224		if (ret)
   225			goto out;
   226	
   227		if (memcmp(buf, sig, key_size))
   228			ret = -EKEYREJECTED;
   229	
   230	out:
   231		mpi_point_free_parts(&sb);
   232		mpi_point_free_parts(&ka);
   233		mpi_free(k);
   234		mpi_free(s);
   235		kfree(buf);
   236		return ret;
   237	}
   238	
   239	static int eddsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
   240				     unsigned int keylen)
   241	{
   242		struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
   243		struct mpi_ec_ctx *ec = &ctx->ec_ctx;
   244		const u8 *pk = key;
   245	
   246		if (ctx->algo_oid != OID_ed25519)
   247			return -ENOPKG;
   248	
   249		if (keylen != CURVE25519_KEY_SIZE)
   250			return -EINVAL;
   251	
   252		return ecc_eddsa_decodepoint(pk, keylen, ec, ec->Q);
   253	}
   254	
 > 255	u32 eddsa_max_size(struct crypto_akcipher *tfm)
   256	{
   257		struct eddsa_ctx *ctx = akcipher_tfm_ctx(tfm);
   258	
   259		if (ctx->algo_oid == OID_ed25519)
   260			return CURVE25519_KEY_SIZE;
   261	
   262		return 0;
   263	}
   264	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67468 bytes --]

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

* Re: [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize
  2021-05-12 14:04 ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize Hongbo Li
@ 2021-05-12 19:07   ` Eric Biggers
       [not found]     ` <c12435701edb4f419b71bfa23be780db@tencent.com>
  0 siblings, 1 reply; 17+ messages in thread
From: Eric Biggers @ 2021-05-12 19:07 UTC (permalink / raw)
  To: Hongbo Li
  Cc: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli, linux-kernel

On Wed, May 12, 2021 at 10:04:09PM +0800, Hongbo Li wrote:
> From: Hongbo Li <herberthbli@tencent.com>
> 
> We should set the additional space to 0 in mpi_resize().
> So use kcalloc() instead of kmalloc_array().
> 
> Signed-off-by: Hongbo Li <herberthbli@tencent.com>

Is this fixing something, and if so what?

- Eric

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

* Re: [PATCH 0/7] crypto: add eddsa support for x509
  2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
                   ` (6 preceding siblings ...)
  2021-05-12 14:04 ` [PATCH 7/7] crypto: add eddsa test vector Hongbo Li
@ 2021-05-12 19:11 ` Eric Biggers
       [not found]   ` <dade7666956c41718ce00e681156533e@tencent.com>
  7 siblings, 1 reply; 17+ messages in thread
From: Eric Biggers @ 2021-05-12 19:11 UTC (permalink / raw)
  To: Hongbo Li
  Cc: keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	herberthbli, linux-kernel

On Wed, May 12, 2021 at 10:04:07PM +0800, Hongbo Li wrote:
> From: Hongbo Li <herberthbli@tencent.com>
> 
> This series of patches add support for x509 cert signed by eddsa,
> which is described in RFC8032 [1], currently ed25519 only.

It would be helpful to explain how this is related to the kernel's existing
Curve25519 support.

- Eric

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

* Re: [PATCH 1/7] crypto: fix a memory leak in sm2
  2021-05-12 14:04 ` [PATCH 1/7] crypto: fix a memory leak in sm2 Hongbo Li
@ 2021-05-14  4:52   ` Tianjia Zhang
  2021-05-18 11:40     ` hongbo li
  0 siblings, 1 reply; 17+ messages in thread
From: Tianjia Zhang @ 2021-05-14  4:52 UTC (permalink / raw)
  To: Hongbo Li, keyrings, linux-crypto, herbert, dhowells, jarkko,
	herberthbli, stable
  Cc: linux-kernel

Hi Hongbo,

On 5/12/21 10:04 PM, Hongbo Li wrote:
> From: Hongbo Li <herberthbli@tencent.com>
> 
> SM2 module alloc ec->Q in sm2_set_pub_key(), when doing alg test in
> test_akcipher_one(), it will set public key for every test vector,
> and don't free ec->Q. This will cause a memory leak.
> 
> This patch alloc ec->Q in sm2_ec_ctx_init().
> 
> Signed-off-by: Hongbo Li <herberthbli@tencent.com>
> ---
>   crypto/sm2.c | 24 ++++++++++--------------
>   1 file changed, 10 insertions(+), 14 deletions(-)
> 
> diff --git a/crypto/sm2.c b/crypto/sm2.c
> index b21addc..db8a4a2 100644
> --- a/crypto/sm2.c
> +++ b/crypto/sm2.c
> @@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
>   		goto free;
>   
>   	rc = -ENOMEM;
> +
> +	ec->Q = mpi_point_new(0);
> +	if (!ec->Q)
> +		goto free;
> +
>   	/* mpi_ec_setup_elliptic_curve */
>   	ec->G = mpi_point_new(0);
> -	if (!ec->G)
> +	if (!ec->G) {
> +		mpi_point_release(ec->Q);
>   		goto free;
> +	}
>   
>   	mpi_set(ec->G->x, x);
>   	mpi_set(ec->G->y, y);
> @@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
>   	rc = -EINVAL;
>   	ec->n = mpi_scanval(ecp->n);
>   	if (!ec->n) {
> +		mpi_point_release(ec->Q);
>   		mpi_point_release(ec->G);
>   		goto free;
>   	}
> @@ -386,27 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm,
>   	MPI a;
>   	int rc;
>   
> -	ec->Q = mpi_point_new(0);
> -	if (!ec->Q)
> -		return -ENOMEM;
> -
>   	/* include the uncompressed flag '0x04' */
> -	rc = -ENOMEM;
>   	a = mpi_read_raw_data(key, keylen);
>   	if (!a)
> -		goto error;
> +		return -ENOMEM;
>   
>   	mpi_normalize(a);
>   	rc = sm2_ecc_os2ec(ec->Q, a);
>   	mpi_free(a);
> -	if (rc)
> -		goto error;
> -
> -	return 0;
>   
> -error:
> -	mpi_point_release(ec->Q);
> -	ec->Q = NULL;
>   	return rc;
>   }
>   
> 

Thanks a lot for fixing this issue.

Reviewed-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>

Also added:

Cc: stable@vger.kernel.org # v5.10+

Best regards,
Tianjia

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

* Re: [PATCH 0/7] crypto: add eddsa support for x509(Internet mail)
       [not found]   ` <dade7666956c41718ce00e681156533e@tencent.com>
@ 2021-05-17 21:21     ` Eric Biggers
  2021-05-18 13:57       ` hongbo li
  0 siblings, 1 reply; 17+ messages in thread
From: Eric Biggers @ 2021-05-17 21:21 UTC (permalink / raw)
  To: herberthbli(李弘博)
  Cc: Hongbo Li, keyrings, linux-crypto, herbert, dhowells, jarkko,
	tianjia.zhang, linux-kernel

On Thu, May 13, 2021 at 02:44:07PM +0000, herberthbli(李弘博) wrote:
> 在 2021/5/13 3:12, Eric Biggers 写道:
> 
> On Wed, May 12, 2021 at 10:04:07PM +0800, Hongbo Li wrote:
> 
> 
> From: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> 
> This series of patches add support for x509 cert signed by eddsa,
> which is described in RFC8032 [1], currently ed25519 only.
> 
> 
> 
> It would be helpful to explain how this is related to the kernel's existing
> Curve25519 support.
> 
> - Eric
> 
> 
> Curve25519 is an elliptic curve used for key agreement(ECDH). It is a Montgomery curve.
> 
> Edwards25519 is a twisted Edwards curve and birationally equivalent to Curve25519, the
> birational maps are described in rfc7748 section 4.1.
> https://datatracker.ietf.org/doc/html/rfc7748#section-4.1
> 
> 
> Ed25519 is a Digital Signature Algorithm over Edwards25519.
> 

Sure, but what does that mean in terms of code.  Can you reuse any of the code,
and if not why not?  I *think* the answer is no, but this is a common point of
confusion, so it would be helpful to properly explain this...

- Eric

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

* Re: [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize(Internet mail)
       [not found]     ` <c12435701edb4f419b71bfa23be780db@tencent.com>
@ 2021-05-17 21:29       ` Eric Biggers
  2021-05-18 13:53         ` hongbo li
  0 siblings, 1 reply; 17+ messages in thread
From: Eric Biggers @ 2021-05-17 21:29 UTC (permalink / raw)
  To: herberthbli(李弘博)
  Cc: Hongbo Li, keyrings, linux-crypto, herbert, dhowells, jarkko,
	tianjia.zhang, linux-kernel

On Thu, May 13, 2021 at 02:49:03PM +0000, herberthbli(李弘博) wrote:
> 在 2021/5/13 3:08, Eric Biggers 写道:
> 
> On Wed, May 12, 2021 at 10:04:09PM +0800, Hongbo Li wrote:
> 
> 
> From: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> 
> We should set the additional space to 0 in mpi_resize().
> So use kcalloc() instead of kmalloc_array().
> 
> Signed-off-by: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> 
> 
> 
> Is this fixing something, and if so what?
> 
> - Eric
> 
> 
> 
> In lib/mpi/ec.c:
> 
> /****************
>  * Resize the array of A to NLIMBS. the additional space is cleared
>  * (set to 0) [done by m_realloc()]
>  */
> int mpi_resize(MPI a, unsigned nlimbs)
> 
> Like the comment of kernel's mpi_resize(), the additional space need to set to 0,
> but when a->d is not NULL, it does not set.
> 
> The kernel's mpi lib is from libgcrypt, the mpi resize in libgcrypt is _gcry_mpi_resize()
> which set the additional space to 0.
> 
> This issue will cause add_points_edwards() get a wrong result, and lead to a failed
> eddsa verification.
> 

That sounds like it's fixing an existing bug, regardless of the ed25519 support.
If that's indeed the case, what is the impact of that bug, and what commit is it
fixing?  Please explain in the commit message and not just email.

- Eric

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

* Re: [PATCH 1/7] crypto: fix a memory leak in sm2
  2021-05-14  4:52   ` Tianjia Zhang
@ 2021-05-18 11:40     ` hongbo li
  0 siblings, 0 replies; 17+ messages in thread
From: hongbo li @ 2021-05-18 11:40 UTC (permalink / raw)
  To: Tianjia Zhang
  Cc: open list:ASYMMETRIC KEYS, linux-crypto, Herbert Xu,
	David Howells, jarkko, herberthbli, stable, open list

Tianjia Zhang <tianjia.zhang@linux.alibaba.com> 于2021年5月14日周五 下午12:52写道:
>
> Hi Hongbo,
>
> On 5/12/21 10:04 PM, Hongbo Li wrote:
> > From: Hongbo Li <herberthbli@tencent.com>
> >
> > SM2 module alloc ec->Q in sm2_set_pub_key(), when doing alg test in
> > test_akcipher_one(), it will set public key for every test vector,
> > and don't free ec->Q. This will cause a memory leak.
> >
> > This patch alloc ec->Q in sm2_ec_ctx_init().
> >
> > Signed-off-by: Hongbo Li <herberthbli@tencent.com>
> > ---
> >   crypto/sm2.c | 24 ++++++++++--------------
> >   1 file changed, 10 insertions(+), 14 deletions(-)
> >
> > diff --git a/crypto/sm2.c b/crypto/sm2.c
> > index b21addc..db8a4a2 100644
> > --- a/crypto/sm2.c
> > +++ b/crypto/sm2.c
> > @@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
> >               goto free;
> >
> >       rc = -ENOMEM;
> > +
> > +     ec->Q = mpi_point_new(0);
> > +     if (!ec->Q)
> > +             goto free;
> > +
> >       /* mpi_ec_setup_elliptic_curve */
> >       ec->G = mpi_point_new(0);
> > -     if (!ec->G)
> > +     if (!ec->G) {
> > +             mpi_point_release(ec->Q);
> >               goto free;
> > +     }
> >
> >       mpi_set(ec->G->x, x);
> >       mpi_set(ec->G->y, y);
> > @@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
> >       rc = -EINVAL;
> >       ec->n = mpi_scanval(ecp->n);
> >       if (!ec->n) {
> > +             mpi_point_release(ec->Q);
> >               mpi_point_release(ec->G);
> >               goto free;
> >       }
> > @@ -386,27 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm,
> >       MPI a;
> >       int rc;
> >
> > -     ec->Q = mpi_point_new(0);
> > -     if (!ec->Q)
> > -             return -ENOMEM;
> > -
> >       /* include the uncompressed flag '0x04' */
> > -     rc = -ENOMEM;
> >       a = mpi_read_raw_data(key, keylen);
> >       if (!a)
> > -             goto error;
> > +             return -ENOMEM;
> >
> >       mpi_normalize(a);
> >       rc = sm2_ecc_os2ec(ec->Q, a);
> >       mpi_free(a);
> > -     if (rc)
> > -             goto error;
> > -
> > -     return 0;
> >
> > -error:
> > -     mpi_point_release(ec->Q);
> > -     ec->Q = NULL;
> >       return rc;
> >   }
> >
> >
>
> Thanks a lot for fixing this issue.
>
> Reviewed-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
>
> Also added:
>
> Cc: stable@vger.kernel.org # v5.10+
>
> Best regards,
> Tianjia

Thank you for your review!
Regards,
Hongbo

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

* Re: [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize(Internet mail)
  2021-05-17 21:29       ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize(Internet mail) Eric Biggers
@ 2021-05-18 13:53         ` hongbo li
  0 siblings, 0 replies; 17+ messages in thread
From: hongbo li @ 2021-05-18 13:53 UTC (permalink / raw)
  To: Eric Biggers
  Cc: herberthbli(李弘博),
	keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	linux-kernel

Ok, I'll explain it in the next version of patches.
Regards,
Hongbo

Eric Biggers <ebiggers@kernel.org> 于2021年5月18日周二 上午5:29写道:
>
> On Thu, May 13, 2021 at 02:49:03PM +0000, herberthbli(李弘博) wrote:
> > 在 2021/5/13 3:08, Eric Biggers 写道:
> >
> > On Wed, May 12, 2021 at 10:04:09PM +0800, Hongbo Li wrote:
> >
> >
> > From: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> >
> > We should set the additional space to 0 in mpi_resize().
> > So use kcalloc() instead of kmalloc_array().
> >
> > Signed-off-by: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> >
> >
> >
> > Is this fixing something, and if so what?
> >
> > - Eric
> >
> >
> >
> > In lib/mpi/ec.c:
> >
> > /****************
> >  * Resize the array of A to NLIMBS. the additional space is cleared
> >  * (set to 0) [done by m_realloc()]
> >  */
> > int mpi_resize(MPI a, unsigned nlimbs)
> >
> > Like the comment of kernel's mpi_resize(), the additional space need to set to 0,
> > but when a->d is not NULL, it does not set.
> >
> > The kernel's mpi lib is from libgcrypt, the mpi resize in libgcrypt is _gcry_mpi_resize()
> > which set the additional space to 0.
> >
> > This issue will cause add_points_edwards() get a wrong result, and lead to a failed
> > eddsa verification.
> >
>
> That sounds like it's fixing an existing bug, regardless of the ed25519 support.
> If that's indeed the case, what is the impact of that bug, and what commit is it
> fixing?  Please explain in the commit message and not just email.
>
> - Eric

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

* Re: [PATCH 0/7] crypto: add eddsa support for x509(Internet mail)
  2021-05-17 21:21     ` [PATCH 0/7] crypto: add eddsa support for x509(Internet mail) Eric Biggers
@ 2021-05-18 13:57       ` hongbo li
  0 siblings, 0 replies; 17+ messages in thread
From: hongbo li @ 2021-05-18 13:57 UTC (permalink / raw)
  To: Eric Biggers
  Cc: herberthbli(李弘博),
	keyrings, linux-crypto, herbert, dhowells, jarkko, tianjia.zhang,
	linux-kernel

Eric Biggers <ebiggers@kernel.org> 于2021年5月18日周二 上午5:21写道:
>
> On Thu, May 13, 2021 at 02:44:07PM +0000, herberthbli(李弘博) wrote:
> > 在 2021/5/13 3:12, Eric Biggers 写道:
> >
> > On Wed, May 12, 2021 at 10:04:07PM +0800, Hongbo Li wrote:
> >
> >
> > From: Hongbo Li <herberthbli@tencent.com><mailto:herberthbli@tencent.com>
> >
> > This series of patches add support for x509 cert signed by eddsa,
> > which is described in RFC8032 [1], currently ed25519 only.
> >
> >
> >
> > It would be helpful to explain how this is related to the kernel's existing
> > Curve25519 support.
> >
> > - Eric
> >
> >
> > Curve25519 is an elliptic curve used for key agreement(ECDH). It is a Montgomery curve.
> >
> > Edwards25519 is a twisted Edwards curve and birationally equivalent to Curve25519, the
> > birational maps are described in rfc7748 section 4.1.
> > https://datatracker.ietf.org/doc/html/rfc7748#section-4.1
> >
> >
> > Ed25519 is a Digital Signature Algorithm over Edwards25519.
> >
>
> Sure, but what does that mean in terms of code.  Can you reuse any of the code,
> and if not why not?  I *think* the answer is no, but this is a common point of
> confusion, so it would be helpful to properly explain this...
>
> - Eric

Thank you for your review. No, the eddsa can't reuse the code of curve25519.
I'll also explain this in the next version of patches.
Regards,
Hongbo

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

end of thread, other threads:[~2021-05-18 13:58 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-12 14:04 [PATCH 0/7] crypto: add eddsa support for x509 Hongbo Li
2021-05-12 14:04 ` [PATCH 1/7] crypto: fix a memory leak in sm2 Hongbo Li
2021-05-14  4:52   ` Tianjia Zhang
2021-05-18 11:40     ` hongbo li
2021-05-12 14:04 ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize Hongbo Li
2021-05-12 19:07   ` Eric Biggers
     [not found]     ` <c12435701edb4f419b71bfa23be780db@tencent.com>
2021-05-17 21:29       ` [PATCH 2/7] lib/mpi: use kcalloc in mpi_resize(Internet mail) Eric Biggers
2021-05-18 13:53         ` hongbo li
2021-05-12 14:04 ` [PATCH 3/7] lib/mpi: export some common function Hongbo Li
2021-05-12 14:04 ` [PATCH 4/7] x509: add support for eddsa Hongbo Li
2021-05-12 14:04 ` [PATCH 5/7] crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h Hongbo Li
2021-05-12 14:04 ` [PATCH 6/7] crypto: ed25519 cert verification Hongbo Li
2021-05-12 18:39   ` kernel test robot
2021-05-12 14:04 ` [PATCH 7/7] crypto: add eddsa test vector Hongbo Li
2021-05-12 19:11 ` [PATCH 0/7] crypto: add eddsa support for x509 Eric Biggers
     [not found]   ` <dade7666956c41718ce00e681156533e@tencent.com>
2021-05-17 21:21     ` [PATCH 0/7] crypto: add eddsa support for x509(Internet mail) Eric Biggers
2021-05-18 13:57       ` hongbo li

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).