Compare commits

..

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
43eec0cb49
!420 fix CVE-2024-13176
From: @jinlun123123 
Reviewed-by: @zcfsite 
Signed-off-by: @zcfsite
2025-02-07 07:03:12 +00:00
jinlun
9b7ddff21b fix CVE-2024-13176 2025-02-05 16:57:48 +08:00
openeuler-ci-bot
e4709ecf2d
!399 [sync] PR-395: fix CVE-2024-9143
From: @openeuler-sync-bot 
Reviewed-by: @zcfsite 
Signed-off-by: @zcfsite
2024-11-04 03:27:42 +00:00
liningjie
3152cefe6f fix CVE-2024-9143
(cherry picked from commit bfa7e6d7c81bc95655e70c87747aa15b723ee708)
2024-10-30 10:34:48 +08:00
openeuler-ci-bot
73157e1fa5
!386 fix openssl asan error
From: @hugel 
Reviewed-by: @zcfsite 
Signed-off-by: @zcfsite
2024-10-11 11:13:08 +00:00
hugel
5b0021e37c fix openssl asan error 2024-10-11 11:51:14 +08:00
openeuler-ci-bot
630edb3e03
!369 [sync] PR-368: fix CVE-2024-5535
From: @openeuler-sync-bot 
Reviewed-by: @jinlun123123, @zcfsite 
Signed-off-by: @zcfsite
2024-07-02 11:11:40 +00:00
jinlun
ccdf078d57 fix CVE-2024-5535
(cherry picked from commit 0e30541e80a802eea016714dbffe2b1c3c864310)
2024-07-02 10:39:28 +08:00
openeuler-ci-bot
b3899197ba
!353 fix CVE-2024-4741
From: @hzero1996 
Reviewed-by: @zcfsite 
Signed-off-by: @zcfsite
2024-06-04 01:19:22 +00:00
hzero1996
dd15fb080c fix CVE-2024-4741 2024-06-03 17:02:56 +08:00
9 changed files with 2754 additions and 1 deletions

View File

