Skip to content

Constant time hardening - #11159

Open
stenslae wants to merge 6 commits into
wolfSSL:masterfrom
stenslae:audit-constant-time
Open

Constant time hardening#11159
stenslae wants to merge 6 commits into
wolfSSL:masterfrom
stenslae:audit-constant-time

Conversation

@stenslae

Copy link
Copy Markdown
Member

Description

  • F-7092: Restricted accel_fp_mul from processing secret scalars when ECC_TIMING_RESISTANT is defined. It now falls back to the constant-time ladder.
  • F-7098, F-7099: Replaced EGCD mp_invmod with Fermat's Little Theorem.
  • F-7426: Refactored mp_div_2_mod_ct, mp_submod_ct, and mp_addmod_ct to use branchless bitwise masks.
  • F-7427: Removed WOLFSSL_MP_INVMOD_CONSTANT_TIME macro to ensure the blinded math paths are always enforced.
  • Replaced memory comparisons across the codebase with ConstantCompare.
  • Changed the ConstantCompare implementation to use const volatile byte* pointers to prevent compiler optimization.

@stenslae stenslae self-assigned this Aug 12, 2026
@stenslae
stenslae force-pushed the audit-constant-time branch from d7fc2ea to 88b4fd7 Compare August 12, 2026 17:44

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11159

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfssl-bugs
Failed targets: wolfcrypt-src, wolfssl-src

Findings: 6
6 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/integer.c
Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/integer.c Outdated
Comment thread wolfcrypt/src/integer.c
Comment thread wolfssl/wolfcrypt/settings.h
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

gcc-arm-cortex-m0plus

  • FLASH: .text +20 B (+0.0%, 64,903 B / 262,144 B, total: 25% used)

gcc-arm-cortex-m3

  • FLASH: .text -72 B (-0.1%, 123,507 B / 262,144 B, total: 47% used)

gcc-arm-cortex-m4-crypto-only

  • FLASH: .text -64 B (-0.0%, 175,914 B / 262,144 B, total: 67% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .text -64 B (-0.0%, 775,420 B / 1,048,576 B, total: 74% used)

gcc-arm-cortex-m4-pq

  • FLASH: .text -64 B (-0.0%, 297,564 B / 1,048,576 B, total: 28% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .text -64 B (-0.0%, 328,048 B / 1,048,576 B, total: 31% used)

gcc-arm-cortex-m4-tls12

  • FLASH: .text -64 B (-0.1%, 124,275 B / 262,144 B, total: 47% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .text -64 B (-0.0%, 238,369 B / 262,144 B, total: 91% used)

linuxkm-pie

  • Data: __patchable_function_entries -8 B (-0.0%, 26,552 B)

linuxkm-standard

Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/integer.c
Comment thread wolfcrypt/src/integer.c Outdated
Comment thread wolfcrypt/src/integer.c
Comment thread wolfssl/wolfcrypt/settings.h
@stenslae
stenslae requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot August 12, 2026 20:06

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11159

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfssl-bugs
Failed targets: wolfcrypt-src, wolfssl-src

Findings: 7
7 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/sakke.c
Comment thread wolfcrypt/src/eccsi.c Outdated
Comment thread wolfcrypt/src/ecc.c Outdated
Comment thread wolfcrypt/src/integer.c Outdated
Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/eccsi.c Outdated
Comment thread wolfcrypt/src/sakke.c
Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/ecc.c Outdated
Comment thread wolfcrypt/src/integer.c Outdated
Comment thread wolfcrypt/src/eccsi.c Outdated
Comment thread wolfcrypt/src/ecc.c
Comment thread wolfcrypt/src/eccsi.c Outdated
@stenslae
stenslae force-pushed the audit-constant-time branch from 59926ce to 23cc479 Compare August 12, 2026 21:14
@stenslae
stenslae requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot August 12, 2026 21:15
@stenslae
stenslae requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot August 12, 2026 21:35

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11159

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfssl-bugs
Failed targets: wolfcrypt-src, wolfssl-src
Findings: 4
3 finding(s) posted as inline comments (see file-level comments below)

Low (1)

build_lut() has no callers when ECC_TIMING_RESISTANT is set without ECC_SHAMIR

File: wolfcrypt/src/ecc.c:13631
Function: build_lut
Category: Dead/unreachable code

With FP_ECC + ECC_TIMING_RESISTANT and ECC_SHAMIR undefined, all three build_lut() call sites (14341/14359 under ECC_SHAMIR, 14477, 14651) are compiled out, leaving the static function defined but unreferenced — -Wunused-function, fatal under -Werror. The LUT points add_entry() allocates are then dead too.

Recommendation: Wrap the build_lut definition in the same #if !defined(ECC_TIMING_RESISTANT) || defined(ECC_SHAMIR) guard used at its call sites.

Referenced code: wolfcrypt/src/ecc.c:13631-13632 (2 lines)


This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread wolfcrypt/src/sakke.c
* the fixed KMS secret z_T. */
if (err == 0) {
err = mp_invmod(a, &key->params.q, a);
mp_int* tmp = &key->tmp.m2;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] wc_MakeSakkeRsk uses key-tmp.m2, initialized only under WOLFCRYPT_SAKKE_CLIENT · Logic errors

wc_MakeSakkeRsk is compiled under WOLFCRYPT_SAKKE_KMS, but the key->tmp.m2 it now uses is passed to mp_init_multi (sakke.c:147) and mp_free (sakke.c:203) only under WOLFCRYPT_SAKKE_CLIENT. A KMS-only build operates on an uninitialized mp_int and never frees it. Latent today: sakke.h hard-defines both macros.

Fix: Use a locally initialized mp_int, or move the m2 init/free out of the WOLFCRYPT_SAKKE_CLIENT guard.

Comment thread wolfcrypt/src/ecc.c
}

/* perform a fixed point ECC mulmod */
#ifndef ECC_TIMING_RESISTANT

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] build_lut/lut_orders become unused and the FP cache becomes dead weight when ECC_TIMING_RESISTANT is set without… · Dead/unreachable code

With FP_ECC + ECC_TIMING_RESISTANT and ECC_SHAMIR undefined, every call site of build_lut (ecc.c:14477, 14651, and the fp_ecc_mul2add sites) is compiled out, leaving build_lut and the lut_orders table with no users — -Wunused-function/-Wunused-const-variable breaks -Werror builds. add_entry still allocates 2^FP_LUT ecc_points per cache entry that are never populated or read.

Fix: Guard build_lut/lut_orders with #if !defined(ECC_TIMING_RESISTANT) || defined(ECC_SHAMIR) and skip the fp-cache entry allocation when no LUT consumer is compiled in.

Comment thread wolfcrypt/src/ecc.c
@@ -14632,7 +14651,16 @@ int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
err = build_lut(idx, a, modulus, mp, mu);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ [Info] wc_ecc_mulmod_ex2 builds an FP-cache LUT it never uses · Dead/unreachable code

Under ECC_TIMING_RESISTANT with ECC_SHAMIR, the retained LUT-build block runs (2^FP_LUT point ops plus one mp_invmod per LUT entry) but its result is unread in this function, which always takes normal_ecc_mulmod. fp_ecc_mul2add already builds the LUT on demand under the identical lru_count >= 2 && !LUT_set condition, so the pre-warm adds no benefit.

Fix: Skip the LUT build in wc_ecc_mulmod_ex2 under ECC_TIMING_RESISTANT and let fp_ecc_mul2add build it on demand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants