Selaa lähdekoodia

Implement a constant-time safe_mem_is_zero.

Nick Mathewson 11 vuotta sitten
vanhempi
commit
f07a5125cb
3 muutettua tiedostoa jossa 29 lisäystä ja 0 poistoa
  1. 17 0
      src/common/di_ops.c
  2. 2 0
      src/common/di_ops.h
  3. 10 0
      src/test/test_util.c

+ 17 - 0
src/common/di_ops.c

@@ -203,3 +203,20 @@ dimap_search(const di_digest256_map_t *map, const uint8_t *key,
   return (void *)result;
 }
 
+/**
+ * Return true iff the <b>sz</b> bytes at <b>mem</b> are all zero. Runs in
+ * time independent of the contents of <b>mem</b>.
+ */
+int
+safe_mem_is_zero(const void *mem, size_t sz)
+{
+  uint32_t total = 0;
+  const uint8_t *ptr = mem;
+
+  while (sz--) {
+    total |= *ptr++;
+  }
+
+  return 1 & ((total - 1) >> 8);
+}
+

+ 2 - 0
src/common/di_ops.h

@@ -27,6 +27,8 @@ int tor_memeq(const void *a, const void *b, size_t sz);
 #define fast_memeq(a,b,c)  (0==memcmp((a),(b),(c)))
 #define fast_memneq(a,b,c) (0!=memcmp((a),(b),(c)))
 
+int safe_mem_is_zero(const void *mem, size_t sz);
+
 /** A type for a map from DIGEST256_LEN-byte blobs to void*, such that
  * data lookups take an amount of time proportional only to the size
  * of the map, and not to the position or presence of the item in the map.

+ 10 - 0
src/test/test_util.c

@@ -2843,6 +2843,16 @@ test_util_di_ops(void)
     test_eq(neq1, !eq1);
   }
 
+  tt_int_op(1, ==, safe_mem_is_zero("", 0));
+  tt_int_op(1, ==, safe_mem_is_zero("", 1));
+  tt_int_op(0, ==, safe_mem_is_zero("a", 1));
+  tt_int_op(0, ==, safe_mem_is_zero("a", 2));
+  tt_int_op(0, ==, safe_mem_is_zero("\0a", 2));
+  tt_int_op(1, ==, safe_mem_is_zero("\0\0a", 2));
+  tt_int_op(1, ==, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
+  tt_int_op(1, ==, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
+  tt_int_op(0, ==, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
+
  done:
   ;
 }