aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hkdf.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/cryptography/hkdf.py b/cryptography/hkdf.py
new file mode 100644
index 00000000..9665ce57
--- /dev/null
+++ b/cryptography/hkdf.py
@@ -0,0 +1,43 @@
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hmac
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import constant_time
+
+def hkdf_derive(input_key, key_length, salt=None, info=None, hash=None, backend=None):
+ if hash is None:
+ hash = hashes.SHA256()
+
+ if backend is None:
+ backend = default_backend()
+
+ if info is None:
+ info = b""
+
+ if salt is None:
+ salt = b"\x00" * (hash.digest_size // 8)
+
+ h = hmac.HMAC(salt, hash, backend=backend)
+ h.update(input_key)
+ PRK = h.finalize()
+
+ output = [b'']
+ counter = 1
+
+ while (hash.digest_size // 8) * len(output) < key_length:
+ h = hmac.HMAC(PRK, hash, backend=backend)
+ h.update(output[-1])
+ h.update(info)
+ h.update(chr(counter))
+ output.append(h.finalize())
+ counter += 1
+
+ return b"".join(output)[:key_length]
+
+
+def hkdf_verify(expected, input_key, key_length, salt=None, info=None,
+ hash=None, backend=None):
+ derived = hkdf_derive(input_key, key_length, salt=salt, info=info,
+ hash=hash, backend=backend)
+
+ return constant_time.bytes_eq(expected, derived)
+