diff --git a/SOURCES/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch b/SOURCES/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch index 927b506..12b4967 100644 --- a/SOURCES/Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch +++ b/SOURCES/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/SOURCES/Use-SHA256-instead-of-SHA1-for-PKINIT-CMS-digest.patch b/SOURCES/Use-SHA256-instead-of-SHA1-for-PKINIT-CMS-digest.patch new file mode 100644 index 0000000..170d58d --- /dev/null +++ b/SOURCES/Use-SHA256-instead-of-SHA1-for-PKINIT-CMS-digest.patch @@ -0,0 +1,113 @@ +From f0740c131b69f3346f07e7b7b03ebf27c50c0ccd Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Fri, 11 Mar 2022 11:33:56 +0100 +Subject: [PATCH] Use SHA-256 instead of SHA-1 for PKINIT CMS digest + +Various organizations including NIST have been strongly recommending to +stop using SHA-1 for digital signatures for some years already. CMS +digest is used to generate such signatures, hence it should be upgraded +to use SHA-256. +--- + .../preauth/pkinit/pkinit_crypto_openssl.c | 27 ++++++++++--------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 42e5c581d..2a6ef4aaa 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -1240,7 +1240,7 @@ cms_signeddata_create(krb5_context context, + /* will not fill-out EVP_PKEY because it's on the smartcard */ + + /* Set digest algs */ +- p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1); ++ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha256); + + if (p7si->digest_alg->parameter != NULL) + ASN1_TYPE_free(p7si->digest_alg->parameter); +@@ -1251,17 +1251,17 @@ cms_signeddata_create(krb5_context context, + /* Set sig algs */ + if (p7si->digest_enc_alg->parameter != NULL) + ASN1_TYPE_free(p7si->digest_enc_alg->parameter); +- p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption); ++ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption); + if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new())) + goto cleanup; + p7si->digest_enc_alg->parameter->type = V_ASN1_NULL; + + /* add signed attributes */ +- /* compute sha1 digest over the EncapsulatedContentInfo */ ++ /* compute sha256 digest over the EncapsulatedContentInfo */ + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + goto cleanup; +- EVP_DigestInit_ex(ctx, EVP_sha1(), NULL); ++ EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); + EVP_DigestUpdate(ctx, data, data_len); + md_tmp = EVP_MD_CTX_md(ctx); + EVP_DigestFinal_ex(ctx, md_data, &md_len); +@@ -1289,9 +1289,10 @@ cms_signeddata_create(krb5_context context, + goto cleanup2; + + #ifndef WITHOUT_PKCS11 +- /* Some tokens can only do RSAEncryption without sha1 hash */ +- /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash +- * function and the hash value into an ASN.1 value of type DigestInfo ++ /* Some tokens can only do RSAEncryption without sha256 hash */ ++ /* to compute sha256WithRSAEncryption, encode the algorithm ID for the ++ * hash function and the hash value into an ASN.1 value of type ++ * DigestInfo + * DigestInfo::=SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING } +@@ -1310,7 +1311,7 @@ cms_signeddata_create(krb5_context context, + alg = X509_ALGOR_new(); + if (alg == NULL) + goto cleanup2; +- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha1), V_ASN1_NULL, NULL); ++ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha256), V_ASN1_NULL, NULL); + alg_len = i2d_X509_ALGOR(alg, NULL); + + digest = ASN1_OCTET_STRING_new(); +@@ -1339,7 +1340,7 @@ cms_signeddata_create(krb5_context context, + #endif + { + pkiDebug("mech = %s\n", +- id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS"); ++ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA256_RSA_PKCS" : "FS"); + retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen, + &sig, &sig_len); + } +@@ -4189,7 +4190,7 @@ create_signature(unsigned char **sig, unsigned int *sig_len, + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) + return ENOMEM; +- EVP_SignInit(ctx, EVP_sha1()); ++ EVP_SignInit(ctx, EVP_sha256()); + EVP_SignUpdate(ctx, data, data_len); + *sig_len = EVP_PKEY_size(pkey); + if ((*sig = malloc(*sig_len)) == NULL) +@@ -4663,10 +4664,10 @@ pkinit_get_certs_pkcs11(krb5_context context, + + #ifndef PKINIT_USE_MECH_LIST + /* +- * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but ++ * We'd like to use CKM_SHA256_RSA_PKCS for signing if it's available, but + * many cards seems to be confused about whether they are capable of + * this or not. The safe thing seems to be to ignore the mechanism list, +- * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves. ++ * always use CKM_RSA_PKCS and calculate the sha256 digest ourselves. + */ + + id_cryptoctx->mech = CKM_RSA_PKCS; +@@ -4694,7 +4695,7 @@ pkinit_get_certs_pkcs11(krb5_context context, + if (mechp[i] == CKM_RSA_PKCS) { + /* This seems backwards... */ + id_cryptoctx->mech = +- (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS; ++ (info.flags & CKF_SIGN) ? CKM_SHA256_RSA_PKCS : CKM_RSA_PKCS; + } + } + free(mechp); +-- +2.35.1 + diff --git a/SOURCES/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch b/SOURCES/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch index 3de59f1..a1f5629 100644 --- a/SOURCES/downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch +++ b/SOURCES/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/SPECS/krb5.spec b/SPECS/krb5.spec index 277654d..7464cab 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -42,7 +42,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.19.1 -Release: %{?zdpd}13%{?dist} +Release: %{?zdpd}15%{?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 @@ -90,6 +90,7 @@ Patch25: Allow-kinit-with-keytab-to-defer-canonicalization.patch Patch26: Fix-kadmin-k-with-fallback-or-referral-realm.patch Patch27: Fix-KDC-null-deref-on-bad-encrypted-challenge.patch Patch28: Fix-KDC-null-deref-on-TGS-inner-body-null-server.patch +Patch29: Use-SHA256-instead-of-SHA1-for-PKINIT-CMS-digest.patch License: MIT URL: https://web.mit.edu/kerberos/www/ @@ -646,6 +647,13 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Mon Mar 14 2022 Julien Rische - 1.19.1-15 +- Use SHA-256 instead of SHA-1 for PKINIT CMS digest + +* 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