diff options
author | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2016-11-28 13:16:13 +0300 |
---|---|---|
committer | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2016-12-14 17:33:32 +0300 |
commit | 90e82f8c37a5cc8ff1647bb088642ab50a89f936 (patch) | |
tree | fc6b452f44aa50168a58ffafced034ec11a8fcb9 | |
parent | b93ebe67872c8008206f58b817b374cce880c45f (diff) | |
download | gnutls-90e82f8c37a5cc8ff1647bb088642ab50a89f936.tar.gz |
Cache MAC algorithm used for PRF function
Instead of spreading checks all over the GnuTLS, cache used PRF after
setting the cipher suite and reference the value later. Like in
_gnutls_PRF_raw the GNUTLS_MAC_MD5_SHA1 means MD5+SHA1 combo.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r-- | lib/constate.c | 9 | ||||
-rw-r--r-- | lib/gnutls_int.h | 1 | ||||
-rw-r--r-- | lib/handshake.c | 101 | ||||
-rw-r--r-- | lib/prf.c | 16 |
4 files changed, 34 insertions, 93 deletions
diff --git a/lib/constate.c b/lib/constate.c index f4f28c2e62..07140c8748 100644 --- a/lib/constate.c +++ b/lib/constate.c @@ -265,6 +265,15 @@ _gnutls_epoch_set_cipher_suite(gnutls_session_t session, if (_gnutls_mac_priority(session, mac_algo->id) < 0) return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_version_has_selectable_prf(get_version(session))) { + if (cs->prf == GNUTLS_MAC_UNKNOWN || + _gnutls_mac_is_ok(mac_to_entry(cs->prf)) == 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); + session->security_parameters.prf_mac = cs->prf; + } else { + session->security_parameters.prf_mac = GNUTLS_MAC_MD5_SHA1; + } + params->cipher = cipher_algo; params->mac = mac_algo; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 5ed45cec4e..f9160fc7ca 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -559,6 +559,7 @@ typedef struct { */ uint8_t cipher_suite[2]; gnutls_compression_method_t compression_method; + gnutls_mac_algorithm_t prf_mac; uint8_t master_secret[GNUTLS_MASTER_SIZE]; uint8_t client_random[GNUTLS_RANDOM_SIZE]; uint8_t server_random[GNUTLS_RANDOM_SIZE]; diff --git a/lib/handshake.c b/lib/handshake.c index b6c72fd198..4b73842403 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -341,48 +341,25 @@ _gnutls_finished(gnutls_session_t session, int type, void *ret, int sending) { const int siz = TLS_MSG_LEN; - uint8_t concat[MAX_HASH_SIZE + 16 /*MD5 */ ]; + uint8_t concat[MAX_HASH_SIZE]; size_t hash_len; const char *mesg; - int rc, len; + int rc, len, algorithm; if (sending) len = session->internals.handshake_hash_buffer.length; else len = session->internals.handshake_hash_buffer_prev_len; - if (!_gnutls_version_has_selectable_prf(get_version(session))) { - rc = _gnutls_hash_fast(GNUTLS_DIG_SHA1, - session->internals. - handshake_hash_buffer.data, len, - &concat[16]); - if (rc < 0) - return gnutls_assert_val(rc); - - rc = _gnutls_hash_fast(GNUTLS_DIG_MD5, - session->internals. - handshake_hash_buffer.data, len, - concat); - if (rc < 0) - return gnutls_assert_val(rc); - - hash_len = 20 + 16; - } else { - int algorithm = - _gnutls_cipher_suite_get_prf(session-> - security_parameters. - cipher_suite); - - rc = _gnutls_hash_fast(algorithm, - session->internals. - handshake_hash_buffer.data, len, - concat); - if (rc < 0) - return gnutls_assert_val(rc); + algorithm = session->security_parameters.prf_mac; + rc = _gnutls_hash_fast(algorithm, + session->internals. + handshake_hash_buffer.data, len, + concat); + if (rc < 0) + return gnutls_assert_val(rc); - hash_len = - _gnutls_hash_get_algo_len(mac_to_entry(algorithm)); - } + hash_len = _gnutls_hash_get_algo_len(mac_to_entry(algorithm)); if (type == GNUTLS_SERVER) { mesg = SERVER_MSG; @@ -3477,8 +3454,6 @@ int _gnutls_handshake_get_session_hash(gnutls_session_t session, gnutls_datum_t int ret; const mac_entry_st *me; uint8_t concat[2*MAX_HASH_SIZE]; - digest_hd_st td_md5; - digest_hd_st td_sha; if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); @@ -3489,50 +3464,18 @@ int _gnutls_handshake_get_session_hash(gnutls_session_t session, gnutls_datum_t return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); } - if (_gnutls_version_has_selectable_prf(ver)) { /* TLS 1.2+ */ - gnutls_mac_algorithm_t prf; - - prf = _gnutls_cipher_suite_get_prf(session->security_parameters.cipher_suite); - if (prf == GNUTLS_MAC_UNKNOWN) - return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); - - me = mac_to_entry(prf); - - ret = - _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id, - session->internals.handshake_hash_buffer. - data, - session->internals.handshake_hash_buffer_client_kx_len, - concat); - if (ret < 0) - return gnutls_assert_val(ret); - - return _gnutls_set_datum(shash, concat, me->output_size); - } else { - ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1)); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - _gnutls_hash(&td_sha, - session->internals.handshake_hash_buffer.data, - session->internals.handshake_hash_buffer_client_kx_len); - - _gnutls_hash_deinit(&td_sha, &concat[16]); - - ret = - _gnutls_hash_init(&td_md5, - hash_to_entry(GNUTLS_DIG_MD5)); - if (ret < 0) - return gnutls_assert_val(ret); - - _gnutls_hash(&td_md5, - session->internals.handshake_hash_buffer.data, - session->internals.handshake_hash_buffer_client_kx_len); + me = mac_to_entry(session->security_parameters.prf_mac); + if (me == NULL) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - _gnutls_hash_deinit(&td_md5, concat); + ret = + _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id, + session->internals.handshake_hash_buffer. + data, + session->internals.handshake_hash_buffer_client_kx_len, + concat); + if (ret < 0) + return gnutls_assert_val(ret); - return _gnutls_set_datum(shash, concat, 36); - } + return _gnutls_set_datum(shash, concat, me->output_size); } @@ -206,25 +206,13 @@ _gnutls_PRF(gnutls_session_t session, const char *label, int label_size, const uint8_t * seed, int seed_size, int total_bytes, void *ret) { - const version_entry_st *ver = get_version(session); - - if (_gnutls_version_has_selectable_prf(ver)) { - return _gnutls_PRF_raw( - _gnutls_cipher_suite_get_prf(session->security_parameters.cipher_suite), - secret, secret_size, - label, label_size, - seed, seed_size, - total_bytes, - ret); - } else { - return _gnutls_PRF_raw( - GNUTLS_MAC_MD5_SHA1, + return _gnutls_PRF_raw( + session->security_parameters.prf_mac, secret, secret_size, label, label_size, seed, seed_size, total_bytes, ret); - } } #ifdef ENABLE_FIPS140 |