[tor-dev] memcmp() & co. timing info disclosures?

Jacob Appelbaum jacob at appelbaum.net
Sat May 7 00:08:13 UTC 2011


Hi Marsh,

Thanks for writing to or-dev, welcome to the list!

On 05/06/2011 04:13 PM, Marsh Ray wrote:
> 
> Greetings all,
> 
> I happened to download the tor-0.2.2.25-alpha.tar.gz source yesterday
> and I noticed something. Apologies in advance if this has already been
> discussed and resolved, I did a cursory web search and didn't see anything.

After some of our discussions and some thinking, I opened this bug:
https://trac.torproject.org/projects/tor/ticket/3122

> 
> There are a lot of places in the code where memcmp() is called on memory
> buffers that look like they might contain various hashes or digests:
> 
>    ~/tor-0.2.2.25-alpha$ grep -r memcmp . | grep -i digest | wc -l
>    137
> 
>     ~/tor-0.2.2.25-alpha$ grep -r memcmp . | grep -i key | wc -l
>     14
> 
> The built-in memcmp typically runs in time proportional to the common
> prefix of the two memory buffers being compared. In networked
> applications, this is often a significant source of timing information.
> Sometimes these are severe enough to result in disclosure of secret key
> material. A good resource for remote timing attacks is Nate Lawson's blog:
> 
> http://rdist.root.org/2010/07/19/exploiting-remote-timing-attacks/
> 

Nate's post is great and anyone reading this email should read the above
url for context. I'd also suggest this one:
http://rdist.root.org/2010/01/07/timing-independent-array-comparison/

> Some cases look particularly concerning. For example, in the following
> code 'handshake_reply' appears to be supplied by the remote party and it
> is compared with something called "key material".
> 
> src/or/onion.c:331:
>   if (memcmp(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
>     /* H(K) does *not* match. Something fishy. */
>      log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on onion handshake. "
>            "Bug or attack.");
>     goto err;
>   }
> 
> In the worst-case, the attacker could simply supply different values of
> handshake_reply, observe how long each takes to compare, and figure out
> the value of key_material statistically byte-by-byte.
> 
> Perhaps this key material is never used again, or there are other
> reasons this timing informaion is not useful. But in general, it's very
> difficult to determine whether or not such a timing info disclosure
> represents a vulnerability or how difficult it would be to exploit.
> Expert programmers seem to consistently underestimate the severtiy of
> these weaknesses, perhaps because they are so subtle. I've just started
> learning about Tor so it's not possible for me to review every instance.
> 

I generally agree - I think it's best to use a constant time comparison
unless you're *certain* that you want something else.

> I think the quickest and easiest solution would be to replace every
> usage of memcmp and str*cmp in the source with an alternate version that
> guarantees a constant time comparison.

I think it's probably a good idea to write a new set of functions, say
safe_memcmp and safe_strcmp, that are properly implemented. We can
#define over memcmp but I fear that it's better to specifically
eradicate each one by hand and really think things over on a case by
case basis.

> 
> I'd expect this could be done with negligible performance impact,
> especially for short comparisons like 20-byte hash values.
> 

I think so too.

All the best,
Jake


More information about the tor-dev mailing list