From c1eac1b966c2584562eddcba3991188866d69d7e Mon Sep 17 00:00:00 2001 From: Tejasree Kondoj Date: Mon, 20 Jun 2022 12:48:07 +0530 Subject: [PATCH] crypto/cnxk: add anti-replay as per new firmware Adding anti-replay changes as per new FP-FC microcode. Signed-off-by: Tejasree Kondoj Acked-by: Akhil Goyal --- drivers/common/cnxk/roc_ie_on.h | 5 +- drivers/crypto/cnxk/cn9k_cryptodev_ops.c | 63 +++++++++++++---- drivers/crypto/cnxk/cn9k_ipsec.c | 3 + drivers/crypto/cnxk/cn9k_ipsec_la_ops.h | 68 ------------------- .../crypto/cnxk/cnxk_cryptodev_capabilities.c | 1 + drivers/crypto/cnxk/cnxk_cryptodev_ops.h | 2 +- 6 files changed, 58 insertions(+), 84 deletions(-) diff --git a/drivers/common/cnxk/roc_ie_on.h b/drivers/common/cnxk/roc_ie_on.h index 37f711c643..2d93cb609c 100644 --- a/drivers/common/cnxk/roc_ie_on.h +++ b/drivers/common/cnxk/roc_ie_on.h @@ -18,8 +18,6 @@ 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 */ @@ -74,7 +72,8 @@ struct roc_ie_on_outb_hdr { struct roc_ie_on_inb_hdr { uint32_t sa_index; - uint64_t seq; + uint32_t seql; + uint32_t seqh; uint32_t pad; }; diff --git a/drivers/crypto/cnxk/cn9k_cryptodev_ops.c b/drivers/crypto/cnxk/cn9k_cryptodev_ops.c index 8aab9c9f60..06dc18d195 100644 --- a/drivers/crypto/cnxk/cn9k_cryptodev_ops.c +++ b/drivers/crypto/cnxk/cn9k_cryptodev_ops.c @@ -65,8 +65,8 @@ cn9k_cpt_sec_inst_fill(struct rte_crypto_op *op, else { infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_DIR_INBOUND; process_inb_sa(op, sa, inst); - if (unlikely(sa->esn_en)) - infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_INB_ESN; + if (unlikely(sa->replay_win_sz)) + infl_req->op_flags |= CPT_OP_FLAGS_IPSEC_INB_REPLAY; ret = 0; } @@ -501,6 +501,45 @@ cn9k_cpt_crypto_adapter_enqueue(uintptr_t base, struct rte_crypto_op *op) return 1; } +static inline int +ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz, + struct roc_ie_on_inb_hdr *data) +{ + struct roc_ie_on_common_sa *common_sa; + struct roc_ie_on_inb_sa *in_sa; + struct roc_ie_on_sa_ctl *ctl; + uint32_t seql, seqh = 0; + uint64_t seq; + uint8_t esn; + int ret; + + in_sa = &sa->in_sa; + common_sa = &in_sa->common_sa; + ctl = &common_sa->ctl; + + esn = ctl->esn_en; + seql = rte_be_to_cpu_32(data->seql); + + if (!esn) { + seq = (uint64_t)seql; + } else { + seqh = rte_be_to_cpu_32(data->seqh); + seq = ((uint64_t)seqh << 32) | seql; + } + + if (unlikely(seq == 0)) + return IPSEC_ANTI_REPLAY_FAILED; + + ret = cnxk_on_anti_replay_check(seq, &sa->ar, win_sz); + if (esn && !ret) { + common_sa = &sa->in_sa.common_sa; + if (seq > common_sa->seq_t.u64) + common_sa->seq_t.u64 = seq; + } + + return ret; +} + static inline void cn9k_cpt_sec_post_process(struct rte_crypto_op *cop, struct cpt_inflight_req *infl_req) @@ -515,23 +554,23 @@ cn9k_cpt_sec_post_process(struct rte_crypto_op *cop, char *data; if (infl_req->op_flags & CPT_OP_FLAGS_IPSEC_DIR_INBOUND) { - struct roc_ie_on_common_sa *common_sa; data = rte_pktmbuf_mtod(m, char *); - if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_IPSEC_INB_ESN)) { - struct roc_ie_on_inb_hdr *inb_hdr; - uint64_t seq; + if (unlikely(infl_req->op_flags & + CPT_OP_FLAGS_IPSEC_INB_REPLAY)) { + int ret; priv = get_sec_session_private_data( sym_op->sec_session); sa = &priv->sa; - common_sa = &sa->in_sa.common_sa; - inb_hdr = (struct roc_ie_on_inb_hdr *)data; - seq = rte_be_to_cpu_64(inb_hdr->seq); - - if (seq > common_sa->seq_t.u64) - common_sa->seq_t.u64 = seq; + ret = ipsec_antireplay_check( + sa, sa->replay_win_sz, + (struct roc_ie_on_inb_hdr *)data); + if (unlikely(ret)) { + cop->status = RTE_CRYPTO_OP_STATUS_ERROR; + return; + } } ip = (struct rte_ipv4_hdr *)(data + ROC_IE_ON_INB_RPTR_HDR); diff --git a/drivers/crypto/cnxk/cn9k_ipsec.c b/drivers/crypto/cnxk/cn9k_ipsec.c index 49a775eb7f..cb9cf174a4 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec.c +++ b/drivers/crypto/cnxk/cn9k_ipsec.c @@ -156,6 +156,9 @@ cn9k_ipsec_inb_sa_create(struct cnxk_cpt_qp *qp, sa->ar.wint = sa->replay_win_sz; sa->ar.base = sa->replay_win_sz; + sa->seq_lo = ipsec->esn.low; + sa->seq_hi = ipsec->esn.hi; + sa->in_sa.common_sa.seq_t.tl = sa->seq_lo; sa->in_sa.common_sa.seq_t.th = sa->seq_hi; } diff --git a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h index 65dbb629b1..e469596756 100644 --- a/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h +++ b/drivers/crypto/cnxk/cn9k_ipsec_la_ops.h @@ -23,53 +23,6 @@ ipsec_po_out_rlen_get(struct cn9k_ipsec_sa *sa, uint32_t plen) return sa->custom_hdr_len + sa->rlens.partial_len + enc_payload_len; } -static __rte_always_inline int -ipsec_antireplay_check(struct cn9k_ipsec_sa *sa, uint32_t win_sz, - struct rte_mbuf *m) -{ - uint32_t esn_low = 0, esn_hi = 0, seql = 0, seqh = 0; - struct roc_ie_on_common_sa *common_sa; - struct roc_ie_on_inb_sa *in_sa; - struct roc_ie_on_sa_ctl *ctl; - uint64_t seq_in_sa, seq = 0; - struct rte_esp_hdr *esp; - uint8_t esn; - int ret; - - in_sa = &sa->in_sa; - common_sa = &in_sa->common_sa; - ctl = &common_sa->ctl; - - esn = ctl->esn_en; - esn_low = rte_be_to_cpu_32(common_sa->seq_t.tl); - esn_hi = rte_be_to_cpu_32(common_sa->seq_t.th); - - esp = rte_pktmbuf_mtod_offset(m, void *, sizeof(struct rte_ipv4_hdr)); - seql = rte_be_to_cpu_32(esp->seq); - - if (!esn) { - seq = (uint64_t)seql; - } else { - seqh = cnxk_on_anti_replay_get_seqh(win_sz, seql, esn_hi, - esn_low); - seq = ((uint64_t)seqh << 32) | seql; - } - - if (unlikely(seq == 0)) - return IPSEC_ANTI_REPLAY_FAILED; - - ret = cnxk_on_anti_replay_check(seq, &sa->ar, win_sz); - if (esn && !ret) { - seq_in_sa = ((uint64_t)esn_hi << 32) | esn_low; - if (seq > seq_in_sa) { - common_sa->seq_t.tl = rte_cpu_to_be_32(seql); - common_sa->seq_t.th = rte_cpu_to_be_32(seqh); - } - } - - return ret; -} - static __rte_always_inline int process_outb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa, struct cpt_inst_s *inst) @@ -143,27 +96,6 @@ process_inb_sa(struct rte_crypto_op *cop, struct cn9k_ipsec_sa *sa, { struct rte_crypto_sym_op *sym_op = cop->sym; struct rte_mbuf *m_src = sym_op->m_src; - int ret; - - if (sa->replay_win_sz) { - ret = ipsec_antireplay_check(sa, sa->replay_win_sz, m_src); - if (unlikely(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; - } - } /* Prepare CPT instruction */ inst->w4.u64 = sa->inst.w4 | rte_pktmbuf_pkt_len(m_src); diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c index ba9eaf2325..705d67e91f 100644 --- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c +++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c @@ -1269,6 +1269,7 @@ cn9k_sec_caps_update(struct rte_security_capability *sec_cap) #endif } sec_cap->ipsec.replay_win_sz_max = CNXK_ON_AR_WIN_SIZE_MAX; + sec_cap->ipsec.options.esn = 1; } void diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h index 0b41d47de9..ffe4ae19aa 100644 --- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h +++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h @@ -33,7 +33,7 @@ struct cpt_qp_meta_info { #define CPT_OP_FLAGS_METABUF (1 << 1) #define CPT_OP_FLAGS_AUTH_VERIFY (1 << 0) #define CPT_OP_FLAGS_IPSEC_DIR_INBOUND (1 << 2) -#define CPT_OP_FLAGS_IPSEC_INB_ESN (1 << 3) +#define CPT_OP_FLAGS_IPSEC_INB_REPLAY (1 << 3) struct cpt_inflight_req { union cpt_res_s res; -- 2.39.5