diff options
author | Christian Heimes <christian@python.org> | 2020-05-17 11:49:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-17 11:49:10 (GMT) |
commit | 54f2898fe7e4ca1f239e96284af3cc5b34d2ae02 (patch) | |
tree | 39080535b3c75be9a15cf5d9664381e24fe9de6c /Modules/clinic/_hashopenssl.c.h | |
parent | 46545000c2a30b46aed717b546bc09e5bae7148f (diff) | |
download | cpython-54f2898fe7e4ca1f239e96284af3cc5b34d2ae02.zip cpython-54f2898fe7e4ca1f239e96284af3cc5b34d2ae02.tar.gz cpython-54f2898fe7e4ca1f239e96284af3cc5b34d2ae02.tar.bz2 |
bpo-40645: Implement HMAC in C (GH-20129)
The internal module ``_hashlib`` wraps and exposes OpenSSL's HMAC API. The
new code will be used in Python 3.10 after the internal implementation
details of the pure Python HMAC module are no longer part of the public API.
The code is based on a patch by Petr Viktorin for RHEL and Python 3.6.
Co-Authored-By: Petr Viktorin <encukou@gmail.com>
Diffstat (limited to 'Modules/clinic/_hashopenssl.c.h')
-rw-r--r-- | Modules/clinic/_hashopenssl.c.h | 175 |
1 files changed, 167 insertions, 8 deletions
diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 71c9246..8745fc7 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -1095,21 +1095,21 @@ exit: #endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ -PyDoc_STRVAR(_hashlib_hmac_digest__doc__, +PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, "hmac_digest($module, /, key, msg, digest)\n" "--\n" "\n" "Single-shot HMAC."); -#define _HASHLIB_HMAC_DIGEST_METHODDEF \ - {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_digest, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_digest__doc__}, +#define _HASHLIB_HMAC_SINGLESHOT_METHODDEF \ + {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_singleshot, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__}, static PyObject * -_hashlib_hmac_digest_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, - const char *digest); +_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, + Py_buffer *msg, const char *digest); static PyObject * -_hashlib_hmac_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "msg", "digest", NULL}; @@ -1150,7 +1150,7 @@ _hashlib_hmac_digest(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _hashlib_hmac_digest_impl(module, &key, &msg, digest); + return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest); exit: /* Cleanup for key */ @@ -1165,6 +1165,165 @@ exit: return return_value; } +PyDoc_STRVAR(_hashlib_hmac_new__doc__, +"hmac_new($module, /, key, msg=b\'\', digestmod=None)\n" +"--\n" +"\n" +"Return a new hmac object."); + +#define _HASHLIB_HMAC_NEW_METHODDEF \ + {"hmac_new", (PyCFunction)(void(*)(void))_hashlib_hmac_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_new__doc__}, + +static PyObject * +_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, + const char *digestmod); + +static PyObject * +_hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer key = {NULL, NULL}; + PyObject *msg_obj = NULL; + const char *digestmod = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&key, 'C')) { + _PyArg_BadArgument("hmac_new", "argument 'key'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + msg_obj = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("hmac_new", "argument 'digestmod'", "str", args[2]); + goto exit; + } + Py_ssize_t digestmod_length; + digestmod = PyUnicode_AsUTF8AndSize(args[2], &digestmod_length); + if (digestmod == NULL) { + goto exit; + } + if (strlen(digestmod) != (size_t)digestmod_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_pos: + return_value = _hashlib_hmac_new_impl(module, &key, msg_obj, digestmod); + +exit: + /* Cleanup for key */ + if (key.obj) { + PyBuffer_Release(&key); + } + + return return_value; +} + +PyDoc_STRVAR(_hashlib_HMAC_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy (\"clone\") of the HMAC object."); + +#define _HASHLIB_HMAC_COPY_METHODDEF \ + {"copy", (PyCFunction)_hashlib_HMAC_copy, METH_NOARGS, _hashlib_HMAC_copy__doc__}, + +static PyObject * +_hashlib_HMAC_copy_impl(HMACobject *self); + +static PyObject * +_hashlib_HMAC_copy(HMACobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _hashlib_HMAC_copy_impl(self); +} + +PyDoc_STRVAR(_hashlib_HMAC_update__doc__, +"update($self, /, msg)\n" +"--\n" +"\n" +"Update the HMAC object with msg."); + +#define _HASHLIB_HMAC_UPDATE_METHODDEF \ + {"update", (PyCFunction)(void(*)(void))_hashlib_HMAC_update, METH_FASTCALL|METH_KEYWORDS, _hashlib_HMAC_update__doc__}, + +static PyObject * +_hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg); + +static PyObject * +_hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"msg", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "update", 0}; + PyObject *argsbuf[1]; + PyObject *msg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + msg = args[0]; + return_value = _hashlib_HMAC_update_impl(self, msg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_hashlib_HMAC_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest of the bytes passed to the update() method so far."); + +#define _HASHLIB_HMAC_DIGEST_METHODDEF \ + {"digest", (PyCFunction)_hashlib_HMAC_digest, METH_NOARGS, _hashlib_HMAC_digest__doc__}, + +static PyObject * +_hashlib_HMAC_digest_impl(HMACobject *self); + +static PyObject * +_hashlib_HMAC_digest(HMACobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _hashlib_HMAC_digest_impl(self); +} + +PyDoc_STRVAR(_hashlib_HMAC_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return hexadecimal digest of the bytes passed to the update() method so far.\n" +"\n" +"This may be used to exchange the value safely in email or other non-binary\n" +"environments."); + +#define _HASHLIB_HMAC_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)_hashlib_HMAC_hexdigest, METH_NOARGS, _hashlib_HMAC_hexdigest__doc__}, + +static PyObject * +_hashlib_HMAC_hexdigest_impl(HMACobject *self); + +static PyObject * +_hashlib_HMAC_hexdigest(HMACobject *self, PyObject *Py_UNUSED(ignored)) +{ + return _hashlib_HMAC_hexdigest_impl(self); +} + #if !defined(LIBRESSL_VERSION_NUMBER) PyDoc_STRVAR(_hashlib_get_fips_mode__doc__, @@ -1243,4 +1402,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=a39bf0a766d7cdf7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=972a198d2e8434bd input=a9049054013a1b77]*/ |