Constant-time handling of the ECC point at infinity - #11173
Draft
dgarske wants to merge 6 commits into
Draft
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR aims to remove data-dependent branching when handling the ECC point at infinity in the “safe” projective add/double paths by always performing the arithmetic and selecting results afterward. Because this branch is stacked on #11172, the diff also includes thread-safety and key-handling related changes (mutex once-init helper, RSA blinding adjustment, netRandom init changes) plus test updates.
Changes:
- Make
ecc_projective_add_point_safe()/ecc_projective_dbl_point_safe()handle infinity without early-exit branches by computing unconditionally and selecting via constant-time conditional copies. - Add
wc_local_InitMutexOnce()and migrate several lazy mutex-init sites to a single “init exactly once” pattern. - Update RSA blinding inversion to avoid using
mp_invmod()directly on a secret-derived value, and adjust tests for the new ECC private-key range checks/import behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| wolfssl/wolfcrypt/wc_port.h | Declares wc_MutexOnceFlag and wc_local_InitMutexOnce() for one-time mutex initialization. |
| wolfcrypt/src/wc_port.c | Implements wc_local_InitMutexOnce() election/wait logic. |
| wolfcrypt/src/random.c | Switches netRandom mutex init to wc_local_InitMutexOnce() and updates init-state tracking. |
| wolfcrypt/src/ecc.c | Reworks infinity handling in projective add/double safe paths; adds ECC private scalar range check and converts mutex init flags to once-init. |
| wolfcrypt/src/cryptocb.c | Adjusts crypto callback registry entry publish/retire ordering and error handling. |
| wolfcrypt/src/rsa.c | Adds masked inversion step for RSA blinding to avoid secret-dependent inversion behavior. |
| wolfcrypt/src/port/nxp/se050_port.c | Ensures sensitive DER buffers are wiped fully before free in SE050 RSA/ECC paths. |
| wolfcrypt/test/test.c | Updates ECC mulmod tests to avoid using curve constants as “private key” inputs. |
| tests/api/test_ecc.h | Registers new ECC private-key range test. |
| tests/api/test_ecc.c | Adds coverage for ECC private-key range rejection and adjusts shared-secret infinity-case coverage accordingly. |
Suppressed comments (1)
wolfcrypt/src/ecc.c:8788
- The infinity check uses logical &&, which may short-circuit and skip the y==0 test when x!=0, creating data-dependent control flow. If the intent is constant-time/cost-independent handling of infinity, compute both mp_iszero() results unconditionally (e.g., with separate statements or bitwise '&').
inf = (mp_iszero(P->x) == MP_YES) && (mp_iszero(P->y) == MP_YES);
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
dgarske
force-pushed
the
fenrir_ecc_ct_points
branch
from
August 13, 2026 23:18
2e9a449 to
a867b11
Compare
dgarske
force-pushed
the
fenrir_ecc_ct_points
branch
from
August 14, 2026 15:08
a867b11 to
f557e75
Compare
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.
Constant-time handling of the ECC point at infinity
Part 4 of 4 from an internal automated source review. Builds on part 3 (
fenrir_threadsafety_keys) and should merge after it. Kept separate because it is the only change in the batch with a measurable performance cost.ecc_projective_add_point_safe()andecc_projective_dbl_point_safe()branched on whether an operand was the point at infinity, collapsing to a point copy instead of doing the arithmetic. Both now run the ordinary operation regardless and select the result withmp_cond_copy(), so an exceptional operand costs the same as an ordinary one.The addition computes into a temporary rather than into
R: every call site passes the first operand as the destination, so writingRearly would destroyAbefore the selection. The temporary is on the stack unless the build asked otherwise, and inherits the key heap and the small-stack cache back-pointer fromRso it behaves like the caller's own points.The
A == Bequality branch is deliberately left in place. The Montgomery ladder cannot reach it, and covering it would mean computing a doubling as well as an addition on every call.Performance
Measured interleaved A/B with standalone binaries, four runs each, on a default
./configurebuild:This is the legacy point arithmetic only. Builds using
--enable-sp- including--enable-all- route P-256/384/521 through the SP implementations and are unaffected.Worth noting for the record: this code is not compiled out under SP math as the report claims. The guard is
!WOLFSSL_SP_MATH, not!WOLFSSL_SP_MATH_ALL, and instrumentation confirms P-256 ECDH and ECDSA reach both functions in a default build.A further caveat:
mp_cmp_ct()andmp_montgomery_reduce_ct()are#defined to the non-constant-time versions oninteger.candtfm.c, so this change cannot deliver constant time on those backends regardless.Testing
make checkpasses on--enable-all,--enable-all --enable-lms,--enable-fastmath,--enable-heapmath,--enable-smallstack --enable-smallstackcacheand--enable-fpecc.