crypto/octeontx2: support IPsec ESN and anti-replay
Adding ESN and anti-replay support for lookaside IPsec. Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com> Acked-by: Anoob Joseph <anoobj@marvell.com>
This commit is contained in:
parent
cc882d6469
commit
5be562bc5b
@ -175,4 +175,6 @@ Features supported
|
||||
* IPv6
|
||||
* ESP
|
||||
* Tunnel mode
|
||||
* ESN
|
||||
* Anti-replay
|
||||
* AES-128/192/256-GCM
|
||||
|
@ -76,6 +76,11 @@ New Features
|
||||
|
||||
* Added inner UDP/IPv4 support for VXLAN IPv4 GSO.
|
||||
|
||||
* **Updated the OCTEON TX2 crypto PMD.**
|
||||
|
||||
* Updated the OCTEON TX2 crypto PMD lookaside protocol offload for IPsec with
|
||||
ESN and anti-replay support.
|
||||
|
||||
|
||||
Removed Items
|
||||
-------------
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "otx2_cryptodev_mbox.h"
|
||||
#include "otx2_cryptodev_ops.h"
|
||||
#include "otx2_cryptodev_ops_helper.h"
|
||||
#include "otx2_ipsec_anti_replay.h"
|
||||
#include "otx2_ipsec_po_ops.h"
|
||||
#include "otx2_mbox.h"
|
||||
#include "otx2_sec_idev.h"
|
||||
@ -650,21 +651,55 @@ static __rte_always_inline int __rte_hot
|
||||
otx2_cpt_enqueue_sec(struct otx2_cpt_qp *qp, struct rte_crypto_op *op,
|
||||
struct pending_queue *pend_q)
|
||||
{
|
||||
uint32_t winsz, esn_low = 0, esn_hi = 0, seql = 0, seqh = 0;
|
||||
struct rte_mbuf *m_src = op->sym->m_src;
|
||||
struct otx2_sec_session_ipsec_lp *sess;
|
||||
struct otx2_ipsec_po_sa_ctl *ctl_wrd;
|
||||
struct otx2_ipsec_po_in_sa *sa;
|
||||
struct otx2_sec_session *priv;
|
||||
struct cpt_request_info *req;
|
||||
uint64_t seq_in_sa, seq = 0;
|
||||
uint8_t esn;
|
||||
int ret;
|
||||
|
||||
priv = get_sec_session_private_data(op->sym->sec_session);
|
||||
sess = &priv->ipsec.lp;
|
||||
sa = &sess->in_sa;
|
||||
|
||||
ctl_wrd = &sess->in_sa.ctl;
|
||||
ctl_wrd = &sa->ctl;
|
||||
esn = ctl_wrd->esn_en;
|
||||
winsz = sa->replay_win_sz;
|
||||
|
||||
if (ctl_wrd->direction == OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND)
|
||||
ret = process_outb_sa(op, sess, &qp->meta_info, (void **)&req);
|
||||
else
|
||||
else {
|
||||
if (winsz) {
|
||||
esn_low = rte_be_to_cpu_32(sa->esn_low);
|
||||
esn_hi = rte_be_to_cpu_32(sa->esn_hi);
|
||||
seql = *rte_pktmbuf_mtod_offset(m_src, uint32_t *,
|
||||
sizeof(struct rte_ipv4_hdr) + 4);
|
||||
seql = rte_be_to_cpu_32(seql);
|
||||
|
||||
if (!esn)
|
||||
seq = (uint64_t)seql;
|
||||
else {
|
||||
seqh = anti_replay_get_seqh(winsz, seql, esn_hi,
|
||||
esn_low);
|
||||
seq = ((uint64_t)seqh << 32) | seql;
|
||||
}
|
||||
|
||||
if (unlikely(seq == 0))
|
||||
return IPSEC_ANTI_REPLAY_FAILED;
|
||||
|
||||
ret = anti_replay_check(sa->replay, seq, winsz);
|
||||
if (unlikely(ret)) {
|
||||
otx2_err("Anti replay check failed");
|
||||
return IPSEC_ANTI_REPLAY_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ret = process_inb_sa(op, sess, &qp->meta_info, (void **)&req);
|
||||
}
|
||||
|
||||
if (unlikely(ret)) {
|
||||
otx2_err("Crypto req : op %p, ret 0x%x", op, ret);
|
||||
@ -673,6 +708,14 @@ otx2_cpt_enqueue_sec(struct otx2_cpt_qp *qp, struct rte_crypto_op *op,
|
||||
|
||||
ret = otx2_cpt_enqueue_req(qp, pend_q, req, sess->cpt_inst_w7);
|
||||
|
||||
if (winsz && esn) {
|
||||
seq_in_sa = ((uint64_t)esn_hi << 32) | 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);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -213,6 +213,7 @@ crypto_sec_ipsec_outb_session_create(struct rte_cryptodev *crypto_dev,
|
||||
int ret;
|
||||
|
||||
sess = get_sec_session_private_data(sec_sess);
|
||||
sess->ipsec.dir = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
|
||||
lp = &sess->ipsec.lp;
|
||||
|
||||
sa = &lp->out_sa;
|
||||
@ -351,6 +352,7 @@ crypto_sec_ipsec_inb_session_create(struct rte_cryptodev *crypto_dev,
|
||||
int ret;
|
||||
|
||||
sess = get_sec_session_private_data(sec_sess);
|
||||
sess->ipsec.dir = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
|
||||
lp = &sess->ipsec.lp;
|
||||
|
||||
sa = &lp->in_sa;
|
||||
@ -362,6 +364,7 @@ crypto_sec_ipsec_inb_session_create(struct rte_cryptodev *crypto_dev,
|
||||
}
|
||||
|
||||
memset(sa, 0, sizeof(struct otx2_ipsec_po_in_sa));
|
||||
sa->replay_win_sz = ipsec->replay_win_sz;
|
||||
|
||||
ret = ipsec_po_sa_ctl_set(ipsec, crypto_xform, ctl);
|
||||
if (ret)
|
||||
@ -414,6 +417,24 @@ crypto_sec_ipsec_inb_session_create(struct rte_cryptodev *crypto_dev,
|
||||
set_session_misc_attributes(lp, crypto_xform,
|
||||
auth_xform, cipher_xform);
|
||||
|
||||
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;
|
||||
|
||||
/* 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 otx2_cpt_enq_sa_write(lp, crypto_dev->data->queue_pairs[0],
|
||||
OTX2_IPSEC_PO_WRITE_IPSEC_INB);
|
||||
}
|
||||
|
@ -204,4 +204,25 @@ cpt_ipsec_ip_antireplay_check(struct otx2_ipsec_fp_in_sa *sa, char *data)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
anti_replay_get_seqh(uint32_t winsz, uint32_t seql,
|
||||
uint32_t esn_hi, uint32_t esn_low)
|
||||
{
|
||||
uint32_t win_low = esn_low - winsz + 1;
|
||||
|
||||
if (esn_low > winsz - 1) {
|
||||
/* Window is in one sequence number subspace */
|
||||
if (seql > win_low)
|
||||
return esn_hi;
|
||||
else
|
||||
return esn_hi + 1;
|
||||
} else {
|
||||
/* Window is split across two sequence number subspaces */
|
||||
if (seql > win_low)
|
||||
return esn_hi - 1;
|
||||
else
|
||||
return esn_hi;
|
||||
}
|
||||
}
|
||||
#endif /* __OTX2_IPSEC_ANTI_REPLAY_H__ */
|
||||
|
@ -161,6 +161,11 @@ struct otx2_ipsec_po_in_sa {
|
||||
uint8_t hmac_key[48];
|
||||
struct otx2_ipsec_po_traffic_selector selector;
|
||||
} aes_gcm;
|
||||
union {
|
||||
struct otx2_ipsec_replay *replay;
|
||||
uint64_t replay64;
|
||||
};
|
||||
uint32_t replay_win_sz;
|
||||
};
|
||||
|
||||
struct otx2_ipsec_po_ip_template {
|
||||
|
@ -124,6 +124,8 @@ process_outb_sa(struct rte_crypto_op *cop,
|
||||
req->ist.ei1 = rte_pktmbuf_iova(m_src);
|
||||
req->ist.ei2 = req->ist.ei1;
|
||||
|
||||
sa->esn_hi = sess->seq_hi;
|
||||
|
||||
hdr->seq = rte_cpu_to_be_32(sess->seq_lo);
|
||||
hdr->ip_id = rte_cpu_to_be_32(sess->ip_id);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user