* [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA @ 2022-06-23 6:14 Lei He 2022-06-23 6:14 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He ` (3 more replies) 0 siblings, 4 replies; 6+ messages in thread From: Lei He @ 2022-06-23 6:14 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] 6+ messages in thread
* [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys 2022-06-23 6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He @ 2022-06-23 6:14 ` Lei He 2022-06-23 6:14 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He ` (2 subsequent siblings) 3 siblings, 0 replies; 6+ messages in thread From: Lei He @ 2022-06-23 6:14 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] 6+ messages in thread
* [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context 2022-06-23 6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He 2022-06-23 6:14 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He @ 2022-06-23 6:14 ` Lei He 2022-06-23 6:15 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He 2022-06-23 7:15 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA 何磊 3 siblings, 0 replies; 6+ messages in thread From: Lei He @ 2022-06-23 6:14 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] 6+ 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:14 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He 2022-06-23 6:14 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He @ 2022-06-23 6:15 ` Lei He 2022-06-23 7:15 ` [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA 何磊 3 siblings, 0 replies; 6+ 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, ¶, 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] 6+ messages in thread
* Re: [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA 2022-06-23 6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He ` (2 preceding siblings ...) 2022-06-23 6:15 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He @ 2022-06-23 7:15 ` 何磊 3 siblings, 0 replies; 6+ messages in thread From: 何磊 @ 2022-06-23 7:15 UTC (permalink / raw) To: davem, herbert, dhowells Cc: 何磊, Michael S. Tsirkin, linux-crypto, linux-kernel, berrange, pizhenwei > On Jun 23, 2022, at 2:14 PM, Lei He <helei.sig11@bytedance.com> wrote: > > From: lei he <helei.sig11@bytedance.com> > > * asn1_encode_tag() - add a tag for optional or explicit value > — > 2.20.1 > Sorry for accidentally separating cover-letter and pacthes, it has been resent, and please ignore this email. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 0/4] virtio-crypto: support ECDSA algorithm @ 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 0 siblings, 1 reply; 6+ 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] 6+ 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 ` Lei He 0 siblings, 0 replies; 6+ 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] 6+ messages in thread
end of thread, other threads:[~2022-06-23 7:15 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-06-23 6:14 [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Lei He 2022-06-23 6:14 ` [PATCH v2 2/4] crypto: pkcs8 parser support ECDSA private keys Lei He 2022-06-23 6:14 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context Lei He 2022-06-23 6:15 ` [PATCH v2 4/4] virtio-crypto: support ECDSA algorithm Lei He 2022-06-23 7:15 ` [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 ` [PATCH v2 3/4] crypto: remove unused field in pkcs8_parse_context 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.