Repository navigation
Bound the DER re-encode in wolfSSL_ECDSA_do_verify under WOLF_CRYPTO_CB_ONLY_ECC - #11926
yosuke-wolfssl wants to merge 2 commits into
Conversation
- In the WOLF_CRYPTO_CB_ONLY_ECC path, wolfSSL_ECDSA_do_verify() queries the encoded length with wolfSSL_i2d_ECDSA_SIG(sig, NULL) and returns WOLFSSL_FATAL_ERROR when it is not positive or exceeds the signature buffer, before encoding. - tests: add test_ECDSA_do_verify_oversized_sig, which verifies an ECDSA_SIG whose r encodes larger than ECC_MAX_SIG_SIZE. Issue: F-11725
- The WOLF_CRYPTO_CB_ONLY_ECC branch of wolfSSL_ECDSA_do_verify() compares the wc_ecc_verify_hash() return value and returns 1 on success. - tests: test_wolfSSL_EC_POINT is compiled out under WOLF_CRYPTO_CB_ONLY_ECC, matching the library's guard on wolfSSL_EC_POINT_get_affine_coordinates_GFp(). - tests: the ECDH derive part of test_wolfSSL_EVP_PKEY_encoded_public_key is compiled out under WOLF_CRYPTO_CB_ONLY_ECC, matching the EC case of wolfSSL_EVP_PKEY_derive().
|
@claude review |
|
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #11926
Scan targets checked: wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): tests/api/test_ossl_ec.h
Coverage: 2 of 3 in-scope changed file(s) opened by the reviewer; not opened: tests/api/test_ossl_ec.c
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Review tier: Lite
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. It fixes a stack buffer overflow in ECDSA verify, so a maintainer familiar with the WOLF_CRYPTO_CB_ONLY_ECC configuration should still take a look.
What was reviewed:
- The CB-only branch of
wolfSSL_ECDSA_do_verify: it queries the length withi2d(sig, NULL), rejects lengths<= 0or> sizeof(signature)before writing anything, and checks that the actual encode returns the same length. Valid signatures now return 1, because thewc_ecc_verify_hashresult is no longer stored inret. - The new test in default builds: there the oversized
ris caught bywc_ecc_check_r_s_range(r must be below the curve order), so-1is the expected result on that path too. TheNO_RSAguard covers builds whose bignums are too small to hold a 133-byter. - The new
WOLF_CRYPTO_CB_ONLY_ECCexclusions fortest_wolfSSL_EC_POINTand the ECDH set1/derive block only remove tests in that configuration.
Extended reasoning...
The change hardens the WOLF_CRYPTO_CB_ONLY_ECC branch of wolfSSL_ECDSA_do_verify in src/pk_ec.c, where caller-controlled r/s were DER-encoded into a fixed ECC_MAX_SIG_SIZE stack buffer with no bounds check. It also fixes that branch returning 0 instead of 1 for valid signatures. It adds a regression test and compiles out two tests in the CB-only configuration. This is memory-safety and signature-verification code in a crypto library, so it falls under the rule not to auto-approve security-sensitive paths, even though the diff is small and looks correct. The PR says no CI job builds CB-only together with opensslextra, so the fixed path is only covered by the author's local runs.
Problem
In builds with
OPENSSL_EXTRAandWOLF_CRYPTO_CB_ONLY_ECC,wolfSSL_ECDSA_do_verify()re-encodesr/sintobyte signature[ECC_MAX_SIG_SIZE]withi2d_ECDSA_SIG(). That call takes no capacity and passes its own computed length toStoreECC_DSA_Sig()as the limit.d2i_ECDSA_SIG()andECDSA_SIG_set0()do not boundr/sto the curve order, so an oversized INTEGER overflows the stack buffer with caller-controlled bytes. Caller-supplied DER reaches it throughEVP_PKEY_verify(),EVP_VerifyFinal()andEVP_DigestVerify[Final]().The same branch assigned the
wc_ecc_verify_hash()result toret, so a valid signature returned0instead of1.ECDSA_do_verify()and the EVP ECDSA verify APIs never succeeded in this configuration.Default builds compile neither path.
Fix (
src/pk_ec.c)wolfSSL_i2d_ECDSA_SIG(sig, NULL)runs before encoding. A length<= 0or> sizeof(signature)returnsWOLFSSL_FATAL_ERRORbefore anything is written, and the encode must return the same length.wc_ecc_verify_hash()return is compared directly, soretstays1for a valid signature.Closes f-11725.
Tests
test_ECDSA_do_verify_oversized_sig: anrthat encodes larger thanECC_MAX_SIG_SIZEmust return-1.test_wolfSSL_EC_POINTand the ECDH derive part oftest_wolfSSL_EVP_PKEY_encoded_public_keyare compiled out underWOLF_CRYPTO_CB_ONLY_ECC, matching the library guards, sounit.testlinks and runs in this configuration.Verification
No CI job builds
WOLF_CRYPTO_CB_ONLY_ECCwith--enable-opensslextra(cryptocb-only.ymlkeeps the compat layer off), so this was verified locally:stack-buffer-overflowbefore the fix and passes after it.cryptocb-only.ymleccflags +--enable-opensslextra, GCC-Werror, Ubuntu 24.04: 0 failed, 1807 passed of 2970. Master does not link; with only theEC_POINTtest guard applied, 5 fail.--enable-asn=original, ASan, boundary input (133-byter,s = 0): returns-1, no ASan errors.--enable-all, ASan: theossl_ecgroup and the guarded EVP test pass.Not in this PR: a CI job for this rare combination.