Skip to content

Commit d5b3f6b

Browse files
authored
bpo-37630: Use SHA3 and SHAKE XOF from OpenSSL (GH-16049)
OpenSSL 1.1.1 comes with SHA3 and SHAKE builtin. Signed-off-by: Christian Heimes <[email protected]> Automerge-Triggered-By: @tiran
1 parent b17e49e commit d5b3f6b

File tree

6 files changed

+845
-21
lines changed

6 files changed

+845
-21
lines changed

Doc/library/hashlib.rst

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ library that Python uses on your platform. On most platforms the
8787
that the hashing algorithm is not used in a security context, e.g. as a
8888
non-cryptographic one-way compression function.
8989

90+
Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer.
91+
9092
For example, to obtain the digest of the byte string ``b'Nobody inspects the
9193
spammish repetition'``::
9294

Lib/hashlib.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@
7171
__builtin_constructor_cache = {}
7272

7373
__block_openssl_constructor = {
74-
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
75-
'shake_128', 'shake_256',
7674
'blake2b', 'blake2s',
7775
}
7876

@@ -125,6 +123,8 @@ def __get_openssl_constructor(name):
125123
# Prefer our blake2 and sha3 implementation.
126124
return __get_builtin_constructor(name)
127125
try:
126+
# MD5, SHA1, and SHA2 are in all supported OpenSSL versions
127+
# SHA3/shake are available in OpenSSL 1.1.1+
128128
f = getattr(_hashlib, 'openssl_' + name)
129129
# Allow the C module to raise ValueError. The function will be
130130
# defined but the hash not actually available thanks to OpenSSL.

Lib/test/test_hashlib.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
2828

2929
try:
30-
from _hashlib import HASH
30+
from _hashlib import HASH, HASHXOF
3131
except ImportError:
3232
HASH = None
33+
HASHXOF = None
3334

3435
try:
3536
import _blake2
@@ -254,6 +255,9 @@ def test_digest_length_overflow(self):
254255
h = cons()
255256
if h.name not in self.shakes:
256257
continue
258+
if HASH is not None and isinstance(h, HASH):
259+
# _hashopenssl's take a size_t
260+
continue
257261
for digest in h.digest, h.hexdigest:
258262
self.assertRaises(ValueError, digest, -10)
259263
for length in large_sizes:
@@ -860,6 +864,18 @@ def hash_in_chunks(chunk_size):
860864
def test_get_fips_mode(self):
861865
self.assertIsInstance(c_hashlib.get_fips_mode(), int)
862866

867+
@unittest.skipUnless(HASH is not None, 'need _hashlib')
868+
def test_internal_types(self):
869+
# internal types like _hashlib.HASH are not constructable
870+
with self.assertRaisesRegex(
871+
TypeError, "cannot create 'HASH' instance"
872+
):
873+
HASH()
874+
with self.assertRaisesRegex(
875+
TypeError, "cannot create 'HASHXOF' instance"
876+
):
877+
HASHXOF()
878+
863879

864880
class KDFTests(unittest.TestCase):
865881

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

0 commit comments

Comments
 (0)