Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import warnings
from test import support
from test.support import _4G, bigmemtest
from test.support.import_helper import import_fresh_module
from test.support.import_helper import import_fresh_module, import_module
from test.support import requires_resource
from test.support import threading_helper
from http.client import HTTPException
Expand Down Expand Up @@ -95,6 +95,19 @@ def read_vectors(hash_name):
yield parts


def find_gil_minsize(*modules_names, default=2048):
gil_minsize = default
for module_name in modules_names:
if SKIP_SHA3 and module_name == '_sha3':
continue
try:
module = importlib.import_module(module_name)
except ImportError:
continue
gil_minsize = max(gil_minsize, module.GIL_MINSIZE)
return gil_minsize


class HashLibTestCase(unittest.TestCase):
supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
'sha224', 'SHA224', 'sha256', 'SHA256',
Expand Down Expand Up @@ -913,9 +926,12 @@ def test_case_shake256_vector(self):

def test_gil(self):
# Check things work fine with an input larger than the size required
# for multithreaded operation (which is hardwired to 2048).
gil_minsize = 2048

# for multithreaded operation. Currently, all cryptographic modules
# have the same constant value (2048) but in the future it might not
# be the case.
gil_minsize = find_gil_minsize(
'_md5', '_sha1', '_sha2', '_sha3', '_blake2', '_hashlib',
)
for cons in self.hash_constructors:
m = cons(usedforsecurity=False)
m.update(b'1')
Expand All @@ -925,6 +941,8 @@ def test_gil(self):
m = cons(b'x' * gil_minsize, usedforsecurity=False)
m.update(b'1')

def test_sha256_gil(self):
gil_minsize = find_gil_minsize('_sha2', '_hashlib')
m = hashlib.sha256()
m.update(b'1')
m.update(b'#' * gil_minsize)
Expand Down
24 changes: 20 additions & 4 deletions Lib/test/test_hmac.py
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,11 @@ def HMAC(self, key, msg=None):
"""Create a HMAC object."""
raise NotImplementedError

@property
def gil_minsize(self):
"""Get the maximal input length for the GIL to be held."""
raise NotImplementedError

def check_update(self, key, chunks):
chunks = list(chunks)
msg = b''.join(chunks)
Expand All @@ -1120,11 +1125,10 @@ def test_update(self):
self.check_update(key, [msg])

def test_update_large(self):
HASHLIB_GIL_MINSIZE = 2048

gil_minsize = self.gil_minsize
key = random.randbytes(16)
top = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
bot = random.randbytes(HASHLIB_GIL_MINSIZE + 1)
top = random.randbytes(gil_minsize + 1)
bot = random.randbytes(gil_minsize + 1)
self.check_update(key, [top, bot])

def test_update_exceptions(self):
Expand All @@ -1140,13 +1144,21 @@ class PyUpdateTestCase(PyModuleMixin, UpdateTestCaseMixin, unittest.TestCase):
def HMAC(self, key, msg=None):
return self.hmac.HMAC(key, msg, digestmod='sha256')

@property
def gil_minsize(self):
self.skipTest("GIL is always held")


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

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

@property
def gil_minsize(self):
return _hashlib.GIL_MINSIZE


class BuiltinUpdateTestCase(BuiltinModuleMixin,
UpdateTestCaseMixin, unittest.TestCase):
Expand All @@ -1156,6 +1168,10 @@ def HMAC(self, key, msg=None):
# are still built, making it possible to use SHA-2 hashes.
return self.hmac.new(key, msg, digestmod='sha256')

@property
def gil_minsize(self):
return self.hmac.GIL_MINSIZE


class CopyBaseTestCase:

Expand Down
11 changes: 11 additions & 0 deletions Modules/_hashopenssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2358,6 +2358,16 @@ hashlib_exception(PyObject *module)
return 0;
}

static int
hashlib_constants(PyObject *module)
{
if (PyModule_AddIntConstant(module, "GIL_MINSIZE",
HASHLIB_GIL_MINSIZE) < 0)
{
return -1;
}
return 0;
}

