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 <jrische@redhat.com>
This commit is contained in:
Julien Rische 2022-02-28 11:15:43 +01:00
parent 859e264a8c
commit d5c38cc27b
3 changed files with 125 additions and 34 deletions

View File

@ -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 KRB5KDF (3des and aes-sha1). We already use OpenSSL's PBKDF2 where
appropriate. OpenSSL added support for these KDFs in 3.0. 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) (cherry picked from commit ef8d11f6fb1232201c9efd2ae2ed567023fb85d2)
[rharwood@redhat.com: 3des removal] [rharwood@redhat.com: 3des removal]
--- ---
@ -201,7 +204,7 @@ index 6707a7308..8e474b38e 100644
+ goto done; + goto done;
+ } + }
+ +
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); + kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
+ if (kdf == NULL) { + if (kdf == NULL) {
+ ret = KRB5_CRYPTO_INTERNAL; + ret = KRB5_CRYPTO_INTERNAL;
+ goto done; + goto done;

View File

@ -1,6 +1,6 @@
From d2b050a5acfacd8d400560ae097f6d5f392d7398 Mon Sep 17 00:00:00 2001 From a7318c3cd6e1f58adb80493c05b59e6c180cd584 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com> From: Julien Rische <jrische@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500 Date: Wed, 23 Feb 2022 17:34:33 +0100
Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4 Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4
NB: Use openssl's PRNG in FIPS mode and taint within krad. 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. 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 +++ doc/admin/conf_files/krb5_conf.rst | 6 ++
src/lib/crypto/krb/prng.c | 11 ++++- src/lib/crypto/krb/prng.c | 11 ++-
.../crypto/openssl/enc_provider/camellia.c | 6 +++ .../crypto/openssl/enc_provider/camellia.c | 6 ++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++- src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++-
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++ .../crypto/openssl/hash_provider/hash_evp.c | 85 ++++++++++++++++++-
src/lib/crypto/openssl/hmac.c | 6 ++- src/lib/crypto/openssl/hmac.c | 6 +-
src/lib/krad/attr.c | 46 ++++++++++++++----- src/lib/krad/attr.c | 46 ++++++++---
src/lib/krad/attrset.c | 5 +- src/lib/krad/attrset.c | 5 +-
src/lib/krad/internal.h | 28 ++++++++++- src/lib/krad/internal.h | 28 ++++++-
src/lib/krad/packet.c | 22 +++++---- src/lib/krad/packet.c | 22 +++---
src/lib/krad/remote.c | 10 +++- src/lib/krad/remote.c | 10 ++-
src/lib/krad/t_attr.c | 3 +- src/lib/krad/t_attr.c | 3 +-
src/lib/krad/t_attrset.c | 4 +- src/lib/krad/t_attrset.c | 4 +-
src/plugins/preauth/spake/spake_client.c | 6 +++ src/plugins/preauth/spake/spake_client.c | 6 ++
src/plugins/preauth/spake/spake_kdc.c | 6 +++ src/plugins/preauth/spake/spake_kdc.c | 6 ++
15 files changed, 151 insertions(+), 33 deletions(-) 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 diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 675175955..adba8238d 100644 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 * 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 * 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 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 --- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/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, @@ -32,6 +32,50 @@
if (ctx == NULL)
return ENOMEM;
+ if (type == EVP_md4() || type == EVP_md5()) { #include "crypto_int.h"
+ /* See comments below in hash_md4() and hash_md5(). */ #include <openssl/evp.h>
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); +#include <openssl/provider.h>
+#include <threads.h>
+
+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); + err = hash_evp(ossl_md_ctx->md, data, num_data, output);
for (i = 0; i < num_data; i++) { +
if (!SIGN_IOV(&data[i])) +end:
@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, + return err;
+}
+
static krb5_error_code static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) 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 + * 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 + * by IPA. These keys are only used along a (separately) secured channel
+ * for legacy reasons when performing trusts to Active Directory. + * 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 static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) 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 - return hash_evp(EVP_md5(), data, num_data, output);
+ * is gated in libkrad by libdefaults->radius_md5_fips_override. */ + /*
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 diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index 7dc59dcc0..769a50c00 100644 index 7dc59dcc0..769a50c00 100644
--- a/src/lib/crypto/openssl/hmac.c --- a/src/lib/crypto/openssl/hmac.c

View File

@ -42,7 +42,7 @@
Summary: The Kerberos network authentication system Summary: The Kerberos network authentication system
Name: krb5 Name: krb5
Version: 1.19.1 Version: 1.19.1
Release: %{?zdpd}13%{?dist} Release: %{?zdpd}14%{?dist}
# rharwood has trust path to signing key and verifies on check-in # 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 Source0: https://web.mit.edu/kerberos/dist/krb5/%{version}/krb5-%{version}%{?dashpre}.tar.gz
@ -646,6 +646,10 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.* %{_libdir}/libkadm5srv_mit.so.*
%changelog %changelog
* Thu Feb 24 2022 Julien Rische <jrische@redhat.com> - 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 <antorres@redhat.com> - 1.19.1-13 * Fri Dec 17 2021 Antonio Torres <antorres@redhat.com> - 1.19.1-13
- Remove -specs= from krb5-config output - Remove -specs= from krb5-config output
- Resolves #1997021 - Resolves #1997021