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. Such exceptions should not be allowed by the default FIPS crypto policy. Resolves: rhbz#2162461 Signed-off-by: Julien Rische <jrische@redhat.com>
This commit is contained in:
parent
12d175e299
commit
49e904cdde
165
0015-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
Normal file
165
0015-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
From 6aea69170c2064aaea73ad3283b6d7dd0cae47e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 19 Jan 2023 19:22:27 +0100
|
||||||
|
Subject: [PATCH] [downstream] Allow KRB5KDF, MD5, and MD4 in FIPS mode
|
||||||
|
|
||||||
|
OpenSSL's restrictions to use KRB5KDF, MD5, and MD4 in FIPS mode are
|
||||||
|
bypassed in case AES SHA-1 HMAC or RC4 encryption types are allowed by
|
||||||
|
the crypto policy.
|
||||||
|
---
|
||||||
|
.../crypto/openssl/hash_provider/hash_evp.c | 97 +++++++++++++++++--
|
||||||
|
src/lib/crypto/openssl/kdf.c | 2 +-
|
||||||
|
2 files changed, 89 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
index 11659908bb..eb2e693e9f 100644
|
||||||
|
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
@@ -44,6 +44,49 @@
|
||||||
|
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#include <openssl/provider.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#include <threads.h>
|
||||||
|
+
|
||||||
|
+typedef struct ossl_lib_md_context {
|
||||||
|
+ OSSL_LIB_CTX *libctx;
|
||||||
|
+ OSSL_PROVIDER *default_provider;
|
||||||
|
+ OSSL_PROVIDER *legacy_provider;
|
||||||
|
+} 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. */
|
||||||
|
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||||
|
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||||
|
+
|
||||||
|
+ if (!(ctx->default_provider && ctx->legacy_provider))
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+deinit_ossl_ctx(ossl_md_context_t *ctx)
|
||||||
|
+{
|
||||||
|
+ if (ctx->legacy_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||||
|
+
|
||||||
|
+ if (ctx->default_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->default_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,
|
||||||
|
krb5_data *output)
|
||||||
|
@@ -60,11 +103,6 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
if (ctx == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
- 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);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||||
|
for (i = 0; i < num_data; i++) {
|
||||||
|
if (!SIGN_IOV(&data[i]))
|
||||||
|
@@ -77,6 +115,43 @@ 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;
|
||||||
|
+ EVP_MD *md = NULL;
|
||||||
|
+
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ err = ENOMEM;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
|
||||||
|
+ if (!md) {
|
||||||
|
+ err = KRB5_CRYPTO_INTERNAL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = hash_evp(md, data, num_data, output);
|
||||||
|
+
|
||||||
|
+end:
|
||||||
|
+ if (md)
|
||||||
|
+ EVP_MD_free(md);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef K5_OPENSSL_MD4
|
||||||
|
@@ -88,7 +163,8 @@ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||||
|
@@ -100,9 +176,12 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||||
|
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);
|
||||||
|
+ /*
|
||||||
|
+ * 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md5 = {
|
||||||
|
diff --git a/src/lib/crypto/openssl/kdf.c b/src/lib/crypto/openssl/kdf.c
|
||||||
|
index 5a43c3d9eb..8528ddc4a9 100644
|
||||||
|
--- a/src/lib/crypto/openssl/kdf.c
|
||||||
|
+++ b/src/lib/crypto/openssl/kdf.c
|
||||||
|
@@ -198,7 +198,7 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
|
||||||
|
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;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -34,7 +34,7 @@
|
|||||||
#
|
#
|
||||||
# baserelease is what we have standardized across Fedora and what
|
# baserelease is what we have standardized across Fedora and what
|
||||||
# rpmdev-bumpspec knows how to handle.
|
# rpmdev-bumpspec knows how to handle.
|
||||||
%global baserelease 4
|
%global baserelease 5
|
||||||
|
|
||||||
# This should be e.g. beta1 or %%nil
|
# This should be e.g. beta1 or %%nil
|
||||||
%global pre_release %nil
|
%global pre_release %nil
|
||||||
@ -97,6 +97,7 @@ Patch11: 0011-downstream-Catch-SHA-1-digest-disallowed-error-for-P.patch
|
|||||||
Patch12: 0012-Add-and-use-ts_interval-helper.patch
|
Patch12: 0012-Add-and-use-ts_interval-helper.patch
|
||||||
Patch13: 0013-downstream-Make-tests-compatible-with-sssd_krb5_loca.patch
|
Patch13: 0013-downstream-Make-tests-compatible-with-sssd_krb5_loca.patch
|
||||||
Patch14: 0014-downstream-Do-not-set-root-as-ksu-file-owner.patch
|
Patch14: 0014-downstream-Do-not-set-root-as-ksu-file-owner.patch
|
||||||
|
Patch15: 0015-downstream-Allow-KRB5KDF-MD5-and-MD4-in-FIPS-mode.patch
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://web.mit.edu/kerberos/www/
|
URL: https://web.mit.edu/kerberos/www/
|
||||||
@ -661,6 +662,10 @@ exit 0
|
|||||||
%{_libdir}/libkadm5srv_mit.so.*
|
%{_libdir}/libkadm5srv_mit.so.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jan 19 2023 Julien Rische <jrische@redhat.com> - 1.20.1-5
|
||||||
|
- 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
|
||||||
|
|
||||||
* Thu Jan 12 2023 Julien Rische <jrische@redhat.com> - 1.20.1-4
|
* Thu Jan 12 2023 Julien Rische <jrische@redhat.com> - 1.20.1-4
|
||||||
- Set aes256-cts-hmac-sha384-192 as EXAMLE.COM master key in kdc.conf
|
- Set aes256-cts-hmac-sha384-192 as EXAMLE.COM master key in kdc.conf
|
||||||
- Add AES SHA-2 HMAC family as EXAMPLE.COM supported etypes in kdc.conf
|
- Add AES SHA-2 HMAC family as EXAMPLE.COM supported etypes in kdc.conf
|
||||||
|
Loading…
Reference in New Issue
Block a user