From d5c38cc27b356822c57e317a03bfd047f60ba43a Mon Sep 17 00:00:00 2001 From: Julien Rische Date: Mon, 28 Feb 2022 11:15:43 +0100 Subject: [PATCH] Do not block KRB5KDF and MD4/5 in FIPS mode Bypass OpenSSL's restrictions to use KRB5KDF in FIPS mode in case at least one of AES SHA-1 HMAC encryption types are used. Use OpenSSL 3.0 library context to access MD4 and MD5 lazily from legacy provider if RADIUS is being used or RC4 encryption type is enabled, without affecting global context. Remove EVP_MD_CTX_FLAG_NON_FIPS_ALLOW flag since does not have any effect anymore. Such exceptions should not be allowed by the default FIPS crypto policy. Resolves: rhbz#2039684 Resolves: rhbz#2053135 Signed-off-by: Julien Rische --- ...KDF-and-KRB5KDF-for-deriving-long-te.patch | 5 +- ...am-FIPS-with-PRNG-and-RADIUS-and-MD4.patch | 148 ++++++++++++++---- krb5.spec | 6 +- 3 files changed, 125 insertions(+), 34 deletions(-) diff --git a/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch b/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch index 927b506..12b4967 100644 --- a/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch +++ b/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch @@ -7,6 +7,9 @@ If supported, use OpenSSL-provided KBKDF (aes-sha2 and camellia) and KRB5KDF (3des and aes-sha1). We already use OpenSSL's PBKDF2 where appropriate. OpenSSL added support for these KDFs in 3.0. +OpenSSL's restrictions to use KRB5KDF in FIPS mode are bypassed in case +AES SHA-1 HMAC encryption types are allowed by the crypto policy. + (cherry picked from commit ef8d11f6fb1232201c9efd2ae2ed567023fb85d2) [rharwood@redhat.com: 3des removal] --- @@ -201,7 +204,7 @@ index 6707a7308..8e474b38e 100644 + goto done; + } + -+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); ++ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips"); + if (kdf == NULL) { + ret = KRB5_CRYPTO_INTERNAL; + goto done; diff --git a/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch b/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch index 3de59f1..a1f5629 100644 --- a/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch +++ b/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch @@ -1,6 +1,6 @@ -From d2b050a5acfacd8d400560ae097f6d5f392d7398 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 9 Nov 2018 15:12:21 -0500 +From a7318c3cd6e1f58adb80493c05b59e6c180cd584 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Wed, 23 Feb 2022 17:34:33 +0100 Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4 NB: Use openssl's PRNG in FIPS mode and taint within krad. @@ -19,24 +19,33 @@ post6 restores MD4 (and therefore keygen-only RC4). post7 restores MD5 and adds radius_md5_fips_override. -Last-updated: krb5-1.17 +post8 restores MD4/MD5 for OpenSSL 3.0 + +Use OpenSSL 3.0 library context to access MD4 and MD5 lazily from +legacy provider if RC4 encryption type is enabled, without affecting +global context. + +Remove EVP_MD_CTX_FLAG_NON_FIPS_ALLOW flag since does not have any +effect anymore. + +Last-updated: krb5-1.19 --- - doc/admin/conf_files/krb5_conf.rst | 6 +++ - src/lib/crypto/krb/prng.c | 11 ++++- - .../crypto/openssl/enc_provider/camellia.c | 6 +++ - src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++- - .../crypto/openssl/hash_provider/hash_evp.c | 12 +++++ - src/lib/crypto/openssl/hmac.c | 6 ++- - src/lib/krad/attr.c | 46 ++++++++++++++----- + doc/admin/conf_files/krb5_conf.rst | 6 ++ + src/lib/crypto/krb/prng.c | 11 ++- + .../crypto/openssl/enc_provider/camellia.c | 6 ++ + src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++- + .../crypto/openssl/hash_provider/hash_evp.c | 85 ++++++++++++++++++- + src/lib/crypto/openssl/hmac.c | 6 +- + src/lib/krad/attr.c | 46 ++++++++--- src/lib/krad/attrset.c | 5 +- - src/lib/krad/internal.h | 28 ++++++++++- - src/lib/krad/packet.c | 22 +++++---- - src/lib/krad/remote.c | 10 +++- + src/lib/krad/internal.h | 28 ++++++- + src/lib/krad/packet.c | 22 +++--- + src/lib/krad/remote.c | 10 ++- src/lib/krad/t_attr.c | 3 +- src/lib/krad/t_attrset.c | 4 +- - src/plugins/preauth/spake/spake_client.c | 6 +++ - src/plugins/preauth/spake/spake_kdc.c | 6 +++ - 15 files changed, 151 insertions(+), 33 deletions(-) + src/plugins/preauth/spake/spake_client.c | 6 ++ + src/plugins/preauth/spake/spake_kdc.c | 6 ++ + 15 files changed, 218 insertions(+), 35 deletions(-) diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst index 675175955..adba8238d 100644 @@ -149,41 +158,116 @@ index bc87c6f42..9bf407899 100644 * The cipher state here is a saved pointer to a struct arcfour_state * object, rather than a flat byte array as in most enc providers. The diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c -index 1e0fb8fc3..2eb5139c0 100644 +index 1e0fb8fc3..4b8e1a6b2 100644 --- a/src/lib/crypto/openssl/hash_provider/hash_evp.c +++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c -@@ -49,6 +49,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, - if (ctx == NULL) - return ENOMEM; +@@ -32,6 +32,50 @@ -+ if (type == EVP_md4() || type == EVP_md5()) { -+ /* See comments below in hash_md4() and hash_md5(). */ -+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + #include "crypto_int.h" + #include ++#include ++#include ++ ++typedef struct ossl_lib_md_context { ++ OSSL_LIB_CTX *libctx; ++ OSSL_PROVIDER *legacy_provider; ++ EVP_MD *md; ++} ossl_md_context_t; ++ ++static thread_local ossl_md_context_t *ossl_md_ctx = NULL; ++ ++static krb5_error_code ++init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo) ++{ ++ ctx->libctx = OSSL_LIB_CTX_new(); ++ if (!ctx->libctx) ++ return KRB5_CRYPTO_INTERNAL; ++ ++ /* ++ * Load both legacy and default provider as both may be needed. ++ * If they fail keep going and an error will be raised when we try to ++ * fetch the cipher later. ++ */ ++ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy"); ++ ++ ctx->md = EVP_MD_fetch(ctx->libctx, algo, NULL); ++ if (!ctx->md) ++ return KRB5_CRYPTO_INTERNAL; ++ ++ return 0; ++} ++ ++static void ++deinit_ossl_ctx(ossl_md_context_t *ctx) ++{ ++ if (ctx->md) ++ EVP_MD_free(ctx->md); ++ ++ if (ctx->legacy_provider) ++ OSSL_PROVIDER_unload(ctx->legacy_provider); ++ ++ if (ctx->libctx) ++ OSSL_LIB_CTX_free(ctx->libctx); ++} + + static krb5_error_code + hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, +@@ -61,16 +104,53 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, + return ok ? 0 : KRB5_CRYPTO_INTERNAL; + } + ++static krb5_error_code ++hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data, ++ krb5_data *output) ++{ ++ krb5_error_code err; ++ ++ if (!ossl_md_ctx) { ++ ossl_md_ctx = malloc(sizeof(ossl_md_context_t)); ++ if (!ossl_md_ctx) ++ return ENOMEM; ++ ++ err = init_ossl_md_ctx(ossl_md_ctx, algo); ++ if (err) { ++ deinit_ossl_ctx(ossl_md_ctx); ++ free(ossl_md_ctx); ++ ossl_md_ctx = NULL; ++ goto end; ++ } + } + - ok = EVP_DigestInit_ex(ctx, type, NULL); - for (i = 0; i < num_data; i++) { - if (!SIGN_IOV(&data[i])) -@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, ++ err = hash_evp(ossl_md_ctx->md, data, num_data, output); ++ ++end: ++ return err; ++} ++ static krb5_error_code hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { +- return hash_evp(EVP_md4(), data, num_data, output); + /* + * MD4 is needed in FIPS mode to perform key generation for RC4 keys used + * by IPA. These keys are only used along a (separately) secured channel + * for legacy reasons when performing trusts to Active Directory. + */ - return hash_evp(EVP_md4(), data, num_data, output); ++ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output) ++ : hash_evp(EVP_md4(), data, num_data, output); } static krb5_error_code hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { -+ /* MD5 is needed in FIPS mode for communication with RADIUS servers. This -+ * is gated in libkrad by libdefaults->radius_md5_fips_override. */ - return hash_evp(EVP_md5(), data, num_data, output); +- return hash_evp(EVP_md5(), data, num_data, output); ++ /* ++ * MD5 is needed in FIPS mode for communication with RADIUS servers. This ++ * is gated in libkrad by libdefaults->radius_md5_fips_override. ++ */ ++ return FIPS_mode() ? hash_legacy_evp("MD5", data, num_data, output) ++ : hash_evp(EVP_md5(), data, num_data, output); } + static krb5_error_code diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c index 7dc59dcc0..769a50c00 100644 --- a/src/lib/crypto/openssl/hmac.c diff --git a/krb5.spec b/krb5.spec index 277654d..91f9b67 100644 --- a/krb5.spec +++ b/krb5.spec @@ -42,7 +42,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.19.1 -Release: %{?zdpd}13%{?dist} +Release: %{?zdpd}14%{?dist} # rharwood has trust path to signing key and verifies on check-in Source0: https://web.mit.edu/kerberos/dist/krb5/%{version}/krb5-%{version}%{?dashpre}.tar.gz @@ -646,6 +646,10 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Thu Feb 24 2022 Julien Rische - 1.19.1-14 +- Bypass FIPS restrictions to use KRB5KDF in case AES SHA-1 HMAC is enabled +- Lazily load MD4/5 from OpenSSL if using RADIUS or RC4 enctype in FIPS mode + * Fri Dec 17 2021 Antonio Torres - 1.19.1-13 - Remove -specs= from krb5-config output - Resolves #1997021