From patchwork Mon Oct 21 18:09:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arkadiusz Kusztal X-Patchwork-Id: 61614 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AC0A71BF01; Mon, 21 Oct 2019 20:09:41 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 605AC1BE98 for ; Mon, 21 Oct 2019 20:09:37 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Oct 2019 11:09:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,324,1566889200"; d="scan'208";a="209416973" Received: from akusztax-mobl.ger.corp.intel.com ([10.103.104.118]) by orsmga002.jf.intel.com with ESMTP; 21 Oct 2019 11:09:35 -0700 From: Arek Kusztal To: dev@dpdk.org Cc: akhil.goyal@nxp.com, fiona.trahe@intel.com, Arek Kusztal Date: Mon, 21 Oct 2019 20:09:16 +0200 Message-Id: <20191021180919.11284-3-arkadiuszx.kusztal@intel.com> X-Mailer: git-send-email 2.19.1.windows.1 In-Reply-To: <20191021180919.11284-1-arkadiuszx.kusztal@intel.com> References: <20191021180919.11284-1-arkadiuszx.kusztal@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3 2/5] crypto/qat: add rsa implementation to asym pmd X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This commit adds rsa algorithm to asymmetric pmd using pair (n, d) private key Signed-off-by: Arek Kusztal --- doc/guides/cryptodevs/features/qat.ini | 2 + doc/guides/cryptodevs/qat.rst | 1 + doc/guides/rel_notes/release_19_11.rst | 2 + .../qat/qat_adf/qat_pke_functionality_arrays.h | 18 ++ drivers/crypto/qat/qat_asym.c | 251 ++++++++++++++++++++- drivers/crypto/qat/qat_asym.h | 2 + drivers/crypto/qat/qat_asym_capabilities.h | 21 ++ drivers/crypto/qat/qat_asym_pmd.c | 3 +- 8 files changed, 298 insertions(+), 2 deletions(-) diff --git a/doc/guides/cryptodevs/features/qat.ini b/doc/guides/cryptodevs/features/qat.ini index cef8015..374b523 100644 --- a/doc/guides/cryptodevs/features/qat.ini +++ b/doc/guides/cryptodevs/features/qat.ini @@ -14,6 +14,7 @@ OOP LB In SGL Out = Y OOP LB In LB Out = Y Digest encrypted = Y Asymmetric sessionless = Y +RSA PRIV OP KEY EXP = Y ; ; Supported crypto algorithms of the 'qat' crypto driver. @@ -71,3 +72,4 @@ AES CCM (256) = Y [Asymmetric] Modular Exponentiation = Y Modular Inversion = Y +RSA = Y diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index ad685a7..8630e27 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -134,6 +134,7 @@ Limitations * Big integers longer than 4096 bits are not supported. * Queue pairs are not thread-safe (that is, within a single queue pair, RX and TX from different lcores is not supported). +* RSA-2560, RSA-3584 are not supported .. _building_qat: diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 6df6b49..b3e7365 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -141,6 +141,8 @@ New Features Added support for asymmetric session-less operations. + Added support for RSA algorithm with pair (n, d) private key representation. + Removed Items ------------- diff --git a/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h b/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h index 8adf209..3e40b86 100644 --- a/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h +++ b/drivers/common/qat/qat_adf/qat_pke_functionality_arrays.h @@ -49,4 +49,22 @@ static const uint32_t MOD_INV_IDS_EVEN[][2] = { { 4096, MATHS_MODINV_EVEN_L4096 }, }; +static const uint32_t RSA_ENC_IDS[][2] = { + { 512, PKE_RSA_EP_512 }, + { 1024, PKE_RSA_EP_1024 }, + { 1536, PKE_RSA_EP_1536 }, + { 2048, PKE_RSA_EP_2048 }, + { 3072, PKE_RSA_EP_3072 }, + { 4096, PKE_RSA_EP_4096 }, +}; + +static const uint32_t RSA_DEC_IDS[][2] = { + { 512, PKE_RSA_DP1_512 }, + { 1024, PKE_RSA_DP1_1024 }, + { 1536, PKE_RSA_DP1_1536 }, + { 2048, PKE_RSA_DP1_2048 }, + { 3072, PKE_RSA_DP1_3072 }, + { 4096, PKE_RSA_DP1_4096 }, +}; + #endif diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c index 63a5363..0a13454 100644 --- a/drivers/crypto/qat/qat_asym.c +++ b/drivers/crypto/qat/qat_asym.c @@ -228,6 +228,170 @@ qat_asym_fill_arrays(struct rte_crypto_asym_op *asym_op, cookie->input_array[1], alg_size_in_bytes); #endif + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + err = qat_asym_check_nonzero(xform->rsa.n); + if (err) { + QAT_LOG(ERR, "Empty modulus in RSA" + " inverse, aborting this operation"); + return err; + } + + alg_size_in_bytes = xform->rsa.n.length; + alg_size = alg_size_in_bytes << 3; + + qat_req->input_param_count = + QAT_ASYM_RSA_NUM_IN_PARAMS; + qat_req->output_param_count = + QAT_ASYM_RSA_NUM_OUT_PARAMS; + + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT || + asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + + if (qat_asym_get_sz_and_func_id(RSA_ENC_IDS, + sizeof(RSA_ENC_IDS)/ + sizeof(*RSA_ENC_IDS), + &alg_size, &func_id)) { + err = -(EINVAL); + QAT_LOG(ERR, + "Not supported RSA parameter size (key)"); + return err; + } + alg_size_in_bytes = alg_size >> 3; + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.message.length + , asym_op->rsa.message.data, + asym_op->rsa.message.length); + break; + default: + err = -(EINVAL); + QAT_LOG(ERR, + "Invalid RSA padding (Encryption)"); + return err; + } +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Message", + cookie->input_array[0], + alg_size_in_bytes); +#endif + } else { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0], + asym_op->rsa.sign.data, + alg_size_in_bytes); + break; + default: + err = -(EINVAL); + QAT_LOG(ERR, + "Invalid RSA padding (Verify)"); + return err; + } + +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, " RSA Signature", + cookie->input_array[0], + alg_size_in_bytes); +#endif + + } + rte_memcpy(cookie->input_array[1] + + alg_size_in_bytes - + xform->rsa.e.length + , xform->rsa.e.data, + xform->rsa.e.length); + rte_memcpy(cookie->input_array[2] + + alg_size_in_bytes - + xform->rsa.n.length, + xform->rsa.n.data, + xform->rsa.n.length); + + cookie->alg_size = alg_size; + qat_req->pke_hdr.cd_pars.func_id = func_id; + +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Public Key", + cookie->input_array[1], alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Modulus", + cookie->input_array[2], alg_size_in_bytes); +#endif + } else { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_DECRYPT) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.cipher.length, + asym_op->rsa.cipher.data, + asym_op->rsa.cipher.length); + break; + default: + QAT_LOG(ERR, + "Invalid padding of RSA (Decrypt)"); + return -(EINVAL); + } + + } else if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_SIGN) { + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(cookie->input_array[0] + + alg_size_in_bytes - + asym_op->rsa.message.length, + asym_op->rsa.message.data, + asym_op->rsa.message.length); + break; + default: + QAT_LOG(ERR, + "Invalid padding of RSA (Signature)"); + return -(EINVAL); + } + } + + if (xform->rsa.key_type == RTE_RSA_KET_TYPE_QT) { + QAT_LOG(ERR, "RSA CRT not implemented"); + return -(EINVAL); + } else if (xform->rsa.key_type == + RTE_RSA_KEY_TYPE_EXP) { + if (qat_asym_get_sz_and_func_id( + RSA_DEC_IDS, + sizeof(RSA_DEC_IDS)/ + sizeof(*RSA_DEC_IDS), + &alg_size, &func_id)) { + return -(EINVAL); + } + alg_size_in_bytes = alg_size >> 3; + rte_memcpy(cookie->input_array[1] + + alg_size_in_bytes - + xform->rsa.d.length, + xform->rsa.d.data, + xform->rsa.d.length); + rte_memcpy(cookie->input_array[2] + + alg_size_in_bytes - + xform->rsa.n.length, + xform->rsa.n.data, + xform->rsa.n.length); +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA ciphertext", cookie->input_array[0], + alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA d", cookie->input_array[1], + alg_size_in_bytes); + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA n", cookie->input_array[2], + alg_size_in_bytes); +#endif + + cookie->alg_size = alg_size; + qat_req->pke_hdr.cd_pars.func_id = func_id; + } else { + QAT_LOG(ERR, "Invalid RSA key type"); + return -(EINVAL); + } + } } else { QAT_LOG(ERR, "Invalid asymmetric crypto xform"); return -(EINVAL); @@ -354,6 +518,85 @@ static void qat_asym_collect_response(struct rte_crypto_op *rx_op, alg_size_in_bytes); #endif } + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + + alg_size = cookie->alg_size; + alg_size_in_bytes = alg_size >> 3; + if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT || + asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_ENCRYPT) { + uint8_t *rsa_result = asym_op->rsa.cipher.data; + + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Encrypted data", + cookie->output_array[0], + alg_size_in_bytes); +#endif + } else if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_VERIFY) { + uint8_t *rsa_result = asym_op->rsa.cipher.data; + + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = + RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Signature", + cookie->output_array[0], + alg_size_in_bytes); +#endif + break; + default: + QAT_LOG(ERR, "Padding not supported"); + rx_op->status = + RTE_CRYPTO_OP_STATUS_ERROR; + break; + } + } + } else { + if (asym_op->rsa.op_type == + RTE_CRYPTO_ASYM_OP_DECRYPT) { + uint8_t *rsa_result = asym_op->rsa.message.data; + + switch (asym_op->rsa.pad) { + case RTE_CRYPTO_RSA_PADDING_NONE: + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + break; + default: + QAT_LOG(ERR, "Padding not supported"); + rx_op->status = + RTE_CRYPTO_OP_STATUS_ERROR; + break; + } +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Decrypted Message", + rsa_result, alg_size_in_bytes); +#endif + } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) { + uint8_t *rsa_result = asym_op->rsa.sign.data; + + rte_memcpy(rsa_result, + cookie->output_array[0], + alg_size_in_bytes); + rx_op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; +#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG + QAT_DP_HEXDUMP_LOG(DEBUG, "RSA Signature", + cookie->output_array[0], + alg_size_in_bytes); +#endif + } + } } qat_clear_arrays_by_alg(cookie, xform->xform_type, alg_size_in_bytes, alg_size_in_bytes); @@ -393,7 +636,7 @@ qat_asym_process_response(void **op, uint8_t *resp, if (rx_op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { ctx = (struct qat_asym_session *)get_asym_session_private_data( - rx_op->asym->session, cryptodev_qat_asym_driver_id); + rx_op->asym->session, cryptodev_qat_asym_driver_id); qat_asym_collect_response(rx_op, cookie, ctx->xform); } else if (rx_op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { qat_asym_collect_response(rx_op, cookie, rx_op->asym->xform); @@ -436,6 +679,12 @@ qat_asym_session_configure(struct rte_cryptodev *dev, err = -EINVAL; goto error; } + } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_RSA) { + if (xform->rsa.n.length == 0) { + QAT_LOG(ERR, "Invalid rsa input parameter"); + err = -EINVAL; + goto error; + } } else if (xform->xform_type >= RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END || xform->xform_type <= RTE_CRYPTO_ASYM_XFORM_NONE) { QAT_LOG(ERR, "Invalid asymmetric crypto xform"); diff --git a/drivers/crypto/qat/qat_asym.h b/drivers/crypto/qat/qat_asym.h index 2959b07..b1dec8f 100644 --- a/drivers/crypto/qat/qat_asym.h +++ b/drivers/crypto/qat/qat_asym.h @@ -22,6 +22,8 @@ typedef uint64_t large_int_ptr; #define QAT_ASYM_MODINV_NUM_OUT_PARAMS 1 #define QAT_ASYM_MODEXP_NUM_IN_PARAMS 3 #define QAT_ASYM_MODEXP_NUM_OUT_PARAMS 1 +#define QAT_ASYM_RSA_NUM_IN_PARAMS 3 +#define QAT_ASYM_RSA_NUM_OUT_PARAMS 1 struct qat_asym_op_cookie { size_t alg_size; diff --git a/drivers/crypto/qat/qat_asym_capabilities.h b/drivers/crypto/qat/qat_asym_capabilities.h index f43c025..523b4da 100644 --- a/drivers/crypto/qat/qat_asym_capabilities.h +++ b/drivers/crypto/qat/qat_asym_capabilities.h @@ -37,6 +37,27 @@ } \ }, \ } \ + }, \ + { /* RSA */ \ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, \ + {.asym = { \ + .xform_capa = { \ + .xform_type = RTE_CRYPTO_ASYM_XFORM_RSA, \ + .op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) | \ + (1 << RTE_CRYPTO_ASYM_OP_VERIFY) | \ + (1 << RTE_CRYPTO_ASYM_OP_ENCRYPT) | \ + (1 << RTE_CRYPTO_ASYM_OP_DECRYPT)), \ + { \ + .modlen = { \ + /* min length is based on openssl rsa keygen */ \ + .min = 64, \ + /* value 0 symbolizes no limit on max length */ \ + .max = 512, \ + .increment = 64 \ + }, } \ + } \ + }, \ + } \ } \ #endif /* _QAT_ASYM_CAPABILITIES_H_ */ diff --git a/drivers/crypto/qat/qat_asym_pmd.c b/drivers/crypto/qat/qat_asym_pmd.c index 71fd709..78fc2d7 100644 --- a/drivers/crypto/qat/qat_asym_pmd.c +++ b/drivers/crypto/qat/qat_asym_pmd.c @@ -271,7 +271,8 @@ qat_asym_dev_create(struct qat_pci_device *qat_pci_dev) cryptodev->feature_flags = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_HW_ACCELERATED | - RTE_CRYPTODEV_FF_ASYM_SESSIONLESS; + RTE_CRYPTODEV_FF_ASYM_SESSIONLESS | + RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP; internals = cryptodev->data->dev_private; internals->qat_dev = qat_pci_dev; qat_pci_dev->asym_dev = internals;