import openssl-3.0.1-47.el9_1

c9 imports/c9/openssl-3.0.1-47.el9_1
CentOS Sources 2 years ago committed by MSVSphere Packaging Team
parent 0f30ebffe9
commit a530b5a7ba

@ -1,7 +1,7 @@
diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/providers/fips/self_test.c
--- openssl-3.0.0/providers/fips/self_test.c.embed-hmac 2021-11-16 13:57:05.127171056 +0100
+++ openssl-3.0.0/providers/fips/self_test.c 2021-11-16 14:07:21.963412455 +0100
@@ -171,11 +171,27 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
diff -up openssl-3.0.7/providers/fips/self_test.c.embed-hmac openssl-3.0.7/providers/fips/self_test.c
--- openssl-3.0.7/providers/fips/self_test.c.embed-hmac 2023-01-05 10:03:44.864869710 +0100
+++ openssl-3.0.7/providers/fips/self_test.c 2023-01-05 10:15:17.041606472 +0100
@@ -172,11 +172,27 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
}
#endif
@ -29,13 +29,7 @@ diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/provi
static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb,
unsigned char *expected, size_t expected_len,
OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev,
@@ -183,14 +199,26 @@ static int verify_integrity(OSSL_CORE_BI
{
int ret = 0, status;
unsigned char out[MAX_MD_SIZE];
- unsigned char buf[INTEGRITY_BUF_SIZE];
+ unsigned char buf[INTEGRITY_BUF_SIZE+HMAC_LEN];
size_t bytes_read = 0, out_len = 0;
@@ -189,9 +205,20 @@ static int verify_integrity(OSSL_CORE_BI
EVP_MAC *mac = NULL;
EVP_MAC_CTX *ctx = NULL;
OSSL_PARAM params[2], *p = params;
@ -44,7 +38,6 @@ diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/provi
+ struct link_map *lm = NULL;
+ unsigned long paddr;
+ unsigned long off = 0;
+ int have_rest = 0;
OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
@ -57,64 +50,52 @@ diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/provi
mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
if (mac == NULL)
goto err;
@@ -204,12 +233,53 @@ static int verify_integrity(OSSL_CORE_BI
@@ -205,13 +233,42 @@ static int verify_integrity(OSSL_CORE_BI
if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params))
goto err;
+ status = read_ex_cb(bio, buf, HMAC_LEN, &bytes_read);
+ if (status != 1 || bytes_read != HMAC_LEN)
+ goto err;
+ off += HMAC_LEN;
+
while (1) {
- while (1) {
- status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
- if (status != 1)
+ status = read_ex_cb(bio, buf+HMAC_LEN, INTEGRITY_BUF_SIZE, &bytes_read);
+ if (status != 1) {
+ have_rest = 1;
+ break;
+ }
+
+ if (bytes_read == INTEGRITY_BUF_SIZE) { /* Full block */
+ /* Logic:
+ * We have HMAC_LEN (read before) + INTEGRITY_BUF_SIZE (read now) in buffer
+ * We calculate HMAC from first INTEGRITY_BUF_SIZE bytes
+ * and move last HMAC_LEN bytes to the beginning of the buffer
+ *
+ * If we have read (a part of) buffer fips_hmac_container
+ * we should replace it with zeros.
+ * If it is inside our current buffer, we will update now.
+ * If it intersects the upper bound, we will clean up on the next step.
+ */
+ if (off - HMAC_LEN <= paddr && paddr <= off + bytes_read)
+ memset (buf + HMAC_LEN + paddr - off, 0, HMAC_LEN);
+ off += bytes_read;
+
+ if (!EVP_MAC_update(ctx, buf, bytes_read))
+ goto err;
+ memcpy (buf, buf+INTEGRITY_BUF_SIZE, HMAC_LEN);
+ } else { /* Final block */
+ /* Logic is basically the same as in previous branch
+ * but we calculate HMAC from HMAC_LEN (rest of previous step)
+ * and bytes_read read on this step
+ * */
+ if (off - HMAC_LEN <= paddr && paddr <= off + bytes_read)
+ memset (buf + HMAC_LEN + paddr - off, 0, HMAC_LEN);
+ if (!EVP_MAC_update(ctx, buf, bytes_read+HMAC_LEN))
+ goto err;
+ off += bytes_read;
+ while ((off + INTEGRITY_BUF_SIZE) <= paddr) {
+ status = read_ex_cb(bio, buf, INTEGRITY_BUF_SIZE, &bytes_read);
if (status != 1)
break;
- if (!EVP_MAC_update(ctx, buf, bytes_read))
+ }
+ }
+ if (have_rest) {
+ if (!EVP_MAC_update(ctx, buf, HMAC_LEN))
if (!EVP_MAC_update(ctx, buf, bytes_read))
goto err;
+ off += HMAC_LEN;
+ off += bytes_read;
}
+
+ if (off + INTEGRITY_BUF_SIZE > paddr) {
+ int delta = paddr - off;
+ status = read_ex_cb(bio, buf, delta, &bytes_read);
+ if (status != 1)
+ goto err;
+ if (!EVP_MAC_update(ctx, buf, bytes_read))
+ goto err;
+ off += bytes_read;
+
+ status = read_ex_cb(bio, buf, HMAC_LEN, &bytes_read);
+ memset(buf, 0, HMAC_LEN);
+ if (status != 1)
+ goto err;
+ if (!EVP_MAC_update(ctx, buf, bytes_read))
+ goto err;
+ off += bytes_read;
+ }
+
+ while (bytes_read > 0) {
+ status = read_ex_cb(bio, buf, INTEGRITY_BUF_SIZE, &bytes_read);
+ if (status != 1)
+ break;
+ if (!EVP_MAC_update(ctx, buf, bytes_read))
+ goto err;
+ off += bytes_read;
+ }
+
if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
goto err;
@@ -284,8 +358,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
@@ -285,8 +342,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
CRYPTO_THREAD_unlock(fips_state_lock);
}
@ -124,7 +105,7 @@ diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/provi
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
goto end;
}
@@ -294,8 +367,9 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
@@ -305,8 +361,9 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
if (ev == NULL)
goto end;
@ -136,7 +117,7 @@ diff -up openssl-3.0.0/providers/fips/self_test.c.embed-hmac openssl-3.0.0/provi
if (module_checksum == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
goto end;
@@ -357,7 +431,6 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
@@ -356,7 +413,6 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS
ok = 1;
end:
OSSL_SELF_TEST_free(ev);

@ -1,50 +1,69 @@
From c4b086fc4de06128695e1fe428f56d776d25e748 Mon Sep 17 00:00:00 2001
From 0c4aaedf29a1ed1559762515bfeaa5923925e18f Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Thu, 11 Aug 2022 09:27:12 +0200
Subject: [PATCH] Add FIPS indicator parameter to HKDF
Subject: [PATCH 1/2] Add FIPS indicator parameter to HKDF
NIST considers HKDF only acceptable when used as in TLS 1.3, and
otherwise unapproved. Add an explicit indicator attached to the
EVP_KDF_CTX that can be queried using EVP_KDF_CTX_get_params() to
determine whether the KDF operation was approved after performing it.
Related: rhbz#2114772
Signed-off-by: Clemens Lang <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 +++++++++++++++++++++++++++
3 files changed, 58 insertions(+)
4 files changed, 65 insertions(+)
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index e70d8e9e84..76fb990de4 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -219,6 +219,13 @@ struct evp_mac_st {
OSSL_FUNC_mac_set_ctx_params_fn *set_ctx_params;
};
+#ifdef FIPS_MODULE
+/* According to NIST Special Publication 800-131Ar2, Section 8: Deriving
+ * Additional Keys from a Cryptographic Key, "[t]he length of the
+ * key-derivation key [i.e., the input key] shall be at least 112 bits". */
+# define EVP_KDF_FIPS_MIN_KEY_LEN (112 / 8)
+#endif
+
struct evp_kdf_st {
OSSL_PROVIDER *prov;
int name_id;
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 21c94d0488..87786680d7 100644
index 21c94d0488..c019afbbb0 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -223,6 +223,7 @@ extern "C" {
#define OSSL_KDF_PARAM_X942_SUPP_PUBINFO "supp-pubinfo"
#define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO "supp-privinfo"
#define OSSL_KDF_PARAM_X942_USE_KEYBITS "use-keybits"
+#define OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR "hkdf-fips-indicator"
+#define OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
/* Known KDF names */
#define OSSL_KDF_NAME_HKDF "HKDF"
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
index 0983230a48..869f23d8fb 100644
index 0983230a48..86171635ea 100644
--- a/include/openssl/kdf.h
+++ b/include/openssl/kdf.h
@@ -63,6 +63,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf,
# define EVP_KDF_HKDF_MODE_EXTRACT_ONLY 1
# define EVP_KDF_HKDF_MODE_EXPAND_ONLY 2
+# define EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED 0
+# define EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED 1
+# define EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED 2
+# define EVP_KDF_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
+# define EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED 1
+# define EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
+
#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV 65
#define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI 66
#define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index afdb7138e1..9d28d292d8 100644
index afdb7138e1..6f06fa58fe 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -298,6 +298,56 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
@ -53,13 +72,13 @@ index afdb7138e1..9d28d292d8 100644
}
+
+#ifdef FIPS_MODULE
+ if ((p = OSSL_PARAM_locate(params,
+ OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR)) != NULL) {
+ int fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED;
+ if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR))
+ != NULL) {
+ int fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_UNDETERMINED;
+ switch (ctx->mode) {
+ case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
+ /* TLS 1.3 never uses extract-and-expand */
+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
+ break;
+ case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
+ {
@ -74,10 +93,10 @@ index afdb7138e1..9d28d292d8 100644
+ * comes from, so all we can do is check the salt length.
+ */
+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+ if (md != NULL && ctx->salt_len == EVP_MD_get_size(md))
+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
+ if (md != NULL && ctx->salt_len == (size_t) EVP_MD_get_size(md))
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
+ else
+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
+ }
+ break;
+ case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
@ -92,9 +111,9 @@ index afdb7138e1..9d28d292d8 100644
+ && ctx->label_len >= 2 /* length */ + 4 /* "dtls" */
+ && (strncmp("tls", (const char *)ctx->label + 2, 3) == 0 ||
+ strncmp("dtls", (const char *)ctx->label + 2, 4) == 0))
+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_APPROVED;
+ else
+ fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
+ fips_indicator = EVP_KDF_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
+ break;
+ }
+ return OSSL_PARAM_set_int(p, fips_indicator);
@ -109,11 +128,11 @@ index afdb7138e1..9d28d292d8 100644
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+#ifdef FIPS_MODULE
+ OSSL_PARAM_int(OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR, NULL),
+ OSSL_PARAM_int(OSSL_KDF_PARAM_REDHAT_FIPS_INDICATOR, NULL),
+#endif /* defined(FIPS_MODULE) */
OSSL_PARAM_END
};
return known_gettable_ctx_params;
--
2.37.1
2.38.1

@ -0,0 +1,288 @@
From 4de5fa26873297f5c2eeed53e5c988437f837f55 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Thu, 17 Nov 2022 13:53:31 +0100
Subject: [PATCH] signature: Remove X9.31 padding from FIPS prov
The current draft of FIPS 186-5 [1] no longer contains specifications
for X9.31 signature padding. Instead, it contains the following
information in Appendix E:
> ANSI X9.31 was withdrawn, so X9.31 RSA signatures were removed from
> this standard.
Since this situation is unlikely to change in future revisions of the
draft, and future FIPS 140-3 validations of the provider will require
X9.31 to be disabled or marked as not approved with an explicit
indicator, disallow this padding mode now.
Remove the X9.31 tests from the acvp test, since they will always fail
now.
[1]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5-draft.pdf
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
providers/implementations/signature/rsa_sig.c | 6 +
test/acvp_test.inc | 214 ------------------
2 files changed, 6 insertions(+), 214 deletions(-)
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
index 34f45175e8..49e7f9158a 100644
--- a/providers/implementations/signature/rsa_sig.c
+++ b/providers/implementations/signature/rsa_sig.c
@@ -1233,7 +1233,13 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
err_extra_text = "No padding not allowed with RSA-PSS";
goto cont;
case RSA_X931_PADDING:
+#ifndef FIPS_MODULE
err_extra_text = "X.931 padding not allowed with RSA-PSS";
+#else /* !defined(FIPS_MODULE) */
+ err_extra_text = "X.931 padding no longer allowed in FIPS mode,"
+ " since it was removed from FIPS 186-5";
+ goto bad_pad;
+#endif /* !defined(FIPS_MODULE) */
cont:
if (RSA_test_flags(prsactx->rsa,
RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSA)
diff --git a/test/acvp_test.inc b/test/acvp_test.inc
index 73b24bdb0c..96a72073f9 100644
--- a/test/acvp_test.inc
+++ b/test/acvp_test.inc
@@ -1204,13 +1204,6 @@ static const struct rsa_siggen_st rsa_siggen_data[] = {
ITM(rsa_siggen0_msg),
NO_PSS_SALT_LEN,
},
- {
- "x931",
- 2048,
- "SHA384",
- ITM(rsa_siggen0_msg),
- NO_PSS_SALT_LEN,
- },
{
"pss",
2048,
@@ -1622,202 +1615,6 @@ static const unsigned char rsa_sigverpss_1_sig[] = {
0x5c, 0xea, 0x8a, 0x92, 0x31, 0xd2, 0x11, 0x4b,
};
-static const unsigned char rsa_sigverx931_0_n[] = {
- 0xa0, 0x16, 0x14, 0x80, 0x8b, 0x17, 0x2b, 0xad,
- 0xd7, 0x07, 0x31, 0x6d, 0xfc, 0xba, 0x25, 0x83,
- 0x09, 0xa0, 0xf7, 0x71, 0xc6, 0x06, 0x22, 0x87,
- 0xd6, 0xbd, 0x13, 0xd9, 0xfe, 0x7c, 0xf7, 0xe6,
- 0x48, 0xdb, 0x27, 0xd8, 0xa5, 0x49, 0x8e, 0x8c,
- 0xea, 0xbe, 0xe0, 0x04, 0x6f, 0x3d, 0x3b, 0x73,
- 0xdc, 0xc5, 0xd4, 0xdc, 0x85, 0xef, 0xea, 0x10,
- 0x46, 0xf3, 0x88, 0xb9, 0x93, 0xbc, 0xa0, 0xb6,
- 0x06, 0x02, 0x82, 0xb4, 0x2d, 0x54, 0xec, 0x79,
- 0x50, 0x8a, 0xfc, 0xfa, 0x62, 0x45, 0xbb, 0xd7,
- 0x26, 0xcd, 0x88, 0xfa, 0xe8, 0x0f, 0x26, 0x5b,
- 0x1f, 0x21, 0x3f, 0x3b, 0x5d, 0x98, 0x3f, 0x02,
- 0x8c, 0xa1, 0xbf, 0xc0, 0x70, 0x4d, 0xd1, 0x41,
- 0xfd, 0xb9, 0x55, 0x12, 0x90, 0xc8, 0x6e, 0x0f,
- 0x19, 0xa8, 0x5c, 0x31, 0xd6, 0x16, 0x0e, 0xdf,
- 0x08, 0x84, 0xcd, 0x4b, 0xfd, 0x28, 0x8d, 0x7d,
- 0x6e, 0xea, 0xc7, 0x95, 0x4a, 0xc3, 0x84, 0x54,
- 0x7f, 0xb0, 0x20, 0x29, 0x96, 0x39, 0x4c, 0x3e,
- 0x85, 0xec, 0x22, 0xdd, 0xb9, 0x14, 0xbb, 0x04,
- 0x2f, 0x4c, 0x0c, 0xe3, 0xfa, 0xae, 0x47, 0x79,
- 0x59, 0x8e, 0x4e, 0x7d, 0x4a, 0x17, 0xae, 0x16,
- 0x38, 0x66, 0x4e, 0xff, 0x45, 0x7f, 0xac, 0x5e,
- 0x75, 0x9f, 0x51, 0x18, 0xe6, 0xad, 0x6b, 0x8b,
- 0x3d, 0x08, 0x4d, 0x9a, 0xd2, 0x11, 0xba, 0xa8,
- 0xc3, 0xb5, 0x17, 0xb5, 0xdf, 0xe7, 0x39, 0x89,
- 0x27, 0x7b, 0xeb, 0xf4, 0xe5, 0x7e, 0xa9, 0x7b,
- 0x39, 0x40, 0x6f, 0xe4, 0x82, 0x14, 0x3d, 0x62,
- 0xb6, 0xd4, 0x43, 0xd0, 0x0a, 0x2f, 0xc1, 0x73,
- 0x3d, 0x99, 0x37, 0xbe, 0x62, 0x13, 0x6a, 0x8b,
- 0xeb, 0xc5, 0x64, 0xd5, 0x2a, 0x8b, 0x4f, 0x7f,
- 0x82, 0x48, 0x69, 0x3e, 0x08, 0x1b, 0xb5, 0x77,
- 0xd3, 0xdc, 0x1b, 0x2c, 0xe5, 0x59, 0xf6, 0x33,
- 0x47, 0xa0, 0x0f, 0xff, 0x8a, 0x6a, 0x1d, 0x66,
- 0x24, 0x67, 0x36, 0x7d, 0x21, 0xda, 0xc1, 0xd4,
- 0x11, 0x6c, 0xe8, 0x5f, 0xd7, 0x8a, 0x53, 0x5c,
- 0xb2, 0xe2, 0xf9, 0x14, 0x29, 0x0f, 0xcf, 0x28,
- 0x32, 0x4f, 0xc6, 0x17, 0xf6, 0xbc, 0x0e, 0xb8,
- 0x99, 0x7c, 0x14, 0xa3, 0x40, 0x3f, 0xf3, 0xe4,
- 0x31, 0xbe, 0x54, 0x64, 0x5a, 0xad, 0x1d, 0xb0,
- 0x37, 0xcc, 0xd9, 0x0b, 0xa4, 0xbc, 0xe0, 0x07,
- 0x37, 0xd1, 0xe1, 0x65, 0xc6, 0x53, 0xfe, 0x60,
- 0x6a, 0x64, 0xa4, 0x01, 0x00, 0xf3, 0x5b, 0x9a,
- 0x28, 0x61, 0xde, 0x7a, 0xd7, 0x0d, 0x56, 0x1e,
- 0x4d, 0xa8, 0x6a, 0xb5, 0xf2, 0x86, 0x2a, 0x4e,
- 0xaa, 0x37, 0x23, 0x5a, 0x3b, 0x69, 0x66, 0x81,
- 0xc8, 0x8e, 0x1b, 0x31, 0x0f, 0x28, 0x31, 0x9a,
- 0x2d, 0xe5, 0x79, 0xcc, 0xa4, 0xca, 0x60, 0x45,
- 0xf7, 0x83, 0x73, 0x5a, 0x01, 0x29, 0xda, 0xf7,
-
-};
-static const unsigned char rsa_sigverx931_0_e[] = {
- 0x01, 0x00, 0x01,
-};
-static const unsigned char rsa_sigverx931_0_msg[] = {
- 0x82, 0x2e, 0x41, 0x70, 0x9d, 0x1f, 0xe9, 0x47,
- 0xec, 0xf1, 0x79, 0xcc, 0x05, 0xef, 0xdb, 0xcd,
- 0xca, 0x8b, 0x8e, 0x61, 0x45, 0xad, 0xa6, 0xd9,
- 0xd7, 0x4b, 0x15, 0xf4, 0x92, 0x3a, 0x2a, 0x52,
- 0xe3, 0x44, 0x57, 0x2b, 0x74, 0x7a, 0x37, 0x41,
- 0x50, 0xcb, 0xcf, 0x13, 0x49, 0xd6, 0x15, 0x54,
- 0x97, 0xfd, 0xae, 0x9b, 0xc1, 0xbb, 0xfc, 0x5c,
- 0xc1, 0x37, 0x58, 0x17, 0x63, 0x19, 0x9c, 0xcf,
- 0xee, 0x9c, 0xe5, 0xbe, 0x06, 0xe4, 0x97, 0x47,
- 0xd1, 0x93, 0xa1, 0x2c, 0x59, 0x97, 0x02, 0x01,
- 0x31, 0x45, 0x8c, 0xe1, 0x5c, 0xac, 0xe7, 0x5f,
- 0x6a, 0x23, 0xda, 0xbf, 0xe4, 0x25, 0xc6, 0x67,
- 0xea, 0x5f, 0x73, 0x90, 0x1b, 0x06, 0x0f, 0x41,
- 0xb5, 0x6e, 0x74, 0x7e, 0xfd, 0xd9, 0xaa, 0xbd,
- 0xe2, 0x8d, 0xad, 0x99, 0xdd, 0x29, 0x70, 0xca,
- 0x1b, 0x38, 0x21, 0x55, 0xde, 0x07, 0xaf, 0x00,
-
-};
-static const unsigned char rsa_sigverx931_0_sig[] = {
- 0x29, 0xa9, 0x3a, 0x8e, 0x9e, 0x90, 0x1b, 0xdb,
- 0xaf, 0x0b, 0x47, 0x5b, 0xb5, 0xc3, 0x8c, 0xc3,
- 0x70, 0xbe, 0x73, 0xf9, 0x65, 0x8e, 0xc6, 0x1e,
- 0x95, 0x0b, 0xdb, 0x24, 0x76, 0x79, 0xf1, 0x00,
- 0x71, 0xcd, 0xc5, 0x6a, 0x7b, 0xd2, 0x8b, 0x18,
- 0xc4, 0xdd, 0xf1, 0x2a, 0x31, 0x04, 0x3f, 0xfc,
- 0x36, 0x06, 0x20, 0x71, 0x3d, 0x62, 0xf2, 0xb5,
- 0x79, 0x0a, 0xd5, 0xd2, 0x81, 0xf1, 0xb1, 0x4f,
- 0x9a, 0x17, 0xe8, 0x67, 0x64, 0x48, 0x09, 0x75,
- 0xff, 0x2d, 0xee, 0x36, 0xca, 0xca, 0x1d, 0x74,
- 0x99, 0xbe, 0x5c, 0x94, 0x31, 0xcc, 0x12, 0xf4,
- 0x59, 0x7e, 0x17, 0x00, 0x4f, 0x7b, 0xa4, 0xb1,
- 0xda, 0xdb, 0x3e, 0xa4, 0x34, 0x10, 0x4a, 0x19,
- 0x0a, 0xd2, 0xa7, 0xa0, 0xc5, 0xe6, 0xef, 0x82,
- 0xd4, 0x2e, 0x21, 0xbe, 0x15, 0x73, 0xac, 0xef,
- 0x05, 0xdb, 0x6a, 0x8a, 0x1a, 0xcb, 0x8e, 0xa5,
- 0xee, 0xfb, 0x28, 0xbf, 0x96, 0xa4, 0x2b, 0xd2,
- 0x85, 0x2b, 0x20, 0xc3, 0xaf, 0x9a, 0x32, 0x04,
- 0xa0, 0x49, 0x24, 0x47, 0xd0, 0x09, 0xf7, 0xcf,
- 0x73, 0xb6, 0xf6, 0x70, 0xda, 0x3b, 0xf8, 0x5a,
- 0x28, 0x2e, 0x14, 0x6c, 0x52, 0xbd, 0x2a, 0x7c,
- 0x8e, 0xc1, 0xa8, 0x0e, 0xb1, 0x1e, 0x6b, 0x8d,
- 0x76, 0xea, 0x70, 0x81, 0xa0, 0x02, 0x63, 0x74,
- 0xbc, 0x7e, 0xb9, 0xac, 0x0e, 0x7b, 0x1b, 0x75,
- 0x82, 0xe2, 0x98, 0x4e, 0x24, 0x55, 0xd4, 0xbd,
- 0x14, 0xde, 0x58, 0x56, 0x3a, 0x5d, 0x4e, 0x57,
- 0x0d, 0x54, 0x74, 0xe8, 0x86, 0x8c, 0xcb, 0x07,
- 0x9f, 0x0b, 0xfb, 0xc2, 0x08, 0x5c, 0xd7, 0x05,
- 0x3b, 0xc8, 0xd2, 0x15, 0x68, 0x8f, 0x3d, 0x3c,
- 0x4e, 0x85, 0xa9, 0x25, 0x6f, 0xf5, 0x2e, 0xca,
- 0xca, 0xa8, 0x27, 0x89, 0x61, 0x4e, 0x1f, 0x57,
- 0x2d, 0x99, 0x10, 0x3f, 0xbc, 0x9e, 0x96, 0x5e,
- 0x2f, 0x0a, 0x25, 0xa7, 0x5c, 0xea, 0x65, 0x2a,
- 0x22, 0x35, 0xa3, 0xf9, 0x13, 0x89, 0x05, 0x2e,
- 0x19, 0x73, 0x1d, 0x70, 0x74, 0x98, 0x15, 0x4b,
- 0xab, 0x56, 0x52, 0xe0, 0x01, 0x42, 0x95, 0x6a,
- 0x46, 0x2c, 0x78, 0xff, 0x26, 0xbc, 0x48, 0x10,
- 0x38, 0x25, 0xab, 0x32, 0x7c, 0x79, 0x7c, 0x5d,
- 0x6f, 0x45, 0x54, 0x74, 0x2d, 0x93, 0x56, 0x52,
- 0x11, 0x34, 0x1e, 0xe3, 0x4b, 0x6a, 0x17, 0x4f,
- 0x37, 0x14, 0x75, 0xac, 0xa3, 0xa1, 0xca, 0xda,
- 0x38, 0x06, 0xa9, 0x78, 0xb9, 0x5d, 0xd0, 0x59,
- 0x1b, 0x5d, 0x1e, 0xc2, 0x0b, 0xfb, 0x39, 0x37,
- 0x44, 0x85, 0xb6, 0x36, 0x06, 0x95, 0xbc, 0x15,
- 0x35, 0xb9, 0xe6, 0x27, 0x42, 0xe3, 0xc8, 0xec,
- 0x30, 0x37, 0x20, 0x26, 0x9a, 0x11, 0x61, 0xc0,
- 0xdb, 0xb2, 0x5a, 0x26, 0x78, 0x27, 0xb9, 0x13,
- 0xc9, 0x1a, 0xa7, 0x67, 0x93, 0xe8, 0xbe, 0xcb,
-};
-
-#define rsa_sigverx931_1_n rsa_sigverx931_0_n
-#define rsa_sigverx931_1_e rsa_sigverx931_0_e
-static const unsigned char rsa_sigverx931_1_msg[] = {
- 0x79, 0x02, 0xb9, 0xd2, 0x3e, 0x84, 0x02, 0xc8,
- 0x2a, 0x94, 0x92, 0x14, 0x8d, 0xd5, 0xd3, 0x8d,
- 0xb2, 0xf6, 0x00, 0x8b, 0x61, 0x2c, 0xd2, 0xf9,
- 0xa8, 0xe0, 0x5d, 0xac, 0xdc, 0xa5, 0x34, 0xf3,
- 0xda, 0x6c, 0xd4, 0x70, 0x92, 0xfb, 0x40, 0x26,
- 0xc7, 0x9b, 0xe8, 0xd2, 0x10, 0x11, 0xcf, 0x7f,
- 0x23, 0xd0, 0xed, 0x55, 0x52, 0x6d, 0xd3, 0xb2,
- 0x56, 0x53, 0x8d, 0x7c, 0x4c, 0xb8, 0xcc, 0xb5,
- 0xfd, 0xd0, 0x45, 0x4f, 0x62, 0x40, 0x54, 0x42,
- 0x68, 0xd5, 0xe5, 0xdd, 0xf0, 0x76, 0x94, 0x59,
- 0x1a, 0x57, 0x13, 0xb4, 0xc3, 0x70, 0xcc, 0xbd,
- 0x4c, 0x2e, 0xc8, 0x6b, 0x9d, 0x68, 0xd0, 0x72,
- 0x6a, 0x94, 0xd2, 0x18, 0xb5, 0x3b, 0x86, 0x45,
- 0x95, 0xaa, 0x50, 0xda, 0x35, 0xeb, 0x69, 0x44,
- 0x1f, 0xf3, 0x3a, 0x51, 0xbb, 0x1d, 0x08, 0x42,
- 0x12, 0xd7, 0xd6, 0x21, 0xd8, 0x9b, 0x87, 0x55,
-};
-
-static const unsigned char rsa_sigverx931_1_sig[] = {
- 0x3b, 0xba, 0xb3, 0xb1, 0xb2, 0x6a, 0x29, 0xb5,
- 0xf9, 0x94, 0xf1, 0x00, 0x5c, 0x16, 0x67, 0x67,
- 0x73, 0xd3, 0xde, 0x7e, 0x07, 0xfa, 0xaa, 0x95,
- 0xeb, 0x5a, 0x55, 0xdc, 0xb2, 0xa9, 0x70, 0x5a,
- 0xee, 0x8f, 0x8d, 0x69, 0x85, 0x2b, 0x00, 0xe3,
- 0xdc, 0xe2, 0x73, 0x9b, 0x68, 0xeb, 0x93, 0x69,
- 0x08, 0x03, 0x17, 0xd6, 0x50, 0x21, 0x14, 0x23,
- 0x8c, 0xe6, 0x54, 0x3a, 0xd9, 0xfc, 0x8b, 0x14,
- 0x81, 0xb1, 0x8b, 0x9d, 0xd2, 0xbe, 0x58, 0x75,
- 0x94, 0x74, 0x93, 0xc9, 0xbb, 0x4e, 0xf6, 0x1f,
- 0x73, 0x7d, 0x1a, 0x5f, 0xbd, 0xbf, 0x59, 0x37,
- 0x5b, 0x98, 0x54, 0xad, 0x3a, 0xef, 0xa0, 0xef,
- 0xcb, 0xc3, 0xe8, 0x84, 0xd8, 0x3d, 0xf5, 0x60,
- 0xb8, 0xc3, 0x8d, 0x1e, 0x78, 0xa0, 0x91, 0x94,
- 0xb7, 0xd7, 0xb1, 0xd4, 0xe2, 0xee, 0x81, 0x93,
- 0xfc, 0x41, 0xf0, 0x31, 0xbb, 0x03, 0x52, 0xde,
- 0x80, 0x20, 0x3a, 0x68, 0xe6, 0xc5, 0x50, 0x1b,
- 0x08, 0x3f, 0x40, 0xde, 0xb3, 0xe5, 0x81, 0x99,
- 0x7f, 0xdb, 0xb6, 0x5d, 0x61, 0x27, 0xd4, 0xfb,
- 0xcd, 0xc5, 0x7a, 0xea, 0xde, 0x7a, 0x66, 0xef,
- 0x55, 0x3f, 0x85, 0xea, 0x84, 0xc5, 0x0a, 0xf6,
- 0x3c, 0x40, 0x38, 0xf7, 0x6c, 0x66, 0xe5, 0xbe,
- 0x61, 0x41, 0xd3, 0xb1, 0x08, 0xe1, 0xb4, 0xf9,
- 0x6e, 0xf6, 0x0e, 0x4a, 0x72, 0x6c, 0x61, 0x63,
- 0x3e, 0x41, 0x33, 0x94, 0xd6, 0x27, 0xa4, 0xd9,
- 0x3a, 0x20, 0x2b, 0x39, 0xea, 0xe5, 0x82, 0x48,
- 0xd6, 0x5b, 0x58, 0x85, 0x44, 0xb0, 0xd2, 0xfd,
- 0xfb, 0x3e, 0xeb, 0x78, 0xac, 0xbc, 0xba, 0x16,
- 0x92, 0x0e, 0x20, 0xc1, 0xb2, 0xd1, 0x92, 0xa8,
- 0x00, 0x88, 0xc0, 0x41, 0x46, 0x38, 0xb6, 0x54,
- 0x70, 0x0c, 0x00, 0x62, 0x97, 0x6a, 0x8e, 0x66,
- 0x5a, 0xa1, 0x6c, 0xf7, 0x6d, 0xc2, 0x27, 0x56,
- 0x60, 0x5b, 0x0c, 0x52, 0xac, 0x5c, 0xae, 0x99,
- 0x55, 0x11, 0x62, 0x52, 0x09, 0x48, 0x53, 0x90,
- 0x3c, 0x0b, 0xd4, 0xdc, 0x7b, 0xe3, 0x4c, 0xe3,
- 0xa8, 0x6d, 0xc5, 0xdf, 0xc1, 0x5c, 0x59, 0x25,
- 0x99, 0x30, 0xde, 0x57, 0x6a, 0x84, 0x25, 0x34,
- 0x3e, 0x64, 0x11, 0xdb, 0x7a, 0x82, 0x8e, 0x70,
- 0xd2, 0x5c, 0x0e, 0x81, 0xa0, 0x24, 0x53, 0x75,
- 0x98, 0xd6, 0x10, 0x01, 0x6a, 0x14, 0xed, 0xc3,
- 0x6f, 0xc4, 0x18, 0xb8, 0xd2, 0x9f, 0x59, 0x53,
- 0x81, 0x3a, 0x86, 0x31, 0xfc, 0x9e, 0xbf, 0x6c,
- 0x52, 0x93, 0x86, 0x9c, 0xaa, 0x6c, 0x6f, 0x07,
- 0x8a, 0x40, 0x33, 0x64, 0xb2, 0x70, 0x48, 0x85,
- 0x05, 0x59, 0x65, 0x2d, 0x6b, 0x9a, 0xad, 0xab,
- 0x20, 0x7e, 0x02, 0x6d, 0xde, 0xcf, 0x22, 0x0b,
- 0xea, 0x6e, 0xbd, 0x1c, 0x39, 0x3a, 0xfd, 0xa4,
- 0xde, 0x54, 0xae, 0xde, 0x5e, 0xf7, 0xb0, 0x6d,
-};
-
static const struct rsa_sigver_st rsa_sigver_data[] = {
{
"pkcs1", /* pkcs1v1.5 */
@@ -1841,17 +1638,6 @@ static const struct rsa_sigver_st rsa_sigver_data[] = {
NO_PSS_SALT_LEN,
FAIL
},
- {
- "x931",
- 3072,
- "SHA256",
- ITM(rsa_sigverx931_1_msg),
- ITM(rsa_sigverx931_1_n),
- ITM(rsa_sigverx931_1_e),
- ITM(rsa_sigverx931_1_sig),
- NO_PSS_SALT_LEN,
- FAIL
- },
{
"pss",
4096,
--
2.38.1

@ -0,0 +1,74 @@
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,112 @@
From e1eba21921ceeffa45ffd2115868c14e4c7fb8d9 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Thu, 17 Nov 2022 18:08:24 +0100
Subject: [PATCH] hmac: Add explicit FIPS indicator for key length
NIST SP 800-131Ar2, table 9 "Approval Status of MAC Algorithms"
specifies key lengths < 112 bytes are disallowed for HMAC generation and
are legacy use for HMAC verification.
Add an explicit indicator that will mark shorter key lengths as
unsupported. The indicator can be queries from the EVP_MAC_CTX object
using EVP_MAC_CTX_get_params() with the
OSSL_MAC_PARAM_REDHAT_FIPS_INDICATOR
parameter.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
include/crypto/evp.h | 7 +++++++
include/openssl/core_names.h | 1 +
include/openssl/evp.h | 3 +++
providers/implementations/macs/hmac_prov.c | 17 +++++++++++++++++
4 files changed, 28 insertions(+)
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 76fb990de4..1e2240516e 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -196,6 +196,13 @@ const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void);
const EVP_PKEY_METHOD *ossl_rsa_pkey_method(void);
const EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void);
+#ifdef FIPS_MODULE
+/* NIST SP 800-131Ar2, Table 9: Approval Status of MAC Algorithms specifies key
+ * lengths < 112 bytes are disallowed for HMAC generation and legacy use for
+ * HMAC verification. */
+# define EVP_HMAC_GEN_FIPS_MIN_KEY_LEN (112 / 8)
+#endif
+
struct evp_mac_st {
OSSL_PROVIDER *prov;
int name_id;
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index c019afbbb0..94fab83193 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -173,6 +173,7 @@ extern "C" {
#define OSSL_MAC_PARAM_SIZE "size" /* size_t */
#define OSSL_MAC_PARAM_BLOCK_SIZE "block-size" /* size_t */
#define OSSL_MAC_PARAM_TLS_DATA_SIZE "tls-data-size" /* size_t */
+#define OSSL_MAC_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
/* Known MAC names */
#define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC"
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 49e8e1df78..a5e78efd6e 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1192,6 +1192,9 @@ void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx,
void *arg);
/* MAC stuff */
+# define EVP_MAC_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
+# define EVP_MAC_REDHAT_FIPS_INDICATOR_APPROVED 1
+# define EVP_MAC_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
const char *properties);
diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c
index 52ebb08b8f..cf5c3ecbe7 100644
--- a/providers/implementations/macs/hmac_prov.c
+++ b/providers/implementations/macs/hmac_prov.c
@@ -21,6 +21,8 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include "crypto/evp.h"
+
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
@@ -244,6 +246,9 @@ static int hmac_final(void *vmacctx, unsigned char *out, size_t *outl,
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
+#ifdef FIPS_MODULE
+ OSSL_PARAM_int(OSSL_MAC_PARAM_REDHAT_FIPS_INDICATOR, NULL),
+#endif /* defined(FIPS_MODULE) */
OSSL_PARAM_END
};
static const OSSL_PARAM *hmac_gettable_ctx_params(ossl_unused void *ctx,
@@ -265,6 +270,18 @@ static int hmac_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
&& !OSSL_PARAM_set_int(p, hmac_block_size(macctx)))
return 0;
+#ifdef FIPS_MODULE
+ if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_REDHAT_FIPS_INDICATOR)) != NULL) {
+ int fips_indicator = EVP_MAC_REDHAT_FIPS_INDICATOR_APPROVED;
+ /* NIST SP 800-131Ar2, Table 9: Approval Status of MAC Algorithms
+ * specifies key lengths < 112 bytes are disallowed for HMAC generation
+ * and legacy use for HMAC verification. */
+ if (macctx->keylen < EVP_HMAC_GEN_FIPS_MIN_KEY_LEN)
+ fips_indicator = EVP_MAC_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
+ return OSSL_PARAM_set_int(p, fips_indicator);
+ }
+#endif /* defined(FIPS_MODULE) */
+
return 1;
}
--
2.38.1

@ -0,0 +1,86 @@
From 754862899058cfb5f2341c81f9e04dd2f7b37056 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Thu, 17 Nov 2022 18:37:17 +0100
Subject: [PATCH] pbkdf2: Set minimum password length of 8 bytes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Implementation Guidance for FIPS 140-3 says in section D.N
"Password-Based Key Derivation for Storage Applications" that "the
vendor shall document in the modules Security Policy the length of
a password/passphrase used in key derivation and establish an upper
bound for the probability of having this parameter guessed at random.
This probability shall take into account not only the length of the
password/passphrase, but also the difficulty of guessing it. The
decision on the minimum length of a password used for key derivation is
the vendors, but the vendor shall at a minimum informally justify the
decision."
We are choosing a minimum password length of 8 bytes, because NIST's
ACVP testing uses passwords as short as 8 bytes, and requiring longer
passwords combined with an implicit indicator (i.e., returning an error)
would cause the module to fail ACVP testing.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
providers/implementations/kdfs/pbkdf2.c | 27 ++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
index 2a0ae63acc..aa0adce5e6 100644
--- a/providers/implementations/kdfs/pbkdf2.c
+++ b/providers/implementations/kdfs/pbkdf2.c
@@ -35,6 +35,21 @@
#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
#define KDF_PBKDF2_MIN_ITERATIONS 1000
#define KDF_PBKDF2_MIN_SALT_LEN (128 / 8)
+/* The Implementation Guidance for FIPS 140-3 says in section D.N
+ * "Password-Based Key Derivation for Storage Applications" that "the vendor
+ * shall document in the modules Security Policy the length of
+ * a password/passphrase used in key derivation and establish an upper bound
+ * for the probability of having this parameter guessed at random. This
+ * probability shall take into account not only the length of the
+ * password/passphrase, but also the difficulty of guessing it. The decision on
+ * the minimum length of a password used for key derivation is the vendors,
+ * but the vendor shall at a minimum informally justify the decision."
+ *
+ * We are choosing a minimum password length of 8 bytes, because NIST's ACVP
+ * testing uses passwords as short as 8 bytes, and requiring longer passwords
+ * combined with an implicit indicator (i.e., returning an error) would cause
+ * the module to fail ACVP testing. */
+#define KDF_PBKDF2_MIN_PASSWORD_LEN (8)
static OSSL_FUNC_kdf_newctx_fn kdf_pbkdf2_new;
static OSSL_FUNC_kdf_freectx_fn kdf_pbkdf2_free;
@@ -186,9 +201,15 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
ctx->lower_bound_checks = pkcs5 == 0;
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) {
+ if (ctx->lower_bound_checks != 0
+ && p->data_size < KDF_PBKDF2_MIN_PASSWORD_LEN) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
if (!pbkdf2_set_membuf(&ctx->pass, &ctx->pass_len, p))
return 0;
+ }
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
if (ctx->lower_bound_checks != 0
@@ -297,6 +318,10 @@ static int pbkdf2_derive(const char *pass, size_t passlen,
}
if (lower_bound_checks) {
+ if (passlen < KDF_PBKDF2_MIN_PASSWORD_LEN) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
return 0;
--
2.38.1

@ -0,0 +1,113 @@
From 52b347703ba2b98a0efee86c1a483c2f0f9f73d6 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Wed, 11 Jan 2023 12:52:59 +0100
Subject: [PATCH] rsa: Disallow SHAKE in OAEP and PSS in FIPS prov
According to FIPS 140-3 IG, section C.C, the SHAKE digest algorithms
must not be used in higher-level algorithms (such as RSA-OAEP and
RSASSA-PSS):
"To be used in an approved mode of operation, the SHA-3 hash functions
may be implemented either as part of an approved higher-level algorithm,
for example, a digital signature algorithm, or as the standalone
functions. The SHAKE128 and SHAKE256 extendable-output functions may
only be used as the standalone algorithms."
Add a check to prevent their use as message digest in PSS signatures and
as MGF1 hash function in both OAEP and PSS.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
crypto/rsa/rsa_oaep.c | 28 ++++++++++++++++++++++++++++
crypto/rsa/rsa_pss.c | 16 ++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index d9be1a4f98..dfe9c9f0e8 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -73,9 +73,23 @@ int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
return 0;
#endif
}
+
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(md, "SHAKE-128") || EVP_MD_is_a(md, "SHAKE-256")) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
+ return 0;
+ }
+#endif
if (mgf1md == NULL)
mgf1md = md;
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(mgf1md, "SHAKE-128") || EVP_MD_is_a(mgf1md, "SHAKE-256")) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
+ return 0;
+ }
+#endif
+
mdlen = EVP_MD_get_size(md);
if (mdlen <= 0) {
ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_LENGTH);
@@ -181,9 +195,23 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
#endif
}
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(md, "SHAKE-128") || EVP_MD_is_a(md, "SHAKE-256")) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
+ return -1;
+ }
+#endif
+
if (mgf1md == NULL)
mgf1md = md;
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(mgf1md, "SHAKE-128") || EVP_MD_is_a(mgf1md, "SHAKE-256")) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED);
+ return -1;
+ }
+#endif
+
mdlen = EVP_MD_get_size(md);
if (tlen <= 0 || flen <= 0)
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index 33874bfef8..e8681b0351 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -53,6 +53,14 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
if (mgf1Hash == NULL)
mgf1Hash = Hash;
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(Hash, "SHAKE-128") || EVP_MD_is_a(Hash, "SHAKE-256"))
+ goto err;
+
+ if (EVP_MD_is_a(mgf1Hash, "SHAKE-128") || EVP_MD_is_a(mgf1Hash, "SHAKE-256"))
+ goto err;
+#endif
+
hLen = EVP_MD_get_size(Hash);
if (hLen < 0)
goto err;
@@ -164,6 +172,14 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
if (mgf1Hash == NULL)
mgf1Hash = Hash;
+#ifdef FIPS_MODULE
+ if (EVP_MD_is_a(Hash, "SHAKE-128") || EVP_MD_is_a(Hash, "SHAKE-256"))
+ goto err;
+
+ if (EVP_MD_is_a(mgf1Hash, "SHAKE-128") || EVP_MD_is_a(mgf1Hash, "SHAKE-256"))
+ goto err;
+#endif
+
hLen = EVP_MD_get_size(Hash);
if (hLen < 0)
goto err;
--
2.39.0

