1
$\begingroup$

libsodium verifies that the HMAC is correct with the following code:

return crypto_verify_32(h, correct) | (-(h == correct)) | sodium_memcmp(correct, h, 32);

where crypto_verify_32 is

for (i = 0; i < n; i++) {
    d |= x[i] ^ y[i];
}
return (1 & ((d - 1) >> 8)) - 1;

and sodium_memcmp is

for (i = 0U; i < len; i++) {
    d |= b1[i] ^ b2[i];
}
return (1 & ((d - 1) >> 8)) - 1;

Why not using a simple memcmp?

$\endgroup$
4
$\begingroup$

memcmp() is not constant-time. The property called "constant-time" does not mean (confusingly) that every runs in a constant amount of time; an algorithm implementation is said to be "constant-time" if it does not leak information about secret data through timing-based side channels.

In the case of memcmp(), the leak is simple: memcmp() looks at bytes in increasing address order, and stops at the first index where bytes differ. Thus, the execution time, and the memory access pattern, if observed by attackers, may reveal how many bytes are identical. If the attacker can repeat the experiment with various purported "HMAC" values, he can use that leak to learn the complete true HMAC value, which can be a very bad thing in some contexts.

For more on the subject, see this page in BearSSL documentation.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.