[Cryptography] Implementing constant-time string comparison

Ben Laurie ben at links.org
Wed Jun 18 14:44:58 EDT 2014


On 17 June 2014 20:36, sycamoreone <sycamoreone at riseup.net> wrote:

> static int vn(const u8 *x,const u8 *y,int n)
> {
>   u32 i,d = 0;
>   for (i = 0,i < n,++i) d |= x[i]^y[i];
>   return (1 & ((d - 1) >> 8)) - 1;
> }
>
> Here the expression in the return statement evaluates to (d == 0)-1
> in a way that makes it impossible for the CPU to produce a timing
> side-channel by short-circuiting a comparison of (half)words.

Not impossible. The compiler could make the same observation you have,
and optimise for that.

> Why are other libraries not doing this? That is, is this paranoid,
> or merely taking constant-time serious? Or does the 'unusual' return
> statement serve another purpose?
>
> For reference I added the code of some other implementations below.

You seem to be saying that other libraries are doing this?

> OpenSSL passes the problem on to the user of the library:

By "the problem", I presume you mean the issue of getting 0 or 1 out
of this. In general, the style is if (CRYPTO_memcmp(...)) (or ! that),
so 0 or 1 is not needed.

But I admit to once being bitten in the ass comparing "booleans" that
weren't (in this case bitfields, though), so I can agree it isn't best
practice.

> int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
>         {
>         size_t i;
>         const unsigned char *a = in_a;
>         const unsigned char *b = in_b;
>         unsigned char x = 0;
>
>         for (i = 0; i < len; i++)
>                 x |= a[i] ^ b[i];
>
>         return x;
>         }


More information about the cryptography mailing list