summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2020-05-16 20:27:06 (GMT)
committerGitHub <noreply@github.com>2020-05-16 20:27:06 (GMT)
commitd5b3f6b7f9fc74438009af63f1de01bd77be9385 (patch)
tree32fed153b988a3dbb9c691ba924d989de5d17578
parentb17e49e0def23238b9e7f48c8a02e2d7bbf1f653 (diff)
downloadcpython-d5b3f6b7f9fc74438009af63f1de01bd77be9385.zip
cpython-d5b3f6b7f9fc74438009af63f1de01bd77be9385.tar.gz
cpython-d5b3f6b7f9fc74438009af63f1de01bd77be9385.tar.bz2
bpo-37630: Use SHA3 and SHAKE XOF from OpenSSL (GH-16049)
OpenSSL 1.1.1 comes with SHA3 and SHAKE builtin. Signed-off-by: Christian Heimes <christian@python.org> Automerge-Triggered-By: @tiran
-rw-r--r--Doc/library/hashlib.rst2
-rw-r--r--Lib/hashlib.py4
-rw-r--r--Lib/test/test_hashlib.py18
-rw-r--r--Misc/NEWS.d/next/Library/2020-05-15-19-53-18.bpo-37630.O5kgAw.rst2
-rw-r--r--Modules/_hashopenssl.c366
-rw-r--r--Modules/clinic/_hashopenssl.c.h474
6 files changed, 845 insertions, 21 deletions
diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst
index b737d22..d644974 100644
--- a/Doc/library/hashlib.rst
+++ b/Doc/library/hashlib.rst
@@ -87,6 +87,8 @@ library that Python uses on your platform. On most platforms the
that the hashing algorithm is not used in a security context, e.g. as a
non-cryptographic one-way compression function.
+ Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer.
+
For example, to obtain the digest of the byte string ``b'Nobody inspects the
spammish repetition'``::
diff --git a/Lib/hashlib.py b/Lib/hashlib.py
index 56873b7..0f81de0 100644
--- a/Lib/hashlib.py
+++ b/Lib/hashlib.py
@@ -71,8 +71,6 @@ __all__ = __always_supported + ('new', 'algorithms_guaranteed',
__builtin_constructor_cache = {}
__block_openssl_constructor = {
- 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
- 'shake_128', 'shake_256',
'blake2b', 'blake2s',
}
@@ -125,6 +123,8 @@ def __get_openssl_constructor(name):
# Prefer our blake2 and sha3 implementation.
return __get_builtin_constructor(name)
try:
+ # MD5, SHA1, and SHA2 are in all supported OpenSSL versions
+ # SHA3/shake are available in OpenSSL 1.1.1+
f = getattr(_hashlib, 'openssl_' + name)
# Allow the C module to raise ValueError. The function will be
# defined but the hash not actually available thanks to OpenSSL.
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index f9fe7e3..b901468 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -27,9 +27,10 @@ c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib'])
py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
try:
- from _hashlib import HASH
+ from _hashlib import HASH, HASHXOF
except ImportError:
HASH = None
+ HASHXOF = None
try:
import _blake2
@@ -254,6 +255,9 @@ class HashLibTestCase(unittest.TestCase):
h = cons()
if h.name not in self.shakes:
continue
+ if HASH is not None and isinstance(h, HASH):
+ # _hashopenssl's take a size_t
+ continue
for digest in h.digest, h.hexdigest:
self.assertRaises(ValueError, digest, -10)
for length in large_sizes:
@@ -860,6 +864,18 @@ class HashLibTestCase(unittest.TestCase):
def test_get_fips_mode(self):
self.assertIsInstance(c_hashlib.get_fips_mode(), int)
+ @unittest.skipUnless(HASH is not None, 'need _hashlib')
+ def test_internal_types(self):
+ # internal types like _hashlib.HASH are not constructable
+ with self.assertRaisesRegex(
+ TypeError, "cannot create 'HASH' instance"
+ ):
+ HASH()
+ with self.assertRaisesRegex(
+ TypeError, "cannot create 'HASHXOF' instance"
+ ):
+ HASHXOF()
+
class KDFTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2020-05-15-19-53-18.bpo-37630.O5kgAw.rst b/Misc/NEWS.d/next/Library/2020-05-15-19-53-18.bpo-37630.O5kgAw.rst
new file mode 100644
index 0000000..78458e6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-05-15-19-53-18.bpo-37630.O5kgAw.rst
@@ -0,0 +1,2 @@
+The :mod:`hashlib` module can now use SHA3 hashes and SHAKE XOF from OpenSSL
+when available.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index b55ac93..936b515 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -55,6 +55,9 @@ static PyModuleDef _hashlibmodule;
typedef struct {
PyTypeObject *EVPtype;
+#ifdef PY_OPENSSL_HAS_SHAKE
+ PyTypeObject *EVPXOFtype;
+#endif
} _hashlibstate;
static inline _hashlibstate*
@@ -79,8 +82,9 @@ typedef struct {
/*[clinic input]
module _hashlib
class _hashlib.HASH "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPtype"
+class _hashlib.HASHXOF "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1adf85e8eb2ab979]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=813acc7b2d8f322c]*/
/* LCOV_EXCL_START */
@@ -114,6 +118,15 @@ _setException(PyObject *exc)
}
/* LCOV_EXCL_STOP */
+/* {Py_tp_new, NULL} doesn't block __new__ */
+static PyObject *
+_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%.100s' instances", _PyType_Name(type));
+ return NULL;
+}
+
static PyObject*
py_digest_name(const EVP_MD *md)
{
@@ -249,11 +262,9 @@ py_digest_by_name(const char *name)
}
static EVPobject *
-newEVPobject(void)
+newEVPobject(PyTypeObject *type)
{
- EVPobject *retval = (EVPobject *)PyObject_New(
- EVPobject, _hashlibstate_global->EVPtype
- );
+ EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, type);
if (retval == NULL) {
return NULL;
}
@@ -327,7 +338,7 @@ EVP_copy_impl(EVPobject *self)
{
EVPobject *newobj;
- if ( (newobj = newEVPobject())==NULL)
+ if ((newobj = newEVPobject(Py_TYPE(self))) == NULL)
return NULL;
if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
@@ -502,7 +513,8 @@ EVP_repr(EVPobject *self)
if (!name_obj) {
return NULL;
}
- repr = PyUnicode_FromFormat("<%U HASH object @ %p>", name_obj, self);
+ repr = PyUnicode_FromFormat("<%U %s object @ %p>",
+ name_obj, Py_TYPE(self)->tp_name, self);
Py_DECREF(name_obj);
return repr;
}
@@ -531,6 +543,7 @@ static PyType_Slot EVPtype_slots[] = {
{Py_tp_doc, (char *)hashtype_doc},
{Py_tp_methods, EVP_methods},
{Py_tp_getset, EVP_getseters},
+ {Py_tp_new, _disabled_new},
{0, 0},
};
@@ -542,19 +555,179 @@ static PyType_Spec EVPtype_spec = {
EVPtype_slots
};
+#ifdef PY_OPENSSL_HAS_SHAKE
+
+/*[clinic input]
+_hashlib.HASHXOF.digest as EVPXOF_digest
+
+ length: Py_ssize_t
+
+Return the digest value as a bytes object.
+[clinic start generated code]*/
+
+static PyObject *
+EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length)
+/*[clinic end generated code: output=ef9320c23280efad input=816a6537cea3d1db]*/
+{
+ EVP_MD_CTX *temp_ctx;
+ PyObject *retval = PyBytes_FromStringAndSize(NULL, length);
+
+ if (retval == NULL) {
+ return NULL;
+ }
+
+ temp_ctx = EVP_MD_CTX_new();
+ if (temp_ctx == NULL) {
+ Py_DECREF(retval);
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
+ Py_DECREF(retval);
+ EVP_MD_CTX_free(temp_ctx);
+ return _setException(PyExc_ValueError);
+ }
+ if (!EVP_DigestFinalXOF(temp_ctx,
+ (unsigned char*)PyBytes_AS_STRING(retval),
+ length)) {
+ Py_DECREF(retval);
+ EVP_MD_CTX_free(temp_ctx);
+ _setException(PyExc_ValueError);
+ return NULL;
+ }
+
+ EVP_MD_CTX_free(temp_ctx);
+ return retval;
+}
+
+/*[clinic input]
+_hashlib.HASHXOF.hexdigest as EVPXOF_hexdigest
+
+ length: Py_ssize_t
+
+Return the digest value as a string of hexadecimal digits.
+[clinic start generated code]*/
+
+static PyObject *
+EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length)
+/*[clinic end generated code: output=eb3e6ee7788bf5b2 input=5f9d6a8f269e34df]*/
+{
+ unsigned char *digest;
+ EVP_MD_CTX *temp_ctx;
+ PyObject *retval;
+
+ digest = (unsigned char*)PyMem_Malloc(length);
+ if (digest == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ temp_ctx = EVP_MD_CTX_new();
+ if (temp_ctx == NULL) {
+ PyMem_Free(digest);
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ /* Get the raw (binary) digest value */
+ if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
+ PyMem_Free(digest);
+ EVP_MD_CTX_free(temp_ctx);
+ return _setException(PyExc_ValueError);
+ }
+ if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) {
+ PyMem_Free(digest);
+ EVP_MD_CTX_free(temp_ctx);
+ _setException(PyExc_ValueError);
+ return NULL;
+ }
+
+ EVP_MD_CTX_free(temp_ctx);
+
+ retval = _Py_strhex((const char *)digest, length);
+ PyMem_Free(digest);
+ return retval;
+}
+
+static PyMethodDef EVPXOF_methods[] = {
+ EVPXOF_DIGEST_METHODDEF
+ EVPXOF_HEXDIGEST_METHODDEF
+ {NULL, NULL} /* sentinel */
+};
+
+
+static PyObject *
+EVPXOF_get_digest_size(EVPobject *self, void *closure)
+{
+ return PyLong_FromLong(0);
+}
+
+static PyGetSetDef EVPXOF_getseters[] = {
+ {"digest_size",
+ (getter)EVPXOF_get_digest_size, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(hashxoftype_doc,
+"HASHXOF(name, string=b\'\')\n"
+"--\n"
+"\n"
+"A hash is an object used to calculate a checksum of a string of information.\n"
+"\n"
+"Methods:\n"
+"\n"
+"update() -- updates the current digest with an additional string\n"
+"digest(length) -- return the current digest value\n"
+"hexdigest(length) -- return the current digest as a string of hexadecimal digits\n"
+"copy() -- return a copy of the current hash object\n"
+"\n"
+"Attributes:\n"
+"\n"
+"name -- the hash algorithm being used by this object\n"
+"digest_size -- number of bytes in this hashes output");
+
+static PyType_Slot EVPXOFtype_slots[] = {
+ {Py_tp_doc, (char *)hashxoftype_doc},
+ {Py_tp_methods, EVPXOF_methods},
+ {Py_tp_getset, EVPXOF_getseters},
+ {Py_tp_new, _disabled_new},
+ {0, 0},
+};
+
+static PyType_Spec EVPXOFtype_spec = {
+ "_hashlib.HASHXOF", /*tp_name*/
+ sizeof(EVPobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ EVPXOFtype_slots
+};
+
+
+#endif
+
static PyObject *
-EVPnew(const EVP_MD *digest,
+EVPnew(PyObject *module, const EVP_MD *digest,
const unsigned char *cp, Py_ssize_t len, int usedforsecurity)
{
int result = 0;
EVPobject *self;
+ PyTypeObject *type = get_hashlib_state(module)->EVPtype;
if (!digest) {
PyErr_SetString(PyExc_ValueError, "unsupported hash type");
return NULL;
}
- if ((self = newEVPobject()) == NULL)
+#ifdef PY_OPENSSL_HAS_SHAKE
+ if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) {
+ type = get_hashlib_state(module)->EVPXOFtype;
+ }
+#endif
+
+ if ((self = newEVPobject(type)) == NULL)
return NULL;
if (!usedforsecurity) {
@@ -614,7 +787,7 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj,
Py_buffer view = { 0 };
PyObject *ret_obj;
char *name;
- const EVP_MD *digest;
+ const EVP_MD *digest = NULL;
if (!PyArg_Parse(name_obj, "s", &name)) {
PyErr_SetString(PyExc_TypeError, "name must be a string");
@@ -626,7 +799,7 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj,
digest = py_digest_by_name(name);
- ret_obj = EVPnew(digest,
+ ret_obj = EVPnew(module, digest,
(unsigned char*)view.buf, view.len,
usedforsecurity);
@@ -645,7 +818,7 @@ EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest,
if (data_obj)
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
- ret_obj = EVPnew(digest,
+ ret_obj = EVPnew(module, digest,
(unsigned char*)view.buf, view.len,
usedforsecurity);
@@ -775,6 +948,125 @@ _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj,
}
+#ifdef PY_OPENSSL_HAS_SHA3
+
+/*[clinic input]
+_hashlib.openssl_sha3_224
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a sha3-224 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha3_224(), usedforsecurity);
+}
+
+/*[clinic input]
+_hashlib.openssl_sha3_256
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a sha3-256 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha3_256(), usedforsecurity);
+}
+
+/*[clinic input]
+_hashlib.openssl_sha3_384
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a sha3-384 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha3_384(), usedforsecurity);
+}
+
+/*[clinic input]
+_hashlib.openssl_sha3_512
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a sha3-512 hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_sha3_512(), usedforsecurity);
+}
+#endif /* PY_OPENSSL_HAS_SHA3 */
+
+#ifdef PY_OPENSSL_HAS_SHAKE
+/*[clinic input]
+_hashlib.openssl_shake128
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a shake128 variable hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_shake128_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=c68a0e30b4c09e1a input=b6d1e9566bacbb64]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_shake128(), usedforsecurity);
+}
+
+/*[clinic input]
+_hashlib.openssl_shake256
+
+ string as data_obj: object(py_default="b''") = NULL
+ *
+ usedforsecurity: bool = True
+
+Returns a shake256 variable hash object; optionally initialized with a string
+
+[clinic start generated code]*/
+
+static PyObject *
+_hashlib_openssl_shake256_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity)
+/*[clinic end generated code: output=d56387762dcad516 input=591b9b78c0498116]*/
+{
+ return EVP_fast_new(module, data_obj, EVP_shake256(), usedforsecurity);
+}
+#endif /* PY_OPENSSL_HAS_SHAKE */
+
/*[clinic input]
_hashlib.pbkdf2_hmac as pbkdf2_hmac
@@ -1163,6 +1455,12 @@ static struct PyMethodDef EVP_functions[] = {
_HASHLIB_OPENSSL_SHA256_METHODDEF
_HASHLIB_OPENSSL_SHA384_METHODDEF
_HASHLIB_OPENSSL_SHA512_METHODDEF
+ _HASHLIB_OPENSSL_SHA3_224_METHODDEF
+ _HASHLIB_OPENSSL_SHA3_256_METHODDEF
+ _HASHLIB_OPENSSL_SHA3_384_METHODDEF
+ _HASHLIB_OPENSSL_SHA3_512_METHODDEF
+ _HASHLIB_OPENSSL_SHAKE128_METHODDEF
+ _HASHLIB_OPENSSL_SHAKE256_METHODDEF
{NULL, NULL} /* Sentinel */
};
@@ -1174,6 +1472,9 @@ hashlib_traverse(PyObject *m, visitproc visit, void *arg)
{
_hashlibstate *state = get_hashlib_state(m);
Py_VISIT(state->EVPtype);
+#ifdef PY_OPENSSL_HAS_SHAKE
+ Py_VISIT(state->EVPXOFtype);
+#endif
return 0;
}
@@ -1182,6 +1483,9 @@ hashlib_clear(PyObject *m)
{
_hashlibstate *state = get_hashlib_state(m);
Py_CLEAR(state->EVPtype);
+#ifdef PY_OPENSSL_HAS_SHAKE
+ Py_CLEAR(state->EVPXOFtype);
+#endif
return 0;
}
@@ -1208,6 +1512,10 @@ PyMODINIT_FUNC
PyInit__hashlib(void)
{
PyObject *m, *openssl_md_meth_names;
+ _hashlibstate *state = NULL;
+#ifdef PY_OPENSSL_HAS_SHAKE
+ PyObject *bases;
+#endif
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
/* Load all digest algorithms and initialize cpuid */
@@ -1225,10 +1533,37 @@ PyInit__hashlib(void)
if (m == NULL)
return NULL;
+ state = get_hashlib_state(m);
+
PyTypeObject *EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec);
- if (EVPtype == NULL)
+ if (EVPtype == NULL) {
+ Py_DECREF(m);
return NULL;
- get_hashlib_state(m)->EVPtype = EVPtype;
+ }
+ state->EVPtype = EVPtype;
+
+ Py_INCREF((PyObject *)state->EVPtype);
+ PyModule_AddObject(m, "HASH", (PyObject *)state->EVPtype);
+
+#ifdef PY_OPENSSL_HAS_SHAKE
+ bases = PyTuple_Pack(1, (PyObject *)EVPtype);
+ if (bases == NULL) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ PyTypeObject *EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases(
+ &EVPXOFtype_spec, bases
+ );
+ Py_DECREF(bases);
+ if (EVPXOFtype == NULL) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ state->EVPXOFtype = EVPXOFtype;
+
+ Py_INCREF((PyObject *)state->EVPXOFtype);
+ PyModule_AddObject(m, "HASHXOF", (PyObject *)state->EVPXOFtype);
+#endif
openssl_md_meth_names = generate_hash_name_list();
if (openssl_md_meth_names == NULL) {
@@ -1240,9 +1575,6 @@ PyInit__hashlib(void)
return NULL;
}
- Py_INCREF((PyObject *)get_hashlib_state(m)->EVPtype);
- PyModule_AddObject(m, "HASH", (PyObject *)get_hashlib_state(m)->EVPtype);
-
PyState_AddModule(m, &_hashlibmodule);
return m;
}
diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h
index 1b0c6d0..71c9246 100644
--- a/Modules/clinic/_hashopenssl.c.h
+++ b/Modules/clinic/_hashopenssl.c.h
@@ -65,6 +65,110 @@ PyDoc_STRVAR(EVP_update__doc__,
#define EVP_UPDATE_METHODDEF \
{"update", (PyCFunction)EVP_update, METH_O, EVP_update__doc__},
+#if defined(PY_OPENSSL_HAS_SHAKE)
+
+PyDoc_STRVAR(EVPXOF_digest__doc__,
+"digest($self, /, length)\n"
+"--\n"
+"\n"
+"Return the digest value as a bytes object.");
+
+#define EVPXOF_DIGEST_METHODDEF \
+ {"digest", (PyCFunction)(void(*)(void))EVPXOF_digest, METH_FASTCALL|METH_KEYWORDS, EVPXOF_digest__doc__},
+
+static PyObject *
+EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length);
+
+static PyObject *
+EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"length", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t length;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (PyFloat_Check(args[0])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ {
+ Py_ssize_t ival = -1;
+ PyObject *iobj = PyNumber_Index(args[0]);
+ if (iobj != NULL) {
+ ival = PyLong_AsSsize_t(iobj);
+ Py_DECREF(iobj);
+ }
+ if (ival == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ length = ival;
+ }
+ return_value = EVPXOF_digest_impl(self, length);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHAKE) */
+
+#if defined(PY_OPENSSL_HAS_SHAKE)
+
+PyDoc_STRVAR(EVPXOF_hexdigest__doc__,
+"hexdigest($self, /, length)\n"
+"--\n"
+"\n"
+"Return the digest value as a string of hexadecimal digits.");
+
+#define EVPXOF_HEXDIGEST_METHODDEF \
+ {"hexdigest", (PyCFunction)(void(*)(void))EVPXOF_hexdigest, METH_FASTCALL|METH_KEYWORDS, EVPXOF_hexdigest__doc__},
+
+static PyObject *
+EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length);
+
+static PyObject *
+EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"length", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0};
+ PyObject *argsbuf[1];
+ Py_ssize_t length;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (PyFloat_Check(args[0])) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float" );
+ goto exit;
+ }
+ {
+ Py_ssize_t ival = -1;
+ PyObject *iobj = PyNumber_Index(args[0]);
+ if (iobj != NULL) {
+ ival = PyLong_AsSsize_t(iobj);
+ Py_DECREF(iobj);
+ }
+ if (ival == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ length = ival;
+ }
+ return_value = EVPXOF_hexdigest_impl(self, length);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHAKE) */
+
PyDoc_STRVAR(EVP_new__doc__,
"new($module, /, name, string=b\'\', *, usedforsecurity=True)\n"
"--\n"
@@ -436,6 +540,342 @@ exit:
return return_value;
}
+#if defined(PY_OPENSSL_HAS_SHA3)
+
+PyDoc_STRVAR(_hashlib_openssl_sha3_224__doc__,
+"openssl_sha3_224($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a sha3-224 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA3_224_METHODDEF \
+ {"openssl_sha3_224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_224__doc__},
+
+static PyObject *
+_hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_224", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_sha3_224_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHA3) */
+
+#if defined(PY_OPENSSL_HAS_SHA3)
+
+PyDoc_STRVAR(_hashlib_openssl_sha3_256__doc__,
+"openssl_sha3_256($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a sha3-256 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA3_256_METHODDEF \
+ {"openssl_sha3_256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_256__doc__},
+
+static PyObject *
+_hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_256", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_sha3_256_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHA3) */
+
+#if defined(PY_OPENSSL_HAS_SHA3)
+
+PyDoc_STRVAR(_hashlib_openssl_sha3_384__doc__,
+"openssl_sha3_384($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a sha3-384 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA3_384_METHODDEF \
+ {"openssl_sha3_384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_384__doc__},
+
+static PyObject *
+_hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_384", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_sha3_384_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHA3) */
+
+#if defined(PY_OPENSSL_HAS_SHA3)
+
+PyDoc_STRVAR(_hashlib_openssl_sha3_512__doc__,
+"openssl_sha3_512($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a sha3-512 hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHA3_512_METHODDEF \
+ {"openssl_sha3_512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_512__doc__},
+
+static PyObject *
+_hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_512", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_sha3_512_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHA3) */
+
+#if defined(PY_OPENSSL_HAS_SHAKE)
+
+PyDoc_STRVAR(_hashlib_openssl_shake128__doc__,
+"openssl_shake128($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a shake128 variable hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHAKE128_METHODDEF \
+ {"openssl_shake128", (PyCFunction)(void(*)(void))_hashlib_openssl_shake128, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake128__doc__},
+
+static PyObject *
+_hashlib_openssl_shake128_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_shake128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake128", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_shake128_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHAKE) */
+
+#if defined(PY_OPENSSL_HAS_SHAKE)
+
+PyDoc_STRVAR(_hashlib_openssl_shake256__doc__,
+"openssl_shake256($module, /, string=b\'\', *, usedforsecurity=True)\n"
+"--\n"
+"\n"
+"Returns a shake256 variable hash object; optionally initialized with a string");
+
+#define _HASHLIB_OPENSSL_SHAKE256_METHODDEF \
+ {"openssl_shake256", (PyCFunction)(void(*)(void))_hashlib_openssl_shake256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake256__doc__},
+
+static PyObject *
+_hashlib_openssl_shake256_impl(PyObject *module, PyObject *data_obj,
+ int usedforsecurity);
+
+static PyObject *
+_hashlib_openssl_shake256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"string", "usedforsecurity", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake256", 0};
+ PyObject *argsbuf[2];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+ PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!noptargs) {
+ goto skip_optional_pos;
+ }
+ if (args[0]) {
+ data_obj = args[0];
+ if (!--noptargs) {
+ goto skip_optional_pos;
+ }
+ }
+skip_optional_pos:
+ if (!noptargs) {
+ goto skip_optional_kwonly;
+ }
+ usedforsecurity = PyObject_IsTrue(args[1]);
+ if (usedforsecurity < 0) {
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = _hashlib_openssl_shake256_impl(module, data_obj, usedforsecurity);
+
+exit:
+ return return_value;
+}
+
+#endif /* defined(PY_OPENSSL_HAS_SHAKE) */
+
PyDoc_STRVAR(pbkdf2_hmac__doc__,
"pbkdf2_hmac($module, /, hash_name, password, salt, iterations,\n"
" dklen=None)\n"
@@ -764,6 +1204,38 @@ exit:
#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
+#ifndef EVPXOF_DIGEST_METHODDEF
+ #define EVPXOF_DIGEST_METHODDEF
+#endif /* !defined(EVPXOF_DIGEST_METHODDEF) */
+
+#ifndef EVPXOF_HEXDIGEST_METHODDEF
+ #define EVPXOF_HEXDIGEST_METHODDEF
+#endif /* !defined(EVPXOF_HEXDIGEST_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHA3_224_METHODDEF
+ #define _HASHLIB_OPENSSL_SHA3_224_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHA3_224_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHA3_256_METHODDEF
+ #define _HASHLIB_OPENSSL_SHA3_256_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHA3_256_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHA3_384_METHODDEF
+ #define _HASHLIB_OPENSSL_SHA3_384_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHA3_384_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHA3_512_METHODDEF
+ #define _HASHLIB_OPENSSL_SHA3_512_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHA3_512_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHAKE128_METHODDEF
+ #define _HASHLIB_OPENSSL_SHAKE128_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHAKE128_METHODDEF) */
+
+#ifndef _HASHLIB_OPENSSL_SHAKE256_METHODDEF
+ #define _HASHLIB_OPENSSL_SHAKE256_METHODDEF
+#endif /* !defined(_HASHLIB_OPENSSL_SHAKE256_METHODDEF) */
+
#ifndef _HASHLIB_SCRYPT_METHODDEF
#define _HASHLIB_SCRYPT_METHODDEF
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
@@ -771,4 +1243,4 @@ exit:
#ifndef _HASHLIB_GET_FIPS_MODE_METHODDEF
#define _HASHLIB_GET_FIPS_MODE_METHODDEF
#endif /* !defined(_HASHLIB_GET_FIPS_MODE_METHODDEF) */
-/*[clinic end generated code: output=4babbd88389a196b input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a39bf0a766d7cdf7 input=a9049054013a1b77]*/