Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codebuild/bin/s2n_fips_openssl.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
10 changes: 0 additions & 10 deletions crypto/s2n_fips.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
13 changes: 12 additions & 1 deletion crypto/s2n_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "utils/s2n_safety.h"

#if S2N_LIBCRYPTO_SUPPORTS_PROVIDERS
#include <openssl/provider.h>
static EVP_MD *s2n_evp_mds[S2N_HASH_ALGS_COUNT] = { 0 };
#else
static const EVP_MD *s2n_evp_mds[S2N_HASH_ALGS_COUNT] = { 0 };
Expand Down Expand Up @@ -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");
}
Comment on lines +62 to +70
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, s2n-tls does not configure Openssl for customers. Any changes we make will affect other libraries / application use of Openssl. If we load "default" here for NULL library context, we're loading "default" globally with no indication of how that will affect other code that depends on Openssl. We require that the application configure Openssl as needed / desired.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack - but the other documentation in s2n-tls README explicitly tells end user to load globally and system-wide for all applications and the system, including s2n-tls but also any other system apps.

My ideal preference is to actually not load the default provider at all - and instead not crash and silently not allow MD5 / SHA1 policies etc, and be more oportunistic. Right now s2n-tls crashes if MD5 is not there, and default provider is not loaded.

Would it be acceptable to make MD5, SHA1, MD5-SHA1 optional when default provider has not already been loaded by the user in the global config and/or within the app context that uses s2n-tls?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be acceptable to make MD5, SHA1, MD5-SHA1 optional when default provider has not already been loaded by the user in the global config and/or within the app context that uses s2n-tls?

That would be the preferred way to do it. The problems you'll run into (if I remember correctly from the last time I poked at this) are 1) lots of old tests assume those algorithms are always available 2) there is currently no existing mechanism to mark hash algorithms available / not available. It might also affect protocol version negotiation: if the legacy hashes aren't available, only TLS1.2+ can be negotiated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, but like effectively all FIPS is now TLS1.2+ only in OpenSSL context => the non-extended-master-secret TLSv1.2 has been retired, which needs at least openssl 1.1.1 which has tlsv1.2 and tlsv1.3 support. And if one otherwise compiles openssl in seclevel 2 by default, and sets min prototocl to tlsv1.2 it is a strong indicator the user does not want these legacy algorithms.

Which is quite contratry to what s2n-tls stands for - to be a universal terminator, with own implementation and configs of arbitrary tls feature sets.

Let me ponder things more around here.

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);
Expand Down
11 changes: 8 additions & 3 deletions crypto/s2n_pkey_evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Comment on lines +88 to +91
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if we don't directly check indicators, we should not knowingly violate the FIPS 140-3 rules. This comment documents that we're aware that "digest-then-sign" is not supported by FIPS 140-3 modules for ECDSA verify or RSA sign/verify based on the tests defined for FIPS 140-3 modules. If we want to advertise support for Openssl + FIPS 140-3 and remove that README warning about only supporting FIPS 140-2, then we must make "digest-and-sign" work for Openssl.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK!

* See https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Digital-Signatures,
* and note that "component" tests only exist for ECDSA sign.
*
Expand Down Expand Up @@ -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)
Expand Down
22 changes: 5 additions & 17 deletions docs/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
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 addition, 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

Expand Down Expand Up @@ -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.
1 change: 1 addition & 0 deletions tls/s2n_cipher_suites.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Loading