All of lore.kernel.org
 help / color / mirror / Atom feed
From: bugzilla@dpdk.org
To: dev@dpdk.org
Subject: [DPDK/cryptodev Bug 1999] cnxk ON common SA 3DES key overflow
Date: Fri, 28 Aug 2026 10:32:23 +0000	[thread overview]
Message-ID: <bug-1999-3@https.bugs.dpdk.org/> (raw)

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

            Bug ID: 1999
           Summary: cnxk ON common SA 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 would like to report what appears to be a real current-head intra-object
overflow in the `cnxk` ON-family IPsec security-SA creation path. I rechecked
current `main` on 2026-03-10 before writing this report.


The relevant issue is in `drivers/common/cnxk/cnxk_security.c`.


The front-door logic accepts `DES` / `3DES` by setting `enc_type`, but it only
performs an AES-family key-length switch:


```c
if (cipher_xform != NULL) {
    switch (cipher_xform->cipher.algo) {
    case RTE_CRYPTO_CIPHER_DES_CBC:
        ctl->enc_type = ROC_IE_SA_ENC_DES_CBC;
        break;
    case RTE_CRYPTO_CIPHER_3DES_CBC:
        ctl->enc_type = ROC_IE_SA_ENC_3DES_CBC;
        break;
    case RTE_CRYPTO_CIPHER_AES_CBC:
    case RTE_CRYPTO_CIPHER_AES_CTR:
        aes_key_len = cipher_xform->cipher.key.length;
        break;
    }
}


if (ctl->enc_type == ROC_IE_SA_ENC_AES_CBC ||
    ctl->enc_type == ROC_IE_SA_ENC_AES_CTR ||
    ctl->enc_type == ROC_IE_SA_ENC_AES_GCM ||
    ctl->enc_type == ROC_IE_SA_ENC_AES_CCM ||
    ctl->auth_type == ROC_IE_SA_AUTH_AES_GMAC) {
    switch (aes_key_len) {
    case 16:
    case 24:
    case 32:
        ...
    default:
        return -EINVAL;
    }
}
```


Later in the same helper, the full runtime key length is copied into a fixed
in-object array with no upper bound:


```c
cipher_key = cipher_xform->cipher.key.data;
cipher_key_len = cipher_xform->cipher.key.length;
...
if (cipher_key_len != 0)
    memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
```


The affected object layout is:


```c
struct roc_ie_on_common_sa {
    struct roc_ie_on_sa_ctl ctl;
    uint8_t cipher_key[32];
    union roc_ie_on_bit_perfect_iv iv;
    ...
};
```


So any `DES` / `3DES` key longer than `32` bytes writes past `cipher_key[32]`
and into the adjacent live `iv` member.


Why I think this is a real bug and not just a capability-metadata concern:


- the DPDK security core does not enforce cipher key sizes before calling the
driver:


```c
if (instance->ops->session_create(instance->device, conf, sess)) {
    rte_mempool_put(mp, (void *)sess);
    return NULL;
}
```


- the driver contract in `rte_security_driver.h` says invalid or unsupported
transforms should be rejected, not accepted after memory corruption
- the copy sink is on the real current-head caller chain:
  - `rte_security_session_create()`
  - `cn9k_eth_sec_session_create()`
  - `cnxk_on_ipsec_outb_sa_create()`
  - `on_fill_ipsec_common_sa()`
- the path still returns success after the adjacent overwrite


The cleanest concrete case is `RTE_CRYPTO_CIPHER_3DES_CBC` with a `40`-byte
key:


- first `32` bytes fill `cipher_key`
- next `8` bytes overwrite the beginning of adjacent `iv`
- the helper returns `0`


I also prepared a minimal local proof that mirrors the current-head layout and
write order. The key outputs are:


- `distance_cipher_key_to_iv=32`
- `accepted_des3_key_without_upper_bound=1`
- `provided_key_len=40`
- `returned=0`
- `overflow_bytes_into_iv=8`
- `iv_prefix_hex=4242424242424242`
- `guard_unchanged=1`


That shows the first eight bytes beyond `cipher_key[32]` already corrupt the
live adjacent `iv` member, while the modeled current-head path still returns
success.


Suggested fix:
1. Reject `DES` / `3DES` key lengths that do not match the supported runtime
contract before the copy.
2. Add a defensive check near the sink, e.g. `if (cipher_key_len >
sizeof(common_sa->cipher_key)) return -EINVAL;`.

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

                 reply	other threads:[~2026-08-28 10:32 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-1999-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.