Skip to content

Fix unsynchronized globalRNG use in BN_rand, AddSession, ECDH and X25519 - #11048

Merged
dgarske merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_7543
Aug 6, 2026
Merged

Fix unsynchronized globalRNG use in BN_rand, AddSession, ECDH and X25519#11048
dgarske merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_7543

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Problem

globalRNG (src/ssl.c) is a single process-wide WC_RNG with no internal
per-instance locking; its designated lock is globalRNGMutex. The RAND_*
family in src/ssl_crypto.c takes that mutex at all eleven of its call sites.
Four OpenSSL-compat entry points using globalRNG as their primary RNG took no
lock at all, so two threads could interleave DRBG generation on the same V/C
state and produce torn or duplicate output used directly as key material.

Closes f-7543.

Fix

Two remedies, depending on whether the site can cheaply own its RNG:

Site File Fix
wolfSSL_BN_rand src/ssl_bn.c hold globalRNGMutex across wc_RNG_GenerateBlock
AddSession src/ssl_sess.c hold globalRNGMutex across wc_RNG_GenerateBlock, global path only
wolfSSL_ECDH_compute_key src/pk_ec.c wolfssl_make_rng() in place of wolfssl_make_global_rng()
wolfSSL_EC25519_shared_key src/pk.c same, for the WOLFSSL_CURVE25519_BLINDING RNG

The two lock sites are open-coded in the style already used in those files, so
no new locking convention is introduced.

The two shared-secret paths instead take a per-call RNG via
wolfssl_make_rng() — the helper the rest of pk.c/pk_ec.c already uses —
removing the sharing rather than serializing on it. Holding globalRNGMutex
across the whole shared-secret operation (the first version of this PR) would
have serialized all ECDH process-wide, including keys that carry their own RNG.
Both sites now NULL-check the RNG; wolfSSL_ECDH_compute_key additionally
guards the shared-secret call on !err and clears key->rng before the local
RNG is freed, so no dangling reference is left behind.

Known trade-off

ECDH and X25519 now init and seed a fresh DRBG per call instead of reusing the
global one, which costs performance on those paths. Accepted as an interim
state — still better than the unsynchronized global.

Intentionally not in this PR

  • Roughly eighteen further sites reach the global only through
    wolfssl_make_rng()'s fallback, after a local wc_InitRng() has already
    failed. Same defect, far lower reachability.
  • A concurrently shared EC_KEY is unsafe independent of the RNG
    (wc_ecc_shared_secret_ex writes private_key->state and dispatches on it).
    That needs per-key locking, which neither wolfSSL nor OpenSSL provides.

Verification

  • Builds clean, no new warnings, across opensslall+keygen, opensslextra+all,
    dh+ecc (no OPENSSL_EXTRA), singlethreaded and wpas, plus a
    -DWOLFSSL_CURVE25519_BLINDING build for the Curve25519 path.
  • make check: 17/17 on --enable-all, 6/6 on opensslall, 0 failures.
  • ThreadSanitizer clean: 32 threads x 150 iterations hammering BN_rand,
    ECDH_compute_key, EC25519_shared_key and RAND_bytes, 0 races.
    Negative control: reverting the BN_rand lock reports races in
    Hash512_DRBG_Generate.

No regression test is added: a threaded test is nondeterministic and there is no
ThreadSanitizer job in CI, so it would add flake without signal.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Aug 4, 2026
Copilot AI lite review requested due to automatic review settings August 4, 2026 05:49

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.

Pull request overview

This PR addresses a thread-safety issue where multiple OpenSSL-compat entry points use the process-wide globalRNG without taking its designated lock (globalRNGMutex), risking concurrent DRBG state corruption and unsafe key material generation.

Changes:

  • Add globalRNGMutex locking around wc_RNG_GenerateBlock() in wolfSSL_BN_rand() and AddSession().
  • Hold globalRNGMutex across EC_KEY->rng mutation and wc_ecc_shared_secret_ex() in wolfSSL_ECDH_compute_key(), including a missing NULL check on wolfssl_make_global_rng().
  • Lock globalRNGMutex around Curve25519 blinding usage during wolfSSL_EC25519_shared_key().

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/ssl_sess.c Locks globalRNGMutex while generating altSessionID via the global RNG.
src/ssl_bn.c Locks globalRNGMutex around global RNG byte generation in wolfSSL_BN_rand().
src/pk.c Locks globalRNGMutex during Curve25519 shared-secret generation when blinding is enabled.
src/pk_ec.c Locks globalRNGMutex across key->rng set/clear and ECDH shared-secret computation, adding a NULL check for the global RNG.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pk.c Outdated

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

Scan targets checked: wolfssl-bugs, wolfssl-src

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

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

Comment thread src/pk_ec.c
@dgarske dgarske assigned douzzer and philljj and unassigned douzzer Aug 5, 2026
@dgarske
dgarske requested a review from philljj August 5, 2026 01:31
Comment thread src/ssl_sess.c
Comment thread src/pk.c
Comment thread src/pk_ec.c Outdated
Comment thread src/pk_ec.c Outdated
Comment thread src/ssl_bn.c
Comment thread src/pk.c Outdated
@philljj philljj assigned yosuke-wolfssl and unassigned wolfSSL-Bot Aug 5, 2026
@philljj philljj removed their assignment Aug 5, 2026
@yosuke-wolfssl

Copy link
Copy Markdown
Contributor Author

Hello @philljj ,
I reworked on this. Could you please review it again ?

@philljj
philljj requested review from philljj and a lite review from Copilot August 6, 2026 16:23

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@philljj
philljj requested a balanced review from Copilot August 6, 2026 17:15

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@philljj philljj assigned wolfSSL-Bot and unassigned philljj Aug 6, 2026

@dgarske dgarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Previously (before this PR) ECDH and X25519 shared-secret paths used the global RNG, but now always instantiate and seed a fresh DRBG on every call. This could impact performance for some customers. I think originally this PR grabbed the global and locked it during the entire ECDH/X25519 which caused a different issue. I am not sure what the best solution is and it requires a larger refactor, which @philljj has agreed to take on. For now we'll merge this PR, but it does need some improvement soon (before next release). Its still better than what was in master. Also the PR title and description are wrong, so please correct those. Thanks

@dgarske
dgarske merged commit 950fe9a into wolfSSL:master Aug 6, 2026
375 of 377 checks passed
@yosuke-wolfssl
yosuke-wolfssl deleted the fix/f_7543 branch August 6, 2026 23:16
@yosuke-wolfssl yosuke-wolfssl changed the title Lock globalRNGMutex in BN_rand, ECDH, EC25519 and AddSession Fix unsynchronized globalRNG use in BN_rand, AddSession, ECDH and X25519 Aug 6, 2026
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.

7 participants