All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
@ 2022-06-23  7:05 Lei He
  2022-06-23  7:05 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  7:05 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

This patch supports the ECDSA algorithm for virtio-crypto.

V1 -> V2:
- explicitly specified an appropriate base commit.
- fixed the link error reported by kernel test robot <lkp@intl.com>.
- removed irrelevant commits.

V1:
- fixed the problem that the max_signature_size of ECDSA is
incorrectly calculated.
- make pkcs8_private_key_parser can identify ECDSA private keys.
- implement ECDSA algorithm for virtio-crypto device


lei he (4):
  crypto: fix the calculation of max_size for ECDSA
  crypto: pkcs8 parser support ECDSA private keys
  crypto: remove unused field in pkcs8_parse_context
  virtio-crypto: support ECDSA algorithm

 crypto/Kconfig                                |   1 +
 crypto/Makefile                               |   2 +
 crypto/akcipher.c                             |  10 +
 crypto/asymmetric_keys/pkcs8.asn1             |   2 +-
 crypto/asymmetric_keys/pkcs8_parser.c         |  46 +++-
 crypto/ecdsa.c                                |   3 +-
 crypto/ecdsa_helper.c                         |  45 +++
 drivers/crypto/virtio/Kconfig                 |   1 +
 .../virtio/virtio_crypto_akcipher_algs.c      | 259 ++++++++++++++++--
 include/crypto/internal/ecdsa.h               |  15 +
 include/linux/asn1_encoder.h                  |   2 +
 lib/asn1_encoder.c                            |   3 +-
 12 files changed, 361 insertions(+), 28 deletions(-)
 create mode 100644 crypto/ecdsa_helper.c
 create mode 100644 include/crypto/internal/ecdsa.h


base-commit: 018ab4fabddd94f1c96f3b59e180691b9e88d5d8
-- 
2.20.1


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

* [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
@ 2022-06-23  7:05 ` Lei He
  2022-06-23  7:05 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  7:05 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

The signature of ECDSA is consists of two big integers up to the
size of keylen, and is DER encoded into one SEQUENCE.
Calculate max_size of ECDSA signature more accurately according to
the DER encoding rules.

Signed-off-by: lei he <helei.sig11@bytedance.com>
---
 crypto/Kconfig                  |  1 +
 crypto/Makefile                 |  2 ++
 crypto/ecdsa.c                  |  3 ++-
 crypto/ecdsa_helper.c           | 45 +++++++++++++++++++++++++++++++++
 include/crypto/internal/ecdsa.h | 15 +++++++++++
 include/linux/asn1_encoder.h    |  2 ++
 lib/asn1_encoder.c              |  3 ++-
 7 files changed, 69 insertions(+), 2 deletions(-)
 create mode 100644 crypto/ecdsa_helper.c
 create mode 100644 include/crypto/internal/ecdsa.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 19197469cfab..3e82c7bc8424 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -254,6 +254,7 @@ config CRYPTO_ECDSA
 	select CRYPTO_ECC
 	select CRYPTO_AKCIPHER
 	select ASN1
+	select ASN1_ENCODER
 	help
 	  Elliptic Curve Digital Signature Algorithm (NIST P192, P256 etc.)
 	  is A NIST cryptographic standard algorithm. Only signature verification
diff --git a/crypto/Makefile b/crypto/Makefile
index 43bc33e247d1..226bc2cfb9b7 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -52,8 +52,10 @@ obj-$(CONFIG_CRYPTO_SM2) += sm2_generic.o
 
 $(obj)/ecdsasignature.asn1.o: $(obj)/ecdsasignature.asn1.c $(obj)/ecdsasignature.asn1.h
 $(obj)/ecdsa.o: $(obj)/ecdsasignature.asn1.h
+
 ecdsa_generic-y += ecdsa.o
 ecdsa_generic-y += ecdsasignature.asn1.o
+ecdsa_generic-y += ecdsa_helper.o
 obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o
 
 crypto_acompress-y := acompress.o
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
index b3a8a6b572ba..2ba44c92d271 100644
--- a/crypto/ecdsa.c
+++ b/crypto/ecdsa.c
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/internal/ecc.h>
+#include <crypto/internal/ecdsa.h>
 #include <crypto/akcipher.h>
 #include <crypto/ecdh.h>
 #include <linux/asn1_decoder.h>
@@ -262,7 +263,7 @@ static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm)
 {
 	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
 
-	return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+	return ecdsa_max_signature_size(ctx->curve);
 }
 
 static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
diff --git a/crypto/ecdsa_helper.c b/crypto/ecdsa_helper.c
new file mode 100644
index 000000000000..487c4e9c0f67
--- /dev/null
+++ b/crypto/ecdsa_helper.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RSA key extract helper
+ *
+ * Copyright 2022 Bytedance CO., LTD.
+ *
+ * Authors: lei he <helei.sig11@bytedance.com>
+ */
+#include <crypto/internal/ecdsa.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/oid_registry.h>
+#include <linux/asn1_encoder.h>
+#include <crypto/ecdh.h>
+
+unsigned int ecdsa_max_signature_size(const struct ecc_curve *curve)
+{
+	unsigned int keylen = curve->g.ndigits * sizeof(u64);
+	/* Up to one extra byte to indicate the format */
+	unsigned char buffer[sizeof(size_t) + 1], *data = buffer;
+	int buffer_len = sizeof(buffer);
+	unsigned int coordinate_length, sequence_length;
+
+	asn1_encode_length(&data, &buffer_len, keylen);
+	/**
+	 * The extra cost for encoding keylen bytes as INTEGER in ASN.1:
+	 * 1. one byte for tag
+	 * 2. sizeof(buffer) - buffer_len bytes for length
+	 * 3. one leading zero byte for integers whose leftmost bit is 1
+	 */
+	coordinate_length = 1 + sizeof(buffer) - buffer_len + 1 + keylen;
+
+	/**
+	 * The extra cost for encoding coordinate_length * 2 bytes as SEQUENCE in ASN.1:
+	 * 1. one byte for tag
+	 * 2. sizeof(buffer) - buffer_len bytes for length
+	 */
+	buffer_len = sizeof(buffer);
+	data = buffer;
+	asn1_encode_length(&data, &buffer_len, coordinate_length * 2);
+	sequence_length = 1 + sizeof(buffer) - buffer_len + coordinate_length * 2;
+
+	return sequence_length;
+}
+EXPORT_SYMBOL_GPL(ecdsa_max_signature_size);
diff --git a/include/crypto/internal/ecdsa.h b/include/crypto/internal/ecdsa.h
new file mode 100644
index 000000000000..e35638a35dc2
--- /dev/null
+++ b/include/crypto/internal/ecdsa.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * ECDSA internal helpers
+ *
+ * Copyright (c) 2022 lei he <helei.sig11@bytedance.com>
+ */
+
+ #ifndef _CRYPTO_ECDSA_H
+ #define _CRYPTO_ECDSA_H
+
+#include <crypto/ecc_curve.h>
+
+unsigned int ecdsa_max_signature_size(const struct ecc_curve *curve);
+
+#endif
diff --git a/include/linux/asn1_encoder.h b/include/linux/asn1_encoder.h
index 08cd0c2ad34f..fe439c9a73e3 100644
--- a/include/linux/asn1_encoder.h
+++ b/include/linux/asn1_encoder.h
@@ -29,4 +29,6 @@ unsigned char *
 asn1_encode_boolean(unsigned char *data, const unsigned char *end_data,
 		    bool val);
 
+int asn1_encode_length(unsigned char **data, int *data_len, int len);
+
 #endif
diff --git a/lib/asn1_encoder.c b/lib/asn1_encoder.c
index 0fd3c454a468..644af3055ebb 100644
--- a/lib/asn1_encoder.c
+++ b/lib/asn1_encoder.c
@@ -188,7 +188,7 @@ EXPORT_SYMBOL_GPL(asn1_encode_oid);
  * encoder primitives to accept negative lengths as singalling the
  * sequence will be re-encoded when the length is known.
  */
-static int asn1_encode_length(unsigned char **data, int *data_len, int len)
+int asn1_encode_length(unsigned char **data, int *data_len, int len)
 {
 	if (*data_len < 1)
 		return -EINVAL;
@@ -239,6 +239,7 @@ static int asn1_encode_length(unsigned char **data, int *data_len, int len)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(asn1_encode_length);
 
 /**
  * asn1_encode_tag() - add a tag for optional or explicit value
-- 
2.20.1


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

* [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
  2022-06-23  7:05 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
@ 2022-06-23  7:05 ` Lei He
  2022-06-23  7:05 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  7:05 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

Make pkcs8_private_key_parser can identify ECDSA private keys.

Signed-off-by: lei he <helei.sig11@bytedance.com>
---
 crypto/akcipher.c                     | 10 ++++++
 crypto/asymmetric_keys/pkcs8.asn1     |  2 +-
 crypto/asymmetric_keys/pkcs8_parser.c | 45 +++++++++++++++++++++++++--
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index f866085c8a4a..3adcdc6d48c2 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)
 	return -ENOSYS;
 }
 
