Skip to content

Commit 3695ba9

Browse files
authored
gh-132993: expose HASHLIB_GIL_MINSIZE to private extension modules (#132999)
1 parent 019ee49 commit 3695ba9

10 files changed

+119
-28
lines changed

Lib/test/support/hashlib_helper.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import functools
22
import hashlib
3+
import importlib
34
import unittest
45
from test.support.import_helper import import_module
56

@@ -100,3 +101,22 @@ def wrapper(*args, **kwargs):
100101
def decorator(func_or_class):
101102
return _decorate_func_or_class(func_or_class, decorator_func)
102103
return decorator
104+
105+
106+
def find_gil_minsize(modules_names, default=2048):
107+
"""Get the largest GIL_MINSIZE value for the given cryptographic modules.
108+
109+
The valid module names are the following:
110+
111+
- _hashlib
112+
- _md5, _sha1, _sha2, _sha3, _blake2
113+
- _hmac
114+
"""
115+
sizes = []
116+
for module_name in modules_names:
117+
try:
118+
module = importlib.import_module(module_name)
119+
except ImportError:
120+
continue
121+
sizes.append(getattr(module, '_GIL_MINSIZE', default))
122+
return max(sizes, default=default)

Lib/test/test_hashlib.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import warnings
2121
from test import support
2222
from test.support import _4G, bigmemtest
23+
from test.support import hashlib_helper
2324
from test.support.import_helper import import_fresh_module
2425
from test.support import requires_resource
2526
from test.support import threading_helper
@@ -911,10 +912,13 @@ def test_case_shake256_vector(self):
911912

912913
def test_gil(self):
913914
# Check things work fine with an input larger than the size required
914-
# for multithreaded operation (which is hardwired to 2048).
915-
gil_minsize = 2048
916-
915+
# for multithreaded operation. Currently, all cryptographic modules
916+
# have the same constant value (2048) but in the future it might not
917+
# be the case.
918+
mods = ['_md5', '_sha1', '_sha2', '_sha3', '_blake2', '_hashlib']
919+
gil_minsize = hashlib_helper.find_gil_minsize(mods)
917920
for cons in self.hash_constructors:
921+
# constructors belong to one of the above modules
918922
m = cons(usedforsecurity=False)
919923
m.update(b'1')
920924
m.update(b'#' * gil_minsize)
@@ -923,6 +927,8 @@ def test_gil(self):
923927
m = cons(b'x' * gil_minsize, usedforsecurity=False)
924928
m.update(b'1')
925929

930+
def test_sha256_gil(self):
931+
gil_minsize = hashlib_helper.find_gil_minsize(['_sha2', '_hashlib'])
926932
m = hashlib.sha256()
927933
m.update(b'1')
928934
m.update(b'#' * gil_minsize)

Lib/test/test_hmac.py

+21-5
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,11 @@ def HMAC(self, key, msg=None):
11001100
"""Create a HMAC object."""
11011101
raise NotImplementedError
11021102

1103+
@property
1104+
def gil_minsize(self):
1105+
"""Get the maximal input length for the GIL to be held."""
1106+
raise NotImplementedError
1107+
11031108
def check_update(self, key, chunks):
11041109
chunks = list(chunks)
11051110
msg = b''.join(chunks)
@@ -1118,11 +1123,10 @@ def test_update(self):
11181123
self.check_update(key, [msg])
11191124

11201125
def test_update_large(self):
1121-
HASHLIB_GIL_MINSIZE = 2048
1122-
1126+
gil_minsize = self.gil_minsize
11231127
key = random.randbytes(16)
1124-
top = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
1125-
bot = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
1128+
top = random.randbytes(gil_minsize + 1)
1129+
bot = random.randbytes(gil_minsize + 1)
11261130
self.check_update(key, [top, bot])
11271131

11281132
def test_update_exceptions(self):
@@ -1132,19 +1136,27 @@ def test_update_exceptions(self):
11321136
self.assertRaises(TypeError, h.update, msg)
11331137

11341138

1135-
@hashlib_helper.requires_hashdigest('sha256')
1139+
@requires_builtin_sha2()
11361140
class PyUpdateTestCase(PyModuleMixin, UpdateTestCaseMixin, unittest.TestCase):
11371141

11381142
def HMAC(self, key, msg=None):
11391143
return self.hmac.HMAC(key, msg, digestmod='sha256')
11401144

1145+
@property
1146+
def gil_minsize(self):
1147+
return sha2._GIL_MINSIZE
1148+
11411149

11421150
@hashlib_helper.requires_openssl_hashdigest('sha256')
11431151
class OpenSSLUpdateTestCase(UpdateTestCaseMixin, unittest.TestCase):
11441152

11451153
def HMAC(self, key, msg=None):
11461154
return _hashlib.hmac_new(key, msg, digestmod='sha256')
11471155

1156+
@property
1157+
def gil_minsize(self):
1158+
return _hashlib._GIL_MINSIZE
1159+
11481160

11491161
class BuiltinUpdateTestCase(BuiltinModuleMixin,
11501162
UpdateTestCaseMixin, unittest.TestCase):
@@ -1154,6 +1166,10 @@ def HMAC(self, key, msg=None):
11541166
# are still built, making it possible to use SHA-2 hashes.
11551167
return self.hmac.new(key, msg, digestmod='sha256')
11561168

1169+
@property
1170+
def gil_minsize(self):
1171+
return self.hmac._GIL_MINSIZE
1172+
11571173

11581174
class CopyBaseTestCase:
11591175

Modules/_hashopenssl.c

+11
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,16 @@ hashlib_exception(PyObject *module)
23582358
return 0;
23592359
}
23602360