@ -0,0 +1,48 @@
From 3d046c4d047a55123beeceffe9f8bae09159445e Mon Sep 17 00:00:00 2001
From: yangyangtiantianlonglong <yangtianlong1224@163.com>
Date: Wed, 19 Jan 2022 11:19:52 +0800
Subject: [PATCH] Fix the same BIO_FLAGS macro definition
Also add comment to the public header to avoid
making another conflict in future.
Fixes #17545
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17546)
(cherry picked from commit e278f18563dd3dd67c00200ee30402f48023c6ef)
---
include/internal/bio.h | 2 +-
include/openssl/bio.h.in | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/internal/bio.h b/include/internal/bio.h
index 2d36a7b980f2..02f7222ab4f1 100644
--- a/include/internal/bio.h
+++ b/include/internal/bio.h
@@ -48,9 +48,9 @@ int bread_conv(BIO *bio, char *data, size_t datal, size_t *read);
* BIO_FLAGS_KTLS_TX_CTRL_MSG means we are about to send a ctrl message next.
* BIO_FLAGS_KTLS_RX means we are using ktls with this BIO for receiving.
*/
-# define BIO_FLAGS_KTLS_TX 0x800
# define BIO_FLAGS_KTLS_TX_CTRL_MSG 0x1000
# define BIO_FLAGS_KTLS_RX 0x2000
+# define BIO_FLAGS_KTLS_TX 0x4000
/* KTLS related controls and flags */
# define BIO_set_ktls_flag(b, is_tx) \
diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in
index 2c65b7e1a79b..686dad3099b7 100644
--- a/include/openssl/bio.h.in
+++ b/include/openssl/bio.h.in
@@ -209,6 +209,8 @@ extern "C" {
# define BIO_FLAGS_NONCLEAR_RST 0x400
# define BIO_FLAGS_IN_EOF 0x800
+/* the BIO FLAGS values 0x1000 to 0x4000 are reserved for internal KTLS flags */
+
typedef union bio_addr_st BIO_ADDR;
typedef struct bio_addrinfo_st BIO_ADDRINFO;

@ -0,0 +1,41 @@
From 34e3cbf99f2113ca01b460cf37b56460262979af Mon Sep 17 00:00:00 2001
From: slontis <shane.lontis@oracle.com>
Date: Wed, 26 Oct 2022 11:10:50 +1000
Subject: [PATCH] Use RSA CRT parameters in FIPS self tests.
Fixes #19488
Use the correct OSSL_PKEY_PARAM_RSA CRT names fior the self tests.
The invalid names cause CRT parameters to be silently ignored.
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19501)
(cherry picked from commit c7424fe68c65aa2187a8e4028d7dea742b95d81a)
(cherry picked from commit 4215d649e92bc4c42997ec4a1e65beba1055bbe1)
---
providers/fips/self_test_data.inc | 10 +++++-----
diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc
index 5f057d5679f1..8ae8cd6f4a5a 100644
--- a/providers/fips/self_test_data.inc
+++ b/providers/fips/self_test_data.inc
@@ -1270,11 +1270,11 @@ static const ST_KAT_PARAM rsa_crt_key[] = {
ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n),
ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e),
ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_D, rsa_d),
- ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR, rsa_p),
- ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR, rsa_q),
- ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT, rsa_dp),
- ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT, rsa_dq),
- ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_COEFFICIENT, rsa_qInv),
+ ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR1, rsa_p),
+ ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR2, rsa_q),
+ ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT1, rsa_dp),
+ ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT2, rsa_dq),
+ ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, rsa_qInv),
ST_KAT_PARAM_END()
};