+static int akcipher_default_set_key(struct crypto_akcipher *tfm,
+				    const void *key, unsigned int keylen)
+{
+	return -ENOSYS;
+}
+
 int crypto_register_akcipher(struct akcipher_alg *alg)
 {
 	struct crypto_alg *base = &alg->base;
@@ -132,6 +138,10 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
 		alg->encrypt = akcipher_default_op;
 	if (!alg->decrypt)
 		alg->decrypt = akcipher_default_op;
+	if (!alg->set_pub_key)
+		alg->set_pub_key = akcipher_default_set_key;
+	if (!alg->set_priv_key)
+		alg->set_priv_key = akcipher_default_set_key;
 
 	akcipher_prepare_alg(alg);
 	return crypto_register_alg(base);
diff --git a/crypto/asymmetric_keys/pkcs8.asn1 b/crypto/asymmetric_keys/pkcs8.asn1
index 702c41a3c713..1791ddf4168a 100644
--- a/crypto/asymmetric_keys/pkcs8.asn1
+++ b/crypto/asymmetric_keys/pkcs8.asn1
@@ -20,5 +20,5 @@ Attribute ::= ANY
 
 AlgorithmIdentifier ::= SEQUENCE {
 	algorithm   OBJECT IDENTIFIER ({ pkcs8_note_OID }),
-	parameters  ANY OPTIONAL
+	parameters  ANY OPTIONAL ({ pkcs8_note_algo_parameter })
 }
diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c
index 105dcce27f71..e507c635ead5 100644
--- a/crypto/asymmetric_keys/pkcs8_parser.c
+++ b/crypto/asymmetric_keys/pkcs8_parser.c
@@ -24,6 +24,8 @@ struct pkcs8_parse_context {
 	enum OID	algo_oid;		/* Algorithm OID */
 	u32		key_size;
 	const void	*key;
+	const void	*algo_param;
+	u32		algo_param_len;
 };
 
 /*
@@ -47,6 +49,17 @@ int pkcs8_note_OID(void *context, size_t hdrlen,
 	return 0;
 }
 
+int pkcs8_note_algo_parameter(void *context, size_t hdrlen,
+			      unsigned char tag,
+			      const void *value, size_t vlen)
+{
+	struct pkcs8_parse_context *ctx = context;
+
+	ctx->algo_param = value;
+	ctx->algo_param_len = vlen;
+	return 0;
+}
+
 /*
  * Note the version number of the ASN.1 blob.
  */
@@ -69,11 +82,37 @@ int pkcs8_note_algo(void *context, size_t hdrlen,
 		    const void *value, size_t vlen)
 {
 	struct pkcs8_parse_context *ctx = context;
-
-	if (ctx->last_oid != OID_rsaEncryption)
+	enum OID curve_id;
+
+	switch (ctx->last_oid) {
+	case OID_id_ecPublicKey:
+		if (!ctx->algo_param || ctx->algo_param_len == 0)
+			return -EBADMSG;
+		curve_id = look_up_OID(ctx->algo_param, ctx->algo_param_len);
+
+		switch (curve_id) {
+		case OID_id_prime192v1:
+			ctx->pub->pkey_algo = "ecdsa-nist-p192";
+			break;
+		case OID_id_prime256v1:
+			ctx->pub->pkey_algo = "ecdsa-nist-p256";
+			break;
+		case OID_id_ansip384r1:
+			ctx->pub->pkey_algo = "ecdsa-nist-p384";
+			break;
+		default:
+			return -ENOPKG;
+		}
+		break;
+
+	case OID_rsaEncryption:
+		ctx->pub->pkey_algo = "rsa";
+		break;
+
+	default:
 		return -ENOPKG;
+	}
 
-	ctx->pub->pkey_algo = "rsa";
 	return 0;
 }
 
-- 
2.20.1


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

* [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
  2022-06-23  7:05 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
  2022-06-23  7:05 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He
@ 2022-06-23  7:05 ` Lei He
  2022-06-23  7:05 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  7:05 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

remove unused field 'algo_oid' in pkcs8_parse_context

Signed-off-by: lei he <helei.sig11@bytedance.com>
---
 crypto/asymmetric_keys/pkcs8_parser.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c
index e507c635ead5..f81317234331 100644
--- a/crypto/asymmetric_keys/pkcs8_parser.c
+++ b/crypto/asymmetric_keys/pkcs8_parser.c
@@ -21,7 +21,6 @@ struct pkcs8_parse_context {
 	struct public_key *pub;
 	unsigned long	data;			/* Start of data */
 	enum OID	last_oid;		/* Last OID encountered */
-	enum OID	algo_oid;		/* Algorithm OID */
 	u32		key_size;
 	const void	*key;
 	const void	*algo_param;
-- 
2.20.1


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

* [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
                   ` (2 preceding siblings ...)
  2022-06-23  7:05 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He
@ 2022-06-23  7:05 ` Lei He
  2022-06-24  6:51 ` [PATCH v2 0/4] " Michael S. Tsirkin
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  7:05 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

Support ECDSA algorithm for driver virtio-crypto

Signed-off-by: lei he <helei.sig11@bytedance.com>
---
 drivers/crypto/virtio/Kconfig                 |   1 +
 .../virtio/virtio_crypto_akcipher_algs.c      | 259 ++++++++++++++++--
 2 files changed, 239 insertions(+), 21 deletions(-)

diff --git a/drivers/crypto/virtio/Kconfig b/drivers/crypto/virtio/Kconfig
index 5f8915f4a9ff..c4b66cf17d7c 100644
--- a/drivers/crypto/virtio/Kconfig
+++ b/drivers/crypto/virtio/Kconfig
@@ -6,6 +6,7 @@ config CRYPTO_DEV_VIRTIO
 	select CRYPTO_AKCIPHER2
 	select CRYPTO_SKCIPHER
 	select CRYPTO_ENGINE
+	select CRYPTO_ECDSA
 	select CRYPTO_RSA
 	select MPILIB
 	help
diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
index 2a60d0525cde..da628a6de696 100644
--- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
+++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
@@ -10,7 +10,9 @@
 #include <linux/mpi.h>
 #include <linux/scatterlist.h>
 #include <crypto/algapi.h>
+#include <crypto/ecdh.h>
 #include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecdsa.h>
 #include <crypto/internal/rsa.h>
 #include <linux/err.h>
 #include <crypto/scatterwalk.h>
@@ -23,6 +25,10 @@ struct virtio_crypto_rsa_ctx {
 	MPI n;
 };
 
+struct virtio_crypto_ecdsa_ctx {
+	const struct ecc_curve *curve;
+};
+
 struct virtio_crypto_akcipher_ctx {
 	struct crypto_engine_ctx enginectx;
 	struct virtio_crypto *vcrypto;
@@ -31,6 +37,7 @@ struct virtio_crypto_akcipher_ctx {
 	__u64 session_id;
 	union {
 		struct virtio_crypto_rsa_ctx rsa_ctx;
+		struct virtio_crypto_ecdsa_ctx ecdsa_ctx;
 	};
 };
 
@@ -279,7 +286,7 @@ static int __virtio_crypto_akcipher_do_req(struct virtio_crypto_akcipher_request
 	return -ENOMEM;
 }
 
-static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
+static int virtio_crypto_akcipher_do_req(struct crypto_engine *engine, void *vreq, int algo)
 {
 	struct akcipher_request *req = container_of(vreq, struct akcipher_request, base);
 	struct virtio_crypto_akcipher_request *vc_akcipher_req = akcipher_request_ctx(req);
@@ -300,7 +307,7 @@ static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
 	/* build request header */
 	header = &vc_req->req_data->header;
 	header->opcode = cpu_to_le32(vc_akcipher_req->opcode);
-	header->algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_RSA);
+	header->algo = cpu_to_le32(algo);
 	header->session_id = cpu_to_le64(ctx->session_id);
 
 	/* build request akcipher data */
@@ -318,7 +325,12 @@ static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
 	return 0;
 }
 
-static int virtio_crypto_rsa_req(struct akcipher_request *req, uint32_t opcode)
+static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
+{
+	return virtio_crypto_akcipher_do_req(engine, vreq, VIRTIO_CRYPTO_AKCIPHER_RSA);
+}
+
+static int virtio_crypto_akcipher_req(struct akcipher_request *req, uint32_t opcode)
 {
 	struct crypto_akcipher *atfm = crypto_akcipher_reqtfm(req);
 	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(atfm);
@@ -337,24 +349,24 @@ static int virtio_crypto_rsa_req(struct akcipher_request *req, uint32_t opcode)
 	return crypto_transfer_akcipher_request_to_engine(data_vq->engine, req);
 }
 
-static int virtio_crypto_rsa_encrypt(struct akcipher_request *req)
+static int virtio_crypto_akcipher_encrypt(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_ENCRYPT);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_ENCRYPT);
 }
 
