mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-06-14 05:49:57 +00:00
iperf3: Fix CVE-2024-26306
iPerf3 before 3.17, when used with OpenSSL before 3.2.0 as a server with RSA authentication, allows a timing side channel in RSA decryption operations. This side channel could be sufficient for an attacker to recover credential plaintext. It requires the attacker to send a large number of messages for decryption, as described in "Everlasting ROBOT: the Marvin Attack" by Hubert Kario. References: https://nvd.nist.gov/vuln/detail/CVE-2024-26306 https://security-tracker.debian.org/tracker/CVE-2024-26306 Upstream patch: https://github.com/esnet/iperf/commit/299b356df6939f71619bf45bf7a7d2222e17d840 Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
This commit is contained in:
committed by
Gyorgy Sarvari
parent
0a0ba8f467
commit
b8333d7c6f
@@ -0,0 +1,218 @@
|
||||
From 299b356df6939f71619bf45bf7a7d2222e17d840 Mon Sep 17 00:00:00 2001
|
||||
From: Sarah Larsen <swlarsen@Sarahs-MBP.lan>
|
||||
Date: Wed, 20 Mar 2024 17:02:31 -0700
|
||||
Subject: [PATCH] Using OAEP padding instead of PKCS1 padding for OpenSSL. Fix
|
||||
for CVE-2024-26306.
|
||||
|
||||
Special thanks to Hubert Kario at Red Hat for finding the vulnerability.
|
||||
|
||||
CVE: CVE-2024-26306
|
||||
|
||||
Upstream-Status: Backport [https://github.com/esnet/iperf/commit/299b356df6939f71619bf45bf7a7d2222e17d840]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
src/iperf.h | 1 +
|
||||
src/iperf_api.c | 8 ++++++--
|
||||
src/iperf_api.h | 1 +
|
||||
src/iperf_auth.c | 26 ++++++++++++++++++--------
|
||||
src/iperf_auth.h | 4 ++--
|
||||
src/iperf_locale.c | 1 +
|
||||
src/t_auth.c | 5 +++--
|
||||
7 files changed, 32 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/iperf.h b/src/iperf.h
|
||||
index c3ce333..ae3feeb 100644
|
||||
--- a/src/iperf.h
|
||||
+++ b/src/iperf.h
|
||||
@@ -308,6 +308,7 @@ struct iperf_test
|
||||
char *server_authorized_users;
|
||||
EVP_PKEY *server_rsa_private_key;
|
||||
int server_skew_threshold;
|
||||
+ int use_pkcs1_padding;
|
||||
#endif // HAVE_SSL
|
||||
|
||||
/* boolean variables for Options */
|
||||
diff --git a/src/iperf_api.c b/src/iperf_api.c
|
||||
index a95e024..3915884 100644
|
||||
--- a/src/iperf_api.c
|
||||
+++ b/src/iperf_api.c
|
||||
@@ -1097,6 +1097,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||
{"rsa-private-key-path", required_argument, NULL, OPT_SERVER_RSA_PRIVATE_KEY},
|
||||
{"authorized-users-path", required_argument, NULL, OPT_SERVER_AUTHORIZED_USERS},
|
||||
{"time-skew-threshold", required_argument, NULL, OPT_SERVER_SKEW_THRESHOLD},
|
||||
+ {"use-pkcs1-padding", no_argument, NULL, OPT_USE_PKCS1_PADDING},
|
||||
#endif /* HAVE_SSL */
|
||||
{"fq-rate", required_argument, NULL, OPT_FQ_RATE},
|
||||
{"pacing-timer", required_argument, NULL, OPT_PACING_TIMER},
|
||||
@@ -1585,6 +1586,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
+ case OPT_USE_PKCS1_PADDING:
|
||||
+ test->use_pkcs1_padding = 1;
|
||||
+ break;
|
||||
#endif /* HAVE_SSL */
|
||||
case OPT_PACING_TIMER:
|
||||
test->settings->pacing_timer = unit_atoi(optarg);
|
||||
@@ -2026,7 +2030,7 @@ int test_is_authorized(struct iperf_test *test){
|
||||
if (test->settings->authtoken){
|
||||
char *username = NULL, *password = NULL;
|
||||
time_t ts;
|
||||
- int rc = decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts);
|
||||
+ int rc = decode_auth_setting(test->debug, test->settings->authtoken, test->server_rsa_private_key, &username, &password, &ts, test->use_pkcs1_padding);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
@@ -2211,7 +2215,7 @@ send_parameters(struct iperf_test *test)
|
||||
#if defined(HAVE_SSL)
|
||||
/* Send authentication parameters */
|
||||
if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){
|
||||
- int rc = encode_auth_setting(test->settings->client_username, test->settings->client_password, test->settings->client_rsa_pubkey, &test->settings->authtoken);
|
||||
+ int rc = encode_auth_setting(test->settings->client_username, test->settings->client_password, test->settings->client_rsa_pubkey, &test->settings->authtoken, test->use_pkcs1_padding);
|
||||
|
||||
if (rc) {
|
||||
cJSON_Delete(j);
|
||||
diff --git a/src/iperf_api.h b/src/iperf_api.h
|
||||
index 171006a..052bc96 100644
|
||||
--- a/src/iperf_api.h
|
||||
+++ b/src/iperf_api.h
|
||||
@@ -90,6 +90,7 @@ typedef uint64_t iperf_size_t;
|
||||
#define OPT_DONT_FRAGMENT 26
|
||||
#define OPT_RCV_TIMEOUT 27
|
||||
#define OPT_SND_TIMEOUT 28
|
||||
+#define OPT_USE_PKCS1_PADDING 30
|
||||
|
||||
/* states */
|
||||
#define TEST_START 1
|
||||
diff --git a/src/iperf_auth.c b/src/iperf_auth.c
|
||||
index 595f730..db48bbf 100644
|
||||
--- a/src/iperf_auth.c
|
||||
+++ b/src/iperf_auth.c
|
||||
@@ -226,7 +226,7 @@ int test_load_private_key_from_file(const char *file){
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned char **encryptedtext) {
|
||||
+int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned char **encryptedtext, int use_pkcs1_padding) {
|
||||
RSA *rsa = NULL;
|
||||
unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
|
||||
int keysize, encryptedtext_len, rsa_buffer_len;
|
||||
@@ -239,7 +239,12 @@ int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned ch
|
||||
|
||||
BIO *bioBuff = BIO_new_mem_buf((void*)plaintext, (int)strlen(plaintext));
|
||||
rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
|
||||
- encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, pad);
|
||||
+
|
||||
+ int padding = RSA_PKCS1_OAEP_PADDING;
|
||||
+ if (use_pkcs1_padding){
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ }
|
||||
+ encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, padding);
|
||||
|
||||
RSA_free(rsa);
|
||||
OPENSSL_free(rsa_buffer);
|
||||
@@ -253,7 +258,7 @@ int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned ch
|
||||
return encryptedtext_len;
|
||||
}
|
||||
|
||||
-int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, EVP_PKEY *private_key, unsigned char **plaintext) {
|
||||
+int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, EVP_PKEY *private_key, unsigned char **plaintext, int use_pkcs1_padding) {
|
||||
RSA *rsa = NULL;
|
||||
unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
|
||||
int plaintext_len, rsa_buffer_len, keysize;
|
||||
@@ -267,7 +272,12 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt
|
||||
|
||||
BIO *bioBuff = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len);
|
||||
rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
|
||||
- plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, pad);
|
||||
+
|
||||
+ int padding = RSA_PKCS1_OAEP_PADDING;
|
||||
+ if (use_pkcs1_padding){
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ }
|
||||
+ plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, padding);
|
||||
|
||||
RSA_free(rsa);
|
||||
OPENSSL_free(rsa_buffer);
|
||||
@@ -281,7 +291,7 @@ int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedt
|
||||
return plaintext_len;
|
||||
}
|
||||
|
||||
-int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken){
|
||||
+int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken, int use_pkcs1_padding){
|
||||
time_t t = time(NULL);
|
||||
time_t utc_seconds = mktime(localtime(&t));
|
||||
|
||||
@@ -298,7 +308,7 @@ int encode_auth_setting(const char *username, const char *password, EVP_PKEY *pu
|
||||
|
||||
unsigned char *encrypted = NULL;
|
||||
int encrypted_len;
|
||||
- encrypted_len = encrypt_rsa_message(text, public_key, &encrypted);
|
||||
+ encrypted_len = encrypt_rsa_message(text, public_key, &encrypted, use_pkcs1_padding);
|
||||
free(text);
|
||||
if (encrypted_len < 0) {
|
||||
return -1;
|
||||
@@ -309,7 +319,7 @@ int encode_auth_setting(const char *username, const char *password, EVP_PKEY *pu
|
||||
return (0); //success
|
||||
}
|
||||
|
||||
-int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts){
|
||||
+int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts, int use_pkcs1_padding){
|
||||
unsigned char *encrypted_b64 = NULL;
|
||||
size_t encrypted_len_b64;
|
||||
int64_t utc_seconds;
|
||||
@@ -317,7 +327,7 @@ int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *priva
|
||||
|
||||
unsigned char *plaintext = NULL;
|
||||
int plaintext_len;
|
||||
- plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext);
|
||||
+ plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext, use_pkcs1_padding);
|
||||
free(encrypted_b64);
|
||||
if (plaintext_len <= 0) {
|
||||
return -1;
|
||||
diff --git a/src/iperf_auth.h b/src/iperf_auth.h
|
||||
index ffadbf3..eedd45a 100644
|
||||
--- a/src/iperf_auth.h
|
||||
+++ b/src/iperf_auth.h
|
||||
@@ -35,7 +35,7 @@ EVP_PKEY *load_pubkey_from_file(const char *file);
|
||||
EVP_PKEY *load_pubkey_from_base64(const char *buffer);
|
||||
EVP_PKEY *load_privkey_from_file(const char *file);
|
||||
EVP_PKEY *load_privkey_from_base64(const char *buffer);
|
||||
-int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken);
|
||||
-int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts);
|
||||
+int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken, int use_pkcs1_padding);
|
||||
+int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts, int use_pkcs1_padding);
|
||||
int check_authentication(const char *username, const char *password, const time_t ts, const char *filename, int skew_threshold);
|
||||
ssize_t iperf_getpass (char **lineptr, size_t *n, FILE *stream);
|
||||
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
|
||||
index 838086e..466f36a 100644
|
||||
--- a/src/iperf_locale.c
|
||||
+++ b/src/iperf_locale.c
|
||||
@@ -156,6 +156,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
|
||||
" credentials\n"
|
||||
" --time-skew-threshold time skew threshold (in seconds) between the server\n"
|
||||
" and client during the authentication process\n"
|
||||
+ " --use-pkcs1-padding use pkcs1 padding at your own risk\n"
|
||||
#endif //HAVE_SSL
|
||||
"Client specific:\n"
|
||||
" -c, --client <host>[%%<dev>] run in client mode, connecting to <host>\n"
|
||||
diff --git a/src/t_auth.c b/src/t_auth.c
|
||||
index 22c78ae..5104855 100644
|
||||
--- a/src/t_auth.c
|
||||
+++ b/src/t_auth.c
|
||||
@@ -103,8 +103,9 @@ test_authtoken(const char *authUser, const char *authPassword, EVP_PKEY *pubkey,
|
||||
char *decodePassword;
|
||||
time_t decodeTime;
|
||||
|
||||
- assert(encode_auth_setting(authUser, authPassword, pubkey, &authToken) == 0);
|
||||
- assert(decode_auth_setting(0, authToken, privkey, &decodeUser, &decodePassword, &decodeTime) == 0);
|
||||
+ int use_pkcs1_padding = 1;
|
||||
+ assert(encode_auth_setting(authUser, authPassword, pubkey, &authToken, use_pkcs1_padding) == 0);
|
||||
+ assert(decode_auth_setting(0, authToken, privkey, &decodeUser, &decodePassword, &decodeTime, use_pkcs1_padding) == 0);
|
||||
|
||||
assert(strcmp(decodeUser, authUser) == 0);
|
||||
assert(strcmp(decodePassword, authPassword) == 0);
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -19,6 +19,7 @@ SRC_URI = "git://github.com/esnet/iperf.git;branch=master;protocol=https \
|
||||
file://CVE-2025-54350.patch \
|
||||
file://CVE-2025-54349.patch \
|
||||
file://CVE-2023-7250.patch \
|
||||
file://CVE-2024-26306.patch \
|
||||
"
|
||||
|
||||
SRCREV = "a0be85934144bc04712a6695b14ea6e45c379e1d"
|
||||
|
||||
Reference in New Issue
Block a user