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