diff --git a/codebuild/bin/s2n_fips_openssl.cnf b/codebuild/bin/s2n_fips_openssl.cnf index 514c7de24f0..1a7d93a8817 100644 --- a/codebuild/bin/s2n_fips_openssl.cnf +++ b/codebuild/bin/s2n_fips_openssl.cnf @@ -56,10 +56,10 @@ alg_section = algorithm_sect # List of providers to load [provider_sect] -default = default_sect +base = base_sect fips = fips_sect -[default_sect] +[base_sect] activate = 1 [algorithm_sect] diff --git a/crypto/s2n_fips.c b/crypto/s2n_fips.c index 13f9f77c079..87542b8e5ed 100644 --- a/crypto/s2n_fips.c +++ b/crypto/s2n_fips.c @@ -57,16 +57,6 @@ int s2n_fips_init(void) { s2n_fips_mode_enabled = s2n_libcrypto_is_fips(); - /* When using Openssl, ONLY 3.0 currently supports FIPS. - * openssl-1.0.2-fips is no longer supported. - * openssl >= 3.5 will likely have a FIPS 140-3 certificate instead of a - * FIPS 140-2 certificate, which will require additional review in order - * to properly integrate. - */ -#if defined(OPENSSL_FIPS) || S2N_OPENSSL_VERSION_AT_LEAST(3, 5, 0) - POSIX_ENSURE(!s2n_fips_mode_enabled, S2N_ERR_FIPS_MODE_UNSUPPORTED); -#endif - return S2N_SUCCESS; } diff --git a/crypto/s2n_hash.c b/crypto/s2n_hash.c index 215236817b1..8714f73833d 100644 --- a/crypto/s2n_hash.c +++ b/crypto/s2n_hash.c @@ -21,6 +21,7 @@ #include "utils/s2n_safety.h" #if S2N_LIBCRYPTO_SUPPORTS_PROVIDERS +#include static EVP_MD *s2n_evp_mds[S2N_HASH_ALGS_COUNT] = { 0 }; #else static const EVP_MD *s2n_evp_mds[S2N_HASH_ALGS_COUNT] = { 0 }; @@ -55,8 +56,18 @@ S2N_RESULT s2n_hash_algorithms_init() * Additionally, the old style methods do not support property query strings * to guide which provider to fetch from. This is important for FIPS, where * the default query string of "fips=yes" will need to be overridden for - * legacy algorithms. + * legacy algorithms. TODO: are they actually still in use in FIPS mode? + * */ + if (!OSSL_PROVIDER_available(NULL, "default")) { + /* System is configured without the default provider, but we are + * about to fetch MD5 and SHA1 from it below, note note sure if + * this should be conditional and opportunistic, as most + * policies no longer use SHA1, and even SHA224 is weak these + * days. Similar approach is taken in python to fetch MD5 when + * usedforsecurity=False */ + OSSL_PROVIDER_load(NULL, "default"); + } s2n_evp_mds[S2N_HASH_MD5] = EVP_MD_fetch(NULL, "MD5", "-fips"); s2n_evp_mds[S2N_HASH_MD5_SHA1] = EVP_MD_fetch(NULL, "MD5-SHA1", "-fips"); s2n_evp_mds[S2N_HASH_SHA1] = EVP_MD_fetch(NULL, "SHA1", NULL); diff --git a/crypto/s2n_pkey_evp.c b/crypto/s2n_pkey_evp.c index 7775f87659b..7c21c48bf2d 100644 --- a/crypto/s2n_pkey_evp.c +++ b/crypto/s2n_pkey_evp.c @@ -85,6 +85,10 @@ static EVP_PKEY_CTX *s2n_evp_pkey_ctx_new(EVP_PKEY *pkey, s2n_hash_algorithm has /* Our "digest-and-sign" EVP signing logic is intended to support FIPS 140-3. * FIPS 140-3 does not allow signing or verifying externally calculated digests * for RSA and ECDSA verify. + * + * However most FIPS 140-3 implementation raise an indicator and allow + * doing so. This implementation does not rely on such indicators. + * * See https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Digital-Signatures, * and note that "component" tests only exist for ECDSA sign. * @@ -155,9 +159,10 @@ static bool s2n_pkey_evp_digest_and_sign_is_required(s2n_signature_algorithm sig return s2n_libcrypto_is_awslc_fips(); } -/* "digest-then-sign" means that we calculate the digest for a hash state, - * then sign the digest bytes. That is not allowed by FIPS 140-3, but is allowed - * in all other cases. +/* "digest-then-sign" means that we calculate the digest for a hash state, then + * sign the digest bytes. That is not allowed by FIPS 140-3 (for specific padding + * methods can succeed whilst raising an indicator but dependes on vendor specific + * implementation details), but is allowed in all other cases. */ static int s2n_pkey_evp_digest_then_sign(EVP_PKEY_CTX *pctx, struct s2n_hash_state *hash_state, struct s2n_blob *signature) diff --git a/docs/BUILD.md b/docs/BUILD.md index 35af87fb963..e4a18b149d9 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -138,27 +138,15 @@ The `CMAKE_INSTALL_PREFIX` option can be provided when building AWS-LC to specif s2n-tls supports FIPS mode when built with a FIPS validated version of aws-lc. See the [AWS-LC FIPS documentation](https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/FIPS.md) for more information. The security policy listed for each FIPS validation includes instructions for how to build the validated version. -### Openssl FIPS +### OpenSSL FIPS You should consider using AWS-LC if you require FIPS. AWS-LC is s2n-tls's recommended libcrypto: see [Why AWS-LC?](https://github.com/aws/aws-lc/blob/main/README.md#why-aws-lc). You can use the `S2N_INTERN_LIBCRYPTO` CMake option to "intern" AWS-LC and keep it isolated to s2n-tls if AWS-LC symbols would conflict with Openssl symbols in your environment. -But if you must use Openssl instead of AWS-LC, then s2n-tls does support FIPS mode when built with a FIPS-validated version of Openssl. See the [Openssl FIPS documentation](https://github.com/openssl/openssl/blob/master/README-FIPS.md) for how to build a FIPS-validated version of Openssl. +But if you must use OpenSSL instead of AWS-LC, then s2n-tls does support FIPS mode when built with a FIPS-validated version of OpenSSL. See the [Openssl FIPS documentation](https://github.com/openssl/openssl/blob/master/README-FIPS.md) for how to build a FIPS-validated version of OpenSSL. Only attempt this if your OS or 3rd-party vendor doesn't already provide a FIPS provider for your installation of OpenSSL. -Note that currently s2n-tls only supports the Openssl-3.0 version of FIPS-validated Openssl. Openssl-3.0 has a FIPS 140-2 certificate, NOT a FIPS 140-3 certificate. If you require FIPS 140-3, consider using AWS-LC instead. Once Openssl releases a FIPS 140-3 validated version (currently planned for Openssl-3.5), then the s2n-tls integration can be updated. Because of the significant changes made in FIPS 140-3, simply building s2n-tls with a FIPS 140-3 validated version of Openssl will not meet all FIPS 140-3 requirements. - -When running in FIPS mode with Openssl, s2n-tls does not support RSA 1024 certificates (https://github.com/aws/s2n-tls/issues/5200) or ChaChaPoly (https://github.com/aws/s2n-tls/issues/5199), even if allowed by the configured security policy. As with non-FIPS Openssl, RC4 is also not supported. - -s2n-tls requires that Openssl be configured with the default provider in addition to the FIPS provider. The base provider is NOT sufficient. s2n-tls assumes that non-FIPS algorithms like MD5 and SHA1 are available even when built with FIPS-validated Openssl. If you are following the [Openssl documentation for how to configure FIPS](https://docs.openssl.org/master/man7/fips_module/), your openssl.cnf must include: -``` -[provider_sect] -default = default_sect -fips = fips_sect - -[default_sect] -activate = 1 -``` -Note the use of `default` instead of `base`. You can see the openssl.cnf that s2n-tls uses for testing [here](https://github.com/aws/s2n-tls/blob/main/codebuild/bin/s2n_fips_openssl.cnf). +The FIPS certificate depends on the version of the FIPS provider, and not of the libcrypto/libssl version that can be higher or lower. Multiple validations exists for 3.0.8 and 3.1.2 providers with FIPS 140-3 standard from multiple vendors. Also alternative providers exist for OpenSSL which might be operating in FIPS mode (Symcrypt, Wolfcrypt, Keypair, and others). The certification of your OpenSSL installation depends on the loaded providers and the certifications they have. Testing all vendors providers is out of scope for s2n-tls, but it may work. Please consider using aws-lc-fips build configuration instead. +When running in FIPS mode with OpenSSL, precise supported runtime configurations depend on the security policy of your FIPS provider. For example, key sizes and algorithms will be enforced by the FIPS provider, even if s2n-tls is configured to attempt to use them. Note runtime indicators are not checked, some usage might be successful but in unapproved mode. Please check approved and unapproved services and service indicators in the security policy of your FIPS provider. In additiona, s2n-tls in FIPS mode blocks support for RSA 1024 certificates (https://github.com/aws/s2n-tls/issues/5200) or ChaChaPoly (https://github.com/aws/s2n-tls/issues/5199), even if allowed by the configured security policy. As with non-FIPS OpenSSL, RC4 is also not supported. ## Other build methods @@ -266,4 +254,4 @@ When both of the above concerns are known to be mitigated in the linked libcrypt The s2n-tls RAND engine may conflict with some environments that use the same libcrypto as s2n-tls. For example, other applications or libraries may have certain requirements for the libcrypto RAND engine that the s2n-tls implementation doesn't provide. Other applications or libraries might also need to implement their own custom RAND engines. If the s2n-tls RAND engine conflicts with your environment, consider enabling libcrypto interning with the `S2N_INTERN_LIBCRYPTO` CMake option, which will build s2n-tls with its own copy of the libcrypto that's isolated from the rest of the environment. -If the s2n-tls RAND engine conflicts with your environment and enabling libcrypto interning is not a viable option, s2n-tls can be forced to disable overriding the RAND engine by setting the `S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE` CMake flag to false when building s2n-tls. This is not recommended unless both of the concerns described above are confirmed to be inapplicable to your use case. +If the s2n-tls RAND engine conflicts with your environment and enabling libcrypto interning is not a viable option, s2n-tls can be forced to disable overriding the RAND engine by setting the `S2N_OVERRIDE_LIBCRYPTO_RAND_ENGINE` CMake flag to false when building s2n-tls. One noteworthy scenario when one should use this option is when using system OpenSSL 3.4+ with certified statically linked jitterentropy source in libcrypto, with callbacks reconfigured to use such entropy source for the OpenSSL FIPS providers, as shipped by Chainguard OS. In all other cases, this is not recommended unless both of the concerns described above are confirmed to be inapplicable to your use case. diff --git a/tls/s2n_cipher_suites.c b/tls/s2n_cipher_suites.c index ebc45b0beab..8e1936c4aed 100644 --- a/tls/s2n_cipher_suites.c +++ b/tls/s2n_cipher_suites.c @@ -1037,6 +1037,7 @@ int s2n_cipher_suites_init(void) /*https://wiki.openssl.org/index.php/Manual:OpenSSL_add_all_algorithms(3)*/ OpenSSL_add_all_algorithms(); #else + /* Note implicit init may have already happened in s2n_hash_algorithms_init() with OpenSSL with providers */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); #endif }