20260616-aes-fixes#10709
Conversation
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #10709
Scan targets checked: wolfcrypt-bugs, wolfcrypt-src
Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
|
a9fefc4 to
f1b8d03
Compare
Frauschi
left a comment
There was a problem hiding this comment.
Should we add test coverage for the OVERFLOW_E cases?
dgarske
left a comment
There was a problem hiding this comment.
Skoll Code Review
Scan type: reviewOverall recommendation: COMMENT
Findings: 5 total — 4 posted, 1 skipped
4 finding(s) posted as inline comments (see file-level comments below)
Posted findings
- [Low] Comment typo: 'cunulative' should be 'cumulative' —
wolfcrypt/src/aes.c:12813,12967 - [Low] Brace-on-own-line and redundant double parentheses deviate from file style —
wolfcrypt/src/aes.c:12816-12821,12970-12975 - [Low] Bare 0xffffffff literal; prefer suffixed/named constant —
wolfcrypt/src/aes.c:12817-12818,12971-12972 - [Low] Reused AES_CCM_OVERFLOW_E error string is about 'invocation counter', not input length —
wolfcrypt/src/aes.c:13621,13785
Skipped findings
- [Medium]
No tests added for new AES-GCM/CCM overflow error paths
Review generated by Skoll
| * can't currently support the maximum allowed. | ||
| */ | ||
| if ((ret == 0) && | ||
| (((aes->cSz > 0xffffffff - sz)) || |
There was a problem hiding this comment.
🔵 [Low] Bare 0xffffffff literal; prefer suffixed/named constant
The overflow bound is written as the bare literal 0xffffffff. It is functionally correct (an unsigned hex literal that fits word32 on all supported platforms, including 16-bit-int targets where it promotes to unsigned long), but the wolfSSL convention favors an explicit unsigned suffix (0xFFFFFFFFU) or a named maximum to make the word32-max intent obvious and avoid any signedness ambiguity in the subtraction.
Fix: Add a U suffix (or use a named WORD32_MAX-style constant) for clarity and consistency.
There was a problem hiding this comment.
fixed. used WOLFSSL_MAX_32BIT, a macro I wasn't previously familiar with.
| /* With a large nonce, B[] runs out of room to represent inSz, and beyond | ||
| * that, the counter itself can wrap. | ||
| */ | ||
| if ((lenSz < sizeof(inSz)) && |
There was a problem hiding this comment.
🔵 [Low] Reused AES_CCM_OVERFLOW_E error string is about 'invocation counter', not input length
The new CCM checks return AES_CCM_OVERFLOW_E, whose human-readable string (error.c:503-504) and header comment (error-crypt.h:255) describe it as 'AES-CCM invocation counter overflow'. The new condition is actually an input-length-vs-nonce-size limitation (the message length doesn't fit the CCM L field), not an invocation-counter overflow. Reusing the closest existing code is reasonable and avoids adding a new error number, but the diagnostic string may mislead someone debugging the failure. (The GCM reuse of AES_GCM_OVERFLOW_E for cumulative-size overflow is a closer semantic fit.)
Fix: Consider broadening the error string (e.g. 'AES-CCM length/counter overflow') so it covers the input-size case, or document the dual meaning. Not blocking.
There was a problem hiding this comment.
The error string does need updating. Have made a note and will fix in a follow-up PR, or if this one needs another spin for a substantive reason, will fix it here.
…esGcmEncryptUpdate(), wc_AesGcmDecryptUpdate(), wc_AesCcmEncrypt(), and wc_AesCcmEncrypt().
…"catch and error on total length overflow".
f1b8d03 to
1070384
Compare
dgarske
left a comment
There was a problem hiding this comment.
Skoll Multi-Scan Review
Modes: reviewOverall recommendation: COMMENT
Findings: 3 total — 3 posted, 0 skipped
3 finding(s) posted as inline comments (see file-level comments below)
One or more scans did not complete — the results below are partial.
Posted findings
- [Low] [review] GCM aSz (AAD) overflow branch is not exercised by tests —
wolfcrypt/test/test.c:19152-19161,19179-19188 - [Low] [review] Raw sizeof in mixed-signedness comparison deviates from function's wordSz convention —
wolfcrypt/src/aes.c:13618,13782 - [Info] [review] Test code pointer style and line length deviate from wolfSSL conventions —
wolfcrypt/test/test.c:21128-21130
Review generated by Skoll
| ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); | ||
|
|
||
| #if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(7, 0, 0) | ||
| ret = wc_AesGcmEncryptUpdate(enc, resultC, p, 0xffffffff, |
There was a problem hiding this comment.
🔵 [Low] GCM aSz (AAD) overflow branch is not exercised by tests · test
The new overflow guard in wc_AesGcmEncryptUpdate/wc_AesGcmDecryptUpdate has two independent branches: aes->cSz > 0xffffffff - sz (ciphertext) and aes->aSz > 0xffffffff - authInSz (AAD). The new tests only drive the ciphertext branch by passing sz = 0xffffffff with authInSz = 0. The AAD-accumulation branch (aes->aSz overflow) is never tested, so a regression in that condition would go undetected.
Fix: Add a test that triggers the aSz overflow branch so both conditions of the new guard are covered. Add a symmetric case that passes a large authInSz (e.g. authIn buffer with authInSz = 0xffffffff and sz = 0) after a prior update that left aes->aSz > 0, asserting AES_GCM_OVERFLOW_E.
| /* With a large nonce, B[] runs out of room to represent inSz, and beyond | ||
| * that, the counter itself can wrap. | ||
| */ | ||
| if ((lenSz < sizeof(inSz)) && |
There was a problem hiding this comment.
🔵 [Low] Raw sizeof in mixed-signedness comparison deviates from function's wordSz convention · convention
The new check (lenSz < sizeof(inSz)) compares lenSz (a byte, integer-promoted to signed int) against sizeof(inSz) (size_t, unsigned). Both functions already define const word32 wordSz = (word32)sizeof(word32); precisely to avoid comparing against a raw sizeof (used in the loop a few lines below). Using the raw sizeof here is inconsistent with that local convention; depending on warning flags it can also surface as a signed/unsigned comparison note. The logic itself is correct (lenSz is small and non-negative).
Fix: Use the existing wordSz (with an explicit cast on lenSz) to keep the comparison consistent with the rest of the function and avoid mixed-signedness: if (((word32)lenSz < wordSz) && (inSz >= ((word32)1 << (lenSz * 8)))) { return AES_CCM_OVERFLOW_E; }
There was a problem hiding this comment.
Not something to fix. The same new code pattern is used at 10 different code points, with widely varying local context. wordSz is only available at 2 of them. It is more useful to keep the checks identical, than to fork 2 of the 10 to leverage the (pointless) wordSz stack allocation.
| wc_static_assert(sizeof(iv) >= 13); | ||
| word32 clear_size = ((word32)1 << 16); | ||
| word32 cipher_size = ((word32)1 << 16); | ||
| byte *large_alloc = (byte *)XMALLOC(clear_size + cipher_size, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); |
There was a problem hiding this comment.
⚪ [Info] Test code pointer style and line length deviate from wolfSSL conventions · style
The new allocation in the CCM large-buffer test uses byte *large_alloc / byte *clear / byte *cipher and (byte *) casts rather than the wolfSSL byte* x placement, and line 21128 (byte *large_alloc = (byte *)XMALLOC(...)) exceeds the project's ~80-column width. The scoped { ... } block is justified (it bounds the malloc lifetime and frees on every path before goto out), so only the pointer style and line width are at issue. New-code-only nit; pre-existing mixed styles in test.c are out of scope.
Fix: Adopt byte* pointer placement and wrap the long XMALLOC line to stay within the column limit for new code.
There was a problem hiding this comment.
Fixed the line length.
The incumbent code in aesccm_128_badarg_test() uses the form I'm using here (e.g. casts by (const byte *)).
| */ | ||
| if ((ret == 0) && | ||
| ((aes->cSz > 0xffffffff - sz) || | ||
| (aes->aSz > 0xffffffff - authInSz))) |
There was a problem hiding this comment.
It this is for WOLFSSL_MAX_32BIT values I think we should use the macro available.
There was a problem hiding this comment.
Definitely the right idea! Fixing. This could protect us from build failures on weird targets in the future.
…c/port/riscv/riscv-64-aes.c, wolfcrypt/src/port/silabs/silabs_aes.c, wolfcrypt/src/port/ti/ti-aes.c: implement AES-CCM counter overflow checks for ports;
wolfcrypt/test/test.c: add missing !HAVE_SELFTEST gate around AES-CCM counter overflow test in aesccm_128_badarg_test();
wolfcrypt/src/error.c and wolfssl/wolfcrypt/error-crypt.h: update messages for AES_{GCM,CCM}_OVERFLOW_E.
…her than magic 0xffffffff; wolfcrypt/test/test.c: in aesgcm_stream_test(), implement tests for sSz overflow, and in aesccm_128_badarg_test(), fix line length.
wolfcrypt/src/aes.c: catch and error on total length overflow inwc_AesGcmEncryptUpdate(),wc_AesGcmDecryptUpdate(),wc_AesCcmEncrypt(), andwc_AesCcmEncrypt().tested with