From patchwork Thu Feb 28 16:35:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arkadiusz Kusztal X-Patchwork-Id: 50663 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 117DA4C9F; Thu, 28 Feb 2019 17:37:28 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id B1E8544BE for ; Thu, 28 Feb 2019 17:37:24 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Feb 2019 08:37:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,423,1544515200"; d="scan'208";a="142425970" Received: from akusztax-mobl.ger.corp.intel.com ([10.103.104.106]) by orsmga001.jf.intel.com with ESMTP; 28 Feb 2019 08:37:22 -0800 From: Arek Kusztal To: dev@dpdk.org Cc: akhil.goyal@nxp.com, fiona.trahe@intel.com, Arek Kusztal Date: Thu, 28 Feb 2019 17:35:22 +0100 Message-Id: <20190228163523.6096-4-arkadiuszx.kusztal@intel.com> X-Mailer: git-send-email 2.19.1.windows.1 In-Reply-To: <20190228163523.6096-1-arkadiuszx.kusztal@intel.com> References: <20190228163523.6096-1-arkadiuszx.kusztal@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 3/4] crypto/qat: add modular exponentiation to qat 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 modular exponentiation to Intel QuickAssist Technology driver. For capabilities or limitations refer to qat.rst or qat_asym_capabilities.h. Signed-off-by: Arek Kusztal --- doc/guides/cryptodevs/qat.rst | 2 + drivers/crypto/qat/qat_asym.c | 117 +++++++++++++++++++++++++++-- drivers/crypto/qat/qat_asym.h | 9 ++- drivers/crypto/qat/qat_asym_capabilities.h | 18 ++++- drivers/crypto/qat/qat_asym_pmd.c | 1 + 5 files changed, 137 insertions(+), 10 deletions(-) diff --git a/doc/guides/cryptodevs/qat.rst b/doc/guides/cryptodevs/qat.rst index 767171d..9c0196f 100644 --- a/doc/guides/cryptodevs/qat.rst +++ b/doc/guides/cryptodevs/qat.rst @@ -105,6 +105,8 @@ Asymmetric Crypto Service on QAT The QAT Asym PMD has support for: +* ``Modular exponentiation`` + Limitations ~~~~~~~~~~~ diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c index 0b6ef4a..04a35eb 100644 --- a/drivers/crypto/qat/qat_asym.c +++ b/drivers/crypto/qat/qat_asym.c @@ -11,7 +11,7 @@ #define qat_asym_sz_2param(arg) (arg, sizeof(arg)/sizeof(*arg)) -static int __rte_unused qat_asym_get_sz_and_func_id(const uint32_t arr[][2], +static int qat_asym_get_sz_and_func_id(const uint32_t arr[][2], size_t arr_sz, size_t *size, uint32_t *func_id) { size_t i; @@ -26,7 +26,7 @@ static int __rte_unused qat_asym_get_sz_and_func_id(const uint32_t arr[][2], } static void qat_asym_build_req_tmpl(void *sess_private_data, - struct rte_crypto_asym_xform __rte_unused *xform) { + struct rte_crypto_asym_xform *xform) { struct icp_qat_fw_pke_request *qat_req; struct qat_asym_session *session = sess_private_data; @@ -47,9 +47,14 @@ static void qat_asym_build_req_tmpl(void *sess_private_data, qat_req->resrvd1 = 0; qat_req->resrvd2 = 0; qat_req->next_req_adr = 0; + + if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_MODEX) { + qat_req->output_param_count = 1; + qat_req->input_param_count = 3; + } } -static size_t __rte_unused max_of(int n, ...) +static size_t max_of(int n, ...) { va_list args; size_t len = 0, num; @@ -68,6 +73,32 @@ static size_t __rte_unused max_of(int n, ...) return len; } +static int qat_asym_check_nonzero(rte_crypto_param n) +{ + if (n.length < 8) { + /* Not a case for any cryptograpic function */ + size_t i; + if (n.data[n.length - 1] == 0x0) { + for (i = 0; i < n.length - 1; i++) + if (n.data[i] != 0x0) + break; + if (i == n.length - 1) + return QAT_ASYM_ERROR_DIVIDE_BY_ZERO; + } + } else if (*(uint64_t *)&n.data[ + n.length - 8] == 0) { + /* Very likely it is zeroed modulus */ + size_t i; + for (i = 0; i < n.length - 8; i++) + if (n.data[i] != 0x0) + break; + if (i == n.length - 8) + return QAT_ASYM_ERROR_DIVIDE_BY_ZERO; + } + + return 0; +} + int qat_asym_build_request(void *in_op, uint8_t *out_msg, @@ -76,27 +107,64 @@ qat_asym_build_request(void *in_op, { struct qat_asym_session *ctx; struct rte_crypto_op *op = (struct rte_crypto_op *)in_op; - struct rte_crypto_asym_op __rte_unused *asym_op = op->asym; + struct rte_crypto_asym_op *asym_op = op->asym; struct icp_qat_fw_pke_request *qat_req = (struct icp_qat_fw_pke_request *)out_msg; struct qat_asym_op_cookie *cookie = (struct qat_asym_op_cookie *)op_cookie; + uint64_t err = 0; + size_t alg_size; + size_t alg_size_in_bytes; + uint32_t func_id; ctx = (struct qat_asym_session *)get_asym_session_private_data( op->asym->session, cryptodev_qat_asym_driver_id); rte_mov64((uint8_t *)qat_req, (const uint8_t *)&(ctx->req_tmpl)); - qat_req->pke_mid.opaque = (uint64_t)(uintptr_t)op; + qat_req->pke_mid.opaque = (uint64_t)(uintptr_t)op; qat_req->pke_mid.src_data_addr = cookie->input_addr; qat_req->pke_mid.dest_data_addr = cookie->output_addr; - goto error; + if (ctx->alg == QAT_PKE_MODEXP) { + err = qat_asym_check_nonzero(ctx->sess_alg_params.mod_exp.n); + if (err) + goto error; + + alg_size_in_bytes = max_of(3, asym_op->modex.base.length, + ctx->sess_alg_params.mod_exp.e.length, + ctx->sess_alg_params.mod_exp.n.length); + alg_size = alg_size_in_bytes << 3; + + if (qat_asym_get_sz_and_func_id(MOD_EXP_SIZE, + sizeof(MOD_EXP_SIZE)/sizeof(*MOD_EXP_SIZE), + &alg_size, &func_id)) { + err = QAT_ASYM_ERROR_INVALID_MODEXP_PARAM; + goto error; + } + + alg_size_in_bytes = alg_size >> 3; + rte_memcpy(cookie->input_array[0] + alg_size_in_bytes - + asym_op->modex.base.length + , asym_op->modex.base.data, + asym_op->modex.base.length); + rte_memcpy(cookie->input_array[1] + alg_size_in_bytes - + ctx->sess_alg_params.mod_exp.e.length + , ctx->sess_alg_params.mod_exp.e.data, + ctx->sess_alg_params.mod_exp.e.length); + rte_memcpy(cookie->input_array[2] + alg_size_in_bytes - + ctx->sess_alg_params.mod_exp.n.length, + ctx->sess_alg_params.mod_exp.n.data, + ctx->sess_alg_params.mod_exp.n.length); + cookie->alg_size = alg_size; + qat_req->pke_hdr.cd_pars.func_id = func_id; + } + return 0; error: qat_req->output_param_count = 0; qat_req->input_param_count = 0; qat_req->pke_hdr.service_type = ICP_QAT_FW_COMN_REQ_NULL; - cookie->error |= QAT_ASYM_ERROR_DEVIDE_BY_ZERO; + cookie->error |= err; return 0; } @@ -105,11 +173,17 @@ void qat_asym_process_response(void **op, uint8_t *resp, void *op_cookie) { + struct qat_asym_session *ctx; struct icp_qat_fw_pke_resp *resp_msg = (struct icp_qat_fw_pke_resp *)resp; struct rte_crypto_op *rx_op = (struct rte_crypto_op *)(uintptr_t) (resp_msg->opaque); + struct rte_crypto_asym_op *asym_op = rx_op->asym; struct qat_asym_op_cookie *cookie = op_cookie; + size_t alg_size, alg_size_in_bytes; + + ctx = (struct qat_asym_session *)get_asym_session_private_data( + rx_op->asym->session, cryptodev_qat_asym_driver_id); *op = rx_op; rx_op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED; @@ -126,6 +200,24 @@ qat_asym_process_response(void **op, uint8_t *resp, cookie->error = 0; rx_op->status = RTE_CRYPTO_OP_STATUS_ERROR; } + + if (ctx->alg == QAT_PKE_MODEXP) { + alg_size = cookie->alg_size; + alg_size_in_bytes = alg_size >> 3; + uint8_t *modexp_result = asym_op->modex.result.data; + + rte_memcpy(modexp_result + + (asym_op->modex.result.length - ctx->sess_alg_params.mod_exp.n.length), + cookie->output_array[0] + alg_size_in_bytes + - ctx->sess_alg_params.mod_exp.n.length, + ctx->sess_alg_params.mod_exp.n.length + ); + + memset(cookie->input_array[0], 0x0, alg_size_in_bytes); + memset(cookie->input_array[1], 0x0, alg_size_in_bytes); + memset(cookie->input_array[2], 0x0, alg_size_in_bytes); + memset(cookie->output_array[0], 0x0, alg_size_in_bytes); + } } int @@ -135,6 +227,7 @@ qat_asym_session_configure(struct rte_cryptodev *dev, struct rte_mempool *mempool) { void *sess_private_data; + struct qat_asym_session *session; if (rte_mempool_get(mempool, &sess_private_data)) { QAT_LOG(ERR, @@ -142,8 +235,16 @@ qat_asym_session_configure(struct rte_cryptodev *dev, return -ENOMEM; } - qat_asym_build_req_tmpl(sess_private_data, xform); + session = sess_private_data; + if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_MODEX) { + session->sess_alg_params.mod_exp.e = xform->modex.exponent; + session->sess_alg_params.mod_exp.n = xform->modex.modulus; + session->alg = QAT_PKE_MODEXP; + if (xform->modex.exponent.length == 0 || xform->modex.modulus.length == 0) + return -EINVAL; + } + qat_asym_build_req_tmpl(sess_private_data, xform); set_asym_session_private_data(sess, dev->driver_id, sess_private_data); diff --git a/drivers/crypto/qat/qat_asym.h b/drivers/crypto/qat/qat_asym.h index 673493d..e6c3ce3 100644 --- a/drivers/crypto/qat/qat_asym.h +++ b/drivers/crypto/qat/qat_asym.h @@ -17,7 +17,8 @@ typedef uint64_t large_int_ptr; #define QAT_PKE_MAX_LN_SIZE 512 #define _PKE_ALIGN_ __attribute__((__aligned__(8))) -#define QAT_ASYM_ERROR_DEVIDE_BY_ZERO 0x01 +#define QAT_ASYM_ERROR_DIVIDE_BY_ZERO 0x01 +#define QAT_ASYM_ERROR_INVALID_MODEXP_PARAM 0x02 struct qat_asym_op_cookie { size_t alg_size; @@ -42,6 +43,12 @@ struct qat_asym_session { enum qat_asym_alg alg; struct icp_qat_fw_pke_request req_tmpl; uint64_t flags; + union { + struct { + rte_crypto_param n; + rte_crypto_param e; + } mod_exp; + } sess_alg_params; }; int diff --git a/drivers/crypto/qat/qat_asym_capabilities.h b/drivers/crypto/qat/qat_asym_capabilities.h index b50e061..1d6323f 100644 --- a/drivers/crypto/qat/qat_asym_capabilities.h +++ b/drivers/crypto/qat/qat_asym_capabilities.h @@ -5,6 +5,22 @@ #ifndef _QAT_ASYM_CAPABILITIES_H_ #define _QAT_ASYM_CAPABILITIES_H_ -#define QAT_BASE_GEN1_ASYM_CAPABILITIES +#define QAT_BASE_GEN1_ASYM_CAPABILITIES \ + { /* modexp */ \ + .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC, \ + {.asym = { \ + .xform_capa = { \ + .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX, \ + .op_types = 0, \ + { \ + .modlen = { \ + .min = 1, \ + .max = 512, \ + .increment = 1 \ + }, } \ + } \ + }, \ + } \ + } \ #endif /* _QAT_ASYM_CAPABILITIES_H_ */ diff --git a/drivers/crypto/qat/qat_asym_pmd.c b/drivers/crypto/qat/qat_asym_pmd.c index 9ebaa8d..a12b695 100644 --- a/drivers/crypto/qat/qat_asym_pmd.c +++ b/drivers/crypto/qat/qat_asym_pmd.c @@ -14,6 +14,7 @@ uint8_t cryptodev_qat_asym_driver_id; static const struct rte_cryptodev_capabilities qat_gen1_asym_capabilities[] = { + QAT_BASE_GEN1_ASYM_CAPABILITIES, RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() };