CVE-2026-5466: Verified Repro With Script Download
CVE-2026-5466: wolfSSL: ECCSI universal signature forgery via missing scalar range check
CVE-2026-5466 is verified against wolfssl · source. Affected versions: < 5.9.1. Fixed in 5.9.1. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00173.
What Is CVE-2026-5466?
CVE-2026-5466 is a high-severity universal signature forgery vulnerability in wolfSSL's implementation of ECCSI (RFC 6507 Elliptic Curve-based Certificateless Signatures for Identity-based Encryption). Pruva reproduced it (reproduction REPRO-2026-00173).
CVE-2026-5466 Severity & CVSS Score
CVE-2026-5466 is rated high severity, with a CVSS base score of 8.1 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
Affected wolfssl Versions
wolfssl · source versions < 5.9.1 are affected.
How to Reproduce CVE-2026-5466
pruva-verify REPRO-2026-00173 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00173/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-5466
Reproduced by Pruva's autonomous agents — 159 tool calls over 16 min. Full root-cause analysis and the complete transcript are below.
Systematic variant analysis of CVE-2026-5466 (wolfSSL ECCSI universal signature forgery). Ten distinct bypass and alternate-trigger attempts were tested against the fixed version (v5.9.1-stable). No bypass or alternate entry point was found. The upstream fix comprehensively covers the only ECCSI verification path.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-5466
wolfSSL's implementation of ECCSI (RFC 6507 — Elliptic Curve-based Certificateless Signatures for Identity-based Encryption) contains a critical flaw in wc_VerifyEccsiHash where the scalar signature components r and s are decoded from the signature buffer using mp_read_unsigned_bin without validating that they lie in the mathematically required range [1, q-1] (where q is the curve order). When either scalar is zero, the subsequent verification arithmetic collapses to identities that the verifier mistakes for a valid signature. An attacker can craft a forged signature with r = 0, s = 0 (or other trivial constants) that passes verification for any message under any identity without possessing any private key material.
- Package/Component: wolfSSL —
wolfcrypt/src/eccsi.c, specifically thewc_VerifyEccsiHashverifier andeccsi_calc_jhelper - Affected Versions: wolfSSL
< 5.9.1(last vulnerable tag:v5.9.0-stable) - Fixed Version:
5.9.1-stable(commit13a016367ff4b4d3cc4c9bc2bfdfe692a512dd81) - Risk Level: High (CVSS 3.1: 8.1, CVSS 4.0: 7.6)
- Consequences: Universal signature forgery — any message can be authenticated as signed by any identity. ECCSI is used in MIKEY-SAKKE, 3GPP MCData/MCVideo, and other identity-based PKI deployments where this flaw effectively nullifies signature security.
Root Cause
The ECCSI verification algorithm (RFC 6507, Section 5.2.2) requires checking that signature scalars r and s are valid non-zero elements less than the curve order q. wolfSSL's wc_VerifyEccsiHash decodes r via eccsi_decode_sig_r_pvt and s via eccsi_decode_sig_s, but proceeds directly to the scalar multiplications and final comparison without range validation.
The arithmetic collapse occurs as follows:
- With
s = 0, the scalar multiplication[s]([HE]G + [r]Y)ineccsi_calc_jevaluates to the point at infinity, whose affine x-coordinateJ_xis0. - With
r = 0, the final comparisonmp_cmp(J_x, r)becomesmp_cmp(0, 0), which returnsMP_EQ. - The verifier interprets this equality as "signature valid," unconditionally accepting the forgery regardless of the message or identity.
The fix (commit 13a01636) adds three defensive checks:
- In
wc_VerifyEccsiHash: rejectrifmp_iszero(r)ormp_cmp(r, ¶ms->order) != MP_LT, returningMP_ZERO_EorECC_OUT_OF_RANGE_E. - In
eccsi_calc_j: rejectswith the same[1, q-1]range checks after decoding. - Defense-in-depth: before the final comparison, reject
Jif it is the point at infinity usingwc_ecc_point_is_at_infinity(j).
Reproduction Steps
The reproduction is fully automated by repro/reproduction_steps.sh, which:
- Clones the wolfSSL repository (if not already present).
- Builds vulnerable wolfSSL
v5.9.0-stablewith--enable-eccsi --enable-ecc --enable-sha256into/tmp/wolfssl-vuln. - Builds fixed wolfSSL
v5.9.1-stablewith the same flags into/tmp/wolfssl-fixed. - Compiles
repro/eccsi_forge.cagainst both libraries. - Runs the forgery harness against both versions and captures output to
logs/vulnerable_forge.txtandlogs/fixed_forge.txt.
The harness (repro/eccsi_forge.c):
- Generates a valid ECCSI KMS key and identity pair on curve P-256.
- Signs a real message to obtain a valid 129-byte signature (
r | s | PVT). - Constructs multiple forged signatures by replacing
randswith:r = 0, s = 0r = q, s = qr = q, s = 0r = q, s = 1r = 2q, s = 2qwhile keeping the original (valid)PVTpoint.
- Calls
wc_VerifyEccsiHashwith each forged signature against an attacker-chosen message. - Also tests
r = 0, s = 0against a completely different, never-signed message.
Expected evidence of reproduction:
- Vulnerable build: at least one forged scalar tuple returns
ret=0, verified=1. The harness confirmsr=0, s=0succeeds for both the original message and an unrelated message. - Fixed build: all forged tuples are rejected.
r=0, s=0returnsMP_ZERO_E (-121);r=q, s=qand related out-of-range values returnECC_OUT_OF_RANGE_E (-217).
Evidence
Vulnerable run log:
logs/vulnerable_forge.txt- Key excerpt:
Test: r=0, s=0 wc_VerifyEccsiHash ret=0, verified=1 *** FORGERY ACCEPTED *** Test: r=0, s=0 with DIFFERENT message wc_VerifyEccsiHash ret=0, verified=1 *** FORGERY ACCEPTED ***
- Key excerpt:
Fixed run log:
logs/fixed_forge.txt- Key excerpt:
Test: r=0, s=0 wc_VerifyEccsiHash ret=-121, verified=0 Forgery rejected (expected) Test: r=q, s=q wc_VerifyEccsiHash ret=-217, verified=0 Forgery rejected (expected)
- Key excerpt:
Validation verdict:
repro/validation_verdict.jsoncontains{"verdict": "confirmed"}because the vulnerable verifier accepted a forgery and the fixed verifier rejected all tested forgeries.Environment: Ubuntu-based container, wolfSSL built from source with
--enable-eccsi, linked statically, compiled with GCC.
Recommendations / Next Steps
- Upgrade immediately to wolfSSL
>= 5.9.1-stable(or apply commit13a01636as a patch). The fix is minimal (35 lines) and only toucheswolfcrypt/src/eccsi.c. - Validate all ECCSI signatures processed by pre-5.9.1 systems as potentially forged. Because the attack requires no secret material and works universally, any signature received from an untrusted channel before the upgrade is suspect.
- Regression tests: Ensure CI includes a test case that submits
r = 0, s = 0andr = q, s = qtowc_VerifyEccsiHashand expects failure. This directly exercises the missing checks. - Audit other ECCSI implementations in the same codebase (or derived from wolfSSL) for the same missing range checks, especially any custom verifiers that may have been copied from the vulnerable code.
Additional Notes
- Idempotency confirmed:
repro/reproduction_steps.shwas executed twice consecutively; both runs produced identical verdicts (confirmed) and the same error codes. - Edge cases tested: The harness tests not only
r=0, s=0but also boundary cases (r=q, s=q,r=2q, s=2q). Only the zero-scalar case produced a successful universal forgery on the vulnerable build; the others were correctly rejected by the arithmetic or the point-at-infinity handling in the vulnerable code. This confirms the attack surface is specifically ther=0, s=0path. - No ASAN / sanitizer required: This is a pure logic bug in the cryptographic protocol; memory safety tools do not detect it. The reproduction demonstrates the actual security failure (universal forgery) rather than a crash or memory corruption.
Variant Analysis & Alternative Triggers for CVE-2026-5466
The original CVE-2026-5466 vulnerability is a universal signature forgery in wolfSSL’s ECCSI (wc_VerifyEccsiHash) verifier caused by missing scalar range checks on the decoded signature components r and s. The upstream fix (commit 13a016367ff4b4d3cc4c9bc2bfdfe692a512dd81, released in v5.9.1) adds three defenses: (1) a [1, q-1] range check on r immediately after decoding in wc_VerifyEccsiHash; (2) a matching range check on s in eccsi_calc_j after eccsi_decode_sig_s; and (3) a defense-in-depth point-at-infinity guard on j before the final comparison.
This variant analysis systematically tested ten distinct bypass and alternate-trigger scenarios against both the vulnerable (v5.9.0-stable, commit 922d04b3568c6428a9fb905ddee3ef5a68db3108) and fixed (v5.9.1-stable, commit 1d363f3adceba9d1478230ede476a37b0dcdef24) versions. No bypass was found. The fix correctly rejects all tested scalar boundary conditions, malformed encodings, and parser-robustness attempts.
Fix Coverage / Assumptions
The fix assumes that the only code path capable of verifying an ECCSI signature is wc_VerifyEccsiHash (client-side), which internally calls the static helper eccsi_calc_j. The fix enforces the following invariants:
- Invariant 1: After
eccsi_decode_sig_r_pvtdecodesrfrom the signature buffer,rmust satisfy1 <= r < q(whereqis the curve order). This is checked withmp_iszero(r)andmp_cmp(r, ¶ms->order) != MP_LT. - Invariant 2: After
eccsi_decode_sig_sdecodess,smust satisfy1 <= s < q. This is checked withmp_iszero(s)andmp_cmp(s, &key->params.order) != MP_LT. - Invariant 3 (defense-in-depth): The intermediate point
jmust not be the point at infinity before the finalmp_cmp(jx, r)comparison.
The fix explicitly covers:
wc_VerifyEccsiHashinwolfcrypt/src/eccsi.ceccsi_calc_jinwolfcrypt/src/eccsi.c
It does not modify the signing path (wc_SignEccsiHash / eccsi_gen_sig), because the signing loop already re-rolls when s == 0 or s == HE. It also does not modify wc_ValidateEccsiPair or wc_ValidateEccsiPvt, which are key-pair validation routines that do not process attacker-supplied signature buffers.
Variant / Alternate Trigger
Ten distinct variant attempts were executed and logged. None succeeded on the fixed version.
| # | Variant Description | Vulnerable Result | Fixed Result |
|---|---|---|---|
| 1 | r = 0, s = 0 (original exploit) |
ACCEPTED | Rejected (MP_ZERO_E, -121) |
| 2 | r = q, s = q (exact order) |
Rejected | Rejected (ECC_OUT_OF_RANGE_E, -217) |
| 3 | r = q+1, s = q+1 (above order) |
Rejected | Rejected (ECC_OUT_OF_RANGE_E, -217) |
| 4 | r = 2q, s = 2q (double order) |
Rejected | Rejected (verified=0) |
| 5 | r = 0, s = q-1 (zero-r, valid-s) |
Rejected | Rejected (MP_ZERO_E, -121) |
| 6 | r = 1, s = 0 (valid-r, zero-s) |
Rejected | Rejected (MP_ZERO_E, -121) |
| 7 | r = q-1, s = q-1 (valid boundary) |
Rejected | Rejected (verified=0) |
| 8 | Wrong sigSz (SIG_SIZE - 1) |
Rejected (BAD_FUNC_ARG, -173) |
Rejected (BAD_FUNC_ARG, -173) |
| 9 | r = 0, s = 0 with PVT encoded as infinity |
Rejected (ECC_INF_E, -140) |
Rejected (ECC_INF_E, -140) |
| 10 | r = 0, s = 0 with a different message |
ACCEPTED | Rejected (MP_ZERO_E, -121) |
Entry point for all attempts: wc_VerifyEccsiHash in wolfcrypt/src/eccsi.c (lines 2204–2333 in v5.9.0-stable, lines 2204–2348 in v5.9.1-stable).
Key finding: wc_VerifyEccsiHash is the sole ECCSI verification API exposed by wolfSSL. eccsi_calc_j, eccsi_decode_sig_r_pvt, and eccsi_decode_sig_s are all static functions with exactly one caller each inside eccsi.c. Therefore there are no alternate entry points that reach the same verification arithmetic without passing through the new checks.
- Package/Component: wolfSSL
wolfcrypt/src/eccsi.c,wc_VerifyEccsiHash - Affected Versions:
< 5.9.1(testedv5.9.0-stable) - Fixed Version:
5.9.1-stable(commit1d363f3adceba9d1478230ede476a37b0dcdef24) - Risk Level: High for unpatched versions; the patched version is not vulnerable to the tested variants.
Root Cause
The same underlying root cause (missing scalar range validation after mp_read_unsigned_bin) is fully mitigated by the upstream fix. No code path in the fixed version reaches the eccsi_calc_j scalar multiplication or the final mp_cmp(jx, r) comparison without first satisfying:
r != 0andr < q(checked inwc_VerifyEccsiHash)s != 0ands < q(checked ineccsi_calc_j)jis not the point at infinity (checked before the final comparison)
Reproduction Steps
- Run
bash vuln_variant/reproduction_steps.sh. - The script:
- Builds wolfSSL
v5.9.0-stable(vulnerable) andv5.9.1-stable(fixed) with--enable-eccsi --enable-ecc --enable-sha256. - Compiles
vuln_variant/eccsi_variant.cagainst each build. - Executes the harness against both libraries, capturing output to
logs/variant_vulnerable.txtandlogs/variant_fixed.txt.
- Builds wolfSSL
- Expected outcome: The vulnerable library accepts
r=0, s=0for any message (universal forgery). The fixed library rejects all ten variant attempts with non-zero error codes (MP_ZERO_E,ECC_OUT_OF_RANGE_E,BAD_FUNC_ARG, orECC_INF_E).
Evidence
- Vulnerable run log:
logs/variant_vulnerable.txt- Shows
*** FORGERY ACCEPTED ***for Tests 1 and 10 (r=0, s=0).
- Shows
- Fixed run log:
logs/variant_fixed.txt- Shows all ten tests rejected; no
FORGERY ACCEPTEDlines.
- Shows all ten tests rejected; no
- Script output: Confirms
NO BYPASS: fixed version correctly rejects all variant attempts.
Recommendations / Next Steps
- No additional fix is required for the ECCSI verification path tested here. The upstream patch is complete for
wc_VerifyEccsiHash. - Future hardening: Consider centralizing scalar validation for all ECC-based signature schemes (ECCSI, ECDSA, SM2 if applicable) through the existing
wc_ecc_check_r_s_rangehelper rather than inlining checks. This reduces the risk of the same class of bug re-appearing in new schemes. - Regression test: Add a unit test in
wolfcrypt/test/test.cthat explicitly feedsr=0, s=0,r=q, s=q, andr=q+1, s=q+1intowc_VerifyEccsiHashand asserts rejection, to prevent regression. - Documentation: Update the ECCSI header doxygen comments to state that
randsmust be in[1, q-1], matching RFC 6507 Section 5.2.2 requirements.
Additional Notes
- Idempotency:
vuln_variant/reproduction_steps.shwas executed twice consecutively; both runs produced identical results and exited cleanly with code 1 (no bypass). - Trust boundary: All tests exercise the attacker-controlled signature buffer path (untrusted input delivered to
wc_VerifyEccsiHash). This is the same trust boundary as the original CVE. - Security policy: wolfSSL’s
.github/SECURITY.mddoes not exclude cryptographic signature verification failures from scope; the fix is in-scope.
CVE-2026-5466 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Unknown error
Unknown error
git clone --depth=100 https://github.com/wolfSSL/wolfssl.git /workspace/external/wolfssl 2>&1 | tail -20Cloning into '/workspace/external/wolfssl'...
cd /workspace/external/wolfssl && git tag | grep -E 'v5\.9\.(0|1)-stable'v5.9.0-stable v5.9.1-stable
Artifacts and Evidence for CVE-2026-5466
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-5466
Upgrade wolfssl · source to 5.9.1 or later.
FAQ: CVE-2026-5466
How does the CVE-2026-5466 signature forgery attack work?
r = 0, s = 0 (or other trivial constants) and submits it for verification. Because wc_VerifyEccsiHash never checks that r and s fall in [1, q-1], the degenerate scalars pass verification for any message under any identity, without the attacker possessing any private key material.Which wolfSSL versions are affected by CVE-2026-5466, and where is it fixed?
v5.9.0-stable). It is fixed in 5.9.1-stable via commit 13a016367ff4b4d3cc4c9bc2bfdfe692a512dd81.How severe is CVE-2026-5466?
How can I reproduce CVE-2026-5466?
wc_VerifyEccsiHash accepting it as valid despite no private key being used.References for CVE-2026-5466
Authoritative sources for CVE-2026-5466 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.