From 670af27b22278dcb6a5c1d915b24102aa8973a1d Mon Sep 17 00:00:00 2001 From: Tejasree Kondoj Date: Mon, 31 Jan 2022 18:00:26 +0530 Subject: [PATCH] crypto/cnxk: support ESN and anti-replay Added lookaside IPsec ESN and anti-replay support through security session update. Signed-off-by: Tejasree Kondoj Acked-by: Akhil Goyal --- doc/guides/cryptodevs/cnxk.rst | 2 + doc/guides/rel_notes/release_22_03.rst | 1 + drivers/common/cnxk/cnxk_security.c | 3 ++ drivers/common/cnxk/cnxk_security_ar.h | 2 +- drivers/common/cnxk/roc_ie_on.h | 2 + drivers/crypto/cnxk/cn10k_ipsec.c | 36 +++++++++++++++- drivers/crypto/cnxk/cn9k_ipsec.c | 43 ++++++++++++++++++- drivers/crypto/cnxk/cn9k_ipsec_la_ops.h | 16 ++++++- .../crypto/cnxk/cnxk_cryptodev_capabilities.c | 4 ++ 9 files changed, 103 insertions(+), 6 deletions(-) diff --git a/doc/guides/cryptodevs/cnxk.rst b/doc/guides/cryptodevs/cnxk.rst index 3c585175e3..46431dd755 100644 --- a/doc/guides/cryptodevs/cnxk.rst +++ b/doc/guides/cryptodevs/cnxk.rst @@ -279,6 +279,8 @@ CN10XX Features supported * IPv4 * ESP +* ESN +* Anti-replay * Tunnel mode * Transport mode * UDP Encapsulation diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst index 93b6de5965..721f1894b4 100644 --- a/doc/guides/rel_notes/release_22_03.rst +++ b/doc/guides/rel_notes/release_22_03.rst @@ -130,6 +130,7 @@ New Features * Added NULL cipher support in lookaside protocol (IPsec) for CN9K & CN10K. * Added AES-XCBC support in lookaside protocol (IPsec) for CN9K & CN10K. * Added AES-CMAC support in CN9K & CN10K. + * Added ESN and anti-replay support in lookaside protocol (IPsec) for CN10K. * **Added support for CPM2.0b devices to Intel QuickAssist Technology PMD.** diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c index bd35f1c336..6ddf589385 100644 --- a/drivers/common/cnxk/cnxk_security.c +++ b/drivers/common/cnxk/cnxk_security.c @@ -492,6 +492,9 @@ skip_tunnel_info: /* ESN */ sa->w0.s.esn_en = !!ipsec_xfrm->options.esn; + if (ipsec_xfrm->esn.value) + sa->ctx.esn_val = ipsec_xfrm->esn.value - 1; + if (ipsec_xfrm->options.udp_encap) { sa->w10.s.udp_src_port = 4500; sa->w10.s.udp_dst_port = 4500; diff --git a/drivers/common/cnxk/cnxk_security_ar.h b/drivers/common/cnxk/cnxk_security_ar.h index 3ec4c296c2..deb38db0d0 100644 --- a/drivers/common/cnxk/cnxk_security_ar.h +++ b/drivers/common/cnxk/cnxk_security_ar.h @@ -13,7 +13,7 @@ /* u64 array size to fit anti replay window bits */ #define AR_WIN_ARR_SZ \ - (PLT_ALIGN_CEIL(CNXK_ON_AR_WIN_SIZE_MAX, BITS_PER_LONG_LONG) / \ + (PLT_ALIGN_CEIL(CNXK_ON_AR_WIN_SIZE_MAX + 1, BITS_PER_LONG_LONG) / \ BITS_PER_LONG_LONG) #define WORD_SHIFT 6 diff --git a/drivers/common/cnxk/roc_ie_on.h b/drivers/common/cnxk/roc_ie_on.h index 8430240592..7dd7b6595f 100644 --- a/drivers/common/cnxk/roc_ie_on.h +++ b/drivers/common/cnxk/roc_ie_on.h @@ -18,6 +18,8 @@ enum roc_ie_on_ucc_ipsec { ROC_IE_ON_UCC_SUCCESS = 0, ROC_IE_ON_AUTH_UNSUPPORTED = 0xB0, ROC_IE_ON_ENCRYPT_UNSUPPORTED = 0xB1, + /* Software defined completion code for anti-replay failed packets */ + ROC_IE_ON_SWCC_ANTI_REPLAY = 0xE7, }; /* Helper macros */ diff --git a/drivers/crypto/cnxk/cn10k_ipsec.c b/drivers/crypto/cnxk/cn10k_ipsec.c index 7f4ccaff99..c95c57a84d 100644 --- a/drivers/crypto/cnxk/cn10k_ipsec.c +++ b/drivers/crypto/cnxk/cn10k_ipsec.c @@ -239,7 +239,7 @@ cn10k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf, } /* Trigger CTX flush so that data is written back to DRAM */ - roc_cpt_lf_ctx_flush(lf, in_sa, false); + roc_cpt_lf_ctx_flush(lf, in_sa, true); plt_atomic_thread_fence(__ATOMIC_SEQ_CST); @@ -410,6 +410,39 @@ cn10k_sec_session_stats_get(void *device, struct rte_security_session *sess, return 0; } +static int +cn10k_sec_session_update(void *device, struct rte_security_session *sess, + struct rte_security_session_conf *conf) +{ + struct rte_cryptodev *crypto_dev = device; + struct cn10k_sec_session *priv; + struct roc_cpt *roc_cpt; + struct cnxk_cpt_qp *qp; + struct cnxk_cpt_vf *vf; + int ret; + + priv = get_sec_session_private_data(sess); + if (priv == NULL) + return -EINVAL; + + qp = crypto_dev->data->queue_pairs[0]; + if (qp == NULL) + return -EINVAL; + + if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + return -ENOTSUP; + + ret = cnxk_ipsec_xform_verify(&conf->ipsec, conf->crypto_xform); + if (ret) + return ret; + + vf = crypto_dev->data->dev_private; + roc_cpt = &vf->cpt; + + return cn10k_ipsec_outb_sa_create(roc_cpt, &qp->lf, &conf->ipsec, + conf->crypto_xform, sess); +} + /* Update platform specific security ops */ void cn10k_sec_ops_override(void) @@ -419,4 +452,5 @@ cn10k_sec_ops_override(void) cnxk_sec_ops.session_destroy = cn10k_sec_session_destroy; cnxk_sec_ops.session_get_size = cn10k_sec_session_get_size; cnxk_sec_ops.session_stats_get = cn10k_sec_session_stats_get; + cnxk_sec_ops.session_update = cn10k_sec_session_update; } diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c index 672b65a5d2..737bafd665 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec.c +++ b/drivers/crypto/cnxk/cn9k_ipsec.c @@ -289,6 +289,11 @@ fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec, if (cipher_key_len != 0) memcpy(common_sa->cipher_key, cipher_key, cipher_key_len); + if (ipsec->esn.value) { + common_sa->esn_low = ipsec->esn.low; + common_sa->esn_hi = ipsec->esn.hi; + } + return 0; } @@ -330,6 +335,9 @@ cn9k_ipsec_outb_sa_create(struct cnxk_cpt_qp *qp, sa->seq_lo = 1; sa->seq_hi = 0; + if (ipsec->esn.value) + sa->esn = ipsec->esn.value; + ret = fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa); if (ret) return ret; @@ -595,8 +603,8 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp, sa->ar.wint = sa->replay_win_sz; sa->ar.base = sa->replay_win_sz; - in_sa->common_sa.esn_low = 0; - in_sa->common_sa.esn_hi = 0; + in_sa->common_sa.esn_low = sa->seq_lo; + in_sa->common_sa.esn_hi = sa->seq_hi; } return cn9k_cpt_enq_sa_write( @@ -772,6 +780,36 @@ cn9k_sec_session_get_size(void *device __rte_unused) return sizeof(struct cn9k_sec_session); } +static int +cn9k_sec_session_update(void *device, struct rte_security_session *sec_sess, + struct rte_security_session_conf *conf) +{ + struct rte_cryptodev *crypto_dev = device; + 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 updating security" + " session"); + return -EPERM; + } + + if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + return -ENOTSUP; + + ret = cnxk_ipsec_xform_verify(&conf->ipsec, conf->crypto_xform); + if (ret) + return ret; + + ret = cn9k_ipsec_xform_verify(&conf->ipsec, conf->crypto_xform); + if (ret) + return ret; + + return cn9k_ipsec_outb_sa_create(qp, &conf->ipsec, conf->crypto_xform, + sec_sess); +} + /* Update platform specific security ops */ void cn9k_sec_ops_override(void) @@ -780,4 +818,5 @@ cn9k_sec_ops_override(void) 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; + cnxk_sec_ops.session_update = cn9k_sec_session_update; } diff --git a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h index 9a1e217042..df89aaca4e 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h +++ b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h @@ -140,8 +140,20 @@ process_inb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa, if (sa->replay_win_sz) { ret = ipsec_antireplay_check(sa, sa->replay_win_sz, m_src); if (unlikely(ret)) { - plt_dp_err("Anti replay check failed"); - return ret; + /* Use PASSTHROUGH op for failed antireplay packet */ + inst->w4.u64 = 0; + inst->w4.s.opcode_major = ROC_SE_MAJOR_OP_MISC; + inst->w4.s.opcode_minor = + ROC_SE_MISC_MINOR_OP_PASSTHROUGH; + inst->w4.s.param1 = 1; + /* Send out completion code only */ + inst->w4.s.param2 = + (ROC_IE_ON_SWCC_ANTI_REPLAY << 8) | 0x1; + inst->w4.s.dlen = 1; + inst->dptr = rte_pktmbuf_iova(m_src); + inst->rptr = inst->dptr; + inst->w7.u64 = sa->inst.w7; + return 0; } } diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c index f8c007e320..04402a4b46 100644 --- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c +++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c @@ -9,6 +9,7 @@ #include "cnxk_cryptodev.h" #include "cnxk_cryptodev_capabilities.h" +#include "cnxk_security_ar.h" #define CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, name) \ do { \ @@ -1161,6 +1162,8 @@ cn10k_sec_caps_update(struct rte_security_capability *sec_cap) sec_cap->ipsec.options.ip_csum_enable = 1; sec_cap->ipsec.options.l4_csum_enable = 1; sec_cap->ipsec.options.stats = 1; + sec_cap->ipsec.options.esn = 1; + sec_cap->ipsec.replay_win_sz_max = ROC_AR_WIN_SIZE_MAX; } static void @@ -1171,6 +1174,7 @@ cn9k_sec_caps_update(struct rte_security_capability *sec_cap) sec_cap->ipsec.options.iv_gen_disable = 1; #endif } + sec_cap->ipsec.replay_win_sz_max = CNXK_ON_AR_WIN_SIZE_MAX; } void -- 2.39.5