[tor-dev] memcmp() & co. timing info disclosures?
Marsh Ray
marsh at extendedsubset.com
Sat May 7 05:35:26 UTC 2011
On 05/06/2011 09:40 PM, Marsh Ray wrote:
> On 05/06/2011 08:00 PM, Nick Mathewson wrote:
>
>> 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.
Spoke too soon.
A little birdie (goes by the name of Skywing) pointed out to me in chat
that certain compilers are smart enough to realize that the
externally-visible result of the function can only go from 0 to 1 one
time. This might enable them to break out of the loop early once that
happened.
A workaround may be the 'volatile sledgehammer':
int mem_neq(const void *m1, const void *m2, size_t n)
{
const uint8_t *b1 = m1, *b2 = m2;
uint8_t diff = 0;
volatile uint8_t * pdiff = &diff;
while (n--)
*pdiff |= *b1++ ^ *b2++;
return *pdiff != 0;
}
or perhaps
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 |= *(volatile const uint8_t *)b1
^ *(volatile const uint8_t *)b2;
b1++; b2++;
}
return diff != 0;
}
Of course, we could always just compute SHA-256 hashes of each side and
then compare those, right? :-)
- Marsh
More information about the tor-dev
mailing list