@@ -143,7 +143,15 @@ def __init__(self, *args, **kwargs):
143143 # For each algorithm, test the direct constructor and the use
144144 # of hashlib.new given the algorithm name.
145145 for algorithm , constructors in self .constructors_to_test .items ():
146- constructors .add (getattr (hashlib , algorithm ))
146+ if get_fips_mode ():
147+ # Arbitrary algorithms may be missing via openssl.cnf
148+ try :
149+ constructor = getattr (hashlib , algorithm )
150+ except AttributeError :
151+ continue
152+ constructors .add (constructor )
153+ else :
154+ constructors .add (getattr (hashlib , algorithm ))
147155 def _test_algorithm_via_hashlib_new (data = None , _alg = algorithm , ** kwargs ):
148156 if data is None :
149157 return hashlib .new (_alg , ** kwargs )
@@ -219,15 +227,23 @@ def test_algorithms_guaranteed(self):
219227 set (_algo for _algo in self .supported_hash_names
220228 if _algo .islower ()))
221229
230+ @unittest .skipIf (get_fips_mode (), reason = "guaranteed algorithms may not be available in FIPS mode" )
222231 def test_algorithms_available (self ):
232+ print (f"{ get_fips_mode ()= } " )
223233 self .assertTrue (set (hashlib .algorithms_guaranteed ).
224- issubset (hashlib .algorithms_available ))
234+ issubset (hashlib .algorithms_available ),
235+ msg = f"\n { sorted (hashlib .algorithms_guaranteed )= } \n { sorted (hashlib .algorithms_available )= } " )
225236 # all available algorithms must be loadable, bpo-47101
226237 self .assertNotIn ("undefined" , hashlib .algorithms_available )
227238 for name in hashlib .algorithms_available :
228- digest = hashlib .new (name , usedforsecurity = False )
239+ with self .subTest (name = name ):
240+ if name in self .blakes and not _blake2 :
241+ self .skipTest ("requires _blake2" )
242+ hashlib .new (name , usedforsecurity = False )
229243
230244 @requires_usedforsecurity
245+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
246+ @unittest .skipUnless (hasattr (hashlib , "md5" ), "md5 unavailable" )
231247 def test_usedforsecurity_true (self ):
232248 hashlib .new ("sha256" , usedforsecurity = True )
233249 for cons in self .hash_constructors :
@@ -239,6 +255,8 @@ def test_usedforsecurity_true(self):
239255 self ._hashlib .new ("md5" , usedforsecurity = True )
240256 self ._hashlib .openssl_md5 (usedforsecurity = True )
241257
258+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
259+ @unittest .skipUnless (hasattr (hashlib , "md5" ), "md5 unavailable" )
242260 def test_usedforsecurity_false (self ):
243261 hashlib .new ("sha256" , usedforsecurity = False )
244262 for cons in self .hash_constructors :
@@ -254,6 +272,7 @@ def test_unknown_hash(self):
254272 self .assertRaises (ValueError , hashlib .new , 'spam spam spam spam spam' )
255273 self .assertRaises (TypeError , hashlib .new , 1 )
256274
275+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
257276 def test_new_upper_to_lower (self ):
258277 self .assertEqual (hashlib .new ("SHA256" , usedforsecurity = False ).name , "sha256" )
259278
@@ -387,7 +406,8 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
387406 hexdigest = hexdigest .lower ()
388407 constructors = self .constructors_to_test [name ]
389408 # 2 is for hashlib.name(...) and hashlib.new(name, ...)
390- self .assertGreaterEqual (len (constructors ), 2 )
409+ if get_fips_mode () == 0 :
410+ self .assertGreaterEqual (len (constructors ), 2 )
391411 for hash_object_constructor in constructors :
392412 m = hash_object_constructor (data , ** kwargs )
393413 computed = m .hexdigest () if not shake else m .hexdigest (length )
@@ -407,8 +427,6 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
407427 # skip shake and blake2 extended parameter tests
408428 self .check_file_digest (name , data , hexdigest )
409429
410- # defaults True because file_digest doesn't support the parameter.
411- @requires_usedforsecurity
412430 def check_file_digest (self , name , data , hexdigest ):
413431 hexdigest = hexdigest .lower ()
414432 try :
@@ -914,6 +932,7 @@ def test_case_shake256_vector(self):
914932 for msg , md in read_vectors ('shake_256' ):
915933 self .check ('shake_256' , msg , md , True )
916934
935+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
917936 def test_gil (self ):
918937 # Check things work fine with an input larger than the size required
919938 # for multithreaded operation (which is hardwired to 2048).
@@ -928,7 +947,7 @@ def test_gil(self):
928947 m = cons (b'x' * gil_minsize , usedforsecurity = False )
929948 m .update (b'1' )
930949
931- m = hashlib .sha256 ()
950+ m = hashlib .sha256 (usedforsecurity = False )
932951 m .update (b'1' )
933952 m .update (b'#' * gil_minsize )
934953 m .update (b'1' )
@@ -937,22 +956,24 @@ def test_gil(self):
937956 '1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
938957 )
939958
940- m = hashlib .sha256 (b'1' + b'#' * gil_minsize + b'1' )
959+ m = hashlib .sha256 (b'1' + b'#' * gil_minsize + b'1' ,
960+ usedforsecurity = False )
941961 self .assertEqual (
942962 m .hexdigest (),
943963 '1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
944964 )
945965
946966 @threading_helper .reap_threads
947967 @threading_helper .requires_working_threading ()
968+ @unittest .skipUnless (hasattr (hashlib , "sha1" ), "sha1 unavailable" )
948969 def test_threaded_hashing (self ):
949970 # Updating the same hash object from several threads at once
950971 # using data chunk sizes containing the same byte sequences.
951972 #
952973 # If the internal locks are working to prevent multiple
953974 # updates on the same object from running at once, the resulting
954975 # hash will be the same as doing it single threaded upfront.
955- hasher = hashlib .sha1 ()
976+ hasher = hashlib .sha1 (usedforsecurity = False )
956977 num_threads = 5
957978 smallest_data = b'swineflu'
958979 data = smallest_data * 200000
@@ -1174,6 +1195,9 @@ def test_normalized_name(self):
11741195 self .assertNotIn ("blake2b512" , hashlib .algorithms_available )
11751196 self .assertNotIn ("sha3-512" , hashlib .algorithms_available )
11761197
1198+ # defaults True because file_digest doesn't support the parameter.
1199+ @requires_usedforsecurity
1200+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
11771201 def test_file_digest (self ):
11781202 data = b'a' * 65536
11791203 d1 = hashlib .sha256 ()
0 commit comments