aboutsummaryrefslogtreecommitdiffstats
path: root/src/cryptography/hazmat
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2019-01-19 00:52:43 -0600
committerAlex Gaynor <alex.gaynor@gmail.com>2019-01-19 00:52:43 -0600
commit5fe88ea0500c6e418492f4b166c0d4a24e9632cc (patch)
tree4e63ba2759c0801646314a0b87056b66198217e2 /src/cryptography/hazmat
parentfdc61a26ea32e2563dfcbe17484b6e662d7f1e0a (diff)
downloadcryptography-5fe88ea0500c6e418492f4b166c0d4a24e9632cc.tar.gz
cryptography-5fe88ea0500c6e418492f4b166c0d4a24e9632cc.tar.bz2
cryptography-5fe88ea0500c6e418492f4b166c0d4a24e9632cc.zip
shake128/256 support (#4611)
* shake128/256 support * remove block_size * doc an exception * change how we detect XOF by adding _xof attribute * interface! * review feedback
Diffstat (limited to 'src/cryptography/hazmat')
-rw-r--r--src/cryptography/hazmat/backends/openssl/hashes.py25
-rw-r--r--src/cryptography/hazmat/primitives/hashes.py41
2 files changed, 61 insertions, 5 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py
index e9a50705..549fa2bf 100644
--- a/src/cryptography/hazmat/backends/openssl/hashes.py
+++ b/src/cryptography/hazmat/backends/openssl/hashes.py
@@ -54,10 +54,25 @@ class _HashContext(object):
self._backend.openssl_assert(res != 0)
def finalize(self):
+ if isinstance(self.algorithm, hashes.ExtendableOutputFunction):
+ # extendable output functions use a different finalize
+ return self._finalize_xof()
+ else:
+ buf = self._backend._ffi.new("unsigned char[]",
+ self._backend._lib.EVP_MAX_MD_SIZE)
+ outlen = self._backend._ffi.new("unsigned int *")
+ res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen)
+ self._backend.openssl_assert(res != 0)
+ self._backend.openssl_assert(
+ outlen[0] == self.algorithm.digest_size
+ )
+ return self._backend._ffi.buffer(buf)[:outlen[0]]
+
+ def _finalize_xof(self):
buf = self._backend._ffi.new("unsigned char[]",
- self._backend._lib.EVP_MAX_MD_SIZE)
- outlen = self._backend._ffi.new("unsigned int *")
- res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen)
+ self.algorithm.digest_size)
+ res = self._backend._lib.EVP_DigestFinalXOF(
+ self._ctx, buf, self.algorithm.digest_size
+ )
self._backend.openssl_assert(res != 0)
- self._backend.openssl_assert(outlen[0] == self.algorithm.digest_size)
- return self._backend._ffi.buffer(buf)[:outlen[0]]
+ return self._backend._ffi.buffer(buf)[:self.algorithm.digest_size]
diff --git a/src/cryptography/hazmat/primitives/hashes.py b/src/cryptography/hazmat/primitives/hashes.py
index 0d6e47fb..9be2b600 100644
--- a/src/cryptography/hazmat/primitives/hashes.py
+++ b/src/cryptography/hazmat/primitives/hashes.py
@@ -57,6 +57,13 @@ class HashContext(object):
"""
+@six.add_metaclass(abc.ABCMeta)
+class ExtendableOutputFunction(object):
+ """
+ An interface for extendable output functions.
+ """
+
+
@utils.register_interface(HashContext)
class Hash(object):
def __init__(self, algorithm, backend, ctx=None):
@@ -174,6 +181,40 @@ class SHA3_512(object): # noqa: N801
@utils.register_interface(HashAlgorithm)
+@utils.register_interface(ExtendableOutputFunction)
+class SHAKE128(object):
+ name = "shake128"
+
+ def __init__(self, digest_size):
+ if not isinstance(digest_size, six.integer_types):
+ raise TypeError("digest_size must be an integer")
+
+ if digest_size < 1:
+ raise ValueError("digest_size must be a positive integer")
+
+ self._digest_size = digest_size
+
+ digest_size = utils.read_only_property("_digest_size")
+
+
+@utils.register_interface(HashAlgorithm)
+@utils.register_interface(ExtendableOutputFunction)
+class SHAKE256(object):
+ name = "shake256"
+
+ def __init__(self, digest_size):
+ if not isinstance(digest_size, six.integer_types):
+ raise TypeError("digest_size must be an integer")
+
+ if digest_size < 1:
+ raise ValueError("digest_size must be a positive integer")
+
+ self._digest_size = digest_size
+
+ digest_size = utils.read_only_property("_digest_size")
+
+
+@utils.register_interface(HashAlgorithm)
class MD5(object):
name = "md5"
digest_size = 16