2361+
static int
2362+
hashlib_constants(PyObject *module)
2363+
{
2364+
if (PyModule_AddIntConstant(module, "_GIL_MINSIZE",
2365+
HASHLIB_GIL_MINSIZE) < 0)
2366+
{
2367+
return -1;
2368+
}
2369+
return 0;
2370+
}
23612371

23622372
static PyModuleDef_Slot hashlib_slots[] = {
23632373
{Py_mod_exec, hashlib_init_hashtable},
@@ -2367,6 +2377,7 @@ static PyModuleDef_Slot hashlib_slots[] = {
23672377
{Py_mod_exec, hashlib_md_meth_names},
23682378
{Py_mod_exec, hashlib_init_constructors},
23692379
{Py_mod_exec, hashlib_exception},
2380+
{Py_mod_exec, hashlib_constants},
23702381
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
23712382
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
23722383
{0, NULL}

Modules/blake2module.c

+2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ blake2_exec(PyObject *m)
229229
// good a place as any to probe the CPU flags.
230230
detect_cpu_features(&st->flags);
231231

232+
ADD_INT_CONST("_GIL_MINSIZE", HASHLIB_GIL_MINSIZE);
233+
232234
st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec(
233235
m, &blake2b_type_spec, NULL);
234236

Modules/hmacmodule.c

+17
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,20 @@ hmacmodule_init_strings(hmacmodule_state *state)
16791679
return 0;
16801680
}
16811681

1682+
static int
1683+
hmacmodule_init_globals(PyObject *module, hmacmodule_state *state)
1684+
{
1685+
#define ADD_INT_CONST(NAME, VALUE) \
1686+
do { \
1687+
if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
1688+
return -1; \
1689+
} \
1690+
} while (0)
1691+
ADD_INT_CONST("_GIL_MINSIZE", HASHLIB_GIL_MINSIZE);
1692+
#undef ADD_INT_CONST
1693+
return 0;
1694+
}
1695+
16821696
static void
16831697
hmacmodule_init_cpu_features(hmacmodule_state *state)
16841698
{
@@ -1769,6 +1783,9 @@ hmacmodule_exec(PyObject *module)
17691783
if (hmacmodule_init_strings(state) < 0) {
17701784
return -1;
17711785
}
1786+
if (hmacmodule_init_globals(module, state) < 0) {
1787+
return -1;
1788+
}
17721789
hmacmodule_init_cpu_features(state);
17731790
return 0;
17741791
}

