summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2016-11-28 13:16:13 +0300
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2016-12-14 17:33:32 +0300
commit90e82f8c37a5cc8ff1647bb088642ab50a89f936 (patch)
treefc6b452f44aa50168a58ffafced034ec11a8fcb9
parentb93ebe67872c8008206f58b817b374cce880c45f (diff)
downloadgnutls-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.c9
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/handshake.c101
-rw-r--r--lib/prf.c16
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);
}
diff --git a/lib/prf.c b/lib/prf.c
index a1fc1923d1..517fac90d9 100644
--- a/lib/prf.c
+++ b/lib/prf.c
@@ -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