2023-08-22 14:39:12 +00:00
|
|
|
From 2000eaead63732669283e6b54c8ef02e268eaeb8 Mon Sep 17 00:00:00 2001
|
|
|
|
From: rpm-build <rpm-build>
|
|
|
|
Date: Mon, 31 Jul 2023 09:41:29 +0200
|
|
|
|
Subject: [PATCH 34/48] 0078-Add-FIPS-indicator-parameter-to-HKDF.patch
|
2022-09-01 10:42:16 +00:00
|
|
|
|
2023-08-22 14:39:12 +00:00
|
|
|
Patch-name: 0078-Add-FIPS-indicator-parameter-to-HKDF.patch
|
|
|
|
Patch-id: 78
|
|
|
|
Patch-status: |
|
|
|
|
# https://bugzilla.redhat.com/show_bug.cgi?id=2114772
|
|
|
|
From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd
|
2022-09-01 10:42:16 +00:00
|
|
|
---
|
2023-08-22 14:39:12 +00:00
|
|
|
include/crypto/evp.h | 7 ++
|
|
|
|
include/openssl/core_names.h | 1 +
|
|
|
|
include/openssl/kdf.h | 4 +
|
|
|
|
providers/implementations/kdfs/hkdf.c | 100 +++++++++++++++++++++-
|
|
|
|
providers/implementations/kdfs/kbkdf.c | 82 ++++++++++++++++--
|
|
|
|
providers/implementations/kdfs/sshkdf.c | 75 +++++++++++++++-
|
|
|
|
providers/implementations/kdfs/sskdf.c | 100 +++++++++++++++++++++-
|
|
|
|
providers/implementations/kdfs/tls1_prf.c | 74 +++++++++++++++-
|
|
|
|
providers/implementations/kdfs/x942kdf.c | 66 +++++++++++++-
|
|
|
|
9 files changed, 487 insertions(+), 22 deletions(-)
|
2022-09-01 10:42:16 +00:00
|
|
|
|
2023-08-22 14:39:12 +00:00
|
|
|
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
|
|
|
|
index dbbdcccbda..aa07153441 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;
|
2022-09-01 10:42:16 +00:00
|
|
|
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
|
2023-08-22 14:39:12 +00:00
|
|
|
index c0cce14297..b431b9f871 100644
|
2022-09-01 10:42:16 +00:00
|
|
|
--- a/include/openssl/core_names.h
|
|
|
|
+++ b/include/openssl/core_names.h
|
2023-08-22 14:39:12 +00:00
|
|
|
@@ -226,6 +226,7 @@ extern "C" {
|
2022-09-01 10:42:16 +00:00
|
|
|
#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"
|
2023-08-22 14:39:12 +00:00
|
|
|
+#define OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
|
2022-09-01 10:42:16 +00:00
|
|
|
|
|
|
|
/* Known KDF names */
|
|
|
|
#define OSSL_KDF_NAME_HKDF "HKDF"
|
|
|
|
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
|
2023-08-22 14:39:12 +00:00
|
|
|
index 0983230a48..86171635ea 100644
|
2022-09-01 10:42:16 +00:00
|
|
|
--- 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
|
|
|
|
|
2023-08-22 14:39:12 +00:00
|
|
|
+# 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
|
2022-09-01 10:42:16 +00:00
|
|
|
+
|
|
|
|
#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
|
2023-08-22 14:39:12 +00:00
|
|
|
index 5304baa6c9..f9c77f4236 100644
|
2022-09-01 10:42:16 +00:00
|
|
|
--- a/providers/implementations/kdfs/hkdf.c
|
|
|
|
+++ b/providers/implementations/kdfs/hkdf.c
|
2023-08-22 14:39:12 +00:00
|
|
|
@@ -43,6 +43,7 @@ static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
|
|
|
|
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params;
|
|
|
|
static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
|
|
|
|
static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
|
|
|
|
+static OSSL_FUNC_kdf_newctx_fn kdf_tls1_3_new;
|
|
|
|
static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive;
|
|
|
|
static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params;
|
|
|
|
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params;
|
|
|
|
@@ -86,6 +87,10 @@ typedef struct {
|
|
|
|
size_t data_len;
|
|
|
|
unsigned char *info;
|
|
|
|
size_t info_len;
|
|
|
|
+ int is_tls13;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} KDF_HKDF;
|
|
|
|
|
|
|
|
static void *kdf_hkdf_new(void *provctx)
|
|
|
|
@@ -201,6 +206,11 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
switch (ctx->mode) {
|
|
|
|
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
|
|
|
default:
|
|
|
|
@@ -363,15 +373,78 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
KDF_HKDF *ctx = (KDF_HKDF *)vctx;
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
|
|
|
|
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
|
|
|
|
size_t sz = kdf_hkdf_size(ctx);
|
|
|
|
|
|
|
|
- if (sz == 0)
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ if (sz == 0 || !OSSL_PARAM_set_size_t(p, sz))
|
2022-09-01 10:42:16 +00:00
|
|
|
return 0;
|
2023-08-22 14:39:12 +00:00
|
|
|
- return OSSL_PARAM_set_size_t(p, sz);
|
|
|
|
}
|
|
|
|
- return -2;
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR))
|
|
|
|
+ != NULL) {
|
|
|
|
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
|
|
+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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->key_len < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ if (ctx->is_tls13) {
|
|
|
|
+ if (md != NULL
|
|
|
|
+ && !EVP_MD_is_a(md, "SHA2-256")
|
|
|
|
+ && !EVP_MD_is_a(md, "SHA2-384")) {
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic
|
|
|
|
+ * Module Validation Program, Section 2.4.B, (5): "The TLS 1.3
|
|
|
|
+ * key derivation function documented in Section 7.1 of RFC
|
|
|
|
+ * 8446. This is considered an approved CVL because the
|
|
|
|
+ * underlying functions performed within the TLS 1.3 KDF map to
|
|
|
|
+ * NIST approved standards, namely: SP 800-133rev2 (Section 6.3
|
|
|
|
+ * Option #3), SP 800-56Crev2, and SP 800-108."
|
|
|
|
+ *
|
|
|
|
+ * RFC 8446 appendix B.4 only lists SHA-256 and SHA-384. */
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (md != NULL
|
|
|
|
+ && (EVP_MD_is_a(md, "SHAKE-128") ||
|
|
|
|
+ EVP_MD_is_a(md, "SHAKE-256"))) {
|
|
|
|
+ /* HKDF is a SP 800-56Cr2 TwoStep KDF, for which all SHA-1,
|
|
|
|
+ * SHA-2 and SHA-3 are approved. SHAKE is not approved, because
|
|
|
|
+ * of FIPS 140-3 IG, section C.C: "The SHAKE128 and SHAKE256
|
|
|
|
+ * extendable-output functions may only be used as the
|
|
|
|
+ * standalone algorithms." */
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
+ if (!any_valid)
|
|
|
|
+ return -2;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
@@ -379,6 +452,9 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
@@ -709,6 +785,17 @@ static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void *kdf_tls1_3_new(void *provctx)
|
|
|
|
+{
|
|
|
|
+ KDF_HKDF *hkdf = kdf_hkdf_new(provctx);
|
|
|
|
+
|
|
|
|
+ if (hkdf != NULL)
|
|
|
|
+ hkdf->is_tls13 = 1;
|
|
|
|
+
|
|
|
|
+ return hkdf;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
const OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
@@ -724,6 +811,11 @@ static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
switch (ctx->mode) {
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
@@ -801,7 +893,7 @@ static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {
|
|
|
|
- { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
|
|
|
|
+ { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_3_new },
|
|
|
|
{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup },
|
|
|
|
{ OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free },
|
|
|
|
{ OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },
|
|
|
|
diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c
|
|
|
|
index aa3df15bc7..3f82710061 100644
|
|
|
|
--- a/providers/implementations/kdfs/kbkdf.c
|
|
|
|
+++ b/providers/implementations/kdfs/kbkdf.c
|
|
|
|
@@ -59,6 +59,9 @@ typedef struct {
|
|
|
|
kbkdf_mode mode;
|
|
|
|
EVP_MAC_CTX *ctx_init;
|
|
|
|
|
|
|
|
+ /* HMAC digest algorithm, if any; used to compute FIPS indicator */
|
|
|
|
+ PROV_DIGEST digest;
|
|
|
|
+
|
|
|
|
/* Names are lowercased versions of those found in SP800-108. */
|
|
|
|
int r;
|
|
|
|
unsigned char *ki;
|
|
|
|
@@ -72,6 +75,9 @@ typedef struct {
|
|
|
|
int use_l;
|
|
|
|
int is_kmac;
|
|
|
|
int use_separator;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} KBKDF;
|
|
|
|
|
|
|
|
/* Definitions needed for typechecking. */
|
|
|
|
@@ -143,6 +149,7 @@ static void kbkdf_reset(void *vctx)
|
|
|
|
void *provctx = ctx->provctx;
|
|
|
|
|
|
|
|
EVP_MAC_CTX_free(ctx->ctx_init);
|
|
|
|
+ ossl_prov_digest_reset(&ctx->digest);
|
|
|
|
OPENSSL_clear_free(ctx->context, ctx->context_len);
|
|
|
|
OPENSSL_clear_free(ctx->label, ctx->label_len);
|
|
|
|
OPENSSL_clear_free(ctx->ki, ctx->ki_len);
|
|
|
|
@@ -308,6 +315,11 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
h = EVP_MAC_CTX_get_mac_size(ctx->ctx_init);
|
|
|
|
if (h == 0)
|
|
|
|
goto done;
|
|
|
|
@@ -381,6 +393,9 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE);
|
|
|
|
if (p != NULL
|
|
|
|
&& OPENSSL_strncasecmp("counter", p->data, p->data_size) == 0) {
|
|
|
|
@@ -461,20 +476,77 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx,
|
|
|
|
static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
|
|
|
|
p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);
|
|
|
|
- if (p == NULL)
|
|
|
|
+ if (p != NULL) {
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* KBKDF can produce results as large as you like. */
|
|
|
|
+ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#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;
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256
|
|
|
|
+ * extendable-output functions may only be used as the standalone
|
|
|
|
+ * algorithms." Note that the digest is only used when the MAC
|
|
|
|
+ * algorithm is HMAC. */
|
|
|
|
+ if (ctx->ctx_init != NULL
|
|
|
|
+ && EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->ctx_init), OSSL_MAC_NAME_HMAC)) {
|
|
|
|
+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
|
|
|
|
+ if (md != NULL
|
|
|
|
+ && (EVP_MD_is_a(md, "SHAKE-128") || EVP_MD_is_a(md, "SHAKE-256"))) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (!any_valid)
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
- /* KBKDF can produce results as large as you like. */
|
|
|
|
- return OSSL_PARAM_set_size_t(p, SIZE_MAX);
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c
|
|
|
|
index 1afac4e477..389b82b714 100644
|
|
|
|
--- a/providers/implementations/kdfs/sshkdf.c
|
|
|
|
+++ b/providers/implementations/kdfs/sshkdf.c
|
|
|
|
@@ -49,6 +49,9 @@ typedef struct {
|
|
|
|
char type; /* X */
|
|
|
|
unsigned char *session_id;
|
|
|
|
size_t session_id_len;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} KDF_SSHKDF;
|
|
|
|
|
|
|
|
static void *kdf_sshkdf_new(void *provctx)
|
|
|
|
@@ -151,6 +154,12 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_TYPE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
return SSHKDF(md, ctx->key, ctx->key_len,
|
|
|
|
ctx->xcghash, ctx->xcghash_len,
|
|
|
|
ctx->session_id, ctx->session_id_len,
|
|
|
|
@@ -219,10 +228,67 @@ static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(ossl_unused void *ctx,
|
|
|
|
static int kdf_sshkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
|
|
|
|
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
|
|
|
- return OSSL_PARAM_set_size_t(p, SIZE_MAX);
|
|
|
|
- return -2;
|
|
|
|
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR);
|
|
|
|
+ if (p != NULL) {
|
|
|
|
+ KDF_SSHKDF *ctx = vctx;
|
|
|
|
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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->key_len < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256
|
|
|
|
+ * extendable-output functions may only be used as the standalone
|
|
|
|
+ * algorithms."
|
|
|
|
+ *
|
|
|
|
+ * Additionally, SP 800-135r1 section 5.2 specifies that the hash
|
|
|
|
+ * function used in SSHKDF "is one of the hash functions specified in
|
|
|
|
+ * FIPS 180-3.", which rules out SHA-3 and truncated variants of SHA-2.
|
|
|
|
+ * */
|
|
|
|
+ if (ctx->digest.md != NULL
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA-1")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-224")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-256")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-384")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-512")) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (!any_valid)
|
|
|
|
+ return -2;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
@@ -230,6 +296,9 @@ static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c
|
|
|
|
index ecb98de6fd..98fcc583d8 100644
|
|
|
|
--- a/providers/implementations/kdfs/sskdf.c
|
|
|
|
+++ b/providers/implementations/kdfs/sskdf.c
|
|
|
|
@@ -63,6 +63,10 @@ typedef struct {
|
|
|
|
size_t salt_len;
|
|
|
|
size_t out_len; /* optional KMAC parameter */
|
|
|
|
int is_kmac;
|
|
|
|
+ int is_x963kdf;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} KDF_SSKDF;
|
|
|
|
|
|
|
|
#define SSKDF_MAX_INLEN (1<<30)
|
|
|
|
@@ -73,6 +77,7 @@ typedef struct {
|
|
|
|
static const unsigned char kmac_custom_str[] = { 0x4B, 0x44, 0x46 };
|
|
|
|
|
|
|
|
static OSSL_FUNC_kdf_newctx_fn sskdf_new;
|
|
|
|
+static OSSL_FUNC_kdf_newctx_fn x963kdf_new;
|
|
|
|
static OSSL_FUNC_kdf_dupctx_fn sskdf_dup;
|
|
|
|
static OSSL_FUNC_kdf_freectx_fn sskdf_free;
|
|
|
|
static OSSL_FUNC_kdf_reset_fn sskdf_reset;
|
|
|
|
@@ -297,6 +302,16 @@ static void *sskdf_new(void *provctx)
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void *x963kdf_new(void *provctx)
|
|
|
|
+{
|
|
|
|
+ KDF_SSKDF *ctx = sskdf_new(provctx);
|
|
|
|
+
|
|
|
|
+ if (ctx)
|
|
|
|
+ ctx->is_x963kdf = 1;
|
|
|
|
+
|
|
|
|
+ return ctx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static void sskdf_reset(void *vctx)
|
|
|
|
{
|
|
|
|
KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
|
|
|
|
@@ -392,6 +407,11 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
2022-09-01 10:42:16 +00:00
|
|
|
}
|
2023-08-22 14:39:12 +00:00
|
|
|
md = ossl_prov_digest_md(&ctx->digest);
|
|
|
|
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
2022-09-01 10:42:16 +00:00
|
|
|
+
|
2023-08-22 14:39:12 +00:00
|
|
|
if (ctx->macctx != NULL) {
|
|
|
|
/* H(x) = KMAC or H(x) = HMAC */
|
|
|
|
int ret;
|
|
|
|
@@ -473,6 +493,11 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-09-01 10:42:16 +00:00
|
|
|
+#ifdef FIPS_MODULE
|
2023-08-22 14:39:12 +00:00
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+
|
|
|
|
return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
|
|
|
|
ctx->info, ctx->info_len, 1, key, keylen);
|
|
|
|
}
|
|
|
|
@@ -545,10 +570,74 @@ static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
+
|
|
|
|
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_size_t(p, sskdf_size(ctx)))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
|
|
|
- return OSSL_PARAM_set_size_t(p, sskdf_size(ctx));
|
|
|
|
- return -2;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR);
|
|
|
|
+ if (p != NULL) {
|
|
|
|
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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->secret_len < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256
|
|
|
|
+ * extendable-output functions may only be used as the standalone
|
|
|
|
+ * algorithms." */
|
|
|
|
+ if (ctx->macctx == NULL
|
|
|
|
+ || (ctx->macctx != NULL &&
|
|
|
|
+ EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), OSSL_MAC_NAME_HMAC))) {
|
|
|
|
+ if (ctx->digest.md != NULL
|
|
|
|
+ && (EVP_MD_is_a(ctx->digest.md, "SHAKE-128") ||
|
|
|
|
+ EVP_MD_is_a(ctx->digest.md, "SHAKE-256"))) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
2022-09-01 10:42:16 +00:00
|
|
|
+ }
|
2023-08-22 14:39:12 +00:00
|
|
|
+
|
|
|
|
+ /* Table H-3 in ANS X9.63-2001 says that 160-bit hash functions
|
|
|
|
+ * should only be used for 80-bit key agreement, but FIPS 140-3
|
|
|
|
+ * requires a security strength of 112 bits, so SHA-1 cannot be
|
|
|
|
+ * used with X9.63. See the discussion in
|
|
|
|
+ * https://github.com/usnistgov/ACVP/issues/1403#issuecomment-1435300395.
|
|
|
|
+ */
|
|
|
|
+ if (ctx->is_x963kdf
|
|
|
|
+ && ctx->digest.md != NULL
|
|
|
|
+ && EVP_MD_is_a(ctx->digest.md, "SHA-1")) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (!any_valid)
|
|
|
|
+ return -2;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
@@ -556,6 +645,9 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
{
|
|
|
|
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, 0),
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
OSSL_PARAM_END
|
|
|
|
};
|
|
|
|
return known_gettable_ctx_params;
|
|
|
|
@@ -577,7 +669,7 @@ const OSSL_DISPATCH ossl_kdf_sskdf_functions[] = {
|
|
|
|
};
|
|
|
|
|
|
|
|
const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = {
|
|
|
|
- { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new },
|
|
|
|
+ { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x963kdf_new },
|
|
|
|
{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))sskdf_dup },
|
|
|
|
{ OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free },
|
|
|
|
{ OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
|
|
|
|
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
|
|
|
|
index 54124ad4cb..25a6c79a2e 100644
|
|
|
|
--- a/providers/implementations/kdfs/tls1_prf.c
|
|
|
|
+++ b/providers/implementations/kdfs/tls1_prf.c
|
|
|
|
@@ -104,6 +104,13 @@ typedef struct {
|
|
|
|
/* Buffer of concatenated seed data */
|
|
|
|
unsigned char seed[TLS1_PRF_MAXBUF];
|
|
|
|
size_t seedlen;
|
|
|
|
+
|
|
|
|
+ /* MAC digest algorithm; used to compute FIPS indicator */
|
|
|
|
+ PROV_DIGEST digest;
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} TLS1_PRF;
|
|
|
|
|
|
|
|
static void *kdf_tls1_prf_new(void *provctx)
|
|
|
|
@@ -140,6 +147,7 @@ static void kdf_tls1_prf_reset(void *vctx)
|
|
|
|
EVP_MAC_CTX_free(ctx->P_sha1);
|
|
|
|
OPENSSL_clear_free(ctx->sec, ctx->seclen);
|
|
|
|
OPENSSL_cleanse(ctx->seed, ctx->seedlen);
|
|
|
|
+ ossl_prov_digest_reset(&ctx->digest);
|
|
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
|
|
ctx->provctx = provctx;
|
|
|
|
}
|
|
|
|
@@ -194,6 +202,10 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The seed buffer is prepended with a label.
|
|
|
|
@@ -243,6 +255,9 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) {
|
|
|
|
OPENSSL_clear_free(ctx->sec, ctx->seclen);
|
|
|
|
ctx->sec = NULL;
|
|
|
|
@@ -284,10 +299,60 @@ static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(
|
|
|
|
static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ TLS1_PRF *ctx = vctx;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
+
|
|
|
|
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR);
|
|
|
|
+ if (p != NULL) {
|
|
|
|
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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->seclen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* SP 800-135r1 section 4.2.2 says TLS 1.2 KDF is approved when "(3)
|
|
|
|
+ * P_HASH uses either SHA-256, SHA-384 or SHA-512." */
|
|
|
|
+ if (ctx->digest.md != NULL
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-256")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-384")
|
|
|
|
+ && !EVP_MD_is_a(ctx->digest.md, "SHA2-512")) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
2022-09-01 10:42:16 +00:00
|
|
|
+ }
|
2023-08-22 14:39:12 +00:00
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
2022-09-01 10:42:16 +00:00
|
|
|
+ }
|
2023-08-22 14:39:12 +00:00
|
|
|
+#endif
|
|
|
|
|
|
|
|
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
|
|
|
- return OSSL_PARAM_set_size_t(p, SIZE_MAX);
|
|
|
|
- return -2;
|
|
|
|
+ if (!any_valid)
|
|
|
|
+ return -2;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(
|
|
|
|
@@ -295,6 +360,9 @@ static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(
|
|
|
|
{
|
|
|
|
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, 0),
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
OSSL_PARAM_END
|
|
|
|
};
|
|
|
|
return known_gettable_ctx_params;
|
|
|
|
diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c
|
|
|
|
index 4c274fe27a..5ce23c8eb9 100644
|
|
|
|
--- a/providers/implementations/kdfs/x942kdf.c
|
|
|
|
+++ b/providers/implementations/kdfs/x942kdf.c
|
|
|
|
@@ -13,11 +13,13 @@
|
|
|
|
#include <openssl/core_dispatch.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
+#include <openssl/kdf.h>
|
|
|
|
#include <openssl/params.h>
|
|
|
|
#include <openssl/proverr.h>
|
|
|
|
#include "internal/packet.h"
|
|
|
|
#include "internal/der.h"
|
|
|
|
#include "internal/nelem.h"
|
|
|
|
+#include "crypto/evp.h"
|
|
|
|
#include "prov/provider_ctx.h"
|
|
|
|
#include "prov/providercommon.h"
|
|
|
|
#include "prov/implementations.h"
|
|
|
|
@@ -49,6 +51,9 @@ typedef struct {
|
|
|
|
const unsigned char *cek_oid;
|
|
|
|
size_t cek_oid_len;
|
|
|
|
int use_keybits;
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ int fips_indicator;
|
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
} KDF_X942;
|
|
|
|
|
|
|
|
/*
|
|
|
|
@@ -497,6 +502,10 @@ static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ ctx->fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
2022-09-01 10:42:16 +00:00
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
2023-08-22 14:39:12 +00:00
|
|
|
ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,
|
|
|
|
der, der_len, ctr, key, keylen);
|
|
|
|
OPENSSL_free(der);
|
|
|
|
@@ -600,10 +609,58 @@ static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
KDF_X942 *ctx = (KDF_X942 *)vctx;
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
+ int any_valid = 0; /* set to 1 when at least one parameter was valid */
|
|
|
|
|
|
|
|
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
|
|
|
- return OSSL_PARAM_set_size_t(p, x942kdf_size(ctx));
|
|
|
|
- return -2;
|
|
|
|
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_size_t(p, x942kdf_size(ctx)))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef FIPS_MODULE
|
|
|
|
+ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR);
|
|
|
|
+ if (p != NULL) {
|
|
|
|
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
|
|
+
|
|
|
|
+ any_valid = 1;
|
|
|
|
+
|
|
|
|
+ /* 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->secret_len < EVP_KDF_FIPS_MIN_KEY_LEN)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Verification Program, Section D.B and NIST Special Publication
|
|
|
|
+ * 800-131Ar2, Section 1.2.2 say that any algorithm at a security
|
|
|
|
+ * strength < 112 bits is legacy use only, so all derived keys should
|
|
|
|
+ * be longer than that. If a derived key has ever been shorter than
|
|
|
|
+ * that, ctx->output_keyelen_indicator will be NOT_APPROVED, and we
|
|
|
|
+ * should also set the returned FIPS indicator to unapproved. */
|
|
|
|
+ if (ctx->fips_indicator == EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED)
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+
|
|
|
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
|
|
|
+ * Validation Program, Section C.C: "The SHAKE128 and SHAKE256
|
|
|
|
+ * extendable-output functions may only be used as the standalone
|
|
|
|
+ * algorithms." */
|
|
|
|
+ if (ctx->digest.md != NULL
|
|
|
|
+ && (EVP_MD_is_a(ctx->digest.md, "SHAKE-128") ||
|
|
|
|
+ EVP_MD_is_a(ctx->digest.md, "SHAKE-256"))) {
|
|
|
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (!any_valid)
|
|
|
|
+ return -2;
|
2022-09-01 10:42:16 +00:00
|
|
|
+
|
2023-08-22 14:39:12 +00:00
|
|
|
+ return 1;
|
2022-09-01 10:42:16 +00:00
|
|
|
}
|
|
|
|
|
2023-08-22 14:39:12 +00:00
|
|
|
static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx,
|
|
|
|
@@ -611,6 +668,9 @@ static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx,
|
2022-09-01 10:42:16 +00:00
|
|
|
{
|
|
|
|
static const OSSL_PARAM known_gettable_ctx_params[] = {
|
|
|
|
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
|
|
|
|
+#ifdef FIPS_MODULE
|
2023-08-22 14:39:12 +00:00
|
|
|
+ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, 0),
|
2022-09-01 10:42:16 +00:00
|
|
|
+#endif /* defined(FIPS_MODULE) */
|
|
|
|
OSSL_PARAM_END
|
|
|
|
};
|
|
|
|
return known_gettable_ctx_params;
|
|
|
|
--
|
2023-08-22 14:39:12 +00:00
|
|
|
2.41.0
|
2022-09-01 10:42:16 +00:00
|
|
|
|