[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

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



On Fri, 6 May 2011 23:14:58 -0400
Nick Mathewson <nickm@xxxxxxxxxxxxx> wrote:

> On Fri, May 6, 2011 at 10:40 PM, Marsh Ray <marsh@xxxxxxxxxxxxxxxxxx> wrote:
> [...]
> >> but the problem in general is worrisome and we
> >> should indeed replace (nearly) all of our memcmps with
> >> data-independent variants.
> >
> > Maybe some of the str*cmps too? I grep 681 of them.
> 
> Yeah; most of these are not parsing anything secret, but we should
> audit all of them to look for worrisome cases.  It's even less clear
> what data-independence means for strcmp: possibly it means that the
> run-time should depend only on the length of the shorter string, or
> the longer string, or on one of the arguments arbitrarily designated
> as the "non-secret" string, or such.  All of these could be reasonable
> under some circumstances, but we should figure out what we actually
> mean.
> 
> > We should also look for other cases where any data or padding might be
> > checked, decompressed, or otherwise operated on without being as obvious as
> > calling memcmp. Lots of error conditions can disclose timing information.
> 
> Yeah.  This is going to be a reasonably big job.
> 
> >> (Pedantic nit-pick: we should be saying "data-independent," not
> >> "constant-time." ÂWe want a memcmp(a,b,c) that takes the same number
> >> of cycles for a given value of c no matter what a and b are. ÂThat's
> >> data-independence. ÂA constant-time version would be one that took the
> >> same number of cycles no matter what c is.)
> >
> > That's a good point. In most of the code I glanced at, the length was fixed
> > at compile-time. I suppose a proper "constant-time" function would have to
> > take as much time as a 2GB comparison (on 32) :-).
> >
> >> int mem_neq(const void *m1, const void *m2, size_t n)
> >> {
> >> Âconst uint8_t *b1 = m1, *b2 = m2;
> >> Âuint8_t diff = 0;
> >> Âwhile (n--)
> >> Â Âdiff |= *b1++ ^ *b2++;
> >> Âreturn diff != 0;
> >> }
> >> #define mem_eq(m1, m2, n) (!mem_neq((m1), (m2),(n)))
> >
> > Looks good to me.
> >
> > What if n is 0? Is 'equals' or 'neq' a more conservative default ?
> 
> If n is 0, then "equals" is the answer: all empty strings are equal, right? :)
> 
> > Would it make sense to die in a well-defined way if m1 or m2 is NULL?
> 
> Adding a tor_assert(m1 && m2) would be fine.
> 
> > Also, if the MSB of n is set it's an invalid condition, the kind that could
> > result from a conversion from a signed value.
> 
> Adding a tor_assert(n < SIZE_T_CEILING) is our usual way of handling this.
> 
> Also, as I said on the bug, doing a memcmp in constant time is harder
> than doing eq/neq.  I *think* that all of the cases where we care
> about memcmp returning a tristate -1/0/1 result, we don't need
> data-independence... but in case we *do* need one, we'll have to do
> some malarkey like
> 
> int memcmp(const void *m1, const void *m2, size_t n)
> {
> /*XXX I don't know if this is even right; I haven't tested it at all */
>   const uint8_t *b1 = m1, *b2 = m2;
>   int retval = 0;
> 
>   while (n--) {
>     const uint8_t v1 = b1[n], v2 = b2[n];
>     int diff = (int)v1 - (int)v2;
>     retval = (v1 == v2) * retval + diff;
>   }
> 
>   return retval;
> }

GCC is likely to turn (v1 == v2) into a backdoor.  Also, we would need
to make sure sign extension is constant-time; it *probably* is on IA-32
and AMD64, but we may need to disassemble the compiler's output to
verify that on ARM.

Other than that, it looks correct.  We *can* fix the dependence on ==
and make the multiply unnecessary at the same time, though.


I've attached my optimized constant-time comparison functions for
16-byte and 32-byte values to this message.  They're packaged in the
format for a submission to SUPERCOP and/or NaCl, but for some reason I
never actually submitted them.


Robert Ransom

Attachment: rransom-crypto_verify-2010-04-13-01.tar.xz
Description: application/xz

Attachment: signature.asc
Description: PGP signature

_______________________________________________
tor-dev mailing list
tor-dev@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev