@@ -66,6 +66,11 @@ def get_fips_mode():
66
66
SKIP_SHA3 = support .check_sanitizer (ub = True )
67
67
requires_sha3 = unittest .skipUnless (not SKIP_SHA3 , 'requires _sha3' )
68
68
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
+ )
69
74
70
75
def hexstr (s ):
71
76
assert isinstance (s , bytes ), repr (s )
@@ -102,6 +107,7 @@ class HashLibTestCase(unittest.TestCase):
102
107
'sha3_224' , 'sha3_256' , 'sha3_384' , 'sha3_512' ,
103
108
'shake_128' , 'shake_256' )
104
109
110
+ blakes = {'blake2b' , 'blake2s' }
105
111
shakes = {'shake_128' , 'shake_256' }
106
112
107
113
# gh-58898: Fallback modules are always compiled under POSIX.
@@ -121,9 +127,12 @@ def __init__(self, *args, **kwargs):
121
127
for algorithm in self .supported_hash_names :
122
128
algorithms .add (algorithm .lower ())
123
129
130
+ # blake2s and blake2b *require* the _blake2 builtin.
124
131
_blake2 = self ._conditional_import_module ('_blake2' )
125
132
if _blake2 :
126
- algorithms .update ({'blake2b' , 'blake2s' })
133
+ algorithms .update (self .blakes )
134
+ else :
135
+ algorithms .difference_update (self .blakes )
127
136
128
137
self .constructors_to_test = {}
129
138
for algorithm in algorithms :
@@ -196,10 +205,6 @@ def hash_constructors(self):
196
205
constructors = self .constructors_to_test .values ()
197
206
return itertools .chain .from_iterable (constructors )
198
207
199
- @property
200
- def is_fips_mode (self ):
201
- return get_fips_mode ()
202
-
203
208
def test_hash_array (self ):
204
209
a = array .array ("b" , range (10 ))
205
210
for cons in self .hash_constructors :
@@ -222,10 +227,9 @@ def test_algorithms_available(self):
222
227
for name in hashlib .algorithms_available :
223
228
digest = hashlib .new (name , usedforsecurity = False )
224
229
230
+ @requires_usedforsecurity
225
231
def test_usedforsecurity_true (self ):
226
232
hashlib .new ("sha256" , usedforsecurity = True )
227
- if self .is_fips_mode :
228
- self .skipTest ("skip in FIPS mode" )
229
233
for cons in self .hash_constructors :
230
234
cons (usedforsecurity = True )
231
235
cons (b'' , usedforsecurity = True )
@@ -251,7 +255,7 @@ def test_unknown_hash(self):
251
255
self .assertRaises (TypeError , hashlib .new , 1 )
252
256
253
257
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" )
255
259
256
260
def test_get_builtin_constructor (self ):
257
261
get_builtin_constructor = getattr (hashlib ,
@@ -309,10 +313,6 @@ def test_name_attribute(self):
309
313
for cons in self .hash_constructors :
310
314
h = cons (usedforsecurity = False )
311
315
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 )
316
316
self .assertEqual (
317
317
h .name ,
318
318
hashlib .new (h .name , usedforsecurity = False ).name
@@ -353,7 +353,7 @@ def test_large_update(self):
353
353
@requires_resource ('cpu' )
354
354
def test_sha256_update_over_4gb (self ):
355
355
zero_1mb = b"\0 " * 1024 * 1024
356
- h = hashlib .sha256 ()
356
+ h = hashlib .sha256 (usedforsecurity = False )
357
357
for i in range (0 , 4096 ):
358
358
h .update (zero_1mb )
359
359
h .update (b"hello world" )
@@ -362,24 +362,27 @@ def test_sha256_update_over_4gb(self):
362
362
@requires_resource ('cpu' )
363
363
def test_sha3_256_update_over_4gb (self ):
364
364
zero_1mb = b"\0 " * 1024 * 1024
365
- h = hashlib .sha3_256 ()
365
+ h = hashlib .sha3_256 (usedforsecurity = False )
366
366
for i in range (0 , 4096 ):
367
367
h .update (zero_1mb )
368
368
h .update (b"hello world" )
369
369
self .assertEqual (h .hexdigest (), "e2d4535e3b613135c14f2fe4e026d7ad8d569db44901740beffa30d430acb038" )
370
370
371
+ @requires_blake2
371
372
@requires_resource ('cpu' )
372
373
def test_blake2_update_over_4gb (self ):
373
374
# blake2s or blake2b doesn't matter based on how our C code is structured, this tests the
374
375
# common loop macro logic.
375
376
zero_1mb = b"\0 " * 1024 * 1024
376
- h = hashlib .blake2s ()
377
+ h = hashlib .blake2s (usedforsecurity = False )
377
378
for i in range (0 , 4096 ):
378
379
h .update (zero_1mb )
379
380
h .update (b"hello world" )
380
381
self .assertEqual (h .hexdigest (), "8a268e83dd30528bc0907fa2008c91de8f090a0b6e0e60a5ff0d999d8485526f" )
381
382
382
383
def check (self , name , data , hexdigest , shake = False , ** kwargs ):
384
+ if 'usedforsecurity' not in kwargs :
385
+ kwargs ['usedforsecurity' ] = False
383
386
length = len (hexdigest )// 2
384
387
hexdigest = hexdigest .lower ()
385
388
constructors = self .constructors_to_test [name ]
@@ -404,6 +407,8 @@ def check(self, name, data, hexdigest, shake=False, **kwargs):
404
407
# skip shake and blake2 extended parameter tests
405
408
self .check_file_digest (name , data , hexdigest )
406
409
410
+ # defaults True because file_digest doesn't support the parameter.
411
+ @requires_usedforsecurity
407
412
def check_file_digest (self , name , data , hexdigest ):
408
413
hexdigest = hexdigest .lower ()
409
414
try :
@@ -434,7 +439,8 @@ def check_no_unicode(self, algorithm_name):
434
439
# Unicode objects are not allowed as input.
435
440
constructors = self .constructors_to_test [algorithm_name ]
436
441
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 )
438
444
439
445
def test_no_unicode (self ):
440
446
self .check_no_unicode ('md5' )
@@ -497,7 +503,7 @@ def test_blocksize_name_sha3(self):
497
503
def check_sha3 (self , name , capacity , rate , suffix ):
498
504
constructors = self .constructors_to_test [name ]
499
505
for hash_object_constructor in constructors :
500
- m = hash_object_constructor ()
506
+ m = hash_object_constructor (usedforsecurity = False )
501
507
if HASH is not None and isinstance (m , HASH ):
502
508
# _hashopenssl's variant does not have extra SHA3 attributes
503
509
continue
@@ -661,7 +667,7 @@ def check_blake2(self, constructor, salt_size, person_size, key_size,
661
667
digest_size , max_offset ):
662
668
self .assertEqual (constructor .SALT_SIZE , salt_size )
663
669
for i in range (salt_size + 1 ):
664
- constructor (salt = b'a' * i )
670
+ constructor (salt = b'a' * i , usedforsecurity = False )
665
671
salt = b'a' * (salt_size + 1 )
666
672
self .assertRaises (ValueError , constructor , salt = salt )
667
673
@@ -975,8 +981,7 @@ def hash_in_chunks(chunk_size):
975
981
self .assertEqual (expected_hash , hasher .hexdigest ())
976
982
977
983
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 :
980
985
self .assertIsInstance (fips_mode , int )
981
986
982
987
@support .cpython_only
0 commit comments