[ruby-core:64123] [ruby-trunk - Feature #10098] [PATCH] Timing-safe string comparison for OpenSSL::HMAC

From: arrtchiu@...
Date: 2014-07-30 02:07:12 UTC
List: ruby-core #64123
Issue #10098 has been updated by Matt U.


Nobuyoshi Nakada wrote:
> `rb_tsafe_eql()` doesn't need to be `VALUE`, `int` is OK.
> Tests for timing-safeness are desirable, but it would be fragile by noise.

I'll get these done. Your benchmark code demonstrated this pretty well so (=
if it's ok with you) I'll use that as a starting point.

cremno phobia wrote:
> I don't like the proposed method name.
>=20
> `tsafe`? It should be `timingsafe`. Saving some keystrokes isn't worth it=
 to have a less obvious name. Even C programmers chose a longer name!
> I'm also not happy about `eql?` either. Then people expect it to work lik=
e `String#eql?`. Same argument requirements/conversion, same result, and it=
's even mentioned in the proposed docs (=E2=80=9Csimilarly=E2=80=9D is vagu=
e)! But it doesn't. For example:
> ...

Thanks for taking the time to test out this patch!
You have some really good points to consider. My thoughts in response:

- Since Ruby has only the one `String` class for text and data, I think it =
does make sense to keep this method on the `String` class.
- The behaviour you've demonstrated is intended, we care about the bytes in=
 the buffer; not the encoding.
- Name and documentation is terrible, I agree :)

I think the easiest way to resolve this would be to come up with a better n=
ame, and to explain more clearly in the documentation.

For a starting point, how about `timingsafe_bytes_eq?` ? I'll improve the d=
ocumentation while making the fixes as suggested by Nobu :)

----------------------------------------
Feature #10098: [PATCH] Timing-safe string comparison for OpenSSL::HMAC
https://bugs.ruby-lang.org/issues/10098#change-48133

* Author: Matt U
* Status: Open
* Priority: Normal
* Assignee:=20
* Category: ext/openssl
* Target version: next minor
----------------------------------------
I could be totally wrong, but it seems the standard library doesn't provide=
 a reliable way of comparing hashes in constant-time.

* The docs for `OpenSSL::HMAC` encourage the use of `Digest#to_s` (see: htt=
p://ruby-doc.org/stdlib-2.1.0/libdoc/openssl/rdoc/OpenSSL/HMAC.html#method-=
c-new )
* Ruby's string comparison uses memcmp, which isn't timing safe (see: http:=
//rxr.whitequark.org/mri/source/string.c#2382 )

With this patch I propose to add an additional method, `OpenSSL::HMAC#verif=
y`, which takes a binary string with a digest and compares it against the c=
omputed hash.


---Files--------------------------------
hmac-timing.patch (2.5 KB)
hmac-timing.patch (2.48 KB)
tsafe_eql.patch (2.48 KB)
tsafe_inline.patch (3.51 KB)


--=20
https://bugs.ruby-lang.org/

In This Thread

Prev Next