fix: bound ECDSA r/s before copy in PSoC6 verify (stack overflow)#10921
Open
MarkAtwood wants to merge 1 commit into
Open
fix: bound ECDSA r/s before copy in PSoC6 verify (stack overflow)#10921MarkAtwood wants to merge 1 commit into
MarkAtwood wants to merge 1 commit into
Conversation
psoc6_ecc_verify_hash_ex copied mp_unsigned_bin_size(r/s) bytes of attacker-controlled signature into the fixed signature_buf keyed only on keySz, with no upper bound on r/s. The generic path guards this via wc_ecc_check_r_s_range(), which is compiled out for WOLFSSL_PSOC6_CRYPTO and skipped by the early return in wc_ecc_verify_hash_ex. Reject rSz/sSz > keySz before the copies, preventing a stack buffer overflow. Also correct three inverted error returns in the same function: 'return -BAD_FUNC_ARG' returned +173 (BAD_FUNC_ARG is already -173), violating the negative-error contract; two predate this change. Add a path-agnostic negative test (oversized r/s of keySz+1 bytes) to test_wc_EccDecisionCoverage2: exercises wc_ecc_check_r_s_range on software builds and the new guard under WOLFSSL_PSOC6_CRYPTO on-device. Found by Fenrir (finding 6778).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the PSoC6 hardware ECDSA verify path against stack buffer overflow by bounding attacker-controlled ECDSA signature component sizes before copying into a fixed-size stack buffer, and adds a regression test to ensure oversized r/s values are rejected.
Changes:
- Fix inverted error returns in
psoc6_ecc_verify_hash_ex()(returningBAD_FUNC_ARGinstead of-BAD_FUNC_ARG). - Reject signatures where
rSzorsSzexceed the curve byte size (keySz) before copying intosignature_buf. - Add a negative test case that constructs
r/swithkeySz + 1bytes and asserts verification fails.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| wolfcrypt/src/port/cypress/psoc6_crypto.c | Add rSz/sSz > keySz guard and correct BAD_FUNC_ARG returns to prevent stack overflow in PSoC6 ECDSA verify. |
| tests/api/test_ecc.c | Add a path-agnostic negative test for oversized r/s inputs in wc_ecc_verify_hash_ex(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
2095
to
+2096
| if (!key || !verif_res || !r || !s || !hash) | ||
| return -BAD_FUNC_ARG; | ||
| return BAD_FUNC_ARG; |
Contributor
|
jenkins retest this please |
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.
psoc6_ecc_verify_hash_ex()copies the signature's r and s components into a fixed 132-byte stack buffer sized for the largest supported curve:keySzis bounded (keySz > MAX_ECC_KEYSIZEis rejected), butrSz/sSzare not. In a verify operation r and s come straight from the attacker-supplied signature, so an oversized r or s overflowssignature_bufon the stack.The generic path guards this with
wc_ecc_check_r_s_range()(rejects r,s outside[1, order-1]), but that function is#if !defined(WOLFSSL_PSOC6_CRYPTO)— compiled out for this port — andwc_ecc_verify_hash_ex()returns early intopsoc6_ecc_verify_hash_ex()before the check would run.Fix: reject
rSz > keySz || sSz > keySzbefore the copies, mirroring the adjacentkeySzguard. A valid ECDSA r,s is in[1, order-1]and always fits inkeySzbytes, so this rejects nothing legitimate.Verification. The PSoC6 port needs Cypress PDL headers/hardware and can't be built or run here, so this is a code-read fix. I modeled the exact buffer arithmetic in a standalone harness under AddressSanitizer: pre-fix, an oversized r (200 bytes, secp256r1 keySz=32) triggers
stack-buffer-overflowin the r/s copy; post-fix it's rejected and a valid signature (rSz/sSz ≤ keySz) still passes. Runtime confirmation on real PSoC6 hardware would be welcome.Scope note. The STM32 PKA path (
WOLFSSL_STM32_PKA) has the same early-return-before-check structure; I left it untouched since I only verified the PSoC6 buffer arithmetic. Worth a look by someone with that hardware.Found by Fenrir (finding 6778).
Update after Skoll self-review: also corrected three inverted error returns in this function (
return -BAD_FUNC_ARGreturned +173, sinceBAD_FUNC_ARGis already -173 — two predate this change), and added a path-agnostic negative test (oversized r/s of keySz+1 bytes) totest_wc_EccDecisionCoverage2that exerciseswc_ecc_check_r_s_range()on software builds and the new guard on-device. Verified: the test passes on a software build and fails under a negative control (asserting the oversized signature must not verify).