aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-10 16:58:38 -0400
committerNick Mathewson <nickm@torproject.org>2011-05-11 16:12:51 -0400
commit59f9097d5c3dc010847c359888d31757d1c97904 (patch)
treebaed5184d13d62645e00d1ed815ffc0861b2ff87 /src/common
parentdb7b2a33eef9c8d432442b072f9c8868a068bb91 (diff)
downloadtor-59f9097d5c3dc010847c359888d31757d1c97904.tar
tor-59f9097d5c3dc010847c359888d31757d1c97904.tar.gz
Hand-conversion and audit phase of memcmp transition
Here I looked at the results of the automated conversion and cleaned them up as follows: If there was a tor_memcmp or tor_memeq that was in fact "safe"[*] I changed it to a fast_memcmp or fast_memeq. Otherwise if there was a tor_memcmp that could turn into a tor_memneq or tor_memeq, I converted it. This wants close attention. [*] I'm erring on the side of caution here, and leaving some things as tor_memcmp that could in my opinion use the data-dependent fast_memcmp variant.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/compat.c4
-rw-r--r--src/common/container.c2
-rw-r--r--src/common/crypto.c2
-rw-r--r--src/common/di_ops.h2
-rw-r--r--src/common/torgzip.c2
-rw-r--r--src/common/util.c21
-rw-r--r--src/common/util.h4
7 files changed, 23 insertions, 14 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index ea46d43d8..39651084a 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -312,6 +312,8 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
* <b>needle</b>, return a pointer to the first occurrence of the needle
* 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.
*/
const void *
@@ -336,7 +338,7 @@ tor_memmem(const void *_haystack, size_t hlen,
while ((p = memchr(p, first, end-p))) {
if (p+nlen > end)
return NULL;
- if (tor_memeq(p, needle, nlen))
+ if (fast_memeq(p, needle, nlen))
return p;
++p;
}
diff --git a/src/common/container.c b/src/common/container.c
index d1d5ce339..c741eb020 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -223,7 +223,7 @@ smartlist_digest_isin(const smartlist_t *sl, const char *element)
int i;
if (!sl) return 0;
for (i=0; i < sl->num_used; i++)
- if (tor_memcmp((const char*)sl->list[i],element,DIGEST_LEN)==0)
+ if (tor_memeq((const char*)sl->list[i],element,DIGEST_LEN))
return 1;
return 0;
}
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 926942897..f3268fe18 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -845,7 +845,7 @@ crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const char *data,
tor_free(buf);
return -1;
}
- if (tor_memcmp(buf, digest, DIGEST_LEN)) {
+ if (tor_memneq(buf, digest, DIGEST_LEN)) {
log_warn(LD_CRYPTO, "Signature mismatched with digest.");
tor_free(buf);
return -1;
diff --git a/src/common/di_ops.h b/src/common/di_ops.h
index 1b223d9ab..4a212b0ca 100644
--- a/src/common/di_ops.h
+++ b/src/common/di_ops.h
@@ -24,5 +24,7 @@ int tor_memeq(const void *a, const void *b, size_t sz);
* 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
diff --git a/src/common/torgzip.c b/src/common/torgzip.c
index 51b29baca..f5709aaf3 100644
--- a/src/common/torgzip.c
+++ b/src/common/torgzip.c
@@ -356,7 +356,7 @@ tor_gzip_uncompress(char **out, size_t *out_len,
compress_method_t
detect_compression_method(const char *in, size_t in_len)
{
- if (in_len > 2 && tor_memeq(in, "\x1f\x8b", 2)) {
+ if (in_len > 2 && fast_memeq(in, "\x1f\x8b", 2)) {
return GZIP_METHOD;
} else if (in_len > 2 && (in[0] & 0x0f) == 8 &&
(ntohs(get_uint16(in)) % 31) == 0) {
diff --git a/src/common/util.c b/src/common/util.c
index cb2cfed64..879a0e4bd 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -459,7 +459,7 @@ strcmp_len(const char *s1, const char *s2, size_t s1_len)
return -1;
if (s1_len > s2_len)
return 1;
- return tor_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
@@ -501,17 +501,17 @@ strcasecmpend(const char *s1, const char *s2)
/** 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.
*
- * [As tor_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is less
- * than strlen(prefix).]
+ * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
+ * less than strlen(prefix).]
*/
int
-memcmpstart(const void *mem, size_t memlen,
+fast_memcmpstart(const void *mem, size_t memlen,
const char *prefix)
{
size_t plen = strlen(prefix);
if (memlen < plen)
return -1;
- return tor_memcmp(mem, prefix, plen);
+ return fast_memcmp(mem, prefix, plen);
}
/** Return a pointer to the first char of s that is not whitespace and
@@ -644,14 +644,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,
};
while (len >= sizeof(ZERO)) {
- if (tor_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;
len -= sizeof(ZERO);
mem += sizeof(ZERO);
}
/* Deal with leftover bytes. */
if (len)
- return tor_memeq(mem, ZERO, len);
+ return fast_memeq(mem, ZERO, len);
return 1;
}
@@ -660,7 +662,10 @@ tor_mem_is_zero(const char *mem, size_t len)
int
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);
}
/* Helper: common code to check whether the result of a strtol or strtoul or
diff --git a/src/common/util.h b/src/common/util.h
index 7bc5286a8..1012a111d 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -172,8 +172,8 @@ int strcasecmpstart(const char *s1, const char *s2)
int strcmpend(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2));
int strcasecmpend(const char *s1, const char *s2)
ATTR_PURE ATTR_NONNULL((1,2));
-int memcmpstart(const void *mem, size_t memlen,
- const char *prefix) ATTR_PURE;
+int fast_memcmpstart(const void *mem, size_t memlen,
+ const char *prefix) ATTR_PURE;
void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));
long tor_parse_long(const char *s, int base, long min,