Skip to content

crypto: discover hashes and ciphers from providers - #65484

Open
panva wants to merge 2 commits into
nodejs:mainfrom
panva:crypto-provider-ciphers
Open

crypto: discover hashes and ciphers from providers#65484
panva wants to merge 2 commits into
nodejs:mainfrom
panva:crypto-provider-ciphers

Conversation

@panva

@panva panva commented Aug 22, 2026

Copy link
Copy Markdown
Member

OpenSSL 3 provider implementations are not necessarily registered in the legacy digest and cipher tables used by EVP_get_digestbyname() and EVP_get_cipherbyname(). As a result, Node.js can omit usable provider-only algorithms from getHashes() and getCiphers() and reject them in crypto operations even when they match the active OpenSSL property query. The permanently memoized algorithm lists can also remain stale after setFips() changes that query.

This change discovers usable hashes, ciphers, and aliases from activated OpenSSL providers while preserving the legacy registries. Numeric OID aliases, NULL implementations, and cipher implementations unsupported by the Node.js Cipher APIs are excluded.

Resolution and API support

  • Provider digest resolution now covers streaming and one-shot hashing, HMAC, KDFs, signing, verification, and RSA digest options.
  • Provider cipher resolution is used for string-based initialization and getCipherInfo() while preserving numeric, WebCrypto, TLS, and predefined-cipher paths.
  • Provider discovery exposes algorithms including KECCAK-KMAC-128, KECCAK-256, SHA256-192, CBC-CTS variants, SM4-GCM, SM4-CCM, SM4-XTS, and additional AES key-wrap implementations when supplied by the active providers.
  • createHash() and crypto.hash() accept functionName and customization for cSHAKE digests with OpenSSL 4.0 or later.
  • Cipher construction accepts ctsMode for CBC-CTS and xtsStandard for selecting the provider XTS variant.
  • CBC-CTS, AES key wrap, SIV/GCM-SIV, and CCM decryption enforce the one-shot and authentication constraints required by their provider implementations.

