From patchwork Fri May 26 09:12:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gowrishankar Muthukrishnan X-Patchwork-Id: 127557 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8C95842BA9; Fri, 26 May 2023 11:12:34 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C604E4114B; Fri, 26 May 2023 11:12:23 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 0AC914114B for ; Fri, 26 May 2023 11:12:21 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 34Q1qvJ7032373; Fri, 26 May 2023 02:12:21 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=It8BX0dJr5S4DjKsu0BZMCaQE1flWPFys+//k0/JAtY=; b=FndsTVTLvN5jpkkfpM6OxpesB5lbB1IhsTmuyxpFOnWBCCMdtgPKSiAm0zTDAoxn2bvl iVsRVmY4nOLJZUwiale/1jrX9QPELnPceJn6JkW61eBTF8pmQdfAXxXznFyalu5C8eUH Sd04cihNEiH7urKkG/BnRBvq+QZdXYHuOFqmst0PtPinrzA2GGtooieRPx6w+DMAU2Di 9u33Db5B0iFHpzRWJa5yfDVvdTk7cpHk5CZEnNEjAfCLXhTSSiSrCo8YsOoDxVELXT/X Lv97K6n8FjfdjSvTWh16DdWVdBRtvG/pD6atlXH4SQ1Iukfk7v1Z6s3stZGIct+A4VcZ ig== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3qtg6t24nf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 26 May 2023 02:12:21 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Fri, 26 May 2023 02:12:19 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Fri, 26 May 2023 02:12:19 -0700 Received: from BG-LT91401.marvell.com (unknown [10.193.69.246]) by maili.marvell.com (Postfix) with ESMTP id 499373F706F; Fri, 26 May 2023 02:12:15 -0700 (PDT) From: Gowrishankar Muthukrishnan To: CC: , Akhil Goyal , Fan Zhang , Gowrishankar Muthukrishnan Subject: [PATCH v2 3/3] crypto/openssl: add SM2 asymmetric crypto support Date: Fri, 26 May 2023 14:42:04 +0530 Message-ID: <2c8912ddde6b6cd4b6978e9256e7a4346ae4d8e8.1685091909.git.gmuthukrishn@marvell.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: c5C9QOcD2YBfpoBI1sMmZQf-yGbzfHSn X-Proofpoint-GUID: c5C9QOcD2YBfpoBI1sMmZQf-yGbzfHSn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.176.26 definitions=2023-05-26_01,2023-05-25_03,2023-05-22_02 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add SM2 asymmetric algorithm support in openssl PMD. Signed-off-by: Gowrishankar Muthukrishnan --- doc/guides/cryptodevs/features/openssl.ini | 1 + doc/guides/cryptodevs/openssl.rst | 1 + doc/guides/rel_notes/release_23_07.rst | 4 + drivers/crypto/openssl/openssl_pmd_private.h | 7 + drivers/crypto/openssl/rte_openssl_pmd.c | 245 +++++++++++++++++++ drivers/crypto/openssl/rte_openssl_pmd_ops.c | 101 ++++++++ 6 files changed, 359 insertions(+) diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini index 4b0f9b162e..b64c8ec4a5 100644 --- a/doc/guides/cryptodevs/features/openssl.ini +++ b/doc/guides/cryptodevs/features/openssl.ini @@ -65,6 +65,7 @@ DSA = Y Modular Exponentiation = Y Modular Inversion = Y Diffie-hellman = Y +SM2 = Y ; ; Supported Operating systems of the 'openssl' crypto driver. diff --git a/doc/guides/cryptodevs/openssl.rst b/doc/guides/cryptodevs/openssl.rst index 03041ceda1..ff21d21b23 100644 --- a/doc/guides/cryptodevs/openssl.rst +++ b/doc/guides/cryptodevs/openssl.rst @@ -53,6 +53,7 @@ Supported Asymmetric Crypto algorithms: * ``RTE_CRYPTO_ASYM_XFORM_DH`` * ``RTE_CRYPTO_ASYM_XFORM_MODINV`` * ``RTE_CRYPTO_ASYM_XFORM_MODEX`` +* ``RTE_CRYPTO_ASYM_XFORM_SM2`` Installation diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst index 8b8e69d619..aeebcffb60 100644 --- a/doc/guides/rel_notes/release_23_07.rst +++ b/doc/guides/rel_notes/release_23_07.rst @@ -61,6 +61,10 @@ New Features along with prime field curve support. +* **Updated OpenSSL crypto driver for SM2 support.** + + Added SM2 algorithm support in asymmetric crypto operations. + Removed Items ------------- diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h index ed6841e460..d7990c8333 100644 --- a/drivers/crypto/openssl/openssl_pmd_private.h +++ b/drivers/crypto/openssl/openssl_pmd_private.h @@ -12,6 +12,7 @@ #include #include #include +#include #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) #include #include @@ -200,6 +201,12 @@ struct openssl_asym_session { OSSL_PARAM_BLD * param_bld; #endif } s; + struct { +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PARAM *key_params; + OSSL_PARAM *enc_params; +#endif + } sm2; } u; } __rte_cache_aligned; /** Set and validate OPENSSL crypto session parameters */ diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c index 384d262621..25feb88ac3 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd.c +++ b/drivers/crypto/openssl/rte_openssl_pmd.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "openssl_pmd_private.h" #include "compat.h" @@ -2662,6 +2663,234 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop, return ret; } + +static int +process_openssl_sm2_op_evp(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL; + OSSL_PARAM *kparams = sess->u.sm2.key_params; + struct rte_crypto_asym_op *op = cop->asym; + EVP_PKEY *pkey = NULL; + int ret = -1; + + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + + if (!kparams) + return ret; + + switch (op->sm2.op_type) { + case RTE_CRYPTO_ASYM_OP_ENCRYPT: + { + OSSL_PARAM *eparams = sess->u.sm2.enc_params; + size_t output_len; + + kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL); + if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 || + EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0) + goto err_sm2; + + cctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!cctx) + goto err_sm2; + + if (!EVP_PKEY_encrypt_init(cctx)) + goto err_sm2; + + if (!EVP_PKEY_CTX_set_params(cctx, eparams)) + goto err_sm2; + + if (!EVP_PKEY_encrypt(cctx, op->sm2.cipher.data, &output_len, + op->sm2.message.data, + op->sm2.message.length)) + goto err_sm2; + op->sm2.cipher.length = output_len; + } + break; + case RTE_CRYPTO_ASYM_OP_DECRYPT: + { + OSSL_PARAM *eparams = sess->u.sm2.enc_params; + + kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL); + if (kctx == NULL + || EVP_PKEY_fromdata_init(kctx) <= 0 + || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0) + goto err_sm2; + + cctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!cctx) + goto err_sm2; + + if (!EVP_PKEY_decrypt_init(cctx)) + goto err_sm2; + + if (!EVP_PKEY_CTX_set_params(cctx, eparams)) + goto err_sm2; + + if (!EVP_PKEY_decrypt(cctx, op->sm2.message.data, &op->sm2.message.length, + op->sm2.cipher.data, op->sm2.cipher.length)) + goto err_sm2; + } + break; + case RTE_CRYPTO_ASYM_OP_SIGN: + { + unsigned char signbuf[128] = {0}; + const unsigned char *signptr = signbuf; + EVP_MD_CTX *md_ctx = NULL; + const BIGNUM *r, *s; + ECDSA_SIG *ec_sign; + EVP_MD *check_md; + size_t signlen; + + kctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); + if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 || + EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, kparams) <= 0) + goto err_sm2; + + md_ctx = EVP_MD_CTX_new(); + if (!md_ctx) + goto err_sm2; + + sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!sctx) + goto err_sm2; + + EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx); + + check_md = EVP_MD_fetch(NULL, "sm3", NULL); + if (!check_md) + goto err_sm2; + + if (!EVP_DigestSignInit(md_ctx, NULL, check_md, NULL, pkey)) + goto err_sm2; + + if (EVP_PKEY_CTX_set1_id(sctx, op->sm2.id.data, op->sm2.id.length) <= 0) + goto err_sm2; + + if (!EVP_DigestSignUpdate(md_ctx, op->sm2.message.data, + op->sm2.message.length)) + goto err_sm2; + + if (!EVP_DigestSignFinal(md_ctx, NULL, &signlen)) + goto err_sm2; + + if (!EVP_DigestSignFinal(md_ctx, signbuf, &signlen)) + goto err_sm2; + + ec_sign = d2i_ECDSA_SIG(NULL, &signptr, signlen); + if (!ec_sign) + goto err_sm2; + + r = ECDSA_SIG_get0_r(ec_sign); + s = ECDSA_SIG_get0_s(ec_sign); + if (!r || !s) + goto err_sm2; + + op->sm2.r.length = BN_num_bytes(r); + op->sm2.s.length = BN_num_bytes(s); + BN_bn2bin(r, op->sm2.r.data); + BN_bn2bin(s, op->sm2.s.data); + + ECDSA_SIG_free(ec_sign); + } + break; + case RTE_CRYPTO_ASYM_OP_VERIFY: + { + unsigned char signbuf[128] = {0}; + EVP_MD_CTX *md_ctx = NULL; + BIGNUM *r = NULL, *s = NULL; + ECDSA_SIG *ec_sign; + EVP_MD *check_md; + size_t signlen; + + kctx = EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL); + if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 || + EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, kparams) <= 0) + goto err_sm2; + + if (!EVP_PKEY_is_a(pkey, "SM2")) + goto err_sm2; + + md_ctx = EVP_MD_CTX_new(); + if (!md_ctx) + goto err_sm2; + + sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!sctx) + goto err_sm2; + + EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx); + + check_md = EVP_MD_fetch(NULL, "sm3", NULL); + if (!check_md) + goto err_sm2; + + if (!EVP_DigestVerifyInit(md_ctx, NULL, check_md, NULL, pkey)) + goto err_sm2; + + if (EVP_PKEY_CTX_set1_id(sctx, op->sm2.id.data, op->sm2.id.length) <= 0) + goto err_sm2; + + if (!EVP_DigestVerifyUpdate(md_ctx, op->sm2.message.data, + op->sm2.message.length)) + goto err_sm2; + + ec_sign = ECDSA_SIG_new(); + if (!ec_sign) + goto err_sm2; + + r = BN_bin2bn(op->sm2.r.data, op->sm2.r.length, r); + s = BN_bin2bn(op->sm2.s.data, op->sm2.s.length, s); + if (!r || !s) + goto err_sm2; + + if (!ECDSA_SIG_set0(ec_sign, r, s)) { + BN_free(r); + BN_free(s); + goto err_sm2; + } + + r = NULL; + s = NULL; + + signlen = i2d_ECDSA_SIG(ec_sign, (unsigned char **)&signbuf); + if (signlen <= 0) + goto err_sm2; + + if (!EVP_DigestVerifyFinal(md_ctx, signbuf, signlen)) + goto err_sm2; + + BN_free(r); + BN_free(s); + ECDSA_SIG_free(ec_sign); + } + break; + default: + /* allow ops with invalid args to be pushed to + * completion queue + */ + cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; + goto err_sm2; + } + + ret = 0; + cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS; +err_sm2: + if (kctx) + EVP_PKEY_CTX_free(kctx); + + if (sctx) + EVP_PKEY_CTX_free(sctx); + + if (cctx) + EVP_PKEY_CTX_free(cctx); + + if (pkey) + EVP_PKEY_free(pkey); + + return ret; +} + #else static int process_openssl_rsa_op(struct rte_crypto_op *cop, @@ -2761,6 +2990,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop, return 0; } + +static int +process_openssl_sm2_op(struct rte_crypto_op *cop, + struct openssl_asym_session *sess) +{ + RTE_SET_USED(cop); + RTE_SET_USED(sess); + return -ENOTSUP; +} #endif static int @@ -2809,6 +3047,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op, process_openssl_dsa_verify_op(op, sess); else op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; +#endif + break; + case RTE_CRYPTO_ASYM_XFORM_SM2: +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + retval = process_openssl_sm2_op_evp(op, sess); +#else + retval = process_openssl_sm2_op(op, sess); #endif break; default: diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c index 29ad1b9505..7a1e1e8e8c 100644 --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c @@ -1282,6 +1282,102 @@ static int openssl_set_asym_session_parameters( BN_free(pub_key); return -1; } + case RTE_CRYPTO_ASYM_XFORM_SM2: + { +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PARAM_BLD *param_bld = NULL; + OSSL_PARAM *params = NULL; + BIGNUM *pkey = NULL; + uint8_t pubkey[64]; + size_t len = 0; + int ret = -1; + + pkey = BN_bin2bn((const unsigned char *)xform->sm2.pkey.data, + xform->sm2.pkey.length, pkey); + + memset(pubkey, 0, RTE_DIM(pubkey)); + pubkey[0] = 0x04; + len += 1; + memcpy(&pubkey[len], xform->sm2.q.x.data, xform->sm2.q.x.length); + len += xform->sm2.q.x.length; + memcpy(&pubkey[len], xform->sm2.q.y.data, xform->sm2.q.y.length); + len += xform->sm2.q.y.length; + + param_bld = OSSL_PARAM_BLD_new(); + if (!param_bld) { + OPENSSL_LOG(ERR, "failed to allocate params\n"); + goto err_sm2; + } + + ret = OSSL_PARAM_BLD_push_utf8_string(param_bld, + OSSL_PKEY_PARAM_GROUP_NAME, "SM2", 0); + if (!ret) { + OPENSSL_LOG(ERR, "failed to push params\n"); + goto err_sm2; + } + + ret = OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, pkey); + if (!ret) { + OPENSSL_LOG(ERR, "failed to push params\n"); + goto err_sm2; + } + + ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY, + pubkey, len); + if (!ret) { + OPENSSL_LOG(ERR, "failed to push params\n"); + goto err_sm2; + } + + params = OSSL_PARAM_BLD_to_param(param_bld); + if (!params) { + OPENSSL_LOG(ERR, "failed to push params\n"); + goto err_sm2; + } + + asym_session->u.sm2.key_params = params; + OSSL_PARAM_BLD_free(param_bld); + + param_bld = OSSL_PARAM_BLD_new(); + if (!param_bld) { + OPENSSL_LOG(ERR, "failed to allocate params\n"); + goto err_sm2; + } + + ret = OSSL_PARAM_BLD_push_utf8_string(param_bld, + OSSL_ASYM_CIPHER_PARAM_DIGEST, "SM3", 0); + if (!ret) { + OPENSSL_LOG(ERR, "failed to push params\n"); + goto err_sm2; + } + + params = OSSL_PARAM_BLD_to_param(param_bld); + if (!params) { + OPENSSL_LOG(ERR, "failed to h params\n"); + goto err_sm2; + } + + asym_session->u.sm2.enc_params = params; + OSSL_PARAM_BLD_free(param_bld); + + asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_SM2; + break; +err_sm2: + if (pkey) + BN_free(pkey); + + if (param_bld) + OSSL_PARAM_BLD_free(param_bld); + + if (asym_session->u.sm2.key_params) + OSSL_PARAM_free(asym_session->u.sm2.key_params); + + if (asym_session->u.sm2.enc_params) + OSSL_PARAM_free(asym_session->u.sm2.enc_params); + + return -1; +#endif + } default: return ret; } @@ -1366,6 +1462,11 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess) DSA_free(sess->u.s.dsa); #endif break; + case RTE_CRYPTO_ASYM_XFORM_SM2: +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + OSSL_PARAM_free(sess->u.sm2.key_params); + OSSL_PARAM_free(sess->u.sm2.enc_params); +#endif default: break; }