static PyModuleDef_Slot hashlib_slots[] = {
{Py_mod_exec, hashlib_init_hashtable},
Expand All @@ -2367,6 +2377,7 @@ static PyModuleDef_Slot hashlib_slots[] = {
{Py_mod_exec, hashlib_md_meth_names},
{Py_mod_exec, hashlib_init_constructors},
{Py_mod_exec, hashlib_exception},
{Py_mod_exec, hashlib_constants},
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
{0, NULL}
Expand Down
2 changes: 2 additions & 0 deletions Modules/blake2module.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ blake2_exec(PyObject *m)
// good a place as any to probe the CPU flags.
detect_cpu_features(&st->flags);

ADD_INT_CONST("GIL_MINSIZE", HASHLIB_GIL_MINSIZE);

st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec(
m, &blake2b_type_spec, NULL);

Expand Down
17 changes: 17 additions & 0 deletions Modules/hmacmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1679,6 +1679,20 @@ hmacmodule_init_strings(hmacmodule_state *state)
return 0;
}

static int
hmacmodule_init_globals(PyObject *module, hmacmodule_state *state)
{
#define ADD_INT_CONST(NAME, VALUE) \
do { \
if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
return -1; \
} \
} while (0)
ADD_INT_CONST("GIL_MINSIZE", HASHLIB_GIL_MINSIZE);
#undef ADD_INT_CONST
return 0;
}

static void
hmacmodule_init_cpu_features(hmacmodule_state *state)
{
Expand Down Expand Up @@ -1769,6 +1783,9 @@ hmacmodule_exec(PyObject *module)
if (hmacmodule_init_strings(state) < 0) {
return -1;
}
if (hmacmodule_init_globals(module, state) < 0) {
return -1;
}
hmacmodule_init_cpu_features(state);
return 0;
}
Expand Down
19 changes: 11 additions & 8 deletions Modules/md5module.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,9 @@ md5_exec(PyObject *m)
if (PyModule_AddObjectRef(m, "MD5Type", (PyObject *)st->md5_type) < 0) {
return -1;
}
if (PyModule_AddIntConstant(m, "GIL_MINSIZE", HASHLIB_GIL_MINSIZE) < 0) {
return -1;
}

return 0;
}
Expand All @@ -383,14 +386,14 @@ static PyModuleDef_Slot _md5_slots[] = {


static struct PyModuleDef _md5module = {
PyModuleDef_HEAD_INIT,
.m_name = "_md5",
.m_size = sizeof(MD5State),
.m_methods = MD5_functions,
.m_slots = _md5_slots,
.m_traverse = _md5_traverse,
.m_clear = _md5_clear,
.m_free = _md5_free,
PyModuleDef_HEAD_INIT,
.m_name = "_md5",
.m_size = sizeof(MD5State),
.m_methods = MD5_functions,
.m_slots = _md5_slots,
.m_traverse = _md5_traverse,
.m_clear = _md5_clear,
.m_free = _md5_free,
};

PyMODINIT_FUNC
Expand Down
27 changes: 17 additions & 10 deletions Modules/sha1module.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,15 @@ _sha1_exec(PyObject *module)
st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec(
module, &sha1_type_spec, NULL);
if (PyModule_AddObjectRef(module,
"SHA1Type",
(PyObject *)st->sha1_type) < 0) {
"SHA1Type",
(PyObject *)st->sha1_type) < 0)
{
return -1;
}
if (PyModule_AddIntConstant(module,
"GIL_MINSIZE",
HASHLIB_GIL_MINSIZE) < 0)
{
return -1;
}

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

static struct PyModuleDef _sha1module = {
PyModuleDef_HEAD_INIT,
.m_name = "_sha1",
.m_size = sizeof(SHA1State),
.m_methods = SHA1_functions,
.m_slots = _sha1_slots,
.m_traverse = _sha1_traverse,
.m_clear = _sha1_clear,
.m_free = _sha1_free
PyModuleDef_HEAD_INIT,
.m_name = "_sha1",
.m_size = sizeof(SHA1State),
.m_methods = SHA1_functions,
.m_slots = _sha1_slots,
.m_traverse = _sha1_traverse,
.m_clear = _sha1_clear,
.m_free = _sha1_free
};

PyMODINIT_FUNC
Expand Down
7 changes: 7 additions & 0 deletions Modules/sha2module.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,13 @@ static int sha2_exec(PyObject *module)
return -1;
}

if (PyModule_AddIntConstant(module,
"GIL_MINSIZE",
HASHLIB_GIL_MINSIZE) < 0)
{
return -1;
}

return 0;
}

Expand Down
6 changes: 4 additions & 2 deletions Modules/sha3module.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,10 @@ _sha3_exec(PyObject *m)
init_sha3type(shake_256_type, SHAKE256_spec);
#undef init_sha3type

if (PyModule_AddStringConstant(m, "implementation",
"HACL") < 0) {
if (PyModule_AddStringConstant(m, "implementation", "HACL") < 0) {
return -1;
}
if (PyModule_AddIntConstant(m, "GIL_MINSIZE", HASHLIB_GIL_MINSIZE) < 0) {
return -1;
}

Expand Down
Loading