Fix CVE-2023-6237、CVE-2024-2511

Signed-off-by: ShenYage <shenyage1@huawei.com>
(cherry picked from commit 591443e21eac71b083d7910220c4102648987009)
This commit is contained in:
ShenYage 2024-04-15 20:06:51 +08:00 committed by openeuler-sync-bot
parent d82d34597a
commit d411de33f5
7 changed files with 764 additions and 1 deletions

View File

@ -0,0 +1,133 @@
From 380d1ef504e3dae8f6b44a345f0fc800d783b9ac Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 4 Mar 2024 13:45:23 +0000
Subject: [PATCH 1/5] Add a test for session cache handling
Repeatedly create sessions to be added to the cache and ensure we never
exceed the expected size.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24042)
reference: https://github.com/openssl/openssl/pull/24042
Signed-off-by: shenyage <shenyage1@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 3d57101..8ed3524 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -10303,6 +10303,97 @@ end:
}
#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */
+/*
+ * Test multiple resumptions and cache size handling
+ * Test 0: TLSv1.3 (max_early_data set)
+ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
+ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
+ * Test 3: TLSv1.2
+ */
+static int test_multi_resume(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ SSL_SESSION *sess = NULL;
+ int max_version = TLS1_3_VERSION;
+ int i, testresult = 0;
+
+ if (idx == 3)
+ max_version = TLS1_2_VERSION;
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), TLS1_VERSION,
+ max_version, &sctx, &cctx, cert,
+ privkey)))
+ goto end;
+
+ /*
+ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for
+ * replay protection), or if SSL_OP_NO_TICKET is in use
+ */
+ if (idx == 0 || idx == 2) {
+ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
+ goto end;
+ }
+ if (idx == 1 || idx == 2)
+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
+
+ SSL_CTX_sess_set_cache_size(sctx, 5);
+
+ for (i = 0; i < 30; i++) {
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ /*
+ * Recreate a bug where dynamically changing the max_early_data value
+ * can cause sessions in the session cache which cannot be deleted.
+ */
+ if ((idx == 0 || idx == 2) && (i % 3) == 2)
+ SSL_set_max_early_data(serverssl, 0);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (sess == NULL || (idx == 0 && (i % 3) == 2)) {
+ if (!TEST_false(SSL_session_reused(clientssl)))
+ goto end;
+ } else {
+ if (!TEST_true(SSL_session_reused(clientssl)))
+ goto end;
+ }
+ SSL_SESSION_free(sess);
+
+ /* Do a full handshake, followed by two resumptions */
+ if ((i % 3) == 2) {
+ sess = NULL;
+ } else {
+ if (!TEST_ptr((sess = SSL_get1_session(clientssl))))
+ goto end;
+ }
+
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+ }
+
+ /* We should never exceed the session cache size limit */
+ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5))
+ goto end;
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(sess);
+ return testresult;
+}
+
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
int setup_tests(void)
@@ -10574,6 +10665,7 @@ int setup_tests(void)
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
ADD_ALL_TESTS(test_pipelining, 6);
#endif
+ ADD_ALL_TESTS(test_multi_resume, 4);
return 1;
err:
--
2.33.0

View File

