Commit dc6b82046cd for nodejs
commit dc6b82046cdb7ea3c55898c09dacbd32ef6bdd94
Author: Filip Skokan <panva.ip@gmail.com>
Date: Wed Nov 11 11:56:08 2026 +0100
crypto: remove the FIPS provider name check
FIPS-capable providers can use names other than fips. Remove the
named-provider lookup and explicit self-test from the startup flags,
leaving algorithm availability checks to each operation.
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/67358
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
diff --git a/doc/api/cli.md b/doc/api/cli.md
index d9d1559c924..6d8a2012cdc 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -1232,8 +1232,9 @@ priority than `--dns-result-order`.
added: v6.0.0
-->
-Enable [FIPS mode][] at startup. A configured provider named `fips` must be
-available and initialize successfully.
+Enable [FIPS mode][] at startup by adding `fips=yes` to OpenSSL's default
+property query. This does not load or validate a FIPS provider or run its
+self-tests. Configure OpenSSL to load the provider separately.
### `--enable-fips-indicator-events`
@@ -1799,7 +1800,8 @@ changes:
-->
Enable [FIPS mode][] at startup and prevent it from being disabled from script
-code. The same OpenSSL requirements as [`--enable-fips`][] apply.
+code. This changes the default property query as described for
+[`--enable-fips`][].
An optional mode can be specified using `--force-fips=mode`:
diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 71061e7965b..bd1c2c49c53 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -7082,9 +7082,9 @@ OpenSSL-backed APIs.
This method only affects subsequent algorithm fetches. Node.js initializes some
OpenSSL state before application code runs. When the property query must be
active from process startup, set `default_properties = fips=yes` in the OpenSSL
-configuration or use [`--enable-fips`][] or [`--force-fips`][]. The command-line
-flags additionally require a configured provider named `fips` to initialize and
-pass its self-test; Node.js fails to start otherwise.
+configuration or use [`--enable-fips`][] or [`--force-fips`][]. Like this method,
+the command-line flags change the property query without loading or validating
+a provider or running its self-tests.
Throws an error if OpenSSL cannot change the state. FIPS mode cannot be
disabled when Node.js was started with `--force-fips`.
@@ -7731,10 +7731,9 @@ default section name.
The configuration above enables the `fips=yes` property query at startup. The
following controls are also available:
-* [`--enable-fips`][] and [`--force-fips`][] enable the property query and
- additionally require the configured provider named `fips` to initialize and
- pass its self-test. Node.js exits if that check fails. `--force-fips` also
- prevents FIPS mode from being disabled from script code. With
+* [`--enable-fips`][] and [`--force-fips`][] enable the property query at startup.
+ They do not load or validate a provider or run its self-tests. `--force-fips`
+ also prevents FIPS mode from being disabled from script code. With
`--force-fips=strict`, Node.js also rejects non-approved operations reported
through the OpenSSL FIPS indicator callback.
* [`crypto.setFips()`][] changes the FIPS/property-query state. It does not
diff --git a/doc/node.1 b/doc/node.1
index dcbd7251c80..8f5287a6355 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -750,8 +750,9 @@ The default is \fBverbatim\fR and \fBdns.setDefaultResultOrder()\fR have higher
priority than \fB--dns-result-order\fR.
.
.It Fl -enable-fips
-Enable FIPS mode at startup. A configured provider named \fBfips\fR must be
-available and initialize successfully.
+Enable FIPS mode at startup by adding \fBfips=yes\fR to OpenSSL's default
+property query. This does not load or validate a FIPS provider or run its
+self-tests. Configure OpenSSL to load the provider separately.
.
.It Fl -enable-fips-indicator-events
Publish OpenSSL FIPS indicator results to the
@@ -962,7 +963,8 @@ Disable loading native addons that are not context-aware.
.
.It Fl -force-fips Ns = Ns Ar [mode]
Enable FIPS mode at startup and prevent it from being disabled from script
-code. The same OpenSSL requirements as \fB--enable-fips\fR apply.
+code. This changes the default property query as described for
+\fB--enable-fips\fR.
An optional mode can be specified using \fB--force-fips=mode\fR:
.Bl -bullet
.It
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 783620c1210..f601685fada 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -448,19 +448,6 @@ std::optional<std::string> ProcessFipsOptions() {
const bool force_fips = per_process::cli_options->force_fips_crypto;
if (!enable_fips && !force_fips) return std::nullopt;
-#ifndef OPENSSL_IS_BORINGSSL
- // Whether FIPS-approved implementations are reachable is decided by the
- // OpenSSL configuration, not by Node.js. Refuse to start rather than
- // restrict the default property query to a provider that is not there,
- // which would leave every operation failing as unsupported.
- if (!ncrypto::testFipsEnabled()) {
- const std::string option = force_fips ? "--force-fips" : "--enable-fips";
- return option + " requires an active OpenSSL provider named \"fips\". "
- "FIPS mode is configured through OpenSSL; see "
- "https://nodejs.org/api/crypto.html#fips-mode";
- }
-#endif
-
CryptoErrorList errors{CryptoErrorList::Option::NONE};
if (!ncrypto::setFipsEnabled(true, &errors)) {
std::string error = "OpenSSL error when trying to enable FIPS";
diff --git a/test/fixtures/openssl3-conf/fips_no_provider.cnf b/test/fixtures/openssl3-conf/fips_no_provider.cnf
new file mode 100644
index 00000000000..ee36d5b31a0
--- /dev/null
+++ b/test/fixtures/openssl3-conf/fips_no_provider.cnf
@@ -0,0 +1,17 @@
+nodejs_conf = nodejs_init
+openssl_conf = nodejs_init
+
+[nodejs_init]
+providers = provider_sect
+random = random_sect
+
+[provider_sect]
+default = default_sect
+
+[default_sect]
+activate = 1
+
+# Allow startup randomness while other operations use the default properties.
+[random_sect]
+properties = fips=no
+seed_properties = fips=no
diff --git a/test/parallel/test-crypto-fips.js b/test/parallel/test-crypto-fips.js
index 2ff8e2325b3..32780057cf4 100644
--- a/test/parallel/test-crypto-fips.js
+++ b/test/parallel/test-crypto-fips.js
@@ -12,17 +12,13 @@ if (isBoringSSL)
const assert = require('assert');
const spawnSync = require('child_process').spawnSync;
const path = require('path');
+const fixtures = require('../common/fixtures');
const { spawnSyncAndAssert } = require('../common/child_process');
const { internalBinding } = require('internal/test/binding');
const { testFipsCrypto } = internalBinding('crypto');
const FIPS_ENABLED = 1;
const FIPS_DISABLED = 0;
-const FIPS_ENABLE_ERROR_STRING =
- '--enable-fips requires an active OpenSSL provider named "fips"';
-const FIPS_FORCE_ERROR_STRING =
- '--force-fips requires an active OpenSSL provider named "fips"';
-
const kNoFailure = 0;
const kGenericUserError = 1;
@@ -66,32 +62,37 @@ function testHelper(stream, args, expectedStatus, expectedOutput, cmd, env) {
responseHandler(child[stream], expectedOutput);
}
-// --enable-fips should raise an error if OpenSSL is not FIPS enabled.
-testHelper(
- testFipsCrypto() ? 'stdout' : 'stderr',
- ['--enable-fips'],
- testFipsCrypto() ? kNoFailure : kGenericUserError,
- testFipsCrypto() ? FIPS_ENABLED : FIPS_ENABLE_ERROR_STRING,
- 'require("crypto").getFips()',
- process.env);
-
-// --force-fips should raise an error if OpenSSL is not FIPS enabled.
-testHelper(
- testFipsCrypto() ? 'stdout' : 'stderr',
- ['--force-fips'],
- testFipsCrypto() ? kNoFailure : kGenericUserError,
- testFipsCrypto() ? FIPS_ENABLED : FIPS_FORCE_ERROR_STRING,
- 'require("crypto").getFips()',
- process.env);
-
-// Explicit provider mode should preserve the behavior of bare --force-fips.
-testHelper(
- testFipsCrypto() ? 'stdout' : 'stderr',
- ['--force-fips=provider'],
- testFipsCrypto() ? kNoFailure : kGenericUserError,
- testFipsCrypto() ? FIPS_ENABLED : FIPS_FORCE_ERROR_STRING,
- 'require("crypto").getFips()',
- process.env);
+const fipsFlags = ['--enable-fips', '--force-fips', '--force-fips=provider'];
+if (hasOpenSSL(3, 4))
+ fipsFlags.push('--force-fips=strict');
+
+// The flags change the default property query without requiring a provider
+// named "fips". This configuration supplies the RNG needed during startup,
+// but has no cryptographic implementations matching fips=yes.
+for (const flag of fipsFlags) {
+ spawnSyncAndAssert(process.execPath, [
+ flag,
+ `--openssl-config=${fixtures.path('openssl3-conf', 'fips_no_provider.cnf')}`,
+ '-e', `
+ const assert = require('assert');
+ const crypto = require('crypto');
+ assert.strictEqual(crypto.getFips(), 1);
+ assert.throws(() => crypto.createHash('sha256'), {
+ code: 'ERR_OSSL_EVP_UNSUPPORTED',
+ });
+ if (${flag === '--enable-fips'}) {
+ crypto.setFips(false);
+ assert.strictEqual(crypto.getFips(), 0);
+ crypto.createHash('sha256');
+ } else {
+ assert.throws(() => crypto.setFips(false), {
+ code: 'ERR_CRYPTO_FIPS_FORCED',
+ });
+ assert.strictEqual(crypto.getFips(), 1);
+ }
+ `,
+ ], { stdout: '', stderr: '' });
+}
{
spawnSyncAndAssert(
@@ -101,15 +102,7 @@ testHelper(
});
}
-if (hasOpenSSL(3, 4)) {
- testHelper(
- testFipsCrypto() ? 'stdout' : 'stderr',
- ['--force-fips=strict'],
- testFipsCrypto() ? kNoFailure : kGenericUserError,
- testFipsCrypto() ? FIPS_ENABLED : FIPS_FORCE_ERROR_STRING,
- 'require("crypto").getFips()',
- process.env);
-} else {
+if (!hasOpenSSL(3, 4)) {
spawnSyncAndAssert(
process.execPath, ['--enable-fips-indicator-events', '-e', '0'], {
status: 9,