* [PATCH 01/16] common/cnxk: use context invalidate for cn20k
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 02/16] crypto/cnxk: return HW CPTR from cptr_get " Tejasree Kondoj
` (15 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Dabilpuram, dev
Using context invalidate for cn20k session APIs.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
drivers/common/cnxk/roc_cpt.c | 75 ++++++++++++++++++++++++++-----
drivers/common/cnxk/roc_cpt.h | 3 ++
drivers/crypto/cnxk/cn20k_ipsec.c | 24 ----------
drivers/crypto/cnxk/cn20k_tls.c | 29 ------------
4 files changed, 68 insertions(+), 63 deletions(-)
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index 686c9eae7e..9ba591d724 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -850,8 +850,10 @@ roc_cpt_dev_init(struct roc_cpt *roc_cpt)
int
roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, void *cptr, bool inval)
{
+ union cpt_lf_ctx_inval ctx_inval;
union cpt_lf_ctx_flush reg;
union cpt_lf_ctx_err err;
+ uint64_t *sa;
if (lf == NULL) {
plt_err("Could not trigger CTX flush");
@@ -879,6 +881,17 @@ roc_cpt_lf_ctx_flush(struct roc_cpt_lf *lf, void *cptr, bool inval)
return -EFAULT;
}
+ if (inval && roc_model_is_cn20k()) {
+ sa = cptr;
+ /* Clear bit 58 aop_valid */
+ sa[0] &= ~(1ULL << ROC_CN20K_CPT_AOP_VALID_BIT);
+ plt_io_wmb();
+
+ ctx_inval.u = 0;
+ ctx_inval.s.cptr = ((uintptr_t)sa) >> 7;
+ plt_write64(ctx_inval.u, lf->rbase + CPT_LF_CTX_INVAL);
+ }
+
return 0;
}
@@ -1265,9 +1278,8 @@ roc_cpt_lmtline_init(struct roc_cpt *roc_cpt, struct roc_cpt_lmtline *lmtline, i
return 0;
}
-int
-roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
- uint16_t sa_len)
+static int
+cpt_cn10k_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr, uint16_t sa_len)
{
union cpt_res_s res, *hw_res;
uint64_t lmt_arg, io_addr;
@@ -1278,13 +1290,8 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
uint8_t egrp;
int i;
- if (!plt_is_aligned(sa_cptr, ROC_CPTR_ALIGN)) {
- plt_err("Context pointer should be %dB aligned", ROC_CPTR_ALIGN);
- return -EINVAL;
- }
-
- if (lf == NULL) {
- plt_err("Invalid CPT LF");
+ if (!plt_is_aligned(sa_cptr, 128)) {
+ plt_err("Context pointer should be 128B aligned");
return -EINVAL;
}
@@ -1363,6 +1370,54 @@ roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
return 0;
}
+static int
+cpt_cn20k_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr, uint16_t sa_len)
+{
+ union cpt_lf_ctx_inval inval;
+ uintptr_t rbase;
+ uint64_t *sa;
+
+ if (!plt_is_aligned(sa_cptr, 256)) {
+ plt_err("Context pointer should be 256B aligned");
+ return -EINVAL;
+ }
+
+ sa = sa_dptr;
+
+ /* Clear bit 58 aop_valid */
+ sa[0] &= ~(1ULL << ROC_CN20K_CPT_AOP_VALID_BIT);
+ memcpy(sa_cptr, sa_dptr, sa_len);
+ plt_io_wmb();
+
+ /* Trigger CTX invalidate */
+ rbase = lf->rbase;
+ inval.u = 0;
+ inval.s.cptr = ((uintptr_t)sa_cptr) >> 7;
+ plt_write64(inval.u, rbase + CPT_LF_CTX_INVAL);
+
+ /* Set bit 58 aop_valid */
+ sa = sa_cptr;
+ sa[0] |= (1ULL << ROC_CN20K_CPT_AOP_VALID_BIT);
+ plt_io_wmb();
+
+ return 0;
+}
+
+int
+roc_cpt_ctx_write(struct roc_cpt_lf *lf, void *sa_dptr, void *sa_cptr,
+ uint16_t sa_len)
+{
+ if (lf == NULL) {
+ plt_err("Invalid CPT LF");
+ return -EINVAL;
+ }
+
+ if (roc_model_is_cn20k())
+ return cpt_cn20k_ctx_write(lf, sa_dptr, sa_cptr, sa_len);
+
+ return cpt_cn10k_ctx_write(lf, sa_dptr, sa_cptr, sa_len);
+}
+
void
roc_cpt_int_misc_cb_register(roc_cpt_int_misc_cb_t cb, void *args)
{
diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h
index 533d194bd4..ea78b73ec5 100644
--- a/drivers/common/cnxk/roc_cpt.h
+++ b/drivers/common/cnxk/roc_cpt.h
@@ -69,6 +69,9 @@
#define ROC_CN20K_CPT_INST_DW_M1 ROC_CN10K_CPT_INST_DW_M1
#define ROC_CN20K_TWO_CPT_INST_DW_M1 ROC_CN10K_TWO_CPT_INST_DW_M1
+/* aop_valid bit for cn20k */
+#define ROC_CN20K_CPT_AOP_VALID_BIT 58
+
/* CPT helper macros */
#define ROC_CPT_AH_HDR_LEN 12
#define ROC_CPT_AES_GCM_IV_LEN 8
diff --git a/drivers/crypto/cnxk/cn20k_ipsec.c b/drivers/crypto/cnxk/cn20k_ipsec.c
index 785bee02d4..b2cab4ff5f 100644
--- a/drivers/crypto/cnxk/cn20k_ipsec.c
+++ b/drivers/crypto/cnxk/cn20k_ipsec.c
@@ -131,20 +131,12 @@ cn20k_ipsec_outb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
rte_atomic_thread_fence(rte_memory_order_seq_cst);
- /* Write session using microcode opcode */
ret = roc_cpt_ctx_write(lf, sa_dptr, out_sa, sizeof(struct roc_ow_ipsec_outb_sa));
if (ret) {
plt_err("Could not write outbound session to hardware");
goto sa_free;
}
- /* Trigger CTX flush so that data is written back to DRAM */
- ret = roc_cpt_lf_ctx_flush(lf, out_sa, false);
- if (ret == -EFAULT) {
- plt_err("Could not flush outbound session");
- goto sa_free;
- }
-
sec_sess->proto = RTE_SECURITY_PROTOCOL_IPSEC;
rte_atomic_thread_fence(rte_memory_order_seq_cst);
@@ -246,20 +238,12 @@ cn20k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
rte_atomic_thread_fence(rte_memory_order_seq_cst);
- /* Write session using microcode opcode */
ret = roc_cpt_ctx_write(lf, sa_dptr, in_sa, sizeof(struct roc_ow_ipsec_inb_sa));
if (ret) {
plt_err("Could not write inbound session to hardware");
goto sa_free;
}
- /* Trigger CTX flush so that data is written back to DRAM */
- ret = roc_cpt_lf_ctx_flush(lf, in_sa, true);
- if (ret == -EFAULT) {
- plt_err("Could not flush inbound session");
- goto sa_free;
- }
-
sec_sess->proto = RTE_SECURITY_PROTOCOL_IPSEC;
rte_atomic_thread_fence(rte_memory_order_seq_cst);
@@ -313,9 +297,6 @@ cn20k_sec_ipsec_session_destroy(struct cnxk_cpt_qp *qp, struct cn20k_sec_session
if (sa->sa_ptr == NULL)
return -EINVAL;
- /* Trigger CTX flush to write dirty data back to DRAM */
- roc_cpt_lf_ctx_flush(lf, sa->in_sa, false);
-
ret = -1;
if (sess->ipsec.is_outbound) {
@@ -339,11 +320,6 @@ cn20k_sec_ipsec_session_destroy(struct cnxk_cpt_qp *qp, struct cn20k_sec_session
plt_free(sa_dptr);
if (ret) {
- /* MC write_ctx failed. Attempt reload of CTX */
-
- /* Wait for 1 ms so that flush is complete */
- rte_delay_ms(1);
-
w2 = (union roc_ow_ipsec_sa_word2 *)&sa->in_sa->w2;
w2->s.valid = 0;
diff --git a/drivers/crypto/cnxk/cn20k_tls.c b/drivers/crypto/cnxk/cn20k_tls.c
index 8556a95ab6..882d193c25 100644
--- a/drivers/crypto/cnxk/cn20k_tls.c
+++ b/drivers/crypto/cnxk/cn20k_tls.c
@@ -446,20 +446,12 @@ cn20k_tls_read_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
rte_atomic_thread_fence(rte_memory_order_seq_cst);
- /* Write session using microcode opcode */
ret = roc_cpt_ctx_write(lf, sa_dptr, read_sa, sizeof(struct roc_ie_ow_tls_read_sa));
if (ret) {
plt_err("Could not write read session to hardware");
goto sa_dptr_free;
}
- /* Trigger CTX flush so that data is written back to DRAM */
- ret = roc_cpt_lf_ctx_flush(lf, read_sa, true);
- if (ret == -EFAULT) {
- plt_err("Could not flush TLS read session to hardware");
- goto sa_dptr_free;
- }
-
rte_atomic_thread_fence(rte_memory_order_seq_cst);
sa_dptr_free:
@@ -782,20 +774,12 @@ cn20k_tls_write_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
rte_atomic_thread_fence(rte_memory_order_seq_cst);
- /* Write session using microcode opcode */
ret = roc_cpt_ctx_write(lf, sa_dptr, write_sa, sizeof(struct roc_ie_ow_tls_write_sa));
if (ret) {
plt_err("Could not write tls write session to hardware");
goto sa_dptr_free;
}
- /* Trigger CTX flush so that data is written back to DRAM */
- ret = roc_cpt_lf_ctx_flush(lf, write_sa, false);
- if (ret == -EFAULT) {
- plt_err("Could not flush TLS write session to hardware");
- goto sa_dptr_free;
- }
-
rte_atomic_thread_fence(rte_memory_order_seq_cst);
sa_dptr_free:
@@ -895,9 +879,6 @@ cn20k_sec_tls_session_destroy(struct cnxk_cpt_qp *qp, struct cn20k_sec_session *
if (tls->sa_ptr == NULL)
return -EINVAL;
- /* Trigger CTX flush to write dirty data back to DRAM */
- roc_cpt_lf_ctx_flush(lf, tls->read_sa, false);
-
if (sess->tls_opt.is_write) {
sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ow_tls_write_sa), 8);
if (sa_dptr != NULL) {
@@ -908,11 +889,6 @@ cn20k_sec_tls_session_destroy(struct cnxk_cpt_qp *qp, struct cn20k_sec_session *
plt_free(sa_dptr);
}
if (ret) {
- /* MC write_ctx failed. Attempt reload of CTX */
-
- /* Wait for 1 ms so that flush is complete */
- rte_delay_ms(1);
-
rte_atomic_thread_fence(rte_memory_order_seq_cst);
/* Trigger CTX reload to fetch new data from DRAM */
@@ -928,11 +904,6 @@ cn20k_sec_tls_session_destroy(struct cnxk_cpt_qp *qp, struct cn20k_sec_session *
plt_free(sa_dptr);
}
if (ret) {
- /* MC write_ctx failed. Attempt reload of CTX */
-
- /* Wait for 1 ms so that flush is complete */
- rte_delay_ms(1);
-
rte_atomic_thread_fence(rte_memory_order_seq_cst);
/* Trigger CTX reload to fetch new data from DRAM */
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 02/16] crypto/cnxk: return HW CPTR from cptr_get for cn20k
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 01/16] common/cnxk: use context invalidate for cn20k Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 03/16] crypto/cnxk: enable cq_all and allocate extra CQ line Tejasree Kondoj
` (14 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Dabilpuram, dev
On cn20k, security session CPTR is allocated separately from the SA
wrapper. Return the HW context pointer so cptr_read/write use the
256-byte aligned buffer as documented by the API.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index 4c9bacecdd..6553ac90a1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -1294,7 +1294,7 @@ rte_pmd_cnxk_crypto_cptr_get(struct rte_pmd_cnxk_crypto_sess *rte_sess)
if (roc_model_is_cn20k()) {
struct cn20k_sec_session *sec_sess = PLT_PTR_CAST(rte_sess->sec_sess);
- return PLT_PTR_CAST(&sec_sess->sa);
+ return PLT_PTR_CAST(sec_sess->sa.sa_ptr);
}
if (roc_model_is_cn10k()) {
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 03/16] crypto/cnxk: enable cq_all and allocate extra CQ line
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 01/16] common/cnxk: use context invalidate for cn20k Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 02/16] crypto/cnxk: return HW CPTR from cptr_get " Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 04/16] common/cnxk: validate cipher key length in IPsec SA fill Tejasree Kondoj
` (13 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Dabilpuram, dev
With cq_all enabled, allocate one extra CQ line beyond the HW ring size
as HW is writing to Nth slot also and update the pending tail after
sym raw dequeue completes a request.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
drivers/common/cnxk/roc_cpt.c | 7 +++++--
drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 1 +
drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index 9ba591d724..8c60a28fff 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -704,8 +704,11 @@ cpt_lf_cq_init(struct roc_cpt_lf *lf)
/* Disable CPT completion queue */
roc_cpt_cq_disable(lf);
- /* Set command queue base address */
- len = PLT_ALIGN(lf->cq_size * (ROC_CPT_CQ_ENTRY_SIZE_UNIT << lf->cq_entry_size), ROC_ALIGN);
+ /* Set completion queue (CQ) base address */
+ len = lf->cq_size;
+ if (roc_model_is_cn20k() && lf->cq_all)
+ len++;
+ len = PLT_ALIGN(len * (ROC_CPT_CQ_ENTRY_SIZE_UNIT << lf->cq_entry_size), ROC_ALIGN);
lf->cq_vaddr = plt_zmalloc(len, ROC_ALIGN);
if (lf->cq_vaddr == NULL)
return -ENOMEM;
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index 18100ff1f8..a63b97654b 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -1429,6 +1429,7 @@ cn20k_cpt_sym_raw_dequeue(void *qptr, uint8_t *drv_ctx, int *dequeue_status,
if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
+ pend_q->tail = pq_tail;
*dequeue_status = 1;
exit:
return opaque;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index 6553ac90a1..1e0ea9d358 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -535,6 +535,7 @@ cnxk_cpt_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
/* CQ entry size is 128B(32 << 2) */
qp->lf.cq_entry_size = 2;
qp->lf.cq_size = nb_desc;
+ qp->lf.cq_all = true;
}
ret = roc_cpt_lf_init(roc_cpt, &qp->lf);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 04/16] common/cnxk: validate cipher key length in IPsec SA fill
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (2 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 03/16] crypto/cnxk: enable cq_all and allocate extra CQ line Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 05/16] crypto/cnxk: reject truncated TLS records in decrypt Tejasree Kondoj
` (12 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
The IPsec SA builders copy the cipher key into the fixed 32-byte
SA context field via memcpy. The per-algorithm length validation
only runs for AES/DES/3DES and AES-GMAC, so a NULL-cipher SA with
a non-zero, oversized key.length skips every check.
Reject any key longer than the SA cipher key field with -EINVAL.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/common/cnxk/cnxk_security.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c
index 228ff2781d..9f734c16b1 100644
--- a/drivers/common/cnxk/cnxk_security.c
+++ b/drivers/common/cnxk/cnxk_security.c
@@ -170,6 +170,10 @@ ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2, uint8_t *cipher_k
w2->s.spi = ipsec_xfrm->spi;
if (key != NULL && length != 0) {
+ if (length > ROC_CTX_MAX_CKEY_LEN) {
+ plt_err("Invalid cipher key length");
+ return -EINVAL;
+ }
/* Validate key length and set AES key len before copy to avoid overflow */
if (w2->s.enc_type == ROC_IE_SA_ENC_AES_CBC ||
w2->s.enc_type == ROC_IE_SA_ENC_AES_CTR ||
@@ -1012,8 +1016,13 @@ on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
}
}
- if (cipher_key_len != 0)
+ if (cipher_key_len != 0) {
+ if (cipher_key_len > (int)sizeof(common_sa->cipher_key)) {
+ plt_err("Invalid cipher key length");
+ return -EINVAL;
+ }
memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
+ }
return 0;
}
@@ -1403,6 +1412,10 @@ ow_ipsec_sa_common_param_fill(union roc_ow_ipsec_sa_word2 *w2, uint8_t *cipher_k
w2->s.spi = ipsec_xfrm->spi;
if (key != NULL && length != 0) {
+ if (length > ROC_CTX_MAX_CKEY_LEN) {
+ plt_err("Invalid cipher key length");
+ return -EINVAL;
+ }
/* Validate key length and set AES key len before copy to avoid overflow */
if (w2->s.enc_type == ROC_IE_SA_ENC_AES_CBC ||
w2->s.enc_type == ROC_IE_SA_ENC_AES_CTR ||
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 05/16] crypto/cnxk: reject truncated TLS records in decrypt
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (3 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 04/16] common/cnxk: validate cipher key length in IPsec SA fill Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 06/16] crypto/cnxk: fix CN20K CPT error recovery Tejasree Kondoj
` (11 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
The TLS decrypt tail-fetch path for CBC/3DES READ sessions computed the
tail-fetch source offset as (pkt_len - tail_len) without checking that
pkt_len >= tail_len. For an inbound record shorter than tail_len, the
subtraction underflows when passed as the uint32_t offset to
rte_pktmbuf_read(), which then returns NULL because offset + len
exceeds the packet length. The following rte_memcpy(in_buffer, output,
tail_len) dereferences that NULL pointer.
Reject records with pkt_len < tail_len (return -EINVAL) before computing
the tail-fetch offset in the scatter-gather branches of process_tls_read()
for both cn10k (SGv1 and SGv2) and cn20k.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn10k_tls_ops.h | 12 ++++++++++++
drivers/crypto/cnxk/cn20k_tls_ops.h | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/crypto/cnxk/cn10k_tls_ops.h b/drivers/crypto/cnxk/cn10k_tls_ops.h
index 90600bd850..416207f676 100644
--- a/drivers/crypto/cnxk/cn10k_tls_ops.h
+++ b/drivers/crypto/cnxk/cn10k_tls_ops.h
@@ -260,6 +260,12 @@ process_tls_read(struct rte_crypto_op *cop, struct cn10k_sec_session *sess,
uint32_t dlen;
int i;
+ if (unlikely(pkt_len < tail_len)) {
+ plt_dp_err("Invalid TLS record: pkt_len %d < tail_len %d", pkt_len,
+ tail_len);
+ return -EINVAL;
+ }
+
if (unlikely(m_src->nb_segs > ROC_SG1_MAX_PTRS)) {
plt_dp_err("Exceeds max supported components. Reduce segments");
return -1;
@@ -320,6 +326,12 @@ process_tls_read(struct rte_crypto_op *cop, struct cn10k_sec_session *sess,
uint32_t g_size_bytes;
int i;
+ if (unlikely(pkt_len < tail_len)) {
+ plt_dp_err("Invalid TLS record: pkt_len %d < tail_len %d", pkt_len,
+ tail_len);
+ return -EINVAL;
+ }
+
if (unlikely(m_src->nb_segs > ROC_SG2_MAX_PTRS)) {
plt_dp_err("Exceeds max supported components. Reduce segments");
return -1;
diff --git a/drivers/crypto/cnxk/cn20k_tls_ops.h b/drivers/crypto/cnxk/cn20k_tls_ops.h
index e7a8ba34ae..670acbe9ab 100644
--- a/drivers/crypto/cnxk/cn20k_tls_ops.h
+++ b/drivers/crypto/cnxk/cn20k_tls_ops.h
@@ -203,6 +203,12 @@ process_tls_read(struct rte_crypto_op *cop, struct cn20k_sec_session *sess,
uint32_t g_size_bytes;
int i;
+ if (unlikely(pkt_len < tail_len)) {
+ plt_dp_err("Invalid TLS record: pkt_len %d < tail_len %d", pkt_len,
+ tail_len);
+ return -EINVAL;
+ }
+
if (unlikely(m_src->nb_segs > ROC_SG2_MAX_PTRS)) {
plt_dp_err("Exceeds max supported components. Reduce segments");
return -1;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 06/16] crypto/cnxk: fix CN20K CPT error recovery
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (4 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 05/16] crypto/cnxk: reject truncated TLS records in decrypt Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 07/16] crypto/cnxk: validate TLS xform and keys before SA key copy Tejasree Kondoj
` (10 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Dabilpuram, dev
Reprogram completion queue base and size registers in
roc_cpt_cq_enable as hardware clears them after fatal error.
Also reset pending queue head and tail during queue pair reset so
software completion state stays aligned with the reset hardware
queue.
Fixes: 13ce9121c3c0 ("common/cnxk: add routines to operate CPT CQ")
Fixes: 4e8a41acaffb ("crypto/cnxk: support CPT CQ for CN20K")
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
drivers/common/cnxk/roc_cpt.c | 13 +++++++++++++
drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 6 ++++++
2 files changed, 19 insertions(+)
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index 8c60a28fff..eae3f134e9 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -1147,7 +1147,20 @@ roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type)
void
roc_cpt_cq_enable(struct roc_cpt_lf *lf)
{
+ union cpt_lf_cq_base lf_cq_base = {.u = 0x0};
+ union cpt_lf_cq_size lf_cq_size = {.u = 0x0};
union cpt_lf_cq_ctl lf_cq_ctl = {.u = 0x0};
+ uintptr_t addr;
+
+ /* Disable completion queue */
+ roc_cpt_cq_disable(lf);
+
+ /* Reconfigure CQ base and size, same as cpt_lf_cq_init() */
+ addr = (uintptr_t)lf->cq_vaddr;
+ lf_cq_base.s.addr = addr >> 7;
+ plt_write64(lf_cq_base.u, lf->rbase + CPT_LF_CQ_BASE);
+ lf_cq_size.s.size = lf->cq_size;
+ plt_write64(lf_cq_size.u, lf->rbase + CPT_LF_CQ_SIZE);
lf_cq_ctl.s.ena = 1;
lf_cq_ctl.s.dq_ack_ena = lf->dq_ack_ena;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index 1e0ea9d358..95f64a79ae 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -596,6 +596,7 @@ cnxk_cpt_queue_pair_reset(struct rte_cryptodev *dev, uint16_t qp_id,
{
if (conf == NULL) {
struct cnxk_cpt_vf *vf = dev->data->dev_private;
+ struct cnxk_cpt_qp *qp;
struct roc_cpt_lf *lf;
if (vf == NULL)
@@ -603,6 +604,11 @@ cnxk_cpt_queue_pair_reset(struct rte_cryptodev *dev, uint16_t qp_id,
lf = vf->cpt.lf[qp_id];
roc_cpt_lf_reset(lf);
+
+ qp = dev->data->queue_pairs[qp_id];
+ qp->pend_q.head = 0;
+ qp->pend_q.tail = 0;
+
roc_cpt_iq_enable(lf);
if (lf->cpt_cq_ena)
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 07/16] crypto/cnxk: validate TLS xform and keys before SA key copy
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (5 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 06/16] crypto/cnxk: fix CN20K CPT error recovery Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 08/16] crypto/cnxk: reject oversized SG vectors in raw datapath Tejasree Kondoj
` (9 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
cn10k_tls_record_session_update() and cn20k_tls_record_session_update()
forwarded the crypto_xform to tls_write_sa_fill() without running
cnxk_tls_xform_verify(), unlike the create path.
Separately, the AEAD key-length guard in the SA fill routines used a
single 16/32 check that incorrectly accepted a 16-byte
ChaCha20-Poly1305 key (ChaCha requires 32), and both the AEAD and the
read-side cipher paths copied key.data without a NULL check, so a
malformed xform could crash in memcpy().
- Call cnxk_tls_xform_verify() on the update path.
- Make the AEAD key-length validation algorithm-specific (AES-GCM
16/32, ChaCha20-Poly1305 32, reject others).
- Reject NULL key pointers before the memcpy on both the AEAD and
cipher paths, for cn10k and cn20k.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn10k_tls.c | 33 +++++++++++++++++++++----
drivers/crypto/cnxk/cn20k_tls.c | 44 +++++++++++++++++++++++++--------
2 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/drivers/crypto/cnxk/cn10k_tls.c b/drivers/crypto/cnxk/cn10k_tls.c
index 1a7b87e400..8aa6d5ad4b 100644
--- a/drivers/crypto/cnxk/cn10k_tls.c
+++ b/drivers/crypto/cnxk/cn10k_tls.c
@@ -358,19 +358,25 @@ tls_read_sa_fill(struct roc_ie_ot_tls_read_sa *read_sa,
if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
length = crypto_xfrm->aead.key.length;
if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
+ if (length != 16 && length != 32)
+ return -EINVAL;
read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_GCM;
if (length == 16)
read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
else
read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
- }
-
- if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ } else if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ if (length != 32)
+ return -EINVAL;
read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_CHACHA_POLY;
read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
+ } else {
+ return -EINVAL;
}
key = crypto_xfrm->aead.key.data;
+ if (key == NULL)
+ return -EINVAL;
memcpy(cipher_key, key, length);
if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
@@ -395,6 +401,8 @@ tls_read_sa_fill(struct roc_ie_ot_tls_read_sa *read_sa,
if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_3DES;
length = cipher_xfrm->cipher.key.length;
+ if (length != 24)
+ return -EINVAL;
} else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_CBC;
length = cipher_xfrm->cipher.key.length;
@@ -409,6 +417,8 @@ tls_read_sa_fill(struct roc_ie_ot_tls_read_sa *read_sa,
}
key = cipher_xfrm->cipher.key.data;
+ if (key == NULL || length == 0)
+ return -EINVAL;
memcpy(cipher_key, key, length);
}
@@ -515,18 +525,25 @@ tls_write_sa_fill(struct roc_ie_ot_tls_write_sa *write_sa,
if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
length = crypto_xfrm->aead.key.length;
if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
+ if (length != 16 && length != 32)
+ return -EINVAL;
write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_GCM;
if (length == 16)
write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
else
write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
- }
- if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ } else if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ if (length != 32)
+ return -EINVAL;
write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_CHACHA_POLY;
write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
+ } else {
+ return -EINVAL;
}
key = crypto_xfrm->aead.key.data;
+ if (key == NULL)
+ return -EINVAL;
memcpy(cipher_key, key, length);
if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
@@ -551,6 +568,8 @@ tls_write_sa_fill(struct roc_ie_ot_tls_write_sa *write_sa,
if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_3DES;
length = cipher_xfrm->cipher.key.length;
+ if (length != 24)
+ return -EINVAL;
} else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_CBC;
length = cipher_xfrm->cipher.key.length;
@@ -833,6 +852,10 @@ cn10k_tls_record_session_update(struct cnxk_cpt_vf *vf, struct cnxk_cpt_qp *qp,
if (conf->tls_record.type == RTE_SECURITY_TLS_SESS_TYPE_READ)
return -ENOTSUP;
+ ret = cnxk_tls_xform_verify(&conf->tls_record, conf->crypto_xform);
+ if (ret)
+ return ret;
+
roc_cpt = &vf->cpt;
ret = cn10k_tls_write_sa_create(roc_cpt, &qp->lf, &conf->tls_record, conf->crypto_xform,
(struct cn10k_sec_session *)sess);
diff --git a/drivers/crypto/cnxk/cn20k_tls.c b/drivers/crypto/cnxk/cn20k_tls.c
index 882d193c25..ac6f6d9c4b 100644
--- a/drivers/crypto/cnxk/cn20k_tls.c
+++ b/drivers/crypto/cnxk/cn20k_tls.c
@@ -249,19 +249,25 @@ tls_read_sa_fill(struct roc_ie_ow_tls_read_sa *read_sa,
if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
length = crypto_xfrm->aead.key.length;
if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
+ if (length != 16 && length != 32)
+ return -EINVAL;
read_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_AES_GCM;
if (length == 16)
read_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_128;
else
read_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_256;
- }
-
- if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ } else if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ if (length != 32)
+ return -EINVAL;
read_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_CHACHA_POLY;
read_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_256;
+ } else {
+ return -EINVAL;
}
key = crypto_xfrm->aead.key.data;
+ if (key == NULL)
+ return -EINVAL;
memcpy(cipher_key, key, length);
if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
@@ -286,6 +292,8 @@ tls_read_sa_fill(struct roc_ie_ow_tls_read_sa *read_sa,
if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
read_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_3DES;
length = cipher_xfrm->cipher.key.length;
+ if (length != 24)
+ return -EINVAL;
} else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
read_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_AES_CBC;
length = cipher_xfrm->cipher.key.length;
@@ -300,6 +308,8 @@ tls_read_sa_fill(struct roc_ie_ow_tls_read_sa *read_sa,
}
key = cipher_xfrm->cipher.key.data;
+ if (key == NULL || length == 0)
+ return -EINVAL;
memcpy(cipher_key, key, length);
}
@@ -576,18 +586,25 @@ tls_write_sa_fill(struct roc_ie_ow_tls_write_sa *write_sa,
if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
length = crypto_xfrm->aead.key.length;
if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
+ if (length != 16 && length != 32)
+ return -EINVAL;
write_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_AES_GCM;
if (length == 16)
write_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_128;
else
write_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_256;
- }
- if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ } else if (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ if (length != 32)
+ return -EINVAL;
write_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_CHACHA_POLY;
write_sa->w2.s.aes_key_len = ROC_IE_OW_TLS_AES_KEY_LEN_256;
+ } else {
+ return -EINVAL;
}
key = crypto_xfrm->aead.key.data;
+ if (key == NULL)
+ return -EINVAL;
memcpy(cipher_key, key, length);
if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
@@ -612,6 +629,8 @@ tls_write_sa_fill(struct roc_ie_ow_tls_write_sa *write_sa,
if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
write_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_3DES;
length = cipher_xfrm->cipher.key.length;
+ if (length != 24)
+ return -EINVAL;
} else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
write_sa->w2.s.cipher_select = ROC_IE_OW_TLS_CIPHER_AES_CBC;
length = cipher_xfrm->cipher.key.length;
@@ -626,10 +645,9 @@ tls_write_sa_fill(struct roc_ie_ow_tls_write_sa *write_sa,
}
key = cipher_xfrm->cipher.key.data;
- if (key != NULL && length != 0) {
- /* Copy encryption key */
- memcpy(cipher_key, key, length);
- }
+ if (key == NULL)
+ return -EINVAL;
+ memcpy(cipher_key, key, length);
}
if (auth_xfrm != NULL) {
@@ -716,7 +734,6 @@ cn20k_tls_write_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
plt_err("Couldn't allocate memory for WRITE SA");
return -ENOMEM;
}
- tls->write_sa = write_sa;
/* Allocate memory to be used as dptr for CPT ucode WRITE_SA op */
sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ow_tls_write_sa), 8);
@@ -782,6 +799,9 @@ cn20k_tls_write_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
rte_atomic_thread_fence(rte_memory_order_seq_cst);
+ if (tls->write_sa != NULL)
+ rte_free(tls->write_sa);
+ tls->write_sa = write_sa;
sa_dptr_free:
plt_free(sa_dptr);
sa_cptr_free:
@@ -834,6 +854,10 @@ cn20k_tls_record_session_update(struct cnxk_cpt_vf *vf, struct cnxk_cpt_qp *qp,
if (conf->tls_record.type == RTE_SECURITY_TLS_SESS_TYPE_READ)
return -ENOTSUP;
+ ret = cnxk_tls_xform_verify(&conf->tls_record, conf->crypto_xform);
+ if (ret)
+ return ret;
+
roc_cpt = &vf->cpt;
ret = cn20k_tls_write_sa_create(roc_cpt, &qp->lf, &conf->tls_record, conf->crypto_xform,
(struct cn20k_sec_session *)sess);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 08/16] crypto/cnxk: reject oversized SG vectors in raw datapath
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (6 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 07/16] crypto/cnxk: validate TLS xform and keys before SA key copy Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 09/16] crypto/cnxk: guard trim len bounds in TLS 1.2 MAC trim Tejasree Kondoj
` (8 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
In raw datapath, iov builders copied application-supplied SG entries
into the fixed-size iov->src[]/dst[] stack buffers (max ROC_MAX_SG_CNT
entries) without validating the segment count. A raw-dp crypto vector
with more than ROC_MAX_SG_CNT segments results in a stack overwrite.
Reject vector lists whose src_sgl[].num, dest_sgl[].num, or n_data_vecs
exceed ROC_MAX_SG_CNT before copying.
cnxk_raw_burst_to_iov() and cnxk_raw_to_iov() now return an error,
which is propagated by the cn10k and cn20k raw enqueue paths to fail
the op cleanly.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 29 ++++++++++++++++++-----
drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 29 ++++++++++++++++++-----
drivers/crypto/cnxk/cnxk_se.h | 23 ++++++++++++++++--
3 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index 870e65c049..bf273774fd 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -1615,17 +1615,30 @@ cn10k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym
infl_req = &pend_q->req_queue[head];
infl_req->op_flags = 0;
- cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+ ret = cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+ if (unlikely(ret != 0)) {
+ plt_dp_err("Failed to convert raw to iov: %d", index);
+ if (i == 0 && count == 0) {
+ *enqueue_status = ret;
+ return 0;
+ } else if (i == 0) {
+ goto pend_q_commit;
+ } else {
+ break;
+ }
+ }
ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[i], infl_req,
user_data[index], is_sgv2);
if (unlikely(ret != 1)) {
plt_dp_err("Could not process vec: %d", index);
- if (i == 0 && count == 0)
- return -1;
- else if (i == 0)
+ if (i == 0 && count == 0) {
+ *enqueue_status = -EINVAL;
+ return 0;
+ } else if (i == 0) {
goto pend_q_commit;
- else
+ } else {
break;
+ }
}
pending_queue_advance(&head, pq_mask);
}
@@ -1694,7 +1707,11 @@ cn10k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data
if (unlikely(nb_allowed == 0))
return -1;
- cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+ ret = cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+ if (unlikely(ret != 0)) {
+ plt_dp_err("Failed to convert raw to iov");
+ return -1;
+ }
lmt_base = qp->lmtline.lmt_base;
io_addr = qp->lmtline.io_addr;
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index a63b97654b..7707755775 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -1189,17 +1189,30 @@ cn20k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym
infl_req = &pend_q->req_queue[head];
infl_req->op_flags = 0;
- cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+ ret = cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+ if (unlikely(ret != 0)) {
+ plt_dp_err("Failed to convert raw to iov: %d", index);
+ if (i == 0 && count == 0) {
+ *enqueue_status = ret;
+ return 0;
+ } else if (i == 0) {
+ goto pend_q_commit;
+ } else {
+ break;
+ }
+ }
ret = cn20k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[i], infl_req,
user_data[index]);
if (unlikely(ret != 1)) {
plt_dp_err("Could not process vec: %d", index);
- if (i == 0 && count == 0)
- return -1;
- else if (i == 0)
+ if (i == 0 && count == 0) {
+ *enqueue_status = -EINVAL;
+ return 0;
+ } else if (i == 0) {
goto pend_q_commit;
- else
+ } else {
break;
+ }
}
pending_queue_advance(&head, pq_mask);
}
@@ -1249,7 +1262,11 @@ cn20k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data
if (unlikely(nb_allowed == 0))
return -1;
- cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+ ret = cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+ if (unlikely(ret != 0)) {
+ plt_dp_err("Failed to convert raw to iov");
+ return -1;
+ }
lmt_base = qp->lmtline.lmt_base;
io_addr = qp->lmtline.io_addr;
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index 505a5fcd37..b712acdccd 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -3633,10 +3633,19 @@ prepare_iov_from_raw_vec(struct rte_crypto_vec *vec, struct roc_se_iov_ptr *iove
return total_len;
}
-static __rte_always_inline void
+static __rte_always_inline int
cnxk_raw_burst_to_iov(struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs *ofs, int index,
struct cnxk_iov *iov)
{
+ uint32_t dst_num =
+ (vec->dest_sgl == NULL) ? vec->src_sgl[index].num : vec->dest_sgl[index].num;
+
+ if (unlikely(vec->src_sgl[index].num > ROC_MAX_SG_CNT || dst_num > ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments (src: %u, dst: %u) exceeds max supported (%u)",
+ vec->src_sgl[index].num, dst_num, ROC_MAX_SG_CNT);
+ return -ENOTSUP;
+ }
+
iov->iv_buf = vec->iv[index].va;
iov->aad_buf = vec->aad[index].va;
iov->mac_buf = vec->digest[index].va;
@@ -3658,13 +3667,21 @@ cnxk_raw_burst_to_iov(struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs *
iov->a_head = ofs->ofs.auth.head;
iov->a_tail = ofs->ofs.auth.tail;
+
+ return 0;
}
-static __rte_always_inline void
+static __rte_always_inline int
cnxk_raw_to_iov(struct rte_crypto_vec *data_vec, uint16_t n_vecs, union rte_crypto_sym_ofs *ofs,
struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
struct rte_crypto_va_iova_ptr *aad, struct cnxk_iov *iov)
{
+ if (unlikely(n_vecs > ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments (%u) exceeds max supported (%u)", n_vecs,
+ ROC_MAX_SG_CNT);
+ return -ENOTSUP;
+ }
+
iov->iv_buf = iv->va;
iov->aad_buf = aad->va;
iov->mac_buf = digest->va;
@@ -3678,6 +3695,8 @@ cnxk_raw_to_iov(struct rte_crypto_vec *data_vec, uint16_t n_vecs, union rte_cryp
iov->a_head = ofs->ofs.auth.head;
iov->a_tail = ofs->ofs.auth.tail;
+
+ return 0;
}
static inline void
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 09/16] crypto/cnxk: guard trim len bounds in TLS 1.2 MAC trim
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (7 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 08/16] crypto/cnxk: reject oversized SG vectors in raw datapath Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 10/16] crypto/cnxk: enable ctx cache for cn20k crypto Tejasree Kondoj
` (7 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
In cn10k_cpt_tls12_trim_mac() the padding length is derived from the
decrypted record. trim_len was used to compute mac_offset/pad_offset
without checking it against the record length, causing out-of-bounds
reads and corrupted mbuf lengths in both direct and SG modes.
Reject records where trim_len exceeds the record length.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index bf273774fd..30ef0d14c2 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -942,6 +942,13 @@ cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
pad_val = ((res->spi >> 16) & 0xff);
pad_len = pad_val + 1;
trim_len = pad_len + mac_len;
+
+ if (trim_len > m_len) {
+ cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+ cop->aux_flags = res->uc_compcode;
+ return;
+ }
+
mac_offset = m_len - trim_len;
pad_offset = mac_offset + mac_len;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 10/16] crypto/cnxk: enable ctx cache for cn20k crypto
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (8 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 09/16] crypto/cnxk: guard trim len bounds in TLS 1.2 MAC trim Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 11/16] crypto/cnxk: guard trim len in TLS 1.2 MAC trim for CN20K Tejasree Kondoj
` (6 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Dabilpuram, dev
Enable ctx cache for cn20k lookaside crypto.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
drivers/crypto/cnxk/cnxk_cryptodev_ops.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index 32fc7a26fc..7bf26d67dc 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -227,7 +227,7 @@ static __rte_always_inline bool
hw_ctx_cache_enable(void)
{
return roc_errata_cpt_hang_on_mixed_ctx_val() || roc_model_is_cn10ka_b0() ||
- roc_model_is_cn10kb_a0();
+ roc_model_is_cn10kb_a0() || roc_model_is_cn20k();
}
static inline uint64_t
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 11/16] crypto/cnxk: guard trim len in TLS 1.2 MAC trim for CN20K
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (9 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 10/16] crypto/cnxk: enable ctx cache for cn20k crypto Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 12/16] crypto/cnxk: validate TLS 1.2 MAC trim lengths Tejasree Kondoj
` (5 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
In cn20k_cpt_tls12_trim_mac() the padding length is derived from the
decrypted record. trim_len was used to compute mac_offset/pad_offset
without checking it against the record length, causing out-of-bounds
reads and corrupted mbuf lengths in both direct and SG modes.
Reject records where trim_len exceeds the record length.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index 7707755775..f91e56f3ed 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -704,6 +704,13 @@ cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res,
pad_val = ((res->spi >> 16) & 0xff);
pad_len = pad_val + 1;
trim_len = pad_len + mac_len;
+
+ if (trim_len > m_len) {
+ cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+ cop->aux_flags = res->uc_compcode;
+ return;
+ }
+
mac_offset = m_len - trim_len;
pad_offset = mac_offset + mac_len;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 12/16] crypto/cnxk: validate TLS 1.2 MAC trim lengths
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (10 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 11/16] crypto/cnxk: guard trim len in TLS 1.2 MAC trim for CN20K Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 13/16] crypto/cnxk: bound SG segment count in packet iov builders Tejasree Kondoj
` (4 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
In cn10k_cpt_tls12_trim_mac() and cn20k_cpt_tls12_trim_mac(), the pad
length comes from the decrypted record and the record length from
hardware. Neither was fully validated against the mbuf. Padding larger
than the record made the MAC and pad offsets underflow. That caused
out-of-bounds reads in direct mode and a walk past the end of the
segment chain in SG mode.
Fail the op with an error and skip trimming when trim_len exceeds the
record length, or when the record length exceedds pkt_len.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 2 +-
drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index 30ef0d14c2..365e3a8535 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -943,7 +943,7 @@ cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
pad_len = pad_val + 1;
trim_len = pad_len + mac_len;
- if (trim_len > m_len) {
+ if (trim_len > m_len || m_len > mbuf->pkt_len) {
cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
cop->aux_flags = res->uc_compcode;
return;
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index f91e56f3ed..bb3384023f 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -705,7 +705,7 @@ cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res,
pad_len = pad_val + 1;
trim_len = pad_len + mac_len;
- if (trim_len > m_len) {
+ if (trim_len > m_len || m_len > mbuf->pkt_len) {
cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
cop->aux_flags = res->uc_compcode;
return;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 13/16] crypto/cnxk: bound SG segment count in packet iov builders
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (11 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 12/16] crypto/cnxk: validate TLS 1.2 MAC trim lengths Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 14/16] crypto/cnxk: bound SG iovec index in mbuf walk Tejasree Kondoj
` (3 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
prepare_iov_from_pkt() and prepare_iov_from_pkt_inplace() wrote one
iovec->bufs[] entry per mbuf segment with no bound check, overflowing
the fixed-size stack buffer (capacity ROC_MAX_SG_CNT) on the lookaside
symmetric path.
Reject segment counts exceeding ROC_MAX_SG_CNT in both builders and
fail the op.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cnxk_se.h | 51 ++++++++++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index b712acdccd..a3c3c3ce86 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -2670,6 +2670,7 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
const bool is_aead, const bool is_sg_ver2)
{
uint16_t index = 0;
+ uint16_t nb_segs = 0;
void *seg_data = NULL;
int32_t seg_size = 0;
@@ -2678,6 +2679,8 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
return 0;
}
+ nb_segs = pkt->nb_segs;
+
if (!start_offset) {
seg_data = rte_pktmbuf_mtod(pkt, void *);
seg_size = pkt->data_len;
@@ -2685,6 +2688,12 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
while (start_offset >= pkt->data_len) {
start_offset -= pkt->data_len;
pkt = pkt->next;
+ nb_segs--;
+
+ if (unlikely(pkt == NULL)) {
+ plt_dp_err("Start offset beyond end of packet");
+ return 1;
+ }
}
seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset);
@@ -2693,6 +2702,12 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
return 1;
}
+ if (unlikely(nb_segs > ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments (%u) exceeds max supported (%u)", nb_segs,
+ ROC_MAX_SG_CNT);
+ return 1;
+ }
+
/* first seg */
iovec->bufs[index].vaddr = seg_data;
iovec->bufs[index].size = seg_size;
@@ -2717,7 +2732,7 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
return 0;
}
-static __rte_always_inline void
+static __rte_always_inline uint32_t
prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
struct roc_se_fc_params *param, uint32_t *flags)
{
@@ -2726,6 +2741,12 @@ prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
uint32_t seg_size = 0;
struct roc_se_iov_ptr *iovec;
+ if (unlikely(pkt->nb_segs > ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments (%u) exceeds max supported (%u)", pkt->nb_segs,
+ ROC_MAX_SG_CNT);
+ return 1;
+ }
+
seg_data = rte_pktmbuf_mtod(pkt, void *);
seg_size = pkt->data_len;
@@ -2740,7 +2761,7 @@ prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
param->bufs[0].vaddr = seg_data;
param->bufs[0].size = seg_size;
- return;
+ return 0;
}
iovec = param->src_iov;
iovec->bufs[index].vaddr = seg_data;
@@ -2764,7 +2785,7 @@ prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
}
iovec->buf_cnt = index;
- return;
+ return 0;
}
static __rte_always_inline int
@@ -2816,7 +2837,11 @@ fill_sm_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
if (m_dst == NULL) {
fc_params.dst_iov = fc_params.src_iov = (void *)src;
- prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
+ if (unlikely(prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags))) {
+ plt_dp_err("Prepare inplace src iov failed");
+ ret = -EINVAL;
+ goto err_exit;
+ }
} else {
/* Out of place processing */
fc_params.src_iov = (void *)src;
@@ -3017,7 +3042,11 @@ fill_fc_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
*/
fc_params.dst_iov = fc_params.src_iov = (void *)src;
- prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
+ if (unlikely(prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags))) {
+ plt_dp_err("Prepare inplace src iov failed");
+ ret = -EINVAL;
+ goto err_exit;
+ }
} else {
/* Out of place processing */
@@ -3165,7 +3194,11 @@ fill_pdcp_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
if (likely(m_dst == NULL || m_src == m_dst)) {
fc_params.dst_iov = fc_params.src_iov = (void *)src;
- prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
+ if (unlikely(prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags))) {
+ plt_dp_err("Prepare inplace src iov failed");
+ ret = -EINVAL;
+ goto err_exit;
+ }
} else {
/* Out of place processing */
@@ -3298,7 +3331,11 @@ fill_pdcp_chain_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
if (likely((m_dst == NULL || m_dst == m_src)) && inplace) {
fc_params.dst_iov = fc_params.src_iov = (void *)src;
- prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
+ if (unlikely(prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags))) {
+ plt_dp_err("Could not prepare inplace src iov");
+ ret = -EINVAL;
+ goto err_exit;
+ }
} else {
/* Out of place processing */
fc_params.src_iov = (void *)src;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 14/16] crypto/cnxk: bound SG iovec index in mbuf walk
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (12 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 13/16] crypto/cnxk: bound SG segment count in packet iov builders Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 15/16] crypto/cnxk: add cq_ena devarg for CPT CQ mode Tejasree Kondoj
` (2 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
prepare_iov_from_pkt() and prepare_iov_from_pkt_inplace() rely on
nb_segs to limit the number of segments written to the on-stack iovec.
Also check the index against ROC_MAX_SG_CNT inside the walk, so a chain
longer than nb_segs reports cannot overrun the buffer.
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cnxk_se.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index a3c3c3ce86..b93a2bfaf8 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -2720,6 +2720,11 @@ prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_
if (!seg_size)
break;
+ if (unlikely(index >= ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments exceeds max supported (%u)", ROC_MAX_SG_CNT);
+ return 1;
+ }
+
iovec->bufs[index].vaddr = seg_data;
iovec->bufs[index].size = seg_size;
@@ -2776,6 +2781,11 @@ prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
if (!seg_size)
break;
+ if (unlikely(index >= ROC_MAX_SG_CNT)) {
+ plt_dp_err("Number of segments exceeds max supported (%u)", ROC_MAX_SG_CNT);
+ return 1;
+ }
+
iovec->bufs[index].vaddr = seg_data;
iovec->bufs[index].size = seg_size;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 15/16] crypto/cnxk: add cq_ena devarg for CPT CQ mode
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (13 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 14/16] crypto/cnxk: bound SG iovec index in mbuf walk Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-19 13:07 ` [PATCH 16/16] crypto/cnxk: size CN20K IPsec SA by context length Tejasree Kondoj
2026-10-22 18:46 ` [PATCH 00/16] fixes and improvements to cnxk crypto PMD Akhil Goyal
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
Add a cq_ena devarg (0 or 1, default 0) to control whether the CPT
completion queue is used on CN20K crypto queue pairs. When set to
0, completions are written to res_addr. When set to 1, completions
are reported through the CPT CQ for all instructions.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
doc/guides/cryptodevs/cnxk.rst | 16 +++++++++++
drivers/common/cnxk/roc_cpt.c | 10 ++++---
drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 2 +-
drivers/crypto/cnxk/cnxk_cryptodev.h | 1 +
drivers/crypto/cnxk/cnxk_cryptodev_devargs.c | 28 +++++++++++++++++++-
drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 3 ++-
drivers/crypto/cnxk/cnxk_cryptodev_ops.h | 2 ++
7 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/doc/guides/cryptodevs/cnxk.rst b/doc/guides/cryptodevs/cnxk.rst
index c0392f4f9c..3c90a12dca 100644
--- a/doc/guides/cryptodevs/cnxk.rst
+++ b/doc/guides/cryptodevs/cnxk.rst
@@ -211,6 +211,22 @@ Runtime Config Options
With the above configuration, CPT initial context fetch size
will be set to ``4+1`` 128 bytes blocks.
+- ``CPT completion queue enable`` (default ``0``)
+
+ Controls whether the CPT completion queue (CQ) is used for all instructions
+ on CN20K. Can be configured during runtime by using ``cq_ena`` ``devargs``
+ parameter. Accepted values are ``0`` and ``1``.
+
+ When set to ``1``, completions of all instructions are reported through the
+ CQ. When set to ``0``, completions are written to the result address
+ (``res_addr``) of the instruction instead.
+
+ For example::
+
+ -a 0002:20:00.1,cq_ena=1
+
+ With the above configuration, CPT completions are reported through the CPT CQ.
+
Debugging Options
-----------------
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index eae3f134e9..645c205480 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -704,10 +704,12 @@ cpt_lf_cq_init(struct roc_cpt_lf *lf)
/* Disable CPT completion queue */
roc_cpt_cq_disable(lf);
- /* Set completion queue (CQ) base address */
- len = lf->cq_size;
- if (roc_model_is_cn20k() && lf->cq_all)
- len++;
+ /* Set completion queue (CQ) base address.
+ * On CN20K the pending-queue pointer (req_queue) is always positioned
+ * at cq_vaddr + 1 entry so that the hardware-managed reserved slot
+ * sits at cq_vaddr[0]. Allocate the extra entry unconditionally.
+ */
+ len = lf->cq_size + 1;
len = PLT_ALIGN(len * (ROC_CPT_CQ_ENTRY_SIZE_UNIT << lf->cq_entry_size), ROC_ALIGN);
lf->cq_vaddr = plt_zmalloc(len, ROC_ALIGN);
if (lf->cq_vaddr == NULL)
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index bb3384023f..c654dbf88d 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -261,7 +261,7 @@ cn20k_cpt_fill_inst(struct cnxk_cpt_qp *qp, struct rte_crypto_op *ops[], struct
}
inst[0].res_addr = (uint64_t)&infl_req->res;
- inst[0].cq_ena = 1;
+ inst[0].cq_ena = qp->inst_cq_ena;
rte_atomic_store_explicit((RTE_ATOMIC(uint64_t) *)(&infl_req->res.u64[0]), res.u64[0],
rte_memory_order_relaxed);
infl_req->cop = op;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index bdc5752905..4ce2cb255a 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -39,6 +39,7 @@ struct cnxk_cpt_vf {
uint16_t max_qps_limit;
uint16_t rx_inject_qp;
uint8_t ctx_ilen;
+ bool cq_ena;
};
uint64_t cnxk_cpt_default_ff_get(void);
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_devargs.c b/drivers/crypto/cnxk/cnxk_cryptodev_devargs.c
index 3623e5aa76..ff0ddb6ed8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_devargs.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_devargs.c
@@ -14,6 +14,7 @@
#define CNXK_RX_INJECT_QP "rx_inject_qp"
#define CNXK_CPT_CTX_ILEN "ctx_ilen"
#define CNXK_MAX_CPT_CTX_ILEN 7
+#define CNXK_CPT_CQ_ENA "cq_ena"
static int
parse_rx_inject_qp(const char *key, const char *value, void *extra_args)
@@ -82,6 +83,21 @@ parse_cpt_ctx_ilen(const char *key, const char *value, void *extra_args)
return 0;
}
+static int
+parse_cpt_cq_ena(const char *key, const char *value, void *extra_args)
+{
+ RTE_SET_USED(key);
+ uint32_t val;
+
+ val = atoi(value);
+ if (val > 1)
+ return -EINVAL;
+
+ *(bool *)extra_args = val ? true : false;
+
+ return 0;
+}
+
int
cnxk_cpt_parse_devargs(struct rte_devargs *devargs, struct cnxk_cpt_vf *vf)
{
@@ -89,6 +105,7 @@ cnxk_cpt_parse_devargs(struct rte_devargs *devargs, struct cnxk_cpt_vf *vf)
struct rte_kvargs *kvlist;
uint16_t rx_inject_qp;
uint16_t ctx_ilen = 0;
+ bool cq_ena = false;
int rc;
/* Set to max value as default so that the feature is disabled by default. */
@@ -126,16 +143,25 @@ cnxk_cpt_parse_devargs(struct rte_devargs *devargs, struct cnxk_cpt_vf *vf)
goto exit;
}
+ rc = rte_kvargs_process(kvlist, CNXK_CPT_CQ_ENA, parse_cpt_cq_ena, &cq_ena);
+ if (rc < 0) {
+ plt_err("cq_ena should be 0 or 1");
+ rte_kvargs_free(kvlist);
+ goto exit;
+ }
+
rte_kvargs_free(kvlist);
null_devargs:
vf->max_qps_limit = max_qps_limit;
vf->rx_inject_qp = rx_inject_qp;
vf->cpt.ctx_ilen = ctx_ilen;
+ vf->cq_ena = cq_ena;
return 0;
exit:
return -EINVAL;
}
-RTE_PMD_REGISTER_PARAM_STRING(crypto_cnxk, CNXK_MAX_QPS_LIMIT "=<1-63>");
+RTE_PMD_REGISTER_PARAM_STRING(crypto_cnxk, CNXK_MAX_QPS_LIMIT "=<1-63> " CNXK_CPT_CQ_ENA
+ "=<0-1> " CNXK_CPT_CTX_ILEN "=<0-7>");
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index 95f64a79ae..a5b8aff146 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -535,7 +535,8 @@ cnxk_cpt_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
/* CQ entry size is 128B(32 << 2) */
qp->lf.cq_entry_size = 2;
qp->lf.cq_size = nb_desc;
- qp->lf.cq_all = true;
+ qp->lf.cq_all = vf->cq_ena;
+ qp->inst_cq_ena = vf->cq_ena;
}
ret = roc_cpt_lf_init(roc_cpt, &qp->lf);
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index 7bf26d67dc..6c4265f339 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -108,6 +108,8 @@ struct crypto_adpter_info {
struct cnxk_cpt_qp {
struct roc_cpt_lf lf;
/**< Crypto LF */
+ bool inst_cq_ena;
+ /**< Set CQ enable bit on instructions */
struct pending_queue pend_q;
/**< Pending queue */
struct roc_cpt_lmtline lmtline;
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 16/16] crypto/cnxk: size CN20K IPsec SA by context length
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (14 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 15/16] crypto/cnxk: add cq_ena devarg for CPT CQ mode Tejasree Kondoj
@ 2026-10-19 13:07 ` Tejasree Kondoj
2026-10-22 18:46 ` [PATCH 00/16] fixes and improvements to cnxk crypto PMD Akhil Goyal
16 siblings, 0 replies; 18+ messages in thread
From: Tejasree Kondoj @ 2026-10-19 13:07 UTC (permalink / raw)
To: Akhil Goyal
Cc: Rupesh Chiluka, Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi,
Nithin Dabilpuram, dev
From: Rupesh Chiluka <rchiluka@marvell.com>
Allocate the CN20K inbound/outbound IPsec SA with a size of at least
(ctx_ilen + 1) * 128 bytes when ctx_ilen is set, so larger contexts
such as a 1 KiB SA are supported. Zero the full allocation instead of
only the default SA size.
Also advertise ctx_ilen in the PMD param string.
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
drivers/crypto/cnxk/cn20k_ipsec.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/cnxk/cn20k_ipsec.c b/drivers/crypto/cnxk/cn20k_ipsec.c
index b2cab4ff5f..c7fe670724 100644
--- a/drivers/crypto/cnxk/cn20k_ipsec.c
+++ b/drivers/crypto/cnxk/cn20k_ipsec.c
@@ -31,12 +31,17 @@ cn20k_ipsec_outb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
struct cnxk_ipsec_outb_rlens rlens;
struct cn20k_ipsec_sa *sa;
union cpt_inst_w4 inst_w4;
+ size_t out_sa_sz;
void *out_sa;
int ret = 0;
sa = &sec_sess->sa;
- out_sa = rte_zmalloc("cn20k_cpt", sizeof(struct roc_ow_ipsec_outb_sa), ROC_CPTR_ALIGN);
+ out_sa_sz = sizeof(struct roc_ow_ipsec_outb_sa);
+ if (roc_cpt->ctx_ilen)
+ out_sa_sz = PLT_MAX(out_sa_sz, (size_t)(roc_cpt->ctx_ilen + 1) * ROC_CTX_UNIT_128B);
+
+ out_sa = rte_zmalloc("cn20k_cpt", out_sa_sz, ROC_CPTR_ALIGN);
if (out_sa == NULL) {
plt_err("Couldn't allocate memory for outbound SA");
return -ENOMEM;
@@ -124,7 +129,7 @@ cn20k_ipsec_outb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
sa_dptr->w0.s.count_glb_octets = 1;
}
- memset(out_sa, 0, sizeof(struct roc_ow_ipsec_outb_sa));
+ memset(out_sa, 0, out_sa_sz);
/* Copy word0 from sa_dptr to populate ctx_push_sz ctx_size fields */
memcpy(out_sa, sa_dptr, 8);
@@ -161,12 +166,17 @@ cn20k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
struct roc_ow_ipsec_inb_sa *sa_dptr;
struct cn20k_ipsec_sa *sa;
union cpt_inst_w4 inst_w4;
+ size_t in_sa_sz;
void *in_sa;
int ret = 0;
sa = &sec_sess->sa;
- in_sa = rte_zmalloc("cn20k_cpt", sizeof(struct roc_ow_ipsec_inb_sa), ROC_CPTR_ALIGN);
+ in_sa_sz = sizeof(struct roc_ow_ipsec_inb_sa);
+ if (roc_cpt->ctx_ilen)
+ in_sa_sz = PLT_MAX(in_sa_sz, (size_t)(roc_cpt->ctx_ilen + 1) * ROC_CTX_UNIT_128B);
+
+ in_sa = rte_zmalloc("cn20k_cpt", in_sa_sz, ROC_CPTR_ALIGN);
if (in_sa == NULL) {
plt_err("Couldn't allocate memory for inbound SA");
return -ENOMEM;
@@ -231,7 +241,7 @@ cn20k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
sa_dptr->w0.s.count_glb_octets = 1;
}
- memset(in_sa, 0, sizeof(struct roc_ow_ipsec_inb_sa));
+ memset(in_sa, 0, in_sa_sz);
/* Copy word0 from sa_dptr to populate ctx_push_sz ctx_size fields */
memcpy(in_sa, sa_dptr, 8);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* RE: [PATCH 00/16] fixes and improvements to cnxk crypto PMD
2026-10-19 13:07 [PATCH 00/16] fixes and improvements to cnxk crypto PMD Tejasree Kondoj
` (15 preceding siblings ...)
2026-10-19 13:07 ` [PATCH 16/16] crypto/cnxk: size CN20K IPsec SA by context length Tejasree Kondoj
@ 2026-10-22 18:46 ` Akhil Goyal
16 siblings, 0 replies; 18+ messages in thread
From: Akhil Goyal @ 2026-10-22 18:46 UTC (permalink / raw)
To: Tejasree Kondoj
Cc: Anoob Joseph, Vidya Sagar Velumuri, Ankur Dwivedi, Rupesh Chiluka,
Nithin Kumar Dabilpuram, dev@dpdk.org
> -----Original Message-----
> From: Tejasree Kondoj <ktejasree@marvell.com>
> Sent: Monday, October 19, 2026 6:38 PM
> To: Akhil Goyal <gakhil@marvell.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Vidya Sagar Velumuri
> <vvelumuri@marvell.com>; Ankur Dwivedi <adwivedi@marvell.com>; Rupesh
> Chiluka <rchiluka@marvell.com>; Nithin Kumar Dabilpuram
> <ndabilpuram@marvell.com>; dev@dpdk.org
> Subject: [PATCH 00/16] fixes and improvements to cnxk crypto PMD
>
> This series adds improvements and fixes to cnxk crypto PMD.
>
> Rupesh Chiluka (11):
> common/cnxk: validate cipher key length in IPsec SA fill
> crypto/cnxk: reject truncated TLS records in decrypt
> crypto/cnxk: validate TLS xform and keys before SA key copy
> crypto/cnxk: reject oversized SG vectors in raw datapath
> crypto/cnxk: guard trim len bounds in TLS 1.2 MAC trim
> crypto/cnxk: guard trim len in TLS 1.2 MAC trim for CN20K
> crypto/cnxk: validate TLS 1.2 MAC trim lengths
> crypto/cnxk: bound SG segment count in packet iov builders
> crypto/cnxk: bound SG iovec index in mbuf walk
> crypto/cnxk: add cq_ena devarg for CPT CQ mode
> crypto/cnxk: size CN20K IPsec SA by context length
>
> Tejasree Kondoj (5):
> common/cnxk: use context invalidate for cn20k
> crypto/cnxk: return HW CPTR from cptr_get for cn20k
> crypto/cnxk: enable cq_all and allocate extra CQ line
> crypto/cnxk: fix CN20K CPT error recovery
> crypto/cnxk: enable ctx cache for cn20k crypto
>
> doc/guides/cryptodevs/cnxk.rst | 16 ++++
> drivers/common/cnxk/cnxk_security.c | 15 ++-
> drivers/common/cnxk/roc_cpt.c | 97 +++++++++++++++++---
> drivers/common/cnxk/roc_cpt.h | 3 +
> drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 36 ++++++--
> drivers/crypto/cnxk/cn10k_tls.c | 33 ++++++-
> drivers/crypto/cnxk/cn10k_tls_ops.h | 12 +++
> drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 39 ++++++--
> drivers/crypto/cnxk/cn20k_ipsec.c | 42 +++------
> drivers/crypto/cnxk/cn20k_tls.c | 73 +++++++--------
> drivers/crypto/cnxk/cn20k_tls_ops.h | 6 ++
> drivers/crypto/cnxk/cnxk_cryptodev.h | 1 +
> drivers/crypto/cnxk/cnxk_cryptodev_devargs.c | 28 +++++-
> drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 10 +-
> drivers/crypto/cnxk/cnxk_cryptodev_ops.h | 4 +-
> drivers/crypto/cnxk/cnxk_se.h | 84 +++++++++++++++--
> 16 files changed, 389 insertions(+), 110 deletions(-)
Series Applied to dpdk-next-crypto
Thanks.
^ permalink raw reply [flat|nested] 18+ messages in thread