Skip to content

Commit c903e66

Browse files
committed
doc: clarify OpenSSL FIPS configuration
Distinguish OpenSSL 3 provider setup from FIPS/property-query state, document configuration precedence and provider limitations, and retain the OpenSSL 1.1 and runtime control guidance. Regenerate the CLI manpage. Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent 6516fbb commit c903e66

4 files changed

Lines changed: 164 additions & 87 deletions

File tree

BUILDING.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,11 +1032,11 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)
10321032
### Configure OpenSSL appname
10331033

10341034
Node.js can use an OpenSSL configuration file by specifying the environment
1035-
variable `OPENSSL_CONF`, or using the command line option `--openssl-conf`, and
1036-
if none of those are specified will default to reading the default OpenSSL
1037-
configuration file `openssl.cnf`. Node.js will only read a section that is by
1038-
default named `nodejs_conf`, but this name can be overridden using the following
1039-
configure option:
1035+
variable `OPENSSL_CONF`, or using the command line option `--openssl-config`,
1036+
which takes precedence. If neither is specified, Node.js defaults to reading the
1037+
default OpenSSL configuration file `openssl.cnf`. Node.js will only read a
1038+
section that is by default named `nodejs_conf`, but this name can be overridden
1039+
using the following configure option:
10401040

10411041
```bash
10421042
./configure --openssl-conf-name=<some_conf_name>
@@ -1048,6 +1048,8 @@ Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via
10481048
[OpenSSL's provider model](https://docs.openssl.org/3.0/man7/crypto/#OPENSSL-PROVIDERS).
10491049
It is not necessary to rebuild Node.js to enable support for FIPS.
10501050

1051+
When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL.
1052+
10511053
See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to
10521054
enable FIPS support in Node.js.
10531055

doc/api/cli.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,9 @@ priority than `--dns-result-order`.
881881
added: v6.0.0
882882
-->
883883

884-
Enable FIPS-compliant crypto at startup. (Requires Node.js to be built
885-
against FIPS-compatible OpenSSL.)
884+
Enable [FIPS mode][] at startup. With OpenSSL 3, a configured provider named
885+
`fips` must be available and initialize successfully. With OpenSSL 1.1.1,
886+
Node.js must be built against a FIPS-capable OpenSSL.
886887

887888
### `--enable-source-maps`
888889

@@ -1595,8 +1596,8 @@ Disable loading native addons that are not [context-aware][].
15951596
added: v6.0.0
15961597
-->
15971598

1598-
Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.)
1599-
(Same requirements as `--enable-fips`.)
1599+
Enable [FIPS mode][] at startup and prevent it from being disabled from script
1600+
code. The same OpenSSL requirements as [`--enable-fips`][] apply.
16001601

16011602
### `--force-node-api-uncaught-exceptions-policy`
16021603

@@ -2286,9 +2287,11 @@ usually only useful for developers debugging Node.js itself.
22862287
added: v6.9.0
22872288
-->
22882289

2289-
Load an OpenSSL configuration file on startup. Among other uses, this can be
2290-
used to enable FIPS-compliant crypto if Node.js is built
2291-
against FIPS-enabled OpenSSL.
2290+
Load an OpenSSL configuration file on startup. The file can activate an
2291+
OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See
2292+
[FIPS mode][].
2293+
2294+
This option takes precedence over the `OPENSSL_CONF` environment variable.
22922295

22932296
### `--openssl-legacy-provider`
22942297

@@ -4269,9 +4272,8 @@ environment variable is arbitrary.
42694272
added: v6.11.0
42704273
-->
42714274

4272-
Load an OpenSSL configuration file on startup. Among other uses, this can be
4273-
used to enable FIPS-compliant crypto if Node.js is built with
4274-
`./configure --openssl-fips`.
4275+
Load an OpenSSL configuration file on startup. The file can be used as part of
4276+
a [FIPS mode][] configuration.
42754277

42764278
If the [`--openssl-config`][] command-line option is used, the environment
42774279
variable is ignored.
@@ -4478,6 +4480,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
44784480
[ECMAScript module]: esm.md#modules-ecmascript-modules
44794481
[EventSource Web API]: https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events
44804482
[ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions
4483+
[FIPS mode]: crypto.md#fips-mode
44814484
[File System Permissions]: permissions.md#file-system-permissions
44824485
[Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require
44834486
[Module resolution and loading]: packages.md#module-resolution-and-loading
@@ -4507,6 +4510,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
45074510
[`--cpu-prof-dir`]: #--cpu-prof-dir
45084511
[`--diagnostic-dir`]: #--diagnostic-dirdirectory
45094512
[`--disable-sigusr1`]: #--disable-sigusr1
4513+
[`--enable-fips`]: #--enable-fips
45104514
[`--env-file-if-exists`]: #--env-file-if-existsfile
45114515
[`--env-file`]: #--env-filefile
45124516
[`--experimental-sea-config`]: single-executable-applications.md#1-generating-single-executable-preparation-blobs

doc/api/crypto.md

Lines changed: 132 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4337,11 +4337,8 @@ deprecated: v10.0.0
43374337

43384338
> Stability: 0 - Deprecated
43394339
4340-
Property for checking and controlling whether a FIPS compliant crypto provider
4341-
is currently in use. Setting to true requires a FIPS build of Node.js.
4342-
4343-
This property is deprecated. Please use `crypto.setFips()` and
4344-
`crypto.getFips()` instead.
4340+
Deprecated property for checking and controlling [FIPS mode][]. Use
4341+
[`crypto.getFips()`][] and [`crypto.setFips()`][] instead.
43454342

43464343
### `crypto.generateKey(type, options, callback)`
43474344

@@ -4932,9 +4929,14 @@ console.log(aliceSecret === bobSecret);
49324929
added: v10.0.0
49334930
-->
49344931

4935-
* Returns: {number} `1` if and only if a FIPS compliant crypto provider is
4936-
currently in use, `0` otherwise. A future semver-major release may change
4937-
the return type of this API to a {boolean}.
4932+
* Returns: {number} `1` if FIPS mode is enabled, `0` otherwise. A future
4933+
semver-major release may change the return type of this API to a {boolean}.
4934+
4935+
With OpenSSL 3, this reports whether the default property query includes
4936+
`fips=yes`. It does not establish that a FIPS provider is loaded or validated.
4937+
It can return `1` even when a requested cryptographic implementation cannot be
4938+
fetched because no loaded provider supplies a match for `fips=yes`. See [FIPS
4939+
mode][].
49384940

49394941
### `crypto.getHashes()`
49404942

@@ -6227,10 +6229,33 @@ is a bit field taking one of or a mix of the following flags (defined in
62276229
added: v10.0.0
62286230
-->
62296231

6230-
* `bool` {boolean} `true` to enable FIPS mode.
6232+
* `bool` {boolean} `true` to enable FIPS mode, `false` to disable it.
6233+
6234+
Changes [FIPS mode][]. With OpenSSL 3, this only adds or removes `fips=yes` in
6235+
the default property query. It does not install, load, initialize, or validate
6236+
a FIPS provider. For a usable FIPS configuration, install the provider and
6237+
configure OpenSSL to load it when Node.js starts, as described in [FIPS
6238+
mode][].
6239+
6240+
If no loaded provider supplies a requested cryptographic implementation
6241+
matching `fips=yes`, the call can still succeed and `crypto.getFips()` can still
6242+
return `1`, but fetching that implementation fails. Affected `node:crypto`
6243+
operations typically fail with `ERR_OSSL_EVP_UNSUPPORTED`. Operations that do
6244+
not require a new fetch, including those using previously fetched
6245+
implementations or initialized operation contexts, may still succeed. Call this
6246+
method during application initialization, before application code uses other
6247+
OpenSSL-backed APIs.
6248+
6249+
This method only affects subsequent algorithm fetches. Node.js initializes some
6250+
OpenSSL state before application code runs. When the property query must be
6251+
active from process startup, set `default_properties = fips=yes` in the OpenSSL
6252+
configuration or use [`--enable-fips`][] or [`--force-fips`][]. The command-line
6253+
flags additionally require a configured provider named `fips` to initialize and
6254+
pass its self-test; Node.js fails to start otherwise.
62316255

6232-
Enables the FIPS compliant crypto provider in a FIPS-enabled Node.js build.
6233-
Throws an error if FIPS mode is not available.
6256+
Throws an error if OpenSSL cannot change the state. FIPS mode cannot be
6257+
disabled when Node.js was started with `--force-fips`. With OpenSSL 1.1.1,
6258+
enabling FIPS mode requires a FIPS-capable OpenSSL build.
62346259

62356260
### `crypto.sign(algorithm, data, key[, callback])`
62366261

@@ -6675,83 +6700,120 @@ console.log(receivedPlaintext);
66756700

66766701
### FIPS mode
66776702

6678-
When using OpenSSL 3, Node.js supports FIPS 140-2 when used with an appropriate
6679-
OpenSSL 3 provider, such as the [FIPS provider from OpenSSL 3][] which can be
6680-
installed by following the instructions in [OpenSSL's FIPS README file][].
6703+
Node.js exposes the FIPS support provided by the linked OpenSSL library. Node.js
6704+
is not itself FIPS validated. Validation belongs to a specific OpenSSL module or
6705+
provider and only applies when it is deployed according to its security policy.
6706+
Vendor-provided Node.js or OpenSSL builds can require a different configuration;
6707+
follow the vendor's documentation for those builds.
66816708

6682-
For FIPS support in Node.js you will need:
6709+
With OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL library.
6710+
6711+
With OpenSSL 3, FIPS support uses the provider model described in the
6712+
[OpenSSL FIPS module guide][]. Using FIPS-approved implementations requires:
66836713

66846714
* A correctly installed OpenSSL 3 FIPS provider.
66856715
* An OpenSSL 3 [FIPS module configuration file][].
6686-
* An OpenSSL 3 configuration file that references the FIPS module
6687-
configuration file.
6716+
* The FIPS provider to be loaded into the OpenSSL library context used by
6717+
Node.js, normally by activating it in an OpenSSL configuration file when
6718+
Node.js starts.
6719+
* The default property query to include `fips=yes` when cryptographic
6720+
implementations are fetched. This can be set from process startup by the
6721+
OpenSSL configuration, [`--enable-fips`][], or [`--force-fips`][], or for
6722+
subsequent fetches by `crypto.setFips(true)`.
66886723

6689-
Node.js will need to be configured with an OpenSSL configuration file that
6690-
points to the FIPS provider. An example configuration file looks like this:
6724+
An example OpenSSL 3 configuration file looks like this:
66916725

66926726
```text
66936727
nodejs_conf = nodejs_init
6728+
config_diagnostics = 1
66946729
66956730
.include /<absolute path>/fipsmodule.cnf
66966731
66976732
[nodejs_init]
66986733
providers = provider_sect
6734+
alg_section = algorithm_sect
66996735
67006736
[provider_sect]
6701-
default = default_sect
67026737
# The fips section name should match the section name inside the
67036738
# included fipsmodule.cnf.
67046739
fips = fips_sect
6740+
base = base_sect
67056741
6706-
[default_sect]
6742+
[base_sect]
67076743
activate = 1
6708-
```
6709-
6710-
where `fipsmodule.cnf` is the FIPS module configuration file generated from the
6711-
FIPS provider installation step:
67126744
6713-
```bash
6714-
openssl fipsinstall
6745+
[algorithm_sect]
6746+
default_properties = fips=yes
67156747
```
67166748

6717-
Set the `OPENSSL_CONF` environment variable to point to
6718-
your configuration file and `OPENSSL_MODULES` to the location of the FIPS
6719-
provider dynamic library. e.g.
6749+
The `fipsmodule.cnf` file is generated as part of the FIPS provider installation
6750+
and contains module integrity and self-test information. The exact command and
6751+
arguments are installation-specific; see [OpenSSL FIPS configuration][] and the
6752+
[OpenSSL FIPS module guide][]. The installation uses `openssl fipsinstall`.
6753+
6754+
The example activates the provider and enables the `fips=yes` property query
6755+
when Node.js starts. To activate the provider at startup but enable the property
6756+
query later with `crypto.setFips(true)`, omit `alg_section = algorithm_sect` and
6757+
the `[algorithm_sect]` block. The provider must still be loaded; when using this
6758+
startup configuration, keep its activation enabled. `crypto.setFips(true)`
6759+
should be called before application code uses other OpenSSL-backed APIs. It is
6760+
not equivalent to enabling the property query from process startup because
6761+
Node.js initializes some OpenSSL state before application code runs. Use the
6762+
example as written, [`--enable-fips`][], or [`--force-fips`][] when the property
6763+
query must be active from process startup.
6764+
6765+
`config_diagnostics` causes configuration errors to prevent startup instead of
6766+
being ignored. The `base` provider supplies non-cryptographic supporting
6767+
algorithms, such as encoders and decoders, that are commonly needed alongside
6768+
the FIPS provider. `default_properties = fips=yes` restricts OpenSSL's default
6769+
algorithm selection to implementations that match `fips=yes`.
6770+
6771+
Set `OPENSSL_CONF` to the OpenSSL configuration file. For a dynamically loaded
6772+
provider, `OPENSSL_MODULES` can set the directory containing the provider module.
6773+
For example:
67206774

67216775
```bash
67226776
export OPENSSL_CONF=/<path to configuration file>/nodejs.cnf
67236777
export OPENSSL_MODULES=/<path to openssl lib>/ossl-modules
67246778
```
67256779

6726-
FIPS mode can then be enabled in Node.js either by:
6727-
6728-
* Starting Node.js with `--enable-fips` or `--force-fips` command line flags.
6729-
* Programmatically calling `crypto.setFips(true)`.
6730-
6731-
Optionally FIPS mode can be enabled in Node.js via the OpenSSL configuration
6732-
file. e.g.
6733-
6734-
```text
6735-
nodejs_conf = nodejs_init
6736-
6737-
.include /<absolute path>/fipsmodule.cnf
6738-
6739-
[nodejs_init]
6740-
providers = provider_sect
6741-
alg_section = algorithm_sect
6742-
6743-
[provider_sect]
6744-
default = default_sect
6745-
# The fips section name should match the section name inside the
6746-
# included fipsmodule.cnf.
6747-
fips = fips_sect
6748-
6749-
[default_sect]
6750-
activate = 1
6751-
6752-
[algorithm_sect]
6753-
default_properties = fips=yes
6754-
```
6780+
The [`--openssl-config`][] command-line option selects the configuration file and
6781+
takes precedence over `OPENSSL_CONF`. If neither is set, OpenSSL's default
6782+
configuration file is used.
6783+
6784+
By default, Node.js reads the `nodejs_conf` section instead of OpenSSL's usual
6785+
`openssl_conf` section. Use [`--openssl-shared-config`][] to read `openssl_conf`,
6786+
or build Node.js with `./configure --openssl-conf-name=<name>` to change the
6787+
default section name.
6788+
6789+
On OpenSSL 3, the configuration above enables the `fips=yes` property query at
6790+
startup. The following controls are also available:
6791+
6792+
* [`--enable-fips`][] and [`--force-fips`][] enable the property query and
6793+
additionally require the configured provider named `fips` to initialize and
6794+
pass its self-test. Node.js exits if that check fails. `--force-fips` also
6795+
prevents FIPS mode from being disabled from script code.
6796+
* [`crypto.setFips()`][] changes the FIPS/property-query state. On OpenSSL 3, it
6797+
does not install, load, initialize, or validate a provider. Implementations
6798+
fetched before the call are not changed.
6799+
* [`crypto.getFips()`][] reports the FIPS/property-query state. On OpenSSL 3, a
6800+
return value of `1` does not prove that a FIPS provider is loaded or validated.
6801+
6802+
With OpenSSL 1.1.1, these controls use the library's FIPS mode support and
6803+
require a FIPS-capable OpenSSL build.
6804+
6805+
Only algorithms available under the active FIPS settings can be used. With
6806+
OpenSSL 3, if no loaded provider supplies a requested cryptographic
6807+
implementation matching `fips=yes`, fetching it fails, typically with
6808+
`ERR_OSSL_EVP_UNSUPPORTED`. The same error can occur for algorithms that
6809+
Node.js supports when FIPS mode is disabled but that are unavailable under the
6810+
active FIPS settings.
6811+
6812+
OpenSSL documents that the same FIPS provider cannot be used by multiple copies
6813+
of `libcrypto` in one process. This can affect native addons that load another
6814+
copy of `libcrypto`; OpenSSL's documented workaround is to use a separate copy
6815+
of the provider for each `libcrypto` instance. See [OpenSSL FIPS provider
6816+
limitations][].
67556817

67566818
## Crypto constants
67576819

@@ -7034,15 +7096,17 @@ See the [list of SSL OP Flags][] for details.
70347096
[CVE-2021-44532]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44532
70357097
[Caveats]: #support-for-weak-or-compromised-algorithms
70367098
[Crypto constants]: #crypto-constants
7037-
[FIPS module configuration file]: https://www.openssl.org/docs/man3.0/man5/fips_config.html
7038-
[FIPS provider from OpenSSL 3]: https://www.openssl.org/docs/man3.0/man7/crypto.html#FIPS-provider
7099+
[FIPS mode]: #fips-mode
7100+
[FIPS module configuration file]: https://docs.openssl.org/3.0/man5/fips_config/
70397101
[HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed
70407102
[JWK]: https://tools.ietf.org/html/rfc7517
70417103
[Key usages]: webcrypto.md#cryptokeyusages
70427104
[NIST SP 800-131A]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
70437105
[NIST SP 800-132]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
70447106
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
7045-
[OpenSSL's FIPS README file]: https://github.com/openssl/openssl/blob/openssl-3.0/README-FIPS.md
7107+
[OpenSSL FIPS configuration]: https://docs.openssl.org/3.0/man5/fips_config/
7108+
[OpenSSL FIPS module guide]: https://docs.openssl.org/master/man7/fips_module/
7109+
[OpenSSL FIPS provider limitations]: https://docs.openssl.org/3.6/man7/OSSL_PROVIDER-FIPS/
70467110
[OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man3.0/man1/openssl-spkac.html
70477111
[Permission Model]: permissions.md#permission-model
70487112
[RFC 1421]: https://www.rfc-editor.org/rfc/rfc1421.txt
@@ -7059,6 +7123,10 @@ See the [list of SSL OP Flags][] for details.
70597123
[RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562.txt
70607124
[Web Crypto API documentation]: webcrypto.md
70617125
[`--allow-openssl-store`]: cli.md#--allow-openssl-store
7126+
[`--enable-fips`]: cli.md#--enable-fips
7127+
[`--force-fips`]: cli.md#--force-fips
7128+
[`--openssl-config`]: cli.md#--openssl-configfile
7129+
[`--openssl-shared-config`]: cli.md#--openssl-shared-config
70627130
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
70637131
[`Buffer`]: buffer.md
70647132
[`DH_generate_key()`]: https://www.openssl.org/docs/man3.0/man3/DH_generate_key.html
@@ -7085,6 +7153,7 @@ See the [list of SSL OP Flags][] for details.
70857153
[`crypto.generateKeyPair()`]: #cryptogeneratekeypairtype-options-callback
70867154
[`crypto.getCurves()`]: #cryptogetcurves
70877155
[`crypto.getDiffieHellman()`]: #cryptogetdiffiehellmangroupname
7156+
[`crypto.getFips()`]: #cryptogetfips
70887157
[`crypto.getHashes()`]: #cryptogethashes
70897158
[`crypto.hash()`]: #cryptohashalgorithm-data-options
70907159
[`crypto.privateDecrypt()`]: #cryptoprivatedecryptprivatekey-buffer
@@ -7093,6 +7162,7 @@ See the [list of SSL OP Flags][] for details.
70937162
[`crypto.publicEncrypt()`]: #cryptopublicencryptkey-buffer
70947163
[`crypto.randomBytes()`]: #cryptorandombytessize-callback
70957164
[`crypto.randomFill()`]: #cryptorandomfillbuffer-offset-size-callback
7165+
[`crypto.setFips()`]: #cryptosetfipsbool
70967166
[`crypto.sign()`]: #cryptosignalgorithm-data-key-callback
70977167
[`crypto.verify()`]: #cryptoverifyalgorithm-data-key-signature-callback
70987168
[`crypto.webcrypto.getRandomValues()`]: webcrypto.md#cryptogetrandomvaluestypedarray

0 commit comments

Comments
 (0)