From 7891469a2771c4b566b0150ec3e0802548c2a461 Mon Sep 17 00:00:00 2001 From: Bart de Water Date: Sun, 18 Aug 2019 00:58:40 -0400 Subject: [PATCH] Add test to ensure constant time comparison stays constant Co-authored-by: arrtchiu --- test/test_ossl.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/test_ossl.rb b/test/test_ossl.rb index 657e1d0a5..085377ade 100644 --- a/test/test_ossl.rb +++ b/test/test_ossl.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require_relative "utils" +require 'benchmark' + if defined?(OpenSSL) class OpenSSL::OSSL < OpenSSL::SSLTestCase @@ -23,6 +25,21 @@ def test_memcmp? refute OpenSSL.memcmp?("aaa", "bbb") assert_raises(ArgumentError) { OpenSSL.memcmp?("aaa", "bbbb") } end + + def test_memcmp_timing + # Ensure using memcmp? takes almost exactly the same amount of time to compare two different strings. + # Regular string comparison will short-circuit on the first non-matching character, failing this test. + # NOTE: this test may be susceptible to noise if the system running the tests is otherwise under load. + a = "x" * 512_000 + b = "#{a}y" + c = "y#{a}" + a = "#{a}x" + + n = 10_000 + a_b_time = Benchmark.measure { n.times { OpenSSL.memcmp?(a, b) } }.real + a_c_time = Benchmark.measure { n.times { OpenSSL.memcmp?(a, c) } }.real + assert_in_delta(a_b_time, a_c_time, 0.25, "memcmp? timing test failed") + end end end