From 7a4d1e7f774da92ff0dd99379ebfc1dc1e552dd0 Mon Sep 17 00:00:00 2001 From: Lindsay Stewart Date: Mon, 17 Feb 2025 15:01:28 -0800 Subject: [PATCH] Revert "refactor: remove unused evp support for md5+sha1 (#5106)" (#5118) --- crypto/s2n_evp_signing.c | 51 ++----------- crypto/s2n_hash.c | 75 ++++++++++++++++--- crypto/s2n_hash.h | 2 + tests/cbmc/include/cbmc_proof/cbmc_utils.h | 5 ++ .../Makefile | 2 +- tests/cbmc/proofs/s2n_hash_copy/Makefile | 2 +- tests/cbmc/proofs/s2n_hash_digest/Makefile | 2 +- tests/cbmc/proofs/s2n_hash_free/Makefile | 2 +- .../s2n_hash_free/s2n_hash_free_harness.c | 10 ++- .../Makefile | 2 +- tests/cbmc/proofs/s2n_hash_init/Makefile | 2 +- tests/cbmc/proofs/s2n_hash_new/Makefile | 2 +- tests/cbmc/proofs/s2n_hash_reset/Makefile | 2 +- tests/cbmc/proofs/s2n_hash_update/Makefile | 2 +- tests/cbmc/proofs/s2n_hmac_copy/Makefile | 2 +- tests/cbmc/proofs/s2n_hmac_digest/Makefile | 2 +- .../Makefile | 2 +- tests/cbmc/proofs/s2n_hmac_free/Makefile | 2 +- .../s2n_hmac_free/s2n_hmac_free_harness.c | 16 +++- tests/cbmc/proofs/s2n_hmac_init/Makefile | 1 - tests/cbmc/proofs/s2n_hmac_new/Makefile | 2 +- tests/cbmc/proofs/s2n_hmac_reset/Makefile | 2 +- tests/cbmc/proofs/s2n_hmac_update/Makefile | 2 +- tests/cbmc/sources/cbmc_utils.c | 13 +++- .../cbmc/sources/make_common_datastructures.c | 5 ++ tests/cbmc/stubs/s2n_evp_signing_supported.c | 28 ------- 26 files changed, 129 insertions(+), 109 deletions(-) delete mode 100644 tests/cbmc/stubs/s2n_evp_signing_supported.c diff --git a/crypto/s2n_evp_signing.c b/crypto/s2n_evp_signing.c index d8ec6e31539..bd0b9c5972d 100644 --- a/crypto/s2n_evp_signing.c +++ b/crypto/s2n_evp_signing.c @@ -16,7 +16,6 @@ #include "crypto/s2n_evp_signing.h" #include "crypto/s2n_evp.h" -#include "crypto/s2n_fips.h" #include "crypto/s2n_pkey.h" #include "crypto/s2n_rsa_pss.h" #include "error/s2n_errno.h" @@ -51,58 +50,18 @@ static S2N_RESULT s2n_evp_pkey_set_rsa_pss_saltlen(EVP_PKEY_CTX *pctx) #endif } -static bool s2n_evp_md5_sha1_is_supported() -{ -#if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH) - return true; -#else - return false; -#endif -} - -static bool s2n_evp_md_ctx_set_pkey_ctx_is_supported() +bool s2n_evp_signing_supported() { #ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX - return true; + /* We can only use EVP signing if the hash state has an EVP_MD_CTX + * that we can pass to the EVP signing methods. + */ + return s2n_hash_evp_fully_supported(); #else return false; #endif } -bool s2n_evp_signing_supported() -{ - /* We must use the FIPS-approved EVP APIs in FIPS mode, - * but we could also use the EVP APIs outside of FIPS mode. - * Only using the EVP APIs in FIPS mode was a choice made to reduce - * the impact of adding support for the EVP APIs. - * We should consider instead making the EVP APIs the default. - */ - if (!s2n_is_in_fips_mode()) { - return false; - } - - /* Our EVP signing logic is intended to support FIPS 140-3. - * FIPS 140-3 does not allow externally calculated digests (except for - * signing, but not verifying, with ECDSA). - * See https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Digital-Signatures, - * and note that "component" tests only exist for ECDSA sign. - * - * We currently work around that restriction by calling EVP_MD_CTX_set_pkey_ctx, - * which lets us set a key on an existing hash state. This is important - * when we need to handle signing the TLS1.2 client cert verify message, - * which requires signing the entire message transcript. If EVP_MD_CTX_set_pkey_ctx - * is unavailable (true for openssl-1.0.2), our current EVP logic will not work. - * - * FIPS 140-3 is also not possible if EVP_md5_sha1() isn't available - * (again true for openssl-1.0.2). In that case, we use two separate hash - * states to track the md5 and sha1 parts of the hash separately. That means - * that we also have to calculate the digests separately, then combine the - * result. We therefore only have an externally calculated digest available - * for signing or verifying. - */ - return s2n_evp_md_ctx_set_pkey_ctx_is_supported() && s2n_evp_md5_sha1_is_supported(); -} - /* If using EVP signing, override the sign and verify pkey methods. * The EVP methods can handle all pkey types / signature algorithms. */ diff --git a/crypto/s2n_hash.c b/crypto/s2n_hash.c index bc78b436a96..8bd57ba563b 100644 --- a/crypto/s2n_hash.c +++ b/crypto/s2n_hash.c @@ -15,22 +15,29 @@ #include "crypto/s2n_hash.h" -#include "crypto/s2n_evp_signing.h" +#include "crypto/s2n_fips.h" #include "crypto/s2n_hmac.h" #include "crypto/s2n_openssl.h" #include "error/s2n_errno.h" #include "utils/s2n_safety.h" +static bool s2n_use_custom_md5_sha1() +{ +#if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH) + return false; +#else + return true; +#endif +} + static bool s2n_use_evp_impl() { - /* Our current EVP signing implementation requires EVP hashing. - * - * We could use the EVP hashing impl with legacy signing, but that would - * unnecessarily complicate the logic. The only known libcrypto that - * doesn't support EVP signing is openssl-1.0.2. Just let legacy - * libcryptos use legacy methods. - */ - return s2n_evp_signing_supported(); + return s2n_is_in_fips_mode(); +} + +bool s2n_hash_evp_fully_supported() +{ + return s2n_use_evp_impl() && !s2n_use_custom_md5_sha1(); } const EVP_MD *s2n_hash_alg_to_evp_md(s2n_hash_algorithm alg) @@ -282,8 +289,13 @@ static int s2n_low_level_hash_free(struct s2n_hash_state *state) static int s2n_evp_hash_new(struct s2n_hash_state *state) { POSIX_ENSURE_REF(state->digest.high_level.evp.ctx = S2N_EVP_MD_CTX_NEW()); + if (s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx = S2N_EVP_MD_CTX_NEW()); + } + state->is_ready_for_input = 0; state->currently_in_hash = 0; + return S2N_SUCCESS; } @@ -299,6 +311,13 @@ static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm al return S2N_SUCCESS; } + if (alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx); + POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED); + POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp_md5_secondary.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED); + return S2N_SUCCESS; + } + POSIX_ENSURE_REF(s2n_hash_alg_to_evp_md(alg)); POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, s2n_hash_alg_to_evp_md(alg), NULL), S2N_ERR_HASH_INIT_FAILED); return S2N_SUCCESS; @@ -316,6 +335,12 @@ static int s2n_evp_hash_update(struct s2n_hash_state *state, const void *data, u POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx)); POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED); + + if (state->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx)); + POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp_md5_secondary.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED); + } + return S2N_SUCCESS; } @@ -337,6 +362,23 @@ static int s2n_evp_hash_digest(struct s2n_hash_state *state, void *out, uint32_t POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx)); + if (state->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx)); + + uint8_t sha1_digest_size = 0; + POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size)); + + unsigned int sha1_primary_digest_size = sha1_digest_size; + unsigned int md5_secondary_digest_size = digest_size - sha1_primary_digest_size; + + POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= sha1_digest_size, S2N_ERR_HASH_DIGEST_FAILED); + POSIX_ENSURE((size_t) EVP_MD_CTX_size(state->digest.high_level.evp_md5_secondary.ctx) <= md5_secondary_digest_size, S2N_ERR_HASH_DIGEST_FAILED); + + POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, ((uint8_t *) out) + MD5_DIGEST_LENGTH, &sha1_primary_digest_size), S2N_ERR_HASH_DIGEST_FAILED); + POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp_md5_secondary.ctx, out, &md5_secondary_digest_size), S2N_ERR_HASH_DIGEST_FAILED); + return S2N_SUCCESS; + } + POSIX_ENSURE((size_t) EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= digest_size, S2N_ERR_HASH_DIGEST_FAILED); POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, out, &digest_size), S2N_ERR_HASH_DIGEST_FAILED); return S2N_SUCCESS; @@ -355,12 +397,21 @@ static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *f POSIX_ENSURE_REF(to->digest.high_level.evp.ctx); POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED); + + if (from->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(to->digest.high_level.evp_md5_secondary.ctx); + 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); + } + return S2N_SUCCESS; } static int s2n_evp_hash_reset(struct s2n_hash_state *state) { 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); + } /* hash_init resets the ready_for_input and currently_in_hash fields. */ return s2n_evp_hash_init(state, state->alg); @@ -370,6 +421,12 @@ static int s2n_evp_hash_free(struct s2n_hash_state *state) { S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp.ctx); state->digest.high_level.evp.ctx = NULL; + + if (s2n_use_custom_md5_sha1()) { + S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx); + state->digest.high_level.evp_md5_secondary.ctx = NULL; + } + state->is_ready_for_input = 0; return S2N_SUCCESS; } diff --git a/crypto/s2n_hash.h b/crypto/s2n_hash.h index 8c0e7385af0..03643a03e9c 100644 --- a/crypto/s2n_hash.h +++ b/crypto/s2n_hash.h @@ -54,6 +54,8 @@ union s2n_hash_low_level_digest { /* The evp_digest stores all OpenSSL structs to be used with OpenSSL's EVP hash API's. */ struct s2n_hash_evp_digest { struct s2n_evp_digest evp; + /* Always store a secondary evp_digest to allow resetting a hash_state to MD5_SHA1 from another alg. */ + struct s2n_evp_digest evp_md5_secondary; }; /* s2n_hash_state stores the s2n_hash implementation being used (low-level or EVP), diff --git a/tests/cbmc/include/cbmc_proof/cbmc_utils.h b/tests/cbmc/include/cbmc_proof/cbmc_utils.h index 4c58d4d5451..19c2b60b0e7 100644 --- a/tests/cbmc/include/cbmc_proof/cbmc_utils.h +++ b/tests/cbmc/include/cbmc_proof/cbmc_utils.h @@ -47,8 +47,13 @@ struct rc_keys_from_evp_pkey_ctx { int pkey_eckey_refs; }; +/** + * In the `rc_keys_from_hash_state`, we store two `rc_keys_from_evp_pkey_ctx` objects: + * one for the `evp` field and another for `evp_md5_secondary` field. + */ struct rc_keys_from_hash_state { struct rc_keys_from_evp_pkey_ctx evp; + struct rc_keys_from_evp_pkey_ctx evp_md5; }; /** diff --git a/tests/cbmc/proofs/s2n_hash_const_time_get_currently_in_hash_block/Makefile b/tests/cbmc/proofs/s2n_hash_const_time_get_currently_in_hash_block/Makefile index 2f7df8c00fa..3e88a91d608 100644 --- a/tests/cbmc/proofs/s2n_hash_const_time_get_currently_in_hash_block/Makefile +++ b/tests/cbmc/proofs/s2n_hash_const_time_get_currently_in_hash_block/Makefile @@ -22,7 +22,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hash_copy/Makefile b/tests/cbmc/proofs/s2n_hash_copy/Makefile index 82cb3b54e39..02e2c6c99be 100644 --- a/tests/cbmc/proofs/s2n_hash_copy/Makefile +++ b/tests/cbmc/proofs/s2n_hash_copy/Makefile @@ -25,7 +25,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/ec_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_ensure.c diff --git a/tests/cbmc/proofs/s2n_hash_digest/Makefile b/tests/cbmc/proofs/s2n_hash_digest/Makefile index 53a8f450683..f4e8cd51fe0 100644 --- a/tests/cbmc/proofs/s2n_hash_digest/Makefile +++ b/tests/cbmc/proofs/s2n_hash_digest/Makefile @@ -27,7 +27,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c diff --git a/tests/cbmc/proofs/s2n_hash_free/Makefile b/tests/cbmc/proofs/s2n_hash_free/Makefile index a873b020619..676317f1dc2 100644 --- a/tests/cbmc/proofs/s2n_hash_free/Makefile +++ b/tests/cbmc/proofs/s2n_hash_free/Makefile @@ -24,7 +24,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/ec_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/cbmc_utils.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hash_free/s2n_hash_free_harness.c b/tests/cbmc/proofs/s2n_hash_free/s2n_hash_free_harness.c index f8fc362ad92..9c646a0b64f 100644 --- a/tests/cbmc/proofs/s2n_hash_free/s2n_hash_free_harness.c +++ b/tests/cbmc/proofs/s2n_hash_free/s2n_hash_free_harness.c @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -#include "crypto/s2n_evp_signing.h" +#include "crypto/s2n_fips.h" #include "crypto/s2n_hash.h" #include @@ -35,8 +35,9 @@ void s2n_hash_free_harness() assert(s2n_hash_free(state) == S2N_SUCCESS); if (state != NULL) { assert(state->hash_impl->free != NULL); - if (s2n_evp_signing_supported()) { + if (s2n_is_in_fips_mode()) { assert(state->digest.high_level.evp.ctx == NULL); + assert(state->digest.high_level.evp_md5_secondary.ctx == NULL); assert_rc_decrement_on_hash_state(&saved_hash_state); } else { assert_rc_unchanged_on_hash_state(&saved_hash_state); @@ -46,10 +47,11 @@ void s2n_hash_free_harness() /* Cleanup after expected error cases, for memory leak check. */ if (state != NULL) { - /* 1. `free` leftover EVP_MD_CTX objects if `s2n_evp_signing_supported`, + /* 1. `free` leftover EVP_MD_CTX objects if `s2n_is_in_fips_mode`, since `s2n_hash_free` is a NO-OP in that case. */ - if (!s2n_evp_signing_supported()) { + if (!s2n_is_in_fips_mode()) { S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp.ctx); + S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx); } /* 2. `free` leftover reference-counted keys (i.e. those with non-zero ref-count), diff --git a/tests/cbmc/proofs/s2n_hash_get_currently_in_hash_total/Makefile b/tests/cbmc/proofs/s2n_hash_get_currently_in_hash_total/Makefile index 7be94f92f02..dd6491d63a4 100644 --- a/tests/cbmc/proofs/s2n_hash_get_currently_in_hash_total/Makefile +++ b/tests/cbmc/proofs/s2n_hash_get_currently_in_hash_total/Makefile @@ -22,7 +22,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hash_init/Makefile b/tests/cbmc/proofs/s2n_hash_init/Makefile index f7ae8963b2b..5d905e7c2ef 100644 --- a/tests/cbmc/proofs/s2n_hash_init/Makefile +++ b/tests/cbmc/proofs/s2n_hash_init/Makefile @@ -24,7 +24,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hash_new/Makefile b/tests/cbmc/proofs/s2n_hash_new/Makefile index c156cd61aaa..da1f324b484 100644 --- a/tests/cbmc/proofs/s2n_hash_new/Makefile +++ b/tests/cbmc/proofs/s2n_hash_new/Makefile @@ -22,7 +22,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hash_reset/Makefile b/tests/cbmc/proofs/s2n_hash_reset/Makefile index b0f408b03eb..55e08b1269c 100644 --- a/tests/cbmc/proofs/s2n_hash_reset/Makefile +++ b/tests/cbmc/proofs/s2n_hash_reset/Makefile @@ -27,7 +27,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c diff --git a/tests/cbmc/proofs/s2n_hash_update/Makefile b/tests/cbmc/proofs/s2n_hash_update/Makefile index 13e35003793..f9239e1946e 100644 --- a/tests/cbmc/proofs/s2n_hash_update/Makefile +++ b/tests/cbmc/proofs/s2n_hash_update/Makefile @@ -27,7 +27,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c PROJECT_SOURCES += $(SRCDIR)/utils/s2n_safety.c diff --git a/tests/cbmc/proofs/s2n_hmac_copy/Makefile b/tests/cbmc/proofs/s2n_hmac_copy/Makefile index e3e1c211460..87231753868 100644 --- a/tests/cbmc/proofs/s2n_hmac_copy/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_copy/Makefile @@ -24,7 +24,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/ec_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hmac_digest/Makefile b/tests/cbmc/proofs/s2n_hmac_digest/Makefile index 7012a41ea8c..90781cff1ba 100644 --- a/tests/cbmc/proofs/s2n_hmac_digest/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_digest/Makefile @@ -19,7 +19,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_copy.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_digest.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_update.c diff --git a/tests/cbmc/proofs/s2n_hmac_digest_two_compression_rounds/Makefile b/tests/cbmc/proofs/s2n_hmac_digest_two_compression_rounds/Makefile index 014cc1d9955..7fdb8a76da8 100644 --- a/tests/cbmc/proofs/s2n_hmac_digest_two_compression_rounds/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_digest_two_compression_rounds/Makefile @@ -19,7 +19,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_copy.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_digest.c PROOF_SOURCES += $(PROOF_STUB)/s2n_hash_reset.c diff --git a/tests/cbmc/proofs/s2n_hmac_free/Makefile b/tests/cbmc/proofs/s2n_hmac_free/Makefile index 8791513153f..fd14d427e94 100644 --- a/tests/cbmc/proofs/s2n_hmac_free/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_free/Makefile @@ -24,7 +24,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/ec_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_SOURCE)/cbmc_utils.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hmac_free/s2n_hmac_free_harness.c b/tests/cbmc/proofs/s2n_hmac_free/s2n_hmac_free_harness.c index fbc0f9f3625..aeff29282ad 100644 --- a/tests/cbmc/proofs/s2n_hmac_free/s2n_hmac_free_harness.c +++ b/tests/cbmc/proofs/s2n_hmac_free/s2n_hmac_free_harness.c @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -#include "crypto/s2n_evp_signing.h" +#include "crypto/s2n_fips.h" #include "crypto/s2n_hash.h" #include @@ -44,17 +44,21 @@ void s2n_hmac_free_harness() assert(state->outer.hash_impl->free != NULL); assert(state->outer_just_key.hash_impl->free != NULL); - if (s2n_evp_signing_supported()) { + if (s2n_is_in_fips_mode()) { assert(state->inner.digest.high_level.evp.ctx == NULL); + assert(state->inner.digest.high_level.evp_md5_secondary.ctx == NULL); assert_rc_decrement_on_hash_state(&saved_inner_hash_state); assert(state->inner_just_key.digest.high_level.evp.ctx == NULL); + assert(state->inner_just_key.digest.high_level.evp_md5_secondary.ctx == NULL); assert_rc_decrement_on_hash_state(&saved_inner_just_key_hash_state); assert(state->outer.digest.high_level.evp.ctx == NULL); + assert(state->outer.digest.high_level.evp_md5_secondary.ctx == NULL); assert_rc_decrement_on_hash_state(&saved_outer_hash_state); assert(state->outer_just_key.digest.high_level.evp.ctx == NULL); + assert(state->outer_just_key.digest.high_level.evp_md5_secondary.ctx == NULL); assert_rc_decrement_on_hash_state(&saved_outer_just_key_hash_state); } else { assert_rc_unchanged_on_hash_state(&saved_inner_hash_state); @@ -71,13 +75,17 @@ void s2n_hmac_free_harness() /* Cleanup after expected error cases, for memory leak check. */ if (state != NULL) { - /* 1. `free` leftover EVP_MD_CTX objects if `s2n_evp_signing_supported`, + /* 1. `free` leftover EVP_MD_CTX objects if `s2n_is_in_fips_mode`, since `s2n_hash_free` is a NO-OP in that case. */ - if (!s2n_evp_signing_supported()) { + if (!s2n_is_in_fips_mode()) { S2N_EVP_MD_CTX_FREE(state->inner.digest.high_level.evp.ctx); + S2N_EVP_MD_CTX_FREE(state->inner.digest.high_level.evp_md5_secondary.ctx); S2N_EVP_MD_CTX_FREE(state->inner_just_key.digest.high_level.evp.ctx); + S2N_EVP_MD_CTX_FREE(state->inner_just_key.digest.high_level.evp_md5_secondary.ctx); S2N_EVP_MD_CTX_FREE(state->outer.digest.high_level.evp.ctx); + S2N_EVP_MD_CTX_FREE(state->outer.digest.high_level.evp_md5_secondary.ctx); S2N_EVP_MD_CTX_FREE(state->outer_just_key.digest.high_level.evp.ctx); + S2N_EVP_MD_CTX_FREE(state->outer_just_key.digest.high_level.evp_md5_secondary.ctx); } /* 2. `free` leftover reference-counted keys (i.e. those with non-zero ref-count), diff --git a/tests/cbmc/proofs/s2n_hmac_init/Makefile b/tests/cbmc/proofs/s2n_hmac_init/Makefile index 964e84d9e6e..4931abbccda 100644 --- a/tests/cbmc/proofs/s2n_hmac_init/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_init/Makefile @@ -24,7 +24,6 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOF_STUB)/s2n_libcrypto_is_awslc.c PROOF_SOURCES += $(PROOF_STUB)/darwin_check_fd_set_overflow.c diff --git a/tests/cbmc/proofs/s2n_hmac_new/Makefile b/tests/cbmc/proofs/s2n_hmac_new/Makefile index b503264b6d6..b553599d793 100644 --- a/tests/cbmc/proofs/s2n_hmac_new/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_new/Makefile @@ -21,7 +21,7 @@ HARNESS_FILE = $(HARNESS_ENTRY).c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hmac_reset/Makefile b/tests/cbmc/proofs/s2n_hmac_reset/Makefile index 066dcc3489c..c74c27914fd 100644 --- a/tests/cbmc/proofs/s2n_hmac_reset/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_reset/Makefile @@ -24,7 +24,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/ec_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/evp_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hash.c diff --git a/tests/cbmc/proofs/s2n_hmac_update/Makefile b/tests/cbmc/proofs/s2n_hmac_update/Makefile index eb16a293d47..0098edb5975 100644 --- a/tests/cbmc/proofs/s2n_hmac_update/Makefile +++ b/tests/cbmc/proofs/s2n_hmac_update/Makefile @@ -26,7 +26,7 @@ PROOF_SOURCES += $(OPENSSL_SOURCE)/md5_override.c PROOF_SOURCES += $(OPENSSL_SOURCE)/sha_override.c PROOF_SOURCES += $(PROOF_SOURCE)/make_common_datastructures.c PROOF_SOURCES += $(PROOF_STUB)/s2n_calculate_stacktrace.c -PROOF_SOURCES += $(PROOF_STUB)/s2n_evp_signing_supported.c +PROOF_SOURCES += $(PROOF_STUB)/s2n_is_in_fips_mode.c PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) PROJECT_SOURCES += $(SRCDIR)/crypto/s2n_hmac.c diff --git a/tests/cbmc/sources/cbmc_utils.c b/tests/cbmc/sources/cbmc_utils.c index f8eb8943627..733c87fb9e1 100644 --- a/tests/cbmc/sources/cbmc_utils.c +++ b/tests/cbmc/sources/cbmc_utils.c @@ -220,11 +220,13 @@ void assert_rc_unchanged_on_evp_pkey_ctx(struct rc_keys_from_evp_pkey_ctx *stora void assert_rc_decrement_on_hash_state(struct rc_keys_from_hash_state *storage) { assert_rc_decrement_on_evp_pkey_ctx(&storage->evp); + assert_rc_decrement_on_evp_pkey_ctx(&storage->evp_md5); } void assert_rc_unchanged_on_hash_state(struct rc_keys_from_hash_state *storage) { assert_rc_unchanged_on_evp_pkey_ctx(&storage->evp); + assert_rc_unchanged_on_evp_pkey_ctx(&storage->evp_md5); } void save_abstract_evp_ctx(const EVP_PKEY_CTX *pctx, struct rc_keys_from_evp_pkey_ctx *storage) @@ -243,7 +245,9 @@ void save_rc_keys_from_hash_state(const struct s2n_hash_state *state, struct rc_ { storage->evp.pkey = NULL; storage->evp.pkey_eckey = NULL; - storage->evp.pkey_refs = storage->evp.pkey_eckey_refs = 0; + storage->evp_md5.pkey = NULL; + storage->evp_md5.pkey_eckey = NULL; + storage->evp.pkey_refs = storage->evp.pkey_eckey_refs = storage->evp_md5.pkey_refs = storage->evp_md5.pkey_eckey_refs = 0; if (state) { if (state->digest.high_level.evp.ctx) { @@ -251,6 +255,12 @@ void save_rc_keys_from_hash_state(const struct s2n_hash_state *state, struct rc_ save_abstract_evp_ctx(state->digest.high_level.evp.ctx->pctx, &storage->evp); } } + + if (state->digest.high_level.evp_md5_secondary.ctx) { + if (state->digest.high_level.evp_md5_secondary.ctx->pctx) { + save_abstract_evp_ctx(state->digest.high_level.evp_md5_secondary.ctx->pctx, &storage->evp_md5); + } + } } } @@ -269,4 +279,5 @@ void free_rc_keys_from_evp_pkey_ctx(struct rc_keys_from_evp_pkey_ctx *pctx) void free_rc_keys_from_hash_state(struct rc_keys_from_hash_state *storage) { free_rc_keys_from_evp_pkey_ctx(&storage->evp); + free_rc_keys_from_evp_pkey_ctx(&storage->evp_md5); } diff --git a/tests/cbmc/sources/make_common_datastructures.c b/tests/cbmc/sources/make_common_datastructures.c index b159986ad8f..59c7590f10d 100644 --- a/tests/cbmc/sources/make_common_datastructures.c +++ b/tests/cbmc/sources/make_common_datastructures.c @@ -270,6 +270,7 @@ void cbmc_populate_s2n_hash_state(struct s2n_hash_state* state) * If required, this initialization should be done in the validation function. */ cbmc_populate_s2n_evp_digest(&state->digest.high_level.evp); + cbmc_populate_s2n_evp_digest(&state->digest.high_level.evp_md5_secondary); } struct s2n_hash_state* cbmc_allocate_s2n_hash_state() @@ -299,9 +300,13 @@ void cbmc_populate_s2n_hmac_evp_backup(struct s2n_hmac_evp_backup *backup) { CBMC_ENSURE_REF(backup); cbmc_populate_s2n_evp_digest(&backup->inner.evp); + cbmc_populate_s2n_evp_digest(&backup->inner.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->inner_just_key.evp); + cbmc_populate_s2n_evp_digest(&backup->inner_just_key.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->outer.evp); + cbmc_populate_s2n_evp_digest(&backup->outer.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->outer_just_key.evp); + cbmc_populate_s2n_evp_digest(&backup->outer_just_key.evp_md5_secondary); } struct s2n_hmac_evp_backup* cbmc_allocate_s2n_hmac_evp_backup() diff --git a/tests/cbmc/stubs/s2n_evp_signing_supported.c b/tests/cbmc/stubs/s2n_evp_signing_supported.c deleted file mode 100644 index 32d709a1167..00000000000 --- a/tests/cbmc/stubs/s2n_evp_signing_supported.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use - * this file except in compliance with the License. A copy of the License is - * located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -static bool is_set = false; -static bool is_evp_signing_supported = false; - -bool s2n_evp_signing_supported() -{ - if (!is_set) { - is_evp_signing_supported = nondet_bool(); - is_set = true; - } - return is_evp_signing_supported; -}