Blame SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch

727bdf
From c4b086fc4de06128695e1fe428f56d776d25e748 Mon Sep 17 00:00:00 2001
727bdf
From: Clemens Lang <cllang@redhat.com>
727bdf
Date: Thu, 11 Aug 2022 09:27:12 +0200
727bdf
Subject: [PATCH] Add FIPS indicator parameter to HKDF
727bdf
727bdf
NIST considers HKDF only acceptable when used as in TLS 1.3, and
727bdf
otherwise unapproved. Add an explicit indicator attached to the
727bdf
EVP_KDF_CTX that can be queried using EVP_KDF_CTX_get_params() to
727bdf
determine whether the KDF operation was approved after performing it.
727bdf
727bdf
Related: rhbz#2114772
727bdf
Signed-off-by: Clemens Lang <cllang@redhat.com>
727bdf
---
727bdf
 include/openssl/core_names.h          |  1 +
727bdf
 include/openssl/kdf.h                 |  4 ++
727bdf
 providers/implementations/kdfs/hkdf.c | 53 +++++++++++++++++++++++++++
727bdf
 3 files changed, 58 insertions(+)
727bdf
727bdf
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
727bdf
index 21c94d0488..87786680d7 100644
727bdf
--- a/include/openssl/core_names.h
727bdf
+++ b/include/openssl/core_names.h
727bdf
@@ -223,6 +223,7 @@ extern "C" {
727bdf
 #define OSSL_KDF_PARAM_X942_SUPP_PUBINFO    "supp-pubinfo"
727bdf
 #define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO   "supp-privinfo"
727bdf
 #define OSSL_KDF_PARAM_X942_USE_KEYBITS     "use-keybits"
727bdf
+#define OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR "hkdf-fips-indicator"
727bdf
 
727bdf
 /* Known KDF names */
727bdf
 #define OSSL_KDF_NAME_HKDF           "HKDF"
727bdf
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
727bdf
index 0983230a48..869f23d8fb 100644
727bdf
--- a/include/openssl/kdf.h
727bdf
+++ b/include/openssl/kdf.h
727bdf
@@ -63,6 +63,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf,
727bdf
 # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY        1
727bdf
 # define EVP_KDF_HKDF_MODE_EXPAND_ONLY         2
727bdf
 
727bdf
+# define EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED 0
727bdf
+# define EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED     1
727bdf
+# define EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED 2
727bdf
+
727bdf
 #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV     65
727bdf
 #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI     66
727bdf
 #define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67
727bdf
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
727bdf
index afdb7138e1..9d28d292d8 100644
727bdf
--- a/providers/implementations/kdfs/hkdf.c
727bdf
+++ b/providers/implementations/kdfs/hkdf.c
727bdf
@@ -298,6 +298,56 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
727bdf
             return 0;
727bdf
         return OSSL_PARAM_set_size_t(p, sz);
727bdf
     }
727bdf
+
727bdf
+#ifdef FIPS_MODULE
727bdf
+    if ((p = OSSL_PARAM_locate(params,
727bdf
+                OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR)) != NULL) {
727bdf
+        int fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED;
727bdf
+        switch (ctx->mode) {
727bdf
+        case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
727bdf
+            /* TLS 1.3 never uses extract-and-expand */
727bdf
+            fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
727bdf
+            break;
727bdf
+        case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
727bdf
+            {
727bdf
+                /* When TLS 1.3 uses extract, the following holds:
727bdf
+                 * 1. The salt length matches the hash length, and either
727bdf
+                 * 2.1. the key is all zeroes and matches the hash length, or
727bdf
+                 * 2.2. the key originates from a PSK (resumption_master_secret
727bdf
+                 *   or some externally esablished key), or an ECDH or DH key
727bdf
+                 *   derivation. See
727bdf
+                 *   https://www.rfc-editor.org/rfc/rfc8446#section-7.1.
727bdf
+                 * Unfortunately at this point, we cannot verify where the key
727bdf
+                 * comes from, so all we can do is check the salt length.
727bdf
+                 */
727bdf
+                const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
727bdf
+                if (md != NULL && ctx->salt_len == EVP_MD_get_size(md))
727bdf
+                    fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
727bdf
+                else
727bdf
+                    fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
727bdf
+            }
727bdf
+            break;
727bdf
+        case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
727bdf
+            /* When TLS 1.3 uses expand, it always provides a label that
727bdf
+             * contains an uint16 for the length, followed by between 7 and 255
727bdf
+             * bytes for a label string that starts with "tls13 " or "dtls13".
727bdf
+             * For compatibility with future versions, we only check for "tls"
727bdf
+             * or "dtls". See
727bdf
+             * https://www.rfc-editor.org/rfc/rfc8446#section-7.1 and
727bdf
+             * https://www.rfc-editor.org/rfc/rfc9147#section-5.9. */
727bdf
+            if (ctx->label != NULL
727bdf
+                    && ctx->label_len >= 2 /* length */ + 4 /* "dtls" */
727bdf
+                    && (strncmp("tls", (const char *)ctx->label + 2, 3) == 0 ||
727bdf
+                        strncmp("dtls", (const char *)ctx->label + 2, 4) == 0))
727bdf
+                fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
727bdf
+            else
727bdf
+                fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
727bdf
+            break;
727bdf
+        }
727bdf
+        return OSSL_PARAM_set_int(p, fips_indicator);
727bdf
+    }
727bdf
+#endif /* defined(FIPS_MODULE) */
727bdf
+
727bdf
     return -2;
727bdf
 }
727bdf
 
727bdf
@@ -306,6 +356,9 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
727bdf
 {
727bdf
     static const OSSL_PARAM known_gettable_ctx_params[] = {
727bdf
         OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
727bdf
+#ifdef FIPS_MODULE
727bdf
+        OSSL_PARAM_int(OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR, NULL),
727bdf
+#endif /* defined(FIPS_MODULE) */
727bdf
         OSSL_PARAM_END
727bdf
     };
727bdf
     return known_gettable_ctx_params;
727bdf
-- 
727bdf
2.37.1
727bdf