-static int virtio_crypto_rsa_decrypt(struct akcipher_request *req)
+static int virtio_crypto_akcipher_decrypt(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_DECRYPT);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_DECRYPT);
 }
 
-static int virtio_crypto_rsa_sign(struct akcipher_request *req)
+static int virtio_crypto_akcipher_sign(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_SIGN);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_SIGN);
 }
 
-static int virtio_crypto_rsa_verify(struct akcipher_request *req)
+static int virtio_crypto_akcipher_verify(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_VERIFY);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_VERIFY);
 }
 
 static int virtio_crypto_rsa_set_key(struct crypto_akcipher *tfm,
@@ -484,18 +496,161 @@ static void virtio_crypto_rsa_exit_tfm(struct crypto_akcipher *tfm)
 	struct virtio_crypto_rsa_ctx *rsa_ctx = &ctx->rsa_ctx;
 
 	virtio_crypto_alg_akcipher_close_session(ctx);
-	virtcrypto_dev_put(ctx->vcrypto);
+	if (ctx->vcrypto)
+		virtcrypto_dev_put(ctx->vcrypto);
 	mpi_free(rsa_ctx->n);
 	rsa_ctx->n = NULL;
 }
 
+static int virtio_crypto_ecdsa_do_req(struct crypto_engine *engine, void *vreq)
+{
+	return virtio_crypto_akcipher_do_req(engine, vreq, VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+}
+
+static int virtio_crypto_ecdsa_set_key(struct crypto_akcipher *tfm,
+				       const void *key,
+				       unsigned int keylen,
+				       bool private,
+				       int curve_id)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto *vcrypto;
+	struct virtio_crypto_ctrl_header header;
+	struct virtio_crypto_akcipher_session_para para;
+	int node = virtio_crypto_get_current_node();
+	uint32_t keytype;
+
+	if (private)
+		keytype = VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
+	else
+		keytype = VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
+
+	if (!ctx->vcrypto) {
+		vcrypto = virtcrypto_get_dev_node(node, VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+						VIRTIO_CRYPTO_AKCIPHER_RSA);
+		if (!vcrypto) {
+			pr_err("virtio_crypto: Could not find a virtio device in the system or unsupported algo\n");
+			return -ENODEV;
+		}
+
+		ctx->vcrypto = vcrypto;
+	} else {
+		virtio_crypto_alg_akcipher_close_session(ctx);
+	}
+
+	/* set ctrl header */
+	header.opcode =	cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION);
+	header.algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+	header.queue_id = 0;
+
+	/* set ECDSA para */
+	para.algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+	para.keytype = cpu_to_le32(keytype);
+	para.keylen = cpu_to_le32(keylen);
+	para.u.ecdsa.curve_id = cpu_to_le32(curve_id);
+
+	return virtio_crypto_alg_akcipher_init_session(ctx, &header, &para, key, keylen);
+}
+
+static int virtio_crypto_ecdsa_nist_p192_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p192_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P384);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P384);
+}
+
+static unsigned int virtio_crypto_ecdsa_max_size(struct crypto_akcipher *tfm)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto_ecdsa_ctx *ecdsa_ctx = &ctx->ecdsa_ctx;
+
+	return ecdsa_max_signature_size(ecdsa_ctx->curve);
+}
+
+static int virtio_crypto_ecdsa_init_tfm(struct crypto_akcipher *tfm, unsigned int curve_id)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	ctx->tfm = tfm;
+	ctx->enginectx.op.do_one_request = virtio_crypto_ecdsa_do_req;
+	ctx->enginectx.op.prepare_request = NULL;
+	ctx->enginectx.op.unprepare_request = NULL;
+	ctx->ecdsa_ctx.curve = ecc_get_curve(curve_id);
+
+	if (!ctx->ecdsa_ctx.curve)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int virtio_crypto_ecdsa_nist_p192_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P384);
+}
+
+static void virtio_crypto_ecdsa_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto_ecdsa_ctx *ecdsa_ctx = &ctx->ecdsa_ctx;
+
+	virtio_crypto_alg_akcipher_close_session(ctx);
+	ecdsa_ctx->curve = NULL;
+	if (ctx->vcrypto)
+		virtcrypto_dev_put(ctx->vcrypto);
+}
+
 static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 	{
 		.algonum = VIRTIO_CRYPTO_AKCIPHER_RSA,
 		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
 		.algo = {
-			.encrypt = virtio_crypto_rsa_encrypt,
-			.decrypt = virtio_crypto_rsa_decrypt,
+			.encrypt = virtio_crypto_akcipher_encrypt,
+			.decrypt = virtio_crypto_akcipher_decrypt,
 			.set_pub_key = virtio_crypto_rsa_raw_set_pub_key,
 			.set_priv_key = virtio_crypto_rsa_raw_set_priv_key,
 			.max_size = virtio_crypto_rsa_max_size,
@@ -515,10 +670,10 @@ static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 		.algonum = VIRTIO_CRYPTO_AKCIPHER_RSA,
 		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
 		.algo = {
-			.encrypt = virtio_crypto_rsa_encrypt,
-			.decrypt = virtio_crypto_rsa_decrypt,
-			.sign = virtio_crypto_rsa_sign,
-			.verify = virtio_crypto_rsa_verify,
+			.encrypt = virtio_crypto_akcipher_encrypt,
+			.decrypt = virtio_crypto_akcipher_decrypt,
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
 			.set_pub_key = virtio_crypto_p1pad_rsa_sha1_set_pub_key,
 			.set_priv_key = virtio_crypto_p1pad_rsa_sha1_set_priv_key,
 			.max_size = virtio_crypto_rsa_max_size,
@@ -534,6 +689,70 @@ static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 			},
 		},
 	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p192_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p192_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p192_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p192",
+				.cra_driver_name = "virtio-ecdsa-nist-p192",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p256_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p256_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p256_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p256",
+				.cra_driver_name = "virtio-ecdsa-nist-p256",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p384_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p384_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p384_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p384",
+				.cra_driver_name = "virtio-ecdsa-nist-p384",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+
+	},
 };
 
 int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
