Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Doc/library/hashlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ library that Python uses on your platform. On most platforms the
that the hashing algorithm is not used in a security context, e.g. as a
non-cryptographic one-way compression function.

Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer.

For example, to obtain the digest of the byte string ``b'Nobody inspects the
spammish repetition'``::

Expand Down
4 changes: 2 additions & 2 deletions Lib/hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@
__builtin_constructor_cache = {}

__block_openssl_constructor = {
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
'shake_128', 'shake_256',
'blake2b', 'blake2s',
}

Expand Down Expand Up @@ -125,6 +123,8 @@ def __get_openssl_constructor(name):
# Prefer our blake2 and sha3 implementation.
return __get_builtin_constructor(name)
try:
# MD5, SHA1, and SHA2 are in all supported OpenSSL versions
# SHA3/shake are available in OpenSSL 1.1.1+
f = getattr(_hashlib, 'openssl_' + name)
# Allow the C module to raise ValueError. The function will be
# defined but the hash not actually available thanks to OpenSSL.
Expand Down
18 changes: 17 additions & 1 deletion Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])

try:
from _hashlib import HASH
from _hashlib import HASH, HASHXOF
except ImportError:
HASH = None
HASHXOF = None

try:
import _blake2
Expand Down Expand Up @@ -254,6 +255,9 @@ def test_digest_length_overflow(self):
h = cons()
if h.name not in self.shakes:
continue
if HASH is not None and isinstance(h, HASH):
# _hashopenssl's take a size_t
continue
for digest in h.digest, h.hexdigest:
self.assertRaises(ValueError, digest, -10)
for length in large_sizes:
Expand Down Expand Up @@ -860,6 +864,18 @@ def hash_in_chunks(chunk_size):
def test_get_fips_mode(self):
self.assertIsInstance(c_hashlib.get_fips_mode(), int)

@unittest.skipUnless(HASH is not None, 'need _hashlib')
def test_internal_types(self):
# internal types like _hashlib.HASH are not constructable
with self.assertRaisesRegex(
TypeError, "cannot create 'HASH' instance"
):
HASH()
with self.assertRaisesRegex(
TypeError, "cannot create 'HASHXOF' instance"
):
HASHXOF()


class KDFTests(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The :mod:`hashlib` module can now use SHA3 hashes and SHAKE XOF from OpenSSL
when available.
Loading