#include <rte_crypto_sym.h>
#include <rte_security.h>
+/* 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,
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;
uint32_t unused;
/* w2 */
- uint32_t esn_low;
uint32_t esn_hi;
+ uint32_t esn_low;
/* w3-w6 */
uint8_t cipher_key[32];
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
#ifndef __OTX2_SECURITY_H__
#define __OTX2_SECURITY_H__
+#include <rte_security.h>
+
#include "otx2_cryptodev_sec.h"
#include "otx2_ethdev_sec.h"
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 {
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;
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) {
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;
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;
}
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)
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);