@ -0,0 +1,110 @@
From a325a23bc83f4efd60130001c417ca5b96bdbff1 Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Thu, 17 Nov 2022 19:33:02 +0100
Subject: [PATCH 1/3] signature: Add indicator for PSS salt length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of
the hash function output block (in bytes)."
It is not exactly clear from this text whether hLen refers to the
message digest or the hash function used for the mask generation
function MGF1. PKCS#1 v2.1 suggests it is the former:
| Typical salt lengths in octets are hLen (the length of the output of
| the hash function Hash) and 0. In both cases the security of
| RSASSA-PSS can be closely related to the hardness of inverting RSAVP1.
| Bellare and Rogaway [4] give a tight lower bound for the security of
| the original RSA-PSS scheme, which corresponds roughly to the former
| case, while Coron [12] gives a lower bound for the related Full Domain
| Hashing scheme, which corresponds roughly to the latter case. In [13]
| Coron provides a general treatment with various salt lengths ranging
| from 0 to hLen; see [27] for discussion. See also [31], which adapts
| the security proofs in [4][13] to address the differences between the
| original and the present version of RSA-PSS as listed in Note 1 above.
Since OpenSSL defaults to creating signatures with the maximum salt
length, blocking the use of longer salts would probably lead to
significant problems in practice. Instead, introduce an explicit
indicator that can be obtained from the EVP_PKEY_CTX object using
EVP_PKEY_CTX_get_params() with the
OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR
parameter.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
include/openssl/core_names.h | 1 +
include/openssl/evp.h | 4 ++++
providers/implementations/signature/rsa_sig.c | 18 ++++++++++++++++++
3 files changed, 23 insertions(+)
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 94fab83193..69c59f0b46 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -453,6 +453,7 @@ extern "C" {
#define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES \
OSSL_PKEY_PARAM_MGF1_PROPERTIES
#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE OSSL_PKEY_PARAM_DIGEST_SIZE
+#define OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
/* Asym cipher parameters */
#define OSSL_ASYM_CIPHER_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index a5e78efd6e..f239200465 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -797,6 +797,10 @@ __owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
int *outl);
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_APPROVED 1
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
+
__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
EVP_PKEY *pkey);
__owur int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
index 49e7f9158a..0c45008a00 100644
--- a/providers/implementations/signature/rsa_sig.c
+++ b/providers/implementations/signature/rsa_sig.c
@@ -1127,6 +1127,21 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
}
}
+#ifdef FIPS_MODULE
+ p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR);
+ if (p != NULL) {
+ int fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_APPROVED;
+ if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) {
+ if (prsactx->md == NULL) {
+ fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_UNDETERMINED;
+ } else if (rsa_pss_compute_saltlen(prsactx) > EVP_MD_get_size(prsactx->md)) {
+ fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
+ }
+ }
+ return OSSL_PARAM_set_int(p, fips_indicator);
+ }
+#endif
+
return 1;
}
@@ -1136,6 +1151,9 @@ static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
+#ifdef FIPS_MODULE
+ OSSL_PARAM_int(OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR, NULL),
+#endif
OSSL_PARAM_END
};
--
2.38.1

@ -0,0 +1,114 @@
From 0879fac692cb1bff0ec4c196cb364d970ad3ecec Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Mon, 21 Nov 2022 14:33:57 +0100
Subject: [PATCH 2/3] Obtain PSS salt length from provider
Rather than computing the PSS salt length again in core using
ossl_rsa_ctx_to_pss_string, which calls rsa_ctx_to_pss and computes the
salt length, obtain it from the provider using the
OSSL_SIGNATURE_PARAM_ALGORITHM_ID param to handle the case where the
interpretation of the magic constants in the provider differs from that
of OpenSSL core.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
crypto/cms/cms_rsa.c | 19 +++++++++++++++----
crypto/rsa/rsa_ameth.c | 34 +++++++++++++++++++++-------------
2 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c
index 20ed816918..997567fdbf 100644
--- a/crypto/cms/cms_rsa.c
+++ b/crypto/cms/cms_rsa.c
@@ -10,6 +10,7 @@
#include <assert.h>
#include <openssl/cms.h>
#include <openssl/err.h>
+#include <openssl/core_names.h>
#include "crypto/asn1.h"
#include "crypto/rsa.h"
#include "cms_local.h"
@@ -191,7 +192,10 @@ static int rsa_cms_sign(CMS_SignerInfo *si)
int pad_mode = RSA_PKCS1_PADDING;
X509_ALGOR *alg;
EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
- ASN1_STRING *os = NULL;
+ unsigned char aid[128];
+ const unsigned char *pp = aid;
+ size_t aid_len = 0;
+ OSSL_PARAM params[2];
CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
if (pkctx != NULL) {
@@ -205,10 +209,17 @@ static int rsa_cms_sign(CMS_SignerInfo *si)
/* We don't support it */
if (pad_mode != RSA_PKCS1_PSS_PADDING)
return 0;
- os = ossl_rsa_ctx_to_pss_string(pkctx);
- if (os == NULL)
+
+ params[0] = OSSL_PARAM_construct_octet_string(
+ OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid));
+ params[1] = OSSL_PARAM_construct_end();
+
+ if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0)
+ return 0;
+ if ((aid_len = params[0].return_size) == 0)
+ return 0;
+ if (d2i_X509_ALGOR(&alg, &pp, aid_len) == NULL)
return 0;
- X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os);
return 1;
}
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index c15554505b..61ec53d424 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -637,22 +637,30 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
if (pad_mode == RSA_PKCS1_PADDING)
return 2;
if (pad_mode == RSA_PKCS1_PSS_PADDING) {
- ASN1_STRING *os1 = NULL;
- os1 = ossl_rsa_ctx_to_pss_string(pkctx);
- if (!os1)
+ unsigned char aid[128];
+ size_t aid_len = 0;
+ OSSL_PARAM params[2];
+
+ params[0] = OSSL_PARAM_construct_octet_string(
+ OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid));
+ params[1] = OSSL_PARAM_construct_end();
+
+ if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0)
return 0;
- /* Duplicate parameters if we have to */
- if (alg2) {
- ASN1_STRING *os2 = ASN1_STRING_dup(os1);
- if (!os2) {
- ASN1_STRING_free(os1);
+ if ((aid_len = params[0].return_size) == 0)
+ return 0;
+
+ if (alg1 != NULL) {
+ const unsigned char *pp = aid;
+ if (d2i_X509_ALGOR(&alg1, &pp, aid_len) == NULL)
+ return 0;
+ }
+ if (alg2 != NULL) {
+ const unsigned char *pp = aid;
+ if (d2i_X509_ALGOR(&alg2, &pp, aid_len) == NULL)
return 0;
- }
- X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS),
- V_ASN1_SEQUENCE, os2);
}
- X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS),
- V_ASN1_SEQUENCE, os1);
+
return 3;
}
return 2;
--
2.38.1

