diff options
author | Nick Mathewson <nickm@torproject.org> | 2020-01-16 19:52:01 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2020-01-21 10:31:36 -0500 |
commit | 942543253a30b8231c46eeaeb44f7ba174152113 (patch) | |
tree | d309fb473db5488db8444055edc7e77fb76efdbe /src/feature/hs/hs_cell.c | |
parent | 4269ab97c685cb3bef9607cbada8af5b6b84640c (diff) | |
download | tor-942543253a30b8231c46eeaeb44f7ba174152113.tar.gz tor-942543253a30b8231c46eeaeb44f7ba174152113.zip |
Use time-invariant conditional memcpy to make onionbalance loop safer
Diffstat (limited to 'src/feature/hs/hs_cell.c')
-rw-r--r-- | src/feature/hs/hs_cell.c | 51 |
1 files changed, 20 insertions, 31 deletions
diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c index 2b83453838..c82ffd647b 100644 --- a/src/feature/hs/hs_cell.c +++ b/src/feature/hs/hs_cell.c @@ -776,20 +776,20 @@ get_introduce2_keys_and_verify_mac(hs_cell_introduce2_data_t *data, if (intro_keys == NULL) { log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to " "compute key material"); - goto err; + return NULL; + } + + /* Make sure we are not about to underflow. */ + if (BUG(encrypted_section_len < DIGEST256_LEN)) { + return NULL; } /* Validate MAC from the cell and our computed key material. The MAC field * in the cell is at the end of the encrypted section. */ - int found_idx = -1; + intro_keys_result = tor_malloc_zero(sizeof(*intro_keys_result)); for (int i = 0; i < data->n_subcredentials; ++i) { uint8_t mac[DIGEST256_LEN]; - /* Make sure we are not about to underflow. */ - if (encrypted_section_len < sizeof(mac)) { - goto err; - } - /* The MAC field is at the very end of the ENCRYPTED section. */ size_t mac_offset = encrypted_section_len - sizeof(mac); /* Compute the MAC. Use the entire encoded payload with a length up to the @@ -800,33 +800,22 @@ get_introduce2_keys_and_verify_mac(hs_cell_introduce2_data_t *data, intro_keys[i].mac_key, sizeof(intro_keys[i].mac_key), mac, sizeof(mac)); - if (tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac))) { - found_idx = i; - break; - } - } - - if (found_idx == -1) { - log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell"); - goto err; + /* Time-invariant conditional copy: if the MAC is what we expected, then + * set intro_keys_result to intro_keys[i]. Otherwise, don't: but don't + * leak which one it was! */ + bool equal = tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac)); + memcpy_if_true_timei(equal, intro_keys_result, &intro_keys[i], + sizeof(*intro_keys_result)); } - /* We found a match! */ - if (data->n_subcredentials == 1) { - /* There was only one; steal it. */ - intro_keys_result = intro_keys; - intro_keys = NULL; - } else { - /* Copy out the one we wanted. */ - intro_keys_result = tor_memdup(&intro_keys[found_idx], - sizeof(hs_ntor_intro_cell_keys_t)); - } + /* We no longer need intro_keys. */ + memwipe(intro_keys, 0, + sizeof(hs_ntor_intro_cell_keys_t) * data->n_subcredentials); + tor_free(intro_keys); - err: - if (intro_keys) { - memwipe(intro_keys, 0, - sizeof(hs_ntor_intro_cell_keys_t) * data->n_subcredentials); - tor_free(intro_keys); + if (safe_mem_is_zero(intro_keys_result, sizeof(*intro_keys_result))) { + log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell"); + tor_free(intro_keys_result); /* sets intro_keys_result to NULL */ } return intro_keys_result; |