"Host being in FIPS mode"
johnrichardrinehart opened this issue · comments
This repo's README says that FIPS mode can be enabled through GOLANG_FIPS=1
or by virtue of the host being in FIPS mode.
Line 28 in ebcd504
Question 1: Can
go/src/crypto/internal/boring/boring.go
Lines 71 to 72 in 1b876a8
true
with an appropriately-configured OpenSSL whose version is <3 (a version which supports FIPS, obviously) without requiring GOLANG_FIPS=1
(so, one where fipsConfigured == true
)?
Question 2: If the answer to Question 1 is that "host mode" is supported then what exactly is required to enable it? Setting OPENSSL_FIPS=1
? Only changing the openssl.cnf
such that the openssl
binary is in FIPS mode, by default, is insufficient.
Question 1: Can
go/src/crypto/internal/boring/boring.go
Lines 71 to 72 in 1b876a8
returntrue
with an appropriately-configured OpenSSL whose version is <3 (a version which supports FIPS, obviously) without requiringGOLANG_FIPS=1
(so, one wherefipsConfigured == true
)?
Yes, if you set fips_mode = on
in the EVP Configuration Module section of the openssl.cnf
file, see https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/doc/man5/config.pod#evp-configuration-module.
Specifically, something like
openssl_conf = openssl_init
[openssl_init]
alg_section = evp_properties
[evp_properties]
fips_mode = on
should do this. For OpenSSL 3, the same applies but the option needs to be default_properties = "fips=yes"
instead of fips_mode = on
.
Some Distributions change this to instead query a system-wide setting, e.g. on RHEL, FIPS mode is enabled using fips-mode-setup(8)
.
Question 2: If the answer to Question 1 is that "host mode" is supported then what exactly is required to enable it? Setting
OPENSSL_FIPS=1
? Only changing theopenssl.cnf
such that theopenssl
binary is in FIPS mode, by default, is insufficient.
See above, but this may depend on your distribution. Check with your distribution vendor for the detailed process.
Thanks for your response. It's interesting that you linked to the OpenSSL 1.1.1 documentation when only OpenSSL 1.0.1, 1.0.2, and 3.0+ support FIPS.
And, I've tested the above configuration file and can confirm that this does change the behavior of the openssl
binary. But, it doesn't seem to affect go
/C
applications which link against OpenSSL (libcrypto
and the FOM). They need to explicitly call FIPS_mode_set(1)
in order to enable FIPS mode which isn't done by only linking against the library. In fact, the implicit call in boring.go
to OPENSSL_init()
does not read this configuration file or call FIPS_mode_set(1)
.
There does seem to be some evidence that calling OPENSSL_config()
would do this but I don't see that being done anywhere.
Have you tested to confirm that the above is true?
Thanks for your response. It's interesting that you linked to the OpenSSL 1.1.1 documentation when only OpenSSL 1.0.1, 1.0.2, and 3.0+ support FIPS.
OpenSSL 1.1 has a FIPS mode, but may never have been certified by OpenSSL upstream. It certainly was certified according to FIPS 140-2 by other vendors ([1], [2], [3], [4] and many more).
Those vendors may have made further changes to the way FIPS mode is enabled. If you're interested in a specific implementation, you should contact the vendor of your FIPS-certified module.
And, I've tested the above configuration file and can confirm that this does change the behavior of the
openssl
binary. But, it doesn't seem to affectgo
/C
applications which link against OpenSSL (libcrypto
and the FOM). They need to explicitly callFIPS_mode_set(1)
in order to enable FIPS mode which isn't done by only linking against the library. In fact, the implicit call inboring.go
toOPENSSL_init()
does not read this configuration file or callFIPS_mode_set(1)
.
I have tested this on RHEL 8, but RHEL 8's copy of OpenSSL adds a patch to read /proc/sys/crypto/fips_enabled
in an __attribute__((constructor))
function and calls FIPS_mode_set()
, so these results do not apply to OpenSSL upstream. It is certainly possible that this code would need to additionally call some other initialization function on a different platform.
There does seem to be some evidence that calling
OPENSSL_config()
would do this but I don't see that being done anywhere.Have you tested to confirm that the above is true?
No.
@neverpanic You're right that OpenSSL
1.1 supports configuring (openssl.cnf
) in FIPS mode and has the logic stubbed out. Better for me not to have said "only X, Y, and Z support FIPS" and, instead, "does not have an OpenSSL FIPS object module available". Thanks, also, for linking to 3rd-party vendors who sought and received validation/certification. Yeah, Oracle Linux has similar functionality which makes sense.
Thanks for interacting with me on this. I understand, now, that OpenSSL
<3 (and not its forks) does not support "system" mode by default when linking against it, but that various operating systems and 3rd-party packages may provide some system-level support. Regardless, these forks are likely calling FIPS_mode_set(1)
as a part of this system-level support.