isaacpittman-hitachi / rpms / openssl

Forked from rpms/openssl 2 years ago
Clone

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

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