* IPv4
* ESP
+* ESN
+* Anti-replay
* Tunnel mode
* Transport mode
* UDP Encapsulation
* 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.**
/* 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;
/* 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
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 */
}
/* 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);
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)
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;
}
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;
}
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;
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(
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)
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;
}
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;
}
}
#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 { \
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
sec_cap->ipsec.options.iv_gen_disable = 1;
#endif
}
+ sec_cap->ipsec.replay_win_sz_max = CNXK_ON_AR_WIN_SIZE_MAX;
}
void