Skip to content

Run one point operation per SP ECC non-blocking step - #12025

Open
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:sp_nb_coarse
Open

dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:sp_nb_coarse

Conversation

@dgarske

@dgarske dgarske commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Description

Each SP ECC non-blocking step was a single field multiply or square: the ladder, window and base-table state machines drove the point add and double through their own sub-state machines, and the order inversion stepped one squaring at a time. Every yield costs the caller fixed work that has nothing to do with the math. Under TLS with the software async device that is a wolfSSL_connect / wolfSSL_accept re-entry plus a wolfSSL_AsyncPoll (event queue walk, wolfAsync_DoSw, ecc.c dispatch), about 10 us per yield on a 375 MHz Cortex-A53 against well under 1 us of field arithmetic, and a TLS 1.2 ECDHE-ECDSA mutual-auth handshake took about 50,000 yields. A customer driving that handshake from a 50 Hz control loop with a 2 ms slice per tick therefore spent several seconds of wall time per handshake, almost all of it yield overhead rather than crypto. Each step is now one point operation; the window doubles run as one step and the order inversion processes one digit of exponent bits per step, so the longest step in every operation is the final conversion out of projective coordinates, which was already a single step, and the same handshake takes about 1,600 yields. The _nb point add and double state machines and their contexts are removed, and the base-point path uses the Z=1 add like the blocking code. Yields per operation (WOLFSSL_DEBUG_NONBLOCK counts) and longest single step in microseconds (Raspberry Pi 5, Cortex-A76 at 2.4 GHz, one core, median of five runs), before -> after:

sign yields sign max us verify yields verify max us key gen yields key gen max us ECDH yields ECDH max us
P-256 large, asm 1495 -> 89 18 -> 13 8143 -> 253 11 -> 13 976 -> 76 10 -> 10 6623 -> 164 11 -> 11
P-384 large, asm 2237 -> 127 35 -> 35 11987 -> 357 13 -> 27 1462 -> 112 40 -> 35 9725 -> 230 36 -> 35
P-521 large, asm 3051 -> 170 79 -> 78 15903 -> 466 19 -> 58 2002 -> 152 78 -> 78 12827 -> 296 79 -> 79
P-256 large, C 1949 -> 110 32 -> 22 8597 -> 274 33 -> 24 1430 -> 97 22 -> 22 6623 -> 164 22 -> 22
P-256 small 12303 -> 789 40 -> 40 24111 -> 1564 4 -> 24 11784 -> 776 40 -> 40 11783 -> 775 40 -> 40

Two related fixes: sp_ecc_verify_*_nb did not reset its context on completion, so a second verify through the same key and context returned the stale result, and a shared secret through that context afterwards never completed because the mulmod state machine has no state matching the leftover one (ecc_test_nonblock now verifies twice through one context, the second with a corrupted signature), and ReuseKey dropped the non-blocking context across the key free and re-init, leaking it and running blocking crypto on a reused WOLFSSL; it now re-attaches it for ECC, X25519 and RSA.

ZD 22480

Testing

Tested with testwolfcrypt under --enable-ecc=nonblock on x86_64 (asm large, small and 32-bit C), aarch64 asm large and small on a Raspberry Pi 5, ARM32 asm, Cortex-M and Thumb-1 asm compile only, and make check with --enable-asynccrypt --enable-asynccrypt-sw (ECC, X25519 and RSA non-blocking). The step timings in the table come from a loop calling wc_ecc_make_key_ex, wc_ecc_sign_hash, wc_ecc_verify_hash and wc_ecc_shared_secret with a non-blocking context and timing each call, pinned to one core.

Copilot AI balanced review requested due to automatic review settings November 5, 2026 22:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The cross-architecture cryptographic state-machine refactor requires maintainer validation of constant-time behavior and worst-case per-yield latency on supported targets.

No open issues 🎉

What changed in this PR

This PR reduces yield overhead in wolfCrypt’s non-blocking SP ECC operations, improving asynchronous TLS handshake performance by doing more arithmetic per step.

Changes:

  • Replaces field-level sub-state machines with complete point operations, grouped window doubles, and single-step order inversion.
  • Resets completed ECC verification contexts and adds a regression test for repeated verification.
  • Preserves non-blocking contexts when reinitializing RSA, ECC, and X25519 keys.
File Description
wolfcrypt/​test/​test.c Tests context reuse with valid and corrupted signatures.
wolfcrypt/​src/​sp_x86_64.c Coarsens non-blocking ECC steps and resets verification contexts on x86_64.
wolfcrypt/​src/​sp_arm64.c Applies the same ECC stepping and context-reset changes on ARM64.
src/​internal.c Reattaches non-blocking contexts after key reinitialization.

Review effort: Balanced

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

@dgarske dgarske changed the title Run one point operation per SP ECC non-blocking step Run one point operation per SP ECC non-blocking step, max step 27 us on Cortex-A76 Nov 5, 2026
@dgarske dgarske changed the title Run one point operation per SP ECC non-blocking step, max step 27 us on Cortex-A76 Run one point operation per SP ECC non-blocking step Nov 5, 2026
@dgarske dgarske self-assigned this Nov 5, 2026

@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 #12025

Scan targets checked: wolfcrypt-src, wolfcrypt-bugs, wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): wolfcrypt/src/sp_arm32.c, wolfcrypt/src/sp_arm64.c, wolfcrypt/src/sp_armthumb.c, wolfcrypt/src/sp_cortexm.c, wolfcrypt/src/sp_x86_64.c
Coverage: 5 of 5 in-scope changed file(s) opened by the reviewer

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Max

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.

5 participants