From 04bcb72cab2733ea348b0914b705a5458b8f9c71 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sat, 23 Apr 2016 21:14:40 +0200 Subject: [PATCH] Add truncate SHA512/224 and SHA512/256 hash algorithms Truncated SHA512 variants with 28 and 32 byte digest use different initialization vector. Signed-off-by: Christian Heimes --- Doc/library/hashlib.rst | 27 +++ Lib/hashlib.py | 8 +- Lib/test/test_hashlib.py | 48 ++++- Modules/clinic/sha512module.c.h | 103 +++------- Modules/sha512module.c | 417 ++++++++++++++++++++++++++++------------ 5 files changed, 398 insertions(+), 205 deletions(-) diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 73a7555e457332fb270090a58372eac2e5ffcdb4..55f97db72dbd13aec4eb97bb54529e7588ab209e 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -176,6 +176,33 @@ A hash object has the following methods: compute the digests of data sharing a common initial substring. ++-------------+--------------------+-------------+------------+-----------------------------+ +| name | constructor | digest size | block size | comment | ++=============+====================+=============+============+=============================+ +| MD5 | :func:`md5` | 16 | 64 | **broken** | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-1 | :func:`sha1` | 20 | 64 | **weaken** | ++-------------+--------------------+-------------+------------+-----------------------------+ +| **SHA-2 family** | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-224 | :func:`sha224` | 28 | 64 | | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-256 | :func:`sha256` | 32 | 64 | | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-384 | :func:`sha384` | 48 | 128 | | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-512 | :func:`sha512` | 64 | 128 | | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-512/224 | :func:`sha512_224` | 28 | 128 | new in Python 3.6 | ++-------------+--------------------+-------------+------------+-----------------------------+ +| SHA-512/256 | :func:`sha512_256` | 32 | 128 | new in Python 3.6 | ++-------------+--------------------+-------------+------------+-----------------------------+ + + +.. versionadded:: 3.6 + Truncated SHA-512 :func:`sha512_224` and :func:`sha512_256`, + + Key derivation -------------- diff --git a/Lib/hashlib.py b/Lib/hashlib.py index 316cecedc209d861db8a46768594b08804348cf7..10a5ab7fe9bce6006a140d4755104aac3e30bf01 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -54,7 +54,8 @@ More condensed: # This tuple and __get_builtin_constructor() must be modified if a new # always available algorithm is added. -__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') +__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', + 'sha512_256', 'sha512_224') algorithms_guaranteed = set(__always_supported) algorithms_available = set(__always_supported) @@ -81,10 +82,13 @@ def __get_builtin_constructor(name): import _sha256 cache['SHA224'] = cache['sha224'] = _sha256.sha224 cache['SHA256'] = cache['sha256'] = _sha256.sha256 - elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'): + elif name in {'SHA512', 'sha512', 'SHA384', 'sha384', + 'sha512_256', 'sha512_224'}: import _sha512 cache['SHA384'] = cache['sha384'] = _sha512.sha384 cache['SHA512'] = cache['sha512'] = _sha512.sha512 + cache['sha512_256'] = _sha512.sha512_256 + cache['sha512_224'] = _sha512.sha512_224 except ImportError: pass # no extension module, this hash is unsupported. diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 8a297dd45eaee2f1f7cfc1f492d5055c9aeb0553..30b39a3e82a34e7b6aa008e819d5399f47989718 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -38,7 +38,8 @@ def hexstr(s): class HashLibTestCase(unittest.TestCase): supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', 'sha224', 'SHA224', 'sha256', 'SHA256', - 'sha384', 'SHA384', 'sha512', 'SHA512') + 'sha384', 'SHA384', 'sha512', 'SHA512', + 'sha512_256', 'sha512_224') # Issue #14693: fallback modules are always compiled under POSIX _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG @@ -99,6 +100,8 @@ class HashLibTestCase(unittest.TestCase): if _sha512: add_builtin_constructor('sha384') add_builtin_constructor('sha512') + add_builtin_constructor('sha512_256') + add_builtin_constructor('sha512_224') super(HashLibTestCase, self).__init__(*args, **kwargs) @@ -225,6 +228,8 @@ class HashLibTestCase(unittest.TestCase): self.check_no_unicode('sha256') self.check_no_unicode('sha384') self.check_no_unicode('sha512') + self.check_no_unicode('sha512_256') + self.check_no_unicode('sha512_224') def check_blocksize_name(self, name, block_size=0, digest_size=0): constructors = self.constructors_to_test[name] @@ -233,6 +238,7 @@ class HashLibTestCase(unittest.TestCase): self.assertEqual(m.block_size, block_size) self.assertEqual(m.digest_size, digest_size) self.assertEqual(len(m.digest()), digest_size) + self.assertEqual(len(m.hexdigest()), 2*digest_size) self.assertEqual(m.name, name) # split for sha3_512 / _sha3.sha3 object self.assertIn(name.split("_")[0], repr(m)) @@ -244,6 +250,8 @@ class HashLibTestCase(unittest.TestCase): self.check_blocksize_name('sha256', 64, 32) self.check_blocksize_name('sha384', 128, 48) self.check_blocksize_name('sha512', 128, 64) + self.check_blocksize_name('sha512_256', 128, 32) + self.check_blocksize_name('sha512_224', 128, 28) def test_case_md5_0(self): self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e') @@ -290,7 +298,7 @@ class HashLibTestCase(unittest.TestCase): # use the examples from Federal Information Processing Standards # Publication 180-2, Secure Hash Standard, 2002 August 1 - # http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + ## http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf def test_case_sha224_0(self): self.check('sha224', b"", @@ -373,6 +381,42 @@ class HashLibTestCase(unittest.TestCase): "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b") + def test_case_sha512_256_0(self): + self.check('sha512_256', b"", + "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a") + + def test_case_sha512_256_1(self): + self.check('sha512_256', b"abc", + "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23") + + def test_case_sha512_256_2(self): + self.check('sha512_256', + b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+ + b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a") + + def test_case_sha512_256_3(self): + self.check('sha512_256', b"a" * 1000000, + "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21") + + def test_case_sha512_224_0(self): + self.check('sha512_224', b"", + "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4") + + def test_case_sha512_224_1(self): + self.check('sha512_224', b"abc", + "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa") + + def test_case_sha512_224_2(self): + self.check('sha512_224', + b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"+ + b"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + "23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9") + + def test_case_sha512_224_3(self): + self.check('sha512_224', b"a" * 1000000, + "37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287") + def test_gil(self): # Check things work fine with an input larger than the size required # for multithreaded operation (which is hardwired to 2048). diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index c308739d44836bf28ccd03da208d253f6ea3421b..64640082f5140364664b4b6f09edeb9dfe58f36b 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -4,6 +4,35 @@ preserve #if defined(PY_LONG_LONG) +PyDoc_STRVAR(SHA512_new__doc__, +"SHA512Type(string=b\'\')\n" +"--\n" +"\n" +"Return a new SHA-512 hash object; optionally initialized with a string."); + +static PyObject * +SHA512_new_impl(PyTypeObject *type, PyObject *string); + +static PyObject * +SHA512_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:SHA512Type", _keywords, + &string)) + goto exit; + return_value = SHA512_new_impl(type, string); + +exit: + return return_value; +} + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + PyDoc_STRVAR(SHA512Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -81,70 +110,6 @@ PyDoc_STRVAR(SHA512Type_update__doc__, #endif /* defined(PY_LONG_LONG) */ -#if defined(PY_LONG_LONG) - -PyDoc_STRVAR(_sha512_sha512__doc__, -"sha512($module, /, string=b\'\')\n" -"--\n" -"\n" -"Return a new SHA-512 hash object; optionally initialized with a string."); - -#define _SHA512_SHA512_METHODDEF \ - {"sha512", (PyCFunction)_sha512_sha512, METH_VARARGS|METH_KEYWORDS, _sha512_sha512__doc__}, - -static PyObject * -_sha512_sha512_impl(PyModuleDef *module, PyObject *string); - -static PyObject * -_sha512_sha512(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; - PyObject *string = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha512", _keywords, - &string)) - goto exit; - return_value = _sha512_sha512_impl(module, string); - -exit: - return return_value; -} - -#endif /* defined(PY_LONG_LONG) */ - -#if defined(PY_LONG_LONG) - -PyDoc_STRVAR(_sha512_sha384__doc__, -"sha384($module, /, string=b\'\')\n" -"--\n" -"\n" -"Return a new SHA-384 hash object; optionally initialized with a string."); - -#define _SHA512_SHA384_METHODDEF \ - {"sha384", (PyCFunction)_sha512_sha384, METH_VARARGS|METH_KEYWORDS, _sha512_sha384__doc__}, - -static PyObject * -_sha512_sha384_impl(PyModuleDef *module, PyObject *string); - -static PyObject * -_sha512_sha384(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"string", NULL}; - PyObject *string = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha384", _keywords, - &string)) - goto exit; - return_value = _sha512_sha384_impl(module, string); - -exit: - return return_value; -} - -#endif /* defined(PY_LONG_LONG) */ - #ifndef SHA512TYPE_COPY_METHODDEF #define SHA512TYPE_COPY_METHODDEF #endif /* !defined(SHA512TYPE_COPY_METHODDEF) */ @@ -160,12 +125,4 @@ exit: #ifndef SHA512TYPE_UPDATE_METHODDEF #define SHA512TYPE_UPDATE_METHODDEF #endif /* !defined(SHA512TYPE_UPDATE_METHODDEF) */ - -#ifndef _SHA512_SHA512_METHODDEF - #define _SHA512_SHA512_METHODDEF -#endif /* !defined(_SHA512_SHA512_METHODDEF) */ - -#ifndef _SHA512_SHA384_METHODDEF - #define _SHA512_SHA384_METHODDEF -#endif /* !defined(_SHA512_SHA384_METHODDEF) */ -/*[clinic end generated code: output=1c7d385731fee7c0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a569d7b471fed76f input=a9049054013a1b77]*/ diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 8237d867f4aa28b15ef23c106e0f922b49666b40..7bfb1d99ac77e59879cb03f6077a65add709aca8 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -20,6 +20,9 @@ #include "structmember.h" #include "hashlib.h" #include "pystrhex.h" +#ifdef WITH_THREAD +#include "pythread.h" +#endif /*[clinic input] module _sha512 @@ -54,6 +57,9 @@ typedef struct { SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ int local; /* unprocessed amount in data */ int digestsize; +#ifdef WITH_THREAD + PyThread_type_lock lock; +#endif } SHAobject; #include "clinic/sha512module.c.h" @@ -286,6 +292,39 @@ sha384_init(SHAobject *sha_info) sha_info->digestsize = 48; } +static void +sha512_224_init(SHAobject *sha_info) +{ + sha_info->digest[0] = Py_ULL(0x8C3D37C819544DA2); + sha_info->digest[1] = Py_ULL(0x73E1996689DCD4D6); + sha_info->digest[2] = Py_ULL(0x1DFAB7AE32FF9C82); + sha_info->digest[3] = Py_ULL(0x679DD514582F9FCF); + sha_info->digest[4] = Py_ULL(0x0F6D2B697BD44DA8); + sha_info->digest[5] = Py_ULL(0x77E36F7304C48942); + sha_info->digest[6] = Py_ULL(0x3F9D85A86A1D36C8); + sha_info->digest[7] = Py_ULL(0x1112E6AD91D692A1); + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 28; +} + +static void +sha512_256_init(SHAobject *sha_info) +{ + sha_info->digest[0] = Py_ULL(0x22312194FC2BF72C); + sha_info->digest[1] = Py_ULL(0x9F555FA3C84C64C2); + sha_info->digest[2] = Py_ULL(0x2393B86B6F53B151); + sha_info->digest[3] = Py_ULL(0x963877195940EABD); + sha_info->digest[4] = Py_ULL(0x96283EE2A88EFFE3); + sha_info->digest[5] = Py_ULL(0xBE5E1E2553863992); + sha_info->digest[6] = Py_ULL(0x2B0199FC2C85B8AA); + sha_info->digest[7] = Py_ULL(0x0EB72DDC81C52CA2); + sha_info->count_lo = 0L; + sha_info->count_hi = 0L; + sha_info->local = 0; + sha_info->digestsize = 32; +} /* update the SHA digest */ @@ -443,26 +482,92 @@ sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) static PyTypeObject SHA384type; static PyTypeObject SHA512type; +static PyTypeObject SHA512_224type; +static PyTypeObject SHA512_256type; static SHAobject * -newSHA384object(void) +newSHA512object(PyTypeObject *type) { - return (SHAobject *)PyObject_New(SHAobject, &SHA384type); -} - -static SHAobject * -newSHA512object(void) -{ - return (SHAobject *)PyObject_New(SHAobject, &SHA512type); + SHAobject *self; + self = (SHAobject *)PyObject_New(SHAobject, type); +#ifdef WITH_THREAD + if (self != NULL) { + self->lock = NULL; + } +#endif + return self; } /* Internal methods for a hash object */ +/*[clinic input] +@classmethod +SHA512Type.__new__ as SHA512_new + + string: object(c_default="NULL") = b'' + +Return a new SHA-512 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +SHA512_new_impl(PyTypeObject *type, PyObject *string) +/*[clinic end generated code: output=1c3501f998b25eb2 input=923e9d9cb8b9d060]*/ +{ + SHAobject *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA512object(type)) == NULL) { + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + if (type == &SHA512type) { + sha512_init(new); + } else if (type == &SHA384type) { + sha384_init(new); + } else if (type == &SHA512_256type) { + sha512_256_init(new); + } else if (type == &SHA512_224type) { + sha512_224_init(new); + } + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + Py_BEGIN_ALLOW_THREADS + sha512_update(new, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + sha512_update(new, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + static void -SHA512_dealloc(PyObject *ptr) +SHA512_dealloc(PyObject *self) { - PyObject_Del(ptr); +#ifdef WITH_THREAD + SHAobject *obj = (SHAobject *)self; + if (obj->lock) { + PyThread_free_lock(obj->lock); + obj->lock = NULL; + } +#endif + PyObject_Del(self); } @@ -480,15 +585,12 @@ SHA512Type_copy_impl(SHAobject *self) { SHAobject *newobj; - if (((PyObject*)self)->ob_type == &SHA512type) { - if ( (newobj = newSHA512object())==NULL) - return NULL; - } else { - if ( (newobj = newSHA384object())==NULL) - return NULL; + if ((newobj = newSHA512object(Py_TYPE(self))) == NULL) { + return NULL; } - + ENTER_HASHLIB(self); SHAcopy(self, newobj); + LEAVE_HASHLIB(self); return (PyObject *)newobj; } @@ -505,7 +607,9 @@ SHA512Type_digest_impl(SHAobject *self) unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; + ENTER_HASHLIB(self); SHAcopy(self, &temp); + LEAVE_HASHLIB(self); sha512_final(digest, &temp); return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } @@ -524,7 +628,9 @@ SHA512Type_hexdigest_impl(SHAobject *self) SHAobject temp; /* Get the raw (binary) digest value */ + ENTER_HASHLIB(self); SHAcopy(self, &temp); + LEAVE_HASHLIB(self); sha512_final(digest, &temp); return _Py_strhex((const char *)digest, self->digestsize); @@ -547,12 +653,27 @@ SHA512Type_update(SHAobject *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); +#ifdef WITH_THREAD + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) + self->lock = PyThread_allocate_lock(); + + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + sha512_update(self, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + sha512_update(self, buf.buf, buf.len); + } +#else sha512_update(self, buf.buf, buf.len); +#endif /* !WITH_THREAD */ PyBuffer_Release(&buf); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } + /*[clinic input] dump buffer [clinic start generated code]*/ @@ -575,10 +696,19 @@ SHA512_get_block_size(PyObject *self, void *closure) static PyObject * SHA512_get_name(PyObject *self, void *closure) { - if (((SHAobject *)self)->digestsize == 64) - return PyUnicode_FromStringAndSize("sha512", 6); - else - return PyUnicode_FromStringAndSize("sha384", 6); + switch (((SHAobject *)self)->digestsize) { + case 64: + return PyUnicode_FromStringAndSize("sha512", 6); + case 48: + return PyUnicode_FromStringAndSize("sha384", 6); + case 32: + return PyUnicode_FromStringAndSize("sha512_256", 10); + case 28: + return PyUnicode_FromStringAndSize("sha512_224", 10); + default: + PyErr_SetString(PyExc_RuntimeError, "Invalid digestsize"); + return NULL; + } } static PyGetSetDef SHA_getseters[] = { @@ -598,6 +728,13 @@ static PyMemberDef SHA_members[] = { {NULL} /* Sentinel */ }; +PyDoc_STRVAR(SHA384_new__doc__, +"SHA384Type(string=b\'\')\n" +"--\n" +"\n" +"Return a new SHA-384 hash object; optionally initialized with a string."); + + static PyTypeObject SHA384type = { PyVarObject_HEAD_INIT(NULL, 0) "_sha512.sha384", /*tp_name*/ @@ -620,16 +757,24 @@ static PyTypeObject SHA384type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ + SHA384_new__doc__, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ - SHA_methods, /* tp_methods */ - SHA_members, /* tp_members */ - SHA_getseters, /* tp_getset */ + SHA_methods, /*tp_methods*/ + SHA_members, /*tp_members */ + SHA_getseters, /*tp_getset */ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + SHA512_new, /*tp_new*/ }; static PyTypeObject SHA512type = { @@ -654,7 +799,7 @@ static PyTypeObject SHA512type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ + SHA512_new__doc__, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ @@ -664,109 +809,115 @@ static PyTypeObject SHA512type = { SHA_methods, /* tp_methods */ SHA_members, /* tp_members */ SHA_getseters, /* tp_getset */ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + SHA512_new, /*tp_new*/ }; -/* The single module-level function: new() */ - -/*[clinic input] -_sha512.sha512 - - string: object(c_default="NULL") = b'' - -Return a new SHA-512 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha512_sha512_impl(PyModuleDef *module, PyObject *string) -/*[clinic end generated code: output=da13bc0a94da6de3 input=e69bad9ae9b6a308]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA512object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha512_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - -/*[clinic input] -_sha512.sha384 - - string: object(c_default="NULL") = b'' - -Return a new SHA-384 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha512_sha384_impl(PyModuleDef *module, PyObject *string) -/*[clinic end generated code: output=ac731aea5509174d input=c9327788d4ea4545]*/ -{ - SHAobject *new; - Py_buffer buf; - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA384object()) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha384_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/*[clinic input] -dump buffer -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA_functions[] = { - _SHA512_SHA512_METHODDEF - _SHA512_SHA384_METHODDEF - {NULL, NULL} /* Sentinel */ +PyDoc_STRVAR(SHA512_256_new__doc__, +"SHA512_256Type(string=b\'\')\n" +"--\n" +"\n" +"Return a new SHA-512-256 hash object; optionally initialized with a string."); + + +static PyTypeObject SHA512_256type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha512.sha512_256", /*tp_name*/ + sizeof(SHAobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA512_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + SHA512_256_new__doc__, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + SHA512_new, /*tp_new*/ }; -/* Initialize this module. */ - -#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } +PyDoc_STRVAR(SHA512_224_new__doc__, +"SHA512_224Type(string=b\'\')\n" +"--\n" +"\n" +"Return a new SHA-512-224 hash object; optionally initialized with a string."); + + +static PyTypeObject SHA512_224type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_sha512.sha512_224", /*tp_name*/ + sizeof(SHAobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + SHA512_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + SHA512_224_new__doc__, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + SHA_methods, /* tp_methods */ + SHA_members, /* tp_members */ + SHA_getseters, /* tp_getset */ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + SHA512_new, /*tp_new*/ +}; static struct PyModuleDef _sha512module = { @@ -774,7 +925,7 @@ static struct PyModuleDef _sha512module = { "_sha512", NULL, -1, - SHA_functions, + NULL, NULL, NULL, NULL, @@ -792,15 +943,25 @@ PyInit__sha512(void) Py_TYPE(&SHA512type) = &PyType_Type; if (PyType_Ready(&SHA512type) < 0) return NULL; + Py_TYPE(&SHA512_256type) = &PyType_Type; + if (PyType_Ready(&SHA512_256type) < 0) + return NULL; + Py_TYPE(&SHA512_224type) = &PyType_Type; + if (PyType_Ready(&SHA512_224type) < 0) + return NULL; m = PyModule_Create(&_sha512module); if (m == NULL) return NULL; Py_INCREF((PyObject *)&SHA384type); - PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type); + PyModule_AddObject(m, "sha384", (PyObject *)&SHA384type); Py_INCREF((PyObject *)&SHA512type); - PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type); + PyModule_AddObject(m, "sha512", (PyObject *)&SHA512type); + Py_INCREF((PyObject *)&SHA512type); + PyModule_AddObject(m, "sha512_256", (PyObject *)&SHA512_256type); + Py_INCREF((PyObject *)&SHA512_224type); + PyModule_AddObject(m, "sha512_224", (PyObject *)&SHA512_224type); return m; } -- 2.5.5