From patchwork Fri Sep 18 11:09:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Dwivedi X-Patchwork-Id: 78090 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1B164A04C8; Fri, 18 Sep 2020 13:11:17 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EDBAB1D9C8; Fri, 18 Sep 2020 13:11:16 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id 22A481D9C6 for ; Fri, 18 Sep 2020 13:11:15 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 08IB5ZAF022685; Fri, 18 Sep 2020 04:11:14 -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=bYQdmYxGsH7Z3LeXrasHxi5rApbXLPvqTAjrR/3qKzU=; b=HwgsrXkgVJfo3KN41ddzXpIChRrjjhLeJwg5QhOknfzKzwOEdBwFpyLsX3KD77eWUNnQ 44E0tXd1DP5usm293iDABMN2FBfAic3kt+K6l2qVIlskjfpeFE3ojRga+2YLLi3E9y3e bDsRVRIq7ubDellsw9QEbX/gC4kIcs2GC89ChnbNBhdjqdQ/sNv6K2eu5TXkiA+sTaIq RKeosijOzrrWVTKf/tQHIb8l/ae5GzsyahohEk92zebZW6AQafpRHsa3cBMtri1fDlw0 BlKzWIFarbwbr4QZzLAXGHd94LopLUkGjzBJFOLZievNgVS7+g13hmsrCjfluJna3lqw nA== Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0b-0016f401.pphosted.com with ESMTP id 33m73p43aa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 18 Sep 2020 04:11:14 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 18 Sep 2020 04:11:12 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 18 Sep 2020 04:11:11 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 18 Sep 2020 04:11:11 -0700 Received: from hyd1349.t110.caveonetworks.com (unknown [10.29.45.13]) by maili.marvell.com (Postfix) with ESMTP id ED1B73F703F; Fri, 18 Sep 2020 04:11:08 -0700 (PDT) From: Ankur Dwivedi To: CC: , , , , Ankur Dwivedi Date: Fri, 18 Sep 2020 16:39:42 +0530 Message-ID: <20200918110943.14553-2-adwivedi@marvell.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200918110943.14553-1-adwivedi@marvell.com> References: <20200903111836.6864-1-adwivedi@marvell.com> <20200918110943.14553-1-adwivedi@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687 definitions=2020-09-18_14:2020-09-16, 2020-09-18 signatures=0 Subject: [dpdk-dev] [PATCH v2 1/2] net/octeontx2: add anti replay support in security session X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Initialize the inbound session for anti replay. The replay window is allocated during session create and freed in session destroy. Signed-off-by: Ankur Dwivedi --- drivers/crypto/octeontx2/otx2_ipsec_fp.h | 29 ++++++++++++++-- drivers/crypto/octeontx2/otx2_security.h | 3 ++ drivers/net/octeontx2/otx2_ethdev_sec.c | 42 ++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/octeontx2/otx2_ipsec_fp.h b/drivers/crypto/octeontx2/otx2_ipsec_fp.h index 52b3b41e2..a33041d77 100644 --- a/drivers/crypto/octeontx2/otx2_ipsec_fp.h +++ b/drivers/crypto/octeontx2/otx2_ipsec_fp.h @@ -8,6 +8,17 @@ #include #include +/* Macros for anti replay and ESN */ +#define OTX2_IPSEC_MAX_REPLAY_WIN_SZ 1024 +#define OTX2_IPSEC_SAINDEX_SZ 4 +#define OTX2_IPSEC_SEQNO_LO 4 + +#define OTX2_IPSEC_SEQNO_LO_INDEX (RTE_ETHER_HDR_LEN + \ + OTX2_IPSEC_SAINDEX_SZ) + +#define OTX2_IPSEC_SEQNO_HI_INDEX (OTX2_IPSEC_SEQNO_LO_INDEX + \ + OTX2_IPSEC_SEQNO_LO) + enum { OTX2_IPSEC_FP_SA_DIRECTION_INBOUND = 0, OTX2_IPSEC_FP_SA_DIRECTION_OUTBOUND = 1, @@ -105,6 +116,14 @@ struct otx2_ipsec_fp_out_sa { uint8_t hmac_key[48]; }; +struct otx2_ipsec_replay { + rte_spinlock_t lock; + uint32_t winb; + uint32_t wint; + uint64_t base; /**< base of the anti-replay window */ + uint64_t window[17]; /**< anti-replay window */ +}; + struct otx2_ipsec_fp_in_sa { /* w0 */ struct otx2_ipsec_fp_sa_ctl ctl; @@ -114,8 +133,8 @@ struct otx2_ipsec_fp_in_sa { uint32_t unused; /* w2 */ - uint32_t esn_low; uint32_t esn_hi; + uint32_t esn_low; /* w3-w6 */ uint8_t cipher_key[32]; @@ -128,9 +147,13 @@ struct otx2_ipsec_fp_in_sa { void *userdata; uint64_t udata64; }; + union { + struct otx2_ipsec_replay *replay; + uint64_t replay64; + }; + uint32_t replay_win_sz; - uint64_t reserved1; - uint64_t reserved2; + uint32_t reserved1; }; static inline int diff --git a/drivers/crypto/octeontx2/otx2_security.h b/drivers/crypto/octeontx2/otx2_security.h index 086b50604..33d3b1515 100644 --- a/drivers/crypto/octeontx2/otx2_security.h +++ b/drivers/crypto/octeontx2/otx2_security.h @@ -5,6 +5,8 @@ #ifndef __OTX2_SECURITY_H__ #define __OTX2_SECURITY_H__ +#include + #include "otx2_cryptodev_sec.h" #include "otx2_ethdev_sec.h" @@ -20,6 +22,7 @@ union otx2_sec_session_ipsec { struct otx2_sec_session_ipsec_ip ip; struct otx2_sec_session_ipsec_lp lp; + enum rte_security_ipsec_sa_direction dir; }; struct otx2_sec_session { diff --git a/drivers/net/octeontx2/otx2_ethdev_sec.c b/drivers/net/octeontx2/otx2_ethdev_sec.c index a155594e2..af91e30f4 100644 --- a/drivers/net/octeontx2/otx2_ethdev_sec.c +++ b/drivers/net/octeontx2/otx2_ethdev_sec.c @@ -360,6 +360,7 @@ eth_sec_ipsec_out_sess_create(struct rte_eth_dev *eth_dev, struct otx2_cpt_qp *qp; priv = get_sec_session_private_data(sec_sess); + priv->ipsec.dir = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; sess = &priv->ipsec.ip; sa = &sess->out_sa; @@ -482,6 +483,7 @@ eth_sec_ipsec_in_sess_create(struct rte_eth_dev *eth_dev, ctl = &sa->ctl; priv = get_sec_session_private_data(sec_sess); + priv->ipsec.dir = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; sess = &priv->ipsec.ip; if (ctl->valid) { @@ -519,6 +521,8 @@ eth_sec_ipsec_in_sess_create(struct rte_eth_dev *eth_dev, sa->userdata = priv->userdata; + sa->replay_win_sz = ipsec->replay_win_sz; + if (lookup_mem_sa_index_update(eth_dev, ipsec->spi, sa)) return -EINVAL; @@ -533,7 +537,32 @@ eth_sec_ipsec_in_sess_create(struct rte_eth_dev *eth_dev, return ret; ret = hmac_init(ctl, qp, auth_key, auth_key_len, sa->hmac_key); otx2_sec_idev_tx_cpt_qp_put(qp); + if (ret) + return ret; } + + if (sa->replay_win_sz) { + if (sa->replay_win_sz > OTX2_IPSEC_MAX_REPLAY_WIN_SZ) { + otx2_err("Replay window size is not supported"); + return -ENOTSUP; + } + sa->replay = rte_zmalloc(NULL, sizeof(struct otx2_ipsec_replay), + 0); + if (sa->replay == NULL) + return -ENOMEM; + + rte_spinlock_init(&sa->replay->lock); + /* + * Set window bottom to 1, base and top to size of + * window + */ + sa->replay->winb = 1; + sa->replay->wint = sa->replay_win_sz; + sa->replay->base = sa->replay_win_sz; + sa->esn_low = 0; + sa->esn_hi = 0; + } + return ret; } @@ -600,6 +629,15 @@ otx2_eth_sec_session_create(void *device, return ret; } +static void +otx2_eth_sec_free_anti_replay(struct otx2_ipsec_fp_in_sa *sa) +{ + if (sa != NULL) { + if (sa->replay_win_sz && sa->replay) + rte_free(sa->replay); + } +} + static int otx2_eth_sec_session_destroy(void *device __rte_unused, struct rte_security_session *sess) @@ -615,6 +653,10 @@ otx2_eth_sec_session_destroy(void *device __rte_unused, sess_ip = &priv->ipsec.ip; + /* Release the anti replay window */ + if (priv->ipsec.dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) + otx2_eth_sec_free_anti_replay(sess_ip->in_sa); + /* Release CPT LF used for this session */ if (sess_ip->qp != NULL) { ret = otx2_sec_idev_tx_cpt_qp_put(sess_ip->qp); From patchwork Fri Sep 18 11:09:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Dwivedi X-Patchwork-Id: 78091 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A137CA04C8; Fri, 18 Sep 2020 13:11:27 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7EFEF1D9C6; Fri, 18 Sep 2020 13:11:27 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id B81B81D973 for ; Fri, 18 Sep 2020 13:11:25 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 08IB5bnT022752; Fri, 18 Sep 2020 04:11:25 -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=jAm7s7pMlgsa1R7IyAcEGse0KRK0KaKm9AWnudRHzpE=; b=SkIjMSlIebgTxSRbVOjxkH17AuNQm156RPim9/jVLJHBrPlOuY9No8gsEa87Np1xJj3F jdAJ7qpblSx8Egvq3OOuLBr8UEqs7SUDHQCyiR41lpN7/RlvzDpTAc4JWtggQqAC2/WB OHi1AZyHlJQ8SjT3BAvu4qeAV5zdKrKjJ0YM057yKbkQcbaUzsRkFBj9lFepmhSCDsxT 10JZEJCZ07XIRGR1sPW8v0euLa4KMBWVflYesBCpzzvjtPvhRRQSBzQL27CCpIWQrILB x5QNvisiZ6tYkUU+PFPt0dXCuYCZJRkCa6PwIKMZ9oD9bcMXpA0ZhPKqsmzdj2ydg7j/ 4g== Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0b-0016f401.pphosted.com with ESMTP id 33m73p43ay-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 18 Sep 2020 04:11:25 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 18 Sep 2020 04:11:21 -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.2 via Frontend Transport; Fri, 18 Sep 2020 04:11:21 -0700 Received: from hyd1349.t110.caveonetworks.com (unknown [10.29.45.13]) by maili.marvell.com (Postfix) with ESMTP id BAB593F704B; Fri, 18 Sep 2020 04:11:16 -0700 (PDT) From: Ankur Dwivedi To: CC: , , , , Ankur Dwivedi Date: Fri, 18 Sep 2020 16:39:43 +0530 Message-ID: <20200918110943.14553-3-adwivedi@marvell.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200918110943.14553-1-adwivedi@marvell.com> References: <20200903111836.6864-1-adwivedi@marvell.com> <20200918110943.14553-1-adwivedi@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687 definitions=2020-09-18_14:2020-09-16, 2020-09-18 signatures=0 Subject: [dpdk-dev] [PATCH v2 2/2] net/octeontx2: add replay check for inline inbound packets X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" The function handling anti replay is added. If replay window is enabled the rx packets will be validated against the window. The rx offload fails in case of error. Signed-off-by: Ankur Dwivedi --- .../crypto/octeontx2/otx2_ipsec_anti_replay.h | 208 ++++++++++++++++++ drivers/net/octeontx2/otx2_rx.h | 7 + 2 files changed, 215 insertions(+) create mode 100644 drivers/crypto/octeontx2/otx2_ipsec_anti_replay.h diff --git a/drivers/crypto/octeontx2/otx2_ipsec_anti_replay.h b/drivers/crypto/octeontx2/otx2_ipsec_anti_replay.h new file mode 100644 index 000000000..858ce5b15 --- /dev/null +++ b/drivers/crypto/octeontx2/otx2_ipsec_anti_replay.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C) 2020 Marvell International Ltd. + */ + +#ifndef __OTX2_IPSEC_ANTI_REPLAY_H__ +#define __OTX2_IPSEC_ANTI_REPLAY_H__ + +#include + +#include "otx2_ipsec_fp.h" + +#define WORD_SHIFT 6 +#define WORD_SIZE (1 << WORD_SHIFT) +#define WORD_MASK (WORD_SIZE - 1) + +#define IPSEC_ANTI_REPLAY_FAILED (-1) + +static inline int +anti_replay_check(uint64_t seq, struct otx2_ipsec_fp_in_sa *sa) +{ + struct otx2_ipsec_replay *replay = sa->replay; + uint64_t *window = &replay->window[0]; + uint64_t winsz = sa->replay_win_sz; + uint64_t ex_winsz = winsz + WORD_SIZE; + uint64_t winwords = ex_winsz >> WORD_SHIFT; + uint64_t base = replay->base; + uint32_t winb = replay->winb; + uint32_t wint = replay->wint; + uint64_t seqword, shiftwords; + uint64_t bit_pos; + uint64_t shift; + uint64_t *wptr; + uint64_t tmp; + + if (winsz > 64) + goto slow_shift; + /* Check if the seq is the biggest one yet */ + if (likely(seq > base)) { + shift = seq - base; + if (shift < winsz) { /* In window */ + /* + * If more than 64-bit anti-replay window, + * use slow shift routine + */ + wptr = window + (shift >> WORD_SHIFT); + *wptr <<= shift; + *wptr |= 1ull; + } else { + /* No special handling of window size > 64 */ + wptr = window + ((winsz - 1) >> WORD_SHIFT); + /* + * Zero out the whole window (especially for + * bigger than 64b window) till the last 64b word + * as the incoming sequence number minus + * base sequence is more than the window size. + */ + while (window != wptr) + *window++ = 0ull; + /* + * Set the last bit (of the window) to 1 + * as that corresponds to the base sequence number. + * Now any incoming sequence number which is + * (base - window size - 1) will pass anti-replay check + */ + *wptr = 1ull; + } + /* + * Set the base to incoming sequence number as + * that is the biggest sequence number seen yet + */ + replay->base = seq; + return 0; + } + + bit_pos = base - seq; + + /* If seq falls behind the window, return failure */ + if (bit_pos >= winsz) + return IPSEC_ANTI_REPLAY_FAILED; + + /* seq is within anti-replay window */ + wptr = window + ((winsz - bit_pos - 1) >> WORD_SHIFT); + bit_pos &= WORD_MASK; + + /* Check if this is a replayed packet */ + if (*wptr & ((1ull) << bit_pos)) + return IPSEC_ANTI_REPLAY_FAILED; + + /* mark as seen */ + *wptr |= ((1ull) << bit_pos); + return 0; + +slow_shift: + if (likely(seq > base)) { + uint32_t i; + + shift = seq - base; + if (unlikely(shift >= winsz)) { + /* + * shift is bigger than the window, + * so just zero out everything + */ + for (i = 0; i < winwords; i++) + window[i] = 0; +winupdate: + /* Find out the word */ + seqword = ((seq - 1) % ex_winsz) >> WORD_SHIFT; + + /* Find out the bit in the word */ + bit_pos = (seq - 1) & WORD_MASK; + + /* + * Set the bit corresponding to sequence number + * in window to mark it as received + */ + window[seqword] |= (1ull << (63 - bit_pos)); + + /* wint and winb range from 1 to ex_winsz */ + replay->wint = ((wint + shift - 1) % ex_winsz) + 1; + replay->winb = ((winb + shift - 1) % ex_winsz) + 1; + + replay->base = seq; + return 0; + } + + /* + * New sequence number is bigger than the base but + * it's not bigger than base + window size + */ + + shiftwords = ((wint + shift - 1) >> WORD_SHIFT) - + ((wint - 1) >> WORD_SHIFT); + if (unlikely(shiftwords)) { + tmp = (wint + WORD_SIZE - 1) / WORD_SIZE; + for (i = 0; i < shiftwords; i++) { + tmp %= winwords; + window[tmp++] = 0; + } + } + + goto winupdate; + } + + /* Sequence number is before the window */ + if (unlikely((seq + winsz) <= base)) + return IPSEC_ANTI_REPLAY_FAILED; + + /* Sequence number is within the window */ + + /* Find out the word */ + seqword = ((seq - 1) % ex_winsz) >> WORD_SHIFT; + + /* Find out the bit in the word */ + bit_pos = (seq - 1) & WORD_MASK; + + /* Check if this is a replayed packet */ + if (window[seqword] & (1ull << (63 - bit_pos))) + return IPSEC_ANTI_REPLAY_FAILED; + + /* + * Set the bit corresponding to sequence number + * in window to mark it as received + */ + window[seqword] |= (1ull << (63 - bit_pos)); + + return 0; +} + +static int +cpt_ipsec_antireplay_check(struct otx2_ipsec_fp_in_sa *sa, char *data) +{ + uint64_t seq_in_sa; + uint32_t seqh = 0; + uint32_t seql; + uint64_t seq; + uint8_t esn; + int ret; + + esn = sa->ctl.esn_en; + seql = rte_be_to_cpu_32(*((uint32_t *)(data + + OTX2_IPSEC_SEQNO_LO_INDEX))); + + if (!esn) + seq = (uint64_t)seql; + else { + seqh = rte_be_to_cpu_32(*((uint32_t *)(data + + OTX2_IPSEC_SEQNO_HI_INDEX))); + seq = ((uint64_t)seqh << 32) | seql; + } + + if (unlikely(seq == 0)) + return IPSEC_ANTI_REPLAY_FAILED; + + rte_spinlock_lock(&sa->replay->lock); + ret = anti_replay_check(seq, sa); + if (esn && (ret == 0)) { + seq_in_sa = ((uint64_t)rte_be_to_cpu_32(sa->esn_hi) << 32) | + rte_be_to_cpu_32(sa->esn_low); + if (seq > seq_in_sa) { + sa->esn_low = rte_cpu_to_be_32(seql); + sa->esn_hi = rte_cpu_to_be_32(seqh); + } + } + rte_spinlock_unlock(&sa->replay->lock); + + return ret; +} +#endif /* __OTX2_IPSEC_ANTI_REPLAY_H__ */ diff --git a/drivers/net/octeontx2/otx2_rx.h b/drivers/net/octeontx2/otx2_rx.h index d8648b692..f29a0542f 100644 --- a/drivers/net/octeontx2/otx2_rx.h +++ b/drivers/net/octeontx2/otx2_rx.h @@ -9,6 +9,7 @@ #include "otx2_common.h" #include "otx2_ethdev_sec.h" +#include "otx2_ipsec_anti_replay.h" #include "otx2_ipsec_fp.h" /* Default mark value used when none is provided. */ @@ -243,6 +244,12 @@ nix_rx_sec_mbuf_update(const struct nix_cqe_hdr_s *cq, struct rte_mbuf *m, m->udata64 = (uint64_t)sa->userdata; data = rte_pktmbuf_mtod(m, char *); + + if (sa->replay_win_sz) { + if (cpt_ipsec_antireplay_check(sa, data) < 0) + return PKT_RX_SEC_OFFLOAD | PKT_RX_SEC_OFFLOAD_FAILED; + } + memcpy(data + INLINE_INB_RPTR_HDR, data, RTE_ETHER_HDR_LEN); m->data_off += INLINE_INB_RPTR_HDR;