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