diff --git a/SOURCES/0044-FIPS-140-3-keychecks.patch b/SOURCES/0044-FIPS-140-3-keychecks.patch index a0ec627..38efa07 100644 --- a/SOURCES/0044-FIPS-140-3-keychecks.patch +++ b/SOURCES/0044-FIPS-140-3-keychecks.patch @@ -35,7 +35,7 @@ diff -up openssl-3.0.1/crypto/dh/dh_key.c.fips3 openssl-3.0.1/crypto/dh/dh_key.c if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) { ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); -@@ -354,8 +367,23 @@ static int generate_key(DH *dh) +@@ -354,8 +367,21 @@ static int generate_key(DH *dh) if (!ossl_dh_generate_public_key(ctx, dh, priv_key, pub_key)) goto err; @@ -50,9 +50,7 @@ diff -up openssl-3.0.1/crypto/dh/dh_key.c.fips3 openssl-3.0.1/crypto/dh/dh_key.c dh->priv_key = priv_key; +#ifdef FIPS_MODULE + if (ossl_dh_check_pairwise(dh) <= 0) { -+ dh->pub_key = dh->priv_key = NULL; -+ ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID); -+ goto err; ++ abort(); + } +#endif + @@ -89,99 +87,276 @@ diff -up openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c.fips3 open retlen = ECDH_compute_key(secret, size, ppubkey, privk, NULL); -diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips3 openssl-3.0.1/crypto/ec/ec_key.c ---- openssl-3.0.1/crypto/ec/ec_key.c.fips3 2022-07-25 14:03:34.420222507 +0200 -+++ openssl-3.0.1/crypto/ec/ec_key.c 2022-07-25 14:09:00.728164294 +0200 -@@ -336,6 +336,11 @@ static int ec_generate_key(EC_KEY *eckey - - OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg); - ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg); -+ +diff -up openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c.pairwise openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c +--- openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c.pairwise 2023-02-20 11:44:18.451884117 +0100 ++++ openssl-3.0.7/providers/implementations/keymgmt/ec_kmgmt.c 2023-02-20 12:39:46.037063842 +0100 +@@ -982,8 +982,17 @@ struct ec_gen_ctx { + int selection; + int ecdh_mode; + EC_GROUP *gen_group; +#ifdef FIPS_MODULE -+ ok &= ossl_ec_key_public_check(eckey, ctx); -+ ok &= ossl_ec_key_pairwise_check(eckey, ctx); -+#endif /* FIPS_MODULE */ - } - err: - /* Step (9): If there is an error return an invalid keypair. */ -diff -up openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3 openssl-3.0.1/crypto/rsa/rsa_gen.c ---- openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3 2022-07-25 17:02:17.807271297 +0200 -+++ openssl-3.0.1/crypto/rsa/rsa_gen.c 2022-07-25 17:18:24.931959649 +0200 -@@ -23,6 +23,7 @@ - #include - #include "internal/cryptlib.h" - #include -+#include - #include - #include "prov/providercommon.h" - #include "rsa_local.h" -@@ -476,52 +476,43 @@ static int rsa_keygen(OSSL_LIB_CTX *libc - static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg) - { - int ret = 0; -- unsigned int ciphertxt_len; -- unsigned char *ciphertxt = NULL; -- const unsigned char plaintxt[16] = {0}; -- unsigned char *decoded = NULL; -- unsigned int decoded_len; -- unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len); -- int padding = RSA_PKCS1_PADDING; -+ unsigned int signature_len; -+ unsigned char *signature = NULL; - OSSL_SELF_TEST *st = NULL; -+ static const unsigned char dgst[] = { -+ 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, -+ 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, -+ 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 -+ }; ++ void *ecdsa_sig_ctx; ++#endif + }; - st = OSSL_SELF_TEST_new(cb, cbarg); - if (st == NULL) - goto err; - OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, -+ /* No special name for RSA signature PCT*/ - OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1); - -- ciphertxt_len = RSA_size(rsa); -+ signature_len = RSA_size(rsa); -- /* -- * RSA_private_encrypt() and RSA_private_decrypt() requires the 'to' -- * parameter to be a maximum of RSA_size() - allocate space for both. -- */ -- ciphertxt = OPENSSL_zalloc(ciphertxt_len * 2); -- if (ciphertxt == NULL) -+ signature = OPENSSL_zalloc(signature_len); -+ if (signature == NULL) - goto err; -- decoded = ciphertxt + ciphertxt_len; - -- ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa, -- padding); -- if (ciphertxt_len <= 0) -+ if (RSA_sign(NID_sha256, dgst, sizeof(dgst), signature, &signature_len, rsa) <= 0) - goto err; -- if (ciphertxt_len == plaintxt_len -- && memcmp(ciphertxt, plaintxt, plaintxt_len) == 0) ++#ifdef FIPS_MODULE ++void *ecdsa_newctx(void *provctx, const char *propq); ++void ecdsa_freectx(void *vctx); ++int do_ec_pct(void *, const char *, void *); ++#endif + -+ if (signature_len <= 0) - goto err; - -- OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt); -+ OSSL_SELF_TEST_oncorrupt_byte(st, signature); - -- decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa, -- padding); -- if (decoded_len != plaintxt_len -- || memcmp(decoded, plaintxt, decoded_len) != 0) -+ if (RSA_verify(NID_sha256, dgst, sizeof(dgst), signature, signature_len, rsa) <= 0) - goto err; - - ret = 1; - err: - OSSL_SELF_TEST_onend(st, ret); - OSSL_SELF_TEST_free(st); -- OPENSSL_free(ciphertxt); -+ OPENSSL_free(signature); - - return ret; + static void *ec_gen_init(void *provctx, int selection, + const OSSL_PARAM params[]) + { +@@ -1002,6 +1011,10 @@ static void *ec_gen_init(void *provctx, + OPENSSL_free(gctx); + gctx = NULL; + } ++#ifdef FIPS_MODULE ++ if (gctx != NULL) ++ gctx->ecdsa_sig_ctx = ecdsa_newctx(provctx, NULL); ++#endif + return gctx; } + +@@ -1272,6 +1285,12 @@ static void *ec_gen(void *genctx, OSSL_C + + if (gctx->ecdh_mode != -1) + ret = ret && ossl_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode); ++#ifdef FIPS_MODULE ++ /* Pairwise consistency test */ ++ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ++ && do_ec_pct(gctx->ecdsa_sig_ctx, "sha256", ec) != 1) ++ abort(); ++#endif + + if (gctx->group_check != NULL) + ret = ret && ossl_ec_set_check_group_type_from_name(ec, gctx->group_check); +@@ -1341,7 +1359,10 @@ static void ec_gen_cleanup(void *genctx) + + if (gctx == NULL) + return; +- ++#ifdef FIPS_MODULE ++ ecdsa_freectx(gctx->ecdsa_sig_ctx); ++ gctx->ecdsa_sig_ctx = NULL; ++#endif + EC_GROUP_free(gctx->gen_group); + BN_free(gctx->p); + BN_free(gctx->a); +diff -up openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c.pairwise openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c +--- openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c.pairwise 2023-02-20 11:50:23.035194347 +0100 ++++ openssl-3.0.7/providers/implementations/signature/ecdsa_sig.c 2023-02-20 12:19:10.809768979 +0100 +@@ -32,7 +32,7 @@ + #include "crypto/ec.h" + #include "prov/der_ec.h" + +-static OSSL_FUNC_signature_newctx_fn ecdsa_newctx; ++OSSL_FUNC_signature_newctx_fn ecdsa_newctx; + static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init; + static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init; + static OSSL_FUNC_signature_sign_fn ecdsa_sign; +@@ -43,7 +43,7 @@ static OSSL_FUNC_signature_digest_sign_f + static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init; + static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update; + static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final; +-static OSSL_FUNC_signature_freectx_fn ecdsa_freectx; ++OSSL_FUNC_signature_freectx_fn ecdsa_freectx; + static OSSL_FUNC_signature_dupctx_fn ecdsa_dupctx; + static OSSL_FUNC_signature_get_ctx_params_fn ecdsa_get_ctx_params; + static OSSL_FUNC_signature_gettable_ctx_params_fn ecdsa_gettable_ctx_params; +@@ -104,7 +104,7 @@ typedef struct { + #endif + } PROV_ECDSA_CTX; + +-static void *ecdsa_newctx(void *provctx, const char *propq) ++void *ecdsa_newctx(void *provctx, const char *propq) + { + PROV_ECDSA_CTX *ctx; + +@@ -370,7 +370,7 @@ int ecdsa_digest_verify_final(void *vctx + return ecdsa_verify(ctx, sig, siglen, digest, (size_t)dlen); + } + +-static void ecdsa_freectx(void *vctx) ++void ecdsa_freectx(void *vctx) + { + PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; + +@@ -581,6 +581,35 @@ static const OSSL_PARAM *ecdsa_settable_ + return EVP_MD_settable_ctx_params(ctx->md); + } + ++#ifdef FIPS_MODULE ++int do_ec_pct(void *vctx, const char *mdname, void *ec) ++{ ++ static const unsigned char data[32]; ++ unsigned char sigbuf[256]; ++ size_t siglen = sizeof(sigbuf); ++ ++ if (ecdsa_digest_sign_init(vctx, mdname, ec, NULL) <= 0) ++ return 0; ++ ++ if (ecdsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0) ++ return 0; ++ ++ if (ecdsa_digest_sign_final(vctx, sigbuf, &siglen, sizeof(sigbuf)) <= 0) ++ return 0; ++ ++ if (ecdsa_digest_verify_init(vctx, mdname, ec, NULL) <= 0) ++ return 0; ++ ++ if (ecdsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0) ++ return 0; ++ ++ if (ecdsa_digest_verify_final(vctx, sigbuf, siglen) <= 0) ++ return 0; ++ ++ return 1; ++} ++#endif ++ + const OSSL_DISPATCH ossl_ecdsa_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init }, +diff -up openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c.pairwise openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c +--- openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c.pairwise 2023-02-20 16:04:27.103364713 +0100 ++++ openssl-3.0.7/providers/implementations/keymgmt/rsa_kmgmt.c 2023-02-20 16:14:13.848119419 +0100 +@@ -434,6 +434,7 @@ struct rsa_gen_ctx { + #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + /* ACVP test parameters */ + OSSL_PARAM *acvp_test_params; ++ void *prov_rsa_ctx; + #endif + }; + +@@ -447,6 +448,12 @@ static int rsa_gencb(int p, int n, BN_GE + return gctx->cb(params, gctx->cbarg); + } + ++#ifdef FIPS_MODULE ++void *rsa_newctx(void *provctx, const char *propq); ++void rsa_freectx(void *vctx); ++int do_rsa_pct(void *, const char *, void *); ++#endif ++ + static void *gen_init(void *provctx, int selection, int rsa_type, + const OSSL_PARAM params[]) + { +@@ -474,6 +481,10 @@ static void *gen_init(void *provctx, int + + if (!rsa_gen_set_params(gctx, params)) + goto err; ++#ifdef FIPS_MODULE ++ if (gctx != NULL) ++ gctx->prov_rsa_ctx = rsa_newctx(provctx, NULL); ++#endif + return gctx; + + err: +@@ -630,6 +641,11 @@ static void *rsa_gen(void *genctx, OSSL_ + + rsa = rsa_tmp; + rsa_tmp = NULL; ++#ifdef FIPS_MODULE ++ /* Pairwise consistency test */ ++ if (do_rsa_pct(gctx->prov_rsa_ctx, "sha256", rsa) != 1) ++ abort(); ++#endif + err: + BN_GENCB_free(gencb); + RSA_free(rsa_tmp); +@@ -645,6 +662,8 @@ static void rsa_gen_cleanup(void *genctx + #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) + ossl_rsa_acvp_test_gen_params_free(gctx->acvp_test_params); + gctx->acvp_test_params = NULL; ++ rsa_freectx(gctx->prov_rsa_ctx); ++ gctx->prov_rsa_ctx = NULL; + #endif + BN_clear_free(gctx->pub_exp); + OPENSSL_free(gctx); +diff -up openssl-3.0.7/providers/implementations/signature/rsa_sig.c.pairwise openssl-3.0.7/providers/implementations/signature/rsa_sig.c +--- openssl-3.0.7/providers/implementations/signature/rsa_sig.c.pairwise 2023-02-20 16:04:22.548327811 +0100 ++++ openssl-3.0.7/providers/implementations/signature/rsa_sig.c 2023-02-20 16:17:50.064871695 +0100 +@@ -36,7 +36,7 @@ + + #define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1 + +-static OSSL_FUNC_signature_newctx_fn rsa_newctx; ++OSSL_FUNC_signature_newctx_fn rsa_newctx; + static OSSL_FUNC_signature_sign_init_fn rsa_sign_init; + static OSSL_FUNC_signature_verify_init_fn rsa_verify_init; + static OSSL_FUNC_signature_verify_recover_init_fn rsa_verify_recover_init; +@@ -49,7 +49,7 @@ static OSSL_FUNC_signature_digest_sign_f + static OSSL_FUNC_signature_digest_verify_init_fn rsa_digest_verify_init; + static OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_signverify_update; + static OSSL_FUNC_signature_digest_verify_final_fn rsa_digest_verify_final; +-static OSSL_FUNC_signature_freectx_fn rsa_freectx; ++OSSL_FUNC_signature_freectx_fn rsa_freectx; + static OSSL_FUNC_signature_dupctx_fn rsa_dupctx; + static OSSL_FUNC_signature_get_ctx_params_fn rsa_get_ctx_params; + static OSSL_FUNC_signature_gettable_ctx_params_fn rsa_gettable_ctx_params; +@@ -172,7 +172,7 @@ static int rsa_check_parameters(PROV_RSA + return 1; + } + +-static void *rsa_newctx(void *provctx, const char *propq) ++void *rsa_newctx(void *provctx, const char *propq) + { + PROV_RSA_CTX *prsactx = NULL; + char *propq_copy = NULL; +@@ -990,7 +990,7 @@ int rsa_digest_verify_final(void *vprsac + return rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); + } + +-static void rsa_freectx(void *vprsactx) ++void rsa_freectx(void *vprsactx) + { + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + +@@ -1504,6 +1504,45 @@ static const OSSL_PARAM *rsa_settable_ct + return EVP_MD_settable_ctx_params(prsactx->md); + } + ++#ifdef FIPS_MODULE ++int do_rsa_pct(void *vctx, const char *mdname, void *rsa) ++{ ++ static const unsigned char data[32]; ++ unsigned char *sigbuf = NULL; ++ size_t siglen = 0; ++ int ret = 0; ++ ++ if (rsa_digest_sign_init(vctx, mdname, rsa, NULL) <= 0) ++ return 0; ++ ++ if (rsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0) ++ return 0; ++ ++ if (rsa_digest_sign_final(vctx, NULL, &siglen, 0) <= 0) ++ return 0; ++ ++ if ((sigbuf = OPENSSL_malloc(siglen)) == NULL) ++ return 0; ++ ++ if (rsa_digest_sign_final(vctx, sigbuf, &siglen, siglen) <= 0) ++ goto err; ++ ++ if (rsa_digest_verify_init(vctx, mdname, rsa, NULL) <= 0) ++ goto err; ++ ++ if (rsa_digest_signverify_update(vctx, data, sizeof(data)) <= 0) ++ goto err; ++ ++ if (rsa_digest_verify_final(vctx, sigbuf, siglen) <= 0) ++ goto err; ++ ret = 1; ++ ++ err: ++ OPENSSL_free(sigbuf); ++ return ret; ++} ++#endif ++ + const OSSL_DISPATCH ossl_rsa_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_sign_init }, diff --git a/SOURCES/0045-FIPS-services-minimize.patch b/SOURCES/0045-FIPS-services-minimize.patch index abb13e0..d2bea7f 100644 --- a/SOURCES/0045-FIPS-services-minimize.patch +++ b/SOURCES/0045-FIPS-services-minimize.patch @@ -697,6 +697,26 @@ diff -up openssl-3.0.1/ssl/ssl_ciph.c.nokrsa openssl-3.0.1/ssl/ssl_ciph.c diff -up openssl-3.0.1/providers/implementations/signature/rsa_sig.c.fipskeylen openssl-3.0.1/providers/implementations/signature/rsa_sig.c --- openssl-3.0.1/providers/implementations/signature/rsa_sig.c.fipskeylen 2022-05-23 14:58:07.764281242 +0200 +++ openssl-3.0.1/providers/implementations/signature/rsa_sig.c 2022-05-23 15:10:29.327993616 +0200 +@@ -692,6 +692,19 @@ static int rsa_verify_recover(void *vprs + { + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + int ret; ++# ifdef FIPS_MODULE ++ size_t rsabits = RSA_bits(prsactx->rsa); ++ ++ if (rsabits < 2048) { ++ if (rsabits != 1024 ++ && rsabits != 1280 ++ && rsabits != 1536 ++ && rsabits != 1792) { ++ ERR_raise(ERR_LIB_FIPS, PROV_R_INVALID_KEY_LENGTH); ++ return 0; ++ } ++ } ++# endif + + if (!ossl_prov_is_running()) + return 0; @@ -770,6 +770,19 @@ static int rsa_verify(void *vprsactx, co { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; diff --git a/SOURCES/0049-Selectively-disallow-SHA1-signatures.patch b/SOURCES/0049-Selectively-disallow-SHA1-signatures.patch index f18e099..d453f97 100644 --- a/SOURCES/0049-Selectively-disallow-SHA1-signatures.patch +++ b/SOURCES/0049-Selectively-disallow-SHA1-signatures.patch @@ -399,7 +399,7 @@ index 325e855333..bea397f0c1 100644 #define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1 +#define RSA_DEFAULT_DIGEST_NAME_NONLEGACY OSSL_DIGEST_NAME_SHA2_256 - static OSSL_FUNC_signature_newctx_fn rsa_newctx; + OSSL_FUNC_signature_newctx_fn rsa_newctx; static OSSL_FUNC_signature_sign_init_fn rsa_sign_init; @@ -289,10 +291,15 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, diff --git a/SOURCES/0058-FIPS-limit-rsa-encrypt.patch b/SOURCES/0058-FIPS-limit-rsa-encrypt.patch index 6dcf7c0..b9cc3aa 100644 --- a/SOURCES/0058-FIPS-limit-rsa-encrypt.patch +++ b/SOURCES/0058-FIPS-limit-rsa-encrypt.patch @@ -19,7 +19,7 @@ diff -up openssl-3.0.1/providers/implementations/asymciphers/rsa_enc.c.no_bad_pa +# ifdef FIPS_MODULE +static int fips_padding_allowed(const PROV_RSA_CTX *prsactx) +{ -+ if (prsactx->pad_mode == RSA_PKCS1_PADDING ++ if (prsactx->pad_mode == RSA_PKCS1_PADDING || prsactx->pad_mode == RSA_NO_PADDING + || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) + return 0; + diff --git a/SOURCES/0076-FIPS-140-3-DRBG.patch b/SOURCES/0076-FIPS-140-3-DRBG.patch index 8f97a6a..4a276f7 100644 --- a/SOURCES/0076-FIPS-140-3-DRBG.patch +++ b/SOURCES/0076-FIPS-140-3-DRBG.patch @@ -143,3 +143,15 @@ diff -up openssl-3.0.1/providers/implementations/rands/crngt.c.fipsrand openssl- if (bytes_needed < min_len) bytes_needed = min_len; if (bytes_needed > max_len) +diff -up openssl-3.0.7/providers/implementations/rands/drbg_local.h.drbg openssl-3.0.7/providers/implementations/rands/drbg_local.h +--- openssl-3.0.7/providers/implementations/rands/drbg_local.h.drbg 2023-03-13 12:17:47.705538612 +0100 ++++ openssl-3.0.7/providers/implementations/rands/drbg_local.h 2023-03-13 12:18:03.060702092 +0100 +@@ -38,7 +38,7 @@ + * + * The value is in bytes. + */ +-#define CRNGT_BUFSIZ 16 ++#define CRNGT_BUFSIZ 32 + + /* + * Maximum input size for the DRBG (entropy, nonce, personalization string) diff --git a/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch b/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch deleted file mode 100644 index b54d0fa..0000000 --- a/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0c4aaedf29a1ed1559762515bfeaa5923925e18f Mon Sep 17 00:00:00 2001 -From: Clemens Lang -Date: Thu, 11 Aug 2022 09:27:12 +0200 -Subject: [PATCH 1/2] Add FIPS indicator parameter to HKDF - -NIST considers HKDF only acceptable when used as in TLS 1.3, and -otherwise unapproved. Add an explicit indicator attached to the -EVP_KDF_CTX that can be queried using EVP_KDF_CTX_get_params() to -determine whether the KDF operation was approved after performing it. - -Signed-off-by: Clemens Lang -Related: rhbz#2114772 ---- - include/crypto/evp.h | 7 ++++ - include/openssl/core_names.h | 1 + - include/openssl/kdf.h | 4 ++ - providers/implementations/kdfs/hkdf.c | 53 +++++++++++++++++++++++++++ - 4 files changed, 65 insertions(+) - -diff --git a/include/crypto/evp.h b/include/crypto/evp.h -index e70d8e9e84..76fb990de4 100644 ---- a/include/crypto/evp.h -+++ b/include/crypto/evp.h -@@ -219,6 +219,13 @@ struct evp_mac_st { - OSSL_FUNC_mac_set_ctx_params_fn *set_ctx_params; - }; - -+#ifdef FIPS_MODULE -+/* According to NIST Special Publication 800-131Ar2, Section 8: Deriving -+ * Additional Keys from a Cryptographic Key, "[t]he length of the -+ * key-derivation key [i.e., the input key] shall be at least 112 bits". */ -+# define EVP_KDF_FIPS_MIN_KEY_LEN (112 / 8) -+#endif -+ - struct evp_kdf_st { - OSSL_PROVIDER *prov; - int name_id; -diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h -index 21c94d0488..c019afbbb0 100644 ---- a/include/openssl/core_names.h -+++ b/include/openssl/core_names.h -@@ -223,6 +223,7 @@ extern "C" { - #define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo" - #define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO "supp-privinfo" - #define OSSL_KDF_PARAM_X942_USE_KEYBITS "use-keybits" -+#define OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" - - /* Known KDF names */ - #define OSSL_KDF_NAME_HKDF "HKDF" -diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h -index 0983230a48..86171635ea 100644 ---- a/include/openssl/kdf.h -+++ b/include/openssl/kdf.h -@@ -63,6 +63,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf, - # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1 - # define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2 - -+# define EVP_KDF_REDHAT_FIPS_INDICATOR_UNDETERMINED 0 -+# define EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED 1 -+# define EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2 -+ - #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV 65 - #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI 66 - #define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67 -diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c -index afdb7138e1..6f06fa58fe 100644 ---- a/providers/implementations/kdfs/hkdf.c -+++ b/providers/implementations/kdfs/hkdf.c -@@ -298,6 +298,56 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) - return 0; - return OSSL_PARAM_set_size_t(p, sz); - } -+ -+#ifdef FIPS_MODULE -+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR)) -+ != NULL) { -+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_UNDETERMINED; -+ switch (ctx->mode) { -+ case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: -+ /* TLS 1.3 never uses extract-and-expand */ -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; -+ break; -+ case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: -+ { -+ /* When TLS 1.3 uses extract, the following holds: -+ * 1. The salt length matches the hash length, and either -+ * 2.1. the key is all zeroes and matches the hash length, or -+ * 2.2. the key originates from a PSK (resumption_master_secret -+ * or some externally esablished key), or an ECDH or DH key -+ * derivation. See -+ * https://www.rfc-editor.org/rfc/rfc8446#section-7.1. -+ * Unfortunately at this point, we cannot verify where the key -+ * comes from, so all we can do is check the salt length. -+ */ -+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); -+ if (md != NULL && ctx->salt_len == (size_t) EVP_MD_get_size(md)) -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; -+ else -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; -+ } -+ break; -+ case EVP_KDF_HKDF_MODE_EXPAND_ONLY: -+ /* When TLS 1.3 uses expand, it always provides a label that -+ * contains an uint16 for the length, followed by between 7 and 255 -+ * bytes for a label string that starts with "tls13 " or "dtls13". -+ * For compatibility with future versions, we only check for "tls" -+ * or "dtls". See -+ * https://www.rfc-editor.org/rfc/rfc8446#section-7.1 and -+ * https://www.rfc-editor.org/rfc/rfc9147#section-5.9. */ -+ if (ctx->label != NULL -+ && ctx->label_len >= 2 /* length */ + 4 /* "dtls" */ -+ && (strncmp("tls", (const char *)ctx->label + 2, 3) == 0 || -+ strncmp("dtls", (const char *)ctx->label + 2, 4) == 0)) -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; -+ else -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; -+ break; -+ } -+ return OSSL_PARAM_set_int(p, fips_indicator); -+ } -+#endif /* defined(FIPS_MODULE) */ -+ - return -2; - } - -@@ -306,6 +356,9 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx, - { - static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), -+#ifdef FIPS_MODULE -+ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), -+#endif /* defined(FIPS_MODULE) */ - OSSL_PARAM_END - }; - return known_gettable_ctx_params; --- -2.38.1 - diff --git a/SOURCES/0078-KDF-Add-FIPS-indicators.patch b/SOURCES/0078-KDF-Add-FIPS-indicators.patch new file mode 100644 index 0000000..1090ffa --- /dev/null +++ b/SOURCES/0078-KDF-Add-FIPS-indicators.patch @@ -0,0 +1,906 @@ +From 2290280617183863eb15425b8925765966723725 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Thu, 11 Aug 2022 09:27:12 +0200 +Subject: KDF: Add FIPS indicators + +FIPS requires a number of restrictions on the parameters of the various +key derivation functions implemented in OpenSSL. The KDFs that use +digest algorithms usually should not allow SHAKE (due to FIPS 140-3 IG +C.C). Additionally, some application-specific KDFs have further +restrictions defined in SP 800-135r1. + +Generally, all KDFs shall use a key-derivation key length of at least +112 bits due to SP 800-131Ar2 section 8. Additionally any use of a KDF +to generate and output length of less than 112 bits will also set the +indicator to unapproved. + +Add explicit indicators to all KDFs usable in FIPS mode except for +PBKDF2 (which has its specific FIPS limits already implemented). The +indicator can be queried using EVP_KDF_CTX_get_params() after setting +the required parameters and keys for the KDF. + +Our FIPS provider implements SHA1, SHA2 (both -256 and -512, and the +truncated variants -224 and -384) and SHA3 (-256 and -512, and the +truncated versions -224 and -384), as well as SHAKE-128 and -256. + +The SHAKE functions are generally not allowed in KDFs. For the rest, the +support matrix is: + + KDF | SHA-1 | SHA-2 | SHA-2 truncated | SHA-3 | SHA-3 truncated +========================================================================== +KBKDF | x | x | x | x | x +HKDF | x | x | x | x | x +TLS1PRF | | SHA-{256,384,512} only | | +SSHKDF | x | x | x | | +SSKDF | x | x | x | x | x +X9.63KDF | | x | x | x | x +X9.42-ASN1 | x | x | x | x | x +TLS1.3PRF | | SHA-{256,384} only | | + +Signed-off-by: Clemens Lang +Resolves: rhbz#2160733 rhbz#2164763 +Related: rhbz#2114772 rhbz#2141695 +--- + include/crypto/evp.h | 7 ++ + include/openssl/core_names.h | 1 + + include/openssl/kdf.h | 4 + + providers/implementations/kdfs/hkdf.c | 100 +++++++++++++++++++++- + providers/implementations/kdfs/kbkdf.c | 82 ++++++++++++++++-- + providers/implementations/kdfs/sshkdf.c | 75 +++++++++++++++- + providers/implementations/kdfs/sskdf.c | 100 +++++++++++++++++++++- + providers/implementations/kdfs/tls1_prf.c | 74 +++++++++++++++- + providers/implementations/kdfs/x942kdf.c | 67 ++++++++++++++- + 9 files changed, 488 insertions(+), 22 deletions(-) + +diff --git a/include/crypto/evp.h b/include/crypto/evp.h +index e70d8e9e84..76fb990de4 100644 +--- a/include/crypto/evp.h ++++ b/include/crypto/evp.h +@@ -219,6 +219,13 @@ struct evp_mac_st { + OSSL_FUNC_mac_set_ctx_params_fn *set_ctx_params; + }; + ++#ifdef FIPS_MODULE ++/* According to NIST Special Publication 800-131Ar2, Section 8: Deriving ++ * Additional Keys from a Cryptographic Key, "[t]he length of the ++ * key-derivation key [i.e., the input key] shall be at least 112 bits". */ ++# define EVP_KDF_FIPS_MIN_KEY_LEN (112 / 8) ++#endif ++ + struct evp_kdf_st { + OSSL_PROVIDER *prov; + int name_id; +diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h +index 6bed5a8a67..680bfbc7cc 100644 +--- a/include/openssl/core_names.h ++++ b/include/openssl/core_names.h +@@ -223,6 +223,7 @@ extern "C" { + #define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo" + #define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO "supp-privinfo" + #define OSSL_KDF_PARAM_X942_USE_KEYBITS "use-keybits" ++#define OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" + + /* Known KDF names */ + #define OSSL_KDF_NAME_HKDF "HKDF" +diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h +index 0983230a48..86171635ea 100644 +--- a/include/openssl/kdf.h ++++ b/include/openssl/kdf.h +@@ -63,6 +63,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf, + # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1 + # define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2 + ++# define EVP_KDF_REDHAT_FIPS_INDICATOR_UNDETERMINED 0 ++# define EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED 1 ++# define EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2 ++ + #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV 65 + #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI 66 + #define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67 +diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c +index dfa7786bde..f01e40ff5a 100644 +--- a/providers/implementations/kdfs/hkdf.c ++++ b/providers/implementations/kdfs/hkdf.c +@@ -42,6 +42,7 @@ static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; + static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params; + static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params; + static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params; ++static OSSL_FUNC_kdf_newctx_fn kdf_tls1_3_new; + static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive; + static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params; + static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params; +@@ -85,6 +86,10 @@ typedef struct { + size_t data_len; + unsigned char info[HKDF_MAXBUF]; + size_t info_len; ++ int is_tls13; ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } KDF_HKDF; + + static void *kdf_hkdf_new(void *provctx) +@@ -170,6 +175,11 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen, + return 0; + } + ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + switch (ctx->mode) { + case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: + default: +@@ -332,15 +342,78 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + KDF_HKDF *ctx = (KDF_HKDF *)vctx; + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ + + if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { + size_t sz = kdf_hkdf_size(ctx); + +- if (sz == 0) ++ any_valid = 1; ++ ++ if (sz == 0 || !OSSL_PARAM_set_size_t(p, sz)) + return 0; +- return OSSL_PARAM_set_size_t(p, sz); + } +- return -2; ++ ++#ifdef FIPS_MODULE ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR)) ++ != NULL) { ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->key_len < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ if (ctx->is_tls13) { ++ if (md != NULL ++ && !EVP_MD_is_a(md, "SHA2-256") ++ && !EVP_MD_is_a(md, "SHA2-384")) { ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic ++ * Module Validation Program, Section 2.4.B, (5): "The TLS 1.3 ++ * key derivation function documented in Section 7.1 of RFC ++ * 8446. This is considered an approved CVL because the ++ * underlying functions performed within the TLS 1.3 KDF map to ++ * NIST approved standards, namely: SP 800-133rev2 (Section 6.3 ++ * Option #3), SP 800-56Crev2, and SP 800-108." ++ * ++ * RFC 8446 appendix B.4 only lists SHA-256 and SHA-384. */ ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ } else { ++ if (md != NULL ++ && (EVP_MD_is_a(md, "SHAKE-128") || ++ EVP_MD_is_a(md, "SHAKE-256"))) { ++ /* HKDF is a SP 800-56Cr2 TwoStep KDF, for which all SHA-1, ++ * SHA-2 and SHA-3 are approved. SHAKE is not approved, because ++ * of FIPS 140-3 IG, section C.C: "The SHAKE128 and SHAKE256 ++ * extendable-output functions may only be used as the ++ * standalone algorithms." */ ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ } ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif /* defined(FIPS_MODULE) */ ++ ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx, +@@ -348,6 +421,9 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx, + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +@@ -677,6 +753,17 @@ static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx, + return ret; + } + ++static void *kdf_tls1_3_new(void *provctx) ++{ ++ KDF_HKDF *hkdf = kdf_hkdf_new(provctx); ++ ++ if (hkdf != NULL) ++ hkdf->is_tls13 = 1; ++ ++ return hkdf; ++} ++ ++ + static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) + { +@@ -692,6 +779,11 @@ static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen, + return 0; + } + ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + switch (ctx->mode) { + default: + return 0; +@@ -769,7 +861,7 @@ static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx, + } + + const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = { +- { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new }, ++ { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_3_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_3_derive }, +diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c +index a542f84dfa..6b6dfb94ac 100644 +--- a/providers/implementations/kdfs/kbkdf.c ++++ b/providers/implementations/kdfs/kbkdf.c +@@ -59,6 +59,9 @@ typedef struct { + kbkdf_mode mode; + EVP_MAC_CTX *ctx_init; + ++ /* HMAC digest algorithm, if any; used to compute FIPS indicator */ ++ PROV_DIGEST digest; ++ + /* Names are lowercased versions of those found in SP800-108. */ + int r; + unsigned char *ki; +@@ -70,6 +73,9 @@ typedef struct { + size_t iv_len; + int use_l; + int use_separator; ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } KBKDF; + + /* Definitions needed for typechecking. */ +@@ -138,6 +144,7 @@ static void kbkdf_reset(void *vctx) + void *provctx = ctx->provctx; + + EVP_MAC_CTX_free(ctx->ctx_init); ++ ossl_prov_digest_reset(&ctx->digest); + OPENSSL_clear_free(ctx->context, ctx->context_len); + OPENSSL_clear_free(ctx->label, ctx->label_len); + OPENSSL_clear_free(ctx->ki, ctx->ki_len); +@@ -240,6 +247,11 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen, + return 0; + } + ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + h = EVP_MAC_CTX_get_mac_size(ctx->ctx_init); + if (h == 0) + goto done; +@@ -297,6 +309,9 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) + return 0; + } + ++ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) ++ return 0; ++ + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE); + if (p != NULL + && OPENSSL_strncasecmp("counter", p->data, p->data_size) == 0) { +@@ -363,20 +378,77 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx, + static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE); +- if (p == NULL) ++ if (p != NULL) { ++ any_valid = 1; ++ ++ /* KBKDF can produce results as large as you like. */ ++ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX)) ++ return 0; ++ } ++ ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ KBKDF *ctx = (KBKDF *)vctx; ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->ki_len < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256 ++ * extendable-output functions may only be used as the standalone ++ * algorithms." Note that the digest is only used when the MAC ++ * algorithm is HMAC. */ ++ if (ctx->ctx_init != NULL ++ && EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->ctx_init), OSSL_MAC_NAME_HMAC)) { ++ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); ++ if (md != NULL ++ && (EVP_MD_is_a(md, "SHAKE-128") || EVP_MD_is_a(md, "SHAKE-256"))) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ } ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif ++ ++ if (!any_valid) + return -2; + +- /* KBKDF can produce results as large as you like. */ +- return OSSL_PARAM_set_size_t(p, SIZE_MAX); ++ return 1; + } + + static const OSSL_PARAM *kbkdf_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *provctx) + { +- static const OSSL_PARAM known_gettable_ctx_params[] = +- { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; ++ static const OSSL_PARAM known_gettable_ctx_params[] = { ++ OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), ++#endif /* defined(FIPS_MODULE) */ ++ OSSL_PARAM_END ++ }; + return known_gettable_ctx_params; + } + +diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c +index c592ba72f1..4a52b38266 100644 +--- a/providers/implementations/kdfs/sshkdf.c ++++ b/providers/implementations/kdfs/sshkdf.c +@@ -48,6 +48,9 @@ typedef struct { + char type; /* X */ + unsigned char *session_id; + size_t session_id_len; ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } KDF_SSHKDF; + + static void *kdf_sshkdf_new(void *provctx) +@@ -126,6 +129,12 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen, + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_TYPE); + return 0; + } ++ ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + return SSHKDF(md, ctx->key, ctx->key_len, + ctx->xcghash, ctx->xcghash_len, + ctx->session_id, ctx->session_id_len, +@@ -194,10 +203,67 @@ static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(ossl_unused void *ctx, + static int kdf_sshkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ + +- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) +- return OSSL_PARAM_set_size_t(p, SIZE_MAX); +- return -2; ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { ++ any_valid = 1; ++ ++ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX)) ++ return 0; ++ } ++ ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ KDF_SSHKDF *ctx = vctx; ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->key_len < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256 ++ * extendable-output functions may only be used as the standalone ++ * algorithms." ++ * ++ * Additionally, SP 800-135r1 section 5.2 specifies that the hash ++ * function used in SSHKDF "is one of the hash functions specified in ++ * FIPS 180-3.", which rules out SHA-3 and truncated variants of SHA-2. ++ * */ ++ if (ctx->digest.md != NULL ++ && !EVP_MD_is_a(ctx->digest.md, "SHA-1") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-224") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-256") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-384") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-512")) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif ++ ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx, +@@ -205,6 +271,9 @@ static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx, + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c +index eb54972e1c..23865cd70f 100644 +--- a/providers/implementations/kdfs/sskdf.c ++++ b/providers/implementations/kdfs/sskdf.c +@@ -62,6 +62,10 @@ typedef struct { + unsigned char *salt; + size_t salt_len; + size_t out_len; /* optional KMAC parameter */ ++ int is_x963kdf; ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } KDF_SSKDF; + + #define SSKDF_MAX_INLEN (1<<30) +@@ -73,6 +77,7 @@ typedef struct { + static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 }; + + static OSSL_FUNC_kdf_newctx_fn sskdf_new; ++static OSSL_FUNC_kdf_newctx_fn x963kdf_new; + static OSSL_FUNC_kdf_freectx_fn sskdf_free; + static OSSL_FUNC_kdf_reset_fn sskdf_reset; + static OSSL_FUNC_kdf_derive_fn sskdf_derive; +@@ -296,6 +301,16 @@ static void *sskdf_new(void *provctx) + return ctx; + } + ++static void *x963kdf_new(void *provctx) ++{ ++ KDF_SSKDF *ctx = sskdf_new(provctx); ++ ++ if (ctx) ++ ctx->is_x963kdf = 1; ++ ++ return ctx; ++} ++ + static void sskdf_reset(void *vctx) + { + KDF_SSKDF *ctx = (KDF_SSKDF *)vctx; +@@ -361,6 +376,11 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen, + } + md = ossl_prov_digest_md(&ctx->digest); + ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + if (ctx->macctx != NULL) { + /* H(x) = KMAC or H(x) = HMAC */ + int ret; +@@ -442,6 +462,11 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen, + return 0; + } + ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ ++ + return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len, + ctx->info, ctx->info_len, 1, key, keylen); + } +@@ -514,10 +539,74 @@ static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + KDF_SSKDF *ctx = (KDF_SSKDF *)vctx; + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ ++ ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { ++ any_valid = 1; ++ ++ if (!OSSL_PARAM_set_size_t(p, sskdf_size(ctx))) ++ return 0; ++ } + +- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) +- return OSSL_PARAM_set_size_t(p, sskdf_size(ctx)); +- return -2; ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->secret_len < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256 ++ * extendable-output functions may only be used as the standalone ++ * algorithms." */ ++ if (ctx->macctx == NULL ++ || (ctx->macctx != NULL && ++ EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), OSSL_MAC_NAME_HMAC))) { ++ if (ctx->digest.md != NULL ++ && (EVP_MD_is_a(ctx->digest.md, "SHAKE-128") || ++ EVP_MD_is_a(ctx->digest.md, "SHAKE-256"))) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ ++ /* Table H-3 in ANS X9.63-2001 says that 160-bit hash functions ++ * should only be used for 80-bit key agreement, but FIPS 140-3 ++ * requires a security strength of 112 bits, so SHA-1 cannot be ++ * used with X9.63. See the discussion in ++ * https://github.com/usnistgov/ACVP/issues/1403#issuecomment-1435300395. ++ */ ++ if (ctx->is_x963kdf ++ && ctx->digest.md != NULL ++ && EVP_MD_is_a(ctx->digest.md, "SHA-1")) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ } ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif ++ ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx, +@@ -525,6 +614,9 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx, + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, 0), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +@@ -545,7 +637,7 @@ const OSSL_DISPATCH ossl_kdf_sskdf_functions[] = { + }; + + const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = { +- { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new }, ++ { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x963kdf_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))x963kdf_derive }, +diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c +index a4d64b9352..f6782a6ca2 100644 +--- a/providers/implementations/kdfs/tls1_prf.c ++++ b/providers/implementations/kdfs/tls1_prf.c +@@ -93,6 +93,13 @@ typedef struct { + /* Buffer of concatenated seed data */ + unsigned char seed[TLS1_PRF_MAXBUF]; + size_t seedlen; ++ ++ /* MAC digest algorithm; used to compute FIPS indicator */ ++ PROV_DIGEST digest; ++ ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } TLS1_PRF; + + static void *kdf_tls1_prf_new(void *provctx) +@@ -129,6 +136,7 @@ static void kdf_tls1_prf_reset(void *vctx) + EVP_MAC_CTX_free(ctx->P_sha1); + OPENSSL_clear_free(ctx->sec, ctx->seclen); + OPENSSL_cleanse(ctx->seed, ctx->seedlen); ++ ossl_prov_digest_reset(&ctx->digest); + memset(ctx, 0, sizeof(*ctx)); + ctx->provctx = provctx; + } +@@ -157,6 +165,10 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen, + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ + + return tls1_prf_alg(ctx->P_hash, ctx->P_sha1, + ctx->sec, ctx->seclen, +@@ -191,6 +203,9 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) + } + } + ++ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) ++ return 0; ++ + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) { + OPENSSL_clear_free(ctx->sec, ctx->seclen); + ctx->sec = NULL; +@@ -232,10 +247,60 @@ static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params( + static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + OSSL_PARAM *p; ++#ifdef FIPS_MODULE ++ TLS1_PRF *ctx = vctx; ++#endif /* defined(FIPS_MODULE) */ ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ ++ ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { ++ any_valid = 1; ++ ++ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX)) ++ return 0; ++ } ++ ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->seclen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* SP 800-135r1 section 4.2.2 says TLS 1.2 KDF is approved when "(3) ++ * P_HASH uses either SHA-256, SHA-384 or SHA-512." */ ++ if (ctx->digest.md != NULL ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-256") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-384") ++ && !EVP_MD_is_a(ctx->digest.md, "SHA2-512")) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif + +- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) +- return OSSL_PARAM_set_size_t(p, SIZE_MAX); +- return -2; ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params( +@@ -243,6 +308,9 @@ static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params( + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, 0), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c +index b1bc6f7e1b..8173fc2cc7 100644 +--- a/providers/implementations/kdfs/x942kdf.c ++++ b/providers/implementations/kdfs/x942kdf.c +@@ -13,10 +13,13 @@ + #include + #include + #include ++#include + #include + #include + #include "internal/packet.h" + #include "internal/der.h" ++#include "internal/nelem.h" ++#include "crypto/evp.h" + #include "prov/provider_ctx.h" + #include "prov/providercommon.h" + #include "prov/implementations.h" +@@ -47,6 +50,9 @@ typedef struct { + const unsigned char *cek_oid; + size_t cek_oid_len; + int use_keybits; ++#ifdef FIPS_MODULE ++ int output_keylen_indicator; ++#endif /* defined(FIPS_MODULE) */ + } KDF_X942; + + /* +@@ -460,6 +466,10 @@ static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen, + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING); + return 0; + } ++#ifdef FIPS_MODULE ++ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN) ++ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++#endif /* defined(FIPS_MODULE) */ + ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len, + der, der_len, ctr, key, keylen); + OPENSSL_free(der); +@@ -563,10 +573,58 @@ static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { + KDF_X942 *ctx = (KDF_X942 *)vctx; + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ + +- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) +- return OSSL_PARAM_set_size_t(p, x942kdf_size(ctx)); +- return -2; ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { ++ any_valid = 1; ++ ++ if (!OSSL_PARAM_set_size_t(p, x942kdf_size(ctx))) ++ return 0; ++ } ++ ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ any_valid = 1; ++ ++ /* According to NIST Special Publication 800-131Ar2, Section 8: ++ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of ++ * the key-derivation key [i.e., the input key] shall be at least 112 ++ * bits". */ ++ if (ctx->secret_len < EVP_KDF_FIPS_MIN_KEY_LEN) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section D.B and NIST Special Publication ++ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security ++ * strength < 112 bits is legacy use only, so all derived keys should ++ * be longer than that. If a derived key has ever been shorter than ++ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we ++ * should also set the returned FIPS indicator to unapproved. */ ++ if (ctx->output_keylen_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256 ++ * extendable-output functions may only be used as the standalone ++ * algorithms." */ ++ if (ctx->digest.md != NULL ++ && (EVP_MD_is_a(ctx->digest.md, "SHAKE-128") || ++ EVP_MD_is_a(ctx->digest.md, "SHAKE-256"))) { ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ } ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif ++ ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx, +@@ -574,6 +632,9 @@ static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx, + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, 0), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +-- +2.39.2 + diff --git a/SOURCES/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch b/SOURCES/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch deleted file mode 100644 index 8542af9..0000000 --- a/SOURCES/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 185fbbfea732588187c81d1b2cafb3e1fae9eb77 Mon Sep 17 00:00:00 2001 -From: Clemens Lang -Date: Thu, 17 Nov 2022 16:38:45 +0100 -Subject: [PATCH 2/2] kbkdf: Add explicit FIPS indicator for key length - -NIST SP 800-131Ar2, section 8 "Deriving Additional Keys from -a Cryptographic Key" says that for KDFs defined in SP 800-108, "[t]he -length of the key-derivation key shall be at least 112 bits". It further -specifies that HMAC-based KDFs "with a key whose length is at least 112 -bits" are acceptable. - -Add an explicit indicator for SP 800-108 KDFs that will mark shorter key -lengths as unapproved. The indicator can be queried from the EVP_KDF_CTX -object using EVP_KDF_CTX_get_params() with the - OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR -parameter. - -Signed-off-by: Clemens Lang ---- - providers/implementations/kdfs/kbkdf.c | 32 +++++++++++++++++++++----- - 1 file changed, 26 insertions(+), 6 deletions(-) - -diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c -index a542f84dfa..93a8a10537 100644 ---- a/providers/implementations/kdfs/kbkdf.c -+++ b/providers/implementations/kdfs/kbkdf.c -@@ -365,18 +365,38 @@ static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE); -- if (p == NULL) -- return -2; -+ if (p != NULL) -+ /* KBKDF can produce results as large as you like. */ -+ return OSSL_PARAM_set_size_t(p, SIZE_MAX); -+ -+#ifdef FIPS_MODULE -+ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR); -+ if (p != NULL) { -+ KBKDF *ctx = (KBKDF *)vctx; -+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; -+ /* According to NIST Special Publication 800-131Ar2, Section 8: -+ * Deriving Additional Keys from a Cryptographic Key, "[t]he length of -+ * the key-derivation key [i.e., the input key] shall be at least 112 -+ * bits". */ -+ if (ctx->ki_len < EVP_KDF_FIPS_MIN_KEY_LEN) -+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; -+ return OSSL_PARAM_set_int(p, fips_indicator); -+ } -+#endif - -- /* KBKDF can produce results as large as you like. */ -- return OSSL_PARAM_set_size_t(p, SIZE_MAX); -+ return -2; - } - - static const OSSL_PARAM *kbkdf_gettable_ctx_params(ossl_unused void *ctx, - ossl_unused void *provctx) - { -- static const OSSL_PARAM known_gettable_ctx_params[] = -- { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; -+ static const OSSL_PARAM known_gettable_ctx_params[] = { -+ OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), -+#ifdef FIPS_MODULE -+ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), -+#endif /* defined(FIPS_MODULE) */ -+ OSSL_PARAM_END -+ }; - return known_gettable_ctx_params; - } - --- -2.38.1 - diff --git a/SOURCES/0088-signature-Add-indicator-for-PSS-salt-length.patch b/SOURCES/0088-signature-Add-indicator-for-PSS-salt-length.patch index 97a0679..20024d3 100644 --- a/SOURCES/0088-signature-Add-indicator-for-PSS-salt-length.patch +++ b/SOURCES/0088-signature-Add-indicator-for-PSS-salt-length.patch @@ -35,6 +35,9 @@ EVP_PKEY_CTX_get_params() with the OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR parameter. +We also add indicator for RSA_NO_PADDING here to avoid patch-over-patch. +Dmitry Belyavskiy + Signed-off-by: Clemens Lang --- include/openssl/core_names.h | 1 + @@ -73,7 +76,7 @@ diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implement index 49e7f9158a..0c45008a00 100644 --- a/providers/implementations/signature/rsa_sig.c +++ b/providers/implementations/signature/rsa_sig.c -@@ -1127,6 +1127,21 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) +@@ -1127,6 +1127,24 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) } } @@ -87,6 +90,9 @@ index 49e7f9158a..0c45008a00 100644 + } else if (rsa_pss_compute_saltlen(prsactx) > EVP_MD_get_size(prsactx->md)) { + fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + } ++ } else if (prsactx->pad_mode == RSA_NO_PADDING) { ++ if (prsactx->md == NULL) /* Should always be the case */ ++ fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + } + return OSSL_PARAM_set_int(p, fips_indicator); + } diff --git a/SOURCES/0093-DH-Disable-FIPS-186-4-type-parameters-in-FIPS-mode.patch b/SOURCES/0093-DH-Disable-FIPS-186-4-type-parameters-in-FIPS-mode.patch new file mode 100644 index 0000000..65bae6f --- /dev/null +++ b/SOURCES/0093-DH-Disable-FIPS-186-4-type-parameters-in-FIPS-mode.patch @@ -0,0 +1,344 @@ +From 8a2d1b22ede5eeca4d104bb027b84f3ecfc69549 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Thu, 11 May 2023 12:51:59 +0200 +Subject: [PATCH] DH: Disable FIPS 186-4 type parameters in FIPS mode + +For DH parameter and key pair generation/verification, the DSA +procedures specified in FIPS 186-4 are used. With the release of FIPS +186-5 and the removal of DSA, the approved status of these groups is in +peril. Once the transition for DSA ends (this transition will be 1 year +long and start once CMVP has published the guidance), no more +submissions claiming DSA will be allowed. Hence, FIPS 186-type +parameters will also be automatically non-approved. + +In the FIPS provider, disable validation of any DH parameters that are +not well-known groups, and remove DH parameter generation completely. + +Adjust tests to use well-known groups or larger DH groups where this +change would now cause failures, and skip tests that are expected to +fail due to this change. + +Related: rhbz#2169757, rhbz#2169757 +Signed-off-by: Clemens Lang +--- + crypto/dh/dh_backend.c | 10 ++++ + crypto/dh/dh_check.c | 12 ++-- + crypto/dh/dh_gen.c | 12 +++- + crypto/dh/dh_key.c | 13 ++-- + crypto/dh/dh_pmeth.c | 10 +++- + providers/implementations/keymgmt/dh_kmgmt.c | 5 ++ + test/endecode_test.c | 4 +- + test/evp_libctx_test.c | 2 +- + test/helpers/predefined_dhparams.c | 62 ++++++++++++++++++++ + test/helpers/predefined_dhparams.h | 1 + + test/recipes/80-test_cms.t | 4 +- + test/recipes/80-test_ssl_old.t | 3 + + 12 files changed, 118 insertions(+), 20 deletions(-) + +diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c +index 726843fd30..24c65ca84f 100644 +--- a/crypto/dh/dh_backend.c ++++ b/crypto/dh/dh_backend.c +@@ -53,6 +53,16 @@ int ossl_dh_params_fromdata(DH *dh, const OSSL_PARAM params[]) + if (!dh_ffc_params_fromdata(dh, params)) + return 0; + ++#ifdef FIPS_MODULE ++ if (!ossl_dh_is_named_safe_prime_group(dh)) { ++ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS, ++ "FIPS 186-4 type domain parameters no longer allowed in" ++ " FIPS mode, since the required validation routines" ++ " were removed from FIPS 186-5"); ++ return 0; ++ } ++#endif ++ + param_priv_len = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN); + if (param_priv_len != NULL +diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c +index 0b391910d6..75581ca347 100644 +--- a/crypto/dh/dh_check.c ++++ b/crypto/dh/dh_check.c +@@ -57,13 +57,15 @@ int DH_check_params(const DH *dh, int *ret) + nid = DH_get_nid((DH *)dh); + if (nid != NID_undef) + return 1; ++ + /* +- * OR +- * (2b) FFC domain params conform to FIPS-186-4 explicit domain param +- * validity tests. ++ * FIPS 186-4 explicit domain parameters are no longer supported in FIPS mode. + */ +- return ossl_ffc_params_FIPS186_4_validate(dh->libctx, &dh->params, +- FFC_PARAM_TYPE_DH, ret, NULL); ++ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS, ++ "FIPS 186-4 type domain parameters no longer allowed in" ++ " FIPS mode, since the required validation routines were" ++ " removed from FIPS 186-5"); ++ return 0; + } + #else + int DH_check_params(const DH *dh, int *ret) +diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c +index aec6b85316..9c55121067 100644 +--- a/crypto/dh/dh_gen.c ++++ b/crypto/dh/dh_gen.c +@@ -38,18 +38,26 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, + BN_GENCB *cb) + { +- int ret, res; ++ int ret = 0; + + #ifndef FIPS_MODULE ++ int res; ++ + if (type == DH_PARAMGEN_TYPE_FIPS_186_2) + ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); + else +-#endif + ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); ++#else ++ /* In FIPS mode, we no longer support FIPS 186-4 domain parameters */ ++ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS, ++ "FIPS 186-4 type domain parameters no longer allowed in" ++ " FIPS mode, since the required generation routines were" ++ " removed from FIPS 186-5"); ++#endif + if (ret > 0) + dh->dirty_cnt++; + return ret; +diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c +index 4e9705beef..14c0b0b6b3 100644 +--- a/crypto/dh/dh_key.c ++++ b/crypto/dh/dh_key.c +@@ -308,8 +308,12 @@ static int generate_key(DH *dh) + goto err; + } else { + #ifdef FIPS_MODULE +- if (dh->params.q == NULL) +- goto err; ++ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS, ++ "FIPS 186-4 type domain parameters no longer" ++ " allowed in FIPS mode, since the required" ++ " generation routines were removed from FIPS" ++ " 186-5"); ++ goto err; + #else + if (dh->params.q == NULL) { + /* secret exponent length, must satisfy 2^(l-1) <= p */ +@@ -330,9 +334,7 @@ static int generate_key(DH *dh) + if (!BN_clear_bit(priv_key, 0)) + goto err; + } +- } else +-#endif +- { ++ } else { + /* Do a partial check for invalid p, q, g */ + if (!ossl_ffc_params_simple_validate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, NULL)) +@@ -348,6 +350,7 @@ static int generate_key(DH *dh) + priv_key)) + goto err; + } ++#endif + } + } + +diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c +index f201eede0d..30f90d15be 100644 +--- a/crypto/dh/dh_pmeth.c ++++ b/crypto/dh/dh_pmeth.c +@@ -305,13 +305,17 @@ static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx, + prime_len, subprime_len, &res, + pcb); + else +-# endif +- /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */ +- if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); ++# else ++ /* In FIPS mode, we no longer support FIPS 186-4 domain parameters */ ++ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS, ++ "FIPS 186-4 type domain parameters no longer allowed in" ++ " FIPS mode, since the required generation routines were" ++ " removed from FIPS 186-5"); ++# endif + if (rv <= 0) { + DH_free(ret); + return NULL; +diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c +index 9a7dde7c66..b3e7bca5ac 100644 +--- a/providers/implementations/keymgmt/dh_kmgmt.c ++++ b/providers/implementations/keymgmt/dh_kmgmt.c +@@ -414,6 +414,11 @@ static int dh_validate(const void *keydata, int selection, int checktype) + if ((selection & DH_POSSIBLE_SELECTIONS) == 0) + return 1; /* nothing to validate */ + ++#ifdef FIPS_MODULE ++ /* In FIPS provider, always check the domain parameters to disallow ++ * operations on keys with FIPS 186-4 params. */ ++ selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; ++#endif + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + /* + * Both of these functions check parameters. DH_check_params_ex() +diff --git a/test/endecode_test.c b/test/endecode_test.c +index e3f7b81f69..1b63daaed5 100644 +--- a/test/endecode_test.c ++++ b/test/endecode_test.c +@@ -80,10 +80,10 @@ static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams) + * for testing only. Use a minimum key size of 2048 for security purposes. + */ + if (strcmp(type, "DH") == 0) +- return get_dh512(keyctx); ++ return get_dh2048(keyctx); + + if (strcmp(type, "X9.42 DH") == 0) +- return get_dhx512(keyctx); ++ return get_dhx_ffdhe2048(keyctx); + # endif + + /* +diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c +index 2448c35a14..92d484fb12 100644 +--- a/test/evp_libctx_test.c ++++ b/test/evp_libctx_test.c +@@ -188,7 +188,7 @@ static int do_dh_param_keygen(int tstid, const BIGNUM **bn) + + if (!TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey_parm, NULL)) + || !TEST_int_gt(EVP_PKEY_keygen_init(gen_ctx), 0) +- || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey), expected)) ++ || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey) == 1, expected)) + goto err; + + if (expected) { +diff --git a/test/helpers/predefined_dhparams.c b/test/helpers/predefined_dhparams.c +index 4bdadc4143..e5186e4b4a 100644 +--- a/test/helpers/predefined_dhparams.c ++++ b/test/helpers/predefined_dhparams.c +@@ -116,6 +116,68 @@ EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx) + dhx512_q, sizeof(dhx512_q)); + } + ++EVP_PKEY *get_dhx_ffdhe2048(OSSL_LIB_CTX *libctx) ++{ ++ /* This is RFC 7919 ffdhe2048, since Red Hat removes support for ++ * non-well-known groups in FIPS mode. */ ++ static unsigned char dhx_p[] = { ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58, ++ 0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1, ++ 0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41, ++ 0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9, ++ 0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02, ++ 0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61, ++ 0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55, ++ 0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35, ++ 0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda, ++ 0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35, ++ 0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82, ++ 0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb, ++ 0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3, ++ 0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19, ++ 0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1, ++ 0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61, ++ 0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32, ++ 0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73, ++ 0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83, ++ 0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa, ++ 0x88, 0x6b, 0x42, 0x38, 0x61, 0x28, 0x5c, 0x97, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff ++ }; ++ static unsigned char dhx_g[] = { ++ 0x02 ++ }; ++ static unsigned char dhx_q[] = { ++ 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xfc, 0x2a, 0x2c, ++ 0x51, 0x5d, 0xa5, 0x4d, 0x57, 0xee, 0x2b, 0x10, 0x13, 0x9e, 0x9e, 0x78, ++ 0xec, 0x5c, 0xe2, 0xc1, 0xe7, 0x16, 0x9b, 0x4a, 0xd4, 0xf0, 0x9b, 0x20, ++ 0x8a, 0x32, 0x19, 0xfd, 0xe6, 0x49, 0xce, 0xe7, 0x12, 0x4d, 0x9f, 0x7c, ++ 0xbe, 0x97, 0xf1, 0xb1, 0xb1, 0x86, 0x3a, 0xec, 0x7b, 0x40, 0xd9, 0x01, ++ 0x57, 0x62, 0x30, 0xbd, 0x69, 0xef, 0x8f, 0x6a, 0xea, 0xfe, 0xb2, 0xb0, ++ 0x92, 0x19, 0xfa, 0x8f, 0xaf, 0x83, 0x37, 0x68, 0x42, 0xb1, 0xb2, 0xaa, ++ 0x9e, 0xf6, 0x8d, 0x79, 0xda, 0xab, 0x89, 0xaf, 0x3f, 0xab, 0xe4, 0x9a, ++ 0xcc, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xbb, 0xf1, 0x53, 0x44, 0xed, ++ 0x79, 0xf7, 0xf4, 0x39, 0x0e, 0xf8, 0xac, 0x50, 0x9b, 0x56, 0xf3, 0x9a, ++ 0x98, 0x56, 0x65, 0x27, 0xa4, 0x1d, 0x3c, 0xbd, 0x5e, 0x05, 0x58, 0xc1, ++ 0x59, 0x92, 0x7d, 0xb0, 0xe8, 0x84, 0x54, 0xa5, 0xd9, 0x64, 0x71, 0xfd, ++ 0xdc, 0xb5, 0x6d, 0x5b, 0xb0, 0x6b, 0xfa, 0x34, 0x0e, 0xa7, 0xa1, 0x51, ++ 0xef, 0x1c, 0xa6, 0xfa, 0x57, 0x2b, 0x76, 0xf3, 0xb1, 0xb9, 0x5d, 0x8c, ++ 0x85, 0x83, 0xd3, 0xe4, 0x77, 0x05, 0x36, 0xb8, 0x4f, 0x01, 0x7e, 0x70, ++ 0xe6, 0xfb, 0xf1, 0x76, 0x60, 0x1a, 0x02, 0x66, 0x94, 0x1a, 0x17, 0xb0, ++ 0xc8, 0xb9, 0x7f, 0x4e, 0x74, 0xc2, 0xc1, 0xff, 0xc7, 0x27, 0x89, 0x19, ++ 0x77, 0x79, 0x40, 0xc1, 0xe1, 0xff, 0x1d, 0x8d, 0xa6, 0x37, 0xd6, 0xb9, ++ 0x9d, 0xda, 0xfe, 0x5e, 0x17, 0x61, 0x10, 0x02, 0xe2, 0xc7, 0x78, 0xc1, ++ 0xbe, 0x8b, 0x41, 0xd9, 0x63, 0x79, 0xa5, 0x13, 0x60, 0xd9, 0x77, 0xfd, ++ 0x44, 0x35, 0xa1, 0x1c, 0x30, 0x94, 0x2e, 0x4b, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff ++ }; ++ ++ return get_dh_from_pg(libctx, "X9.42 DH", ++ dhx_p, sizeof(dhx_p), ++ dhx_g, sizeof(dhx_g), ++ dhx_q, sizeof(dhx_q)); ++} ++ + EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx) + { + static unsigned char dh1024_p[] = { +diff --git a/test/helpers/predefined_dhparams.h b/test/helpers/predefined_dhparams.h +index f0e8709062..2ff6d6e721 100644 +--- a/test/helpers/predefined_dhparams.h ++++ b/test/helpers/predefined_dhparams.h +@@ -12,6 +12,7 @@ + #ifndef OPENSSL_NO_DH + EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx); + EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx); ++EVP_PKEY *get_dhx_ffdhe2048(OSSL_LIB_CTX *libctx); + EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libct); + EVP_PKEY *get_dh2048(OSSL_LIB_CTX *libctx); + EVP_PKEY *get_dh4096(OSSL_LIB_CTX *libctx); +diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t +index cabbe3ecdf..efe56c5665 100644 +--- a/test/recipes/80-test_cms.t ++++ b/test/recipes/80-test_cms.t +@@ -627,10 +627,10 @@ my @smime_cms_param_tests = ( + ], + + [ "enveloped content test streaming S/MIME format, X9.42 DH", +- [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, ++ [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont, + "-stream", "-out", "{output}.cms", + "-recip", catfile($smdir, "smdh.pem"), "-aes128" ], +- [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"), ++ [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"), + "-in", "{output}.cms", "-out", "{output}.txt" ], + \&final_compare + ] +diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t +index 8c52b637fc..31ed54621b 100644 +--- a/test/recipes/80-test_ssl_old.t ++++ b/test/recipes/80-test_ssl_old.t +@@ -390,6 +390,9 @@ sub testssl { + skip "skipping dhe1024dsa test", 1 + if ($no_dh); + ++ skip "FIPS 186-4 type DH groups are no longer supported by the FIPS provider", 1 ++ if $provider eq "fips"; ++ + ok(run(test([@ssltest, "-bio_pair", "-dhe1024dsa", "-v"])), + 'test sslv2/sslv3 with 1024bit DHE via BIO pair'); + } +-- +2.40.1 + diff --git a/SOURCES/0109-fips-Zeroize-out-in-fips-selftest.patch b/SOURCES/0109-fips-Zeroize-out-in-fips-selftest.patch new file mode 100644 index 0000000..3cd48df --- /dev/null +++ b/SOURCES/0109-fips-Zeroize-out-in-fips-selftest.patch @@ -0,0 +1,26 @@ +From 9dbc6069665690bd238caa7622647ea8ac94124f Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Mon, 13 Feb 2023 11:01:44 +0100 +Subject: fips: Zeroize `out` in fips selftest + +Signed-off-by: Clemens Lang +Resolves: rhbz#2169314 +--- + providers/fips/self_test.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c +index 80d048a847..11a989209c 100644 +--- a/providers/fips/self_test.c ++++ b/providers/fips/self_test.c +@@ -221,6 +221,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex + goto err; + ret = 1; + err: ++ OPENSSL_cleanse(out, sizeof(out)); + OSSL_SELF_TEST_onend(ev, ret); + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(mac); +-- +2.39.1 + diff --git a/SOURCES/0110-GCM-Implement-explicit-FIPS-indicator-for-IV-gen.patch b/SOURCES/0110-GCM-Implement-explicit-FIPS-indicator-for-IV-gen.patch new file mode 100644 index 0000000..5cb8ce4 --- /dev/null +++ b/SOURCES/0110-GCM-Implement-explicit-FIPS-indicator-for-IV-gen.patch @@ -0,0 +1,101 @@ +From 589eb3898896c1ac916bc20069ecd5adb8534850 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Fri, 17 Feb 2023 15:31:08 +0100 +Subject: [PATCH] GCM: Implement explicit FIPS indicator for IV gen + +Implementation Guidance for FIPS 140-3 and the Cryptographic Module +Verification Program, Section C.H requires guarantees about the +uniqueness of key/iv pairs, and proposes a few approaches to ensure +this. Provide an indicator for option 2 "The IV may be generated +internally at its entirety randomly." + +Resolves: rhbz#2168289 +Signed-off-by: Clemens Lang +--- + include/openssl/core_names.h | 1 + + include/openssl/evp.h | 4 +++ + .../implementations/ciphers/ciphercommon.c | 4 +++ + .../ciphers/ciphercommon_gcm.c | 25 +++++++++++++++++++ + 4 files changed, 34 insertions(+) + +diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h +index 680bfbc7cc..832502a034 100644 +--- a/include/openssl/core_names.h ++++ b/include/openssl/core_names.h +@@ -97,6 +97,7 @@ extern "C" { + #define OSSL_CIPHER_PARAM_CTS_MODE "cts_mode" /* utf8_string */ + /* For passing the AlgorithmIdentifier parameter in DER form */ + #define OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS "alg_id_param" /* octet_string */ ++#define OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" /* int */ + + #define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT \ + "tls1multi_maxsndfrag" /* uint */ +diff --git a/include/openssl/evp.h b/include/openssl/evp.h +index 49e8e1df78..ec2ba46fbd 100644 +--- a/include/openssl/evp.h ++++ b/include/openssl/evp.h +@@ -746,6 +746,10 @@ void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); + void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); + int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + ++# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_UNDETERMINED 0 ++# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_APPROVED 1 ++# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2 ++ + __owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); + /*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, +diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c +index fa383165d8..716add7339 100644 +--- a/providers/implementations/ciphers/ciphercommon.c ++++ b/providers/implementations/ciphers/ciphercommon.c +@@ -149,6 +149,10 @@ static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), ++ /* normally we would hide this under an #ifdef FIPS_MODULE, but that does ++ * not work in ciphercommon.c because it is compiled only once into ++ * libcommon.a */ ++ OSSL_PARAM_int(OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR, NULL), + OSSL_PARAM_END + }; + const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params( +diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c +index ed95c97ff4..db7910eb0e 100644 +--- a/providers/implementations/ciphers/ciphercommon_gcm.c ++++ b/providers/implementations/ciphers/ciphercommon_gcm.c +@@ -224,6 +224,31 @@ int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) + || !getivgen(ctx, p->data, p->data_size)) + return 0; + } ++ ++ /* We would usually hide this under #ifdef FIPS_MODULE, but ++ * ciphercommon_gcm.c is only compiled once into libcommon.a, so ifdefs do ++ * not work here. */ ++ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ int fips_indicator = EVP_CIPHER_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module ++ * Verification Program, Section C.H requires guarantees about the ++ * uniqueness of key/iv pairs, and proposes a few approaches to ensure ++ * this. This provides an indicator for option 2 "The IV may be ++ * generated internally at its entirety randomly." Note that one of the ++ * conditions of this option is that "The IV length shall be at least ++ * 96 bits (per SP 800-38D)." We do not specically check for this ++ * condition here, because gcm_iv_generate will fail in this case. */ ++ if (ctx->enc && !ctx->iv_gen_rand) ++ fips_indicator = EVP_CIPHER_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ++ return 0; ++ } ++ } ++ + return 1; + } + +-- +2.39.1 + diff --git a/SOURCES/0111-fips-Use-salt-16-bytes-in-PBKDF2-selftest.patch b/SOURCES/0111-fips-Use-salt-16-bytes-in-PBKDF2-selftest.patch new file mode 100644 index 0000000..3868089 --- /dev/null +++ b/SOURCES/0111-fips-Use-salt-16-bytes-in-PBKDF2-selftest.patch @@ -0,0 +1,82 @@ +From 56090fca0a0c8b6cf1782aced0a02349358aae7d Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Fri, 3 Mar 2023 12:22:03 +0100 +Subject: [PATCH 1/2] fips: Use salt >= 16 bytes in PBKDF2 selftest + +NIST SP 800-132 [1] section 5.1 says "[t]he length of the +randomly-generated portion of the salt shall be at least +128 bits", which implies that the salt for PBKDF2 must be at least 16 +bytes long (see also Appendix A.2.1). + +The FIPS 140-3 IG [2] section 10.3.A requires that "the lengths and the +properties of the Password and Salt parameters, as well as the desired +length of the Master Key used in a CAST shall be among those supported +by the module in the approved mode." + +As a consequence, the salt length in the self test must be at least 16 +bytes long for FIPS 140-3 compliance. Switch the self test to use the +only test vector from RFC 6070 that uses salt that is long enough to +fulfil this requirement. Since RFC 6070 does not provide expected +results for PBKDF2 with HMAC-SHA256, use the output from [3], which was +generated with python cryptography, which was tested against the RFC +6070 vectors with HMAC-SHA1. + + [1]: https://doi.org/10.6028/NIST.SP.800-132 + [2]: https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf + [3]: https://github.com/brycx/Test-Vector-Generation/blob/master/PBKDF2/pbkdf2-hmac-sha2-test-vectors.md + +Signed-off-by: Clemens Lang + +Reviewed-by: Paul Dale +Reviewed-by: Dmitry Belyavskiy +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/20429) + +(cherry picked from commit 451cb23c41c90d5a02902b3a77551aa9ee1c6956) +--- + providers/fips/self_test_data.inc | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc +index 8ae8cd6f4a..03adf28f3c 100644 +--- a/providers/fips/self_test_data.inc ++++ b/providers/fips/self_test_data.inc +@@ -361,19 +361,29 @@ static const ST_KAT_PARAM x963kdf_params[] = { + }; + + static const char pbkdf2_digest[] = "SHA256"; ++/* ++ * Input parameters from RFC 6070, vector 5 (because it is the only one with ++ * a salt >= 16 bytes, which NIST SP 800-132 section 5.1 requires). The ++ * expected output is taken from ++ * https://github.com/brycx/Test-Vector-Generation/blob/master/PBKDF2/pbkdf2-hmac-sha2-test-vectors.md, ++ * which ran these test vectors with SHA-256. ++ */ + static const unsigned char pbkdf2_password[] = { +- 0x70, 0x61, 0x73, 0x73, 0x00, 0x77, 0x6f, 0x72, +- 0x64 ++ 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x50, 0x41, 0x53, 0x53, ++ 0x57, 0x4f, 0x52, 0x44, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64 + }; + static const unsigned char pbkdf2_salt[] = { +- 0x73, 0x61, 0x00, 0x6c, 0x74 ++ 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, ++ 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, ++ 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74 + }; + static const unsigned char pbkdf2_expected[] = { +- 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, +- 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, ++ 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8, ++ 0x11, 0x6e, 0x84, 0xcf, 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, ++ 0x1c + }; + static int pbkdf2_iterations = 4096; +-static int pbkdf2_pkcs5 = 1; ++static int pbkdf2_pkcs5 = 0; + static const ST_KAT_PARAM pbkdf2_params[] = { + ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, pbkdf2_digest), + ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_PASSWORD, pbkdf2_password), +-- +2.39.2 + diff --git a/SOURCES/0112-pbdkf2-Set-indicator-if-pkcs5-param-disabled-checks.patch b/SOURCES/0112-pbdkf2-Set-indicator-if-pkcs5-param-disabled-checks.patch new file mode 100644 index 0000000..2e869e2 --- /dev/null +++ b/SOURCES/0112-pbdkf2-Set-indicator-if-pkcs5-param-disabled-checks.patch @@ -0,0 +1,80 @@ +From fa96a2f493276e7a57512e8c3d535052586f1525 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Mon, 6 Mar 2023 12:32:04 +0100 +Subject: [PATCH 2/2] pbdkf2: Set indicator if pkcs5 param disabled checks + +The pbkdf2 implementation in the FIPS provider supports the checks +required by NIST, but allows disabling these checks by setting the +OSSL_KDF_PARAM_PKCS5 parameter to 1. The implementation must indicate +that the use of this configuration is not approved in FIPS mode. Add an +explicit indicator to provide this indication. + +Resolves: rhbz#2175145 +Signed-off-by: Clemens Lang +--- + providers/implementations/kdfs/pbkdf2.c | 40 +++++++++++++++++++++++-- + 1 file changed, 37 insertions(+), 3 deletions(-) + +diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c +index aa0adce5e6..6df8c6d321 100644 +--- a/providers/implementations/kdfs/pbkdf2.c ++++ b/providers/implementations/kdfs/pbkdf2.c +@@ -251,11 +251,42 @@ static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(ossl_unused void *ctx, + + static int kdf_pbkdf2_get_ctx_params(void *vctx, OSSL_PARAM params[]) + { ++#ifdef FIPS_MODULE ++ KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx; ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM *p; ++ int any_valid = 0; /* set to 1 when at least one parameter was valid */ ++ ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { ++ any_valid = 1; ++ ++ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX)) ++ return 0; ++ } ++ ++#ifdef FIPS_MODULE ++ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR)) ++ != NULL) { ++ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ /* The lower_bound_checks parameter enables checks required by FIPS. If ++ * those checks are disabled, the PBKDF2 implementation will also ++ * support non-approved parameters (e.g., salt lengths < 16 bytes, see ++ * NIST SP 800-132 section 5.1). */ ++ if (!ctx->lower_bound_checks) ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + +- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) +- return OSSL_PARAM_set_size_t(p, SIZE_MAX); +- return -2; ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ ++ any_valid = 1; ++ } ++#endif /* defined(FIPS_MODULE) */ ++ ++ if (!any_valid) ++ return -2; ++ ++ return 1; + } + + static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(ossl_unused void *ctx, +@@ -263,6 +294,9 @@ static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(ossl_unused void *ctx, + { + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +-- +2.39.2 + diff --git a/SOURCES/0113-asymciphers-kem-Add-explicit-FIPS-indicator.patch b/SOURCES/0113-asymciphers-kem-Add-explicit-FIPS-indicator.patch new file mode 100644 index 0000000..4c648d8 --- /dev/null +++ b/SOURCES/0113-asymciphers-kem-Add-explicit-FIPS-indicator.patch @@ -0,0 +1,150 @@ +From ee6e381e4140efd5365ddf27a12055859103cf59 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Fri, 17 Mar 2023 15:39:15 +0100 +Subject: [PATCH] asymciphers, kem: Add explicit FIPS indicator + +NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key +confirmation (section 6.4.2.3.2), or assurance from a trusted third +party (section 6.4.2.3.1) for the KTS-OAEP key transport scheme and key +agreement schemes, but explicit key confirmation is not implemented and +cannot be implemented without protocol changes, and the FIPS provider +does not implement trusted third party validation, since it relies on +its callers to do that. We must thus mark RSA-OAEP encryption and RSASVE +as unapproved until we have received clarification from NIST on how +library modules such as OpenSSL should implement TTP validation. + +This does not affect RSA-OAEP decryption, because it is approved as +a component according to the FIPS 140-3 IG, section 2.4.G. + +Resolves: rhbz#2179331 +Signed-off-by: Clemens Lang +--- + include/openssl/core_names.h | 2 ++ + include/openssl/evp.h | 4 +++ + .../implementations/asymciphers/rsa_enc.c | 24 +++++++++++++++ + providers/implementations/kem/rsa_kem.c | 30 ++++++++++++++++++- + 4 files changed, 59 insertions(+), 1 deletion(-) + +diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h +index 832502a034..e15d208421 100644 +--- a/include/openssl/core_names.h ++++ b/include/openssl/core_names.h +@@ -477,6 +477,7 @@ extern "C" { + #ifdef FIPS_MODULE + #define OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED "redhat-kat-oaep-seed" + #endif ++#define OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" + + /* + * Encoder / decoder parameters +@@ -503,6 +504,7 @@ extern "C" { + + /* KEM parameters */ + #define OSSL_KEM_PARAM_OPERATION "operation" ++#define OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" /* int */ + + /* OSSL_KEM_PARAM_OPERATION values */ + #define OSSL_KEM_PARAM_OPERATION_RSASVE "RSASVE" +diff --git a/include/openssl/evp.h b/include/openssl/evp.h +index ec2ba46fbd..3803b03422 100644 +--- a/include/openssl/evp.h ++++ b/include/openssl/evp.h +@@ -1757,6 +1757,10 @@ OSSL_DEPRECATEDIN_3_0 size_t EVP_PKEY_meth_get_count(void); + OSSL_DEPRECATEDIN_3_0 const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); + # endif + ++# define EVP_PKEY_REDHAT_FIPS_INDICATOR_UNDETERMINED 0 ++# define EVP_PKEY_REDHAT_FIPS_INDICATOR_APPROVED 1 ++# define EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2 ++ + EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties); + int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt); +diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c +index 568452ec56..2e7ea632d7 100644 +--- a/providers/implementations/asymciphers/rsa_enc.c ++++ b/providers/implementations/asymciphers/rsa_enc.c +@@ -399,6 +399,27 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) + if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->alt_version)) + return 0; + ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ int fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_APPROVED; ++ ++ /* NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key ++ * confirmation (section 6.4.2.3.2), or assurance from a trusted third ++ * party (section 6.4.2.3.1) for the KTS-OAEP key transport scheme, but ++ * explicit key confirmation is not implemented here and cannot be ++ * implemented without protocol changes, and the FIPS provider does not ++ * implement trusted third party validation, since it relies on its ++ * callers to do that. We must thus mark RSA-OAEP as unapproved until ++ * we have received clarification from NIST on how library modules such ++ * as OpenSSL should implement TTP validation. */ ++ fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif /* defined(FIPS_MODULE) */ ++ + return 1; + } + +@@ -465,6 +493,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), + #ifdef FIPS_MODULE + OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED, NULL, 0), ++ OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR, NULL), + #endif /* FIPS_MODULE */ + OSSL_PARAM_END + }; +diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c +index 882cf16125..b4cc0f9237 100644 +--- a/providers/implementations/kem/rsa_kem.c ++++ b/providers/implementations/kem/rsa_kem.c +@@ -151,11 +151,39 @@ static int rsakem_decapsulate_init(void *vprsactx, void *vrsa, + static int rsakem_get_ctx_params(void *vprsactx, OSSL_PARAM *params) + { + PROV_RSA_CTX *ctx = (PROV_RSA_CTX *)vprsactx; ++#ifdef FIPS_MODULE ++ OSSL_PARAM *p; ++#endif /* defined(FIPS_MODULE) */ ++ ++ if (ctx == NULL) ++ return 0; ++ ++#ifdef FIPS_MODULE ++ p = OSSL_PARAM_locate(params, OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR); ++ if (p != NULL) { ++ /* NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key ++ * confirmation (section 6.4.2.3.2), or assurance from a trusted third ++ * party (section 6.4.2.3.1) for key agreement or key transport, but ++ * explicit key confirmation is not implemented here and cannot be ++ * implemented without protocol changes, and the FIPS provider does not ++ * implement trusted third party validation, since it relies on its ++ * callers to do that. We must thus mark RSASVE unapproved until we ++ * have received clarification from NIST on how library modules such as ++ * OpenSSL should implement TTP validation. */ ++ int fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED; ++ ++ if (!OSSL_PARAM_set_int(p, fips_indicator)) ++ return 0; ++ } ++#endif /* defined(FIPS_MODULE) */ + +- return ctx != NULL; ++ return 1; + } + + static const OSSL_PARAM known_gettable_rsakem_ctx_params[] = { ++#ifdef FIPS_MODULE ++ OSSL_PARAM_int(OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR, NULL), ++#endif /* defined(FIPS_MODULE) */ + OSSL_PARAM_END + }; + +-- +2.39.2 + diff --git a/SOURCES/0114-FIPS-enforce-EMS-support.patch b/SOURCES/0114-FIPS-enforce-EMS-support.patch new file mode 100644 index 0000000..3b38deb --- /dev/null +++ b/SOURCES/0114-FIPS-enforce-EMS-support.patch @@ -0,0 +1,473 @@ +diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt +index e90e5dc03339..f391e756475c 100644 +--- a/crypto/err/openssl.txt ++++ b/crypto/err/openssl.txt +@@ -1006,6 +1006,7 @@ PROV_R_BN_ERROR:160:bn error + PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed + PROV_R_DERIVATION_FUNCTION_INIT_FAILED:205:derivation function init failed + PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed ++PROV_R_EMS_NOT_ENABLED:233:ems not enabled + PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK:186:entropy source strength too weak + PROV_R_ERROR_INSTANTIATING_DRBG:188:error instantiating drbg + PROV_R_ERROR_RETRIEVING_ENTROPY:189:error retrieving entropy +diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h +index 173a81d28bbe..5e5be567a578 100644 +--- a/include/openssl/core_names.h ++++ b/include/openssl/core_names.h +@@ -21,11 +21,12 @@ extern "C" { + #define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" /* utf8_ptr */ + + /* Well known parameter names that Providers can define */ +-#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */ +-#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */ +-#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */ +-#define OSSL_PROV_PARAM_STATUS "status" /* uint */ +-#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */ ++#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */ ++#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */ ++#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */ ++#define OSSL_PROV_PARAM_STATUS "status" /* uint */ ++#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */ ++#define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" /* uint */ + + /* Self test callback parameters */ + #define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */ +diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h +index 0fdf5440c7cb..3f29369b3f92 100644 +--- a/include/openssl/fips_names.h ++++ b/include/openssl/fips_names.h +@@ -53,6 +53,14 @@ extern "C" { + */ + # define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks" + ++/* ++ * A boolean that determines if the runtime FIPS check for TLS1_PRF EMS is performed. ++ * This is disabled by default. ++ * ++ * Type: OSSL_PARAM_UTF8_STRING ++ */ ++# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" ++ + # ifdef __cplusplus + } + # endif +diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h +index 3685430f5d3e..bf4dc135f592 100644 +--- a/include/openssl/proverr.h ++++ b/include/openssl/proverr.h +@@ -32,6 +32,7 @@ + # define PROV_R_CIPHER_OPERATION_FAILED 102 + # define PROV_R_DERIVATION_FUNCTION_INIT_FAILED 205 + # define PROV_R_DIGEST_NOT_ALLOWED 174 ++# define PROV_R_EMS_NOT_ENABLED 233 + # define PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK 186 + # define PROV_R_ERROR_INSTANTIATING_DRBG 188 + # define PROV_R_ERROR_RETRIEVING_ENTROPY 189 +diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h +index 4a7f85f71186..62e60cc0103f 100644 +--- a/providers/common/include/prov/securitycheck.h ++++ b/providers/common/include/prov/securitycheck.h +@@ -28,3 +28,4 @@ int ossl_digest_get_approved_nid(const EVP_MD *md); + int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md, + int sha1_allowed); + int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx); ++int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx); +diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c +index f6144072aa04..954aabe80cfc 100644 +--- a/providers/common/provider_err.c ++++ b/providers/common/provider_err.c +@@ -33,6 +33,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { + "derivation function init failed"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED), + "digest not allowed"}, ++ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_EMS_NOT_ENABLED), "ems not enabled"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK), + "entropy source strength too weak"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_INSTANTIATING_DRBG), +diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c +index de7f0d3a0a57..63c875ecd0b7 100644 +--- a/providers/common/securitycheck_default.c ++++ b/providers/common/securitycheck_default.c +@@ -22,6 +22,12 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx) + return 0; + } + ++/* Disable the ems check in the default provider */ ++int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx) ++{ ++ return 0; ++} ++ + int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md, + int sha1_allowed) + { +diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c +index b7659bd395c3..2bc8a5992685 100644 +--- a/providers/common/securitycheck_fips.c ++++ b/providers/common/securitycheck_fips.c +@@ -20,6 +20,7 @@ + #include "prov/securitycheck.h" + + int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx); ++int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx); + + int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx) + { +@@ -30,6 +31,11 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx) + #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + } + ++int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx) ++{ ++ return FIPS_tls_prf_ems_check(libctx); ++} ++ + int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md, + int sha1_allowed) + { +diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c +index b86b27d236f3..b881f46f36ad 100644 +--- a/providers/fips/fipsprov.c ++++ b/providers/fips/fipsprov.c +@@ -47,6 +47,7 @@ static OSSL_FUNC_provider_query_operation_fn fips_query; + #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL) + extern OSSL_FUNC_core_thread_start_fn *c_thread_start; + int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx); ++int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx); + + /* + * Should these function pointers be stored in the provider side provctx? Could +@@ -82,7 +83,9 @@ typedef struct fips_global_st { + const OSSL_CORE_HANDLE *handle; + SELF_TEST_POST_PARAMS selftest_params; + int fips_security_checks; ++ int fips_tls1_prf_ems_check; + const char *fips_security_check_option; ++ const char *fips_tls1_prf_ems_check_option; + } FIPS_GLOBAL; + + static void *fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) +@@ -94,6 +97,9 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) + fgbl->fips_security_checks = 1; + fgbl->fips_security_check_option = "1"; + ++ fgbl->fips_tls1_prf_ems_check = 1; /* Enabled */ ++ fgbl->fips_tls1_prf_ems_check_option = "1"; ++ + return fgbl; + } + +@@ -109,6 +115,7 @@ static const OSSL_PARAM fips_param_types[] = { + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0), ++ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, OSSL_PARAM_INTEGER, NULL, 0), /* Ignored in RHEL */ + OSSL_PARAM_END + }; + +@@ -119,9 +126,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) + * NOTE: inside core_get_params() these will be loaded from config items + * stored inside prov->parameters (except for + * OSSL_PROV_PARAM_CORE_MODULE_FILENAME). +- * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS is not a self test parameter. ++ * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and ++ * OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters. + */ +- OSSL_PARAM core_params[8], *p = core_params; ++ OSSL_PARAM core_params[9], *p = core_params; + + *p++ = OSSL_PARAM_construct_utf8_ptr( + OSSL_PROV_PARAM_CORE_MODULE_FILENAME, +@@ -151,6 +159,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) + OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, + (char **)&fgbl->fips_security_check_option, + sizeof(fgbl->fips_security_check_option)); ++ /* *p++ = OSSL_PARAM_construct_utf8_ptr( ++ OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK, ++ (char **)&fgbl->fips_tls1_prf_ems_check_option, ++ sizeof(fgbl->fips_tls1_prf_ems_check_option)); */ /* Ignored in RHEL */ + *p = OSSL_PARAM_construct_end(); + + if (!c_get_params(fgbl->handle, core_params)) { +@@ -187,6 +199,9 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[]) + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS); + if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_security_checks)) + return 0; ++ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK); ++ if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_tls1_prf_ems_check)) ++ return 0; + return 1; + } + +@@ -703,6 +718,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, + && strcmp(fgbl->fips_security_check_option, "0") == 0) + fgbl->fips_security_checks = 0; + ++ /* Enable the ems check. */ ++ fgbl->fips_tls1_prf_ems_check = 1; ++ + ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers); + + if (!SELF_TEST_post(&fgbl->selftest_params, 0)) { +@@ -898,6 +918,15 @@ int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx) + return fgbl->fips_security_checks; + } + ++int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx) ++{ ++ FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx, ++ OSSL_LIB_CTX_FIPS_PROV_INDEX, ++ &fips_prov_ossl_ctx_method); ++ ++ return fgbl->fips_tls1_prf_ems_check; ++} ++ + void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, + void **cbarg) + { +diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c +index 8a3807308408..2c2dbf31cc0b 100644 +--- a/providers/implementations/kdfs/tls1_prf.c ++++ b/providers/implementations/kdfs/tls1_prf.c +@@ -45,6 +45,13 @@ + * A(0) = seed + * A(i) = HMAC_(secret, A(i-1)) + */ ++ ++/* ++ * Low level APIs (such as DH) are deprecated for public use, but still ok for ++ * internal use. ++ */ ++#include "internal/deprecated.h" ++ + #include + #include + #include +@@ -60,6 +67,7 @@ + #include "prov/providercommon.h" + #include "prov/implementations.h" + #include "prov/provider_util.h" ++#include "prov/securitycheck.h" + #include "e_os.h" + + static OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new; +@@ -78,6 +86,8 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, + unsigned char *out, size_t olen); + + #define TLS1_PRF_MAXBUF 1024 ++#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" ++#define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + + /* TLS KDF kdf context structure */ + typedef struct { +@@ -160,6 +170,7 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) + { + TLS1_PRF *ctx = (TLS1_PRF *)vctx; ++ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); + + if (!ossl_prov_is_running() || !kdf_tls1_prf_set_ctx_params(ctx, params)) + return 0; +@@ -181,6 +192,21 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen, + ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + #endif /* defined(FIPS_MODULE) */ + ++ /* ++ * The seed buffer is prepended with a label. ++ * If EMS mode is enforced then the label "master secret" is not allowed, ++ * We do the check this way since the PRF is used for other purposes, as well ++ * as "extended master secret". ++ */ ++ if (ossl_tls1_prf_ems_check_enabled(libctx)) { ++ if (ctx->seedlen >= TLS_MD_MASTER_SECRET_CONST_SIZE ++ && memcmp(ctx->seed, TLS_MD_MASTER_SECRET_CONST, ++ TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) { ++ ERR_raise(ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED); ++ return 0; ++ } ++ } ++ + return tls1_prf_alg(ctx->P_hash, ctx->P_sha1, + ctx->sec, ctx->seclen, + ctx->seed, ctx->seedlen, +diff --git a/test/sslapitest.c b/test/sslapitest.c +index 3a8242d2d8c8..b0fbb504689e 100644 +--- a/test/sslapitest.c ++++ b/test/sslapitest.c +@@ -99,6 +99,7 @@ static char *tmpfilename = NULL; + static char *dhfile = NULL; + + static int is_fips = 0; ++static int fips_ems_check = 0; + + #define LOG_BUFFER_SIZE 2048 + static char server_log_buffer[LOG_BUFFER_SIZE + 1] = {0}; +@@ -796,7 +797,7 @@ static int test_no_ems(void) + { + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; +- int testresult = 0; ++ int testresult = 0, status; + + if (!create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS1_2_VERSION, +@@ -812,19 +813,25 @@ static int test_no_ems(void) + goto end; + } + +- if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) { +- printf("Creating SSL connection failed\n"); +- goto end; +- } +- +- if (SSL_get_extms_support(serverssl)) { +- printf("Server reports Extended Master Secret support\n"); +- goto end; +- } +- +- if (SSL_get_extms_support(clientssl)) { +- printf("Client reports Extended Master Secret support\n"); +- goto end; ++ status = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE); ++ if (fips_ems_check) { ++ if (status == 1) { ++ printf("When FIPS uses the EMS check a connection that doesnt use EMS should fail\n"); ++ goto end; ++ } ++ } else { ++ if (!status) { ++ printf("Creating SSL connection failed\n"); ++ goto end; ++ } ++ if (SSL_get_extms_support(serverssl)) { ++ printf("Server reports Extended Master Secret support\n"); ++ goto end; ++ } ++ if (SSL_get_extms_support(clientssl)) { ++ printf("Client reports Extended Master Secret support\n"); ++ goto end; ++ } + } + testresult = 1; + +@@ -10740,9 +10747,24 @@ int setup_tests(void) + && !TEST_false(OSSL_PROVIDER_available(libctx, "default"))) + return 0; + +- if (strcmp(modulename, "fips") == 0) ++ if (strcmp(modulename, "fips") == 0) { ++ OSSL_PROVIDER *prov = NULL; ++ OSSL_PARAM params[2]; ++ + is_fips = 1; + ++ prov = OSSL_PROVIDER_load(libctx, "fips"); ++ if (prov != NULL) { ++ /* Query the fips provider to check if the check ems option is enabled */ ++ params[0] = ++ OSSL_PARAM_construct_int(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, ++ &fips_ems_check); ++ params[1] = OSSL_PARAM_construct_end(); ++ OSSL_PROVIDER_get_params(prov, params); ++ OSSL_PROVIDER_unload(prov); ++ } ++ } ++ + /* + * We add, but don't load the test "tls-provider". We'll load it when we + * need it. +@@ -10816,6 +10838,12 @@ int setup_tests(void) + if (privkey8192 == NULL) + goto err; + ++ if (fips_ems_check) { ++#ifndef OPENSSL_NO_TLS1_2 ++ ADD_TEST(test_no_ems); ++#endif ++ return 1; ++ } + #if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) + # if !defined(OPENSSL_NO_TLS1_2) || !defined(OSSL_NO_USABLE_TLS1_3) + ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4); +diff -up openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt.xxx openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt +--- openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt.xxx 2023-04-17 13:04:21.078501747 +0200 ++++ openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt 2023-04-17 13:11:03.189059638 +0200 +@@ -13,6 +13,7 @@ + + Title = TLS12 PRF tests (from NIST test vectors) + ++Availablein = default + KDF = TLS1-PRF + Ctrl.digest = digest:SHA256 + Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc +@@ -21,6 +22,16 @@ Ctrl.client_random = hexseed:36c129d01a3 + Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce + Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf + ++Availablein = fips ++KDF = TLS1-PRF ++Ctrl.digest = digest:SHA256 ++Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc ++Ctrl.label = seed:master secret ++Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c ++Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce ++Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf ++Result = KDF_DERIVE_ERROR ++ + KDF = TLS1-PRF + Ctrl.digest = digest:SHA256 + Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf +diff -up openssl-3.0.7/ssl/t1_enc.c.noems openssl-3.0.7/ssl/t1_enc.c +--- openssl-3.0.7/ssl/t1_enc.c.noems 2023-05-05 11:15:57.934415272 +0200 ++++ openssl-3.0.7/ssl/t1_enc.c 2023-05-05 11:39:03.578163778 +0200 +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* seed1 through seed5 are concatenated */ + static int tls1_PRF(SSL *s, +@@ -75,8 +76,14 @@ static int tls1_PRF(SSL *s, + } + + err: +- if (fatal) +- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); ++ if (fatal) { ++ /* The calls to this function are local so it's safe to implement the check */ ++ if (FIPS_mode() && seed1_len >= TLS_MD_MASTER_SECRET_CONST_SIZE ++ && memcmp(seed1, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) ++ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_UNSUPPORTED); ++ else ++ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); ++ } + else + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + EVP_KDF_CTX_free(kctx); +diff -up openssl-3.0.7/ssl/statem/extensions_srvr.c.noems openssl-3.0.7/ssl/statem/extensions_srvr.c +--- openssl-3.0.7/ssl/statem/extensions_srvr.c.noems 2023-05-05 17:14:04.663800271 +0200 ++++ openssl-3.0.7/ssl/statem/extensions_srvr.c 2023-05-05 17:20:33.764599507 +0200 +@@ -11,6 +11,7 @@ + #include "../ssl_local.h" + #include "statem_local.h" + #include "internal/cryptlib.h" ++#include + + #define COOKIE_STATE_FORMAT_VERSION 1 + +@@ -1552,8 +1553,13 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s + EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) + { +- if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) ++ if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) { ++ if (FIPS_mode()) { ++ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_UNSUPPORTED); ++ return EXT_RETURN_FAIL; ++ } + return EXT_RETURN_NOT_SENT; ++ } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) + || !WPACKET_put_bytes_u16(pkt, 0)) { diff --git a/SOURCES/0115-CVE-2023-0464.patch b/SOURCES/0115-CVE-2023-0464.patch new file mode 100644 index 0000000..97f3b6d --- /dev/null +++ b/SOURCES/0115-CVE-2023-0464.patch @@ -0,0 +1,195 @@ +diff --git a/crypto/x509/pcy_local.h b/crypto/x509/pcy_local.h +index 18b53cc09e..cba107ca03 100644 +--- a/crypto/x509/pcy_local.h ++++ b/crypto/x509/pcy_local.h +@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st { + }; + + struct X509_POLICY_TREE_st { ++ /* The number of nodes in the tree */ ++ size_t node_count; ++ /* The maximum number of nodes in the tree */ ++ size_t node_maximum; ++ + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; +@@ -157,7 +162,8 @@ X509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree); ++ X509_POLICY_TREE *tree, ++ int extra_data); + void ossl_policy_node_free(X509_POLICY_NODE *node); + int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); +diff --git a/crypto/x509/pcy_node.c b/crypto/x509/pcy_node.c +index 9d9a7ea179..450f95a655 100644 +--- a/crypto/x509/pcy_node.c ++++ b/crypto/x509/pcy_node.c +@@ -59,10 +59,15 @@ X509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level, + X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, +- X509_POLICY_TREE *tree) ++ X509_POLICY_TREE *tree, ++ int extra_data) + { + X509_POLICY_NODE *node; + ++ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */ ++ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum) ++ return NULL; ++ + node = OPENSSL_zalloc(sizeof(*node)); + if (node == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); +@@ -70,7 +75,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + } + node->data = data; + node->parent = parent; +- if (level) { ++ if (level != NULL) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; +@@ -90,7 +95,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + } + } + +- if (tree) { ++ if (extra_data) { + if (tree->extra_data == NULL) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (tree->extra_data == NULL){ +@@ -103,6 +108,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level, + } + } + ++ tree->node_count++; + if (parent) + parent->nchild++; + +diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c +index fa45da5117..f953a05a41 100644 +--- a/crypto/x509/pcy_tree.c ++++ b/crypto/x509/pcy_tree.c +@@ -14,6 +14,17 @@ + + #include "pcy_local.h" + ++/* ++ * If the maximum number of nodes in the policy tree isn't defined, set it to ++ * a generous default of 1000 nodes. ++ * ++ * Defining this to be zero means unlimited policy tree growth which opens the ++ * door on CVE-2023-0464. ++ */ ++#ifndef OPENSSL_POLICY_TREE_NODES_MAX ++# define OPENSSL_POLICY_TREE_NODES_MAX 1000 ++#endif ++ + static void expected_print(BIO *channel, + X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, + int indent) +@@ -163,6 +174,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + return X509_PCY_TREE_INTERNAL; + } + ++ /* Limit the growth of the tree to mitigate CVE-2023-0464 */ ++ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX; ++ + /* + * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3. + * +@@ -180,7 +194,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + if ((data = ossl_policy_data_new(NULL, + OBJ_nid2obj(NID_any_policy), 0)) == NULL) + goto bad_tree; +- if (ossl_policy_level_add_node(level, data, NULL, tree) == NULL) { ++ if (ossl_policy_level_add_node(level, data, NULL, tree, 1) == NULL) { + ossl_policy_data_free(data); + goto bad_tree; + } +@@ -239,7 +253,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + * Return value: 1 on success, 0 otherwise + */ + static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, +- X509_POLICY_DATA *data) ++ X509_POLICY_DATA *data, ++ X509_POLICY_TREE *tree) + { + X509_POLICY_LEVEL *last = curr - 1; + int i, matched = 0; +@@ -249,13 +264,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (ossl_policy_node_match(last, node, data->valid_policy)) { +- if (ossl_policy_level_add_node(curr, data, node, NULL) == NULL) ++ if (ossl_policy_level_add_node(curr, data, node, tree, 0) == NULL) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { +- if (ossl_policy_level_add_node(curr, data, last->anyPolicy, NULL) == NULL) ++ if (ossl_policy_level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL) + return 0; + } + return 1; +@@ -268,7 +283,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + * Return value: 1 on success, 0 otherwise. + */ + static int tree_link_nodes(X509_POLICY_LEVEL *curr, +- const X509_POLICY_CACHE *cache) ++ const X509_POLICY_CACHE *cache, ++ X509_POLICY_TREE *tree) + { + int i; + +@@ -276,7 +292,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr, + X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i); + + /* Look for matching nodes in previous level */ +- if (!tree_link_matching_nodes(curr, data)) ++ if (!tree_link_matching_nodes(curr, data, tree)) + return 0; + } + return 1; +@@ -307,7 +323,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; +- if (ossl_policy_level_add_node(curr, data, node, tree) == NULL) { ++ if (ossl_policy_level_add_node(curr, data, node, tree, 1) == NULL) { + ossl_policy_data_free(data); + return 0; + } +@@ -370,7 +386,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr, + /* Finally add link to anyPolicy */ + if (last->anyPolicy && + ossl_policy_level_add_node(curr, cache->anyPolicy, +- last->anyPolicy, NULL) == NULL) ++ last->anyPolicy, tree, 0) == NULL) + return 0; + return 1; + } +@@ -553,7 +569,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; + node = ossl_policy_level_add_node(NULL, extra, anyPolicy->parent, +- tree); ++ tree, 1); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); +@@ -580,7 +596,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree) + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = ossl_policy_cache_set(curr->cert); +- if (!tree_link_nodes(curr, cache)) ++ if (!tree_link_nodes(curr, cache, tree)) + return X509_PCY_TREE_INTERNAL; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) diff --git a/SOURCES/0116-CVE-2023-0465.patch b/SOURCES/0116-CVE-2023-0465.patch new file mode 100644 index 0000000..3a9acb5 --- /dev/null +++ b/SOURCES/0116-CVE-2023-0465.patch @@ -0,0 +1,179 @@ +diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c +index 9384f1da9b..a0282c3ef1 100644 +--- a/crypto/x509/x509_vfy.c ++++ b/crypto/x509/x509_vfy.c +@@ -1654,15 +1654,23 @@ static int check_policy(X509_STORE_CTX *ctx) + goto memerr; + /* Invalid or inconsistent extensions */ + if (ret == X509_PCY_TREE_INVALID) { +- int i; ++ int i, cbcalled = 0; + + /* Locate certificates with bad extensions and notify callback. */ +- for (i = 1; i < sk_X509_num(ctx->chain); i++) { ++ for (i = 0; i < sk_X509_num(ctx->chain); i++) { + X509 *x = sk_X509_value(ctx->chain, i); + ++ if ((x->ex_flags & EXFLAG_INVALID_POLICY) != 0) ++ cbcalled = 1; + CB_FAIL_IF((x->ex_flags & EXFLAG_INVALID_POLICY) != 0, + ctx, x, i, X509_V_ERR_INVALID_POLICY_EXTENSION); + } ++ if (!cbcalled) { ++ /* Should not be able to get here */ ++ ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ /* The callback ignored the error so we return success */ + return 1; + } + if (ret == X509_PCY_TREE_FAILURE) { +diff --git a/test/certs/ca-pol-cert.pem b/test/certs/ca-pol-cert.pem +new file mode 100644 +index 0000000000..244af3292b +--- /dev/null ++++ b/test/certs/ca-pol-cert.pem +@@ -0,0 +1,19 @@ ++-----BEGIN CERTIFICATE----- ++MIIDFzCCAf+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 ++IENBMCAXDTIzMDMwODEyMjMxNloYDzIxMjMwMzA5MTIyMzE2WjANMQswCQYDVQQD ++DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd ++j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz ++n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W ++l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l ++YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc ++ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9 ++CLNNsUcCAwEAAaN7MHkwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYD ++VR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8GA1UdIwQYMBaAFI71Ja8em2uE ++PXyAmslTnE1y96NSMBkGA1UdIAQSMBAwDgYMKwYBBAGBgVy8+0cBMA0GCSqGSIb3 ++DQEBCwUAA4IBAQBbE+MO9mewWIUY2kt85yhl0oZtvVxbn9K2Hty59ItwJGRNfzx7 ++Ge7KgawkvNzMOXmj6qf8TpbJnf41ZLWdRyVZBVyIwrAKIVw1VxfGh8aEifHKN97H ++unZkBPcUkAhUJSiC1BOD/euaMYqOi8QwiI702Q6q1NBY1/UKnV/ZIBLecnqfj9vZ ++7T0wKxrwGYBztP4pNcxCmBoD9Dg+Dx3ZElo0WXyO4SOh/BgrsKJHKyhbuTpjrI/g ++DhcINRp6+lIzuFBtJ67+YXnAEspb3lKMk0YL/LXrCNF2scdmNfOPwHi+OKBqt69C ++9FJyWFEMxx2qm/ENE9sbOswgJRnKkaAqHBHx ++-----END CERTIFICATE----- +diff --git a/test/certs/ee-cert-policies-bad.pem b/test/certs/ee-cert-policies-bad.pem +new file mode 100644 +index 0000000000..0fcd6372b3 +--- /dev/null ++++ b/test/certs/ee-cert-policies-bad.pem +@@ -0,0 +1,20 @@ ++-----BEGIN CERTIFICATE----- ++MIIDTTCCAjWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg ++Fw0yMzAzMDgxMjIzMzJaGA8yMTIzMDMwOTEyMjMzMlowGTEXMBUGA1UEAwwOc2Vy ++dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY ++YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT ++5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l ++Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1 ++U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5 ++ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn ++iIQPYf55NB9KiR+3AgMBAAGjgakwgaYwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H ++mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC ++MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w ++bGUwKQYDVR0gBCIwIDAOBgwrBgEEAYGBXLz7RwEwDgYMKwYBBAGBgVy8+0cBMA0G ++CSqGSIb3DQEBCwUAA4IBAQArwtwNO++7kStcJeMg3ekz2D/m/8UEjTA1rknBjQiQ ++P0FK7tNeRqus9i8PxthNWk+biRayvDzaGIBV7igpDBPfXemDgmW9Adc4MKyiQDfs ++YfkHi3xJKvsK2fQmyCs2InVDaKpVAkNFcgAW8nSOhGliqIxLb0EOLoLNwaktou0N ++XQHmRzY8S7aIr8K9Qo9y/+MLar+PS4h8l6FkLLkTICiFzE4/wje5S3NckAnadRJa ++QpjwM2S6NuA+tYWuOcN//r7BSpW/AZKanYWPzHMrKlqCh+9o7sthPd72+hObG9kx ++wSGdzfStNK1I1zM5LiI08WtXCvR6AfLANTo2x1AYhSxF ++-----END CERTIFICATE----- +diff --git a/test/certs/ee-cert-policies.pem b/test/certs/ee-cert-policies.pem +new file mode 100644 +index 0000000000..2f06d7433f +--- /dev/null ++++ b/test/certs/ee-cert-policies.pem +@@ -0,0 +1,20 @@ ++-----BEGIN CERTIFICATE----- ++MIIDPTCCAiWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg ++Fw0yMzAzMDgxMjIzMjNaGA8yMTIzMDMwOTEyMjMyM1owGTEXMBUGA1UEAwwOc2Vy ++dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY ++YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT ++5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l ++Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1 ++U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5 ++ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn ++iIQPYf55NB9KiR+3AgMBAAGjgZkwgZYwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H ++mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC ++MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w ++bGUwGQYDVR0gBBIwEDAOBgwrBgEEAYGBXLz7RwEwDQYJKoZIhvcNAQELBQADggEB ++AGbWslmAAdMX3+5ChcnFrX+NqDGoyhb3PTgWdtlQB5qtWdIt4rSxN50OcQxFTX0D ++QOBabSzR0DDKrgfBe4waL19WsdEvR9GyO4M7ASze/A3IEZue9C9k0n7Vq8zDaAZl ++CiR/Zqo9nAOuhKHMgmC/NjUlX7STv5pJVgc4SH8VEKmSRZDmNihaOalUtK5X8/Oa ++dawKxsZcaP5IKnOEPPKjtVNJxBu5CXywJHsO0GcoDEnEx1/NLdFoJ6WFw8NuTyDK ++NGLq2MHEdyKaigHQlptEs9bXyu9McJjzbx0uXj3BenRULASreccFej0L1RU6jDlk ++D3brBn24UISaFRZoB7jsjok= ++-----END CERTIFICATE----- +diff --git a/test/certs/mkcert.sh b/test/certs/mkcert.sh +index c3f7ac14b5..a57d9f38dc 100755 +--- a/test/certs/mkcert.sh ++++ b/test/certs/mkcert.sh +@@ -119,11 +119,12 @@ genca() { + local OPTIND=1 + local purpose= + +- while getopts p: o ++ while getopts p:c: o + do + case $o in + p) purpose="$OPTARG";; +- *) echo "Usage: $0 genca [-p EKU] cn keyname certname cakeyname cacertname" >&2 ++ c) certpol="$OPTARG";; ++ *) echo "Usage: $0 genca [-p EKU][-c policyoid] cn keyname certname cakeyname cacertname" >&2 + return 1;; + esac + done +@@ -146,6 +147,10 @@ genca() { + if [ -n "$NC" ]; then + exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC") + fi ++ if [ -n "$certpol" ]; then ++ exts=$(printf "%s\ncertificatePolicies = %s\n" "$exts" "$certpol") ++ fi ++ + csr=$(req "$key" "CN = $cn") || return 1 + echo "$csr" | + cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \ +diff --git a/test/certs/setup.sh b/test/certs/setup.sh +index 2240cd9df0..76ceadc7d8 100755 +--- a/test/certs/setup.sh ++++ b/test/certs/setup.sh +@@ -440,3 +440,9 @@ OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genee ed448 \ + + # critical id-pkix-ocsp-no-check extension + ./mkcert.sh geneeextra server.example ee-key ee-cert-ocsp-nocheck ca-key ca-cert "1.3.6.1.5.5.7.48.1.5=critical,DER:05:00" ++ ++# certificatePolicies extension ++./mkcert.sh genca -c "1.3.6.1.4.1.16604.998855.1" "CA" ca-key ca-pol-cert root-key root-cert ++./mkcert.sh geneeextra server.example ee-key ee-cert-policies ca-key ca-cert "certificatePolicies=1.3.6.1.4.1.16604.998855.1" ++# We can create a cert with a duplicate policy oid - but its actually invalid! ++./mkcert.sh geneeextra server.example ee-key ee-cert-policies-bad ca-key ca-cert "certificatePolicies=1.3.6.1.4.1.16604.998855.1,1.3.6.1.4.1.16604.998855.1" +diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t +index 2a4c36e86d..818c9ac50d 100644 +--- a/test/recipes/25-test_verify.t ++++ b/test/recipes/25-test_verify.t +@@ -29,7 +29,7 @@ sub verify { + run(app([@args])); + } + +-plan tests => 163; ++plan tests => 165; + + # Canonical success + ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), +@@ -516,3 +516,14 @@ SKIP: { + ok(run(app([ qw(openssl verify -trusted), $rsapluscert_file, $cert_file ])), + 'Mixed key + cert file test'); + } ++ ++# Certificate Policies ++ok(verify("ee-cert-policies", "", ["root-cert"], ["ca-pol-cert"], ++ "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1", ++ "-explicit_policy"), ++ "Certificate policy"); ++ ++ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"], ++ "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1", ++ "-explicit_policy"), ++ "Bad certificate policy"); diff --git a/SOURCES/0117-CVE-2023-0466.patch b/SOURCES/0117-CVE-2023-0466.patch new file mode 100644 index 0000000..ef06edf --- /dev/null +++ b/SOURCES/0117-CVE-2023-0466.patch @@ -0,0 +1,27 @@ +diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod +index 75a1677022..43c1900bca 100644 +--- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod ++++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod +@@ -98,8 +98,9 @@ B. + X509_VERIFY_PARAM_set_time() sets the verification time in B to + B. Normally the current time is used. + +-X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled +-by default) and adds B to the acceptable policy set. ++X509_VERIFY_PARAM_add0_policy() adds B to the acceptable policy set. ++Contrary to preexisting documentation of this function it does not enable ++policy checking. + + X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled + by default) and sets the acceptable policy set to B. Any existing +@@ -400,6 +401,10 @@ The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i. + The X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), + and X509_VERIFY_PARAM_get1_ip_asc() functions were added in OpenSSL 3.0. + ++The function X509_VERIFY_PARAM_add0_policy() was historically documented as ++enabling policy checking however the implementation has never done this. ++The documentation was changed to align with the implementation. ++ + =head1 COPYRIGHT + + Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. diff --git a/SOURCES/0118-CVE-2023-1255.patch b/SOURCES/0118-CVE-2023-1255.patch new file mode 100644 index 0000000..91efb20 --- /dev/null +++ b/SOURCES/0118-CVE-2023-1255.patch @@ -0,0 +1,20 @@ +--- a/crypto/aes/asm/aesv8-armx.pl ++++ b/crypto/aes/asm/aesv8-armx.pl +@@ -3353,7 +3353,7 @@ $code.=<<___ if ($flavour =~ /64/); + .align 4 + .Lxts_dec_tail4x: + add $inp,$inp,#16 +- vld1.32 {$dat0},[$inp],#16 ++ tst $tailcnt,#0xf + veor $tmp1,$dat1,$tmp0 + vst1.8 {$tmp1},[$out],#16 + veor $tmp2,$dat2,$tmp2 +@@ -3362,6 +3362,8 @@ $code.=<<___ if ($flavour =~ /64/); + veor $tmp4,$dat4,$tmp4 + vst1.8 {$tmp3-$tmp4},[$out],#32 + ++ b.eq .Lxts_dec_abort ++ vld1.32 {$dat0},[$inp],#16 + b .Lxts_done + .align 4 + .Lxts_outer_dec_tail: diff --git a/SOURCES/0122-CVE-2023-2650.patch b/SOURCES/0122-CVE-2023-2650.patch new file mode 100644 index 0000000..ba56969 --- /dev/null +++ b/SOURCES/0122-CVE-2023-2650.patch @@ -0,0 +1,30 @@ +diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c +index 01cde00e98..c0e55197a0 100644 +--- a/crypto/objects/obj_dat.c ++++ b/crypto/objects/obj_dat.c +@@ -443,6 +443,25 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) + first = 1; + bl = NULL; + ++ /* ++ * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs: ++ * ++ * > 3.5. OBJECT IDENTIFIER values ++ * > ++ * > An OBJECT IDENTIFIER value is an ordered list of non-negative ++ * > numbers. For the SMIv2, each number in the list is referred to as a ++ * > sub-identifier, there are at most 128 sub-identifiers in a value, ++ * > and each sub-identifier has a maximum value of 2^32-1 (4294967295 ++ * > decimal). ++ * ++ * So a legitimate OID according to this RFC is at most (32 * 128 / 7), ++ * i.e. 586 bytes long. ++ * ++ * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5 ++ */ ++ if (len > 586) ++ goto err; ++ + while (len > 0) { + l = 0; + use_bn = 0; diff --git a/SOURCES/0123-ibmca-atexit-crash.patch b/SOURCES/0123-ibmca-atexit-crash.patch new file mode 100644 index 0000000..893e598 --- /dev/null +++ b/SOURCES/0123-ibmca-atexit-crash.patch @@ -0,0 +1,244 @@ +diff --git a/crypto/context.c b/crypto/context.c +index bdfc4d02a3f0..548665fba265 100644 +--- a/crypto/context.c ++++ b/crypto/context.c +@@ -15,6 +15,7 @@ + #include "internal/bio.h" + #include "internal/provider.h" + #include "crypto/ctype.h" ++#include "crypto/rand.h" + + # include + # include +@@ -271,6 +272,20 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx) + + return NULL; + } ++ ++void ossl_release_default_drbg_ctx(void) ++{ ++ int dynidx = default_context_int.dyn_indexes[OSSL_LIB_CTX_DRBG_INDEX]; ++ ++ /* early release of the DRBG in global default libctx, no locking */ ++ if (dynidx != -1) { ++ void *data; ++ ++ data = CRYPTO_get_ex_data(&default_context_int.data, dynidx); ++ ossl_rand_ctx_free(data); ++ CRYPTO_set_ex_data(&default_context_int.data, dynidx, NULL); ++ } ++} + #endif + + OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx) +diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c +index c453d3226133..f341d915db76 100644 +--- a/crypto/rand/rand_lib.c ++++ b/crypto/rand/rand_lib.c +@@ -96,6 +96,7 @@ void ossl_rand_cleanup_int(void) + CRYPTO_THREAD_lock_free(rand_meth_lock); + rand_meth_lock = NULL; + # endif ++ ossl_release_default_drbg_ctx(); + rand_inited = 0; + } + +@@ -469,7 +470,7 @@ static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx) + return NULL; + } + +-static void rand_ossl_ctx_free(void *vdgbl) ++void ossl_rand_ctx_free(void *vdgbl) + { + RAND_GLOBAL *dgbl = vdgbl; + +@@ -494,7 +495,7 @@ static void rand_ossl_ctx_free(void *vdgbl) + static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = { + OSSL_LIB_CTX_METHOD_PRIORITY_2, + rand_ossl_ctx_new, +- rand_ossl_ctx_free, ++ ossl_rand_ctx_free, + }; + + static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) +diff --git a/engines/e_dasync.c b/engines/e_dasync.c +index 5a303a9f8528..7974106ae219 100644 +--- a/engines/e_dasync.c ++++ b/engines/e_dasync.c +@@ -139,6 +139,14 @@ static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx); + ++static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, ++ void *ptr); ++static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc); ++static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl); ++static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx); ++ + static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, + int arg, void *ptr); + static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, +@@ -171,6 +179,12 @@ static const EVP_CIPHER *dasync_aes_128_cbc(void) + return _hidden_aes_128_cbc; + } + ++static EVP_CIPHER *_hidden_aes_256_ctr = NULL; ++static const EVP_CIPHER *dasync_aes_256_ctr(void) ++{ ++ return _hidden_aes_256_ctr; ++} ++ + /* + * Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up + * once only during engine bind and can then be reused many times. +@@ -192,8 +206,10 @@ static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void) + static void destroy_ciphers(void) + { + EVP_CIPHER_meth_free(_hidden_aes_128_cbc); ++ EVP_CIPHER_meth_free(_hidden_aes_256_ctr); + EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1); + _hidden_aes_128_cbc = NULL; ++ _hidden_aes_256_ctr = NULL; + _hidden_aes_128_cbc_hmac_sha1 = NULL; + } + +@@ -202,6 +218,7 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + + static int dasync_cipher_nids[] = { + NID_aes_128_cbc, ++ NID_aes_256_ctr, + NID_aes_128_cbc_hmac_sha1, + 0 + }; +@@ -284,6 +301,30 @@ static int bind_dasync(ENGINE *e) + _hidden_aes_128_cbc = NULL; + } + ++ _hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr, ++ 1 /* block size */, ++ 32 /* key len */); ++ if (_hidden_aes_256_ctr == NULL ++ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr,16) ++ || !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr, ++ EVP_CIPH_FLAG_DEFAULT_ASN1 ++ | EVP_CIPH_CTR_MODE ++ | EVP_CIPH_FLAG_PIPELINE ++ | EVP_CIPH_CUSTOM_COPY) ++ || !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr, ++ dasync_aes256_init_key) ++ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_cipher) ++ || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_cleanup) ++ || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr, ++ dasync_aes256_ctr_ctrl) ++ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr, ++ sizeof(struct dasync_pipeline_ctx))) { ++ EVP_CIPHER_meth_free(_hidden_aes_256_ctr); ++ _hidden_aes_256_ctr = NULL; ++ } ++ + _hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new( + NID_aes_128_cbc_hmac_sha1, + 16 /* block size */, +@@ -445,6 +486,9 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + case NID_aes_128_cbc: + *cipher = dasync_aes_128_cbc(); + break; ++ case NID_aes_256_ctr: ++ *cipher = dasync_aes_256_ctr(); ++ break; + case NID_aes_128_cbc_hmac_sha1: + *cipher = dasync_aes_128_cbc_hmac_sha1(); + break; +@@ -779,6 +823,29 @@ static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx) + return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc()); + } + ++static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, ++ void *ptr) ++{ ++ return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc) ++{ ++ return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl) ++{ ++ return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr()); ++} ++ ++static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx) ++{ ++ return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr()); ++} ++ + + /* + * AES128 CBC HMAC SHA1 Implementation +diff --git a/include/crypto/rand.h b/include/crypto/rand.h +index 6a71a339c812..165deaf95c5e 100644 +--- a/include/crypto/rand.h ++++ b/include/crypto/rand.h +@@ -125,4 +125,5 @@ void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle, + size_t ossl_pool_acquire_entropy(RAND_POOL *pool); + int ossl_pool_add_nonce_data(RAND_POOL *pool); + ++void ossl_rand_ctx_free(void *vdgbl); + #endif +diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h +index 1291299b6e50..934d4b089c20 100644 +--- a/include/internal/cryptlib.h ++++ b/include/internal/cryptlib.h +@@ -199,6 +199,8 @@ int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn); + const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx); + ++void ossl_release_default_drbg_ctx(void); ++ + OSSL_LIB_CTX *ossl_crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad); + int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, + CRYPTO_EX_DATA *ad); +diff --git a/test/recipes/05-test_rand.t b/test/recipes/05-test_rand.t +index 4da1e64cb6da..3f352db9df3a 100644 +--- a/test/recipes/05-test_rand.t ++++ b/test/recipes/05-test_rand.t +@@ -11,9 +11,30 @@ use warnings; + use OpenSSL::Test; + use OpenSSL::Test::Utils; + +-plan tests => 3; ++plan tests => 5; + setup("test_rand"); + + ok(run(test(["rand_test"]))); + ok(run(test(["drbgtest"]))); + ok(run(test(["rand_status_test"]))); ++ ++SKIP: { ++ skip "engine is not supported by this OpenSSL build", 2 ++ if disabled("engine") || disabled("dynamic-engine"); ++ ++ my $success; ++ my @randdata; ++ my $expected = '0102030405060708090a0b0c0d0e0f10'; ++ ++ @randdata = run(app(['openssl', 'rand', '-engine', 'ossltest', '-hex', '16' ]), ++ capture => 1, statusvar => \$success); ++ chomp(@randdata); ++ ok($success and $randdata[0] eq $expected, ++ "rand with ossltest: Check rand output is as expected"); ++ ++ @randdata = run(app(['openssl', 'rand', '-engine', 'dasync', '-hex', '16' ]), ++ capture => 1, statusvar => \$success); ++ chomp(@randdata); ++ ok($success and length($randdata[0]) == 32, ++ "rand with dasync: Check rand output is of expected length"); ++} diff --git a/SOURCES/1000-replace-upstream-references.patch b/SOURCES/1000-replace-upstream-references.patch new file mode 100644 index 0000000..9519cd7 --- /dev/null +++ b/SOURCES/1000-replace-upstream-references.patch @@ -0,0 +1,29 @@ +From a194940b0fc62054430ca36b2bcec473a56745a1 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 7 Jul 2022 08:53:21 -0700 +Subject: [PATCH] Replace upstream references + +Orabug: 34340177 + +Signed-off-by: Darren Archibald +Reviewed-by: Laurence Rochfort +--- + apps/fipsinstall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c +index e978057..67d6957 100644 +--- a/apps/fipsinstall.c ++++ b/apps/fipsinstall.c +@@ -311,7 +311,7 @@ int fipsinstall_main(int argc, char **argv) + EVP_MAC *mac = NULL; + CONF *conf = NULL; + +- BIO_printf(bio_err, "This command is not enabled in the Red Hat Enterprise Linux OpenSSL build, please consult Red Hat documentation to learn how to enable FIPS mode\n"); ++ BIO_printf(bio_err, "This command is not enabled in the Oracle Linux OpenSSL build, please consult Oracle Linux documentation to learn how to enable FIPS mode\n"); + return 1; + + if ((opts = sk_OPENSSL_STRING_new_null()) == NULL) +-- +2.27.0 + diff --git a/SPECS/openssl.spec b/SPECS/openssl.spec index 6499d56..da6bd5f 100644 --- a/SPECS/openssl.spec +++ b/SPECS/openssl.spec @@ -29,7 +29,7 @@ print(string.sub(hash, 0, 16)) Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 3.0.7 -Release: 6%{?dist} +Release: 16.0.1%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -131,13 +131,14 @@ Patch76: 0076-FIPS-140-3-DRBG.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2102542 Patch77: 0077-FIPS-140-3-zeroization.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2114772 -Patch78: 0078-Add-FIPS-indicator-parameter-to-HKDF.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2141695 +# https://bugzilla.redhat.com/show_bug.cgi?id=2160733 +# https://bugzilla.redhat.com/show_bug.cgi?id=2164763 +Patch78: 0078-KDF-Add-FIPS-indicators.patch #https://bugzilla.redhat.com/show_bug.cgi?id=2141748 Patch80: 0080-rand-Forbid-truncated-hashes-SHA-3-in-FIPS-prov.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2142131 Patch81: 0081-signature-Remove-X9.31-padding-from-FIPS-prov.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=2141695 -Patch82: 0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2136250 Patch83: 0083-hmac-Add-explicit-FIPS-indicator-for-key-length.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2137557 @@ -154,6 +155,8 @@ Patch90: 0090-signature-Clamp-PSS-salt-len-to-MD-len.patch Patch91: 0091-FIPS-RSA-encapsulate.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2142517 Patch92: 0092-provider-improvements.patch +# FIPS-95 +Patch93: 0093-DH-Disable-FIPS-186-4-type-parameters-in-FIPS-mode.patch # OpenSSL 3.0.8 CVEs Patch101: 0101-CVE-2022-4203-nc-match.patch @@ -164,6 +167,30 @@ Patch105: 0105-CVE-2023-0216-pkcs7-deref.patch Patch106: 0106-CVE-2023-0217-dsa.patch Patch107: 0107-CVE-2023-0286-X400.patch Patch108: 0108-CVE-2023-0401-pkcs7-md.patch +Patch1000: 1000-replace-upstream-references.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=2169314 +Patch109: 0109-fips-Zeroize-out-in-fips-selftest.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2168289 +Patch110: 0110-GCM-Implement-explicit-FIPS-indicator-for-IV-gen.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2175145 +Patch111: 0111-fips-Use-salt-16-bytes-in-PBKDF2-selftest.patch +Patch112: 0112-pbdkf2-Set-indicator-if-pkcs5-param-disabled-checks.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2179331 +Patch113: 0113-asymciphers-kem-Add-explicit-FIPS-indicator.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2157951 +Patch114: 0114-FIPS-enforce-EMS-support.patch + +# X.509 policies minor CVEs +Patch115: 0115-CVE-2023-0464.patch +Patch116: 0116-CVE-2023-0465.patch +Patch117: 0117-CVE-2023-0466.patch +# AES-XTS CVE +Patch118: 0118-CVE-2023-1255.patch +# ASN.1 OID parse CVE +Patch122: 0122-CVE-2023-2650.patch +# https://github.com/openssl/openssl/pull/19386 +Patch123: 0123-ibmca-atexit-crash.patch License: ASL 2.0 URL: http://www.openssl.org/ @@ -494,6 +521,82 @@ install -m644 %{SOURCE9} \ %ldconfig_scriptlets libs %changelog +* Wed Jun 21 2023 EL Errata - 3.0.7-16.0.1 +- Replace upstream references [Orabug: 34340177] + +* Wed May 31 2023 Dmitry Belyavskiy - 1:3.0.7-16 +- Fix possible DoS translating ASN.1 object identifiers + Resolves: CVE-2023-2650 +- Release the DRBG in global default libctx early + Resolves: rhbz#2211396 + +* Tue May 23 2023 Clemens Lang - 1:3.0.7-15.1 +- Re-enable DHX keys in FIPS mode, disable FIPS 186-4 parameter validation and generation in FIPS mode + Resolves: rhbz#2178030 + +* Fri May 05 2023 Dmitry Belyavskiy - 1:3.0.7-15 +- Enforce using EMS in FIPS mode - alerts tuning + Related: rhbz#2157951 + +* Fri Apr 21 2023 Dmitry Belyavskiy - 1:3.0.7-14 +- Input buffer over-read in AES-XTS implementation on 64 bit ARM + Resolves: rhbz#2188554 + +* Tue Apr 18 2023 Dmitry Belyavskiy - 1:3.0.7-13 +- Enforce using EMS in FIPS mode + Resolves: rhbz#2157951 +- Fix excessive resource usage in verifying X509 policy constraints + Resolves: rhbz#2186661 +- Fix invalid certificate policies in leaf certificates check + Resolves: rhbz#2187429 +- Certificate policy check not enabled + Resolves: rhbz#2187431 +- OpenSSL rsa_verify_recover key length checks in FIPS mode + Resolves: rhbz#2186819 + +* Fri Mar 24 2023 Clemens Lang - 1:3.0.7-12 +- Change explicit FIPS indicator for RSA decryption to unapproved + Resolves: rhbz#2179379 + +* Mon Mar 20 2023 Clemens Lang - 1:3.0.7-11 +- Add missing reference to patchfile to add explicit FIPS indicator to RSA + encryption and RSASVE and fix the gettable parameter list for the RSA + asymmetric cipher implementation. + Resolves: rhbz#2179379 + +* Fri Mar 17 2023 Clemens Lang - 1:3.0.7-10 +- Add explicit FIPS indicator to RSA encryption and RSASVE + Resolves: rhbz#2179379 + +* Thu Mar 16 2023 Clemens Lang - 1:3.0.7-9 +- Fix explicit FIPS indicator for X9.42 KDF when used with output lengths < 14 bytes + Resolves: rhbz#2175864 + +* Thu Mar 16 2023 Clemens Lang - 1:3.0.7-8 +- Fix Wpointer-sign compiler warning + Resolves: rhbz#2178034 + +* Tue Mar 14 2023 Clemens Lang - 1:3.0.7-7 +- Add explicit FIPS indicators to key derivation functions + Resolves: rhbz#2175860 rhbz#2175864 +- Zeroize FIPS module integrity check MAC after check + Resolves: rhbz#2175873 +- Add explicit FIPS indicator for IV generation in AES-GCM + Resolves: rhbz#2175868 +- Add explicit FIPS indicator for PBKDF2, use test vector with FIPS-compliant + salt in PBKDF2 FIPS self-test + Resolves: rhbz#2178137 +- Limit RSA_NO_PADDING for encryption and signature in FIPS mode + Resolves: rhbz#2178029 +- Pairwise consistency tests should use Digest+Sign/Verify + Resolves: rhbz#2178034 +- Forbid DHX keys import in FIPS mode + Resolves: rhbz#2178030 +- DH PCT should abort on failure + Resolves: rhbz#2178039 +- Increase RNG seeding buffer size to 32 + Related: rhbz#2168224 + * Wed Mar 08 2023 Dmitry Belyavskiy - 1:3.0.7-6 - Fixes RNG slowdown in FIPS mode Resolves: rhbz#2168224