Warm tip: This article is reproduced from stackoverflow.com, please click
hmac security string tcl

Timing safe comparison of strings

发布于 2020-04-23 10:55:00

Does Tcl have any built in function for comparing strings in a timing safe manner, so no secrets are leaked because of short circuits?

string equal starts from the left and returns on the first difference, so it's not suited to compare secrets.

Specifically, I want to compare two sha256 HMACs. Double HMAC would also solve the leakage, but I want to find a timing safe comparison function.

Questioner
kelunik
Viewed
29
Donal Fellows 2016-01-31 16:58

Assuming that you are dealing with two strings of the same length (e.g., HMACs) then you can just apply a comparison to each character and accumulate the result:

proc safeequal {s1 s2} {
    set equal 1
    foreach c1 [split $s1 ""] c2 [split $s2 ""] {
        set equal [expr {$equal & ($c1 eq $c2)}]
    }
    return $equal
}

Now, there might be some timing effects due to split doing character sharing, but they'll be really difficult to exploit to determine the content of the strings as the timings won't be identifiable with a position and will in any case be down in the noise. I can't make my system anywhere near quiet enough for me to see a difference even between comparing two strings (of about HMAC length) that are equal at every character and comparing two that are different at every character.

% time {safeequal qwertyuiopasdfghjklzxcvbnm qwertyuiopasdfghjklzxcvbnm} 100000
9.847818689999999 microseconds per iteration
% time {safeequal qwertyuiopasdfghjklzxcvbnm QWERTYUIOPASDFGHJKLZXCVBNM} 100000
9.78685247 microseconds per iteration
% time {safeequal qwertyuiopasdfghjklzxcvbnm qwertyuiopasdfghjklzxcvbnm} 100000
9.72245421 microseconds per iteration
% time {safeequal qwertyuiopasdfghjklzxcvbnm QWERTYUIOPASDFGHJKLZXCVBNM} 100000
9.88214891 microseconds per iteration