diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-06-21 10:53:29 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-06-21 11:03:39 -0400 |
commit | a403ee6bb31168e19cf4173fff0e9acf9548231f (patch) | |
tree | 841bd1a24df1e9aefa6e8370635170a561e80a75 /src/common | |
parent | 275aff6917260209dc53e553d895ec886f6c8c52 (diff) | |
download | tor-a403ee6bb31168e19cf4173fff0e9acf9548231f.tar.gz tor-a403ee6bb31168e19cf4173fff0e9acf9548231f.zip |
Move consttime library code into its own directory.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/di_ops.c | 274 | ||||
-rw-r--r-- | src/common/di_ops.h | 55 | ||||
-rw-r--r-- | src/common/include.am | 23 |
3 files changed, 0 insertions, 352 deletions
diff --git a/src/common/di_ops.c b/src/common/di_ops.c deleted file mode 100644 index 1ff1988b10..0000000000 --- a/src/common/di_ops.c +++ /dev/null @@ -1,274 +0,0 @@ -/* Copyright (c) 2011-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file di_ops.c - * \brief Functions for data-independent operations. - **/ - -#include "orconfig.h" -#include "common/di_ops.h" -#include "common/torlog.h" -#include "common/util.h" - -/** - * Timing-safe version of memcmp. As memcmp, compare the <b>sz</b> bytes at - * <b>a</b> with the <b>sz</b> bytes at <b>b</b>, and return less than 0 if - * the bytes at <b>a</b> lexically precede those at <b>b</b>, 0 if the byte - * ranges are equal, and greater than zero if the bytes at <b>a</b> lexically - * follow those at <b>b</b>. - * - * This implementation differs from memcmp in that its timing behavior is not - * data-dependent: it should return in the same amount of time regardless of - * the contents of <b>a</b> and <b>b</b>. - */ -int -tor_memcmp(const void *a, const void *b, size_t len) -{ -#ifdef HAVE_TIMINGSAFE_MEMCMP - return timingsafe_memcmp(a, b, len); -#else - const uint8_t *x = a; - const uint8_t *y = b; - size_t i = len; - int retval = 0; - - /* This loop goes from the end of the arrays to the start. At the - * start of every iteration, before we decrement i, we have set - * "retval" equal to the result of memcmp(a+i,b+i,len-i). During the - * loop, we update retval by leaving it unchanged if x[i]==y[i] and - * setting it to x[i]-y[i] if x[i]!= y[i]. - * - * The following assumes we are on a system with two's-complement - * arithmetic. We check for this at configure-time with the check - * that sets USING_TWOS_COMPLEMENT. If we aren't two's complement, then - * torint.h will stop compilation with an error. - */ - while (i--) { - int v1 = x[i]; - int v2 = y[i]; - int equal_p = v1 ^ v2; - - /* The following sets bits 8 and above of equal_p to 'equal_p == - * 0', and thus to v1 == v2. (To see this, note that if v1 == - * v2, then v1^v2 == equal_p == 0, so equal_p-1 == -1, which is the - * same as ~0 on a two's-complement machine. Then note that if - * v1 != v2, then 0 < v1 ^ v2 < 256, so 0 <= equal_p - 1 < 255.) - */ - --equal_p; - - equal_p >>= 8; - /* Thanks to (sign-preserving) arithmetic shift, equal_p is now - * equal to -(v1 == v2), which is exactly what we need below. - * (Since we're assuming two's-complement arithmetic, -1 is the - * same as ~0 (all bits set).) - * - * (The result of an arithmetic shift on a negative value is - * actually implementation-defined in standard C. So how do we - * get away with assuming it? Easy. We check.) */ -#if ((-60 >> 8) != -1) -#error "According to cpp, right-shift doesn't perform sign-extension." -#endif -#ifndef RSHIFT_DOES_SIGN_EXTEND -#error "According to configure, right-shift doesn't perform sign-extension." -#endif - - /* If v1 == v2, equal_p is ~0, so this will leave retval - * unchanged; otherwise, equal_p is 0, so this will zero it. */ - retval &= equal_p; - - /* If v1 == v2, then this adds 0, and leaves retval unchanged. - * Otherwise, we just zeroed retval, so this sets it to v1 - v2. */ - retval += (v1 - v2); - - /* There. Now retval is equal to its previous value if v1 == v2, and - * equal to v1 - v2 if v1 != v2. */ - } - - return retval; -#endif /* defined(HAVE_TIMINGSAFE_MEMCMP) */ -} - -/** - * Timing-safe memory comparison. Return true if the <b>sz</b> bytes at - * <b>a</b> are the same as the <b>sz</b> bytes at <b>b</b>, and 0 otherwise. - * - * This implementation differs from !memcmp(a,b,sz) in that its timing - * behavior is not data-dependent: it should return in the same amount of time - * regardless of the contents of <b>a</b> and <b>b</b>. It differs from - * !tor_memcmp(a,b,sz) by being faster. - */ -int -tor_memeq(const void *a, const void *b, size_t sz) -{ - /* Treat a and b as byte ranges. */ - const uint8_t *ba = a, *bb = b; - uint32_t any_difference = 0; - while (sz--) { - /* Set byte_diff to all of those bits that are different in *ba and *bb, - * and advance both ba and bb. */ - const uint8_t byte_diff = *ba++ ^ *bb++; - - /* Set bits in any_difference if they are set in byte_diff. */ - any_difference |= byte_diff; - } - - /* Now any_difference is 0 if there are no bits different between - * a and b, and is nonzero if there are bits different between a - * and b. Now for paranoia's sake, let's convert it to 0 or 1. - * - * (If we say "!any_difference", the compiler might get smart enough - * to optimize-out our data-independence stuff above.) - * - * To unpack: - * - * If any_difference == 0: - * any_difference - 1 == ~0 - * (any_difference - 1) >> 8 == 0x00ffffff - * 1 & ((any_difference - 1) >> 8) == 1 - * - * If any_difference != 0: - * 0 < any_difference < 256, so - * 0 <= any_difference - 1 < 255 - * (any_difference - 1) >> 8 == 0 - * 1 & ((any_difference - 1) >> 8) == 0 - */ - - /*coverity[overflow]*/ - return 1 & ((any_difference - 1) >> 8); -} - -/* Implement di_digest256_map_t as a linked list of entries. */ -struct di_digest256_map_t { - struct di_digest256_map_t *next; - uint8_t key[32]; - void *val; -}; - -/** Release all storage held in <b>map</b>, calling free_fn on each value - * as we go. */ -void -dimap_free_(di_digest256_map_t *map, dimap_free_fn free_fn) -{ - while (map) { - di_digest256_map_t *victim = map; - map = map->next; - if (free_fn) - free_fn(victim->val); - tor_free(victim); - } -} - -/** Adjust the map at *<b>map</b>, adding an entry for <b>key</b> -> - * <b>val</b>, where <b>key</b> is a DIGEST256_LEN-byte key. - * - * The caller MUST NOT add a key that already appears in the map. - */ -void -dimap_add_entry(di_digest256_map_t **map, - const uint8_t *key, void *val) -{ - di_digest256_map_t *new_ent; - { - void *old_val = dimap_search(*map, key, NULL); - tor_assert(! old_val); - tor_assert(val); - } - new_ent = tor_malloc_zero(sizeof(di_digest256_map_t)); - new_ent->next = *map; - memcpy(new_ent->key, key, 32); - new_ent->val = val; - *map = new_ent; -} - -/** Search the map at <b>map</b> for an entry whose key is <b>key</b> (a - * DIGEST256_LEN-byte key) returning the corresponding value if we found one, - * and returning <b>dflt_val</b> if the key wasn't found. - * - * This operation takes an amount of time dependent only on the length of - * <b>map</b>, not on the position or presence of <b>key</b> within <b>map</b>. - */ -void * -dimap_search(const di_digest256_map_t *map, const uint8_t *key, - void *dflt_val) -{ - uintptr_t result = (uintptr_t)dflt_val; - - while (map) { - uintptr_t r = (uintptr_t) tor_memeq(map->key, key, 32); - r -= 1; /* Now r is (uintptr_t)-1 if memeq returned false, and - * 0 if memeq returned true. */ - - result &= r; - result |= ((uintptr_t)(map->val)) & ~r; - - map = map->next; - } - - 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++; - } - - /*coverity[overflow]*/ - return 1 & ((total - 1) >> 8); -} - -/** Time-invariant 64-bit greater-than; works on two integers in the range - * (0,INT64_MAX). */ -#if SIZEOF_VOID_P == 8 -#define gt_i64_timei(a,b) ((a) > (b)) -#else -static inline int -gt_i64_timei(uint64_t a, uint64_t b) -{ - int64_t diff = (int64_t) (b - a); - int res = diff >> 63; - return res & 1; -} -#endif /* SIZEOF_VOID_P == 8 */ - -/** - * Given an array of list of <b>n_entries</b> uint64_t values, whose sum is - * <b>total</b>, find the first i such that the total of all elements 0...i is - * greater than rand_val. - * - * Try to perform this operation in a constant-time way. - */ -int -select_array_member_cumulative_timei(const uint64_t *entries, int n_entries, - uint64_t total, uint64_t rand_val) -{ - int i, i_chosen=-1, n_chosen=0; - uint64_t total_so_far = 0; - - for (i = 0; i < n_entries; ++i) { - total_so_far += entries[i]; - if (gt_i64_timei(total_so_far, rand_val)) { - i_chosen = i; - n_chosen++; - /* Set rand_val to INT64_MAX rather than stopping the loop. This way, - * the time we spend in the loop does not leak which element we chose. */ - rand_val = INT64_MAX; - } - } - tor_assert(total_so_far == total); - tor_assert(n_chosen == 1); - tor_assert(i_chosen >= 0); - tor_assert(i_chosen < n_entries); - - return i_chosen; -} - diff --git a/src/common/di_ops.h b/src/common/di_ops.h deleted file mode 100644 index 8298bfa73a..0000000000 --- a/src/common/di_ops.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2003-2004, Roger Dingledine - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file di_ops.h - * \brief Headers for di_ops.c - **/ - -#ifndef TOR_DI_OPS_H -#define TOR_DI_OPS_H - -#include "orconfig.h" -#include "common/torint.h" - -int tor_memcmp(const void *a, const void *b, size_t sz); -int tor_memeq(const void *a, const void *b, size_t sz); -#define tor_memneq(a,b,sz) (!tor_memeq((a),(b),(sz))) - -/** Alias for the platform's memcmp() function. This function is - * <em>not</em> data-independent: we define this alias so that we can - * mark cases where we are deliberately using a data-dependent memcmp() - * implementation. - */ -#define fast_memcmp(a,b,c) (memcmp((a),(b),(c))) -#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. - * - * Not efficient for large maps! */ -typedef struct di_digest256_map_t di_digest256_map_t; -typedef void (*dimap_free_fn)(void *); - -void dimap_free_(di_digest256_map_t *map, dimap_free_fn free_fn); -#define dimap_free(map, free_fn) \ - do { \ - dimap_free_((map), (free_fn)); \ - (map) = NULL; \ - } while (0) -void dimap_add_entry(di_digest256_map_t **map, - const uint8_t *key, void *val); -void *dimap_search(const di_digest256_map_t *map, const uint8_t *key, - void *dflt_val); -int select_array_member_cumulative_timei(const uint64_t *entries, - int n_entries, - uint64_t total, uint64_t rand_val); - -#endif /* !defined(TOR_DI_OPS_H) */ - diff --git a/src/common/include.am b/src/common/include.am index 5337034861..fa12888ac0 100644 --- a/src/common/include.am +++ b/src/common/include.am @@ -1,14 +1,12 @@ noinst_LIBRARIES += \ src/common/libor.a \ - src/common/libor-ctime.a \ src/common/libor-crypto.a \ src/common/libor-event.a if UNITTESTS_ENABLED noinst_LIBRARIES += \ src/common/libor-testing.a \ - src/common/libor-ctime-testing.a \ src/common/libor-crypto-testing.a \ src/common/libor-event-testing.a endif @@ -59,26 +57,6 @@ else readpassphrase_source= endif -if ADD_MULODI4 -mulodi4_source=src/ext/mulodi/mulodi4.c -else -mulodi4_source= -endif - -LIBOR_CTIME_A_SRC = \ - $(mulodi4_source) \ - src/ext/csiphash.c \ - src/common/di_ops.c - -src_common_libor_ctime_a_SOURCES = $(LIBOR_CTIME_A_SRC) -if UNITTESTS_ENABLED -src_common_libor_ctime_testing_a_SOURCES = $(LIBOR_CTIME_A_SRC) -else -src_common_libor_ctime_testing_a_SOURCES = -endif -src_common_libor_ctime_a_CFLAGS = @CFLAGS_CONSTTIME@ -src_common_libor_ctime_testing_a_CFLAGS = @CFLAGS_CONSTTIME@ $(TEST_CFLAGS) - LIBOR_A_SRC = \ src/common/address.c \ src/common/address_set.c \ @@ -189,7 +167,6 @@ COMMONHEADERS = \ src/common/crypto_rsa.h \ src/common/crypto_s2k.h \ src/common/crypto_util.h \ - src/common/di_ops.h \ src/common/handles.h \ src/common/memarea.h \ src/common/linux_syscalls.inc \ |