@ -0,0 +1,142 @@
From 751c6e6100726b7159eac4d7bd011cb1fb177263 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Wed, 15 Jan 2025 18:27:02 +0100
Subject: [PATCH] Fix timing side-channel in ECDSA signature computation
There is a timing signal of around 300 nanoseconds when the top word of
the inverted ECDSA nonce value is zero. This can happen with significant
probability only for some of the supported elliptic curves. In particular
the NIST P-521 curve is affected. To be able to measure this leak, the
attacker process must either be located in the same physical computer or
must have a very fast network connection with low latency.
Attacks on ECDSA nonce are also known as Minerva attack.
Fixes CVE-2024-13176
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/26429)
(cherry picked from commit 63c40a66c5dc287485705d06122d3a6e74a6a203)
---
crypto/bn/bn_exp.c | 23 ++++++++++++++++-------
crypto/ec/ec_lib.c | 8 ++++----
include/crypto/bn.h | 3 +++
include/openssl/bnerr.h | 1 +
4 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index 517e3c29fc..1f64f35cba 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -601,7 +601,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
* out by Colin Percival,
* http://www.daemonology.net/hyperthreading-considered-harmful/)
*/
-int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *in_mont)
{
@@ -618,12 +618,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned int t4 = 0;
#endif
- bn_check_top(a);
- bn_check_top(p);
- bn_check_top(m);
-
if (!BN_is_odd(m)) {
- BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);
+ BNerr(BN_F_BN_MOD_EXP_MONT_FIXED_TOP, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
@@ -1141,7 +1137,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
} else
#endif
- if (!BN_from_montgomery(rr, &tmp, mont, ctx))
+ if (!bn_from_mont_fixed_top(rr, &tmp, mont, ctx))
goto err;
ret = 1;
err:
@@ -1155,6 +1151,19 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
return ret;
}
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont)
+{
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+ if (!bn_mod_exp_mont_fixed_top(rr, a, p, m, ctx, in_mont))
+ return 0;
+ bn_correct_top(rr);
+ return 1;
+}
+
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 08db89fcee..9f0b480705 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -12,8 +12,8 @@
#include <openssl/err.h>
#include <openssl/opensslv.h>
-
#include "ec_local.h"
+#include "crypto/bn.h"
/* functions for EC_GROUP objects */
@@ -1155,10 +1155,10 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
if (!BN_sub(e, group->order, e))
goto err;
/*-
- * Exponent e is public.
- * No need for scatter-gather or BN_FLG_CONSTTIME.
+ * Although the exponent is public we want the result to be
+ * fixed top.
*/
- if (!BN_mod_exp_mont(r, x, e, group->order, ctx, group->mont_data))
+ if (!bn_mod_exp_mont_fixed_top(r, x, e, group->order, ctx, group->mont_data))
goto err;
ret = 1;
diff --git a/include/crypto/bn.h b/include/crypto/bn.h
index 250914c46a..8484047fd0 100644
--- a/include/crypto/bn.h
+++ b/include/crypto/bn.h
@@ -72,6 +72,9 @@ int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words);
*/
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_MONT_CTX *mont, BN_CTX *ctx);
+int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont);
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
BN_CTX *ctx);
int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
diff --git a/include/openssl/bnerr.h b/include/openssl/bnerr.h
index 5c83777f9f..f6aef13441 100644
--- a/include/openssl/bnerr.h
+++ b/include/openssl/bnerr.h
@@ -73,6 +73,7 @@ int ERR_load_BN_strings(void);
# define BN_F_BN_STACK_PUSH 148
# define BN_F_BN_USUB 115
# define BN_F_OSSL_BN_RSA_DO_UNBLIND 151
+# define BN_F_BN_MOD_EXP_MONT_FIXED_TOP 152
/*
* BN reason codes.
--
2.33.0

View File

@ -0,0 +1,71 @@
From b3f0eb0a295f58f16ba43ba99dad70d4ee5c437d Mon Sep 17 00:00:00 2001
From: Watson Ladd <watsonbladd@gmail.com>
Date: Wed, 24 Apr 2024 11:26:56 +0100
Subject: [PATCH] Only free the read buffers if we're not using them
If we're part way through processing a record, or the application has
not released all the records then we should not free our buffer because
they are still needed.
CVE-2024-4741
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24395)
(cherry picked from commit 704f725b96aa373ee45ecfb23f6abfe8be8d9177)
Reference:https://github.com/openssl/openssl/commit/b3f0eb0a295f58f16ba43ba99dad70d4ee5c437d
Conflict:NA
---
ssl/record/rec_layer_s3.c | 9 +++++++++
ssl/record/record.h | 1 +
ssl/ssl_lib.c | 3 +++
3 files changed, 13 insertions(+)
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 4bcffcc41e364..1569997bea2d3 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -81,6 +81,15 @@ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
}
+int RECORD_LAYER_data_present(const RECORD_LAYER *rl)
+{
+ if (rl->rstate == SSL_ST_READ_BODY)
+ return 1;
+ if (RECORD_LAYER_processed_read_pending(rl))
+ return 1;
+ return 0;
+}
+
/* Checks if we have decrypted unread record data pending */
int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl)
{
diff --git a/ssl/record/record.h b/ssl/record/record.h
index 234656bf93942..b60f71c8cb23b 100644
--- a/ssl/record/record.h
+++ b/ssl/record/record.h
@@ -205,6 +205,7 @@ void RECORD_LAYER_release(RECORD_LAYER *rl);
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl);
int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_data_present(const RECORD_LAYER *rl);
void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index eed649c6fdee9..d14c55ae557bc 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -5492,6 +5492,9 @@ int SSL_free_buffers(SSL *ssl)
if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl))
return 0;
+ if (RECORD_LAYER_data_present(rl))
+ return 0;
+
RECORD_LAYER_release(rl);
return 1;
}

View File