@@ -552,8 +771,7 @@ int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
 
 		if (virtio_crypto_akcipher_algs[i].active_devs == 0) {
 			ret = crypto_register_akcipher(&virtio_crypto_akcipher_algs[i].algo);
-			if (ret)
-				goto unlock;
+			continue;
 		}
 
 		virtio_crypto_akcipher_algs[i].active_devs++;
@@ -561,7 +779,6 @@ int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
 			 virtio_crypto_akcipher_algs[i].algo.base.cra_name);
 	}
 
-unlock:
 	mutex_unlock(&algs_lock);
 	return ret;
 }
-- 
2.20.1


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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
                   ` (3 preceding siblings ...)
  2022-06-23  7:05 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He
@ 2022-06-24  6:51 ` Michael S. Tsirkin
  2022-06-30  6:59 ` Herbert Xu
  2022-08-09 18:36 ` Michael S. Tsirkin
  6 siblings, 0 replies; 19+ messages in thread
From: Michael S. Tsirkin @ 2022-06-24  6:51 UTC (permalink / raw)
  To: Lei He
  Cc: davem, herbert, dhowells, linux-crypto, linux-kernel, berrange,
	pizhenwei

On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
> From: lei he <helei.sig11@bytedance.com>
> 
> This patch supports the ECDSA algorithm for virtio-crypto.

virtio parts:

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> V1 -> V2:
> - explicitly specified an appropriate base commit.
> - fixed the link error reported by kernel test robot <lkp@intl.com>.
> - removed irrelevant commits.
> 
> V1:
> - fixed the problem that the max_signature_size of ECDSA is
> incorrectly calculated.
> - make pkcs8_private_key_parser can identify ECDSA private keys.
> - implement ECDSA algorithm for virtio-crypto device
> 
> 
> lei he (4):
>   crypto: fix the calculation of max_size for ECDSA
>   crypto: pkcs8 parser support ECDSA private keys
>   crypto: remove unused field in pkcs8_parse_context
>   virtio-crypto: support ECDSA algorithm
> 
>  crypto/Kconfig                                |   1 +
>  crypto/Makefile                               |   2 +
>  crypto/akcipher.c                             |  10 +
>  crypto/asymmetric_keys/pkcs8.asn1             |   2 +-
>  crypto/asymmetric_keys/pkcs8_parser.c         |  46 +++-
>  crypto/ecdsa.c                                |   3 +-
>  crypto/ecdsa_helper.c                         |  45 +++
>  drivers/crypto/virtio/Kconfig                 |   1 +
>  .../virtio/virtio_crypto_akcipher_algs.c      | 259 ++++++++++++++++--
>  include/crypto/internal/ecdsa.h               |  15 +
>  include/linux/asn1_encoder.h                  |   2 +
>  lib/asn1_encoder.c                            |   3 +-
>  12 files changed, 361 insertions(+), 28 deletions(-)
>  create mode 100644 crypto/ecdsa_helper.c
>  create mode 100644 include/crypto/internal/ecdsa.h
> 
> 
> base-commit: 018ab4fabddd94f1c96f3b59e180691b9e88d5d8
> -- 
> 2.20.1


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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
                   ` (4 preceding siblings ...)
  2022-06-24  6:51 ` [PATCH v2 0/4] " Michael S. Tsirkin
