logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git
commit: 732d09a691b0455f04db8ea11dc8133c0dda5dfb
parent a13fa66f67543d4320b75d4aeb18d9ad7dbae180
Author: Michael Forney <mforney@mforney.org>
Date:   Sun, 16 May 2021 01:12:58 -0700

python: Port _hashlib to BearSSL

Diffstat:

Mpkg/python/gen.lua7++++++-
Mpkg/python/modules.lua2+-
Apkg/python/patch/0001-Add-BearSSL-implementation-of-_hashlib.patch2276+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dpkg/python/patch/0001-Fix-build-with-libressl.patch25-------------------------
Mpkg/python/ver2+-
5 files changed, 2284 insertions(+), 28 deletions(-)

diff --git a/pkg/python/gen.lua b/pkg/python/gen.lua @@ -15,7 +15,12 @@ if modules._ctypes then table.insert(pkg.deps, 'pkg/libffi/headers') table.insert(libs, 'libffi/libffi.a') end -if modules._hashlib or modules._ssl then +if modules._hashlib then + cflags{'-isystem $builddir/pkg/bearssl/include'} + table.insert(pkg.deps, 'pkg/bearssl/headers') + table.insert(libs, 'bearssl/libbearssl.a') +end +if modules._ssl then cflags{'-isystem $builddir/pkg/libressl/include'} table.insert(pkg.deps, 'pkg/libressl/headers') table.insert(libs, { diff --git a/pkg/python/modules.lua b/pkg/python/modules.lua @@ -105,7 +105,7 @@ return { --_ctypes_test={'_ctypes/_ctypes_test.c'}, --_decimal={'_decimal/_decimal.c'}, _ssl={'_ssl.c'}, - _hashlib={'_hashopenssl.c'}, + _hashlib={'_hashbearssl.c'}, --_sha256={'sha256module.c'}, --_sha512={'sha512module.c'}, --_md5={'md5module.c'}, diff --git a/pkg/python/patch/0001-Add-BearSSL-implementation-of-_hashlib.patch b/pkg/python/patch/0001-Add-BearSSL-implementation-of-_hashlib.patch @@ -0,0 +1,2276 @@ +From 40cce685bfce6c2824177f3e550d6ffbd24e08c6 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Sat, 15 May 2021 22:48:13 -0700 +Subject: [PATCH] Add BearSSL implementation of _hashlib + +--- + Modules/_hashbearssl.c | 1136 +++++++++++++++++++++++++++++++ + Modules/clinic/_hashbearssl.c.h | 1113 ++++++++++++++++++++++++++++++ + 2 files changed, 2249 insertions(+) + create mode 100644 Modules/_hashbearssl.c + create mode 100644 Modules/clinic/_hashbearssl.c.h + +diff --git a/Modules/_hashbearssl.c b/Modules/_hashbearssl.c +new file mode 100644 +index 0000000000..98fd1d84dc +--- /dev/null ++++ b/Modules/_hashbearssl.c +@@ -0,0 +1,1136 @@ ++/* Module that wraps all BearSSL hash algorithms */ ++#define PY_SSIZE_T_CLEAN ++#include "Python.h" ++#include "hashlib.h" ++#include "pystrhex.h" ++ ++#include <bearssl.h> ++ ++static PyModuleDef _hashlibmodule; ++static PyTypeObject Hash_Type; ++static PyTypeObject SHAKE_Type; ++static PyTypeObject HMAC_Type; ++ ++typedef struct { ++ PyObject_HEAD ++ br_hash_compat_context ctx; ++ PyThread_type_lock lock; ++} Hash; ++ ++typedef struct { ++ PyObject_HEAD ++ br_hmac_context ctx; ++ br_hmac_key_context key; ++ PyThread_type_lock lock; ++} HMAC; ++ ++typedef struct { ++ PyObject_HEAD ++ br_shake_context ctx; ++ int bits; ++ PyThread_type_lock lock; ++} SHAKE; ++ ++#include "clinic/_hashbearssl.c.h" ++/*[clinic input] ++module _hashlib ++class _hashlib.Hash "Hash *" "Hash_Type" ++class _hashlib.HMAC "HMAC *" "HMAC_Type" ++class _hashlib.SHAKE "SHAKE *" "SHAKE_Type" ++[clinic start generated code]*/ ++/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a269412ec77c79a]*/ ++ ++/* NULL .tp_new doesn't block __new__ */ ++static PyObject * ++_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) ++{ ++ PyErr_Format(PyExc_TypeError, ++ "cannot create '%.100s' instances", _PyType_Name(type)); ++ return NULL; ++} ++ ++static const br_hash_class * ++py_hash_by_name(const char *name) ++{ ++ if (strcmp(name, "md5") == 0) ++ return &br_md5_vtable; ++ else if (strcmp(name, "sha1") == 0) ++ return &br_sha1_vtable; ++ else if (strcmp(name, "sha224") == 0) ++ return &br_sha224_vtable; ++ else if (strcmp(name, "sha256") == 0) ++ return &br_sha256_vtable; ++ else if (strcmp(name, "sha384") == 0) ++ return &br_sha384_vtable; ++ else if (strcmp(name, "sha512") == 0) ++ return &br_sha512_vtable; ++ return NULL; ++} ++ ++PyDoc_STRVAR(Hash_doc, ++"Hash(name, string=b\'\')\n" ++"--\n" ++"\n" ++"A hash is an object used to calculate a checksum of a string of information.\n" ++"\n" ++"Methods:\n" ++"\n" ++"update() -- updates the current digest with an additional string\n" ++"digest() -- return the current digest value\n" ++"hexdigest() -- return the current digest as a string of hexadecimal digits\n" ++"copy() -- return a copy of the current hash object\n" ++"\n" ++"Attributes:\n" ++"\n" ++"name -- the hash algorithm being used by this object\n" ++"digest_size -- number of bytes in this hashes output"); ++ ++static void ++Hash_dealloc(Hash *self) ++{ ++ if (self->lock) ++ PyThread_free_lock(self->lock); ++ PyObject_Del(self); ++} ++ ++/*[clinic input] ++_hashlib.Hash.update as Hash_update ++ ++ data: Py_buffer ++ / ++ ++Update this hash object's state with the provided string. ++[clinic start generated code]*/ ++ ++static PyObject * ++Hash_update_impl(Hash *self, Py_buffer *data) ++/*[clinic end generated code: output=eed11f7503e289a3 input=0547d16ba3981abf]*/ ++{ ++ if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE) ++ self->lock = PyThread_allocate_lock(); ++ if (self->lock) { ++ Py_BEGIN_ALLOW_THREADS ++ PyThread_acquire_lock(self->lock, 1); ++ self->ctx.vtable->update(&self->ctx.vtable, data->buf, data->len); ++ PyThread_release_lock(self->lock); ++ Py_END_ALLOW_THREADS ++ } else { ++ self->ctx.vtable->update(&self->ctx.vtable, data->buf, data->len); ++ } ++ Py_RETURN_NONE; ++} ++ ++/*[clinic input] ++_hashlib.Hash.digest as Hash_digest ++ ++Return the digest value as a bytes object. ++[clinic start generated code]*/ ++ ++static PyObject * ++Hash_digest_impl(Hash *self) ++/*[clinic end generated code: output=b3eafdc9f37cf341 input=6d4afcd832edc55a]*/ ++{ ++ char digest[64]; ++ Py_ssize_t digest_size; ++ ++ ENTER_HASHLIB(self) ++ self->ctx.vtable->out(&self->ctx.vtable, digest); ++ LEAVE_HASHLIB(self) ++ digest_size = (self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; ++ ++ return PyBytes_FromStringAndSize(digest, digest_size); ++} ++ ++/*[clinic input] ++_hashlib.Hash.hexdigest as Hash_hexdigest ++ ++Return the digest value as a string of hexadecimal digits. ++[clinic start generated code]*/ ++ ++static PyObject * ++Hash_hexdigest_impl(Hash *self) ++/*[clinic end generated code: output=eff810494302910a input=6b224236fad6ff65]*/ ++{ ++ char digest[64]; ++ Py_ssize_t digest_size; ++ ++ ENTER_HASHLIB(self) ++ self->ctx.vtable->out(&self->ctx.vtable, digest); ++ LEAVE_HASHLIB(self) ++ digest_size = (self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; ++ ++ return _Py_strhex(digest, digest_size); ++} ++ ++/*[clinic input] ++_hashlib.Hash.copy as Hash_copy ++ ++Return a copy of the hash object. ++[clinic start generated code]*/ ++ ++static PyObject * ++Hash_copy_impl(Hash *self) ++/*[clinic end generated code: output=e97863340f55061b input=b830c9d949d08256]*/ ++{ ++ Hash *newobj; ++ ++ newobj = PyObject_New(Hash, &Hash_Type); ++ if (!newobj) ++ return NULL; ++ newobj->lock = NULL; ++ ENTER_HASHLIB(self) ++ newobj->ctx = self->ctx; ++ LEAVE_HASHLIB(self) ++ ++ return (PyObject *)newobj; ++} ++ ++static PyMethodDef Hash_methods[] = { ++ HASH_UPDATE_METHODDEF ++ HASH_DIGEST_METHODDEF ++ HASH_HEXDIGEST_METHODDEF ++ HASH_COPY_METHODDEF ++ {0} ++}; ++ ++static PyObject * ++Hash_get_digest_size(Hash *self, void *closure) ++{ ++ long digest_size; ++ ++ digest_size = self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK; ++ return PyLong_FromLong(digest_size); ++} ++ ++static PyObject * ++Hash_get_block_size(Hash *self, void *closure) ++{ ++ long block_size; ++ ++ block_size = 1 << (self->ctx.vtable->desc >> BR_HASHDESC_LBLEN_OFF & BR_HASHDESC_LBLEN_MASK); ++ return PyLong_FromLong(block_size); ++} ++ ++static PyObject * ++Hash_get_name(Hash *self, void *closure) ++{ ++ const char *name = NULL; ++ ++ switch (self->ctx.vtable->desc >> BR_HASHDESC_ID_OFF & BR_HASHDESC_ID_MASK) { ++ case br_md5_ID: name = "md5"; break; ++ case br_sha1_ID: name = "sha1"; break; ++ case br_sha224_ID: name = "sha224"; break; ++ case br_sha256_ID: name = "sha256"; break; ++ case br_sha384_ID: name = "sha384"; break; ++ case br_sha512_ID: name = "sha512"; break; ++ } ++ ++ return PyUnicode_FromString(name); ++} ++ ++static PyGetSetDef Hash_getset[] = { ++ {"digest_size", (getter)Hash_get_digest_size, NULL, NULL, NULL}, ++ {"block_size", (getter)Hash_get_block_size, NULL, NULL, NULL}, ++ {"name", (getter)Hash_get_name, NULL, NULL, NULL}, ++ {0} ++}; ++ ++static PyTypeObject Hash_Type = { ++ PyVarObject_HEAD_INIT(NULL, 0) ++ .tp_name = "_hashlib.Hash", ++ .tp_dealloc = (destructor)Hash_dealloc, ++ .tp_doc = Hash_doc, ++ .tp_basicsize = sizeof(Hash), ++ .tp_flags = Py_TPFLAGS_DEFAULT, ++ .tp_methods = Hash_methods, ++ .tp_getset = Hash_getset, ++ .tp_new = _disabled_new, ++}; ++ ++PyDoc_STRVAR(SHAKE_doc, ++"SHAKE(name, string=b\'\')\n" ++"--\n" ++"\n" ++"A hash is an object used to calculate a checksum of a string of information.\n" ++"\n" ++"Methods:\n" ++"\n" ++"update() -- updates the current digest with an additional string\n" ++"digest(length) -- return the current digest value\n" ++"hexdigest(length) -- return the current digest as a string of hexadecimal digits\n" ++"copy() -- return a copy of the current hash object\n" ++"\n" ++"Attributes:\n" ++"\n" ++"name -- the hash algorithm being used by this object\n" ++"digest_size -- number of bytes in this hashes output"); ++ ++static void ++SHAKE_dealloc(SHAKE *self) ++{ ++ if (self->lock) ++ PyThread_free_lock(self->lock); ++ PyObject_Del(self); ++} ++ ++/*[clinic input] ++_hashlib.SHAKE.update as SHAKE_update ++ ++ data: Py_buffer ++ / ++ ++Update this hash object's state with the provided string. ++[clinic start generated code]*/ ++ ++static PyObject * ++SHAKE_update_impl(SHAKE *self, Py_buffer *data) ++/*[clinic end generated code: output=b7f5cd67459e2fb3 input=87a80642380b615f]*/ ++{ ++ if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE) ++ self->lock = PyThread_allocate_lock(); ++ if (self->lock) { ++ Py_BEGIN_ALLOW_THREADS ++ PyThread_acquire_lock(self->lock, 1); ++ br_shake_inject(&self->ctx, data->buf, data->len); ++ PyThread_release_lock(self->lock); ++ Py_END_ALLOW_THREADS ++ } else { ++ br_shake_inject(&self->ctx, data->buf, data->len); ++ } ++ Py_RETURN_NONE; ++} ++ ++/*[clinic input] ++_hashlib.SHAKE.digest as SHAKE_digest ++ ++ length: Py_ssize_t ++ ++Return the digest value as a bytes object. ++[clinic start generated code]*/ ++ ++static PyObject * ++SHAKE_digest_impl(SHAKE *self, Py_ssize_t length) ++/*[clinic end generated code: output=4235ee593cba0b23 input=9e31587954f5e87a]*/ ++{ ++ br_shake_context ctx; ++ PyObject *bytes; ++ ++ bytes = PyBytes_FromStringAndSize(NULL, length); ++ if (!bytes) ++ return NULL; ++ ++ ENTER_HASHLIB(self) ++ ctx = self->ctx; ++ LEAVE_HASHLIB(self) ++ br_shake_flip(&ctx); ++ br_shake_produce(&ctx, PyBytes_AS_STRING(bytes), length); ++ ++ return bytes; ++} ++ ++/*[clinic input] ++_hashlib.SHAKE.hexdigest as SHAKE_hexdigest ++ ++ length: Py_ssize_t ++ ++Return the digest value as a string of hexadecimal digits. ++[clinic start generated code]*/ ++ ++static PyObject * ++SHAKE_hexdigest_impl(SHAKE *self, Py_ssize_t length) ++/*[clinic end generated code: output=fd9a7905a89a1509 input=2c43a9638ca1db5e]*/ ++{ ++ br_shake_context ctx; ++ char *bytes; ++ PyObject *str; ++ ++ bytes = PyMem_Malloc(length); ++ if (!bytes) { ++ PyErr_NoMemory(); ++ return NULL; ++ } ++ ++ ENTER_HASHLIB(self) ++ ctx = self->ctx; ++ LEAVE_HASHLIB(self) ++ br_shake_flip(&ctx); ++ br_shake_produce(&ctx, bytes, length); ++ ++ str = _Py_strhex(bytes, length); ++ PyMem_Free(bytes); ++ return str; ++} ++ ++/*[clinic input] ++_hashlib.SHAKE.copy as SHAKE_copy ++ ++Return a copy of the SHAKE object. ++[clinic start generated code]*/ ++ ++static PyObject * ++SHAKE_copy_impl(SHAKE *self) ++/*[clinic end generated code: output=19cff23538f29dc6 input=34c8368c5c9e910c]*/ ++{ ++ SHAKE *newobj; ++ ++ newobj = PyObject_New(SHAKE, &SHAKE_Type); ++ if (!newobj) ++ return NULL; ++ newobj->lock = NULL; ++ ENTER_HASHLIB(self) ++ newobj->ctx = self->ctx; ++ LEAVE_HASHLIB(self) ++ ++ return (PyObject *)newobj; ++} ++ ++static PyMethodDef SHAKE_methods[] = { ++ SHAKE_UPDATE_METHODDEF ++ SHAKE_DIGEST_METHODDEF ++ SHAKE_HEXDIGEST_METHODDEF ++ SHAKE_COPY_METHODDEF ++ {0} ++}; ++ ++static PyObject * ++SHAKE_get_digest_size(SHAKE *self, void *closure) ++{ ++ return PyLong_FromLong(0); ++} ++ ++static PyObject * ++SHAKE_get_block_size(SHAKE *self, void *closure) ++{ ++ return PyLong_FromLong(self->ctx.rate); ++} ++ ++static PyObject * ++SHAKE_get_name(SHAKE *self, void *closure) ++{ ++ const char *name = NULL; ++ ++ switch (self->bits) { ++ case 128: name = "shake_128"; break; ++ case 256: name = "shake_256"; break; ++ } ++ ++ return PyUnicode_FromString(name); ++} ++ ++static PyGetSetDef SHAKE_getset[] = { ++ {"digest_size", (getter)SHAKE_get_digest_size, NULL, NULL, NULL}, ++ {"block_size", (getter)SHAKE_get_block_size, NULL, NULL, NULL}, ++ {"name", (getter)SHAKE_get_name, NULL, NULL, NULL}, ++ {0} ++}; ++ ++static PyTypeObject SHAKE_Type = { ++ PyVarObject_HEAD_INIT(NULL, 0) ++ .tp_name = "_hashlib.SHAKE", ++ .tp_dealloc = (destructor)SHAKE_dealloc, ++ .tp_doc = SHAKE_doc, ++ .tp_basicsize = sizeof(SHAKE), ++ .tp_flags = Py_TPFLAGS_DEFAULT, ++ .tp_methods = SHAKE_methods, ++ .tp_getset = SHAKE_getset, ++ .tp_new = _disabled_new, ++}; ++ ++PyDoc_STRVAR(HMAC_doc, ++"The object used to calculate HMAC of a message.\n\ ++\n\ ++Methods:\n\ ++\n\ ++update() -- updates the current digest with an additional string\n\ ++digest() -- return the current digest value\n\ ++hexdigest() -- return the current digest as a string of hexadecimal digits\n\ ++copy() -- return a copy of the current hash object\n\ ++\n\ ++Attributes:\n\ ++\n\ ++name -- the name, including the hash algorithm used by this object\n\ ++digest_size -- number of bytes in digest() output\n"); ++ ++static void ++HMAC_dealloc(HMAC *self) ++{ ++ if (self->lock) ++ PyThread_free_lock(self->lock); ++ PyObject_Del(self); ++} ++/*[clinic input] ++_hashlib.HMAC.copy as HMAC_copy ++ ++Return a copy of the HMAC object. ++[clinic start generated code]*/ ++ ++static PyObject * ++HMAC_copy_impl(HMAC *self) ++/*[clinic end generated code: output=6a3595133ec708a5 input=c471e903458ee9a7]*/ ++{ ++ HMAC *newobj; ++ ++ newobj = PyObject_New(HMAC, &HMAC_Type); ++ if (!newobj) ++ return NULL; ++ newobj->lock = NULL; ++ ENTER_HASHLIB(self) ++ newobj->ctx = self->ctx; ++ newobj->key = self->key; ++ LEAVE_HASHLIB(self) ++ ++ return (PyObject *)newobj; ++} ++ ++/*[clinic input] ++_hashlib.HMAC.update as HMAC_update ++ ++ data: Py_buffer ++ / ++ ++Update the HMAC object with data. ++[clinic start generated code]*/ ++ ++static PyObject * ++HMAC_update_impl(HMAC *self, Py_buffer *data) ++/*[clinic end generated code: output=d3520ecffa6cc3ab input=827e77e990887267]*/ ++{ ++ if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE) ++ self->lock = PyThread_allocate_lock(); ++ if (self->lock) { ++ Py_BEGIN_ALLOW_THREADS ++ PyThread_acquire_lock(self->lock, 1); ++ br_hmac_update(&self->ctx, data->buf, data->len); ++ PyThread_release_lock(self->lock); ++ Py_END_ALLOW_THREADS ++ } else { ++ br_hmac_update(&self->ctx, data->buf, data->len); ++ } ++ Py_RETURN_NONE; ++} ++ ++/*[clinic input] ++_hashlib.HMAC.digest as HMAC_digest ++ ++Return the digest of the bytes passed to the update() method so far. ++[clinic start generated code]*/ ++ ++static PyObject * ++HMAC_digest_impl(HMAC *self) ++/*[clinic end generated code: output=9853eeca2bdd96df input=d39cb2285b557318]*/ ++{ ++ char digest[64]; ++ Py_ssize_t digest_size; ++ ++ ENTER_HASHLIB(self) ++ digest_size = br_hmac_out(&self->ctx, digest); ++ LEAVE_HASHLIB(self) ++ ++ return PyBytes_FromStringAndSize(digest, digest_size); ++} ++ ++/*[clinic input] ++_hashlib.HMAC.hexdigest as HMAC_hexdigest ++ ++Return hexadecimal digest of the bytes passed to the update() method so far. ++ ++This may be used to exchange the value safely in email or other non-binary ++environments. ++[clinic start generated code]*/ ++ ++static PyObject * ++HMAC_hexdigest_impl(HMAC *self) ++/*[clinic end generated code: output=9bb0c7abb6940bab input=2471f22b8dba7433]*/ ++{ ++ char digest[64]; ++ Py_ssize_t digest_size; ++ ++ ENTER_HASHLIB(self) ++ digest_size = br_hmac_out(&self->ctx, digest); ++ LEAVE_HASHLIB(self) ++ ++ return _Py_strhex(digest, digest_size); ++} ++ ++static PyMethodDef HMAC_methods[] = { ++ HMAC_UPDATE_METHODDEF ++ HMAC_DIGEST_METHODDEF ++ HMAC_HEXDIGEST_METHODDEF ++ HMAC_COPY_METHODDEF ++ {0}, ++}; ++ ++static PyObject * ++HMAC_get_digest_size(HMAC *self, void *closure) ++{ ++ const br_hash_class *hc; ++ long digest_size; ++ ++ hc = br_hmac_get_digest(&self->ctx); ++ digest_size = hc->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK; ++ return PyLong_FromLong(digest_size); ++} ++ ++static PyObject * ++HMAC_get_block_size(HMAC *self, void *closure) ++{ ++ const br_hash_class *hc; ++ long block_size; ++ ++ hc = br_hmac_get_digest(&self->ctx); ++ block_size = 1 << (hc->desc >> BR_HASHDESC_LBLEN_OFF & BR_HASHDESC_LBLEN_MASK); ++ return PyLong_FromLong(block_size); ++} ++ ++static PyObject * ++HMAC_get_name(HMAC *self, void *closure) ++{ ++ const br_hash_class *hc; ++ const char *name = NULL; ++ ++ hc = br_hmac_get_digest(&self->ctx); ++ switch (hc->desc >> BR_HASHDESC_ID_OFF & BR_HASHDESC_ID_MASK) { ++ case br_md5_ID: name = "hmac-md5"; break; ++ case br_sha1_ID: name = "hmac-sha1"; break; ++ case br_sha224_ID: name = "hmac-sha224"; break; ++ case br_sha256_ID: name = "hmac-sha256"; break; ++ case br_sha384_ID: name = "hmac-sha384"; break; ++ case br_sha512_ID: name = "hmac-sha512"; break; ++ } ++ ++ return PyUnicode_FromString(name); ++} ++ ++static PyGetSetDef HMAC_getset[] = { ++ {"digest_size", (getter)HMAC_get_digest_size, NULL, NULL, NULL}, ++ {"block_size", (getter)HMAC_get_block_size, NULL, NULL, NULL}, ++ {"name", (getter)HMAC_get_name, NULL, NULL, NULL}, ++ {0} ++}; ++ ++static PyTypeObject HMAC_Type = { ++ PyVarObject_HEAD_INIT(NULL, 0) ++ .tp_name = "_hashlib.HMAC", ++ .tp_dealloc = (destructor)HMAC_dealloc, ++ .tp_doc = HMAC_doc, ++ .tp_basicsize = sizeof(HMAC), ++ .tp_flags = Py_TPFLAGS_DEFAULT, ++ .tp_methods = HMAC_methods, ++ .tp_getset = HMAC_getset, ++ .tp_new = _disabled_new, ++}; ++ ++static PyObject * ++Hash_new_vtable(PyObject *module, const br_hash_class *hc, ++ Py_buffer *string, int usedforsecurity) ++{ ++ Hash *self; ++ ++ self = PyObject_New(Hash, &Hash_Type); ++ if (!self) ++ return NULL; ++ self->lock = NULL; ++ hc->init(&self->ctx.vtable); ++ ++ if (string->len >= HASHLIB_GIL_MINSIZE) { ++ Py_BEGIN_ALLOW_THREADS ++ hc->update(&self->ctx.vtable, string->buf, string->len); ++ Py_END_ALLOW_THREADS ++ } else { ++ hc->update(&self->ctx.vtable, string->buf, string->len); ++ } ++ ++ return (PyObject *)self; ++} ++ ++static PyObject * ++SHAKE_new(PyObject *module, int bits, Py_buffer *string, int usedforsecurity) ++{ ++ SHAKE *self; ++ ++ self = PyObject_New(SHAKE, &SHAKE_Type); ++ if (!self) ++ return NULL; ++ self->lock = NULL; ++ br_shake_init(&self->ctx, bits); ++ ++ if (string->len >= HASHLIB_GIL_MINSIZE) { ++ Py_BEGIN_ALLOW_THREADS ++ br_shake_inject(&self->ctx, string->buf, string->len); ++ Py_END_ALLOW_THREADS ++ } else { ++ br_shake_inject(&self->ctx, string->buf, string->len); ++ } ++ ++ return (PyObject *)self; ++} ++ ++/*[clinic input] ++_hashlib.new ++ ++ name: str ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Return a new hash object using the named algorithm. ++ ++An optional string argument may be provided and will be ++automatically hashed. ++ ++The MD5 and SHA1 algorithms are always supported. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_new_impl(PyObject *module, const char *name, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=5459beb11946eb8d input=c7e3a9928c6af923]*/ ++{ ++ const br_hash_class *hc = NULL; ++ int shake = 0; ++ ++ hc = py_hash_by_name(name); ++ if (hc) ++ ; ++ else if (strcmp(name, "shake_128") == 0) ++ shake = 128; ++ else if (strcmp(name, "shake_256") == 0) ++ shake = 256; ++ else { ++ PyErr_SetString(PyExc_ValueError, "unsupported hash type"); ++ return NULL; ++ } ++ ++ if (hc) ++ return Hash_new_vtable(module, hc, string, usedforsecurity); ++ if (shake) ++ return SHAKE_new(module, shake, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_md5 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a md5 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_md5_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=bf0df21c3ecd9d85 input=75e59cc38a292e51]*/ ++{ ++ return Hash_new_vtable(module, &br_md5_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_sha1 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a sha1 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_sha1_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=9c468cf3cfdd2e57 input=0f8ad0fa5d988be8]*/ ++{ ++ return Hash_new_vtable(module, &br_sha1_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_sha224 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a sha224 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_sha224_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=9b3fea17aacc8dfe input=21aacab0e6949431]*/ ++{ ++ return Hash_new_vtable(module, &br_sha224_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_sha256 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a sha256 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_sha256_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=2c0585ccc6dfa22a input=81dd291675e0f6c9]*/ ++{ ++ return Hash_new_vtable(module, &br_sha256_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_sha384 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a sha384 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_sha384_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=196d8d7558cfd155 input=eed0b0128dd67969]*/ ++{ ++ return Hash_new_vtable(module, &br_sha384_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_sha512 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a sha512 hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_sha512_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=7349b37b20ff6f75 input=da1228b585897043]*/ ++{ ++ return Hash_new_vtable(module, &br_sha512_vtable, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_shake_128 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a shake-128 variable hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_shake_128_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=e51cc0e4bded887e input=fb6dce24fc91d53d]*/ ++{ ++ return SHAKE_new(module, 128, string, usedforsecurity); ++} ++ ++/*[clinic input] ++_hashlib.openssl_shake_256 ++ ++ string: Py_buffer = None ++ * ++ usedforsecurity: bool = True ++ ++Returns a shake-256 variable hash object; optionally initialized with a string. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_openssl_shake_256_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity) ++/*[clinic end generated code: output=983a76ff0796751b input=9eb2a133d11e34dc]*/ ++{ ++ return SHAKE_new(module, 256, string, usedforsecurity); ++} ++ ++static int ++_tscmp(const unsigned char *a, const unsigned char *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. ++ */ ++ Py_ssize_t length = len_b; ++ unsigned result = 0; ++ size_t i; ++ ++ if (len_a != length) { ++ a = b; ++ result = 1; ++ } ++ ++ for (i = 0; i < length; i++) ++ result |= (unsigned)a[i] ^ (unsigned)b[i]; ++ ++ return ~(result | -result) >> CHAR_BIT * sizeof(result) - 1; ++} ++ ++/*[clinic input] ++_hashlib.compare_digest ++ ++ a: object ++ b: object ++ / ++ ++Return 'a == b'. ++ ++This function uses an approach designed to prevent ++timing analysis, making it appropriate for cryptography. ++ ++a and b must both be of the same type: either str (ASCII only), ++or any bytes-like object. ++ ++Note: If a and b are of different lengths, or if an error occurs, ++a timing attack could theoretically reveal information about the ++types and lengths of a and b--but not their values. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) ++/*[clinic end generated code: output=6f1c13927480aed9 input=f9cc6da970b1b1d5]*/ ++{ ++ int rc; ++ ++ /* ASCII unicode string */ ++ if(PyUnicode_Check(a) && PyUnicode_Check(b)) { ++ if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) { ++ return NULL; ++ } ++ if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) { ++ PyErr_SetString(PyExc_TypeError, ++ "comparing strings with non-ASCII characters is " ++ "not supported"); ++ return NULL; ++ } ++ ++ rc = _tscmp(PyUnicode_DATA(a), ++ PyUnicode_DATA(b), ++ PyUnicode_GET_LENGTH(a), ++ PyUnicode_GET_LENGTH(b)); ++ } ++ /* fallback to buffer interface for bytes, bytesarray and other */ ++ else { ++ Py_buffer view_a; ++ Py_buffer view_b; ++ ++ if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) { ++ PyErr_Format(PyExc_TypeError, ++ "unsupported operand types(s) or combination of types: " ++ "'%.100s' and '%.100s'", ++ Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); ++ return NULL; ++ } ++ ++ if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) { ++ return NULL; ++ } ++ if (view_a.ndim > 1) { ++ PyErr_SetString(PyExc_BufferError, ++ "Buffer must be single dimension"); ++ PyBuffer_Release(&view_a); ++ return NULL; ++ } ++ ++ if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) { ++ PyBuffer_Release(&view_a); ++ return NULL; ++ } ++ if (view_b.ndim > 1) { ++ PyErr_SetString(PyExc_BufferError, ++ "Buffer must be single dimension"); ++ PyBuffer_Release(&view_a); ++ PyBuffer_Release(&view_b); ++ return NULL; ++ } ++ ++ rc = _tscmp((const unsigned char*)view_a.buf, ++ (const unsigned char*)view_b.buf, ++ view_a.len, ++ view_b.len); ++ ++ PyBuffer_Release(&view_a); ++ PyBuffer_Release(&view_b); ++ } ++ ++ return PyBool_FromLong(rc); ++} ++ ++static struct PyMethodDef hashlib_methods[] = { ++ _HASHLIB_NEW_METHODDEF ++ _HASHLIB_HMAC_SINGLESHOT_METHODDEF ++ _HASHLIB_HMAC_NEW_METHODDEF ++ _HASHLIB_OPENSSL_MD5_METHODDEF ++ _HASHLIB_OPENSSL_SHA1_METHODDEF ++ _HASHLIB_OPENSSL_SHA224_METHODDEF ++ _HASHLIB_OPENSSL_SHA256_METHODDEF ++ _HASHLIB_OPENSSL_SHA384_METHODDEF ++ _HASHLIB_OPENSSL_SHA512_METHODDEF ++ _HASHLIB_OPENSSL_SHAKE_128_METHODDEF ++ _HASHLIB_OPENSSL_SHAKE_256_METHODDEF ++ _HASHLIB_COMPARE_DIGEST_METHODDEF ++ {0} ++}; ++ ++/* Fast HMAC for hmac.digest() */ ++ ++/*[clinic input] ++_hashlib.hmac_digest as _hashlib_hmac_singleshot ++ ++ key: Py_buffer ++ msg: Py_buffer ++ digest: str ++ ++Single-shot HMAC. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, ++ Py_buffer *msg, const char *digest) ++/*[clinic end generated code: output=15658ede5ab98185 input=019dffc571909a46]*/ ++{ ++ char buf[64]; ++ Py_ssize_t buf_len; ++ br_hmac_context ctx; ++ br_hmac_key_context keyctx; ++ const br_hash_class *hc; ++ ++ hc = py_hash_by_name(digest); ++ if (!hc) { ++ PyErr_SetString(PyExc_ValueError, "unsupported hash type"); ++ return NULL; ++ } ++ if (msg->len >= HASHLIB_GIL_MINSIZE) { ++ Py_BEGIN_ALLOW_THREADS ++ br_hmac_key_init(&keyctx, hc, key->buf, key->len); ++ br_hmac_init(&ctx, &keyctx, 0); ++ br_hmac_update(&ctx, msg->buf, msg->len); ++ br_hmac_out(&ctx, buf); ++ Py_END_ALLOW_THREADS ++ } else { ++ br_hmac_key_init(&keyctx, hc, key->buf, key->len); ++ br_hmac_init(&ctx, &keyctx, 0); ++ br_hmac_update(&ctx, msg->buf, msg->len); ++ br_hmac_out(&ctx, buf); ++ } ++ buf_len = br_hmac_size(&ctx); ++ ++ return PyBytes_FromStringAndSize(buf, buf_len); ++} ++ ++/*[clinic input] ++_hashlib.hmac_new ++ ++ key: Py_buffer ++ msg: Py_buffer = None ++ digestmod: str(c_default="NULL") = None ++ ++Return a new hmac object. ++[clinic start generated code]*/ ++ ++static PyObject * ++_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, ++ const char *digestmod) ++/*[clinic end generated code: output=5733a8600554bba2 input=b0125f4222a0d06d]*/ ++{ ++ HMAC *self; ++ const br_hash_class *hc; ++ ++ printf("hmac new\n"); ++ ++ if (!digestmod || !digestmod[0]) { ++ PyErr_SetString( ++ PyExc_TypeError, "missing required parameter 'digestmod'"); ++ return NULL; ++ } ++ hc = py_hash_by_name(digestmod); ++ if (!hc) { ++ PyErr_SetString(PyExc_ValueError, "unknown hash function"); ++ return NULL; ++ } ++ self = PyObject_New(HMAC, &HMAC_Type); ++ if (!self) ++ return NULL; ++ self->lock = NULL; ++ br_hmac_key_init(&self->key, hc, key->buf, key->len); ++ br_hmac_init(&self->ctx, &self->key, 0); ++ ++ if (msg->len >= HASHLIB_GIL_MINSIZE) { ++ Py_BEGIN_ALLOW_THREADS ++ br_hmac_update(&self->ctx, msg->buf, msg->len); ++ Py_END_ALLOW_THREADS ++ } else { ++ br_hmac_update(&self->ctx, msg->buf, msg->len); ++ } ++ ++ return (PyObject *)self; ++} ++ ++static struct PyModuleDef _hashlibmodule = { ++ PyModuleDef_HEAD_INIT, ++ .m_name = "_hashlib", ++ .m_doc = "BearSSL interface for hashlib module", ++ .m_methods = hashlib_methods, ++}; ++ ++PyMODINIT_FUNC ++PyInit__hashlib(void) ++{ ++ PyObject *m = NULL, *set = NULL, *name; ++ static const char *const names[] = { ++ "md5", ++ "sha1", ++ "sha224", ++ "sha256", ++ "sha384", ++ "sha512", ++ "shake_128", ++ "shake_256", ++ }; ++ int r; ++ ++ m = PyState_FindModule(&_hashlibmodule); ++ if (m) { ++ Py_INCREF(m); ++ return m; ++ } ++ m = PyModule_Create(&_hashlibmodule); ++ if (!m) ++ goto err; ++ if (PyModule_AddType(m, &Hash_Type) < 0) ++ goto err; ++ if (PyModule_AddType(m, &SHAKE_Type) < 0) ++ goto err; ++ if (PyModule_AddType(m, &HMAC_Type) < 0) ++ goto err; ++ set = PyFrozenSet_New(NULL); ++ if (!set) ++ goto err; ++ for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) { ++ name = PyUnicode_FromString(names[i]); ++ if (!name) ++ goto err; ++ r = PySet_Add(set, name); ++ Py_DECREF(name); ++ if (r != 0) ++ goto err; ++ } ++ if (PyModule_AddObject(m, "openssl_md_meth_names", set) < 0) ++ goto err; ++ ++ return m; ++ ++ err: ++ if (set) ++ Py_DECREF(set); ++ if (m) ++ Py_DECREF(m); ++ return NULL; ++} +diff --git a/Modules/clinic/_hashbearssl.c.h b/Modules/clinic/_hashbearssl.c.h +new file mode 100644 +index 0000000000..49bf8f9287 +--- /dev/null ++++ b/Modules/clinic/_hashbearssl.c.h +@@ -0,0 +1,1113 @@ ++/*[clinic input] ++preserve ++[clinic start generated code]*/ ++ ++PyDoc_STRVAR(Hash_update__doc__, ++"update($self, data, /)\n" ++"--\n" ++"\n" ++"Update this hash object\'s state with the provided string."); ++ ++#define HASH_UPDATE_METHODDEF \ ++ {"update", (PyCFunction)Hash_update, METH_O, Hash_update__doc__}, ++ ++static PyObject * ++Hash_update_impl(Hash *self, Py_buffer *data); ++ ++static PyObject * ++Hash_update(Hash *self, PyObject *arg) ++{ ++ PyObject *return_value = NULL; ++ Py_buffer data = {NULL, NULL}; ++ ++ if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&data, 'C')) { ++ _PyArg_BadArgument("update", "argument", "contiguous buffer", arg); ++ goto exit; ++ } ++ return_value = Hash_update_impl(self, &data); ++ ++exit: ++ /* Cleanup for data */ ++ if (data.obj) { ++ PyBuffer_Release(&data); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(Hash_digest__doc__, ++"digest($self, /)\n" ++"--\n" ++"\n" ++"Return the digest value as a bytes object."); ++ ++#define HASH_DIGEST_METHODDEF \ ++ {"digest", (PyCFunction)Hash_digest, METH_NOARGS, Hash_digest__doc__}, ++ ++static PyObject * ++Hash_digest_impl(Hash *self); ++ ++static PyObject * ++Hash_digest(Hash *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return Hash_digest_impl(self); ++} ++ ++PyDoc_STRVAR(Hash_hexdigest__doc__, ++"hexdigest($self, /)\n" ++"--\n" ++"\n" ++"Return the digest value as a string of hexadecimal digits."); ++ ++#define HASH_HEXDIGEST_METHODDEF \ ++ {"hexdigest", (PyCFunction)Hash_hexdigest, METH_NOARGS, Hash_hexdigest__doc__}, ++ ++static PyObject * ++Hash_hexdigest_impl(Hash *self); ++ ++static PyObject * ++Hash_hexdigest(Hash *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return Hash_hexdigest_impl(self); ++} ++ ++PyDoc_STRVAR(Hash_copy__doc__, ++"copy($self, /)\n" ++"--\n" ++"\n" ++"Return a copy of the hash object."); ++ ++#define HASH_COPY_METHODDEF \ ++ {"copy", (PyCFunction)Hash_copy, METH_NOARGS, Hash_copy__doc__}, ++ ++static PyObject * ++Hash_copy_impl(Hash *self); ++ ++static PyObject * ++Hash_copy(Hash *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return Hash_copy_impl(self); ++} ++ ++PyDoc_STRVAR(SHAKE_update__doc__, ++"update($self, data, /)\n" ++"--\n" ++"\n" ++"Update this hash object\'s state with the provided string."); ++ ++#define SHAKE_UPDATE_METHODDEF \ ++ {"update", (PyCFunction)SHAKE_update, METH_O, SHAKE_update__doc__}, ++ ++static PyObject * ++SHAKE_update_impl(SHAKE *self, Py_buffer *data); ++ ++static PyObject * ++SHAKE_update(SHAKE *self, PyObject *arg) ++{ ++ PyObject *return_value = NULL; ++ Py_buffer data = {NULL, NULL}; ++ ++ if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&data, 'C')) { ++ _PyArg_BadArgument("update", "argument", "contiguous buffer", arg); ++ goto exit; ++ } ++ return_value = SHAKE_update_impl(self, &data); ++ ++exit: ++ /* Cleanup for data */ ++ if (data.obj) { ++ PyBuffer_Release(&data); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(SHAKE_digest__doc__, ++"digest($self, /, length)\n" ++"--\n" ++"\n" ++"Return the digest value as a bytes object."); ++ ++#define SHAKE_DIGEST_METHODDEF \ ++ {"digest", (PyCFunction)(void(*)(void))SHAKE_digest, METH_FASTCALL|METH_KEYWORDS, SHAKE_digest__doc__}, ++ ++static PyObject * ++SHAKE_digest_impl(SHAKE *self, Py_ssize_t length); ++ ++static PyObject * ++SHAKE_digest(SHAKE *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"length", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0}; ++ PyObject *argsbuf[1]; ++ Py_ssize_t length; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (PyFloat_Check(args[0])) { ++ PyErr_SetString(PyExc_TypeError, ++ "integer argument expected, got float" ); ++ goto exit; ++ } ++ { ++ Py_ssize_t ival = -1; ++ PyObject *iobj = PyNumber_Index(args[0]); ++ if (iobj != NULL) { ++ ival = PyLong_AsSsize_t(iobj); ++ Py_DECREF(iobj); ++ } ++ if (ival == -1 && PyErr_Occurred()) { ++ goto exit; ++ } ++ length = ival; ++ } ++ return_value = SHAKE_digest_impl(self, length); ++ ++exit: ++ return return_value; ++} ++ ++PyDoc_STRVAR(SHAKE_hexdigest__doc__, ++"hexdigest($self, /, length)\n" ++"--\n" ++"\n" ++"Return the digest value as a string of hexadecimal digits."); ++ ++#define SHAKE_HEXDIGEST_METHODDEF \ ++ {"hexdigest", (PyCFunction)(void(*)(void))SHAKE_hexdigest, METH_FASTCALL|METH_KEYWORDS, SHAKE_hexdigest__doc__}, ++ ++static PyObject * ++SHAKE_hexdigest_impl(SHAKE *self, Py_ssize_t length); ++ ++static PyObject * ++SHAKE_hexdigest(SHAKE *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"length", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0}; ++ PyObject *argsbuf[1]; ++ Py_ssize_t length; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (PyFloat_Check(args[0])) { ++ PyErr_SetString(PyExc_TypeError, ++ "integer argument expected, got float" ); ++ goto exit; ++ } ++ { ++ Py_ssize_t ival = -1; ++ PyObject *iobj = PyNumber_Index(args[0]); ++ if (iobj != NULL) { ++ ival = PyLong_AsSsize_t(iobj); ++ Py_DECREF(iobj); ++ } ++ if (ival == -1 && PyErr_Occurred()) { ++ goto exit; ++ } ++ length = ival; ++ } ++ return_value = SHAKE_hexdigest_impl(self, length); ++ ++exit: ++ return return_value; ++} ++ ++PyDoc_STRVAR(SHAKE_copy__doc__, ++"copy($self, /)\n" ++"--\n" ++"\n" ++"Return a copy of the SHAKE object."); ++ ++#define SHAKE_COPY_METHODDEF \ ++ {"copy", (PyCFunction)SHAKE_copy, METH_NOARGS, SHAKE_copy__doc__}, ++ ++static PyObject * ++SHAKE_copy_impl(SHAKE *self); ++ ++static PyObject * ++SHAKE_copy(SHAKE *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return SHAKE_copy_impl(self); ++} ++ ++PyDoc_STRVAR(HMAC_copy__doc__, ++"copy($self, /)\n" ++"--\n" ++"\n" ++"Return a copy of the HMAC object."); ++ ++#define HMAC_COPY_METHODDEF \ ++ {"copy", (PyCFunction)HMAC_copy, METH_NOARGS, HMAC_copy__doc__}, ++ ++static PyObject * ++HMAC_copy_impl(HMAC *self); ++ ++static PyObject * ++HMAC_copy(HMAC *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return HMAC_copy_impl(self); ++} ++ ++PyDoc_STRVAR(HMAC_update__doc__, ++"update($self, data, /)\n" ++"--\n" ++"\n" ++"Update the HMAC object with data."); ++ ++#define HMAC_UPDATE_METHODDEF \ ++ {"update", (PyCFunction)HMAC_update, METH_O, HMAC_update__doc__}, ++ ++static PyObject * ++HMAC_update_impl(HMAC *self, Py_buffer *data); ++ ++static PyObject * ++HMAC_update(HMAC *self, PyObject *arg) ++{ ++ PyObject *return_value = NULL; ++ Py_buffer data = {NULL, NULL}; ++ ++ if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&data, 'C')) { ++ _PyArg_BadArgument("update", "argument", "contiguous buffer", arg); ++ goto exit; ++ } ++ return_value = HMAC_update_impl(self, &data); ++ ++exit: ++ /* Cleanup for data */ ++ if (data.obj) { ++ PyBuffer_Release(&data); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(HMAC_digest__doc__, ++"digest($self, /)\n" ++"--\n" ++"\n" ++"Return the digest of the bytes passed to the update() method so far."); ++ ++#define HMAC_DIGEST_METHODDEF \ ++ {"digest", (PyCFunction)HMAC_digest, METH_NOARGS, HMAC_digest__doc__}, ++ ++static PyObject * ++HMAC_digest_impl(HMAC *self); ++ ++static PyObject * ++HMAC_digest(HMAC *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return HMAC_digest_impl(self); ++} ++ ++PyDoc_STRVAR(HMAC_hexdigest__doc__, ++"hexdigest($self, /)\n" ++"--\n" ++"\n" ++"Return hexadecimal digest of the bytes passed to the update() method so far.\n" ++"\n" ++"This may be used to exchange the value safely in email or other non-binary\n" ++"environments."); ++ ++#define HMAC_HEXDIGEST_METHODDEF \ ++ {"hexdigest", (PyCFunction)HMAC_hexdigest, METH_NOARGS, HMAC_hexdigest__doc__}, ++ ++static PyObject * ++HMAC_hexdigest_impl(HMAC *self); ++ ++static PyObject * ++HMAC_hexdigest(HMAC *self, PyObject *Py_UNUSED(ignored)) ++{ ++ return HMAC_hexdigest_impl(self); ++} ++ ++PyDoc_STRVAR(_hashlib_new__doc__, ++"new($module, /, name, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Return a new hash object using the named algorithm.\n" ++"\n" ++"An optional string argument may be provided and will be\n" ++"automatically hashed.\n" ++"\n" ++"The MD5 and SHA1 algorithms are always supported."); ++ ++#define _HASHLIB_NEW_METHODDEF \ ++ {"new", (PyCFunction)(void(*)(void))_hashlib_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_new__doc__}, ++ ++static PyObject * ++_hashlib_new_impl(PyObject *module, const char *name, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "new", 0}; ++ PyObject *argsbuf[3]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; ++ const char *name; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ 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; ++ } ++ if (args[1]) { ++ if (PyObject_GetBuffer(args[1], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("new", "argument 'string'", "contiguous buffer", args[1]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[2]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_new_impl(module, name, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_md5__doc__, ++"openssl_md5($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a md5 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_MD5_METHODDEF \ ++ {"openssl_md5", (PyCFunction)(void(*)(void))_hashlib_openssl_md5, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__}, ++ ++static PyObject * ++_hashlib_openssl_md5_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_md5", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_md5_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_sha1__doc__, ++"openssl_sha1($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a sha1 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHA1_METHODDEF \ ++ {"openssl_sha1", (PyCFunction)(void(*)(void))_hashlib_openssl_sha1, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__}, ++ ++static PyObject * ++_hashlib_openssl_sha1_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_sha1", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_sha1_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_sha224__doc__, ++"openssl_sha224($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a sha224 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHA224_METHODDEF \ ++ {"openssl_sha224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__}, ++ ++static PyObject * ++_hashlib_openssl_sha224_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_sha224", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_sha224_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_sha256__doc__, ++"openssl_sha256($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a sha256 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHA256_METHODDEF \ ++ {"openssl_sha256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__}, ++ ++static PyObject * ++_hashlib_openssl_sha256_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_sha256", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_sha256_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_sha384__doc__, ++"openssl_sha384($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a sha384 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHA384_METHODDEF \ ++ {"openssl_sha384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__}, ++ ++static PyObject * ++_hashlib_openssl_sha384_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_sha384", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_sha384_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_sha512__doc__, ++"openssl_sha512($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a sha512 hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHA512_METHODDEF \ ++ {"openssl_sha512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__}, ++ ++static PyObject * ++_hashlib_openssl_sha512_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_sha512", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_sha512_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_shake_128__doc__, ++"openssl_shake_128($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a shake-128 variable hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHAKE_128_METHODDEF \ ++ {"openssl_shake_128", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_128, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_128__doc__}, ++ ++static PyObject * ++_hashlib_openssl_shake_128_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_128", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_shake_128", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_shake_128_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_openssl_shake_256__doc__, ++"openssl_shake_256($module, /, string=None, *, usedforsecurity=True)\n" ++"--\n" ++"\n" ++"Returns a shake-256 variable hash object; optionally initialized with a string."); ++ ++#define _HASHLIB_OPENSSL_SHAKE_256_METHODDEF \ ++ {"openssl_shake_256", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_256__doc__}, ++ ++static PyObject * ++_hashlib_openssl_shake_256_impl(PyObject *module, Py_buffer *string, ++ int usedforsecurity); ++ ++static PyObject * ++_hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_256", 0}; ++ PyObject *argsbuf[2]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; ++ Py_buffer string = {NULL, NULL}; ++ int usedforsecurity = 1; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[0]) { ++ if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&string, 'C')) { ++ _PyArg_BadArgument("openssl_shake_256", "argument 'string'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++skip_optional_pos: ++ if (!noptargs) { ++ goto skip_optional_kwonly; ++ } ++ usedforsecurity = PyObject_IsTrue(args[1]); ++ if (usedforsecurity < 0) { ++ goto exit; ++ } ++skip_optional_kwonly: ++ return_value = _hashlib_openssl_shake_256_impl(module, &string, usedforsecurity); ++ ++exit: ++ /* Cleanup for string */ ++ if (string.obj) { ++ PyBuffer_Release(&string); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_compare_digest__doc__, ++"compare_digest($module, a, b, /)\n" ++"--\n" ++"\n" ++"Return \'a == b\'.\n" ++"\n" ++"This function uses an approach designed to prevent\n" ++"timing analysis, making it appropriate for cryptography.\n" ++"\n" ++"a and b must both be of the same type: either str (ASCII only),\n" ++"or any bytes-like object.\n" ++"\n" ++"Note: If a and b are of different lengths, or if an error occurs,\n" ++"a timing attack could theoretically reveal information about the\n" ++"types and lengths of a and b--but not their values."); ++ ++#define _HASHLIB_COMPARE_DIGEST_METHODDEF \ ++ {"compare_digest", (PyCFunction)(void(*)(void))_hashlib_compare_digest, METH_FASTCALL, _hashlib_compare_digest__doc__}, ++ ++static PyObject * ++_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b); ++ ++static PyObject * ++_hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs) ++{ ++ PyObject *return_value = NULL; ++ PyObject *a; ++ PyObject *b; ++ ++ if (!_PyArg_CheckPositional("compare_digest", nargs, 2, 2)) { ++ goto exit; ++ } ++ a = args[0]; ++ b = args[1]; ++ return_value = _hashlib_compare_digest_impl(module, a, b); ++ ++exit: ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, ++"hmac_digest($module, /, key, msg, digest)\n" ++"--\n" ++"\n" ++"Single-shot HMAC."); ++ ++#define _HASHLIB_HMAC_SINGLESHOT_METHODDEF \ ++ {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_singleshot, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__}, ++ ++static PyObject * ++_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, ++ Py_buffer *msg, const char *digest); ++ ++static PyObject * ++_hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"key", "msg", "digest", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0}; ++ PyObject *argsbuf[3]; ++ Py_buffer key = {NULL, NULL}; ++ Py_buffer msg = {NULL, NULL}; ++ const char *digest; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&key, 'C')) { ++ _PyArg_BadArgument("hmac_digest", "argument 'key'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&msg, 'C')) { ++ _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]); ++ goto exit; ++ } ++ if (!PyUnicode_Check(args[2])) { ++ _PyArg_BadArgument("hmac_digest", "argument 'digest'", "str", args[2]); ++ goto exit; ++ } ++ Py_ssize_t digest_length; ++ digest = PyUnicode_AsUTF8AndSize(args[2], &digest_length); ++ if (digest == NULL) { ++ goto exit; ++ } ++ if (strlen(digest) != (size_t)digest_length) { ++ PyErr_SetString(PyExc_ValueError, "embedded null character"); ++ goto exit; ++ } ++ return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest); ++ ++exit: ++ /* Cleanup for key */ ++ if (key.obj) { ++ PyBuffer_Release(&key); ++ } ++ /* Cleanup for msg */ ++ if (msg.obj) { ++ PyBuffer_Release(&msg); ++ } ++ ++ return return_value; ++} ++ ++PyDoc_STRVAR(_hashlib_hmac_new__doc__, ++"hmac_new($module, /, key, msg=None, digestmod=None)\n" ++"--\n" ++"\n" ++"Return a new hmac object."); ++ ++#define _HASHLIB_HMAC_NEW_METHODDEF \ ++ {"hmac_new", (PyCFunction)(void(*)(void))_hashlib_hmac_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_new__doc__}, ++ ++static PyObject * ++_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, ++ const char *digestmod); ++ ++static PyObject * ++_hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) ++{ ++ PyObject *return_value = NULL; ++ static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; ++ static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0}; ++ PyObject *argsbuf[3]; ++ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; ++ Py_buffer key = {NULL, NULL}; ++ Py_buffer msg = {NULL, NULL}; ++ const char *digestmod = NULL; ++ ++ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); ++ if (!args) { ++ goto exit; ++ } ++ if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&key, 'C')) { ++ _PyArg_BadArgument("hmac_new", "argument 'key'", "contiguous buffer", args[0]); ++ goto exit; ++ } ++ if (!noptargs) { ++ goto skip_optional_pos; ++ } ++ if (args[1]) { ++ if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) { ++ goto exit; ++ } ++ if (!PyBuffer_IsContiguous(&msg, 'C')) { ++ _PyArg_BadArgument("hmac_new", "argument 'msg'", "contiguous buffer", args[1]); ++ goto exit; ++ } ++ if (!--noptargs) { ++ goto skip_optional_pos; ++ } ++ } ++ if (!PyUnicode_Check(args[2])) { ++ _PyArg_BadArgument("hmac_new", "argument 'digestmod'", "str", args[2]); ++ goto exit; ++ } ++ Py_ssize_t digestmod_length; ++ digestmod = PyUnicode_AsUTF8AndSize(args[2], &digestmod_length); ++ if (digestmod == NULL) { ++ goto exit; ++ } ++ if (strlen(digestmod) != (size_t)digestmod_length) { ++ PyErr_SetString(PyExc_ValueError, "embedded null character"); ++ goto exit; ++ } ++skip_optional_pos: ++ return_value = _hashlib_hmac_new_impl(module, &key, &msg, digestmod); ++ ++exit: ++ /* Cleanup for key */ ++ if (key.obj) { ++ PyBuffer_Release(&key); ++ } ++ /* Cleanup for msg */ ++ if (msg.obj) { ++ PyBuffer_Release(&msg); ++ } ++ ++ return return_value; ++} ++/*[clinic end generated code: output=b4705bad5ece43e9 input=a9049054013a1b77]*/ +-- +2.31.1 + diff --git a/pkg/python/patch/0001-Fix-build-with-libressl.patch b/pkg/python/patch/0001-Fix-build-with-libressl.patch @@ -1,25 +0,0 @@ -From c10df94443a1193da36af080993d64942b272be4 Mon Sep 17 00:00:00 2001 -From: Michael Forney <mforney@mforney.org> -Date: Tue, 6 Oct 2020 00:58:09 -0700 -Subject: [PATCH] Fix build with libressl - ---- - Modules/_hashopenssl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index adc8653773..c40a3ff705 100644 ---- a/Modules/_hashopenssl.c -+++ b/Modules/_hashopenssl.c -@@ -32,7 +32,7 @@ - # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" - #endif - --#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) -+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) - /* OpenSSL < 1.1.0 */ - #define EVP_MD_CTX_new EVP_MD_CTX_create - #define EVP_MD_CTX_free EVP_MD_CTX_destroy --- -2.28.0 - diff --git a/pkg/python/ver b/pkg/python/ver @@ -1 +1 @@ -3.9.4 r0 +3.9.4 r1