Merge remote-tracking branch 'public/bug3122_memcmp_022' into bug3122_memcmp_023

Conflicts in various places, mainly node-related.  Resolved them in
favor of HEAD, with copying of tor_mem* operations from bug3122_memcmp_022.

	src/common/Makefile.am
	src/or/circuitlist.c
	src/or/connection_edge.c
	src/or/directory.c
	src/or/microdesc.c
	src/or/networkstatus.c
	src/or/router.c
	src/or/routerlist.c
	src/test/test_util.c
This commit is contained in:
Nick Mathewson 2011-05-11 16:39:45 -04:00
commit 9fba014e3f
36 changed files with 429 additions and 175 deletions

7
changes/bug3122_memcmp Normal file
View File

@ -0,0 +1,7 @@
o Security fixes
- Replace all potentially sensitive memory comparison operations
with versions whose runtime does not depend on the data being
compared. This will help resist a class of attacks where an
adversary can use variations in timing information to learn
sensitive data. Fix for one case of bug 3122. (Safe memcmp
implementation by Robert Ransom based partially on code by DJB.)

View File

@ -905,6 +905,24 @@ if test "$tor_cv_twos_complement" != no ; then
[Define to 1 iff we represent negative integers with two's complement]) [Define to 1 iff we represent negative integers with two's complement])
fi fi
# What does shifting a negative value do?
AC_CACHE_CHECK([whether right-shift on negative values does sign-extension], tor_cv_sign_extend,
[AC_RUN_IFELSE([AC_LANG_SOURCE(
[[int main () { int okay = (-60 >> 8) == -1; return okay ? 0 : 1; }]])],
[tor_cv_sign_extend=yes],
[tor_cv_sign_extend=no],
[tor_cv_sign_extend=cross])])
if test "$tor_cv_sign_extend" = cross ; then
# Cross-compiling; let's hope that the target isn't raving mad.
AC_MSG_NOTICE([Cross-compiling: we'll assume that right-shifting negative integers causes sign-extension])
fi
if test "$tor_cv_sign_extend" != no ; then
AC_DEFINE([RSHIFT_DOES_SIGN_EXTEND], 1,
[Define to 1 iff right-shifting a negative value performs sign-extension])
fi
# Whether we should use the dmalloc memory allocation debugging library. # Whether we should use the dmalloc memory allocation debugging library.
AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library)) AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library))
AC_ARG_WITH(dmalloc, AC_ARG_WITH(dmalloc,

View File

@ -15,6 +15,7 @@ libor_a_SOURCES = \
address.c \ address.c \
compat.c \ compat.c \
container.c \ container.c \
di_ops.c \
log.c \ log.c \
memarea.c \ memarea.c \
mempool.c \ mempool.c \
@ -38,6 +39,7 @@ noinst_HEADERS = \
compat_libevent.h \ compat_libevent.h \
container.h \ container.h \
crypto.h \ crypto.h \
di_ops.h \
ht.h \ ht.h \
memarea.h \ memarea.h \
mempool.h \ mempool.h \

View File

@ -837,7 +837,7 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
const uint8_t *a2 = tor_addr_to_in6_addr8(addr2); const uint8_t *a2 = tor_addr_to_in6_addr8(addr2);
const int bytes = mbits >> 3; const int bytes = mbits >> 3;
const int leftover_bits = mbits & 7; const int leftover_bits = mbits & 7;
if (bytes && (r = memcmp(a1, a2, bytes))) { if (bytes && (r = tor_memcmp(a1, a2, bytes))) {
return r; return r;
} else if (leftover_bits) { } else if (leftover_bits) {
uint8_t b1 = a1[bytes] >> (8-leftover_bits); uint8_t b1 = a1[bytes] >> (8-leftover_bits);

View File

@ -442,6 +442,8 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
* <b>needle</b>, return a pointer to the first occurrence of the needle * <b>needle</b>, return a pointer to the first occurrence of the needle
* within the haystack, or NULL if there is no such occurrence. * within the haystack, or NULL if there is no such occurrence.
* *
* This function is <em>not</em> timing-safe.
*
* Requires that nlen be greater than zero. * Requires that nlen be greater than zero.
*/ */
const void * const void *
@ -466,7 +468,7 @@ tor_memmem(const void *_haystack, size_t hlen,
while ((p = memchr(p, first, end-p))) { while ((p = memchr(p, first, end-p))) {
if (p+nlen > end) if (p+nlen > end)
return NULL; return NULL;
if (!memcmp(p, needle, nlen)) if (fast_memeq(p, needle, nlen))
return p; return p;
++p; ++p;
} }

View File

@ -216,7 +216,7 @@ smartlist_string_num_isin(const smartlist_t *sl, int num)
} }
/** Return true iff <b>sl</b> has some element E such that /** Return true iff <b>sl</b> has some element E such that
* !memcmp(E,<b>element</b>,DIGEST_LEN) * tor_memeq(E,<b>element</b>,DIGEST_LEN)
*/ */
int int
smartlist_digest_isin(const smartlist_t *sl, const char *element) smartlist_digest_isin(const smartlist_t *sl, const char *element)
@ -224,7 +224,7 @@ smartlist_digest_isin(const smartlist_t *sl, const char *element)
int i; int i;
if (!sl) return 0; if (!sl) return 0;
for (i=0; i < sl->num_used; i++) for (i=0; i < sl->num_used; i++)
if (memcmp((const char*)sl->list[i],element,DIGEST_LEN)==0) if (tor_memeq((const char*)sl->list[i],element,DIGEST_LEN))
return 1; return 1;
return 0; return 0;
} }
@ -801,7 +801,7 @@ smartlist_pqueue_assert_ok(smartlist_t *sl,
static int static int
_compare_digests(const void **_a, const void **_b) _compare_digests(const void **_a, const void **_b)
{ {
return memcmp((const char*)*_a, (const char*)*_b, DIGEST_LEN); return tor_memcmp((const char*)*_a, (const char*)*_b, DIGEST_LEN);
} }
/** Sort the list of DIGEST_LEN-byte digests into ascending order. */ /** Sort the list of DIGEST_LEN-byte digests into ascending order. */
@ -823,7 +823,7 @@ smartlist_uniq_digests(smartlist_t *sl)
static int static int
_compare_digests256(const void **_a, const void **_b) _compare_digests256(const void **_a, const void **_b)
{ {
return memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN); return tor_memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN);
} }
/** Sort the list of DIGEST256_LEN-byte digests into ascending order. */ /** Sort the list of DIGEST256_LEN-byte digests into ascending order. */
@ -885,7 +885,7 @@ strmap_entry_hash(const strmap_entry_t *a)
static INLINE int static INLINE int
digestmap_entries_eq(const digestmap_entry_t *a, const digestmap_entry_t *b) digestmap_entries_eq(const digestmap_entry_t *a, const digestmap_entry_t *b)
{ {
return !memcmp(a->key, b->key, DIGEST_LEN); return tor_memeq(a->key, b->key, DIGEST_LEN);
} }
/** Helper: return a hash value for a digest_map_t. */ /** Helper: return a hash value for a digest_map_t. */

View File

@ -259,7 +259,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
* Example use: * Example use:
* SMARTLIST_FOREACH_JOIN(routerstatus_list, routerstatus_t *, rs, * SMARTLIST_FOREACH_JOIN(routerstatus_list, routerstatus_t *, rs,
* routerinfo_list, routerinfo_t *, ri, * routerinfo_list, routerinfo_t *, ri,
* memcmp(rs->identity_digest, ri->identity_digest, 20), * tor_memcmp(rs->identity_digest, ri->identity_digest, 20),
* log_info(LD_GENERAL,"No match for %s", ri->nickname)) { * log_info(LD_GENERAL,"No match for %s", ri->nickname)) {
* log_info(LD_GENERAL, "%s matches routerstatus %p", ri->nickname, rs); * log_info(LD_GENERAL, "%s matches routerstatus %p", ri->nickname, rs);
* } SMARTLIST_FOREACH_JOIN_END(rs, ri); * } SMARTLIST_FOREACH_JOIN_END(rs, ri);
@ -274,7 +274,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
* ri = smartlist_get(routerinfo_list, ri_sl_idx); * ri = smartlist_get(routerinfo_list, ri_sl_idx);
* while (rs_sl_idx < rs_sl_len) { * while (rs_sl_idx < rs_sl_len) {
* rs = smartlist_get(routerstatus_list, rs_sl_idx); * rs = smartlist_get(routerstatus_list, rs_sl_idx);
* rs_ri_cmp = memcmp(rs->identity_digest, ri->identity_digest, 20); * rs_ri_cmp = tor_memcmp(rs->identity_digest, ri->identity_digest, 20);
* if (rs_ri_cmp > 0) { * if (rs_ri_cmp > 0) {
* break; * break;
* } else if (rs_ri_cmp == 0) { * } else if (rs_ri_cmp == 0) {

View File

@ -933,7 +933,7 @@ crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const char *data,
tor_free(buf); tor_free(buf);
return -1; return -1;
} }
if (memcmp(buf, digest, DIGEST_LEN)) { if (tor_memneq(buf, digest, DIGEST_LEN)) {
log_warn(LD_CRYPTO, "Signature mismatched with digest."); log_warn(LD_CRYPTO, "Signature mismatched with digest.");
tor_free(buf); tor_free(buf);
return -1; return -1;

133
src/common/di_ops.c Normal file
View File

@ -0,0 +1,133 @@
/* Copyright (c) 2011, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file di_ops.c
* \brief Functions for data-independent operations
**/
#include "orconfig.h"
#include "di_ops.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>, and returns 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>.
*
* 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)
{
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;
}
/**
* 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>, 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
*/
return 1 & ((any_difference - 1) >> 8);
}

30
src/common/di_ops.h Normal file
View File

@ -0,0 +1,30 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2011, 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 "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)))
#endif

View File

@ -378,7 +378,7 @@ tor_gzip_uncompress(char **out, size_t *out_len,
compress_method_t compress_method_t
detect_compression_method(const char *in, size_t in_len) detect_compression_method(const char *in, size_t in_len)
{ {
if (in_len > 2 && !memcmp(in, "\x1f\x8b", 2)) { if (in_len > 2 && fast_memeq(in, "\x1f\x8b", 2)) {
return GZIP_METHOD; return GZIP_METHOD;
} else if (in_len > 2 && (in[0] & 0x0f) == 8 && } else if (in_len > 2 && (in[0] & 0x0f) == 8 &&
(ntohs(get_uint16(in)) % 31) == 0) { (ntohs(get_uint16(in)) % 31) == 0) {

View File

@ -516,7 +516,7 @@ strcmp_len(const char *s1, const char *s2, size_t s1_len)
return -1; return -1;
if (s1_len > s2_len) if (s1_len > s2_len)
return 1; return 1;
return memcmp(s1, s2, s2_len); return fast_memcmp(s1, s2, s2_len);
} }
/** Compares the first strlen(s2) characters of s1 with s2. Returns as for /** Compares the first strlen(s2) characters of s1 with s2. Returns as for
@ -558,17 +558,17 @@ strcasecmpend(const char *s1, const char *s2)
/** Compare the value of the string <b>prefix</b> with the start of the /** Compare the value of the string <b>prefix</b> with the start of the
* <b>memlen</b>-byte memory chunk at <b>mem</b>. Return as for strcmp. * <b>memlen</b>-byte memory chunk at <b>mem</b>. Return as for strcmp.
* *
* [As memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is less * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
* than strlen(prefix).] * less than strlen(prefix).]
*/ */
int int
memcmpstart(const void *mem, size_t memlen, fast_memcmpstart(const void *mem, size_t memlen,
const char *prefix) const char *prefix)
{ {
size_t plen = strlen(prefix); size_t plen = strlen(prefix);
if (memlen < plen) if (memlen < plen)
return -1; return -1;
return memcmp(mem, prefix, plen); return fast_memcmp(mem, prefix, plen);
} }
/** Return a pointer to the first char of s that is not whitespace and /** Return a pointer to the first char of s that is not whitespace and
@ -724,14 +724,16 @@ tor_mem_is_zero(const char *mem, size_t len)
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
}; };
while (len >= sizeof(ZERO)) { while (len >= sizeof(ZERO)) {
if (memcmp(mem, ZERO, sizeof(ZERO))) /* It's safe to use fast_memcmp here, since the very worst thing an
* attacker could learn is how many initial bytes of a secret were zero */
if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
return 0; return 0;
len -= sizeof(ZERO); len -= sizeof(ZERO);
mem += sizeof(ZERO); mem += sizeof(ZERO);
} }
/* Deal with leftover bytes. */ /* Deal with leftover bytes. */
if (len) if (len)
return ! memcmp(mem, ZERO, len); return fast_memeq(mem, ZERO, len);
return 1; return 1;
} }
@ -740,7 +742,10 @@ tor_mem_is_zero(const char *mem, size_t len)
int int
tor_digest_is_zero(const char *digest) tor_digest_is_zero(const char *digest)
{ {
return tor_mem_is_zero(digest, DIGEST_LEN); static const uint8_t ZERO_DIGEST[] = {
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
};
return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
} }
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */ /** Return true iff the DIGEST256_LEN bytes in digest are all zero. */

View File

@ -14,6 +14,7 @@
#include "orconfig.h" #include "orconfig.h"
#include "torint.h" #include "torint.h"
#include "compat.h" #include "compat.h"
#include "di_ops.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -181,7 +182,7 @@ int strcasecmpstart(const char *s1, const char *s2)
int strcmpend(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2)); int strcmpend(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2));
int strcasecmpend(const char *s1, const char *s2) int strcasecmpend(const char *s1, const char *s2)
ATTR_PURE ATTR_NONNULL((1,2)); ATTR_PURE ATTR_NONNULL((1,2));
int memcmpstart(const void *mem, size_t memlen, int fast_memcmpstart(const void *mem, size_t memlen,
const char *prefix) ATTR_PURE; const char *prefix) ATTR_PURE;
void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2)); void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));