Modules/md5module.c

+11-8
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ md5_exec(PyObject *m)
370370
if (PyModule_AddObjectRef(m, "MD5Type", (PyObject *)st->md5_type) < 0) {
371371
return -1;
372372
}
373+
if (PyModule_AddIntConstant(m, "_GIL_MINSIZE", HASHLIB_GIL_MINSIZE) < 0) {
374+
return -1;
375+
}
373376

374377
return 0;
375378
}
@@ -383,14 +386,14 @@ static PyModuleDef_Slot _md5_slots[] = {
383386

384387

385388
static struct PyModuleDef _md5module = {
386-
PyModuleDef_HEAD_INIT,
387-
.m_name = "_md5",
388-
.m_size = sizeof(MD5State),
389-
.m_methods = MD5_functions,
390-
.m_slots = _md5_slots,
391-
.m_traverse = _md5_traverse,
392-
.m_clear = _md5_clear,
393-
.m_free = _md5_free,
389+
PyModuleDef_HEAD_INIT,
390+
.m_name = "_md5",
391+
.m_size = sizeof(MD5State),
392+
.m_methods = MD5_functions,
393+
.m_slots = _md5_slots,
394+
.m_traverse = _md5_traverse,
395+
.m_clear = _md5_clear,
396+
.m_free = _md5_free,
394397
};
395398

396399
PyMODINIT_FUNC

Modules/sha1module.c

+17-10
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,15 @@ _sha1_exec(PyObject *module)
362362
st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec(
363363
module, &sha1_type_spec, NULL);
364364
if (PyModule_AddObjectRef(module,
365-
"SHA1Type",
366-
(PyObject *)st->sha1_type) < 0) {
365+
"SHA1Type",
366+
(PyObject *)st->sha1_type) < 0)
367+
{
368+
return -1;
369+
}
370+
if (PyModule_AddIntConstant(module,
371+
"_GIL_MINSIZE",
372+
HASHLIB_GIL_MINSIZE) < 0)
373+
{
367374
return -1;
368375
}
369376

@@ -381,14 +388,14 @@ static PyModuleDef_Slot _sha1_slots[] = {
381388
};
382389

383390
static struct PyModuleDef _sha1module = {
384-
PyModuleDef_HEAD_INIT,
385-
.m_name = "_sha1",
386-
.m_size = sizeof(SHA1State),
387-
.m_methods = SHA1_functions,
388-
.m_slots = _sha1_slots,
389-
.m_traverse = _sha1_traverse,
390-
.m_clear = _sha1_clear,
391-
.m_free = _sha1_free
391+
PyModuleDef_HEAD_INIT,
392+
.m_name = "_sha1",
393+
.m_size = sizeof(SHA1State),
394+
.m_methods = SHA1_functions,
395+
.m_slots = _sha1_slots,
396+
.m_traverse = _sha1_traverse,
397+
.m_clear = _sha1_clear,
398+
.m_free = _sha1_free
392399
};
393400

394401
PyMODINIT_FUNC

Modules/sha2module.c

+7
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,13 @@ static int sha2_exec(PyObject *module)
894894
return -1;
895895
}
896896

897+
if (PyModule_AddIntConstant(module,
898+
"_GIL_MINSIZE",
899+
HASHLIB_GIL_MINSIZE) < 0)
900+
{
901+
return -1;
902+
}
903+
897904
return 0;
898905
}
899906

Modules/sha3module.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,10 @@ _sha3_exec(PyObject *m)
639639
init_sha3type(shake_256_type, SHAKE256_spec);
640640
#undef init_sha3type
641641

642-
if (PyModule_AddStringConstant(m, "implementation",
643-
"HACL") < 0) {
642+
if (PyModule_AddStringConstant(m, "implementation", "HACL") < 0) {
643+
return -1;
644+
}
645+
if (PyModule_AddIntConstant(m, "_GIL_MINSIZE", HASHLIB_GIL_MINSIZE) < 0) {
644646
return -1;
645647
}
646648

0 commit comments

Comments
 (0)