LCOV - code coverage report
Current view: | top level - Modules/_blake2 - blake2b_impl.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 0 | 124 | 0.0 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 0 | 10 | 0.0 %
|  |  | Branches: | 0 | 98 | 0.0 %

               Branch data     Line data    Source code
           1                 :            : /*
           2                 :            :  * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com>
           3                 :            :  * Modified for CPython by Christian Heimes <christian@python.org>
           4                 :            :  *
           5                 :            :  * To the extent possible under law, the author have dedicated all
           6                 :            :  * copyright and related and neighboring rights to this software to
           7                 :            :  * the public domain worldwide. This software is distributed without
           8                 :            :  * any warranty. http://creativecommons.org/publicdomain/zero/1.0/
           9                 :            :  */
          10                 :            :
          11                 :            : /* WARNING: autogenerated file!
          12                 :            :  *
          13                 :            :  * The blake2s_impl.c is autogenerated from blake2b_impl.c.
          14                 :            :  */
          15                 :            :
          16                 :            : #ifndef Py_BUILD_CORE_BUILTIN
          17                 :            : #  define Py_BUILD_CORE_MODULE 1
          18                 :            : #endif
          19                 :            :
          20                 :            : #include "Python.h"
          21                 :            : #include "pycore_strhex.h"       // _Py_strhex()
          22                 :            :
          23                 :            : #include "../hashlib.h"
          24                 :            : #include "blake2module.h"
          25                 :            :
          26                 :            : #ifndef HAVE_LIBB2
          27                 :            : /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+
          28                 :            :  * https://bugs.python.org/issue31834 */
          29                 :            : #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__)
          30                 :            : #include "impl/blake2b.c"
          31                 :            : #else
          32                 :            : #include "impl/blake2b-ref.c"
          33                 :            : #endif
          34                 :            : #endif // !HAVE_LIBB2
          35                 :            :
          36                 :            : #define HAVE_BLAKE2B 1
          37                 :            :
          38                 :            : extern PyType_Spec blake2b_type_spec;
          39                 :            :
          40                 :            :
          41                 :            : typedef struct {
          42                 :            :     PyObject_HEAD
          43                 :            :     blake2b_param    param;
          44                 :            :     blake2b_state    state;
          45                 :            :     PyThread_type_lock lock;
          46                 :            : } BLAKE2bObject;
          47                 :            :
          48                 :            : #include "clinic/blake2b_impl.c.h"
          49                 :            :
          50                 :            : /*[clinic input]
          51                 :            : module _blake2
          52                 :            : class _blake2.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
          53                 :            : [clinic start generated code]*/
          54                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d47b0527b39c673f]*/
          55                 :            :
          56                 :            :
          57                 :            : static BLAKE2bObject *
          58                 :          0 : new_BLAKE2bObject(PyTypeObject *type)
          59                 :            : {
          60                 :            :     BLAKE2bObject *self;
          61                 :          0 :     self = (BLAKE2bObject *)type->tp_alloc(type, 0);
          62         [ #  # ]:          0 :     if (self != NULL) {
          63                 :          0 :         self->lock = NULL;
          64                 :            :     }
          65                 :          0 :     return self;
          66                 :            : }
          67                 :            :
          68                 :            : /*[clinic input]
          69                 :            : @classmethod
          70                 :            : _blake2.blake2b.__new__ as py_blake2b_new
          71                 :            :     data: object(c_default="NULL") = b''
          72                 :            :     /
          73                 :            :     *
          74                 :            :     digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2.blake2b.MAX_DIGEST_SIZE
          75                 :            :     key: Py_buffer(c_default="NULL", py_default="b''") = None
          76                 :            :     salt: Py_buffer(c_default="NULL", py_default="b''") = None
          77                 :            :     person: Py_buffer(c_default="NULL", py_default="b''") = None
          78                 :            :     fanout: int = 1
          79                 :            :     depth: int = 1
          80                 :            :     leaf_size: unsigned_long = 0
          81                 :            :     node_offset: unsigned_long_long = 0
          82                 :            :     node_depth: int = 0
          83                 :            :     inner_size: int = 0
          84                 :            :     last_node: bool = False
          85                 :            :     usedforsecurity: bool = True
          86                 :            :
          87                 :            : Return a new BLAKE2b hash object.
          88                 :            : [clinic start generated code]*/
          89                 :            :
          90                 :            : static PyObject *
          91                 :          0 : py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
          92                 :            :                     Py_buffer *key, Py_buffer *salt, Py_buffer *person,
          93                 :            :                     int fanout, int depth, unsigned long leaf_size,
          94                 :            :                     unsigned long long node_offset, int node_depth,
          95                 :            :                     int inner_size, int last_node, int usedforsecurity)
          96                 :            : /*[clinic end generated code: output=32bfd8f043c6896f input=b947312abff46977]*/
          97                 :            : {
          98                 :          0 :     BLAKE2bObject *self = NULL;
          99                 :            :     Py_buffer buf;
         100                 :            :
         101                 :          0 :     self = new_BLAKE2bObject(type);
         102         [ #  # ]:          0 :     if (self == NULL) {
         103                 :          0 :         goto error;
         104                 :            :     }
         105                 :            :
         106                 :            :     /* Zero parameter block. */
         107                 :          0 :     memset(&self->param, 0, sizeof(self->param));
         108                 :            :
         109                 :            :     /* Set digest size. */
         110   [ #  #  #  # ]:          0 :     if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) {
         111                 :          0 :         PyErr_Format(PyExc_ValueError,
         112                 :            :                 "digest_size must be between 1 and %d bytes",
         113                 :            :                 BLAKE2B_OUTBYTES);
         114                 :          0 :         goto error;
         115                 :            :     }
         116                 :          0 :     self->param.digest_length = digest_size;
         117                 :            :
         118                 :            :     /* Set salt parameter. */
         119   [ #  #  #  # ]:          0 :     if ((salt->obj != NULL) && salt->len) {
         120         [ #  # ]:          0 :         if (salt->len > BLAKE2B_SALTBYTES) {
         121                 :          0 :             PyErr_Format(PyExc_ValueError,
         122                 :            :                 "maximum salt length is %d bytes",
         123                 :            :                 BLAKE2B_SALTBYTES);
         124                 :          0 :             goto error;
         125                 :            :         }
         126                 :          0 :         memcpy(self->param.salt, salt->buf, salt->len);
         127                 :            :     }
         128                 :            :
         129                 :            :     /* Set personalization parameter. */
         130   [ #  #  #  # ]:          0 :     if ((person->obj != NULL) && person->len) {
         131         [ #  # ]:          0 :         if (person->len > BLAKE2B_PERSONALBYTES) {
         132                 :          0 :             PyErr_Format(PyExc_ValueError,
         133                 :            :                 "maximum person length is %d bytes",
         134                 :            :                 BLAKE2B_PERSONALBYTES);
         135                 :          0 :             goto error;
         136                 :            :         }
         137                 :          0 :         memcpy(self->param.personal, person->buf, person->len);
         138                 :            :     }
         139                 :            :
         140                 :            :     /* Set tree parameters. */
         141   [ #  #  #  # ]:          0 :     if (fanout < 0 || fanout > 255) {
         142                 :          0 :         PyErr_SetString(PyExc_ValueError,
         143                 :            :                 "fanout must be between 0 and 255");
         144                 :          0 :         goto error;
         145                 :            :     }
         146                 :          0 :     self->param.fanout = (uint8_t)fanout;
         147                 :            :
         148   [ #  #  #  # ]:          0 :     if (depth <= 0 || depth > 255) {
         149                 :          0 :         PyErr_SetString(PyExc_ValueError,
         150                 :            :                 "depth must be between 1 and 255");
         151                 :          0 :         goto error;
         152                 :            :     }
         153                 :          0 :     self->param.depth = (uint8_t)depth;
         154                 :            :
         155         [ #  # ]:          0 :     if (leaf_size > 0xFFFFFFFFU) {
         156                 :          0 :         PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
         157                 :          0 :         goto error;
         158                 :            :     }
         159                 :            :     // NB: Simple assignment here would be incorrect on big endian platforms.
         160                 :          0 :     store32(&(self->param.leaf_length), leaf_size);
         161                 :            :
         162                 :            : #ifdef HAVE_BLAKE2S
         163                 :            :     if (node_offset > 0xFFFFFFFFFFFFULL) {
         164                 :            :         /* maximum 2**48 - 1 */
         165                 :            :          PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
         166                 :            :          goto error;
         167                 :            :      }
         168                 :            :     store48(&(self->param.node_offset), node_offset);
         169                 :            : #else
         170                 :            :     // NB: Simple assignment here would be incorrect on big endian platforms.
         171                 :          0 :     store64(&(self->param.node_offset), node_offset);
         172                 :            : #endif
         173                 :            :
         174   [ #  #  #  # ]:          0 :     if (node_depth < 0 || node_depth > 255) {
         175                 :          0 :         PyErr_SetString(PyExc_ValueError,
         176                 :            :                 "node_depth must be between 0 and 255");
         177                 :          0 :         goto error;
         178                 :            :     }
         179                 :          0 :     self->param.node_depth = node_depth;
         180                 :            :
         181   [ #  #  #  # ]:          0 :     if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) {
         182                 :          0 :         PyErr_Format(PyExc_ValueError,
         183                 :            :                 "inner_size must be between 0 and is %d",
         184                 :            :                 BLAKE2B_OUTBYTES);
         185                 :          0 :         goto error;
         186                 :            :     }
         187                 :          0 :     self->param.inner_length = inner_size;
         188                 :            :
         189                 :            :     /* Set key length. */
         190   [ #  #  #  # ]:          0 :     if ((key->obj != NULL) && key->len) {
         191         [ #  # ]:          0 :         if (key->len > BLAKE2B_KEYBYTES) {
         192                 :          0 :             PyErr_Format(PyExc_ValueError,
         193                 :            :                 "maximum key length is %d bytes",
         194                 :            :                 BLAKE2B_KEYBYTES);
         195                 :          0 :             goto error;
         196                 :            :         }
         197                 :          0 :         self->param.key_length = (uint8_t)key->len;
         198                 :            :     }
         199                 :            :
         200                 :            :     /* Initialize hash state. */
         201         [ #  # ]:          0 :     if (blake2b_init_param(&self->state, &self->param) < 0) {
         202                 :          0 :         PyErr_SetString(PyExc_RuntimeError,
         203                 :            :                 "error initializing hash state");
         204                 :          0 :         goto error;
         205                 :            :     }
         206                 :            :
         207                 :            :     /* Set last node flag (must come after initialization). */
         208                 :          0 :     self->state.last_node = last_node;
         209                 :            :
         210                 :            :     /* Process key block if any. */
         211         [ #  # ]:          0 :     if (self->param.key_length) {
         212                 :            :         uint8_t block[BLAKE2B_BLOCKBYTES];
         213                 :          0 :         memset(block, 0, sizeof(block));
         214                 :          0 :         memcpy(block, key->buf, key->len);
         215                 :          0 :         blake2b_update(&self->state, block, sizeof(block));
         216                 :          0 :         secure_zero_memory(block, sizeof(block));
         217                 :            :     }
         218                 :            :
         219                 :            :     /* Process initial data if any. */
         220         [ #  # ]:          0 :     if (data != NULL) {
         221   [ #  #  #  #  :          0 :         GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
                 #  #  #  # ]
         222                 :            :
         223         [ #  # ]:          0 :         if (buf.len >= HASHLIB_GIL_MINSIZE) {
         224                 :          0 :             Py_BEGIN_ALLOW_THREADS
         225                 :          0 :             blake2b_update(&self->state, buf.buf, buf.len);
         226                 :          0 :             Py_END_ALLOW_THREADS
         227                 :            :         } else {
         228                 :          0 :             blake2b_update(&self->state, buf.buf, buf.len);
         229                 :            :         }
         230                 :          0 :         PyBuffer_Release(&buf);
         231                 :            :     }
         232                 :            :
         233                 :          0 :     return (PyObject *)self;
         234                 :            :
         235                 :          0 :   error:
         236         [ #  # ]:          0 :     if (self != NULL) {
         237                 :          0 :         Py_DECREF(self);
         238                 :            :     }
         239                 :          0 :     return NULL;
         240                 :            : }
         241                 :            :
         242                 :            : /*[clinic input]
         243                 :            : _blake2.blake2b.copy
         244                 :            :
         245                 :            : Return a copy of the hash object.
         246                 :            : [clinic start generated code]*/
         247                 :            :
         248                 :            : static PyObject *
         249                 :          0 : _blake2_blake2b_copy_impl(BLAKE2bObject *self)
         250                 :            : /*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/
         251                 :            : {
         252                 :            :     BLAKE2bObject *cpy;
         253                 :            :
         254         [ #  # ]:          0 :     if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL)
         255                 :          0 :         return NULL;
         256                 :            :
         257   [ #  #  #  # ]:          0 :     ENTER_HASHLIB(self);
         258                 :          0 :     cpy->param = self->param;
         259                 :          0 :     cpy->state = self->state;
         260         [ #  # ]:          0 :     LEAVE_HASHLIB(self);
         261                 :          0 :     return (PyObject *)cpy;
         262                 :            : }
         263                 :            :
         264                 :            : /*[clinic input]
         265                 :            : _blake2.blake2b.update
         266                 :            :
         267                 :            :     data: object
         268                 :            :     /
         269                 :            :
         270                 :            : Update this hash object's state with the provided bytes-like object.
         271                 :            : [clinic start generated code]*/
         272                 :            :
         273                 :            : static PyObject *
         274                 :          0 : _blake2_blake2b_update(BLAKE2bObject *self, PyObject *data)
         275                 :            : /*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/
         276                 :            : {
         277                 :            :     Py_buffer buf;
         278                 :            :
         279   [ #  #  #  #  :          0 :     GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
                 #  #  #  # ]
         280                 :            :
         281   [ #  #  #  # ]:          0 :     if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
         282                 :          0 :         self->lock = PyThread_allocate_lock();
         283                 :            :
         284         [ #  # ]:          0 :     if (self->lock != NULL) {
         285                 :          0 :        Py_BEGIN_ALLOW_THREADS
         286                 :          0 :        PyThread_acquire_lock(self->lock, 1);
         287                 :          0 :        blake2b_update(&self->state, buf.buf, buf.len);
         288                 :          0 :        PyThread_release_lock(self->lock);
         289                 :          0 :        Py_END_ALLOW_THREADS
         290                 :            :     } else {
         291                 :          0 :         blake2b_update(&self->state, buf.buf, buf.len);
         292                 :            :     }
         293                 :          0 :     PyBuffer_Release(&buf);
         294                 :            :
         295                 :          0 :     Py_RETURN_NONE;
         296                 :            : }
         297                 :            :
         298                 :            : /*[clinic input]
         299                 :            : _blake2.blake2b.digest
         300                 :            :
         301                 :            : Return the digest value as a bytes object.
         302                 :            : [clinic start generated code]*/
         303                 :            :
         304                 :            : static PyObject *
         305                 :          0 : _blake2_blake2b_digest_impl(BLAKE2bObject *self)
         306                 :            : /*[clinic end generated code: output=a5864660f4bfc61a input=7d21659e9c5fff02]*/
         307                 :            : {
         308                 :            :     uint8_t digest[BLAKE2B_OUTBYTES];
         309                 :            :     blake2b_state state_cpy;
         310                 :            :
         311   [ #  #  #  # ]:          0 :     ENTER_HASHLIB(self);
         312                 :          0 :     state_cpy = self->state;
         313                 :          0 :     blake2b_final(&state_cpy, digest, self->param.digest_length);
         314         [ #  # ]:          0 :     LEAVE_HASHLIB(self);
         315                 :          0 :     return PyBytes_FromStringAndSize((const char *)digest,
         316                 :          0 :             self->param.digest_length);
         317                 :            : }
         318                 :            :
         319                 :            : /*[clinic input]
         320                 :            : _blake2.blake2b.hexdigest
         321                 :            :
         322                 :            : Return the digest value as a string of hexadecimal digits.
         323                 :            : [clinic start generated code]*/
         324                 :            :
         325                 :            : static PyObject *
         326                 :          0 : _blake2_blake2b_hexdigest_impl(BLAKE2bObject *self)
         327                 :            : /*[clinic end generated code: output=b5598a87d8794a60 input=76930f6946351f56]*/
         328                 :            : {
         329                 :            :     uint8_t digest[BLAKE2B_OUTBYTES];
         330                 :            :     blake2b_state state_cpy;
         331                 :            :
         332   [ #  #  #  # ]:          0 :     ENTER_HASHLIB(self);
         333                 :          0 :     state_cpy = self->state;
         334                 :          0 :     blake2b_final(&state_cpy, digest, self->param.digest_length);
         335         [ #  # ]:          0 :     LEAVE_HASHLIB(self);
         336                 :          0 :     return _Py_strhex((const char *)digest, self->param.digest_length);
         337                 :            : }
         338                 :            :
         339                 :            :
         340                 :            : static PyMethodDef py_blake2b_methods[] = {
         341                 :            :     _BLAKE2_BLAKE2B_COPY_METHODDEF
         342                 :            :     _BLAKE2_BLAKE2B_DIGEST_METHODDEF
         343                 :            :     _BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF
         344                 :            :     _BLAKE2_BLAKE2B_UPDATE_METHODDEF
         345                 :            :     {NULL, NULL}
         346                 :            : };
         347                 :            :
         348                 :            :
         349                 :            :
         350                 :            : static PyObject *
         351                 :          0 : py_blake2b_get_name(BLAKE2bObject *self, void *closure)
         352                 :            : {
         353                 :          0 :     return PyUnicode_FromString("blake2b");
         354                 :            : }
         355                 :            :
         356                 :            :
         357                 :            :
         358                 :            : static PyObject *
         359                 :          0 : py_blake2b_get_block_size(BLAKE2bObject *self, void *closure)
         360                 :            : {
         361                 :          0 :     return PyLong_FromLong(BLAKE2B_BLOCKBYTES);
         362                 :            : }
         363                 :            :
         364                 :            :
         365                 :            :
         366                 :            : static PyObject *
         367                 :          0 : py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure)
         368                 :            : {
         369                 :          0 :     return PyLong_FromLong(self->param.digest_length);
         370                 :            : }
         371                 :            :
         372                 :            :
         373                 :            : static PyGetSetDef py_blake2b_getsetters[] = {
         374                 :            :     {"name", (getter)py_blake2b_get_name,
         375                 :            :         NULL, NULL, NULL},
         376                 :            :     {"block_size", (getter)py_blake2b_get_block_size,
         377                 :            :         NULL, NULL, NULL},
         378                 :            :     {"digest_size", (getter)py_blake2b_get_digest_size,
         379                 :            :         NULL, NULL, NULL},
         380                 :            :     {NULL}
         381                 :            : };
         382                 :            :
         383                 :            :
         384                 :            : static void
         385                 :          0 : py_blake2b_dealloc(PyObject *self)
         386                 :            : {
         387                 :          0 :     BLAKE2bObject *obj = (BLAKE2bObject *)self;
         388                 :            :
         389                 :            :     /* Try not to leave state in memory. */
         390                 :          0 :     secure_zero_memory(&obj->param, sizeof(obj->param));
         391                 :          0 :     secure_zero_memory(&obj->state, sizeof(obj->state));
         392         [ #  # ]:          0 :     if (obj->lock) {
         393                 :          0 :         PyThread_free_lock(obj->lock);
         394                 :          0 :         obj->lock = NULL;
         395                 :            :     }
         396                 :            :
         397                 :          0 :     PyTypeObject *type = Py_TYPE(self);
         398                 :          0 :     PyObject_Free(self);
         399                 :          0 :     Py_DECREF(type);
         400                 :          0 : }
         401                 :            :
         402                 :            : static PyType_Slot blake2b_type_slots[] = {
         403                 :            :     {Py_tp_dealloc, py_blake2b_dealloc},
         404                 :            :     {Py_tp_doc, (char *)py_blake2b_new__doc__},
         405                 :            :     {Py_tp_methods, py_blake2b_methods},
         406                 :            :     {Py_tp_getset, py_blake2b_getsetters},
         407                 :            :     {Py_tp_new, py_blake2b_new},
         408                 :            :     {0,0}
         409                 :            : };
         410                 :            :
         411                 :            : PyType_Spec blake2b_type_spec = {
         412                 :            :     .name = "_blake2.blake2b",
         413                 :            :     .basicsize =  sizeof(BLAKE2bObject),
         414                 :            :     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
         415                 :            :     .slots = blake2b_type_slots
         416                 :            : };

Generated by: LCOV version 1.14