@ -0,0 +1,338 @@
From 9cc914ff3e1fda124bdc76d72ebc9349ec19f8ae Mon Sep 17 00:00:00 2001
From: Clemens Lang <cllang@redhat.com>
Date: Fri, 18 Nov 2022 12:35:33 +0100
Subject: [PATCH 3/3] signature: Clamp PSS salt len to MD len
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
the hash function output block (in bytes)."
Introduce a new option RSA_PSS_SALTLEN_AUTO_DIGEST_MAX and make it the
default. The new value will behave like RSA_PSS_SALTLEN_AUTO, but will
not use more than the digest legth when signing, so that FIPS 186-4 is
not violated. This value has two advantages when compared with
RSA_PSS_SALTLEN_DIGEST: (1) It will continue to do auto-detection when
verifying signatures for maximum compatibility, where
RSA_PSS_SALTLEN_DIGEST would fail for other digest sizes. (2) It will
work for combinations where the maximum salt length is smaller than the
digest size, which typically happens with large digest sizes (e.g.,
SHA-512) and small RSA keys.
Signed-off-by: Clemens Lang <cllang@redhat.com>
---
crypto/rsa/rsa_ameth.c | 18 ++++++++-
crypto/rsa/rsa_pss.c | 26 ++++++++++--
doc/man3/EVP_PKEY_CTX_ctrl.pod | 11 ++++-
doc/man7/EVP_SIGNATURE-RSA.pod | 5 +++
include/openssl/core_names.h | 1 +
include/openssl/rsa.h | 3 ++
providers/implementations/signature/rsa_sig.c | 40 ++++++++++++++-----
test/recipes/25-test_req.t | 2 +-
8 files changed, 87 insertions(+), 19 deletions(-)
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 61ec53d424..e69a98d116 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -450,6 +450,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
const EVP_MD *sigmd, *mgf1md;
EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
int saltlen;
+ int saltlenMax = -1;
if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
return NULL;
@@ -457,14 +458,27 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
return NULL;
if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
return NULL;
- if (saltlen == -1) {
+ if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
saltlen = EVP_MD_get_size(sigmd);
- } else if (saltlen == -2 || saltlen == -3) {
+ } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm",
+ * subsection 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in
+ * bytes) of the salt (sLen) shall satisfy 0 <= sLen <= hLen, where
+ * hLen is the length of the hash function output block (in bytes)."
+ *
+ * Provide a way to use at most the digest length, so that the default
+ * does not violate FIPS 186-4. */
+ saltlen = RSA_PSS_SALTLEN_MAX;
+ saltlenMax = EVP_MD_get_size(sigmd);
+ }
+ if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) {
saltlen = EVP_PKEY_get_size(pk) - EVP_MD_get_size(sigmd) - 2;
if ((EVP_PKEY_get_bits(pk) & 0x7) == 1)
saltlen--;
if (saltlen < 0)
return NULL;
+ if (saltlenMax >= 0 && saltlen > saltlenMax)
+ saltlen = saltlenMax;
}
return ossl_rsa_pss_params_create(sigmd, mgf1md, saltlen);
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index 33874bfef8..430c36eb2a 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -61,11 +61,12 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
* -1 sLen == hLen
* -2 salt length is autorecovered from signature
* -3 salt length is maximized
+ * -4 salt length is autorecovered from signature
* -N reserved
*/
if (sLen == RSA_PSS_SALTLEN_DIGEST) {
sLen = hLen;
- } else if (sLen < RSA_PSS_SALTLEN_MAX) {
+ } else if (sLen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
@@ -112,7 +113,9 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED);
goto err;
}
- if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) {
+ if (sLen != RSA_PSS_SALTLEN_AUTO
+ && sLen != RSA_PSS_SALTLEN_AUTO_DIGEST_MAX
+ && (maskedDBLen - i) != sLen) {
ERR_raise_data(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED,
"expected: %d retrieved: %d", sLen,
maskedDBLen - i);
@@ -160,6 +163,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
int hLen, maskedDBLen, MSBits, emLen;
unsigned char *H, *salt = NULL, *p;
EVP_MD_CTX *ctx = NULL;
+ int sLenMax = -1;
if (mgf1Hash == NULL)
mgf1Hash = Hash;
@@ -172,13 +176,25 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
* -1 sLen == hLen
* -2 salt length is maximized
* -3 same as above (on signing)
+ * -4 salt length is min(hLen, maximum salt length)
* -N reserved
*/
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
+ * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
+ * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
+ * the hash function output block (in bytes)."
+ *
+ * Provide a way to use at most the digest length, so that the default does
+ * not violate FIPS 186-4. */
if (sLen == RSA_PSS_SALTLEN_DIGEST) {
sLen = hLen;
- } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) {
+ } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN
+ || sLen == RSA_PSS_SALTLEN_AUTO) {
sLen = RSA_PSS_SALTLEN_MAX;
- } else if (sLen < RSA_PSS_SALTLEN_MAX) {
+ } else if (sLen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
+ sLen = RSA_PSS_SALTLEN_MAX;
+ sLenMax = hLen;
+ } else if (sLen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
@@ -195,6 +211,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
}
if (sLen == RSA_PSS_SALTLEN_MAX) {
sLen = emLen - hLen - 2;
+ if (sLenMax >= 0 && sLen > sLenMax)
+ sLen = sLenMax;
} else if (sLen > emLen - hLen - 2) {
ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
index 3075eaafd6..9b96f42dbc 100644
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
@@ -270,8 +270,8 @@ EVP_PKEY_CTX_get_rsa_padding() gets the RSA padding mode for I<ctx>.
EVP_PKEY_CTX_set_rsa_pss_saltlen() sets the RSA PSS salt length to I<saltlen>.
As its name implies it is only supported for PSS padding. If this function is
-not called then the maximum salt length is used when signing and auto detection
-when verifying. Three special values are supported:
+not called then the salt length is maximized up to the digest length when
+signing and auto detection when verifying. Four special values are supported:
=over 4
@@ -289,6 +289,13 @@ causes the salt length to be automatically determined based on the
B<PSS> block structure when verifying. When signing, it has the same
meaning as B<RSA_PSS_SALTLEN_MAX>.
+=item B<RSA_PSS_SALTLEN_AUTO_DIGEST_MAX>
+
+causes the salt length to be automatically determined based on the B<PSS> block
+structure when verifying, like B<RSA_PSS_SALTLEN_AUTO>. When signing, the salt
+length is maximized up to a maximum of the digest length to comply with FIPS
+186-4 section 5.5.
+
=back
EVP_PKEY_CTX_get_rsa_pss_saltlen() gets the RSA PSS salt length for I<ctx>.
diff --git a/doc/man7/EVP_SIGNATURE-RSA.pod b/doc/man7/EVP_SIGNATURE-RSA.pod
index 1ce32cc443..13d053e262 100644
--- a/doc/man7/EVP_SIGNATURE-RSA.pod
+++ b/doc/man7/EVP_SIGNATURE-RSA.pod
@@ -68,6 +68,11 @@ Use the maximum salt length.
Auto detect the salt length.
+=item "auto-digestmax" (B<OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX>)
+
+Auto detect the salt length when verifying. Maximize the salt length up to the
+digest size when signing to comply with FIPS 186-4 section 5.5.
+
=back
=back
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 69c59f0b46..5779f41427 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -399,6 +399,7 @@ extern "C" {
#define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest"
#define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max"
#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto"
+#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX "auto-digestmax"
/* Key generation parameters */
#define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index a55c9727c6..daf55bc6d4 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -137,6 +137,9 @@ int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
# define RSA_PSS_SALTLEN_AUTO -2
/* Set salt length to maximum possible */
# define RSA_PSS_SALTLEN_MAX -3
+/* Auto-detect on verify, set salt length to min(maximum possible, digest
+ * length) on sign */
+# define RSA_PSS_SALTLEN_AUTO_DIGEST_MAX -4
/* Old compatible max salt length for sign only */
# define RSA_PSS_SALTLEN_MAX_SIGN -2
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
index 0c45008a00..1a787d77db 100644
--- a/providers/implementations/signature/rsa_sig.c
+++ b/providers/implementations/signature/rsa_sig.c
@@ -191,8 +191,8 @@ static void *rsa_newctx(void *provctx, const char *propq)
prsactx->libctx = PROV_LIBCTX_OF(provctx);
prsactx->flag_allow_md = 1;
prsactx->propq = propq_copy;
- /* Maximum for sign, auto for verify */
- prsactx->saltlen = RSA_PSS_SALTLEN_AUTO;
+ /* Maximum up to digest length for sign, auto for verify */
+ prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
prsactx->min_saltlen = -1;
return prsactx;
}
@@ -200,13 +200,27 @@ static void *rsa_newctx(void *provctx, const char *propq)
static int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx)
{
int saltlen = ctx->saltlen;
-
+ int saltlenMax = -1;
+
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
+ * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
+ * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
+ * the hash function output block (in bytes)."
+ *
+ * Provide a way to use at most the digest length, so that the default does
+ * not violate FIPS 186-4. */
if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
saltlen = EVP_MD_get_size(ctx->md);
- } else if (saltlen == RSA_PSS_SALTLEN_AUTO || saltlen == RSA_PSS_SALTLEN_MAX) {
+ } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
+ saltlen = RSA_PSS_SALTLEN_MAX;
+ saltlenMax = EVP_MD_get_size(ctx->md);
+ }
+ if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) {
saltlen = RSA_size(ctx->rsa) - EVP_MD_get_size(ctx->md) - 2;
if ((RSA_bits(ctx->rsa) & 0x7) == 1)
saltlen--;
+ if (saltlenMax >= 0 && saltlen > saltlenMax)
+ saltlen = saltlenMax;
}
if (saltlen < 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
@@ -411,8 +425,8 @@ static int rsa_signverify_init(void *vprsactx, void *vrsa,
prsactx->operation = operation;
- /* Maximum for sign, auto for verify */
- prsactx->saltlen = RSA_PSS_SALTLEN_AUTO;
+ /* Maximize up to digest length for sign, auto for verify */
+ prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
prsactx->min_saltlen = -1;
switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) {
@@ -1110,6 +1124,9 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
case RSA_PSS_SALTLEN_AUTO:
value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO;
break;
+ case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
+ value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX;
+ break;
default:
{
int len = BIO_snprintf(p->data, p->data_size, "%d",
@@ -1297,6 +1314,8 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
saltlen = RSA_PSS_SALTLEN_MAX;
else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
saltlen = RSA_PSS_SALTLEN_AUTO;
+ else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
+ saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
else
saltlen = atoi(p->data);
break;
@@ -1305,11 +1324,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
}
/*
- * RSA_PSS_SALTLEN_MAX seems curiously named in this check.
- * Contrary to what it's name suggests, it's the currently
- * lowest saltlen number possible.
+ * RSA_PSS_SALTLEN_AUTO_DIGEST_MAX seems curiously named in this check.
+ * Contrary to what it's name suggests, it's the currently lowest
+ * saltlen number possible.
*/
- if (saltlen < RSA_PSS_SALTLEN_MAX) {
+ if (saltlen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
return 0;
}
@@ -1317,6 +1336,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
if (rsa_pss_restricted(prsactx)) {
switch (saltlen) {
case RSA_PSS_SALTLEN_AUTO:
+ case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
if (prsactx->operation == EVP_PKEY_OP_VERIFY) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH,
"Cannot use autodetected salt length");
diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t
index e615f1b338..35541aed12 100644
--- a/test/recipes/25-test_req.t
+++ b/test/recipes/25-test_req.t
@@ -199,7 +199,7 @@ subtest "generating certificate requests with RSA-PSS" => sub {
ok(!run(app(["openssl", "req",
"-config", srctop_file("test", "test.cnf"),
"-new", "-out", "testreq-rsapss3.pem", "-utf8",
- "-sigopt", "rsa_pss_saltlen:-4",
+ "-sigopt", "rsa_pss_saltlen:-5",
"-key", srctop_file("test", "testrsapss.pem")])),
"Generating request with expected failure");
--
2.38.1

@ -0,0 +1,32 @@
diff -up openssl-3.0.1/providers/implementations/kem/rsa_kem.c.encap openssl-3.0.1/providers/implementations/kem/rsa_kem.c
--- openssl-3.0.1/providers/implementations/kem/rsa_kem.c.encap 2022-11-22 12:27:30.994530801 +0100
+++ openssl-3.0.1/providers/implementations/kem/rsa_kem.c 2022-11-22 12:32:15.916875495 +0100
@@ -264,6 +264,14 @@ static int rsasve_generate(PROV_RSA_CTX
*secretlen = nlen;
return 1;
}
+
+#ifdef FIPS_MODULE
+ if (nlen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS/8) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+#endif
+
/*
* Step (2): Generate a random byte string z of nlen bytes where
* 1 < z < n - 1
@@ -307,6 +315,13 @@ static int rsasve_recover(PROV_RSA_CTX *
return 1;
}
+#ifdef FIPS_MODULE
+ if (nlen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS/8) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+#endif
+
/* Step (2): check the input ciphertext 'inlen' matches the nlen */
if (inlen != nlen) {
ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);

@ -0,0 +1,82 @@
From b00f2cab6b8dfc4ffb23fd50b049b4a443910946 Mon Sep 17 00:00:00 2001
From: Juergen Christ <jchrist@linux.ibm.com>
Date: Wed, 5 Oct 2022 13:57:21 +0200
Subject: [PATCH] Add translation for ECX group parameter
Legacy EVP_PKEY_CTX objects did not support the "group" parameter for X25519
and X448. The translation of this parameter resulted in an error. This
caused errors for legacy keys and engines.
Fix this situation by adding a translation that simply checks that the correct
parameter is to be set, but does not actually set anything. This is correct
since the group name is anyway optional for these two curves.
Fixes #19313
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
---
crypto/evp/ctrl_params_translate.c | 37 +++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c
index ffea7b108b6f..47a935ce9cca 100644
--- a/crypto/evp/ctrl_params_translate.c
+++ b/crypto/evp/ctrl_params_translate.c
@@ -1955,6 +1955,32 @@ IMPL_GET_RSA_PAYLOAD_COEFFICIENT(7)
IMPL_GET_RSA_PAYLOAD_COEFFICIENT(8)
IMPL_GET_RSA_PAYLOAD_COEFFICIENT(9)
+static int fix_group_ecx(enum state state,
+ const struct translation_st *translation,
+ struct translation_ctx_st *ctx)
+{
+ const char *value = NULL;
+
+ switch (state) {
+ case PRE_PARAMS_TO_CTRL:
+ if (!EVP_PKEY_CTX_IS_GEN_OP(ctx->pctx))
+ return 0;
+ ctx->action_type = NONE;
+ return 1;
+ case POST_PARAMS_TO_CTRL:
+ if (OSSL_PARAM_get_utf8_string_ptr(ctx->params, &value) == 0 ||
+ OPENSSL_strcasecmp(ctx->pctx->keytype, value) != 0) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT);
+ ctx->p1 = 0;
+ return 0;
+ }
+ ctx->p1 = 1;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/*-
* The translation table itself
* ============================
@@ -2274,6 +2300,15 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
{ GET, -1, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_GET_MD, NULL, NULL,
OSSL_SIGNATURE_PARAM_DIGEST, OSSL_PARAM_UTF8_STRING, fix_md },
+
+ /*-
+ * ECX
+ * ===
+ */
+ { SET, EVP_PKEY_X25519, EVP_PKEY_X25519, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
+ OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
+ { SET, EVP_PKEY_X448, EVP_PKEY_X448, EVP_PKEY_OP_KEYGEN, -1, NULL, NULL,
+ OSSL_PKEY_PARAM_GROUP_NAME, OSSL_PARAM_UTF8_STRING, fix_group_ecx },
};
static const struct translation_st evp_pkey_translations[] = {
@@ -2692,7 +2727,7 @@ static int evp_pkey_ctx_setget_params_to_ctrl(EVP_PKEY_CTX *pctx,
ret = fixup(PRE_PARAMS_TO_CTRL, translation, &ctx);
- if (ret > 0 && action_type != NONE)
+ if (ret > 0 && ctx.action_type != NONE)
ret = EVP_PKEY_CTX_ctrl(pctx, keytype, optype,
ctx.ctrl_cmd, ctx.p1, ctx.p2);

@ -0,0 +1,281 @@
From c927a3492698c254637da836762f9b1f86cffabc Mon Sep 17 00:00:00 2001
From: Viktor Dukhovni <openssl-users@dukhovni.org>
Date: Tue, 13 Dec 2022 08:49:13 +0100
Subject: [PATCH 01/18] Fix type confusion in nc_match_single()
This function assumes that if the "gen" is an OtherName, then the "base"
is a rfc822Name constraint. This assumption is not true in all cases.
If the end-entity certificate contains an OtherName SAN of any type besides
SmtpUtf8Mailbox and the CA certificate contains a name constraint of
OtherName (of any type), then "nc_email_eai" will be invoked, with the
OTHERNAME "base" being incorrectly interpreted as a ASN1_IA5STRING.
Reported by Corey Bonnell from Digicert.
CVE-2022-4203
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/x509/v3_ncons.c | 45 +++++++++++++++++++++++++++++-------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c
index 70a7e8304e..5101598512 100644
--- a/crypto/x509/v3_ncons.c
+++ b/crypto/x509/v3_ncons.c
@@ -31,7 +31,8 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
-static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
+static int nc_match_single(int effective_type, GENERAL_NAME *sub,
+ GENERAL_NAME *gen);
static int nc_dn(const X509_NAME *sub, const X509_NAME *nm);
static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
@@ -472,14 +473,17 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
{
GENERAL_SUBTREE *sub;
int i, r, match = 0;
+ int effective_type = gen->type;
+
/*
* We need to compare not gen->type field but an "effective" type because
* the otherName field may contain EAI email address treated specially
* according to RFC 8398, section 6
*/
- int effective_type = ((gen->type == GEN_OTHERNAME) &&
- (OBJ_obj2nid(gen->d.otherName->type_id) ==
- NID_id_on_SmtpUTF8Mailbox)) ? GEN_EMAIL : gen->type;
+ if (effective_type == GEN_OTHERNAME &&
+ (OBJ_obj2nid(gen->d.otherName->type_id) == NID_id_on_SmtpUTF8Mailbox)) {
+ effective_type = GEN_EMAIL;
+ }
/*
* Permitted subtrees: if any subtrees exist of matching the type at
@@ -488,7 +492,10 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
- if (effective_type != sub->base->type)
+ if (effective_type != sub->base->type
+ || (effective_type == GEN_OTHERNAME &&
+ OBJ_cmp(gen->d.otherName->type_id,
+ sub->base->d.otherName->type_id) != 0))
continue;
if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX;
@@ -497,7 +504,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
continue;
if (match == 0)
match = 1;
- r = nc_match_single(gen, sub->base);
+ r = nc_match_single(effective_type, gen, sub->base);
if (r == X509_V_OK)
match = 2;
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
@@ -511,12 +518,15 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
- if (effective_type != sub->base->type)
+ if (effective_type != sub->base->type
+ || (effective_type == GEN_OTHERNAME &&
+ OBJ_cmp(gen->d.otherName->type_id,
+ sub->base->d.otherName->type_id) != 0))
continue;
if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX;
- r = nc_match_single(gen, sub->base);
+ r = nc_match_single(effective_type, gen, sub->base);
if (r == X509_V_OK)
return X509_V_ERR_EXCLUDED_VIOLATION;
else if (r != X509_V_ERR_PERMITTED_VIOLATION)
@@ -528,15 +538,22 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
}
-static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
+static int nc_match_single(int effective_type, GENERAL_NAME *gen,
+ GENERAL_NAME *base)
{
switch (gen->type) {
case GEN_OTHERNAME:
- /*
- * We are here only when we have SmtpUTF8 name,
- * so we match the value of othername with base->d.rfc822Name
- */
- return nc_email_eai(gen->d.otherName->value, base->d.rfc822Name);
+ switch (effective_type) {
+ case GEN_EMAIL:
+ /*
+ * We are here only when we have SmtpUTF8 name,
+ * so we match the value of othername with base->d.rfc822Name
+ */
+ return nc_email_eai(gen->d.otherName->value, base->d.rfc822Name);
+
+ default:
+ return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+ }
case GEN_DIRNAME:
return nc_dn(gen->d.directoryName, base->d.directoryName);
--
2.39.1
From fe6842f5a5dc2fb66da7fb24bf4343a3aeedd50a Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Tue, 13 Dec 2022 19:45:09 +0100
Subject: [PATCH 02/18] Add testcase for nc_match_single type confusion
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
---
test/certs/bad-othername-cert.pem | 20 ++++++++++++++++++++
test/certs/nccaothername-cert.pem | 20 ++++++++++++++++++++
test/certs/nccaothername-key.pem | 28 ++++++++++++++++++++++++++++
test/certs/setup.sh | 11 +++++++++++
test/recipes/25-test_verify.t | 5 ++++-
5 files changed, 83 insertions(+), 1 deletion(-)
create mode 100644 test/certs/bad-othername-cert.pem
create mode 100644 test/certs/nccaothername-cert.pem
create mode 100644 test/certs/nccaothername-key.pem
diff --git a/test/certs/bad-othername-cert.pem b/test/certs/bad-othername-cert.pem
new file mode 100644
index 0000000000..cf279de5ea
--- /dev/null
+++ b/test/certs/bad-othername-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDRDCCAiygAwIBAgIBAjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRUZXN0
+IE5DIENBIG90aGVybmFtZTAgFw0yMjEyMTMxODMzMTZaGA8yMTIyMTIxNDE4MzMx
+NlowMTEvMC0GA1UECgwmTkMgZW1haWwgaW4gb3RoZXJuYW1lIFRlc3QgQ2VydGlm
+aWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPgeoakqHk1zYt
+JZpEC0qkJPU/X0lfI+6GY2LHFY9KOSFqqmTXxrUtjQc3SdpQvBZhPuMZ8p82Jid2
+kkRHnWs0uqX9NtLO923yQalYvP6Mt3fokcYgw/C9b+I/q1PKUyN0kPB6McROguD5
+Jz2DcEufJBhbpyay1bFjEI2DAQJKDP/U7uH0EA7kH/27UMk0vfvL5uVjDvlo8i6S
+Ul8+u0cDV5ZFJW2VAJKLU3wp6IY4fZl9UqkHZuRQpMJGqAjAleWOIEpyyvfGGh0b
+75n3GJ+4YZ7CIBEgY7K0nIbKxtcDZPvmtbYg3g1tkPMTHcodFT7yEdqkBTJ5AGL7
+6U850OhjAgMBAAGjdzB1MB0GA1UdDgQWBBTBz0k+q6d4c3aM+s2IyOF/QP6zCTAf
+BgNVHSMEGDAWgBTwhghX7uNdMejZ3f4XorqOQoMqwTAJBgNVHRMEAjAAMCgGA1Ud
+EQQhMB+gHQYIKwYBBQUHCAegEQwPZm9vQGV4YW1wbGUub3JnMA0GCSqGSIb3DQEB
+CwUAA4IBAQAhxbCEVH8pq0aUMaLWaodyXdCqA0AKTFG6Mz9Rpwn89OwC8FylTEru
+t+Bqx/ZuTo8YzON8h9m7DIrQIjZKDLW/g5YbvIsxIVV9gWhAGohdsIyMKRBepSmr
+NxJQkO74RLBTamfl0WUCVM4HqroflFjBBG67CTJaQ9cH9ug3TKxaXCK1L6iQAXtq
+enILGai98Byo0LCFH4MQOhmhV1BDT2boIG/iYb5VKCTSX25vhaF+PNBhUoysjW0O
+vhQX8vrw42QRr4Qi7VfUBXzrbRTzxjOc4yqki7h2DcEdpginqe+aGyaFY+H9m/ka
+1AR5KN8h5SYKltSXknjs0pp1w4k49aHl
+-----END CERTIFICATE-----
diff --git a/test/certs/nccaothername-cert.pem b/test/certs/nccaothername-cert.pem
new file mode 100644
index 0000000000..f9b9b07b80
--- /dev/null
+++ b/test/certs/nccaothername-cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTIyMTIxMzE4MTgwM1oYDzIxMjIxMjE0MTgxODAzWjAfMR0wGwYDVQQD
+DBRUZXN0IE5DIENBIG90aGVybmFtZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAN0Dx+ei8CgtRKnDcYiLwX4vrA48at/o/zfX24X/WZZM1o9HUKo1FQBN
+vhESJu+gqPxuIePrk+/L25XdRqwCKk8wkWX0XIz18q5orOHUUFAWNK3g0FDj6N8H
+d8urNIbDJ44FCx+/0n8Ppiht/EYN3aVOW5enqbgZ+EEt+3AUG6ibieRdGri9g4oh
+IIx60MmVHLbuT/TcVZxaeWyTl6iWmsYosUyqlhTtu1uGtbVtkCAhBYloVvz4J5eA
+mVu/JuJbsNxbxVeO9Q8Kj6nb4jPPdGvZ3JPcabbWrz5LwaereBf5IPrXEVdQTlYB
+gI0pTz2CEDHSIrd7jzRUX/9EC2gMk6UCAwEAAaOBjzCBjDAPBgNVHRMBAf8EBTAD
+AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU8IYIV+7jXTHo2d3+F6K6jkKDKsEw
+HwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwLAYDVR0eBCUwI6EhMB+g
+HQYIKwYBBQUHCAegEQwPZm9vQGV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4IB
+AQDPI5uZd8DhSNKMvYF5bxOshd6h6UJ7YzZS7K6fhiygltdqzkHQ/5+4yiuUkDe4
+hOZlH8MCfXQy5jVZDTk24yNchpdfie5Bswn4SmQVQh3QyzOLxizoh0rLCf2PHueu
+dNVNhfiiJNJ5kd8MIuVG7CPK68dP0QrVR+DihROuJgvGB3ClKttLrgle19t4PFRR
+2wW6hJT9aXEjzLNyN1QFZKoShuiGX4xwjZh7VyKkV64p8hjojhcLk6dQkel+Jw4y
+OP26XbVfM8/6KG8f6WAZ8P0qJwHlhmi0EvRTnEpAM8WuenOeZH6ERZ9uZbRGh6xx
+LKQu2Aw2+bOEZ2vUtz0dBhX8
+-----END CERTIFICATE-----
diff --git a/test/certs/nccaothername-key.pem b/test/certs/nccaothername-key.pem
new file mode 100644
index 0000000000..d3e300ac2f
--- /dev/null
+++ b/test/certs/nccaothername-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDdA8fnovAoLUSp
+w3GIi8F+L6wOPGrf6P8319uF/1mWTNaPR1CqNRUATb4REibvoKj8biHj65Pvy9uV
+3UasAipPMJFl9FyM9fKuaKzh1FBQFjSt4NBQ4+jfB3fLqzSGwyeOBQsfv9J/D6Yo
+bfxGDd2lTluXp6m4GfhBLftwFBuom4nkXRq4vYOKISCMetDJlRy27k/03FWcWnls
+k5eolprGKLFMqpYU7btbhrW1bZAgIQWJaFb8+CeXgJlbvybiW7DcW8VXjvUPCo+p
+2+Izz3Rr2dyT3Gm21q8+S8Gnq3gX+SD61xFXUE5WAYCNKU89ghAx0iK3e480VF//
+RAtoDJOlAgMBAAECggEAMFSJlCyEFlER3Qq9asXe9eRgXEuXdmfZ2aEVIuf8M/sR
+B0tpxxKtCUA24j5FL+0CzxKZTCFBnDRIzCyTbf1aOa9t+CzXyUZmP3/p4EdgmabF
+dcl93FZ+X7kfF/VUGu0Vmv+c12BH3Fu0cs5cVohlMecg7diu6zCYok43F+L5ymRy
+2mTcKkGc0ShWizj8Z9R3WJGssZOlxbxa/Zr4rZwRC24UVhfN8AfGWYx/StyQPQIw
+gtbbtOmwbyredQmY4jwNqgrnfZS9bkWwJbRuCmD5l7lxubBgcHQpoM+DQVeOLZIq
+uksFXeNfal9G5Bo747MMzpD7dJMCGmX+gbMY5oZF+QKBgQDs2MbY4nbxi+fV+KuV
+zUvis8m8Lpzf3T6NLkgSkUPRN9tGr95iLIrB/bRPJg5Ne02q/cT7d86B9rpE42w7
+eeIF9fANezX2AF8LUqNZhIR23J3tfB/eqGlJRZeMNia+lD09a7SWGwrS7sufY1I+
+JQGcHx77ntt+eQT1MUJ1skF06QKBgQDu4z+TW4QIA5ItxIReVdcfh5e3xLkzDEVP
+3KNo9tpXxvPwqapdeBh6c9z4Lqe3MKr5UPlDvVW+o40t6OjKxDCXczB8+JAM0OyX
+8V+K3zXXUxRgieSd3oMncTylSWIvouPP3aW37B67TKdRlRHgaBrpJT2wdk3kYR4t
+62J1eDdjXQKBgQDMsY0pZI/nskJrar7geM1c4IU5Xg+2aj/lRFqFsYYrC1s3fEd2
+EYjan6l1vi4eSLKXVTspGiIfsFzLrMGdpXjyLduJyzKXqTp7TrBebWkOUR0sYloo
+1OQprzuKskJJ81P6AVvRXw27vyW8Wtp5WwJJK5xbWq/YXj8qqagGkEiCAQKBgQCc
+RK3XAFurPmLGa7JHX5Hc/z8BKMAZo6JHrsZ6qFiGaRA0U1it0hz5JYfcFfECheSi
+ORUF+fn4PlbhPGXkFljPCbwjVBovOBA9CNl+J6u50pAW4r1ZhDB5gbqxSQLgtIaf
++JcqbFxiG6+sT36lNJS+BO2I3KrxhZJPaZY7z8szxQKBgQDRy70XzwOk8jXayiF2
+ej2IN7Ow9cgSE4tLEwR/vCjxvOlWhA3jC3wxoggshGJkpbP3DqLkQtwQm0h1lM8J
+QNtFwKzjtpf//bTlfFq08/YxWimTPMqzcV2PgRacB8P3yf1r8T7M4fA5TORCDWpW
+5FtOCFEmwQHTR8lu4c63qfxkEQ==
+-----END PRIVATE KEY-----
diff --git a/test/certs/setup.sh b/test/certs/setup.sh
index b9766aab20..2240cd9df0 100755
--- a/test/certs/setup.sh
+++ b/test/certs/setup.sh
@@ -388,6 +388,17 @@ REQMASK=MASK:0x800 ./mkcert.sh req badalt7-key "O = Bad NC Test Certificate 7" \
"email.1 = good@good.org" "email.2 = any@good.com" \
"IP = 127.0.0.1" "IP = 192.168.0.1"
+# Certs for CVE-2022-4203 testcase
+
+NC="excluded;otherName:SRVName;UTF8STRING:foo@example.org" ./mkcert.sh genca \
+ "Test NC CA othername" nccaothername-key nccaothername-cert \
+ root-key root-cert
+
+./mkcert.sh req alt-email-key "O = NC email in othername Test Certificate" | \
+ ./mkcert.sh geneealt bad-othername-key bad-othername-cert \
+ nccaothername-key nccaothername-cert \
+ "otherName.1 = SRVName;UTF8STRING:foo@example.org"
+
# RSA-PSS signatures
# SHA1
./mkcert.sh genee PSS-SHA1 ee-key ee-pss-sha1-cert ca-key ca-cert \
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index 4613489f57..e6a2bca731 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 => 162;
+plan tests => 163;
# Canonical success
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -402,6 +402,9 @@ ok(!verify("badalt9-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
ok(!verify("badalt10-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ),
"Name constraints nested DNS name excluded");
+ok(!verify("bad-othername-cert", "", ["root-cert"], ["nccaothername-cert"], ),
+ "CVE-2022-4203 type confusion test");
+
#Check that we get the expected failure return code
with({ exit_checker => sub { return shift == 2; } },
sub {
--
2.39.1

@ -0,0 +1,750 @@
From 8e257b86e5812c6e1cfa9e8e5f5660ac7bed899d Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Fri, 20 Jan 2023 15:03:40 +0000
Subject: [PATCH 03/18] Fix Timing Oracle in RSA decryption
A timing based side channel exists in the OpenSSL RSA Decryption
implementation which could be sufficient to recover a plaintext across
a network in a Bleichenbacher style attack. To achieve a successful
decryption an attacker would have to be able to send a very large number
of trial messages for decryption. The vulnerability affects all RSA
padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
Patch written by Dmitry Belyavsky and Hubert Kario
CVE-2022-4304
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/bn/bn_blind.c | 14 -
crypto/bn/bn_local.h | 14 +
crypto/bn/build.info | 2 +-
crypto/bn/rsa_sup_mul.c | 604 ++++++++++++++++++++++++++++++++++++++++
crypto/rsa/rsa_ossl.c | 19 +-
include/crypto/bn.h | 6 +
6 files changed, 638 insertions(+), 21 deletions(-)
create mode 100644 crypto/bn/rsa_sup_mul.c
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index 72457b34cf..6061ebb4c0 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -13,20 +13,6 @@
#define BN_BLINDING_COUNTER 32
-struct bn_blinding_st {
- BIGNUM *A;
- BIGNUM *Ai;
- BIGNUM *e;
- BIGNUM *mod; /* just a reference */
- CRYPTO_THREAD_ID tid;
- int counter;
- unsigned long flags;
- BN_MONT_CTX *m_ctx;
- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
- CRYPTO_RWLOCK *lock;
-};
-
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
{
BN_BLINDING *ret = NULL;
diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h
index c9a7ecf298..8c428f919d 100644
--- a/crypto/bn/bn_local.h
+++ b/crypto/bn/bn_local.h
@@ -290,6 +290,20 @@ struct bn_gencb_st {
} cb;
};
+struct bn_blinding_st {
+ BIGNUM *A;
+ BIGNUM *Ai;
+ BIGNUM *e;
+ BIGNUM *mod; /* just a reference */
+ CRYPTO_THREAD_ID tid;
+ int counter;
+ unsigned long flags;
+ BN_MONT_CTX *m_ctx;
+ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+ CRYPTO_RWLOCK *lock;
+};
+
/*-
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
*
diff --git a/crypto/bn/build.info b/crypto/bn/build.info
index c4ba51b265..f4ff619239 100644
--- a/crypto/bn/build.info
+++ b/crypto/bn/build.info
@@ -105,7 +105,7 @@ $COMMON=bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \
bn_mod.c bn_conv.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_sqr.c \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
- bn_intern.c bn_dh.c bn_rsa_fips186_4.c bn_const.c
+ bn_intern.c bn_dh.c bn_rsa_fips186_4.c bn_const.c rsa_sup_mul.c
SOURCE[../../libcrypto]=$COMMON $BNASM bn_print.c bn_err.c bn_srp.c
DEFINE[../../libcrypto]=$BNDEF
IF[{- !$disabled{'deprecated-0.9.8'} -}]
diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c
new file mode 100644
index 0000000000..0e0d02e194
--- /dev/null
+++ b/crypto/bn/rsa_sup_mul.c
@@ -0,0 +1,604 @@
+#include <openssl/e_os2.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <string.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/rsaerr.h>
+#include "internal/endian.h"
+#include "internal/numbers.h"
+#include "internal/constant_time.h"
+#include "bn_local.h"
+
+# if BN_BYTES == 8
+typedef uint64_t limb_t;
+# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
+typedef uint128_t limb2_t;
+# define HAVE_LIMB2_T
+# endif
+# define LIMB_BIT_SIZE 64
+# define LIMB_BYTE_SIZE 8
+# elif BN_BYTES == 4
+typedef uint32_t limb_t;
+typedef uint64_t limb2_t;
+# define LIMB_BIT_SIZE 32
+# define LIMB_BYTE_SIZE 4
+# define HAVE_LIMB2_T
+# else
+# error "Not supported"
+# endif
+
+/*
+ * For multiplication we're using schoolbook multiplication,
+ * so if we have two numbers, each with 6 "digits" (words)
+ * the multiplication is calculated as follows:
+ * A B C D E F
+ * x I J K L M N
+ * --------------
+ * N*F
+ * N*E
+ * N*D
+ * N*C
+ * N*B
+ * N*A
+ * M*F
+ * M*E
+ * M*D
+ * M*C
+ * M*B
+ * M*A
+ * L*F
+ * L*E
+ * L*D
+ * L*C
+ * L*B
+ * L*A
+ * K*F
+ * K*E
+ * K*D
+ * K*C
+ * K*B
+ * K*A
+ * J*F
+ * J*E
+ * J*D
+ * J*C
+ * J*B
+ * J*A
+ * I*F
+ * I*E
+ * I*D
+ * I*C
+ * I*B
+ * + I*A
+ * ==========================
+ * N*B N*D N*F
+ * + N*A N*C N*E
+ * + M*B M*D M*F
+ * + M*A M*C M*E
+ * + L*B L*D L*F
+ * + L*A L*C L*E
+ * + K*B K*D K*F
+ * + K*A K*C K*E
+ * + J*B J*D J*F
+ * + J*A J*C J*E
+ * + I*B I*D I*F
+ * + I*A I*C I*E
+ *
+ * 1+1 1+3 1+5
+ * 1+0 1+2 1+4
+ * 0+1 0+3 0+5
+ * 0+0 0+2 0+4
+ *
+ * 0 1 2 3 4 5 6
+ * which requires n^2 multiplications and 2n full length additions
+ * as we can keep every other result of limb multiplication in two separate
+ * limbs
+ */
+
+#if defined HAVE_LIMB2_T
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ limb2_t t;
+ /*
+ * this is idiomatic code to tell compiler to use the native mul
+ * those three lines will actually compile to single instruction
+ */
+
+ t = (limb2_t)a * b;
+ *hi = t >> LIMB_BIT_SIZE;
+ *lo = (limb_t)t;
+}
+#elif (BN_BYTES == 8) && (defined _MSC_VER)
+/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */
+#pragma intrinsic(_umul128)
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ *lo = _umul128(a, b, hi);
+}
+#else
+/*
+ * if the compiler doesn't have either a 128bit data type nor a "return
+ * high 64 bits of multiplication"
+ */
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ limb_t a_low = (limb_t)(uint32_t)a;
+ limb_t a_hi = a >> 32;
+ limb_t b_low = (limb_t)(uint32_t)b;
+ limb_t b_hi = b >> 32;
+
+ limb_t p0 = a_low * b_low;
+ limb_t p1 = a_low * b_hi;
+ limb_t p2 = a_hi * b_low;
+ limb_t p3 = a_hi * b_hi;
+
+ uint32_t cy = (uint32_t)(((p0 >> 32) + (uint32_t)p1 + (uint32_t)p2) >> 32);
+
+ *lo = p0 + (p1 << 32) + (p2 << 32);
+ *hi = p3 + (p1 >> 32) + (p2 >> 32) + cy;
+}
+#endif
+
+/* add two limbs with carry in, return carry out */
+static ossl_inline limb_t _add_limb(limb_t *ret, limb_t a, limb_t b, limb_t carry)
+{
+ limb_t carry1, carry2, t;
+ /*
+ * `c = a + b; if (c < a)` is idiomatic code that makes compilers
+ * use add with carry on assembly level
+ */
+
+ *ret = a + carry;
+ if (*ret < a)
+ carry1 = 1;
+ else
+ carry1 = 0;
+
+ t = *ret;
+ *ret = t + b;
+ if (*ret < t)
+ carry2 = 1;
+ else
+ carry2 = 0;
+
+ return carry1 + carry2;
+}
+
+/*
+ * add two numbers of the same size, return overflow
+ *
+ * add a to b, place result in ret; all arrays need to be n limbs long
+ * return overflow from addition (0 or 1)
+ */
+static ossl_inline limb_t add(limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ limb_t c = 0;
+ ossl_ssize_t i;
+
+ for(i = n - 1; i > -1; i--)
+ c = _add_limb(&ret[i], a[i], b[i], c);
+
+ return c;
+}
+
+/*
+ * return number of limbs necessary for temporary values
+ * when multiplying numbers n limbs large
+ */
+static ossl_inline size_t mul_limb_numb(size_t n)
+{
+ return 2 * n * 2;
+}
+
+/*
+ * multiply two numbers of the same size
+ *
+ * multiply a by b, place result in ret; a and b need to be n limbs long
+ * ret needs to be 2*n limbs long, tmp needs to be mul_limb_numb(n) limbs
+ * long
+ */
+static void limb_mul(limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp)
+{
+ limb_t *r_odd, *r_even;
+ size_t i, j, k;
+
+ r_odd = tmp;
+ r_even = &tmp[2 * n];
+
+ memset(ret, 0, 2 * n * sizeof(limb_t));
+
+ for (i = 0; i < n; i++) {
+ for (k = 0; k < i + n + 1; k++) {
+ r_even[k] = 0;
+ r_odd[k] = 0;
+ }
+ for (j = 0; j < n; j++) {
+ /*
+ * place results from even and odd limbs in separate arrays so that
+ * we don't have to calculate overflow every time we get individual
+ * limb multiplication result
+ */
+ if (j % 2 == 0)
+ _mul_limb(&r_even[i + j], &r_even[i + j + 1], a[i], b[j]);
+ else
+ _mul_limb(&r_odd[i + j], &r_odd[i + j + 1], a[i], b[j]);
+ }
+ /*
+ * skip the least significant limbs when adding multiples of
+ * more significant limbs (they're zero anyway)
+ */
+ add(ret, ret, r_even, n + i + 1);
+ add(ret, ret, r_odd, n + i + 1);
+ }
+}
+
+/* modifies the value in place by performing a right shift by one bit */
+static ossl_inline void rshift1(limb_t *val, size_t n)
+{
+ limb_t shift_in = 0, shift_out = 0;
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ shift_out = val[i] & 1;
+ val[i] = shift_in << (LIMB_BIT_SIZE - 1) | (val[i] >> 1);
+ shift_in = shift_out;
+ }
+}
+
+/* extend the LSB of flag to all bits of limb */
+static ossl_inline limb_t mk_mask(limb_t flag)
+{
+ flag |= flag << 1;
+ flag |= flag << 2;
+ flag |= flag << 4;
+ flag |= flag << 8;
+ flag |= flag << 16;
+#if (LIMB_BYTE_SIZE == 8)
+ flag |= flag << 32;
+#endif
+ return flag;
+}
+
+/*
+ * copy from either a or b to ret based on flag
+ * when flag == 0, then copies from b
+ * when flag == 1, then copies from a
+ */
+static ossl_inline void cselect(limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ /*
+ * would be more efficient with non volatile mask, but then gcc
+ * generates code with jumps
+ */
+ volatile limb_t mask;
+ size_t i;
+
+ mask = mk_mask(flag);
+ for (i = 0; i < n; i++) {
+#if (LIMB_BYTE_SIZE == 8)
+ ret[i] = constant_time_select_64(mask, a[i], b[i]);
+#else
+ ret[i] = constant_time_select_32(mask, a[i], b[i]);
+#endif
+ }
+}
+
+static limb_t _sub_limb(limb_t *ret, limb_t a, limb_t b, limb_t borrow)
+{
+ limb_t borrow1, borrow2, t;
+ /*
+ * while it doesn't look constant-time, this is idiomatic code
+ * to tell compilers to use the carry bit from subtraction
+ */
+
+ *ret = a - borrow;
+ if (*ret > a)
+ borrow1 = 1;
+ else
+ borrow1 = 0;
+
+ t = *ret;
+ *ret = t - b;
+ if (*ret > t)
+ borrow2 = 1;
+ else
+ borrow2 = 0;
+
+ return borrow1 + borrow2;
+}
+
+/*
+ * place the result of a - b into ret, return the borrow bit.
+ * All arrays need to be n limbs long
+ */
+static limb_t sub(limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ limb_t borrow = 0;
+ ossl_ssize_t i;
+
+ for (i = n - 1; i > -1; i--)
+ borrow = _sub_limb(&ret[i], a[i], b[i], borrow);
+
+ return borrow;
+}
+
+/* return the number of limbs necessary to allocate for the mod() tmp operand */
+static ossl_inline size_t mod_limb_numb(size_t anum, size_t modnum)
+{
+ return (anum + modnum) * 3;
+}
+
+/*
+ * calculate a % mod, place the result in ret
+ * size of a is defined by anum, size of ret and mod is modnum,
+ * size of tmp is returned by mod_limb_numb()
+ */
+static void mod(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
+ size_t modnum, limb_t *tmp)
+{
+ limb_t *atmp, *modtmp, *rettmp;
+ limb_t res;
+ size_t i;
+
+ memset(tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE);
+
+ atmp = tmp;
+ modtmp = &tmp[anum + modnum];
+ rettmp = &tmp[(anum + modnum) * 2];
+
+ for (i = modnum; i <modnum + anum; i++)
+ atmp[i] = a[i-modnum];
+
+ for (i = 0; i < modnum; i++)
+ modtmp[i] = mod[i];
+
+ for (i = 0; i < anum * LIMB_BIT_SIZE; i++) {
+ rshift1(modtmp, anum + modnum);
+ res = sub(rettmp, atmp, modtmp, anum+modnum);
+ cselect(res, atmp, atmp, rettmp, anum+modnum);
+ }
+
+ memcpy(ret, &atmp[anum], sizeof(limb_t) * modnum);
+}
+
+/* necessary size of tmp for a _mul_add_limb() call with provided anum */
+static ossl_inline size_t _mul_add_limb_numb(size_t anum)
+{
+ return 2 * (anum + 1);
+}
+
+/* multiply a by m, add to ret, return carry */
+static limb_t _mul_add_limb(limb_t *ret, limb_t *a, size_t anum,
+ limb_t m, limb_t *tmp)
+{
+ limb_t carry = 0;
+ limb_t *r_odd, *r_even;
+ size_t i;
+
+ memset(tmp, 0, sizeof(limb_t) * (anum + 1) * 2);
+
+ r_odd = tmp;
+ r_even = &tmp[anum + 1];
+
+ for (i = 0; i < anum; i++) {
+ /*
+ * place the results from even and odd limbs in separate arrays
+ * so that we have to worry about carry just once
+ */
+ if (i % 2 == 0)
+ _mul_limb(&r_even[i], &r_even[i + 1], a[i], m);
+ else
+ _mul_limb(&r_odd[i], &r_odd[i + 1], a[i], m);
+ }
+ /* assert: add() carry here will be equal zero */
+ add(r_even, r_even, r_odd, anum + 1);
+ /*
+ * while here it will not overflow as the max value from multiplication
+ * is -2 while max overflow from addition is 1, so the max value of
+ * carry is -1 (i.e. max int)
+ */
+ carry = add(ret, ret, &r_even[1], anum) + r_even[0];
+
+ return carry;
+}
+
+static ossl_inline size_t mod_montgomery_limb_numb(size_t modnum)
+{
+ return modnum * 2 + _mul_add_limb_numb(modnum);
+}
+
+/*
+ * calculate a % mod, place result in ret
+ * assumes that a is in Montgomery form with the R (Montgomery modulus) being
+ * smallest power of two big enough to fit mod and that's also a power
+ * of the count of number of bits in limb_t (B).
+ * For calculation, we also need n', such that mod * n' == -1 mod B.
+ * anum must be <= 2 * modnum
+ * ret needs to be modnum words long
+ * tmp needs to be mod_montgomery_limb_numb(modnum) limbs long
+ */
+static void mod_montgomery(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
+ size_t modnum, limb_t ni0, limb_t *tmp)
+{
+ limb_t carry, v;
+ limb_t *res, *rp, *tmp2;
+ ossl_ssize_t i;
+
+ res = tmp;
+ /*
+ * for intermediate result we need an integer twice as long as modulus
+ * but keep the input in the least significant limbs
+ */
+ memset(res, 0, sizeof(limb_t) * (modnum * 2));
+ memcpy(&res[modnum * 2 - anum], a, sizeof(limb_t) * anum);
+ rp = &res[modnum];
+ tmp2 = &res[modnum * 2];
+
+ carry = 0;
+
+ /* add multiples of the modulus to the value until R divides it cleanly */
+ for (i = modnum; i > 0; i--, rp--) {
+ v = _mul_add_limb(rp, mod, modnum, rp[modnum-1] * ni0, tmp2);
+ v = v + carry + rp[-1];
+ carry |= (v != rp[-1]);
+ carry &= (v <= rp[-1]);
+ rp[-1] = v;
+ }
+
+ /* perform the final reduction by mod... */
+ carry -= sub(ret, rp, mod, modnum);
+
+ /* ...conditionally */
+ cselect(carry, ret, rp, ret, modnum);
+}
+
+/* allocated buffer should be freed afterwards */
+static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs)
+{
+ int i;
+ int real_limbs = (BN_num_bytes(bn) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ limb_t *ptr = buf + (limbs - real_limbs);
+
+ for (i = 0; i < real_limbs; i++)
+ ptr[i] = bn->d[real_limbs - i - 1];
+}
+
+#if LIMB_BYTE_SIZE == 8
+static ossl_inline uint64_t be64(uint64_t host)
+{
+ uint64_t big = 0;
+ DECLARE_IS_ENDIAN;
+
+ if (!IS_LITTLE_ENDIAN)
+ return host;
+
+ big |= (host & 0xff00000000000000) >> 56;
+ big |= (host & 0x00ff000000000000) >> 40;
+ big |= (host & 0x0000ff0000000000) >> 24;
+ big |= (host & 0x000000ff00000000) >> 8;
+ big |= (host & 0x00000000ff000000) << 8;
+ big |= (host & 0x0000000000ff0000) << 24;
+ big |= (host & 0x000000000000ff00) << 40;
+ big |= (host & 0x00000000000000ff) << 56;
+ return big;
+}
+
+#else
+/* Not all platforms have htobe32(). */
+static ossl_inline uint32_t be32(uint32_t host)
+{
+ uint32_t big = 0;
+ DECLARE_IS_ENDIAN;
+
+ if (!IS_LITTLE_ENDIAN)
+ return host;
+
+ big |= (host & 0xff000000) >> 24;
+ big |= (host & 0x00ff0000) >> 8;
+ big |= (host & 0x0000ff00) << 8;
+ big |= (host & 0x000000ff) << 24;
+ return big;
+}
+#endif
+
+/*
+ * We assume that intermediate, possible_arg2, blinding, and ctx are used
+ * similar to BN_BLINDING_invert_ex() arguments.
+ * to_mod is RSA modulus.
+ * buf and num is the serialization buffer and its length.
+ *
+ * Here we use classic/Montgomery multiplication and modulo. After the calculation finished
+ * we serialize the new structure instead of BIGNUMs taking endianness into account.
+ */
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
+ const BN_BLINDING *blinding,
+ const BIGNUM *possible_arg2,
+ const BIGNUM *to_mod, BN_CTX *ctx,
+ unsigned char *buf, int num)
+{
+ limb_t *l_im = NULL, *l_mul = NULL, *l_mod = NULL;
+ limb_t *l_ret = NULL, *l_tmp = NULL, l_buf;
+ size_t l_im_count = 0, l_mul_count = 0, l_size = 0, l_mod_count = 0;
+ size_t l_tmp_count = 0;
+ int ret = 0;
+ size_t i;
+ unsigned char *tmp;
+ const BIGNUM *arg1 = intermediate;
+ const BIGNUM *arg2 = (possible_arg2 == NULL) ? blinding->Ai : possible_arg2;
+
+ l_im_count = (BN_num_bytes(arg1) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ l_mul_count = (BN_num_bytes(arg2) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ l_mod_count = (BN_num_bytes(to_mod) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+
+ l_size = l_im_count > l_mul_count ? l_im_count : l_mul_count;
+ l_im = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
+ l_mul = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
+ l_mod = OPENSSL_zalloc(l_mod_count * LIMB_BYTE_SIZE);
+
+ if ((l_im == NULL) || (l_mul == NULL) || (l_mod == NULL))
+ goto err;
+
+ BN_to_limb(arg1, l_im, l_size);
+ BN_to_limb(arg2, l_mul, l_size);
+ BN_to_limb(to_mod, l_mod, l_mod_count);
+
+ l_ret = OPENSSL_malloc(2 * l_size * LIMB_BYTE_SIZE);
+
+ if (blinding->m_ctx != NULL) {
+ l_tmp_count = mul_limb_numb(l_size) > mod_montgomery_limb_numb(l_mod_count) ?
+ mul_limb_numb(l_size) : mod_montgomery_limb_numb(l_mod_count);
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
+ } else {
+ l_tmp_count = mul_limb_numb(l_size) > mod_limb_numb(2 * l_size, l_mod_count) ?
+ mul_limb_numb(l_size) : mod_limb_numb(2 * l_size, l_mod_count);
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
+ }
+
+ if ((l_ret == NULL) || (l_tmp == NULL))
+ goto err;
+
+ if (blinding->m_ctx != NULL) {
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
+ mod_montgomery(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count,
+ blinding->m_ctx->n0[0], l_tmp);
+ } else {
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
+ mod(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, l_tmp);
+ }
+
+ /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */
+ if (num < BN_num_bytes(to_mod)) {
+ ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+
+ memset(buf, 0, num);
+ tmp = buf + num - BN_num_bytes(to_mod);
+ for (i = 0; i < l_mod_count; i++) {
+#if LIMB_BYTE_SIZE == 8
+ l_buf = be64(l_ret[i]);
+#else
+ l_buf = be32(l_ret[i]);
+#endif
+ if (i == 0) {
+ int delta = LIMB_BYTE_SIZE - ((l_mod_count * LIMB_BYTE_SIZE) - num);
+
+ memcpy(tmp, ((char *)&l_buf) + LIMB_BYTE_SIZE - delta, delta);
+ tmp += delta;
+ } else {
+ memcpy(tmp, &l_buf, LIMB_BYTE_SIZE);
+ tmp += LIMB_BYTE_SIZE;
+ }
+ }
+ ret = num;
+
+ err:
+ OPENSSL_free(l_im);
+ OPENSSL_free(l_mul);
+ OPENSSL_free(l_mod);
+ OPENSSL_free(l_tmp);
+ OPENSSL_free(l_ret);
+
+ return ret;
+}
diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c
index 381c659352..7e8b791fba 100644
--- a/crypto/rsa/rsa_ossl.c
+++ b/crypto/rsa/rsa_ossl.c
@@ -469,13 +469,20 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
BN_free(d);
}
- if (blinding)
- if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+ if (blinding) {
+ /*
+ * ossl_bn_rsa_do_unblind() combines blinding inversion and
+ * 0-padded BN BE serialization
+ */
+ j = ossl_bn_rsa_do_unblind(ret, blinding, unblind, rsa->n, ctx,
+ buf, num);
+ if (j == 0)
goto err;
-
- j = BN_bn2binpad(ret, buf, num);
- if (j < 0)
- goto err;
+ } else {
+ j = BN_bn2binpad(ret, buf, num);
+ if (j < 0)
+ goto err;
+ }
switch (padding) {
case RSA_PKCS1_PADDING:
diff --git a/include/crypto/bn.h b/include/crypto/bn.h
index cf69bea848..cd45654210 100644
--- a/include/crypto/bn.h
+++ b/include/crypto/bn.h
@@ -114,4 +114,10 @@ OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx);
extern const BIGNUM ossl_bn_inv_sqrt_2;
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
+ const BN_BLINDING *blinding,
+ const BIGNUM *possible_arg2,
+ const BIGNUM *to_mod, BN_CTX *ctx,
+ unsigned char *buf, int num);
+
#endif
--
2.39.1

@ -0,0 +1,106 @@
From 63bcf189be73a9cc1264059bed6f57974be74a83 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 13 Dec 2022 14:54:55 +0000
Subject: [PATCH 04/18] Avoid dangling ptrs in header and data params for
PEM_read_bio_ex
In the event of a failure in PEM_read_bio_ex() we free the buffers we
allocated for the header and data buffers. However we were not clearing
the ptrs stored in *header and *data. Since, on success, the caller is
responsible for freeing these ptrs this can potentially lead to a double
free if the caller frees them even on failure.
Thanks to Dawei Wang for reporting this issue.
Based on a proposed patch by Kurt Roeckx.
CVE-2022-4450
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
---
crypto/pem/pem_lib.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index f9ff80162a..85c47fb627 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -989,7 +989,9 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
*data = pem_malloc(len, flags);
if (*header == NULL || *data == NULL) {
pem_free(*header, flags, 0);
+ *header = NULL;
pem_free(*data, flags, 0);
+ *data = NULL;
goto end;
}
BIO_read(headerB, *header, headerlen);
--
2.39.1
From cbafa34b5a057794c5c08cd4657038e1f643c1ac Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 13 Dec 2022 15:02:26 +0000
Subject: [PATCH 05/18] Add a test for CVE-2022-4450
Call PEM_read_bio_ex() and expect a failure. There should be no dangling
ptrs and therefore there should be no double free if we free the ptrs on
error.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
---
test/pemtest.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/test/pemtest.c b/test/pemtest.c
index a8d2d49bb5..a5d28cb256 100644
--- a/test/pemtest.c
+++ b/test/pemtest.c
@@ -96,6 +96,35 @@ static int test_cert_key_cert(void)
return 1;
}
+static int test_empty_payload(void)
+{
+ BIO *b;
+ static char *emptypay =
+ "-----BEGIN CERTIFICATE-----\n"
+ "-\n" /* Base64 EOF character */
+ "-----END CERTIFICATE-----";
+ char *name = NULL, *header = NULL;
+ unsigned char *data = NULL;
+ long len;
+ int ret = 0;
+
+ b = BIO_new_mem_buf(emptypay, strlen(emptypay));
+ if (!TEST_ptr(b))
+ return 0;
+
+ /* Expected to fail because the payload is empty */
+ if (!TEST_false(PEM_read_bio_ex(b, &name, &header, &data, &len, 0)))
+ goto err;
+
+ ret = 1;
+ err:
+ OPENSSL_free(name);
+ OPENSSL_free(header);
+ OPENSSL_free(data);
+ BIO_free(b);
+ return ret;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(pemfile = test_get_argument(0)))
@@ -103,5 +132,6 @@ int setup_tests(void)
ADD_ALL_TESTS(test_b64, OSSL_NELEM(b64_pem_data));
ADD_TEST(test_invalid);
ADD_TEST(test_cert_key_cert);
+ ADD_TEST(test_empty_payload);
return 1;
}
--
2.39.1

@ -0,0 +1,187 @@
From 8818064ce3c3c0f1b740a5aaba2a987e75bfbafd Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Wed, 14 Dec 2022 16:18:14 +0000
Subject: [PATCH 06/18] Fix a UAF resulting from a bug in BIO_new_NDEF
If the aux->asn1_cb() call fails in BIO_new_NDEF then the "out" BIO will
be part of an invalid BIO chain. This causes a "use after free" when the
BIO is eventually freed.
Based on an original patch by Viktor Dukhovni and an idea from Theo
Buehler.
Thanks to Octavio Galland for reporting this issue.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/asn1/bio_ndef.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
index d94e3a3644..b9df3a7a47 100644
--- a/crypto/asn1/bio_ndef.c
+++ b/crypto/asn1/bio_ndef.c
@@ -49,13 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg);
-/* unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() */
+/*
+ * On success, the returned BIO owns the input BIO as part of its BIO chain.
+ * On failure, NULL is returned and the input BIO is owned by the caller.
+ *
+ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream()
+ */
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
+ BIO *pop_bio = NULL;
if (!aux || !aux->asn1_cb) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
@@ -70,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
out = BIO_push(asn_bio, out);
if (out == NULL)
goto err;
+ pop_bio = asn_bio;
- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+ if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0
+ || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0
+ || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0)
+ goto err;
/*
- * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
- * needs.
+ * Now let the callback prepend any digest, cipher, etc., that the BIO's
+ * ASN1 structure needs.
*/
sarg.out = out;
sarg.ndef_bio = NULL;
sarg.boundary = NULL;
- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+ /*
+ * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the
+ * middle of some partially built, but not returned BIO chain.
+ */
+ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) {
+ /*
+ * ndef_aux is now owned by asn_bio so we must not free it in the err
+ * clean up block
+ */
+ ndef_aux = NULL;
goto err;
+ }
+
+ /*
+ * We must not fail now because the callback has prepended additional
+ * BIOs to the chain
+ */
ndef_aux->val = val;
ndef_aux->it = it;
@@ -92,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
-
return sarg.ndef_bio;
err:
+ /* BIO_pop() is NULL safe */
+ (void)BIO_pop(pop_bio);
BIO_free(asn_bio);
OPENSSL_free(ndef_aux);
return NULL;
--
2.39.1
From f596ec8a6f9f5fcfa8e46a73b60f78a609725294 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Wed, 14 Dec 2022 17:15:18 +0000
Subject: [PATCH 07/18] Check CMS failure during BIO setup with -stream is
handled correctly
Test for the issue fixed in the previous commit
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
test/recipes/80-test_cms.t | 15 +++++++++++++--
test/smime-certs/badrsa.pem | 18 ++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 test/smime-certs/badrsa.pem
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
index 610f1cbc51..fd53683e6b 100644
--- a/test/recipes/80-test_cms.t
+++ b/test/recipes/80-test_cms.t
@@ -13,7 +13,7 @@ use warnings;
use POSIX;
use File::Spec::Functions qw/catfile/;
use File::Compare qw/compare_text compare/;
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with/;
use OpenSSL::Test::Utils;
@@ -50,7 +50,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
$no_rc2 = 1 if disabled("legacy");
-plan tests => 12;
+plan tests => 13;
ok(run(test(["pkcs7_test"])), "test pkcs7");
@@ -972,3 +972,14 @@ ok(!run(app(['openssl', 'cms', '-verify',
return "";
}
+
+# Check that we get the expected failure return code
+with({ exit_checker => sub { return shift == 6; } },
+ sub {
+ ok(run(app(['openssl', 'cms', '-encrypt',
+ '-in', srctop_file("test", "smcont.txt"),
+ '-stream', '-recip',
+ srctop_file("test/smime-certs", "badrsa.pem"),
+ ])),
+ "Check failure during BIO setup with -stream is handled correctly");
+ });
diff --git a/test/smime-certs/badrsa.pem b/test/smime-certs/badrsa.pem
new file mode 100644
index 0000000000..f824fc2267
--- /dev/null
+++ b/test/smime-certs/badrsa.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIToTV4Z0iuK08vZP20oTh//hC8BDANBgkqhkiG9w0BAQ0FADAtMSswKQYD
+VfcDEyJTYW1wbGUgTEFNUFMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTE5MTEyMDA2NTQxOFoY
+DzIwNTIwOTI3MDY1NDE4WjAZMRcwFQYDVQQDEw5BbGljZSBMb3ZlbGFjZTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBALT0iehYOBY+TZp/T5K2KNI05Hwr+E3wP6XTvyi6WWyTgBK9LCOw
+I2juwdRrjFBmXkk7pWpjXwsA3A5GOtz0FpfgyC7OxsVcF7q4WHWZWleYXFKlQHJD73nQwXP968+A
+/3rBX7PhO0DBbZnfitOLPgPEwjTtdg0VQQ6Wz+CRQ/YbHPKaw7aRphZO63dKvIKp4cQVtkWQHi6s
+yTjGsgkLcLNau5LZDQUdsGV+SAo3nBdWCRYV+I65x8Kf4hCxqqmjV3d/2NKRu0BXnDe/N+iDz3X0
+zEoj0fqXgq4SWcC0nsG1lyyXt1TL270I6ATKRGJWiQVCCpDtc0NT6vdJ45bCSxgCAwEAAaOBlzCB
+lDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE2FsaWNlQHNtaW1lLmV4YW1wbGUwEwYDVR0lBAww
+CgYIKwYBBQUHAwQwDwYDVR0PAQH/BAUDAwfAADAdBgNVHQ4EFgQUu/bMsi0dBhIcl64papAQ0yBm
+ZnMwHwYDVR0jBBgwFoAUeF8OWnjYa+RUcD2z3ez38fL6wEcwDQYJKoZIhvcNAQENBQADggEBABbW
+eonR6TMTckehDKNOabwaCIcekahAIL6l9tTzUX5ew6ufiAPlC6I/zQlmUaU0iSyFDG1NW14kNbFt
+5CAokyLhMtE4ASHBIHbiOp/ZSbUBTVYJZB61ot7w1/ol5QECSs08b8zrxIncf+t2DHGuVEy/Qq1d
+rBz8d4ay8zpqAE1tUyL5Da6ZiKUfWwZQXSI/JlbjQFzYQqTRDnzHWrg1xPeMTO1P2/cplFaseTiv
+yk4cYwOp/W9UAWymOZXF8WcJYCIUXkdcG/nEZxr057KlScrJmFXOoh7Y+8ON4iWYYcAfiNgpUFo/
+j8BAwrKKaFvdlZS9k1Ypb2+UQY75mKJE9Bg=
+-----END CERTIFICATE-----
--
2.39.1

@ -0,0 +1,110 @@
From 934a04f0e775309cadbef0aa6b9692e1b12a76c6 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Mon, 16 Jan 2023 19:45:23 +0100
Subject: [PATCH 08/18] Do not dereference PKCS7 object data if not set
Fixes CVE-2023-0216
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
---
crypto/pkcs7/pk7_lib.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c
index 753f1276e6..936e50da54 100644
--- a/crypto/pkcs7/pk7_lib.c
+++ b/crypto/pkcs7/pk7_lib.c
@@ -414,6 +414,8 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
{
+ if (p7->d.ptr == NULL)
+ return NULL;
if (PKCS7_type_is_signed(p7))
return p7->d.sign->cert;
if (PKCS7_type_is_signedAndEnveloped(p7))
@@ -423,6 +425,8 @@ static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
{
+ if (p7->d.ptr == NULL)
+ return NULL;
if (PKCS7_type_is_signedAndEnveloped(p7))
return p7->d.signed_and_enveloped->recipientinfo;
if (PKCS7_type_is_enveloped(p7))
@@ -440,13 +444,17 @@ void ossl_pkcs7_resolve_libctx(PKCS7 *p7)
const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
- STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7);
- STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
- STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7);
+ STACK_OF(PKCS7_RECIP_INFO) *rinfos;
+ STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+ STACK_OF(X509) *certs;
- if (ctx == NULL)
+ if (ctx == NULL || p7->d.ptr == NULL)
return;
+ rinfos = pkcs7_get_recipient_info(p7);
+ sinfos = PKCS7_get_signer_info(p7);
+ certs = pkcs7_get_signer_certs(p7);
+
for (i = 0; i < sk_X509_num(certs); i++)
ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
--
2.39.1
From 67813d8a4d110f4174bbd2fee8a2f15388e324b5 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Mon, 16 Jan 2023 19:56:20 +0100
Subject: [PATCH 09/18] Add test for d2i_PKCS7 NULL dereference
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
---
test/recipes/25-test_pkcs7.t | 7 +++++--
test/recipes/25-test_pkcs7_data/malformed.pkcs7 | 3 +++
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 test/recipes/25-test_pkcs7_data/malformed.pkcs7
diff --git a/test/recipes/25-test_pkcs7.t b/test/recipes/25-test_pkcs7.t
index 37cd43dc6b..d61cd6abad 100644
--- a/test/recipes/25-test_pkcs7.t
+++ b/test/recipes/25-test_pkcs7.t
@@ -11,11 +11,11 @@ use strict;
use warnings;
use File::Spec;
-use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test qw/:DEFAULT srctop_file data_file/;
setup("test_pkcs7");
-plan tests => 3;
+plan tests => 4;
require_ok(srctop_file('test','recipes','tconversion.pl'));
@@ -27,3 +27,6 @@ subtest 'pkcs7 conversions -- pkcs7d' => sub {
tconversion( -type => 'p7d', -in => srctop_file("test", "pkcs7-1.pem"),
-args => ["pkcs7"] );
};
+
+my $malformed = data_file('malformed.pkcs7');
+ok(run(app(["openssl", "pkcs7", "-in", $malformed])));
diff --git a/test/recipes/25-test_pkcs7_data/malformed.pkcs7 b/test/recipes/25-test_pkcs7_data/malformed.pkcs7
new file mode 100644
index 0000000000..e30d1b582c
--- /dev/null
+++ b/test/recipes/25-test_pkcs7_data/malformed.pkcs7
@@ -0,0 +1,3 @@
+-----BEGIN PKCS7-----
+MAsGCSqGSIb3DQEHAg==
+-----END PKCS7-----
--
2.39.1

@ -0,0 +1,430 @@
From 23985bac83fd50c8e29431009302b5442f985096 Mon Sep 17 00:00:00 2001
From: slontis <shane.lontis@oracle.com>
Date: Wed, 11 Jan 2023 11:05:04 +1000
Subject: [PATCH 10/18] Fix NULL deference when validating FFC public key.
Fixes CVE-2023-0217
When attempting to do a BN_Copy of params->p there was no NULL check.
Since BN_copy does not check for NULL this is a NULL reference.
As an aside BN_cmp() does do a NULL check, so there are other checks
that fail because a NULL is passed. A more general check for NULL params
has been added for both FFC public and private key validation instead.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/ffc/ffc_key_validate.c | 9 +++++++++
include/internal/ffc.h | 1 +
test/ffc_internal_test.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/crypto/ffc/ffc_key_validate.c b/crypto/ffc/ffc_key_validate.c
index 9f6525a2c8..442303e4b3 100644
--- a/crypto/ffc/ffc_key_validate.c
+++ b/crypto/ffc/ffc_key_validate.c
@@ -24,6 +24,11 @@ int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params,
BN_CTX *ctx = NULL;
*ret = 0;
+ if (params == NULL || pub_key == NULL || params->p == NULL) {
+ *ret = FFC_ERROR_PASSED_NULL_PARAM;
+ return 0;
+ }
+
ctx = BN_CTX_new_ex(NULL);
if (ctx == NULL)
goto err;
@@ -107,6 +112,10 @@ int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv,
*ret = 0;
+ if (priv == NULL || upper == NULL) {
+ *ret = FFC_ERROR_PASSED_NULL_PARAM;
+ goto err;
+ }
if (BN_cmp(priv, BN_value_one()) < 0) {
*ret |= FFC_ERROR_PRIVKEY_TOO_SMALL;
goto err;
diff --git a/include/internal/ffc.h b/include/internal/ffc.h
index 732514a6c2..b8b7140857 100644
--- a/include/internal/ffc.h
+++ b/include/internal/ffc.h
@@ -76,6 +76,7 @@
# define FFC_ERROR_NOT_SUITABLE_GENERATOR 0x08
# define FFC_ERROR_PRIVKEY_TOO_SMALL 0x10
# define FFC_ERROR_PRIVKEY_TOO_LARGE 0x20
+# define FFC_ERROR_PASSED_NULL_PARAM 0x40
/*
* Finite field cryptography (FFC) domain parameters are used by DH and DSA.
diff --git a/test/ffc_internal_test.c b/test/ffc_internal_test.c
index 2c97293573..9f67bd29b9 100644
--- a/test/ffc_internal_test.c
+++ b/test/ffc_internal_test.c
@@ -510,6 +510,27 @@ static int ffc_public_validate_test(void)
if (!TEST_true(ossl_ffc_validate_public_key(params, pub, &res)))
goto err;
+ /* Fail if params is NULL */
+ if (!TEST_false(ossl_ffc_validate_public_key(NULL, pub, &res)))
+ goto err;
+ if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+ goto err;
+ res = -1;
+ /* Fail if pubkey is NULL */
+ if (!TEST_false(ossl_ffc_validate_public_key(params, NULL, &res)))
+ goto err;
+ if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+ goto err;
+ res = -1;
+
+ BN_free(params->p);
+ params->p = NULL;
+ /* Fail if params->p is NULL */
+ if (!TEST_false(ossl_ffc_validate_public_key(params, pub, &res)))
+ goto err;
+ if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+ goto err;
+
ret = 1;
err:
DH_free(dh);
@@ -567,6 +588,16 @@ static int ffc_private_validate_test(void)
if (!TEST_true(ossl_ffc_validate_private_key(params->q, priv, &res)))
goto err;
+ if (!TEST_false(ossl_ffc_validate_private_key(NULL, priv, &res)))
+ goto err;
+ if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+ goto err;
+ res = -1;
+ if (!TEST_false(ossl_ffc_validate_private_key(params->q, NULL, &res)))
+ goto err;
+ if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+ goto err;
+
ret = 1;
err:
DH_free(dh);
--
2.39.1
From c1b4467a7cc129a74fc5205b80a5c47556b99416 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Fri, 13 Jan 2023 17:57:59 +0100
Subject: [PATCH 11/18] Prevent creating DSA and DH keys without parameters
through import
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
---
providers/implementations/keymgmt/dh_kmgmt.c | 4 ++--
providers/implementations/keymgmt/dsa_kmgmt.c | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index 58a5fd009f..c2d87b4a7f 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -198,8 +198,8 @@ static int dh_import(void *keydata, int selection, const OSSL_PARAM params[])
if ((selection & DH_POSSIBLE_SELECTIONS) == 0)
return 0;
- if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
- ok = ok && ossl_dh_params_fromdata(dh, params);
+ /* a key without parameters is meaningless */
+ ok = ok && ossl_dh_params_fromdata(dh, params);
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
ok = ok && ossl_dh_key_fromdata(dh, params);
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index 100e917167..881680c085 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -199,8 +199,9 @@ static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)
return 0;
- if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
- ok = ok && ossl_dsa_ffc_params_fromdata(dsa, params);
+ /* a key without parameters is meaningless */
+ ok = ok && ossl_dsa_ffc_params_fromdata(dsa, params);
+
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
ok = ok && ossl_dsa_key_fromdata(dsa, params);
--
2.39.1
From fab4973801bdc11c29c4c8ccf65cf39cbc63ce9b Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Fri, 13 Jan 2023 17:59:52 +0100
Subject: [PATCH 12/18] Do not create DSA keys without parameters by decoder
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
---
crypto/x509/x_pubkey.c | 24 +++++++++++++++++++
include/crypto/x509.h | 3 +++
.../encode_decode/decode_der2key.c | 2 +-
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
index bc90ddd89b..77790faa1f 100644
--- a/crypto/x509/x_pubkey.c
+++ b/crypto/x509/x_pubkey.c
@@ -745,6 +745,30 @@ DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
return key;
}
+/* Called from decoders; disallows provided DSA keys without parameters. */
+DSA *ossl_d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+ DSA *key = NULL;
+ const unsigned char *data;
+ const BIGNUM *p, *q, *g;
+
+ data = *pp;
+ key = d2i_DSA_PUBKEY(NULL, &data, length);
+ if (key == NULL)
+ return NULL;
+ DSA_get0_pqg(key, &p, &q, &g);
+ if (p == NULL || q == NULL || g == NULL) {
+ DSA_free(key);
+ return NULL;
+ }
+ *pp = data;
+ if (a != NULL) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
{
EVP_PKEY *pktmp;
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index 1f00178e89..0c42730ee9 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -339,6 +339,9 @@ void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub);
RSA *ossl_d2i_RSA_PSS_PUBKEY(RSA **a, const unsigned char **pp, long length);
int ossl_i2d_RSA_PSS_PUBKEY(const RSA *a, unsigned char **pp);
+# ifndef OPENSSL_NO_DSA
+DSA *ossl_d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+# endif /* OPENSSL_NO_DSA */
# ifndef OPENSSL_NO_DH
DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length);
int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp);
diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c
index ebc2d24833..d6ad738ef3 100644
--- a/providers/implementations/encode_decode/decode_der2key.c
+++ b/providers/implementations/encode_decode/decode_der2key.c
@@ -374,7 +374,7 @@ static void *dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
(key_from_pkcs8_t *)ossl_dsa_key_from_pkcs8);
}
-# define dsa_d2i_PUBKEY (d2i_of_void *)d2i_DSA_PUBKEY
+# define dsa_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DSA_PUBKEY
# define dsa_free (free_key_fn *)DSA_free
# define dsa_check NULL
--
2.39.1
From 7e37185582995b35f885fec9dcc3670af9ffcbef Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Fri, 13 Jan 2023 18:46:15 +0100
Subject: [PATCH 13/18] Add test for DSA pubkey without param import and check
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
---
test/recipes/91-test_pkey_check.t | 48 ++++++++++++++----
.../91-test_pkey_check_data/dsapub.pem | 12 +++++
.../dsapub_noparam.der | Bin 0 -> 108 bytes
3 files changed, 49 insertions(+), 11 deletions(-)
create mode 100644 test/recipes/91-test_pkey_check_data/dsapub.pem
create mode 100644 test/recipes/91-test_pkey_check_data/dsapub_noparam.der
--- openssl-3.0.1/test/recipes/91-test_pkey_check.t 2023-02-08 13:43:56.228487948 +0100
+++ openssl-3.0.7/test/recipes/91-test_pkey_check.t 2023-02-08 12:47:13.531027540 +0100
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
@@ -11,24 +11,37 @@
use warnings;
use File::Spec;
-use OpenSSL::Test qw/:DEFAULT data_file/;
+use OpenSSL::Test qw/:DEFAULT data_file with/;
use OpenSSL::Test::Utils;
-sub check_key {
+sub pkey_check {
my $f = shift;
+ my $pubcheck = shift;
+ my @checkopt = ('-check');
+
+ @checkopt = ('-pubcheck', '-pubin') if $pubcheck;
- return run(app(['openssl', 'pkey', '-check', '-text',
+ return run(app(['openssl', 'pkey', @checkopt, '-text',
'-in', $f]));
}
-sub check_key_notok {
+sub check_key {
my $f = shift;
- my $str = "$f should fail validation";
+ my $should_fail = shift;
+ my $pubcheck = shift;
+ my $str;
+
+
+ $str = "$f should fail validation" if $should_fail;
+ $str = "$f should pass validation" unless $should_fail;
$f = data_file($f);
if ( -s $f ) {
- ok(!check_key($f), $str);
+ with({ exit_checker => sub { return shift == $should_fail; } },
+ sub {
+ ok(pkey_check($f, $pubcheck), $str);
+ });
} else {
fail("Missing file $f");
}
@@ -36,26 +49,54 @@
setup("test_pkey_check");
-my @tests = ();
+my @negative_tests = ();
-push(@tests, (
+push(@negative_tests, (
# For EC keys the range for the secret scalar `k` is `1 <= k <= n-1`
"ec_p256_bad_0.pem", # `k` set to `n` (equivalent to `0 mod n`, invalid)
"ec_p256_bad_1.pem", # `k` set to `n+1` (equivalent to `1 mod n`, invalid)
)) unless disabled("ec");
-push(@tests, (
+push(@negative_tests, (
# For SM2 keys the range for the secret scalar `k` is `1 <= k < n-1`
"sm2_bad_neg1.pem", # `k` set to `n-1` (invalid, because SM2 range)
"sm2_bad_0.pem", # `k` set to `n` (equivalent to `0 mod n`, invalid)
"sm2_bad_1.pem", # `k` set to `n+1` (equivalent to `1 mod n`, invalid)
)) unless disabled("sm2");
+my @positive_tests = ();
+
+my @negative_pubtests = ();
+
+push(@negative_pubtests, (
+ "dsapub_noparam.der"
+ )) unless disabled("dsa");
+
+my @positive_pubtests = ();
+
+push(@positive_pubtests, (
+ "dsapub.pem"
+ )) unless disabled("dsa");
+
plan skip_all => "No tests within the current enabled feature set"
- unless @tests;
+ unless @negative_tests && @positive_tests
+ && @negative_pubtests && @positive_pubtests;
+
+plan tests => scalar(@negative_tests) + scalar(@positive_tests)
+ + scalar(@negative_pubtests) + scalar(@positive_pubtests);
+
+foreach my $t (@negative_tests) {
+ check_key($t, 1, 0);
+}
+
+foreach my $t (@positive_tests) {
+ check_key($t, 0, 0);
+}
-plan tests => scalar(@tests);
+foreach my $t (@negative_pubtests) {
+ check_key($t, 1, 1);
+}
-foreach my $t (@tests) {
- check_key_notok($t);
+foreach my $t (@positive_pubtests) {
+ check_key($t, 0, 1);
}
diff --git a/test/recipes/91-test_pkey_check_data/dsapub.pem b/test/recipes/91-test_pkey_check_data/dsapub.pem
new file mode 100644
index 0000000000..0ff4bd83ed
--- /dev/null
+++ b/test/recipes/91-test_pkey_check_data/dsapub.pem
@@ -0,0 +1,12 @@
+-----BEGIN PUBLIC KEY-----
+MIIBvzCCATQGByqGSM44BAEwggEnAoGBAIjbXpOVVciVNuagg26annKkghIIZFI4
+4WdMomnV+I/oXyxHbZTBBBpW9xy/E1+yMjbp4GmX+VxyDj3WxUWxXllzL+miEkzD
+9Xz638VzIBhjFbMvk1/N4kS4bKVUd9yk7HfvYzAdnRphk0WI+RoDiDrBNPPxSoQD
+CEWgvwgsLIDhAh0A6dbz1IQpQwGF4+Ca28x6OO+UfJJv3ggeZ++fNwKBgQCA9XKV
+lRrTY8ALBxS0KbZjpaIXuUj5nr3i1lIDyP3ISksDF0ekyLtn6eK9VijX6Pm65Np+
+4ic9Nr5WKLKhPaUSpLNRx1gDqo3sd92hYgiEUifzEuhLYfK/CsgFED+l2hDXtJUq
+bISNSHVwI5lsyNXLu7HI1Fk8F5UO3LqsboFAngOBhAACgYATxFY89nEYcUhgHGgr
+YDHhXBQfMKnTKYdvon4DN7WQ9ip+t4VUsLpTD1ZE9zrM2R/B04+8C6KGoViwyeER
+kS4dxWOkX71x4X2DlNpYevcR53tNcTDqmMD7YKfDDmrb0lftMyfW8aESaiymVMys
+DRjhKHBjdo0rZeSM8DAk3ctrXA==
+-----END PUBLIC KEY-----
diff --git a/test/recipes/91-test_pkey_check_data/dsapub_noparam.der b/test/recipes/91-test_pkey_check_data/dsapub_noparam.der
new file mode 100644
index 0000000000000000000000000000000000000000..b8135f1ca94da914b6829421e0c13f6daa731862
GIT binary patch
literal 108
zcmXpIGT>xm*J|@PXTieE%*wz71<Xv0AT}3_&&0^YB*etj0OvEYF$n`XLd*y;pgagL
U3o&W4F|x9<gY>|F5F-Nv0Bz9(=Kufz
literal 0
HcmV?d00001
--
2.39.1
From 2ad9928170768653d19d81881deabc5f9c1665c0 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Fri, 3 Feb 2023 14:57:04 +0100
Subject: [PATCH 18/18] Internaly declare the DSA type for no-deprecated builds
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(cherry picked from commit 7a21a1b5fa2dac438892cf3292d1f9c445d870d9)
---
include/crypto/types.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/crypto/types.h b/include/crypto/types.h
index 0d81404091..0a75f03a3f 100644
--- a/include/crypto/types.h
+++ b/include/crypto/types.h
@@ -20,6 +20,9 @@ typedef struct rsa_meth_st RSA_METHOD;
typedef struct ec_key_st EC_KEY;
typedef struct ec_key_method_st EC_KEY_METHOD;
# endif
+# ifndef OPENSSL_NO_DSA
+typedef struct dsa_st DSA;
+# endif
# endif
# ifndef OPENSSL_NO_EC
--
2.39.1

@ -0,0 +1,63 @@
From 2f7530077e0ef79d98718138716bc51ca0cad658 Mon Sep 17 00:00:00 2001
From: Hugo Landau <hlandau@openssl.org>
Date: Tue, 17 Jan 2023 17:45:42 +0000
Subject: [PATCH 14/18] CVE-2023-0286: Fix GENERAL_NAME_cmp for x400Address
(3.0)
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
CHANGES.md | 19 +++++++++++++++++++
crypto/x509/v3_genn.c | 2 +-
include/openssl/x509v3.h.in | 2 +-
test/v3nametest.c | 8 ++++++++
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/crypto/x509/v3_genn.c b/crypto/x509/v3_genn.c
index c0a7166cd0..1741c2d2f6 100644
--- a/crypto/x509/v3_genn.c
+++ b/crypto/x509/v3_genn.c
@@ -98,7 +98,7 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
return -1;
switch (a->type) {
case GEN_X400:
- result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
+ result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
break;
case GEN_EDIPARTY:
diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in
index d00a66a343..c087e3cf92 100644
--- a/include/openssl/x509v3.h.in
+++ b/include/openssl/x509v3.h.in
@@ -154,7 +154,7 @@ typedef struct GENERAL_NAME_st {
OTHERNAME *otherName; /* otherName */
ASN1_IA5STRING *rfc822Name;
ASN1_IA5STRING *dNSName;
- ASN1_TYPE *x400Address;
+ ASN1_STRING *x400Address;
X509_NAME *directoryName;
EDIPARTYNAME *ediPartyName;
ASN1_IA5STRING *uniformResourceIdentifier;
diff --git a/test/v3nametest.c b/test/v3nametest.c
index 6d2e2f8e27..0341995dde 100644
--- a/test/v3nametest.c
+++ b/test/v3nametest.c
@@ -644,6 +644,14 @@ static struct gennamedata {
0xb7, 0x09, 0x02, 0x02
},
15
+ }, {
+ /*
+ * Regression test for CVE-2023-0286.
+ */
+ {
+ 0xa3, 0x00
+ },
+ 2
}
};
--
2.39.1

@ -0,0 +1,150 @@
From d3b6dfd70db844c4499bec6ad6601623a565e674 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Wed, 18 Jan 2023 09:27:53 +0100
Subject: [PATCH 15/18] pk7_doit.c: Check return of BIO_set_md() calls
These calls invoke EVP_DigestInit() which can fail for digests
with implicit fetches. Subsequent EVP_DigestUpdate() from BIO_write()
or EVP_DigestFinal() from BIO_read() will segfault on NULL
dereference. This can be triggered by an attacker providing
PKCS7 data digested with MD4 for example if the legacy provider
is not loaded.
If BIO_set_md() fails the md BIO cannot be used.
CVE-2023-0401
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
---
crypto/pkcs7/pk7_doit.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index bde9ac4787..5e562fbea5 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -84,7 +84,11 @@ static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg,
}
(void)ERR_pop_to_mark();
- BIO_set_md(btmp, md);
+ if (BIO_set_md(btmp, md) <= 0) {
+ ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
+ EVP_MD_free(fetched);
+ goto err;
+ }
EVP_MD_free(fetched);
if (*pbio == NULL)
*pbio = btmp;
@@ -522,7 +526,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
}
(void)ERR_pop_to_mark();
- BIO_set_md(btmp, md);
+ if (BIO_set_md(btmp, md) <= 0) {
+ EVP_MD_free(evp_md);
+ ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
+ goto err;
+ }
EVP_MD_free(evp_md);
if (out == NULL)
out = btmp;
--
2.39.1
From a0f2359613f50b5ca6b74b78bf4b54d7dc925fd2 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Wed, 18 Jan 2023 17:07:24 +0100
Subject: [PATCH 16/18] Add testcase for missing return check of BIO_set_md()
calls
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
---
test/recipes/80-test_cms.t | 15 ++++++++--
test/recipes/80-test_cms_data/pkcs7-md4.pem | 32 +++++++++++++++++++++
2 files changed, 45 insertions(+), 2 deletions(-)
create mode 100644 test/recipes/80-test_cms_data/pkcs7-md4.pem
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
index fd53683e6b..d45789de70 100644
--- a/test/recipes/80-test_cms.t
+++ b/test/recipes/80-test_cms.t
@@ -13,7 +13,7 @@ use warnings;
use POSIX;
use File::Spec::Functions qw/catfile/;
use File::Compare qw/compare_text compare/;
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with/;
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with data_file/;
use OpenSSL::Test::Utils;
@@ -50,7 +50,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
$no_rc2 = 1 if disabled("legacy");
-plan tests => 13;
+plan tests => 14;
ok(run(test(["pkcs7_test"])), "test pkcs7");
@@ -941,6 +941,17 @@ subtest "CMS binary input tests\n" => sub {
"verify binary input with -binary missing -crlfeol");
};
+# Test case for missing MD algorithm (must not segfault)
+
+with({ exit_checker => sub { return shift == 4; } },
+ sub {
+ ok(run(app(['openssl', 'smime', '-verify', '-noverify',
+ '-inform', 'PEM',
+ '-in', data_file("pkcs7-md4.pem"),
+ ])),
+ "Check failure of EVP_DigestInit is handled correctly");
+ });
+
sub check_availability {
my $tnam = shift;
diff --git a/test/recipes/80-test_cms_data/pkcs7-md4.pem b/test/recipes/80-test_cms_data/pkcs7-md4.pem
new file mode 100644
index 0000000000..ecff611deb
--- /dev/null
+++ b/test/recipes/80-test_cms_data/pkcs7-md4.pem
@@ -0,0 +1,32 @@
+-----BEGIN PKCS7-----
+MIIFhAYJKoZIhvcNAQcCoIIFdTCCBXECAQExDjAMBggqhkiG9w0CBAUAMB0GCSqG
+SIb3DQEHAaAQBA5UZXN0IGNvbnRlbnQNCqCCAyQwggMgMIICCKADAgECAgECMA0G
+CSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMMAkNBMCAXDTE2MDExNTA4MTk0OVoYDzIx
+MTYwMTE2MDgxOTQ5WjAZMRcwFQYDVQQDDA5zZXJ2ZXIuZXhhbXBsZTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKj/iVhhha7e2ywP1XP74reoG3p1YCvU
+fTxzdrWu3pMvfySQbckc9Io4zZ+igBZWy7Qsu5PlFx//DcZD/jE0+CjYdemju4iC
+76Ny4lNiBUVN4DGX76qdENJYDZ4GnjK7GwhWXWUPP2aOwjagEf/AWTX9SRzdHEIz
+BniuBDgj5ed1Z9OUrVqpQB+sWRD1DMFkrUrExjVTs5ZqghsVi9GZq+Seb5Sq0pbl
+V/uMkWSKPCQWxtIZvoJgEztisO0+HbPK+WvfMbl6nktHaKcpxz9K4iIntO+QY9fv
+0HJJPlutuRvUK2+GaN3VcxK4Q8ncQQ+io0ZPi2eIhA9h/nk0H0qJH7cCAwEAAaN9
+MHswHQYDVR0OBBYEFOeb4iqtimw6y3ZR5Y4HmCKX4XOiMB8GA1UdIwQYMBaAFLQR
+M/HX4l73U54gIhBPhga/H8leMAkGA1UdEwQCMAAwEwYDVR0lBAwwCgYIKwYBBQUH
+AwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1wbGUwDQYJKoZIhvcNAQELBQADggEB
+AEG0PE9hQuXlvtUULv9TQ2BXy9MmTjOk+dQwxDhAXYBYMUB6TygsqvPXwpDwz8MS
+EPGCRqh5cQwtPoElQRU1i4URgcQMZquXScwNFcvE6AATF/PdN/+mOwtqFrlpYfs3
+IJIpYL6ViQg4n8pv+b/pCwMmhewQLwCGs9+omHNTOwKjEiVoNaprAfj5Lxt15fS2
++zZW0mT9Y4kfEypetrqSAjh8CDK+vaQhkeKdDfJyBfjS4ALfxvCkT3mQnsWFJ9CU
+TVG3uw6ylSPT3wN3RE0Ofa4rI5PESogQsd/DgBc7dcDO3yoPKGjycR3/GJDqqCxC
+e9dr6FJEnDjaDf9zNWyTFHExggITMIICDwIBATASMA0xCzAJBgNVBAMMAkNBAgEC
+MAwGCCqGSIb3DQIEBQCggdQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkq
+hkiG9w0BCQUxDxcNMjMwMTE4MTU0NzExWjAfBgkqhkiG9w0BCQQxEgQQRXO4TKpp
+RgA4XHb8bD1pczB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjALBglghkgB
+ZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDAN
+BggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0B
+AQEFAASCAQAe+xlm/TGg/s/7b0xBc3FFnmmUDEe7ljkehIx61OnBV9ZWA+LcBX/7
+kmMSMdaHjRq4w8FmwBMLzn0ttXVqf0QuPbBF/E6X5EqK9lpOdkUQhNiN2v+ZfY6c
+lrH4ADsSD9D+UHw0sxo5KEF+PPuneUfYCJZosFUJosBbuSEXK0C9yfJoDKVE8Syp
+0vdqh73ogLeNgZLAUGSSB66OmHDxwgAj4qPAv6FHFBy1Xs4uFZER5vniYrH9OrAk
+Z6XdvzDoYZC4XcGMDtcOpOM6D4owqy5svHPDw8wIlM4GVhrTw7CQmuBz5uRNnf6a
+ZK3jZIxG1hr/INaNWheHoPIhPblYaVc6
+-----END PKCS7-----
--
2.39.1

@ -29,7 +29,7 @@ print(string.sub(hash, 0, 16))
Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl
Version: 3.0.1
Release: 43%{?dist}
Release: 47%{?dist}
Epoch: 1
# We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below.
@ -164,6 +164,43 @@ Patch77: 0077-FIPS-140-3-zeroization.patch
Patch78: 0078-Add-FIPS-indicator-parameter-to-HKDF.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=2137723
Patch79: 0079-CVE-2022-3602.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=2141748
Patch80: 0080-rand-Forbid-truncated-hashes-SHA-3-in-FIPS-prov.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2142131
Patch81: 0081-signature-Remove-X9.31-padding-from-FIPS-prov.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2141695
Patch82: 0082-kbkdf-Add-explicit-FIPS-indicator-for-key-length.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2136250
Patch83: 0083-hmac-Add-explicit-FIPS-indicator-for-key-length.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2137557
Patch84: 0084-pbkdf2-Set-minimum-password-length-of-8-bytes.patch
#https://bugzilla.redhat.com/show_bug.cgi?id=2142121
Patch85: 0085-FIPS-RSA-disable-shake.patch
#https://github.com/openssl/openssl/pull/17546
Patch86: 0086-avoid-bio-memleak.patch
#https://github.com/openssl/openssl/pull/19501
Patch87: 0087-FIPS-RSA-selftest-params.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2142087
Patch88: 0088-signature-Add-indicator-for-PSS-salt-length.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2142087
Patch89: 0089-PSS-salt-length-from-provider.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2142087
Patch90: 0090-signature-Clamp-PSS-salt-len-to-MD-len.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2144561
Patch91: 0091-FIPS-RSA-encapsulate.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2149010
#https://github.com/openssl/openssl/pull/19348
Patch94: 0094-ibmca-engine-compat.patch
# OpenSSL 3.0.8 CVEs
Patch101: 0101-CVE-2022-4203-nc-match.patch
Patch102: 0102-CVE-2022-4304-RSA-time-oracle.patch
Patch103: 0103-CVE-2022-4450-pem-read-bio.patch
Patch104: 0104-CVE-2023-0215-UAF-bio.patch
Patch105: 0105-CVE-2023-0216-pkcs7-deref.patch
Patch106: 0106-CVE-2023-0217-dsa.patch
Patch107: 0107-CVE-2023-0286-X400.patch
Patch108: 0108-CVE-2023-0401-pkcs7-md.patch
License: ASL 2.0
URL: http://www.openssl.org/
@ -494,46 +531,102 @@ install -m644 %{SOURCE9} \
%ldconfig_scriptlets libs
%changelog
* Wed Oct 26 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-43
- CVE-2022-3602: X.509 Email Address Buffer Overflow - running tests
* Wed Feb 08 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-47
- Fixed X.509 Name Constraints Read Buffer Overflow
Resolves: CVE-2022-4203
- Fixed Timing Oracle in RSA Decryption
Resolves: CVE-2022-4304
- Fixed Double free after calling PEM_read_bio_ex
Resolves: CVE-2022-4450
- Fixed Use-after-free following BIO_new_NDEF
Resolves: CVE-2023-0215
- Fixed Invalid pointer dereference in d2i_PKCS7 functions
Resolves: CVE-2023-0216
- Fixed NULL dereference validating DSA public key
Resolves: CVE-2023-0217
- Fixed X.400 address type confusion in X.509 GeneralName
Resolves: CVE-2023-0286
- Fixed NULL dereference during PKCS7 data verification
Resolves: CVE-2023-0401
* Thu Jan 05 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-46
- Refactor OpenSSL fips module MAC verification
Resolves: rhbz#2158412
- Disallow SHAKE in RSA-OAEP decryption in FIPS mode
Resolves: rhbz#2144010
* Mon Nov 28 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-45
- Add support of X25519 and X448 "group" parameter in EVP_PKEY_CTX objects
Resolves: rhbz#2149010
- Fix explicit indicator for PSS salt length in FIPS mode when used with
negative magic values
Resolves: rhbz#2144012
- Update change to default PSS salt length with patch state from upstream
Related: rhbz#2144012
* Mon Nov 14 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-44
- SHAKE-128/256 are not allowed with RSA in FIPS mode
Resolves: rhbz#2144010
- Avoid memory leaks in TLS
Resolves: rhbz#2144008
- FIPS RSA CRT tests must use correct parameters
Resolves: rhbz#2144006
- FIPS-140-3 permits only SHA1, SHA256, and SHA512 for DRBG-HASH/DRBG-HMAC
Resolves: rhbz#2144017
- Remove support for X9.31 signature padding in FIPS mode
Resolves: rhbz#2144015
- Add explicit indicator for SP 800-108 KDFs with short key lengths
Resolves: rhbz#2144019
- Add explicit indicator for HMAC with short key lengths
Resolves: rhbz#2144000
- Set minimum password length for PBKDF2 in FIPS mode
Resolves: rhbz#2144003
- Add explicit indicator for PSS salt length in FIPS mode
Resolves: rhbz#2144012
- Clamp default PSS salt length to digest size for FIPS 186-4 compliance
Related: rhbz#2144012
- Forbid short RSA keys for key encapsulation/decapsulation in FIPS mode
Resolves: rhbz#2145170
* Tue Nov 01 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-43
- CVE-2022-3602: X.509 Email Address Buffer Overflow
- CVE-2022-3786: X.509 Email Address Buffer Overflow
Resolves: CVE-2022-3602
* Wed Oct 26 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-42
- CVE-2022-3602: X.509 Email Address Buffer Overflow
Resolves: CVE-2022-3602
Resolves: CVE-2022-3602 (rhbz#2137723)
* Thu Aug 11 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-41
- Zeroize public keys as required by FIPS 140-3
Resolves: rhbz#2115861
Related: rhbz#2102542
- Add FIPS indicator for HKDF
Resolves: rhbz#2118388
Related: rhbz#2114772
* Fri Aug 05 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-40
- Deal with DH keys in FIPS mode according FIPS-140-3 requirements
Related: rhbz#2115856
Related: rhbz#2102536
- Deal with ECDH keys in FIPS mode according FIPS-140-3 requirements
Related: rhbz#2115857
Related: rhbz#2102537
- Use signature for RSA pairwise test according FIPS-140-3 requirements
Related: rhbz#2115858
Related: rhbz#2102540
- Reseed all the parent DRBGs in chain on reseeding a DRBG
Related: rhbz#2115859
- Zeroization according to FIPS-140-3 requirements
Related: rhbz#2115861
Related: rhbz#2102541
* Mon Aug 01 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-39
- Use RSA-OAEP in FIPS RSA encryption/decryption FIPS self-test
- Use Use digest_sign & digest_verify in FIPS signature self test
- Use FFDHE2048 in Diffie-Hellman FIPS self-test
Resolves: rhbz#2112978
Resolves: rhbz#2102535
* Thu Jul 14 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-38
- Fix segfault in EVP_PKEY_Q_keygen() when OpenSSL was not previously
initialized.
Resolves: rhbz#2107530
Resolves: rhbz#2103289
- Improve AES-GCM performance on Power9 and Power10 ppc64le
Resolves: rhbz#2103044
Resolves: rhbz#2051312
- Improve ChaCha20 performance on Power10 ppc64le
Resolves: rhbz#2103044
Resolves: rhbz#2051312
* Tue Jul 05 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-37
- CVE-2022-2097: AES OCB fails to encrypt some bytes on 32-bit x86
@ -541,122 +634,123 @@ install -m644 %{SOURCE9} \
* Thu Jun 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-36
- Ciphersuites with RSAPSK KX should be filterd in FIPS mode
- Related: rhbz#2091994
- Related: rhbz#2085088
- FIPS provider should block RSA encryption for key transport.
- Other RSA encryption options should still be available if key length is enough
- Related: rhbz#2091977
- Related: rhbz#2053289
- Improve diagnostics when passing unsupported groups in TLS
- Related: rhbz#2086554
- Related: rhbz#2070197
- Fix PPC64 Montgomery multiplication bug
- Related: rhbz#2101346
- Related: rhbz#2098199
- Strict certificates validation shouldn't allow explicit EC parameters
- Related: rhbz#2085521
- Related: rhbz#2058663
- CVE-2022-2068: the c_rehash script allows command injection
- Related: rhbz#2098276
- Related: rhbz#2098277
* Wed Jun 08 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-35
- Add explicit indicators for signatures in FIPS mode and mark signature
primitives as unapproved.
Resolves: rhbz#2087234
Resolves: rhbz#2087147
* Fri Jun 03 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-34
- Some OpenSSL test certificates are expired, updating
- Resolves: rhbz#2095696
- Resolves: rhbz#2092456
* Thu May 26 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-33
- CVE-2022-1473 openssl: OPENSSL_LH_flush() breaks reuse of memory
- Resolves: rhbz#2089443
- Resolves: rhbz#2089444
- CVE-2022-1343 openssl: Signer certificate verification returned
inaccurate response when using OCSP_NOCHECKS
- Resolves: rhbz#2089439
- Resolves: rhbz#2087911
- CVE-2022-1292 openssl: c_rehash script allows command injection
- Resolves: rhbz#2090361
- Resolves: rhbz#2090362
- Revert "Disable EVP_PKEY_sign/EVP_PKEY_verify in FIPS mode"
Related: rhbz#2087234
Related: rhbz#2087147
- Use KAT for ECDSA signature tests, s390 arch
- Resolves: rhbz#2086866
- Resolves: rhbz#2069235
* Thu May 19 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-32
- `openssl ecparam -list_curves` lists only FIPS-approved curves in FIPS mode
- Resolves: rhbz#2091929
- Resolves: rhbz#2083240
- Ciphersuites with RSA KX should be filterd in FIPS mode
- Related: rhbz#2091994
- Related: rhbz#2085088
- In FIPS mode, signature verification works with keys of arbitrary size
above 2048 bit, and only with 1024, 1280, 1536, 1792 bits for keys
below 2048 bits
- Resolves: rhbz#2091938
- Resolves: rhbz#2077884
* Wed May 18 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-31
- Disable SHA-1 signature verification in FIPS mode
- Disable EVP_PKEY_sign/EVP_PKEY_verify in FIPS mode
Resolves: rhbz#2087234
Resolves: rhbz#2087147
* Mon May 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-30
- Use KAT for ECDSA signature tests
- Resolves: rhbz#2086866
- Resolves: rhbz#2069235
* Thu May 12 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-29
- `-config` argument of openssl app should work properly in FIPS mode
- Resolves: rhbz#2085500
- Resolves: rhbz#2083274
- openssl req defaults on PKCS#8 encryption changed to AES-256-CBC
- Resolves: rhbz#2085499
- Resolves: rhbz#2063947
* Fri May 06 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-28
- OpenSSL should not accept custom elliptic curve parameters
- Resolves rhbz#2085508
- Resolves rhbz#2066412
- OpenSSL should not accept explicit curve parameters in FIPS mode
- Resolves rhbz#2085521
- Resolves rhbz#2058663
* Fri May 06 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-27
- Change FIPS module version to include hash of specfile, patches and sources
Resolves: rhbz#2082585
Resolves: rhbz#2070550
* Thu May 05 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-26
- OpenSSL FIPS module should not build in non-approved algorithms
Resolves: rhbz#2082584
- Resolves: rhbz#2081378
* Mon May 02 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-25
- FIPS provider should block RSA encryption for key transport.
- Other RSA encryption options should still be available
- Resolves: rhbz#2053289
* Mon May 02 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-24
- Fix occasional internal error in TLS when DHE is used
Resolves: rhbz#2080323
* Thu Apr 28 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-24
- Fix regression in evp_pkey_name2type caused by tr_TR locale fix
Resolves: rhbz#2071631
* Tue Apr 26 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-23
- Update missing initialization patch with feedback from upstream
Resolves: rhbz#2076654
* Wed Apr 20 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-23
- Fix openssl curl error with LANG=tr_TR.utf8
- Resolves: rhbz#2071631
* Fri Apr 22 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-22
- Invocation of the missing initialization
- Resolves: rhbz#2076654
* Mon Mar 28 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-22
- FIPS provider should block RSA encryption for key transport
- Resolves: rhbz#2053289
* Wed Apr 20 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-21
- Fix openssl curl error with LANG=tr_TR.utf8
- Resolves: rhbz#2076654
* Tue Mar 22 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-21
- Fix occasional internal error in TLS when DHE is used
- Resolves: rhbz#2004915
* Fri Mar 18 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-20
- Fix acceptance of SHA-1 certificates with rh-allow-sha1-signatures = yes when
no OpenSSL library context is set
- Resolves: rhbz#2063306
- Resolves: rhbz#2065400
* Fri Mar 18 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-19
- Fix TLS connections with SHA1 signatures if rh-allow-sha1-signatures = yes
- Resolves: rhbz#2063306
- Resolves: rhbz#2065400
* Wed Mar 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-18
- CVE-2022-0778 fix
- Resolves: rhbz#2062314
- Resolves: rhbz#2062315
* Thu Mar 10 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-15.1
* Thu Mar 10 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-17
- Fix invocation of EVP_PKEY_CTX_set_rsa_padding(RSA_PKCS1_PSS_PADDING) before
setting an allowed digest with EVP_PKEY_CTX_set_signature_md()
- Resolves: rhbz#2061607
- Skipping 3.0.1-16 due to version numbering confusion with the RHEL-9.0 branch
- Resolves: rhbz#2062640
* Tue Mar 01 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-14.1
* Tue Mar 01 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-15
- Allow SHA1 in SECLEVEL 2 if rh-allow-sha1-signatures = yes
- Resolves: rhbz#2031742
- Resolves: rhbz#2060510
* Fri Feb 25 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-14
- Prevent use of SHA1 with ECDSA

Loading…
Cancel
Save