Skip to content

Commit 44c0c8f

Browse files
panvaaduh95
authored andcommitted
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> PR-URL: #64982 Reviewed-By: Richard Lau <richard.lau@ibm.com> Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent 89a6724 commit 44c0c8f

4 files changed

Lines changed: 180 additions & 94 deletions

File tree

BUILDING.md

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

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

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

953+
When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL.
954+
953955
See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to
954956
enable FIPS support in Node.js.
955957

doc/api/cli.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -790,8 +790,9 @@ priority than `--dns-result-order`.
790790
added: v6.0.0
791791
-->
792792

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

796797
### `--enable-network-family-autoselection`
797798

@@ -1391,8 +1392,8 @@ Disable loading native addons that are not [context-aware][].
13911392
added: v6.0.0
13921393
-->
13931394

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

13971398
### `--force-node-api-uncaught-exceptions-policy`
13981399

@@ -2067,9 +2068,11 @@ usually only useful for developers debugging Node.js itself.
20672068
added: v6.9.0
20682069
-->
20692070

2070-
Load an OpenSSL configuration file on startup. Among other uses, this can be
2071-
used to enable FIPS-compliant crypto if Node.js is built
2072-
against FIPS-enabled OpenSSL.
2071+
Load an OpenSSL configuration file on startup. The file can activate an
2072+
OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See
2073+
[FIPS mode][].
2074+
2075+
This option takes precedence over the `OPENSSL_CONF` environment variable.
20732076

20742077
### `--openssl-legacy-provider`
20752078

@@ -4016,9 +4019,8 @@ environment variable is arbitrary.
40164019
added: v6.11.0
40174020
-->
40184021

4019-
Load an OpenSSL configuration file on startup. Among other uses, this can be
4020-
used to enable FIPS-compliant crypto if Node.js is built with
4021-
`./configure --openssl-fips`.
4022+
Load an OpenSSL configuration file on startup. The file can be used as part of
4023+
a [FIPS mode][] configuration.
40224024

