From: naruse@... Date: 2016-04-15T12:32:14+00:00 Subject: [ruby-core:74968] [Ruby trunk Feature#10098] [PATCH] Timing-safe string comparison for OpenSSL::HMAC Issue #10098 has been updated by Yui NARUSE. Following is a patch but I just found there's OPENSSL_memcmp, which is not timing safe... ```diff diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index d03dfa7..76333e2 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -551,6 +551,21 @@ static void Init_ossl_locks(void) CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback); } +static VALUE +ossl_memcmp(VALUE dummy, VALUE str1, VALUE str2) +{ + const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1); + const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2); + long len = RSTRING_LEN(str1); + long i; + unsigned char ret = 0; + if (len != RSTRING_LEN(str2)) return Qfalse; + for (i=0; i < len; i++) { + ret |= p1[i] ^ p2[i]; + } + return ret ? Qfalse : Qtrue; +} + /* * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the * OpenSSL[http://www.openssl.org/] library. @@ -1088,6 +1103,7 @@ Init_openssl(void) */ mOSSL = rb_define_module("OpenSSL"); rb_global_variable(&mOSSL); + rb_define_singleton_method(mOSSL, "memcmp", ossl_memcmp, 2); /* * OpenSSL ruby extension version ``` ---------------------------------------- Feature #10098: [PATCH] Timing-safe string comparison for OpenSSL::HMAC https://bugs.ruby-lang.org/issues/10098#change-58095 * Author: Matt U * Status: Assigned * Priority: Normal * Assignee: Yukihiro Matsumoto ---------------------------------------- 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: http://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#verify`, which takes a binary string with a digest and compares it against the computed 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) 0001-add-timing-safe-string-compare-method.patch (4.31 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: