LCOV - code coverage report
Current view: | top level - Modules - sha2module.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 37 | 240 | 15.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 6 | 35 | 17.1 %
|  |  | Branches: | 24 | 168 | 14.3 %

               Branch data     Line data    Source code
           1                 :            : /* SHA2 module */
           2                 :            :
           3                 :            : /* This provides an interface to NIST's SHA2 224, 256, 384, & 512 Algorithms */
           4                 :            :
           5                 :            : /* See below for information about the original code this module was
           6                 :            :    based upon. Additional work performed by:
           7                 :            :
           8                 :            :    Andrew Kuchling (amk@amk.ca)
           9                 :            :    Greg Stein (gstein@lyra.org)
          10                 :            :    Trevor Perrin (trevp@trevp.net)
          11                 :            :    Jonathan Protzenko (jonathan@protzenko.fr)
          12                 :            :
          13                 :            :    Copyright (C) 2005-2007   Gregory P. Smith (greg@krypto.org)
          14                 :            :    Licensed to PSF under a Contributor Agreement.
          15                 :            :
          16                 :            : */
          17                 :            :
          18                 :            : /* SHA objects */
          19                 :            : #ifndef Py_BUILD_CORE_BUILTIN
          20                 :            : #  define Py_BUILD_CORE_MODULE 1
          21                 :            : #endif
          22                 :            :
          23                 :            : #include "Python.h"
          24                 :            : #include "pycore_bitutils.h"      // _Py_bswap32()
          25                 :            : #include "pycore_moduleobject.h"  // _PyModule_GetState()
          26                 :            : #include "pycore_typeobject.h"    // _PyType_GetModuleState()
          27                 :            : #include "pycore_strhex.h"        // _Py_strhex()
          28                 :            : #include "structmember.h"         // PyMemberDef
          29                 :            : #include "hashlib.h"
          30                 :            :
          31                 :            : /*[clinic input]
          32                 :            : module _sha2
          33                 :            : class SHA256Type "SHA256object *" "&PyType_Type"
          34                 :            : class SHA512Type "SHA512object *" "&PyType_Type"
          35                 :            : [clinic start generated code]*/
          36                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5315a7b611c9afc]*/
          37                 :            :
          38                 :            :
          39                 :            : /* The SHA block sizes and maximum message digest sizes, in bytes */
          40                 :            :
          41                 :            : #define SHA256_BLOCKSIZE   64
          42                 :            : #define SHA256_DIGESTSIZE  32
          43                 :            : #define SHA512_BLOCKSIZE   128
          44                 :            : #define SHA512_DIGESTSIZE  64
          45                 :            :
          46                 :            : /* Our SHA2 implementations defer to the HACL* verified library. */
          47                 :            :
          48                 :            : #include "_hacl/Hacl_Streaming_SHA2.h"
          49                 :            :
          50                 :            : // TODO: Get rid of int digestsize in favor of Hacl state info?
          51                 :            :
          52                 :            : typedef struct {
          53                 :            :     PyObject_HEAD
          54                 :            :     int digestsize;
          55                 :            :     Hacl_Streaming_SHA2_state_sha2_256 *state;
          56                 :            : } SHA256object;
          57                 :            :
          58                 :            : typedef struct {
          59                 :            :     PyObject_HEAD
          60                 :            :     int digestsize;
          61                 :            :     Hacl_Streaming_SHA2_state_sha2_512 *state;
          62                 :            : } SHA512object;
          63                 :            :
          64                 :            : #include "clinic/sha2module.c.h"
          65                 :            :
          66                 :            : /* We shall use run-time type information in the remainder of this module to
          67                 :            :  * tell apart SHA2-224 and SHA2-256 */
          68                 :            : typedef struct {
          69                 :            :     PyTypeObject* sha224_type;
          70                 :            :     PyTypeObject* sha256_type;
          71                 :            :     PyTypeObject* sha384_type;
          72                 :            :     PyTypeObject* sha512_type;
          73                 :            : } sha2_state;
          74                 :            :
          75                 :            : static inline sha2_state*
          76                 :         11 : sha2_get_state(PyObject *module)
          77                 :            : {
          78                 :         11 :     void *state = _PyModule_GetState(module);
          79                 :            :     assert(state != NULL);
          80                 :         11 :     return (sha2_state *)state;
          81                 :            : }
          82                 :            :
          83                 :          0 : static void SHA256copy(SHA256object *src, SHA256object *dest)
          84                 :            : {
          85                 :          0 :     dest->digestsize = src->digestsize;
          86                 :          0 :     dest->state = Hacl_Streaming_SHA2_copy_256(src->state);
          87                 :          0 : }
          88                 :            :
          89                 :          0 : static void SHA512copy(SHA512object *src, SHA512object *dest)
          90                 :            : {
          91                 :          0 :     dest->digestsize = src->digestsize;
          92                 :          0 :     dest->state = Hacl_Streaming_SHA2_copy_512(src->state);
          93                 :          0 : }
          94                 :            :
          95                 :            : static SHA256object *
          96                 :          0 : newSHA224object(sha2_state *state)
          97                 :            : {
          98                 :          0 :     SHA256object *sha = (SHA256object *)PyObject_GC_New(
          99                 :            :         SHA256object, state->sha224_type);
         100         [ #  # ]:          0 :     if (!sha) {
         101                 :          0 :         return NULL;
         102                 :            :     }
         103                 :          0 :     PyObject_GC_Track(sha);
         104                 :          0 :     return sha;
         105                 :            : }
         106                 :            :
         107                 :            : static SHA256object *
         108                 :          0 : newSHA256object(sha2_state *state)
         109                 :            : {
         110                 :          0 :     SHA256object *sha = (SHA256object *)PyObject_GC_New(
         111                 :            :         SHA256object, state->sha256_type);
         112         [ #  # ]:          0 :     if (!sha) {
         113                 :          0 :         return NULL;
         114                 :            :     }
         115                 :          0 :     PyObject_GC_Track(sha);
         116                 :          0 :     return sha;
         117                 :            : }
         118                 :            :
         119                 :            : static SHA512object *
         120                 :          0 : newSHA384object(sha2_state *state)
         121                 :            : {
         122                 :          0 :     SHA512object *sha = (SHA512object *)PyObject_GC_New(
         123                 :            :         SHA512object, state->sha384_type);
         124         [ #  # ]:          0 :     if (!sha) {
         125                 :          0 :         return NULL;
         126                 :            :     }
         127                 :          0 :     PyObject_GC_Track(sha);
         128                 :          0 :     return sha;
         129                 :            : }
         130                 :            :
         131                 :            : static SHA512object *
         132                 :          0 : newSHA512object(sha2_state *state)
         133                 :            : {
         134                 :          0 :     SHA512object *sha = (SHA512object *)PyObject_GC_New(
         135                 :            :         SHA512object, state->sha512_type);
         136         [ #  # ]:          0 :     if (!sha) {
         137                 :          0 :         return NULL;
         138                 :            :     }
         139                 :          0 :     PyObject_GC_Track(sha);
         140                 :          0 :     return sha;
         141                 :            : }
         142                 :            :
         143                 :            : /* Internal methods for our hash objects. */
         144                 :            :
         145                 :            : static int
         146                 :          0 : SHA2_traverse(PyObject *ptr, visitproc visit, void *arg)
         147                 :            : {
         148   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(ptr));
         149                 :          0 :     return 0;
         150                 :            : }
         151                 :            :
         152                 :            : static void
         153                 :          0 : SHA256_dealloc(SHA256object *ptr)
         154                 :            : {
         155                 :          0 :     Hacl_Streaming_SHA2_free_256(ptr->state);
         156                 :          0 :     PyTypeObject *tp = Py_TYPE(ptr);
         157                 :          0 :     PyObject_GC_UnTrack(ptr);
         158                 :          0 :     PyObject_GC_Del(ptr);
         159                 :          0 :     Py_DECREF(tp);
         160                 :          0 : }
         161                 :            :
         162                 :            : static void
         163                 :          0 : SHA512_dealloc(SHA512object *ptr)
         164                 :            : {
         165                 :          0 :     Hacl_Streaming_SHA2_free_512(ptr->state);
         166                 :          0 :     PyTypeObject *tp = Py_TYPE(ptr);
         167                 :          0 :     PyObject_GC_UnTrack(ptr);
         168                 :          0 :     PyObject_GC_Del(ptr);
         169                 :          0 :     Py_DECREF(tp);
         170                 :          0 : }
         171                 :            :
         172                 :            : /* HACL* takes a uint32_t for the length of its parameter, but Py_ssize_t can be
         173                 :            :  * 64 bits so we loop in <4gig chunks when needed. */
         174                 :            :
         175                 :          0 : static void update_256(Hacl_Streaming_SHA2_state_sha2_256 *state, uint8_t *buf, Py_ssize_t len) {
         176                 :            :   /* Note: we explicitly ignore the error code on the basis that it would take >
         177                 :            :    * 1 billion years to overflow the maximum admissible length for SHA2-256
         178                 :            :    * (namely, 2^61-1 bytes). */
         179                 :            : #if PY_SSIZE_T_MAX > UINT32_MAX
         180         [ #  # ]:          0 :   while (len > UINT32_MAX) {
         181                 :          0 :     Hacl_Streaming_SHA2_update_256(state, buf, UINT32_MAX);
         182                 :          0 :     len -= UINT32_MAX;
         183                 :          0 :     buf += UINT32_MAX;
         184                 :            :   }
         185                 :            : #endif
         186                 :            :   /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */
         187                 :          0 :   Hacl_Streaming_SHA2_update_256(state, buf, (uint32_t) len);
         188                 :          0 : }
         189                 :            :
         190                 :          0 : static void update_512(Hacl_Streaming_SHA2_state_sha2_512 *state, uint8_t *buf, Py_ssize_t len) {
         191                 :            :   /* Note: we explicitly ignore the error code on the basis that it would take >
         192                 :            :    * 1 billion years to overflow the maximum admissible length for this API
         193                 :            :    * (namely, 2^64-1 bytes). */
         194                 :            : #if PY_SSIZE_T_MAX > UINT32_MAX
         195         [ #  # ]:          0 :   while (len > UINT32_MAX) {
         196                 :          0 :     Hacl_Streaming_SHA2_update_512(state, buf, UINT32_MAX);
         197                 :          0 :     len -= UINT32_MAX;
         198                 :          0 :     buf += UINT32_MAX;
         199                 :            :   }
         200                 :            : #endif
         201                 :            :   /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */
         202                 :          0 :   Hacl_Streaming_SHA2_update_512(state, buf, (uint32_t) len);
         203                 :          0 : }
         204                 :            :
         205                 :            :
         206                 :            : /* External methods for our hash objects */
         207                 :            :
         208                 :            : /*[clinic input]
         209                 :            : SHA256Type.copy
         210                 :            :
         211                 :            :     cls:defining_class
         212                 :            :
         213                 :            : Return a copy of the hash object.
         214                 :            : [clinic start generated code]*/
         215                 :            :
         216                 :            : static PyObject *
         217                 :          0 : SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls)
         218                 :            : /*[clinic end generated code: output=fabd515577805cd3 input=3137146fcb88e212]*/
         219                 :            : {
         220                 :            :     SHA256object *newobj;
         221                 :          0 :     sha2_state *state = _PyType_GetModuleState(cls);
         222         [ #  # ]:          0 :     if (Py_IS_TYPE(self, state->sha256_type)) {
         223         [ #  # ]:          0 :         if ((newobj = newSHA256object(state)) == NULL) {
         224                 :          0 :             return NULL;
         225                 :            :         }
         226                 :            :     } else {
         227         [ #  # ]:          0 :         if ((newobj = newSHA224object(state)) == NULL) {
         228                 :          0 :             return NULL;
         229                 :            :         }
         230                 :            :     }
         231                 :            :
         232                 :          0 :     SHA256copy(self, newobj);
         233                 :          0 :     return (PyObject *)newobj;
         234                 :            : }
         235                 :            :
         236                 :            : /*[clinic input]
         237                 :            : SHA512Type.copy
         238                 :            :
         239                 :            :     cls: defining_class
         240                 :            :
         241                 :            : Return a copy of the hash object.
         242                 :            : [clinic start generated code]*/
         243                 :            :
         244                 :            : static PyObject *
         245                 :          0 : SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls)
         246                 :            : /*[clinic end generated code: output=66d2a8ef20de8302 input=f673a18f66527c90]*/
         247                 :            : {
         248                 :            :     SHA512object *newobj;
         249                 :          0 :     sha2_state *state = _PyType_GetModuleState(cls);
         250                 :            :
         251         [ #  # ]:          0 :     if (Py_IS_TYPE((PyObject*)self, state->sha512_type)) {
         252         [ #  # ]:          0 :         if ((newobj = newSHA512object(state)) == NULL) {
         253                 :          0 :             return NULL;
         254                 :            :         }
         255                 :            :     }
         256                 :            :     else {
         257         [ #  # ]:          0 :         if ((newobj = newSHA384object(state)) == NULL) {
         258                 :          0 :             return NULL;
         259                 :            :         }
         260                 :            :     }
         261                 :            :
         262                 :          0 :     SHA512copy(self, newobj);
         263                 :          0 :     return (PyObject *)newobj;
         264                 :            : }
         265                 :            :
         266                 :            : /*[clinic input]
         267                 :            : SHA256Type.digest
         268                 :            :
         269                 :            : Return the digest value as a bytes object.
         270                 :            : [clinic start generated code]*/
         271                 :            :
         272                 :            : static PyObject *
         273                 :          0 : SHA256Type_digest_impl(SHA256object *self)
         274                 :            : /*[clinic end generated code: output=3a2e3997a98ee792 input=f1f4cfea5cbde35c]*/
         275                 :            : {
         276                 :            :     uint8_t digest[SHA256_DIGESTSIZE];
         277                 :            :     assert(self->digestsize <= SHA256_DIGESTSIZE);
         278                 :            :     // HACL* performs copies under the hood so that self->state remains valid
         279                 :            :     // after this call.
         280                 :          0 :     Hacl_Streaming_SHA2_finish_256(self->state, digest);
         281                 :          0 :     return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
         282                 :            : }
         283                 :            :
         284                 :            : /*[clinic input]
         285                 :            : SHA512Type.digest
         286                 :            :
         287                 :            : Return the digest value as a bytes object.
         288                 :            : [clinic start generated code]*/
         289                 :            :
         290                 :            : static PyObject *
         291                 :          0 : SHA512Type_digest_impl(SHA512object *self)
         292                 :            : /*[clinic end generated code: output=dd8c6320070458e0 input=f6470dd359071f4b]*/
         293                 :            : {
         294                 :            :     uint8_t digest[SHA512_DIGESTSIZE];
         295                 :            :     assert(self->digestsize <= SHA512_DIGESTSIZE);
         296                 :            :     // HACL* performs copies under the hood so that self->state remains valid
         297                 :            :     // after this call.
         298                 :          0 :     Hacl_Streaming_SHA2_finish_512(self->state, digest);
         299                 :          0 :     return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
         300                 :            : }
         301                 :            :
         302                 :            : /*[clinic input]
         303                 :            : SHA256Type.hexdigest
         304                 :            :
         305                 :            : Return the digest value as a string of hexadecimal digits.
         306                 :            : [clinic start generated code]*/
         307                 :            :
         308                 :            : static PyObject *
         309                 :          0 : SHA256Type_hexdigest_impl(SHA256object *self)
         310                 :            : /*[clinic end generated code: output=96cb68996a780ab3 input=0cc4c714693010d1]*/
         311                 :            : {
         312                 :            :     uint8_t digest[SHA256_DIGESTSIZE];
         313                 :            :     assert(self->digestsize <= SHA256_DIGESTSIZE);
         314                 :          0 :     Hacl_Streaming_SHA2_finish_256(self->state, digest);
         315                 :          0 :     return _Py_strhex((const char *)digest, self->digestsize);
         316                 :            : }
         317                 :            :
         318                 :            : /*[clinic input]
         319                 :            : SHA512Type.hexdigest
         320                 :            :
         321                 :            : Return the digest value as a string of hexadecimal digits.
         322                 :            : [clinic start generated code]*/
         323                 :            :
         324                 :            : static PyObject *
         325                 :          0 : SHA512Type_hexdigest_impl(SHA512object *self)
         326                 :            : /*[clinic end generated code: output=cbd6f844aba1fe7c input=498b877b25cbe0a2]*/
         327                 :            : {
         328                 :            :     uint8_t digest[SHA512_DIGESTSIZE];
         329                 :            :     assert(self->digestsize <= SHA512_DIGESTSIZE);
         330                 :          0 :     Hacl_Streaming_SHA2_finish_512(self->state, digest);
         331                 :          0 :     return _Py_strhex((const char *)digest, self->digestsize);
         332                 :            : }
         333                 :            :
         334                 :            : /*[clinic input]
         335                 :            : SHA256Type.update
         336                 :            :
         337                 :            :     obj: object
         338                 :            :     /
         339                 :            :
         340                 :            : Update this hash object's state with the provided string.
         341                 :            : [clinic start generated code]*/
         342                 :            :
         343                 :            : static PyObject *
         344                 :          0 : SHA256Type_update(SHA256object *self, PyObject *obj)
         345                 :            : /*[clinic end generated code: output=1b240f965ddbd8c6 input=b2d449d5b30f0f5a]*/
         346                 :            : {
         347                 :            :     Py_buffer buf;
         348                 :            :
         349   [ #  #  #  #  :          0 :     GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
                 #  #  #  # ]
         350                 :            :
         351                 :          0 :     update_256(self->state, buf.buf, buf.len);
         352                 :            :
         353                 :          0 :     PyBuffer_Release(&buf);
         354                 :          0 :     Py_RETURN_NONE;
         355                 :            : }
         356                 :            :
         357                 :            : /*[clinic input]
         358                 :            : SHA512Type.update
         359                 :            :
         360                 :            :     obj: object
         361                 :            :     /
         362                 :            :
         363                 :            : Update this hash object's state with the provided string.
         364                 :            : [clinic start generated code]*/
         365                 :            :
         366                 :            : static PyObject *
         367                 :          0 : SHA512Type_update(SHA512object *self, PyObject *obj)
         368                 :            : /*[clinic end generated code: output=745f51057a985884 input=ded2b46656566283]*/
         369                 :            : {
         370                 :            :     Py_buffer buf;
         371                 :            :
         372   [ #  #  #  #  :          0 :     GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
                 #  #  #  # ]
         373                 :            :
         374                 :          0 :     update_512(self->state, buf.buf, buf.len);
         375                 :            :
         376                 :          0 :     PyBuffer_Release(&buf);
         377                 :          0 :     Py_RETURN_NONE;
         378                 :            : }
         379                 :            :
         380                 :            : static PyMethodDef SHA256_methods[] = {
         381                 :            :     SHA256TYPE_COPY_METHODDEF
         382                 :            :     SHA256TYPE_DIGEST_METHODDEF
         383                 :            :     SHA256TYPE_HEXDIGEST_METHODDEF
         384                 :            :     SHA256TYPE_UPDATE_METHODDEF
         385                 :            :     {NULL,        NULL}         /* sentinel */
         386                 :            : };
         387                 :            :
         388                 :            : static PyMethodDef SHA512_methods[] = {
         389                 :            :     SHA512TYPE_COPY_METHODDEF
         390                 :            :     SHA512TYPE_DIGEST_METHODDEF
         391                 :            :     SHA512TYPE_HEXDIGEST_METHODDEF
         392                 :            :     SHA512TYPE_UPDATE_METHODDEF
         393                 :            :     {NULL,        NULL}         /* sentinel */
         394                 :            : };
         395                 :            :
         396                 :            : static PyObject *
         397                 :          0 : SHA256_get_block_size(PyObject *self, void *closure)
         398                 :            : {
         399                 :          0 :     return PyLong_FromLong(SHA256_BLOCKSIZE);
         400                 :            : }
         401                 :            :
         402                 :            : static PyObject *
         403                 :          0 : SHA512_get_block_size(PyObject *self, void *closure)
         404                 :            : {
         405                 :          0 :     return PyLong_FromLong(SHA512_BLOCKSIZE);
         406                 :            : }
         407                 :            :
         408                 :            : static PyObject *
         409                 :          0 : SHA256_get_digest_size(SHA256object *self, void *closure)
         410                 :            : {
         411                 :          0 :     return PyLong_FromLong(self->digestsize);
         412                 :            : }
         413                 :            :
         414                 :            : static PyObject *
         415                 :          0 : SHA512_get_digest_size(SHA512object *self, void *closure)
         416                 :            : {
         417                 :          0 :     return PyLong_FromLong(self->digestsize);
         418                 :            : }
         419                 :            :
         420                 :            : static PyObject *
         421                 :          0 : SHA256_get_name(SHA256object *self, void *closure)
         422                 :            : {
         423         [ #  # ]:          0 :     if (self->digestsize == 28) {
         424                 :          0 :         return PyUnicode_FromStringAndSize("sha224", 6);
         425                 :            :     }
         426                 :          0 :     return PyUnicode_FromStringAndSize("sha256", 6);
         427                 :            : }
         428                 :            :
         429                 :            : static PyObject *
         430                 :          0 : SHA512_get_name(SHA512object *self, void *closure)
         431                 :            : {
         432         [ #  # ]:          0 :     if (self->digestsize == 64) {
         433                 :          0 :         return PyUnicode_FromStringAndSize("sha512", 6);
         434                 :            :     }
         435                 :          0 :     return PyUnicode_FromStringAndSize("sha384", 6);
         436                 :            : }
         437                 :            :
         438                 :            : static PyGetSetDef SHA256_getseters[] = {
         439                 :            :     {"block_size",
         440                 :            :      (getter)SHA256_get_block_size, NULL,
         441                 :            :      NULL,
         442                 :            :      NULL},
         443                 :            :     {"name",
         444                 :            :      (getter)SHA256_get_name, NULL,
         445                 :            :      NULL,
         446                 :            :      NULL},
         447                 :            :     {"digest_size",
         448                 :            :      (getter)SHA256_get_digest_size, NULL,
         449                 :            :      NULL,
         450                 :            :      NULL},
         451                 :            :     {NULL}  /* Sentinel */
         452                 :            : };
         453                 :            :
         454                 :            : static PyGetSetDef SHA512_getseters[] = {
         455                 :            :     {"block_size",
         456                 :            :      (getter)SHA512_get_block_size, NULL,
         457                 :            :      NULL,
         458                 :            :      NULL},
         459                 :            :     {"name",
         460                 :            :      (getter)SHA512_get_name, NULL,
         461                 :            :      NULL,
         462                 :            :      NULL},
         463                 :            :     {"digest_size",
         464                 :            :      (getter)SHA512_get_digest_size, NULL,
         465                 :            :      NULL,
         466                 :            :      NULL},
         467                 :            :     {NULL}  /* Sentinel */
         468                 :            : };
         469                 :            :
         470                 :            : static PyType_Slot sha256_types_slots[] = {
         471                 :            :     {Py_tp_dealloc, SHA256_dealloc},
         472                 :            :     {Py_tp_methods, SHA256_methods},
         473                 :            :     {Py_tp_getset, SHA256_getseters},
         474                 :            :     {Py_tp_traverse, SHA2_traverse},
         475                 :            :     {0,0}
         476                 :            : };
         477                 :            :
         478                 :            : static PyType_Slot sha512_type_slots[] = {
         479                 :            :     {Py_tp_dealloc, SHA512_dealloc},
         480                 :            :     {Py_tp_methods, SHA512_methods},
         481                 :            :     {Py_tp_getset, SHA512_getseters},
         482                 :            :     {Py_tp_traverse, SHA2_traverse},
         483                 :            :     {0,0}
         484                 :            : };
         485                 :            :
         486                 :            : // Using _PyType_GetModuleState() on these types is safe since they
         487                 :            : // cannot be subclassed: they don't have the Py_TPFLAGS_BASETYPE flag.
         488                 :            : static PyType_Spec sha224_type_spec = {
         489                 :            :     .name = "_sha2.SHA224Type",
         490                 :            :     .basicsize = sizeof(SHA256object),
         491                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
         492                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
         493                 :            :     .slots = sha256_types_slots
         494                 :            : };
         495                 :            :
         496                 :            : static PyType_Spec sha256_type_spec = {
         497                 :            :     .name = "_sha2.SHA256Type",
         498                 :            :     .basicsize = sizeof(SHA256object),
         499                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
         500                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
         501                 :            :     .slots = sha256_types_slots
         502                 :            : };
         503                 :            :
         504                 :            : static PyType_Spec sha384_type_spec = {
         505                 :            :     .name = "_sha2.SHA384Type",
         506                 :            :     .basicsize =  sizeof(SHA512object),
         507                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
         508                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
         509                 :            :     .slots = sha512_type_slots
         510                 :            : };
         511                 :            :
         512                 :            : static PyType_Spec sha512_type_spec = {
         513                 :            :     .name = "_sha2.SHA512Type",
         514                 :            :     .basicsize =  sizeof(SHA512object),
         515                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
         516                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
         517                 :            :     .slots = sha512_type_slots
         518                 :            : };
         519                 :            :
         520                 :            : /* The module-level constructors. */
         521                 :            :
         522                 :            : /*[clinic input]
         523                 :            : _sha2.sha256
         524                 :            :
         525                 :            :     string: object(c_default="NULL") = b''
         526                 :            :     *
         527                 :            :     usedforsecurity: bool = True
         528                 :            :
         529                 :            : Return a new SHA-256 hash object; optionally initialized with a string.
         530                 :            : [clinic start generated code]*/
         531                 :            :
         532                 :            : static PyObject *
         533                 :          0 : _sha2_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity)
         534                 :            : /*[clinic end generated code: output=243c9dd289931f87 input=6249da1de607280a]*/
         535                 :            : {
         536                 :            :     Py_buffer buf;
         537                 :            :
         538         [ #  # ]:          0 :     if (string) {
         539   [ #  #  #  #  :          0 :         GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
                 #  #  #  # ]
         540                 :            :     }
         541                 :            :
         542                 :          0 :     sha2_state *state = sha2_get_state(module);
         543                 :            :
         544                 :            :     SHA256object *new;
         545         [ #  # ]:          0 :     if ((new = newSHA256object(state)) == NULL) {
         546         [ #  # ]:          0 :         if (string) {
         547                 :          0 :             PyBuffer_Release(&buf);
         548                 :            :         }
         549                 :          0 :         return NULL;
         550                 :            :     }
         551                 :            :
         552                 :          0 :     new->state = Hacl_Streaming_SHA2_create_in_256();
         553                 :          0 :     new->digestsize = 32;
         554                 :            :
         555         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         556                 :          0 :         Py_DECREF(new);
         557         [ #  # ]:          0 :         if (string) {
         558                 :          0 :             PyBuffer_Release(&buf);
         559                 :            :         }
         560                 :          0 :         return NULL;
         561                 :            :     }
         562         [ #  # ]:          0 :     if (string) {
         563                 :          0 :         update_256(new->state, buf.buf, buf.len);
         564                 :          0 :         PyBuffer_Release(&buf);
         565                 :            :     }
         566                 :            :
         567                 :          0 :     return (PyObject *)new;
         568                 :            : }
         569                 :            :
         570                 :            : /*[clinic input]
         571                 :            : _sha2.sha224
         572                 :            :
         573                 :            :     string: object(c_default="NULL") = b''
         574                 :            :     *
         575                 :            :     usedforsecurity: bool = True
         576                 :            :
         577                 :            : Return a new SHA-224 hash object; optionally initialized with a string.
         578                 :            : [clinic start generated code]*/
         579                 :            :
         580                 :            : static PyObject *
         581                 :          0 : _sha2_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity)
         582                 :            : /*[clinic end generated code: output=68191f232e4a3843 input=c42bcba47fd7d2b7]*/
         583                 :            : {
         584                 :            :     Py_buffer buf;
         585         [ #  # ]:          0 :     if (string) {
         586   [ #  #  #  #  :          0 :         GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
                 #  #  #  # ]
         587                 :            :     }
         588                 :            :
         589                 :          0 :     sha2_state *state = sha2_get_state(module);
         590                 :            :     SHA256object *new;
         591         [ #  # ]:          0 :     if ((new = newSHA224object(state)) == NULL) {
         592         [ #  # ]:          0 :         if (string) {
         593                 :          0 :             PyBuffer_Release(&buf);
         594                 :            :         }
         595                 :          0 :         return NULL;
         596                 :            :     }
         597                 :            :
         598                 :          0 :     new->state = Hacl_Streaming_SHA2_create_in_224();
         599                 :          0 :     new->digestsize = 28;
         600                 :            :
         601         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         602                 :          0 :         Py_DECREF(new);
         603         [ #  # ]:          0 :         if (string) {
         604                 :          0 :             PyBuffer_Release(&buf);
         605                 :            :         }
         606                 :          0 :         return NULL;
         607                 :            :     }
         608         [ #  # ]:          0 :     if (string) {
         609                 :          0 :         update_256(new->state, buf.buf, buf.len);
         610                 :          0 :         PyBuffer_Release(&buf);
         611                 :            :     }
         612                 :            :
         613                 :          0 :     return (PyObject *)new;
         614                 :            : }
         615                 :            :
         616                 :            : /*[clinic input]
         617                 :            : _sha2.sha512
         618                 :            :
         619                 :            :     string: object(c_default="NULL") = b''
         620                 :            :     *
         621                 :            :     usedforsecurity: bool = True
         622                 :            :
         623                 :            : Return a new SHA-512 hash object; optionally initialized with a string.
         624                 :            : [clinic start generated code]*/
         625                 :            :
         626                 :            : static PyObject *
         627                 :          0 : _sha2_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity)
         628                 :            : /*[clinic end generated code: output=d55c8996eca214d7 input=0576ae2a6ebfad25]*/
         629                 :            : {
         630                 :            :     SHA512object *new;
         631                 :            :     Py_buffer buf;
         632                 :            :
         633                 :          0 :     sha2_state *state = sha2_get_state(module);
         634                 :            :
         635         [ #  # ]:          0 :     if (string)
         636   [ #  #  #  #  :          0 :         GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
                 #  #  #  # ]
         637                 :            :
         638         [ #  # ]:          0 :     if ((new = newSHA512object(state)) == NULL) {
         639         [ #  # ]:          0 :         if (string)
         640                 :          0 :             PyBuffer_Release(&buf);
         641                 :          0 :         return NULL;
         642                 :            :     }
         643                 :            :
         644                 :          0 :     new->state = Hacl_Streaming_SHA2_create_in_512();
         645                 :          0 :     new->digestsize = 64;
         646                 :            :
         647         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         648                 :          0 :         Py_DECREF(new);
         649         [ #  # ]:          0 :         if (string)
         650                 :          0 :             PyBuffer_Release(&buf);
         651                 :          0 :         return NULL;
         652                 :            :     }
         653         [ #  # ]:          0 :     if (string) {
         654                 :          0 :         update_512(new->state, buf.buf, buf.len);
         655                 :          0 :         PyBuffer_Release(&buf);
         656                 :            :     }
         657                 :            :
         658                 :          0 :     return (PyObject *)new;
         659                 :            : }
         660                 :            :
         661                 :            : /*[clinic input]
         662                 :            : _sha2.sha384
         663                 :            :
         664                 :            :     string: object(c_default="NULL") = b''
         665                 :            :     *
         666                 :            :     usedforsecurity: bool = True
         667                 :            :
         668                 :            : Return a new SHA-384 hash object; optionally initialized with a string.
         669                 :            : [clinic start generated code]*/
         670                 :            :
         671                 :            : static PyObject *
         672                 :          0 : _sha2_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity)
         673                 :            : /*[clinic end generated code: output=b29a0d81d51d1368 input=4e9199d8de0d2f9b]*/
         674                 :            : {
         675                 :            :     SHA512object *new;
         676                 :            :     Py_buffer buf;
         677                 :            :
         678                 :          0 :     sha2_state *state = sha2_get_state(module);
         679                 :            :
         680         [ #  # ]:          0 :     if (string)
         681   [ #  #  #  #  :          0 :         GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
                 #  #  #  # ]
         682                 :            :
         683         [ #  # ]:          0 :     if ((new = newSHA384object(state)) == NULL) {
         684         [ #  # ]:          0 :         if (string)
         685                 :          0 :             PyBuffer_Release(&buf);
         686                 :          0 :         return NULL;
         687                 :            :     }
         688                 :            :
         689                 :          0 :     new->state = Hacl_Streaming_SHA2_create_in_384();
         690                 :          0 :     new->digestsize = 48;
         691                 :            :
         692         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         693                 :          0 :         Py_DECREF(new);
         694         [ #  # ]:          0 :         if (string)
         695                 :          0 :             PyBuffer_Release(&buf);
         696                 :          0 :         return NULL;
         697                 :            :     }
         698         [ #  # ]:          0 :     if (string) {
         699                 :          0 :         update_512(new->state, buf.buf, buf.len);
         700                 :          0 :         PyBuffer_Release(&buf);
         701                 :            :     }
         702                 :            :
         703                 :          0 :     return (PyObject *)new;
         704                 :            : }
         705                 :            :
         706                 :            : /* List of functions exported by this module */
         707                 :            :
         708                 :            : static struct PyMethodDef SHA2_functions[] = {
         709                 :            :     _SHA2_SHA256_METHODDEF
         710                 :            :     _SHA2_SHA224_METHODDEF
         711                 :            :     _SHA2_SHA512_METHODDEF
         712                 :            :     _SHA2_SHA384_METHODDEF
         713                 :            :     {NULL,      NULL}            /* Sentinel */
         714                 :            : };
         715                 :            :
         716                 :            : static int
         717                 :          8 : _sha2_traverse(PyObject *module, visitproc visit, void *arg)
         718                 :            : {
         719                 :          8 :     sha2_state *state = sha2_get_state(module);
         720   [ +  -  -  + ]:          8 :     Py_VISIT(state->sha224_type);
         721   [ +  -  -  + ]:          8 :     Py_VISIT(state->sha256_type);
         722   [ +  -  -  + ]:          8 :     Py_VISIT(state->sha384_type);
         723   [ +  -  -  + ]:          8 :     Py_VISIT(state->sha512_type);
         724                 :          8 :     return 0;
         725                 :            : }
         726                 :            :
         727                 :            : static int
         728                 :          2 : _sha2_clear(PyObject *module)
         729                 :            : {
         730                 :          2 :     sha2_state *state = sha2_get_state(module);
         731         [ +  + ]:          2 :     Py_CLEAR(state->sha224_type);
         732         [ +  + ]:          2 :     Py_CLEAR(state->sha256_type);
         733         [ +  + ]:          2 :     Py_CLEAR(state->sha384_type);
         734         [ +  + ]:          2 :     Py_CLEAR(state->sha512_type);
         735                 :          2 :     return 0;
         736                 :            : }
         737                 :            :
         738                 :            : static void
         739                 :          1 : _sha2_free(void *module)
         740                 :            : {
         741                 :          1 :     _sha2_clear((PyObject *)module);
         742                 :          1 : }
         743                 :            :
         744                 :            : /* Initialize this module. */
         745                 :          1 : static int sha2_exec(PyObject *module)
         746                 :            : {
         747                 :          1 :     sha2_state *state = sha2_get_state(module);
         748                 :            :
         749                 :          1 :     state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec(
         750                 :            :         module, &sha224_type_spec, NULL);
         751         [ -  + ]:          1 :     if (state->sha224_type == NULL) {
         752                 :          0 :         return -1;
         753                 :            :     }
         754                 :          1 :     state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec(
         755                 :            :         module, &sha256_type_spec, NULL);
         756         [ -  + ]:          1 :     if (state->sha256_type == NULL) {
         757                 :          0 :         return -1;
         758                 :            :     }
         759                 :          1 :     state->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec(
         760                 :            :         module, &sha384_type_spec, NULL);
         761         [ -  + ]:          1 :     if (state->sha384_type == NULL) {
         762                 :          0 :         return -1;
         763                 :            :     }
         764                 :          1 :     state->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec(
         765                 :            :         module, &sha512_type_spec, NULL);
         766         [ -  + ]:          1 :     if (state->sha512_type == NULL) {
         767                 :          0 :         return -1;
         768                 :            :     }
         769                 :            :
         770         [ -  + ]:          1 :     if (PyModule_AddType(module, state->sha224_type) < 0) {
         771                 :          0 :         return -1;
         772                 :            :     }
         773         [ -  + ]:          1 :     if (PyModule_AddType(module, state->sha256_type) < 0) {
         774                 :          0 :         return -1;
         775                 :            :     }
         776         [ -  + ]:          1 :     if (PyModule_AddType(module, state->sha384_type) < 0) {
         777                 :          0 :         return -1;
         778                 :            :     }
         779         [ -  + ]:          1 :     if (PyModule_AddType(module, state->sha512_type) < 0) {
         780                 :          0 :         return -1;
         781                 :            :     }
         782                 :            :
         783                 :          1 :     return 0;
         784                 :            : }
         785                 :            :
         786                 :            : static PyModuleDef_Slot _sha2_slots[] = {
         787                 :            :     {Py_mod_exec, sha2_exec},
         788                 :            :     {0, NULL}
         789                 :            : };
         790                 :            :
         791                 :            : static struct PyModuleDef _sha2module = {
         792                 :            :     PyModuleDef_HEAD_INIT,
         793                 :            :     .m_name = "_sha2",
         794                 :            :     .m_size = sizeof(sha2_state),
         795                 :            :     .m_methods = SHA2_functions,
         796                 :            :     .m_slots = _sha2_slots,
         797                 :            :     .m_traverse = _sha2_traverse,
         798                 :            :     .m_clear = _sha2_clear,
         799                 :            :     .m_free = _sha2_free
         800                 :            : };
         801                 :            :
         802                 :            : PyMODINIT_FUNC
         803                 :          1 : PyInit__sha2(void)
         804                 :            : {
         805                 :          1 :     return PyModuleDef_Init(&_sha2module);
         806                 :            : }

Generated by: LCOV version 1.14