aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2013-10-31 15:55:33 -0700
committerAlex Gaynor <alex.gaynor@gmail.com>2013-10-31 15:55:33 -0700
commit3d5041cda29f8201418a4c2d340059f68c7bb41d (patch)
tree919833f0d4cde4d1a346863df1fc4c10df9c2b00
parent69ab59e59670c3865fb8240aa81ca9195a96e003 (diff)
downloadcryptography-3d5041cda29f8201418a4c2d340059f68c7bb41d.tar.gz
cryptography-3d5041cda29f8201418a4c2d340059f68c7bb41d.tar.bz2
cryptography-3d5041cda29f8201418a4c2d340059f68c7bb41d.zip
Moved constant_time_compare to be C
-rw-r--r--cryptography/fernet.py34
1 files changed, 22 insertions, 12 deletions
diff --git a/cryptography/fernet.py b/cryptography/fernet.py
index f923911a..214b9374 100644
--- a/cryptography/fernet.py
+++ b/cryptography/fernet.py
@@ -4,6 +4,8 @@ import os
import struct
import time
+import cffi
+
import six
from cryptography.hazmat.primitives import padding, hashes
@@ -15,6 +17,25 @@ class InvalidToken(Exception):
pass
+ffi = cffi.FFI()
+ffi.cdef("""
+bool constant_time_compare(uint8_t *, size_t, uint8_t *, size_t);
+""")
+lib = ffi.verify("""
+#include <stdbool.h>
+
+bool constant_time_compare(uint8_t *a, size_t len_a, uint8_t *b, size_t len_b) {
+ if (len_a != len_b) {
+ return false;
+ }
+ int result = 0;
+ for (size_t i = 0; i < len_a; i++) {
+ result |= a[i] ^ b[i];
+ }
+ return result == 0;
+}
+""")
+
class Fernet(object):
def __init__(self, key):
super(Fernet, self).__init__()
@@ -75,7 +96,7 @@ class Fernet(object):
h.update(data[:-32])
hmac = h.digest()
- if not constant_time_compare(hmac, data[-32:]):
+ if not lib.constant_time_compare(hmac, len(hmac), data[-32:], 32):
raise InvalidToken
decryptor = BlockCipher(
@@ -90,14 +111,3 @@ class Fernet(object):
except ValueError:
raise InvalidToken
return unpadded
-
-
-def constant_time_compare(a, b):
- # TOOD: replace with a cffi function
- assert isinstance(a, bytes) and isinstance(b, bytes)
- if len(a) != len(b):
- return False
- result = 0
- for i in range(len(a)):
- result |= six.indexbytes(a, i) ^ six.indexbytes(b, i)
- return result == 0