summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-09-12 06:03:50 -0700
committerStéphane Wirtel <stephane@wirtel.be>2019-09-12 14:03:50 +0100
commit67b90a079c39066aa9d51690fe5678c36ccbc258 (patch)
tree1773f0f00663e811be925e03c03f1b80388da93b
parent345bfc990f5f3e873774051d43136b06bfed82cb (diff)
downloadcpython-git-67b90a079c39066aa9d51690fe5678c36ccbc258.tar.gz
bpo-38132: Simplify _hashopenssl code (GH-16023) (#16040)
Signed-off-by: Christian Heimes <christian@python.org> (cherry picked from commit 5a4f82f457049b5b07b6fba4ca42bc1ecf597976) Co-authored-by: Christian Heimes <christian@python.org>
-rw-r--r--Lib/test/test_hashlib.py3
-rw-r--r--Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst3
-rw-r--r--Modules/_hashopenssl.c283
-rw-r--r--Modules/clinic/_hashopenssl.c.h224
4 files changed, 391 insertions, 122 deletions
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index f83f73a0cc..b7b04a37f0 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -194,6 +194,9 @@ class HashLibTestCase(unittest.TestCase):
self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
self.assertRaises(TypeError, hashlib.new, 1)
+ def test_new_upper_to_lower(self):
+ self.assertEqual(hashlib.new("SHA256").name, "sha256")
+
def test_get_builtin_constructor(self):
get_builtin_constructor = getattr(hashlib,
'__get_builtin_constructor')
diff --git a/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst b/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst
new file mode 100644
index 0000000000..c2e3b6290d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst
@@ -0,0 +1,3 @@
+The OpenSSL hashlib wrapper uses a simpler implementation. Several Macros
+and pointless caches are gone. The hash name now comes from OpenSSL's EVP.
+The algorithm name stays the same, except it is now always lower case.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index 5e76853b34..798317fb58 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -30,7 +30,6 @@
typedef struct {
PyObject_HEAD
- PyObject *name; /* name of this hash algorithm */
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
PyThread_type_lock lock; /* OpenSSL context lock */
} EVPobject;
@@ -38,18 +37,6 @@ typedef struct {
static PyTypeObject EVPtype;
-
-#define DEFINE_CONSTS_FOR_NEW(Name) \
- static PyObject *CONST_ ## Name ## _name_obj = NULL; \
- static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
-
-DEFINE_CONSTS_FOR_NEW(md5)
-DEFINE_CONSTS_FOR_NEW(sha1)
-DEFINE_CONSTS_FOR_NEW(sha224)
-DEFINE_CONSTS_FOR_NEW(sha256)
-DEFINE_CONSTS_FOR_NEW(sha384)
-DEFINE_CONSTS_FOR_NEW(sha512)
-
#include "clinic/_hashopenssl.c.h"
/*[clinic input]
module _hashlib
@@ -90,16 +77,13 @@ _setException(PyObject *exc)
/* LCOV_EXCL_STOP */
static EVPobject *
-newEVPobject(PyObject *name)
+newEVPobject(void)
{
EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
if (retval == NULL) {
return NULL;
}
- /* save the name for .name to return */
- Py_INCREF(name);
- retval->name = name;
retval->lock = NULL;
retval->ctx = EVP_MD_CTX_new();
@@ -139,7 +123,6 @@ EVP_dealloc(EVPobject *self)
if (self->lock != NULL)
PyThread_free_lock(self->lock);
EVP_MD_CTX_free(self->ctx);
- Py_XDECREF(self->name);
PyObject_Del(self);
}
@@ -167,7 +150,7 @@ EVP_copy_impl(EVPobject *self)
{
EVPobject *newobj;
- if ( (newobj = newEVPobject(self->name))==NULL)
+ if ( (newobj = newEVPobject())==NULL)
return NULL;
if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
@@ -307,10 +290,20 @@ EVP_get_digest_size(EVPobject *self, void *closure)
return PyLong_FromLong(size);
}
-static PyMemberDef EVP_members[] = {
- {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
- {NULL} /* Sentinel */
-};
+static PyObject *
+EVP_get_name(EVPobject *self, void *closure)
+{
+ const char *name = EVP_MD_name(EVP_MD_CTX_md(self->ctx));
+ PyObject *name_obj, *name_lower;
+
+ name_obj = PyUnicode_FromString(name);
+ if (!name_obj) {
+ return NULL;
+ }
+ name_lower = PyObject_CallMethod(name_obj, "lower", NULL);
+ Py_DECREF(name_obj);
+ return name_lower;
+}
static PyGetSetDef EVP_getseters[] = {
{"digest_size",
@@ -321,6 +314,10 @@ static PyGetSetDef EVP_getseters[] = {
(getter)EVP_get_block_size, NULL,
NULL,
NULL},
+ {"name",
+ (getter)EVP_get_name, NULL,
+ NULL,
+ PyDoc_STR("algorithm name.")},
{NULL} /* Sentinel */
};
@@ -328,7 +325,14 @@ static PyGetSetDef EVP_getseters[] = {
static PyObject *
EVP_repr(EVPobject *self)
{
- return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self);
+ PyObject *name_obj, *repr;
+ name_obj = EVP_get_name(self, NULL);
+ if (!name_obj) {
+ return NULL;
+ }
+ repr = PyUnicode_FromFormat("<%U HASH object @ %p>", name_obj, self);
+ Py_DECREF(name_obj);
+ return repr;
}
PyDoc_STRVAR(hashtype_doc,
@@ -379,7 +383,7 @@ static PyTypeObject EVPtype = {
0, /*tp_iter*/
0, /*tp_iternext*/
EVP_methods, /* tp_methods */
- EVP_members, /* tp_members */
+ NULL, /* tp_members */
EVP_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
@@ -389,28 +393,23 @@ static PyTypeObject EVPtype = {
};
static PyObject *
-EVPnew(PyObject *name_obj,
- const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
+EVPnew(const EVP_MD *digest,
const unsigned char *cp, Py_ssize_t len)
{
EVPobject *self;
- if (!digest && !initial_ctx) {
+ if (!digest) {
PyErr_SetString(PyExc_ValueError, "unsupported hash type");
return NULL;
}
- if ((self = newEVPobject(name_obj)) == NULL)
+ if ((self = newEVPobject()) == NULL)
return NULL;
- if (initial_ctx) {
- EVP_MD_CTX_copy(self->ctx, initial_ctx);
- } else {
- if (!EVP_DigestInit(self->ctx, digest)) {
- _setException(PyExc_ValueError);
- Py_DECREF(self);
- return NULL;
- }
+ if (!EVP_DigestInit(self->ctx, digest)) {
+ _setException(PyExc_ValueError);
+ Py_DECREF(self);
+ return NULL;
}
if (cp && len) {
@@ -462,13 +461,132 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj)
digest = EVP_get_digestbyname(name);
- ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
+ ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len);
if (data_obj)
PyBuffer_Release(&view);
return ret_obj;
}
+static PyObject*
+EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest)
+{
+ Py_buffer view = { 0 };
+ PyObject *ret_obj;
+
+ if (data_obj)
+ GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
+
+ ret_obj = EVPnew(digest, (unsigned char*)view.buf, view.len);
+
+ if (data_obj)
+ PyBuffer_Release(&view);
+
+ return ret_obj;
+}
+
+/*[clinic input]
+_hashlib.openssl_md5
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a md5 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=6caae75b73e22c3f input=52010d3869e1b1a7]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_md5());
+}
+
+
+/*[clinic input]
+_hashlib.openssl_sha1
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a sha1 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=07606d8f75153e61 input=16807d30e4aa8ae9]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha1());
+}
+
+
+/*[clinic input]
+_hashlib.openssl_sha224
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a sha224 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=55e848761bcef0c9 input=5dbc2f1d84eb459b]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha224());
+}
+
+
+/*[clinic input]
+_hashlib.openssl_sha256
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a sha256 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=05851d7cce34ac65 input=a68a5d21cda5a80f]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha256());
+}
+
+
+/*[clinic input]
+_hashlib.openssl_sha384
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a sha384 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=5101a4704a932c2f input=6bdfa006622b64ea]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha384());
+}
+
+
+/*[clinic input]
+_hashlib.openssl_sha512
+
+ string as data_obj: object(py_default="b''") = NULL
+
+Returns a sha512 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj)
+/*[clinic end generated code: output=20c8e63ee560a5cb input=ece50182ad4b76a6]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha512());
+}
+
+
/*[clinic input]
_hashlib.pbkdf2_hmac as pbkdf2_hmac
@@ -800,76 +918,6 @@ generate_hash_name_list(void)
return state.set;
}
-
-/*
- * This macro generates constructor function definitions for specific
- * hash algorithms. These constructors are much faster than calling
- * the generic one passing it a python string and are noticeably
- * faster than calling a python new() wrapper. That is important for
- * code that wants to make hashes of a bunch of small strings.
- * The first call will lazy-initialize, which reports an exception
- * if initialization fails.
- */
-#define GEN_CONSTRUCTOR(NAME) \
- static PyObject * \
- EVP_new_ ## NAME (PyObject *self, PyObject *const *args, Py_ssize_t nargs) \
- { \
- PyObject *data_obj = NULL; \
- Py_buffer view = { 0 }; \
- PyObject *ret_obj; \
- \
- if (!_PyArg_ParseStack(args, nargs, "|O:" #NAME , &data_obj)) { \
- return NULL; \
- } \
- \
- if (CONST_new_ ## NAME ## _ctx_p == NULL) { \
- EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \
- if (!EVP_get_digestbyname(#NAME) || \
- !EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \
- _setException(PyExc_ValueError); \
- EVP_MD_CTX_free(ctx_p); \
- return NULL; \
- } \
- CONST_new_ ## NAME ## _ctx_p = ctx_p; \
- } \
- \
- if (data_obj) \
- GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \
- \
- ret_obj = EVPnew( \
- CONST_ ## NAME ## _name_obj, \
- NULL, \
- CONST_new_ ## NAME ## _ctx_p, \
- (unsigned char*)view.buf, \
- view.len); \
- \
- if (data_obj) \
- PyBuffer_Release(&view); \
- return ret_obj; \
- }
-
-/* a PyMethodDef structure for the constructor */
-#define CONSTRUCTOR_METH_DEF(NAME) \
- {"openssl_" #NAME, (PyCFunction)(void(*)(void))EVP_new_ ## NAME, METH_FASTCALL, \
- PyDoc_STR("Returns a " #NAME \
- " hash object; optionally initialized with a string") \
- }
-
-/* used in the init function to setup a constructor: initialize OpenSSL
- constructor constants if they haven't been initialized already. */
-#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
- if (CONST_ ## NAME ## _name_obj == NULL) { \
- CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
- } \
-} while (0);
-
-GEN_CONSTRUCTOR(md5)
-GEN_CONSTRUCTOR(sha1)
-GEN_CONSTRUCTOR(sha224)
-GEN_CONSTRUCTOR(sha256)
-GEN_CONSTRUCTOR(sha384)
-GEN_CONSTRUCTOR(sha512)
-
/* List of functions exported by this module */
static struct PyMethodDef EVP_functions[] = {
@@ -877,12 +925,12 @@ static struct PyMethodDef EVP_functions[] = {
PBKDF2_HMAC_METHODDEF
_HASHLIB_SCRYPT_METHODDEF
_HASHLIB_HMAC_DIGEST_METHODDEF
- CONSTRUCTOR_METH_DEF(md5),
- CONSTRUCTOR_METH_DEF(sha1),
- CONSTRUCTOR_METH_DEF(sha224),
- CONSTRUCTOR_METH_DEF(sha256),
- CONSTRUCTOR_METH_DEF(sha384),
- CONSTRUCTOR_METH_DEF(sha512),
+ _HASHLIB_OPENSSL_MD5_METHODDEF
+ _HASHLIB_OPENSSL_SHA1_METHODDEF
+ _HASHLIB_OPENSSL_SHA224_METHODDEF
+ _HASHLIB_OPENSSL_SHA256_METHODDEF
+ _HASHLIB_OPENSSL_SHA384_METHODDEF
+ _HASHLIB_OPENSSL_SHA512_METHODDEF
{NULL, NULL} /* Sentinel */
};
@@ -939,12 +987,5 @@ PyInit__hashlib(void)
Py_INCREF((PyObject *)&EVPtype);
PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
- /* these constants are used by the convenience constructors */
- INIT_CONSTRUCTOR_CONSTANTS(md5);
- INIT_CONSTRUCTOR_CONSTANTS(sha1);
- INIT_CONSTRUCTOR_CONSTANTS(sha224);
- INIT_CONSTRUCTOR_CONSTANTS(sha256);
- INIT_CONSTRUCTOR_CONSTANTS(sha384);
- INIT_CONSTRUCTOR_CONSTANTS(sha512);
return m;
}
diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h
index 854d925377..9aaea47e83 100644
--- a/Modules/clinic/_hashopenssl.c.h
+++ b/Modules/clinic/_hashopenssl.c.h
@@ -109,6 +109,228 @@ exit:
return return_value;
}
+PyDoc_STRVAR(_hashlib_openssl_md5__doc__,
+"openssl_md5($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a md5 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_MD5_METHODDEF \
+ {"openssl_md5", (PyCFunction)(void(*)(void))_hashlib_openssl_md5, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__},
+
+static PyObject *
+_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_md5_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_hashlib_openssl_sha1__doc__,
+"openssl_sha1($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a sha1 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA1_METHODDEF \
+ {"openssl_sha1", (PyCFunction)(void(*)(void))_hashlib_openssl_sha1, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__},
+
+static PyObject *
+_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_sha1_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_hashlib_openssl_sha224__doc__,
+"openssl_sha224($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a sha224 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA224_METHODDEF \
+ {"openssl_sha224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__},
+
+static PyObject *
+_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_sha224_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_hashlib_openssl_sha256__doc__,
+"openssl_sha256($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a sha256 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA256_METHODDEF \
+ {"openssl_sha256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__},
+
+static PyObject *
+_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_sha256_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_hashlib_openssl_sha384__doc__,
+"openssl_sha384($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a sha384 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA384_METHODDEF \
+ {"openssl_sha384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__},
+
+static PyObject *
+_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_sha384_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(_hashlib_openssl_sha512__doc__,
+"openssl_sha512($module, /, string=b\'\')\n"
+"--\n"
+"\n"
+"Returns a sha512 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA512_METHODDEF \
+ {"openssl_sha512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__},
+
+static PyObject *
+_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj);
+
+static PyObject *
+_hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ data_obj = args[0];
+skip_optional_pos:
+ return_value = _hashlib_openssl_sha512_impl(module, data_obj);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(pbkdf2_hmac__doc__,
"pbkdf2_hmac($module, /, hash_name, password, salt, iterations,\n"
" dklen=None)\n"
@@ -401,4 +623,4 @@ exit:
#ifndef _HASHLIB_SCRYPT_METHODDEF
#define _HASHLIB_SCRYPT_METHODDEF
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
-/*[clinic end generated code: output=cfe686cb2fa042e1 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=38c2637f67e9bb79 input=a9049054013a1b77]*/