From 4e214fa6be8eb7a1f547bfb2eb1c546162151d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:23:19 +0200 Subject: [PATCH 01/10] explode `hashlib.h` into multiple files --- Modules/_hashlib/hashlib_buffer.c | 40 ++++++ Modules/_hashlib/hashlib_buffer.h | 60 +++++++++ Modules/_hashlib/hashlib_fetch.h | 127 ++++++++++++++++++ .../{hashlib.h => _hashlib/hashlib_mutex.h} | 90 ++----------- 4 files changed, 235 insertions(+), 82 deletions(-) create mode 100644 Modules/_hashlib/hashlib_buffer.c create mode 100644 Modules/_hashlib/hashlib_buffer.h create mode 100644 Modules/_hashlib/hashlib_fetch.h rename Modules/{hashlib.h => _hashlib/hashlib_mutex.h} (53%) diff --git a/Modules/_hashlib/hashlib_buffer.c b/Modules/_hashlib/hashlib_buffer.c new file mode 100644 index 00000000000000..34811c6266fd64 --- /dev/null +++ b/Modules/_hashlib/hashlib_buffer.c @@ -0,0 +1,40 @@ +#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; + } +} diff --git a/Modules/_hashlib/hashlib_buffer.h b/Modules/_hashlib/hashlib_buffer.h new file mode 100644 index 00000000000000..13b0aa1ab3cb61 --- /dev/null +++ b/Modules/_hashlib/hashlib_buffer.h @@ -0,0 +1,60 @@ +#ifndef _HASHLIB_HASHLIB_BUFFER_H +#define _HASHLIB_HASHLIB_BUFFER_H + +#include "Python.h" + +/* + * Given an buffer-like OBJ, fill in the buffer VIEW with the result + * of PyObject_GetBuffer. + * + * On error, set an exception and execute the ERRACTION statements, + * e.g. 'return NULL' or 'goto error'. + * + * Parameters + * + * OBJ An object supporting the buffer API. + * VIEW A Py_buffer pointer to fill. + * ERRACTION The statements to execute on error. + */ +#define GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, ERRACTION) \ + do { \ + if (PyUnicode_Check((OBJ))) { \ + PyErr_SetString(PyExc_TypeError, \ + "strings must be encoded before hashing"); \ + ERRACTION; \ + } \ + if (!PyObject_CheckBuffer((OBJ))) { \ + PyErr_SetString(PyExc_TypeError, \ + "object supporting the buffer API required"); \ + ERRACTION; \ + } \ + if (PyObject_GetBuffer((OBJ), (VIEW), PyBUF_SIMPLE) == -1) { \ + ERRACTION; \ + } \ + if ((VIEW)->ndim > 1) { \ + PyErr_SetString(PyExc_BufferError, \ + "buffer must be one-dimensional"); \ + PyBuffer_Release((VIEW)); \ + 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) + +/* + * 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); + +#endif // !_HASHLIB_HASHLIB_BUFFER_H diff --git a/Modules/_hashlib/hashlib_fetch.h b/Modules/_hashlib/hashlib_fetch.h new file mode 100644 index 00000000000000..a62b8de2a206e6 --- /dev/null +++ b/Modules/_hashlib/hashlib_fetch.h @@ -0,0 +1,127 @@ +/* + * Interface for fetching a message digest from a digest-like identifier. + * + * The following table summaries the possible algorthms: + * + * +----------+--------------+--------------+---------------------------------+ + * | Family | Algorithm | Python Name | Notes | + * +==========+==============+==============+=================================+ + * | MD @ | + * | +--------------+--------------+---------------------------------+ + * | | MD5 | "md5" | | + * +----------+--------------+--------------+---------------------------------+ + * | SHA1 @ | + * | +--------------+--------------+---------------------------------+ + * | | SHA1-160 | "sha1" | | + * +----------+--------------+--------------+---------------------------------+ + * | SHA2 @ | + * | +--------------+--------------+---------------------------------+ + * | | SHA2-224 | "sha224" | | + * | | SHA2-256 | "sha256" | | + * | | SHA2-384 | "sha384" | | + * | | SHA2-512 | "sha512" | | + * +----------+--------------+--------------+---------------------------------+ + * | SHA2t @ Truncated SHA2-512 | + * | +--------------+--------------+---------------------------------+ + * | | SHA2-512/224 | "sha512_224" | | + * | | SHA2-512/256 | "sha512_256" | | + * +----------+--------------+--------------+---------------------------------+ + * | SHA3 @ | + * | +--------------+--------------+---------------------------------+ + * | | SHA3-224 | "sha3_224" | | + * | | SHA3-256 | "sha3_256" | | + * | | SHA3-384 | "sha3_384" | | + * | | SHA3-512 | "sha3_512" | | + * +----------+--------------+--------------+---------------------------------+ + * | SHA3-XOF @ Extensible Output Functions | + * | +--------------+--------------+---------------------------------+ + * | | SHAKE-128 | "shake_128" | | + * | | SHAKE-256 | "shake_256" | | + * +----------+--------------+--------------+---------------------------------+ + * | BLAKE2 @ | + * | +--------------+--------------+---------------------------------+ + * | | BLAKE2b | "blake2b" | | + * | | BLAKE2s | "blake2s" | | + * +----------+--------------+--------------+---------------------------------+ + */ + +#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" + +#define _Py_HASHLIB_MD_OID(ID) _Py_hashlib_MD_OID_ ## ID + +typedef enum { + /* MD-family */ + _Py_HASHLIB_MD_OID(md5) = 0, + /* SHA-1 family */ + _Py_HASHLIB_MD_OID(sha1), + /* SHA-2 family */ + _Py_HASHLIB_MD_OID(sha224), + _Py_HASHLIB_MD_OID(sha256), + _Py_HASHLIB_MD_OID(sha384), + _Py_HASHLIB_MD_OID(sha512), + /* Truncated SHA-2 family */ + _Py_HASHLIB_MD_OID(sha512_224), + _Py_HASHLIB_MD_OID(sha512_256), + /* SHA-3 family */ + _Py_HASHLIB_MD_OID(sha3_224), + _Py_HASHLIB_MD_OID(sha3_256), + _Py_HASHLIB_MD_OID(sha3_384), + _Py_HASHLIB_MD_OID(sha3_512), + /* SHA-3 XOF SHAKE family */ + _Py_HASHLIB_MD_OID(shake_128), + _Py_HASHLIB_MD_OID(shake_256), + /* BLAKE-2 family */ + _Py_HASHLIB_MD_OID(blake2b), + _Py_HASHLIB_MD_OID(blake2s), +} _Py_hashlib_MD_OID; + +static const char *_Py_HASHLIB_MD_NAMES[] = { +#define DECL_MESSAGE_DIGEST_NAME(ID) [_Py_HASHLIB_MD_OID(ID)] = #ID + /* MD-family */ + DECL_MESSAGE_DIGEST_NAME(md5), + /* SHA-1 family */ + DECL_MESSAGE_DIGEST_NAME(sha1), + /* SHA-2 family */ + DECL_MESSAGE_DIGEST_NAME(sha224), + DECL_MESSAGE_DIGEST_NAME(sha256), + DECL_MESSAGE_DIGEST_NAME(sha384), + DECL_MESSAGE_DIGEST_NAME(sha512), + /* Truncated SHA-2 family */ + DECL_MESSAGE_DIGEST_NAME(sha512_224), + DECL_MESSAGE_DIGEST_NAME(sha512_256), + /* SHA-3 family */ + DECL_MESSAGE_DIGEST_NAME(sha3_224), + DECL_MESSAGE_DIGEST_NAME(sha3_256), + DECL_MESSAGE_DIGEST_NAME(sha3_384), + DECL_MESSAGE_DIGEST_NAME(sha3_512), + /* SHA-3 XOF SHAKE family */ + DECL_MESSAGE_DIGEST_NAME(shake_128), + DECL_MESSAGE_DIGEST_NAME(shake_256), + /* BLAKE-2 family */ + DECL_MESSAGE_DIGEST_NAME(blake2b), + DECL_MESSAGE_DIGEST_NAME(blake2s), +#undef DECL_MESSAGE_DIGEST_NAME + NULL /* sentinel */ +}; + +static inline const char * +_Py_hashlib_md_name(_Py_hashlib_MD_OID id) +{ + assert(id >= 0); + assert(id < Py_ARRAY_LENGTH(_Py_HASHLIB_MD_NAMES)); + return _Py_HASHLIB_MD_NAMES[id]; +} + +#endif // !_HASHLIB_HASHLIB_FETCH_H diff --git a/Modules/hashlib.h b/Modules/_hashlib/hashlib_mutex.h similarity index 53% rename from Modules/hashlib.h rename to Modules/_hashlib/hashlib_mutex.h index 5de5922c345047..d6924a2ef61e81 100644 --- a/Modules/hashlib.h +++ b/Modules/_hashlib/hashlib_mutex.h @@ -1,45 +1,14 @@ -/* Common code for use by all hashlib related modules. */ +#ifndef _HASHLIB_HASHLIB_MUTEX_H +#define _HASHLIB_HASHLIB_MUTEX_H -#include "pycore_lock.h" // PyMutex +#include "Python.h" +#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" - -/* - * Given a PyObject* obj, fill in the Py_buffer* viewp with the result - * of PyObject_GetBuffer. Sets an exception and issues the erraction - * on any errors, e.g. 'return NULL' or 'goto error'. + * Message length above which the GIL is to be released + * when performing hashing operations. */ -#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ - if (PyUnicode_Check((obj))) { \ - PyErr_SetString(PyExc_TypeError, \ - "Strings must be encoded before hashing");\ - erraction; \ - } \ - if (!PyObject_CheckBuffer((obj))) { \ - PyErr_SetString(PyExc_TypeError, \ - "object supporting the buffer API required"); \ - erraction; \ - } \ - if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ - erraction; \ - } \ - if ((viewp)->ndim > 1) { \ - PyErr_SetString(PyExc_BufferError, \ - "Buffer must be single dimension"); \ - PyBuffer_Release((viewp)); \ - erraction; \ - } \ - } while(0) - -#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ - GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) +#define HASHLIB_GIL_MINSIZE 2048 /* * Helper code to synchronize access to the hash object when the GIL is @@ -64,12 +33,6 @@ #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 @@ -116,41 +79,4 @@ } \ } 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; - } -} +#endif // !_HASHLIB_HASHLIB_MUTEX_H From 854bf43ebcc86a5a7726b3f0e60ea8fa3aab4efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:23:33 +0200 Subject: [PATCH 02/10] update usage of `hashlib.h` --- Modules/_hashopenssl.c | 9 ++++++--- Modules/blake2module.c | 6 ++++-- Modules/hmacmodule.c | 8 +++++--- Modules/md5module.c | 3 ++- Modules/sha1module.c | 4 +++- Modules/sha2module.c | 5 +++-- Modules/sha3module.c | 4 +++- 7 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index d79e4b360e95c5..c42513a53d4561 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -26,7 +26,10 @@ #include "pycore_hashtable.h" #include "pycore_strhex.h" // _Py_strhex() #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_RELAXED -#include "hashlib.h" + +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_fetch.h" +#include "_hashlib/hashlib_mutex.h" /* EVP is the preferred interface to hashing in OpenSSL */ #include @@ -532,7 +535,7 @@ raise_unsupported_algorithm_error(_hashlibstate *state, PyObject *digestmod) { raise_unsupported_algorithm_impl( state->unsupported_digestmod_error, - HASHLIB_UNSUPPORTED_ALGORITHM, + _Py_HASHLIB_UNSUPPORTED_ALGORITHM, digestmod ); } @@ -542,7 +545,7 @@ raise_unsupported_str_algorithm_error(_hashlibstate *state, const char *name) { raise_unsupported_algorithm_impl( state->unsupported_digestmod_error, - HASHLIB_UNSUPPORTED_STR_ALGORITHM, + _Py_HASHLIB_UNSUPPORTED_STR_ALGORITHM, name ); } diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 163f238a4268d0..5eaa9962e010b2 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -15,10 +15,12 @@ #endif #include "Python.h" -#include "hashlib.h" +#include "pycore_moduleobject.h" #include "pycore_strhex.h" // _Py_strhex() #include "pycore_typeobject.h" -#include "pycore_moduleobject.h" + +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_mutex.h" // QUICK CPU AUTODETECTION // diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index b5405c99f1f8ce..1752d0593c46f2 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -20,6 +20,10 @@ #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. @@ -47,8 +51,6 @@ #include -#include "hashlib.h" - // --- Reusable error messages ------------------------------------------------ static inline void @@ -656,7 +658,7 @@ find_hash_info(hmacmodule_state *state, PyObject *hash_info_ref) } if (rc == 0) { PyErr_Format(state->unknown_hash_error, - HASHLIB_UNSUPPORTED_ALGORITHM, hash_info_ref); + _Py_HASHLIB_UNSUPPORTED_ALGORITHM, hash_info_ref); return NULL; } assert(info != NULL); diff --git a/Modules/md5module.c b/Modules/md5module.c index 8b6dd4a8195dfb..d56388f8d95bd5 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -24,7 +24,8 @@ #include "Python.h" #include "pycore_strhex.h" // _Py_strhex() -#include "hashlib.h" +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_mutex.h" #include "_hacl/Hacl_Hash_MD5.h" diff --git a/Modules/sha1module.c b/Modules/sha1module.c index faa9dcccc5755b..07d8f0b52f49f1 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -20,10 +20,12 @@ #endif #include "Python.h" -#include "hashlib.h" #include "pycore_strhex.h" // _Py_strhex() #include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_mutex.h" + #include "_hacl/Hacl_Hash_SHA1.h" /* The SHA1 block size and message digest sizes, in bytes */ diff --git a/Modules/sha2module.c b/Modules/sha2module.c index 36300ba899fd44..2cafefc54c32f9 100644 --- a/Modules/sha2module.c +++ b/Modules/sha2module.c @@ -22,10 +22,11 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() -#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() -#include "hashlib.h" +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_mutex.h" #include "_hacl/Hacl_Hash_SHA2.h" diff --git a/Modules/sha3module.c b/Modules/sha3module.c index 5764556bb680f3..55820d7b8db95c 100644 --- a/Modules/sha3module.c +++ b/Modules/sha3module.c @@ -23,7 +23,9 @@ #include "Python.h" #include "pycore_strhex.h" // _Py_strhex() #include "pycore_typeobject.h" // _PyType_GetModuleState() -#include "hashlib.h" + +#include "_hashlib/hashlib_buffer.h" +#include "_hashlib/hashlib_mutex.h" #include "_hacl/Hacl_Hash_SHA3.h" From e1d233e6e8dfe365ba268798e6dc37fcb311e400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:30:34 +0200 Subject: [PATCH 03/10] update build configuration --- Makefile.pre.in | 37 ++++++++++++++++++++----- PCbuild/_hashlib.vcxproj | 6 +++++ PCbuild/_hashlib.vcxproj.filters | 2 +- PCbuild/pythoncore.vcxproj | 4 +++ PCbuild/pythoncore.vcxproj.filters | 12 +++++++++ Tools/c-analyzer/cpython/ignored.tsv | 1 + configure | 40 ++++++++++++++++++---------- configure.ac | 17 ++++++++++-- 8 files changed, 95 insertions(+), 24 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index fa17f5d7bfc0ac..9582b002320b37 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -227,6 +227,7 @@ 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@ @@ -761,6 +762,17 @@ 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 @@ -1511,6 +1523,17 @@ $(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 # @@ -3353,21 +3376,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=$(srcdir)/Modules/hashlib.h +MODULE__HASHLIB_DEPS=@LIBHASHLIB_INTERNAL@ MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h # HACL*-based cryptographic primitives -MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__MD5_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_MD5_HEADERS) $(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__MD5_LDEPS=$(LIBHACL_MD5_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA1_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA1_HEADERS) $(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA1_LDEPS=$(LIBHACL_SHA1_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA2_LDEPS=$(LIBHACL_SHA2_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__SHA3_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_SHA3_HEADERS) $(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__SHA3_LDEPS=$(LIBHACL_SHA3_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__BLAKE2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__BLAKE2_DEPS=$(MODULE__HASHLIB_DEPS) $(LIBHACL_BLAKE2_HEADERS) $(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) MODULE__BLAKE2_LDEPS=$(LIBHACL_BLAKE2_LIB_@LIBHACL_LDEPS_LIBTYPE@) -MODULE__HMAC_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HMAC_HEADERS) $(LIBHACL_HMAC_LIB_@LIBHACL_LDEPS_LIBTYPE@) +MODULE__HMAC_DEPS=$(MODULE__HASHLIB_DEPS) $(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/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index 2cd205224bc089..9e6dcee40793d3 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -100,6 +100,12 @@ + + + + + + diff --git a/PCbuild/_hashlib.vcxproj.filters b/PCbuild/_hashlib.vcxproj.filters index 7a0700c007f644..d465d92a956eda 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 b911c9385634d7..7fbb8f9dc7609c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -447,6 +447,10 @@ HACL_CAN_COMPILE_VEC128;%(PreprocessorDefinitions) /arch:AVX %(AdditionalOptions) + + + + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 0e6d42cc959ba5..088c99eab01b61 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -255,6 +255,15 @@ Include + + Modules\_hashlib + + + Modules\_hashlib + + + Modules\_hashlib + Modules @@ -971,6 +980,9 @@ Modules + + Modules\_hashlib + Modules diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index dc626e4bea0f59..de24325fb63838 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -238,6 +238,7 @@ Modules/_decimal/_decimal.c - signal_map_template - Modules/_decimal/_decimal.c - ssize_constants - Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG - Modules/_elementtree.c - ExpatMemoryHandler - +Modules/_hashlib/hashlib_fetch.h - _Py_HASHLIB_MD_NAMES - Modules/_hashopenssl.c - py_hashes - Modules/_hacl/Hacl_Hash_SHA1.c - _h0 - Modules/_hacl/Hacl_Hash_MD5.c - _h0 - diff --git a/configure b/configure index 8db2e9c46abba2..aa5223f1d77a24 100755 --- a/configure +++ b/configure @@ -725,6 +725,8 @@ 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 @@ -29947,6 +29949,7 @@ SRCDIRS="\ Modules/_decimal \ Modules/_decimal/libmpdec \ Modules/_hacl \ + Modules/_hashlib \ Modules/_io \ Modules/_multiprocessing \ Modules/_sqlite \ @@ -32523,6 +32526,15 @@ 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) # @@ -32771,8 +32783,8 @@ fi if test "x$py_cv_module__md5" = xyes then : - 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" + 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" fi if test "$py_cv_module__md5" = yes; then @@ -32816,8 +32828,8 @@ fi if test "x$py_cv_module__sha1" = xyes then : - 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" + 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" fi if test "$py_cv_module__sha1" = yes; then @@ -32861,8 +32873,8 @@ fi if test "x$py_cv_module__sha2" = xyes then : - 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" + 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" fi if test "$py_cv_module__sha2" = yes; then @@ -32906,8 +32918,8 @@ fi if test "x$py_cv_module__sha3" = xyes then : - 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" + 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" fi if test "$py_cv_module__sha3" = yes; then @@ -32951,8 +32963,8 @@ fi if test "x$py_cv_module__blake2" = xyes then : - 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" + 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" fi if test "$py_cv_module__blake2" = yes; then @@ -32997,8 +33009,8 @@ fi if test "x$py_cv_module__hmac" = xyes then : - 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" + 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" fi if test "$py_cv_module__hmac" = yes; then @@ -33679,8 +33691,8 @@ fi if test "x$py_cv_module__hashlib" = xyes then : - 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" + 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" fi if test "$py_cv_module__hashlib" = yes; then diff --git a/configure.ac b/configure.ac index c839dd65a5fc5a..f05ad35abd71a6 100644 --- a/configure.ac +++ b/configure.ac @@ -7186,6 +7186,7 @@ SRCDIRS="\ Modules/_decimal \ Modules/_decimal/libmpdec \ Modules/_hacl \ + Modules/_hashlib \ Modules/_io \ Modules/_multiprocessing \ Modules/_sqlite \ @@ -7956,6 +7957,15 @@ 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) # @@ -8092,7 +8102,9 @@ 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], [\$($v)]) + PY_STDLIB_MOD([$2], [$3], [], + [$LIBHACL_CFLAGS $LIBHASHLIB_INTERNAL_CFLAGS], + [\$($v) $LIBHASHLIB_INTERNAL_LDFLAGS]) AS_VAR_POPDEF([v]) ]) @@ -8173,7 +8185,8 @@ 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], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) + [$OPENSSL_INCLUDES $LIBHASHLIB_INTERNAL_CFLAGS], + [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS $LIBHASHLIB_INTERNAL_LDFLAGS]) dnl test modules PY_STDLIB_MOD([_testcapi], From 59b0cda0b18ccd667a0302269e1c50590ac51606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:47:49 +0200 Subject: [PATCH 04/10] blurb --- .../next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst 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 new file mode 100644 index 00000000000000..304f2c30f664db --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-07-22-14-47-45.gh-issue-131876.oaYEEP.rst @@ -0,0 +1,2 @@ +Remove :file:`!Modules/hashlib.h` and move its content into dedicated files +now located in ``Modules/_hashlib``. Patch by Bénédikt Tran. From 42636888f368802781c59ab0cc8c8e0fe4869bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 26 Jul 2025 09:02:59 +0200 Subject: [PATCH 05/10] remove code that is currently unused --- Modules/_hashlib/hashlib_fetch.h | 65 -------------------------------- 1 file changed, 65 deletions(-) diff --git a/Modules/_hashlib/hashlib_fetch.h b/Modules/_hashlib/hashlib_fetch.h index a62b8de2a206e6..c1479e96148df6 100644 --- a/Modules/_hashlib/hashlib_fetch.h +++ b/Modules/_hashlib/hashlib_fetch.h @@ -59,69 +59,4 @@ #define _Py_HASHLIB_UNSUPPORTED_ALGORITHM "unsupported hash algorithm %S" #define _Py_HASHLIB_UNSUPPORTED_STR_ALGORITHM "unsupported hash algorithm %s" -#define _Py_HASHLIB_MD_OID(ID) _Py_hashlib_MD_OID_ ## ID - -typedef enum { - /* MD-family */ - _Py_HASHLIB_MD_OID(md5) = 0, - /* SHA-1 family */ - _Py_HASHLIB_MD_OID(sha1), - /* SHA-2 family */ - _Py_HASHLIB_MD_OID(sha224), - _Py_HASHLIB_MD_OID(sha256), - _Py_HASHLIB_MD_OID(sha384), - _Py_HASHLIB_MD_OID(sha512), - /* Truncated SHA-2 family */ - _Py_HASHLIB_MD_OID(sha512_224), - _Py_HASHLIB_MD_OID(sha512_256), - /* SHA-3 family */ - _Py_HASHLIB_MD_OID(sha3_224), - _Py_HASHLIB_MD_OID(sha3_256), - _Py_HASHLIB_MD_OID(sha3_384), - _Py_HASHLIB_MD_OID(sha3_512), - /* SHA-3 XOF SHAKE family */ - _Py_HASHLIB_MD_OID(shake_128), - _Py_HASHLIB_MD_OID(shake_256), - /* BLAKE-2 family */ - _Py_HASHLIB_MD_OID(blake2b), - _Py_HASHLIB_MD_OID(blake2s), -} _Py_hashlib_MD_OID; - -static const char *_Py_HASHLIB_MD_NAMES[] = { -#define DECL_MESSAGE_DIGEST_NAME(ID) [_Py_HASHLIB_MD_OID(ID)] = #ID - /* MD-family */ - DECL_MESSAGE_DIGEST_NAME(md5), - /* SHA-1 family */ - DECL_MESSAGE_DIGEST_NAME(sha1), - /* SHA-2 family */ - DECL_MESSAGE_DIGEST_NAME(sha224), - DECL_MESSAGE_DIGEST_NAME(sha256), - DECL_MESSAGE_DIGEST_NAME(sha384), - DECL_MESSAGE_DIGEST_NAME(sha512), - /* Truncated SHA-2 family */ - DECL_MESSAGE_DIGEST_NAME(sha512_224), - DECL_MESSAGE_DIGEST_NAME(sha512_256), - /* SHA-3 family */ - DECL_MESSAGE_DIGEST_NAME(sha3_224), - DECL_MESSAGE_DIGEST_NAME(sha3_256), - DECL_MESSAGE_DIGEST_NAME(sha3_384), - DECL_MESSAGE_DIGEST_NAME(sha3_512), - /* SHA-3 XOF SHAKE family */ - DECL_MESSAGE_DIGEST_NAME(shake_128), - DECL_MESSAGE_DIGEST_NAME(shake_256), - /* BLAKE-2 family */ - DECL_MESSAGE_DIGEST_NAME(blake2b), - DECL_MESSAGE_DIGEST_NAME(blake2s), -#undef DECL_MESSAGE_DIGEST_NAME - NULL /* sentinel */ -}; - -static inline const char * -_Py_hashlib_md_name(_Py_hashlib_MD_OID id) -{ - assert(id >= 0); - assert(id < Py_ARRAY_LENGTH(_Py_HASHLIB_MD_NAMES)); - return _Py_HASHLIB_MD_NAMES[id]; -} - #endif // !_HASHLIB_HASHLIB_FETCH_H From eb817fd57facb93a10845b314e578c73f843e61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 26 Jul 2025 09:03:04 +0200 Subject: [PATCH 06/10] cleanup imports --- Modules/_hashopenssl.c | 6 +++--- Modules/blake2module.c | 2 +- Modules/md5module.c | 2 +- Modules/sha1module.c | 4 ++-- Modules/sha2module.c | 6 +++--- Modules/sha3module.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index c42513a53d4561..c5d101289af1e7 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -24,8 +24,8 @@ #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 "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" @@ -34,7 +34,7 @@ /* 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 diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 5eaa9962e010b2..13c969056be354 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -16,7 +16,7 @@ #include "Python.h" #include "pycore_moduleobject.h" -#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_strhex.h" // _Py_strhex() #include "pycore_typeobject.h" #include "_hashlib/hashlib_buffer.h" diff --git a/Modules/md5module.c b/Modules/md5module.c index d56388f8d95bd5..d5dc4f60a575d4 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -22,7 +22,7 @@ #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" diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 07d8f0b52f49f1..86e5691e8463e4 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -20,8 +20,8 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "_hashlib/hashlib_buffer.h" #include "_hashlib/hashlib_mutex.h" diff --git a/Modules/sha2module.c b/Modules/sha2module.c index 2cafefc54c32f9..dbf6dde1b8c121 100644 --- a/Modules/sha2module.c +++ b/Modules/sha2module.c @@ -21,9 +21,9 @@ #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_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "_hashlib/hashlib_buffer.h" #include "_hashlib/hashlib_mutex.h" diff --git a/Modules/sha3module.c b/Modules/sha3module.c index 55820d7b8db95c..c67bfadbe4664a 100644 --- a/Modules/sha3module.c +++ b/Modules/sha3module.c @@ -21,8 +21,8 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "_hashlib/hashlib_buffer.h" #include "_hashlib/hashlib_mutex.h" From 06d2c87e7144de356570e5076d22417a57a3c0fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:10:14 +0200 Subject: [PATCH 07/10] amend comments --- Modules/_hashlib/hashlib_fetch.h | 45 +------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/Modules/_hashlib/hashlib_fetch.h b/Modules/_hashlib/hashlib_fetch.h index c1479e96148df6..09add71e0c798c 100644 --- a/Modules/_hashlib/hashlib_fetch.h +++ b/Modules/_hashlib/hashlib_fetch.h @@ -1,48 +1,5 @@ /* - * Interface for fetching a message digest from a digest-like identifier. - * - * The following table summaries the possible algorthms: - * - * +----------+--------------+--------------+---------------------------------+ - * | Family | Algorithm | Python Name | Notes | - * +==========+==============+==============+=================================+ - * | MD @ | - * | +--------------+--------------+---------------------------------+ - * | | MD5 | "md5" | | - * +----------+--------------+--------------+---------------------------------+ - * | SHA1 @ | - * | +--------------+--------------+---------------------------------+ - * | | SHA1-160 | "sha1" | | - * +----------+--------------+--------------+---------------------------------+ - * | SHA2 @ | - * | +--------------+--------------+---------------------------------+ - * | | SHA2-224 | "sha224" | | - * | | SHA2-256 | "sha256" | | - * | | SHA2-384 | "sha384" | | - * | | SHA2-512 | "sha512" | | - * +----------+--------------+--------------+---------------------------------+ - * | SHA2t @ Truncated SHA2-512 | - * | +--------------+--------------+---------------------------------+ - * | | SHA2-512/224 | "sha512_224" | | - * | | SHA2-512/256 | "sha512_256" | | - * +----------+--------------+--------------+---------------------------------+ - * | SHA3 @ | - * | +--------------+--------------+---------------------------------+ - * | | SHA3-224 | "sha3_224" | | - * | | SHA3-256 | "sha3_256" | | - * | | SHA3-384 | "sha3_384" | | - * | | SHA3-512 | "sha3_512" | | - * +----------+--------------+--------------+---------------------------------+ - * | SHA3-XOF @ Extensible Output Functions | - * | +--------------+--------------+---------------------------------+ - * | | SHAKE-128 | "shake_128" | | - * | | SHAKE-256 | "shake_256" | | - * +----------+--------------+--------------+---------------------------------+ - * | BLAKE2 @ | - * | +--------------+--------------+---------------------------------+ - * | | BLAKE2b | "blake2b" | | - * | | BLAKE2s | "blake2s" | | - * +----------+--------------+--------------+---------------------------------+ + * Utilities used when fetching a message digest from a digest-like identifier. */ #ifndef _HASHLIB_HASHLIB_FETCH_H From a1a2f1bed381014ab194ab331dca3cd402af4b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:13:36 +0200 Subject: [PATCH 08/10] remove unused rules --- Tools/c-analyzer/cpython/ignored.tsv | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index de24325fb63838..dc626e4bea0f59 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -238,7 +238,6 @@ Modules/_decimal/_decimal.c - signal_map_template - Modules/_decimal/_decimal.c - ssize_constants - Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG - Modules/_elementtree.c - ExpatMemoryHandler - -Modules/_hashlib/hashlib_fetch.h - _Py_HASHLIB_MD_NAMES - Modules/_hashopenssl.c - py_hashes - Modules/_hacl/Hacl_Hash_SHA1.c - _h0 - Modules/_hacl/Hacl_Hash_MD5.c - _h0 - From 89c0e3c1888064c9fe74e5ed15135e896da11cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:32:30 +0200 Subject: [PATCH 09/10] reduce exported scope --- Modules/_hashlib/hashlib_buffer.c | 25 +++++++++++++++ Modules/_hashlib/hashlib_buffer.h | 52 +++++++++---------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Modules/_hashlib/hashlib_buffer.c b/Modules/_hashlib/hashlib_buffer.c index 34811c6266fd64..032f93ad53ad1b 100644 --- a/Modules/_hashlib/hashlib_buffer.c +++ b/Modules/_hashlib/hashlib_buffer.c @@ -38,3 +38,28 @@ _Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string) 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 index 74ef20968f1c6b..585ae10566f134 100644 --- a/Modules/_hashlib/hashlib_buffer.h +++ b/Modules/_hashlib/hashlib_buffer.h @@ -3,36 +3,26 @@ #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. + */ +extern 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. */ -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; -} +extern int +_Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view); /* * Call _Py_hashlib_get_buffer_view() and check if it succeeded. @@ -51,18 +41,4 @@ _Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view) #define GET_BUFFER_VIEW_OR_ERROUT(OBJ, VIEW) \ GET_BUFFER_VIEW_OR_ERROR(OBJ, VIEW, return NULL) -/* - * 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); - #endif // !_HASHLIB_HASHLIB_BUFFER_H From a0fa84954ae76c912fa5ba9b36fb52983e0267d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:45:57 +0200 Subject: [PATCH 10/10] Windows is not happy --- Modules/_hashlib/hashlib_buffer.h | 8 ++++++-- PCbuild/_hashlib.vcxproj | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Modules/_hashlib/hashlib_buffer.h b/Modules/_hashlib/hashlib_buffer.h index 585ae10566f134..809f19884f41b7 100644 --- a/Modules/_hashlib/hashlib_buffer.h +++ b/Modules/_hashlib/hashlib_buffer.h @@ -11,8 +11,10 @@ * - 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. */ -extern int +PyAPI_FUNC(int) _Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string); /* @@ -20,8 +22,10 @@ _Py_hashlib_data_argument(PyObject **res, PyObject *data, PyObject *string); * * 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. */ -extern int +PyAPI_FUNC(int) _Py_hashlib_get_buffer_view(PyObject *obj, Py_buffer *view); /* diff --git a/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index 9e6dcee40793d3..cfb43cee935b86 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -101,7 +101,6 @@ - pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy