Commit c6c72372 authored by Tal Einat's avatar Tal Einat Committed by GitHub

bpo-20182: AC convert remaining functions/methods in _hashopenssl.c (GH-9213)

parent 34ae04f7
...@@ -26,12 +26,6 @@ ...@@ -26,12 +26,6 @@
#include <openssl/objects.h> #include <openssl/objects.h>
#include "openssl/err.h" #include "openssl/err.h"
#include "clinic/_hashopenssl.c.h"
/*[clinic input]
module _hashlib
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c2b4ff081bac4be1]*/
#define MUNCH_SIZE INT_MAX #define MUNCH_SIZE INT_MAX
#ifndef HASH_OBJ_CONSTRUCTOR #ifndef HASH_OBJ_CONSTRUCTOR
...@@ -72,6 +66,13 @@ DEFINE_CONSTS_FOR_NEW(sha256) ...@@ -72,6 +66,13 @@ DEFINE_CONSTS_FOR_NEW(sha256)
DEFINE_CONSTS_FOR_NEW(sha384) DEFINE_CONSTS_FOR_NEW(sha384)
DEFINE_CONSTS_FOR_NEW(sha512) DEFINE_CONSTS_FOR_NEW(sha512)
#include "clinic/_hashopenssl.c.h"
/*[clinic input]
module _hashlib
class _hashlib.HASH "EVPobject *" "&EVPtype"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a881a5092eecad28]*/
/* LCOV_EXCL_START */ /* LCOV_EXCL_START */
static PyObject * static PyObject *
...@@ -169,11 +170,15 @@ locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) ...@@ -169,11 +170,15 @@ locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
/* External methods for a hash object */ /* External methods for a hash object */
PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object."); /*[clinic input]
_hashlib.HASH.copy as EVP_copy
Return a copy of the hash object.
[clinic start generated code]*/
static PyObject * static PyObject *
EVP_copy(EVPobject *self, PyObject *unused) EVP_copy_impl(EVPobject *self)
/*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/
{ {
EVPobject *newobj; EVPobject *newobj;
...@@ -186,11 +191,15 @@ EVP_copy(EVPobject *self, PyObject *unused) ...@@ -186,11 +191,15 @@ EVP_copy(EVPobject *self, PyObject *unused)
return (PyObject *)newobj; return (PyObject *)newobj;
} }
PyDoc_STRVAR(EVP_digest__doc__, /*[clinic input]
"Return the digest value as a bytes object."); _hashlib.HASH.digest as EVP_digest
Return the digest value as a bytes object.
[clinic start generated code]*/
static PyObject * static PyObject *
EVP_digest(EVPobject *self, PyObject *unused) EVP_digest_impl(EVPobject *self)
/*[clinic end generated code: output=0f6a3a0da46dc12d input=03561809a419bf00]*/
{ {
unsigned char digest[EVP_MAX_MD_SIZE]; unsigned char digest[EVP_MAX_MD_SIZE];
EVP_MD_CTX *temp_ctx; EVP_MD_CTX *temp_ctx;
...@@ -217,11 +226,15 @@ EVP_digest(EVPobject *self, PyObject *unused) ...@@ -217,11 +226,15 @@ EVP_digest(EVPobject *self, PyObject *unused)
return retval; return retval;
} }
PyDoc_STRVAR(EVP_hexdigest__doc__, /*[clinic input]
"Return the digest value as a string of hexadecimal digits."); _hashlib.HASH.hexdigest as EVP_hexdigest
Return the digest value as a string of hexadecimal digits.
[clinic start generated code]*/
static PyObject * static PyObject *
EVP_hexdigest(EVPobject *self, PyObject *unused) EVP_hexdigest_impl(EVPobject *self)
/*[clinic end generated code: output=18e6decbaf197296 input=aff9cf0e4c741a9a]*/
{ {
unsigned char digest[EVP_MAX_MD_SIZE]; unsigned char digest[EVP_MAX_MD_SIZE];
EVP_MD_CTX *temp_ctx; EVP_MD_CTX *temp_ctx;
...@@ -248,18 +261,21 @@ EVP_hexdigest(EVPobject *self, PyObject *unused) ...@@ -248,18 +261,21 @@ EVP_hexdigest(EVPobject *self, PyObject *unused)
return _Py_strhex((const char *)digest, (Py_ssize_t)digest_size); return _Py_strhex((const char *)digest, (Py_ssize_t)digest_size);
} }
PyDoc_STRVAR(EVP_update__doc__, /*[clinic input]
"Update this hash object's state with the provided string."); _hashlib.HASH.update as EVP_update
obj: object
/
Update this hash object's state with the provided string.
[clinic start generated code]*/
static PyObject * static PyObject *
EVP_update(EVPobject *self, PyObject *args) EVP_update(EVPobject *self, PyObject *obj)
/*[clinic end generated code: output=ec1d55ed2432e966 input=9b30ec848f015501]*/
{ {
PyObject *obj;
Py_buffer view; Py_buffer view;
if (!PyArg_ParseTuple(args, "O:update", &obj))
return NULL;
GET_BUFFER_VIEW_OR_ERROUT(obj, &view); GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
...@@ -282,10 +298,10 @@ EVP_update(EVPobject *self, PyObject *args) ...@@ -282,10 +298,10 @@ EVP_update(EVPobject *self, PyObject *args)
} }
static PyMethodDef EVP_methods[] = { static PyMethodDef EVP_methods[] = {
{"update", (PyCFunction)EVP_update, METH_VARARGS, EVP_update__doc__}, EVP_UPDATE_METHODDEF
{"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__}, EVP_DIGEST_METHODDEF
{"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__}, EVP_HEXDIGEST_METHODDEF
{"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__}, EVP_COPY_METHODDEF
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
...@@ -329,24 +345,37 @@ EVP_repr(EVPobject *self) ...@@ -329,24 +345,37 @@ EVP_repr(EVPobject *self)
return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self); return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self);
} }
#if HASH_OBJ_CONSTRUCTOR /*[clinic input]
_hashlib.HASH.__init__ as EVP_tp_init
name as name_obj: object
string as data_obj: object(py_default="b''") = NULL
A hash is an object used to calculate a checksum of a string of information.
Methods:
update() -- updates the current digest with an additional string
digest() -- return the current digest value
hexdigest() -- return the current digest as a string of hexadecimal digits
copy() -- return a copy of the current hash object
Attributes:
name -- the hash algorithm being used by this object
digest_size -- number of bytes in this hashes output
[clinic start generated code]*/
static int static int
EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) EVP_tp_init_impl(EVPobject *self, PyObject *name_obj, PyObject *data_obj)
/*[clinic end generated code: output=44766d27757cf851 input=dac22658387f9b5d]*/
{ {
static char *kwlist[] = {"name", "string", NULL};
PyObject *name_obj = NULL;
PyObject *data_obj = NULL;
Py_buffer view; Py_buffer view;
char *nameStr; char *nameStr;
const EVP_MD *digest; const EVP_MD *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist,
&name_obj, &data_obj)) {
return -1;
}
if (data_obj) if (data_obj)
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); GET_BUFFER_VIEW_OR_ERROR(data_obj, &view, return -1);
if (!PyArg_Parse(name_obj, "s", &nameStr)) { if (!PyArg_Parse(name_obj, "s", &nameStr)) {
PyErr_SetString(PyExc_TypeError, "name must be a string"); PyErr_SetString(PyExc_TypeError, "name must be a string");
...@@ -385,24 +414,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) ...@@ -385,24 +414,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
return 0; return 0;
} }
#endif
PyDoc_STRVAR(hashtype_doc,
"A hash represents the object used to calculate a checksum of a\n\
string of information.\n\
\n\
Methods:\n\
\n\
update() -- updates the current digest with an additional string\n\
digest() -- return the current digest value\n\
hexdigest() -- return the current digest as a string of hexadecimal digits\n\
copy() -- return a copy of the current hash object\n\
\n\
Attributes:\n\
\n\
name -- the hash algorithm being used by this object\n\
digest_size -- number of bytes in this hashes output\n");
static PyTypeObject EVPtype = { static PyTypeObject EVPtype = {
PyVarObject_HEAD_INIT(NULL, 0) PyVarObject_HEAD_INIT(NULL, 0)
...@@ -426,7 +438,7 @@ static PyTypeObject EVPtype = { ...@@ -426,7 +438,7 @@ static PyTypeObject EVPtype = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
hashtype_doc, /*tp_doc*/ EVP_tp_init__doc__, /*tp_doc*/
0, /*tp_traverse*/ 0, /*tp_traverse*/
0, /*tp_clear*/ 0, /*tp_clear*/
0, /*tp_richcompare*/ 0, /*tp_richcompare*/
...@@ -489,29 +501,29 @@ EVPnew(PyObject *name_obj, ...@@ -489,29 +501,29 @@ EVPnew(PyObject *name_obj,
/* The module-level function: new() */ /* The module-level function: new() */
PyDoc_STRVAR(EVP_new__doc__, /*[clinic input]
"Return a new hash object using the named algorithm.\n\ _hashlib.new as EVP_new
An optional string argument may be provided and will be\n\
automatically hashed.\n\ name as name_obj: object
\n\ string as data_obj: object(py_default="b''") = NULL
The MD5 and SHA1 algorithms are always supported.\n");
Return a new hash object using the named algorithm.
An optional string argument may be provided and will be
automatically hashed.
The MD5 and SHA1 algorithms are always supported.
[clinic start generated code]*/
static PyObject * static PyObject *
EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj)
/*[clinic end generated code: output=9e7cf664e04b0226 input=1c46e40e0fec91f3]*/
{ {
static char *kwlist[] = {"name", "string", NULL};
PyObject *name_obj = NULL;
PyObject *data_obj = NULL;
Py_buffer view = { 0 }; Py_buffer view = { 0 };
PyObject *ret_obj; PyObject *ret_obj;
char *name; char *name;
const EVP_MD *digest; const EVP_MD *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist,
&name_obj, &data_obj)) {
return NULL;
}
if (!PyArg_Parse(name_obj, "s", &name)) { if (!PyArg_Parse(name_obj, "s", &name)) {
PyErr_SetString(PyExc_TypeError, "name must be a string"); PyErr_SetString(PyExc_TypeError, "name must be a string");
return NULL; return NULL;
...@@ -619,43 +631,44 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, ...@@ -619,43 +631,44 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
#endif #endif
PyDoc_STRVAR(pbkdf2_hmac__doc__,
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\ /*[clinic input]
\n\ _hashlib.pbkdf2_hmac as pbkdf2_hmac
Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as\n\
pseudorandom function."); hash_name: str
password: Py_buffer
salt: Py_buffer
iterations: long
dklen as dklen_obj: object = None
Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function.
[clinic start generated code]*/
static PyObject * static PyObject *
pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict) pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
Py_buffer *password, Py_buffer *salt, long iterations,
PyObject *dklen_obj)
/*[clinic end generated code: output=144b76005416599b input=ed3ab0d2d28b5d5c]*/
{ {
static char *kwlist[] = {"hash_name", "password", "salt", "iterations", PyObject *key_obj = NULL;
"dklen", NULL}; char *key;
PyObject *key_obj = NULL, *dklen_obj = Py_None; long dklen;
char *name, *key;
Py_buffer password, salt;
long iterations, dklen;
int retval; int retval;
const EVP_MD *digest; const EVP_MD *digest;
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "sy*y*l|O:pbkdf2_hmac", digest = EVP_get_digestbyname(hash_name);
kwlist, &name, &password, &salt,
&iterations, &dklen_obj)) {
return NULL;
}
digest = EVP_get_digestbyname(name);
if (digest == NULL) { if (digest == NULL) {
PyErr_SetString(PyExc_ValueError, "unsupported hash type"); PyErr_SetString(PyExc_ValueError, "unsupported hash type");
goto end; goto end;
} }
if (password.len > INT_MAX) { if (password->len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"password is too long."); "password is too long.");
goto end; goto end;
} }
if (salt.len > INT_MAX) { if (salt->len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"salt is too long."); "salt is too long.");
goto end; goto end;
...@@ -700,13 +713,13 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict) ...@@ -700,13 +713,13 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
#if HAS_FAST_PKCS5_PBKDF2_HMAC #if HAS_FAST_PKCS5_PBKDF2_HMAC
retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len, retval = PKCS5_PBKDF2_HMAC((char*)password->buf, (int)password->len,
(unsigned char *)salt.buf, (int)salt.len, (unsigned char *)salt->buf, (int)salt->len,
iterations, digest, dklen, iterations, digest, dklen,
(unsigned char *)key); (unsigned char *)key);
#else #else
retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len, retval = PKCS5_PBKDF2_HMAC_fast((char*)password->buf, (int)password->len,
(unsigned char *)salt.buf, (int)salt.len, (unsigned char *)salt->buf, (int)salt->len,
iterations, digest, dklen, iterations, digest, dklen,
(unsigned char *)key); (unsigned char *)key);
#endif #endif
...@@ -719,8 +732,6 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict) ...@@ -719,8 +732,6 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
} }
end: end:
PyBuffer_Release(&password);
PyBuffer_Release(&salt);
return key_obj; return key_obj;
} }
...@@ -1034,10 +1045,9 @@ GEN_CONSTRUCTOR(sha512) ...@@ -1034,10 +1045,9 @@ GEN_CONSTRUCTOR(sha512)
/* List of functions exported by this module */ /* List of functions exported by this module */
static struct PyMethodDef EVP_functions[] = { static struct PyMethodDef EVP_functions[] = {
{"new", (PyCFunction)(void(*)(void))EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__}, EVP_NEW_METHODDEF
#ifdef PY_PBKDF2_HMAC #ifdef PY_PBKDF2_HMAC
{"pbkdf2_hmac", (PyCFunction)(void(*)(void))pbkdf2_hmac, METH_VARARGS|METH_KEYWORDS, PBKDF2_HMAC_METHODDEF
pbkdf2_hmac__doc__},
#endif #endif
_HASHLIB_SCRYPT_METHODDEF _HASHLIB_SCRYPT_METHODDEF
_HASHLIB_HMAC_DIGEST_METHODDEF _HASHLIB_HMAC_DIGEST_METHODDEF
......
...@@ -2,6 +2,195 @@ ...@@ -2,6 +2,195 @@
preserve preserve
[clinic start generated code]*/ [clinic start generated code]*/
PyDoc_STRVAR(EVP_copy__doc__,
"copy($self, /)\n"
"--\n"
"\n"
"Return a copy of the hash object.");
#define EVP_COPY_METHODDEF \
{"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__},
static PyObject *
EVP_copy_impl(EVPobject *self);
static PyObject *
EVP_copy(EVPobject *self, PyObject *Py_UNUSED(ignored))
{
return EVP_copy_impl(self);
}
PyDoc_STRVAR(EVP_digest__doc__,
"digest($self, /)\n"
"--\n"
"\n"
"Return the digest value as a bytes object.");
#define EVP_DIGEST_METHODDEF \
{"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__},
static PyObject *
EVP_digest_impl(EVPobject *self);
static PyObject *
EVP_digest(EVPobject *self, PyObject *Py_UNUSED(ignored))
{
return EVP_digest_impl(self);
}
PyDoc_STRVAR(EVP_hexdigest__doc__,
"hexdigest($self, /)\n"
"--\n"
"\n"
"Return the digest value as a string of hexadecimal digits.");
#define EVP_HEXDIGEST_METHODDEF \
{"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__},
static PyObject *
EVP_hexdigest_impl(EVPobject *self);
static PyObject *
EVP_hexdigest(EVPobject *self, PyObject *Py_UNUSED(ignored))
{
return EVP_hexdigest_impl(self);
}
PyDoc_STRVAR(EVP_update__doc__,
"update($self, obj, /)\n"
"--\n"
"\n"
"Update this hash object\'s state with the provided string.");
#define EVP_UPDATE_METHODDEF \
{"update", (PyCFunction)EVP_update, METH_O, EVP_update__doc__},
PyDoc_STRVAR(EVP_tp_init__doc__,
"HASH(name, string=b\'\')\n"
"--\n"
"\n"
"A hash is an object used to calculate a checksum of a string of information.\n"
"\n"
"Methods:\n"
"\n"
"update() -- updates the current digest with an additional string\n"
"digest() -- return the current digest value\n"
"hexdigest() -- return the current digest as a string of hexadecimal digits\n"
"copy() -- return a copy of the current hash object\n"
"\n"
"Attributes:\n"
"\n"
"name -- the hash algorithm being used by this object\n"
"digest_size -- number of bytes in this hashes output");
static int
EVP_tp_init_impl(EVPobject *self, PyObject *name_obj, PyObject *data_obj);
static int
EVP_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
int return_value = -1;
static const char * const _keywords[] = {"name", "string", NULL};
static _PyArg_Parser _parser = {"O|O:HASH", _keywords, 0};
PyObject *name_obj;
PyObject *data_obj = NULL;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&name_obj, &data_obj)) {
goto exit;
}
return_value = EVP_tp_init_impl((EVPobject *)self, name_obj, data_obj);
exit:
return return_value;
}
PyDoc_STRVAR(EVP_new__doc__,
"new($module, /, name, string=b\'\')\n"
"--\n"
"\n"
"Return a new hash object using the named algorithm.\n"
"\n"
"An optional string argument may be provided and will be\n"
"automatically hashed.\n"
"\n"
"The MD5 and SHA1 algorithms are always supported.");
#define EVP_NEW_METHODDEF \
{"new", (PyCFunction)(void(*)(void))EVP_new, METH_FASTCALL|METH_KEYWORDS, EVP_new__doc__},
static PyObject *
EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj);
static PyObject *
EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"name", "string", NULL};
static _PyArg_Parser _parser = {"O|O:new", _keywords, 0};
PyObject *name_obj;
PyObject *data_obj = NULL;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&name_obj, &data_obj)) {
goto exit;
}
return_value = EVP_new_impl(module, name_obj, data_obj);
exit:
return return_value;
}
#if ((OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA)))
PyDoc_STRVAR(pbkdf2_hmac__doc__,
"pbkdf2_hmac($module, /, hash_name, password, salt, iterations,\n"
" dklen=None)\n"
"--\n"
"\n"
"Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function.");
#define PBKDF2_HMAC_METHODDEF \
{"pbkdf2_hmac", (PyCFunction)(void(*)(void))pbkdf2_hmac, METH_FASTCALL|METH_KEYWORDS, pbkdf2_hmac__doc__},
static PyObject *
pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
Py_buffer *password, Py_buffer *salt, long iterations,
PyObject *dklen_obj);
static PyObject *
pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL};
static _PyArg_Parser _parser = {"sy*y*l|O:pbkdf2_hmac", _keywords, 0};
const char *hash_name;
Py_buffer password = {NULL, NULL};
Py_buffer salt = {NULL, NULL};
long iterations;
PyObject *dklen_obj = Py_None;
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
&hash_name, &password, &salt, &iterations, &dklen_obj)) {
goto exit;
}
return_value = pbkdf2_hmac_impl(module, hash_name, &password, &salt, iterations, dklen_obj);
exit:
/* Cleanup for password */
if (password.obj) {
PyBuffer_Release(&password);
}
/* Cleanup for salt */
if (salt.obj) {
PyBuffer_Release(&salt);
}
return return_value;
}
#endif /* ((OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA))) */
#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) #if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER))
PyDoc_STRVAR(_hashlib_scrypt__doc__, PyDoc_STRVAR(_hashlib_scrypt__doc__,
...@@ -96,7 +285,11 @@ exit: ...@@ -96,7 +285,11 @@ exit:
return return_value; return return_value;
} }
#ifndef PBKDF2_HMAC_METHODDEF
#define PBKDF2_HMAC_METHODDEF
#endif /* !defined(PBKDF2_HMAC_METHODDEF) */
#ifndef _HASHLIB_SCRYPT_METHODDEF #ifndef _HASHLIB_SCRYPT_METHODDEF
#define _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
/*[clinic end generated code: output=acf668396f59f2b6 input=a9049054013a1b77]*/ /*[clinic end generated code: output=cae09468e2cdbefe input=a9049054013a1b77]*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment