@@ -66,6 +66,11 @@ def get_fips_mode():
6666SKIP_SHA3 = support .check_sanitizer (ub = True )
6767requires_sha3 = unittest .skipUnless (not SKIP_SHA3 , 'requires _sha3' )
6868
69+ requires_usedforsecurity = unittest .skipIf (
70+ get_fips_mode (),
71+ "If an OpenSSL FIPS mode configuration has disabled any algorithms" +
72+ " in the default provider, this test would fail."
73+ )
6974
7075def hexstr (s ):
7176 assert isinstance (s , bytes ), repr (s )
@@ -102,6 +107,7 @@ class HashLibTestCase(unittest.TestCase):
102107 'sha3_224' , 'sha3_256' , 'sha3_384' , 'sha3_512' ,
103108 'shake_128' , 'shake_256' )
104109
110+ blakes = {'blake2b' , 'blake2s' }
105111 shakes = {'shake_128' , 'shake_256' }
106112
107113 # gh-58898: Fallback modules are always compiled under POSIX.
@@ -121,9 +127,12 @@ def __init__(self, *args, **kwargs):
121127 for algorithm in self .supported_hash_names :
122128 algorithms .add (algorithm .lower ())
123129
130+ # blake2s and blake2b *require* the _blake2 builtin.
124131 _blake2 = self ._conditional_import_module ('_blake2' )
125132 if _blake2 :
126- algorithms .update ({'blake2b' , 'blake2s' })
133+ algorithms .update (self .blakes )
134+ else :
135+ algorithms .difference_update (self .blakes )
127136
128137 self .constructors_to_test = {}
129138 for algorithm in algorithms :
@@ -196,10 +205,6 @@ def hash_constructors(self):
196205 constructors = self .constructors_to_test .values ()
197206 return itertools .chain .from_iterable (constructors )
198207
199- @property
200- def is_fips_mode (self ):
201- return get_fips_mode ()
202-
203208 def test_hash_array (self ):
204209 a = array .array ("b" , range (10 ))
205210 for cons in self .hash_constructors :
@@ -222,10 +227,9 @@ def test_algorithms_available(self):
222227 for name in hashlib .algorithms_available :
223228 digest = hashlib .new (name , usedforsecurity = False )
224229
230+ @requires_usedforsecurity
225231 def test_usedforsecurity_true (self ):
226232 hashlib .new ("sha256" , usedforsecurity = True )
227- if self .is_fips_mode :
228- self .skipTest ("skip in FIPS mode" )
229233 for cons in self .hash_constructors :
230234 cons (usedforsecurity = True )
231235 cons (b'' , usedforsecurity = True )
@@ -251,7 +255,7 @@ def test_unknown_hash(self):
251255 self .assertRaises (TypeError , hashlib .new , 1 )
252256
253257 def test_new_upper_to_lower (self ):
254- self .assertEqual (hashlib .new ("SHA256" ).name , "sha256" )
258+ self .assertEqual (hashlib .new ("SHA256" , usedforsecurity = False ).name , "sha256" )
255259
256260 def test_get_builtin_constructor (self ):
257261 get_builtin_constructor = getattr (hashlib ,
@@ -309,10 +313,6 @@ def test_name_attribute(self):
309313 for cons in self .hash_constructors :
310314 h = cons (usedforsecurity = False )
311315 self .assertIsInstance (h .name , str )
312- if h .name in self .supported_hash_names :
313- self .assertIn (h .name , self .supported_hash_names )
314- else :
315- self .assertNotIn (h .name , self .supported_hash_names )
316316 self .assertEqual (
317317 h .name ,
318318 hashlib .new (h .name , usedforsecurity = False ).name
@@ -353,7 +353,7 @@ def test_large_update(self):
353353 @requires_resource ('cpu' )
354354 def test_sha256_update_over_4gb (self ):
355355 zero_1mb = b"\0 " * 1024 * 1024
356- h = hashlib .sha256 ()
356+ h = hashlib .sha256 (usedforsecurity = False )
357357 for i in range (0 , 4096 ):
358358 h .update (zero_1mb )
359359 h .update (b"hello world" )
@@ -362,24 +362,27 @@ def test_sha256_update_over_4gb(self):
362362 @requires_resource ('cpu' )
363363 def test_sha3_256_update_over_4gb (self ):
364364 zero_1mb = b"\0 " * 1024 * 1024
365- h = hashlib .sha3_256 ()
365+ h = hashlib .sha3_256 (usedforsecurity = False )
366366 for i in range (0 , 4096 ):
367367 h .update (zero_1mb )
368368 h .update (b"hello world" )
369369 self .assertEqual (h .hexdigest (), "e2d4535e3b613135c14f2fe4e026d7ad8d569db44901740beffa30d430acb038" )
370370
371+ @requires_blake2
371372 @requires_resource ('cpu' )
372373 def test_blake2_update_over_4gb (self ):
373374 # blake2s or blake2b doesn't matter based on how our C code is structured, this tests the
374375 # common loop macro logic.
375376 zero_1mb = b"\0 " * 1024 * 1024
376- h = hashlib .blake2s ()
377+ h = hashlib .blake2s (usedforsecurity = False )
377378 for i in range (0 , 4096 ):
378379 h .update (zero_1mb )
379380 h .update (b"hello world" )
380381 self .assertEqual (h .hexdigest (), "8a268e83dd30528bc0907fa2008c91de8f090a0b6e0e60a5ff0d999d8485526f" )
381382
382383 def check (self , name , data , hexdigest , shake = False , ** kwargs ):
384+ if 'usedforsecurity' not in kwargs :
385+ kwargs ['usedforsecurity' ] = False
383386 length = len (hexdigest )// 2
384387 hexdigest = hexdigest .lower ()
385388 constructors = self .constructors_to_test [name ]
@@ -404,6 +407,8 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
404407 # skip shake and blake2 extended parameter tests
405408 self .check_file_digest (name , data , hexdigest )
406409
410+ # defaults True because file_digest doesn't support the parameter.
411+ @requires_usedforsecurity
407412 def check_file_digest (self , name , data , hexdigest ):
408413 hexdigest = hexdigest .lower ()
409414 try :
@@ -434,7 +439,8 @@ def check_no_unicode(self, algorithm_name):
434439 # Unicode objects are not allowed as input.
435440 constructors = self .constructors_to_test [algorithm_name ]
436441 for hash_object_constructor in constructors :
437- self .assertRaises (TypeError , hash_object_constructor , 'spam' )
442+ with self .assertRaises (TypeError ):
443+ hash_object_constructor ('spam' , usedforsecurity = False )
438444
439445 def test_no_unicode (self ):
440446 self .check_no_unicode ('md5' )
@@ -497,7 +503,7 @@ def test_blocksize_name_sha3(self):
497503 def check_sha3 (self , name , capacity , rate , suffix ):
498504 constructors = self .constructors_to_test [name ]
499505 for hash_object_constructor in constructors :
500- m = hash_object_constructor ()
506+ m = hash_object_constructor (usedforsecurity = False )
501507 if HASH is not None and isinstance (m , HASH ):
502508 # _hashopenssl's variant does not have extra SHA3 attributes
503509 continue
@@ -661,7 +667,7 @@ def check_blake2(self, constructor, salt_size, person_size, key_size,
661667 digest_size , max_offset ):
662668 self .assertEqual (constructor .SALT_SIZE , salt_size )
663669 for i in range (salt_size + 1 ):
664- constructor (salt = b'a' * i )
670+ constructor (salt = b'a' * i , usedforsecurity = False )
665671 salt = b'a' * (salt_size + 1 )
666672 self .assertRaises (ValueError , constructor , salt = salt )
667673
@@ -975,8 +981,7 @@ def hash_in_chunks(chunk_size):
975981 self .assertEqual (expected_hash , hasher .hexdigest ())
976982
977983 def test_get_fips_mode (self ):
978- fips_mode = self .is_fips_mode
979- if fips_mode is not None :
984+ if (fips_mode := get_fips_mode ()) is not None :
980985 self .assertIsInstance (fips_mode , int )
981986
982987 @support .cpython_only
0 commit comments