From 8123ce62094bf88a4107506d7acd3e8e2866bc1f Mon Sep 17 00:00:00 2001
From: Mark Haines <mark.haines@matrix.org>
Date: Tue, 3 Mar 2015 15:08:56 +0000
Subject: Constant time comparison for mac

---
 include/axolotl/memory.hh | 11 +++++++++--
 src/memory.cpp            | 20 +++++++++++++++++---
 src/ratchet.cpp           |  2 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/include/axolotl/memory.hh b/include/axolotl/memory.hh
index 7749c54..8313a19 100644
--- a/include/axolotl/memory.hh
+++ b/include/axolotl/memory.hh
@@ -1,17 +1,24 @@
 #include <cstddef>
+#include <cstdint>
 
 namespace axolotl {
 
 /** Clear the memory held in the buffer */
 void unset(
-    volatile void * buffer, std::size_t buffer_length
+    void volatile * buffer, std::size_t buffer_length
 );
 
 /** Clear the memory backing an object */
 template<typename T>
 void unset(T & value) {
-    unset(reinterpret_cast<volatile void *>(&value), sizeof(T));
+    unset(reinterpret_cast<void volatile *>(&value), sizeof(T));
 }
 
+/** Check if two buffers are equal in constant time. */
+bool is_equal(
+    std::uint8_t const * buffer_a,
+    std::uint8_t const * buffer_b,
+    std::size_t length
+);
 
 } // namespace axolotl
diff --git a/src/memory.cpp b/src/memory.cpp
index 14c95dd..07e8de2 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -1,11 +1,25 @@
 #include "axolotl/memory.hh"
 
+
 void axolotl::unset(
-    volatile void * buffer, std::size_t buffer_length
+    void volatile * buffer, std::size_t buffer_length
 ) {
-    volatile char * pos = reinterpret_cast<volatile char *>(buffer);
-    volatile char * end = pos + buffer_length;
+    char volatile * pos = reinterpret_cast<char volatile *>(buffer);
+    char volatile * end = pos + buffer_length;
     while (pos != end) {
         *(pos++) = 0;
     }
 }
+
+
+bool axolotl::is_equal(
+    std::uint8_t const * buffer_a,
+    std::uint8_t const * buffer_b,
+    std::size_t length
+) {
+    std::uint8_t volatile result = 0;
+    while (length--) {
+        result |= (*(buffer_a++)) ^ (*(buffer_b++));
+    }
+    return result == 0;
+}
diff --git a/src/ratchet.cpp b/src/ratchet.cpp
index d2903bb..ccb8e73 100644
--- a/src/ratchet.cpp
+++ b/src/ratchet.cpp
@@ -104,7 +104,7 @@ bool verify_mac(
         mac
     );
 
-    bool result = std::memcmp(mac, reader.mac, MAC_LENGTH) == 0;
+    bool result = axolotl::is_equal(mac, reader.mac, MAC_LENGTH);
     axolotl::unset(mac);
     return result;
 }
-- 
cgit v1.2.3-70-g09d2