From: Tejasree Kondoj Date: Tue, 29 Jun 2021 07:34:30 +0000 (+0530) Subject: crypto/cnxk: add security session operations X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=bcd59ec6f42f1383216d6f4a4d39284d5aa5937b;p=dpdk.git crypto/cnxk: add security session operations Add security session ops in cn10k crypto PMD to support lookaside protocol offload IPsec. Signed-off-by: Anoob Joseph Signed-off-by: Archana Muniganti Signed-off-by: Srujana Challa Signed-off-by: Tejasree Kondoj Acked-by: Akhil Goyal --- diff --git a/drivers/crypto/cnxk/cn10k_cryptodev.c b/drivers/crypto/cnxk/cn10k_cryptodev.c index ffe654c968..cacf9c2e29 100644 --- a/drivers/crypto/cnxk/cn10k_cryptodev.c +++ b/drivers/crypto/cnxk/cn10k_cryptodev.c @@ -12,6 +12,7 @@ #include "cn10k_cryptodev.h" #include "cn10k_cryptodev_ops.h" +#include "cn10k_ipsec.h" #include "cnxk_cryptodev.h" #include "cnxk_cryptodev_capabilities.h" #include "cnxk_cryptodev_sec.h" @@ -101,6 +102,7 @@ cn10k_cpt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED; cn10k_cpt_set_enqdeq_fns(dev); + cn10k_sec_ops_override(); return 0; diff --git a/drivers/crypto/cnxk/cn10k_ipsec.c b/drivers/crypto/cnxk/cn10k_ipsec.c new file mode 100644 index 0000000000..1d567bf188 --- /dev/null +++ b/drivers/crypto/cnxk/cn10k_ipsec.c @@ -0,0 +1,275 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cnxk_cryptodev.h" +#include "cnxk_ipsec.h" +#include "cnxk_security.h" +#include "cn10k_ipsec.h" + +#include "roc_api.h" + +static int +ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS && + crypto_xfrm->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT) + return -EINVAL; + + if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && + crypto_xfrm->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT) + return -EINVAL; + + if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) { + switch (crypto_xfrm->aead.key.length) { + case ROC_CPT_AES128_KEY_LEN: + case ROC_CPT_AES192_KEY_LEN: + case ROC_CPT_AES256_KEY_LEN: + break; + default: + return -EINVAL; + } + return 0; + } + + return -ENOTSUP; +} + +static int +cn10k_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + if ((ipsec_xfrm->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && + (ipsec_xfrm->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS)) + return -EINVAL; + + if ((ipsec_xfrm->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) && + (ipsec_xfrm->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH)) + return -EINVAL; + + if ((ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) && + (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)) + return -EINVAL; + + if ((ipsec_xfrm->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) && + (ipsec_xfrm->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6)) + return -EINVAL; + + if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) + return ipsec_xform_aead_verify(ipsec_xfrm, crypto_xfrm); + + return -ENOTSUP; +} + +static uint64_t +ipsec_cpt_inst_w7_get(struct roc_cpt *roc_cpt, void *sa) +{ + union cpt_inst_w7 w7; + + w7.u64 = 0; + w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE]; + w7.s.ctx_val = 1; + w7.s.cptr = (uint64_t)sa; + rte_mb(); + + return w7.u64; +} + +static int +cn10k_ipsec_outb_sa_create(struct roc_cpt *roc_cpt, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm, + struct rte_security_session *sec_sess) +{ + struct roc_ot_ipsec_outb_sa *out_sa; + struct cnxk_ipsec_outb_rlens rlens; + struct cn10k_sec_session *sess; + struct cn10k_ipsec_sa *sa; + union cpt_inst_w4 inst_w4; + int ret; + + sess = get_sec_session_private_data(sec_sess); + sa = &sess->sa; + out_sa = &sa->out_sa; + + memset(out_sa, 0, sizeof(struct roc_ot_ipsec_outb_sa)); + + /* Translate security parameters to SA */ + ret = cnxk_ot_ipsec_outb_sa_fill(out_sa, ipsec_xfrm, crypto_xfrm); + if (ret) + return ret; + + sa->inst.w7 = ipsec_cpt_inst_w7_get(roc_cpt, sa); + + /* Get Rlen calculation data */ + ret = cnxk_ipsec_outb_rlens_get(&rlens, ipsec_xfrm, crypto_xfrm); + if (ret) + return ret; + + sa->partial_len = rlens.partial_len; + sa->roundup_byte = rlens.roundup_byte; + sa->roundup_len = rlens.roundup_len; + + /* pre-populate CPT INST word 4 */ + inst_w4.u64 = 0; + inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_OUTBOUND_IPSEC; + inst_w4.s.param1 = 0; + sa->inst.w4 = inst_w4.u64; + + return 0; +} + +static int +cn10k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm, + struct rte_security_session *sec_sess) +{ + struct roc_ot_ipsec_inb_sa *in_sa; + struct cn10k_sec_session *sess; + struct cn10k_ipsec_sa *sa; + union cpt_inst_w4 inst_w4; + int ret; + + sess = get_sec_session_private_data(sec_sess); + sa = &sess->sa; + in_sa = &sa->in_sa; + + /* Translate security parameters to SA */ + ret = cnxk_ot_ipsec_inb_sa_fill(in_sa, ipsec_xfrm, crypto_xfrm); + if (ret) + return ret; + + /* TODO add support for antireplay */ + sa->in_sa.w0.s.ar_win = 0; + + /* TODO add support for udp encap */ + + sa->inst.w7 = ipsec_cpt_inst_w7_get(roc_cpt, sa); + + /* pre-populate CPT INST word 4 */ + inst_w4.u64 = 0; + inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC; + + /* Disable checksum verification for now */ + inst_w4.s.param1 = 7; + sa->inst.w4 = inst_w4.u64; + + return 0; +} + +static int +cn10k_ipsec_session_create(void *dev, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm, + struct rte_security_session *sess) +{ + struct rte_cryptodev *crypto_dev = dev; + struct roc_cpt *roc_cpt; + struct cnxk_cpt_vf *vf; + int ret; + + vf = crypto_dev->data->dev_private; + roc_cpt = &vf->cpt; + + if (crypto_dev->data->queue_pairs[0] == NULL) { + plt_err("Setup cpt queue pair before creating security session"); + return -EPERM; + } + + ret = cn10k_ipsec_xform_verify(ipsec_xfrm, crypto_xfrm); + if (ret) + return ret; + + if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + return cn10k_ipsec_inb_sa_create(roc_cpt, ipsec_xfrm, + crypto_xfrm, sess); + else + return cn10k_ipsec_outb_sa_create(roc_cpt, ipsec_xfrm, + crypto_xfrm, sess); +} + +static int +cn10k_sec_session_create(void *device, struct rte_security_session_conf *conf, + struct rte_security_session *sess, + struct rte_mempool *mempool) +{ + struct cn10k_sec_session *priv; + int ret; + + if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL) + return -EINVAL; + + if (rte_security_dynfield_register() < 0) + return -ENOTSUP; + + if (rte_mempool_get(mempool, (void **)&priv)) { + plt_err("Could not allocate security session private data"); + return -ENOMEM; + } + + set_sec_session_private_data(sess, priv); + + priv->userdata = conf->userdata; + + if (conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) { + ret = -ENOTSUP; + goto mempool_put; + } + ret = cn10k_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 +cn10k_sec_session_destroy(void *device __rte_unused, + struct rte_security_session *sess) +{ + struct cn10k_sec_session *priv; + struct rte_mempool *sess_mp; + + priv = get_sec_session_private_data(sess); + + if (priv == NULL) + return 0; + + sess_mp = rte_mempool_from_obj(priv); + + set_sec_session_private_data(sess, NULL); + rte_mempool_put(sess_mp, priv); + + return 0; +} + +static unsigned int +cn10k_sec_session_get_size(void *device __rte_unused) +{ + return sizeof(struct cn10k_sec_session); +} + +/* Update platform specific security ops */ +void +cn10k_sec_ops_override(void) +{ + /* Update platform specific ops */ + cnxk_sec_ops.session_create = cn10k_sec_session_create; + cnxk_sec_ops.session_destroy = cn10k_sec_session_destroy; + cnxk_sec_ops.session_get_size = cn10k_sec_session_get_size; +} diff --git a/drivers/crypto/cnxk/cn10k_ipsec.h b/drivers/crypto/cnxk/cn10k_ipsec.h new file mode 100644 index 0000000000..668282f7aa --- /dev/null +++ b/drivers/crypto/cnxk/cn10k_ipsec.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef __CN10K_IPSEC_H__ +#define __CN10K_IPSEC_H__ + +#include + +#include "cnxk_ipsec.h" + +#define CN10K_IPSEC_SA_CTX_HDR_SIZE 1 + +struct cn10k_ipsec_sa { + union { + /** Inbound SA */ + struct roc_ot_ipsec_inb_sa in_sa; + /** Outbound SA */ + struct roc_ot_ipsec_outb_sa out_sa; + }; + /** Pre-populated CPT inst words */ + struct cnxk_cpt_inst_tmpl inst; + uint8_t partial_len; + uint8_t roundup_len; + uint8_t roundup_byte; +}; + +struct cn10k_sec_session { + struct cn10k_ipsec_sa sa; + void *userdata; + /**< Userdata registered by the application */ +} __rte_cache_aligned; + +void cn10k_sec_ops_override(void); + +#endif /* __CN10K_IPSEC_H__ */ diff --git a/drivers/crypto/cnxk/cnxk_ipsec.h b/drivers/crypto/cnxk/cnxk_ipsec.h new file mode 100644 index 0000000000..f6897a0e14 --- /dev/null +++ b/drivers/crypto/cnxk/cnxk_ipsec.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ +#ifndef __CNXK_IPSEC_H__ +#define __CNXK_IPSEC_H__ + +#include +#include + +#include "roc_api.h" + +extern struct rte_security_ops cnxk_sec_ops; + +struct cnxk_cpt_inst_tmpl { + uint64_t w2; + uint64_t w4; + uint64_t w7; +}; + +#endif /* __CNXK_IPSEC_H__ */ diff --git a/drivers/crypto/cnxk/meson.build b/drivers/crypto/cnxk/meson.build index a2b461efaa..c56d6cf35d 100644 --- a/drivers/crypto/cnxk/meson.build +++ b/drivers/crypto/cnxk/meson.build @@ -13,6 +13,7 @@ sources = files( 'cn9k_cryptodev_ops.c', 'cn10k_cryptodev.c', 'cn10k_cryptodev_ops.c', + 'cn10k_ipsec.c', 'cnxk_cryptodev.c', 'cnxk_cryptodev_capabilities.c', 'cnxk_cryptodev_ops.c', @@ -20,3 +21,5 @@ sources = files( ) deps += ['bus_pci', 'common_cnxk', 'security'] + +includes += include_directories('../../../lib/net')