From 01e2032669d0f4897db90abe5ce96e2f834c0d6b Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@lothar.com>
Date: Sun, 22 Mar 2009 20:20:55 -0700
Subject: [PATCH] hashutil: add constant-time comparison function, to avoid
 timing attacks when python's short-circuiting data-dependent == operator is
 used to, say, check a write-enabler

---
 src/allmydata/test/test_util.py | 6 ++++++
 src/allmydata/util/hashutil.py  | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/src/allmydata/test/test_util.py b/src/allmydata/test/test_util.py
index ece54181..19ae70f5 100644
--- a/src/allmydata/test/test_util.py
+++ b/src/allmydata/test/test_util.py
@@ -601,6 +601,12 @@ class HashUtilTests(unittest.TestCase):
         h2.update("foo")
         self.failUnlessEqual(h1, h2.digest())
 
+    def test_constant_time_compare(self):
+        self.failUnless(hashutil.constant_time_compare("a", "a"))
+        self.failUnless(hashutil.constant_time_compare("ab", "ab"))
+        self.failIf(hashutil.constant_time_compare("a", "b"))
+        self.failIf(hashutil.constant_time_compare("a", "aa"))
+
 class Abbreviate(unittest.TestCase):
     def test_time(self):
         a = abbreviate.abbreviate_time
diff --git a/src/allmydata/util/hashutil.py b/src/allmydata/util/hashutil.py
index 0161e676..d5b260ad 100644
--- a/src/allmydata/util/hashutil.py
+++ b/src/allmydata/util/hashutil.py
@@ -189,3 +189,7 @@ def ssk_readkey_data_hash(IV, readkey):
     return tagged_pair_hash(MUTABLE_DATAKEY_TAG, IV, readkey, KEYLEN)
 def ssk_storage_index_hash(readkey):
     return tagged_hash(MUTABLE_STORAGEINDEX_TAG, readkey, KEYLEN)
+
+def constant_time_compare(a, b):
+    n = os.urandom(8)
+    return bool(tagged_hash(n, a) == tagged_hash(n, b))
-- 
2.45.2