All of lore.kernel.org
 help / color / mirror / Atom feed
From: bugzilla@dpdk.org
To: dev@dpdk.org
Subject: [DPDK/cryptodev Bug 1997] CN20K inline IPsec 3DES key overflow
Date: Fri, 28 Aug 2026 10:29:57 +0000	[thread overview]
Message-ID: <bug-1997-3@https.bugs.dpdk.org/> (raw)

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: dev@dpdk.org
          Reporter: thomas@monjalon.net
  Target Milestone: ---
             Group: security

Report date: 2026-03-11
Reported by: 侯朋朋 <pengpeng@iscas.ac.cn>

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.

-- 
You are receiving this mail because:
You are the assignee for the bug.

                 reply	other threads:[~2026-08-28 10:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-1997-3@https.bugs.dpdk.org/ \
    --to=bugzilla@dpdk.org \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.