Skip to content

Commit a472a8d

Browse files
richardlaupull[bot]
authored andcommitted
doc: update documentation for FIPS support
When using OpenSSL 3, Node.js supports FIPS 140-2 when used with an appropriate OpenSSL 3 provider. It is no longer necessary to rebuild Node.js with different build time options. Add a section on how to configure Node.js to use an OpenSSL 3 FIPS provider to the documentation for the `crypto` module. PR-URL: #48194 Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 2ed8a9e commit a472a8d

File tree

2 files changed

+88
-239
lines changed

2 files changed

+88
-239
lines changed

BUILDING.md

+5-239
Original file line numberDiff line numberDiff line change
@@ -794,246 +794,12 @@ configure option:
794794

795795
## Building Node.js with FIPS-compliant OpenSSL
796796

797-
The current version of Node.js supports FIPS when statically and
798-
dynamically linking with OpenSSL 3.0.0 by using the configuration flag
799-
`--openssl-is-fips`.
797+
Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via
798+
[OpenSSL's provider model](https://www.openssl.org/docs/man3.0/man7/crypto.html#OPENSSL-PROVIDERS).
799+
It is not necessary to rebuild Node.js to enable support for FIPS.
800800

801-
### FIPS support when statically linking OpenSSL
802-
803-
FIPS can be supported by specifying the configuration flag `--openssl-is-fips`:
804-
805-
```bash
806-
./configure --openssl-is-fips
807-
make -j8
808-
```
809-
810-
The above command will build and install the FIPS module into the out directory.
811-
This includes building fips.so, running the `installfips` command that generates
812-
the FIPS configuration file (fipsmodule.cnf), copying and updating openssl.cnf
813-
to include the correct path to fipsmodule.cnf and finally uncomment the fips
814-
section.
815-
816-
We can then run node specifying `--enable-fips`:
817-
818-
```console
819-
$ ./node --enable-fips -p 'crypto.getFips()'
820-
1
821-
```
822-
823-
The above will use the Node.js default locations for OpenSSL 3.0:
824-
825-
```console
826-
$ ./out/Release/openssl-cli version -m -d
827-
OPENSSLDIR: "/nodejs/openssl/out/Release/obj.target/deps/openssl"
828-
MODULESDIR: "/nodejs/openssl/out/Release/obj.target/deps/openssl/lib/openssl-modules"
829-
```
830-
831-
The OpenSSL configuration files will be found in `OPENSSLDIR` directory above:
832-
833-
```console
834-
$ ls -w 1 out/Release/obj.target/deps/openssl/*.cnf
835-
out/Release/obj.target/deps/openssl/fipsmodule.cnf
836-
out/Release/obj.target/deps/openssl/openssl.cnf
837-
```
838-
839-
And the FIPS module will be located in the `MODULESDIR` directory:
840-
841-
```console
842-
$ ls out/Release/obj.target/deps/openssl/lib/openssl-modules/
843-
fips.so
844-
```
845-
846-
Running `configure` without `--openssl-is-fips` flag and rebuilding will reset
847-
the FIPS configuration.
848-
849-
### FIPS support when dynamically linking OpenSSL
850-
851-
For quictls/openssl 3.0 it is possible to enable FIPS when dynamically linking.
852-
If you want to build Node.js using openssl-3.0.0+quic, you can follow these
853-
steps:
854-
855-
**clone OpenSSL source and prepare build**
856-
857-
```bash
858-
git clone git@github.com:quictls/openssl.git
859-
860-
cd openssl
861-
862-
./config \
863-
--prefix=/path/to/install/dir/ \
864-
shared \
865-
enable-fips \
866-
linux-x86_64
867-
```
868-
869-
The `/path/to/install/dir` is the path in which the `make install` instructions
870-
will publish the OpenSSL libraries and such. We will also use this path
871-
(and sub-paths) later when compiling Node.js.
872-
873-
**compile and install OpenSSL**
874-
875-
```bash
876-
make -j8
877-
make install
878-
make install_ssldirs
879-
make install_fips
880-
```
881-
882-
After the OpenSSL (including FIPS) modules have been compiled and installed
883-
(into the `/path/to/install/dir`) by the above instructions we also need to
884-
update the OpenSSL configuration file located under
885-
`/path/to/install/dir/ssl/openssl.cnf`. Right next to this file, you should
886-
find the `fipsmodule.cnf` file - let's add the following to the end of the
887-
`openssl.cnf` file.
888-
889-
**alter openssl.cnf**
890-
891-
```text
892-
.include /absolute/path/to/fipsmodule.cnf
893-
894-
# List of providers to load
895-
[provider_sect]
896-
default = default_sect
897-
# The fips section name should match the section name inside the
898-
# included /path/to/install/dir/ssl/fipsmodule.cnf.
899-
fips = fips_sect
900-
901-
[default_sect]
902-
activate = 1
903-
```
904-
905-
You can e.g. accomplish this by running the following command - be sure to
906-
replace `/path/to/install/dir/` with the path you have selected. Please make
907-
sure that you specify an absolute path for the `.include fipsmodule.cnf` line -
908-
using relative paths did not work on my system!
909-
910-
**alter openssl.cnf using a script**
911-
912-
```bash
913-
cat <<EOT >> /path/to/install/dir/ssl/openssl.cnf
914-
.include /path/to/install/dir/ssl/fipsmodule.cnf
915-
916-
# List of providers to load
917-
[provider_sect]
918-
default = default_sect
919-
# The fips section name should match the section name inside the
920-
# included /path/to/install/dir/ssl/fipsmodule.cnf.
921-
fips = fips_sect
922-
923-
[default_sect]
924-
activate = 1
925-
EOT
926-
```
927-
928-
As you might have picked a non-custom path for your OpenSSL install dir, we
929-
have to export the following two environment variables in order for Node.js to
930-
find our OpenSSL modules we built beforehand:
931-
932-
```bash
933-
export OPENSSL_CONF=/path/to/install/dir/ssl/openssl.cnf
934-
export OPENSSL_MODULES=/path/to/install/dir/lib/ossl-modules
935-
```
936-
937-
**build Node.js**
938-
939-
```bash
940-
./configure \
941-
--shared-openssl \
942-
--shared-openssl-libpath=/path/to/install/dir/lib \
943-
--shared-openssl-includes=/path/to/install/dir/include \
944-
--shared-openssl-libname=crypto,ssl \
945-
--openssl-is-fips
946-
947-
export LD_LIBRARY_PATH=/path/to/install/dir/lib
948-
949-
make -j8
950-
```
951-
952-
**verify the produced executable**
953-
954-
```console
955-
$ ldd ./node
956-
linux-vdso.so.1 (0x00007ffd7917b000)
957-
libcrypto.so.81.3 => /path/to/install/dir/lib/libcrypto.so.81.3 (0x00007fd911321000)
958-
libssl.so.81.3 => /path/to/install/dir/lib/libssl.so.81.3 (0x00007fd91125e000)
959-
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007fd911232000)
960-
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd911039000)
961-
libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd910ef3000)
962-
libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd910ed9000)
963-
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007fd910eb5000)
964-
libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd910cec000)
965-
/lib64/ld-linux-x86-64.so.2 (0x00007fd9117f2000)
966-
```
967-
968-
If the `ldd` command says that `libcrypto` cannot be found one needs to set
969-
`LD_LIBRARY_PATH` to point to the directory used above for
970-
`--shared-openssl-libpath` (see previous step).
971-
972-
**verify the OpenSSL version**
973-
974-
```console
975-
$ ./node -p process.versions.openssl
976-
3.0.0-alpha16+quic
977-
```
978-
979-
**verify that FIPS is available**
980-
981-
```console
982-
$ ./node -p 'process.config.variables.openssl_is_fips'
983-
true
984-
985-
$ ./node --enable-fips -p 'crypto.getFips()'
986-
1
987-
```
988-
989-
FIPS support can then be enable via the OpenSSL configuration file or
990-
using `--enable-fips` or `--force-fips` command line options to the Node.js
991-
executable. See sections
992-
[Enabling FIPS using Node.js options](#enabling-fips-using-node.js-options) and
993-
[Enabling FIPS using OpenSSL config](#enabling-fips-using-openssl-config) below.
994-
995-
### Enabling FIPS using Node.js options
996-
997-
This is done using one of the Node.js options `--enable-fips` or
998-
`--force-fips`, for example:
999-
1000-
```bash
1001-
node --enable-fips -p 'crypto.getFips()'
1002-
```
1003-
1004-
### Enabling FIPS using OpenSSL config
1005-
1006-
This example show that using OpenSSL's configuration file, FIPS can be enabled
1007-
without specifying the `--enable-fips` or `--force-fips` options by setting
1008-
`default_properties = fips=yes` in the FIPS configuration file. See
1009-
[link](https://github.com/openssl/openssl/blob/master/README-FIPS.md#loading-the-fips-module-at-the-same-time-as-other-providers)
1010-
for details.
1011-
1012-
For this to work the OpenSSL configuration file (default openssl.cnf) needs to
1013-
be updated. The following shows an example:
1014-
1015-
```text
1016-
openssl_conf = openssl_init
1017-
1018-
.include /path/to/install/dir/ssl/fipsmodule.cnf
1019-
1020-
[openssl_init]
1021-
providers = prov
1022-
alg_section = algorithm_sect
1023-
1024-
[prov]
1025-
fips = fips_sect
1026-
default = default_sect
1027-
1028-
[default_sect]
1029-
activate = 1
1030-
1031-
[algorithm_sect]
1032-
default_properties = fips=yes
1033-
```
1034-
1035-
After this change Node.js can be run without the `--enable-fips` or `--force-fips`
1036-
options.
801+
See [FIPS mode](./doc/api/crypto.md#fips-mode) for more information on how to
802+
enable FIPS support in Node.js.
1037803

1038804
## Building Node.js with external core modules
1039805

doc/api/crypto.md

+83
Original file line numberDiff line numberDiff line change
@@ -5723,6 +5723,86 @@ try {
57235723
console.log(receivedPlaintext);
57245724
```
57255725

5726+
### FIPS mode
5727+
5728+
When using OpenSSL 3, Node.js supports FIPS 140-2 when used with an appropriate
5729+
OpenSSL 3 provider, such as the [FIPS provider from OpenSSL 3][] which can be
5730+
installed by following the instructions in [OpenSSL's FIPS README file][].
5731+
5732+
For FIPS support in Node.js you will need:
5733+
5734+
* A correctly installed OpenSSL 3 FIPS provider.
5735+
* An OpenSSL 3 [FIPS module configuration file][].
5736+
* An OpenSSL 3 configuration file that references the FIPS module
5737+
configuration file.
5738+
5739+
Node.js will need to be configured with an OpenSSL configuration file that
5740+
points to the FIPS provider. An example configuration file looks like this:
5741+
5742+
```text
5743+
nodejs_conf = nodejs_init
5744+
5745+
.include /<absolute path>/fipsmodule.cnf
5746+
5747+
[nodejs_init]
5748+
providers = provider_sect
5749+
5750+
[provider_sect]
5751+
default = default_sect
5752+
# The fips section name should match the section name inside the
5753+
# included fipsmodule.cnf.
5754+
fips = fips_sect
5755+
5756+
[default_sect]
5757+
activate = 1
5758+
```
5759+
5760+
where `fipsmodule.cnf` is the FIPS module configuration file generated from the
5761+
FIPS provider installation step:
5762+
5763+
```bash
5764+
openssl fipsinstall
5765+
```
5766+
5767+
Set the `OPENSSL_CONF` environment variable to point to
5768+
your configuration file and `OPENSSL_MODULES` to the location of the FIPS
5769+
provider dynamic library. e.g.
5770+
5771+
```bash
5772+
export OPENSSL_CONF=/<path to configuration file>/nodejs.cnf
5773+
export OPENSSL_MODULES=/<path to openssl lib>/ossl-modules
5774+
```
5775+
5776+
FIPS mode can then be enabled in Node.js either by:
5777+
5778+
* Starting Node.js with `--enable-fips` or `--force-fips` command line flags.
5779+
* Programmatically calling `crypto.setFips(true)`.
5780+
5781+
Optionally FIPS mode can be enabled in Node.js via the OpenSSL configuration
5782+
file. e.g.
5783+
5784+
```text
5785+
nodejs_conf = nodejs_init
5786+
5787+
.include /<absolute path>/fipsmodule.cnf
5788+
5789+
[nodejs_init]
5790+
providers = provider_sect
5791+
alg_section = algorithm_sect
5792+
5793+
[provider_sect]
5794+
default = default_sect
5795+
# The fips section name should match the section name inside the
5796+
# included fipsmodule.cnf.
5797+
fips = fips_sect
5798+
5799+
[default_sect]
5800+
activate = 1
5801+
5802+
[algorithm_sect]
5803+
default_properties = fips=yes
5804+
```
5805+
57265806
## Crypto constants
57275807

57285808
The following constants exported by `crypto.constants` apply to various uses of
@@ -5998,12 +6078,15 @@ See the [list of SSL OP Flags][] for details.
59986078
[CVE-2021-44532]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44532
59996079
[Caveats]: #support-for-weak-or-compromised-algorithms
60006080
[Crypto constants]: #crypto-constants
6081+
[FIPS module configuration file]: https://www.openssl.org/docs/man3.0/man5/fips_config.html
6082+
[FIPS provider from OpenSSL 3]: https://www.openssl.org/docs/man3.0/man7/crypto.html#FIPS-provider
60016083
[HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed
60026084
[JWK]: https://tools.ietf.org/html/rfc7517
60036085
[NIST SP 800-131A]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf
60046086
[NIST SP 800-132]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
60056087
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
60066088
[Nonce-Disrespecting Adversaries]: https://github.com/nonce-disrespect/nonce-disrespect
6089+
[OpenSSL's FIPS README file]: https://github.com/openssl/openssl/blob/openssl-3.0/README-FIPS.md
60076090
[OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man3.0/man1/openssl-spkac.html
60086091
[RFC 1421]: https://www.rfc-editor.org/rfc/rfc1421.txt
60096092
[RFC 2409]: https://www.rfc-editor.org/rfc/rfc2409.txt

0 commit comments

Comments
 (0)