From d19bf2ffa80a5e94fb33e10e793735c1f9bb2f1b 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, 24 May 2025 11:18:47 +0200 Subject: [PATCH 01/15] use a macro for checking `OPENSSL_VERSION_NUMBER >= 0x30000000L` --- Modules/_hashopenssl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 48eed5eac975ed..23b9f76ca21230 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -38,6 +38,10 @@ #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +# define Py_HAS_OPENSSL3_SUPPORT +#endif + #ifndef OPENSSL_THREADS # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" #endif @@ -55,7 +59,7 @@ #define PY_OPENSSL_HAS_BLAKE2 1 #endif -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifdef Py_HAS_OPENSSL3_SUPPORT #define PY_EVP_MD EVP_MD #define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties) #define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md) @@ -1926,7 +1930,7 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifdef Py_HAS_OPENSSL3_SUPPORT _openssl_hash_name_mapper(EVP_MD *md, void *arg) #else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, @@ -1966,7 +1970,7 @@ hashlib_md_meth_names(PyObject *module) return -1; } -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifdef Py_HAS_OPENSSL3_SUPPORT // get algorithms from all activated providers in default context EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); #else @@ -1999,7 +2003,7 @@ _hashlib_get_fips_mode_impl(PyObject *module) /*[clinic end generated code: output=87eece1bab4d3fa9 input=2db61538c41c6fef]*/ { -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifdef Py_HAS_OPENSSL3_SUPPORT return EVP_default_properties_is_fips_enabled(NULL); #else ERR_clear_error(); From a6f772e14306508146849286f0416ea638de49d7 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, 24 May 2025 11:20:43 +0200 Subject: [PATCH 02/15] make `Py_hash_type` a `typedef` --- Modules/_hashopenssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 23b9f76ca21230..fca6c721c9a65e 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -81,12 +81,12 @@ * py_alias as keys. */ -enum Py_hash_type { +typedef enum Py_hash_type { Py_ht_evp, // usedforsecurity=True / default Py_ht_evp_nosecurity, // usedforsecurity=False Py_ht_mac, // HMAC Py_ht_pbkdf2, // PKBDF2 -}; +} Py_hash_type; typedef struct { const char *py_name; @@ -398,7 +398,7 @@ py_digest_name(const EVP_MD *md) /* Get EVP_MD by HID and purpose */ static PY_EVP_MD* -py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) +py_digest_by_name(PyObject *module, const char *name, Py_hash_type py_ht) { PY_EVP_MD *digest = NULL; PY_EVP_MD *other_digest = NULL; @@ -472,7 +472,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) * on error returns NULL with exception set. */ static PY_EVP_MD* -py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type py_ht) { +py_digest_by_digestmod(PyObject *module, PyObject *digestmod, Py_hash_type py_ht) { PyObject *name_obj = NULL; const char *name; From 10ce66f5e1444f1e6331d279de0c0e2bb7d48e20 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, 24 May 2025 11:30:18 +0200 Subject: [PATCH 03/15] replace `EVP` by `HASH/HASHXOF` when necessary --- Modules/_hashopenssl.c | 381 +++++++++++++++++--------------- Modules/clinic/_hashopenssl.c.h | 116 +++++----- 2 files changed, 262 insertions(+), 235 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index fca6c721c9a65e..44d639ee7f89c8 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -82,10 +82,10 @@ */ typedef enum Py_hash_type { - Py_ht_evp, // usedforsecurity=True / default - Py_ht_evp_nosecurity, // usedforsecurity=False - Py_ht_mac, // HMAC - Py_ht_pbkdf2, // PKBDF2 + Py_ht_evp_md, // usedforsecurity=True / default + Py_ht_evp_md_nosecurity, // usedforsecurity=False + Py_ht_mac, // HMAC + Py_ht_pbkdf2, // PKBDF2 } Py_hash_type; typedef struct { @@ -94,8 +94,8 @@ typedef struct { const char *ossl_name; int ossl_nid; int refcnt; - PY_EVP_MD *evp; - PY_EVP_MD *evp_nosecurity; + PY_EVP_MD *evp_md; + PY_EVP_MD *evp_md_nosecurity; } py_hashentry_t; // Fundamental to TLS, assumed always present in any libcrypto: @@ -202,13 +202,13 @@ static void py_hashentry_t_destroy_value(void *entry) { py_hashentry_t *h = (py_hashentry_t *)entry; if (--(h->refcnt) == 0) { - if (h->evp != NULL) { - PY_EVP_MD_free(h->evp); - h->evp = NULL; + if (h->evp_md != NULL) { + PY_EVP_MD_free(h->evp_md); + h->evp_md = NULL; } - if (h->evp_nosecurity != NULL) { - PY_EVP_MD_free(h->evp_nosecurity); - h->evp_nosecurity = NULL; + if (h->evp_md_nosecurity != NULL) { + PY_EVP_MD_free(h->evp_md_nosecurity); + h->evp_md_nosecurity = NULL; } PyMem_Free(entry); } @@ -259,10 +259,10 @@ py_hashentry_table_new(void) { static PyModuleDef _hashlibmodule; typedef struct { - PyTypeObject *EVPtype; + PyTypeObject *HASH_type; // based on EVP_MD PyTypeObject *HMACtype; #ifdef PY_OPENSSL_HAS_SHAKE - PyTypeObject *EVPXOFtype; + PyTypeObject *HASHXOF_type; // based on EVP_MD #endif PyObject *constructs; PyObject *unsupported_digestmod_error; @@ -279,20 +279,21 @@ get_hashlib_state(PyObject *module) typedef struct { PyObject_HEAD - EVP_MD_CTX *ctx; /* OpenSSL message digest context */ + EVP_MD_CTX *ctx; /* OpenSSL message digest context */ // Prevents undefined behavior via multiple threads entering the C API. bool use_mutex; - PyMutex mutex; /* OpenSSL context lock */ -} EVPobject; + PyMutex mutex; /* OpenSSL context lock */ +} HASHobject; -#define EVPobject_CAST(op) ((EVPobject *)(op)) +#define HASHXOFobject HASHobject +#define HASHobject_CAST(op) ((HASHobject *)(op)) typedef struct { PyObject_HEAD - HMAC_CTX *ctx; /* OpenSSL hmac context */ + HMAC_CTX *ctx; /* OpenSSL hmac context */ // Prevents undefined behavior via multiple threads entering the C API. bool use_mutex; - PyMutex mutex; /* HMAC context lock */ + PyMutex mutex; /* HMAC context lock */ } HMACobject; #define HMACobject_CAST(op) ((HMACobject *)(op)) @@ -300,11 +301,11 @@ typedef struct { #include "clinic/_hashopenssl.c.h" /*[clinic input] module _hashlib -class _hashlib.HASH "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPtype" -class _hashlib.HASHXOF "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype" +class _hashlib.HASH "HASHobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPtype" +class _hashlib.HASHXOF "HASHXOFobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype" class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))->HMACtype" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7df1bcf6f75cb8ef]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=466d7751ac96b4b1]*/ /* LCOV_EXCL_START */ @@ -368,8 +369,8 @@ notify_ssl_error_occurred(void) } /* LCOV_EXCL_STOP */ -static PyObject* -py_digest_name(const EVP_MD *md) +static const char * +get_openssl_evp_md_utf8name(const EVP_MD *md) { assert(md != NULL); int nid = EVP_MD_nid(md); @@ -389,16 +390,24 @@ py_digest_name(const EVP_MD *md) * names for several algorithms. */ name = OBJ_nid2ln(nid); - if (name == NULL) + if (name == NULL) { name = OBJ_nid2sn(nid); + } } + return name; +} +static inline PyObject * +get_openssl_evp_md_name(const EVP_MD *md) +{ + const char *name = get_openssl_evp_md_utf8name(md); return PyUnicode_FromString(name); } /* Get EVP_MD by HID and purpose */ -static PY_EVP_MD* -py_digest_by_name(PyObject *module, const char *name, Py_hash_type py_ht) +static PY_EVP_MD * +get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, + Py_hash_type hash_type) { PY_EVP_MD *digest = NULL; PY_EVP_MD *other_digest = NULL; @@ -408,30 +417,30 @@ py_digest_by_name(PyObject *module, const char *name, Py_hash_type py_ht) ); if (entry != NULL) { - switch (py_ht) { - case Py_ht_evp: + switch (hash_type) { + case Py_ht_evp_md: case Py_ht_mac: case Py_ht_pbkdf2: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp); + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); if (digest == NULL) { digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); #ifdef Py_GIL_DISABLED // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp, (void *)digest); + other_digest = _Py_atomic_exchange_ptr(&entry->evp_md, (void *)digest); #else - entry->evp = digest; + entry->evp_md = digest; #endif } break; - case Py_ht_evp_nosecurity: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_nosecurity); + case Py_ht_evp_md_nosecurity: + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); if (digest == NULL) { digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); #ifdef Py_GIL_DISABLED // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_nosecurity, (void *)digest); + other_digest = _Py_atomic_exchange_ptr(&entry->evp_md_nosecurity, (void *)digest); #else - entry->evp_nosecurity = digest; + entry->evp_md_nosecurity = digest; #endif } break; @@ -445,13 +454,13 @@ py_digest_by_name(PyObject *module, const char *name, Py_hash_type py_ht) } } else { // Fall back for looking up an unindexed OpenSSL specific name. - switch (py_ht) { - case Py_ht_evp: + switch (hash_type) { + case Py_ht_evp_md: case Py_ht_mac: case Py_ht_pbkdf2: digest = PY_EVP_MD_fetch(name, NULL); break; - case Py_ht_evp_nosecurity: + case Py_ht_evp_md_nosecurity: digest = PY_EVP_MD_fetch(name, "-fips"); break; } @@ -464,15 +473,17 @@ py_digest_by_name(PyObject *module, const char *name, Py_hash_type py_ht) return digest; } -/* Get digest EVP from object +/* Get digest EVP_MD from object * * * string * * _hashopenssl builtin function * * on error returns NULL with exception set. */ -static PY_EVP_MD* -py_digest_by_digestmod(PyObject *module, PyObject *digestmod, Py_hash_type py_ht) { +static PY_EVP_MD * +get_openssl_evp_md(PyObject *module, PyObject *digestmod, + Py_hash_type hash_type) +{ PyObject *name_obj = NULL; const char *name; @@ -498,13 +509,13 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, Py_hash_type py_ht return NULL; } - return py_digest_by_name(module, name, py_ht); + return get_openssl_evp_md_by_utf8name(module, name, hash_type); } -static EVPobject * -newEVPobject(PyTypeObject *type) +static HASHobject * +_hashlib_HASH_alloc(PyTypeObject *type) { - EVPobject *retval = PyObject_New(EVPobject, type); + HASHobject *retval = PyObject_New(HASHobject, type); if (retval == NULL) { return NULL; } @@ -521,7 +532,7 @@ newEVPobject(PyTypeObject *type) } static int -EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) +_hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len) { unsigned int process; const unsigned char *cp = (const unsigned char *)vp; @@ -543,9 +554,9 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) /* Internal methods for a hash object */ static void -EVP_dealloc(PyObject *op) +_hashlib_HASH_dealloc(PyObject *op) { - EVPobject *self = EVPobject_CAST(op); + HASHobject *self = HASHobject_CAST(op); PyTypeObject *tp = Py_TYPE(self); EVP_MD_CTX_free(self->ctx); PyObject_Free(self); @@ -553,7 +564,7 @@ EVP_dealloc(PyObject *op) } static int -locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) +_hashlib_HASH_copy_locked(HASHobject *self, EVP_MD_CTX *new_ctx_p) { int result; ENTER_HASHLIB(self); @@ -565,21 +576,21 @@ locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) /* External methods for a hash object */ /*[clinic input] -_hashlib.HASH.copy as EVP_copy +_hashlib.HASH.copy Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -EVP_copy_impl(EVPobject *self) -/*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/ +_hashlib_HASH_copy_impl(HASHobject *self) +/*[clinic end generated code: output=2545541af18d53d7 input=814b19202cd08a26]*/ { - EVPobject *newobj; + HASHobject *newobj; - if ((newobj = newEVPobject(Py_TYPE(self))) == NULL) + if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) return NULL; - if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { + if (!_hashlib_HASH_copy_locked(self, newobj->ctx)) { Py_DECREF(newobj); notify_ssl_error_occurred(); return NULL; @@ -588,14 +599,14 @@ EVP_copy_impl(EVPobject *self) } /*[clinic input] -_hashlib.HASH.digest as EVP_digest +_hashlib.HASH.digest Return the digest value as a bytes object. [clinic start generated code]*/ static PyObject * -EVP_digest_impl(EVPobject *self) -/*[clinic end generated code: output=0f6a3a0da46dc12d input=03561809a419bf00]*/ +_hashlib_HASH_digest_impl(HASHobject *self) +/*[clinic end generated code: output=3fc6f9671d712850 input=d8d528d6e50af0de]*/ { unsigned char digest[EVP_MAX_MD_SIZE]; EVP_MD_CTX *temp_ctx; @@ -608,7 +619,7 @@ EVP_digest_impl(EVPobject *self) return NULL; } - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { + if (!_hashlib_HASH_copy_locked(self, temp_ctx)) { goto error; } digest_size = EVP_MD_CTX_size(temp_ctx); @@ -627,14 +638,14 @@ EVP_digest_impl(EVPobject *self) } /*[clinic input] -_hashlib.HASH.hexdigest as EVP_hexdigest +_hashlib.HASH.hexdigest Return the digest value as a string of hexadecimal digits. [clinic start generated code]*/ static PyObject * -EVP_hexdigest_impl(EVPobject *self) -/*[clinic end generated code: output=18e6decbaf197296 input=aff9cf0e4c741a9a]*/ +_hashlib_HASH_hexdigest_impl(HASHobject *self) +/*[clinic end generated code: output=1b8e60d9711e7f4d input=ae7553f78f8372d8]*/ { unsigned char digest[EVP_MAX_MD_SIZE]; EVP_MD_CTX *temp_ctx; @@ -647,7 +658,7 @@ EVP_hexdigest_impl(EVPobject *self) } /* Get the raw (binary) digest value */ - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { + if (!_hashlib_HASH_copy_locked(self, temp_ctx)) { goto error; } digest_size = EVP_MD_CTX_size(temp_ctx); @@ -666,7 +677,7 @@ EVP_hexdigest_impl(EVPobject *self) } /*[clinic input] -_hashlib.HASH.update as EVP_update +_hashlib.HASH.update obj: object / @@ -675,8 +686,8 @@ Update this hash object's state with the provided string. [clinic start generated code]*/ static PyObject * -EVP_update_impl(EVPobject *self, PyObject *obj) -/*[clinic end generated code: output=d56f91c68348f95f input=9b30ec848f015501]*/ +_hashlib_HASH_update_impl(HASHobject *self, PyObject *obj) +/*[clinic end generated code: output=62ad989754946b86 input=aa1ce20e3f92ceb6]*/ { int result; Py_buffer view; @@ -689,11 +700,11 @@ EVP_update_impl(EVPobject *self, PyObject *obj) if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS PyMutex_Lock(&self->mutex); - result = EVP_hash(self, view.buf, view.len); + result = _hashlib_HASH_hash(self, view.buf, view.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { - result = EVP_hash(self, view.buf, view.len); + result = _hashlib_HASH_hash(self, view.buf, view.len); } PyBuffer_Release(&view); @@ -703,54 +714,54 @@ EVP_update_impl(EVPobject *self, PyObject *obj) Py_RETURN_NONE; } -static PyMethodDef EVP_methods[] = { - EVP_UPDATE_METHODDEF - EVP_DIGEST_METHODDEF - EVP_HEXDIGEST_METHODDEF - EVP_COPY_METHODDEF +static PyMethodDef HASH_methods[] = { + _HASHLIB_HASH_COPY_METHODDEF + _HASHLIB_HASH_DIGEST_METHODDEF + _HASHLIB_HASH_HEXDIGEST_METHODDEF + _HASHLIB_HASH_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; static PyObject * -EVP_get_block_size(PyObject *op, void *Py_UNUSED(closure)) +_hashlib_HASH_get_blocksize(PyObject *op, void *Py_UNUSED(closure)) { - EVPobject *self = EVPobject_CAST(op); + HASHobject *self = HASHobject_CAST(op); long block_size = EVP_MD_CTX_block_size(self->ctx); return PyLong_FromLong(block_size); } static PyObject * -EVP_get_digest_size(PyObject *op, void *Py_UNUSED(closure)) +_hashlib_HASH_get_digestsize(PyObject *op, void *Py_UNUSED(closure)) { - EVPobject *self = EVPobject_CAST(op); + HASHobject *self = HASHobject_CAST(op); long size = EVP_MD_CTX_size(self->ctx); return PyLong_FromLong(size); } static PyObject * -EVP_get_name(PyObject *op, void *Py_UNUSED(closure)) +_hashlib_HASH_get_name(PyObject *op, void *Py_UNUSED(closure)) { - EVPobject *self = EVPobject_CAST(op); + HASHobject *self = HASHobject_CAST(op); const EVP_MD *md = EVP_MD_CTX_md(self->ctx); if (md == NULL) { notify_ssl_error_occurred(); return NULL; } - return py_digest_name(md); + return get_openssl_evp_md_name(md); } -static PyGetSetDef EVP_getseters[] = { - {"digest_size", EVP_get_digest_size, NULL, NULL, NULL}, - {"block_size", EVP_get_block_size, NULL, NULL, NULL}, - {"name", EVP_get_name, NULL, NULL, PyDoc_STR("algorithm name.")}, +static PyGetSetDef HASH_getsets[] = { + {"digest_size", _hashlib_HASH_get_digestsize, NULL, NULL, NULL}, + {"block_size", _hashlib_HASH_get_blocksize, NULL, NULL, NULL}, + {"name", _hashlib_HASH_get_name, NULL, NULL, PyDoc_STR("algorithm name.")}, {NULL} /* Sentinel */ }; static PyObject * -EVP_repr(PyObject *self) +_hashlib_HASH_repr(PyObject *self) { - PyObject *name = EVP_get_name(self, NULL); + PyObject *name = _hashlib_HASH_get_name(self, NULL); if (name == NULL) { return NULL; } @@ -760,7 +771,7 @@ EVP_repr(PyObject *self) return repr; } -PyDoc_STRVAR(hashtype_doc, +PyDoc_STRVAR(HASHobject_type_doc, "HASH(name, string=b\'\')\n" "--\n" "\n" @@ -778,27 +789,31 @@ PyDoc_STRVAR(hashtype_doc, "name -- the hash algorithm being used by this object\n" "digest_size -- number of bytes in this hashes output"); -static PyType_Slot EVPtype_slots[] = { - {Py_tp_dealloc, EVP_dealloc}, - {Py_tp_repr, EVP_repr}, - {Py_tp_doc, (char *)hashtype_doc}, - {Py_tp_methods, EVP_methods}, - {Py_tp_getset, EVP_getseters}, +static PyType_Slot HASHobject_type_slots[] = { + {Py_tp_dealloc, _hashlib_HASH_dealloc}, + {Py_tp_repr, _hashlib_HASH_repr}, + {Py_tp_doc, (char *)HASHobject_type_doc}, + {Py_tp_methods, HASH_methods}, + {Py_tp_getset, HASH_getsets}, {0, 0}, }; -static PyType_Spec EVPtype_spec = { - "_hashlib.HASH", /*tp_name*/ - sizeof(EVPobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, - EVPtype_slots +static PyType_Spec HASHobject_type_spec = { + .name = "_hashlib.HASH", + .basicsize = sizeof(HASHobject), + .flags = ( + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION + | Py_TPFLAGS_IMMUTABLETYPE + ), + .slots = HASHobject_type_slots }; #ifdef PY_OPENSSL_HAS_SHAKE /*[clinic input] -_hashlib.HASHXOF.digest as EVPXOF_digest +_hashlib.HASHXOF.digest length: Py_ssize_t @@ -806,8 +821,8 @@ Return the digest value as a bytes object. [clinic start generated code]*/ static PyObject * -EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length) -/*[clinic end generated code: output=ef9320c23280efad input=816a6537cea3d1db]*/ +_hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length) +/*[clinic end generated code: output=a9ecbb885b3054a5 input=3eb034ce03c55b21]*/ { EVP_MD_CTX *temp_ctx; PyObject *retval = PyBytes_FromStringAndSize(NULL, length); @@ -823,7 +838,7 @@ EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length) return NULL; } - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { + if (!_hashlib_HASH_copy_locked(self, temp_ctx)) { goto error; } if (!EVP_DigestFinalXOF(temp_ctx, @@ -844,7 +859,7 @@ EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length) } /*[clinic input] -_hashlib.HASHXOF.hexdigest as EVPXOF_hexdigest +_hashlib.HASHXOF.hexdigest length: Py_ssize_t @@ -852,8 +867,8 @@ Return the digest value as a string of hexadecimal digits. [clinic start generated code]*/ static PyObject * -EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length) -/*[clinic end generated code: output=eb3e6ee7788bf5b2 input=5f9d6a8f269e34df]*/ +_hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length) +/*[clinic end generated code: output=1fe78f301ff7e28f input=0e58f7238adb7ab8]*/ { unsigned char *digest; EVP_MD_CTX *temp_ctx; @@ -873,7 +888,7 @@ EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length) } /* Get the raw (binary) digest value */ - if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { + if (!_hashlib_HASH_copy_locked(self, temp_ctx)) { goto error; } if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) { @@ -893,25 +908,26 @@ EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length) return NULL; } -static PyMethodDef EVPXOF_methods[] = { - EVPXOF_DIGEST_METHODDEF - EVPXOF_HEXDIGEST_METHODDEF +static PyMethodDef HASHXOFobject_methods[] = { + _HASHLIB_HASHXOF_DIGEST_METHODDEF + _HASHLIB_HASHXOF_HEXDIGEST_METHODDEF {NULL, NULL} /* sentinel */ }; static PyObject * -EVPXOF_get_digest_size(PyObject *Py_UNUSED(self), void *Py_UNUSED(closure)) +_hashlib_HASHXOF_digest_size(PyObject *Py_UNUSED(self), + void *Py_UNUSED(closure)) { return PyLong_FromLong(0); } -static PyGetSetDef EVPXOF_getseters[] = { - {"digest_size", EVPXOF_get_digest_size, NULL, NULL, NULL}, +static PyGetSetDef HASHXOFobject_getsets[] = { + {"digest_size", _hashlib_HASHXOF_digest_size, NULL, NULL, NULL}, {NULL} /* Sentinel */ }; -PyDoc_STRVAR(hashxoftype_doc, +PyDoc_STRVAR(HASHXOFobject_type_doc, "HASHXOF(name, string=b\'\')\n" "--\n" "\n" @@ -929,51 +945,55 @@ PyDoc_STRVAR(hashxoftype_doc, "name -- the hash algorithm being used by this object\n" "digest_size -- number of bytes in this hashes output"); -static PyType_Slot EVPXOFtype_slots[] = { - {Py_tp_doc, (char *)hashxoftype_doc}, - {Py_tp_methods, EVPXOF_methods}, - {Py_tp_getset, EVPXOF_getseters}, +static PyType_Slot HASHXOFobject_type_slots[] = { + {Py_tp_doc, (char *)HASHXOFobject_type_doc}, + {Py_tp_methods, HASHXOFobject_methods}, + {Py_tp_getset, HASHXOFobject_getsets}, {0, 0}, }; -static PyType_Spec EVPXOFtype_spec = { - "_hashlib.HASHXOF", /*tp_name*/ - sizeof(EVPobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, - EVPXOFtype_slots +static PyType_Spec HASHXOFobject_type_spec = { + .name = "_hashlib.HASHXOF", + .basicsize = sizeof(HASHXOFobject), + .flags = ( + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION + | Py_TPFLAGS_IMMUTABLETYPE + ), + .slots = HASHXOFobject_type_slots }; #endif -static PyObject* -py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, - int usedforsecurity) +static PyObject * +_hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, + int usedforsecurity) { Py_buffer view = { 0 }; PY_EVP_MD *digest = NULL; PyTypeObject *type; - EVPobject *self = NULL; + HASHobject *self = NULL; if (data_obj != NULL) { GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); } - digest = py_digest_by_name( - module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity + digest = get_openssl_evp_md_by_utf8name( + module, digestname, usedforsecurity ? Py_ht_evp_md : Py_ht_evp_md_nosecurity ); if (digest == NULL) { goto exit; } if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) { - type = get_hashlib_state(module)->EVPXOFtype; + type = get_hashlib_state(module)->HASHXOF_type; } else { - type = get_hashlib_state(module)->EVPtype; + type = get_hashlib_state(module)->HASH_type; } - self = newEVPobject(type); + self = _hashlib_HASH_alloc(type); if (self == NULL) { goto exit; } @@ -998,10 +1018,10 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, /* We do not initialize self->lock here as this is the constructor * where it is not yet possible to have concurrent access. */ Py_BEGIN_ALLOW_THREADS - result = EVP_hash(self, view.buf, view.len); + result = _hashlib_HASH_hash(self, view.buf, view.len); Py_END_ALLOW_THREADS } else { - result = EVP_hash(self, view.buf, view.len); + result = _hashlib_HASH_hash(self, view.buf, view.len); } if (result == -1) { assert(PyErr_Occurred()); @@ -1025,9 +1045,9 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, /* The module-level function: new() */ /*[clinic input] -_hashlib.new as EVP_new +_hashlib.new as _hashlib_HASH_new - name as name_obj: object + name: str string as data_obj: object(c_default="NULL") = b'' * usedforsecurity: bool = True @@ -1041,16 +1061,11 @@ The MD5 and SHA1 algorithms are always supported. [clinic start generated code]*/ static PyObject * -EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj, - int usedforsecurity) -/*[clinic end generated code: output=ddd5053f92dffe90 input=c24554d0337be1b0]*/ +_hashlib_HASH_new_impl(PyObject *module, const char *name, + PyObject *data_obj, int usedforsecurity) +/*[clinic end generated code: output=30c6e7b9a5a4dce3 input=28848db5ccd0a9b5]*/ { - char *name; - if (!PyArg_Parse(name_obj, "s", &name)) { - PyErr_SetString(PyExc_TypeError, "name must be a string"); - return NULL; - } - return py_evp_fromname(module, name, data_obj, usedforsecurity); + return _hashlib_HASH(module, name, data_obj, usedforsecurity); } @@ -1070,7 +1085,7 @@ _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/ { - return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_md5, data_obj, usedforsecurity); } @@ -1090,7 +1105,7 @@ _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/ { - return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha1, data_obj, usedforsecurity); } @@ -1110,7 +1125,7 @@ _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/ { - return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha224, data_obj, usedforsecurity); } @@ -1130,7 +1145,7 @@ _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=1f874a34870f0a68 input=549fad9d2930d4c5]*/ { - return py_evp_fromname(module, Py_hash_sha256, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha256, data_obj, usedforsecurity); } @@ -1150,7 +1165,7 @@ _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=58529eff9ca457b2 input=48601a6e3bf14ad7]*/ { - return py_evp_fromname(module, Py_hash_sha384, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha384, data_obj, usedforsecurity); } @@ -1170,7 +1185,7 @@ _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=2c744c9e4a40d5f6 input=c5c46a2a817aa98f]*/ { - return py_evp_fromname(module, Py_hash_sha512, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha512, data_obj, usedforsecurity); } @@ -1192,7 +1207,7 @@ _hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/ { - return py_evp_fromname(module, Py_hash_sha3_224, data_obj, usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha3_224, data_obj, usedforsecurity); } /*[clinic input] @@ -1211,7 +1226,7 @@ _hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/ { - return py_evp_fromname(module, Py_hash_sha3_256, data_obj , usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha3_256, data_obj, usedforsecurity); } /*[clinic input] @@ -1230,7 +1245,7 @@ _hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/ { - return py_evp_fromname(module, Py_hash_sha3_384, data_obj , usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha3_384, data_obj, usedforsecurity); } /*[clinic input] @@ -1249,7 +1264,7 @@ _hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/ { - return py_evp_fromname(module, Py_hash_sha3_512, data_obj , usedforsecurity); + return _hashlib_HASH(module, Py_hash_sha3_512, data_obj, usedforsecurity); } #endif /* PY_OPENSSL_HAS_SHA3 */ @@ -1270,7 +1285,7 @@ _hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=bc49cdd8ada1fa97 input=6c9d67440eb33ec8]*/ { - return py_evp_fromname(module, Py_hash_shake_128, data_obj , usedforsecurity); + return _hashlib_HASH(module, Py_hash_shake_128, data_obj, usedforsecurity); } /*[clinic input] @@ -1289,7 +1304,7 @@ _hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=358d213be8852df7 input=479cbe9fefd4a9f8]*/ { - return py_evp_fromname(module, Py_hash_shake_256, data_obj , usedforsecurity); + return _hashlib_HASH(module, Py_hash_shake_256, data_obj, usedforsecurity); } #endif /* PY_OPENSSL_HAS_SHAKE */ @@ -1316,7 +1331,7 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, long dklen; int retval; - PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2); + PY_EVP_MD *digest = get_openssl_evp_md_by_utf8name(module, hash_name, Py_ht_pbkdf2); if (digest == NULL) { goto end; } @@ -1518,7 +1533,7 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, return NULL; } - evp = py_digest_by_digestmod(module, digest, Py_ht_mac); + evp = get_openssl_evp_md(module, digest, Py_ht_mac); if (evp == NULL) { return NULL; } @@ -1587,7 +1602,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, return NULL; } - digest = py_digest_by_digestmod(module, digestmod, Py_ht_mac); + digest = get_openssl_evp_md(module, digestmod, Py_ht_mac); if (digest == NULL) { return NULL; } @@ -1744,7 +1759,7 @@ _hmac_repr(PyObject *op) if (md == NULL) { return NULL; } - PyObject *digest_name = py_digest_name(md); + PyObject *digest_name = get_openssl_evp_md_name(md); if (digest_name == NULL) { return NULL; } @@ -1864,7 +1879,7 @@ _hashlib_hmac_get_name(PyObject *op, void *Py_UNUSED(closure)) if (md == NULL) { return NULL; } - PyObject *digest_name = py_digest_name(md); + PyObject *digest_name = get_openssl_evp_md_name(md); if (digest_name == NULL) { return NULL; } @@ -1946,7 +1961,7 @@ _openssl_hash_name_mapper(const EVP_MD *md, const char *from, return; } - py_name = py_digest_name(md); + py_name = get_openssl_evp_md_name(md); if (py_name == NULL) { state->error = 1; } else { @@ -2138,7 +2153,7 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) /* List of functions exported by this module */ static struct PyMethodDef EVP_functions[] = { - EVP_NEW_METHODDEF + _HASHLIB_HASH_NEW_METHODDEF PBKDF2_HMAC_METHODDEF _HASHLIB_SCRYPT_METHODDEF _HASHLIB_GET_FIPS_MODE_METHODDEF @@ -2167,10 +2182,10 @@ static int hashlib_traverse(PyObject *m, visitproc visit, void *arg) { _hashlibstate *state = get_hashlib_state(m); - Py_VISIT(state->EVPtype); + Py_VISIT(state->HASH_type); Py_VISIT(state->HMACtype); #ifdef PY_OPENSSL_HAS_SHAKE - Py_VISIT(state->EVPXOFtype); + Py_VISIT(state->HASHXOF_type); #endif Py_VISIT(state->constructs); Py_VISIT(state->unsupported_digestmod_error); @@ -2181,10 +2196,10 @@ static int hashlib_clear(PyObject *m) { _hashlibstate *state = get_hashlib_state(m); - Py_CLEAR(state->EVPtype); + Py_CLEAR(state->HASH_type); Py_CLEAR(state->HMACtype); #ifdef PY_OPENSSL_HAS_SHAKE - Py_CLEAR(state->EVPXOFtype); + Py_CLEAR(state->HASHXOF_type); #endif Py_CLEAR(state->constructs); Py_CLEAR(state->unsupported_digestmod_error); @@ -2218,37 +2233,37 @@ hashlib_init_hashtable(PyObject *module) } static int -hashlib_init_evptype(PyObject *module) +hashlib_init_HASH_type(PyObject *module) { _hashlibstate *state = get_hashlib_state(module); - state->EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec); - if (state->EVPtype == NULL) { + state->HASH_type = (PyTypeObject *)PyType_FromSpec(&HASHobject_type_spec); + if (state->HASH_type == NULL) { return -1; } - if (PyModule_AddType(module, state->EVPtype) < 0) { + if (PyModule_AddType(module, state->HASH_type) < 0) { return -1; } return 0; } static int -hashlib_init_evpxoftype(PyObject *module) +hashlib_init_HASHXOF_type(PyObject *module) { #ifdef PY_OPENSSL_HAS_SHAKE _hashlibstate *state = get_hashlib_state(module); - if (state->EVPtype == NULL) { + if (state->HASH_type == NULL) { return -1; } - state->EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases( - &EVPXOFtype_spec, (PyObject *)state->EVPtype + state->HASHXOF_type = (PyTypeObject *)PyType_FromSpecWithBases( + &HASHXOFobject_type_spec, (PyObject *)state->HASH_type ); - if (state->EVPXOFtype == NULL) { + if (state->HASHXOF_type == NULL) { return -1; } - if (PyModule_AddType(module, state->EVPXOFtype) < 0) { + if (PyModule_AddType(module, state->HASHXOF_type) < 0) { return -1; } #endif @@ -2345,8 +2360,8 @@ hashlib_constants(PyObject *module) static PyModuleDef_Slot hashlib_slots[] = { {Py_mod_exec, hashlib_init_hashtable}, - {Py_mod_exec, hashlib_init_evptype}, - {Py_mod_exec, hashlib_init_evpxoftype}, + {Py_mod_exec, hashlib_init_HASH_type}, + {Py_mod_exec, hashlib_init_HASHXOF_type}, {Py_mod_exec, hashlib_init_hmactype}, {Py_mod_exec, hashlib_md_meth_names}, {Py_mod_exec, hashlib_init_constructors}, diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 59ab46ca3f0978..cbe65cb82f3aae 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -10,98 +10,98 @@ preserve #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() -PyDoc_STRVAR(EVP_copy__doc__, +PyDoc_STRVAR(_hashlib_HASH_copy__doc__, "copy($self, /)\n" "--\n" "\n" "Return a copy of the hash object."); -#define EVP_COPY_METHODDEF \ - {"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__}, +#define _HASHLIB_HASH_COPY_METHODDEF \ + {"copy", (PyCFunction)_hashlib_HASH_copy, METH_NOARGS, _hashlib_HASH_copy__doc__}, static PyObject * -EVP_copy_impl(EVPobject *self); +_hashlib_HASH_copy_impl(HASHobject *self); static PyObject * -EVP_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) +_hashlib_HASH_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return EVP_copy_impl((EVPobject *)self); + return _hashlib_HASH_copy_impl((HASHobject *)self); } -PyDoc_STRVAR(EVP_digest__doc__, +PyDoc_STRVAR(_hashlib_HASH_digest__doc__, "digest($self, /)\n" "--\n" "\n" "Return the digest value as a bytes object."); -#define EVP_DIGEST_METHODDEF \ - {"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__}, +#define _HASHLIB_HASH_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_hashlib_HASH_digest, METH_NOARGS, _hashlib_HASH_digest__doc__}, static PyObject * -EVP_digest_impl(EVPobject *self); +_hashlib_HASH_digest_impl(HASHobject *self); static PyObject * -EVP_digest(PyObject *self, PyObject *Py_UNUSED(ignored)) +_hashlib_HASH_digest(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return EVP_digest_impl((EVPobject *)self); + return _hashlib_HASH_digest_impl((HASHobject *)self); } -PyDoc_STRVAR(EVP_hexdigest__doc__, +PyDoc_STRVAR(_hashlib_HASH_hexdigest__doc__, "hexdigest($self, /)\n" "--\n" "\n" "Return the digest value as a string of hexadecimal digits."); -#define EVP_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__}, +#define _HASHLIB_HASH_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_hashlib_HASH_hexdigest, METH_NOARGS, _hashlib_HASH_hexdigest__doc__}, static PyObject * -EVP_hexdigest_impl(EVPobject *self); +_hashlib_HASH_hexdigest_impl(HASHobject *self); static PyObject * -EVP_hexdigest(PyObject *self, PyObject *Py_UNUSED(ignored)) +_hashlib_HASH_hexdigest(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return EVP_hexdigest_impl((EVPobject *)self); + return _hashlib_HASH_hexdigest_impl((HASHobject *)self); } -PyDoc_STRVAR(EVP_update__doc__, +PyDoc_STRVAR(_hashlib_HASH_update__doc__, "update($self, obj, /)\n" "--\n" "\n" "Update this hash object\'s state with the provided string."); -#define EVP_UPDATE_METHODDEF \ - {"update", (PyCFunction)EVP_update, METH_O, EVP_update__doc__}, +#define _HASHLIB_HASH_UPDATE_METHODDEF \ + {"update", (PyCFunction)_hashlib_HASH_update, METH_O, _hashlib_HASH_update__doc__}, static PyObject * -EVP_update_impl(EVPobject *self, PyObject *obj); +_hashlib_HASH_update_impl(HASHobject *self, PyObject *obj); static PyObject * -EVP_update(PyObject *self, PyObject *obj) +_hashlib_HASH_update(PyObject *self, PyObject *obj) { PyObject *return_value = NULL; - return_value = EVP_update_impl((EVPobject *)self, obj); + return_value = _hashlib_HASH_update_impl((HASHobject *)self, obj); return return_value; } #if defined(PY_OPENSSL_HAS_SHAKE) -PyDoc_STRVAR(EVPXOF_digest__doc__, +PyDoc_STRVAR(_hashlib_HASHXOF_digest__doc__, "digest($self, /, length)\n" "--\n" "\n" "Return the digest value as a bytes object."); -#define EVPXOF_DIGEST_METHODDEF \ - {"digest", _PyCFunction_CAST(EVPXOF_digest), METH_FASTCALL|METH_KEYWORDS, EVPXOF_digest__doc__}, +#define _HASHLIB_HASHXOF_DIGEST_METHODDEF \ + {"digest", _PyCFunction_CAST(_hashlib_HASHXOF_digest), METH_FASTCALL|METH_KEYWORDS, _hashlib_HASHXOF_digest__doc__}, static PyObject * -EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length); +_hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length); static PyObject * -EVPXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_hashlib_HASHXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -151,7 +151,7 @@ EVPXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } length = ival; } - return_value = EVPXOF_digest_impl((EVPobject *)self, length); + return_value = _hashlib_HASHXOF_digest_impl((HASHXOFobject *)self, length); exit: return return_value; @@ -161,20 +161,20 @@ EVPXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject #if defined(PY_OPENSSL_HAS_SHAKE) -PyDoc_STRVAR(EVPXOF_hexdigest__doc__, +PyDoc_STRVAR(_hashlib_HASHXOF_hexdigest__doc__, "hexdigest($self, /, length)\n" "--\n" "\n" "Return the digest value as a string of hexadecimal digits."); -#define EVPXOF_HEXDIGEST_METHODDEF \ - {"hexdigest", _PyCFunction_CAST(EVPXOF_hexdigest), METH_FASTCALL|METH_KEYWORDS, EVPXOF_hexdigest__doc__}, +#define _HASHLIB_HASHXOF_HEXDIGEST_METHODDEF \ + {"hexdigest", _PyCFunction_CAST(_hashlib_HASHXOF_hexdigest), METH_FASTCALL|METH_KEYWORDS, _hashlib_HASHXOF_hexdigest__doc__}, static PyObject * -EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length); +_hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length); static PyObject * -EVPXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_hashlib_HASHXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -224,7 +224,7 @@ EVPXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } length = ival; } - return_value = EVPXOF_hexdigest_impl((EVPobject *)self, length); + return_value = _hashlib_HASHXOF_hexdigest_impl((HASHXOFobject *)self, length); exit: return return_value; @@ -232,7 +232,7 @@ EVPXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje #endif /* defined(PY_OPENSSL_HAS_SHAKE) */ -PyDoc_STRVAR(EVP_new__doc__, +PyDoc_STRVAR(_hashlib_HASH_new__doc__, "new($module, /, name, string=b\'\', *, usedforsecurity=True)\n" "--\n" "\n" @@ -243,15 +243,15 @@ PyDoc_STRVAR(EVP_new__doc__, "\n" "The MD5 and SHA1 algorithms are always supported."); -#define EVP_NEW_METHODDEF \ - {"new", _PyCFunction_CAST(EVP_new), METH_FASTCALL|METH_KEYWORDS, EVP_new__doc__}, +#define _HASHLIB_HASH_NEW_METHODDEF \ + {"new", _PyCFunction_CAST(_hashlib_HASH_new), METH_FASTCALL|METH_KEYWORDS, _hashlib_HASH_new__doc__}, static PyObject * -EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj, - int usedforsecurity); +_hashlib_HASH_new_impl(PyObject *module, const char *name, + PyObject *data_obj, int usedforsecurity); static PyObject * -EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_hashlib_HASH_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) @@ -283,7 +283,7 @@ EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *name_obj; + const char *name; PyObject *data_obj = NULL; int usedforsecurity = 1; @@ -292,7 +292,19 @@ EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn if (!args) { goto exit; } - name_obj = args[0]; + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("new", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } if (!noptargs) { goto skip_optional_pos; } @@ -311,7 +323,7 @@ EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn goto exit; } skip_optional_kwonly: - return_value = EVP_new_impl(module, name_obj, data_obj, usedforsecurity); + return_value = _hashlib_HASH_new_impl(module, name, data_obj, usedforsecurity); exit: return return_value; @@ -1836,13 +1848,13 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg return return_value; } -#ifndef EVPXOF_DIGEST_METHODDEF - #define EVPXOF_DIGEST_METHODDEF -#endif /* !defined(EVPXOF_DIGEST_METHODDEF) */ +#ifndef _HASHLIB_HASHXOF_DIGEST_METHODDEF + #define _HASHLIB_HASHXOF_DIGEST_METHODDEF +#endif /* !defined(_HASHLIB_HASHXOF_DIGEST_METHODDEF) */ -#ifndef EVPXOF_HEXDIGEST_METHODDEF - #define EVPXOF_HEXDIGEST_METHODDEF -#endif /* !defined(EVPXOF_HEXDIGEST_METHODDEF) */ +#ifndef _HASHLIB_HASHXOF_HEXDIGEST_METHODDEF + #define _HASHLIB_HASHXOF_HEXDIGEST_METHODDEF +#endif /* !defined(_HASHLIB_HASHXOF_HEXDIGEST_METHODDEF) */ #ifndef _HASHLIB_OPENSSL_SHA3_224_METHODDEF #define _HASHLIB_OPENSSL_SHA3_224_METHODDEF @@ -1871,4 +1883,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=2c78822e38be64a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8a65f61e4546540e input=a9049054013a1b77]*/ From 9d535ac110b13816a561491d380f4f464c750b24 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, 24 May 2025 12:14:28 +0200 Subject: [PATCH 04/15] PEP-7 --- Modules/_hashopenssl.c | 158 +++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 71 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 44d639ee7f89c8..c962849a4ac65e 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -13,8 +13,8 @@ /* Don't warn about deprecated functions, */ #ifndef OPENSSL_API_COMPAT - // 0x10101000L == 1.1.1, 30000 == 3.0.0 - #define OPENSSL_API_COMPAT 0x10101000L +// 0x10101000L == 1.1.1, 30000 == 3.0.0 +# define OPENSSL_API_COMPAT 0x10101000L #endif #define OPENSSL_NO_DEPRECATED 1 @@ -189,17 +189,20 @@ static const py_hashentry_t py_hashes[] = { }; static Py_uhash_t -py_hashentry_t_hash_name(const void *key) { +py_hashentry_t_hash_name(const void *key) +{ return Py_HashBuffer(key, strlen((const char *)key)); } static int -py_hashentry_t_compare_name(const void *key1, const void *key2) { +py_hashentry_t_compare_name(const void *key1, const void *key2) +{ return strcmp((const char *)key1, (const char *)key2) == 0; } static void -py_hashentry_t_destroy_value(void *entry) { +py_hashentry_t_destroy_value(void *entry) +{ py_hashentry_t *h = (py_hashentry_t *)entry; if (--(h->refcnt) == 0) { if (h->evp_md != NULL) { @@ -215,7 +218,8 @@ py_hashentry_t_destroy_value(void *entry) { } static _Py_hashtable_t * -py_hashentry_table_new(void) { +py_hashentry_table_new(void) +{ _Py_hashtable_t *ht = _Py_hashtable_new_full( py_hashentry_t_hash_name, py_hashentry_t_compare_name, @@ -234,14 +238,14 @@ py_hashentry_table_new(void) { } memcpy(entry, h, sizeof(py_hashentry_t)); - if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) { + if (_Py_hashtable_set(ht, (const void *)entry->py_name, (void *)entry) < 0) { PyMem_Free(entry); goto error; } entry->refcnt = 1; if (h->py_alias != NULL) { - if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) { + if (_Py_hashtable_set(ht, (const void *)entry->py_alias, (void *)entry) < 0) { PyMem_Free(entry); goto error; } @@ -250,7 +254,7 @@ py_hashentry_table_new(void) { } return ht; - error: +error: _Py_hashtable_destroy(ht); return NULL; } @@ -269,7 +273,7 @@ typedef struct { _Py_hashtable_t *hashtable; } _hashlibstate; -static inline _hashlibstate* +static inline _hashlibstate * get_hashlib_state(PyObject *module) { void *state = PyModule_GetState(module); @@ -412,38 +416,36 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, PY_EVP_MD *digest = NULL; PY_EVP_MD *other_digest = NULL; _hashlibstate *state = get_hashlib_state(module); - py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get( - state->hashtable, (const void*)name - ); + py_hashentry_t *entry = _Py_hashtable_get(state->hashtable, name); if (entry != NULL) { switch (hash_type) { - case Py_ht_evp_md: - case Py_ht_mac: - case Py_ht_pbkdf2: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); - if (digest == NULL) { - digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); + case Py_ht_evp_md: + case Py_ht_mac: + case Py_ht_pbkdf2: + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); + if (digest == NULL) { + digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); #ifdef Py_GIL_DISABLED - // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_md, (void *)digest); + // exchange just in case another thread did same thing at same time + other_digest = _Py_atomic_exchange_ptr(&entry->evp, (void *)digest); #else - entry->evp_md = digest; + entry->evp_md = digest; #endif - } - break; - case Py_ht_evp_md_nosecurity: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); - if (digest == NULL) { - digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); + } + break; + case Py_ht_evp_md_nosecurity: + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); + if (digest == NULL) { + digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); #ifdef Py_GIL_DISABLED - // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_md_nosecurity, (void *)digest); + // exchange just in case another thread did same thing at same time + other_digest = _Py_atomic_exchange_ptr(&entry->evp_nosecurity, (void *)digest); #else - entry->evp_md_nosecurity = digest; + entry->evp_md_nosecurity = digest; #endif - } - break; + } + break; } // if another thread same thing at same time make sure we got same ptr assert(other_digest == NULL || other_digest == digest); @@ -452,17 +454,18 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, PY_EVP_MD_up_ref(digest); } } - } else { + } + else { // Fall back for looking up an unindexed OpenSSL specific name. switch (hash_type) { - case Py_ht_evp_md: - case Py_ht_mac: - case Py_ht_pbkdf2: - digest = PY_EVP_MD_fetch(name, NULL); - break; - case Py_ht_evp_md_nosecurity: - digest = PY_EVP_MD_fetch(name, "-fips"); - break; + case Py_ht_evp_md: + case Py_ht_mac: + case Py_ht_pbkdf2: + digest = PY_EVP_MD_fetch(name, NULL); + break; + case Py_ht_evp_md_nosecurity: + digest = PY_EVP_MD_fetch(name, "-fips"); + break; } } if (digest == NULL) { @@ -489,7 +492,8 @@ get_openssl_evp_md(PyObject *module, PyObject *digestmod, if (PyUnicode_Check(digestmod)) { name_obj = digestmod; - } else { + } + else { _hashlibstate *state = get_hashlib_state(module); // borrowed ref name_obj = PyDict_GetItemWithError(state->constructs, digestmod); @@ -537,11 +541,13 @@ _hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len) unsigned int process; const unsigned char *cp = (const unsigned char *)vp; while (0 < len) { - if (len > (Py_ssize_t)MUNCH_SIZE) + if (len > (Py_ssize_t)MUNCH_SIZE) { process = MUNCH_SIZE; - else + } + else { process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); - if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { + } + if (!EVP_DigestUpdate(self->ctx, (const void *)cp, process)) { notify_ssl_error_occurred(); return -1; } @@ -587,8 +593,9 @@ _hashlib_HASH_copy_impl(HASHobject *self) { HASHobject *newobj; - if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) + if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) { return NULL; + } if (!_hashlib_HASH_copy_locked(self, newobj->ctx)) { Py_DECREF(newobj); @@ -703,14 +710,16 @@ _hashlib_HASH_update_impl(HASHobject *self, PyObject *obj) result = _hashlib_HASH_hash(self, view.buf, view.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS - } else { + } + else { result = _hashlib_HASH_hash(self, view.buf, view.len); } PyBuffer_Release(&view); - if (result == -1) + if (result == -1) { return NULL; + } Py_RETURN_NONE; } @@ -754,7 +763,7 @@ static PyGetSetDef HASH_getsets[] = { {"digest_size", _hashlib_HASH_get_digestsize, NULL, NULL, NULL}, {"block_size", _hashlib_HASH_get_blocksize, NULL, NULL, NULL}, {"name", _hashlib_HASH_get_name, NULL, NULL, PyDoc_STR("algorithm name.")}, - {NULL} /* Sentinel */ + {NULL} /* sentinel */ }; @@ -842,7 +851,7 @@ _hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length) goto error; } if (!EVP_DigestFinalXOF(temp_ctx, - (unsigned char*)PyBytes_AS_STRING(retval), + (unsigned char *)PyBytes_AS_STRING(retval), length)) { goto error; @@ -874,7 +883,7 @@ _hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length) EVP_MD_CTX *temp_ctx; PyObject *retval; - digest = (unsigned char*)PyMem_Malloc(length); + digest = (unsigned char *)PyMem_Malloc(length); if (digest == NULL) { PyErr_NoMemory(); return NULL; @@ -924,7 +933,7 @@ _hashlib_HASHXOF_digest_size(PyObject *Py_UNUSED(self), static PyGetSetDef HASHXOFobject_getsets[] = { {"digest_size", _hashlib_HASHXOF_digest_size, NULL, NULL, NULL}, - {NULL} /* Sentinel */ + {NULL} /* sentinel */ }; PyDoc_STRVAR(HASHXOFobject_type_doc, @@ -971,7 +980,7 @@ static PyObject * _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, int usedforsecurity) { - Py_buffer view = { 0 }; + Py_buffer view = {0}; PY_EVP_MD *digest = NULL; PyTypeObject *type; HASHobject *self = NULL; @@ -989,7 +998,8 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) { type = get_hashlib_state(module)->HASHXOF_type; - } else { + } + else { type = get_hashlib_state(module)->HASH_type; } @@ -1020,7 +1030,8 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, Py_BEGIN_ALLOW_THREADS result = _hashlib_HASH_hash(self, view.buf, view.len); Py_END_ALLOW_THREADS - } else { + } + else { result = _hashlib_HASH_hash(self, view.buf, view.len); } if (result == -1) { @@ -1361,7 +1372,8 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, if (dklen_obj == Py_None) { dklen = EVP_MD_size(digest); - } else { + } + else { dklen = PyLong_AsLong(dklen_obj); if ((dklen == -1) && PyErr_Occurred()) { goto end; @@ -1473,7 +1485,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, raise_ssl_error(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem."); return NULL; - } + } key_obj = PyBytes_FromStringAndSize(NULL, dklen); if (key_obj == NULL) { @@ -1483,7 +1495,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, Py_BEGIN_ALLOW_THREADS retval = EVP_PBE_scrypt( - (const char*)password->buf, (size_t)password->len, + (const char *)password->buf, (size_t)password->len, (const unsigned char *)salt->buf, (size_t)salt->len, n, r, p, maxmem, (unsigned char *)key, (size_t)dklen @@ -1552,13 +1564,13 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, notify_ssl_error_occurred(); return NULL; } - return PyBytes_FromStringAndSize((const char*)md, md_len); + return PyBytes_FromStringAndSize((const char *)md, md_len); } /* OpenSSL-based HMAC implementation */ -static int _hmac_update(HMACobject*, PyObject*); +static int _hmac_update(HMACobject *, PyObject *); static const EVP_MD * _hashlib_hmac_get_md(HMACobject *self) @@ -1639,7 +1651,9 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, return (PyObject *)self; error: - if (ctx) HMAC_CTX_free(ctx); + if (ctx) { + HMAC_CTX_free(ctx); + } Py_XDECREF(self); return NULL; } @@ -1690,7 +1704,8 @@ _hmac_update(HMACobject *self, PyObject *obj) (size_t)view.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS - } else { + } + else { r = HMAC_Update(self->ctx, (const unsigned char *)view.buf, (size_t)view.len); @@ -1900,7 +1915,7 @@ static PyGetSetDef HMAC_getset[] = { {"digest_size", _hashlib_hmac_get_digest_size, NULL, NULL, NULL}, {"block_size", _hashlib_hmac_get_block_size, NULL, NULL, NULL}, {"name", _hashlib_hmac_get_name, NULL, NULL, NULL}, - {NULL} /* Sentinel */ + {NULL} /* sentinel */ }; @@ -1964,7 +1979,8 @@ _openssl_hash_name_mapper(const EVP_MD *md, const char *from, py_name = get_openssl_evp_md_name(md); if (py_name == NULL) { state->error = 1; - } else { + } + else { if (PySet_Add(state->set, py_name) != 0) { state->error = 1; } @@ -2041,7 +2057,7 @@ _hashlib_get_fips_mode_impl(PyObject *module) static int _tscmp(const unsigned char *a, const unsigned char *b, - Py_ssize_t len_a, Py_ssize_t len_b) + Py_ssize_t len_a, Py_ssize_t len_b) { /* loop count depends on length of b. Might leak very little timing * information if sizes are different. @@ -2090,7 +2106,7 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) int rc; /* ASCII unicode string */ - if(PyUnicode_Check(a) && PyUnicode_Check(b)) { + if (PyUnicode_Check(a) && PyUnicode_Check(b)) { if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) { PyErr_SetString(PyExc_TypeError, "comparing strings with non-ASCII characters is " @@ -2138,8 +2154,8 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) return NULL; } - rc = _tscmp((const unsigned char*)view_a.buf, - (const unsigned char*)view_b.buf, + rc = _tscmp((const unsigned char *)view_a.buf, + (const unsigned char *)view_b.buf, view_a.len, view_b.len); @@ -2172,7 +2188,7 @@ static struct PyMethodDef EVP_functions[] = { _HASHLIB_OPENSSL_SHA3_512_METHODDEF _HASHLIB_OPENSSL_SHAKE_128_METHODDEF _HASHLIB_OPENSSL_SHAKE_256_METHODDEF - {NULL, NULL} /* Sentinel */ + {NULL, NULL} /* sentinel */ }; @@ -2314,7 +2330,7 @@ hashlib_init_constructors(PyObject *module) if (name_obj == NULL) { return -1; } - func = PyObject_GetAttrString(module, fdef->ml_name); + func = PyObject_GetAttrString(module, fdef->ml_name); if (func == NULL) { Py_DECREF(name_obj); return -1; From 4f792482e33af846853625f1e1e21da7a014aad3 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, 24 May 2025 12:28:44 +0200 Subject: [PATCH 05/15] Revert "PEP-7" This reverts commit 9d535ac110b13816a561491d380f4f464c750b24. --- Modules/_hashopenssl.c | 158 ++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 87 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index c962849a4ac65e..44d639ee7f89c8 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -13,8 +13,8 @@ /* Don't warn about deprecated functions, */ #ifndef OPENSSL_API_COMPAT -// 0x10101000L == 1.1.1, 30000 == 3.0.0 -# define OPENSSL_API_COMPAT 0x10101000L + // 0x10101000L == 1.1.1, 30000 == 3.0.0 + #define OPENSSL_API_COMPAT 0x10101000L #endif #define OPENSSL_NO_DEPRECATED 1 @@ -189,20 +189,17 @@ static const py_hashentry_t py_hashes[] = { }; static Py_uhash_t -py_hashentry_t_hash_name(const void *key) -{ +py_hashentry_t_hash_name(const void *key) { return Py_HashBuffer(key, strlen((const char *)key)); } static int -py_hashentry_t_compare_name(const void *key1, const void *key2) -{ +py_hashentry_t_compare_name(const void *key1, const void *key2) { return strcmp((const char *)key1, (const char *)key2) == 0; } static void -py_hashentry_t_destroy_value(void *entry) -{ +py_hashentry_t_destroy_value(void *entry) { py_hashentry_t *h = (py_hashentry_t *)entry; if (--(h->refcnt) == 0) { if (h->evp_md != NULL) { @@ -218,8 +215,7 @@ py_hashentry_t_destroy_value(void *entry) } static _Py_hashtable_t * -py_hashentry_table_new(void) -{ +py_hashentry_table_new(void) { _Py_hashtable_t *ht = _Py_hashtable_new_full( py_hashentry_t_hash_name, py_hashentry_t_compare_name, @@ -238,14 +234,14 @@ py_hashentry_table_new(void) } memcpy(entry, h, sizeof(py_hashentry_t)); - if (_Py_hashtable_set(ht, (const void *)entry->py_name, (void *)entry) < 0) { + if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) { PyMem_Free(entry); goto error; } entry->refcnt = 1; if (h->py_alias != NULL) { - if (_Py_hashtable_set(ht, (const void *)entry->py_alias, (void *)entry) < 0) { + if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) { PyMem_Free(entry); goto error; } @@ -254,7 +250,7 @@ py_hashentry_table_new(void) } return ht; -error: + error: _Py_hashtable_destroy(ht); return NULL; } @@ -273,7 +269,7 @@ typedef struct { _Py_hashtable_t *hashtable; } _hashlibstate; -static inline _hashlibstate * +static inline _hashlibstate* get_hashlib_state(PyObject *module) { void *state = PyModule_GetState(module); @@ -416,36 +412,38 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, PY_EVP_MD *digest = NULL; PY_EVP_MD *other_digest = NULL; _hashlibstate *state = get_hashlib_state(module); - py_hashentry_t *entry = _Py_hashtable_get(state->hashtable, name); + py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get( + state->hashtable, (const void*)name + ); if (entry != NULL) { switch (hash_type) { - case Py_ht_evp_md: - case Py_ht_mac: - case Py_ht_pbkdf2: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); - if (digest == NULL) { - digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); + case Py_ht_evp_md: + case Py_ht_mac: + case Py_ht_pbkdf2: + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); + if (digest == NULL) { + digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); #ifdef Py_GIL_DISABLED - // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp, (void *)digest); + // exchange just in case another thread did same thing at same time + other_digest = _Py_atomic_exchange_ptr(&entry->evp_md, (void *)digest); #else - entry->evp_md = digest; + entry->evp_md = digest; #endif - } - break; - case Py_ht_evp_md_nosecurity: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); - if (digest == NULL) { - digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); + } + break; + case Py_ht_evp_md_nosecurity: + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); + if (digest == NULL) { + digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); #ifdef Py_GIL_DISABLED - // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_nosecurity, (void *)digest); + // exchange just in case another thread did same thing at same time + other_digest = _Py_atomic_exchange_ptr(&entry->evp_md_nosecurity, (void *)digest); #else - entry->evp_md_nosecurity = digest; + entry->evp_md_nosecurity = digest; #endif - } - break; + } + break; } // if another thread same thing at same time make sure we got same ptr assert(other_digest == NULL || other_digest == digest); @@ -454,18 +452,17 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, PY_EVP_MD_up_ref(digest); } } - } - else { + } else { // Fall back for looking up an unindexed OpenSSL specific name. switch (hash_type) { - case Py_ht_evp_md: - case Py_ht_mac: - case Py_ht_pbkdf2: - digest = PY_EVP_MD_fetch(name, NULL); - break; - case Py_ht_evp_md_nosecurity: - digest = PY_EVP_MD_fetch(name, "-fips"); - break; + case Py_ht_evp_md: + case Py_ht_mac: + case Py_ht_pbkdf2: + digest = PY_EVP_MD_fetch(name, NULL); + break; + case Py_ht_evp_md_nosecurity: + digest = PY_EVP_MD_fetch(name, "-fips"); + break; } } if (digest == NULL) { @@ -492,8 +489,7 @@ get_openssl_evp_md(PyObject *module, PyObject *digestmod, if (PyUnicode_Check(digestmod)) { name_obj = digestmod; - } - else { + } else { _hashlibstate *state = get_hashlib_state(module); // borrowed ref name_obj = PyDict_GetItemWithError(state->constructs, digestmod); @@ -541,13 +537,11 @@ _hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len) unsigned int process; const unsigned char *cp = (const unsigned char *)vp; while (0 < len) { - if (len > (Py_ssize_t)MUNCH_SIZE) { + if (len > (Py_ssize_t)MUNCH_SIZE) process = MUNCH_SIZE; - } - else { + else process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); - } - if (!EVP_DigestUpdate(self->ctx, (const void *)cp, process)) { + if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { notify_ssl_error_occurred(); return -1; } @@ -593,9 +587,8 @@ _hashlib_HASH_copy_impl(HASHobject *self) { HASHobject *newobj; - if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) { + if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) return NULL; - } if (!_hashlib_HASH_copy_locked(self, newobj->ctx)) { Py_DECREF(newobj); @@ -710,16 +703,14 @@ _hashlib_HASH_update_impl(HASHobject *self, PyObject *obj) result = _hashlib_HASH_hash(self, view.buf, view.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS - } - else { + } else { result = _hashlib_HASH_hash(self, view.buf, view.len); } PyBuffer_Release(&view); - if (result == -1) { + if (result == -1) return NULL; - } Py_RETURN_NONE; } @@ -763,7 +754,7 @@ static PyGetSetDef HASH_getsets[] = { {"digest_size", _hashlib_HASH_get_digestsize, NULL, NULL, NULL}, {"block_size", _hashlib_HASH_get_blocksize, NULL, NULL, NULL}, {"name", _hashlib_HASH_get_name, NULL, NULL, PyDoc_STR("algorithm name.")}, - {NULL} /* sentinel */ + {NULL} /* Sentinel */ }; @@ -851,7 +842,7 @@ _hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length) goto error; } if (!EVP_DigestFinalXOF(temp_ctx, - (unsigned char *)PyBytes_AS_STRING(retval), + (unsigned char*)PyBytes_AS_STRING(retval), length)) { goto error; @@ -883,7 +874,7 @@ _hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length) EVP_MD_CTX *temp_ctx; PyObject *retval; - digest = (unsigned char *)PyMem_Malloc(length); + digest = (unsigned char*)PyMem_Malloc(length); if (digest == NULL) { PyErr_NoMemory(); return NULL; @@ -933,7 +924,7 @@ _hashlib_HASHXOF_digest_size(PyObject *Py_UNUSED(self), static PyGetSetDef HASHXOFobject_getsets[] = { {"digest_size", _hashlib_HASHXOF_digest_size, NULL, NULL, NULL}, - {NULL} /* sentinel */ + {NULL} /* Sentinel */ }; PyDoc_STRVAR(HASHXOFobject_type_doc, @@ -980,7 +971,7 @@ static PyObject * _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, int usedforsecurity) { - Py_buffer view = {0}; + Py_buffer view = { 0 }; PY_EVP_MD *digest = NULL; PyTypeObject *type; HASHobject *self = NULL; @@ -998,8 +989,7 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) { type = get_hashlib_state(module)->HASHXOF_type; - } - else { + } else { type = get_hashlib_state(module)->HASH_type; } @@ -1030,8 +1020,7 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, Py_BEGIN_ALLOW_THREADS result = _hashlib_HASH_hash(self, view.buf, view.len); Py_END_ALLOW_THREADS - } - else { + } else { result = _hashlib_HASH_hash(self, view.buf, view.len); } if (result == -1) { @@ -1372,8 +1361,7 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, if (dklen_obj == Py_None) { dklen = EVP_MD_size(digest); - } - else { + } else { dklen = PyLong_AsLong(dklen_obj); if ((dklen == -1) && PyErr_Occurred()) { goto end; @@ -1485,7 +1473,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, raise_ssl_error(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem."); return NULL; - } + } key_obj = PyBytes_FromStringAndSize(NULL, dklen); if (key_obj == NULL) { @@ -1495,7 +1483,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, Py_BEGIN_ALLOW_THREADS retval = EVP_PBE_scrypt( - (const char *)password->buf, (size_t)password->len, + (const char*)password->buf, (size_t)password->len, (const unsigned char *)salt->buf, (size_t)salt->len, n, r, p, maxmem, (unsigned char *)key, (size_t)dklen @@ -1564,13 +1552,13 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, notify_ssl_error_occurred(); return NULL; } - return PyBytes_FromStringAndSize((const char *)md, md_len); + return PyBytes_FromStringAndSize((const char*)md, md_len); } /* OpenSSL-based HMAC implementation */ -static int _hmac_update(HMACobject *, PyObject *); +static int _hmac_update(HMACobject*, PyObject*); static const EVP_MD * _hashlib_hmac_get_md(HMACobject *self) @@ -1651,9 +1639,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, return (PyObject *)self; error: - if (ctx) { - HMAC_CTX_free(ctx); - } + if (ctx) HMAC_CTX_free(ctx); Py_XDECREF(self); return NULL; } @@ -1704,8 +1690,7 @@ _hmac_update(HMACobject *self, PyObject *obj) (size_t)view.len); PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS - } - else { + } else { r = HMAC_Update(self->ctx, (const unsigned char *)view.buf, (size_t)view.len); @@ -1915,7 +1900,7 @@ static PyGetSetDef HMAC_getset[] = { {"digest_size", _hashlib_hmac_get_digest_size, NULL, NULL, NULL}, {"block_size", _hashlib_hmac_get_block_size, NULL, NULL, NULL}, {"name", _hashlib_hmac_get_name, NULL, NULL, NULL}, - {NULL} /* sentinel */ + {NULL} /* Sentinel */ }; @@ -1979,8 +1964,7 @@ _openssl_hash_name_mapper(const EVP_MD *md, const char *from, py_name = get_openssl_evp_md_name(md); if (py_name == NULL) { state->error = 1; - } - else { + } else { if (PySet_Add(state->set, py_name) != 0) { state->error = 1; } @@ -2057,7 +2041,7 @@ _hashlib_get_fips_mode_impl(PyObject *module) static int _tscmp(const unsigned char *a, const unsigned char *b, - Py_ssize_t len_a, Py_ssize_t len_b) + Py_ssize_t len_a, Py_ssize_t len_b) { /* loop count depends on length of b. Might leak very little timing * information if sizes are different. @@ -2106,7 +2090,7 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) int rc; /* ASCII unicode string */ - if (PyUnicode_Check(a) && PyUnicode_Check(b)) { + if(PyUnicode_Check(a) && PyUnicode_Check(b)) { if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) { PyErr_SetString(PyExc_TypeError, "comparing strings with non-ASCII characters is " @@ -2154,8 +2138,8 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) return NULL; } - rc = _tscmp((const unsigned char *)view_a.buf, - (const unsigned char *)view_b.buf, + rc = _tscmp((const unsigned char*)view_a.buf, + (const unsigned char*)view_b.buf, view_a.len, view_b.len); @@ -2188,7 +2172,7 @@ static struct PyMethodDef EVP_functions[] = { _HASHLIB_OPENSSL_SHA3_512_METHODDEF _HASHLIB_OPENSSL_SHAKE_128_METHODDEF _HASHLIB_OPENSSL_SHAKE_256_METHODDEF - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* Sentinel */ }; @@ -2330,7 +2314,7 @@ hashlib_init_constructors(PyObject *module) if (name_obj == NULL) { return -1; } - func = PyObject_GetAttrString(module, fdef->ml_name); + func = PyObject_GetAttrString(module, fdef->ml_name); if (func == NULL) { Py_DECREF(name_obj); return -1; From 7dc81492a417bb349e711e7d8086da30b2c96c5d 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, 24 May 2025 12:31:19 +0200 Subject: [PATCH 06/15] do not distinguish HASHXOF from HASH at struct level --- Modules/_hashopenssl.c | 15 +++++++-------- Modules/clinic/_hashopenssl.c.h | 10 +++++----- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 44d639ee7f89c8..65c5a6aac3db05 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -285,7 +285,6 @@ typedef struct { PyMutex mutex; /* OpenSSL context lock */ } HASHobject; -#define HASHXOFobject HASHobject #define HASHobject_CAST(op) ((HASHobject *)(op)) typedef struct { @@ -302,10 +301,10 @@ typedef struct { /*[clinic input] module _hashlib class _hashlib.HASH "HASHobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPtype" -class _hashlib.HASHXOF "HASHXOFobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype" +class _hashlib.HASHXOF "HASHobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype" class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))->HMACtype" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=466d7751ac96b4b1]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4f6b8873ed13d1ff]*/ /* LCOV_EXCL_START */ @@ -821,8 +820,8 @@ Return the digest value as a bytes object. [clinic start generated code]*/ static PyObject * -_hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length) -/*[clinic end generated code: output=a9ecbb885b3054a5 input=3eb034ce03c55b21]*/ +_hashlib_HASHXOF_digest_impl(HASHobject *self, Py_ssize_t length) +/*[clinic end generated code: output=dcb09335dd2fe908 input=3eb034ce03c55b21]*/ { EVP_MD_CTX *temp_ctx; PyObject *retval = PyBytes_FromStringAndSize(NULL, length); @@ -867,8 +866,8 @@ Return the digest value as a string of hexadecimal digits. [clinic start generated code]*/ static PyObject * -_hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length) -/*[clinic end generated code: output=1fe78f301ff7e28f input=0e58f7238adb7ab8]*/ +_hashlib_HASHXOF_hexdigest_impl(HASHobject *self, Py_ssize_t length) +/*[clinic end generated code: output=519431cafa014f39 input=0e58f7238adb7ab8]*/ { unsigned char *digest; EVP_MD_CTX *temp_ctx; @@ -954,7 +953,7 @@ static PyType_Slot HASHXOFobject_type_slots[] = { static PyType_Spec HASHXOFobject_type_spec = { .name = "_hashlib.HASHXOF", - .basicsize = sizeof(HASHXOFobject), + .basicsize = sizeof(HASHobject), .flags = ( Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index cbe65cb82f3aae..b2f6b25a235e68 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -98,7 +98,7 @@ PyDoc_STRVAR(_hashlib_HASHXOF_digest__doc__, {"digest", _PyCFunction_CAST(_hashlib_HASHXOF_digest), METH_FASTCALL|METH_KEYWORDS, _hashlib_HASHXOF_digest__doc__}, static PyObject * -_hashlib_HASHXOF_digest_impl(HASHXOFobject *self, Py_ssize_t length); +_hashlib_HASHXOF_digest_impl(HASHobject *self, Py_ssize_t length); static PyObject * _hashlib_HASHXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -151,7 +151,7 @@ _hashlib_HASHXOF_digest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, } length = ival; } - return_value = _hashlib_HASHXOF_digest_impl((HASHXOFobject *)self, length); + return_value = _hashlib_HASHXOF_digest_impl((HASHobject *)self, length); exit: return return_value; @@ -171,7 +171,7 @@ PyDoc_STRVAR(_hashlib_HASHXOF_hexdigest__doc__, {"hexdigest", _PyCFunction_CAST(_hashlib_HASHXOF_hexdigest), METH_FASTCALL|METH_KEYWORDS, _hashlib_HASHXOF_hexdigest__doc__}, static PyObject * -_hashlib_HASHXOF_hexdigest_impl(HASHXOFobject *self, Py_ssize_t length); +_hashlib_HASHXOF_hexdigest_impl(HASHobject *self, Py_ssize_t length); static PyObject * _hashlib_HASHXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -224,7 +224,7 @@ _hashlib_HASHXOF_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t nar } length = ival; } - return_value = _hashlib_HASHXOF_hexdigest_impl((HASHXOFobject *)self, length); + return_value = _hashlib_HASHXOF_hexdigest_impl((HASHobject *)self, length); exit: return return_value; @@ -1883,4 +1883,4 @@ _hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t narg #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=8a65f61e4546540e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dc03b64435166a64 input=a9049054013a1b77]*/ From 978628bf0563d9f6b7e6692eb8d0f1c99ee413f6 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, 24 May 2025 12:32:43 +0200 Subject: [PATCH 07/15] revert HMAC changes --- Modules/_hashopenssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 65c5a6aac3db05..c7156f0c98bbc0 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -289,10 +289,10 @@ typedef struct { typedef struct { PyObject_HEAD - HMAC_CTX *ctx; /* OpenSSL hmac context */ + HMAC_CTX *ctx; /* OpenSSL hmac context */ // Prevents undefined behavior via multiple threads entering the C API. bool use_mutex; - PyMutex mutex; /* HMAC context lock */ + PyMutex mutex; /* HMAC context lock */ } HMACobject; #define HMACobject_CAST(op) ((HMACobject *)(op)) From e207509527982c02baa62bced3d77e1d2775fbdf 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, 24 May 2025 12:33:29 +0200 Subject: [PATCH 08/15] remove incorrect `inline` qualifier --- Modules/_hashopenssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index c7156f0c98bbc0..df3994014f7d73 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -396,7 +396,7 @@ get_openssl_evp_md_utf8name(const EVP_MD *md) return name; } -static inline PyObject * +static PyObject * get_openssl_evp_md_name(const EVP_MD *md) { const char *name = get_openssl_evp_md_utf8name(md); From 6d7c5b63dbe4084caaeea0219c480babc2a14fb6 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, 24 May 2025 12:33:54 +0200 Subject: [PATCH 09/15] revert some renaming --- Modules/_hashopenssl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index df3994014f7d73..be508149f168d1 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -406,7 +406,7 @@ get_openssl_evp_md_name(const EVP_MD *md) /* Get EVP_MD by HID and purpose */ static PY_EVP_MD * get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, - Py_hash_type hash_type) + Py_hash_type py_ht) { PY_EVP_MD *digest = NULL; PY_EVP_MD *other_digest = NULL; @@ -416,7 +416,7 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, ); if (entry != NULL) { - switch (hash_type) { + switch (py_ht) { case Py_ht_evp_md: case Py_ht_mac: case Py_ht_pbkdf2: @@ -453,7 +453,7 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, } } else { // Fall back for looking up an unindexed OpenSSL specific name. - switch (hash_type) { + switch (py_ht) { case Py_ht_evp_md: case Py_ht_mac: case Py_ht_pbkdf2: @@ -481,7 +481,7 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, */ static PY_EVP_MD * get_openssl_evp_md(PyObject *module, PyObject *digestmod, - Py_hash_type hash_type) + Py_hash_type py_ht) { PyObject *name_obj = NULL; const char *name; @@ -508,7 +508,7 @@ get_openssl_evp_md(PyObject *module, PyObject *digestmod, return NULL; } - return get_openssl_evp_md_by_utf8name(module, name, hash_type); + return get_openssl_evp_md_by_utf8name(module, name, py_ht); } static HASHobject * From f0acb930b1c53c8eb2d399a68c49f038349fd73a 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, 24 May 2025 12:34:53 +0200 Subject: [PATCH 10/15] `_hashlib_HASH_alloc` -> `new_hash_object` --- Modules/_hashopenssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index be508149f168d1..4b74366996dd04 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -512,7 +512,7 @@ get_openssl_evp_md(PyObject *module, PyObject *digestmod, } static HASHobject * -_hashlib_HASH_alloc(PyTypeObject *type) +new_hash_object(PyTypeObject *type) { HASHobject *retval = PyObject_New(HASHobject, type); if (retval == NULL) { @@ -586,7 +586,7 @@ _hashlib_HASH_copy_impl(HASHobject *self) { HASHobject *newobj; - if ((newobj = _hashlib_HASH_alloc(Py_TYPE(self))) == NULL) + if ((newobj = new_hash_object(Py_TYPE(self))) == NULL) return NULL; if (!_hashlib_HASH_copy_locked(self, newobj->ctx)) { @@ -992,7 +992,7 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, type = get_hashlib_state(module)->HASH_type; } - self = _hashlib_HASH_alloc(type); + self = new_hash_object(type); if (self == NULL) { goto exit; } From 6d9df04e87d2872df784307979e7feff89b5ae13 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, 24 May 2025 12:36:44 +0200 Subject: [PATCH 11/15] reduce diff --- Modules/_hashopenssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 4b74366996dd04..1beb660c152ec4 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -292,7 +292,7 @@ typedef struct { HMAC_CTX *ctx; /* OpenSSL hmac context */ // Prevents undefined behavior via multiple threads entering the C API. bool use_mutex; - PyMutex mutex; /* HMAC context lock */ + PyMutex mutex; /* HMAC context lock */ } HMACobject; #define HMACobject_CAST(op) ((HMACobject *)(op)) From d409a2c05378d6c6c87683ed465a4630d88ba2c3 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, 24 May 2025 12:37:03 +0200 Subject: [PATCH 12/15] reduce diff --- Modules/_hashopenssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 1beb660c152ec4..6a8273f46c3f3a 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -389,9 +389,8 @@ get_openssl_evp_md_utf8name(const EVP_MD *md) * names for several algorithms. */ name = OBJ_nid2ln(nid); - if (name == NULL) { + if (name == NULL) name = OBJ_nid2sn(nid); - } } return name; } From 4f8d6f16bc8b8190cc14446434099905aaef5a26 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, 24 May 2025 12:37:45 +0200 Subject: [PATCH 13/15] no need to actually change `Py_ht_evp_md` --- Modules/_hashopenssl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 6a8273f46c3f3a..8077b6ef3b2a5f 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -82,10 +82,10 @@ */ typedef enum Py_hash_type { - Py_ht_evp_md, // usedforsecurity=True / default - Py_ht_evp_md_nosecurity, // usedforsecurity=False - Py_ht_mac, // HMAC - Py_ht_pbkdf2, // PKBDF2 + Py_ht_evp, // usedforsecurity=True / default + Py_ht_evp_nosecurity, // usedforsecurity=False + Py_ht_mac, // HMAC + Py_ht_pbkdf2, // PKBDF2 } Py_hash_type; typedef struct { @@ -416,7 +416,7 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, if (entry != NULL) { switch (py_ht) { - case Py_ht_evp_md: + case Py_ht_evp: case Py_ht_mac: case Py_ht_pbkdf2: digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); @@ -430,7 +430,7 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, #endif } break; - case Py_ht_evp_md_nosecurity: + case Py_ht_evp_nosecurity: digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); if (digest == NULL) { digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); @@ -453,12 +453,12 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, } else { // Fall back for looking up an unindexed OpenSSL specific name. switch (py_ht) { - case Py_ht_evp_md: + case Py_ht_evp: case Py_ht_mac: case Py_ht_pbkdf2: digest = PY_EVP_MD_fetch(name, NULL); break; - case Py_ht_evp_md_nosecurity: + case Py_ht_evp_nosecurity: digest = PY_EVP_MD_fetch(name, "-fips"); break; } @@ -979,7 +979,7 @@ _hashlib_HASH(PyObject *module, const char *digestname, PyObject *data_obj, } digest = get_openssl_evp_md_by_utf8name( - module, digestname, usedforsecurity ? Py_ht_evp_md : Py_ht_evp_md_nosecurity + module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity ); if (digest == NULL) { goto exit; From 63bc38c3f94362457b18f8c4dd63b1555c4cf116 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, 24 May 2025 12:39:27 +0200 Subject: [PATCH 14/15] no need to actually change `py_hashentry_t` --- Modules/_hashopenssl.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 8077b6ef3b2a5f..dab0bb9b67fa00 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -94,8 +94,8 @@ typedef struct { const char *ossl_name; int ossl_nid; int refcnt; - PY_EVP_MD *evp_md; - PY_EVP_MD *evp_md_nosecurity; + PY_EVP_MD *evp; + PY_EVP_MD *evp_nosecurity; } py_hashentry_t; // Fundamental to TLS, assumed always present in any libcrypto: @@ -202,13 +202,13 @@ static void py_hashentry_t_destroy_value(void *entry) { py_hashentry_t *h = (py_hashentry_t *)entry; if (--(h->refcnt) == 0) { - if (h->evp_md != NULL) { - PY_EVP_MD_free(h->evp_md); - h->evp_md = NULL; + if (h->evp != NULL) { + PY_EVP_MD_free(h->evp); + h->evp = NULL; } - if (h->evp_md_nosecurity != NULL) { - PY_EVP_MD_free(h->evp_md_nosecurity); - h->evp_md_nosecurity = NULL; + if (h->evp_nosecurity != NULL) { + PY_EVP_MD_free(h->evp_nosecurity); + h->evp_nosecurity = NULL; } PyMem_Free(entry); } @@ -419,26 +419,26 @@ get_openssl_evp_md_by_utf8name(PyObject *module, const char *name, case Py_ht_evp: case Py_ht_mac: case Py_ht_pbkdf2: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md); + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp); if (digest == NULL) { digest = PY_EVP_MD_fetch(entry->ossl_name, NULL); #ifdef Py_GIL_DISABLED // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_md, (void *)digest); + other_digest = _Py_atomic_exchange_ptr(&entry->evp, (void *)digest); #else - entry->evp_md = digest; + entry->evp = digest; #endif } break; case Py_ht_evp_nosecurity: - digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_md_nosecurity); + digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_nosecurity); if (digest == NULL) { digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); #ifdef Py_GIL_DISABLED // exchange just in case another thread did same thing at same time - other_digest = _Py_atomic_exchange_ptr(&entry->evp_md_nosecurity, (void *)digest); + other_digest = _Py_atomic_exchange_ptr(&entry->evp_nosecurity, (void *)digest); #else - entry->evp_md_nosecurity = digest; + entry->evp_nosecurity = digest; #endif } break; From bb8624a70af7c950f1ec902705383c6447d5bae4 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, 26 May 2025 11:02:00 +0200 Subject: [PATCH 15/15] blurb --- .../next/Library/2025-05-26-11-01-54.gh-issue-134531.my1Fzt.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-05-26-11-01-54.gh-issue-134531.my1Fzt.rst diff --git a/Misc/NEWS.d/next/Library/2025-05-26-11-01-54.gh-issue-134531.my1Fzt.rst b/Misc/NEWS.d/next/Library/2025-05-26-11-01-54.gh-issue-134531.my1Fzt.rst new file mode 100644 index 00000000000000..ee5690df5c4193 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-26-11-01-54.gh-issue-134531.my1Fzt.rst @@ -0,0 +1,2 @@ +:mod:`!_hashlib`: Rename internal C functions for :class:`!_hashlib.HASH` +and :class:`!_hashlib.HASHXOF` objects. Patch by Bénédikt Tran.