@ -0,0 +1,55 @@
From 5d0aba426b076094f74c5910a7e7bf7c0026148b Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Wed, 29 May 2024 16:17:48 +0800
Subject: [PATCH] Set rlayer.packet to NULL after we've finished using it
In order to ensure we do not have a UAF we reset the rlayer.packet pointer
to NULL after we free it.
CVE-2024-4741
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from #24395)
Reference:https://github.com/openssl/openssl/commit/2d05959073c4bf8803401668b9df85931a08e020
Conflict:Context Adaptation
(cherry picked from commit d146349)
---
ssl/record/rec_layer_s3.c | 6 ++++++
ssl/record/ssl3_buffer.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 81d20ad..71b0413 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -248,6 +248,12 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
/* ... now we can act as if 'extend' was set */
}
+ if (!ossl_assert(s->rlayer.packet != NULL)) {
+ /* does not happen */
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
len = s->rlayer.packet_length;
pkt = rb->buf + align;
/*
diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c
index fa597c2..b8b91d1 100644
--- a/ssl/record/ssl3_buffer.c
+++ b/ssl/record/ssl3_buffer.c
@@ -179,5 +179,7 @@ int ssl3_release_read_buffer(SSL *s)
b = RECORD_LAYER_get_rbuf(&s->rlayer);
OPENSSL_free(b->buf);
b->buf = NULL;
+ s->rlayer.packet = NULL;
+ s->rlayer.packet_length = 0;
return 1;
}
--
2.27.0

View File

@ -0,0 +1,262 @@
From 1d8c4ef6a90b87f3b516e9310a0e53bf1425a780 Mon Sep 17 00:00:00 2001
From: c30013472 <chengqguangqiang1@huawei.com>
Date: Wed, 29 May 2024 15:25:31 +0800
Subject: [PATCH] Fix possible use-after-free in SSL_free_buffers
Related to CVE-2024-4741
Reference:https://gitee.com/openeuler/openssl/commit/1d8c4ef6a90b87f3b516e9310a0e53bf1425a780
Conflict:rec_layer_s3.c,ssl3_buffer.c,ssl_lib.c
Signed-off-by: c30013472 <chengqguangqiang1@huawei.com>
---
test/sslbuffertest.c | 167 +++++++++++++++++++++++++++++++++++++-
test/ssltestlib.c | 25 ++++++
test/ssltestlib.h | 1 +
7 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/test/sslbuffertest.c b/test/sslbuffertest.c
index b5f815f7db..f57db36630 100644
--- a/test/sslbuffertest.c
+++ b/test/sslbuffertest.c
@@ -12,7 +12,7 @@
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
-
+#include <openssl/engine.h>
#include "../ssl/packet_local.h"
#include "ssltestlib.h"
@@ -157,6 +157,166 @@ int global_init(void)
return 1;
}
+/*
+ * Test that attempting to free the buffers at points where they cannot be freed
+ * works as expected
+ * Test 0: Attempt to free buffers after a full record has been processed, but
+ * the application has only performed a partial read
+ * Test 1: Attempt to free buffers after only a partial record header has been
+ * received
+ * Test 2: Attempt to free buffers after a full record header but no record body
+ * Test 3: Attempt to free buffers after a full record hedaer and partial record
+ * body
+ * Test 4-7: We repeat tests 0-3 but including data from a second pipelined
+ * record
+ */
+static int test_free_buffers(int test)
+{
+ int result = 0;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ const char testdata[] = "Test data";
+ char buf[120];
+ size_t written, readbytes;
+ int i, pipeline = test > 3;
+ ENGINE *e = NULL;
+
+ if (pipeline) {
+ e = load_dasync();
+ if (e == NULL)
+ goto end;
+ test -= 4;
+ }
+
+ if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ if (pipeline) {
+ if (!TEST_true(SSL_set_cipher_list(serverssl, "AES128-SHA"))
+ || !TEST_true(SSL_set_max_proto_version(serverssl,
+ TLS1_2_VERSION))
+ || !TEST_true(SSL_set_max_pipelines(serverssl, 2)))
+ goto end;
+ }
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+
+ /*
+ * For the non-pipeline case we write one record. For pipelining we write
+ * two records.
+ */
+ for (i = 0; i <= pipeline; i++) {
+ if (!TEST_true(SSL_write_ex(clientssl, testdata, strlen(testdata),
+ &written)))
+ goto end;
+ }
+
+ if (test == 0) {
+ size_t readlen = 1;
+
+ /*
+ * Deliberately only read the first byte - so the remaining bytes are
+ * still buffered. In the pipelining case we read as far as the first
+ * byte from the second record.
+ */
+ if (pipeline)
+ readlen += strlen(testdata);
+
+ if (!TEST_true(SSL_read_ex(serverssl, buf, readlen, &readbytes))
+ || !TEST_size_t_eq(readlen, readbytes))
+ goto end;
+ } else {
+ BIO *tmp;
+ size_t partial_len;
+
+ /* Remove all the data that is pending for read by the server */
+ tmp = SSL_get_rbio(serverssl);
+ if (!TEST_true(BIO_read_ex(tmp, buf, sizeof(buf), &readbytes))
+ || !TEST_size_t_lt(readbytes, sizeof(buf))
+ || !TEST_size_t_gt(readbytes, SSL3_RT_HEADER_LENGTH))
+ goto end;
+
+ switch(test) {
+ case 1:
+ partial_len = SSL3_RT_HEADER_LENGTH - 1;
+ break;
+ case 2:
+ partial_len = SSL3_RT_HEADER_LENGTH;
+ break;
+ case 3:
+ partial_len = readbytes - 1;
+ break;
+ default:
+ TEST_error("Invalid test index");
+ goto end;
+ }
+
+ if (pipeline) {
+ /* We happen to know the first record is 57 bytes long */
+ const size_t first_rec_len = 57;
+
+ if (test != 3)
+ partial_len += first_rec_len;
+
+ /*
+ * Sanity check. If we got the record len right then this should
+ * never fail.
+ */
+ if (!TEST_int_eq(buf[first_rec_len], SSL3_RT_APPLICATION_DATA))
+ goto end;
+ }
+ /*
+ * Put back just the partial record (plus the whole initial record in
+ * the pipelining case)
+ */
+ if (!TEST_true(BIO_write_ex(tmp, buf, partial_len, &written)))
+ goto end;
+
+ if (pipeline) {
+ /*
+ * Attempt a read. This should pass but only return data from the
+ * first record. Only a partial record is available for the second
+ * record.
+ */
+ if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf),
+ &readbytes))
+ || !TEST_size_t_eq(readbytes, strlen(testdata)))
+ goto end;
+ } else {
+ /*
+ * Attempt a read. This should fail because only a partial record is
+ * available.
+ */
+ if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
+ &readbytes)))
+ goto end;
+ }
+ }
+
+ /*
+ * Attempting to free the buffers at this point should fail because they are
+ * still in use
+ */
+ if (!TEST_false(SSL_free_buffers(serverssl)))
+ goto end;
+
+ result = 1;
+ end:
+ SSL_free(clientssl);
+ SSL_free(serverssl);
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+ if (e != NULL) {
+ ENGINE_unregister_ciphers(e);
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ }
+#endif
+ return result;
+}
+
int setup_tests(void)
{
char *cert, *pkey;
@@ -173,6 +333,11 @@ int setup_tests(void)
}
ADD_ALL_TESTS(test_func, 9);
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
+ ADD_ALL_TESTS(test_free_buffers, 8);
+#else
+ ADD_ALL_TESTS(test_free_buffers, 4);
+#endif
return 1;
}
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
index 422787b0f5..b1da6866c0 100644
--- a/test/ssltestlib.c
+++ b/test/ssltestlib.c
@@ -9,6 +9,7 @@
#include <string.h>
+#include <openssl/engine.h>
#include "internal/nelem.h"
#include "ssltestlib.h"
#include "testutil.h"
@@ -975,3 +976,27 @@ void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl)
SSL_free(serverssl);
SSL_free(clientssl);
}
+
+ENGINE *load_dasync(void)
+{
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
+ ENGINE *e;
+
+ if (!TEST_ptr(e = ENGINE_by_id("dasync")))
+ return NULL;
+
+ if (!TEST_true(ENGINE_init(e))) {
+ ENGINE_free(e);
+ return NULL;
+ }
+
+ if (!TEST_true(ENGINE_register_ciphers(e))) {
+ ENGINE_free(e);
+ return NULL;
+ }
+
+ return e;
+#else
+ return NULL;
+#endif
+}
diff --git a/test/ssltestlib.h b/test/ssltestlib.h
index 8f0a1b5308..38f97a8cbd 100644
--- a/test/ssltestlib.h
+++ b/test/ssltestlib.h
@@ -54,4 +54,5 @@ typedef struct mempacket_st MEMPACKET;
DEFINE_STACK_OF(MEMPACKET)
+ENGINE *load_dasync(void);
#endif /* OSSL_TEST_SSLTESTLIB_H */
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
From d7afe8e89ced1f4d5f1e5aab474dd9c069115b6e Mon Sep 17 00:00:00 2001
From: xuhuiyue <xuhuiyue@huawei.com>
Date: Fri, 28 Jun 2024 17:31:29 +0800
Subject: [PATCH 2/2] Fix SSL_select_next_proto and add ALPN validation in the
client
Fix CVE-2024-5535.
Signed-off-by: xuhuiyue <xuhuiyue@huawei.com>
---
ssl/ssl_lib.c | 63 +++++++++++++++++++++++-------------
ssl/statem/extensions_clnt.c | 27 +++++++++++++++-
ssl/statem/extensions_srvr.c | 3 +-
3 files changed, 68 insertions(+), 25 deletions(-)
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 00410a7385..cb2dca4247 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2767,37 +2767,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
unsigned int server_len,
const unsigned char *client, unsigned int client_len)
{
- unsigned int i, j;
- const unsigned char *result;
- int status = OPENSSL_NPN_UNSUPPORTED;
+ PACKET cpkt, csubpkt, spkt, ssubpkt;
+
+ if (!PACKET_buf_init(&cpkt, client, client_len)
+ || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt)
+ || PACKET_remaining(&csubpkt) == 0) {
+ *out = NULL;
+ *outlen = 0;
+ return OPENSSL_NPN_NO_OVERLAP;
+ }
+
+ /*
+ * Set the default opportunistic protocol. Will be overwritten if we find
+ * a match.
+ */
+ *out = (unsigned char *)PACKET_data(&csubpkt);
+ *outlen = (unsigned char)PACKET_remaining(&csubpkt);
/*
* For each protocol in server preference order, see if we support it.
*/
- for (i = 0; i < server_len;) {
- for (j = 0; j < client_len;) {
- if (server[i] == client[j] &&
- memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
- /* We found a match */
- result = &server[i];
- status = OPENSSL_NPN_NEGOTIATED;
- goto found;
+ if (PACKET_buf_init(&spkt, server, server_len)) {
+ while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) {
+ if (PACKET_remaining(&ssubpkt) == 0)
+ continue; /* Invalid - ignore it */
+ if (PACKET_buf_init(&cpkt, client, client_len)) {
+ while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) {
+ if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt),
+ PACKET_remaining(&ssubpkt))) {
+ /* We found a match */
+ *out = (unsigned char *)PACKET_data(&ssubpkt);
+ *outlen = (unsigned char)PACKET_remaining(&ssubpkt);
+ return OPENSSL_NPN_NEGOTIATED;
+ }
+ }
+ /* Ignore spurious trailing bytes in the client list */
+ } else {
+ /* This should never happen */
+ return OPENSSL_NPN_NO_OVERLAP;
}
- j += client[j];
- j++;
}
- i += server[i];
- i++;
+ /* Ignore spurious trailing bytes in the server list */
}
- /* There's no overlap between our protocols and the server's list. */
- result = client;
- status = OPENSSL_NPN_NO_OVERLAP;
-
- found:
- *out = (unsigned char *)result + 1;
- *outlen = result[0];
- return status;
+ /*
+ * There's no overlap between our protocols and the server's list. We use
+ * the default opportunistic protocol selected earlier
+ */
+ return OPENSSL_NPN_NO_OVERLAP;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index c641ae7351..4ad75c8e2d 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1602,7 +1602,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
PACKET_data(pkt),
PACKET_remaining(pkt),
s->ctx->ext.npn_select_cb_arg) !=
- SSL_TLSEXT_ERR_OK) {
+ SSL_TLSEXT_ERR_OK
+ || selected_len == 0) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_STOC_NPN,
SSL_R_BAD_EXTENSION);
return 0;
@@ -1633,6 +1634,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
size_t chainidx)
{
size_t len;
+ PACKET confpkt, protpkt;
+ int valid = 0;
/* We must have requested it. */
if (!s->s3->alpn_sent) {
@@ -1653,6 +1656,28 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
SSL_R_BAD_EXTENSION);
return 0;
}
+
+ /* It must be a protocol that we sent */
+ if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) {
+ if (PACKET_remaining(&protpkt) != len)
+ continue;
+ if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) {
+ /* Valid protocol found */
+ valid = 1;
+ break;
+ }
+ }
+
+ if (!valid) {
+ /* The protocol sent from the server does not match one we advertised */
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, SSL_R_BAD_EXTENSION);
+ return 0;
+ }
+
OPENSSL_free(s->s3->alpn_selected);
s->s3->alpn_selected = OPENSSL_malloc(len);
if (s->s3->alpn_selected == NULL) {
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 775d9a7444..a08027fd6d 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1562,9 +1562,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt,
return EXT_RETURN_FAIL;
}
s->s3->npn_seen = 1;
+ return EXT_RETURN_SENT;
}
- return EXT_RETURN_SENT;
+ return EXT_RETURN_NOT_SENT;
}
#endif
--
2.33.0

