Skip to content

Commit 7558ef3

Browse files
richardlauMoLow
authored andcommittedJul 6, 2023
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 361cf8c commit 7558ef3

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
@@ -792,246 +792,12 @@ $ ./configure --openssl-conf-name=<some_conf_name>
792792

793793
## Building Node.js with FIPS-compliant OpenSSL
794794

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

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

1036802
## Building Node.js with external core modules
1037803

‎doc/api/crypto.md

+83
Original file line numberDiff line numberDiff line change
@@ -5736,6 +5736,86 @@ try {
57365736
console.log(receivedPlaintext);
57375737
```
57385738

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

57415821
The following constants exported by `crypto.constants` apply to various uses of
@@ -6015,12 +6095,15 @@ See the [list of SSL OP Flags][] for details.
60156095
[CVE-2021-44532]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44532
60166096
[Caveats]: #support-for-weak-or-compromised-algorithms
60176097
[Crypto constants]: #crypto-constants
6098+
[FIPS module configuration file]: https://www.openssl.org/docs/man3.0/man5/fips_config.html
6099+
[FIPS provider from OpenSSL 3]: https://www.openssl.org/docs/man3.0/man7/crypto.html#FIPS-provider
60186100
[HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed
60196101
[JWK]: https://tools.ietf.org/html/rfc7517
60206102
[NIST SP 800-131A]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf
60216103
[NIST SP 800-132]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
60226104
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
60236105
[Nonce-Disrespecting Adversaries]: https://github.com/nonce-disrespect/nonce-disrespect
6106+
[OpenSSL's FIPS README file]: https://github.com/openssl/openssl/blob/openssl-3.0/README-FIPS.md
60246107
[OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man3.0/man1/openssl-spkac.html
60256108
[RFC 1421]: https://www.rfc-editor.org/rfc/rfc1421.txt
60266109
[RFC 2409]: https://www.rfc-editor.org/rfc/rfc2409.txt

0 commit comments

Comments
 (0)
Please sign in to comment.