Issue #14532: Add a secure_compare() helper to the hmac module, to mitigate
timing attacks. Patch by Jon Oberheide.
diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
index 4de0620..042bc5d 100644
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -302,12 +302,48 @@
         self.assertEqual(h1.hexdigest(), h2.hexdigest(),
             "Hexdigest of copy doesn't match original hexdigest.")
 
+class SecureCompareTestCase(unittest.TestCase):
+
+    def test_compare(self):
+        # Testing input type exception handling
+        a, b = 100, 200
+        self.assertRaises(TypeError, hmac.secure_compare, a, b)
+        a, b = 100, "foobar"
+        self.assertRaises(TypeError, hmac.secure_compare, a, b)
+        a, b = "foobar", b"foobar"
+        self.assertRaises(TypeError, hmac.secure_compare, a, b)
+
+        # Testing str/bytes of different lengths
+        a, b = "foobar", "foo"
+        self.assertFalse(hmac.secure_compare(a, b))
+        a, b = b"foobar", b"foo"
+        self.assertFalse(hmac.secure_compare(a, b))
+        a, b = b"\xde\xad\xbe\xef", b"\xde\xad"
+        self.assertFalse(hmac.secure_compare(a, b))
+
+        # Testing str/bytes of same lengths, different values
+        a, b = "foobar", "foobaz"
+        self.assertFalse(hmac.secure_compare(a, b))
+        a, b = b"foobar", b"foobaz"
+        self.assertFalse(hmac.secure_compare(a, b))
+        a, b = b"\xde\xad\xbe\xef", b"\xab\xad\x1d\xea"
+        self.assertFalse(hmac.secure_compare(a, b))
+
+        # Testing str/bytes of same lengths, same values
+        a, b = "foobar", "foobar"
+        self.assertTrue(hmac.secure_compare(a, b))
+        a, b = b"foobar", b"foobar"
+        self.assertTrue(hmac.secure_compare(a, b))
+        a, b = b"\xde\xad\xbe\xef", b"\xde\xad\xbe\xef"
+        self.assertTrue(hmac.secure_compare(a, b))
+
 def test_main():
     support.run_unittest(
         TestVectorsTestCase,
         ConstructorTestCase,
         SanityTestCase,
-        CopyTestCase
+        CopyTestCase,
+        SecureCompareTestCase
     )
 
 if __name__ == "__main__":