@ 2022-06-30  6:59 ` Herbert Xu
  2022-06-30  7:23   ` [External] " Lei He
  2022-08-09 18:36 ` Michael S. Tsirkin
  6 siblings, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2022-06-30  6:59 UTC (permalink / raw)
  To: Lei He
  Cc: davem, dhowells, mst, linux-crypto, linux-kernel, berrange, pizhenwei

On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
> From: lei he <helei.sig11@bytedance.com>
> 
> This patch supports the ECDSA algorithm for virtio-crypto.

Why is this necessary?

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [External] [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  6:59 ` Herbert Xu
@ 2022-06-30  7:23   ` Lei He
  2022-06-30  7:41     ` Herbert Xu
  2022-06-30  9:48     ` [External] " Daniel P. Berrangé
  0 siblings, 2 replies; 19+ messages in thread
From: Lei He @ 2022-06-30  7:23 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Lei He, davem, dhowells, Michael S. Tsirkin, linux-crypto,
	linux-kernel, berrange, pizhenwei


> On Jun 30, 2022, at 2:59 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
> On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
>> From: lei he <helei.sig11@bytedance.com>
>> 
>> This patch supports the ECDSA algorithm for virtio-crypto.
> 
> Why is this necessary?
> 

The main purpose of this patch is to offload ECDSA computations to virtio-crypto dev.
We can modify the backend of virtio-crypto to allow hardware like Intel QAT cards to 
perform the actual calculations, and user-space applications such as HTTPS server 
can access those backend in a unified way(eg, keyctl_pk_xx syscall).

Related works are also described in following patch series:
https://lwn.net/ml/linux-crypto/20220525090118.43403-1-helei.sig11@bytedance.com/

> Thanks,
> -- 
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


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

* Re: [External] [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  7:23   ` [External] " Lei He
@ 2022-06-30  7:41     ` Herbert Xu
  2022-06-30  8:30       ` Lei He
  2022-06-30  9:48     ` [External] " Daniel P. Berrangé
  1 sibling, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2022-06-30  7:41 UTC (permalink / raw)
  To: Lei He
  Cc: davem, dhowells, Michael S. Tsirkin, linux-crypto, linux-kernel,
	berrange, pizhenwei

On Thu, Jun 30, 2022 at 03:23:39PM +0800, Lei He wrote:
>
> The main purpose of this patch is to offload ECDSA computations to virtio-crypto dev.
> We can modify the backend of virtio-crypto to allow hardware like Intel QAT cards to 
> perform the actual calculations, and user-space applications such as HTTPS server 
> can access those backend in a unified way(eg, keyctl_pk_xx syscall).

The things is I don't see any driver support in the kernel for
ECDSA.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  7:41     ` Herbert Xu
@ 2022-06-30  8:30       ` Lei He
  2022-06-30  9:07         ` Herbert Xu
  2022-06-30 23:12         ` Sandy Harris
  0 siblings, 2 replies; 19+ messages in thread
From: Lei He @ 2022-06-30  8:30 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Lei He, davem, dhowells, Michael S. Tsirkin, linux-crypto,
	linux-kernel, berrange, pizhenwei


> On Jun 30, 2022, at 3:41 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
> The things is I don't see any driver support in the kernel for
> ECDSA.
> 

I have explained above why we need a driver that supports ECDSA, and this patch
enables virtio-crypto to support ECDSA. I think this is a good time to support ECDSA
in the kernel crypto framework, and there will be more drivers supporting ECDSA in the 
future.
Looking forward to your opinion :-).


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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  8:30       ` Lei He
@ 2022-06-30  9:07         ` Herbert Xu
  2022-06-30 12:44           ` Lei He
  2022-06-30 23:12         ` Sandy Harris
  1 sibling, 1 reply; 19+ messages in thread
From: Herbert Xu @ 2022-06-30  9:07 UTC (permalink / raw)
  To: Lei He
  Cc: davem, dhowells, Michael S. Tsirkin, linux-crypto, linux-kernel,
	berrange, pizhenwei

On Thu, Jun 30, 2022 at 04:30:39PM +0800, Lei He wrote:
>
> I have explained above why we need a driver that supports ECDSA, and this patch
> enables virtio-crypto to support ECDSA. I think this is a good time to support ECDSA
> in the kernel crypto framework, and there will be more drivers supporting ECDSA in the 
> future.
> Looking forward to your opinion :-).

Until there are drivers in the kernel it's pointless to implement
this.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [External] [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  7:23   ` [External] " Lei He
  2022-06-30  7:41     ` Herbert Xu
@ 2022-06-30  9:48     ` Daniel P. Berrangé
  2022-06-30 12:43       ` Lei He
  1 sibling, 1 reply; 19+ messages in thread
From: Daniel P. Berrangé @ 2022-06-30  9:48 UTC (permalink / raw)
  To: Lei He
  Cc: Herbert Xu, davem, dhowells, Michael S. Tsirkin, linux-crypto,
	linux-kernel, pizhenwei

On Thu, Jun 30, 2022 at 03:23:39PM +0800, Lei He wrote:
> 
> > On Jun 30, 2022, at 2:59 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> > 
> > On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
> >> From: lei he <helei.sig11@bytedance.com>
> >> 
> >> This patch supports the ECDSA algorithm for virtio-crypto.
> > 
> > Why is this necessary?
> > 
> 
> The main purpose of this patch is to offload ECDSA computations to virtio-crypto dev.
> We can modify the backend of virtio-crypto to allow hardware like Intel QAT cards to 
> perform the actual calculations, and user-space applications such as HTTPS server 
> can access those backend in a unified way(eg, keyctl_pk_xx syscall).
> 
> Related works are also described in following patch series:
> https://lwn.net/ml/linux-crypto/20220525090118.43403-1-helei.sig11@bytedance.com/

IIUC, this link refers to testing performance of the RSA impl of
virtio-crypto with a vhost-user backend, leveraging an Intel QAT
device on the host. What's the status of that depolyment setup ?
Is code for it published anywhere, and does it have dependancy on
any kernel patches that are not yet posted and/or merged ? Does it
cover both ECDSA and RSA yet, or still only RSA ?

The QEMU backend part of the virtio-crypto support for ECDSA looks fine
to merge, but obviously I'd like some positive sign that the kernel
maintainers are willing to accept the guest driver side.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  9:48     ` [External] " Daniel P. Berrangé
@ 2022-06-30 12:43       ` Lei He
  0 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-30 12:43 UTC (permalink / raw)
  To: "Daniel P. Berrangé"
  Cc: Lei He, Herbert Xu, davem, dhowells, Michael S. Tsirkin,
	linux-crypto, linux-kernel, pizhenwei

On Jun 30, 2022, at 5:48 PM, Daniel P. Berrangé <berrange@redhat.com> wrote:
> 
> On Thu, Jun 30, 2022 at 03:23:39PM +0800, Lei He wrote:
>> 
>>> On Jun 30, 2022, at 2:59 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
>>> 
>>> On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
>>>> From: lei he <helei.sig11@bytedance.com>
>>>> 
>>>> This patch supports the ECDSA algorithm for virtio-crypto.
>>> 
>>> Why is this necessary?
>>> 
>> 
>> The main purpose of this patch is to offload ECDSA computations to virtio-crypto dev.
>> We can modify the backend of virtio-crypto to allow hardware like Intel QAT cards to 
>> perform the actual calculations, and user-space applications such as HTTPS server 
>> can access those backend in a unified way(eg, keyctl_pk_xx syscall).
>> 
>> Related works are also described in following patch series:
>> https://lwn.net/ml/linux-crypto/20220525090118.43403-1-helei.sig11@bytedance.com/
> 
> IIUC, this link refers to testing performance of the RSA impl of
> virtio-crypto with a vhost-user backend, leveraging an Intel QAT
> device on the host. What's the status of that depolyment setup ?
> Is code for it published anywhere, and does it have dependancy on
> any kernel patches that are not yet posted and/or merged ? Does it
> cover both ECDSA and RSA yet, or still only RSA ?
> 
> The QEMU backend part of the virtio-crypto support for ECDSA looks fine
> to merge, but obviously I'd like some positive sign that the kernel
> maintainers are willing to accept the guest driver side.
> 

1. We have now been able to provide offload capability for nginx’s TLS handshake in the virtual
machine(with the kctl-engine), and have achieved	about 0.8~0.9 times performance improvement. 
But as you can see, when we were testing, both authentication and key exchange only supported 
RSA at the moment. 
2. The code for the QAT offload backend is not posted now, it does not support the ECDSA, so it also does not 
depends on any other patches that have not been merged. To support ECDSA, this patch is required.
At present, I have only implemented and tested the ECDSA for the builtin backend, and the ECDSA support
for another backend that can offload is also in progress.

By the way,  the virtio part of QEMU( for support ECDSA)  is also ready,  I will post it soon.

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

* Re:  [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  9:07         ` Herbert Xu
@ 2022-06-30 12:44           ` Lei He
  2022-06-30 12:50             ` Lei He
  0 siblings, 1 reply; 19+ messages in thread
From: Lei He @ 2022-06-30 12:44 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Lei He, davem, dhowells, Michael S. Tsirkin, linux-crypto,
	linux-kernel, "Daniel P . Berrangé",
	zhenwei pi

On Jun 30, 2022, at 5:07 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:

