Skip to contentSkip to conversation

CN20K inline inbound AES-GMAC key overflow

DPDK/cryptodev Bug 1996 [email protected] 1 participant 1 message Aug 28

lore
Share & tools
lore
#0 lore raw

https://bugs.dpdk.org/show_bug.cgi?id=1996

Bug ID: 1996
Summary: CN20K inline inbound AES-GMAC 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 would like to report what appears to be a real current-head intra-object overflow in the cn20k inline inbound IPsec path for AES_GMAC. I rechecked current main on 2026-03-10 before writing this report.

The relevant current-head path is:

```c
cn20k_eth_sec_session_create(...)
{
    ...
    rc = cnxk_ow_ipsec_inb_sa_fill(inb_sa_dptr, ipsec, crypto, 0);
    ...
}
```

and the update path reaches the same helper.

The OW helper has the same copy-first-then-validate pattern on the AES_GMAC path:

```c
case RTE_CRYPTO_AUTH_AES_GMAC:
    w2->s.auth_type = ROC_IE_SA_AUTH_AES_GMAC;
    key = auth_xfrm->auth.key.data;
    length = auth_xfrm->auth.key.length;
    ...
    break;
...
if (key != NULL && length != 0) {
    memcpy(cipher_key, key, length);
}
...
switch (length) {
case 16:
case 24:
case 32:
    break;
default:
    return -EINVAL;
}
```

The destination object on this inbound cn20k path is:

```c
struct roc_ow_ipsec_inb_sa {
    ...
    uint8_t cipher_key[ROC_CTX_MAX_CKEY_LEN];
    union {
        struct {
            uint32_t rsvd8;
            uint8_t salt[4];
        } s;
        uint64_t u64;
    } w8;
    ...
};
```

with ROC_CTX_MAX_CKEY_LEN == 32.

So a 40-byte AES_GMAC key overwrites the adjacent member before the function reports invalid input:

- bytes 0..31 fill cipher_key[32]
- bytes 32..39 overwrite adjacent w8
- bytes 36..39 overwrite live salt[4]

Why I believe this should be accepted:

- the overwrite is in the real current-head OW helper used by inline inbound session create/update
- the destination is a fixed in-object field followed by a live adjacent member
- the bug does not depend on a crash or sanitizer output
- later -EINVAL does not undo the earlier write

The local proof results for the narrow case are:

- distance_cipher_key_to_w8=32
- distance_cipher_key_to_salt=36
- advertised_aes_gmac_key_max=32
- provided_key_len=40
- returned=-22
- overflow_bytes_into_w8=8
- overflow_bytes_into_salt=4
- w8_u64_hex=4242424242424242
- salt_prefix_hex=42424242
- guard_unchanged=1

Suggested fix:

1. Enforce AES_GMAC key length before cnxk_ow_ipsec_inb_sa_fill() is called on the inline path.
2. Add a direct length <= sizeof(cipher_key) guard before the memcpy().
3. Reuse the same crypto-length verification logic across the inline and non-inline cnxk IPsec implementations.

Signature · 2 lines
You are receiving this mail because:
You are the assignee for the bug.