From patchwork Thu Sep 2 13:42:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archana Muniganti X-Patchwork-Id: 97812 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 C9624A0C4C; Thu, 2 Sep 2021 15:44:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BDA62406A2; Thu, 2 Sep 2021 15:44:01 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 9694840698 for ; Thu, 2 Sep 2021 15:43:59 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1825LH8b028339 for ; Thu, 2 Sep 2021 06:43:58 -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=QS9V3lvVDvcnSOA8N7SHScAELU/a//OrY0D7X+ugRr0=; b=ccG3UsUn6ezqkWvZ/K7rmx4lQSlCynJadK8ronRK6LBQGYL4ePwTipKYbW7bpjvUy9lc bzpt/YPECr5wCGTgFoZQ0QG3+G/hw6Y6r+6NXzbk5EvO682iNQHmTVW/Dm6NrZBZr0YS OoMwAymuxWFDs0hK3VlAaoPb7NrVEMKaf4EbtXll0SXLcWZBWjKyf6Ravs1WyKDEcd3U aG+ylE3eo1qnrMpPFlXprUwV3TMwy6j5UziMb3wBJlLz/DLNOoZLVtjHxuUP8hFLII6E JZ2y/KnHVcJwwEZiZNInYFTk37IBPUwxj8vECyUZqZGCQ/RMkEvzuyp3lF7pT8SYxzh7 lQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com with ESMTP id 3atrd2hs04-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Thu, 02 Sep 2021 06:43:58 -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.18; Thu, 2 Sep 2021 06:43:57 -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.18 via Frontend Transport; Thu, 2 Sep 2021 06:43:57 -0700 Received: from hyd1409.caveonetworks.com.com (unknown [10.29.45.15]) by maili.marvell.com (Postfix) with ESMTP id D6EB53F7064; Thu, 2 Sep 2021 06:43:54 -0700 (PDT) From: Archana Muniganti To: CC: Archana Muniganti , , , , , , Vamsi Attunuru Date: Thu, 2 Sep 2021 19:12:49 +0530 Message-ID: <20210902134254.28373-4-marchana@marvell.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210902134254.28373-1-marchana@marvell.com> References: <20210902134254.28373-1-marchana@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: tql7puYnoGmqEKYCaQ5XBS5egocx_5Rg X-Proofpoint-ORIG-GUID: tql7puYnoGmqEKYCaQ5XBS5egocx_5Rg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.391,FMLib:17.0.607.475 definitions=2021-09-02_04,2021-09-02_02,2020-04-07_01 Subject: [dpdk-dev] [PATCH 3/8] crypto/cnxk: add cn9k IPsec session related functions 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 Sender: "dev" Add helper functions useful in implementing IPsec outbound and inbound session create apis. Signed-off-by: Archana Muniganti Signed-off-by: Tejasree Kondoj Signed-off-by: Vamsi Attunuru --- drivers/crypto/cnxk/cn9k_cryptodev.c | 2 + drivers/crypto/cnxk/cn9k_ipsec.c | 425 +++++++++++++++++++++++++++ drivers/crypto/cnxk/cn9k_ipsec.h | 29 ++ drivers/crypto/cnxk/meson.build | 1 + 4 files changed, 457 insertions(+) create mode 100644 drivers/crypto/cnxk/cn9k_ipsec.c create mode 100644 drivers/crypto/cnxk/cn9k_ipsec.h diff --git a/drivers/crypto/cnxk/cn9k_cryptodev.c b/drivers/crypto/cnxk/cn9k_cryptodev.c index db2e085161..e60b352fac 100644 --- a/drivers/crypto/cnxk/cn9k_cryptodev.c +++ b/drivers/crypto/cnxk/cn9k_cryptodev.c @@ -12,6 +12,7 @@ #include "cn9k_cryptodev.h" #include "cn9k_cryptodev_ops.h" +#include "cn9k_ipsec.h" #include "cnxk_cryptodev.h" #include "cnxk_cryptodev_capabilities.h" #include "cnxk_cryptodev_sec.h" @@ -92,6 +93,7 @@ cn9k_cpt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, cnxk_cpt_caps_populate(vf); cn9k_cpt_set_enqdeq_fns(dev); + cn9k_sec_ops_override(); return 0; diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c new file mode 100644 index 0000000000..dd02cc7764 --- /dev/null +++ b/drivers/crypto/cnxk/cn9k_ipsec.c @@ -0,0 +1,425 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include + +#include "cnxk_cryptodev.h" +#include "cnxk_cryptodev_ops.h" +#include "cnxk_ipsec.h" +#include "cnxk_security.h" +#include "cn9k_ipsec.h" + +#include "roc_api.h" + +static inline int +cn9k_cpt_enq_sa_write(struct cn9k_ipsec_sa *sa, struct cnxk_cpt_qp *qp, + uint8_t opcode, size_t ctx_len) +{ + uint64_t lmtline = qp->lmtline.lmt_base; + uint64_t io_addr = qp->lmtline.io_addr; + uint64_t lmt_status, time_out; + struct cpt_cn9k_res_s *res; + struct cpt_inst_s inst; + uint64_t *mdata; + int ret = 0; + + if (unlikely(rte_mempool_get(qp->meta_info.pool, (void **)&mdata) < 0)) + return -ENOMEM; + + res = (struct cpt_cn9k_res_s *)RTE_PTR_ALIGN(mdata, 16); + res->compcode = CPT_COMP_NOT_DONE; + + inst.w4.s.opcode_major = opcode; + inst.w4.s.opcode_minor = ctx_len >> 3; + inst.w4.s.param1 = 0; + inst.w4.s.param2 = 0; + inst.w4.s.dlen = ctx_len; + inst.dptr = rte_mempool_virt2iova(sa); + inst.rptr = 0; + inst.w7.s.cptr = rte_mempool_virt2iova(sa); + inst.w7.s.egrp = ROC_CPT_DFLT_ENG_GRP_SE; + + inst.w0.u64 = 0; + inst.w2.u64 = 0; + inst.w3.u64 = 0; + inst.res_addr = rte_mempool_virt2iova(res); + + rte_io_wmb(); + + do { + /* Copy CPT command to LMTLINE */ + roc_lmt_mov((void *)lmtline, &inst, 2); + lmt_status = roc_lmt_submit_ldeor(io_addr); + } while (lmt_status == 0); + + time_out = rte_get_timer_cycles() + + DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz(); + + while (res->compcode == CPT_COMP_NOT_DONE) { + if (rte_get_timer_cycles() > time_out) { + rte_mempool_put(qp->meta_info.pool, mdata); + plt_err("Request timed out"); + return -ETIMEDOUT; + } + rte_io_rmb(); + } + + if (unlikely(res->compcode != CPT_COMP_GOOD)) { + ret = res->compcode; + switch (ret) { + case CPT_COMP_INSTERR: + plt_err("Request failed with instruction error"); + break; + case CPT_COMP_FAULT: + plt_err("Request failed with DMA fault"); + break; + case CPT_COMP_HWERR: + plt_err("Request failed with hardware error"); + break; + default: + plt_err("Request failed with unknown hardware " + "completion code : 0x%x", + ret); + } + ret = -EINVAL; + goto mempool_put; + } + + if (unlikely(res->uc_compcode != ROC_IE_ON_UCC_SUCCESS)) { + ret = res->uc_compcode; + switch (ret) { + case ROC_IE_ON_AUTH_UNSUPPORTED: + plt_err("Invalid auth type"); + break; + case ROC_IE_ON_ENCRYPT_UNSUPPORTED: + plt_err("Invalid encrypt type"); + break; + default: + plt_err("Request failed with unknown microcode " + "completion code : 0x%x", + ret); + } + ret = -ENOTSUP; + } + +mempool_put: + rte_mempool_put(qp->meta_info.pool, mdata); + return ret; +} + +static inline int +ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_sa_ctl *ctl) +{ + struct rte_crypto_sym_xform *cipher_xform, *auth_xform; + int aes_key_len; + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { + ctl->direction = ROC_IE_SA_DIR_OUTBOUND; + cipher_xform = crypto_xform; + auth_xform = crypto_xform->next; + } else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { + ctl->direction = ROC_IE_SA_DIR_INBOUND; + auth_xform = crypto_xform; + cipher_xform = crypto_xform->next; + } else { + return -EINVAL; + } + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { + if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4; + else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) + ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6; + else + return -EINVAL; + } + + ctl->inner_ip_ver = ctl->outer_ip_ver; + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) + ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT; + else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) + ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL; + else + return -EINVAL; + + if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) + ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH; + else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) + ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP; + else + return -EINVAL; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) { + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM; + aes_key_len = crypto_xform->aead.key.length; + } else { + return -ENOTSUP; + } + } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) { + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC; + aes_key_len = cipher_xform->cipher.key.length; + } else { + return -ENOTSUP; + } + + switch (aes_key_len) { + case 16: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; + break; + case 24: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; + break; + case 32: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; + break; + default: + return -EINVAL; + } + + if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { + switch (auth_xform->auth.algo) { + case RTE_CRYPTO_AUTH_NULL: + ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL; + break; + case RTE_CRYPTO_AUTH_MD5_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5; + break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1; + break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224; + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256; + break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384; + break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512; + break; + case RTE_CRYPTO_AUTH_AES_GMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC; + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128; + break; + default: + return -ENOTSUP; + } + } + + if (ipsec->options.esn) + ctl->esn_en = 1; + + if (ipsec->options.udp_encap == 1) + ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP; + + ctl->spi = rte_cpu_to_be_32(ipsec->spi); + + rte_io_wmb(); + + ctl->valid = 1; + + return 0; +} + +static inline int +fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct roc_ie_on_common_sa *common_sa) +{ + struct rte_crypto_sym_xform *cipher_xform; + const uint8_t *cipher_key; + int cipher_key_len = 0; + int ret; + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + cipher_xform = crypto_xform->next; + else + cipher_xform = crypto_xform; + + ret = ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl); + if (ret) + return ret; + + if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) + memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4); + cipher_key = crypto_xform->aead.key.data; + cipher_key_len = crypto_xform->aead.key.length; + } else { + cipher_key = cipher_xform->cipher.key.data; + cipher_key_len = cipher_xform->cipher.key.length; + } + + if (cipher_key_len != 0) + memcpy(common_sa->cipher_key, cipher_key, cipher_key_len); + else + return -EINVAL; + + return 0; +} + +static int +cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp, + struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct rte_security_session *sec_sess) +{ + RTE_SET_USED(qp); + RTE_SET_USED(ipsec); + RTE_SET_USED(crypto_xform); + RTE_SET_USED(sec_sess); + + return 0; +} + +static int +cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp, + struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *crypto_xform, + struct rte_security_session *sec_sess) +{ + RTE_SET_USED(qp); + RTE_SET_USED(ipsec); + RTE_SET_USED(crypto_xform); + RTE_SET_USED(sec_sess); + + return 0; +} + +static inline int +cn9k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec) +{ + RTE_SET_USED(ipsec); + + return 0; +} + +static int +cn9k_ipsec_session_create(void *dev, + struct rte_security_ipsec_xform *ipsec_xform, + struct rte_crypto_sym_xform *crypto_xform, + struct rte_security_session *sess) +{ + struct rte_cryptodev *crypto_dev = dev; + struct cnxk_cpt_qp *qp; + int ret; + + qp = crypto_dev->data->queue_pairs[0]; + if (qp == NULL) { + plt_err("CPT queue pairs need to be setup for creating security" + " session"); + return -EPERM; + } + + ret = cnxk_ipsec_xform_verify(ipsec_xform, crypto_xform); + if (ret) + return ret; + + ret = cn9k_ipsec_xform_verify(ipsec_xform); + if (ret) + return ret; + + if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + return cn9k_ipsec_inb_sa_create(qp, ipsec_xform, crypto_xform, + sess); + else + return cn9k_ipsec_outb_sa_create(qp, ipsec_xform, crypto_xform, + sess); +} + +static int +cn9k_sec_session_create(void *device, struct rte_security_session_conf *conf, + struct rte_security_session *sess, + struct rte_mempool *mempool) +{ + struct cn9k_sec_session *priv; + int ret; + + if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) + return -EINVAL; + + if (rte_mempool_get(mempool, (void **)&priv)) { + plt_err("Could not allocate security session private data"); + return -ENOMEM; + } + + memset(priv, 0, sizeof(*priv)); + + set_sec_session_private_data(sess, priv); + + if (conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) { + ret = -ENOTSUP; + goto mempool_put; + } + + ret = cn9k_ipsec_session_create(device, &conf->ipsec, + conf->crypto_xform, sess); + if (ret) + goto mempool_put; + + return 0; + +mempool_put: + rte_mempool_put(mempool, priv); + set_sec_session_private_data(sess, NULL); + return ret; +} + +static int +cn9k_sec_session_destroy(void *device __rte_unused, + struct rte_security_session *sess) +{ + struct roc_ie_on_outb_sa *out_sa; + struct cn9k_sec_session *priv; + struct rte_mempool *sess_mp; + struct roc_ie_on_sa_ctl *ctl; + struct cn9k_ipsec_sa *sa; + + priv = get_sec_session_private_data(sess); + if (priv == NULL) + return 0; + + sa = &priv->sa; + out_sa = &sa->out_sa; + + ctl = &out_sa->common_sa.ctl; + ctl->valid = 0; + + rte_io_wmb(); + + sess_mp = rte_mempool_from_obj(priv); + + memset(priv, 0, sizeof(*priv)); + + set_sec_session_private_data(sess, NULL); + rte_mempool_put(sess_mp, priv); + + return 0; +} + +static unsigned int +cn9k_sec_session_get_size(void *device __rte_unused) +{ + return sizeof(struct cn9k_sec_session); +} + +/* Update platform specific security ops */ +void +cn9k_sec_ops_override(void) +{ + /* Update platform specific ops */ + cnxk_sec_ops.session_create = cn9k_sec_session_create; + cnxk_sec_ops.session_destroy = cn9k_sec_session_destroy; + cnxk_sec_ops.session_get_size = cn9k_sec_session_get_size; +} diff --git a/drivers/crypto/cnxk/cn9k_ipsec.h b/drivers/crypto/cnxk/cn9k_ipsec.h new file mode 100644 index 0000000000..0fe78df49b --- /dev/null +++ b/drivers/crypto/cnxk/cn9k_ipsec.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef __CN9K_IPSEC_H__ +#define __CN9K_IPSEC_H__ + +#include "cnxk_ipsec.h" + +struct cn9k_ipsec_sa { + union { + /** Inbound SA */ + struct roc_ie_on_inb_sa in_sa; + /** Outbound SA */ + struct roc_ie_on_outb_sa out_sa; + }; + /** IPsec SA direction */ + enum rte_security_ipsec_sa_direction dir; + /** Pre-populated CPT inst words */ + struct cnxk_cpt_inst_tmpl inst; +}; + +struct cn9k_sec_session { + struct cn9k_ipsec_sa sa; +} __rte_cache_aligned; + +void cn9k_sec_ops_override(void); + +#endif /* __CN9K_IPSEC_H__ */ diff --git a/drivers/crypto/cnxk/meson.build b/drivers/crypto/cnxk/meson.build index e076783629..e40d132f80 100644 --- a/drivers/crypto/cnxk/meson.build +++ b/drivers/crypto/cnxk/meson.build @@ -11,6 +11,7 @@ endif sources = files( 'cn9k_cryptodev.c', 'cn9k_cryptodev_ops.c', + 'cn9k_ipsec.c', 'cn10k_cryptodev.c', 'cn10k_cryptodev_ops.c', 'cn10k_ipsec.c',