> 
> On Thu, Jun 30, 2022 at 04:30:39PM +0800, Lei He wrote:
>> 
>> I have explained above why we need a driver that supports ECDSA, and this patch
>> enables virtio-crypto to support ECDSA. I think this is a good time to support ECDSA
>> in the kernel crypto framework, and there will be more drivers supporting ECDSA in the 
>> future.
>> Looking forward to your opinion :-).
> 
> Until there are drivers in the kernel it's pointless to implement
> this.
> 

I guess you mean that if there are no drivers in the linux kernel source tree that supports the 
ECDSA, then there is no way under linux to offload ECDSA to other devices, so even if the
virtio-crypto can get the akcipher request, it can’t do better, right? I have some different opinions
 on this:
1. There does exist hardware for offloading ECDSA calculations, for example, IBM PCIe
Cryptographic Coprocessor, Intel QAT, etc, and those chips are already on the market now.
Of course, they also provided corresponding drivers to access these devices, but for some reason,
these drivers have not been submitted to the kernel source tree now.
2. With this patch, when we use QEMU to create a virtual machine, people can directly access the 
virtio-crypto device without caring about where these akcipher requests are executed, and no need
to update drivers(and other stuff) for guest kernel when the  co-processor is updated. 
3.  I will communicate with the Intel QAT team about their plans to provide ECDSA support and ECDH 
support.



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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30 12:44           ` Lei He
@ 2022-06-30 12:50             ` Lei He
  0 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-30 12:50 UTC (permalink / raw)
  To: Xin Zeng
  Cc: Lei He, davem, dhowells, Michael S. Tsirkin, linux-crypto,
	linux-kernel, "Daniel P . Berrangé",
	zhenwei pi, Herbert Xu

On Jun 30, 2022, at 8:44 PM, Lei He <helei.sig11@bytedance.com> wrote:
> 
> On Jun 30, 2022, at 5:07 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
>> 
>> On Thu, Jun 30, 2022 at 04:30:39PM +0800, Lei He wrote:
>>> 
>>> I have explained above why we need a driver that supports ECDSA, and this patch
>>> enables virtio-crypto to support ECDSA. I think this is a good time to support ECDSA
>>> in the kernel crypto framework, and there will be more drivers supporting ECDSA in the 
>>> future.
>>> Looking forward to your opinion :-).
>> 
>> Until there are drivers in the kernel it's pointless to implement
>> this.
>> 
> 
> I guess you mean that if there are no drivers in the linux kernel source tree that supports the 
> ECDSA, then there is no way under linux to offload ECDSA to other devices, so even if the
> virtio-crypto can get the akcipher request, it can’t do better, right? I have some different opinions
> on this:
> 1. There does exist hardware for offloading ECDSA calculations, for example, IBM PCIe
> Cryptographic Coprocessor, Intel QAT, etc, and those chips are already on the market now.
> Of course, they also provided corresponding drivers to access these devices, but for some reason,
> these drivers have not been submitted to the kernel source tree now.
> 2. With this patch, when we use QEMU to create a virtual machine, people can directly access the 
> virtio-crypto device without caring about where these akcipher requests are executed, and no need
> to update drivers(and other stuff) for guest kernel when the  co-processor is updated. 
> 3.  I will communicate with the Intel QAT team about their plans to provide ECDSA support and ECDH 
> support.

Hi, xin:
	I would like to ask if you have any plans to support ECDSA in LKC for QAT driver, and if so how is
it going?

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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30  8:30       ` Lei He
  2022-06-30  9:07         ` Herbert Xu
@ 2022-06-30 23:12         ` Sandy Harris
  2022-07-01  2:54           ` [External] " Lei He
  1 sibling, 1 reply; 19+ messages in thread
From: Sandy Harris @ 2022-06-30 23:12 UTC (permalink / raw)
  To: Lei He
  Cc: Herbert Xu, David S. Miller, David Howells, Michael S. Tsirkin,
	Linux Crypto Mailing List, LKML, berrange, pizhenwei

On Thu, Jun 30, 2022 at 4:37 PM Lei He <helei.sig11@bytedance.com> wrote:

> I have explained above why we need a driver that supports ECDSA, ...

I do not think we do. There are some security concerns.
https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Security

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

* Re: [External] Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-30 23:12         ` Sandy Harris
@ 2022-07-01  2:54           ` Lei He
  0 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-07-01  2:54 UTC (permalink / raw)
  To: Sandy Harris
  Cc: Herbert Xu, David S. Miller, David Howells, Michael S. Tsirkin,
	Linux Crypto Mailing List, LKML, berrange, pizhenwei

On 7/1/2022 7:12 AM, Sandy Harris wrote:
> On Thu, Jun 30, 2022 at 4:37 PM Lei He <helei.sig11@bytedance.com> wrote:
> 
>> I have explained above why we need a driver that supports ECDSA, ...
> 
> I do not think we do. There are some security concerns.
> https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Security

But since tls1.0, the ECDSA algorithm has been retained to the current 
1.3 version.
https://en.wikipedia.org/wiki/Transport_Layer_Security#Algorithms

Best regards,
Lei He
--
helei.sig11@bytedance.com


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

