@@ -143,7 +143,15 @@ def __init__(self, *args, **kwargs):
143
143
# For each algorithm, test the direct constructor and the use
144
144
# of hashlib.new given the algorithm name.
145
145
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 ))
147
155
def _test_algorithm_via_hashlib_new (data = None , _alg = algorithm , ** kwargs ):
148
156
if data is None :
149
157
return hashlib .new (_alg , ** kwargs )
@@ -219,15 +227,23 @@ def test_algorithms_guaranteed(self):
219
227
set (_algo for _algo in self .supported_hash_names
220
228
if _algo .islower ()))
221
229
230
+ @unittest .skipIf (get_fips_mode (), reason = "guaranteed algorithms may not be available in FIPS mode" )
222
231
def test_algorithms_available (self ):
232
+ print (f"{ get_fips_mode ()= } " )
223
233
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 )= } " )
225
236
# all available algorithms must be loadable, bpo-47101
226
237
self .assertNotIn ("undefined" , hashlib .algorithms_available )
227
238
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 )
229
243
230
244
@requires_usedforsecurity
245
+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
246
+ @unittest .skipUnless (hasattr (hashlib , "md5" ), "md5 unavailable" )
231
247
def test_usedforsecurity_true (self ):
232
248
hashlib .new ("sha256" , usedforsecurity = True )
233
249
for cons in self .hash_constructors :
@@ -239,6 +255,8 @@ def test_usedforsecurity_true(self):
239
255
self ._hashlib .new ("md5" , usedforsecurity = True )
240
256
self ._hashlib .openssl_md5 (usedforsecurity = True )
241
257
258
+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
259
+ @unittest .skipUnless (hasattr (hashlib , "md5" ), "md5 unavailable" )
242
260
def test_usedforsecurity_false (self ):
243
261
hashlib .new ("sha256" , usedforsecurity = False )
244
262
for cons in self .hash_constructors :
@@ -254,6 +272,7 @@ def test_unknown_hash(self):
254
272
self .assertRaises (ValueError , hashlib .new , 'spam spam spam spam spam' )
255
273
self .assertRaises (TypeError , hashlib .new , 1 )
256
274
275
+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
257
276
def test_new_upper_to_lower (self ):
258
277
self .assertEqual (hashlib .new ("SHA256" , usedforsecurity = False ).name , "sha256" )
259
278
@@ -387,7 +406,8 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
387
406
hexdigest = hexdigest .lower ()
388
407
constructors = self .constructors_to_test [name ]
389
408
# 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 )
391
411
for hash_object_constructor in constructors :
392
412
m = hash_object_constructor (data , ** kwargs )
393
413
computed = m .hexdigest () if not shake else m .hexdigest (length )
@@ -407,8 +427,6 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
407
427
# skip shake and blake2 extended parameter tests
408
428
self .check_file_digest (name , data , hexdigest )
409
429
410
- # defaults True because file_digest doesn't support the parameter.
411
- @requires_usedforsecurity
412
430
def check_file_digest (self , name , data , hexdigest ):
413
431
hexdigest = hexdigest .lower ()
414
432
try :
@@ -914,6 +932,7 @@ def test_case_shake256_vector(self):
914
932
for msg , md in read_vectors ('shake_256' ):
915
933
self .check ('shake_256' , msg , md , True )
916
934
935
+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
917
936
def test_gil (self ):
918
937
# Check things work fine with an input larger than the size required
919
938
# for multithreaded operation (which is hardwired to 2048).
@@ -928,7 +947,7 @@ def test_gil(self):
928
947
m = cons (b'x' * gil_minsize , usedforsecurity = False )
929
948
m .update (b'1' )
930
949
931
- m = hashlib .sha256 ()
950
+ m = hashlib .sha256 (usedforsecurity = False )
932
951
m .update (b'1' )
933
952
m .update (b'#' * gil_minsize )
934
953
m .update (b'1' )
@@ -937,22 +956,24 @@ def test_gil(self):
937
956
'1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
938
957
)
939
958
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 )
941
961
self .assertEqual (
942
962
m .hexdigest (),
943
963
'1cfceca95989f51f658e3f3ffe7f1cd43726c9e088c13ee10b46f57cef135b94'
944
964
)
945
965
946
966
@threading_helper .reap_threads
947
967
@threading_helper .requires_working_threading ()
968
+ @unittest .skipUnless (hasattr (hashlib , "sha1" ), "sha1 unavailable" )
948
969
def test_threaded_hashing (self ):
949
970
# Updating the same hash object from several threads at once
950
971
# using data chunk sizes containing the same byte sequences.
951
972
#
952
973
# If the internal locks are working to prevent multiple
953
974
# updates on the same object from running at once, the resulting
954
975
# hash will be the same as doing it single threaded upfront.
955
- hasher = hashlib .sha1 ()
976
+ hasher = hashlib .sha1 (usedforsecurity = False )
956
977
num_threads = 5
957
978
smallest_data = b'swineflu'
958
979
data = smallest_data * 200000
@@ -1174,6 +1195,9 @@ def test_normalized_name(self):
1174
1195
self .assertNotIn ("blake2b512" , hashlib .algorithms_available )
1175
1196
self .assertNotIn ("sha3-512" , hashlib .algorithms_available )
1176
1197
1198
+ # defaults True because file_digest doesn't support the parameter.
1199
+ @requires_usedforsecurity
1200
+ @unittest .skipUnless (hasattr (hashlib , "sha256" ), "sha256 unavailable" )
1177
1201
def test_file_digest (self ):
1178
1202
data = b'a' * 65536
1179
1203
d1 = hashlib .sha256 ()
0 commit comments