Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
gnutls.32646
curl-CVE-2023-5981.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File curl-CVE-2023-5981.patch of Package gnutls.32646
From 29d6298d0b04cfff970b993915db71ba3f580b6d Mon Sep 17 00:00:00 2001 From: Daiki Ueno <ueno@gnu.org> Date: Mon, 23 Oct 2023 09:26:57 +0900 Subject: [PATCH 1/2] auth/rsa_psk: side-step potential side-channel This removes branching that depends on secret data, porting changes for regular RSA key exchange from 4804febddc2ed958e5ae774de2a8f85edeeff538 and 80a6ce8ddb02477cd724cd5b2944791aaddb702a. This also removes the allow_wrong_pms as it was used sorely to control debug output depending on the branching. Signed-off-by: Daiki Ueno <ueno@gnu.org> --- lib/auth/rsa.c | 2 +- lib/auth/rsa_psk.c | 90 ++++++++++++++++++---------------------------- lib/gnutls_int.h | 4 --- lib/priority.c | 1 - 4 files changed, 35 insertions(+), 62 deletions(-) Index: gnutls-3.7.3/lib/auth/rsa.c =================================================================== --- gnutls-3.7.3.orig/lib/auth/rsa.c +++ gnutls-3.7.3/lib/auth/rsa.c @@ -207,7 +207,7 @@ proc_rsa_client_kx(gnutls_session_t sess 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 Index: gnutls-3.7.3/lib/auth/rsa_psk.c =================================================================== --- gnutls-3.7.3.orig/lib/auth/rsa_psk.c +++ gnutls-3.7.3/lib/auth/rsa_psk.c @@ -264,14 +264,13 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se { 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); @@ -288,7 +287,7 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se return ret; } - /*** 1. Extract user psk_identity ***/ + /*** 1. Extract user psk_identity ***/ DECR_LEN(data_size, 2); username.size = _gnutls_read_uint16(&data[0]); @@ -317,7 +316,7 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se /* Adjust data so it points to EncryptedPreMasterSecret */ data += username.size + 2; - /*** 2. Decrypt and extract EncryptedPreMasterSecret ***/ + /*** 2. Decrypt and extract EncryptedPreMasterSecret ***/ DECR_LEN(data_size, 2); ciphertext.data = &data[2]; @@ -329,71 +328,49 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se } 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). - */ - 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"); - } - } + 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(); + 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 */ Index: gnutls-3.7.3/lib/gnutls_int.h =================================================================== --- gnutls-3.7.3.orig/lib/gnutls_int.h +++ gnutls-3.7.3/lib/gnutls_int.h @@ -977,7 +977,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 */ @@ -995,7 +994,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) \ @@ -1004,7 +1002,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. @@ -1129,7 +1126,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 Index: gnutls-3.7.3/lib/priority.c =================================================================== --- gnutls-3.7.3.orig/lib/priority.c +++ gnutls-3.7.3/lib/priority.c @@ -690,7 +690,6 @@ gnutls_priority_set(gnutls_session_t ses 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);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor