[tor-commits] [tor/master] Use time-invariant conditional memcpy to make onionbalance loop safer

nickm at torproject.org nickm at torproject.org
Mon Feb 24 12:48:35 UTC 2020


commit 942543253a30b8231c46eeaeb44f7ba174152113
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jan 16 19:52:01 2020 -0500

    Use time-invariant conditional memcpy to make onionbalance loop safer
---
 src/feature/hs/hs_cell.c | 51 +++++++++++++++++++-----------------------------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c
index 2b8345383..c82ffd647 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;





More information about the tor-commits mailing list