@ -0,0 +1,160 @@
From 4023a42e26e3c476c6989e2c5bf2db08937e0df8 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 5 Mar 2024 15:35:51 +0000
Subject: [PATCH 2/5] Extend the multi_resume test for simultaneous resumptions
Test what happens if the same session gets resumed multiple times at the
same time - and one of them gets marked as not_resumable.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24042)
reference: https://github.com/openssl/openssl/pull/24042
Signed-off-by: shenyage <shenyage1@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 88 ++++++++++++++++++-
1 file changed, 84 insertions(+), 4 deletions(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 8ed3524..0529793 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -10303,12 +10303,62 @@ end:
}
#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */
+struct resume_servername_cb_data {
+ int i;
+ SSL_CTX *cctx;
+ SSL_CTX *sctx;
+ SSL_SESSION *sess;
+ int recurse;
+};
+
+/*
+ * Servername callback. We use it here to run another complete handshake using
+ * the same session - and mark the session as not_resuamble at the end
+ */
+static int resume_servername_cb(SSL *s, int *ad, void *arg)
+{
+ struct resume_servername_cb_data *cbdata = arg;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if (cbdata->recurse)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if ((cbdata->i % 3) != 1)
+ return SSL_TLSEXT_ERR_OK;
+
+ cbdata->recurse = 1;
+
+ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl,
+ &clientssl, NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, cbdata->sess)))
+ goto end;
+
+ ERR_set_mark();
+ /*
+ * We expect this to fail - because the servername cb will fail. This will
+ * mark the session as not_resumable.
+ */
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
+ ERR_clear_last_mark();
+ goto end;
+ }
+ ERR_pop_to_mark();
+
+ ret = SSL_TLSEXT_ERR_OK;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ cbdata->recurse = 0;
+ return ret;
+}
/*
* Test multiple resumptions and cache size handling
* Test 0: TLSv1.3 (max_early_data set)
* Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
* Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
- * Test 3: TLSv1.2
+ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes)
+ * Test 4: TLSv1.2
*/
static int test_multi_resume(int idx)
{
@@ -10317,9 +10367,19 @@ static int test_multi_resume(int idx)
SSL_SESSION *sess = NULL;
int max_version = TLS1_3_VERSION;
int i, testresult = 0;
+ struct resume_servername_cb_data cbdata;
- if (idx == 3)
+#if defined(OPENSSL_NO_TLS1_2)
+ if (idx == 4)
+ return TEST_skip("TLSv1.2 is disabled in this build");
+#else
+ if (idx == 4)
max_version = TLS1_2_VERSION;
+#endif
+#if defined(OSSL_NO_USABLE_TLS1_3)
+ if (idx != 4)
+ return TEST_skip("No usable TLSv1.3 in this build");
+#endif
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
TLS_client_method(), TLS1_VERSION,
@@ -10335,17 +10395,37 @@ static int test_multi_resume(int idx)
if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
goto end;
}
- if (idx == 1 || idx == 2)
+ if (idx == 1 || idx == 2 || idx == 3)
SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
SSL_CTX_sess_set_cache_size(sctx, 5);
+ if (idx == 3) {
+ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata);
+ cbdata.cctx = cctx;
+ cbdata.sctx = sctx;
+ cbdata.recurse = 0;
+ }
+
for (i = 0; i < 30; i++) {
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL))
|| !TEST_true(SSL_set_session(clientssl, sess)))
goto end;
+ /*
+ * Check simultaneous resumes. We pause the connection part way through
+ * the handshake by (mis)using the servername_cb. The pause occurs after
+ * session resumption has already occurred, but before any session
+ * tickets have been issued. While paused we run another complete
+ * handshake resuming the same session.
+ */
+ if (idx == 3) {
+ cbdata.i = i;
+ cbdata.sess = sess;
+ }
+
/*
* Recreate a bug where dynamically changing the max_early_data value
* can cause sessions in the session cache which cannot be deleted.
@@ -10665,7 +10745,7 @@ int setup_tests(void)
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
ADD_ALL_TESTS(test_pipelining, 6);
#endif
- ADD_ALL_TESTS(test_multi_resume, 4);
+ ADD_ALL_TESTS(test_multi_resume, 5);
return 1;
err:
--
2.33.0

View File

@ -0,0 +1,122 @@
From ff3df21663344b334aa2a06a3e83cb3a2552f072 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 5 Mar 2024 15:43:53 +0000
Subject: [PATCH 3/5] Fix unconstrained session cache growth in TLSv1.3
In TLSv1.3 we create a new session object for each ticket that we send.
We do this by duplicating the original session. If SSL_OP_NO_TICKET is in
use then the new session will be added to the session cache. However, if
early data is not in use (and therefore anti-replay protection is being
used), then multiple threads could be resuming from the same session
simultaneously. If this happens and a problem occurs on one of the threads,
then the original session object could be marked as not_resumable. When we
duplicate the session object this not_resumable status gets copied into the
new session object. The new session object is then added to the session
cache even though it is not_resumable.
Subsequently, another bug means that the session_id_length is set to 0 for
sessions that are marked as not_resumable - even though that session is
still in the cache. Once this happens the session can never be removed from
the cache. When that object gets to be the session cache tail object the
cache never shrinks again and grows indefinitely.
CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24042)
reference: https://github.com/openssl/openssl/pull/24042
Signed-off-by: shenyage <shenyage1@huawei.com>
---
.../Library/OpensslLib/openssl/ssl/ssl_lib.c | 5 ++--
.../Library/OpensslLib/openssl/ssl/ssl_sess.c | 28 +++++++++++++++----
.../openssl/ssl/statem/statem_srvr.c | 5 ++--
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
index 214884b..35420eb 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
@@ -3717,9 +3717,10 @@ void ssl_update_cache(SSL *s, int mode)
/*
* If the session_id_length is 0, we are not supposed to cache it, and it
- * would be rather hard to do anyway :-)
+ * would be rather hard to do anyway :-). Also if the session has already
+ * been marked as not_resumable we should not cache it for later reuse.
*/
- if (s->session->session_id_length == 0)
+ if (s->session->session_id_length == 0 || s->session->not_resumable)
return;
/*
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
index c322a11..8f2f37b 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
@@ -152,16 +152,11 @@ SSL_SESSION *SSL_SESSION_new(void)
return ss;
}
-SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
-{
- return ssl_session_dup(src, 1);
-}
-
/*
* Create a new SSL_SESSION and duplicate the contents of |src| into it. If
* ticket == 0 then no ticket information is duplicated, otherwise it is.
*/
-SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
+static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
{
SSL_SESSION *dest;
@@ -282,6 +277,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
return NULL;
}
+SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
+{
+ return ssl_session_dup_intern(src, 1);
+}
+
+/*
+ * Used internally when duplicating a session which might be already shared.
+ * We will have resumed the original session. Subsequently we might have marked
+ * it as non-resumable (e.g. in another thread) - but this copy should be ok to
+ * resume from.
+ */
+SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);
+
+ if (sess != NULL)
+ sess->not_resumable = 0;
+
+ return sess;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if (len)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
index a9e67f9..70c1893 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
@@ -2338,9 +2338,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
* so the following won't overwrite an ID that we're supposed
* to send back.
*/
- if (s->session->not_resumable ||
- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
- && !s->hit))
+ if (!(SSL_CONNECTION_GET_CTX(s)->session_cache_mode & SSL_SESS_CACHE_SERVER)
+ && !s->hit)
s->session->session_id_length = 0;
if (usetls13) {
--
2.33.0

View File

@ -0,0 +1,39 @@
From c44d5f799061ed8d7174c58e0cef0e43bda185be Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 15 Mar 2024 17:58:42 +0000
Subject: [PATCH 4/5] Hardening around not_resumable sessions
Make sure we can't inadvertently use a not_resumable session
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24042)
reference: https://github.com/openssl/openssl/pull/24042
Signed-off-by: shenyage <shenyage1@huawei.com>
---
CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
index 8f2f37b..46f4f75 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
@@ -528,6 +528,12 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, &copy);
if (ret != NULL) {
+ if (ret->not_resumable) {
+ /* If its not resumable then ignore this session */
+ if (!copy)
+ SSL_SESSION_free(ret);
+ return NULL;
+ }
ssl_tsan_counter(s->session_ctx,
&s->session_ctx->stats.sess_cb_hit);
--
2.33.0

View File

@ -0,0 +1,172 @@
From 3ce388a7ea5c1e53dd10ea7d083f8de5c21adb54 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 15 Jul 2022 13:26:33 +0100
Subject: [PATCH 5/5] Add a test for session cache overflow
Test sessions behave as we expect even in the case that an overflow
occurs when adding a new session into the session cache.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24042)
reference: https://github.com/openssl/openssl/pull/24042
Signed-off-by: shenyage <shenyage1@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 124 +++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 0529793..a8eed30 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -2386,7 +2386,6 @@ static int test_session_wo_ca_names(void)
#endif
}
-
#ifndef OSSL_NO_USABLE_TLS1_3
static SSL_SESSION *sesscache[6];
static int do_cache;
@@ -8938,6 +8937,126 @@ static int test_session_timeout(int test)
return testresult;
}
+/*
+ * Test that a session cache overflow works as expected
+ * Test 0: TLSv1.3, timeout on new session later than old session
+ * Test 1: TLSv1.2, timeout on new session later than old session
+ * Test 2: TLSv1.3, timeout on new session earlier than old session
+ * Test 3: TLSv1.2, timeout on new session earlier than old session
+ */
+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
+static int test_session_cache_overflow(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+ SSL_SESSION *sess = NULL;
+
+#ifdef OSSL_NO_USABLE_TLS1_3
+ /* If no TLSv1.3 available then do nothing in this case */
+ if (idx % 2 == 0)
+ return TEST_skip("No TLSv1.3 available");
+#endif
+#ifdef OPENSSL_NO_TLS1_2
+ /* If no TLSv1.2 available then do nothing in this case */
+ if (idx % 2 == 1)
+ return TEST_skip("No TLSv1.2 available");
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), TLS1_VERSION,
+ (idx % 2 == 0) ? TLS1_3_VERSION
+ : TLS1_2_VERSION,
+ &sctx, &cctx, cert, privkey))
+ || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET)))
+ goto end;
+
+ SSL_CTX_sess_set_get_cb(sctx, get_session_cb);
+ get_sess_val = NULL;
+
+ SSL_CTX_sess_set_cache_size(sctx, 1);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (idx > 1) {
+ sess = SSL_get_session(serverssl);
+ if (!TEST_ptr(sess))
+ goto end;
+
+ /*
+ * Cause this session to have a longer timeout than the next session to
+ * be added.
+ */
+ if (!TEST_true(SSL_SESSION_set_timeout(sess, LONG_MAX))) {
+ sess = NULL;
+ goto end;
+ }
+ sess = NULL;
+ }
+
+ SSL_shutdown(serverssl);
+ SSL_shutdown(clientssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+
+ /*
+ * Session cache size is 1 and we already populated the cache with a session
+ * so the next connection should cause an overflow.
+ */
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ /*
+ * The session we just negotiated may have been already removed from the
+ * internal cache - but we will return it anyway from our external cache.
+ */
+ get_sess_val = SSL_get_session(serverssl);
+ if (!TEST_ptr(get_sess_val))
+ goto end;
+ sess = SSL_get1_session(clientssl);
+ if (!TEST_ptr(sess))
+ goto end;
+
+ SSL_shutdown(serverssl);
+ SSL_shutdown(clientssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(sess);
+
+ return testresult;
+}
+#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */
+
/*
* Test 0: Client sets servername and server acknowledges it (TLSv1.2)
* Test 1: Client sets servername and server does not acknowledge it (TLSv1.2)
@@ -10738,6 +10857,9 @@ int setup_tests(void)
ADD_TEST(test_set_verify_cert_store_ssl_ctx);
ADD_TEST(test_set_verify_cert_store_ssl);
ADD_ALL_TESTS(test_session_timeout, 1);
+#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
+ ADD_ALL_TESTS(test_session_cache_overflow, 4);
+#endif
ADD_TEST(test_load_dhfile);
#if !defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3)
ADD_ALL_TESTS(test_serverinfo_custom, 4);
--
2.33.0

View File

@ -0,0 +1,126 @@
From 02ec2aa154d26f078e9457998cd2e64b05b35b53 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Fri, 22 Dec 2023 16:25:56 +0100
Subject: [PATCH] Limit the execution time of RSA public key check
Fixes CVE-2023-6237
If a large and incorrect RSA public key is checked with
EVP_PKEY_public_check() the computation could take very long time
due to no limit being applied to the RSA public key size and
unnecessarily high number of Miller-Rabin algorithm rounds
used for non-primality check of the modulus.
Now the keys larger than 16384 bits (OPENSSL_RSA_MAX_MODULUS_BITS)
will fail the check with RSA_R_MODULUS_TOO_LARGE error reason.
Also the number of Miller-Rabin rounds was set to 5.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23243)
reference: https://github.com/openssl/openssl/pull/23243
Signed-off-by: ShenYage <shenyage1@huawei.com>
---
.../openssl/crypto/rsa/rsa_sp800_56b_check.c | 8 +++-
.../openssl/test/recipes/91-test_pkey_check.t | 2 +-
.../91-test_pkey_check_data/rsapub_17k.pem | 48 +++++++++++++++++++
3 files changed, 56 insertions(+), 2 deletions(-)
create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem
diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c
index fc8f19b..bcbdd24 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sp800_56b_check.c
@@ -289,6 +289,11 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
return 0;
nbits = BN_num_bits(rsa->n);
+ if (nbits > OPENSSL_RSA_MAX_MODULUS_BITS) {
+ ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE);
+ return 0;
+ }
+
#ifdef FIPS_MODULE
/*
* (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1)
@@ -324,7 +329,8 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
goto err;
}
- ret = ossl_bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status);
+ /* Highest number of MR rounds from FIPS 186-5 Section B.3 Table B.1 */
+ ret = ossl_bn_miller_rabin_is_prime(rsa->n, 5, ctx, NULL, 1, &status);
#ifdef FIPS_MODULE
if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) {
#else
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t
index dc7cc64..f8088df 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check.t
@@ -70,7 +70,7 @@ push(@positive_tests, (
"dhpkey.pem"
)) unless disabled("dh");
-my @negative_pubtests = ();
+my @negative_pubtests = ("rsapub_17k.pem"); # Too big RSA public key
push(@negative_pubtests, (
"dsapub_noparam.der"
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem
new file mode 100644
index 0000000..9a2eaed
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/recipes/91-test_pkey_check_data/rsapub_17k.pem
@@ -0,0 +1,48 @@
+-----BEGIN PUBLIC KEY-----
+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
+AQAB
+-----END PUBLIC KEY-----
--
2.33.0

View File

@ -7,7 +7,7 @@
Name: edk2
Version: %{stable_date}
Release: 5
Release: 6
Summary: EFI Development Kit II
License: BSD-2-Clause-Patent and OpenSSL and MIT
URL: https://github.com/tianocore/edk2
@ -61,6 +61,14 @@ patch37: 0037-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch
patch38: 0038-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch
patch39: 0039-NetworkPkg-Updating-SecurityFixes.yaml.patch
# Fix CVE-2023-6237、CVE-2024-2511
patch40: 0040-Add-a-test-for-session-cache-handling.patch
patch41: 0041-Extend-the-multi_resume-test-for-simultaneous-resump.patch
patch42: 0042-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch
patch43: 0043-Hardening-around-not_resumable-sessions.patch
patch44: 0044-Add-a-test-for-session-cache-overflow.patch
patch45: 0045-Limit-the-execution-time-of-RSA-public-key-check.patch
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
%description
@ -297,6 +305,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
%endif
%changelog
* Mon Apr 15 2024 shenyage<shenyage1@huawei.com> - 202308-6
- fix CVE-2023-6237、CVE-2024-2511
* Thu Mar 7 2024 yexiao<yexiao7@huawei.com> - 202308-5
- fix CVE-2023-45229、CVE-2023-45230、CVE-2023-45231、CVE-2023-45232、CVE-2023-45233、CVE-2023-45234、CVE-2023-45235