From: "Dmitry S. Kravtsov" Date: 2012-05-29T18:10:53+09:00 Subject: Re: does this leak more than the size of the string via timing side channels --047d7b163089c4876d04c129358e Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable How did i missed it? well then we can replace 'all?' with reducing here: if computed_mac.length =3D=3D presented_mac.length then computed_mac.chars.zip(presented_mac.chars).map {|x,y| x =3D=3D y}.reduce= (:&) end But as everyone mentioned here, simply comparing hashes is better option, because good hashes (like SHA) changes significantly when original value changes slightly. 2012/5/29 Martin Bo=C3=9Flet > 2012/5/29 Dmitry S. Kravtsov : > > Ok, now I get it, > > well I may only suggest to use high order functions, and write it like > this: > > > > if computed_mac.length =3D=3D presented_mac.length then > > computed_mac.chars.zip(presented_mac.chars).map {|x,y| x =3D=3D y}.al= l? > > end > > > > all? will be most likely short-circuiting, too, so this has the same > problem as using =3D=3D. > > There's two ways I know that security folks have approved of: > > 1. As it is done in eql_time_cmp in [1]. > > 2. sha =3D OpenSSL::Digest::SHA256.new > if sha.digest(computed_mac) =3D=3D sha.digest(presented_mac) > .. > end > > Although some say that there is even a problem with the first method: > An extremely > optimized (byte code) compiler could figure out what we're trying to > do there and "help" > us in short-circuiting again. This won't apply to the second method, > though. > > > [1] > http://www.ruby-doc.org/stdlib-2.0/libdoc/openssl/rdoc/OpenSSL/PKCS5.html > > --=20 Dmitry S. Kravtsov --047d7b163089c4876d04c129358e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable How did i missed it?
well then we can replace 'all?' with reduc= ing here:

if computed_mac.length =3D=3D presented_= mac.length then
=C2=A0 computed_mac.chars.zip(presented_mac.chars= ).map {|x,y| x =3D=3D y}.reduce(:&)
end

But as everyone mentioned here, simply co= mparing hashes is better option,
because good hashes (like SHA) c= hanges significantly when original value=C2=A0
changes slightly.= =C2=A0

2012/5/29 Martin Bo=C3=9Flet <martin.bosslet@googlemail.com>
2012/5/29 Dmitry S. Kravtsov <idk= ravitz@gmail.com>:
> Ok, now I get it,
> well I may only suggest to use high order functions, and write it like= this:
>
> if computed_mac.length =3D=3D presented_mac.length then
> =C2=A0 computed_mac.chars.zip(presented_mac.chars).map {|x,y| x =3D=3D= y}.all?
> end
>

all? will be most likely short-circuiting, too, so this has the same<= br> problem as using =3D=3D.

There's two ways I know that security folks have approved of:

1. As it is done in eql_time_cmp in [1].

2. sha =3D OpenSSL::Digest::SHA256.new
=C2=A0 =C2=A0if sha.digest(computed_mac) =3D=3D sha.digest(presented_mac)<= br> =C2=A0 =C2=A0 =C2=A0..
=C2=A0 =C2=A0end

Although some say that there is even a problem with the first method:
An extremely
optimized (byte code) compiler could figure out what we're trying to do there and "help"
us in short-circuiting again. This won't apply to the second method, th= ough.


[1] http://www.ruby-doc.org/stdlib-2.0/libdoc/= openssl/rdoc/OpenSSL/PKCS5.html




--
Dmitry S. Kr= avtsov
--047d7b163089c4876d04c129358e--