• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Test hashlib module
2#
3# $Id$
4#
5#  Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
6#  Licensed to PSF under a Contributor Agreement.
7#
8
9import array
10from binascii import unhexlify
11import hashlib
12import importlib
13import itertools
14import os
15import sys
16import sysconfig
17import threading
18import unittest
19import warnings
20from test import support
21from test.support import _4G, bigmemtest
22from test.support.import_helper import import_fresh_module
23from test.support import threading_helper
24from test.support import warnings_helper
25from http.client import HTTPException
26
27# Were we compiled --with-pydebug or with #define Py_DEBUG?
28COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')
29
30# default builtin hash module
31default_builtin_hashes = {'md5', 'sha1', 'sha256', 'sha512', 'sha3', 'blake2'}
32# --with-builtin-hashlib-hashes override
33builtin_hashes = sysconfig.get_config_var("PY_BUILTIN_HASHLIB_HASHES")
34if builtin_hashes is None:
35    builtin_hashes = default_builtin_hashes
36else:
37    builtin_hashes = {
38        m.strip() for m in builtin_hashes.strip('"').lower().split(",")
39    }
40
41# hashlib with and without OpenSSL backend for PBKDF2
42# only import builtin_hashlib when all builtin hashes are available.
43# Otherwise import prints noise on stderr
44openssl_hashlib = import_fresh_module('hashlib', fresh=['_hashlib'])
45if builtin_hashes == default_builtin_hashes:
46    builtin_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
47else:
48    builtin_hashlib = None
49
50try:
51    from _hashlib import HASH, HASHXOF, openssl_md_meth_names, get_fips_mode
52except ImportError:
53    HASH = None
54    HASHXOF = None
55    openssl_md_meth_names = frozenset()
56
57    def get_fips_mode():
58        return 0
59
60try:
61    import _blake2
62except ImportError:
63    _blake2 = None
64
65requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2')
66
67
68def hexstr(s):
69    assert isinstance(s, bytes), repr(s)
70    h = "0123456789abcdef"
71    r = ''
72    for i in s:
73        r += h[(i >> 4) & 0xF] + h[i & 0xF]
74    return r
75
76
77URL = "http://www.pythontest.net/hashlib/{}.txt"
78
79def read_vectors(hash_name):
80    url = URL.format(hash_name)
81    try:
82        testdata = support.open_urlresource(url, encoding="utf-8")
83    except (OSError, HTTPException):
84        raise unittest.SkipTest("Could not retrieve {}".format(url))
85    with testdata:
86        for line in testdata:
87            line = line.strip()
88            if line.startswith('#') or not line:
89                continue
90            parts = line.split(',')
91            parts[0] = bytes.fromhex(parts[0])
92            yield parts
93
94
95class HashLibTestCase(unittest.TestCase):
96    supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
97                             'sha224', 'SHA224', 'sha256', 'SHA256',
98                             'sha384', 'SHA384', 'sha512', 'SHA512',
99                             'blake2b', 'blake2s',
100                             'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
101                             'shake_128', 'shake_256')
102
103    shakes = {'shake_128', 'shake_256'}
104
105    # Issue #14693: fallback modules are always compiled under POSIX
106    _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG
107
108    def _conditional_import_module(self, module_name):
109        """Import a module and return a reference to it or None on failure."""
110        try:
111            return importlib.import_module(module_name)
112        except ModuleNotFoundError as error:
113            if self._warn_on_extension_import and module_name in builtin_hashes:
114                warnings.warn('Did a C extension fail to compile? %s' % error)
115        return None
116
117    def __init__(self, *args, **kwargs):
118        algorithms = set()
119        for algorithm in self.supported_hash_names:
120            algorithms.add(algorithm.lower())
121
122        _blake2 = self._conditional_import_module('_blake2')
123        if _blake2:
124            algorithms.update({'blake2b', 'blake2s'})
125
126        self.constructors_to_test = {}
127        for algorithm in algorithms:
128            self.constructors_to_test[algorithm] = set()
129
130        # For each algorithm, test the direct constructor and the use
131        # of hashlib.new given the algorithm name.
132        for algorithm, constructors in self.constructors_to_test.items():
133            constructors.add(getattr(hashlib, algorithm))
134            def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, **kwargs):
135                if data is None:
136                    return hashlib.new(_alg, **kwargs)
137                return hashlib.new(_alg, data, **kwargs)
138            constructors.add(_test_algorithm_via_hashlib_new)
139
140        _hashlib = self._conditional_import_module('_hashlib')
141        self._hashlib = _hashlib
142        if _hashlib:
143            # These two algorithms should always be present when this module
144            # is compiled.  If not, something was compiled wrong.
145            self.assertTrue(hasattr(_hashlib, 'openssl_md5'))
146            self.assertTrue(hasattr(_hashlib, 'openssl_sha1'))
147            for algorithm, constructors in self.constructors_to_test.items():
148                constructor = getattr(_hashlib, 'openssl_'+algorithm, None)
149                if constructor:
150                    try:
151                        constructor()
152                    except ValueError:
153                        # default constructor blocked by crypto policy
154                        pass
155                    else:
156                        constructors.add(constructor)
157
158        def add_builtin_constructor(name):
159            constructor = getattr(hashlib, "__get_builtin_constructor")(name)
160            self.constructors_to_test[name].add(constructor)
161
162        _md5 = self._conditional_import_module('_md5')
163        if _md5:
164            add_builtin_constructor('md5')
165        _sha1 = self._conditional_import_module('_sha1')
166        if _sha1:
167            add_builtin_constructor('sha1')
168        _sha256 = self._conditional_import_module('_sha256')
169        if _sha256:
170            add_builtin_constructor('sha224')
171            add_builtin_constructor('sha256')
172        _sha512 = self._conditional_import_module('_sha512')
173        if _sha512:
174            add_builtin_constructor('sha384')
175            add_builtin_constructor('sha512')
176        if _blake2:
177            add_builtin_constructor('blake2s')
178            add_builtin_constructor('blake2b')
179
180        _sha3 = self._conditional_import_module('_sha3')
181        if _sha3:
182            add_builtin_constructor('sha3_224')
183            add_builtin_constructor('sha3_256')
184            add_builtin_constructor('sha3_384')
185            add_builtin_constructor('sha3_512')
186            add_builtin_constructor('shake_128')
187            add_builtin_constructor('shake_256')
188
189        super(HashLibTestCase, self).__init__(*args, **kwargs)
190
191    @property
192    def hash_constructors(self):
193        constructors = self.constructors_to_test.values()
194        return itertools.chain.from_iterable(constructors)
195
196    @property
197    def is_fips_mode(self):
198        return get_fips_mode()
199
200    def test_hash_array(self):
201        a = array.array("b", range(10))
202        for cons in self.hash_constructors:
203            c = cons(a, usedforsecurity=False)
204            if c.name in self.shakes:
205                c.hexdigest(16)
206            else:
207                c.hexdigest()
208
209    def test_algorithms_guaranteed(self):
210        self.assertEqual(hashlib.algorithms_guaranteed,
211            set(_algo for _algo in self.supported_hash_names
212                  if _algo.islower()))
213
214    def test_algorithms_available(self):
215        self.assertTrue(set(hashlib.algorithms_guaranteed).
216                            issubset(hashlib.algorithms_available))
217
218    def test_usedforsecurity_true(self):
219        hashlib.new("sha256", usedforsecurity=True)
220        if self.is_fips_mode:
221            self.skipTest("skip in FIPS mode")
222        for cons in self.hash_constructors:
223            cons(usedforsecurity=True)
224            cons(b'', usedforsecurity=True)
225        hashlib.new("md5", usedforsecurity=True)
226        hashlib.md5(usedforsecurity=True)
227        if self._hashlib is not None:
228            self._hashlib.new("md5", usedforsecurity=True)
229            self._hashlib.openssl_md5(usedforsecurity=True)
230
231    def test_usedforsecurity_false(self):
232        hashlib.new("sha256", usedforsecurity=False)
233        for cons in self.hash_constructors:
234            cons(usedforsecurity=False)
235            cons(b'', usedforsecurity=False)
236        hashlib.new("md5", usedforsecurity=False)
237        hashlib.md5(usedforsecurity=False)
238        if self._hashlib is not None:
239            self._hashlib.new("md5", usedforsecurity=False)
240            self._hashlib.openssl_md5(usedforsecurity=False)
241
242    def test_unknown_hash(self):
243        self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
244        self.assertRaises(TypeError, hashlib.new, 1)
245
246    def test_new_upper_to_lower(self):
247        self.assertEqual(hashlib.new("SHA256").name, "sha256")
248
249    def test_get_builtin_constructor(self):
250        get_builtin_constructor = getattr(hashlib,
251                                          '__get_builtin_constructor')
252        builtin_constructor_cache = getattr(hashlib,
253                                            '__builtin_constructor_cache')
254        self.assertRaises(ValueError, get_builtin_constructor, 'test')
255        try:
256            import _md5
257        except ImportError:
258            self.skipTest("_md5 module not available")
259        # This forces an ImportError for "import _md5" statements
260        sys.modules['_md5'] = None
261        # clear the cache
262        builtin_constructor_cache.clear()
263        try:
264            self.assertRaises(ValueError, get_builtin_constructor, 'md5')
265        finally:
266            if '_md5' in locals():
267                sys.modules['_md5'] = _md5
268            else:
269                del sys.modules['_md5']
270        self.assertRaises(TypeError, get_builtin_constructor, 3)
271        constructor = get_builtin_constructor('md5')
272        self.assertIs(constructor, _md5.md5)
273        self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])
274
275    def test_hexdigest(self):
276        for cons in self.hash_constructors:
277            h = cons(usedforsecurity=False)
278            if h.name in self.shakes:
279                self.assertIsInstance(h.digest(16), bytes)
280                self.assertEqual(hexstr(h.digest(16)), h.hexdigest(16))
281            else:
282                self.assertIsInstance(h.digest(), bytes)
283                self.assertEqual(hexstr(h.digest()), h.hexdigest())
284
285    def test_digest_length_overflow(self):
286        # See issue #34922
287        large_sizes = (2**29, 2**32-10, 2**32+10, 2**61, 2**64-10, 2**64+10)
288        for cons in self.hash_constructors:
289            h = cons(usedforsecurity=False)
290            if h.name not in self.shakes:
291                continue
292            if HASH is not None and isinstance(h, HASH):
293                # _hashopenssl's take a size_t
294                continue
295            for digest in h.digest, h.hexdigest:
296                self.assertRaises(ValueError, digest, -10)
297                for length in large_sizes:
298                    with self.assertRaises((ValueError, OverflowError)):
299                        digest(length)
300
301    def test_name_attribute(self):
302        for cons in self.hash_constructors:
303            h = cons(usedforsecurity=False)
304            self.assertIsInstance(h.name, str)
305            if h.name in self.supported_hash_names:
306                self.assertIn(h.name, self.supported_hash_names)
307            else:
308                self.assertNotIn(h.name, self.supported_hash_names)
309            self.assertEqual(
310                h.name,
311                hashlib.new(h.name, usedforsecurity=False).name
312            )
313
314    def test_large_update(self):
315        aas = b'a' * 128
316        bees = b'b' * 127
317        cees = b'c' * 126
318        dees = b'd' * 2048 #  HASHLIB_GIL_MINSIZE
319
320        for cons in self.hash_constructors:
321            m1 = cons(usedforsecurity=False)
322            m1.update(aas)
323            m1.update(bees)
324            m1.update(cees)
325            m1.update(dees)
326            if m1.name in self.shakes:
327                args = (16,)
328            else:
329                args = ()
330
331            m2 = cons(usedforsecurity=False)
332            m2.update(aas + bees + cees + dees)
333            self.assertEqual(m1.digest(*args), m2.digest(*args))
334
335            m3 = cons(aas + bees + cees + dees, usedforsecurity=False)
336            self.assertEqual(m1.digest(*args), m3.digest(*args))
337
338            # verify copy() doesn't touch original
339            m4 = cons(aas + bees + cees, usedforsecurity=False)
340            m4_digest = m4.digest(*args)
341            m4_copy = m4.copy()
342            m4_copy.update(dees)
343            self.assertEqual(m1.digest(*args), m4_copy.digest(*args))
344            self.assertEqual(m4.digest(*args), m4_digest)
345
346    def check(self, name, data, hexdigest, shake=False, **kwargs):
347        length = len(hexdigest)//2
348        hexdigest = hexdigest.lower()
349        constructors = self.constructors_to_test[name]
350        # 2 is for hashlib.name(...) and hashlib.new(name, ...)
351        self.assertGreaterEqual(len(constructors), 2)
352        for hash_object_constructor in constructors:
353            m = hash_object_constructor(data, **kwargs)
354            computed = m.hexdigest() if not shake else m.hexdigest(length)
355            self.assertEqual(
356                    computed, hexdigest,
357                    "Hash algorithm %s constructed using %s returned hexdigest"
358                    " %r for %d byte input data that should have hashed to %r."
359                    % (name, hash_object_constructor,
360                       computed, len(data), hexdigest))
361            computed = m.digest() if not shake else m.digest(length)
362            digest = bytes.fromhex(hexdigest)
363            self.assertEqual(computed, digest)
364            if not shake:
365                self.assertEqual(len(digest), m.digest_size)
366
367    def check_no_unicode(self, algorithm_name):
368        # Unicode objects are not allowed as input.
369        constructors = self.constructors_to_test[algorithm_name]
370        for hash_object_constructor in constructors:
371            self.assertRaises(TypeError, hash_object_constructor, 'spam')
372
373    def test_no_unicode(self):
374        self.check_no_unicode('md5')
375        self.check_no_unicode('sha1')
376        self.check_no_unicode('sha224')
377        self.check_no_unicode('sha256')
378        self.check_no_unicode('sha384')
379        self.check_no_unicode('sha512')
380
381    @requires_blake2
382    def test_no_unicode_blake2(self):
383        self.check_no_unicode('blake2b')
384        self.check_no_unicode('blake2s')
385
386    def test_no_unicode_sha3(self):
387        self.check_no_unicode('sha3_224')
388        self.check_no_unicode('sha3_256')
389        self.check_no_unicode('sha3_384')
390        self.check_no_unicode('sha3_512')
391        self.check_no_unicode('shake_128')
392        self.check_no_unicode('shake_256')
393
394    def check_blocksize_name(self, name, block_size=0, digest_size=0,
395                             digest_length=None):
396        constructors = self.constructors_to_test[name]
397        for hash_object_constructor in constructors:
398            m = hash_object_constructor(usedforsecurity=False)
399            self.assertEqual(m.block_size, block_size)
400            self.assertEqual(m.digest_size, digest_size)
401            if digest_length:
402                self.assertEqual(len(m.digest(digest_length)),
403                                 digest_length)
404                self.assertEqual(len(m.hexdigest(digest_length)),
405                                 2*digest_length)
406            else:
407                self.assertEqual(len(m.digest()), digest_size)
408                self.assertEqual(len(m.hexdigest()), 2*digest_size)
409            self.assertEqual(m.name, name)
410            # split for sha3_512 / _sha3.sha3 object
411            self.assertIn(name.split("_")[0], repr(m))
412
413    def test_blocksize_name(self):
414        self.check_blocksize_name('md5', 64, 16)
415        self.check_blocksize_name('sha1', 64, 20)
416        self.check_blocksize_name('sha224', 64, 28)
417        self.check_blocksize_name('sha256', 64, 32)
418        self.check_blocksize_name('sha384', 128, 48)
419        self.check_blocksize_name('sha512', 128, 64)
420
421    def test_blocksize_name_sha3(self):
422        self.check_blocksize_name('sha3_224', 144, 28)
423        self.check_blocksize_name('sha3_256', 136, 32)
424        self.check_blocksize_name('sha3_384', 104, 48)
425        self.check_blocksize_name('sha3_512', 72, 64)
426        self.check_blocksize_name('shake_128', 168, 0, 32)
427        self.check_blocksize_name('shake_256', 136, 0, 64)
428
429    def check_sha3(self, name, capacity, rate, suffix):
430        constructors = self.constructors_to_test[name]
431        for hash_object_constructor in constructors:
432            m = hash_object_constructor()
433            if HASH is not None and isinstance(m, HASH):
434                # _hashopenssl's variant does not have extra SHA3 attributes
435                continue
436            self.assertEqual(capacity + rate, 1600)
437            self.assertEqual(m._capacity_bits, capacity)
438            self.assertEqual(m._rate_bits, rate)
439            self.assertEqual(m._suffix, suffix)
440
441    def test_extra_sha3(self):
442        self.check_sha3('sha3_224', 448, 1152, b'\x06')
443        self.check_sha3('sha3_256', 512, 1088, b'\x06')
444        self.check_sha3('sha3_384', 768, 832, b'\x06')
445        self.check_sha3('sha3_512', 1024, 576, b'\x06')
446        self.check_sha3('shake_128', 256, 1344, b'\x1f')
447        self.check_sha3('shake_256', 512, 1088, b'\x1f')
448
449    @requires_blake2
450    def test_blocksize_name_blake2(self):
451        self.check_blocksize_name('blake2b', 128, 64)
452        self.check_blocksize_name('blake2s', 64, 32)
453
454    def test_case_md5_0(self):
455        self.check(
456            'md5', b'', 'd41d8cd98f00b204e9800998ecf8427e',
457            usedforsecurity=False
458        )
459
460    def test_case_md5_1(self):
461        self.check(
462            'md5', b'abc', '900150983cd24fb0d6963f7d28e17f72',
463            usedforsecurity=False
464        )
465
466    def test_case_md5_2(self):
467        self.check(
468            'md5',
469            b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
470            'd174ab98d277d9f5a5611c2c9f419d9f',
471            usedforsecurity=False
472        )
473
474    @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems')
475    @bigmemtest(size=_4G + 5, memuse=1, dry_run=False)
476    def test_case_md5_huge(self, size):
477        self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d')
478
479    @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
480    @bigmemtest(size=_4G - 1, memuse=1, dry_run=False)
481    def test_case_md5_uintmax(self, size):
482        self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
483
484    @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
485    @bigmemtest(size=_4G - 1, memuse=1, dry_run=False)
486    def test_sha3_update_overflow(self, size):
487        """Regression test for gh-98517 CVE-2022-37454."""
488        h = hashlib.sha3_224()
489        h.update(b'\x01')
490        h.update(b'\x01'*0xffff_ffff)
491        self.assertEqual(h.hexdigest(), '80762e8ce6700f114fec0f621fd97c4b9c00147fa052215294cceeed')
492
493    # use the three examples from Federal Information Processing Standards
494    # Publication 180-1, Secure Hash Standard,  1995 April 17
495    # http://www.itl.nist.gov/div897/pubs/fip180-1.htm
496
497    def test_case_sha1_0(self):
498        self.check('sha1', b"",
499                   "da39a3ee5e6b4b0d3255bfef95601890afd80709")
500
501    def test_case_sha1_1(self):
502        self.check('sha1', b"abc",
503                   "a9993e364706816aba3e25717850c26c9cd0d89d")
504
505    def test_case_sha1_2(self):
506        self.check('sha1',
507                   b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
508                   "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
509
510    def test_case_sha1_3(self):
511        self.check('sha1', b"a" * 1000000,
512                   "34aa973cd4c4daa4f61eeb2bdbad27316534016f")
513
514
515    # use the examples from Federal Information Processing Standards
516    # Publication 180-2, Secure Hash Standard,  2002 August 1
517    # http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
518
519    def test_case_sha224_0(self):
520        self.check('sha224', b"",
521          "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
522
523    def test_case_sha224_1(self):
524        self.check('sha224', b"abc",
525          "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7")
526
527    def test_case_sha224_2(self):
528        self.check('sha224',
529          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
530          "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525")
531
532    def test_case_sha224_3(self):
533        self.check('sha224', b"a" * 1000000,
534          "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67")
535
536
537    def test_case_sha256_0(self):
538        self.check('sha256', b"",
539          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
540
541    def test_case_sha256_1(self):
542        self.check('sha256', b"abc",
543          "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
544
545    def test_case_sha256_2(self):
546        self.check('sha256',
547          b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
548          "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1")
549
550    def test_case_sha256_3(self):
551        self.check('sha256', b"a" * 1000000,
552          "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0")
553
554
555    def test_case_sha384_0(self):
556        self.check('sha384', b"",
557          "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da"+
558          "274edebfe76f65fbd51ad2f14898b95b")
559
560    def test_case_sha384_1(self):
561        self.check('sha384', b"abc",
562          "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"+
563          "8086072ba1e7cc2358baeca134c825a7")
564
565    def test_case_sha384_2(self):
566        self.check('sha384',
567                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
568                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
569          "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"+
570          "fcc7c71a557e2db966c3e9fa91746039")
571
572    def test_case_sha384_3(self):
573        self.check('sha384', b"a" * 1000000,
574          "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"+
575          "07b8b3dc38ecc4ebae97ddd87f3d8985")
576
577
578    def test_case_sha512_0(self):
579        self.check('sha512', b"",
580          "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"+
581          "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
582
583    def test_case_sha512_1(self):
584        self.check('sha512', b"abc",
585          "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"+
586          "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
587
588    def test_case_sha512_2(self):
589        self.check('sha512',
590                   b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+
591                   b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
592          "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"+
593          "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909")
594
595    def test_case_sha512_3(self):
596        self.check('sha512', b"a" * 1000000,
597          "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+
598          "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b")
599
600    def check_blake2(self, constructor, salt_size, person_size, key_size,
601                     digest_size, max_offset):
602        self.assertEqual(constructor.SALT_SIZE, salt_size)
603        for i in range(salt_size + 1):
604            constructor(salt=b'a' * i)
605        salt = b'a' * (salt_size + 1)
606        self.assertRaises(ValueError, constructor, salt=salt)
607
608        self.assertEqual(constructor.PERSON_SIZE, person_size)
609        for i in range(person_size+1):
610            constructor(person=b'a' * i)
611        person = b'a' * (person_size + 1)
612        self.assertRaises(ValueError, constructor, person=person)
613
614        self.assertEqual(constructor.MAX_DIGEST_SIZE, digest_size)
615        for i in range(1, digest_size + 1):
616            constructor(digest_size=i)
617        self.assertRaises(ValueError, constructor, digest_size=-1)
618        self.assertRaises(ValueError, constructor, digest_size=0)
619        self.assertRaises(ValueError, constructor, digest_size=digest_size+1)
620
621        self.assertEqual(constructor.MAX_KEY_SIZE, key_size)
622        for i in range(key_size+1):
623            constructor(key=b'a' * i)
624        key = b'a' * (key_size + 1)
625        self.assertRaises(ValueError, constructor, key=key)
626        self.assertEqual(constructor().hexdigest(),
627                         constructor(key=b'').hexdigest())
628
629        for i in range(0, 256):
630            constructor(fanout=i)
631        self.assertRaises(ValueError, constructor, fanout=-1)
632        self.assertRaises(ValueError, constructor, fanout=256)
633
634        for i in range(1, 256):
635            constructor(depth=i)
636        self.assertRaises(ValueError, constructor, depth=-1)
637        self.assertRaises(ValueError, constructor, depth=0)
638        self.assertRaises(ValueError, constructor, depth=256)
639
640        for i in range(0, 256):
641            constructor(node_depth=i)
642        self.assertRaises(ValueError, constructor, node_depth=-1)
643        self.assertRaises(ValueError, constructor, node_depth=256)
644
645        for i in range(0, digest_size + 1):
646            constructor(inner_size=i)
647        self.assertRaises(ValueError, constructor, inner_size=-1)
648        self.assertRaises(ValueError, constructor, inner_size=digest_size+1)
649
650        constructor(leaf_size=0)
651        constructor(leaf_size=(1<<32)-1)
652        self.assertRaises(ValueError, constructor, leaf_size=-1)
653        self.assertRaises(OverflowError, constructor, leaf_size=1<<32)
654
655        constructor(node_offset=0)
656        constructor(node_offset=max_offset)
657        self.assertRaises(ValueError, constructor, node_offset=-1)
658        self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)
659
660        self.assertRaises(TypeError, constructor, data=b'')
661        self.assertRaises(TypeError, constructor, string=b'')
662        self.assertRaises(TypeError, constructor, '')
663
664        constructor(
665            b'',
666            key=b'',
667            salt=b'',
668            person=b'',
669            digest_size=17,
670            fanout=1,
671            depth=1,
672            leaf_size=256,
673            node_offset=512,
674            node_depth=1,
675            inner_size=7,
676            last_node=True
677        )
678
679    def blake2_rfc7693(self, constructor, md_len, in_len):
680        def selftest_seq(length, seed):
681            mask = (1<<32)-1
682            a = (0xDEAD4BAD * seed) & mask
683            b = 1
684            out = bytearray(length)
685            for i in range(length):
686                t = (a + b) & mask
687                a, b = b, t
688                out[i] = (t >> 24) & 0xFF
689            return out
690        outer = constructor(digest_size=32)
691        for outlen in md_len:
692            for inlen in in_len:
693                indata = selftest_seq(inlen, inlen)
694                key = selftest_seq(outlen, outlen)
695                unkeyed = constructor(indata, digest_size=outlen)
696                outer.update(unkeyed.digest())
697                keyed = constructor(indata, key=key, digest_size=outlen)
698                outer.update(keyed.digest())
699        return outer.hexdigest()
700
701    @requires_blake2
702    def test_blake2b(self):
703        self.check_blake2(hashlib.blake2b, 16, 16, 64, 64, (1<<64)-1)
704        b2b_md_len = [20, 32, 48, 64]
705        b2b_in_len = [0, 3, 128, 129, 255, 1024]
706        self.assertEqual(
707            self.blake2_rfc7693(hashlib.blake2b, b2b_md_len, b2b_in_len),
708            "c23a7800d98123bd10f506c61e29da5603d763b8bbad2e737f5e765a7bccd475")
709
710    @requires_blake2
711    def test_case_blake2b_0(self):
712        self.check('blake2b', b"",
713          "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419"+
714          "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce")
715
716    @requires_blake2
717    def test_case_blake2b_1(self):
718        self.check('blake2b', b"abc",
719          "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"+
720          "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")
721
722    @requires_blake2
723    def test_case_blake2b_all_parameters(self):
724        # This checks that all the parameters work in general, and also that
725        # parameter byte order doesn't get confused on big endian platforms.
726        self.check('blake2b', b"foo",
727          "920568b0c5873b2f0ab67bedb6cf1b2b",
728          digest_size=16,
729          key=b"bar",
730          salt=b"baz",
731          person=b"bing",
732          fanout=2,
733          depth=3,
734          leaf_size=4,
735          node_offset=5,
736          node_depth=6,
737          inner_size=7,
738          last_node=True)
739
740    @requires_blake2
741    def test_blake2b_vectors(self):
742        for msg, key, md in read_vectors('blake2b'):
743            key = bytes.fromhex(key)
744            self.check('blake2b', msg, md, key=key)
745
746    @requires_blake2
747    def test_blake2s(self):
748        self.check_blake2(hashlib.blake2s, 8, 8, 32, 32, (1<<48)-1)
749        b2s_md_len = [16, 20, 28, 32]
750        b2s_in_len = [0, 3, 64, 65, 255, 1024]
751        self.assertEqual(
752            self.blake2_rfc7693(hashlib.blake2s, b2s_md_len, b2s_in_len),
753            "6a411f08ce25adcdfb02aba641451cec53c598b24f4fc787fbdc88797f4c1dfe")
754
755    @requires_blake2
756    def test_case_blake2s_0(self):
757        self.check('blake2s', b"",
758          "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9")
759
760    @requires_blake2
761    def test_case_blake2s_1(self):
762        self.check('blake2s', b"abc",
763          "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982")
764
765    @requires_blake2
766    def test_case_blake2s_all_parameters(self):
767        # This checks that all the parameters work in general, and also that
768        # parameter byte order doesn't get confused on big endian platforms.
769        self.check('blake2s', b"foo",
770          "bf2a8f7fe3c555012a6f8046e646bc75",
771          digest_size=16,
772          key=b"bar",
773          salt=b"baz",
774          person=b"bing",
775          fanout=2,
776          depth=3,
777          leaf_size=4,
778          node_offset=5,
779          node_depth=6,
780          inner_size=7,
781          last_node=True)
782
783    @requires_blake2
784    def test_blake2s_vectors(self):
785        for msg, key, md in read_vectors('blake2s'):
786            key = bytes.fromhex(key)
787            self.check('blake2s', msg, md, key=key)
788
789    def test_case_sha3_224_0(self):
790        self.check('sha3_224', b"",
791          "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7")
792
793    def test_case_sha3_224_vector(self):
794        for msg, md in read_vectors('sha3_224'):
795            self.check('sha3_224', msg, md)
796
797    def test_case_sha3_256_0(self):
798        self.check('sha3_256', b"",
799          "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a")
800
801    def test_case_sha3_256_vector(self):
802        for msg, md in read_vectors('sha3_256'):
803            self.check('sha3_256', msg, md)
804
805    def test_case_sha3_384_0(self):
806        self.check('sha3_384', b"",
807          "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+
808          "c3713831264adb47fb6bd1e058d5f004")
809
810    def test_case_sha3_384_vector(self):
811        for msg, md in read_vectors('sha3_384'):
812            self.check('sha3_384', msg, md)
813
814    def test_case_sha3_512_0(self):
815        self.check('sha3_512', b"",
816          "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+
817          "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26")
818
819    def test_case_sha3_512_vector(self):
820        for msg, md in read_vectors('sha3_512'):
821            self.check('sha3_512', msg, md)
822
823    def test_case_shake_128_0(self):
824        self.check('shake_128', b"",
825          "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26",
826          True)
827        self.check('shake_128', b"", "7f9c", True)
828
829    def test_case_shake128_vector(self):
830        for msg, md in read_vectors('shake_128'):
831            self.check('shake_128', msg, md, True)
832
833    def test_case_shake_256_0(self):
834        self.check('shake_256', b"",
835          "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f",
836          True)
837        self.check('shake_256', b"", "46b9", True)
838
839    def test_case_shake256_vector(self):
840        for msg, md in read_vectors('shake_256'):
841            self.check('shake_256', msg, md, True)
842
843    def test_gil(self):
844        # Check things work fine with an input larger than the size required
845        # for multithreaded operation (which is hardwired to 2048).
846        gil_minsize = 2048
847
848        for cons in self.hash_constructors:
849            m = cons(usedforsecurity=False)
850            m.update(b'1')
851            m.update(b'#' * gil_minsize)
852            m.update(b'1')
853
854            m = cons(b'x' * gil_minsize, usedforsecurity=False)
855            m.update(b'1')
856
857        m = hashlib.sha256()
858        m.update(b'1')
859        m.update(b'#' * gil_minsize)
860        m.update(b'1')
861        self.assertEqual(
862            m.hexdigest(),
863            '1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
864        )
865
866        m = hashlib.sha256(b'1' + b'#' * gil_minsize + b'1')
867        self.assertEqual(
868            m.hexdigest(),
869            '1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
870        )
871
872    @threading_helper.reap_threads
873    def test_threaded_hashing(self):
874        # Updating the same hash object from several threads at once
875        # using data chunk sizes containing the same byte sequences.
876        #
877        # If the internal locks are working to prevent multiple
878        # updates on the same object from running at once, the resulting
879        # hash will be the same as doing it single threaded upfront.
880        hasher = hashlib.sha1()
881        num_threads = 5
882        smallest_data = b'swineflu'
883        data = smallest_data * 200000
884        expected_hash = hashlib.sha1(data*num_threads).hexdigest()
885
886        def hash_in_chunks(chunk_size):
887            index = 0
888            while index < len(data):
889                hasher.update(data[index:index + chunk_size])
890                index += chunk_size
891
892        threads = []
893        for threadnum in range(num_threads):
894            chunk_size = len(data) // (10 ** threadnum)
895            self.assertGreater(chunk_size, 0)
896            self.assertEqual(chunk_size % len(smallest_data), 0)
897            thread = threading.Thread(target=hash_in_chunks,
898                                      args=(chunk_size,))
899            threads.append(thread)
900
901        for thread in threads:
902            thread.start()
903        for thread in threads:
904            thread.join()
905
906        self.assertEqual(expected_hash, hasher.hexdigest())
907
908    def test_get_fips_mode(self):
909        fips_mode = self.is_fips_mode
910        if fips_mode is not None:
911            self.assertIsInstance(fips_mode, int)
912
913    @support.cpython_only
914    def test_disallow_instantiation(self):
915        for algorithm, constructors in self.constructors_to_test.items():
916            if algorithm.startswith(("sha3_", "shake", "blake")):
917                # _sha3 and _blake types can be instantiated
918                continue
919            # all other types have DISALLOW_INSTANTIATION
920            for constructor in constructors:
921                # In FIPS mode some algorithms are not available raising ValueError
922                try:
923                    h = constructor()
924                except ValueError:
925                    continue
926                with self.subTest(constructor=constructor):
927                    support.check_disallow_instantiation(self, type(h))
928
929    @unittest.skipUnless(HASH is not None, 'need _hashlib')
930    def test_hash_disallow_instantiation(self):
931        # internal types like _hashlib.HASH are not constructable
932        support.check_disallow_instantiation(self, HASH)
933        support.check_disallow_instantiation(self, HASHXOF)
934
935    def test_readonly_types(self):
936        for algorithm, constructors in self.constructors_to_test.items():
937            # all other types have DISALLOW_INSTANTIATION
938            for constructor in constructors:
939                # In FIPS mode some algorithms are not available raising ValueError
940                try:
941                    hash_type = type(constructor())
942                except ValueError:
943                    continue
944                with self.subTest(hash_type=hash_type):
945                    with self.assertRaisesRegex(TypeError, "immutable type"):
946                        hash_type.value = False
947
948
949class KDFTests(unittest.TestCase):
950
951    pbkdf2_test_vectors = [
952        (b'password', b'salt', 1, None),
953        (b'password', b'salt', 2, None),
954        (b'password', b'salt', 4096, None),
955        # too slow, it takes over a minute on a fast CPU.
956        #(b'password', b'salt', 16777216, None),
957        (b'passwordPASSWORDpassword', b'saltSALTsaltSALTsaltSALTsaltSALTsalt',
958         4096, -1),
959        (b'pass\0word', b'sa\0lt', 4096, 16),
960    ]
961
962    scrypt_test_vectors = [
963        (b'', b'', 16, 1, 1, unhexlify('77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906')),
964        (b'password', b'NaCl', 1024, 8, 16, unhexlify('fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640')),
965        (b'pleaseletmein', b'SodiumChloride', 16384, 8, 1, unhexlify('7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887')),
966   ]
967
968    pbkdf2_results = {
969        "sha1": [
970            # official test vectors from RFC 6070
971            (bytes.fromhex('0c60c80f961f0e71f3a9b524af6012062fe037a6'), None),
972            (bytes.fromhex('ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'), None),
973            (bytes.fromhex('4b007901b765489abead49d926f721d065a429c1'), None),
974            #(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None),
975            (bytes.fromhex('3d2eec4fe41c849b80c8d83662c0e44a8b291a964c'
976                           'f2f07038'), 25),
977            (bytes.fromhex('56fa6aa75548099dcc37d7f03425e0c3'), None),],
978        "sha256": [
979            (bytes.fromhex('120fb6cffcf8b32c43e7225256c4f837'
980                           'a86548c92ccc35480805987cb70be17b'), None),
981            (bytes.fromhex('ae4d0c95af6b46d32d0adff928f06dd0'
982                           '2a303f8ef3c251dfd6e2d85a95474c43'), None),
983            (bytes.fromhex('c5e478d59288c841aa530db6845c4c8d'
984                           '962893a001ce4e11a4963873aa98134a'), None),
985            #(bytes.fromhex('cf81c66fe8cfc04d1f31ecb65dab4089'
986            #               'f7f179e89b3b0bcb17ad10e3ac6eba46'), None),
987            (bytes.fromhex('348c89dbcbd32b2f32d814b8116e84cf2b17'
988                           '347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9'), 40),
989            (bytes.fromhex('89b69d0516f829893c696226650a8687'), None),],
990        "sha512": [
991            (bytes.fromhex('867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5'
992                           'd513554e1c8cf252c02d470a285a0501bad999bfe943c08f'
993                           '050235d7d68b1da55e63f73b60a57fce'), None),
994            (bytes.fromhex('e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f004071'
995                           '3f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82'
996                           'be67335c77a6068e04112754f27ccf4e'), None),
997            (bytes.fromhex('d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f8'
998                           '7f6902e072f457b5143f30602641b3d55cd335988cb36b84'
999                           '376060ecd532e039b742a239434af2d5'), None),
1000            (bytes.fromhex('8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b8'
1001                           '68c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30'
1002                           '225c583a186cd82bd4daea9724a3d3b8'), 64),
1003            (bytes.fromhex('9d9e9c4cd21fe4be24d5b8244c759665'), None),],
1004    }
1005
1006    def _test_pbkdf2_hmac(self, pbkdf2, supported):
1007        for digest_name, results in self.pbkdf2_results.items():
1008            if digest_name not in supported:
1009                continue
1010            for i, vector in enumerate(self.pbkdf2_test_vectors):
1011                password, salt, rounds, dklen = vector
1012                expected, overwrite_dklen = results[i]
1013                if overwrite_dklen:
1014                    dklen = overwrite_dklen
1015                out = pbkdf2(digest_name, password, salt, rounds, dklen)
1016                self.assertEqual(out, expected,
1017                                 (digest_name, password, salt, rounds, dklen))
1018                out = pbkdf2(digest_name, memoryview(password),
1019                             memoryview(salt), rounds, dklen)
1020                self.assertEqual(out, expected)
1021                out = pbkdf2(digest_name, bytearray(password),
1022                             bytearray(salt), rounds, dklen)
1023                self.assertEqual(out, expected)
1024                if dklen is None:
1025                    out = pbkdf2(digest_name, password, salt, rounds)
1026                    self.assertEqual(out, expected,
1027                                     (digest_name, password, salt, rounds))
1028
1029        with self.assertRaisesRegex(ValueError, '.*unsupported.*'):
1030            pbkdf2('unknown', b'pass', b'salt', 1)
1031
1032        if 'sha1' in supported:
1033            self.assertRaises(
1034                TypeError, pbkdf2, b'sha1', b'pass', b'salt', 1
1035            )
1036            self.assertRaises(
1037                TypeError, pbkdf2, 'sha1', 'pass', 'salt', 1
1038            )
1039            self.assertRaises(
1040                ValueError, pbkdf2, 'sha1', b'pass', b'salt', 0
1041            )
1042            self.assertRaises(
1043                ValueError, pbkdf2, 'sha1', b'pass', b'salt', -1
1044            )
1045            self.assertRaises(
1046                ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, 0
1047            )
1048            self.assertRaises(
1049                ValueError, pbkdf2, 'sha1', b'pass', b'salt', 1, -1
1050            )
1051            out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt',
1052                iterations=1, dklen=None)
1053            self.assertEqual(out, self.pbkdf2_results['sha1'][0][0])
1054
1055    @unittest.skipIf(builtin_hashlib is None, "test requires builtin_hashlib")
1056    def test_pbkdf2_hmac_py(self):
1057        with warnings_helper.check_warnings():
1058            self._test_pbkdf2_hmac(
1059                builtin_hashlib.pbkdf2_hmac, builtin_hashes
1060            )
1061
1062    @unittest.skipUnless(hasattr(openssl_hashlib, 'pbkdf2_hmac'),
1063                     '   test requires OpenSSL > 1.0')
1064    def test_pbkdf2_hmac_c(self):
1065        self._test_pbkdf2_hmac(openssl_hashlib.pbkdf2_hmac, openssl_md_meth_names)
1066
1067    @unittest.skipUnless(hasattr(hashlib, 'scrypt'),
1068                     '   test requires OpenSSL > 1.1')
1069    @unittest.skipIf(get_fips_mode(), reason="scrypt is blocked in FIPS mode")
1070    def test_scrypt(self):
1071        for password, salt, n, r, p, expected in self.scrypt_test_vectors:
1072            result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p)
1073            self.assertEqual(result, expected)
1074
1075        # this values should work
1076        hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1)
1077        # password and salt must be bytes-like
1078        with self.assertRaises(TypeError):
1079            hashlib.scrypt('password', salt=b'salt', n=2, r=8, p=1)
1080        with self.assertRaises(TypeError):
1081            hashlib.scrypt(b'password', salt='salt', n=2, r=8, p=1)
1082        # require keyword args
1083        with self.assertRaises(TypeError):
1084            hashlib.scrypt(b'password')
1085        with self.assertRaises(TypeError):
1086            hashlib.scrypt(b'password', b'salt')
1087        with self.assertRaises(TypeError):
1088            hashlib.scrypt(b'password', 2, 8, 1, salt=b'salt')
1089        for n in [-1, 0, 1, None]:
1090            with self.assertRaises((ValueError, OverflowError, TypeError)):
1091                hashlib.scrypt(b'password', salt=b'salt', n=n, r=8, p=1)
1092        for r in [-1, 0, None]:
1093            with self.assertRaises((ValueError, OverflowError, TypeError)):
1094                hashlib.scrypt(b'password', salt=b'salt', n=2, r=r, p=1)
1095        for p in [-1, 0, None]:
1096            with self.assertRaises((ValueError, OverflowError, TypeError)):
1097                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=p)
1098        for maxmem in [-1, None]:
1099            with self.assertRaises((ValueError, OverflowError, TypeError)):
1100                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
1101                               maxmem=maxmem)
1102        for dklen in [-1, None]:
1103            with self.assertRaises((ValueError, OverflowError, TypeError)):
1104                hashlib.scrypt(b'password', salt=b'salt', n=2, r=8, p=1,
1105                               dklen=dklen)
1106
1107    def test_normalized_name(self):
1108        self.assertNotIn("blake2b512", hashlib.algorithms_available)
1109        self.assertNotIn("sha3-512", hashlib.algorithms_available)
1110
1111
1112if __name__ == "__main__":
1113    unittest.main()
1114