* Re: [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm
  2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
                   ` (5 preceding siblings ...)
  2022-06-30  6:59 ` Herbert Xu
@ 2022-08-09 18:36 ` Michael S. Tsirkin
  6 siblings, 0 replies; 19+ messages in thread
From: Michael S. Tsirkin @ 2022-08-09 18:36 UTC (permalink / raw)
  To: Lei He
  Cc: davem, herbert, dhowells, linux-crypto, linux-kernel, berrange,
	pizhenwei

On Thu, Jun 23, 2022 at 03:05:46PM +0800, Lei He wrote:
> From: lei he <helei.sig11@bytedance.com>
> 
> This patch supports the ECDSA algorithm for virtio-crypto.
> 
> V1 -> V2:
> - explicitly specified an appropriate base commit.
> - fixed the link error reported by kernel test robot <lkp@intl.com>.
> - removed irrelevant commits.
> 
> V1:
> - fixed the problem that the max_signature_size of ECDSA is
> incorrectly calculated.
> - make pkcs8_private_key_parser can identify ECDSA private keys.
> - implement ECDSA algorithm for virtio-crypto device


So this depends on core crypto changes that need Herbert's ack.
I'll drop this from my radar for now.

> 
> lei he (4):
>   crypto: fix the calculation of max_size for ECDSA
>   crypto: pkcs8 parser support ECDSA private keys
>   crypto: remove unused field in pkcs8_parse_context
>   virtio-crypto: support ECDSA algorithm
> 
>  crypto/Kconfig                                |   1 +
>  crypto/Makefile                               |   2 +
>  crypto/akcipher.c                             |  10 +
>  crypto/asymmetric_keys/pkcs8.asn1             |   2 +-
>  crypto/asymmetric_keys/pkcs8_parser.c         |  46 +++-
>  crypto/ecdsa.c                                |   3 +-
>  crypto/ecdsa_helper.c                         |  45 +++
>  drivers/crypto/virtio/Kconfig                 |   1 +
>  .../virtio/virtio_crypto_akcipher_algs.c      | 259 ++++++++++++++++--
>  include/crypto/internal/ecdsa.h               |  15 +
>  include/linux/asn1_encoder.h                  |   2 +
>  lib/asn1_encoder.c                            |   3 +-
>  12 files changed, 361 insertions(+), 28 deletions(-)
>  create mode 100644 crypto/ecdsa_helper.c
>  create mode 100644 include/crypto/internal/ecdsa.h
> 
> 
> base-commit: 018ab4fabddd94f1c96f3b59e180691b9e88d5d8
> -- 
> 2.20.1


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

* [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm
  2022-06-23  6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
@ 2022-06-23  6:15 ` Lei He
  0 siblings, 0 replies; 19+ messages in thread
From: Lei He @ 2022-06-23  6:15 UTC (permalink / raw)
  To: davem, herbert, dhowells
  Cc: mst, linux-crypto, linux-kernel, berrange, pizhenwei, lei he

From: lei he <helei.sig11@bytedance.com>

Support ECDSA algorithm for driver virtio-crypto

Signed-off-by: lei he <helei.sig11@bytedance.com>
---
 drivers/crypto/virtio/Kconfig                 |   1 +
 .../virtio/virtio_crypto_akcipher_algs.c      | 259 ++++++++++++++++--
 2 files changed, 239 insertions(+), 21 deletions(-)

diff --git a/drivers/crypto/virtio/Kconfig b/drivers/crypto/virtio/Kconfig
index 5f8915f4a9ff..c4b66cf17d7c 100644
--- a/drivers/crypto/virtio/Kconfig
+++ b/drivers/crypto/virtio/Kconfig
@@ -6,6 +6,7 @@ config CRYPTO_DEV_VIRTIO
 	select CRYPTO_AKCIPHER2
 	select CRYPTO_SKCIPHER
 	select CRYPTO_ENGINE
+	select CRYPTO_ECDSA
 	select CRYPTO_RSA
 	select MPILIB
 	help
diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
index 2a60d0525cde..da628a6de696 100644
--- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
+++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c
@@ -10,7 +10,9 @@
 #include <linux/mpi.h>
 #include <linux/scatterlist.h>
 #include <crypto/algapi.h>
+#include <crypto/ecdh.h>
 #include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecdsa.h>
 #include <crypto/internal/rsa.h>
 #include <linux/err.h>
 #include <crypto/scatterwalk.h>
@@ -23,6 +25,10 @@ struct virtio_crypto_rsa_ctx {
 	MPI n;
 };
 
+struct virtio_crypto_ecdsa_ctx {
+	const struct ecc_curve *curve;
+};
+
 struct virtio_crypto_akcipher_ctx {
 	struct crypto_engine_ctx enginectx;
 	struct virtio_crypto *vcrypto;
@@ -31,6 +37,7 @@ struct virtio_crypto_akcipher_ctx {
 	__u64 session_id;
 	union {
 		struct virtio_crypto_rsa_ctx rsa_ctx;
+		struct virtio_crypto_ecdsa_ctx ecdsa_ctx;
 	};
 };
 
@@ -279,7 +286,7 @@ static int __virtio_crypto_akcipher_do_req(struct virtio_crypto_akcipher_request
 	return -ENOMEM;
 }
 
-static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
+static int virtio_crypto_akcipher_do_req(struct crypto_engine *engine, void *vreq, int algo)
 {
 	struct akcipher_request *req = container_of(vreq, struct akcipher_request, base);
 	struct virtio_crypto_akcipher_request *vc_akcipher_req = akcipher_request_ctx(req);
@@ -300,7 +307,7 @@ static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
 	/* build request header */
 	header = &vc_req->req_data->header;
 	header->opcode = cpu_to_le32(vc_akcipher_req->opcode);
-	header->algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_RSA);
+	header->algo = cpu_to_le32(algo);
 	header->session_id = cpu_to_le64(ctx->session_id);
 
 	/* build request akcipher data */
@@ -318,7 +325,12 @@ static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
 	return 0;
 }
 
-static int virtio_crypto_rsa_req(struct akcipher_request *req, uint32_t opcode)
+static int virtio_crypto_rsa_do_req(struct crypto_engine *engine, void *vreq)
+{
+	return virtio_crypto_akcipher_do_req(engine, vreq, VIRTIO_CRYPTO_AKCIPHER_RSA);
+}
+
+static int virtio_crypto_akcipher_req(struct akcipher_request *req, uint32_t opcode)
 {
 	struct crypto_akcipher *atfm = crypto_akcipher_reqtfm(req);
 	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(atfm);
@@ -337,24 +349,24 @@ static int virtio_crypto_rsa_req(struct akcipher_request *req, uint32_t opcode)
 	return crypto_transfer_akcipher_request_to_engine(data_vq->engine, req);
 }
 
-static int virtio_crypto_rsa_encrypt(struct akcipher_request *req)
+static int virtio_crypto_akcipher_encrypt(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_ENCRYPT);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_ENCRYPT);
 }
 
-static int virtio_crypto_rsa_decrypt(struct akcipher_request *req)
+static int virtio_crypto_akcipher_decrypt(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_DECRYPT);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_DECRYPT);
 }
 
-static int virtio_crypto_rsa_sign(struct akcipher_request *req)
+static int virtio_crypto_akcipher_sign(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_SIGN);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_SIGN);
 }
 
-static int virtio_crypto_rsa_verify(struct akcipher_request *req)
+static int virtio_crypto_akcipher_verify(struct akcipher_request *req)
 {
-	return virtio_crypto_rsa_req(req, VIRTIO_CRYPTO_AKCIPHER_VERIFY);
+	return virtio_crypto_akcipher_req(req, VIRTIO_CRYPTO_AKCIPHER_VERIFY);
 }
 
 static int virtio_crypto_rsa_set_key(struct crypto_akcipher *tfm,
@@ -484,18 +496,161 @@ static void virtio_crypto_rsa_exit_tfm(struct crypto_akcipher *tfm)
 	struct virtio_crypto_rsa_ctx *rsa_ctx = &ctx->rsa_ctx;
 
 	virtio_crypto_alg_akcipher_close_session(ctx);
-	virtcrypto_dev_put(ctx->vcrypto);
+	if (ctx->vcrypto)
+		virtcrypto_dev_put(ctx->vcrypto);
 	mpi_free(rsa_ctx->n);
 	rsa_ctx->n = NULL;
 }
 
