Michael Rogers wrote:
> On 20/03/14 14:58, Guido Witmond wrote:
>> On 03/20/14 14:17, Michael Rogers wrote:
>>> You should use a constant-time comparison here to avoid timing
>>> attacks. Something like:
>>>
>>> boolean matches = true;
>>> for (i = 0; i < 32; i++) {
>>> matches &= (digest[i] == decoded[i + 32]);
>>> }
>>> if (!matches) {
>>> // incorrectly decoded: we're not the intended recipient
>>> return null;
>>> }
>> Wouldn't this be vulnerable to a compiler-optimisation that
>> short-circuits the &= operator?
>
> Good point, maybe so!
>
>> If so, will this be better?
>>
>> // count the number of matches; must be equal to length.
>> int len = 32
>> int matchcount = 0
>> for (i = 0; i < len; i++) {
>> matches += !(digest[i] == decoded[i + len]);
>> }
>> if (matches != len) {
>> // incorrectly decoded: we're not the intended recipient
>> return null;
>> }
>
> You can't add a boolean to an int in Java, but you could do this:
>
> matches += (digest[i] == decoded[i + len]) ? 1 : 0;
Note that all above variants may be NOT actually branchless and thus NOT really
constant-time (depending on architecture, jvm implementation and options, etc).
Most likely, resulting time difference won't be sufficient to be useful for
attacker, but...
(I doubt very much you can write guaranteed-constant-time code in java (and most
other high-level languages) at all.)
PS If you don't want to invent bicycle, there are boolean
java.security.MessageDigest.isEqual(byte [], byte[]) method.
--
Liberationtech is public & archives are searchable on Google. Violations of
list guidelines will get you moderated:
https://mailman.stanford.edu/mailman/listinfo/liberationtech. Unsubscribe,
change to digest, or change password by emailing moderator at
[email protected].