-
Notifications
You must be signed in to change notification settings - Fork 718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: remove openssl-1.0.2-fips 'allow md5' logic #5048
Changes from 3 commits
9bfe1fa
3e01156
c60e3fd
01745fb
20684fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,39 +15,6 @@ | |
|
||
#include "crypto/s2n_evp.h" | ||
|
||
#include "crypto/s2n_fips.h" | ||
#include "error/s2n_errno.h" | ||
#include "utils/s2n_safety.h" | ||
|
||
int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest) | ||
{ | ||
POSIX_ENSURE_REF(evp_digest); | ||
/* This is only to be used for EVP digests that will require MD5 to be used | ||
* to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used | ||
* outside of the TLS 1.0 and 1.1 PRF when in FIPS mode. | ||
*/ | ||
S2N_ERROR_IF(!s2n_is_in_fips_mode() || (evp_digest->ctx == NULL), S2N_ERR_ALLOW_MD5_FOR_FIPS_FAILED); | ||
|
||
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) | ||
EVP_MD_CTX_set_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); | ||
#endif | ||
return S2N_SUCCESS; | ||
} | ||
|
||
S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out) | ||
{ | ||
RESULT_ENSURE_REF(out); | ||
*out = false; | ||
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC) | ||
if (s2n_is_in_fips_mode() && evp_digest && evp_digest->ctx && EVP_MD_CTX_test_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) { | ||
/* s2n is in FIPS mode and the EVP digest allows MD5. */ | ||
*out = true; | ||
} | ||
#else | ||
if (s2n_is_in_fips_mode()) { | ||
/* If s2n is in FIPS mode and built with AWS-LC or BoringSSL, there are no flags to check in the EVP digest to allow MD5. */ | ||
*out = true; | ||
} | ||
#endif | ||
Comment on lines
-40
to
-51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one's a bit trickier. It roughly translates to:
So with the removal of openssl+fips via openssl-1.0.2-fips, this method boils down to "is fips?". We only use this method for two purposes (see search):
|
||
return S2N_RESULT_OK; | ||
} | ||
/* | ||
* TODO: update all CBMC proofs that depend on this file, then delete. | ||
*/ | ||
Comment on lines
+18
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I delete this file, I have to update ALL of the s2n_hash CBMC proofs because they all declare it as a source file. It's unnecessary noise, so I'd prefer to do it in a follow-up PR: fe97ffa |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -113,8 +113,6 @@ bool s2n_hash_is_available(s2n_hash_algorithm alg) | |||||||||||||
switch (alg) { | ||||||||||||||
case S2N_HASH_MD5: | ||||||||||||||
case S2N_HASH_MD5_SHA1: | ||||||||||||||
/* return false if in FIPS mode, as MD5 algs are not available in FIPS mode. */ | ||||||||||||||
return !s2n_is_in_fips_mode(); | ||||||||||||||
Comment on lines
-116
to
-117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was not really true even before this change. You could use md5 with fips in awslc, just not in openssl-1.0.2. So whenever we checked s2n_hash_is_available and got "false" because of fips, we'd then check s2n_digest_is_md5_allowed_for_fips and get "true", overriding the original "false". I'm just skipping straight to the final "true". You can confirm the limited non-test usage of this method: https://github.com/search?q=repo%3Aaws%2Fs2n-tls+s2n_hash_is_available+-path%3A*tests%2Funit%2F*.c&type=code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are here, can we also update this comment to reflect the current behavior? s2n-tls/tls/s2n_handshake_transcript.c Lines 50 to 55 in 431f014
|
||||||||||||||
case S2N_HASH_NONE: | ||||||||||||||
case S2N_HASH_SHA1: | ||||||||||||||
case S2N_HASH_SHA224: | ||||||||||||||
|
@@ -301,20 +299,6 @@ static int s2n_evp_hash_new(struct s2n_hash_state *state) | |||||||||||||
return S2N_SUCCESS; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
static int s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state *state) | ||||||||||||||
{ | ||||||||||||||
/* This is only to be used for s2n_hash_states that will require MD5 to be used | ||||||||||||||
* to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used | ||||||||||||||
* outside of the TLS 1.0 and 1.1 PRF when in FIPS mode. When needed, this must | ||||||||||||||
* be called prior to s2n_hash_init(). | ||||||||||||||
*/ | ||||||||||||||
POSIX_GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp)); | ||||||||||||||
if (s2n_use_custom_md5_sha1()) { | ||||||||||||||
POSIX_GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp_md5_secondary)); | ||||||||||||||
} | ||||||||||||||
return S2N_SUCCESS; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg) | ||||||||||||||
{ | ||||||||||||||
POSIX_ENSURE_REF(state->digest.high_level.evp.ctx); | ||||||||||||||
|
@@ -419,32 +403,16 @@ static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *f | |||||||||||||
POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp_md5_secondary.ctx, from->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_COPY_FAILED); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
bool is_md5_allowed_for_fips = false; | ||||||||||||||
POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips)); | ||||||||||||||
if (is_md5_allowed_for_fips && (from->alg == S2N_HASH_MD5 || from->alg == S2N_HASH_MD5_SHA1)) { | ||||||||||||||
POSIX_GUARD(s2n_hash_allow_md5_for_fips(to)); | ||||||||||||||
} | ||||||||||||||
return S2N_SUCCESS; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
static int s2n_evp_hash_reset(struct s2n_hash_state *state) | ||||||||||||||
{ | ||||||||||||||
int reset_md5_for_fips = 0; | ||||||||||||||
bool is_md5_allowed_for_fips = false; | ||||||||||||||
POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips)); | ||||||||||||||
if ((state->alg == S2N_HASH_MD5 || state->alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips) { | ||||||||||||||
reset_md5_for_fips = 1; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
POSIX_GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp.ctx), S2N_ERR_HASH_WIPE_FAILED); | ||||||||||||||
if (state->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { | ||||||||||||||
POSIX_GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_WIPE_FAILED); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
if (reset_md5_for_fips) { | ||||||||||||||
POSIX_GUARD(s2n_hash_allow_md5_for_fips(state)); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/* hash_init resets the ready_for_input and currently_in_hash fields. */ | ||||||||||||||
return s2n_evp_hash_init(state, state->alg); | ||||||||||||||
} | ||||||||||||||
|
@@ -465,7 +433,6 @@ static int s2n_evp_hash_free(struct s2n_hash_state *state) | |||||||||||||
|
||||||||||||||
static const struct s2n_hash s2n_low_level_hash = { | ||||||||||||||
.alloc = &s2n_low_level_hash_new, | ||||||||||||||
.allow_md5_for_fips = NULL, | ||||||||||||||
.init = &s2n_low_level_hash_init, | ||||||||||||||
.update = &s2n_low_level_hash_update, | ||||||||||||||
.digest = &s2n_low_level_hash_digest, | ||||||||||||||
|
@@ -476,7 +443,6 @@ static const struct s2n_hash s2n_low_level_hash = { | |||||||||||||
|
||||||||||||||
static const struct s2n_hash s2n_evp_hash = { | ||||||||||||||
.alloc = &s2n_evp_hash_new, | ||||||||||||||
.allow_md5_for_fips = &s2n_evp_hash_allow_md5_for_fips, | ||||||||||||||
.init = &s2n_evp_hash_init, | ||||||||||||||
.update = &s2n_evp_hash_update, | ||||||||||||||
.digest = &s2n_evp_hash_digest, | ||||||||||||||
|
@@ -514,19 +480,6 @@ S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state) | |||||||||||||
return S2N_RESULT_OK; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state) | ||||||||||||||
{ | ||||||||||||||
POSIX_ENSURE_REF(state); | ||||||||||||||
/* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe. | ||||||||||||||
* When in FIPS mode, the EVP API's must be used for hashes. | ||||||||||||||
*/ | ||||||||||||||
POSIX_GUARD(s2n_hash_set_impl(state)); | ||||||||||||||
goatgoose marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
|
||||||||||||||
POSIX_ENSURE_REF(state->hash_impl->allow_md5_for_fips); | ||||||||||||||
|
||||||||||||||
return state->hash_impl->allow_md5_for_fips(state); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg) | ||||||||||||||
{ | ||||||||||||||
POSIX_ENSURE_REF(state); | ||||||||||||||
|
@@ -535,15 +488,8 @@ int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg) | |||||||||||||
*/ | ||||||||||||||
POSIX_GUARD(s2n_hash_set_impl(state)); | ||||||||||||||
|
||||||||||||||
bool is_md5_allowed_for_fips = false; | ||||||||||||||
POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips)); | ||||||||||||||
|
||||||||||||||
if (s2n_hash_is_available(alg) || ((alg == S2N_HASH_MD5 || alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips)) { | ||||||||||||||
/* s2n will continue to initialize an "unavailable" hash when s2n is in FIPS mode and | ||||||||||||||
* FIPS is forcing the hash to be made available. | ||||||||||||||
*/ | ||||||||||||||
if (s2n_hash_is_available(alg)) { | ||||||||||||||
POSIX_ENSURE_REF(state->hash_impl->init); | ||||||||||||||
|
||||||||||||||
return state->hash_impl->init(state, alg); | ||||||||||||||
} else { | ||||||||||||||
POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); | ||||||||||||||
|
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This translates to "if openssl+fips, call an API to allow md5". With the removal of openssl-1.0.2-fips, we no longer support openssl+fips, and this is a no-op. I've removed it everywhere it appears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Openssl-3-fips support the use of md5? Just want to make sure we won't need to add any of these logic back when we add support for openssl-3-fips
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
openssl-3.0-fips doesn't support the use of md5, or a couple other options. But openssl-3.0 also doesn't support enabling MD5 this way. There's no overlap between how openssl-3.0 does fips and how openssl-1.0.2 did fips. We can't reuse the openssl-1.0.2-fips logic, so it's cleaner to just tear it out where we find it. And this particular logic is way more complicated / deceptive than it needs to be anyway.