Project

General

Profile

hmac-timing.patch

arrtchiu (Matt U), 07/28/2014 03:13 PM

View differences:

ext/openssl/ossl_hmac.c
324 324
}
325 325

  
326 326
/*
327
 *  call-seq:
328
 *     hmac.verify(bytes) -> aBoolean
329
 *
330
 * Compares the receiver's digest to another digest in a timing-safe way.
331
 * +bytes+ must be a binary string containing a digest, for example by calling +#digest+ on another
332
 * instance of +OpenSSL::Digest+.
333
 */
334
VALUE
335
ossl_hmac_verify(VALUE self, VALUE other)
336
{
337
  HMAC_CTX *ctx;
338
  unsigned char *buf;
339
  unsigned int buf_len;
340
  unsigned char result;
341
  unsigned int cur_idx;
342
  unsigned char *other_buf;
343

  
344
  if (!RB_TYPE_P(other, T_STRING))
345
    rb_raise(rb_eArgError, "digest value must be a string");
346

  
347
  GetHMAC(self, ctx);
348
  hmac_final(ctx, &buf, &buf_len);
349

  
350
  if (!buf_len || buf_len != RSTRING_LEN(other))
351
    return Qfalse;
352

  
353
  other_buf = (unsigned char *)RSTRING_PTR(other);
354

  
355
  result = 0;
356
  for (cur_idx = 0; cur_idx < buf_len; cur_idx++) {
357
    result |= buf[cur_idx] ^ other_buf[cur_idx];
358
  }
359

  
360
  if (result == 0)
361
    return Qtrue;
362

  
363
  return Qfalse;
364
}
365

  
366
/*
327 367
 * INIT
328 368
 */
329 369
void
......
352 392
    rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0);
353 393
    rb_define_alias(cHMAC, "inspect", "hexdigest");
354 394
    rb_define_alias(cHMAC, "to_s", "hexdigest");
395
    rb_define_method(cHMAC, "verify", ossl_hmac_verify, 1);
355 396
}
356 397

  
357 398
#else /* NO_HMAC */
test/openssl/test_hmac.rb
24 24

  
25 25
    assert_equal(OpenSSL::HMAC.digest("MD5", @key, @data), @h2.digest, "digest")
26 26
    assert_equal(OpenSSL::HMAC.hexdigest("MD5", @key, @data), @h2.hexdigest, "hexdigest")
27

  
28
    assert_same(false, @h1.verify("\x9EPYl\x0F\xA1\x19\x7F\x85\x87D:\x94-\x8A\xFD"))
29
    assert_same(true, @h1.verify("\x9EPYl\x0F\xA1\x19\x7F\x85\x87D:\x94-\x8A\xFC"))
30
  end
31

  
32
  def test_hmac_verify
27 33
  end
28 34

  
29 35
  def test_dup
30
-