From 105cc32a208cb3063869a71486c09ddd5b63c222 Mon Sep 17 00:00:00 2001 From: Clemens Lang Date: Thu, 17 Nov 2022 17:34:28 +0100 Subject: [PATCH] Add indicator for SP 800-108 KDFs w/short keys 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. This also modifies the previously applied HKDF indicator patch to use the same interface to query its FIPS indicator. This provides better consistency across the various KDFs with explicit indicators. Additionally, the new constants are clearly marked as being specific to Red Hat. Signed-off-by: Clemens Lang Resolves: rhbz#2144019 --- ...Add-FIPS-indicator-parameter-to-HKDF.patch | 63 ++++++++++------ ...plicit-FIPS-indicator-for-key-length.patch | 74 +++++++++++++++++++ openssl.spec | 4 + 3 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch diff --git a/0078-Add-FIPS-indicator-parameter-to-HKDF.patch b/0078-Add-FIPS-indicator-parameter-to-HKDF.patch index 31e3c7d..b54d0fa 100644 --- a/0078-Add-FIPS-indicator-parameter-to-HKDF.patch +++ b/0078-Add-FIPS-indicator-parameter-to-HKDF.patch @@ -1,50 +1,69 @@ -From c4b086fc4de06128695e1fe428f56d776d25e748 Mon Sep 17 00:00:00 2001 +From 0c4aaedf29a1ed1559762515bfeaa5923925e18f Mon Sep 17 00:00:00 2001 From: Clemens Lang Date: Thu, 11 Aug 2022 09:27:12 +0200 -Subject: [PATCH] Add FIPS indicator parameter to HKDF +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. -Related: rhbz#2114772 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 +++++++++++++++++++++++++++ - 3 files changed, 58 insertions(+) + 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..87786680d7 100644 +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_HKDF_REDHAT_FIPS_INDICATOR "hkdf-fips-indicator" ++#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..869f23d8fb 100644 +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_HKDF_FIPS_INDICATOR_UNDETERMINED 0 -+# define EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED 1 -+# define EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED 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..9d28d292d8 100644 +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[]) @@ -53,13 +72,13 @@ index afdb7138e1..9d28d292d8 100644 } + +#ifdef FIPS_MODULE -+ if ((p = OSSL_PARAM_locate(params, -+ OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR)) != NULL) { -+ int fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED; ++ 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_HKDF_FIPS_INDICATOR_NOT_APPROVED; ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + break; + case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: + { @@ -74,10 +93,10 @@ index afdb7138e1..9d28d292d8 100644 + * 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 == EVP_MD_get_size(md)) -+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED; ++ 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_HKDF_FIPS_INDICATOR_NOT_APPROVED; ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + } + break; + case EVP_KDF_HKDF_MODE_EXPAND_ONLY: @@ -92,9 +111,9 @@ index afdb7138e1..9d28d292d8 100644 + && 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_HKDF_FIPS_INDICATOR_APPROVED; ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED; + else -+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED; ++ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED; + break; + } + return OSSL_PARAM_set_int(p, fips_indicator); @@ -109,11 +128,11 @@ index afdb7138e1..9d28d292d8 100644 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_HKDF_REDHAT_FIPS_INDICATOR, NULL), ++ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL), +#endif /* defined(FIPS_MODULE) */ OSSL_PARAM_END }; return known_gettable_ctx_params; -- -2.37.1 +2.38.1 diff --git a/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch b/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch new file mode 100644 index 0000000..8542af9 --- /dev/null +++ b/0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch @@ -0,0 +1,74 @@ +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/openssl.spec b/openssl.spec index 407d938..4b2763e 100644 --- a/openssl.spec +++ b/openssl.spec @@ -168,6 +168,8 @@ Patch79: 0079-CVE-2022-3602.patch 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=2142121 Patch85: 0085-FIPS-RSA-disable-shake.patch #https://github.com/openssl/openssl/pull/17546 @@ -515,6 +517,8 @@ install -m644 %{SOURCE9} \ Resolves: rhbz#2144017 - Remove support for X9.31 signature padding in FIPS mode Resolves: rhbz#2144015 +- Add explicit indicator for SP 800-108 KDFs with short key lengths + Resolves: rhbz#2144019 * Tue Nov 01 2022 Dmitry Belyavskiy - 1:3.0.1-43 - CVE-2022-3602: X.509 Email Address Buffer Overflow