master hovercats/oakiss / pkg / python / patch / 0001-Add-BearSSL-implementation-of-_hashlib.patch
   1From 61ad7f5ec78d4c80a99ac71820d9bc8b62c3fbae Mon Sep 17 00:00:00 2001
   2From: Michael Forney <mforney@mforney.org>
   3Date: Sat, 15 May 2021 22:48:13 -0700
   4Subject: [PATCH] Add BearSSL implementation of _hashlib
   5
   6---
   7 Modules/_hashbearssl.c          | 1126 +++++++++++++++++++++++++++++++
   8 Modules/clinic/_hashbearssl.c.h | 1113 ++++++++++++++++++++++++++++++
   9 2 files changed, 2239 insertions(+)
  10 create mode 100644 Modules/_hashbearssl.c
  11 create mode 100644 Modules/clinic/_hashbearssl.c.h
  12
  13diff --git a/Modules/_hashbearssl.c b/Modules/_hashbearssl.c
  14new file mode 100644
  15index 0000000000..2d1a76296d
  16--- /dev/null
  17+++ b/Modules/_hashbearssl.c
  18@@ -0,0 +1,1126 @@
  19+/* Module that wraps all BearSSL hash algorithms */
  20+#define PY_SSIZE_T_CLEAN
  21+#include "Python.h"
  22+#include "hashlib.h"
  23+#include "pystrhex.h"
  24+
  25+#include <bearssl.h>
  26+
  27+static PyModuleDef _hashlibmodule;
  28+static PyTypeObject Hash_Type;
  29+static PyTypeObject SHAKE_Type;
  30+static PyTypeObject HMAC_Type;
  31+
  32+typedef struct {
  33+    PyObject_HEAD
  34+    br_hash_compat_context ctx;
  35+    PyThread_type_lock lock;
  36+} Hash;
  37+
  38+typedef struct {
  39+    PyObject_HEAD
  40+    br_hmac_context ctx;
  41+    br_hmac_key_context key;
  42+    PyThread_type_lock lock;
  43+} HMAC;
  44+
  45+typedef struct {
  46+    PyObject_HEAD
  47+    br_shake_context ctx;
  48+    int bits;
  49+    PyThread_type_lock lock;
  50+} SHAKE;
  51+
  52+#include "clinic/_hashbearssl.c.h"
  53+/*[clinic input]
  54+module _hashlib
  55+class _hashlib.Hash "Hash *" "Hash_Type"
  56+class _hashlib.HMAC "HMAC *" "HMAC_Type"
  57+class _hashlib.SHAKE "SHAKE *" "SHAKE_Type"
  58+[clinic start generated code]*/
  59+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a269412ec77c79a]*/
  60+
  61+static const br_hash_class *
  62+py_hash_by_name(const char *name)
  63+{
  64+    if (strcmp(name, "md5") == 0)
  65+        return &br_md5_vtable;
  66+    else if (strcmp(name, "sha1") == 0)
  67+        return &br_sha1_vtable;
  68+    else if (strcmp(name, "sha224") == 0)
  69+        return &br_sha224_vtable;
  70+    else if (strcmp(name, "sha256") == 0)
  71+        return &br_sha256_vtable;
  72+    else if (strcmp(name, "sha384") == 0)
  73+        return &br_sha384_vtable;
  74+    else if (strcmp(name, "sha512") == 0)
  75+        return &br_sha512_vtable;
  76+    return NULL;
  77+}
  78+
  79+PyDoc_STRVAR(Hash_doc,
  80+"Hash(name, string=b\'\')\n"
  81+"--\n"
  82+"\n"
  83+"A hash is an object used to calculate a checksum of a string of information.\n"
  84+"\n"
  85+"Methods:\n"
  86+"\n"
  87+"update() -- updates the current digest with an additional string\n"
  88+"digest() -- return the current digest value\n"
  89+"hexdigest() -- return the current digest as a string of hexadecimal digits\n"
  90+"copy() -- return a copy of the current hash object\n"
  91+"\n"
  92+"Attributes:\n"
  93+"\n"
  94+"name -- the hash algorithm being used by this object\n"
  95+"digest_size -- number of bytes in this hashes output");
  96+
  97+static void
  98+Hash_dealloc(Hash *self)
  99+{
 100+    if (self->lock)
 101+        PyThread_free_lock(self->lock);
 102+    PyObject_Free(self);
 103+}
 104+
 105+/*[clinic input]
 106+_hashlib.Hash.update as Hash_update
 107+
 108+    data: Py_buffer
 109+    /
 110+
 111+Update this hash object's state with the provided string.
 112+[clinic start generated code]*/
 113+
 114+static PyObject *
 115+Hash_update_impl(Hash *self, Py_buffer *data)
 116+/*[clinic end generated code: output=eed11f7503e289a3 input=0547d16ba3981abf]*/
 117+{
 118+    if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE)
 119+        self->lock = PyThread_allocate_lock();
 120+    if (self->lock) {
 121+        Py_BEGIN_ALLOW_THREADS
 122+        PyThread_acquire_lock(self->lock, 1);
 123+        self->ctx.vtable->update(&self->ctx.vtable, data->buf, data->len);
 124+        PyThread_release_lock(self->lock);
 125+        Py_END_ALLOW_THREADS
 126+    } else {
 127+        self->ctx.vtable->update(&self->ctx.vtable, data->buf, data->len);
 128+    }
 129+    Py_RETURN_NONE;
 130+}
 131+
 132+/*[clinic input]
 133+_hashlib.Hash.digest as Hash_digest
 134+
 135+Return the digest value as a bytes object.
 136+[clinic start generated code]*/
 137+
 138+static PyObject *
 139+Hash_digest_impl(Hash *self)
 140+/*[clinic end generated code: output=b3eafdc9f37cf341 input=6d4afcd832edc55a]*/
 141+{
 142+    char digest[64];
 143+    Py_ssize_t digest_size;
 144+
 145+    ENTER_HASHLIB(self)
 146+    self->ctx.vtable->out(&self->ctx.vtable, digest);
 147+    LEAVE_HASHLIB(self)
 148+    digest_size = (self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK;
 149+
 150+    return PyBytes_FromStringAndSize(digest, digest_size);
 151+}
 152+
 153+/*[clinic input]
 154+_hashlib.Hash.hexdigest as Hash_hexdigest
 155+
 156+Return the digest value as a string of hexadecimal digits.
 157+[clinic start generated code]*/
 158+
 159+static PyObject *
 160+Hash_hexdigest_impl(Hash *self)
 161+/*[clinic end generated code: output=eff810494302910a input=6b224236fad6ff65]*/
 162+{
 163+    char digest[64];
 164+    Py_ssize_t digest_size;
 165+
 166+    ENTER_HASHLIB(self)
 167+    self->ctx.vtable->out(&self->ctx.vtable, digest);
 168+    LEAVE_HASHLIB(self)
 169+    digest_size = (self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK;
 170+
 171+    return _Py_strhex(digest, digest_size);
 172+}
 173+
 174+/*[clinic input]
 175+_hashlib.Hash.copy as Hash_copy
 176+
 177+Return a copy of the hash object.
 178+[clinic start generated code]*/
 179+
 180+static PyObject *
 181+Hash_copy_impl(Hash *self)
 182+/*[clinic end generated code: output=e97863340f55061b input=b830c9d949d08256]*/
 183+{
 184+    Hash *newobj;
 185+
 186+    newobj = PyObject_New(Hash, &Hash_Type);
 187+    if (!newobj)
 188+        return NULL;
 189+    newobj->lock = NULL;
 190+    ENTER_HASHLIB(self)
 191+    newobj->ctx = self->ctx;
 192+    LEAVE_HASHLIB(self)
 193+
 194+    return (PyObject *)newobj;
 195+}
 196+
 197+static PyMethodDef Hash_methods[] = {
 198+    HASH_UPDATE_METHODDEF
 199+    HASH_DIGEST_METHODDEF
 200+    HASH_HEXDIGEST_METHODDEF
 201+    HASH_COPY_METHODDEF
 202+    {0}
 203+};
 204+
 205+static PyObject *
 206+Hash_get_digest_size(Hash *self, void *closure)
 207+{
 208+    long digest_size;
 209+
 210+    digest_size = self->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK;
 211+    return PyLong_FromLong(digest_size);
 212+}
 213+
 214+static PyObject *
 215+Hash_get_block_size(Hash *self, void *closure)
 216+{
 217+    long block_size;
 218+
 219+    block_size = 1 << (self->ctx.vtable->desc >> BR_HASHDESC_LBLEN_OFF & BR_HASHDESC_LBLEN_MASK);
 220+    return PyLong_FromLong(block_size);
 221+}
 222+
 223+static PyObject *
 224+Hash_get_name(Hash *self, void *closure)
 225+{
 226+    const char *name = NULL;
 227+
 228+    switch (self->ctx.vtable->desc >> BR_HASHDESC_ID_OFF & BR_HASHDESC_ID_MASK) {
 229+    case br_md5_ID:    name = "md5";    break;
 230+    case br_sha1_ID:   name = "sha1";   break;
 231+    case br_sha224_ID: name = "sha224"; break;
 232+    case br_sha256_ID: name = "sha256"; break;
 233+    case br_sha384_ID: name = "sha384"; break;
 234+    case br_sha512_ID: name = "sha512"; break;
 235+    }
 236+
 237+    return PyUnicode_FromString(name);
 238+}
 239+
 240+static PyGetSetDef Hash_getset[] = {
 241+    {"digest_size", (getter)Hash_get_digest_size, NULL, NULL, NULL},
 242+    {"block_size", (getter)Hash_get_block_size, NULL, NULL, NULL},
 243+    {"name", (getter)Hash_get_name, NULL, NULL, NULL},
 244+    {0}
 245+};
 246+
 247+static PyTypeObject Hash_Type = {
 248+    PyVarObject_HEAD_INIT(NULL, 0)
 249+    .tp_name = "_hashlib.Hash",
 250+    .tp_dealloc = (destructor)Hash_dealloc,
 251+    .tp_doc = Hash_doc,
 252+    .tp_basicsize = sizeof(Hash),
 253+    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
 254+    .tp_methods = Hash_methods,
 255+    .tp_getset = Hash_getset,
 256+};
 257+
 258+PyDoc_STRVAR(SHAKE_doc,
 259+"SHAKE(name, string=b\'\')\n"
 260+"--\n"
 261+"\n"
 262+"A hash is an object used to calculate a checksum of a string of information.\n"
 263+"\n"
 264+"Methods:\n"
 265+"\n"
 266+"update() -- updates the current digest with an additional string\n"
 267+"digest(length) -- return the current digest value\n"
 268+"hexdigest(length) -- return the current digest as a string of hexadecimal digits\n"
 269+"copy() -- return a copy of the current hash object\n"
 270+"\n"
 271+"Attributes:\n"
 272+"\n"
 273+"name -- the hash algorithm being used by this object\n"
 274+"digest_size -- number of bytes in this hashes output");
 275+
 276+static void
 277+SHAKE_dealloc(SHAKE *self)
 278+{
 279+    if (self->lock)
 280+        PyThread_free_lock(self->lock);
 281+    PyObject_Free(self);
 282+}
 283+
 284+/*[clinic input]
 285+_hashlib.SHAKE.update as SHAKE_update
 286+
 287+    data: Py_buffer
 288+    /
 289+
 290+Update this hash object's state with the provided string.
 291+[clinic start generated code]*/
 292+
 293+static PyObject *
 294+SHAKE_update_impl(SHAKE *self, Py_buffer *data)
 295+/*[clinic end generated code: output=b7f5cd67459e2fb3 input=87a80642380b615f]*/
 296+{
 297+    if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE)
 298+        self->lock = PyThread_allocate_lock();
 299+    if (self->lock) {
 300+        Py_BEGIN_ALLOW_THREADS
 301+        PyThread_acquire_lock(self->lock, 1);
 302+        br_shake_inject(&self->ctx, data->buf, data->len);
 303+        PyThread_release_lock(self->lock);
 304+        Py_END_ALLOW_THREADS
 305+    } else {
 306+        br_shake_inject(&self->ctx, data->buf, data->len);
 307+    }
 308+    Py_RETURN_NONE;
 309+}
 310+
 311+/*[clinic input]
 312+_hashlib.SHAKE.digest as SHAKE_digest
 313+
 314+  length: Py_ssize_t
 315+
 316+Return the digest value as a bytes object.
 317+[clinic start generated code]*/
 318+
 319+static PyObject *
 320+SHAKE_digest_impl(SHAKE *self, Py_ssize_t length)
 321+/*[clinic end generated code: output=4235ee593cba0b23 input=9e31587954f5e87a]*/
 322+{
 323+    br_shake_context ctx;
 324+    PyObject *bytes;
 325+
 326+    bytes = PyBytes_FromStringAndSize(NULL, length);
 327+    if (!bytes)
 328+        return NULL;
 329+
 330+    ENTER_HASHLIB(self)
 331+    ctx = self->ctx;
 332+    LEAVE_HASHLIB(self)
 333+    br_shake_flip(&ctx);
 334+    br_shake_produce(&ctx, PyBytes_AS_STRING(bytes), length);
 335+
 336+    return bytes;
 337+}
 338+
 339+/*[clinic input]
 340+_hashlib.SHAKE.hexdigest as SHAKE_hexdigest
 341+
 342+    length: Py_ssize_t
 343+
 344+Return the digest value as a string of hexadecimal digits.
 345+[clinic start generated code]*/
 346+
 347+static PyObject *
 348+SHAKE_hexdigest_impl(SHAKE *self, Py_ssize_t length)
 349+/*[clinic end generated code: output=fd9a7905a89a1509 input=2c43a9638ca1db5e]*/
 350+{
 351+    br_shake_context ctx;
 352+    char *bytes;
 353+    PyObject *str;
 354+
 355+    bytes = PyMem_Malloc(length);
 356+    if (!bytes) {
 357+        PyErr_NoMemory();
 358+        return NULL;
 359+    }
 360+
 361+    ENTER_HASHLIB(self)
 362+    ctx = self->ctx;
 363+    LEAVE_HASHLIB(self)
 364+    br_shake_flip(&ctx);
 365+    br_shake_produce(&ctx, bytes, length);
 366+
 367+    str = _Py_strhex(bytes, length);
 368+    PyMem_Free(bytes);
 369+    return str;
 370+}
 371+
 372+/*[clinic input]
 373+_hashlib.SHAKE.copy as SHAKE_copy
 374+
 375+Return a copy of the SHAKE object.
 376+[clinic start generated code]*/
 377+
 378+static PyObject *
 379+SHAKE_copy_impl(SHAKE *self)
 380+/*[clinic end generated code: output=19cff23538f29dc6 input=34c8368c5c9e910c]*/
 381+{
 382+    SHAKE *newobj;
 383+
 384+    newobj = PyObject_New(SHAKE, &SHAKE_Type);
 385+    if (!newobj)
 386+        return NULL;
 387+    newobj->lock = NULL;
 388+    ENTER_HASHLIB(self)
 389+    newobj->ctx = self->ctx;
 390+    newobj->bits = self->bits;
 391+    LEAVE_HASHLIB(self)
 392+
 393+    return (PyObject *)newobj;
 394+}
 395+
 396+static PyMethodDef SHAKE_methods[] = {
 397+    SHAKE_UPDATE_METHODDEF
 398+    SHAKE_DIGEST_METHODDEF
 399+    SHAKE_HEXDIGEST_METHODDEF
 400+    SHAKE_COPY_METHODDEF
 401+    {0}
 402+};
 403+
 404+static PyObject *
 405+SHAKE_get_digest_size(SHAKE *self, void *closure)
 406+{
 407+    return PyLong_FromLong(0);
 408+}
 409+
 410+static PyObject *
 411+SHAKE_get_block_size(SHAKE *self, void *closure)
 412+{
 413+    return PyLong_FromLong(self->ctx.rate);
 414+}
 415+
 416+static PyObject *
 417+SHAKE_get_name(SHAKE *self, void *closure)
 418+{
 419+    const char *name = NULL;
 420+
 421+    switch (self->bits) {
 422+    case 128: name = "shake_128"; break;
 423+    case 256: name = "shake_256"; break;
 424+    }
 425+
 426+    return PyUnicode_FromString(name);
 427+}
 428+
 429+static PyGetSetDef SHAKE_getset[] = {
 430+    {"digest_size", (getter)SHAKE_get_digest_size, NULL, NULL, NULL},
 431+    {"block_size", (getter)SHAKE_get_block_size, NULL, NULL, NULL},
 432+    {"name", (getter)SHAKE_get_name, NULL, NULL, NULL},
 433+    {0}
 434+};
 435+
 436+static PyTypeObject SHAKE_Type = {
 437+    PyVarObject_HEAD_INIT(NULL, 0)
 438+    .tp_name = "_hashlib.SHAKE",
 439+    .tp_dealloc = (destructor)SHAKE_dealloc,
 440+    .tp_doc = SHAKE_doc,
 441+    .tp_basicsize = sizeof(SHAKE),
 442+    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
 443+    .tp_methods = SHAKE_methods,
 444+    .tp_getset = SHAKE_getset,
 445+};
 446+
 447+PyDoc_STRVAR(HMAC_doc,
 448+"The object used to calculate HMAC of a message.\n\
 449+\n\
 450+Methods:\n\
 451+\n\
 452+update() -- updates the current digest with an additional string\n\
 453+digest() -- return the current digest value\n\
 454+hexdigest() -- return the current digest as a string of hexadecimal digits\n\
 455+copy() -- return a copy of the current hash object\n\
 456+\n\
 457+Attributes:\n\
 458+\n\
 459+name -- the name, including the hash algorithm used by this object\n\
 460+digest_size -- number of bytes in digest() output\n");
 461+
 462+static void
 463+HMAC_dealloc(HMAC *self)
 464+{
 465+    if (self->lock)
 466+        PyThread_free_lock(self->lock);
 467+    PyObject_Free(self);
 468+}
 469+/*[clinic input]
 470+_hashlib.HMAC.copy as HMAC_copy
 471+
 472+Return a copy of the HMAC object.
 473+[clinic start generated code]*/
 474+
 475+static PyObject *
 476+HMAC_copy_impl(HMAC *self)
 477+/*[clinic end generated code: output=6a3595133ec708a5 input=c471e903458ee9a7]*/
 478+{
 479+    HMAC *newobj;
 480+
 481+    newobj = PyObject_New(HMAC, &HMAC_Type);
 482+    if (!newobj)
 483+        return NULL;
 484+    newobj->lock = NULL;
 485+    ENTER_HASHLIB(self)
 486+    newobj->ctx = self->ctx;
 487+    newobj->key = self->key;
 488+    LEAVE_HASHLIB(self)
 489+
 490+    return (PyObject *)newobj;
 491+}
 492+
 493+/*[clinic input]
 494+_hashlib.HMAC.update as HMAC_update
 495+
 496+    data: Py_buffer
 497+    /
 498+
 499+Update the HMAC object with data.
 500+[clinic start generated code]*/
 501+
 502+static PyObject *
 503+HMAC_update_impl(HMAC *self, Py_buffer *data)
 504+/*[clinic end generated code: output=d3520ecffa6cc3ab input=827e77e990887267]*/
 505+{
 506+    if (!self->lock && data->len >= HASHLIB_GIL_MINSIZE)
 507+        self->lock = PyThread_allocate_lock();
 508+    if (self->lock) {
 509+        Py_BEGIN_ALLOW_THREADS
 510+        PyThread_acquire_lock(self->lock, 1);
 511+        br_hmac_update(&self->ctx, data->buf, data->len);
 512+        PyThread_release_lock(self->lock);
 513+        Py_END_ALLOW_THREADS
 514+    } else {
 515+        br_hmac_update(&self->ctx, data->buf, data->len);
 516+    }
 517+    Py_RETURN_NONE;
 518+}
 519+
 520+/*[clinic input]
 521+_hashlib.HMAC.digest as HMAC_digest
 522+
 523+Return the digest of the bytes passed to the update() method so far.
 524+[clinic start generated code]*/
 525+
 526+static PyObject *
 527+HMAC_digest_impl(HMAC *self)
 528+/*[clinic end generated code: output=9853eeca2bdd96df input=d39cb2285b557318]*/
 529+{
 530+    char digest[64];
 531+    Py_ssize_t digest_size;
 532+
 533+    ENTER_HASHLIB(self)
 534+    digest_size = br_hmac_out(&self->ctx, digest);
 535+    LEAVE_HASHLIB(self)
 536+
 537+    return PyBytes_FromStringAndSize(digest, digest_size);
 538+}
 539+
 540+/*[clinic input]
 541+_hashlib.HMAC.hexdigest as HMAC_hexdigest
 542+
 543+Return hexadecimal digest of the bytes passed to the update() method so far.
 544+
 545+This may be used to exchange the value safely in email or other non-binary
 546+environments.
 547+[clinic start generated code]*/
 548+
 549+static PyObject *
 550+HMAC_hexdigest_impl(HMAC *self)
 551+/*[clinic end generated code: output=9bb0c7abb6940bab input=2471f22b8dba7433]*/
 552+{
 553+    char digest[64];
 554+    Py_ssize_t digest_size;
 555+
 556+    ENTER_HASHLIB(self)
 557+    digest_size = br_hmac_out(&self->ctx, digest);
 558+    LEAVE_HASHLIB(self)
 559+
 560+    return _Py_strhex(digest, digest_size);
 561+}
 562+
 563+static PyMethodDef HMAC_methods[] = {
 564+    HMAC_UPDATE_METHODDEF
 565+    HMAC_DIGEST_METHODDEF
 566+    HMAC_HEXDIGEST_METHODDEF
 567+    HMAC_COPY_METHODDEF
 568+    {0},
 569+};
 570+
 571+static PyObject *
 572+HMAC_get_digest_size(HMAC *self, void *closure)
 573+{
 574+    const br_hash_class *hc;
 575+    long digest_size;
 576+
 577+    hc = br_hmac_get_digest(&self->ctx);
 578+    digest_size = hc->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK;
 579+    return PyLong_FromLong(digest_size);
 580+}
 581+
 582+static PyObject *
 583+HMAC_get_block_size(HMAC *self, void *closure)
 584+{
 585+    const br_hash_class *hc;
 586+    long block_size;
 587+
 588+    hc = br_hmac_get_digest(&self->ctx);
 589+    block_size = 1 << (hc->desc >> BR_HASHDESC_LBLEN_OFF & BR_HASHDESC_LBLEN_MASK);
 590+    return PyLong_FromLong(block_size);
 591+}
 592+
 593+static PyObject *
 594+HMAC_get_name(HMAC *self, void *closure)
 595+{
 596+    const br_hash_class *hc;
 597+    const char *name = NULL;
 598+
 599+    hc = br_hmac_get_digest(&self->ctx);
 600+    switch (hc->desc >> BR_HASHDESC_ID_OFF & BR_HASHDESC_ID_MASK) {
 601+    case br_md5_ID:    name = "hmac-md5";    break;
 602+    case br_sha1_ID:   name = "hmac-sha1";   break;
 603+    case br_sha224_ID: name = "hmac-sha224"; break;
 604+    case br_sha256_ID: name = "hmac-sha256"; break;
 605+    case br_sha384_ID: name = "hmac-sha384"; break;
 606+    case br_sha512_ID: name = "hmac-sha512"; break;
 607+    }
 608+
 609+    return PyUnicode_FromString(name);
 610+}
 611+
 612+static PyGetSetDef HMAC_getset[] = {
 613+    {"digest_size", (getter)HMAC_get_digest_size, NULL, NULL, NULL},
 614+    {"block_size", (getter)HMAC_get_block_size, NULL, NULL, NULL},
 615+    {"name", (getter)HMAC_get_name, NULL, NULL, NULL},
 616+    {0}
 617+};
 618+
 619+static PyTypeObject HMAC_Type = {
 620+    PyVarObject_HEAD_INIT(NULL, 0)
 621+    .tp_name = "_hashlib.HMAC",
 622+    .tp_dealloc = (destructor)HMAC_dealloc,
 623+    .tp_doc = HMAC_doc,
 624+    .tp_basicsize = sizeof(HMAC),
 625+    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
 626+    .tp_methods = HMAC_methods,
 627+    .tp_getset = HMAC_getset,
 628+};
 629+
 630+static PyObject *
 631+Hash_new_vtable(PyObject *module, const br_hash_class *hc,
 632+                Py_buffer *string, int usedforsecurity)
 633+{
 634+    Hash *self;
 635+
 636+    self = PyObject_New(Hash, &Hash_Type);
 637+    if (!self)
 638+        return NULL;
 639+    self->lock = NULL;
 640+    hc->init(&self->ctx.vtable);
 641+
 642+    if (string->len >= HASHLIB_GIL_MINSIZE) {
 643+        Py_BEGIN_ALLOW_THREADS
 644+        hc->update(&self->ctx.vtable, string->buf, string->len);
 645+        Py_END_ALLOW_THREADS
 646+    } else {
 647+        hc->update(&self->ctx.vtable, string->buf, string->len);
 648+    }
 649+
 650+    return (PyObject *)self;
 651+}
 652+
 653+static PyObject *
 654+SHAKE_new(PyObject *module, int bits, Py_buffer *string, int usedforsecurity)
 655+{
 656+    SHAKE *self;
 657+
 658+    self = PyObject_New(SHAKE, &SHAKE_Type);
 659+    if (!self)
 660+        return NULL;
 661+    self->lock = NULL;
 662+    self->bits = bits;
 663+    br_shake_init(&self->ctx, bits);
 664+
 665+    if (string->len >= HASHLIB_GIL_MINSIZE) {
 666+        Py_BEGIN_ALLOW_THREADS
 667+        br_shake_inject(&self->ctx, string->buf, string->len);
 668+        Py_END_ALLOW_THREADS
 669+    } else {
 670+        br_shake_inject(&self->ctx, string->buf, string->len);
 671+    }
 672+
 673+    return (PyObject *)self;
 674+}
 675+
 676+/*[clinic input]
 677+_hashlib.new
 678+
 679+    name: str
 680+    string: Py_buffer = None
 681+    *
 682+    usedforsecurity: bool = True
 683+
 684+Return a new hash object using the named algorithm.
 685+
 686+An optional string argument may be provided and will be
 687+automatically hashed.
 688+
 689+The MD5 and SHA1 algorithms are always supported.
 690+[clinic start generated code]*/
 691+
 692+static PyObject *
 693+_hashlib_new_impl(PyObject *module, const char *name, Py_buffer *string,
 694+                  int usedforsecurity)
 695+/*[clinic end generated code: output=5459beb11946eb8d input=c7e3a9928c6af923]*/
 696+{
 697+    const br_hash_class *hc = NULL;
 698+    int shake = 0;
 699+
 700+    hc = py_hash_by_name(name);
 701+    if (hc)
 702+        ;
 703+    else if (strcmp(name, "shake_128") == 0)
 704+        shake = 128;
 705+    else if (strcmp(name, "shake_256") == 0)
 706+        shake = 256;
 707+    else {
 708+        PyErr_SetString(PyExc_ValueError, "unsupported hash type");
 709+        return NULL;
 710+    }
 711+
 712+    if (hc)
 713+        return Hash_new_vtable(module, hc, string, usedforsecurity);
 714+    if (shake)
 715+        return SHAKE_new(module, shake, string, usedforsecurity);
 716+}
 717+
 718+/*[clinic input]
 719+_hashlib.openssl_md5
 720+
 721+    string: Py_buffer = None
 722+    *
 723+    usedforsecurity: bool = True
 724+
 725+Returns a md5 hash object; optionally initialized with a string.
 726+[clinic start generated code]*/
 727+
 728+static PyObject *
 729+_hashlib_openssl_md5_impl(PyObject *module, Py_buffer *string,
 730+                          int usedforsecurity)
 731+/*[clinic end generated code: output=bf0df21c3ecd9d85 input=75e59cc38a292e51]*/
 732+{
 733+    return Hash_new_vtable(module, &br_md5_vtable, string, usedforsecurity);
 734+}
 735+
 736+/*[clinic input]
 737+_hashlib.openssl_sha1
 738+
 739+    string: Py_buffer = None
 740+    *
 741+    usedforsecurity: bool = True
 742+
 743+Returns a sha1 hash object; optionally initialized with a string.
 744+[clinic start generated code]*/
 745+
 746+static PyObject *
 747+_hashlib_openssl_sha1_impl(PyObject *module, Py_buffer *string,
 748+                           int usedforsecurity)
 749+/*[clinic end generated code: output=9c468cf3cfdd2e57 input=0f8ad0fa5d988be8]*/
 750+{
 751+    return Hash_new_vtable(module, &br_sha1_vtable, string, usedforsecurity);
 752+}
 753+
 754+/*[clinic input]
 755+_hashlib.openssl_sha224
 756+
 757+    string: Py_buffer = None
 758+    *
 759+    usedforsecurity: bool = True
 760+
 761+Returns a sha224 hash object; optionally initialized with a string.
 762+[clinic start generated code]*/
 763+
 764+static PyObject *
 765+_hashlib_openssl_sha224_impl(PyObject *module, Py_buffer *string,
 766+                             int usedforsecurity)
 767+/*[clinic end generated code: output=9b3fea17aacc8dfe input=21aacab0e6949431]*/
 768+{
 769+    return Hash_new_vtable(module, &br_sha224_vtable, string, usedforsecurity);
 770+}
 771+
 772+/*[clinic input]
 773+_hashlib.openssl_sha256
 774+
 775+    string: Py_buffer = None
 776+    *
 777+    usedforsecurity: bool = True
 778+
 779+Returns a sha256 hash object; optionally initialized with a string.
 780+[clinic start generated code]*/
 781+
 782+static PyObject *
 783+_hashlib_openssl_sha256_impl(PyObject *module, Py_buffer *string,
 784+                             int usedforsecurity)
 785+/*[clinic end generated code: output=2c0585ccc6dfa22a input=81dd291675e0f6c9]*/
 786+{
 787+    return Hash_new_vtable(module, &br_sha256_vtable, string, usedforsecurity);
 788+}
 789+
 790+/*[clinic input]
 791+_hashlib.openssl_sha384
 792+
 793+    string: Py_buffer = None
 794+    *
 795+    usedforsecurity: bool = True
 796+
 797+Returns a sha384 hash object; optionally initialized with a string.
 798+[clinic start generated code]*/
 799+
 800+static PyObject *
 801+_hashlib_openssl_sha384_impl(PyObject *module, Py_buffer *string,
 802+                             int usedforsecurity)
 803+/*[clinic end generated code: output=196d8d7558cfd155 input=eed0b0128dd67969]*/
 804+{
 805+    return Hash_new_vtable(module, &br_sha384_vtable, string, usedforsecurity);
 806+}
 807+
 808+/*[clinic input]
 809+_hashlib.openssl_sha512
 810+
 811+    string: Py_buffer = None
 812+    *
 813+    usedforsecurity: bool = True
 814+
 815+Returns a sha512 hash object; optionally initialized with a string.
 816+[clinic start generated code]*/
 817+
 818+static PyObject *
 819+_hashlib_openssl_sha512_impl(PyObject *module, Py_buffer *string,
 820+                             int usedforsecurity)
 821+/*[clinic end generated code: output=7349b37b20ff6f75 input=da1228b585897043]*/
 822+{
 823+    return Hash_new_vtable(module, &br_sha512_vtable, string, usedforsecurity);
 824+}
 825+
 826+/*[clinic input]
 827+_hashlib.openssl_shake_128
 828+
 829+    string: Py_buffer = None
 830+    *
 831+    usedforsecurity: bool = True
 832+
 833+Returns a shake-128 variable hash object; optionally initialized with a string.
 834+[clinic start generated code]*/
 835+
 836+static PyObject *
 837+_hashlib_openssl_shake_128_impl(PyObject *module, Py_buffer *string,
 838+                                int usedforsecurity)
 839+/*[clinic end generated code: output=e51cc0e4bded887e input=fb6dce24fc91d53d]*/
 840+{
 841+    return SHAKE_new(module, 128, string, usedforsecurity);
 842+}
 843+
 844+/*[clinic input]
 845+_hashlib.openssl_shake_256
 846+
 847+    string: Py_buffer = None
 848+    *
 849+    usedforsecurity: bool = True
 850+
 851+Returns a shake-256 variable hash object; optionally initialized with a string.
 852+[clinic start generated code]*/
 853+
 854+static PyObject *
 855+_hashlib_openssl_shake_256_impl(PyObject *module, Py_buffer *string,
 856+                                int usedforsecurity)
 857+/*[clinic end generated code: output=983a76ff0796751b input=9eb2a133d11e34dc]*/
 858+{
 859+    return SHAKE_new(module, 256, string, usedforsecurity);
 860+}
 861+
 862+static int
 863+_tscmp(const unsigned char *a, const unsigned char *b,
 864+        Py_ssize_t len_a, Py_ssize_t len_b)
 865+{
 866+    /* loop count depends on length of b. Might leak very little timing
 867+     * information if sizes are different.
 868+     */
 869+    Py_ssize_t length = len_b;
 870+    unsigned result = 0;
 871+    size_t i;
 872+
 873+    if (len_a != length) {
 874+        a = b;
 875+        result = 1;
 876+    }
 877+
 878+    for (i = 0; i < length; i++)
 879+        result |= (unsigned)a[i] ^ (unsigned)b[i];
 880+
 881+    return ~(result | -result) >> CHAR_BIT * sizeof(result) - 1;
 882+}
 883+
 884+/*[clinic input]
 885+_hashlib.compare_digest
 886+
 887+    a: object
 888+    b: object
 889+    /
 890+
 891+Return 'a == b'.
 892+
 893+This function uses an approach designed to prevent
 894+timing analysis, making it appropriate for cryptography.
 895+
 896+a and b must both be of the same type: either str (ASCII only),
 897+or any bytes-like object.
 898+
 899+Note: If a and b are of different lengths, or if an error occurs,
 900+a timing attack could theoretically reveal information about the
 901+types and lengths of a and b--but not their values.
 902+[clinic start generated code]*/
 903+
 904+static PyObject *
 905+_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
 906+/*[clinic end generated code: output=6f1c13927480aed9 input=f9cc6da970b1b1d5]*/
 907+{
 908+    int rc;
 909+
 910+    /* ASCII unicode string */
 911+    if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
 912+        if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
 913+            return NULL;
 914+        }
 915+        if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
 916+            PyErr_SetString(PyExc_TypeError,
 917+                            "comparing strings with non-ASCII characters is "
 918+                            "not supported");
 919+            return NULL;
 920+        }
 921+
 922+        rc = _tscmp(PyUnicode_DATA(a),
 923+                    PyUnicode_DATA(b),
 924+                    PyUnicode_GET_LENGTH(a),
 925+                    PyUnicode_GET_LENGTH(b));
 926+    }
 927+    /* fallback to buffer interface for bytes, bytesarray and other */
 928+    else {
 929+        Py_buffer view_a;
 930+        Py_buffer view_b;
 931+
 932+        if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
 933+            PyErr_Format(PyExc_TypeError,
 934+                         "unsupported operand types(s) or combination of types: "
 935+                         "'%.100s' and '%.100s'",
 936+                         Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
 937+            return NULL;
 938+        }
 939+
 940+        if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
 941+            return NULL;
 942+        }
 943+        if (view_a.ndim > 1) {
 944+            PyErr_SetString(PyExc_BufferError,
 945+                            "Buffer must be single dimension");
 946+            PyBuffer_Release(&view_a);
 947+            return NULL;
 948+        }
 949+
 950+        if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
 951+            PyBuffer_Release(&view_a);
 952+            return NULL;
 953+        }
 954+        if (view_b.ndim > 1) {
 955+            PyErr_SetString(PyExc_BufferError,
 956+                            "Buffer must be single dimension");
 957+            PyBuffer_Release(&view_a);
 958+            PyBuffer_Release(&view_b);
 959+            return NULL;
 960+        }
 961+
 962+        rc = _tscmp((const unsigned char*)view_a.buf,
 963+                    (const unsigned char*)view_b.buf,
 964+                    view_a.len,
 965+                    view_b.len);
 966+
 967+        PyBuffer_Release(&view_a);
 968+        PyBuffer_Release(&view_b);
 969+    }
 970+
 971+    return PyBool_FromLong(rc);
 972+}
 973+
 974+static struct PyMethodDef hashlib_methods[] = {
 975+    _HASHLIB_NEW_METHODDEF
 976+    _HASHLIB_HMAC_SINGLESHOT_METHODDEF
 977+    _HASHLIB_HMAC_NEW_METHODDEF
 978+    _HASHLIB_OPENSSL_MD5_METHODDEF
 979+    _HASHLIB_OPENSSL_SHA1_METHODDEF
 980+    _HASHLIB_OPENSSL_SHA224_METHODDEF
 981+    _HASHLIB_OPENSSL_SHA256_METHODDEF
 982+    _HASHLIB_OPENSSL_SHA384_METHODDEF
 983+    _HASHLIB_OPENSSL_SHA512_METHODDEF
 984+    _HASHLIB_OPENSSL_SHAKE_128_METHODDEF
 985+    _HASHLIB_OPENSSL_SHAKE_256_METHODDEF
 986+    _HASHLIB_COMPARE_DIGEST_METHODDEF
 987+    {0}
 988+};
 989+
 990+/* Fast HMAC for hmac.digest() */
 991+
 992+/*[clinic input]
 993+_hashlib.hmac_digest as _hashlib_hmac_singleshot
 994+
 995+    key: Py_buffer
 996+    msg: Py_buffer
 997+    digest: str
 998+
 999+Single-shot HMAC.
1000+[clinic start generated code]*/
1001+
1002+static PyObject *
1003+_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
1004+                              Py_buffer *msg, const char *digest)
1005+/*[clinic end generated code: output=15658ede5ab98185 input=019dffc571909a46]*/
1006+{
1007+    char buf[64];
1008+    Py_ssize_t buf_len;
1009+    br_hmac_context ctx;
1010+    br_hmac_key_context keyctx;
1011+    const br_hash_class *hc;
1012+
1013+    hc = py_hash_by_name(digest);
1014+    if (!hc) {
1015+        PyErr_SetString(PyExc_ValueError, "unsupported hash type");
1016+        return NULL;
1017+    }
1018+    if (msg->len >= HASHLIB_GIL_MINSIZE) {
1019+        Py_BEGIN_ALLOW_THREADS
1020+        br_hmac_key_init(&keyctx, hc, key->buf, key->len);
1021+        br_hmac_init(&ctx, &keyctx, 0);
1022+        br_hmac_update(&ctx, msg->buf, msg->len);
1023+        br_hmac_out(&ctx, buf);
1024+        Py_END_ALLOW_THREADS
1025+    } else {
1026+        br_hmac_key_init(&keyctx, hc, key->buf, key->len);
1027+        br_hmac_init(&ctx, &keyctx, 0);
1028+        br_hmac_update(&ctx, msg->buf, msg->len);
1029+        br_hmac_out(&ctx, buf);
1030+    }
1031+    buf_len = br_hmac_size(&ctx);
1032+
1033+    return PyBytes_FromStringAndSize(buf, buf_len);
1034+}
1035+
1036+/*[clinic input]
1037+_hashlib.hmac_new
1038+
1039+    key: Py_buffer
1040+    msg: Py_buffer = None
1041+    digestmod: str(c_default="NULL") = None
1042+
1043+Return a new hmac object.
1044+[clinic start generated code]*/
1045+
1046+static PyObject *
1047+_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, Py_buffer *msg,
1048+                       const char *digestmod)
1049+/*[clinic end generated code: output=5733a8600554bba2 input=b0125f4222a0d06d]*/
1050+{
1051+    HMAC *self;
1052+    const br_hash_class *hc;
1053+
1054+    printf("hmac new\n");
1055+
1056+    if (!digestmod || !digestmod[0]) {
1057+        PyErr_SetString(
1058+            PyExc_TypeError, "missing required parameter 'digestmod'");
1059+        return NULL;
1060+    }
1061+    hc = py_hash_by_name(digestmod);
1062+    if (!hc) {
1063+        PyErr_SetString(PyExc_ValueError, "unknown hash function");
1064+        return NULL;
1065+    }
1066+    self = PyObject_New(HMAC, &HMAC_Type);
1067+    if (!self)
1068+        return NULL;
1069+    self->lock = NULL;
1070+    br_hmac_key_init(&self->key, hc, key->buf, key->len);
1071+    br_hmac_init(&self->ctx, &self->key, 0);
1072+
1073+    if (msg->len >= HASHLIB_GIL_MINSIZE) {
1074+        Py_BEGIN_ALLOW_THREADS
1075+        br_hmac_update(&self->ctx, msg->buf, msg->len);
1076+        Py_END_ALLOW_THREADS
1077+    } else {
1078+        br_hmac_update(&self->ctx, msg->buf, msg->len);
1079+    }
1080+
1081+    return (PyObject *)self;
1082+}
1083+
1084+static struct PyModuleDef _hashlibmodule = {
1085+    PyModuleDef_HEAD_INIT,
1086+    .m_name = "_hashlib",
1087+    .m_doc = "BearSSL interface for hashlib module",
1088+    .m_methods = hashlib_methods,
1089+};
1090+
1091+PyMODINIT_FUNC
1092+PyInit__hashlib(void)
1093+{
1094+    PyObject *m = NULL, *set = NULL, *name;
1095+    static const char *const names[] = {
1096+        "md5",
1097+        "sha1",
1098+        "sha224",
1099+        "sha256",
1100+        "sha384",
1101+        "sha512",
1102+        "shake_128",
1103+        "shake_256",
1104+    };
1105+    int r;
1106+
1107+    m = PyState_FindModule(&_hashlibmodule);
1108+    if (m) {
1109+        Py_INCREF(m);
1110+        return m;
1111+    }
1112+    m = PyModule_Create(&_hashlibmodule);
1113+    if (!m)
1114+        goto err;
1115+    if (PyModule_AddType(m, &Hash_Type) < 0)
1116+        goto err;
1117+    if (PyModule_AddType(m, &SHAKE_Type) < 0)
1118+        goto err;
1119+    if (PyModule_AddType(m, &HMAC_Type) < 0)
1120+        goto err;
1121+    set = PyFrozenSet_New(NULL);
1122+    if (!set)
1123+        goto err;
1124+    for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
1125+        name = PyUnicode_FromString(names[i]);
1126+        if (!name)
1127+            goto err;
1128+        r = PySet_Add(set, name);
1129+        Py_DECREF(name);
1130+        if (r != 0)
1131+            goto err;
1132+    }
1133+    if (PyModule_AddObject(m, "openssl_md_meth_names", set) < 0)
1134+        goto err;
1135+
1136+    return m;
1137+
1138+  err:
1139+    if (set)
1140+        Py_DECREF(set);
1141+    if (m)
1142+        Py_DECREF(m);
1143+    return NULL;
1144+}
1145diff --git a/Modules/clinic/_hashbearssl.c.h b/Modules/clinic/_hashbearssl.c.h
1146new file mode 100644
1147index 0000000000..49bf8f9287
1148--- /dev/null
1149+++ b/Modules/clinic/_hashbearssl.c.h
1150@@ -0,0 +1,1113 @@
1151+/*[clinic input]
1152+preserve
1153+[clinic start generated code]*/
1154+
1155+PyDoc_STRVAR(Hash_update__doc__,
1156+"update($self, data, /)\n"
1157+"--\n"
1158+"\n"
1159+"Update this hash object\'s state with the provided string.");
1160+
1161+#define HASH_UPDATE_METHODDEF    \
1162+    {"update", (PyCFunction)Hash_update, METH_O, Hash_update__doc__},
1163+
1164+static PyObject *
1165+Hash_update_impl(Hash *self, Py_buffer *data);
1166+
1167+static PyObject *
1168+Hash_update(Hash *self, PyObject *arg)
1169+{
1170+    PyObject *return_value = NULL;
1171+    Py_buffer data = {NULL, NULL};
1172+
1173+    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
1174+        goto exit;
1175+    }
1176+    if (!PyBuffer_IsContiguous(&data, 'C')) {
1177+        _PyArg_BadArgument("update", "argument", "contiguous buffer", arg);
1178+        goto exit;
1179+    }
1180+    return_value = Hash_update_impl(self, &data);
1181+
1182+exit:
1183+    /* Cleanup for data */
1184+    if (data.obj) {
1185+       PyBuffer_Release(&data);
1186+    }
1187+
1188+    return return_value;
1189+}
1190+
1191+PyDoc_STRVAR(Hash_digest__doc__,
1192+"digest($self, /)\n"
1193+"--\n"
1194+"\n"
1195+"Return the digest value as a bytes object.");
1196+
1197+#define HASH_DIGEST_METHODDEF    \
1198+    {"digest", (PyCFunction)Hash_digest, METH_NOARGS, Hash_digest__doc__},
1199+
1200+static PyObject *
1201+Hash_digest_impl(Hash *self);
1202+
1203+static PyObject *
1204+Hash_digest(Hash *self, PyObject *Py_UNUSED(ignored))
1205+{
1206+    return Hash_digest_impl(self);
1207+}
1208+
1209+PyDoc_STRVAR(Hash_hexdigest__doc__,
1210+"hexdigest($self, /)\n"
1211+"--\n"
1212+"\n"
1213+"Return the digest value as a string of hexadecimal digits.");
1214+
1215+#define HASH_HEXDIGEST_METHODDEF    \
1216+    {"hexdigest", (PyCFunction)Hash_hexdigest, METH_NOARGS, Hash_hexdigest__doc__},
1217+
1218+static PyObject *
1219+Hash_hexdigest_impl(Hash *self);
1220+
1221+static PyObject *
1222+Hash_hexdigest(Hash *self, PyObject *Py_UNUSED(ignored))
1223+{
1224+    return Hash_hexdigest_impl(self);
1225+}
1226+
1227+PyDoc_STRVAR(Hash_copy__doc__,
1228+"copy($self, /)\n"
1229+"--\n"
1230+"\n"
1231+"Return a copy of the hash object.");
1232+
1233+#define HASH_COPY_METHODDEF    \
1234+    {"copy", (PyCFunction)Hash_copy, METH_NOARGS, Hash_copy__doc__},
1235+
1236+static PyObject *
1237+Hash_copy_impl(Hash *self);
1238+
1239+static PyObject *
1240+Hash_copy(Hash *self, PyObject *Py_UNUSED(ignored))
1241+{
1242+    return Hash_copy_impl(self);
1243+}
1244+
1245+PyDoc_STRVAR(SHAKE_update__doc__,
1246+"update($self, data, /)\n"
1247+"--\n"
1248+"\n"
1249+"Update this hash object\'s state with the provided string.");
1250+
1251+#define SHAKE_UPDATE_METHODDEF    \
1252+    {"update", (PyCFunction)SHAKE_update, METH_O, SHAKE_update__doc__},
1253+
1254+static PyObject *
1255+SHAKE_update_impl(SHAKE *self, Py_buffer *data);
1256+
1257+static PyObject *
1258+SHAKE_update(SHAKE *self, PyObject *arg)
1259+{
1260+    PyObject *return_value = NULL;
1261+    Py_buffer data = {NULL, NULL};
1262+
1263+    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
1264+        goto exit;
1265+    }
1266+    if (!PyBuffer_IsContiguous(&data, 'C')) {
1267+        _PyArg_BadArgument("update", "argument", "contiguous buffer", arg);
1268+        goto exit;
1269+    }
1270+    return_value = SHAKE_update_impl(self, &data);
1271+
1272+exit:
1273+    /* Cleanup for data */
1274+    if (data.obj) {
1275+       PyBuffer_Release(&data);
1276+    }
1277+
1278+    return return_value;
1279+}
1280+
1281+PyDoc_STRVAR(SHAKE_digest__doc__,
1282+"digest($self, /, length)\n"
1283+"--\n"
1284+"\n"
1285+"Return the digest value as a bytes object.");
1286+
1287+#define SHAKE_DIGEST_METHODDEF    \
1288+    {"digest", (PyCFunction)(void(*)(void))SHAKE_digest, METH_FASTCALL|METH_KEYWORDS, SHAKE_digest__doc__},
1289+
1290+static PyObject *
1291+SHAKE_digest_impl(SHAKE *self, Py_ssize_t length);
1292+
1293+static PyObject *
1294+SHAKE_digest(SHAKE *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1295+{
1296+    PyObject *return_value = NULL;
1297+    static const char * const _keywords[] = {"length", NULL};
1298+    static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0};
1299+    PyObject *argsbuf[1];
1300+    Py_ssize_t length;
1301+
1302+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
1303+    if (!args) {
1304+        goto exit;
1305+    }
1306+    if (PyFloat_Check(args[0])) {
1307+        PyErr_SetString(PyExc_TypeError,
1308+                        "integer argument expected, got float" );
1309+        goto exit;
1310+    }
1311+    {
1312+        Py_ssize_t ival = -1;
1313+        PyObject *iobj = PyNumber_Index(args[0]);
1314+        if (iobj != NULL) {
1315+            ival = PyLong_AsSsize_t(iobj);
1316+            Py_DECREF(iobj);
1317+        }
1318+        if (ival == -1 && PyErr_Occurred()) {
1319+            goto exit;
1320+        }
1321+        length = ival;
1322+    }
1323+    return_value = SHAKE_digest_impl(self, length);
1324+
1325+exit:
1326+    return return_value;
1327+}
1328+
1329+PyDoc_STRVAR(SHAKE_hexdigest__doc__,
1330+"hexdigest($self, /, length)\n"
1331+"--\n"
1332+"\n"
1333+"Return the digest value as a string of hexadecimal digits.");
1334+
1335+#define SHAKE_HEXDIGEST_METHODDEF    \
1336+    {"hexdigest", (PyCFunction)(void(*)(void))SHAKE_hexdigest, METH_FASTCALL|METH_KEYWORDS, SHAKE_hexdigest__doc__},
1337+
1338+static PyObject *
1339+SHAKE_hexdigest_impl(SHAKE *self, Py_ssize_t length);
1340+
1341+static PyObject *
1342+SHAKE_hexdigest(SHAKE *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1343+{
1344+    PyObject *return_value = NULL;
1345+    static const char * const _keywords[] = {"length", NULL};
1346+    static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0};
1347+    PyObject *argsbuf[1];
1348+    Py_ssize_t length;
1349+
1350+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
1351+    if (!args) {
1352+        goto exit;
1353+    }
1354+    if (PyFloat_Check(args[0])) {
1355+        PyErr_SetString(PyExc_TypeError,
1356+                        "integer argument expected, got float" );
1357+        goto exit;
1358+    }
1359+    {
1360+        Py_ssize_t ival = -1;
1361+        PyObject *iobj = PyNumber_Index(args[0]);
1362+        if (iobj != NULL) {
1363+            ival = PyLong_AsSsize_t(iobj);
1364+            Py_DECREF(iobj);
1365+        }
1366+        if (ival == -1 && PyErr_Occurred()) {
1367+            goto exit;
1368+        }
1369+        length = ival;
1370+    }
1371+    return_value = SHAKE_hexdigest_impl(self, length);
1372+
1373+exit:
1374+    return return_value;
1375+}
1376+
1377+PyDoc_STRVAR(SHAKE_copy__doc__,
1378+"copy($self, /)\n"
1379+"--\n"
1380+"\n"
1381+"Return a copy of the SHAKE object.");
1382+
1383+#define SHAKE_COPY_METHODDEF    \
1384+    {"copy", (PyCFunction)SHAKE_copy, METH_NOARGS, SHAKE_copy__doc__},
1385+
1386+static PyObject *
1387+SHAKE_copy_impl(SHAKE *self);
1388+
1389+static PyObject *
1390+SHAKE_copy(SHAKE *self, PyObject *Py_UNUSED(ignored))
1391+{
1392+    return SHAKE_copy_impl(self);
1393+}
1394+
1395+PyDoc_STRVAR(HMAC_copy__doc__,
1396+"copy($self, /)\n"
1397+"--\n"
1398+"\n"
1399+"Return a copy of the HMAC object.");
1400+
1401+#define HMAC_COPY_METHODDEF    \
1402+    {"copy", (PyCFunction)HMAC_copy, METH_NOARGS, HMAC_copy__doc__},
1403+
1404+static PyObject *
1405+HMAC_copy_impl(HMAC *self);
1406+
1407+static PyObject *
1408+HMAC_copy(HMAC *self, PyObject *Py_UNUSED(ignored))
1409+{
1410+    return HMAC_copy_impl(self);
1411+}
1412+
1413+PyDoc_STRVAR(HMAC_update__doc__,
1414+"update($self, data, /)\n"
1415+"--\n"
1416+"\n"
1417+"Update the HMAC object with data.");
1418+
1419+#define HMAC_UPDATE_METHODDEF    \
1420+    {"update", (PyCFunction)HMAC_update, METH_O, HMAC_update__doc__},
1421+
1422+static PyObject *
1423+HMAC_update_impl(HMAC *self, Py_buffer *data);
1424+
1425+static PyObject *
1426+HMAC_update(HMAC *self, PyObject *arg)
1427+{
1428+    PyObject *return_value = NULL;
1429+    Py_buffer data = {NULL, NULL};
1430+
1431+    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
1432+        goto exit;
1433+    }
1434+    if (!PyBuffer_IsContiguous(&data, 'C')) {
1435+        _PyArg_BadArgument("update", "argument", "contiguous buffer", arg);
1436+        goto exit;
1437+    }
1438+    return_value = HMAC_update_impl(self, &data);
1439+
1440+exit:
1441+    /* Cleanup for data */
1442+    if (data.obj) {
1443+       PyBuffer_Release(&data);
1444+    }
1445+
1446+    return return_value;
1447+}
1448+
1449+PyDoc_STRVAR(HMAC_digest__doc__,
1450+"digest($self, /)\n"
1451+"--\n"
1452+"\n"
1453+"Return the digest of the bytes passed to the update() method so far.");
1454+
1455+#define HMAC_DIGEST_METHODDEF    \
1456+    {"digest", (PyCFunction)HMAC_digest, METH_NOARGS, HMAC_digest__doc__},
1457+
1458+static PyObject *
1459+HMAC_digest_impl(HMAC *self);
1460+
1461+static PyObject *
1462+HMAC_digest(HMAC *self, PyObject *Py_UNUSED(ignored))
1463+{
1464+    return HMAC_digest_impl(self);
1465+}
1466+
1467+PyDoc_STRVAR(HMAC_hexdigest__doc__,
1468+"hexdigest($self, /)\n"
1469+"--\n"
1470+"\n"
1471+"Return hexadecimal digest of the bytes passed to the update() method so far.\n"
1472+"\n"
1473+"This may be used to exchange the value safely in email or other non-binary\n"
1474+"environments.");
1475+
1476+#define HMAC_HEXDIGEST_METHODDEF    \
1477+    {"hexdigest", (PyCFunction)HMAC_hexdigest, METH_NOARGS, HMAC_hexdigest__doc__},
1478+
1479+static PyObject *
1480+HMAC_hexdigest_impl(HMAC *self);
1481+
1482+static PyObject *
1483+HMAC_hexdigest(HMAC *self, PyObject *Py_UNUSED(ignored))
1484+{
1485+    return HMAC_hexdigest_impl(self);
1486+}
1487+
1488+PyDoc_STRVAR(_hashlib_new__doc__,
1489+"new($module, /, name, string=None, *, usedforsecurity=True)\n"
1490+"--\n"
1491+"\n"
1492+"Return a new hash object using the named algorithm.\n"
1493+"\n"
1494+"An optional string argument may be provided and will be\n"
1495+"automatically hashed.\n"
1496+"\n"
1497+"The MD5 and SHA1 algorithms are always supported.");
1498+
1499+#define _HASHLIB_NEW_METHODDEF    \
1500+    {"new", (PyCFunction)(void(*)(void))_hashlib_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_new__doc__},
1501+
1502+static PyObject *
1503+_hashlib_new_impl(PyObject *module, const char *name, Py_buffer *string,
1504+                  int usedforsecurity);
1505+
1506+static PyObject *
1507+_hashlib_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1508+{
1509+    PyObject *return_value = NULL;
1510+    static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL};
1511+    static _PyArg_Parser _parser = {NULL, _keywords, "new", 0};
1512+    PyObject *argsbuf[3];
1513+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
1514+    const char *name;
1515+    Py_buffer string = {NULL, NULL};
1516+    int usedforsecurity = 1;
1517+
1518+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
1519+    if (!args) {
1520+        goto exit;
1521+    }
1522+    if (!PyUnicode_Check(args[0])) {
1523+        _PyArg_BadArgument("new", "argument 'name'", "str", args[0]);
1524+        goto exit;
1525+    }
1526+    Py_ssize_t name_length;
1527+    name = PyUnicode_AsUTF8AndSize(args[0], &name_length);
1528+    if (name == NULL) {
1529+        goto exit;
1530+    }
1531+    if (strlen(name) != (size_t)name_length) {
1532+        PyErr_SetString(PyExc_ValueError, "embedded null character");
1533+        goto exit;
1534+    }
1535+    if (!noptargs) {
1536+        goto skip_optional_pos;
1537+    }
1538+    if (args[1]) {
1539+        if (PyObject_GetBuffer(args[1], &string, PyBUF_SIMPLE) != 0) {
1540+            goto exit;
1541+        }
1542+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1543+            _PyArg_BadArgument("new", "argument 'string'", "contiguous buffer", args[1]);
1544+            goto exit;
1545+        }
1546+        if (!--noptargs) {
1547+            goto skip_optional_pos;
1548+        }
1549+    }
1550+skip_optional_pos:
1551+    if (!noptargs) {
1552+        goto skip_optional_kwonly;
1553+    }
1554+    usedforsecurity = PyObject_IsTrue(args[2]);
1555+    if (usedforsecurity < 0) {
1556+        goto exit;
1557+    }
1558+skip_optional_kwonly:
1559+    return_value = _hashlib_new_impl(module, name, &string, usedforsecurity);
1560+
1561+exit:
1562+    /* Cleanup for string */
1563+    if (string.obj) {
1564+       PyBuffer_Release(&string);
1565+    }
1566+
1567+    return return_value;
1568+}
1569+
1570+PyDoc_STRVAR(_hashlib_openssl_md5__doc__,
1571+"openssl_md5($module, /, string=None, *, usedforsecurity=True)\n"
1572+"--\n"
1573+"\n"
1574+"Returns a md5 hash object; optionally initialized with a string.");
1575+
1576+#define _HASHLIB_OPENSSL_MD5_METHODDEF    \
1577+    {"openssl_md5", (PyCFunction)(void(*)(void))_hashlib_openssl_md5, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__},
1578+
1579+static PyObject *
1580+_hashlib_openssl_md5_impl(PyObject *module, Py_buffer *string,
1581+                          int usedforsecurity);
1582+
1583+static PyObject *
1584+_hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1585+{
1586+    PyObject *return_value = NULL;
1587+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1588+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0};
1589+    PyObject *argsbuf[2];
1590+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1591+    Py_buffer string = {NULL, NULL};
1592+    int usedforsecurity = 1;
1593+
1594+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1595+    if (!args) {
1596+        goto exit;
1597+    }
1598+    if (!noptargs) {
1599+        goto skip_optional_pos;
1600+    }
1601+    if (args[0]) {
1602+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1603+            goto exit;
1604+        }
1605+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1606+            _PyArg_BadArgument("openssl_md5", "argument 'string'", "contiguous buffer", args[0]);
1607+            goto exit;
1608+        }
1609+        if (!--noptargs) {
1610+            goto skip_optional_pos;
1611+        }
1612+    }
1613+skip_optional_pos:
1614+    if (!noptargs) {
1615+        goto skip_optional_kwonly;
1616+    }
1617+    usedforsecurity = PyObject_IsTrue(args[1]);
1618+    if (usedforsecurity < 0) {
1619+        goto exit;
1620+    }
1621+skip_optional_kwonly:
1622+    return_value = _hashlib_openssl_md5_impl(module, &string, usedforsecurity);
1623+
1624+exit:
1625+    /* Cleanup for string */
1626+    if (string.obj) {
1627+       PyBuffer_Release(&string);
1628+    }
1629+
1630+    return return_value;
1631+}
1632+
1633+PyDoc_STRVAR(_hashlib_openssl_sha1__doc__,
1634+"openssl_sha1($module, /, string=None, *, usedforsecurity=True)\n"
1635+"--\n"
1636+"\n"
1637+"Returns a sha1 hash object; optionally initialized with a string.");
1638+
1639+#define _HASHLIB_OPENSSL_SHA1_METHODDEF    \
1640+    {"openssl_sha1", (PyCFunction)(void(*)(void))_hashlib_openssl_sha1, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__},
1641+
1642+static PyObject *
1643+_hashlib_openssl_sha1_impl(PyObject *module, Py_buffer *string,
1644+                           int usedforsecurity);
1645+
1646+static PyObject *
1647+_hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1648+{
1649+    PyObject *return_value = NULL;
1650+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1651+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0};
1652+    PyObject *argsbuf[2];
1653+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1654+    Py_buffer string = {NULL, NULL};
1655+    int usedforsecurity = 1;
1656+
1657+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1658+    if (!args) {
1659+        goto exit;
1660+    }
1661+    if (!noptargs) {
1662+        goto skip_optional_pos;
1663+    }
1664+    if (args[0]) {
1665+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1666+            goto exit;
1667+        }
1668+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1669+            _PyArg_BadArgument("openssl_sha1", "argument 'string'", "contiguous buffer", args[0]);
1670+            goto exit;
1671+        }
1672+        if (!--noptargs) {
1673+            goto skip_optional_pos;
1674+        }
1675+    }
1676+skip_optional_pos:
1677+    if (!noptargs) {
1678+        goto skip_optional_kwonly;
1679+    }
1680+    usedforsecurity = PyObject_IsTrue(args[1]);
1681+    if (usedforsecurity < 0) {
1682+        goto exit;
1683+    }
1684+skip_optional_kwonly:
1685+    return_value = _hashlib_openssl_sha1_impl(module, &string, usedforsecurity);
1686+
1687+exit:
1688+    /* Cleanup for string */
1689+    if (string.obj) {
1690+       PyBuffer_Release(&string);
1691+    }
1692+
1693+    return return_value;
1694+}
1695+
1696+PyDoc_STRVAR(_hashlib_openssl_sha224__doc__,
1697+"openssl_sha224($module, /, string=None, *, usedforsecurity=True)\n"
1698+"--\n"
1699+"\n"
1700+"Returns a sha224 hash object; optionally initialized with a string.");
1701+
1702+#define _HASHLIB_OPENSSL_SHA224_METHODDEF    \
1703+    {"openssl_sha224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__},
1704+
1705+static PyObject *
1706+_hashlib_openssl_sha224_impl(PyObject *module, Py_buffer *string,
1707+                             int usedforsecurity);
1708+
1709+static PyObject *
1710+_hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1711+{
1712+    PyObject *return_value = NULL;
1713+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1714+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0};
1715+    PyObject *argsbuf[2];
1716+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1717+    Py_buffer string = {NULL, NULL};
1718+    int usedforsecurity = 1;
1719+
1720+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1721+    if (!args) {
1722+        goto exit;
1723+    }
1724+    if (!noptargs) {
1725+        goto skip_optional_pos;
1726+    }
1727+    if (args[0]) {
1728+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1729+            goto exit;
1730+        }
1731+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1732+            _PyArg_BadArgument("openssl_sha224", "argument 'string'", "contiguous buffer", args[0]);
1733+            goto exit;
1734+        }
1735+        if (!--noptargs) {
1736+            goto skip_optional_pos;
1737+        }
1738+    }
1739+skip_optional_pos:
1740+    if (!noptargs) {
1741+        goto skip_optional_kwonly;
1742+    }
1743+    usedforsecurity = PyObject_IsTrue(args[1]);
1744+    if (usedforsecurity < 0) {
1745+        goto exit;
1746+    }
1747+skip_optional_kwonly:
1748+    return_value = _hashlib_openssl_sha224_impl(module, &string, usedforsecurity);
1749+
1750+exit:
1751+    /* Cleanup for string */
1752+    if (string.obj) {
1753+       PyBuffer_Release(&string);
1754+    }
1755+
1756+    return return_value;
1757+}
1758+
1759+PyDoc_STRVAR(_hashlib_openssl_sha256__doc__,
1760+"openssl_sha256($module, /, string=None, *, usedforsecurity=True)\n"
1761+"--\n"
1762+"\n"
1763+"Returns a sha256 hash object; optionally initialized with a string.");
1764+
1765+#define _HASHLIB_OPENSSL_SHA256_METHODDEF    \
1766+    {"openssl_sha256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__},
1767+
1768+static PyObject *
1769+_hashlib_openssl_sha256_impl(PyObject *module, Py_buffer *string,
1770+                             int usedforsecurity);
1771+
1772+static PyObject *
1773+_hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1774+{
1775+    PyObject *return_value = NULL;
1776+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1777+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0};
1778+    PyObject *argsbuf[2];
1779+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1780+    Py_buffer string = {NULL, NULL};
1781+    int usedforsecurity = 1;
1782+
1783+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1784+    if (!args) {
1785+        goto exit;
1786+    }
1787+    if (!noptargs) {
1788+        goto skip_optional_pos;
1789+    }
1790+    if (args[0]) {
1791+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1792+            goto exit;
1793+        }
1794+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1795+            _PyArg_BadArgument("openssl_sha256", "argument 'string'", "contiguous buffer", args[0]);
1796+            goto exit;
1797+        }
1798+        if (!--noptargs) {
1799+            goto skip_optional_pos;
1800+        }
1801+    }
1802+skip_optional_pos:
1803+    if (!noptargs) {
1804+        goto skip_optional_kwonly;
1805+    }
1806+    usedforsecurity = PyObject_IsTrue(args[1]);
1807+    if (usedforsecurity < 0) {
1808+        goto exit;
1809+    }
1810+skip_optional_kwonly:
1811+    return_value = _hashlib_openssl_sha256_impl(module, &string, usedforsecurity);
1812+
1813+exit:
1814+    /* Cleanup for string */
1815+    if (string.obj) {
1816+       PyBuffer_Release(&string);
1817+    }
1818+
1819+    return return_value;
1820+}
1821+
1822+PyDoc_STRVAR(_hashlib_openssl_sha384__doc__,
1823+"openssl_sha384($module, /, string=None, *, usedforsecurity=True)\n"
1824+"--\n"
1825+"\n"
1826+"Returns a sha384 hash object; optionally initialized with a string.");
1827+
1828+#define _HASHLIB_OPENSSL_SHA384_METHODDEF    \
1829+    {"openssl_sha384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__},
1830+
1831+static PyObject *
1832+_hashlib_openssl_sha384_impl(PyObject *module, Py_buffer *string,
1833+                             int usedforsecurity);
1834+
1835+static PyObject *
1836+_hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1837+{
1838+    PyObject *return_value = NULL;
1839+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1840+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0};
1841+    PyObject *argsbuf[2];
1842+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1843+    Py_buffer string = {NULL, NULL};
1844+    int usedforsecurity = 1;
1845+
1846+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1847+    if (!args) {
1848+        goto exit;
1849+    }
1850+    if (!noptargs) {
1851+        goto skip_optional_pos;
1852+    }
1853+    if (args[0]) {
1854+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1855+            goto exit;
1856+        }
1857+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1858+            _PyArg_BadArgument("openssl_sha384", "argument 'string'", "contiguous buffer", args[0]);
1859+            goto exit;
1860+        }
1861+        if (!--noptargs) {
1862+            goto skip_optional_pos;
1863+        }
1864+    }
1865+skip_optional_pos:
1866+    if (!noptargs) {
1867+        goto skip_optional_kwonly;
1868+    }
1869+    usedforsecurity = PyObject_IsTrue(args[1]);
1870+    if (usedforsecurity < 0) {
1871+        goto exit;
1872+    }
1873+skip_optional_kwonly:
1874+    return_value = _hashlib_openssl_sha384_impl(module, &string, usedforsecurity);
1875+
1876+exit:
1877+    /* Cleanup for string */
1878+    if (string.obj) {
1879+       PyBuffer_Release(&string);
1880+    }
1881+
1882+    return return_value;
1883+}
1884+
1885+PyDoc_STRVAR(_hashlib_openssl_sha512__doc__,
1886+"openssl_sha512($module, /, string=None, *, usedforsecurity=True)\n"
1887+"--\n"
1888+"\n"
1889+"Returns a sha512 hash object; optionally initialized with a string.");
1890+
1891+#define _HASHLIB_OPENSSL_SHA512_METHODDEF    \
1892+    {"openssl_sha512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__},
1893+
1894+static PyObject *
1895+_hashlib_openssl_sha512_impl(PyObject *module, Py_buffer *string,
1896+                             int usedforsecurity);
1897+
1898+static PyObject *
1899+_hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1900+{
1901+    PyObject *return_value = NULL;
1902+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1903+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0};
1904+    PyObject *argsbuf[2];
1905+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1906+    Py_buffer string = {NULL, NULL};
1907+    int usedforsecurity = 1;
1908+
1909+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1910+    if (!args) {
1911+        goto exit;
1912+    }
1913+    if (!noptargs) {
1914+        goto skip_optional_pos;
1915+    }
1916+    if (args[0]) {
1917+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1918+            goto exit;
1919+        }
1920+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1921+            _PyArg_BadArgument("openssl_sha512", "argument 'string'", "contiguous buffer", args[0]);
1922+            goto exit;
1923+        }
1924+        if (!--noptargs) {
1925+            goto skip_optional_pos;
1926+        }
1927+    }
1928+skip_optional_pos:
1929+    if (!noptargs) {
1930+        goto skip_optional_kwonly;
1931+    }
1932+    usedforsecurity = PyObject_IsTrue(args[1]);
1933+    if (usedforsecurity < 0) {
1934+        goto exit;
1935+    }
1936+skip_optional_kwonly:
1937+    return_value = _hashlib_openssl_sha512_impl(module, &string, usedforsecurity);
1938+
1939+exit:
1940+    /* Cleanup for string */
1941+    if (string.obj) {
1942+       PyBuffer_Release(&string);
1943+    }
1944+
1945+    return return_value;
1946+}
1947+
1948+PyDoc_STRVAR(_hashlib_openssl_shake_128__doc__,
1949+"openssl_shake_128($module, /, string=None, *, usedforsecurity=True)\n"
1950+"--\n"
1951+"\n"
1952+"Returns a shake-128 variable hash object; optionally initialized with a string.");
1953+
1954+#define _HASHLIB_OPENSSL_SHAKE_128_METHODDEF    \
1955+    {"openssl_shake_128", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_128, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_128__doc__},
1956+
1957+static PyObject *
1958+_hashlib_openssl_shake_128_impl(PyObject *module, Py_buffer *string,
1959+                                int usedforsecurity);
1960+
1961+static PyObject *
1962+_hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
1963+{
1964+    PyObject *return_value = NULL;
1965+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
1966+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_128", 0};
1967+    PyObject *argsbuf[2];
1968+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
1969+    Py_buffer string = {NULL, NULL};
1970+    int usedforsecurity = 1;
1971+
1972+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
1973+    if (!args) {
1974+        goto exit;
1975+    }
1976+    if (!noptargs) {
1977+        goto skip_optional_pos;
1978+    }
1979+    if (args[0]) {
1980+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
1981+            goto exit;
1982+        }
1983+        if (!PyBuffer_IsContiguous(&string, 'C')) {
1984+            _PyArg_BadArgument("openssl_shake_128", "argument 'string'", "contiguous buffer", args[0]);
1985+            goto exit;
1986+        }
1987+        if (!--noptargs) {
1988+            goto skip_optional_pos;
1989+        }
1990+    }
1991+skip_optional_pos:
1992+    if (!noptargs) {
1993+        goto skip_optional_kwonly;
1994+    }
1995+    usedforsecurity = PyObject_IsTrue(args[1]);
1996+    if (usedforsecurity < 0) {
1997+        goto exit;
1998+    }
1999+skip_optional_kwonly:
2000+    return_value = _hashlib_openssl_shake_128_impl(module, &string, usedforsecurity);
2001+
2002+exit:
2003+    /* Cleanup for string */
2004+    if (string.obj) {
2005+       PyBuffer_Release(&string);
2006+    }
2007+
2008+    return return_value;
2009+}
2010+
2011+PyDoc_STRVAR(_hashlib_openssl_shake_256__doc__,
2012+"openssl_shake_256($module, /, string=None, *, usedforsecurity=True)\n"
2013+"--\n"
2014+"\n"
2015+"Returns a shake-256 variable hash object; optionally initialized with a string.");
2016+
2017+#define _HASHLIB_OPENSSL_SHAKE_256_METHODDEF    \
2018+    {"openssl_shake_256", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_256__doc__},
2019+
2020+static PyObject *
2021+_hashlib_openssl_shake_256_impl(PyObject *module, Py_buffer *string,
2022+                                int usedforsecurity);
2023+
2024+static PyObject *
2025+_hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
2026+{
2027+    PyObject *return_value = NULL;
2028+    static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
2029+    static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_256", 0};
2030+    PyObject *argsbuf[2];
2031+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
2032+    Py_buffer string = {NULL, NULL};
2033+    int usedforsecurity = 1;
2034+
2035+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
2036+    if (!args) {
2037+        goto exit;
2038+    }
2039+    if (!noptargs) {
2040+        goto skip_optional_pos;
2041+    }
2042+    if (args[0]) {
2043+        if (PyObject_GetBuffer(args[0], &string, PyBUF_SIMPLE) != 0) {
2044+            goto exit;
2045+        }
2046+        if (!PyBuffer_IsContiguous(&string, 'C')) {
2047+            _PyArg_BadArgument("openssl_shake_256", "argument 'string'", "contiguous buffer", args[0]);
2048+            goto exit;
2049+        }
2050+        if (!--noptargs) {
2051+            goto skip_optional_pos;
2052+        }
2053+    }
2054+skip_optional_pos:
2055+    if (!noptargs) {
2056+        goto skip_optional_kwonly;
2057+    }
2058+    usedforsecurity = PyObject_IsTrue(args[1]);
2059+    if (usedforsecurity < 0) {
2060+        goto exit;
2061+    }
2062+skip_optional_kwonly:
2063+    return_value = _hashlib_openssl_shake_256_impl(module, &string, usedforsecurity);
2064+
2065+exit:
2066+    /* Cleanup for string */
2067+    if (string.obj) {
2068+       PyBuffer_Release(&string);
2069+    }
2070+
2071+    return return_value;
2072+}
2073+
2074+PyDoc_STRVAR(_hashlib_compare_digest__doc__,
2075+"compare_digest($module, a, b, /)\n"
2076+"--\n"
2077+"\n"
2078+"Return \'a == b\'.\n"
2079+"\n"
2080+"This function uses an approach designed to prevent\n"
2081+"timing analysis, making it appropriate for cryptography.\n"
2082+"\n"
2083+"a and b must both be of the same type: either str (ASCII only),\n"
2084+"or any bytes-like object.\n"
2085+"\n"
2086+"Note: If a and b are of different lengths, or if an error occurs,\n"
2087+"a timing attack could theoretically reveal information about the\n"
2088+"types and lengths of a and b--but not their values.");
2089+
2090+#define _HASHLIB_COMPARE_DIGEST_METHODDEF    \
2091+    {"compare_digest", (PyCFunction)(void(*)(void))_hashlib_compare_digest, METH_FASTCALL, _hashlib_compare_digest__doc__},
2092+
2093+static PyObject *
2094+_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b);
2095+
2096+static PyObject *
2097+_hashlib_compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
2098+{
2099+    PyObject *return_value = NULL;
2100+    PyObject *a;
2101+    PyObject *b;
2102+
2103+    if (!_PyArg_CheckPositional("compare_digest", nargs, 2, 2)) {
2104+        goto exit;
2105+    }
2106+    a = args[0];
2107+    b = args[1];
2108+    return_value = _hashlib_compare_digest_impl(module, a, b);
2109+
2110+exit:
2111+    return return_value;
2112+}
2113+
2114+PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__,
2115+"hmac_digest($module, /, key, msg, digest)\n"
2116+"--\n"
2117+"\n"
2118+"Single-shot HMAC.");
2119+
2120+#define _HASHLIB_HMAC_SINGLESHOT_METHODDEF    \
2121+    {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_singleshot, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__},
2122+
2123+static PyObject *
2124+_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
2125+                              Py_buffer *msg, const char *digest);
2126+
2127+static PyObject *
2128+_hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
2129+{
2130+    PyObject *return_value = NULL;
2131+    static const char * const _keywords[] = {"key", "msg", "digest", NULL};
2132+    static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0};
2133+    PyObject *argsbuf[3];
2134+    Py_buffer key = {NULL, NULL};
2135+    Py_buffer msg = {NULL, NULL};
2136+    const char *digest;
2137+
2138+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf);
2139+    if (!args) {
2140+        goto exit;
2141+    }
2142+    if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) {
2143+        goto exit;
2144+    }
2145+    if (!PyBuffer_IsContiguous(&key, 'C')) {
2146+        _PyArg_BadArgument("hmac_digest", "argument 'key'", "contiguous buffer", args[0]);
2147+        goto exit;
2148+    }
2149+    if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) {
2150+        goto exit;
2151+    }
2152+    if (!PyBuffer_IsContiguous(&msg, 'C')) {
2153+        _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]);
2154+        goto exit;
2155+    }
2156+    if (!PyUnicode_Check(args[2])) {
2157+        _PyArg_BadArgument("hmac_digest", "argument 'digest'", "str", args[2]);
2158+        goto exit;
2159+    }
2160+    Py_ssize_t digest_length;
2161+    digest = PyUnicode_AsUTF8AndSize(args[2], &digest_length);
2162+    if (digest == NULL) {
2163+        goto exit;
2164+    }
2165+    if (strlen(digest) != (size_t)digest_length) {
2166+        PyErr_SetString(PyExc_ValueError, "embedded null character");
2167+        goto exit;
2168+    }
2169+    return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest);
2170+
2171+exit:
2172+    /* Cleanup for key */
2173+    if (key.obj) {
2174+       PyBuffer_Release(&key);
2175+    }
2176+    /* Cleanup for msg */
2177+    if (msg.obj) {
2178+       PyBuffer_Release(&msg);
2179+    }
2180+
2181+    return return_value;
2182+}
2183+
2184+PyDoc_STRVAR(_hashlib_hmac_new__doc__,
2185+"hmac_new($module, /, key, msg=None, digestmod=None)\n"
2186+"--\n"
2187+"\n"
2188+"Return a new hmac object.");
2189+
2190+#define _HASHLIB_HMAC_NEW_METHODDEF    \
2191+    {"hmac_new", (PyCFunction)(void(*)(void))_hashlib_hmac_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_new__doc__},
2192+
2193+static PyObject *
2194+_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, Py_buffer *msg,
2195+                       const char *digestmod);
2196+
2197+static PyObject *
2198+_hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
2199+{
2200+    PyObject *return_value = NULL;
2201+    static const char * const _keywords[] = {"key", "msg", "digestmod", NULL};
2202+    static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0};
2203+    PyObject *argsbuf[3];
2204+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
2205+    Py_buffer key = {NULL, NULL};
2206+    Py_buffer msg = {NULL, NULL};
2207+    const char *digestmod = NULL;
2208+
2209+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf);
2210+    if (!args) {
2211+        goto exit;
2212+    }
2213+    if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) {
2214+        goto exit;
2215+    }
2216+    if (!PyBuffer_IsContiguous(&key, 'C')) {
2217+        _PyArg_BadArgument("hmac_new", "argument 'key'", "contiguous buffer", args[0]);
2218+        goto exit;
2219+    }
2220+    if (!noptargs) {
2221+        goto skip_optional_pos;
2222+    }
2223+    if (args[1]) {
2224+        if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) {
2225+            goto exit;
2226+        }
2227+        if (!PyBuffer_IsContiguous(&msg, 'C')) {
2228+            _PyArg_BadArgument("hmac_new", "argument 'msg'", "contiguous buffer", args[1]);
2229+            goto exit;
2230+        }
2231+        if (!--noptargs) {
2232+            goto skip_optional_pos;
2233+        }
2234+    }
2235+    if (!PyUnicode_Check(args[2])) {
2236+        _PyArg_BadArgument("hmac_new", "argument 'digestmod'", "str", args[2]);
2237+        goto exit;
2238+    }
2239+    Py_ssize_t digestmod_length;
2240+    digestmod = PyUnicode_AsUTF8AndSize(args[2], &digestmod_length);
2241+    if (digestmod == NULL) {
2242+        goto exit;
2243+    }
2244+    if (strlen(digestmod) != (size_t)digestmod_length) {
2245+        PyErr_SetString(PyExc_ValueError, "embedded null character");
2246+        goto exit;
2247+    }
2248+skip_optional_pos:
2249+    return_value = _hashlib_hmac_new_impl(module, &key, &msg, digestmod);
2250+
2251+exit:
2252+    /* Cleanup for key */
2253+    if (key.obj) {
2254+       PyBuffer_Release(&key);
2255+    }
2256+    /* Cleanup for msg */
2257+    if (msg.obj) {
2258+       PyBuffer_Release(&msg);
2259+    }
2260+
2261+    return return_value;
2262+}
2263+/*[clinic end generated code: output=b4705bad5ece43e9 input=a9049054013a1b77]*/
2264-- 
22652.32.0
2266