Reject zero modulus in mulmod/sqrmod - #11065
Open
MarkAtwood wants to merge 1 commit into
Open
Conversation
_sp_sqrmod() and _sp_mulmod_tmp() short-circuit on a zero operand and store zero without checking the modulus, while the non-aliased paths reject a zero modulus through sp_mod(). The return value therefore depended on whether the caller aliased the result onto the modulus, contradicting the MP_VAL contract documented on sp_sqrmod() and sp_mulmod(). Check the modulus in the zero-operand branch of each helper and document the new return. hw_mulmod() and hw_sqrmod() in the MAX3266X port carry the same pattern and get the same check, by inspection only, as building that port needs the Maxim SDK. The fastmath and heap math backends have no such short-circuit and are unaffected. The regression test requires WOLFSSL_PUBLIC_MP to run. Found via OSS-Fuzz 513887571 (cryptofuzz BignumCalc SqrMod). Fixes wolfSSL#11063
Contributor
There was a problem hiding this comment.
🟢 Ready to approve
The change is narrowly scoped, aligns behavior with the documented API contract, and is backed by targeted regression tests for the previously inconsistent aliasing cases.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR fixes an inconsistency in the SP math mulmod/sqrmod helpers where a zero operand could short-circuit to a zero result without validating that the modulus is non-zero, making the return code depend on whether the result aliases the modulus.
Changes:
- Add explicit
m == 0validation in the zero-operand short-circuit paths of_sp_mulmod_tmp()and_sp_sqrmod()so aliasing and non-aliasing cases returnMP_VALconsistently. - Extend
mp_test_mulmod_sqrmod()to cover zero-modulus behavior for both aliasing and non-aliasing arrangements (and both halves of the_sp_mulmod_tmp()zero-operand disjunction). - Apply the same zero-modulus validation to the Maxim MAX3266x hardware backend’s zero-operand short-circuits for mulmod/sqrmod.
File summaries
| File | Description |
|---|---|
| wolfcrypt/test/test.c | Adds regression tests ensuring zero modulus returns MP_VAL regardless of result aliasing in mulmod/sqrmod. |
| wolfcrypt/src/sp_int.c | Fixes SP math helper short-circuit to reject zero modulus in aliasing paths, aligning with the documented contract. |
| wolfcrypt/src/port/maxim/max3266x.c | Ensures hardware mulmod/sqrmod short-circuits also reject a zero modulus instead of returning a zero result. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
|
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.
Fixes #11063.
_sp_sqrmod()and_sp_mulmod_tmp()short-circuit on a zero operand and store zero without checking the modulus, while the non-aliased paths reject a zero modulus throughsp_mod(). So the return value depended on whether the caller aliased the result onto the modulus:mp_mulmodbehaves the same way through_sp_mulmod_tmp(). Both public wrappers already documentMP_VALfor a zero modulus (sp_sqrmodandsp_mulmod), so the aliased path did not match its documented contract.The check goes in the zero-operand branch of each helper rather than in the public wrappers, so the non-zero path keeps getting it from
sp_mod()as before.Other backends
tfm.c(fp_mulmod,fp_sqrmod) andinteger.c(mp_mulmod,mp_sqrmod) have no zero-operand short-circuit and always reduce throughfp_div/mp_div, which reject a zero divisor. Already correct in both aliasings, unchanged here.hw_mulmod()andhw_sqrmod()inport/maxim/max3266x.ccarry the identical pattern, andwolfmath.hmapsmp_mulmod/mp_sqrmodonto them whenWOLFSSL_USE_HW_MPis defined. They get the same check. That hunk is by inspection only — building the port needs the Maxim SDK, so it has not been compiled or run. Happy to drop it into a separate PR if you would rather someone with the hardware take it.Behavior change
The only production caller reaching the changed branch is
wc_CheckRsaKey(), atrsa.c:927andrsa.c:950, which callmp_mulmod(&key->dP, &key->e, tmp, tmp)with the result aliased onto the modulus.tmpisp-1/q-1, non-zero for any real key. For a malformed key withp == 1the call now returnsMP_VALand the key is rejected asMP_EXPTMOD_E, where previously it returnedMP_OKAYwithtmp = 0and was rejected by the following!mp_isone(tmp)check. Same outcome, explicit rather than incidental.Testing
Extends the existing aliasing test in
mp_test_mulmod_sqrmod()to cover a zero modulus in both arrangements, including both halves of the_sp_mulmod_tmp()zero-operand disjunction. The test fails before thesp_int.cchange and passes after.Note that
mp_test()is gated behindWOLFSSL_PUBLIC_MP, so a default./configure && make checkskips the whole mp suite. Verified withCFLAGS=-DWOLFSSL_PUBLIC_MP. CI covers it viacmake.ymlandos-check-linux.json.Found via OSS-Fuzz 513887571 (cryptofuzz
BignumCalc SqrMod).