+static int virtio_crypto_ecdsa_do_req(struct crypto_engine *engine, void *vreq)
+{
+	return virtio_crypto_akcipher_do_req(engine, vreq, VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+}
+
+static int virtio_crypto_ecdsa_set_key(struct crypto_akcipher *tfm,
+				       const void *key,
+				       unsigned int keylen,
+				       bool private,
+				       int curve_id)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto *vcrypto;
+	struct virtio_crypto_ctrl_header header;
+	struct virtio_crypto_akcipher_session_para para;
+	int node = virtio_crypto_get_current_node();
+	uint32_t keytype;
+
+	if (private)
+		keytype = VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
+	else
+		keytype = VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
+
+	if (!ctx->vcrypto) {
+		vcrypto = virtcrypto_get_dev_node(node, VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+						VIRTIO_CRYPTO_AKCIPHER_RSA);
+		if (!vcrypto) {
+			pr_err("virtio_crypto: Could not find a virtio device in the system or unsupported algo\n");
+			return -ENODEV;
+		}
+
+		ctx->vcrypto = vcrypto;
+	} else {
+		virtio_crypto_alg_akcipher_close_session(ctx);
+	}
+
+	/* set ctrl header */
+	header.opcode =	cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION);
+	header.algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+	header.queue_id = 0;
+
+	/* set ECDSA para */
+	para.algo = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_ECDSA);
+	para.keytype = cpu_to_le32(keytype);
+	para.keylen = cpu_to_le32(keylen);
+	para.u.ecdsa.curve_id = cpu_to_le32(curve_id);
+
+	return virtio_crypto_alg_akcipher_init_session(ctx, &header, &para, key, keylen);
+}
+
+static int virtio_crypto_ecdsa_nist_p192_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p192_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_set_pub_key(struct crypto_akcipher *tfm,
+						     const void *key,
+						     unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 0, VIRTIO_CRYPTO_CURVE_NIST_P384);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_set_priv_key(struct crypto_akcipher *tfm,
+						      const void *key,
+						      unsigned int keylen)
+{
+	return virtio_crypto_ecdsa_set_key(tfm, key, keylen, 1, VIRTIO_CRYPTO_CURVE_NIST_P384);
+}
+
+static unsigned int virtio_crypto_ecdsa_max_size(struct crypto_akcipher *tfm)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto_ecdsa_ctx *ecdsa_ctx = &ctx->ecdsa_ctx;
+
+	return ecdsa_max_signature_size(ecdsa_ctx->curve);
+}
+
+static int virtio_crypto_ecdsa_init_tfm(struct crypto_akcipher *tfm, unsigned int curve_id)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+	ctx->tfm = tfm;
+	ctx->enginectx.op.do_one_request = virtio_crypto_ecdsa_do_req;
+	ctx->enginectx.op.prepare_request = NULL;
+	ctx->enginectx.op.unprepare_request = NULL;
+	ctx->ecdsa_ctx.curve = ecc_get_curve(curve_id);
+
+	if (!ctx->ecdsa_ctx.curve)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int virtio_crypto_ecdsa_nist_p192_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P192);
+}
+
+static int virtio_crypto_ecdsa_nist_p256_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P256);
+}
+
+static int virtio_crypto_ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
+{
+	return virtio_crypto_ecdsa_init_tfm(tfm, ECC_CURVE_NIST_P384);
+}
+
+static void virtio_crypto_ecdsa_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct virtio_crypto_akcipher_ctx *ctx = akcipher_tfm_ctx(tfm);
+	struct virtio_crypto_ecdsa_ctx *ecdsa_ctx = &ctx->ecdsa_ctx;
+
+	virtio_crypto_alg_akcipher_close_session(ctx);
+	ecdsa_ctx->curve = NULL;
+	if (ctx->vcrypto)
+		virtcrypto_dev_put(ctx->vcrypto);
+}
+
 static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 	{
 		.algonum = VIRTIO_CRYPTO_AKCIPHER_RSA,
 		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
 		.algo = {
-			.encrypt = virtio_crypto_rsa_encrypt,
-			.decrypt = virtio_crypto_rsa_decrypt,
+			.encrypt = virtio_crypto_akcipher_encrypt,
+			.decrypt = virtio_crypto_akcipher_decrypt,
 			.set_pub_key = virtio_crypto_rsa_raw_set_pub_key,
 			.set_priv_key = virtio_crypto_rsa_raw_set_priv_key,
 			.max_size = virtio_crypto_rsa_max_size,
@@ -515,10 +670,10 @@ static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 		.algonum = VIRTIO_CRYPTO_AKCIPHER_RSA,
 		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
 		.algo = {
-			.encrypt = virtio_crypto_rsa_encrypt,
-			.decrypt = virtio_crypto_rsa_decrypt,
-			.sign = virtio_crypto_rsa_sign,
-			.verify = virtio_crypto_rsa_verify,
+			.encrypt = virtio_crypto_akcipher_encrypt,
+			.decrypt = virtio_crypto_akcipher_decrypt,
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
 			.set_pub_key = virtio_crypto_p1pad_rsa_sha1_set_pub_key,
 			.set_priv_key = virtio_crypto_p1pad_rsa_sha1_set_priv_key,
 			.max_size = virtio_crypto_rsa_max_size,
@@ -534,6 +689,70 @@ static struct virtio_crypto_akcipher_algo virtio_crypto_akcipher_algs[] = {
 			},
 		},
 	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p192_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p192_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p192_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p192",
+				.cra_driver_name = "virtio-ecdsa-nist-p192",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p256_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p256_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p256_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p256",
+				.cra_driver_name = "virtio-ecdsa-nist-p256",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+	},
+	{
+		.algonum = VIRTIO_CRYPTO_AKCIPHER_ECDSA,
+		.service = VIRTIO_CRYPTO_SERVICE_AKCIPHER,
+		.algo = {
+			.sign = virtio_crypto_akcipher_sign,
+			.verify = virtio_crypto_akcipher_verify,
+			.set_pub_key = virtio_crypto_ecdsa_nist_p384_set_pub_key,
+			.set_priv_key = virtio_crypto_ecdsa_nist_p384_set_priv_key,
+			.max_size = virtio_crypto_ecdsa_max_size,
+			.init = virtio_crypto_ecdsa_nist_p384_init_tfm,
+			.exit = virtio_crypto_ecdsa_exit_tfm,
+			.reqsize = sizeof(struct virtio_crypto_akcipher_request),
+			.base = {
+				.cra_name = "ecdsa-nist-p384",
+				.cra_driver_name = "virtio-ecdsa-nist-p384",
+				.cra_priority = 150,
+				.cra_module = THIS_MODULE,
+				.cra_ctxsize = sizeof(struct virtio_crypto_akcipher_ctx),
+			},
+		},
+
+	},
 };
 
 int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
@@ -552,8 +771,7 @@ int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
 
 		if (virtio_crypto_akcipher_algs[i].active_devs == 0) {
 			ret = crypto_register_akcipher(&virtio_crypto_akcipher_algs[i].algo);
-			if (ret)
-				goto unlock;
+			continue;
 		}
 
 		virtio_crypto_akcipher_algs[i].active_devs++;
@@ -561,7 +779,6 @@ int virtio_crypto_akcipher_algs_register(struct virtio_crypto *vcrypto)
 			 virtio_crypto_akcipher_algs[i].algo.base.cra_name);
 	}
 
-unlock:
 	mutex_unlock(&algs_lock);
 	return ret;
 }
-- 
2.20.1


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

end of thread, other threads:[~2022-08-09 19:03 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-23  7:05 [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm Lei He
2022-06-23  7:05 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
2022-06-23  7:05 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He
2022-06-23  7:05 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He
2022-06-23  7:05 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He
2022-06-24  6:51 ` [PATCH v2 0/4] " Michael S. Tsirkin
2022-06-30  6:59 ` Herbert Xu
2022-06-30  7:23   ` [External] " Lei He
2022-06-30  7:41     ` Herbert Xu
2022-06-30  8:30       ` Lei He
2022-06-30  9:07         ` Herbert Xu
2022-06-30 12:44           ` Lei He
2022-06-30 12:50             ` Lei He
2022-06-30 23:12         ` Sandy Harris
2022-07-01  2:54           ` [External] " Lei He
2022-06-30  9:48     ` [External] " Daniel P. Berrangé
2022-06-30 12:43       ` Lei He
2022-08-09 18:36 ` Michael S. Tsirkin
  -- strict thread matches above, loose matches on Subject: below --
2022-06-23  6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He
2022-06-23  6:15 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.