Fix AES-GCM nonce reuse in the async encrypt path - #11175
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a critical TLS 1.2 AES-GCM security issue where the nonce/counter in wc_AesGcmEncrypt_ex() was not advanced when an asynchronous crypto backend reported a successful submission via WC_PENDING_E, allowing nonce reuse under a single traffic key. It also hardens nonce handling by using ivOut as the stable nonce buffer for backends that treat aes->reg as scratch space, and adds regression tests to detect nonce reuse in both the raw crypto API and the TLS record layer.
Changes:
- Advance the internal nonce counter on both
0andWC_PENDING_Ereturns inwc_AesGcmEncrypt_ex()/wc_AesCcmEncrypt_ex(), and ensure the consumed nonce is passed/stored viaivOutrather than relying onaes->reg. - Apply analogous nonce handling adjustments in the TI AES port’s
_ex()encrypt paths. - Add new API- and TLS-level tests that validate nonce uniqueness (and correct increment/carry behavior) across multiple encryptions/records.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| wolfcrypt/src/port/ti/ti-aes.c | Uses ivOut as the nonce source for encrypt calls and restores aes->reg after backend use to avoid scratch-space corruption. |
| wolfcrypt/src/aes.c | Fixes async nonce reuse by advancing the nonce counter on WC_PENDING_E and makes nonce storage stable via ivOut. |
| tests/api/test_tls.h | Registers the new TLS nonce-uniqueness test. |
| tests/api/test_tls.c | Adds a TLS 1.2 AES-GCM record-level test ensuring explicit nonces on the wire never repeat. |
| tests/api/test_aes.h | Registers new AES _ex() nonce-uniqueness tests. |
| tests/api/test_aes.c | Adds API-level tests for nonce uniqueness/increment/carry for AES-GCM/CCM _ex() encrypt paths (including async submission behavior for GCM). |
| doc/dox_comments/header_files/aes.h | Updates Doxygen for _ex() APIs to document nonce/IV behavior and async buffer-lifetime expectations. |
Suppressed comments (1)
doc/dox_comments/header_files/aes.h:2936
- The nonce-counter behavior is documented as “advanced on every call”, but the code only advances the nonce counter when a nonce is actually consumed (success / async submission). The current wording (and the note about failure behavior) is likely to misstate what happens when the call fails before consuming a nonce.
The nonce is taken from an internal counter that is advanced on every
call, so no two calls under one key produce the same nonce. ivOut must not
overlap out, in, authTag or authIn: the buffer is the working copy of the
nonce that was consumed, and overwriting it corrupts the counter for the
next call. ivOut may be written even when the function returns an error -
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11175
Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src
Findings: 5
5 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
Description
wc_AesGcmEncrypt_ex()reports the nonce it consumed viaivOutand advances an internal counter so no two records share a nonce under one key. The counter only advanced whenwc_AesGcmEncrypt()returned 0; but an async backend reports a successful submission withWC_PENDING_E.Fixes zd22291
Testing
test_wc_AesGcmEncrypt_ex_NonceUniquetest_wc_AesCcmEncrypt_ex_NonceUniquetest_tls12_aesgcm_record_nonce_uniqueChecklist