From fe0e921817a7f96c62c91085884ab910859328ce Mon Sep 17 00:00:00 2001 From: =?utf8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:45:40 +0200 Subject: [PATCH] gh-131876: Revert "gh-131876: extract `_hashlib` helpers into a separate directory (#136995) (#137307) Revert "gh-131876: extract `_hashlib` helpers into a separate directory (#136995)" This reverts commit 45138d35843297395b2d646f5391be108243957a. --- Makefile.pre.in | 37 +--- ...-07-22-14-47-45.gh-issue-131876.oaYEEP.rst | 2 - Modules/_hashlib/hashlib_buffer.c | 65 ------- Modules/_hashlib/hashlib_buffer.h | 48 ----- Modules/_hashlib/hashlib_fetch.h | 19 -- Modules/_hashlib/hashlib_mutex.h | 82 --------- Modules/_hashopenssl.c | 15 +- Modules/blake2module.c | 8 +- Modules/hashlib.h | 173 ++++++++++++++++++ Modules/hmacmodule.c | 8 +- Modules/md5module.c | 5 +- Modules/sha1module.c | 8 +- Modules/sha2module.c | 9 +- Modules/sha3module.c | 8 +- PCbuild/_hashlib.vcxproj | 5 - PCbuild/_hashlib.vcxproj.filters | 2 +- PCbuild/pythoncore.vcxproj | 4 - PCbuild/pythoncore.vcxproj.filters | 12 -- configure | 40 ++-- configure.ac | 17 +- 20 files changed, 221 insertions(+), 346 deletions(-) delete mode 100644 Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst delete mode 100644 Modules/_hashlib/hashlib_buffer.c delete mode 100644 Modules/_hashlib/hashlib_buffer.h delete mode 100644 Modules/_hashlib/hashlib_fetch.h delete mode 100644 Modules/_hashlib/hashlib_mutex.h create mode 100644 Modules/hashlib.h diff --git a/Makefile.pre.in b/Makefile.pre.in index e2253d3e35b3..67e963f83c12 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -227,7 +227,6 @@ ENSUREPIP= @ENSUREPIP@ # Internal static libraries LIBMPDEC_A= Modules/_decimal/libmpdec/libmpdec.a LIBEXPAT_A= Modules/expat/libexpat.a -LIBHASHLIB_INTERNAL_A=Modules/_hashlib/libhashlib.a # HACL* build configuration LIBHACL_CFLAGS=@LIBHACL_CFLAGS@ @@ -762,17 +761,6 @@ LIBHACL_HMAC_HEADERS= \ $(LIBHACL_BLAKE2_HEADERS) \ $(LIBHACL_HEADERS) -########################################################################## -# Internal library for cryptographic primitives - -LIBHASHLIB_INTERNAL_OBJS= \ - Modules/_hashlib/hashlib_buffer.o - -LIBHASHLIB_INTERNAL_HEADERS= \ - Modules/_hashlib/hashlib_buffer.h \ - Modules/_hashlib/hashlib_fetch.h \ - Modules/_hashlib/hashlib_mutex.h - ######################################################################### # Rules @@ -1527,17 +1515,6 @@ $(LIBEXPAT_A): $(LIBEXPAT_OBJS) -rm -f $@ $(AR) $(ARFLAGS) $@ $(LIBEXPAT_OBJS) -########################################################################## -# '_hashlib', '_hmac' and HACL*-based modules helpers -LIBHASHLIB_INTERNAL_CFLAGS=@LIBHASHLIB_INTERNAL_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) - -Modules/_hashlib/hashlib_buffer.o: Modules/_hashlib/hashlib_buffer.c $(LIBHASHLIB_INTERNAL_HEADERS) $(PYTHON_HEADERS) - $(CC) -I$(srcdir)/Modules/_hashlib -c $(LIBHASHLIB_INTERNAL_CFLAGS) -o $@ $(srcdir)/Modules/_hashlib/hashlib_buffer.c - -$(LIBHASHLIB_INTERNAL_A): $(LIBHASHLIB_INTERNAL_OBJS) - -rm -f $@ - $(AR) $(ARFLAGS) $@ $(LIBHASHLIB_INTERNAL_OBJS) - ########################################################################## # HACL* library build # @@ -3380,21 +3357,21 @@ MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@ MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@ MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@ -MODULE__HASHLIB_DEPS=@LIBHASHLIB_INTERNAL@ +MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h # HACL*-based cryptographic primitives -MODULE__MD5_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__MD5_LDEPS=$(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA1_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA1_LDEPS=$(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA2_LDEPS=$(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA3_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA3_LDEPS=$(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__BLAKE2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__BLAKE2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__BLAKE2_LDEPS=$(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__HMAC_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__HMAC_LDEPS=$(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c diff --git a/Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst b/Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst deleted file mode 100644 index 304f2c30f664..000000000000 --- a/Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove :file:`!Modules/hashlib.h` and move its content into dedicated files -now located in ``Modules/_hashlib``. Patch by Bénédikt Tran. diff --git a/Modules/_hashlib/hashlib_buffer.c b/Modules/_hashlib/hashlib_buffer.c deleted file mode 100644 index 032f93ad53ad..000000000000 --- a/Modules/_hashlib/hashlib_buffer.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "hashlib_buffer.h" - -int -_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string) -{ - if (data != NULL && string == NULL) { - // called as H(data) or H(data=...) - *res = data; - return 1; - } - else if (data == NULL && string != NULL) { - // called as H(string=...) - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "the 'string' keyword parameter is deprecated since " - "Python 3.15 and slated for removal in Python 3.19; " - "use the 'data' keyword parameter or pass the data " - "to hash as a positional argument instead", 1) < 0) - { - *res = NULL; - return -1; - } - *res = string; - return 1; - } - else if (data == NULL && string == NULL) { - // fast path when no data is given - assert(!PyErr_Occurred()); - *res = NULL; - return 0; - } - else { - // called as H(data=..., string) - *res = NULL; - PyErr_SetString(PyExc_TypeError, - "'data' and 'string' are mutually exclusive " - "and support for 'string' keyword parameter " - "is slated for removal in a future version."); - return -1; - } -} - -int -_Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view) -{ - if (PyUnicode_Check(obj)) { - PyErr_SetString(PyExc_TypeError, - "Strings must be encoded before hashing"); - return -1; - } - if (!PyObject_CheckBuffer(obj)) { - PyErr_SetString(PyExc_TypeError, - "object supporting the buffer API required"); - return -1; - } - if (PyObject_GetBuffer(obj, view, PyBUF_SIMPLE) == -1) { - return -1; - } - if (view->ndim > 1) { - PyErr_SetString(PyExc_BufferError, - "Buffer must be single dimension"); - PyBuffer_Release(view); - return -1; - } - return 0; -} diff --git a/Modules/_hashlib/hashlib_buffer.h b/Modules/_hashlib/hashlib_buffer.h deleted file mode 100644 index 809f19884f41..000000000000 --- a/Modules/_hashlib/hashlib_buffer.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _HASHLIB_HASHLIB_BUFFER_H -#define _HASHLIB_HASHLIB_BUFFER_H - -#include "Python.h" - -/* - * Allow to use the 'data' or 'string' keyword in hashlib.new() - * and other hash functions named constructors. - * - * - If 'data' and 'string' are both non-NULL, set an exception and return -1. - * - If 'data' and 'string' are both NULL, set '*res' to NULL and return 0. - * - Otherwise, set '*res' to 'data' or 'string' and return 1. A deprecation - * warning is set when 'string' is specified. - * - * The symbol is exported for '_hashlib' and HACL*-based extension modules. - */ -PyAPI_FUNC(int) -_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string); - -/* - * Obtain a buffer view from a buffer-like object 'obj'. - * - * On success, store the result in 'view' and return 0. - * On error, set an exception and return -1. - * - * The symbol is exported for '_hashlib' and HACL*-based extension modules. - */ -PyAPI_FUNC(int) -_Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view); - -/* - * Call _Py_hashlib_get_buffer_view() and check if it succeeded. - * - * On error, set an exception and execute the ERRACTION statements. - */ -#define GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, ERRACTION) \ - do { \ - if (_Py_hashlib_get_buffer_view(OBJ, VIEW) < 0) { \ - assert(PyErr_Occurred()); \ - ERRACTION; \ - } \ - } while (0) - -/* Specialization of GET_BUFFER_VIEW_OR_ERROR() returning NULL on error. */ -#define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \ - GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL) - -#endif // !_HASHLIB_HASHLIB_BUFFER_H diff --git a/Modules/_hashlib/hashlib_fetch.h b/Modules/_hashlib/hashlib_fetch.h deleted file mode 100644 index 09add71e0c79..000000000000 --- a/Modules/_hashlib/hashlib_fetch.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Utilities used when fetching a message digest from a digest-like identifier. - */ - -#ifndef _HASHLIB_HASHLIB_FETCH_H -#define _HASHLIB_HASHLIB_FETCH_H - -#include "Python.h" - -/* - * Internal error messages used for reporting an unsupported hash algorithm. - * The algorithm can be given by its name, a callable or a PEP-247 module. - * The same message is raised by Lib/hashlib.py::__get_builtin_constructor() - * and _hmacmodule.c::find_hash_info(). - */ -#define _Py_HASHLIB_UNSUPPORTED_ALGORITHM "unsupported hash algorithm %S" -#define _Py_HASHLIB_UNSUPPORTED_STR_ALGORITHM "unsupported hash algorithm %s" - -#endif // !_HASHLIB_HASHLIB_FETCH_H diff --git a/Modules/_hashlib/hashlib_mutex.h b/Modules/_hashlib/hashlib_mutex.h deleted file mode 100644 index d6924a2ef61e..000000000000 --- a/Modules/_hashlib/hashlib_mutex.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _HASHLIB_HASHLIB_MUTEX_H -#define _HASHLIB_HASHLIB_MUTEX_H - -#include "Python.h" -#include "pycore_lock.h" // PyMutex - -/* - * Message length above which the GIL is to be released - * when performing hashing operations. - */ -#define HASHLIB_GIL_MINSIZE 2048 - -/* - * Helper code to synchronize access to the hash object when the GIL is - * released around a CPU consuming hashlib operation. - * - * Code accessing a mutable part of the hash object must be enclosed in - * an HASHLIB_{ACQUIRE,RELEASE}_LOCK block or explicitly acquire and release - * the mutex inside a Py_BEGIN_ALLOW_THREADS -- Py_END_ALLOW_THREADS block if - * they wish to release the GIL for an operation. - */ - -#define HASHLIB_OBJECT_HEAD \ - PyObject_HEAD \ - /* Guard against race conditions during incremental update(). */ \ - PyMutex mutex; - -#define HASHLIB_INIT_MUTEX(OBJ) \ - do { \ - (OBJ)->mutex = (PyMutex){0}; \ - } while (0) - -#define HASHLIB_ACQUIRE_LOCK(OBJ) PyMutex_Lock(&(OBJ)->mutex) -#define HASHLIB_RELEASE_LOCK(OBJ) PyMutex_Unlock(&(OBJ)->mutex) - -// Macros for executing code while conditionally holding the GIL. -// -// These only drop the GIL if the lock acquisition itself is likely to -// block. Thus the non-blocking acquire gating the GIL release for a -// blocking lock acquisition. The intent of these macros is to surround -// the assumed always "fast" operations that you aren't releasing the -// GIL around. - -/* - * Execute a suite of C statements 'STATEMENTS'. - * - * The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold. - */ -#define HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(SIZE, STATEMENTS) \ - do { \ - if ((SIZE) > HASHLIB_GIL_MINSIZE) { \ - Py_BEGIN_ALLOW_THREADS \ - STATEMENTS; \ - Py_END_ALLOW_THREADS \ - } \ - else { \ - STATEMENTS; \ - } \ - } while (0) - -/* - * Lock 'OBJ' and execute a suite of C statements 'STATEMENTS'. - * - * The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold. - */ -#define HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(OBJ, SIZE, STATEMENTS) \ - do { \ - if ((SIZE) > HASHLIB_GIL_MINSIZE) { \ - Py_BEGIN_ALLOW_THREADS \ - HASHLIB_ACQUIRE_LOCK(OBJ); \ - STATEMENTS; \ - HASHLIB_RELEASE_LOCK(OBJ); \ - Py_END_ALLOW_THREADS \ - } \ - else { \ - HASHLIB_ACQUIRE_LOCK(OBJ); \ - STATEMENTS; \ - HASHLIB_RELEASE_LOCK(OBJ); \ - } \ - } while (0) - -#endif // !_HASHLIB_HASHLIB_MUTEX_H diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 26412cb62430..00f98c090b39 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -24,17 +24,14 @@ #include "Python.h" #include "pycore_hashtable.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_RELAXED - -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_fetch.h" -#include "_hashlib/hashlib_mutex.h" +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_RELAXED +#include "hashlib.h" /* EVP is the preferred interface to hashing in OpenSSL */ #include #include -#include // FIPS_mode() +#include // FIPS_mode() /* We use the object interface to discover what hashes OpenSSL supports. */ #include #include @@ -535,7 +532,7 @@ raise_unsupported_algorithm_error(_hashlibstate *state, PyObject *digestmod) { raise_unsupported_algorithm_impl( state->unsupported_digestmod_error, - _Py_HASHLIB_UNSUPPORTED_ALGORITHM, + HASHLIB_UNSUPPORTED_ALGORITHM, digestmod ); } @@ -545,7 +542,7 @@ raise_unsupported_str_algorithm_error(_hashlibstate *state, const char *name) { raise_unsupported_algorithm_impl( state->unsupported_digestmod_error, - _Py_HASHLIB_UNSUPPORTED_STR_ALGORITHM, + HASHLIB_UNSUPPORTED_STR_ALGORITHM, name ); } diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 13c969056be3..163f238a4268 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -15,12 +15,10 @@ #endif #include "Python.h" -#include "pycore_moduleobject.h" -#include "pycore_strhex.h" // _Py_strhex() +#include "hashlib.h" +#include "pycore_strhex.h" // _Py_strhex() #include "pycore_typeobject.h" - -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_mutex.h" +#include "pycore_moduleobject.h" // QUICK CPU AUTODETECTION // diff --git a/Modules/hashlib.h b/Modules/hashlib.h new file mode 100644 index 000000000000..5ada4ef4b863 --- /dev/null +++ b/Modules/hashlib.h @@ -0,0 +1,173 @@ +/* Common code for use by all hashlib related modules. */ + +#include "pycore_lock.h" // PyMutex + +/* + * Internal error messages used for reporting an unsupported hash algorithm. + * The algorithm can be given by its name, a callable or a PEP-247 module. + * The same message is raised by Lib/hashlib.py::__get_builtin_constructor() + * and _hmacmodule.c::find_hash_info(). + */ +#define HASHLIB_UNSUPPORTED_ALGORITHM "unsupported hash algorithm %S" +#define HASHLIB_UNSUPPORTED_STR_ALGORITHM "unsupported hash algorithm %s" + +/* + * Obtain a buffer view from a buffer-like object 'obj'. + * + * On success, store the result in 'view' and return 0. + * On error, set an exception and return -1. + */ +static inline int +_Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view) +{ + if (PyUnicode_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "Strings must be encoded before hashing"); + return -1; + } + if (!PyObject_CheckBuffer(obj)) { + PyErr_SetString(PyExc_TypeError, + "object supporting the buffer API required"); + return -1; + } + if (PyObject_GetBuffer(obj, view, PyBUF_SIMPLE) == -1) { + return -1; + } + if (view->ndim > 1) { + PyErr_SetString(PyExc_BufferError, + "Buffer must be single dimension"); + PyBuffer_Release(view); + return -1; + } + return 0; +} + +/* + * Call _Py_hashlib_get_buffer_view() and check if it succeeded. + * + * On error, set an exception and execute the ERRACTION statements. + */ +#define GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, ERRACTION) \ + do { \ + if (_Py_hashlib_get_buffer_view(OBJ, VIEW) < 0) { \ + assert(PyErr_Occurred()); \ + ERRACTION; \ + } \ + } while (0) + +#define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \ + GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL) + +/* + * Helper code to synchronize access to the hash object when the GIL is + * released around a CPU consuming hashlib operation. + * + * Code accessing a mutable part of the hash object must be enclosed in + * an HASHLIB_{ACQUIRE,RELEASE}_LOCK block or explicitly acquire and release + * the mutex inside a Py_BEGIN_ALLOW_THREADS -- Py_END_ALLOW_THREADS block if + * they wish to release the GIL for an operation. + */ + +#define HASHLIB_OBJECT_HEAD \ + PyObject_HEAD \ + /* Guard against race conditions during incremental update(). */ \ + PyMutex mutex; + +#define HASHLIB_INIT_MUTEX(OBJ) \ + do { \ + (OBJ)->mutex = (PyMutex){0}; \ + } while (0) + +#define HASHLIB_ACQUIRE_LOCK(OBJ) PyMutex_Lock(&(OBJ)->mutex) +#define HASHLIB_RELEASE_LOCK(OBJ) PyMutex_Unlock(&(OBJ)->mutex) + +/* + * Message length above which the GIL is to be released + * when performing hashing operations. + */ +#define HASHLIB_GIL_MINSIZE 2048 + +// Macros for executing code while conditionally holding the GIL. +// +// These only drop the GIL if the lock acquisition itself is likely to +// block. Thus the non-blocking acquire gating the GIL release for a +// blocking lock acquisition. The intent of these macros is to surround +// the assumed always "fast" operations that you aren't releasing the +// GIL around. + +/* + * Execute a suite of C statements 'STATEMENTS'. + * + * The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold. + */ +#define HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(SIZE, STATEMENTS) \ + do { \ + if ((SIZE) > HASHLIB_GIL_MINSIZE) { \ + Py_BEGIN_ALLOW_THREADS \ + STATEMENTS; \ + Py_END_ALLOW_THREADS \ + } \ + else { \ + STATEMENTS; \ + } \ + } while (0) + +/* + * Lock 'OBJ' and execute a suite of C statements 'STATEMENTS'. + * + * The GIL is held if 'SIZE' is below the HASHLIB_GIL_MINSIZE threshold. + */ +#define HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(OBJ, SIZE, STATEMENTS) \ + do { \ + if ((SIZE) > HASHLIB_GIL_MINSIZE) { \ + Py_BEGIN_ALLOW_THREADS \ + HASHLIB_ACQUIRE_LOCK(OBJ); \ + STATEMENTS; \ + HASHLIB_RELEASE_LOCK(OBJ); \ + Py_END_ALLOW_THREADS \ + } \ + else { \ + HASHLIB_ACQUIRE_LOCK(OBJ); \ + STATEMENTS; \ + HASHLIB_RELEASE_LOCK(OBJ); \ + } \ + } while (0) + +static inline int +_Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string) +{ + if (data != NULL && string == NULL) { + // called as H(data) or H(data=...) + *res = data; + return 1; + } + else if (data == NULL && string != NULL) { + // called as H(string=...) + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the 'string' keyword parameter is deprecated since " + "Python 3.15 and slated for removal in Python 3.19; " + "use the 'data' keyword parameter or pass the data " + "to hash as a positional argument instead", 1) < 0) + { + *res = NULL; + return -1; + } + *res = string; + return 1; + } + else if (data == NULL && string == NULL) { + // fast path when no data is given + assert(!PyErr_Occurred()); + *res = NULL; + return 0; + } + else { + // called as H(data=..., string) + *res = NULL; + PyErr_SetString(PyExc_TypeError, + "'data' and 'string' are mutually exclusive " + "and support for 'string' keyword parameter " + "is slated for removal in a future version."); + return -1; + } +} diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index 92be49c5a879..694e2a095744 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -20,10 +20,6 @@ #include "pycore_hashtable.h" #include "pycore_strhex.h" // _Py_strhex() -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_fetch.h" -#include "_hashlib/hashlib_mutex.h" - /* * Taken from blake2module.c. In the future, detection of SIMD support * should be delegated to https://github.com/python/cpython/pull/125011. @@ -51,6 +47,8 @@ #include +#include "hashlib.h" + // --- Reusable error messages ------------------------------------------------ static inline void @@ -658,7 +656,7 @@ find_hash_info(hmacmodule_state *state, PyObject *hash_info_ref) } if (rc == 0) { PyErr_Format(state->unknown_hash_error, - _Py_HASHLIB_UNSUPPORTED_ALGORITHM, hash_info_ref); + HASHLIB_UNSUPPORTED_ALGORITHM, hash_info_ref); return NULL; } assert(info != NULL); diff --git a/Modules/md5module.c b/Modules/md5module.c index d5dc4f60a575..8b6dd4a8195d 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -22,10 +22,9 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_strhex.h" // _Py_strhex() -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_mutex.h" +#include "hashlib.h" #include "_hacl/Hacl_Hash_MD5.h" diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 86e5691e8463..faa9dcccc575 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -20,11 +20,9 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() - -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_mutex.h" +#include "hashlib.h" +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "_hacl/Hacl_Hash_SHA1.h" diff --git a/Modules/sha2module.c b/Modules/sha2module.c index dbf6dde1b8c1..36300ba899fd 100644 --- a/Modules/sha2module.c +++ b/Modules/sha2module.c @@ -21,12 +21,11 @@ #endif #include "Python.h" -#include "pycore_moduleobject.h" // _PyModule_GetState() -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "pycore_strhex.h" // _Py_strhex() -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_mutex.h" +#include "hashlib.h" #include "_hacl/Hacl_Hash_SHA2.h" diff --git a/Modules/sha3module.c b/Modules/sha3module.c index c67bfadbe466..5764556bb680 100644 --- a/Modules/sha3module.c +++ b/Modules/sha3module.c @@ -21,11 +21,9 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() - -#include "_hashlib/hashlib_buffer.h" -#include "_hashlib/hashlib_mutex.h" +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "hashlib.h" #include "_hacl/Hacl_Hash_SHA3.h" diff --git a/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index cfb43cee935b..2cd205224bc0 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -100,11 +100,6 @@ - - - - - diff --git a/PCbuild/_hashlib.vcxproj.filters b/PCbuild/_hashlib.vcxproj.filters index d465d92a956e..7a0700c007f6 100644 --- a/PCbuild/_hashlib.vcxproj.filters +++ b/PCbuild/_hashlib.vcxproj.filters @@ -18,4 +18,4 @@ Resource Files - + \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index c59b380d814e..517103acea8d 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -447,10 +447,6 @@ HACL_CAN_COMPILE_VEC128;%(PreprocessorDefinitions) /arch:AVX %(AdditionalOptions) - - - - diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 1410cbbef6c8..e9eedfd1312f 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -255,15 +255,6 @@ Include - - Modules\_hashlib - - - Modules\_hashlib - - - Modules\_hashlib - Modules @@ -980,9 +971,6 @@ Modules - - Modules\_hashlib - Modules diff --git a/configure b/configure index 0e7aefed5ee6..74df430d10d6 100755 --- a/configure +++ b/configure @@ -725,8 +725,6 @@ LIBHACL_BLAKE2_SIMD128_OBJS LIBHACL_SIMD128_FLAGS LIBHACL_LDFLAGS LIBHACL_CFLAGS -LIBHASHLIB_INTERNAL -LIBHASHLIB_INTERNAL_CFLAGS MODULE_UNICODEDATA_FALSE MODULE_UNICODEDATA_TRUE MODULE__MULTIBYTECODEC_FALSE @@ -29951,7 +29949,6 @@ SRCDIRS="\ Modules/_decimal \ Modules/_decimal/libmpdec \ Modules/_hacl \ - Modules/_hashlib \ Modules/_io \ Modules/_multiprocessing \ Modules/_sqlite \ @@ -32528,15 +32525,6 @@ then : fi -############################################################################### -# Cryptographic primitives -LIBHASHLIB_INTERNAL_CFLAGS="-I\$(srcdir)/Modules/_hashlib" -LIBHASHLIB_INTERNAL_LDFLAGS="-lm \$(LIBHASHLIB_INTERNAL_A)" -LIBHASHLIB_INTERNAL="\$(LIBHASHLIB_INTERNAL_HEADERS) \$(LIBHASHLIB_INTERNAL_A)" - - - - ############################################################################### # HACL* compilation and linking configuration (contact: @picnixz) # @@ -32785,8 +32773,8 @@ fi if test "x$py_cv_module__md5" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__MD5_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__MD5_LDFLAGS=\$($LIBHACL_MD5_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__MD5_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__MD5_LDFLAGS=\$($LIBHACL_MD5_LDFLAGS)$as_nl" fi if test "$py_cv_module__md5" = yes; then @@ -32830,8 +32818,8 @@ fi if test "x$py_cv_module__sha1" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__SHA1_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__SHA1_LDFLAGS=\$($LIBHACL_SHA1_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA1_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA1_LDFLAGS=\$($LIBHACL_SHA1_LDFLAGS)$as_nl" fi if test "$py_cv_module__sha1" = yes; then @@ -32875,8 +32863,8 @@ fi if test "x$py_cv_module__sha2" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__SHA2_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__SHA2_LDFLAGS=\$($LIBHACL_SHA2_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA2_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA2_LDFLAGS=\$($LIBHACL_SHA2_LDFLAGS)$as_nl" fi if test "$py_cv_module__sha2" = yes; then @@ -32920,8 +32908,8 @@ fi if test "x$py_cv_module__sha3" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__SHA3_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__SHA3_LDFLAGS=\$($LIBHACL_SHA3_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA3_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SHA3_LDFLAGS=\$($LIBHACL_SHA3_LDFLAGS)$as_nl" fi if test "$py_cv_module__sha3" = yes; then @@ -32965,8 +32953,8 @@ fi if test "x$py_cv_module__blake2" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=\$($LIBHACL_BLAKE2_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=\$($LIBHACL_BLAKE2_LDFLAGS)$as_nl" fi if test "$py_cv_module__blake2" = yes; then @@ -33011,8 +32999,8 @@ fi if test "x$py_cv_module__hmac" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__HMAC_CFLAGS=$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__HMAC_LDFLAGS=\$($LIBHACL_HMAC_LDFLAGS) $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HMAC_CFLAGS=$LIBHACL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HMAC_LDFLAGS=\$($LIBHACL_HMAC_LDFLAGS)$as_nl" fi if test "$py_cv_module__hmac" = yes; then @@ -33693,8 +33681,8 @@ fi if test "x$py_cv_module__hashlib" = xyes then : - as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES $LIBHASHLIB_INTERNAL_CFLAGS$as_nl" - as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS $LIBHASHLIB_INTERNAL_LDFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl" fi if test "$py_cv_module__hashlib" = yes; then diff --git a/configure.ac b/configure.ac index 1e590e1d0fd7..29e36f217402 100644 --- a/configure.ac +++ b/configure.ac @@ -7187,7 +7187,6 @@ SRCDIRS="\ Modules/_decimal \ Modules/_decimal/libmpdec \ Modules/_hacl \ - Modules/_hashlib \ Modules/_io \ Modules/_multiprocessing \ Modules/_sqlite \ @@ -7958,15 +7957,6 @@ PY_STDLIB_MOD_SIMPLE([_codecs_tw]) PY_STDLIB_MOD_SIMPLE([_multibytecodec]) PY_STDLIB_MOD_SIMPLE([unicodedata]) -############################################################################### -# Cryptographic primitives -LIBHASHLIB_INTERNAL_CFLAGS="-I\$(srcdir)/Modules/_hashlib" -LIBHASHLIB_INTERNAL_LDFLAGS="-lm \$(LIBHASHLIB_INTERNAL_A)" -LIBHASHLIB_INTERNAL="\$(LIBHASHLIB_INTERNAL_HEADERS) \$(LIBHASHLIB_INTERNAL_A)" - -AC_SUBST([LIBHASHLIB_INTERNAL_CFLAGS]) -AC_SUBST([LIBHASHLIB_INTERNAL]) - ############################################################################### # HACL* compilation and linking configuration (contact: @picnixz) # @@ -8103,9 +8093,7 @@ dnl The EXTNAME is the name of the extension module being built. AC_DEFUN([PY_HACL_CREATE_MODULE], [ AS_VAR_PUSHDEF([v], [[LIBHACL_][$1][_LDFLAGS]]) AS_VAR_SET([v], [[LIBHACL_][$1][_LIB_${LIBHACL_LDEPS_LIBTYPE}]]) - PY_STDLIB_MOD([$2], [$3], [], - [$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS], - [\$($v) $LIBHASHLIB_INTERNAL_LDFLAGS]) + PY_STDLIB_MOD([$2], [$3], [], [$LIBHACL_CFLAGS], [\$($v)]) AS_VAR_POPDEF([v]) ]) @@ -8186,8 +8174,7 @@ dnl OpenSSL bindings PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], - [$OPENSSL_INCLUDES $LIBHASHLIB_INTERNAL_CFLAGS], - [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS $LIBHASHLIB_INTERNAL_LDFLAGS]) + [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) dnl test modules PY_STDLIB_MOD([_testcapi], -- 2.47.2