All of lore.kernel.org
 help / color / mirror / Atom feed
From: Archana Muniganti <marchana@marvell.com>
To: <gakhil@marvell.com>
Cc: Archana Muniganti <marchana@marvell.com>, <ktejasree@marvell.com>,
	<adwivedi@marvell.com>, <anoobj@marvell.com>,
	<jerinj@marvell.com>, <dev@dpdk.org>,
	Vamsi Attunuru <vattunuru@marvell.com>
Subject: [dpdk-dev] [PATCH 3/8] crypto/cnxk: add cn9k IPsec session related functions
Date: Thu, 2 Sep 2021 19:12:49 +0530	[thread overview]
Message-ID: <20210902134254.28373-4-marchana@marvell.com> (raw)
In-Reply-To: <20210902134254.28373-1-marchana@marvell.com>

Add helper functions useful in implementing IPsec outbound
and inbound session create apis.

Signed-off-by: Archana Muniganti <marchana@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
---
 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 <rte_cryptodev.h>
+#include <rte_security.h>
+#include <rte_security_driver.h>
+
+#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',
-- 
2.22.0


  parent reply	other threads:[~2021-09-02 13:44 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-02 13:42 [dpdk-dev] [PATCH 0/8] add cn9k lookaside IPsec support Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 1/8] crypto/cnxk: add cn9k security ctx Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 2/8] common/cnxk: add cn9k IPsec microcode defines Archana Muniganti
2021-09-02 13:42 ` Archana Muniganti [this message]
2021-09-06 19:39   ` [dpdk-dev] [PATCH 3/8] crypto/cnxk: add cn9k IPsec session related functions Akhil Goyal
2021-09-02 13:42 ` [dpdk-dev] [PATCH 4/8] crypto/cnxk: add cn9k IPsec outbound session create function Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 5/8] crypto/cnxk: add cn9k IPsec inbound " Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 6/8] crypto/cnxk: add cn9k lookaside IPsec datapath Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 7/8] crypto/cnxk: update tailroom requirement Archana Muniganti
2021-09-02 13:42 ` [dpdk-dev] [PATCH 8/8] crypto/cnxk: update feature flag for cn9k lookaside IPsec Archana Muniganti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210902134254.28373-4-marchana@marvell.com \
    --to=marchana@marvell.com \
    --cc=adwivedi@marvell.com \
    --cc=anoobj@marvell.com \
    --cc=dev@dpdk.org \
    --cc=gakhil@marvell.com \
    --cc=jerinj@marvell.com \
    --cc=ktejasree@marvell.com \
    --cc=vattunuru@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.