This commits adds Diffie-Hellman key exchange algorithm to Intel QuickAssist Technology PMD.
Signed-off-by: Arek Kusztal <arkadiuszx.kusz...@intel.com> --- Depends-on: series-22343 ("crypto/qat: refactor asym algorithm macros and logs") drivers/common/qat/qat_adf/qat_pke.h | 36 ++++++++ drivers/crypto/qat/qat_asym.c | 168 +++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) diff --git a/drivers/common/qat/qat_adf/qat_pke.h b/drivers/common/qat/qat_adf/qat_pke.h index 6c12bfd989..c727e4e1af 100644 --- a/drivers/common/qat/qat_adf/qat_pke.h +++ b/drivers/common/qat/qat_adf/qat_pke.h @@ -137,6 +137,42 @@ get_modinv_function(struct rte_crypto_asym_xform *xform) } static struct qat_asym_function +get_dh_g2_function(uint32_t bytesize) +{ + struct qat_asym_function qat_function = { }; + + if (bytesize <= 256) { + qat_function.func_id = PKE_DH_G2_2048; + qat_function.bytesize = 256; + } else if (bytesize <= 384) { + qat_function.func_id = PKE_DH_G2_3072; + qat_function.bytesize = 384; + } else if (bytesize <= 512) { + qat_function.func_id = PKE_DH_G2_4096; + qat_function.bytesize = 512; + } + return qat_function; +} + +static struct qat_asym_function +get_dh_function(uint32_t bytesize) +{ + struct qat_asym_function qat_function = { }; + + if (bytesize <= 256) { + qat_function.func_id = PKE_DH_2048; + qat_function.bytesize = 256; + } else if (bytesize <= 384) { + qat_function.func_id = PKE_DH_3072; + qat_function.bytesize = 384; + } else if (bytesize <= 512) { + qat_function.func_id = PKE_DH_4096; + qat_function.bytesize = 512; + } + return qat_function; +} + +static struct qat_asym_function get_rsa_enc_function(struct rte_crypto_asym_xform *xform) { struct qat_asym_function qat_function = { }; diff --git a/drivers/crypto/qat/qat_asym.c b/drivers/crypto/qat/qat_asym.c index d2041b2efa..c2a985b355 100644 --- a/drivers/crypto/qat/qat_asym.c +++ b/drivers/crypto/qat/qat_asym.c @@ -748,6 +748,125 @@ ecpm_collect(struct rte_crypto_asym_op *asym_op, } static int +dh_mod_g2_input(struct rte_crypto_asym_op *asym_op, + struct icp_qat_fw_pke_request *qat_req, + struct qat_asym_op_cookie *cookie, + struct rte_crypto_asym_xform *xform) +{ + struct qat_asym_function qat_function; + uint32_t alg_bytesize, func_id; + + qat_function = get_dh_g2_function(xform->dh.p.length); + func_id = qat_function.func_id; + if (qat_function.func_id == 0) { + QAT_LOG(ERR, "Cannot obtain functionality id"); + return -EINVAL; + } + alg_bytesize = qat_function.bytesize; + SET_PKE_LN(asym_op->dh.priv_key, alg_bytesize, 0); + SET_PKE_LN(xform->dh.p, alg_bytesize, 1); + cookie->alg_bytesize = alg_bytesize; + cookie->qat_func_alignsize = alg_bytesize; + + qat_req->pke_hdr.cd_pars.func_id = func_id; + qat_req->input_param_count = 2; + qat_req->output_param_count = 1; + + HEXDUMP("DH Priv", cookie->input_array[0], alg_bytesize); + HEXDUMP("DH p", cookie->input_array[1], alg_bytesize); + + return 0; +} + +static int +dh_mod_n_input(struct rte_crypto_asym_op *asym_op, + struct icp_qat_fw_pke_request *qat_req, + struct qat_asym_op_cookie *cookie, + struct rte_crypto_asym_xform *xform) +{ + struct qat_asym_function qat_function; + uint32_t alg_bytesize, func_id; + + qat_function = get_dh_function(xform->dh.p.length); + func_id = qat_function.func_id; + if (qat_function.func_id == 0) { + QAT_LOG(ERR, "Cannot obtain functionality id"); + return -EINVAL; + } + alg_bytesize = qat_function.bytesize; + if (xform->dh.type == RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE) { + SET_PKE_LN(xform->dh.g, alg_bytesize, 0); + SET_PKE_LN(asym_op->dh.priv_key, alg_bytesize, 1); + SET_PKE_LN(xform->dh.p, alg_bytesize, 2); + } else { + SET_PKE_LN(asym_op->dh.pub_key, alg_bytesize, 0); + SET_PKE_LN(asym_op->dh.priv_key, alg_bytesize, 1); + SET_PKE_LN(xform->dh.p, alg_bytesize, 2); + } + cookie->alg_bytesize = alg_bytesize; + cookie->qat_func_alignsize = alg_bytesize; + + qat_req->pke_hdr.cd_pars.func_id = func_id; + qat_req->input_param_count = 3; + qat_req->output_param_count = 1; + + HEXDUMP("ModExp g/priv key", cookie->input_array[0], alg_bytesize); + HEXDUMP("ModExp priv/pub", cookie->input_array[1], alg_bytesize); + HEXDUMP("ModExp p", cookie->input_array[2], alg_bytesize); + + return 0; +} + +static int +dh_mod_set_input(struct rte_crypto_asym_op *asym_op, + struct icp_qat_fw_pke_request *qat_req, + struct qat_asym_op_cookie *cookie, + struct rte_crypto_asym_xform *xform) +{ + if (xform->dh.type == RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE && + xform->dh.g.length == 1 && xform->dh.g.data[0] == 2) + return dh_mod_g2_input(asym_op, qat_req, cookie, xform); + else + return dh_mod_n_input(asym_op, qat_req, cookie, xform); +} + +static int +dh_set_input(struct rte_crypto_asym_op *asym_op, + struct icp_qat_fw_pke_request *qat_req, + struct qat_asym_op_cookie *cookie, + struct rte_crypto_asym_xform *xform) +{ + switch (xform->xform_type) { + case RTE_CRYPTO_ASYM_XFORM_DH: + return dh_mod_set_input(asym_op, qat_req, cookie, xform); + default: + QAT_LOG(ERR, + "Invalid/unsupported asymmetric crypto xform type"); + return -1; + } +} + +static uint8_t +dh_collect(struct rte_crypto_asym_op *asym_op, + struct qat_asym_op_cookie *cookie, + struct rte_crypto_asym_xform *xform) +{ + uint8_t *DH; + uint32_t alg_bytesize = cookie->alg_bytesize; + + if (xform->dh.type == RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE) { + DH = asym_op->dh.pub_key.data; + asym_op->dh.pub_key.length = alg_bytesize; + } else { + DH = asym_op->dh.shared_secret.data; + asym_op->dh.shared_secret.length = alg_bytesize; + } + rte_memcpy(DH, cookie->output_array[0], alg_bytesize); + HEXDUMP("DH", DH, alg_bytesize); + return RTE_CRYPTO_OP_STATUS_SUCCESS; +} + +static int asym_set_input(struct rte_crypto_asym_op *asym_op, struct icp_qat_fw_pke_request *qat_req, struct qat_asym_op_cookie *cookie, @@ -760,6 +879,9 @@ asym_set_input(struct rte_crypto_asym_op *asym_op, case RTE_CRYPTO_ASYM_XFORM_MODINV: return modinv_set_input(asym_op, qat_req, cookie, xform); + case RTE_CRYPTO_ASYM_XFORM_DH: + return dh_set_input(asym_op, qat_req, + cookie, xform); case RTE_CRYPTO_ASYM_XFORM_RSA: return rsa_set_input(asym_op, qat_req, cookie, xform); @@ -849,6 +971,8 @@ qat_asym_collect_response(struct rte_crypto_op *op, return modexp_collect(asym_op, cookie, xform); case RTE_CRYPTO_ASYM_XFORM_MODINV: return modinv_collect(asym_op, cookie, xform); + case RTE_CRYPTO_ASYM_XFORM_DH: + return dh_collect(asym_op, cookie, xform); case RTE_CRYPTO_ASYM_XFORM_RSA: return rsa_collect(asym_op, cookie); case RTE_CRYPTO_ASYM_XFORM_ECDSA: @@ -967,6 +1091,35 @@ session_set_modinv(struct qat_asym_session *qat_session, } static int +session_set_dh(struct qat_asym_session *qat_session, + struct rte_crypto_asym_xform *xform) +{ + uint8_t *g = xform->dh.g.data; + uint8_t *p = xform->dh.p.data; + + qat_session->xform.dh.type = xform->dh.type; + qat_session->xform.dh.g.data = + rte_malloc(NULL, xform->dh.g.length, 0); + if (qat_session->xform.dh.g.data == NULL) + return -ENOMEM; + qat_session->xform.dh.g.length = xform->dh.g.length; + qat_session->xform.dh.p.data = rte_malloc(NULL, + xform->dh.p.length, 0); + if (qat_session->xform.dh.p.data == NULL) { + rte_free(qat_session->xform.dh.p.data); + return -ENOMEM; + } + qat_session->xform.dh.p.length = xform->dh.p.length; + + rte_memcpy(qat_session->xform.dh.g.data, g, + xform->dh.g.length); + rte_memcpy(qat_session->xform.dh.p.data, p, + xform->dh.p.length); + + return 0; +} + +static int session_set_rsa(struct qat_asym_session *qat_session, struct rte_crypto_asym_xform *xform) { @@ -1118,6 +1271,9 @@ qat_asym_session_configure(struct rte_cryptodev *dev __rte_unused, case RTE_CRYPTO_ASYM_XFORM_RSA: ret = session_set_rsa(qat_session, xform); break; + case RTE_CRYPTO_ASYM_XFORM_DH: + ret = session_set_dh(qat_session, xform); + break; case RTE_CRYPTO_ASYM_XFORM_ECDSA: case RTE_CRYPTO_ASYM_XFORM_ECPM: session_set_ecdsa(qat_session, xform); @@ -1157,6 +1313,15 @@ session_clear_modinv(struct rte_crypto_modinv_xform *modinv) } static void +session_clear_dh(struct rte_crypto_dh_xform *dh) +{ + memset(dh->g.data, 0, dh->g.length); + rte_free(dh->g.data); + memset(dh->p.data, 0, dh->p.length); + rte_free(dh->p.data); +} + +static void session_clear_rsa(struct rte_crypto_rsa_xform *rsa) { memset(rsa->n.data, 0, rsa->n.length); @@ -1190,6 +1355,9 @@ session_clear_xform(struct qat_asym_session *qat_session) case RTE_CRYPTO_ASYM_XFORM_MODINV: session_clear_modinv(&qat_session->xform.modinv); break; + case RTE_CRYPTO_ASYM_XFORM_DH: + session_clear_dh(&qat_session->xform.dh); + break; case RTE_CRYPTO_ASYM_XFORM_RSA: session_clear_rsa(&qat_session->xform.rsa); break; -- 2.13.6