40234025
If the [`--openssl-config`][] command-line option is used, the environment
40244026
variable is ignored.
@@ -4225,6 +4227,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
42254227
[ECMAScript module]: esm.md#modules-ecmascript-modules
42264228
[EventSource Web API]: https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events
42274229
[ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions
4230+
[FIPS mode]: crypto.md#fips-mode
42284231
[File System Permissions]: permissions.md#file-system-permissions
42294232
[Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require
42304233
[Module resolution and loading]: packages.md#module-resolution-and-loading
@@ -4253,6 +4256,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
42534256
[`--cpu-prof-dir`]: #--cpu-prof-dir
42544257
[`--diagnostic-dir`]: #--diagnostic-dirdirectory
42554258
[`--disable-sigusr1`]: #--disable-sigusr1
4259+
[`--enable-fips`]: #--enable-fips
42564260
[`--env-file-if-exists`]: #--env-file-if-existsfile
42574261
[`--env-file`]: #--env-filefile
42584262
[`--experimental-sea-config`]: single-executable-applications.md#generating-single-executable-preparation-blobs

doc/api/crypto.md

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

42814281
> Stability: 0 - Deprecated
42824282
4283-
Property for checking and controlling whether a FIPS compliant crypto provider
4284-
is currently in use. Setting to true requires a FIPS build of Node.js.
4285-
4286-
This property is deprecated. Please use `crypto.setFips()` and
4287-
`crypto.getFips()` instead.
4283+
Deprecated property for checking and controlling [FIPS mode][]. Use
4284+
[`crypto.getFips()`][] and [`crypto.setFips()`][] instead.
42884285

42894286
### `crypto.generateKey(type, options, callback)`
42904287

@@ -4875,9 +4872,14 @@ console.log(aliceSecret === bobSecret);
48754872
added: v10.0.0
48764873
-->
48774874

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

48824884
### `crypto.getHashes()`
48834885

@@ -6147,10 +6149,33 @@ is a bit field taking one of or a mix of the following flags (defined in
61476149
added: v10.0.0
61486150
-->
61496151

6150-
* `bool` {boolean} `true` to enable FIPS mode.
6152+
* `bool` {boolean} `true` to enable FIPS mode, `false` to disable it.
6153+
6154+
Changes [FIPS mode][]. With OpenSSL 3, this only adds or removes `fips=yes` in
6155+
the default property query. It does not install, load, initialize, or validate
6156+
a FIPS provider. For a usable FIPS configuration, install the provider and
6157+
configure OpenSSL to load it when Node.js starts, as described in [FIPS
6158+
mode][].
6159+
6160+
If no loaded provider supplies a requested cryptographic implementation
6161+
matching `fips=yes`, the call can still succeed and `crypto.getFips()` can still
6162+
return `1`, but fetching that implementation fails. Affected `node:crypto`
6163+
operations typically fail with `ERR_OSSL_EVP_UNSUPPORTED`. Operations that do
6164+
not require a new fetch, including those using previously fetched
6165+
implementations or initialized operation contexts, may still succeed. Call this
6166+
method during application initialization, before application code uses other
6167+
OpenSSL-backed APIs.
6168+
6169+
This method only affects subsequent algorithm fetches. Node.js initializes some
6170+
OpenSSL state before application code runs. When the property query must be
6171+
active from process startup, set `default_properties = fips=yes` in the OpenSSL
6172+
configuration or use [`--enable-fips`][] or [`--force-fips`][]. The command-line
6173+
flags additionally require a configured provider named `fips` to initialize and
6174+
pass its self-test; Node.js fails to start otherwise.
61516175

6152-
Enables the FIPS compliant crypto provider in a FIPS-enabled Node.js build.
6153-
Throws an error if FIPS mode is not available.
6176+
Throws an error if OpenSSL cannot change the state. FIPS mode cannot be
6177+
disabled when Node.js was started with `--force-fips`. With OpenSSL 1.1.1,
6178+
enabling FIPS mode requires a FIPS-capable OpenSSL build.
61546179

61556180
### `crypto.sign(algorithm, data, key[, callback])`
61566181

@@ -6585,83 +6610,120 @@ console.log(receivedPlaintext);
65856610

65866611
### FIPS mode
65876612

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

6592-
For FIPS support in Node.js you will need:
6619+
With OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL library.
6620+
6621+
With OpenSSL 3, FIPS support uses the provider model described in the
6622+
[OpenSSL FIPS module guide][]. Using FIPS-approved implementations requires:
65936623

65946624
* A correctly installed OpenSSL 3 FIPS provider.
65956625
* An OpenSSL 3 [FIPS module configuration file][].
6596-
* An OpenSSL 3 configuration file that references the FIPS module
6597-
configuration file.
6626+
* The FIPS provider to be loaded into the OpenSSL library context used by
6627+
Node.js, normally by activating it in an OpenSSL configuration file when
6628+
Node.js starts.
6629+
* The default property query to include `fips=yes` when cryptographic
6630+
implementations are fetched. This can be set from process startup by the
6631+
OpenSSL configuration, [`--enable-fips`][], or [`--force-fips`][], or for
6632+
subsequent fetches by `crypto.setFips(true)`.
65986633

6599-
Node.js will need to be configured with an OpenSSL configuration file that
6600-
points to the FIPS provider. An example configuration file looks like this:
6634+
An example OpenSSL 3 configuration file looks like this:
66016635

66026636
```text
66036637
nodejs_conf = nodejs_init
6638+
config_diagnostics = 1
66046639
66056640
.include /<absolute path>/fipsmodule.cnf
66066641
66076642
[nodejs_init]
66086643
providers = provider_sect
6644+
alg_section = algorithm_sect
66096645
66106646
[provider_sect]
6611-
default = default_sect
66126647
# The fips section name should match the section name inside the
66136648
# included fipsmodule.cnf.
66146649
fips = fips_sect
6650+
base = base_sect
66156651
6616-
[default_sect]
6652+
[base_sect]
66176653
activate = 1
6618-
```
6619-
6620-
where `fipsmodule.cnf` is the FIPS module configuration file generated from the
6621-
FIPS provider installation step:
66226654
6623-
```bash
6624-
openssl fipsinstall
6655+
[algorithm_sect]
6656+
default_properties = fips=yes
66256657
```
66266658

6627-
Set the `OPENSSL_CONF` environment variable to point to
6628-
your configuration file and `OPENSSL_MODULES` to the location of the FIPS
6629-
provider dynamic library. e.g.
6659+
The `fipsmodule.cnf` file is generated as part of the FIPS provider installation
6660+
and contains module integrity and self-test information. The exact command and
6661+
arguments are installation-specific; see [OpenSSL FIPS configuration][] and the
6662+
[OpenSSL FIPS module guide][]. The installation uses `openssl fipsinstall`.
6663+
6664+
The example activates the provider and enables the `fips=yes` property query
6665+
when Node.js starts. To activate the provider at startup but enable the property
6666+
query later with `crypto.setFips(true)`, omit `alg_section = algorithm_sect` and
6667+
the `[algorithm_sect]` block. The provider must still be loaded; when using this
6668+
startup configuration, keep its activation enabled. `crypto.setFips(true)`
6669+
should be called before application code uses other OpenSSL-backed APIs. It is
6670+
not equivalent to enabling the property query from process startup because
6671+
Node.js initializes some OpenSSL state before application code runs. Use the
6672+
example as written, [`--enable-fips`][], or [`--force-fips`][] when the property
6673+
query must be active from process startup.
6674+
6675+
`config_diagnostics` causes configuration errors to prevent startup instead of
6676+
being ignored. The `base` provider supplies non-cryptographic supporting
6677+
algorithms, such as encoders and decoders, that are commonly needed alongside
6678+
the FIPS provider. `default_properties = fips=yes` restricts OpenSSL's default
6679+
algorithm selection to implementations that match `fips=yes`.
6680+
6681+
Set `OPENSSL_CONF` to the OpenSSL configuration file. For a dynamically loaded
6682+
provider, `OPENSSL_MODULES` can set the directory containing the provider module.
6683+
For example:
66306684

66316685
```bash
66326686
export OPENSSL_CONF=/<path to configuration file>/nodejs.cnf
66336687
export OPENSSL_MODULES=/<path to openssl lib>/ossl-modules
66346688
```
66356689

6636-
FIPS mode can then be enabled in Node.js either by:
6637-
6638-
* Starting Node.js with `--enable-fips` or `--force-fips` command line flags.
6639-
* Programmatically calling `crypto.setFips(true)`.
6640-
6641-
Optionally FIPS mode can be enabled in Node.js via the OpenSSL configuration
6642-
file. e.g.
6643-
6644-
```text
6645-
nodejs_conf = nodejs_init
6646-
6647-
.include /<absolute path>/fipsmodule.cnf
6648-
6649-
[nodejs_init]
6650-
providers = provider_sect
6651-
alg_section = algorithm_sect
6652-
6653-
[provider_sect]
6654-
default = default_sect
6655-
# The fips section name should match the section name inside the
6656-
# included fipsmodule.cnf.
6657-
fips = fips_sect
6658-
6659-
[default_sect]
6660-
activate = 1
6661-
6662-
[algorithm_sect]
6663-
default_properties = fips=yes
6664-
```
6690+
The [`--openssl-config`][] command-line option selects the configuration file and
6691+
takes precedence over `OPENSSL_CONF`. If neither is set, OpenSSL's default
6692+
configuration file is used.
6693+
6694+
By default, Node.js reads the `nodejs_conf` section instead of OpenSSL's usual
6695+
`openssl_conf` section. Use [`--openssl-shared-config`][] to read `openssl_conf`,
6696+
or build Node.js with `./configure --openssl-conf-name=<name>` to change the
6697+
default section name.
6698+
6699+
On OpenSSL 3, the configuration above enables the `fips=yes` property query at
6700+
startup. The following controls are also available:
6701+
6702+
* [`--enable-fips`][] and [`--force-fips`][] enable the property query and
6703+
additionally require the configured provider named `fips` to initialize and
6704+
pass its self-test. Node.js exits if that check fails. `--force-fips` also
6705+
prevents FIPS mode from being disabled from script code.
6706+
* [`crypto.setFips()`][] changes the FIPS/property-query state. On OpenSSL 3, it
6707+
does not install, load, initialize, or validate a provider. Implementations
6708+
fetched before the call are not changed.
6709+
* [`crypto.getFips()`][] reports the FIPS/property-query state. On OpenSSL 3, a
6710+
return value of `1` does not prove that a FIPS provider is loaded or validated.
6711+
6712+
With OpenSSL 1.1.1, these controls use the library's FIPS mode support and
6713+
require a FIPS-capable OpenSSL build.
6714+
6715+
Only algorithms available under the active FIPS settings can be used. With
6716+
OpenSSL 3, if no loaded provider supplies a requested cryptographic
6717+
implementation matching `fips=yes`, fetching it fails, typically with
6718+
`ERR_OSSL_EVP_UNSUPPORTED`. The same error can occur for algorithms that
6719+
Node.js supports when FIPS mode is disabled but that are unavailable under the
6720+
active FIPS settings.
6721+
6722+
OpenSSL documents that the same FIPS provider cannot be used by multiple copies
6723+
of `libcrypto` in one process. This can affect native addons that load another
6724+
copy of `libcrypto`; OpenSSL's documented workaround is to use a separate copy
6725+
of the provider for each `libcrypto` instance. See [OpenSSL FIPS provider
6726+
limitations][].
66656727

66666728
## Crypto constants
66676729

@@ -6945,15 +7007,17 @@ See the [list of SSL OP Flags][] for details.
69457007
[Caveats]: #support-for-weak-or-compromised-algorithms
69467008
[Crypto constants]: #crypto-constants
69477009
[DEP0182]: deprecations.md#dep0182-short-gcm-authentication-tags-without-explicit-authtaglength
6948-
[FIPS module configuration file]: https://www.openssl.org/docs/man3.0/man5/fips_config.html
6949-
[FIPS provider from OpenSSL 3]: https://www.openssl.org/docs/man3.0/man7/crypto.html#FIPS-provider
7010+
[FIPS mode]: #fips-mode
7011+
[FIPS module configuration file]: https://docs.openssl.org/3.0/man5/fips_config/
69507012
[HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed
69517013
[JWK]: https://tools.ietf.org/html/rfc7517
69527014
[Key usages]: webcrypto.md#cryptokeyusages
69537015
[NIST SP 800-131A]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
69547016
[NIST SP 800-132]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
69557017
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
6956-
[OpenSSL's FIPS README file]: https://github.com/openssl/openssl/blob/openssl-3.0/README-FIPS.md
7018+
[OpenSSL FIPS configuration]: https://docs.openssl.org/3.0/man5/fips_config/
7019+
[OpenSSL FIPS module guide]: https://docs.openssl.org/master/man7/fips_module/
7020+
[OpenSSL FIPS provider limitations]: https://docs.openssl.org/3.6/man7/OSSL_PROVIDER-FIPS/
69577021
[OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man3.0/man1/openssl-spkac.html
69587022
[Permission Model]: permissions.md#permission-model
69597023
[RFC 1421]: https://www.rfc-editor.org/rfc/rfc1421.txt
@@ -6970,6 +7034,10 @@ See the [list of SSL OP Flags][] for details.
69707034
[RFC 9562]: https://www.rfc-editor.org/rfc/rfc9562.txt
69717035
[Web Crypto API documentation]: webcrypto.md
69727036
[`--allow-openssl-store`]: cli.md#--allow-openssl-store
7037+
[`--enable-fips`]: cli.md#--enable-fips
7038+
[`--force-fips`]: cli.md#--force-fips
7039+
[`--openssl-config`]: cli.md#--openssl-configfile
7040+
[`--openssl-shared-config`]: cli.md#--openssl-shared-config
69737041
[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html
69747042
[`Buffer`]: buffer.md
69757043
[`DH_generate_key()`]: https://www.openssl.org/docs/man3.0/man3/DH_generate_key.html
@@ -6996,6 +7064,7 @@ See the [list of SSL OP Flags][] for details.
69967064
[`crypto.generateKeyPair()`]: #cryptogeneratekeypairtype-options-callback
69977065
[`crypto.getCurves()`]: #cryptogetcurves
69987066
[`crypto.getDiffieHellman()`]: #cryptogetdiffiehellmangroupname
7067+
[`crypto.getFips()`]: #cryptogetfips
69997068
[`crypto.getHashes()`]: #cryptogethashes
70007069
[`crypto.hash()`]: #cryptohashalgorithm-data-options
70017070
[`crypto.privateDecrypt()`]: #cryptoprivatedecryptprivatekey-buffer
@@ -7004,6 +7073,7 @@ See the [list of SSL OP Flags][] for details.
70047073
[`crypto.publicEncrypt()`]: #cryptopublicencryptkey-buffer
70057074
[`crypto.randomBytes()`]: #cryptorandombytessize-callback
70067075
[`crypto.randomFill()`]: #cryptorandomfillbuffer-offset-size-callback
7076+
[`crypto.setFips()`]: #cryptosetfipsbool
70077077
[`crypto.sign()`]: #cryptosignalgorithm-data-key-callback
70087078
[`crypto.verify()`]: #cryptoverifyalgorithm-data-key-signature-callback
70097079
[`crypto.webcrypto.getRandomValues()`]: webcrypto.md#cryptogetrandomvaluestypedarray

0 commit comments

Comments
 (0)