Caching and invalidation

  • Ordinary hashes and ciphers retain their legacy lookup and direct initialization paths, and the extended native binding arities are used only when the new cSHAKE, CTS, or XTS options are supplied.
  • Successful provider fetches are cached per Environment under case-insensitive query, canonical, and alias names, with owners deduplicated by provider and canonical identity.
  • Warm cache hits return borrowed pointers without another explicit fetch or reference increment, and failed lookups are not cached.
  • A process-wide generation advances only after a successful setFips() call that changes the FIPS state.
  • Each Environment lazily clears aliases before releasing owning provider references when it observes a new generation.
  • getHashes() and getCiphers() keep independent generation-aware snapshots, retry enumeration if the generation changes concurrently, return defensive copies, and discard their JavaScript snapshots during snapshot serialization.
  • Existing hash and cipher contexts retain their implementation and can finish across a FIPS transition, while new contexts resolve against the new property query.
  • Provider owners are released before worker addon DSOs are unloaded.
  • Engine registration changes, explicit provider load or unload, and default-property changes made by native addons intentionally do not participate in this invalidation mechanism since engines are on the way out of the codebase (crypto,https,tls: runtime-deprecate OpenSSL engine-based APIs (DEP0183) #63966, crypto,build: require OpenSSL 3, drop the bundled FIPS provider build #64777 (comment)).

Fixes: #43040
Fixes: #64866
Refs: #62982

@panva
panva requested a review from jasnell August 22, 2026 12:47
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto
  • @nodejs/security-wg

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Aug 22, 2026
@panva
panva requested a review from tniessen August 22, 2026 12:47
@panva panva added the crypto Issues and PRs related to the crypto subsystem. label Aug 22, 2026
@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.24324% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.12%. Comparing base (30fe871) to head (4bca8c4).
⚠️ Report is 23 commits behind head on main.

Files with missing lines Patch % Lines
src/crypto/crypto_cipher.cc 93.61% 0 Missing and 3 partials ⚠️
src/crypto/crypto_context.cc 71.42% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65484      +/-   ##
==========================================
+ Coverage   90.11%   90.12%   +0.01%     
==========================================
  Files         751      751              
  Lines      252473   252688     +215     
  Branches    47487    47558      +71     
==========================================
+ Hits       227517   227742     +225     
+ Misses      16270    16240      -30     
- Partials     8686     8706      +20     
Files with missing lines Coverage Δ
lib/internal/crypto/cipher.js 98.12% <100.00%> (+0.11%) ⬆️
src/crypto/crypto_aes.h 33.33% <ø> (ø)
src/crypto/crypto_chacha20_poly1305.cc 52.27% <100.00%> (ø)
src/crypto/crypto_cipher.h 68.47% <ø> (ø)
src/crypto/crypto_context.cc 71.73% <71.42%> (+0.06%) ⬆️
src/crypto/crypto_cipher.cc 78.93% <93.61%> (+0.71%) ⬆️

... and 62 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@panva
panva marked this pull request as draft August 22, 2026 18:56
@panva
panva force-pushed the crypto-provider-ciphers branch from 9242acf to 2cebe48 Compare August 22, 2026 20:11
@panva
panva marked this pull request as ready for review August 22, 2026 20:12
@panva panva added author ready PRs that have at least one approval, no outstanding review comments, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Aug 22, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 22, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@panva
panva marked this pull request as draft August 23, 2026 09:57
panva added 2 commits August 23, 2026 14:07
Enumerate usable digests and aliases from activated OpenSSL 3 providers
rather than relying only on the legacy digest registry. Normalize
provider aliases, omit numeric OIDs and NULL, and validate them against
the active default property query. Preserve legacy names and the OpenSSL
1.1.1 and BoringSSL paths.

Expose KECCAK-KMAC-128, KECCAK-256, SHA256-192, and other provider
digests. Add `functionName` and `customization` options for cSHAKE
digests in `createHash()` and `crypto.hash()` with OpenSSL 4.0 or later.

Resolve provider-only digest names across hashing, HMAC, KDF, signing,
verification, and RSA digest options. Keep ordinary hash construction
and one-shot hashing on the original binding arities and direct
initialization paths. Use parameterized setup only when cSHAKE options
are supplied.

Lazily cache successful provider fetches per Environment.
Index entries by case-insensitive query, canonical, and alias names.
Deduplicate owners by provider and canonical identity. Return borrowed
pointers on warm hits.

Introduce a process-wide FIPS-state generation that advances only after
successful, state-changing `setFips()` calls. Use it to invalidate
per-Environment digest caches and refresh `getHashes()` snapshots in the
main thread and workers. Keep cache IDs monotonic across invalidation
because JavaScript Realms can retain them. Existing hash contexts can
finish across a transition.

Release provider owners before unloading worker addon DSOs. Document
provider-dependent availability and operation-specific restrictions.
Add known-answer vectors, option validation, provider resolution,
property-query, FIPS transition, worker, snapshot, and cross-API
coverage.

Refs: nodejs#62982
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Enumerate usable ciphers and aliases from activated OpenSSL 3 providers
instead of maintaining lists of provider-only algorithms. Skip numeric
OID aliases and filter NULL, TLS composite, multiblock, and
encrypt-then-MAC implementations that the Cipher APIs cannot use.
Preserve the OpenSSL 1.1.1 and BoringSSL paths.

Expose CBC-CTS, SM4-GCM, SM4-CCM, SM4-XTS, and additional AES key wrap
implementations. Add `ctsMode` (CS1/CS2/CS3) and `xtsStandard`
(GB/IEEE) options for selecting provider CTS and SM4-XTS variants.

Keep ordinary cipher construction on the original binding and legacy
lookup paths.

Lazily cache successful provider fetches per Environment for
string initialization and `getCipherInfo()`.
Index entries by case-insensitive query, canonical, and alias names.
Deduplicate owners by provider and canonical identity. Return borrowed
pointers on warm hits.

Use the shared process-wide FIPS-state generation to invalidate
per-Environment cipher caches and refresh `getCiphers()` snapshots in
the main thread and workers. Existing cipher contexts retain their
implementation and can finish across a transition. Release provider
owners before unloading worker addon DSOs.

Enforce one-shot updates for CBC-CTS, AES key wrap, SIV/GCM-SIV, and
CCM decryption. Reject finalization without required input or CCM tags,
and defer authentication failures to `final()`. Document streaming and
XTS data-unit constraints.

Add known-answer vectors, option validation, provider round trips,
cache, worker, snapshot, FIPS transition, and construction benchmark
coverage.

Fixes: nodejs#43040
Fixes: nodejs#64866
Refs: nodejs#62982
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
@panva
panva force-pushed the crypto-provider-ciphers branch from 4bca8c4 to 54489eb Compare August 23, 2026 12:14
@panva panva changed the title crypto: discover ciphers from OpenSSL providers crypto: discover hashes and ciphers from providers Aug 23, 2026
@panva
panva marked this pull request as ready for review August 23, 2026 12:17
@panva
panva requested a review from jasnell August 23, 2026 12:17
@panva panva added the commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. label Aug 23, 2026
@panva panva removed the author ready PRs that have at least one approval, no outstanding review comments, and a CI started. label Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. crypto Issues and PRs related to the crypto subsystem. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

3 participants