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