CN20K inline IPsec 3DES key overflow
https://bugs.dpdk.org/show_bug.cgi?id=1997
Bug ID: 1997
Summary: CN20K inline IPsec 3DES key overflow
Product: DPDK
Version: unspecified
Hardware: All
OS: All
Status: UNCONFIRMED
Severity: normal
Priority: Normal
Component: cryptodev
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Group: security
Report date: 2026-03-11
Reported by: 侯朋朋 <[email protected]>
Hello DPDK maintainers,
I am reporting what looks like a real current-head intra-object overflow in the cn20k inline-IPsec Ethernet security path. I rechecked current main (8dc80afda7a52a1bd28088fe34102e7c1ba17282) on 2026-03-10 before writing this mail.
As on cn10k, the DPDK security core forwards the caller-provided configuration directly into the driver callback:
```c
if (instance->ops->session_create(instance->device, conf, sess)) {
rte_mempool_put(mp, (void *)sess);
return NULL;
}
```For the cn20k inline path, current head then calls the OW SA fill helpers directly:
```c rc = cnxk_ow_ipsec_outb_sa_fill(outb_sa_dptr, ipsec, crypto, 0); ... rc = cnxk_ow_ipsec_outb_sa_fill(outb_sa_dptr, ipsec, crypto, 0); ```
and again does not first call cnxk_ipsec_xform_verify().
In the shared OW helper, 3DES is accepted by setting enc_type, but there is no exact == 24 check before the key copy:
```c
case RTE_CRYPTO_CIPHER_3DES_CBC:
w2->s.enc_type = ROC_IE_SA_ENC_3DES_CBC;
break;
...
key = cipher_xfrm->cipher.key.data;
length = cipher_xfrm->cipher.key.length;
...
if (key != NULL && length != 0) {
memcpy(cipher_key, key, length);
...
}
```The same cn20k driver publishes exact 24 for 3DES in its capability table:
```c
.key_size = {
.min = 24,
.max = 24,
.increment = 0
},
```But the runtime inline path still copies the full user-provided length into a fixed object field.
The destination object is:
```c
struct roc_ow_ipsec_outb_sa {
...
uint8_t cipher_key[ROC_CTX_MAX_CKEY_LEN];
union roc_ow_ipsec_outb_iv iv;
...
};
```with ROC_CTX_MAX_CKEY_LEN == 32.
So any 3DES key longer than 32 bytes writes into the adjacent live iv.
The cleanest concrete case is a 40-byte RTE_CRYPTO_CIPHER_3DES_CBC key:
- first 32 bytes fill cipher_key
- next 8 bytes overwrite the beginning of iv
- the helper returns 0
- cn20k_eth_sec_session_create() proceeds with SA installation
Why I think this should be accepted as a real bug:
- the path is current-head and reachable from the public session-create API
- capability metadata is not a runtime guard in this path
- the runtime code bypasses the verifier that would have enforced exact-length constraints
- the sink writes through a fixed in-object array into the next live member
- the corrupted SA is still treated as successfully created
The local proof results for the narrow 40-byte case are:
- distance_cipher_key_to_iv=32
- advertised_3des_key_max=24
- provided_key_len=40
- returned=0
- overflow_bytes_into_iv=8
- iv_prefix_hex=4242424242424242
- guard_unchanged=1
Suggested fix:
1. Enforce exact 3DES key length before cnxk_ow_ipsec_*_sa_fill() is called on the inline path.
2. Add a direct upper-bound guard before memcpy(cipher_key, key, length).
3. Reuse the same xform-length verification logic across inline and non-inline cnxk IPsec paths.
Signature · 2 lines
You are receiving this mail because: You are the assignee for the bug.