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