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