View File

@ -0,0 +1,201 @@
From 72ae83ad214d2eef262461365a1975707f862712 Mon Sep 17 00:00:00 2001
From: Viktor Dukhovni <viktor@openssl.org>
Date: Thu, 19 Sep 2024 01:02:40 +1000
Subject: [PATCH] Harden BN_GF2m_poly2arr against misuse.
The BN_GF2m_poly2arr() function converts characteristic-2 field
(GF_{2^m}) Galois polynomials from a representation as a BIGNUM bitmask,
to a compact array with just the exponents of the non-zero terms.
These polynomials are then used in BN_GF2m_mod_arr() to perform modular
reduction. A precondition of calling BN_GF2m_mod_arr() is that the
polynomial must have a non-zero constant term (i.e. the array has `0` as
its final element).
Internally, callers of BN_GF2m_poly2arr() did not verify that
precondition, and binary EC curve parameters with an invalid polynomial
could lead to out of bounds memory reads and writes in BN_GF2m_mod_arr().
The precondition is always true for polynomials that arise from the
standard form of EC parameters for characteristic-two fields (X9.62).
See the "Finite Field Identification" section of:
https://www.itu.int/ITU-T/formal-language/itu-t/x/x894/2018-cor1/ANSI-X9-62.html
The OpenSSL GF(2^m) code supports only the trinomial and pentanomial
basis X9.62 forms.
This commit updates BN_GF2m_poly2arr() to return `0` (failure) when
the constant term is zero (i.e. the input bitmask BIGNUM is not odd).
Additionally, the return value is made unambiguous when there is not
enough space to also pad the array with a final `-1` sentinel value.
The return value is now always the number of elements (including the
final `-1`) that would be filled when the output array is sufficiently
large. Previously the same count was returned both when the array has
just enough room for the final `-1` and when it had only enough space
for non-sentinel values.
Finally, BN_GF2m_poly2arr() is updated to reject polynomials whose
degree exceeds `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against
CPU exhausition attacks via excessively large inputs.
The above issues do not arise in processing X.509 certificates. These
generally have EC keys from "named curves", and RFC5840 (Section 2.1.1)
disallows explicit EC parameters. The TLS code in OpenSSL enforces this
constraint only after the certificate is decoded, but, even if explicit
parameters are specified, they are in X9.62 form, which cannot represent
problem values as noted above.
Initially reported as oss-fuzz issue 71623.
A closely related issue was earlier reported in
<https://github.com/openssl/openssl/issues/19826>.
Severity: Low, CVE-2024-9143
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25639)
(cherry picked from commit 8e008cb8b23ec7dc75c45a66eeed09c815b11cd2)
---
crypto/bn/bn_gf2m.c | 28 +++++++++++++++-------
test/ec_internal_test.c | 51 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index c811ae82d6..bcc66613cc 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -15,6 +15,7 @@
#include "bn_local.h"
#ifndef OPENSSL_NO_EC2M
+# include <openssl/ec.h>
/*
* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should
@@ -1140,16 +1141,26 @@ int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
/*
* Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i *
* x^i) into an array of integers corresponding to the bits with non-zero
- * coefficient. Array is terminated with -1. Up to max elements of the array
- * will be filled. Return value is total number of array elements that would
- * be filled if array was large enough.
+ * coefficient. The array is intended to be suitable for use with
+ * `BN_GF2m_mod_arr()`, and so the constant term of the polynomial must not be
+ * zero. This translates to a requirement that the input BIGNUM `a` is odd.
+ *
+ * Given sufficient room, the array is terminated with -1. Up to max elements
+ * of the array will be filled.
+ *
+ * The return value is total number of array elements that would be filled if
+ * array was large enough, including the terminating `-1`. It is `0` when `a`
+ * is not odd or the constant term is zero contrary to requirement.
+ *
+ * The return value is also `0` when the leading exponent exceeds
+ * `OPENSSL_ECC_MAX_FIELD_BITS`, this guards against CPU exhaustion attacks,
*/
int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
{
int i, j, k = 0;
BN_ULONG mask;
- if (BN_is_zero(a))
+ if (!BN_is_odd(a))
return 0;
for (i = a->top - 1; i >= 0; i--) {
@@ -1167,12 +1178,13 @@ int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
}
}
- if (k < max) {
+ if (k > 0 && p[0] > OPENSSL_ECC_MAX_FIELD_BITS)
+ return 0;
+
+ if (k < max)
p[k] = -1;
- k++;
- }
- return k;
+ return k + 1;
}
/*
diff --git a/test/ec_internal_test.c b/test/ec_internal_test.c
index 8c2cd05631..02cfd4e9d8 100644
--- a/test/ec_internal_test.c
+++ b/test/ec_internal_test.c
@@ -155,6 +155,56 @@ static int field_tests_ecp_mont(void)
}
#ifndef OPENSSL_NO_EC2M
+/* Test that decoding of invalid GF2m field parameters fails. */
+static int ec2m_field_sanity(void)
+{
+ int ret = 0;
+ BN_CTX *ctx = BN_CTX_new();
+ BIGNUM *p, *a, *b;
+ EC_GROUP *group1 = NULL, *group2 = NULL, *group3 = NULL;
+
+ TEST_info("Testing GF2m hardening\n");
+
+ BN_CTX_start(ctx);
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ if (!TEST_ptr(b = BN_CTX_get(ctx))
+ || !TEST_true(BN_one(a))
+ || !TEST_true(BN_one(b)))
+ goto out;
+
+ /* Even pentanomial value should be rejected */
+ if (!TEST_true(BN_set_word(p, 0xf2)))
+ goto out;
+ if (!TEST_ptr_null(group1 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
+ TEST_error("Zero constant term accepted in GF2m polynomial");
+
+ /* Odd hexanomial should also be rejected */
+ if (!TEST_true(BN_set_word(p, 0xf3)))
+ goto out;
+ if (!TEST_ptr_null(group2 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
+ TEST_error("Hexanomial accepted as GF2m polynomial");
+
+ /* Excessive polynomial degree should also be rejected */
+ if (!TEST_true(BN_set_word(p, 0x71))
+ || !TEST_true(BN_set_bit(p, OPENSSL_ECC_MAX_FIELD_BITS + 1)))
+ goto out;
+ if (!TEST_ptr_null(group3 = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
+ TEST_error("GF2m polynomial degree > %d accepted",
+ OPENSSL_ECC_MAX_FIELD_BITS);
+
+ ret = group1 == NULL && group2 == NULL && group3 == NULL;
+
+ out:
+ EC_GROUP_free(group1);
+ EC_GROUP_free(group2);
+ EC_GROUP_free(group3);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+
+ return ret;
+}
+
/* test EC_GF2m_simple_method directly */
static int field_tests_ec2_simple(void)
{
@@ -443,6 +493,7 @@ int setup_tests(void)
ADD_TEST(field_tests_ecp_simple);
ADD_TEST(field_tests_ecp_mont);
#ifndef OPENSSL_NO_EC2M
+ ADD_TEST(ec2m_field_sanity);
ADD_TEST(field_tests_ec2_simple);
#endif
ADD_ALL_TESTS(field_tests_default, crv_len);
--
2.43.0.windows.1

View File

@ -0,0 +1,45 @@
From df9c7ceefef59cc870c80346906471fabec62494 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 21 Oct 2022 14:08:29 +0100
Subject: [PATCH] Pipeline output/input buf arrays must live until the
EVP_Cipher is called
Conflict:adapt context
Reference:https://github.com/openssl/openssl/commit/df9c7ceefef59cc870c80346906471fabec62494
The pipeline input/output buf arrays must remain accessible to the
EVP_CIPHER_CTX until EVP_Cipher is subsequently called. This fixes an
asan error discovered by the newly added pipeline test.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20208)
---
ssl/record/ssl3_record.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 368aaea5e9..4256f29663 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -964,6 +964,7 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending,
EVP_CIPHER_CTX *ds;
size_t reclen[SSL_MAX_PIPELINES];
unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
+ unsigned char *data[SSL_MAX_PIPELINES];
int i, pad = 0, ret, tmpr;
size_t bs, mac_size = 0, ctr, padnum, loop;
unsigned char padval;
@@ -1123,8 +1124,6 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending,
}
}
if (n_recs > 1) {
- unsigned char *data[SSL_MAX_PIPELINES];
-
/* Set the output buffers */
for (ctr = 0; ctr < n_recs; ctr++) {
data[ctr] = recs[ctr].data;
--
2.33.0

View File

@ -2,7 +2,7 @@
Name: openssl
Epoch: 1
Version: 1.1.1wa
Release: 6
Release: 11
Summary: Cryptography and SSL/TLS Toolkit
License: OpenSSL and SSLeay
URL: https://gitee.com/openeuler/openssl
@ -20,6 +20,14 @@ Patch9: backport-Add-a-test-for-session-cache-handling.patch
Patch10: backport-Extend-the-multi_resume-test-for-simultaneous-resump.patch
Patch11: backport-Hardening-around-not_resumable-sessions.patch
Patch12: backport-Add-a-test-for-session-cache-overflow.patch
Patch13: backport-CVE-2024-4741-Only-free-the-read-buffer.patch
Patch14: backport-CVE-2024-4741-Set-rlayer.packet-to-NULL-after-we-ve-.patch
Patch15: backport-CVE-2024-4741-test-Fix-possible-use-after-free.patch
Patch16: backport-CVE-2024-5535-Fix-SSL_select_next_proto-and-add-ALPN.patch
Patch17: backport-CVE-2024-5535-Add-a-test-for-ALPN-and-NPN.patch
Patch18: backport-Pipeline-output-input-buf-arrays-must-live-until-the.patch
Patch19: backport-CVE-2024-9143-Harden-BN_GF2m_poly2arr-against-misuse.patch
Patch20: backport-CVE-2024-13176-Fix-timing-side-channel.patch
BuildRequires: gcc perl make lksctp-tools-devel coreutils util-linux zlib-devel
Requires: coreutils %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
@ -228,6 +236,21 @@ make test || :
%ldconfig_scriptlets libs
%changelog
* Wed Feb 5 2025 jinlun <jinlun@huawei.comi> - 1:1.1.1wa-11
- fix CVE-2024-13176
* Mon Oct 28 2024 liningjie <liningjie@xfusion.com> - 1:1.1.1wa-10
- fix CVE-2024-9143
* Fri Oct 11 2024 hugel <gengqihu2@h-partners.com> - 1:1.1.1wa-9
- fix openssl asan error
* Sat Jun 29 2024 jinlun <jinlun@huawei.comi> - 1:1.1.1wa-8
- fix CVE-2024-5535
* Mon Jun 3 2024 wangcheng <wangcheng156@huawei.com> - 1:1.1.1wa-7
- fix CVE-2024-4741
* Wed Apr 17 2024 fuanan <fuanan3@h-partners.com> - 1:1.1.1wa-6
- fix CVE-2024-2511