From 762ea8caa547c47bd5b9a73f94643cce2c7ac0fb Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 10 Jan 2024 17:49:05 +0000 Subject: [PATCH] import UBI gnutls-3.6.16-8.el8_9 --- SOURCES/gnutls-3.6.16-rsa-psk-timing.patch | 202 +++++++++++++++++++++ SPECS/gnutls.spec | 6 +- 2 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 SOURCES/gnutls-3.6.16-rsa-psk-timing.patch diff --git a/SOURCES/gnutls-3.6.16-rsa-psk-timing.patch b/SOURCES/gnutls-3.6.16-rsa-psk-timing.patch new file mode 100644 index 0000000..e8beb02 --- /dev/null +++ b/SOURCES/gnutls-3.6.16-rsa-psk-timing.patch @@ -0,0 +1,202 @@ +From e007a54432c98618bde500649817d153225abf6b Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 7 Dec 2023 11:52:08 +0900 +Subject: [PATCH] gnutls-3.6.16-rsa-psk-timing.patch + +Signed-off-by: rpm-build +--- + lib/auth/rsa.c | 2 +- + lib/auth/rsa_psk.c | 93 +++++++++++++++++----------------------------- + lib/gnutls_int.h | 4 -- + lib/priority.c | 1 - + 4 files changed, 35 insertions(+), 65 deletions(-) + +diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c +index 858701f..02b6a34 100644 +--- a/lib/auth/rsa.c ++++ b/lib/auth/rsa.c +@@ -207,7 +207,7 @@ proc_rsa_client_kx(gnutls_session_t session, uint8_t * data, + session->key.key.size); + /* After this point, any conditional on failure that cause differences + * in execution may create a timing or cache access pattern side +- * channel that can be used as an oracle, so treat very carefully */ ++ * channel that can be used as an oracle, so tread carefully */ + + /* Error handling logic: + * In case decryption fails then don't inform the peer. Just use the +diff --git a/lib/auth/rsa_psk.c b/lib/auth/rsa_psk.c +index 1a9dab5..93c2dc9 100644 +--- a/lib/auth/rsa_psk.c ++++ b/lib/auth/rsa_psk.c +@@ -264,14 +264,13 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data, + { + gnutls_datum_t username; + psk_auth_info_t info; +- gnutls_datum_t plaintext; + gnutls_datum_t ciphertext; + gnutls_datum_t pwd_psk = { NULL, 0 }; + int ret, dsize; +- int randomize_key = 0; + ssize_t data_size = _data_size; + gnutls_psk_server_credentials_t cred; + gnutls_datum_t premaster_secret = { NULL, 0 }; ++ volatile uint8_t ver_maj, ver_min; + + cred = (gnutls_psk_server_credentials_t) + _gnutls_get_cred(session, GNUTLS_CRD_PSK); +@@ -327,71 +326,47 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, uint8_t * data, + } + ciphertext.size = dsize; + +- ret = +- gnutls_privkey_decrypt_data(session->internals.selected_key, 0, +- &ciphertext, &plaintext); +- if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE) { +- /* In case decryption fails then don't inform +- * the peer. Just use a random key. (in order to avoid +- * attack against pkcs-1 formatting). +- */ ++ ver_maj = _gnutls_get_adv_version_major(session); ++ ver_min = _gnutls_get_adv_version_minor(session); ++ ++ premaster_secret.data = gnutls_malloc(GNUTLS_MASTER_SIZE); ++ if (premaster_secret.data == NULL) { + gnutls_assert(); +- _gnutls_debug_log +- ("auth_rsa_psk: Possible PKCS #1 format attack\n"); +- if (ret >= 0) { +- gnutls_free(plaintext.data); +- } +- randomize_key = 1; +- } else { +- /* If the secret was properly formatted, then +- * check the version number. +- */ +- if (_gnutls_get_adv_version_major(session) != +- plaintext.data[0] +- || (session->internals.allow_wrong_pms == 0 +- && _gnutls_get_adv_version_minor(session) != +- plaintext.data[1])) { +- /* No error is returned here, if the version number check +- * fails. We proceed normally. +- * That is to defend against the attack described in the paper +- * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima, +- * Ondej Pokorny and Tomas Rosa. +- */ +- gnutls_assert(); +- _gnutls_debug_log +- ("auth_rsa: Possible PKCS #1 version check format attack\n"); +- } ++ return GNUTLS_E_MEMORY_ERROR; + } ++ premaster_secret.size = GNUTLS_MASTER_SIZE; + +- +- if (randomize_key != 0) { +- premaster_secret.size = GNUTLS_MASTER_SIZE; +- premaster_secret.data = +- gnutls_malloc(premaster_secret.size); +- if (premaster_secret.data == NULL) { +- gnutls_assert(); +- return GNUTLS_E_MEMORY_ERROR; +- } +- +- /* we do not need strong random numbers here. +- */ +- ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data, +- premaster_secret.size); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } +- } else { +- premaster_secret.data = plaintext.data; +- premaster_secret.size = plaintext.size; ++ /* Fallback value when decryption fails. Needs to be unpredictable. */ ++ ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data, ++ premaster_secret.size); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; + } + ++ gnutls_privkey_decrypt_data2(session->internals.selected_key, 0, ++ &ciphertext, premaster_secret.data, ++ premaster_secret.size); ++ /* After this point, any conditional on failure that cause differences ++ * in execution may create a timing or cache access pattern side ++ * channel that can be used as an oracle, so tread carefully */ ++ ++ /* Error handling logic: ++ * In case decryption fails then don't inform the peer. Just use the ++ * random key previously generated. (in order to avoid attack against ++ * pkcs-1 formatting). ++ * ++ * If we get version mismatches no error is returned either. We ++ * proceed normally. This is to defend against the attack described ++ * in the paper "Attacking RSA-based sessions in SSL/TLS" by ++ * Vlastimil Klima, Ondej Pokorny and Tomas Rosa. ++ */ ++ + /* This is here to avoid the version check attack + * discussed above. + */ +- +- premaster_secret.data[0] = _gnutls_get_adv_version_major(session); +- premaster_secret.data[1] = _gnutls_get_adv_version_minor(session); ++ premaster_secret.data[0] = ver_maj; ++ premaster_secret.data[1] = ver_min; + + /* find the key of this username + */ +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index 31cec5c..815f69b 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -971,7 +971,6 @@ struct gnutls_priority_st { + bool _no_etm; + bool _no_ext_master_secret; + bool _allow_key_usage_violation; +- bool _allow_wrong_pms; + bool _dumbfw; + unsigned int _dh_prime_bits; /* old (deprecated) variable */ + +@@ -989,7 +988,6 @@ struct gnutls_priority_st { + (x)->no_etm = 1; \ + (x)->no_ext_master_secret = 1; \ + (x)->allow_key_usage_violation = 1; \ +- (x)->allow_wrong_pms = 1; \ + (x)->dumbfw = 1 + + #define ENABLE_PRIO_COMPAT(x) \ +@@ -998,7 +996,6 @@ struct gnutls_priority_st { + (x)->_no_etm = 1; \ + (x)->_no_ext_master_secret = 1; \ + (x)->_allow_key_usage_violation = 1; \ +- (x)->_allow_wrong_pms = 1; \ + (x)->_dumbfw = 1 + + /* DH and RSA parameters types. +@@ -1123,7 +1120,6 @@ typedef struct { + bool no_etm; + bool no_ext_master_secret; + bool allow_key_usage_violation; +- bool allow_wrong_pms; + bool dumbfw; + + /* old (deprecated) variable. This is used for both srp_prime_bits +diff --git a/lib/priority.c b/lib/priority.c +index 0a284ae..67ec887 100644 +--- a/lib/priority.c ++++ b/lib/priority.c +@@ -681,7 +681,6 @@ gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority) + COPY_TO_INTERNALS(no_etm); + COPY_TO_INTERNALS(no_ext_master_secret); + COPY_TO_INTERNALS(allow_key_usage_violation); +- COPY_TO_INTERNALS(allow_wrong_pms); + COPY_TO_INTERNALS(dumbfw); + COPY_TO_INTERNALS(dh_prime_bits); + +-- +2.43.0 + diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec index e525b8a..013b8ad 100644 --- a/SPECS/gnutls.spec +++ b/SPECS/gnutls.spec @@ -1,5 +1,5 @@ Version: 3.6.16 -Release: 7%{?dist} +Release: 8%{?dist} Patch1: gnutls-3.2.7-rpath.patch Patch2: gnutls-3.6.4-no-now-guile.patch Patch3: gnutls-3.6.13-enable-intel-cet.patch @@ -12,6 +12,7 @@ Patch15: gnutls-3.6.16-pkcs7-verify.patch Patch16: gnutls-3.6.16-cpuid.patch Patch17: gnutls-3.7.8-rsa-kx-timing.patch Patch18: gnutls-3.6.16-rehandshake-tickets.patch +Patch19: gnutls-3.6.16-rsa-psk-timing.patch %bcond_without dane %if 0%{?rhel} %bcond_with guile @@ -296,6 +297,9 @@ fi %endif %changelog +* Wed Dec 6 2023 Daiki Ueno - 3.6.16-8 +- auth/rsa_psk: side-step potential side-channel (RHEL-16753) + * Mon Jun 26 2023 Daiki Ueno - 3.6.16-7 - Clear server's session ticket indication at rehandshake (#2089817)