View File

@ -1818,7 +1818,7 @@ circuit_n_conn_done(or_connection_t *or_conn, int status)
continue; continue;
} else { } else {
/* We expected a key. See if it's the right one. */ /* We expected a key. See if it's the right one. */
if (memcmp(or_conn->identity_digest, if (tor_memneq(or_conn->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN)) circ->n_hop->identity_digest, DIGEST_LEN))
continue; continue;
} }
@ -2226,7 +2226,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
/* Next, check if we're being asked to connect to the hop that the /* Next, check if we're being asked to connect to the hop that the
* extend cell came from. There isn't any reason for that, and it can * extend cell came from. There isn't any reason for that, and it can
* assist circular-path attacks. */ * assist circular-path attacks. */
if (!memcmp(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest, if (tor_memeq(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Client asked me to extend back to the previous hop."); "Client asked me to extend back to the previous hop.");
@ -3527,7 +3527,7 @@ static INLINE entry_guard_t *
is_an_entry_guard(const char *digest) is_an_entry_guard(const char *digest)
{ {
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry, SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
if (!memcmp(digest, entry->identity, DIGEST_LEN)) if (tor_memeq(digest, entry->identity, DIGEST_LEN))
return entry; return entry;
); );
return NULL; return NULL;
@ -3860,7 +3860,7 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e, SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
{ {
if (!memcmp(e->identity, digest, DIGEST_LEN)) { if (tor_memeq(e->identity, digest, DIGEST_LEN)) {
entry = e; entry = e;
idx = e_sl_idx; idx = e_sl_idx;
break; break;
@ -4524,7 +4524,7 @@ get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
!tor_addr_compare(&bridge->addr, addr, CMP_EXACT) && !tor_addr_compare(&bridge->addr, addr, CMP_EXACT) &&
bridge->port == port) bridge->port == port)
return bridge; return bridge;
if (!memcmp(bridge->identity, digest, DIGEST_LEN)) if (tor_memeq(bridge->identity, digest, DIGEST_LEN))
return bridge; return bridge;
} }
SMARTLIST_FOREACH_END(bridge); SMARTLIST_FOREACH_END(bridge);
@ -4605,7 +4605,7 @@ find_bridge_by_digest(const char *digest)
{ {
SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge, SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
{ {
if (!memcmp(bridge->identity, digest, DIGEST_LEN)) if (tor_memeq(bridge->identity, digest, DIGEST_LEN))
return bridge; return bridge;
}); });
return NULL; return NULL;

View File

@ -254,7 +254,7 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
continue; continue;
} else { } else {
/* We expected a key. See if it's the right one. */ /* We expected a key. See if it's the right one. */
if (memcmp(or_conn->identity_digest, if (tor_memneq(or_conn->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN)) circ->n_hop->identity_digest, DIGEST_LEN))
continue; continue;
} }
@ -717,7 +717,7 @@ circuit_dump_by_conn(connection_t *conn, int severity)
tor_addr_eq(&circ->n_hop->addr, &conn->addr) && tor_addr_eq(&circ->n_hop->addr, &conn->addr) &&
circ->n_hop->port == conn->port && circ->n_hop->port == conn->port &&
conn->type == CONN_TYPE_OR && conn->type == CONN_TYPE_OR &&
!memcmp(TO_OR_CONN(conn)->identity_digest, tor_memeq(TO_OR_CONN(conn)->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN)) { circ->n_hop->identity_digest, DIGEST_LEN)) {
circuit_dump_details(severity, circ, conn->conn_array_index, circuit_dump_details(severity, circ, conn->conn_array_index,
(circ->state == CIRCUIT_STATE_OPEN && (circ->state == CIRCUIT_STATE_OPEN &&
@ -911,7 +911,7 @@ circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
if (!digest) if (!digest)
return TO_ORIGIN_CIRCUIT(circ); return TO_ORIGIN_CIRCUIT(circ);
else if (TO_ORIGIN_CIRCUIT(circ)->rend_data && else if (TO_ORIGIN_CIRCUIT(circ)->rend_data &&
!memcmp(TO_ORIGIN_CIRCUIT(circ)->rend_data->rend_pk_digest, tor_memeq(TO_ORIGIN_CIRCUIT(circ)->rend_data->rend_pk_digest,
digest, DIGEST_LEN)) digest, DIGEST_LEN))
return TO_ORIGIN_CIRCUIT(circ); return TO_ORIGIN_CIRCUIT(circ);
} }
@ -929,7 +929,7 @@ circuit_get_by_rend_token_and_purpose(uint8_t purpose, const char *token,
for (circ = global_circuitlist; circ; circ = circ->next) { for (circ = global_circuitlist; circ; circ = circ->next) {
if (! circ->marked_for_close && if (! circ->marked_for_close &&
circ->purpose == purpose && circ->purpose == purpose &&
! memcmp(TO_OR_CIRCUIT(circ)->rend_token, token, len)) tor_memeq(TO_OR_CIRCUIT(circ)->rend_token, token, len))
return TO_OR_CIRCUIT(circ); return TO_OR_CIRCUIT(circ);
} }
return NULL; return NULL;
@ -1006,7 +1006,7 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
const node_t *ri1 = node_get_by_id(info->identity_digest); const node_t *ri1 = node_get_by_id(info->identity_digest);
do { do {
const node_t *ri2; const node_t *ri2;
if (!memcmp(hop->extend_info->identity_digest, if (tor_memeq(hop->extend_info->identity_digest,
info->identity_digest, DIGEST_LEN)) info->identity_digest, DIGEST_LEN))
goto next; goto next;
if (ri1 && if (ri1 &&

View File

@ -109,7 +109,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
char digest[DIGEST_LEN]; char digest[DIGEST_LEN];
if (hexdigest_to_digest(conn->chosen_exit_name, digest) < 0) if (hexdigest_to_digest(conn->chosen_exit_name, digest) < 0)
return 0; /* broken digest, we don't want it */ return 0; /* broken digest, we don't want it */
if (memcmp(digest, build_state->chosen_exit->identity_digest, if (tor_memneq(digest, build_state->chosen_exit->identity_digest,
DIGEST_LEN)) DIGEST_LEN))
return 0; /* this is a circuit to somewhere else */ return 0; /* this is a circuit to somewhere else */
if (tor_digest_is_zero(digest)) { if (tor_digest_is_zero(digest)) {

View File

@ -577,7 +577,7 @@ connection_ap_fail_onehop(const char *failed_digest,
if (!edge_conn->want_onehop) if (!edge_conn->want_onehop)
continue; continue;
if (hexdigest_to_digest(edge_conn->chosen_exit_name, digest) < 0 || if (hexdigest_to_digest(edge_conn->chosen_exit_name, digest) < 0 ||
memcmp(digest, failed_digest, DIGEST_LEN)) tor_memneq(digest, failed_digest, DIGEST_LEN))
continue; continue;
if (tor_digest_is_zero(digest)) { if (tor_digest_is_zero(digest)) {
/* we don't know the digest; have to compare addr:port */ /* we don't know the digest; have to compare addr:port */
@ -3072,7 +3072,7 @@ connection_ap_can_use_exit(edge_connection_t *conn, const node_t *exit)
if (conn->chosen_exit_name) { if (conn->chosen_exit_name) {
const node_t *chosen_exit = const node_t *chosen_exit =
node_get_by_nickname(conn->chosen_exit_name, 1); node_get_by_nickname(conn->chosen_exit_name, 1);
if (!chosen_exit || memcmp(chosen_exit->identity, if (!chosen_exit || tor_memneq(chosen_exit->identity,
exit->identity, DIGEST_LEN)) { exit->identity, DIGEST_LEN)) {
/* doesn't match */ /* doesn't match */
// log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.", // log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.",

View File

@ -124,7 +124,7 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
if (!orconn_identity_map) if (!orconn_identity_map)
orconn_identity_map = digestmap_new(); orconn_identity_map = digestmap_new();
if (!memcmp(conn->identity_digest, digest, DIGEST_LEN)) if (tor_memeq(conn->identity_digest, digest, DIGEST_LEN))
return; return;
/* If the identity was set previously, remove the old mapping. */ /* If the identity was set previously, remove the old mapping. */
@ -143,7 +143,7 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
#if 1 #if 1
/* Testing code to check for bugs in representation. */ /* Testing code to check for bugs in representation. */
for (; tmp; tmp = tmp->next_with_same_id) { for (; tmp; tmp = tmp->next_with_same_id) {
tor_assert(!memcmp(tmp->identity_digest, digest, DIGEST_LEN)); tor_assert(tor_memeq(tmp->identity_digest, digest, DIGEST_LEN));
tor_assert(tmp != conn); tor_assert(tmp != conn);
} }
#endif #endif
@ -585,7 +585,7 @@ connection_or_get_for_extend(const char *digest,
for (; conn; conn = conn->next_with_same_id) { for (; conn; conn = conn->next_with_same_id) {
tor_assert(conn->_base.magic == OR_CONNECTION_MAGIC); tor_assert(conn->_base.magic == OR_CONNECTION_MAGIC);
tor_assert(conn->_base.type == CONN_TYPE_OR); tor_assert(conn->_base.type == CONN_TYPE_OR);
tor_assert(!memcmp(conn->identity_digest, digest, DIGEST_LEN)); tor_assert(tor_memeq(conn->identity_digest, digest, DIGEST_LEN));
if (conn->_base.marked_for_close) if (conn->_base.marked_for_close)
continue; continue;
/* Never return a non-open connection. */ /* Never return a non-open connection. */
@ -788,7 +788,7 @@ connection_or_set_bad_connections(const char *digest, int force)
return; return;
DIGESTMAP_FOREACH(orconn_identity_map, identity, or_connection_t *, conn) { DIGESTMAP_FOREACH(orconn_identity_map, identity, or_connection_t *, conn) {
if (!digest || !memcmp(digest, conn->identity_digest, DIGEST_LEN)) if (!digest || tor_memeq(digest, conn->identity_digest, DIGEST_LEN))
connection_or_group_set_badness(conn, force); connection_or_group_set_badness(conn, force);
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
} }
@ -1221,7 +1221,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
int as_advertised = 1; int as_advertised = 1;
tor_assert(has_cert); tor_assert(has_cert);
tor_assert(has_identity); tor_assert(has_identity);
if (memcmp(digest_rcvd_out, conn->identity_digest, DIGEST_LEN)) { if (tor_memneq(digest_rcvd_out, conn->identity_digest, DIGEST_LEN)) {
/* I was aiming for a particular digest. I didn't get it! */ /* I was aiming for a particular digest. I didn't get it! */
char seen[HEX_DIGEST_LEN+1]; char seen[HEX_DIGEST_LEN+1];
char expected[HEX_DIGEST_LEN+1]; char expected[HEX_DIGEST_LEN+1];

View File

@ -341,7 +341,7 @@ write_escaped_data(const char *data, size_t len, char **out)
} }
*outp++ = *data++; *outp++ = *data++;
} }
if (outp < *out+2 || memcmp(outp-2, "\r\n", 2)) { if (outp < *out+2 || fast_memcmp(outp-2, "\r\n", 2)) {
*outp++ = '\r'; *outp++ = '\r';
*outp++ = '\n'; *outp++ = '\n';
} }
@ -507,7 +507,7 @@ connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
return; return;
} }
len = strlen(buf); len = strlen(buf);
if (memcmp("\r\n\0", buf+len-2, 3)) { if (fast_memcmp("\r\n\0", buf+len-2, 3)) {
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0'; buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0';
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n'; buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r'; buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
@ -588,7 +588,7 @@ send_control_event_impl(uint16_t event, event_format_t which,
} }
len = strlen(buf); len = strlen(buf);
if (memcmp("\r\n\0", buf+len-2, 3)) { if (fast_memcmp("\r\n\0", buf+len-2, 3)) {
/* if it is not properly terminated, do it now */ /* if it is not properly terminated, do it now */
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0'; buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0';
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n'; buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n';
@ -1078,7 +1078,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
goto err; goto err;
} }
bad_cookie = 1; bad_cookie = 1;
} else if (memcmp(authentication_cookie, password, password_len)) { } else if (tor_memneq(authentication_cookie, password, password_len)) {
if (!also_password) { if (!also_password) {
log_warn(LD_CONTROL, "Got mismatched authentication cookie"); log_warn(LD_CONTROL, "Got mismatched authentication cookie");
errstr = "Authentication cookie did not match expected value."; errstr = "Authentication cookie did not match expected value.";
@ -1128,7 +1128,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
SMARTLIST_FOREACH(sl, char *, expected, SMARTLIST_FOREACH(sl, char *, expected,
{ {
secret_to_key(received,DIGEST_LEN,password,password_len,expected); secret_to_key(received,DIGEST_LEN,password,password_len,expected);
if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN)) if (tor_memeq(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
goto ok; goto ok;
}); });
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
@ -2921,13 +2921,13 @@ connection_control_process_inbuf(control_connection_t *conn)
break; break;
/* XXXX this code duplication is kind of dumb. */ /* XXXX this code duplication is kind of dumb. */
if (last_idx+3 == conn->incoming_cmd_cur_len && if (last_idx+3 == conn->incoming_cmd_cur_len &&
!memcmp(conn->incoming_cmd + last_idx, ".\r\n", 3)) { tor_memeq(conn->incoming_cmd + last_idx, ".\r\n", 3)) {
/* Just appended ".\r\n"; we're done. Remove it. */ /* Just appended ".\r\n"; we're done. Remove it. */
conn->incoming_cmd[last_idx] = '\0'; conn->incoming_cmd[last_idx] = '\0';
conn->incoming_cmd_cur_len -= 3; conn->incoming_cmd_cur_len -= 3;
break; break;
} else if (last_idx+2 == conn->incoming_cmd_cur_len && } else if (last_idx+2 == conn->incoming_cmd_cur_len &&
!memcmp(conn->incoming_cmd + last_idx, ".\n", 2)) { tor_memeq(conn->incoming_cmd + last_idx, ".\n", 2)) {
/* Just appended ".\n"; we're done. Remove it. */ /* Just appended ".\n"; we're done. Remove it. */
conn->incoming_cmd[last_idx] = '\0'; conn->incoming_cmd[last_idx] = '\0';
conn->incoming_cmd_cur_len -= 2; conn->incoming_cmd_cur_len -= 2;

View File

@ -2541,7 +2541,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
SMARTLIST_FOREACH_BEGIN(v->voters, networkstatus_voter_info_t *, vi) { SMARTLIST_FOREACH_BEGIN(v->voters, networkstatus_voter_info_t *, vi) {
if (smartlist_len(vi->sigs) && if (smartlist_len(vi->sigs) &&
!memcmp(vi->identity_digest, want_digest, want_len)) { tor_memeq(vi->identity_digest, want_digest, want_len)) {
have++; have++;
break; break;
}; };
@ -3744,17 +3744,17 @@ dir_microdesc_download_failed(smartlist_t *failed,
} SMARTLIST_FOREACH_END(d); } SMARTLIST_FOREACH_END(d);
} }
/** Helper. Compare two fp_pair_t objects, and return -1, 0, or 1 as /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
* appropriate. */ * positive as appropriate. */
static int static int
_compare_pairs(const void **a, const void **b) _compare_pairs(const void **a, const void **b)
{ {
const fp_pair_t *fp1 = *a, *fp2 = *b; const fp_pair_t *fp1 = *a, *fp2 = *b;
int r; int r;
if ((r = memcmp(fp1->first, fp2->first, DIGEST_LEN))) if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
return r; return r;
else else
return memcmp(fp1->second, fp2->second, DIGEST_LEN); return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
} }
/** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each

View File

@ -2116,7 +2116,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
/* This assert can fire for the control port, because /* This assert can fire for the control port, because
* it can request NS documents before all descriptors * it can request NS documents before all descriptors
* have been fetched. */ * have been fetched. */
if (memcmp(desc->cache_info.signed_descriptor_digest, if (tor_memneq(desc->cache_info.signed_descriptor_digest,
rs->descriptor_digest, rs->descriptor_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
char rl_d[HEX_DIGEST_LEN+1]; char rl_d[HEX_DIGEST_LEN+1];
@ -2132,7 +2132,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
"(router %s)\n", "(router %s)\n",
rl_d, rs_d, id); rl_d, rs_d, id);
tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest, tor_assert(tor_memeq(desc->cache_info.signed_descriptor_digest,
rs->descriptor_digest, rs->descriptor_digest,
DIGEST_LEN)); DIGEST_LEN));
}; };
@ -2234,7 +2234,7 @@ _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
/* They're equal! Compare by identity digest, so there's a /* They're equal! Compare by identity digest, so there's a
* deterministic order and we avoid flapping. */ * deterministic order and we avoid flapping. */
return memcmp(first->cache_info.identity_digest, return fast_memcmp(first->cache_info.identity_digest,
second->cache_info.identity_digest, second->cache_info.identity_digest,
DIGEST_LEN); DIGEST_LEN);
} }
@ -3185,7 +3185,7 @@ dirserv_orconn_tls_done(const char *address,
SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) { SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
if (!strcasecmp(address, ri->address) && or_port == ri->or_port && if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
as_advertised && as_advertised &&
!memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) { fast_memeq(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
/* correct digest. mark this router reachable! */ /* correct digest. mark this router reachable! */
if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) { if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
tor_addr_t addr, *addrp=NULL; tor_addr_t addr, *addrp=NULL;

View File

@ -337,7 +337,7 @@ static int
_compare_votes_by_authority_id(const void **_a, const void **_b) _compare_votes_by_authority_id(const void **_a, const void **_b)
{ {
const networkstatus_t *a = *_a, *b = *_b; const networkstatus_t *a = *_a, *b = *_b;
return memcmp(get_voter(a)->identity_digest, return fast_memcmp(get_voter(a)->identity_digest,
get_voter(b)->identity_digest, DIGEST_LEN); get_voter(b)->identity_digest, DIGEST_LEN);
} }
@ -354,7 +354,7 @@ _compare_dir_src_ents_by_authority_id(const void **_a, const void **_b)
a_id = a->is_legacy ? a_v->legacy_id_digest : a_v->identity_digest; a_id = a->is_legacy ? a_v->legacy_id_digest : a_v->identity_digest;
b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest; b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
return memcmp(a_id, b_id, DIGEST_LEN); return fast_memcmp(a_id, b_id, DIGEST_LEN);
} }
/** Given a sorted list of strings <b>in</b>, add every member to <b>out</b> /** Given a sorted list of strings <b>in</b>, add every member to <b>out</b>
@ -391,10 +391,10 @@ static int
compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b) compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
{ {
int r; int r;
if ((r = memcmp(a->status.identity_digest, b->status.identity_digest, if ((r = fast_memcmp(a->status.identity_digest, b->status.identity_digest,
DIGEST_LEN))) DIGEST_LEN)))
return r; return r;
if ((r = memcmp(a->status.descriptor_digest, b->status.descriptor_digest, if ((r = fast_memcmp(a->status.descriptor_digest, b->status.descriptor_digest,
DIGEST_LEN))) DIGEST_LEN)))
return r; return r;
if ((r = (int)(b->status.published_on - a->status.published_on))) if ((r = (int)(b->status.published_on - a->status.published_on)))
@ -1641,7 +1641,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
strmap_set_lc(name_to_id_map, rs->status.nickname, strmap_set_lc(name_to_id_map, rs->status.nickname,
rs->status.identity_digest); rs->status.identity_digest);
} else if (d != conflict && } else if (d != conflict &&
memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { fast_memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
/* Authorities disagree about this nickname. */ /* Authorities disagree about this nickname. */
strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
} else { } else {
@ -1665,7 +1665,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
} else if (!d) { } else if (!d) {
/* We have no name officially mapped to this digest. */ /* We have no name officially mapped to this digest. */
strmap_set_lc(name_to_id_map, rs->status.nickname, unknown); strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
} else if (!memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { } else if (fast_memeq(d, rs->status.identity_digest, DIGEST_LEN)) {
/* Authorities disagree about this nickname. */ /* Authorities disagree about this nickname. */
strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
} else { } else {
@ -1698,7 +1698,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (index[v_sl_idx] < size[v_sl_idx]) { if (index[v_sl_idx] < size[v_sl_idx]) {
rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]); rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
if (!lowest_id || if (!lowest_id ||
memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN) < 0) fast_memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN) < 0)
lowest_id = rs->status.identity_digest; lowest_id = rs->status.identity_digest;
} }
}); });
@ -1717,7 +1717,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (index[v_sl_idx] >= size[v_sl_idx]) if (index[v_sl_idx] >= size[v_sl_idx])
continue; /* out of entries. */ continue; /* out of entries. */
rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]); rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
if (memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN)) if (fast_memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
continue; /* doesn't include this router. */ continue; /* doesn't include this router. */
/* At this point, we know that we're looking at a routerstatus with /* At this point, we know that we're looking at a routerstatus with
* identity "lowest". * identity "lowest".
@ -1762,7 +1762,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
rs = compute_routerstatus_consensus(matching_descs, consensus_method, rs = compute_routerstatus_consensus(matching_descs, consensus_method,
microdesc_digest); microdesc_digest);
/* Copy bits of that into rs_out. */ /* Copy bits of that into rs_out. */
tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN)); tor_assert(fast_memeq(lowest_id, rs->status.identity_digest, DIGEST_LEN));
memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN); memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest, memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
DIGEST_LEN); DIGEST_LEN);
@ -1786,7 +1786,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname); const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
if (!d) { if (!d) {
is_named = is_unnamed = 0; is_named = is_unnamed = 0;
} else if (!memcmp(d, lowest_id, DIGEST_LEN)) { } else if (fast_memeq(d, lowest_id, DIGEST_LEN)) {
is_named = 1; is_unnamed = 0; is_named = 1; is_unnamed = 0;
} else { } else {
is_named = 0; is_unnamed = 1; is_named = 0; is_unnamed = 1;
@ -1884,11 +1884,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, { SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
/* Check if the vote where this status comes from had the /* Check if the vote where this status comes from had the
* proper descriptor */ * proper descriptor */
tor_assert(!memcmp(rs_out.identity_digest, tor_assert(fast_memeq(rs_out.identity_digest,
vsr->status.identity_digest, vsr->status.identity_digest,
DIGEST_LEN)); DIGEST_LEN));
if (vsr->status.has_exitsummary && if (vsr->status.has_exitsummary &&
!memcmp(rs_out.descriptor_digest, fast_memeq(rs_out.descriptor_digest,
vsr->status.descriptor_digest, vsr->status.descriptor_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
tor_assert(vsr->status.exitsummary); tor_assert(vsr->status.exitsummary);
@ -2204,7 +2204,7 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
} }
for (alg = DIGEST_SHA1; alg < N_DIGEST_ALGORITHMS; ++alg) { for (alg = DIGEST_SHA1; alg < N_DIGEST_ALGORITHMS; ++alg) {
if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) { if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
if (!memcmp(target->digests.d[alg], digests->d[alg], DIGEST256_LEN)) { if (fast_memeq(target->digests.d[alg], digests->d[alg], DIGEST256_LEN)) {
++n_matches; ++n_matches;
} else { } else {
*msg_out = "Mismatched digest."; *msg_out = "Mismatched digest.";
@ -2968,11 +2968,11 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
/* Now see whether we already have a vote from this authority. */ /* Now see whether we already have a vote from this authority. */
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, { SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
if (! memcmp(v->vote->cert->cache_info.identity_digest, if (fast_memeq(v->vote->cert->cache_info.identity_digest,
vote->cert->cache_info.identity_digest, vote->cert->cache_info.identity_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
networkstatus_voter_info_t *vi_old = get_voter(v->vote); networkstatus_voter_info_t *vi_old = get_voter(v->vote);
if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) { if (fast_memeq(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
/* Ah, it's the same vote. Not a problem. */ /* Ah, it's the same vote. Not a problem. */
log_info(LD_DIR, "Discarding a vote we already have (from %s).", log_info(LD_DIR, "Discarding a vote we already have (from %s).",
vi->address); vi->address);
@ -3473,23 +3473,23 @@ dirvote_get_vote(const char *fp, int flags)
if (by_id) { if (by_id) {
if (pending_vote_list && include_pending) { if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv, SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN)) if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body); return pv->vote_body);
} }
if (previous_vote_list && include_previous) { if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv, SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN)) if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body); return pv->vote_body);
} }
} else { } else {
if (pending_vote_list && include_pending) { if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv, SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body); return pv->vote_body);
} }
if (previous_vote_list && include_previous) { if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv, SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body); return pv->vote_body);
} }
} }
@ -3608,7 +3608,7 @@ vote_routerstatus_find_microdesc_hash(char *digest256_out,
* the first part. */ * the first part. */
while (1) { while (1) {
num_len = strspn(cp, "1234567890"); num_len = strspn(cp, "1234567890");
if (num_len == mlen && !memcmp(mstr, cp, mlen)) { if (num_len == mlen && fast_memeq(mstr, cp, mlen)) {
/* This is the line. */ /* This is the line. */
char buf[BASE64_DIGEST256_LEN+1]; char buf[BASE64_DIGEST256_LEN+1];
/* XXXX ignores extraneous stuff if the digest is too long. This /* XXXX ignores extraneous stuff if the digest is too long. This

View File

@ -461,7 +461,7 @@ sockaddr_eq(const struct sockaddr *sa1, const struct sockaddr *sa2,
const struct sockaddr_in6 *sin1, *sin2; const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *)sa1; sin1 = (const struct sockaddr_in6 *)sa1;
sin2 = (const struct sockaddr_in6 *)sa2; sin2 = (const struct sockaddr_in6 *)sa2;
if (memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)) if (tor_memneq(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16))
return 0; return 0;
else if (include_port && sin1->sin6_port != sin2->sin6_port) else if (include_port && sin1->sin6_port != sin2->sin6_port)
return 0; return 0;
@ -2253,7 +2253,7 @@ sockaddr_is_loopback(const struct sockaddr *addr)
return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000; return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
} else if (addr->sa_family == AF_INET6) { } else if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16); return fast_memeq(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
} }
return 0; return 0;
} }

View File

@ -55,7 +55,7 @@ _microdesc_hash(microdesc_t *md)
static INLINE int static INLINE int
_microdesc_eq(microdesc_t *a, microdesc_t *b) _microdesc_eq(microdesc_t *a, microdesc_t *b)
{ {
return !memcmp(a->digest, b->digest, DIGEST256_LEN); return tor_memeq(a->digest, b->digest, DIGEST256_LEN);
} }
HT_PROTOTYPE(microdesc_map, microdesc_t, node, HT_PROTOTYPE(microdesc_map, microdesc_t, node,
@ -477,7 +477,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
" with \"onion-key\". Instead I got %s.", " with \"onion-key\". Instead I got %s.",
(int)md->off, escaped(bad_str)); (int)md->off, escaped(bad_str));
tor_free(bad_str); tor_free(bad_str);
tor_assert(!memcmp(md->body, "onion-key", 9)); tor_assert(fast_memeq(md->body, "onion-key", 9));
} }
} SMARTLIST_FOREACH_END(md); } SMARTLIST_FOREACH_END(md);

View File

@ -424,7 +424,7 @@ networkstatus_get_voter_by_id(networkstatus_t *vote,
if (!vote || !vote->voters) if (!vote || !vote->voters)
return NULL; return NULL;
SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter, SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter,
if (!memcmp(voter->identity_digest, identity, DIGEST_LEN)) if (fast_memeq(voter->identity_digest, identity, DIGEST_LEN))
return voter); return voter);
return NULL; return NULL;
} }
@ -445,8 +445,8 @@ networkstatus_check_document_signature(const networkstatus_t *consensus,
if (crypto_pk_get_digest(cert->signing_key, key_digest)<0) if (crypto_pk_get_digest(cert->signing_key, key_digest)<0)
return -1; return -1;
if (memcmp(sig->signing_key_digest, key_digest, DIGEST_LEN) || if (tor_memneq(sig->signing_key_digest, key_digest, DIGEST_LEN) ||
memcmp(sig->identity_digest, cert->cache_info.identity_digest, tor_memneq(sig->identity_digest, cert->cache_info.identity_digest,
DIGEST_LEN)) DIGEST_LEN))
return -1; return -1;
@ -457,7 +457,7 @@ networkstatus_check_document_signature(const networkstatus_t *consensus,
signed_digest_len, signed_digest_len,
sig->signature, sig->signature,
sig->signature_len) < dlen || sig->signature_len) < dlen ||
memcmp(signed_digest, consensus->digests.d[sig->alg], dlen)) { tor_memneq(signed_digest, consensus->digests.d[sig->alg], dlen)) {
log_warn(LD_DIR, "Got a bad signature on a networkstatus vote"); log_warn(LD_DIR, "Got a bad signature on a networkstatus vote");
sig->bad_signature = 1; sig->bad_signature = 1;
} else { } else {
@ -509,7 +509,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
authority_cert_t *cert = authority_cert_t *cert =
authority_cert_get_by_digests(sig->identity_digest, authority_cert_get_by_digests(sig->identity_digest,
sig->signing_key_digest); sig->signing_key_digest);
tor_assert(!memcmp(sig->identity_digest, voter->identity_digest, tor_assert(tor_memeq(sig->identity_digest, voter->identity_digest,
DIGEST_LEN)); DIGEST_LEN));
if (!is_v3_auth) { if (!is_v3_auth) {
@ -812,8 +812,8 @@ router_set_networkstatus_v2(const char *s, time_t arrived_at,
for (i=0; i < smartlist_len(networkstatus_v2_list); ++i) { for (i=0; i < smartlist_len(networkstatus_v2_list); ++i) {
networkstatus_v2_t *old_ns = smartlist_get(networkstatus_v2_list, i); networkstatus_v2_t *old_ns = smartlist_get(networkstatus_v2_list, i);
if (!memcmp(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) { if (tor_memeq(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) {
if (!memcmp(old_ns->networkstatus_digest, if (tor_memeq(old_ns->networkstatus_digest,
ns->networkstatus_digest, DIGEST_LEN)) { ns->networkstatus_digest, DIGEST_LEN)) {
/* Same one we had before. */ /* Same one we had before. */
networkstatus_v2_free(ns); networkstatus_v2_free(ns);
@ -939,7 +939,7 @@ compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
{ {
const char *key = _key; const char *key = _key;
const routerstatus_t *rs = *_member; const routerstatus_t *rs = *_member;
return memcmp(key, rs->identity_digest, DIGEST_LEN); return tor_memcmp(key, rs->identity_digest, DIGEST_LEN);
} }
/** As networkstatus_v2_find_entry, but do not return a const pointer */ /** As networkstatus_v2_find_entry, but do not return a const pointer */
@ -1404,7 +1404,7 @@ networkstatus_v2_get_by_digest(const char *digest)
{ {
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
{ {
if (!memcmp(ns->identity_digest, digest, DIGEST_LEN)) if (tor_memeq(ns->identity_digest, digest, DIGEST_LEN))
return ns; return ns;
}); });
return NULL; return NULL;
@ -1467,10 +1467,10 @@ networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
static int static int
routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b) routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
{ {
tor_assert(!memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN)); tor_assert(tor_memeq(a->identity_digest, b->identity_digest, DIGEST_LEN));
return strcmp(a->nickname, b->nickname) || return strcmp(a->nickname, b->nickname) ||
memcmp(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) || fast_memneq(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
a->addr != b->addr || a->addr != b->addr ||
a->or_port != b->or_port || a->or_port != b->or_port ||
a->dir_port != b->dir_port || a->dir_port != b->dir_port ||
@ -1522,7 +1522,7 @@ notify_control_networkstatus_changed(const networkstatus_t *old_c,
SMARTLIST_FOREACH_JOIN( SMARTLIST_FOREACH_JOIN(
old_c->routerstatus_list, const routerstatus_t *, rs_old, old_c->routerstatus_list, const routerstatus_t *, rs_old,
new_c->routerstatus_list, const routerstatus_t *, rs_new, new_c->routerstatus_list, const routerstatus_t *, rs_new,
memcmp(rs_old->identity_digest, tor_memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN), rs_new->identity_digest, DIGEST_LEN),
smartlist_add(changed, (void*) rs_new)) { smartlist_add(changed, (void*) rs_new)) {
if (routerstatus_has_changed(rs_old, rs_new)) if (routerstatus_has_changed(rs_old, rs_new))
@ -1546,13 +1546,13 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old, SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
new_c->routerstatus_list, routerstatus_t *, rs_new, new_c->routerstatus_list, routerstatus_t *, rs_new,
memcmp(rs_old->identity_digest, tor_memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN), rs_new->identity_digest, DIGEST_LEN),
STMT_NIL) { STMT_NIL) {
/* Okay, so we're looking at the same identity. */ /* Okay, so we're looking at the same identity. */
rs_new->last_dir_503_at = rs_old->last_dir_503_at; rs_new->last_dir_503_at = rs_old->last_dir_503_at;
if (!memcmp(rs_old->descriptor_digest, rs_new->descriptor_digest, if (tor_memeq(rs_old->descriptor_digest, rs_new->descriptor_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
/* And the same descriptor too! */ /* And the same descriptor too! */
memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t)); memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t));
@ -1668,7 +1668,7 @@ networkstatus_set_current_consensus(const char *consensus,
} }
if (current_digests && if (current_digests &&
!memcmp(&c->digests, current_digests, sizeof(c->digests))) { tor_memeq(&c->digests, current_digests, sizeof(c->digests))) {
/* We already have this one. That's a failure. */ /* We already have this one. That's a failure. */
log_info(LD_DIR, "Got a %s consensus we already have", flavor); log_info(LD_DIR, "Got a %s consensus we already have", flavor);
goto done; goto done;
@ -2003,7 +2003,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
SMARTLIST_FOREACH_JOIN(ns->routerstatus_list, routerstatus_t *, rs, SMARTLIST_FOREACH_JOIN(ns->routerstatus_list, routerstatus_t *, rs,
routers, routerinfo_t *, router, routers, routerinfo_t *, router,
memcmp(rs->identity_digest, tor_memcmp(rs->identity_digest,
router->cache_info.identity_digest, DIGEST_LEN), router->cache_info.identity_digest, DIGEST_LEN),
{ {
#if 0 #if 0
@ -2020,7 +2020,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
ds = router_get_trusteddirserver_by_digest(digest); ds = router_get_trusteddirserver_by_digest(digest);
/* Is it the same descriptor, or only the same identity? */ /* Is it the same descriptor, or only the same identity? */
if (!memcmp(router->cache_info.signed_descriptor_digest, if (tor_memeq(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) { rs->descriptor_digest, DIGEST_LEN)) {
if (ns->valid_until > router->cache_info.last_listed_as_valid_until) if (ns->valid_until > router->cache_info.last_listed_as_valid_until)
router->cache_info.last_listed_as_valid_until = ns->valid_until; router->cache_info.last_listed_as_valid_until = ns->valid_until;
@ -2049,10 +2049,10 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME; time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs, SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs,
routers, routerinfo_t *, ri, routers, routerinfo_t *, ri,
memcmp(rs->identity_digest, tor_memcmp(rs->identity_digest,
ri->cache_info.identity_digest, DIGEST_LEN), ri->cache_info.identity_digest, DIGEST_LEN),
STMT_NIL) { STMT_NIL) {
if (!memcmp(ri->cache_info.signed_descriptor_digest, if (tor_memeq(ri->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) { rs->descriptor_digest, DIGEST_LEN)) {
if (live_until > ri->cache_info.last_listed_as_valid_until) if (live_until > ri->cache_info.last_listed_as_valid_until)
ri->cache_info.last_listed_as_valid_until = live_until; ri->cache_info.last_listed_as_valid_until = live_until;

View File

@ -328,7 +328,7 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
if (len < 0) if (len < 0)
goto err; goto err;
if (memcmp(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) { if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
/* H(K) does *not* match. Something fishy. */ /* H(K) does *not* match. Something fishy. */
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on onion handshake. " log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on onion handshake. "
"Bug or attack."); "Bug or attack.");
@ -415,7 +415,7 @@ fast_client_handshake(const uint8_t *handshake_state,/*DIGEST_LEN bytes*/
if (crypto_expand_key_material(tmp, sizeof(tmp), out, out_len)) { if (crypto_expand_key_material(tmp, sizeof(tmp), out, out_len)) {
goto done; goto done;
} }
if (memcmp(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) { if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
/* H(K) does *not* match. Something fishy. */ /* H(K) does *not* match. Something fishy. */
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on fast handshake. " log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on fast handshake. "
"Bug or attack."); "Bug or attack.");

View File

@ -134,7 +134,7 @@ relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell)
crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE); crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
crypto_digest_get_digest(digest, calculated_integrity, 4); crypto_digest_get_digest(digest, calculated_integrity, 4);
if (memcmp(received_integrity, calculated_integrity, 4)) { if (tor_memneq(received_integrity, calculated_integrity, 4)) {
// log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing."); // log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity); // (%d vs %d).", received_integrity, calculated_integrity);
/* restore digest to its old form */ /* restore digest to its old form */

View File

@ -158,7 +158,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
intro_key = NULL; intro_key = NULL;
SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *, SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
intro, { intro, {
if (!memcmp(introcirc->build_state->chosen_exit->identity_digest, if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) { intro->extend_info->identity_digest, DIGEST_LEN)) {
intro_key = intro->intro_key; intro_key = intro->intro_key;
break; break;
@ -629,7 +629,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro,
for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) { for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i); rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
if (!memcmp(failed_intro->identity_digest, if (tor_memeq(failed_intro->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) { intro->extend_info->identity_digest, DIGEST_LEN)) {
rend_intro_point_free(intro); rend_intro_point_free(intro);
smartlist_del(ent->parsed->intro_nodes, i); smartlist_del(ent->parsed->intro_nodes, i);
@ -728,7 +728,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
goto err; goto err;
/* Check whether the digest is right... */ /* Check whether the digest is right... */
if (memcmp(keys, request+DH_KEY_LEN, DIGEST_LEN)) { if (tor_memneq(keys, request+DH_KEY_LEN, DIGEST_LEN)) {
log_warn(LD_PROTOCOL, "Incorrect digest of key material."); log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
goto err; goto err;
} }

View File

@ -884,15 +884,15 @@ rend_id_is_in_interval(const char *a, const char *b, const char *c)
tor_assert(c); tor_assert(c);
/* There are five cases in which a is outside the interval ]b,c]: */ /* There are five cases in which a is outside the interval ]b,c]: */
a_b = memcmp(a,b,DIGEST_LEN); a_b = tor_memcmp(a,b,DIGEST_LEN);
if (a_b == 0) if (a_b == 0)
return 0; /* 1. a == b (b is excluded) */ return 0; /* 1. a == b (b is excluded) */
b_c = memcmp(b,c,DIGEST_LEN); b_c = tor_memcmp(b,c,DIGEST_LEN);
if (b_c == 0) if (b_c == 0)
return 0; /* 2. b == c (interval is empty) */ return 0; /* 2. b == c (interval is empty) */
else if (a_b <= 0 && b_c < 0) else if (a_b <= 0 && b_c < 0)
return 0; /* 3. a b c */ return 0; /* 3. a b c */
c_a = memcmp(c,a,DIGEST_LEN); c_a = tor_memcmp(c,a,DIGEST_LEN);
if (c_a < 0 && a_b <= 0) if (c_a < 0 && a_b <= 0)
return 0; /* 4. c a b */ return 0; /* 4. c a b */
else if (b_c < 0 && c_a < 0) else if (b_c < 0 && c_a < 0)
@ -1066,7 +1066,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
rend_service_descriptor_free(parsed); rend_service_descriptor_free(parsed);
return 0; return 0;
} }
if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) { if (e && e->len == desc_len && tor_memeq(desc,e->desc,desc_len)) {
log_info(LD_REND,"We already have this service descriptor %s.", log_info(LD_REND,"We already have this service descriptor %s.",
safe_str_client(query)); safe_str_client(query));
e->received = time(NULL); e->received = time(NULL);

View File

@ -62,7 +62,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
log_warn(LD_BUG, "Internal error computing digest."); log_warn(LD_BUG, "Internal error computing digest.");
goto err; goto err;
} }
if (memcmp(expected_digest, request+2+asn1len, DIGEST_LEN)) { if (tor_memneq(expected_digest, request+2+asn1len, DIGEST_LEN)) {
log_warn(LD_PROTOCOL, "Hash of session info was not as expected."); log_warn(LD_PROTOCOL, "Hash of session info was not as expected.");
reason = END_CIRC_REASON_TORPROTOCOL; reason = END_CIRC_REASON_TORPROTOCOL;
goto err; goto err;

View File

@ -466,7 +466,7 @@ rend_config_services(or_options_t *options, int validate_only)
int keep_it = 0; int keep_it = 0;
tor_assert(oc->rend_data); tor_assert(oc->rend_data);
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, { SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest, if (tor_memeq(ptr->pk_digest, oc->rend_data->rend_pk_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
keep_it = 1; keep_it = 1;
break; break;
@ -761,7 +761,7 @@ static rend_service_t *
rend_service_get_by_pk_digest(const char* digest) rend_service_get_by_pk_digest(const char* digest)
{ {
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s, SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
if (!memcmp(s->pk_digest,digest,DIGEST_LEN)) if (tor_memeq(s->pk_digest,digest,DIGEST_LEN))
return s); return s);
return NULL; return NULL;
} }
@ -801,7 +801,7 @@ rend_check_authorization(rend_service_t *service,
/* Look up client authorization by descriptor cookie. */ /* Look up client authorization by descriptor cookie. */
SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, client, { SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, client, {
if (!memcmp(client->descriptor_cookie, descriptor_cookie, if (tor_memeq(client->descriptor_cookie, descriptor_cookie,
REND_DESC_COOKIE_LEN)) { REND_DESC_COOKIE_LEN)) {
auth_client = client; auth_client = client;
break; break;
@ -915,7 +915,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
/* first DIGEST_LEN bytes of request is intro or service pk digest */ /* first DIGEST_LEN bytes of request is intro or service pk digest */
crypto_pk_get_digest(intro_key, intro_key_digest); crypto_pk_get_digest(intro_key, intro_key_digest);
if (memcmp(intro_key_digest, request, DIGEST_LEN)) { if (tor_memneq(intro_key_digest, request, DIGEST_LEN)) {
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1, base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
(char*)request, REND_SERVICE_ID_LEN); (char*)request, REND_SERVICE_ID_LEN);
log_warn(LD_REND, "Got an INTRODUCE2 cell for the wrong service (%s).", log_warn(LD_REND, "Got an INTRODUCE2 cell for the wrong service (%s).",
@ -1270,7 +1270,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
return -1; return -1;
} }
if (memcmp(intro->extend_info->identity_digest, if (tor_memneq(intro->extend_info->identity_digest,
launched->build_state->chosen_exit->identity_digest, DIGEST_LEN)) { launched->build_state->chosen_exit->identity_digest, DIGEST_LEN)) {
char cann[HEX_DIGEST_LEN+1], orig[HEX_DIGEST_LEN+1]; char cann[HEX_DIGEST_LEN+1], orig[HEX_DIGEST_LEN+1];
base16_encode(cann, sizeof(cann), base16_encode(cann, sizeof(cann),
@ -1556,7 +1556,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
tor_assert(intro); tor_assert(intro);
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
CIRCUIT_PURPOSE_S_INTRO))) { CIRCUIT_PURPOSE_S_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest, if (tor_memeq(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) && intro->extend_info->identity_digest, DIGEST_LEN) &&
circ->rend_data) { circ->rend_data) {
return circ; return circ;
@ -1566,7 +1566,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
circ = NULL; circ = NULL;
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
if (!memcmp(circ->build_state->chosen_exit->identity_digest, if (tor_memeq(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) && intro->extend_info->identity_digest, DIGEST_LEN) &&
circ->rend_data) { circ->rend_data) {
return circ; return circ;
@ -1823,7 +1823,7 @@ rend_services_introduce(void)
if (service->desc) { if (service->desc) {
SMARTLIST_FOREACH(service->desc->intro_nodes, rend_intro_point_t *, SMARTLIST_FOREACH(service->desc->intro_nodes, rend_intro_point_t *,
dintro, { dintro, {
if (!memcmp(dintro->extend_info->identity_digest, if (tor_memeq(dintro->extend_info->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) { intro->extend_info->identity_digest, DIGEST_LEN)) {
log_info(LD_REND, "The intro point we are giving up on was " log_info(LD_REND, "The intro point we are giving up on was "
"included in the last published descriptor. " "included in the last published descriptor. "

View File

@ -118,7 +118,7 @@ get_or_history(const char* id)
{ {
or_history_t *hist; or_history_t *hist;
if (tor_mem_is_zero(id, DIGEST_LEN)) if (tor_digest_is_zero(id))
return NULL; return NULL;
hist = digestmap_get(history_map, id); hist = digestmap_get(history_map, id);
@ -146,7 +146,7 @@ get_link_history(const char *from_id, const char *to_id)
orhist = get_or_history(from_id); orhist = get_or_history(from_id);
if (!orhist) if (!orhist)
return NULL; return NULL;
if (tor_mem_is_zero(to_id, DIGEST_LEN)) if (tor_digest_is_zero(to_id))
return NULL; return NULL;
lhist = (link_history_t*) digestmap_get(orhist->link_history_map, to_id); lhist = (link_history_t*) digestmap_get(orhist->link_history_map, to_id);
if (!lhist) { if (!lhist) {

View File

@ -725,7 +725,7 @@ init_keys(void)
ds->type = type; ds->type = type;
} }
if (v3_digest_set && (ds->type & V3_DIRINFO) && if (v3_digest_set && (ds->type & V3_DIRINFO) &&
memcmp(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) { tor_memneq(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, "V3 identity key does not match identity declared in " log_warn(LD_DIR, "V3 identity key does not match identity declared in "
"DirServer line. Adjusting."); "DirServer line. Adjusting.");
memcpy(ds->v3_identity_digest, v3_digest, DIGEST_LEN); memcpy(ds->v3_identity_digest, v3_digest, DIGEST_LEN);
@ -1267,7 +1267,7 @@ int
router_digest_is_me(const char *digest) router_digest_is_me(const char *digest)
{ {
return (server_identitykey && return (server_identitykey &&
!memcmp(server_identitykey_digest, digest, DIGEST_LEN)); tor_memeq(server_identitykey_digest, digest, DIGEST_LEN));
} }
/** Return true iff I'm a server and <b>digest</b> is equal to /** Return true iff I'm a server and <b>digest</b> is equal to
@ -1279,7 +1279,7 @@ router_extrainfo_digest_is_me(const char *digest)
if (!ei) if (!ei)
return 0; return 0;
return !memcmp(digest, return tor_memeq(digest,
ei->cache_info.signed_descriptor_digest, ei->cache_info.signed_descriptor_digest,
DIGEST_LEN); DIGEST_LEN);
} }

View File

@ -170,7 +170,7 @@ already_have_cert(authority_cert_t *cert)
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
{ {
if (!memcmp(c->cache_info.signed_descriptor_digest, if (tor_memeq(c->cache_info.signed_descriptor_digest,
cert->cache_info.signed_descriptor_digest, cert->cache_info.signed_descriptor_digest,
DIGEST_LEN)) DIGEST_LEN))
return 1; return 1;
@ -384,16 +384,16 @@ authority_cert_get_by_sk_digest(const char *sk_digest)
return NULL; return NULL;
if ((c = get_my_v3_authority_cert()) && if ((c = get_my_v3_authority_cert()) &&
!memcmp(c->signing_key_digest, sk_digest, DIGEST_LEN)) tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
return c; return c;
if ((c = get_my_v3_legacy_cert()) && if ((c = get_my_v3_legacy_cert()) &&
!memcmp(c->signing_key_digest, sk_digest, DIGEST_LEN)) tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
return c; return c;
DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
{ {
if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
return cert; return cert;
}); });
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
@ -412,7 +412,7 @@ authority_cert_get_by_digests(const char *id_digest,
!(cl = digestmap_get(trusted_dir_certs, id_digest))) !(cl = digestmap_get(trusted_dir_certs, id_digest)))
return NULL; return NULL;
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
return cert; ); return cert; );
return NULL; return NULL;
@ -1008,7 +1008,7 @@ router_get_trusteddirserver_by_digest(const char *digest)
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{ {
if (!memcmp(ds->digest, digest, DIGEST_LEN)) if (tor_memeq(ds->digest, digest, DIGEST_LEN))
return ds; return ds;
}); });
@ -1027,7 +1027,7 @@ trusteddirserver_get_by_v3_auth_digest(const char *digest)
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{ {
if (!memcmp(ds->v3_identity_digest, digest, DIGEST_LEN) && if (tor_memeq(ds->v3_identity_digest, digest, DIGEST_LEN) &&
(ds->type & V3_DIRINFO)) (ds->type & V3_DIRINFO))
return ds; return ds;
}); });
@ -2280,7 +2280,7 @@ hex_digest_nickname_matches(const char *hexdigest, const char *identity_digest,
return 0; return 0;
} }
return !memcmp(digest, identity_digest, DIGEST_LEN); return tor_memeq(digest, identity_digest, DIGEST_LEN);
} }
/* Return true iff <b>router</b> is listed as named in the current /* Return true iff <b>router</b> is listed as named in the current
@ -2292,7 +2292,7 @@ router_is_named(const routerinfo_t *router)
networkstatus_get_router_digest_by_nickname(router->nickname); networkstatus_get_router_digest_by_nickname(router->nickname);
return (digest && return (digest &&
!memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN)); tor_memeq(digest, router->cache_info.identity_digest, DIGEST_LEN));
} }
/** Return true iff the digest of <b>router</b>'s identity key, /** Return true iff the digest of <b>router</b>'s identity key,
@ -2382,7 +2382,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
if (n_matches <= 1 || router->is_running) if (n_matches <= 1 || router->is_running)
best_match = router; best_match = router;
} else if (maybedigest && } else if (maybedigest &&
!memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN) tor_memeq(digest, router->cache_info.identity_digest, DIGEST_LEN)
) { ) {
if (router_hex_digest_matches(router, nickname)) if (router_hex_digest_matches(router, nickname))
return router; return router;
@ -2459,7 +2459,7 @@ router_digest_is_trusted_dir_type(const char *digest, dirinfo_type_t type)
if (authdir_mode(get_options()) && router_digest_is_me(digest)) if (authdir_mode(get_options()) && router_digest_is_me(digest))
return 1; return 1;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
if (!memcmp(digest, ent->digest, DIGEST_LEN)) { if (tor_memeq(digest, ent->digest, DIGEST_LEN)) {
return (!type) || ((type & ent->type) != 0); return (!type) || ((type & ent->type) != 0);
}); });
return 0; return 0;
@ -2608,7 +2608,7 @@ signed_descriptor_get_body_impl(const signed_descriptor_t *desc,
tor_assert(r); tor_assert(r);
if (!with_annotations) { if (!with_annotations) {
if (memcmp("router ", r, 7) && memcmp("extra-info ", r, 11)) { if (fast_memcmp("router ", r, 7) && fast_memcmp("extra-info ", r, 11)) {
char *cp = tor_strndup(r, 64); char *cp = tor_strndup(r, 64);
log_err(LD_DIR, "descriptor at %p begins with unexpected string %s. " log_err(LD_DIR, "descriptor at %p begins with unexpected string %s. "
"Is another process running in our data directory? Exiting.", "Is another process running in our data directory? Exiting.",
@ -3086,7 +3086,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
routerlist_insert(rl, ri_new); routerlist_insert(rl, ri_new);
return; return;
} }
if (memcmp(ri_old->cache_info.identity_digest, if (tor_memneq(ri_old->cache_info.identity_digest,
ri_new->cache_info.identity_digest, DIGEST_LEN)) { ri_new->cache_info.identity_digest, DIGEST_LEN)) {
/* digests don't match; digestmap_set won't replace */ /* digests don't match; digestmap_set won't replace */
rimap_remove(rl->identity_map, ri_old->cache_info.identity_digest); rimap_remove(rl->identity_map, ri_old->cache_info.identity_digest);
@ -3103,7 +3103,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
&ri_new->cache_info); &ri_new->cache_info);
} }
same_descriptors = ! memcmp(ri_old->cache_info.signed_descriptor_digest, same_descriptors = tor_memeq(ri_old->cache_info.signed_descriptor_digest,
ri_new->cache_info.signed_descriptor_digest, ri_new->cache_info.signed_descriptor_digest,
DIGEST_LEN); DIGEST_LEN);
@ -3125,7 +3125,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
sdmap_remove(rl->desc_digest_map, sdmap_remove(rl->desc_digest_map,
ri_old->cache_info.signed_descriptor_digest); ri_old->cache_info.signed_descriptor_digest);
if (memcmp(ri_old->cache_info.extra_info_digest, if (tor_memneq(ri_old->cache_info.extra_info_digest,
ri_new->cache_info.extra_info_digest, DIGEST_LEN)) { ri_new->cache_info.extra_info_digest, DIGEST_LEN)) {
ei_tmp = eimap_remove(rl->extra_info_map, ei_tmp = eimap_remove(rl->extra_info_map,
ri_old->cache_info.extra_info_digest); ri_old->cache_info.extra_info_digest);
@ -3224,7 +3224,7 @@ router_set_status(const char *digest, int up)
tor_assert(digest); tor_assert(digest);
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
if (!memcmp(d->digest, digest, DIGEST_LEN)) if (tor_memeq(d->digest, digest, DIGEST_LEN))
d->is_running = up); d->is_running = up);
node = node_get_mutable_by_id(digest); node = node_get_mutable_by_id(digest);
@ -3348,7 +3348,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
{ {
routerstatus_t *rs = routerstatus_t *rs =
networkstatus_v2_find_mutable_entry(ns, id_digest); networkstatus_v2_find_mutable_entry(ns, id_digest);
if (rs && !memcmp(rs->descriptor_digest, if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest, router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) DIGEST_LEN))
rs->need_to_mirror = 0; rs->need_to_mirror = 0;
@ -3356,7 +3356,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
if (consensus) { if (consensus) {
routerstatus_t *rs = networkstatus_vote_find_mutable_entry( routerstatus_t *rs = networkstatus_vote_find_mutable_entry(
consensus, id_digest); consensus, id_digest);
if (rs && !memcmp(rs->descriptor_digest, if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest, router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
in_consensus = 1; in_consensus = 1;
@ -3478,7 +3478,7 @@ _compare_old_routers_by_identity(const void **_a, const void **_b)
{ {
int i; int i;
const signed_descriptor_t *r1 = *_a, *r2 = *_b; const signed_descriptor_t *r1 = *_a, *r2 = *_b;
if ((i = memcmp(r1->identity_digest, r2->identity_digest, DIGEST_LEN))) if ((i = fast_memcmp(r1->identity_digest, r2->identity_digest, DIGEST_LEN)))
return i; return i;
return (int)(r1->published_on - r2->published_on); return (int)(r1->published_on - r2->published_on);
} }
@ -3526,7 +3526,7 @@ routerlist_remove_old_cached_routers_with_id(time_t now,
ident = ((signed_descriptor_t*)smartlist_get(lst, lo))->identity_digest; ident = ((signed_descriptor_t*)smartlist_get(lst, lo))->identity_digest;
for (i = lo+1; i <= hi; ++i) { for (i = lo+1; i <= hi; ++i) {
signed_descriptor_t *r = smartlist_get(lst, i); signed_descriptor_t *r = smartlist_get(lst, i);
tor_assert(!memcmp(ident, r->identity_digest, DIGEST_LEN)); tor_assert(tor_memeq(ident, r->identity_digest, DIGEST_LEN));
} }
#endif #endif
/* Check whether we need to do anything at all. */ /* Check whether we need to do anything at all. */
@ -3738,7 +3738,7 @@ routerlist_remove_old_routers(void)
cur_id = r->identity_digest; cur_id = r->identity_digest;
hi = i; hi = i;
} }
if (memcmp(cur_id, r->identity_digest, DIGEST_LEN)) { if (tor_memneq(cur_id, r->identity_digest, DIGEST_LEN)) {
routerlist_remove_old_cached_routers_with_id(now, routerlist_remove_old_cached_routers_with_id(now,
cutoff, i+1, hi, retain); cutoff, i+1, hi, retain);
cur_id = r->identity_digest; cur_id = r->identity_digest;
@ -3976,7 +3976,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
if (consensus) { if (consensus) {
rs = networkstatus_vote_find_entry(consensus, desc->identity_digest); rs = networkstatus_vote_find_entry(consensus, desc->identity_digest);
if (rs && !memcmp(rs->descriptor_digest, if (rs && tor_memeq(rs->descriptor_digest,
desc->signed_descriptor_digest, DIGEST_LEN)) desc->signed_descriptor_digest, DIGEST_LEN))
return 1; return 1;
} }
@ -3985,7 +3985,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
{ {
if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest))) if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest)))
continue; continue;
if (!memcmp(rs->descriptor_digest, if (tor_memeq(rs->descriptor_digest,
desc->signed_descriptor_digest, DIGEST_LEN)) desc->signed_descriptor_digest, DIGEST_LEN))
return 1; return 1;
}); });
@ -4630,7 +4630,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
const routerinfo_t *ri; const routerinfo_t *ri;
++n_have; ++n_have;
if (!(ri = router_get_by_id_digest(rs->identity_digest)) || if (!(ri = router_get_by_id_digest(rs->identity_digest)) ||
memcmp(ri->cache_info.signed_descriptor_digest, tor_memneq(ri->cache_info.signed_descriptor_digest,
sd->signed_descriptor_digest, DIGEST_LEN)) { sd->signed_descriptor_digest, DIGEST_LEN)) {
/* We have a descriptor with this digest, but either there is no /* We have a descriptor with this digest, but either there is no
* entry in routerlist with the same ID (!ri), or there is one, * entry in routerlist with the same ID (!ri), or there is one,
@ -5159,12 +5159,12 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
return 1; return 1;
} }
digest_matches = !memcmp(ei->cache_info.signed_descriptor_digest, digest_matches = tor_memeq(ei->cache_info.signed_descriptor_digest,
sd->extra_info_digest, DIGEST_LEN); sd->extra_info_digest, DIGEST_LEN);
/* The identity must match exactly to have been generated at the same time /* The identity must match exactly to have been generated at the same time
* by the same router. */ * by the same router. */
if (memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest, if (tor_memneq(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo"; if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo";
goto err; /* different servers */ goto err; /* different servers */
@ -5175,7 +5175,7 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
if (crypto_pk_public_checksig(ri->identity_pkey, if (crypto_pk_public_checksig(ri->identity_pkey,
signed_digest, sizeof(signed_digest), signed_digest, sizeof(signed_digest),
ei->pending_sig, ei->pending_sig_len) != DIGEST_LEN || ei->pending_sig, ei->pending_sig_len) != DIGEST_LEN ||
memcmp(signed_digest, ei->cache_info.signed_descriptor_digest, tor_memneq(signed_digest, ei->cache_info.signed_descriptor_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
ei->bad_sig = 1; ei->bad_sig = 1;
tor_free(ei->pending_sig); tor_free(ei->pending_sig);
@ -5271,25 +5271,25 @@ routerlist_assert_ok(const routerlist_t *rl)
}); });
RIMAP_FOREACH(rl->identity_map, d, r) { RIMAP_FOREACH(rl->identity_map, d, r) {
tor_assert(!memcmp(r->cache_info.identity_digest, d, DIGEST_LEN)); tor_assert(tor_memeq(r->cache_info.identity_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
SDMAP_FOREACH(rl->desc_digest_map, d, sd) { SDMAP_FOREACH(rl->desc_digest_map, d, sd) {
tor_assert(!memcmp(sd->signed_descriptor_digest, d, DIGEST_LEN)); tor_assert(tor_memeq(sd->signed_descriptor_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
SDMAP_FOREACH(rl->desc_by_eid_map, d, sd) { SDMAP_FOREACH(rl->desc_by_eid_map, d, sd) {
tor_assert(!tor_digest_is_zero(d)); tor_assert(!tor_digest_is_zero(d));
tor_assert(sd); tor_assert(sd);
tor_assert(!memcmp(sd->extra_info_digest, d, DIGEST_LEN)); tor_assert(tor_memeq(sd->extra_info_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
EIMAP_FOREACH(rl->extra_info_map, d, ei) { EIMAP_FOREACH(rl->extra_info_map, d, ei) {
signed_descriptor_t *sd; signed_descriptor_t *sd;
tor_assert(!memcmp(ei->cache_info.signed_descriptor_digest, tor_assert(tor_memeq(ei->cache_info.signed_descriptor_digest,
d, DIGEST_LEN)); d, DIGEST_LEN));
sd = sdmap_get(rl->desc_by_eid_map, sd = sdmap_get(rl->desc_by_eid_map,
ei->cache_info.signed_descriptor_digest); ei->cache_info.signed_descriptor_digest);
// tor_assert(sd); // XXXX see above // tor_assert(sd); // XXXX see above
if (sd) { if (sd) {
tor_assert(!memcmp(ei->cache_info.signed_descriptor_digest, tor_assert(tor_memeq(ei->cache_info.signed_descriptor_digest,
sd->extra_info_digest, DIGEST_LEN)); sd->extra_info_digest, DIGEST_LEN));
} }
} DIGESTMAP_FOREACH_END; } DIGESTMAP_FOREACH_END;
@ -5335,7 +5335,7 @@ static int
_compare_routerinfo_by_id_digest(const void **a, const void **b) _compare_routerinfo_by_id_digest(const void **a, const void **b)
{ {
routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b; routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b;
return memcmp(first->cache_info.identity_digest, return fast_memcmp(first->cache_info.identity_digest,
second->cache_info.identity_digest, second->cache_info.identity_digest,
DIGEST_LEN); DIGEST_LEN);
} }

View File

@ -1093,7 +1093,7 @@ check_signature_token(const char *digest,
} }
// log_debug(LD_DIR,"Signed %s hash starts %s", doctype, // log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
// hex_str(signed_digest,4)); // hex_str(signed_digest,4));
if (memcmp(digest, signed_digest, digest_len)) { if (tor_memneq(digest, signed_digest, digest_len)) {
log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype); log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype);
tor_free(signed_digest); tor_free(signed_digest);
return -1; return -1;
@ -1480,7 +1480,7 @@ router_parse_entry_from_string(const char *s, const char *end,
escaped(tok->args[0])); escaped(tok->args[0]));
goto err; goto err;
} }
if (memcmp(d,router->cache_info.identity_digest, DIGEST_LEN)!=0) { if (tor_memneq(d,router->cache_info.identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, "Fingerprint '%s' does not match identity digest.", log_warn(LD_DIR, "Fingerprint '%s' does not match identity digest.",
tok->args[0]); tok->args[0]);
goto err; goto err;
@ -1795,7 +1795,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
cert->cache_info.identity_digest)) cert->cache_info.identity_digest))
goto err; goto err;
if (memcmp(cert->cache_info.identity_digest, fp_declared, DIGEST_LEN)) { if (tor_memneq(cert->cache_info.identity_digest, fp_declared, DIGEST_LEN)) {
log_warn(LD_DIR, "Digest of certificate key didn't match declared " log_warn(LD_DIR, "Digest of certificate key didn't match declared "
"fingerprint"); "fingerprint");
goto err; goto err;
@ -1843,7 +1843,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
* buy us much. */ * buy us much. */
if (old_cert->cache_info.signed_descriptor_len == len && if (old_cert->cache_info.signed_descriptor_len == len &&
old_cert->cache_info.signed_descriptor_body && old_cert->cache_info.signed_descriptor_body &&
!memcmp(s, old_cert->cache_info.signed_descriptor_body, len)) { tor_memeq(s, old_cert->cache_info.signed_descriptor_body, len)) {
log_debug(LD_DIR, "We already checked the signature on this " log_debug(LD_DIR, "We already checked the signature on this "
"certificate; no need to do so again."); "certificate; no need to do so again.");
found = 1; found = 1;
@ -2203,7 +2203,7 @@ int
compare_routerstatus_entries(const void **_a, const void **_b) compare_routerstatus_entries(const void **_a, const void **_b)
{ {
const routerstatus_t *a = *_a, *b = *_b; const routerstatus_t *a = *_a, *b = *_b;
return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN); return fast_memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
} }
/** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */ /** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */
@ -2296,7 +2296,7 @@ networkstatus_v2_parse_from_string(const char *s)
log_warn(LD_DIR, "Couldn't compute signing key digest"); log_warn(LD_DIR, "Couldn't compute signing key digest");
goto err; goto err;
} }
if (memcmp(tmp_digest, ns->identity_digest, DIGEST_LEN)) { if (tor_memneq(tmp_digest, ns->identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, log_warn(LD_DIR,
"network-status fingerprint did not match dir-signing-key"); "network-status fingerprint did not match dir-signing-key");
goto err; goto err;
@ -3000,7 +3000,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err; goto err;
} }
if (ns->type != NS_TYPE_CONSENSUS && if (ns->type != NS_TYPE_CONSENSUS &&
memcmp(ns->cert->cache_info.identity_digest, tor_memneq(ns->cert->cache_info.identity_digest,
voter->identity_digest, DIGEST_LEN)) { voter->identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR,"Mismatch between identities in certificate and vote"); log_warn(LD_DIR,"Mismatch between identities in certificate and vote");
goto err; goto err;
@ -3106,7 +3106,8 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
rs1 = smartlist_get(ns->routerstatus_list, i-1); rs1 = smartlist_get(ns->routerstatus_list, i-1);
rs2 = smartlist_get(ns->routerstatus_list, i); rs2 = smartlist_get(ns->routerstatus_list, i);
} }
if (memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN) >= 0) { if (fast_memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN)
>= 0) {
log_warn(LD_DIR, "Vote networkstatus entries not sorted by identity " log_warn(LD_DIR, "Vote networkstatus entries not sorted by identity "
"digest"); "digest");
goto err; goto err;
@ -3225,7 +3226,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
} }
if (ns->type != NS_TYPE_CONSENSUS) { if (ns->type != NS_TYPE_CONSENSUS) {
if (memcmp(declared_identity, ns->cert->cache_info.identity_digest, if (tor_memneq(declared_identity, ns->cert->cache_info.identity_digest,
DIGEST_LEN)) { DIGEST_LEN)) {
log_warn(LD_DIR, "Digest mismatch between declared and actual on " log_warn(LD_DIR, "Digest mismatch between declared and actual on "
"network-status vote."); "network-status vote.");
@ -3507,8 +3508,8 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
is_duplicate = 0; is_duplicate = 0;
SMARTLIST_FOREACH(siglist, document_signature_t *, s, { SMARTLIST_FOREACH(siglist, document_signature_t *, s, {
if (s->alg == alg && if (s->alg == alg &&
!memcmp(id_digest, s->identity_digest, DIGEST_LEN) && tor_memeq(id_digest, s->identity_digest, DIGEST_LEN) &&
!memcmp(sk_digest, s->signing_key_digest, DIGEST_LEN)) { tor_memeq(sk_digest, s->signing_key_digest, DIGEST_LEN)) {
is_duplicate = 1; is_duplicate = 1;
} }
}); });
@ -4546,7 +4547,7 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
else if ((i = a->git_tag_len - b->git_tag_len)) else if ((i = a->git_tag_len - b->git_tag_len))
return i; return i;
else if (a->git_tag_len) else if (a->git_tag_len)
return memcmp(a->git_tag, b->git_tag, a->git_tag_len); return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
else else
return 0; return 0;
} }
@ -4765,7 +4766,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
crypto_pk_get_digest(result->pk, public_key_hash); crypto_pk_get_digest(result->pk, public_key_hash);
rend_get_descriptor_id_bytes(test_desc_id, public_key_hash, rend_get_descriptor_id_bytes(test_desc_id, public_key_hash,
secret_id_part); secret_id_part);
if (memcmp(desc_id_out, test_desc_id, DIGEST_LEN)) { if (tor_memneq(desc_id_out, test_desc_id, DIGEST_LEN)) {
log_warn(LD_REND, "Parsed descriptor ID does not match " log_warn(LD_REND, "Parsed descriptor ID does not match "
"computed descriptor ID."); "computed descriptor ID.");
goto err; goto err;
@ -4830,7 +4831,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
crypto_free_digest_env(digest); crypto_free_digest_env(digest);
for (pos = 2; pos < 2 + client_entries_len; for (pos = 2; pos < 2 + client_entries_len;
pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN) { pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN) {
if (!memcmp(ipos_encrypted + pos, client_id, if (tor_memeq(ipos_encrypted + pos, client_id,
REND_BASIC_AUTH_CLIENT_ID_LEN)) { REND_BASIC_AUTH_CLIENT_ID_LEN)) {
/* Attempt to decrypt introduction points. */ /* Attempt to decrypt introduction points. */
cipher = crypto_create_init_cipher(descriptor_cookie, 0); cipher = crypto_create_init_cipher(descriptor_cookie, 0);
@ -4854,7 +4855,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
tor_free(dec); tor_free(dec);
return -1; return -1;
} }
if (memcmpstart(dec, declen, "introduction-point ")) { if (fast_memcmpstart(dec, declen, "introduction-point ")) {
log_warn(LD_REND, "Decrypted introduction points don't " log_warn(LD_REND, "Decrypted introduction points don't "
"look like we could parse them."); "look like we could parse them.");
tor_free(dec); tor_free(dec);
@ -4923,7 +4924,7 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
parsed->intro_nodes = smartlist_create(); parsed->intro_nodes = smartlist_create();
area = memarea_new(); area = memarea_new();
while (!memcmpstart(current_ipo, end_of_intro_points-current_ipo, while (!fast_memcmpstart(current_ipo, end_of_intro_points-current_ipo,
"introduction-point ")) { "introduction-point ")) {
/* Determine end of string. */ /* Determine end of string. */
const char *eos = tor_memstr(current_ipo, end_of_intro_points-current_ipo, const char *eos = tor_memstr(current_ipo, end_of_intro_points-current_ipo,

View File

@ -1418,6 +1418,60 @@ test_util_spawn_background_fail(void *ptr)
} }
#endif #endif
static void
test_util_di_ops(void)
{
#define LT -1
#define GT 1
#define EQ 0
const struct {
const char *a; int want_sign; const char *b;
} examples[] = {
{ "Foo", EQ, "Foo" },
{ "foo", GT, "bar", },
{ "foobar", EQ ,"foobar" },
{ "foobar", LT, "foobaw" },
{ "foobar", GT, "f00bar" },
{ "foobar", GT, "boobar" },
{ "", EQ, "" },
{ NULL, 0, NULL },
};
int i;
for (i = 0; examples[i].a; ++i) {
size_t len = strlen(examples[i].a);
int eq1, eq2, neq1, neq2, cmp1, cmp2;
test_eq(len, strlen(examples[i].b));
/* We do all of the operations, with operands in both orders. */
eq1 = tor_memeq(examples[i].a, examples[i].b, len);
eq2 = tor_memeq(examples[i].b, examples[i].a, len);
neq1 = tor_memneq(examples[i].a, examples[i].b, len);
neq2 = tor_memneq(examples[i].b, examples[i].a, len);
cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
/* Check for correctness of cmp1 */
if (cmp1 < 0 && examples[i].want_sign != LT)
test_fail();
else if (cmp1 > 0 && examples[i].want_sign != GT)
test_fail();
else if (cmp1 == 0 && examples[i].want_sign != EQ)
test_fail();
/* Check for consistency of everything else with cmp1 */
test_eq(eq1, eq2);
test_eq(neq1, neq2);
test_eq(cmp1, -cmp2);
test_eq(eq1, cmp1 == 0);
test_eq(neq1, !eq1);
}
done:
;
}
#define UTIL_LEGACY(name) \ #define UTIL_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name } { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
@ -1438,6 +1492,7 @@ struct testcase_t util_tests[] = {
UTIL_LEGACY(threads), UTIL_LEGACY(threads),
UTIL_LEGACY(sscanf), UTIL_LEGACY(sscanf),
UTIL_LEGACY(strtok), UTIL_LEGACY(strtok),
UTIL_LEGACY(di_ops),
UTIL_TEST(find_str_at_start_of_line, 0), UTIL_TEST(find_str_at_start_of_line, 0),
UTIL_TEST(asprintf, 0), UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0), UTIL_TEST(listdir, 0),