parent
7712e145d7
commit
5817d74282
@ -1,138 +0,0 @@
|
|||||||
From 0c4aaedf29a1ed1559762515bfeaa5923925e18f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Clemens Lang <cllang@redhat.com>
|
|
||||||
Date: Thu, 11 Aug 2022 09:27:12 +0200
|
|
||||||
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.
|
|
||||||
|
|
||||||
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
|
||||||
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 +++++++++++++++++++++++++++
|
|
||||||
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..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_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..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_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..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[])
|
|
||||||
return 0;
|
|
||||||
return OSSL_PARAM_set_size_t(p, sz);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+#ifdef FIPS_MODULE
|
|
||||||
+ 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_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
||||||
+ break;
|
|
||||||
+ case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
|
|
||||||
+ {
|
|
||||||
+ /* When TLS 1.3 uses extract, the following holds:
|
|
||||||
+ * 1. The salt length matches the hash length, and either
|
|
||||||
+ * 2.1. the key is all zeroes and matches the hash length, or
|
|
||||||
+ * 2.2. the key originates from a PSK (resumption_master_secret
|
|
||||||
+ * or some externally esablished key), or an ECDH or DH key
|
|
||||||
+ * derivation. See
|
|
||||||
+ * https://www.rfc-editor.org/rfc/rfc8446#section-7.1.
|
|
||||||
+ * Unfortunately at this point, we cannot verify where the key
|
|
||||||
+ * 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 == (size_t) EVP_MD_get_size(md))
|
|
||||||
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
||||||
+ else
|
|
||||||
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
|
|
||||||
+ /* When TLS 1.3 uses expand, it always provides a label that
|
|
||||||
+ * contains an uint16 for the length, followed by between 7 and 255
|
|
||||||
+ * bytes for a label string that starts with "tls13 " or "dtls13".
|
|
||||||
+ * For compatibility with future versions, we only check for "tls"
|
|
||||||
+ * or "dtls". See
|
|
||||||
+ * https://www.rfc-editor.org/rfc/rfc8446#section-7.1 and
|
|
||||||
+ * https://www.rfc-editor.org/rfc/rfc9147#section-5.9. */
|
|
||||||
+ if (ctx->label != NULL
|
|
||||||
+ && 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_REDHAT_FIPS_INDICATOR_APPROVED;
|
|
||||||
+ else
|
|
||||||
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ return OSSL_PARAM_set_int(p, fips_indicator);
|
|
||||||
+ }
|
|
||||||
+#endif /* defined(FIPS_MODULE) */
|
|
||||||
+
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -306,6 +356,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;
|
|
||||||
--
|
|
||||||
2.38.1
|
|
||||||
|
|
@ -0,0 +1,906 @@
|
|||||||
|
From 2290280617183863eb15425b8925765966723725 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Thu, 11 Aug 2022 09:27:12 +0200
|
||||||
|
Subject: KDF: Add FIPS indicators
|
||||||
|
|
||||||
|
FIPS requires a number of restrictions on the parameters of the various
|
||||||
|
key derivation functions implemented in OpenSSL. The KDFs that use
|
||||||
|
digest algorithms usually should not allow SHAKE (due to FIPS 140-3 IG
|
||||||
|
C.C). Additionally, some application-specific KDFs have further
|
||||||
|
restrictions defined in SP 800-135r1.
|
||||||
|
|
||||||
|
Generally, all KDFs shall use a key-derivation key length of at least
|
||||||
|
112 bits due to SP 800-131Ar2 section 8. Additionally any use of a KDF
|
||||||
|
to generate and output length of less than 112 bits will also set the
|
||||||
|
indicator to unapproved.
|
||||||
|
|
||||||
|
Add explicit indicators to all KDFs usable in FIPS mode except for
|
||||||
|
PBKDF2 (which has its specific FIPS limits already implemented). The
|
||||||
|
indicator can be queried using EVP_KDF_CTX_get_params() after setting
|
||||||
|
the required parameters and keys for the KDF.
|
||||||
|
|
||||||
|
Our FIPS provider implements SHA1, SHA2 (both -256 and -512, and the
|
||||||
|
truncated variants -224 and -384) and SHA3 (-256 and -512, and the
|
||||||
|
truncated versions -224 and -384), as well as SHAKE-128 and -256.
|
||||||
|
|
||||||
|
The SHAKE functions are generally not allowed in KDFs. For the rest, the
|
||||||
|
support matrix is:
|
||||||
|
|
||||||
|
KDF | SHA-1 | SHA-2 | SHA-2 truncated | SHA-3 | SHA-3 truncated
|
||||||
|
==========================================================================
|
||||||
|
KBKDF | x | x | x | x | x
|
||||||
|
HKDF | x | x | x | x | x
|
||||||
|
TLS1PRF | | SHA-{256,384,512} only | |
|
||||||
|
SSHKDF | x | x | x | |
|
||||||
|
SSKDF | x | x | x | x | x
|
||||||
|
X9.63KDF | | x | x | x | x
|
||||||
|
X9.42-ASN1 | x | x | x | x | x
|
||||||
|
TLS1.3PRF | | SHA-{256,384} only | |
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
Resolves: rhbz#2160733 rhbz#2164763
|
||||||
|
Related: rhbz#2114772 rhbz#2141695
|
||||||
|
---
|
||||||
|
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 | 67 ++++++++++++++-
|
||||||
|
9 files changed, 488 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
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 6bed5a8a67..680bfbc7cc 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_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..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_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 dfa7786bde..f01e40ff5a 100644
|
||||||
|
--- a/providers/implementations/kdfs/hkdf.c
|
||||||
|
+++ b/providers/implementations/kdfs/hkdf.c
|
||||||
|
@@ -42,6 +42,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;
|
||||||
|
@@ -85,6 +86,10 @@ typedef struct {
|
||||||
|
size_t data_len;
|
||||||
|
unsigned char info[HKDF_MAXBUF];
|
||||||
|
size_t info_len;
|
||||||
|
+ int is_tls13;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ int output_keylen_indicator;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
} KDF_HKDF;
|
||||||
|
|
||||||
|
static void *kdf_hkdf_new(void *provctx)
|
||||||
|
@@ -170,6 +175,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->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
switch (ctx->mode) {
|
||||||
|
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
|
||||||
|
default:
|
||||||
|
@@ -332,15 +342,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))
|
||||||
|
return 0;
|
||||||
|
- 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->output_keylen_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,
|
||||||
|
@@ -348,6 +421,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;
|
||||||
|
@@ -677,6 +753,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[])
|
||||||
|
{
|
||||||
|
@@ -692,6 +779,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->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
switch (ctx->mode) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
@@ -769,7 +861,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_FREECTX, (void(*)(void))kdf_hkdf_free },
|
||||||
|
{ OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset },
|
||||||
|
{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_3_derive },
|
||||||
|
diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c
|
||||||
|
index a542f84dfa..6b6dfb94ac 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;
|
||||||
|
@@ -70,6 +73,9 @@ typedef struct {
|
||||||
|
size_t iv_len;
|
||||||
|
int use_l;
|
||||||
|
int use_separator;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ int output_keylen_indicator;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
} KBKDF;
|
||||||
|
|
||||||
|
/* Definitions needed for typechecking. */
|
||||||
|
@@ -138,6 +144,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);
|
||||||
|
@@ -240,6 +247,11 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
||||||
|
+ ctx->output_keylen_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;
|
||||||
|
@@ -297,6 +309,9 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ 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) {
|
||||||
|
@@ -363,20 +378,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->output_keylen_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 c592ba72f1..4a52b38266 100644
|
||||||
|
--- a/providers/implementations/kdfs/sshkdf.c
|
||||||
|
+++ b/providers/implementations/kdfs/sshkdf.c
|
||||||
|
@@ -48,6 +48,9 @@ typedef struct {
|
||||||
|
char type; /* X */
|
||||||
|
unsigned char *session_id;
|
||||||
|
size_t session_id_len;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ int output_keylen_indicator;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
} KDF_SSHKDF;
|
||||||
|
|
||||||
|
static void *kdf_sshkdf_new(void *provctx)
|
||||||
|
@@ -126,6 +129,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->output_keylen_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,
|
||||||
|
@@ -194,10 +203,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->output_keylen_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,
|
||||||
|
@@ -205,6 +271,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 eb54972e1c..23865cd70f 100644
|
||||||
|
--- a/providers/implementations/kdfs/sskdf.c
|
||||||
|
+++ b/providers/implementations/kdfs/sskdf.c
|
||||||
|
@@ -62,6 +62,10 @@ typedef struct {
|
||||||
|
unsigned char *salt;
|
||||||
|
size_t salt_len;
|
||||||
|
size_t out_len; /* optional KMAC parameter */
|
||||||
|
+ int is_x963kdf;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ int output_keylen_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_freectx_fn sskdf_free;
|
||||||
|
static OSSL_FUNC_kdf_reset_fn sskdf_reset;
|
||||||
|
static OSSL_FUNC_kdf_derive_fn sskdf_derive;
|
||||||
|
@@ -296,6 +301,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;
|
||||||
|
@@ -361,6 +376,11 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
||||||
|
}
|
||||||
|
md = ossl_prov_digest_md(&ctx->digest);
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
||||||
|
+ ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
if (ctx->macctx != NULL) {
|
||||||
|
/* H(x) = KMAC or H(x) = HMAC */
|
||||||
|
int ret;
|
||||||
|
@@ -442,6 +462,11 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ if (keylen < EVP_KDF_FIPS_MIN_KEY_LEN)
|
||||||
|
+ ctx->output_keylen_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);
|
||||||
|
}
|
||||||
|
@@ -514,10 +539,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->output_keylen_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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* 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,
|
||||||
|
@@ -525,6 +614,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;
|
||||||
|
@@ -545,7 +637,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_FREECTX, (void(*)(void))sskdf_free },
|
||||||
|
{ OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
|
||||||
|
{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))x963kdf_derive },
|
||||||
|
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
index a4d64b9352..f6782a6ca2 100644
|
||||||
|
--- a/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
+++ b/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
@@ -93,6 +93,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 output_keylen_indicator;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
} TLS1_PRF;
|
||||||
|
|
||||||
|
static void *kdf_tls1_prf_new(void *provctx)
|
||||||
|
@@ -129,6 +136,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;
|
||||||
|
}
|
||||||
|
@@ -157,6 +165,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->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
|
||||||
|
return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
|
||||||
|
ctx->sec, ctx->seclen,
|
||||||
|
@@ -191,6 +203,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;
|
||||||
|
@@ -232,10 +247,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->output_keylen_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;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#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(
|
||||||
|
@@ -243,6 +308,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 b1bc6f7e1b..8173fc2cc7 100644
|
||||||
|
--- a/providers/implementations/kdfs/x942kdf.c
|
||||||
|
+++ b/providers/implementations/kdfs/x942kdf.c
|
||||||
|
@@ -13,10 +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"
|
||||||
|
@@ -47,6 +50,9 @@ typedef struct {
|
||||||
|
const unsigned char *cek_oid;
|
||||||
|
size_t cek_oid_len;
|
||||||
|
int use_keybits;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ int output_keylen_indicator;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
} KDF_X942;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -460,6 +466,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->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
ret = x942kdf_hash_kdm(md, ctx->secret, ctx->secret_len,
|
||||||
|
der, der_len, ctr, key, keylen);
|
||||||
|
OPENSSL_free(der);
|
||||||
|
@@ -563,10 +573,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->output_keylen_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;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *ctx,
|
||||||
|
@@ -574,6 +632,9 @@ static const OSSL_PARAM *x942kdf_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;
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
From 185fbbfea732588187c81d1b2cafb3e1fae9eb77 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Clemens Lang <cllang@redhat.com>
|
|
||||||
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 <cllang@redhat.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
|
|
@ -0,0 +1,344 @@
|
|||||||
|
From 8a2d1b22ede5eeca4d104bb027b84f3ecfc69549 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Thu, 11 May 2023 12:51:59 +0200
|
||||||
|
Subject: [PATCH] DH: Disable FIPS 186-4 type parameters in FIPS mode
|
||||||
|
|
||||||
|
For DH parameter and key pair generation/verification, the DSA
|
||||||
|
procedures specified in FIPS 186-4 are used. With the release of FIPS
|
||||||
|
186-5 and the removal of DSA, the approved status of these groups is in
|
||||||
|
peril. Once the transition for DSA ends (this transition will be 1 year
|
||||||
|
long and start once CMVP has published the guidance), no more
|
||||||
|
submissions claiming DSA will be allowed. Hence, FIPS 186-type
|
||||||
|
parameters will also be automatically non-approved.
|
||||||
|
|
||||||
|
In the FIPS provider, disable validation of any DH parameters that are
|
||||||
|
not well-known groups, and remove DH parameter generation completely.
|
||||||
|
|
||||||
|
Adjust tests to use well-known groups or larger DH groups where this
|
||||||
|
change would now cause failures, and skip tests that are expected to
|
||||||
|
fail due to this change.
|
||||||
|
|
||||||
|
Related: rhbz#2169757, rhbz#2169757
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
---
|
||||||
|
crypto/dh/dh_backend.c | 10 ++++
|
||||||
|
crypto/dh/dh_check.c | 12 ++--
|
||||||
|
crypto/dh/dh_gen.c | 12 +++-
|
||||||
|
crypto/dh/dh_key.c | 13 ++--
|
||||||
|
crypto/dh/dh_pmeth.c | 10 +++-
|
||||||
|
providers/implementations/keymgmt/dh_kmgmt.c | 5 ++
|
||||||
|
test/endecode_test.c | 4 +-
|
||||||
|
test/evp_libctx_test.c | 2 +-
|
||||||
|
test/helpers/predefined_dhparams.c | 62 ++++++++++++++++++++
|
||||||
|
test/helpers/predefined_dhparams.h | 1 +
|
||||||
|
test/recipes/80-test_cms.t | 4 +-
|
||||||
|
test/recipes/80-test_ssl_old.t | 3 +
|
||||||
|
12 files changed, 118 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c
|
||||||
|
index 726843fd30..24c65ca84f 100644
|
||||||
|
--- a/crypto/dh/dh_backend.c
|
||||||
|
+++ b/crypto/dh/dh_backend.c
|
||||||
|
@@ -53,6 +53,16 @@ int ossl_dh_params_fromdata(DH *dh, const OSSL_PARAM params[])
|
||||||
|
if (!dh_ffc_params_fromdata(dh, params))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ if (!ossl_dh_is_named_safe_prime_group(dh)) {
|
||||||
|
+ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS,
|
||||||
|
+ "FIPS 186-4 type domain parameters no longer allowed in"
|
||||||
|
+ " FIPS mode, since the required validation routines"
|
||||||
|
+ " were removed from FIPS 186-5");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
param_priv_len =
|
||||||
|
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN);
|
||||||
|
if (param_priv_len != NULL
|
||||||
|
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
|
||||||
|
index 0b391910d6..75581ca347 100644
|
||||||
|
--- a/crypto/dh/dh_check.c
|
||||||
|
+++ b/crypto/dh/dh_check.c
|
||||||
|
@@ -57,13 +57,15 @@ int DH_check_params(const DH *dh, int *ret)
|
||||||
|
nid = DH_get_nid((DH *)dh);
|
||||||
|
if (nid != NID_undef)
|
||||||
|
return 1;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
- * OR
|
||||||
|
- * (2b) FFC domain params conform to FIPS-186-4 explicit domain param
|
||||||
|
- * validity tests.
|
||||||
|
+ * FIPS 186-4 explicit domain parameters are no longer supported in FIPS mode.
|
||||||
|
*/
|
||||||
|
- return ossl_ffc_params_FIPS186_4_validate(dh->libctx, &dh->params,
|
||||||
|
- FFC_PARAM_TYPE_DH, ret, NULL);
|
||||||
|
+ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS,
|
||||||
|
+ "FIPS 186-4 type domain parameters no longer allowed in"
|
||||||
|
+ " FIPS mode, since the required validation routines were"
|
||||||
|
+ " removed from FIPS 186-5");
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int DH_check_params(const DH *dh, int *ret)
|
||||||
|
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
|
||||||
|
index aec6b85316..9c55121067 100644
|
||||||
|
--- a/crypto/dh/dh_gen.c
|
||||||
|
+++ b/crypto/dh/dh_gen.c
|
||||||
|
@@ -38,18 +38,26 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
|
||||||
|
int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits,
|
||||||
|
BN_GENCB *cb)
|
||||||
|
{
|
||||||
|
- int ret, res;
|
||||||
|
+ int ret = 0;
|
||||||
|
|
||||||
|
#ifndef FIPS_MODULE
|
||||||
|
+ int res;
|
||||||
|
+
|
||||||
|
if (type == DH_PARAMGEN_TYPE_FIPS_186_2)
|
||||||
|
ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params,
|
||||||
|
FFC_PARAM_TYPE_DH,
|
||||||
|
pbits, qbits, &res, cb);
|
||||||
|
else
|
||||||
|
-#endif
|
||||||
|
ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params,
|
||||||
|
FFC_PARAM_TYPE_DH,
|
||||||
|
pbits, qbits, &res, cb);
|
||||||
|
+#else
|
||||||
|
+ /* In FIPS mode, we no longer support FIPS 186-4 domain parameters */
|
||||||
|
+ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS,
|
||||||
|
+ "FIPS 186-4 type domain parameters no longer allowed in"
|
||||||
|
+ " FIPS mode, since the required generation routines were"
|
||||||
|
+ " removed from FIPS 186-5");
|
||||||
|
+#endif
|
||||||
|
if (ret > 0)
|
||||||
|
dh->dirty_cnt++;
|
||||||
|
return ret;
|
||||||
|
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
|
||||||
|
index 4e9705beef..14c0b0b6b3 100644
|
||||||
|
--- a/crypto/dh/dh_key.c
|
||||||
|
+++ b/crypto/dh/dh_key.c
|
||||||
|
@@ -308,8 +308,12 @@ static int generate_key(DH *dh)
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
#ifdef FIPS_MODULE
|
||||||
|
- if (dh->params.q == NULL)
|
||||||
|
- goto err;
|
||||||
|
+ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS,
|
||||||
|
+ "FIPS 186-4 type domain parameters no longer"
|
||||||
|
+ " allowed in FIPS mode, since the required"
|
||||||
|
+ " generation routines were removed from FIPS"
|
||||||
|
+ " 186-5");
|
||||||
|
+ goto err;
|
||||||
|
#else
|
||||||
|
if (dh->params.q == NULL) {
|
||||||
|
/* secret exponent length, must satisfy 2^(l-1) <= p */
|
||||||
|
@@ -330,9 +334,7 @@ static int generate_key(DH *dh)
|
||||||
|
if (!BN_clear_bit(priv_key, 0))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
- } else
|
||||||
|
-#endif
|
||||||
|
- {
|
||||||
|
+ } else {
|
||||||
|
/* Do a partial check for invalid p, q, g */
|
||||||
|
if (!ossl_ffc_params_simple_validate(dh->libctx, &dh->params,
|
||||||
|
FFC_PARAM_TYPE_DH, NULL))
|
||||||
|
@@ -348,6 +350,7 @@ static int generate_key(DH *dh)
|
||||||
|
priv_key))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
|
||||||
|
index f201eede0d..30f90d15be 100644
|
||||||
|
--- a/crypto/dh/dh_pmeth.c
|
||||||
|
+++ b/crypto/dh/dh_pmeth.c
|
||||||
|
@@ -305,13 +305,17 @@ static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
|
||||||
|
prime_len, subprime_len, &res,
|
||||||
|
pcb);
|
||||||
|
else
|
||||||
|
-# endif
|
||||||
|
- /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
|
||||||
|
- if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
|
||||||
|
rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
|
||||||
|
FFC_PARAM_TYPE_DH,
|
||||||
|
prime_len, subprime_len, &res,
|
||||||
|
pcb);
|
||||||
|
+# else
|
||||||
|
+ /* In FIPS mode, we no longer support FIPS 186-4 domain parameters */
|
||||||
|
+ ERR_raise_data(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS,
|
||||||
|
+ "FIPS 186-4 type domain parameters no longer allowed in"
|
||||||
|
+ " FIPS mode, since the required generation routines were"
|
||||||
|
+ " removed from FIPS 186-5");
|
||||||
|
+# endif
|
||||||
|
if (rv <= 0) {
|
||||||
|
DH_free(ret);
|
||||||
|
return NULL;
|
||||||
|
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
|
||||||
|
index 9a7dde7c66..b3e7bca5ac 100644
|
||||||
|
--- a/providers/implementations/keymgmt/dh_kmgmt.c
|
||||||
|
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
|
||||||
|
@@ -414,6 +414,11 @@ static int dh_validate(const void *keydata, int selection, int checktype)
|
||||||
|
if ((selection & DH_POSSIBLE_SELECTIONS) == 0)
|
||||||
|
return 1; /* nothing to validate */
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ /* In FIPS provider, always check the domain parameters to disallow
|
||||||
|
+ * operations on keys with FIPS 186-4 params. */
|
||||||
|
+ selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||||
|
+#endif
|
||||||
|
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
|
||||||
|
/*
|
||||||
|
* Both of these functions check parameters. DH_check_params_ex()
|
||||||
|
diff --git a/test/endecode_test.c b/test/endecode_test.c
|
||||||
|
index e3f7b81f69..1b63daaed5 100644
|
||||||
|
--- a/test/endecode_test.c
|
||||||
|
+++ b/test/endecode_test.c
|
||||||
|
@@ -80,10 +80,10 @@ static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
|
||||||
|
* for testing only. Use a minimum key size of 2048 for security purposes.
|
||||||
|
*/
|
||||||
|
if (strcmp(type, "DH") == 0)
|
||||||
|
- return get_dh512(keyctx);
|
||||||
|
+ return get_dh2048(keyctx);
|
||||||
|
|
||||||
|
if (strcmp(type, "X9.42 DH") == 0)
|
||||||
|
- return get_dhx512(keyctx);
|
||||||
|
+ return get_dhx_ffdhe2048(keyctx);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c
|
||||||
|
index 2448c35a14..92d484fb12 100644
|
||||||
|
--- a/test/evp_libctx_test.c
|
||||||
|
+++ b/test/evp_libctx_test.c
|
||||||
|
@@ -188,7 +188,7 @@ static int do_dh_param_keygen(int tstid, const BIGNUM **bn)
|
||||||
|
|
||||||
|
if (!TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey_parm, NULL))
|
||||||
|
|| !TEST_int_gt(EVP_PKEY_keygen_init(gen_ctx), 0)
|
||||||
|
- || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey), expected))
|
||||||
|
+ || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey) == 1, expected))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (expected) {
|
||||||
|
diff --git a/test/helpers/predefined_dhparams.c b/test/helpers/predefined_dhparams.c
|
||||||
|
index 4bdadc4143..e5186e4b4a 100644
|
||||||
|
--- a/test/helpers/predefined_dhparams.c
|
||||||
|
+++ b/test/helpers/predefined_dhparams.c
|
||||||
|
@@ -116,6 +116,68 @@ EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx)
|
||||||
|
dhx512_q, sizeof(dhx512_q));
|
||||||
|
}
|
||||||
|
|
||||||
|
+EVP_PKEY *get_dhx_ffdhe2048(OSSL_LIB_CTX *libctx)
|
||||||
|
+{
|
||||||
|
+ /* This is RFC 7919 ffdhe2048, since Red Hat removes support for
|
||||||
|
+ * non-well-known groups in FIPS mode. */
|
||||||
|
+ static unsigned char dhx_p[] = {
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58,
|
||||||
|
+ 0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
|
||||||
|
+ 0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
|
||||||
|
+ 0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
|
||||||
|
+ 0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02,
|
||||||
|
+ 0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
|
||||||
|
+ 0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
|
||||||
|
+ 0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
|
||||||
|
+ 0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda,
|
||||||
|
+ 0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
|
||||||
|
+ 0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
|
||||||
|
+ 0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
|
||||||
|
+ 0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3,
|
||||||
|
+ 0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
|
||||||
|
+ 0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
|
||||||
|
+ 0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
|
||||||
|
+ 0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32,
|
||||||
|
+ 0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
|
||||||
|
+ 0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
|
||||||
|
+ 0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
|
||||||
|
+ 0x88, 0x6b, 0x42, 0x38, 0x61, 0x28, 0x5c, 0x97, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff
|
||||||
|
+ };
|
||||||
|
+ static unsigned char dhx_g[] = {
|
||||||
|
+ 0x02
|
||||||
|
+ };
|
||||||
|
+ static unsigned char dhx_q[] = {
|
||||||
|
+ 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0xfc, 0x2a, 0x2c,
|
||||||
|
+ 0x51, 0x5d, 0xa5, 0x4d, 0x57, 0xee, 0x2b, 0x10, 0x13, 0x9e, 0x9e, 0x78,
|
||||||
|
+ 0xec, 0x5c, 0xe2, 0xc1, 0xe7, 0x16, 0x9b, 0x4a, 0xd4, 0xf0, 0x9b, 0x20,
|
||||||
|
+ 0x8a, 0x32, 0x19, 0xfd, 0xe6, 0x49, 0xce, 0xe7, 0x12, 0x4d, 0x9f, 0x7c,
|
||||||
|
+ 0xbe, 0x97, 0xf1, 0xb1, 0xb1, 0x86, 0x3a, 0xec, 0x7b, 0x40, 0xd9, 0x01,
|
||||||
|
+ 0x57, 0x62, 0x30, 0xbd, 0x69, 0xef, 0x8f, 0x6a, 0xea, 0xfe, 0xb2, 0xb0,
|
||||||
|
+ 0x92, 0x19, 0xfa, 0x8f, 0xaf, 0x83, 0x37, 0x68, 0x42, 0xb1, 0xb2, 0xaa,
|
||||||
|
+ 0x9e, 0xf6, 0x8d, 0x79, 0xda, 0xab, 0x89, 0xaf, 0x3f, 0xab, 0xe4, 0x9a,
|
||||||
|
+ 0xcc, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xbb, 0xf1, 0x53, 0x44, 0xed,
|
||||||
|
+ 0x79, 0xf7, 0xf4, 0x39, 0x0e, 0xf8, 0xac, 0x50, 0x9b, 0x56, 0xf3, 0x9a,
|
||||||
|
+ 0x98, 0x56, 0x65, 0x27, 0xa4, 0x1d, 0x3c, 0xbd, 0x5e, 0x05, 0x58, 0xc1,
|
||||||
|
+ 0x59, 0x92, 0x7d, 0xb0, 0xe8, 0x84, 0x54, 0xa5, 0xd9, 0x64, 0x71, 0xfd,
|
||||||
|
+ 0xdc, 0xb5, 0x6d, 0x5b, 0xb0, 0x6b, 0xfa, 0x34, 0x0e, 0xa7, 0xa1, 0x51,
|
||||||
|
+ 0xef, 0x1c, 0xa6, 0xfa, 0x57, 0x2b, 0x76, 0xf3, 0xb1, 0xb9, 0x5d, 0x8c,
|
||||||
|
+ 0x85, 0x83, 0xd3, 0xe4, 0x77, 0x05, 0x36, 0xb8, 0x4f, 0x01, 0x7e, 0x70,
|
||||||
|
+ 0xe6, 0xfb, 0xf1, 0x76, 0x60, 0x1a, 0x02, 0x66, 0x94, 0x1a, 0x17, 0xb0,
|
||||||
|
+ 0xc8, 0xb9, 0x7f, 0x4e, 0x74, 0xc2, 0xc1, 0xff, 0xc7, 0x27, 0x89, 0x19,
|
||||||
|
+ 0x77, 0x79, 0x40, 0xc1, 0xe1, 0xff, 0x1d, 0x8d, 0xa6, 0x37, 0xd6, 0xb9,
|
||||||
|
+ 0x9d, 0xda, 0xfe, 0x5e, 0x17, 0x61, 0x10, 0x02, 0xe2, 0xc7, 0x78, 0xc1,
|
||||||
|
+ 0xbe, 0x8b, 0x41, 0xd9, 0x63, 0x79, 0xa5, 0x13, 0x60, 0xd9, 0x77, 0xfd,
|
||||||
|
+ 0x44, 0x35, 0xa1, 0x1c, 0x30, 0x94, 0x2e, 0x4b, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
+ 0xff, 0xff, 0xff, 0xff
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ return get_dh_from_pg(libctx, "X9.42 DH",
|
||||||
|
+ dhx_p, sizeof(dhx_p),
|
||||||
|
+ dhx_g, sizeof(dhx_g),
|
||||||
|
+ dhx_q, sizeof(dhx_q));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx)
|
||||||
|
{
|
||||||
|
static unsigned char dh1024_p[] = {
|
||||||
|
diff --git a/test/helpers/predefined_dhparams.h b/test/helpers/predefined_dhparams.h
|
||||||
|
index f0e8709062..2ff6d6e721 100644
|
||||||
|
--- a/test/helpers/predefined_dhparams.h
|
||||||
|
+++ b/test/helpers/predefined_dhparams.h
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#ifndef OPENSSL_NO_DH
|
||||||
|
EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx);
|
||||||
|
EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx);
|
||||||
|
+EVP_PKEY *get_dhx_ffdhe2048(OSSL_LIB_CTX *libctx);
|
||||||
|
EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libct);
|
||||||
|
EVP_PKEY *get_dh2048(OSSL_LIB_CTX *libctx);
|
||||||
|
EVP_PKEY *get_dh4096(OSSL_LIB_CTX *libctx);
|
||||||
|
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
|
||||||
|
index cabbe3ecdf..efe56c5665 100644
|
||||||
|
--- a/test/recipes/80-test_cms.t
|
||||||
|
+++ b/test/recipes/80-test_cms.t
|
||||||
|
@@ -627,10 +627,10 @@ my @smime_cms_param_tests = (
|
||||||
|
],
|
||||||
|
|
||||||
|
[ "enveloped content test streaming S/MIME format, X9.42 DH",
|
||||||
|
- [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
|
||||||
|
+ [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
|
||||||
|
"-stream", "-out", "{output}.cms",
|
||||||
|
"-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
|
||||||
|
- [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
|
||||||
|
+ [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
|
||||||
|
"-in", "{output}.cms", "-out", "{output}.txt" ],
|
||||||
|
\&final_compare
|
||||||
|
]
|
||||||
|
diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t
|
||||||
|
index 8c52b637fc..31ed54621b 100644
|
||||||
|
--- a/test/recipes/80-test_ssl_old.t
|
||||||
|
+++ b/test/recipes/80-test_ssl_old.t
|
||||||
|
@@ -390,6 +390,9 @@ sub testssl {
|
||||||
|
skip "skipping dhe1024dsa test", 1
|
||||||
|
if ($no_dh);
|
||||||
|
|
||||||
|
+ skip "FIPS 186-4 type DH groups are no longer supported by the FIPS provider", 1
|
||||||
|
+ if $provider eq "fips";
|
||||||
|
+
|
||||||
|
ok(run(test([@ssltest, "-bio_pair", "-dhe1024dsa", "-v"])),
|
||||||
|
'test sslv2/sslv3 with 1024bit DHE via BIO pair');
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 9dbc6069665690bd238caa7622647ea8ac94124f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Mon, 13 Feb 2023 11:01:44 +0100
|
||||||
|
Subject: fips: Zeroize `out` in fips selftest
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
Resolves: rhbz#2169314
|
||||||
|
---
|
||||||
|
providers/fips/self_test.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c
|
||||||
|
index 80d048a847..11a989209c 100644
|
||||||
|
--- a/providers/fips/self_test.c
|
||||||
|
+++ b/providers/fips/self_test.c
|
||||||
|
@@ -221,6 +221,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
|
||||||
|
goto err;
|
||||||
|
ret = 1;
|
||||||
|
err:
|
||||||
|
+ OPENSSL_cleanse(out, sizeof(out));
|
||||||
|
OSSL_SELF_TEST_onend(ev, ret);
|
||||||
|
EVP_MAC_CTX_free(ctx);
|
||||||
|
EVP_MAC_free(mac);
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,101 @@
|
|||||||
|
From 589eb3898896c1ac916bc20069ecd5adb8534850 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Fri, 17 Feb 2023 15:31:08 +0100
|
||||||
|
Subject: [PATCH] GCM: Implement explicit FIPS indicator for IV gen
|
||||||
|
|
||||||
|
Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
||||||
|
Verification Program, Section C.H requires guarantees about the
|
||||||
|
uniqueness of key/iv pairs, and proposes a few approaches to ensure
|
||||||
|
this. Provide an indicator for option 2 "The IV may be generated
|
||||||
|
internally at its entirety randomly."
|
||||||
|
|
||||||
|
Resolves: rhbz#2168289
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
---
|
||||||
|
include/openssl/core_names.h | 1 +
|
||||||
|
include/openssl/evp.h | 4 +++
|
||||||
|
.../implementations/ciphers/ciphercommon.c | 4 +++
|
||||||
|
.../ciphers/ciphercommon_gcm.c | 25 +++++++++++++++++++
|
||||||
|
4 files changed, 34 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
|
||||||
|
index 680bfbc7cc..832502a034 100644
|
||||||
|
--- a/include/openssl/core_names.h
|
||||||
|
+++ b/include/openssl/core_names.h
|
||||||
|
@@ -97,6 +97,7 @@ extern "C" {
|
||||||
|
#define OSSL_CIPHER_PARAM_CTS_MODE "cts_mode" /* utf8_string */
|
||||||
|
/* For passing the AlgorithmIdentifier parameter in DER form */
|
||||||
|
#define OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS "alg_id_param" /* octet_string */
|
||||||
|
+#define OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" /* int */
|
||||||
|
|
||||||
|
#define OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT \
|
||||||
|
"tls1multi_maxsndfrag" /* uint */
|
||||||
|
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
|
||||||
|
index 49e8e1df78..ec2ba46fbd 100644
|
||||||
|
--- a/include/openssl/evp.h
|
||||||
|
+++ b/include/openssl/evp.h
|
||||||
|
@@ -746,6 +746,10 @@ void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
|
||||||
|
void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
|
||||||
|
int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);
|
||||||
|
|
||||||
|
+# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
|
||||||
|
+# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_APPROVED 1
|
||||||
|
+# define EVP_CIPHER_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
|
||||||
|
+
|
||||||
|
__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, const unsigned char *iv);
|
||||||
|
/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
|
||||||
|
diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c
|
||||||
|
index fa383165d8..716add7339 100644
|
||||||
|
--- a/providers/implementations/ciphers/ciphercommon.c
|
||||||
|
+++ b/providers/implementations/ciphers/ciphercommon.c
|
||||||
|
@@ -149,6 +149,10 @@ static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
|
||||||
|
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
|
||||||
|
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
|
||||||
|
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0),
|
||||||
|
+ /* normally we would hide this under an #ifdef FIPS_MODULE, but that does
|
||||||
|
+ * not work in ciphercommon.c because it is compiled only once into
|
||||||
|
+ * libcommon.a */
|
||||||
|
+ OSSL_PARAM_int(OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR, NULL),
|
||||||
|
OSSL_PARAM_END
|
||||||
|
};
|
||||||
|
const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params(
|
||||||
|
diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c
|
||||||
|
index ed95c97ff4..db7910eb0e 100644
|
||||||
|
--- a/providers/implementations/ciphers/ciphercommon_gcm.c
|
||||||
|
+++ b/providers/implementations/ciphers/ciphercommon_gcm.c
|
||||||
|
@@ -224,6 +224,31 @@ int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||||
|
|| !getivgen(ctx, p->data, p->data_size))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* We would usually hide this under #ifdef FIPS_MODULE, but
|
||||||
|
+ * ciphercommon_gcm.c is only compiled once into libcommon.a, so ifdefs do
|
||||||
|
+ * not work here. */
|
||||||
|
+ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_REDHAT_FIPS_INDICATOR);
|
||||||
|
+ if (p != NULL) {
|
||||||
|
+ int fips_indicator = EVP_CIPHER_REDHAT_FIPS_INDICATOR_APPROVED;
|
||||||
|
+
|
||||||
|
+ /* Implementation Guidance for FIPS 140-3 and the Cryptographic Module
|
||||||
|
+ * Verification Program, Section C.H requires guarantees about the
|
||||||
|
+ * uniqueness of key/iv pairs, and proposes a few approaches to ensure
|
||||||
|
+ * this. This provides an indicator for option 2 "The IV may be
|
||||||
|
+ * generated internally at its entirety randomly." Note that one of the
|
||||||
|
+ * conditions of this option is that "The IV length shall be at least
|
||||||
|
+ * 96 bits (per SP 800-38D)." We do not specically check for this
|
||||||
|
+ * condition here, because gcm_iv_generate will fail in this case. */
|
||||||
|
+ if (ctx->enc && !ctx->iv_gen_rand)
|
||||||
|
+ fips_indicator = EVP_CIPHER_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+
|
||||||
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator)) {
|
||||||
|
+ ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
From 56090fca0a0c8b6cf1782aced0a02349358aae7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Fri, 3 Mar 2023 12:22:03 +0100
|
||||||
|
Subject: [PATCH 1/2] fips: Use salt >= 16 bytes in PBKDF2 selftest
|
||||||
|
|
||||||
|
NIST SP 800-132 [1] section 5.1 says "[t]he length of the
|
||||||
|
randomly-generated portion of the salt shall be at least
|
||||||
|
128 bits", which implies that the salt for PBKDF2 must be at least 16
|
||||||
|
bytes long (see also Appendix A.2.1).
|
||||||
|
|
||||||
|
The FIPS 140-3 IG [2] section 10.3.A requires that "the lengths and the
|
||||||
|
properties of the Password and Salt parameters, as well as the desired
|
||||||
|
length of the Master Key used in a CAST shall be among those supported
|
||||||
|
by the module in the approved mode."
|
||||||
|
|
||||||
|
As a consequence, the salt length in the self test must be at least 16
|
||||||
|
bytes long for FIPS 140-3 compliance. Switch the self test to use the
|
||||||
|
only test vector from RFC 6070 that uses salt that is long enough to
|
||||||
|
fulfil this requirement. Since RFC 6070 does not provide expected
|
||||||
|
results for PBKDF2 with HMAC-SHA256, use the output from [3], which was
|
||||||
|
generated with python cryptography, which was tested against the RFC
|
||||||
|
6070 vectors with HMAC-SHA1.
|
||||||
|
|
||||||
|
[1]: https://doi.org/10.6028/NIST.SP.800-132
|
||||||
|
[2]: https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf
|
||||||
|
[3]: https://github.com/brycx/Test-Vector-Generation/blob/master/PBKDF2/pbkdf2-hmac-sha2-test-vectors.md
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
|
||||||
|
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||||
|
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
||||||
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||||
|
(Merged from https://github.com/openssl/openssl/pull/20429)
|
||||||
|
|
||||||
|
(cherry picked from commit 451cb23c41c90d5a02902b3a77551aa9ee1c6956)
|
||||||
|
---
|
||||||
|
providers/fips/self_test_data.inc | 22 ++++++++++++++++------
|
||||||
|
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc
|
||||||
|
index 8ae8cd6f4a..03adf28f3c 100644
|
||||||
|
--- a/providers/fips/self_test_data.inc
|
||||||
|
+++ b/providers/fips/self_test_data.inc
|
||||||
|
@@ -361,19 +361,29 @@ static const ST_KAT_PARAM x963kdf_params[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char pbkdf2_digest[] = "SHA256";
|
||||||
|
+/*
|
||||||
|
+ * Input parameters from RFC 6070, vector 5 (because it is the only one with
|
||||||
|
+ * a salt >= 16 bytes, which NIST SP 800-132 section 5.1 requires). The
|
||||||
|
+ * expected output is taken from
|
||||||
|
+ * https://github.com/brycx/Test-Vector-Generation/blob/master/PBKDF2/pbkdf2-hmac-sha2-test-vectors.md,
|
||||||
|
+ * which ran these test vectors with SHA-256.
|
||||||
|
+ */
|
||||||
|
static const unsigned char pbkdf2_password[] = {
|
||||||
|
- 0x70, 0x61, 0x73, 0x73, 0x00, 0x77, 0x6f, 0x72,
|
||||||
|
- 0x64
|
||||||
|
+ 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x50, 0x41, 0x53, 0x53,
|
||||||
|
+ 0x57, 0x4f, 0x52, 0x44, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64
|
||||||
|
};
|
||||||
|
static const unsigned char pbkdf2_salt[] = {
|
||||||
|
- 0x73, 0x61, 0x00, 0x6c, 0x74
|
||||||
|
+ 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74,
|
||||||
|
+ 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54,
|
||||||
|
+ 0x73, 0x61, 0x6c, 0x74, 0x53, 0x41, 0x4c, 0x54, 0x73, 0x61, 0x6c, 0x74
|
||||||
|
};
|
||||||
|
static const unsigned char pbkdf2_expected[] = {
|
||||||
|
- 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
|
||||||
|
- 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87,
|
||||||
|
+ 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8,
|
||||||
|
+ 0x11, 0x6e, 0x84, 0xcf, 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
|
||||||
|
+ 0x1c
|
||||||
|
};
|
||||||
|
static int pbkdf2_iterations = 4096;
|
||||||
|
-static int pbkdf2_pkcs5 = 1;
|
||||||
|
+static int pbkdf2_pkcs5 = 0;
|
||||||
|
static const ST_KAT_PARAM pbkdf2_params[] = {
|
||||||
|
ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, pbkdf2_digest),
|
||||||
|
ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_PASSWORD, pbkdf2_password),
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
From fa96a2f493276e7a57512e8c3d535052586f1525 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Mon, 6 Mar 2023 12:32:04 +0100
|
||||||
|
Subject: [PATCH 2/2] pbdkf2: Set indicator if pkcs5 param disabled checks
|
||||||
|
|
||||||
|
The pbkdf2 implementation in the FIPS provider supports the checks
|
||||||
|
required by NIST, but allows disabling these checks by setting the
|
||||||
|
OSSL_KDF_PARAM_PKCS5 parameter to 1. The implementation must indicate
|
||||||
|
that the use of this configuration is not approved in FIPS mode. Add an
|
||||||
|
explicit indicator to provide this indication.
|
||||||
|
|
||||||
|
Resolves: rhbz#2175145
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
---
|
||||||
|
providers/implementations/kdfs/pbkdf2.c | 40 +++++++++++++++++++++++--
|
||||||
|
1 file changed, 37 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
|
||||||
|
index aa0adce5e6..6df8c6d321 100644
|
||||||
|
--- a/providers/implementations/kdfs/pbkdf2.c
|
||||||
|
+++ b/providers/implementations/kdfs/pbkdf2.c
|
||||||
|
@@ -251,11 +251,42 @@ static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(ossl_unused void *ctx,
|
||||||
|
|
||||||
|
static int kdf_pbkdf2_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||||
|
{
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
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, SIZE_MAX))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#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;
|
||||||
|
+
|
||||||
|
+ /* The lower_bound_checks parameter enables checks required by FIPS. If
|
||||||
|
+ * those checks are disabled, the PBKDF2 implementation will also
|
||||||
|
+ * support non-approved parameters (e.g., salt lengths < 16 bytes, see
|
||||||
|
+ * NIST SP 800-132 section 5.1). */
|
||||||
|
+ if (!ctx->lower_bound_checks)
|
||||||
|
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
|
||||||
|
- if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
|
||||||
|
- return OSSL_PARAM_set_size_t(p, SIZE_MAX);
|
||||||
|
- return -2;
|
||||||
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ any_valid = 1;
|
||||||
|
+ }
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
+ if (!any_valid)
|
||||||
|
+ return -2;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(ossl_unused void *ctx,
|
||||||
|
@@ -263,6 +294,9 @@ static const OSSL_PARAM *kdf_pbkdf2_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;
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,150 @@
|
|||||||
|
From ee6e381e4140efd5365ddf27a12055859103cf59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Lang <cllang@redhat.com>
|
||||||
|
Date: Fri, 17 Mar 2023 15:39:15 +0100
|
||||||
|
Subject: [PATCH] asymciphers, kem: Add explicit FIPS indicator
|
||||||
|
|
||||||
|
NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key
|
||||||
|
confirmation (section 6.4.2.3.2), or assurance from a trusted third
|
||||||
|
party (section 6.4.2.3.1) for the KTS-OAEP key transport scheme and key
|
||||||
|
agreement schemes, but explicit key confirmation is not implemented and
|
||||||
|
cannot be implemented without protocol changes, and the FIPS provider
|
||||||
|
does not implement trusted third party validation, since it relies on
|
||||||
|
its callers to do that. We must thus mark RSA-OAEP encryption and RSASVE
|
||||||
|
as unapproved until we have received clarification from NIST on how
|
||||||
|
library modules such as OpenSSL should implement TTP validation.
|
||||||
|
|
||||||
|
This does not affect RSA-OAEP decryption, because it is approved as
|
||||||
|
a component according to the FIPS 140-3 IG, section 2.4.G.
|
||||||
|
|
||||||
|
Resolves: rhbz#2179331
|
||||||
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
||||||
|
---
|
||||||
|
include/openssl/core_names.h | 2 ++
|
||||||
|
include/openssl/evp.h | 4 +++
|
||||||
|
.../implementations/asymciphers/rsa_enc.c | 24 +++++++++++++++
|
||||||
|
providers/implementations/kem/rsa_kem.c | 30 ++++++++++++++++++-
|
||||||
|
4 files changed, 59 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
|
||||||
|
index 832502a034..e15d208421 100644
|
||||||
|
--- a/include/openssl/core_names.h
|
||||||
|
+++ b/include/openssl/core_names.h
|
||||||
|
@@ -477,6 +477,7 @@ extern "C" {
|
||||||
|
#ifdef FIPS_MODULE
|
||||||
|
#define OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED "redhat-kat-oaep-seed"
|
||||||
|
#endif
|
||||||
|
+#define OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encoder / decoder parameters
|
||||||
|
@@ -503,6 +504,7 @@ extern "C" {
|
||||||
|
|
||||||
|
/* KEM parameters */
|
||||||
|
#define OSSL_KEM_PARAM_OPERATION "operation"
|
||||||
|
+#define OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator" /* int */
|
||||||
|
|
||||||
|
/* OSSL_KEM_PARAM_OPERATION values */
|
||||||
|
#define OSSL_KEM_PARAM_OPERATION_RSASVE "RSASVE"
|
||||||
|
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
|
||||||
|
index ec2ba46fbd..3803b03422 100644
|
||||||
|
--- a/include/openssl/evp.h
|
||||||
|
+++ b/include/openssl/evp.h
|
||||||
|
@@ -1757,6 +1757,10 @@ OSSL_DEPRECATEDIN_3_0 size_t EVP_PKEY_meth_get_count(void);
|
||||||
|
OSSL_DEPRECATEDIN_3_0 const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
+# define EVP_PKEY_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
|
||||||
|
+# define EVP_PKEY_REDHAT_FIPS_INDICATOR_APPROVED 1
|
||||||
|
+# define EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
|
||||||
|
+
|
||||||
|
EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
|
||||||
|
const char *properties);
|
||||||
|
int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt);
|
||||||
|
diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c
|
||||||
|
index 568452ec56..2e7ea632d7 100644
|
||||||
|
--- a/providers/implementations/asymciphers/rsa_enc.c
|
||||||
|
+++ b/providers/implementations/asymciphers/rsa_enc.c
|
||||||
|
@@ -399,6 +399,27 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
|
||||||
|
if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->alt_version))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR);
|
||||||
|
+ if (p != NULL) {
|
||||||
|
+ int fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_APPROVED;
|
||||||
|
+
|
||||||
|
+ /* NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key
|
||||||
|
+ * confirmation (section 6.4.2.3.2), or assurance from a trusted third
|
||||||
|
+ * party (section 6.4.2.3.1) for the KTS-OAEP key transport scheme, but
|
||||||
|
+ * explicit key confirmation is not implemented here and cannot be
|
||||||
|
+ * implemented without protocol changes, and the FIPS provider does not
|
||||||
|
+ * implement trusted third party validation, since it relies on its
|
||||||
|
+ * callers to do that. We must thus mark RSA-OAEP as unapproved until
|
||||||
|
+ * we have received clarification from NIST on how library modules such
|
||||||
|
+ * as OpenSSL should implement TTP validation. */
|
||||||
|
+ fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+
|
||||||
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -465,6 +493,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = {
|
||||||
|
OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
|
||||||
|
#ifdef FIPS_MODULE
|
||||||
|
OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED, NULL, 0),
|
||||||
|
+ OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_REDHAT_FIPS_INDICATOR, NULL),
|
||||||
|
#endif /* FIPS_MODULE */
|
||||||
|
OSSL_PARAM_END
|
||||||
|
};
|
||||||
|
diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c
|
||||||
|
index 882cf16125..b4cc0f9237 100644
|
||||||
|
--- a/providers/implementations/kem/rsa_kem.c
|
||||||
|
+++ b/providers/implementations/kem/rsa_kem.c
|
||||||
|
@@ -151,11 +151,39 @@ static int rsakem_decapsulate_init(void *vprsactx, void *vrsa,
|
||||||
|
static int rsakem_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
|
||||||
|
{
|
||||||
|
PROV_RSA_CTX *ctx = (PROV_RSA_CTX *)vprsactx;
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ OSSL_PARAM *p;
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
+
|
||||||
|
+ if (ctx == NULL)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ p = OSSL_PARAM_locate(params, OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR);
|
||||||
|
+ if (p != NULL) {
|
||||||
|
+ /* NIST SP 800-56Br2 section 6.4.2.1 requires either explicit key
|
||||||
|
+ * confirmation (section 6.4.2.3.2), or assurance from a trusted third
|
||||||
|
+ * party (section 6.4.2.3.1) for key agreement or key transport, but
|
||||||
|
+ * explicit key confirmation is not implemented here and cannot be
|
||||||
|
+ * implemented without protocol changes, and the FIPS provider does not
|
||||||
|
+ * implement trusted third party validation, since it relies on its
|
||||||
|
+ * callers to do that. We must thus mark RSASVE unapproved until we
|
||||||
|
+ * have received clarification from NIST on how library modules such as
|
||||||
|
+ * OpenSSL should implement TTP validation. */
|
||||||
|
+ int fips_indicator = EVP_PKEY_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
+
|
||||||
|
+ if (!OSSL_PARAM_set_int(p, fips_indicator))
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
|
||||||
|
- return ctx != NULL;
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const OSSL_PARAM known_gettable_rsakem_ctx_params[] = {
|
||||||
|
+#ifdef FIPS_MODULE
|
||||||
|
+ OSSL_PARAM_int(OSSL_KEM_PARAM_REDHAT_FIPS_INDICATOR, NULL),
|
||||||
|
+#endif /* defined(FIPS_MODULE) */
|
||||||
|
OSSL_PARAM_END
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,473 @@
|
|||||||
|
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
|
||||||
|
index e90e5dc03339..f391e756475c 100644
|
||||||
|
--- a/crypto/err/openssl.txt
|
||||||
|
+++ b/crypto/err/openssl.txt
|
||||||
|
@@ -1006,6 +1006,7 @@ PROV_R_BN_ERROR:160:bn error
|
||||||
|
PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
|
||||||
|
PROV_R_DERIVATION_FUNCTION_INIT_FAILED:205:derivation function init failed
|
||||||
|
PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed
|
||||||
|
+PROV_R_EMS_NOT_ENABLED:233:ems not enabled
|
||||||
|
PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK:186:entropy source strength too weak
|
||||||
|
PROV_R_ERROR_INSTANTIATING_DRBG:188:error instantiating drbg
|
||||||
|
PROV_R_ERROR_RETRIEVING_ENTROPY:189:error retrieving entropy
|
||||||
|
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
|
||||||
|
index 173a81d28bbe..5e5be567a578 100644
|
||||||
|
--- a/include/openssl/core_names.h
|
||||||
|
+++ b/include/openssl/core_names.h
|
||||||
|
@@ -21,11 +21,12 @@ extern "C" {
|
||||||
|
#define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" /* utf8_ptr */
|
||||||
|
|
||||||
|
/* Well known parameter names that Providers can define */
|
||||||
|
-#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */
|
||||||
|
-#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */
|
||||||
|
-#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */
|
||||||
|
-#define OSSL_PROV_PARAM_STATUS "status" /* uint */
|
||||||
|
-#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */
|
||||||
|
+#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */
|
||||||
|
+#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */
|
||||||
|
+#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */
|
||||||
|
+#define OSSL_PROV_PARAM_STATUS "status" /* uint */
|
||||||
|
+#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */
|
||||||
|
+#define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" /* uint */
|
||||||
|
|
||||||
|
/* Self test callback parameters */
|
||||||
|
#define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */
|
||||||
|
diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h
|
||||||
|
index 0fdf5440c7cb..3f29369b3f92 100644
|
||||||
|
--- a/include/openssl/fips_names.h
|
||||||
|
+++ b/include/openssl/fips_names.h
|
||||||
|
@@ -53,6 +53,14 @@ extern "C" {
|
||||||
|
*/
|
||||||
|
# define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks"
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * A boolean that determines if the runtime FIPS check for TLS1_PRF EMS is performed.
|
||||||
|
+ * This is disabled by default.
|
||||||
|
+ *
|
||||||
|
+ * Type: OSSL_PARAM_UTF8_STRING
|
||||||
|
+ */
|
||||||
|
+# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check"
|
||||||
|
+
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h
|
||||||
|
index 3685430f5d3e..bf4dc135f592 100644
|
||||||
|
--- a/include/openssl/proverr.h
|
||||||
|
+++ b/include/openssl/proverr.h
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
# define PROV_R_CIPHER_OPERATION_FAILED 102
|
||||||
|
# define PROV_R_DERIVATION_FUNCTION_INIT_FAILED 205
|
||||||
|
# define PROV_R_DIGEST_NOT_ALLOWED 174
|
||||||
|
+# define PROV_R_EMS_NOT_ENABLED 233
|
||||||
|
# define PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK 186
|
||||||
|
# define PROV_R_ERROR_INSTANTIATING_DRBG 188
|
||||||
|
# define PROV_R_ERROR_RETRIEVING_ENTROPY 189
|
||||||
|
diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h
|
||||||
|
index 4a7f85f71186..62e60cc0103f 100644
|
||||||
|
--- a/providers/common/include/prov/securitycheck.h
|
||||||
|
+++ b/providers/common/include/prov/securitycheck.h
|
||||||
|
@@ -28,3 +28,4 @@ int ossl_digest_get_approved_nid(const EVP_MD *md);
|
||||||
|
int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||||
|
int sha1_allowed);
|
||||||
|
int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx);
|
||||||
|
+int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx);
|
||||||
|
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
|
||||||
|
index f6144072aa04..954aabe80cfc 100644
|
||||||
|
--- a/providers/common/provider_err.c
|
||||||
|
+++ b/providers/common/provider_err.c
|
||||||
|
@@ -33,6 +33,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||||
|
"derivation function init failed"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED),
|
||||||
|
"digest not allowed"},
|
||||||
|
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_EMS_NOT_ENABLED), "ems not enabled"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK),
|
||||||
|
"entropy source strength too weak"},
|
||||||
|
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_INSTANTIATING_DRBG),
|
||||||
|
diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c
|
||||||
|
index de7f0d3a0a57..63c875ecd0b7 100644
|
||||||
|
--- a/providers/common/securitycheck_default.c
|
||||||
|
+++ b/providers/common/securitycheck_default.c
|
||||||
|
@@ -22,6 +22,12 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Disable the ems check in the default provider */
|
||||||
|
+int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||||
|
int sha1_allowed)
|
||||||
|
{
|
||||||
|
diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c
|
||||||
|
index b7659bd395c3..2bc8a5992685 100644
|
||||||
|
--- a/providers/common/securitycheck_fips.c
|
||||||
|
+++ b/providers/common/securitycheck_fips.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include "prov/securitycheck.h"
|
||||||
|
|
||||||
|
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
|
||||||
|
+int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
|
||||||
|
|
||||||
|
int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
{
|
||||||
|
@@ -30,6 +31,11 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
|
||||||
|
}
|
||||||
|
|
||||||
|
+int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
+{
|
||||||
|
+ return FIPS_tls_prf_ems_check(libctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||||
|
int sha1_allowed)
|
||||||
|
{
|
||||||
|
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
|
||||||
|
index b86b27d236f3..b881f46f36ad 100644
|
||||||
|
--- a/providers/fips/fipsprov.c
|
||||||
|
+++ b/providers/fips/fipsprov.c
|
||||||
|
@@ -47,6 +47,7 @@ static OSSL_FUNC_provider_query_operation_fn fips_query;
|
||||||
|
#define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
|
||||||
|
extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
|
||||||
|
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
|
||||||
|
+int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should these function pointers be stored in the provider side provctx? Could
|
||||||
|
@@ -82,7 +83,9 @@ typedef struct fips_global_st {
|
||||||
|
const OSSL_CORE_HANDLE *handle;
|
||||||
|
SELF_TEST_POST_PARAMS selftest_params;
|
||||||
|
int fips_security_checks;
|
||||||
|
+ int fips_tls1_prf_ems_check;
|
||||||
|
const char *fips_security_check_option;
|
||||||
|
+ const char *fips_tls1_prf_ems_check_option;
|
||||||
|
} FIPS_GLOBAL;
|
||||||
|
|
||||||
|
static void *fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
|
||||||
|
@@ -94,6 +97,9 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
|
||||||
|
fgbl->fips_security_checks = 1;
|
||||||
|
fgbl->fips_security_check_option = "1";
|
||||||
|
|
||||||
|
+ fgbl->fips_tls1_prf_ems_check = 1; /* Enabled */
|
||||||
|
+ fgbl->fips_tls1_prf_ems_check_option = "1";
|
||||||
|
+
|
||||||
|
return fgbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -109,6 +115,7 @@ static const OSSL_PARAM fips_param_types[] = {
|
||||||
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
|
||||||
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
|
||||||
|
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0),
|
||||||
|
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, OSSL_PARAM_INTEGER, NULL, 0), /* Ignored in RHEL */
|
||||||
|
OSSL_PARAM_END
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -119,9 +126,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
|
||||||
|
* NOTE: inside core_get_params() these will be loaded from config items
|
||||||
|
* stored inside prov->parameters (except for
|
||||||
|
* OSSL_PROV_PARAM_CORE_MODULE_FILENAME).
|
||||||
|
- * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS is not a self test parameter.
|
||||||
|
+ * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and
|
||||||
|
+ * OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters.
|
||||||
|
*/
|
||||||
|
- OSSL_PARAM core_params[8], *p = core_params;
|
||||||
|
+ OSSL_PARAM core_params[9], *p = core_params;
|
||||||
|
|
||||||
|
*p++ = OSSL_PARAM_construct_utf8_ptr(
|
||||||
|
OSSL_PROV_PARAM_CORE_MODULE_FILENAME,
|
||||||
|
@@ -151,6 +159,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
|
||||||
|
OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
|
||||||
|
(char **)&fgbl->fips_security_check_option,
|
||||||
|
sizeof(fgbl->fips_security_check_option));
|
||||||
|
+ /* *p++ = OSSL_PARAM_construct_utf8_ptr(
|
||||||
|
+ OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK,
|
||||||
|
+ (char **)&fgbl->fips_tls1_prf_ems_check_option,
|
||||||
|
+ sizeof(fgbl->fips_tls1_prf_ems_check_option)); */ /* Ignored in RHEL */
|
||||||
|
*p = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (!c_get_params(fgbl->handle, core_params)) {
|
||||||
|
@@ -187,6 +199,9 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
|
||||||
|
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS);
|
||||||
|
if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_security_checks))
|
||||||
|
return 0;
|
||||||
|
+ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK);
|
||||||
|
+ if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_tls1_prf_ems_check))
|
||||||
|
+ return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -703,6 +718,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
|
||||||
|
&& strcmp(fgbl->fips_security_check_option, "0") == 0)
|
||||||
|
fgbl->fips_security_checks = 0;
|
||||||
|
|
||||||
|
+ /* Enable the ems check. */
|
||||||
|
+ fgbl->fips_tls1_prf_ems_check = 1;
|
||||||
|
+
|
||||||
|
ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
|
||||||
|
|
||||||
|
if (!SELF_TEST_post(&fgbl->selftest_params, 0)) {
|
||||||
|
@@ -898,6 +918,15 @@ int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx)
|
||||||
|
return fgbl->fips_security_checks;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx)
|
||||||
|
+{
|
||||||
|
+ FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx,
|
||||||
|
+ OSSL_LIB_CTX_FIPS_PROV_INDEX,
|
||||||
|
+ &fips_prov_ossl_ctx_method);
|
||||||
|
+
|
||||||
|
+ return fgbl->fips_tls1_prf_ems_check;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb,
|
||||||
|
void **cbarg)
|
||||||
|
{
|
||||||
|
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
index 8a3807308408..2c2dbf31cc0b 100644
|
||||||
|
--- a/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
+++ b/providers/implementations/kdfs/tls1_prf.c
|
||||||
|
@@ -45,6 +45,13 @@
|
||||||
|
* A(0) = seed
|
||||||
|
* A(i) = HMAC_<hash>(secret, A(i-1))
|
||||||
|
*/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Low level APIs (such as DH) are deprecated for public use, but still ok for
|
||||||
|
+ * internal use.
|
||||||
|
+ */
|
||||||
|
+#include "internal/deprecated.h"
|
||||||
|
+
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -60,6 +67,7 @@
|
||||||
|
#include "prov/providercommon.h"
|
||||||
|
#include "prov/implementations.h"
|
||||||
|
#include "prov/provider_util.h"
|
||||||
|
+#include "prov/securitycheck.h"
|
||||||
|
#include "e_os.h"
|
||||||
|
|
||||||
|
static OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new;
|
||||||
|
@@ -78,6 +86,8 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
|
||||||
|
unsigned char *out, size_t olen);
|
||||||
|
|
||||||
|
#define TLS1_PRF_MAXBUF 1024
|
||||||
|
+#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
|
||||||
|
+#define TLS_MD_MASTER_SECRET_CONST_SIZE 13
|
||||||
|
|
||||||
|
/* TLS KDF kdf context structure */
|
||||||
|
typedef struct {
|
||||||
|
@@ -160,6 +170,7 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
|
||||||
|
const OSSL_PARAM params[])
|
||||||
|
{
|
||||||
|
TLS1_PRF *ctx = (TLS1_PRF *)vctx;
|
||||||
|
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
|
||||||
|
|
||||||
|
if (!ossl_prov_is_running() || !kdf_tls1_prf_set_ctx_params(ctx, params))
|
||||||
|
return 0;
|
||||||
|
@@ -181,6 +192,21 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
|
||||||
|
ctx->output_keylen_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
|
||||||
|
#endif /* defined(FIPS_MODULE) */
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * The seed buffer is prepended with a label.
|
||||||
|
+ * If EMS mode is enforced then the label "master secret" is not allowed,
|
||||||
|
+ * We do the check this way since the PRF is used for other purposes, as well
|
||||||
|
+ * as "extended master secret".
|
||||||
|
+ */
|
||||||
|
+ if (ossl_tls1_prf_ems_check_enabled(libctx)) {
|
||||||
|
+ if (ctx->seedlen >= TLS_MD_MASTER_SECRET_CONST_SIZE
|
||||||
|
+ && memcmp(ctx->seed, TLS_MD_MASTER_SECRET_CONST,
|
||||||
|
+ TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) {
|
||||||
|
+ ERR_raise(ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
|
||||||
|
ctx->sec, ctx->seclen,
|
||||||
|
ctx->seed, ctx->seedlen,
|
||||||
|
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||||
|
index 3a8242d2d8c8..b0fbb504689e 100644
|
||||||
|
--- a/test/sslapitest.c
|
||||||
|
+++ b/test/sslapitest.c
|
||||||
|
@@ -99,6 +99,7 @@ static char *tmpfilename = NULL;
|
||||||
|
static char *dhfile = NULL;
|
||||||
|
|
||||||
|
static int is_fips = 0;
|
||||||
|
+static int fips_ems_check = 0;
|
||||||
|
|
||||||
|
#define LOG_BUFFER_SIZE 2048
|
||||||
|
static char server_log_buffer[LOG_BUFFER_SIZE + 1] = {0};
|
||||||
|
@@ -796,7 +797,7 @@ static int test_no_ems(void)
|
||||||
|
{
|
||||||
|
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||||
|
SSL *clientssl = NULL, *serverssl = NULL;
|
||||||
|
- int testresult = 0;
|
||||||
|
+ int testresult = 0, status;
|
||||||
|
|
||||||
|
if (!create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(),
|
||||||
|
TLS1_VERSION, TLS1_2_VERSION,
|
||||||
|
@@ -812,19 +813,25 @@ static int test_no_ems(void)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) {
|
||||||
|
- printf("Creating SSL connection failed\n");
|
||||||
|
- goto end;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (SSL_get_extms_support(serverssl)) {
|
||||||
|
- printf("Server reports Extended Master Secret support\n");
|
||||||
|
- goto end;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (SSL_get_extms_support(clientssl)) {
|
||||||
|
- printf("Client reports Extended Master Secret support\n");
|
||||||
|
- goto end;
|
||||||
|
+ status = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE);
|
||||||
|
+ if (fips_ems_check) {
|
||||||
|
+ if (status == 1) {
|
||||||
|
+ printf("When FIPS uses the EMS check a connection that doesnt use EMS should fail\n");
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if (!status) {
|
||||||
|
+ printf("Creating SSL connection failed\n");
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ if (SSL_get_extms_support(serverssl)) {
|
||||||
|
+ printf("Server reports Extended Master Secret support\n");
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ if (SSL_get_extms_support(clientssl)) {
|
||||||
|
+ printf("Client reports Extended Master Secret support\n");
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
testresult = 1;
|
||||||
|
|
||||||
|
@@ -10740,9 +10747,24 @@ int setup_tests(void)
|
||||||
|
&& !TEST_false(OSSL_PROVIDER_available(libctx, "default")))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (strcmp(modulename, "fips") == 0)
|
||||||
|
+ if (strcmp(modulename, "fips") == 0) {
|
||||||
|
+ OSSL_PROVIDER *prov = NULL;
|
||||||
|
+ OSSL_PARAM params[2];
|
||||||
|
+
|
||||||
|
is_fips = 1;
|
||||||
|
|
||||||
|
+ prov = OSSL_PROVIDER_load(libctx, "fips");
|
||||||
|
+ if (prov != NULL) {
|
||||||
|
+ /* Query the fips provider to check if the check ems option is enabled */
|
||||||
|
+ params[0] =
|
||||||
|
+ OSSL_PARAM_construct_int(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
|
||||||
|
+ &fips_ems_check);
|
||||||
|
+ params[1] = OSSL_PARAM_construct_end();
|
||||||
|
+ OSSL_PROVIDER_get_params(prov, params);
|
||||||
|
+ OSSL_PROVIDER_unload(prov);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* We add, but don't load the test "tls-provider". We'll load it when we
|
||||||
|
* need it.
|
||||||
|
@@ -10816,6 +10838,12 @@ int setup_tests(void)
|
||||||
|
if (privkey8192 == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
+ if (fips_ems_check) {
|
||||||
|
+#ifndef OPENSSL_NO_TLS1_2
|
||||||
|
+ ADD_TEST(test_no_ems);
|
||||||
|
+#endif
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK)
|
||||||
|
# if !defined(OPENSSL_NO_TLS1_2) || !defined(OSSL_NO_USABLE_TLS1_3)
|
||||||
|
ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4);
|
||||||
|
diff -up openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt.xxx openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt
|
||||||
|
--- openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt.xxx 2023-04-17 13:04:21.078501747 +0200
|
||||||
|
+++ openssl-3.0.7/test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt 2023-04-17 13:11:03.189059638 +0200
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
|
||||||
|
Title = TLS12 PRF tests (from NIST test vectors)
|
||||||
|
|
||||||
|
+Availablein = default
|
||||||
|
KDF = TLS1-PRF
|
||||||
|
Ctrl.digest = digest:SHA256
|
||||||
|
Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc
|
||||||
|
@@ -21,6 +22,16 @@ Ctrl.client_random = hexseed:36c129d01a3
|
||||||
|
Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce
|
||||||
|
Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf
|
||||||
|
|
||||||
|
+Availablein = fips
|
||||||
|
+KDF = TLS1-PRF
|
||||||
|
+Ctrl.digest = digest:SHA256
|
||||||
|
+Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc
|
||||||
|
+Ctrl.label = seed:master secret
|
||||||
|
+Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c
|
||||||
|
+Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce
|
||||||
|
+Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf
|
||||||
|
+Result = KDF_DERIVE_ERROR
|
||||||
|
+
|
||||||
|
KDF = TLS1-PRF
|
||||||
|
Ctrl.digest = digest:SHA256
|
||||||
|
Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf
|
||||||
|
diff -up openssl-3.0.7/ssl/t1_enc.c.noems openssl-3.0.7/ssl/t1_enc.c
|
||||||
|
--- openssl-3.0.7/ssl/t1_enc.c.noems 2023-05-05 11:15:57.934415272 +0200
|
||||||
|
+++ openssl-3.0.7/ssl/t1_enc.c 2023-05-05 11:39:03.578163778 +0200
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include <openssl/obj_mac.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
#include <openssl/trace.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
|
||||||
|
/* seed1 through seed5 are concatenated */
|
||||||
|
static int tls1_PRF(SSL *s,
|
||||||
|
@@ -75,8 +76,14 @@ static int tls1_PRF(SSL *s,
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
- if (fatal)
|
||||||
|
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
+ if (fatal) {
|
||||||
|
+ /* The calls to this function are local so it's safe to implement the check */
|
||||||
|
+ if (FIPS_mode() && seed1_len >= TLS_MD_MASTER_SECRET_CONST_SIZE
|
||||||
|
+ && memcmp(seed1, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE) == 0)
|
||||||
|
+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_UNSUPPORTED);
|
||||||
|
+ else
|
||||||
|
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
|
||||||
|
EVP_KDF_CTX_free(kctx);
|
||||||
|
diff -up openssl-3.0.7/ssl/statem/extensions_srvr.c.noems openssl-3.0.7/ssl/statem/extensions_srvr.c
|
||||||
|
--- openssl-3.0.7/ssl/statem/extensions_srvr.c.noems 2023-05-05 17:14:04.663800271 +0200
|
||||||
|
+++ openssl-3.0.7/ssl/statem/extensions_srvr.c 2023-05-05 17:20:33.764599507 +0200
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include "../ssl_local.h"
|
||||||
|
#include "statem_local.h"
|
||||||
|
#include "internal/cryptlib.h"
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
|
||||||
|
#define COOKIE_STATE_FORMAT_VERSION 1
|
||||||
|
|
||||||
|
@@ -1552,8 +1553,13 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s
|
||||||
|
EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context,
|
||||||
|
X509 *x, size_t chainidx)
|
||||||
|
{
|
||||||
|
- if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0)
|
||||||
|
+ if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) {
|
||||||
|
+ if (FIPS_mode()) {
|
||||||
|
+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_UNSUPPORTED);
|
||||||
|
+ return EXT_RETURN_FAIL;
|
||||||
|
+ }
|
||||||
|
return EXT_RETURN_NOT_SENT;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
|
||||||
|
|| !WPACKET_put_bytes_u16(pkt, 0)) {
|
@ -0,0 +1,195 @@
|
|||||||
|
diff --git a/crypto/x509/pcy_local.h b/crypto/x509/pcy_local.h
|
||||||
|
index 18b53cc09e..cba107ca03 100644
|
||||||
|
--- a/crypto/x509/pcy_local.h
|
||||||
|
+++ b/crypto/x509/pcy_local.h
|
||||||
|
@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct X509_POLICY_TREE_st {
|
||||||
|
+ /* The number of nodes in the tree */
|
||||||
|
+ size_t node_count;
|
||||||
|
+ /* The maximum number of nodes in the tree */
|
||||||
|
+ size_t node_maximum;
|
||||||
|
+
|
||||||
|
/* This is the tree 'level' data */
|
||||||
|
X509_POLICY_LEVEL *levels;
|
||||||
|
int nlevel;
|
||||||
|
@@ -157,7 +162,8 @@ X509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
|
||||||
|
X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
|
||||||
|
X509_POLICY_DATA *data,
|
||||||
|
X509_POLICY_NODE *parent,
|
||||||
|
- X509_POLICY_TREE *tree);
|
||||||
|
+ X509_POLICY_TREE *tree,
|
||||||
|
+ int extra_data);
|
||||||
|
void ossl_policy_node_free(X509_POLICY_NODE *node);
|
||||||
|
int ossl_policy_node_match(const X509_POLICY_LEVEL *lvl,
|
||||||
|
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
|
||||||
|
diff --git a/crypto/x509/pcy_node.c b/crypto/x509/pcy_node.c
|
||||||
|
index 9d9a7ea179..450f95a655 100644
|
||||||
|
--- a/crypto/x509/pcy_node.c
|
||||||
|
+++ b/crypto/x509/pcy_node.c
|
||||||
|
@@ -59,10 +59,15 @@ X509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level,
|
||||||
|
X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
|
||||||
|
X509_POLICY_DATA *data,
|
||||||
|
X509_POLICY_NODE *parent,
|
||||||
|
- X509_POLICY_TREE *tree)
|
||||||
|
+ X509_POLICY_TREE *tree,
|
||||||
|
+ int extra_data)
|
||||||
|
{
|
||||||
|
X509_POLICY_NODE *node;
|
||||||
|
|
||||||
|
+ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */
|
||||||
|
+ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
node = OPENSSL_zalloc(sizeof(*node));
|
||||||
|
if (node == NULL) {
|
||||||
|
ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
|
||||||
|
@@ -70,7 +75,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
|
||||||
|
}
|
||||||
|
node->data = data;
|
||||||
|
node->parent = parent;
|
||||||
|
- if (level) {
|
||||||
|
+ if (level != NULL) {
|
||||||
|
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
|
||||||
|
if (level->anyPolicy)
|
||||||
|
goto node_error;
|
||||||
|
@@ -90,7 +95,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (tree) {
|
||||||
|
+ if (extra_data) {
|
||||||
|
if (tree->extra_data == NULL)
|
||||||
|
tree->extra_data = sk_X509_POLICY_DATA_new_null();
|
||||||
|
if (tree->extra_data == NULL){
|
||||||
|
@@ -103,6 +108,7 @@ X509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ tree->node_count++;
|
||||||
|
if (parent)
|
||||||
|
parent->nchild++;
|
||||||
|
|
||||||
|
diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c
|
||||||
|
index fa45da5117..f953a05a41 100644
|
||||||
|
--- a/crypto/x509/pcy_tree.c
|
||||||
|
+++ b/crypto/x509/pcy_tree.c
|
||||||
|
@@ -14,6 +14,17 @@
|
||||||
|
|
||||||
|
#include "pcy_local.h"
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * If the maximum number of nodes in the policy tree isn't defined, set it to
|
||||||
|
+ * a generous default of 1000 nodes.
|
||||||
|
+ *
|
||||||
|
+ * Defining this to be zero means unlimited policy tree growth which opens the
|
||||||
|
+ * door on CVE-2023-0464.
|
||||||
|
+ */
|
||||||
|
+#ifndef OPENSSL_POLICY_TREE_NODES_MAX
|
||||||
|
+# define OPENSSL_POLICY_TREE_NODES_MAX 1000
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static void expected_print(BIO *channel,
|
||||||
|
X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node,
|
||||||
|
int indent)
|
||||||
|
@@ -163,6 +174,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||||
|
return X509_PCY_TREE_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Limit the growth of the tree to mitigate CVE-2023-0464 */
|
||||||
|
+ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
|
||||||
|
*
|
||||||
|
@@ -180,7 +194,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||||
|
if ((data = ossl_policy_data_new(NULL,
|
||||||
|
OBJ_nid2obj(NID_any_policy), 0)) == NULL)
|
||||||
|
goto bad_tree;
|
||||||
|
- if (ossl_policy_level_add_node(level, data, NULL, tree) == NULL) {
|
||||||
|
+ if (ossl_policy_level_add_node(level, data, NULL, tree, 1) == NULL) {
|
||||||
|
ossl_policy_data_free(data);
|
||||||
|
goto bad_tree;
|
||||||
|
}
|
||||||
|
@@ -239,7 +253,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||||
|
* Return value: 1 on success, 0 otherwise
|
||||||
|
*/
|
||||||
|
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||||
|
- X509_POLICY_DATA *data)
|
||||||
|
+ X509_POLICY_DATA *data,
|
||||||
|
+ X509_POLICY_TREE *tree)
|
||||||
|
{
|
||||||
|
X509_POLICY_LEVEL *last = curr - 1;
|
||||||
|
int i, matched = 0;
|
||||||
|
@@ -249,13 +264,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||||
|
X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);
|
||||||
|
|
||||||
|
if (ossl_policy_node_match(last, node, data->valid_policy)) {
|
||||||
|
- if (ossl_policy_level_add_node(curr, data, node, NULL) == NULL)
|
||||||
|
+ if (ossl_policy_level_add_node(curr, data, node, tree, 0) == NULL)
|
||||||
|
return 0;
|
||||||
|
matched = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matched && last->anyPolicy) {
|
||||||
|
- if (ossl_policy_level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
|
||||||
|
+ if (ossl_policy_level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
@@ -268,7 +283,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||||
|
* Return value: 1 on success, 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int tree_link_nodes(X509_POLICY_LEVEL *curr,
|
||||||
|
- const X509_POLICY_CACHE *cache)
|
||||||
|
+ const X509_POLICY_CACHE *cache,
|
||||||
|
+ X509_POLICY_TREE *tree)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -276,7 +292,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
|
||||||
|
X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);
|
||||||
|
|
||||||
|
/* Look for matching nodes in previous level */
|
||||||
|
- if (!tree_link_matching_nodes(curr, data))
|
||||||
|
+ if (!tree_link_matching_nodes(curr, data, tree))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
@@ -307,7 +323,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
|
||||||
|
/* Curr may not have anyPolicy */
|
||||||
|
data->qualifier_set = cache->anyPolicy->qualifier_set;
|
||||||
|
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
|
||||||
|
- if (ossl_policy_level_add_node(curr, data, node, tree) == NULL) {
|
||||||
|
+ if (ossl_policy_level_add_node(curr, data, node, tree, 1) == NULL) {
|
||||||
|
ossl_policy_data_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -370,7 +386,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
|
||||||
|
/* Finally add link to anyPolicy */
|
||||||
|
if (last->anyPolicy &&
|
||||||
|
ossl_policy_level_add_node(curr, cache->anyPolicy,
|
||||||
|
- last->anyPolicy, NULL) == NULL)
|
||||||
|
+ last->anyPolicy, tree, 0) == NULL)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -553,7 +569,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree,
|
||||||
|
extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
|
||||||
|
| POLICY_DATA_FLAG_EXTRA_NODE;
|
||||||
|
node = ossl_policy_level_add_node(NULL, extra, anyPolicy->parent,
|
||||||
|
- tree);
|
||||||
|
+ tree, 1);
|
||||||
|
}
|
||||||
|
if (!tree->user_policies) {
|
||||||
|
tree->user_policies = sk_X509_POLICY_NODE_new_null();
|
||||||
|
@@ -580,7 +596,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
|
||||||
|
|
||||||
|
for (i = 1; i < tree->nlevel; i++, curr++) {
|
||||||
|
cache = ossl_policy_cache_set(curr->cert);
|
||||||
|
- if (!tree_link_nodes(curr, cache))
|
||||||
|
+ if (!tree_link_nodes(curr, cache, tree))
|
||||||
|
return X509_PCY_TREE_INTERNAL;
|
||||||
|
|
||||||
|
if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
|
@ -0,0 +1,179 @@
|
|||||||
|
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
|
||||||
|
index 9384f1da9b..a0282c3ef1 100644
|
||||||
|
--- a/crypto/x509/x509_vfy.c
|
||||||
|
+++ b/crypto/x509/x509_vfy.c
|
||||||
|
@@ -1654,15 +1654,23 @@ static int check_policy(X509_STORE_CTX *ctx)
|
||||||
|
goto memerr;
|
||||||
|
/* Invalid or inconsistent extensions */
|
||||||
|
if (ret == X509_PCY_TREE_INVALID) {
|
||||||
|
- int i;
|
||||||
|
+ int i, cbcalled = 0;
|
||||||
|
|
||||||
|
/* Locate certificates with bad extensions and notify callback. */
|
||||||
|
- for (i = 1; i < sk_X509_num(ctx->chain); i++) {
|
||||||
|
+ for (i = 0; i < sk_X509_num(ctx->chain); i++) {
|
||||||
|
X509 *x = sk_X509_value(ctx->chain, i);
|
||||||
|
|
||||||
|
+ if ((x->ex_flags & EXFLAG_INVALID_POLICY) != 0)
|
||||||
|
+ cbcalled = 1;
|
||||||
|
CB_FAIL_IF((x->ex_flags & EXFLAG_INVALID_POLICY) != 0,
|
||||||
|
ctx, x, i, X509_V_ERR_INVALID_POLICY_EXTENSION);
|
||||||
|
}
|
||||||
|
+ if (!cbcalled) {
|
||||||
|
+ /* Should not be able to get here */
|
||||||
|
+ ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ /* The callback ignored the error so we return success */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ret == X509_PCY_TREE_FAILURE) {
|
||||||
|
diff --git a/test/certs/ca-pol-cert.pem b/test/certs/ca-pol-cert.pem
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..244af3292b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/certs/ca-pol-cert.pem
|
||||||
|
@@ -0,0 +1,19 @@
|
||||||
|
+-----BEGIN CERTIFICATE-----
|
||||||
|
+MIIDFzCCAf+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
|
||||||
|
+IENBMCAXDTIzMDMwODEyMjMxNloYDzIxMjMwMzA5MTIyMzE2WjANMQswCQYDVQQD
|
||||||
|
+DAJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJadpD0ASxxfxsvd
|
||||||
|
+j9IxsogVzMSGLFziaYuE9KejU9+R479RifvwfBANO62sNWJ19X//9G5UjwWmkiOz
|
||||||
|
+n1k50DkYsBBA3mJzik6wjt/c58lBIlSEgAgpvDU8ht8w3t20JP9+YqXAeugqFj/W
|
||||||
|
+l9rFQtsvaWSRywjXVlp5fxuEQelNnXcJEKhsKTNExsBUZebo4/J1BWpklWzA9P0l
|
||||||
|
+YW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2MTE4hehxjdgCSci8GYnFirE/ojXqqpAc
|
||||||
|
+ZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3GdzI+oljt29102JIUaqj3yzRYkah8FLF9
|
||||||
|
+CLNNsUcCAwEAAaN7MHkwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYD
|
||||||
|
+VR0OBBYEFLQRM/HX4l73U54gIhBPhga/H8leMB8GA1UdIwQYMBaAFI71Ja8em2uE
|
||||||
|
+PXyAmslTnE1y96NSMBkGA1UdIAQSMBAwDgYMKwYBBAGBgVy8+0cBMA0GCSqGSIb3
|
||||||
|
+DQEBCwUAA4IBAQBbE+MO9mewWIUY2kt85yhl0oZtvVxbn9K2Hty59ItwJGRNfzx7
|
||||||
|
+Ge7KgawkvNzMOXmj6qf8TpbJnf41ZLWdRyVZBVyIwrAKIVw1VxfGh8aEifHKN97H
|
||||||
|
+unZkBPcUkAhUJSiC1BOD/euaMYqOi8QwiI702Q6q1NBY1/UKnV/ZIBLecnqfj9vZ
|
||||||
|
+7T0wKxrwGYBztP4pNcxCmBoD9Dg+Dx3ZElo0WXyO4SOh/BgrsKJHKyhbuTpjrI/g
|
||||||
|
+DhcINRp6+lIzuFBtJ67+YXnAEspb3lKMk0YL/LXrCNF2scdmNfOPwHi+OKBqt69C
|
||||||
|
+9FJyWFEMxx2qm/ENE9sbOswgJRnKkaAqHBHx
|
||||||
|
+-----END CERTIFICATE-----
|
||||||
|
diff --git a/test/certs/ee-cert-policies-bad.pem b/test/certs/ee-cert-policies-bad.pem
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..0fcd6372b3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/certs/ee-cert-policies-bad.pem
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+-----BEGIN CERTIFICATE-----
|
||||||
|
+MIIDTTCCAjWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
|
||||||
|
+Fw0yMzAzMDgxMjIzMzJaGA8yMTIzMDMwOTEyMjMzMlowGTEXMBUGA1UEAwwOc2Vy
|
||||||
|
+dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY
|
||||||
|
+YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT
|
||||||
|
+5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l
|
||||||
|
+Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1
|
||||||
|
+U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5
|
||||||
|
+ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn
|
||||||
|
+iIQPYf55NB9KiR+3AgMBAAGjgakwgaYwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H
|
||||||
|
+mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC
|
||||||
|
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w
|
||||||
|
+bGUwKQYDVR0gBCIwIDAOBgwrBgEEAYGBXLz7RwEwDgYMKwYBBAGBgVy8+0cBMA0G
|
||||||
|
+CSqGSIb3DQEBCwUAA4IBAQArwtwNO++7kStcJeMg3ekz2D/m/8UEjTA1rknBjQiQ
|
||||||
|
+P0FK7tNeRqus9i8PxthNWk+biRayvDzaGIBV7igpDBPfXemDgmW9Adc4MKyiQDfs
|
||||||
|
+YfkHi3xJKvsK2fQmyCs2InVDaKpVAkNFcgAW8nSOhGliqIxLb0EOLoLNwaktou0N
|
||||||
|
+XQHmRzY8S7aIr8K9Qo9y/+MLar+PS4h8l6FkLLkTICiFzE4/wje5S3NckAnadRJa
|
||||||
|
+QpjwM2S6NuA+tYWuOcN//r7BSpW/AZKanYWPzHMrKlqCh+9o7sthPd72+hObG9kx
|
||||||
|
+wSGdzfStNK1I1zM5LiI08WtXCvR6AfLANTo2x1AYhSxF
|
||||||
|
+-----END CERTIFICATE-----
|
||||||
|
diff --git a/test/certs/ee-cert-policies.pem b/test/certs/ee-cert-policies.pem
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..2f06d7433f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/certs/ee-cert-policies.pem
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+-----BEGIN CERTIFICATE-----
|
||||||
|
+MIIDPTCCAiWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAg
|
||||||
|
+Fw0yMzAzMDgxMjIzMjNaGA8yMTIzMDMwOTEyMjMyM1owGTEXMBUGA1UEAwwOc2Vy
|
||||||
|
+dmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo/4lY
|
||||||
|
+YYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAWVsu0LLuT
|
||||||
|
+5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4yuxsIVl1l
|
||||||
|
+Dz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzBZK1KxMY1
|
||||||
|
+U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2zyvlr3zG5
|
||||||
|
+ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEPoqNGT4tn
|
||||||
|
+iIQPYf55NB9KiR+3AgMBAAGjgZkwgZYwHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4H
|
||||||
|
+mCKX4XOiMB8GA1UdIwQYMBaAFLQRM/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQC
|
||||||
|
+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1w
|
||||||
|
+bGUwGQYDVR0gBBIwEDAOBgwrBgEEAYGBXLz7RwEwDQYJKoZIhvcNAQELBQADggEB
|
||||||
|
+AGbWslmAAdMX3+5ChcnFrX+NqDGoyhb3PTgWdtlQB5qtWdIt4rSxN50OcQxFTX0D
|
||||||
|
+QOBabSzR0DDKrgfBe4waL19WsdEvR9GyO4M7ASze/A3IEZue9C9k0n7Vq8zDaAZl
|
||||||
|
+CiR/Zqo9nAOuhKHMgmC/NjUlX7STv5pJVgc4SH8VEKmSRZDmNihaOalUtK5X8/Oa
|
||||||
|
+dawKxsZcaP5IKnOEPPKjtVNJxBu5CXywJHsO0GcoDEnEx1/NLdFoJ6WFw8NuTyDK
|
||||||
|
+NGLq2MHEdyKaigHQlptEs9bXyu9McJjzbx0uXj3BenRULASreccFej0L1RU6jDlk
|
||||||
|
+D3brBn24UISaFRZoB7jsjok=
|
||||||
|
+-----END CERTIFICATE-----
|
||||||
|
diff --git a/test/certs/mkcert.sh b/test/certs/mkcert.sh
|
||||||
|
index c3f7ac14b5..a57d9f38dc 100755
|
||||||
|
--- a/test/certs/mkcert.sh
|
||||||
|
+++ b/test/certs/mkcert.sh
|
||||||
|
@@ -119,11 +119,12 @@ genca() {
|
||||||
|
local OPTIND=1
|
||||||
|
local purpose=
|
||||||
|
|
||||||
|
- while getopts p: o
|
||||||
|
+ while getopts p:c: o
|
||||||
|
do
|
||||||
|
case $o in
|
||||||
|
p) purpose="$OPTARG";;
|
||||||
|
- *) echo "Usage: $0 genca [-p EKU] cn keyname certname cakeyname cacertname" >&2
|
||||||
|
+ c) certpol="$OPTARG";;
|
||||||
|
+ *) echo "Usage: $0 genca [-p EKU][-c policyoid] cn keyname certname cakeyname cacertname" >&2
|
||||||
|
return 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
@@ -146,6 +147,10 @@ genca() {
|
||||||
|
if [ -n "$NC" ]; then
|
||||||
|
exts=$(printf "%s\nnameConstraints = %s\n" "$exts" "$NC")
|
||||||
|
fi
|
||||||
|
+ if [ -n "$certpol" ]; then
|
||||||
|
+ exts=$(printf "%s\ncertificatePolicies = %s\n" "$exts" "$certpol")
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
csr=$(req "$key" "CN = $cn") || return 1
|
||||||
|
echo "$csr" |
|
||||||
|
cert "$cert" "$exts" -CA "${cacert}.pem" -CAkey "${cakey}.pem" \
|
||||||
|
diff --git a/test/certs/setup.sh b/test/certs/setup.sh
|
||||||
|
index 2240cd9df0..76ceadc7d8 100755
|
||||||
|
--- a/test/certs/setup.sh
|
||||||
|
+++ b/test/certs/setup.sh
|
||||||
|
@@ -440,3 +440,9 @@ OPENSSL_SIGALG=ED448 OPENSSL_KEYALG=ed448 ./mkcert.sh genee ed448 \
|
||||||
|
|
||||||
|
# critical id-pkix-ocsp-no-check extension
|
||||||
|
./mkcert.sh geneeextra server.example ee-key ee-cert-ocsp-nocheck ca-key ca-cert "1.3.6.1.5.5.7.48.1.5=critical,DER:05:00"
|
||||||
|
+
|
||||||
|
+# certificatePolicies extension
|
||||||
|
+./mkcert.sh genca -c "1.3.6.1.4.1.16604.998855.1" "CA" ca-key ca-pol-cert root-key root-cert
|
||||||
|
+./mkcert.sh geneeextra server.example ee-key ee-cert-policies ca-key ca-cert "certificatePolicies=1.3.6.1.4.1.16604.998855.1"
|
||||||
|
+# We can create a cert with a duplicate policy oid - but its actually invalid!
|
||||||
|
+./mkcert.sh geneeextra server.example ee-key ee-cert-policies-bad ca-key ca-cert "certificatePolicies=1.3.6.1.4.1.16604.998855.1,1.3.6.1.4.1.16604.998855.1"
|
||||||
|
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
|
||||||
|
index 2a4c36e86d..818c9ac50d 100644
|
||||||
|
--- a/test/recipes/25-test_verify.t
|
||||||
|
+++ b/test/recipes/25-test_verify.t
|
||||||
|
@@ -29,7 +29,7 @@ sub verify {
|
||||||
|
run(app([@args]));
|
||||||
|
}
|
||||||
|
|
||||||
|
-plan tests => 163;
|
||||||
|
+plan tests => 165;
|
||||||
|
|
||||||
|
# Canonical success
|
||||||
|
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
|
||||||
|
@@ -516,3 +516,14 @@ SKIP: {
|
||||||
|
ok(run(app([ qw(openssl verify -trusted), $rsapluscert_file, $cert_file ])),
|
||||||
|
'Mixed key + cert file test');
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+# Certificate Policies
|
||||||
|
+ok(verify("ee-cert-policies", "", ["root-cert"], ["ca-pol-cert"],
|
||||||
|
+ "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",
|
||||||
|
+ "-explicit_policy"),
|
||||||
|
+ "Certificate policy");
|
||||||
|
+
|
||||||
|
+ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"],
|
||||||
|
+ "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",
|
||||||
|
+ "-explicit_policy"),
|
||||||
|
+ "Bad certificate policy");
|
@ -0,0 +1,27 @@
|
|||||||
|
diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||||
|
index 75a1677022..43c1900bca 100644
|
||||||
|
--- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||||
|
+++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||||
|
@@ -98,8 +98,9 @@ B<trust>.
|
||||||
|
X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to
|
||||||
|
B<t>. Normally the current time is used.
|
||||||
|
|
||||||
|
-X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled
|
||||||
|
-by default) and adds B<policy> to the acceptable policy set.
|
||||||
|
+X509_VERIFY_PARAM_add0_policy() adds B<policy> to the acceptable policy set.
|
||||||
|
+Contrary to preexisting documentation of this function it does not enable
|
||||||
|
+policy checking.
|
||||||
|
|
||||||
|
X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled
|
||||||
|
by default) and sets the acceptable policy set to B<policies>. Any existing
|
||||||
|
@@ -400,6 +401,10 @@ The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i.
|
||||||
|
The X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(),
|
||||||
|
and X509_VERIFY_PARAM_get1_ip_asc() functions were added in OpenSSL 3.0.
|
||||||
|
|
||||||
|
+The function X509_VERIFY_PARAM_add0_policy() was historically documented as
|
||||||
|
+enabling policy checking however the implementation has never done this.
|
||||||
|
+The documentation was changed to align with the implementation.
|
||||||
|
+
|
||||||
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
|
Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved.
|
@ -0,0 +1,20 @@
|
|||||||
|
--- a/crypto/aes/asm/aesv8-armx.pl
|
||||||
|
+++ b/crypto/aes/asm/aesv8-armx.pl
|
||||||
|
@@ -3353,7 +3353,7 @@ $code.=<<___ if ($flavour =~ /64/);
|
||||||
|
.align 4
|
||||||
|
.Lxts_dec_tail4x:
|
||||||
|
add $inp,$inp,#16
|
||||||
|
- vld1.32 {$dat0},[$inp],#16
|
||||||
|
+ tst $tailcnt,#0xf
|
||||||
|
veor $tmp1,$dat1,$tmp0
|
||||||
|
vst1.8 {$tmp1},[$out],#16
|
||||||
|
veor $tmp2,$dat2,$tmp2
|
||||||
|
@@ -3362,6 +3362,8 @@ $code.=<<___ if ($flavour =~ /64/);
|
||||||
|
veor $tmp4,$dat4,$tmp4
|
||||||
|
vst1.8 {$tmp3-$tmp4},[$out],#32
|
||||||
|
|
||||||
|
+ b.eq .Lxts_dec_abort
|
||||||
|
+ vld1.32 {$dat0},[$inp],#16
|
||||||
|
b .Lxts_done
|
||||||
|
.align 4
|
||||||
|
.Lxts_outer_dec_tail:
|
@ -0,0 +1,30 @@
|
|||||||
|
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
|
||||||
|
index 01cde00e98..c0e55197a0 100644
|
||||||
|
--- a/crypto/objects/obj_dat.c
|
||||||
|
+++ b/crypto/objects/obj_dat.c
|
||||||
|
@@ -443,6 +443,25 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
||||||
|
first = 1;
|
||||||
|
bl = NULL;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * RFC 2578 (STD 58) says this about OBJECT IDENTIFIERs:
|
||||||
|
+ *
|
||||||
|
+ * > 3.5. OBJECT IDENTIFIER values
|
||||||
|
+ * >
|
||||||
|
+ * > An OBJECT IDENTIFIER value is an ordered list of non-negative
|
||||||
|
+ * > numbers. For the SMIv2, each number in the list is referred to as a
|
||||||
|
+ * > sub-identifier, there are at most 128 sub-identifiers in a value,
|
||||||
|
+ * > and each sub-identifier has a maximum value of 2^32-1 (4294967295
|
||||||
|
+ * > decimal).
|
||||||
|
+ *
|
||||||
|
+ * So a legitimate OID according to this RFC is at most (32 * 128 / 7),
|
||||||
|
+ * i.e. 586 bytes long.
|
||||||
|
+ *
|
||||||
|
+ * Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
|
||||||
|
+ */
|
||||||
|
+ if (len > 586)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
while (len > 0) {
|
||||||
|
l = 0;
|
||||||
|
use_bn = 0;
|
@ -0,0 +1,244 @@
|
|||||||
|
diff --git a/crypto/context.c b/crypto/context.c
|
||||||
|
index bdfc4d02a3f0..548665fba265 100644
|
||||||
|
--- a/crypto/context.c
|
||||||
|
+++ b/crypto/context.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include "internal/bio.h"
|
||||||
|
#include "internal/provider.h"
|
||||||
|
#include "crypto/ctype.h"
|
||||||
|
+#include "crypto/rand.h"
|
||||||
|
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
@@ -271,6 +272,20 @@ OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx)
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void ossl_release_default_drbg_ctx(void)
|
||||||
|
+{
|
||||||
|
+ int dynidx = default_context_int.dyn_indexes[OSSL_LIB_CTX_DRBG_INDEX];
|
||||||
|
+
|
||||||
|
+ /* early release of the DRBG in global default libctx, no locking */
|
||||||
|
+ if (dynidx != -1) {
|
||||||
|
+ void *data;
|
||||||
|
+
|
||||||
|
+ data = CRYPTO_get_ex_data(&default_context_int.data, dynidx);
|
||||||
|
+ ossl_rand_ctx_free(data);
|
||||||
|
+ CRYPTO_set_ex_data(&default_context_int.data, dynidx, NULL);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx)
|
||||||
|
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
|
||||||
|
index c453d3226133..f341d915db76 100644
|
||||||
|
--- a/crypto/rand/rand_lib.c
|
||||||
|
+++ b/crypto/rand/rand_lib.c
|
||||||
|
@@ -96,6 +96,7 @@ void ossl_rand_cleanup_int(void)
|
||||||
|
CRYPTO_THREAD_lock_free(rand_meth_lock);
|
||||||
|
rand_meth_lock = NULL;
|
||||||
|
# endif
|
||||||
|
+ ossl_release_default_drbg_ctx();
|
||||||
|
rand_inited = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -469,7 +470,7 @@ static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void rand_ossl_ctx_free(void *vdgbl)
|
||||||
|
+void ossl_rand_ctx_free(void *vdgbl)
|
||||||
|
{
|
||||||
|
RAND_GLOBAL *dgbl = vdgbl;
|
||||||
|
|
||||||
|
@@ -494,7 +495,7 @@ static void rand_ossl_ctx_free(void *vdgbl)
|
||||||
|
static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = {
|
||||||
|
OSSL_LIB_CTX_METHOD_PRIORITY_2,
|
||||||
|
rand_ossl_ctx_new,
|
||||||
|
- rand_ossl_ctx_free,
|
||||||
|
+ ossl_rand_ctx_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx)
|
||||||
|
diff --git a/engines/e_dasync.c b/engines/e_dasync.c
|
||||||
|
index 5a303a9f8528..7974106ae219 100644
|
||||||
|
--- a/engines/e_dasync.c
|
||||||
|
+++ b/engines/e_dasync.c
|
||||||
|
@@ -139,6 +139,14 @@ static int dasync_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
const unsigned char *in, size_t inl);
|
||||||
|
static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx);
|
||||||
|
|
||||||
|
+static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||||
|
+ void *ptr);
|
||||||
|
+static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
|
+ const unsigned char *iv, int enc);
|
||||||
|
+static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
+ const unsigned char *in, size_t inl);
|
||||||
|
+static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx);
|
||||||
|
+
|
||||||
|
static int dasync_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
|
||||||
|
int arg, void *ptr);
|
||||||
|
static int dasync_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
|
||||||
|
@@ -171,6 +179,12 @@ static const EVP_CIPHER *dasync_aes_128_cbc(void)
|
||||||
|
return _hidden_aes_128_cbc;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static EVP_CIPHER *_hidden_aes_256_ctr = NULL;
|
||||||
|
+static const EVP_CIPHER *dasync_aes_256_ctr(void)
|
||||||
|
+{
|
||||||
|
+ return _hidden_aes_256_ctr;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Holds the EVP_CIPHER object for aes_128_cbc_hmac_sha1 in this engine. Set up
|
||||||
|
* once only during engine bind and can then be reused many times.
|
||||||
|
@@ -192,8 +206,10 @@ static const EVP_CIPHER *dasync_aes_128_cbc_hmac_sha1(void)
|
||||||
|
static void destroy_ciphers(void)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
|
||||||
|
+ EVP_CIPHER_meth_free(_hidden_aes_256_ctr);
|
||||||
|
EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
|
||||||
|
_hidden_aes_128_cbc = NULL;
|
||||||
|
+ _hidden_aes_256_ctr = NULL;
|
||||||
|
_hidden_aes_128_cbc_hmac_sha1 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -202,6 +218,7 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||||
|
|
||||||
|
static int dasync_cipher_nids[] = {
|
||||||
|
NID_aes_128_cbc,
|
||||||
|
+ NID_aes_256_ctr,
|
||||||
|
NID_aes_128_cbc_hmac_sha1,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
@@ -284,6 +301,30 @@ static int bind_dasync(ENGINE *e)
|
||||||
|
_hidden_aes_128_cbc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ _hidden_aes_256_ctr = EVP_CIPHER_meth_new(NID_aes_256_ctr,
|
||||||
|
+ 1 /* block size */,
|
||||||
|
+ 32 /* key len */);
|
||||||
|
+ if (_hidden_aes_256_ctr == NULL
|
||||||
|
+ || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_256_ctr,16)
|
||||||
|
+ || !EVP_CIPHER_meth_set_flags(_hidden_aes_256_ctr,
|
||||||
|
+ EVP_CIPH_FLAG_DEFAULT_ASN1
|
||||||
|
+ | EVP_CIPH_CTR_MODE
|
||||||
|
+ | EVP_CIPH_FLAG_PIPELINE
|
||||||
|
+ | EVP_CIPH_CUSTOM_COPY)
|
||||||
|
+ || !EVP_CIPHER_meth_set_init(_hidden_aes_256_ctr,
|
||||||
|
+ dasync_aes256_init_key)
|
||||||
|
+ || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_256_ctr,
|
||||||
|
+ dasync_aes256_ctr_cipher)
|
||||||
|
+ || !EVP_CIPHER_meth_set_cleanup(_hidden_aes_256_ctr,
|
||||||
|
+ dasync_aes256_ctr_cleanup)
|
||||||
|
+ || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_256_ctr,
|
||||||
|
+ dasync_aes256_ctr_ctrl)
|
||||||
|
+ || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_256_ctr,
|
||||||
|
+ sizeof(struct dasync_pipeline_ctx))) {
|
||||||
|
+ EVP_CIPHER_meth_free(_hidden_aes_256_ctr);
|
||||||
|
+ _hidden_aes_256_ctr = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_hidden_aes_128_cbc_hmac_sha1 = EVP_CIPHER_meth_new(
|
||||||
|
NID_aes_128_cbc_hmac_sha1,
|
||||||
|
16 /* block size */,
|
||||||
|
@@ -445,6 +486,9 @@ static int dasync_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||||
|
case NID_aes_128_cbc:
|
||||||
|
*cipher = dasync_aes_128_cbc();
|
||||||
|
break;
|
||||||
|
+ case NID_aes_256_ctr:
|
||||||
|
+ *cipher = dasync_aes_256_ctr();
|
||||||
|
+ break;
|
||||||
|
case NID_aes_128_cbc_hmac_sha1:
|
||||||
|
*cipher = dasync_aes_128_cbc_hmac_sha1();
|
||||||
|
break;
|
||||||
|
@@ -779,6 +823,29 @@ static int dasync_aes128_cbc_cleanup(EVP_CIPHER_CTX *ctx)
|
||||||
|
return dasync_cipher_cleanup_helper(ctx, EVP_aes_128_cbc());
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int dasync_aes256_ctr_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||||
|
+ void *ptr)
|
||||||
|
+{
|
||||||
|
+ return dasync_cipher_ctrl_helper(ctx, type, arg, ptr, 0, EVP_aes_256_ctr());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int dasync_aes256_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
|
+ const unsigned char *iv, int enc)
|
||||||
|
+{
|
||||||
|
+ return dasync_cipher_init_key_helper(ctx, key, iv, enc, EVP_aes_256_ctr());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int dasync_aes256_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
|
+ const unsigned char *in, size_t inl)
|
||||||
|
+{
|
||||||
|
+ return dasync_cipher_helper(ctx, out, in, inl, EVP_aes_256_ctr());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int dasync_aes256_ctr_cleanup(EVP_CIPHER_CTX *ctx)
|
||||||
|
+{
|
||||||
|
+ return dasync_cipher_cleanup_helper(ctx, EVP_aes_256_ctr());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AES128 CBC HMAC SHA1 Implementation
|
||||||
|
diff --git a/include/crypto/rand.h b/include/crypto/rand.h
|
||||||
|
index 6a71a339c812..165deaf95c5e 100644
|
||||||
|
--- a/include/crypto/rand.h
|
||||||
|
+++ b/include/crypto/rand.h
|
||||||
|
@@ -125,4 +125,5 @@ void ossl_rand_cleanup_nonce(ossl_unused const OSSL_CORE_HANDLE *handle,
|
||||||
|
size_t ossl_pool_acquire_entropy(RAND_POOL *pool);
|
||||||
|
int ossl_pool_add_nonce_data(RAND_POOL *pool);
|
||||||
|
|
||||||
|
+void ossl_rand_ctx_free(void *vdgbl);
|
||||||
|
#endif
|
||||||
|
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
|
||||||
|
index 1291299b6e50..934d4b089c20 100644
|
||||||
|
--- a/include/internal/cryptlib.h
|
||||||
|
+++ b/include/internal/cryptlib.h
|
||||||
|
@@ -199,6 +199,8 @@ int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx,
|
||||||
|
int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn);
|
||||||
|
const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx);
|
||||||
|
|
||||||
|
+void ossl_release_default_drbg_ctx(void);
|
||||||
|
+
|
||||||
|
OSSL_LIB_CTX *ossl_crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad);
|
||||||
|
int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
|
||||||
|
CRYPTO_EX_DATA *ad);
|
||||||
|
diff --git a/test/recipes/05-test_rand.t b/test/recipes/05-test_rand.t
|
||||||
|
index 4da1e64cb6da..3f352db9df3a 100644
|
||||||
|
--- a/test/recipes/05-test_rand.t
|
||||||
|
+++ b/test/recipes/05-test_rand.t
|
||||||
|
@@ -11,9 +11,30 @@ use warnings;
|
||||||
|
use OpenSSL::Test;
|
||||||
|
use OpenSSL::Test::Utils;
|
||||||
|
|
||||||
|
-plan tests => 3;
|
||||||
|
+plan tests => 5;
|
||||||
|
setup("test_rand");
|
||||||
|
|
||||||
|
ok(run(test(["rand_test"])));
|
||||||
|
ok(run(test(["drbgtest"])));
|
||||||
|
ok(run(test(["rand_status_test"])));
|
||||||
|
+
|
||||||
|
+SKIP: {
|
||||||
|
+ skip "engine is not supported by this OpenSSL build", 2
|
||||||
|
+ if disabled("engine") || disabled("dynamic-engine");
|
||||||
|
+
|
||||||
|
+ my $success;
|
||||||
|
+ my @randdata;
|
||||||
|
+ my $expected = '0102030405060708090a0b0c0d0e0f10';
|
||||||
|
+
|
||||||
|
+ @randdata = run(app(['openssl', 'rand', '-engine', 'ossltest', '-hex', '16' ]),
|
||||||
|
+ capture => 1, statusvar => \$success);
|
||||||
|
+ chomp(@randdata);
|
||||||
|
+ ok($success and $randdata[0] eq $expected,
|
||||||
|
+ "rand with ossltest: Check rand output is as expected");
|
||||||
|
+
|
||||||
|
+ @randdata = run(app(['openssl', 'rand', '-engine', 'dasync', '-hex', '16' ]),
|
||||||
|
+ capture => 1, statusvar => \$success);
|
||||||
|
+ chomp(@randdata);
|
||||||
|
+ ok($success and length($randdata[0]) == 32,
|
||||||
|
+ "rand with dasync: Check rand output is of expected length");
|
||||||
|
+}
|
Loading…
Reference in new issue