fix: EVP_CIPHER_iv_length returns 0 for AES-CFB128 and AES-OFB (ZD-21730)#10364
Open
MarkAtwood wants to merge 3 commits intowolfSSL:masterfrom
Open
fix: EVP_CIPHER_iv_length returns 0 for AES-CFB128 and AES-OFB (ZD-21730)#10364MarkAtwood wants to merge 3 commits intowolfSSL:masterfrom
MarkAtwood wants to merge 3 commits intowolfSSL:masterfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes incorrect IV length reporting for AES CFB/OFB cipher descriptors in the OpenSSL-compat EVP API, preventing callers from accidentally using zero-length/uninitialized IVs.
Changes:
- Add missing AES-OFB and AES-CFB* name mappings to
wolfSSL_EVP_CIPHER_iv_length()so they returnWC_AES_BLOCK_SIZEinstead of falling through to0. - Extend
test_wolfSSL_EVP_CIPHER_iv_lengthto cover AES-CFB128 and AES-OFB NIDs. - Tighten Curve25519 private scalar clamping validation to enforce RFC 7748 §5 rule requiring bit 6 of the last byte to be set, and add a regression test.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
wolfcrypt/src/evp.c |
Adds AES CFB/OFB descriptors to the string-based IV length mapping. |
tests/api/test_evp_cipher.c |
Adds coverage ensuring AES-CFB128 and AES-OFB IV lengths are 16 bytes. |
wolfcrypt/src/curve25519.c |
Enforces the missing RFC 7748 clamping invariant (last-byte bit 6 set). |
tests/api/test_curve25519.c |
Adds a regression test validating the stricter clamp check via wc_curve25519_make_pub(). |
tests/api/test_curve25519.h |
Registers the new Curve25519 clamp-check test in the API test declarations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The iv_length test used EVP_get_cipherbynid(NID_aes_128_cfb128) which returned NULL because the switch had no CFB128 or OFB cases, causing a segfault in EVP_CIPHER_iv_length(NULL).
dgarske
previously approved these changes
May 5, 2026
The merge-base changed after approval.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
wolfSSL_EVP_CIPHER_iv_lengthreturns 0 for all CFB and OFB cipher descriptors (CFB1, CFB8, CFB128, OFB for all three key sizes). The correct IV length for these modes is 16 bytes (AES_BLOCK_SIZE). A 0 return causes callers that size their IV buffer from the descriptor to use a zero-length or uninitialized IV on every call — silent IV reuse that destroys semantic security.Fixes Zendesk ticket ZD-21730.
Root cause
wolfSSL_EVP_CIPHER_iv_lengthis a string-comparison chain mapping cipher descriptor names to IV lengths. It has entries for AES-CBC, AES-GCM, AES-CCM, AES-CTR, AES-XTS, DES, ChaCha20, and SM4 — but the entire CFB and OFB sections are absent. No comparison matches"AES-128-CFB128"(or any CFB/OFB variant), so the function falls through toreturn 0.The companion function
wolfSSL_EVP_CIPHER_CTX_iv_length(which dispatches by integercipherTypefrom an initialized context) correctly returnsWC_AES_BLOCK_SIZEfor all CFB and OFB variants. The bug is isolated to the string-comparison version.Why it was missed
Two parallel implementations with no enforced parity. CFB and OFB were added to the CTX-based function correctly but never added to the string-based function. No shared table or generated code links the two.
CFB/OFB are later additions. The string-comparison function was written when only CBC, GCM, CCM, and CTR existed. When CFB/OFB support was added later, the developer added cipher operations, string constants, and CTX dispatch — but did not audit the string-comparison function for completeness.
Test coverage matched the bug exactly.
test_wolfSSL_EVP_CIPHER_iv_lengthcovered only the modes present in the buggy function (CBC, GCM, CTR, DES, ChaCha20-Poly1305). No test ever calledEVP_CIPHER_iv_length(EVP_aes_128_cfb128()).Silent failure. Returning 0 is valid for stream ciphers (RC4), so no assertion fires. A caller must know independently that 0 is wrong for CFB128 to notice.
How we fixed it
wolfcrypt/src/evp.c— Added 12 missing entries towolfSSL_EVP_CIPHER_iv_lengthinside the existing#ifndef NO_AESblock, after the XTS section. Gated by the same compile guards as the corresponding string constant declarations (WOLFSSL_AES_CFB,WOLFSSL_NO_AES_CFB_1_8,WOLFSSL_AES_OFB, and per-keysizeWOLFSSL_AES_128/192/256):WC_AES_BLOCK_SIZEWC_AES_BLOCK_SIZE(gated!WOLFSSL_NO_AES_CFB_1_8)WC_AES_BLOCK_SIZE(gated!WOLFSSL_NO_AES_CFB_1_8)WC_AES_BLOCK_SIZEtests/api/test_evp_cipher.c— Extendedtest_wolfSSL_EVP_CIPHER_iv_lengthto include CFB128 and OFB NIDs in thenids[]/iv_lengths[]parallel arrays. These returned 0 before the fix and 16 after. The independent oracle is NIST SP 800-38A, which specifies a 16-byte IV for all AES feedback modes.Test plan
./wolfcrypt/test/testwolfcryptpasses./tests/unit.testpasses (test 659test_wolfSSL_EVP_CIPHER_iv_lengthpasses and now covers CFB128 and OFB)EVP_CIPHER_iv_length(EVP_aes_128_cfb128())returns 16, not 0