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 blake2s_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/blake2s.c" 31#else 32#include "impl/blake2s-ref.c" 33#endif 34#endif // !HAVE_LIBB2 35 36#define HAVE_BLAKE2S 1 37 38extern PyType_Spec blake2s_type_spec; 39 40 41typedef struct { 42 PyObject_HEAD 43 blake2s_param param; 44 blake2s_state state; 45 PyThread_type_lock lock; 46} BLAKE2sObject; 47 48#include "clinic/blake2s_impl.c.h" 49 50/*[clinic input] 51module _blake2 52class _blake2.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType" 53[clinic start generated code]*/ 54/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b79d7ffe07286ce]*/ 55 56 57static BLAKE2sObject * 58new_BLAKE2sObject(PyTypeObject *type) 59{ 60 BLAKE2sObject *self; 61 self = (BLAKE2sObject *)type->tp_alloc(type, 0); 62 if (self != NULL) { 63 self->lock = NULL; 64 } 65 return self; 66} 67 68/*[clinic input] 69@classmethod 70_blake2.blake2s.__new__ as py_blake2s_new 71 data: object(c_default="NULL") = b'' 72 / 73 * 74 digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2.blake2s.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 87Return a new BLAKE2s hash object. 88[clinic start generated code]*/ 89 90static PyObject * 91py_blake2s_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=556181f73905c686 input=4dda87723f23abb0]*/ 97{ 98 BLAKE2sObject *self = NULL; 99 Py_buffer buf; 100 101 self = new_BLAKE2sObject(type); 102 if (self == NULL) { 103 goto error; 104 } 105 106 /* Zero parameter block. */ 107 memset(&self->param, 0, sizeof(self->param)); 108 109 /* Set digest size. */ 110 if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) { 111 PyErr_Format(PyExc_ValueError, 112 "digest_size must be between 1 and %d bytes", 113 BLAKE2S_OUTBYTES); 114 goto error; 115 } 116 self->param.digest_length = digest_size; 117 118 /* Set salt parameter. */ 119 if ((salt->obj != NULL) && salt->len) { 120 if (salt->len > BLAKE2S_SALTBYTES) { 121 PyErr_Format(PyExc_ValueError, 122 "maximum salt length is %d bytes", 123 BLAKE2S_SALTBYTES); 124 goto error; 125 } 126 memcpy(self->param.salt, salt->buf, salt->len); 127 } 128 129 /* Set personalization parameter. */ 130 if ((person->obj != NULL) && person->len) { 131 if (person->len > BLAKE2S_PERSONALBYTES) { 132 PyErr_Format(PyExc_ValueError, 133 "maximum person length is %d bytes", 134 BLAKE2S_PERSONALBYTES); 135 goto error; 136 } 137 memcpy(self->param.personal, person->buf, person->len); 138 } 139 140 /* Set tree parameters. */ 141 if (fanout < 0 || fanout > 255) { 142 PyErr_SetString(PyExc_ValueError, 143 "fanout must be between 0 and 255"); 144 goto error; 145 } 146 self->param.fanout = (uint8_t)fanout; 147 148 if (depth <= 0 || depth > 255) { 149 PyErr_SetString(PyExc_ValueError, 150 "depth must be between 1 and 255"); 151 goto error; 152 } 153 self->param.depth = (uint8_t)depth; 154 155 if (leaf_size > 0xFFFFFFFFU) { 156 PyErr_SetString(PyExc_OverflowError, "leaf_size is too large"); 157 goto error; 158 } 159 // NB: Simple assignment here would be incorrect on big endian platforms. 160 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 store64(&(self->param.node_offset), node_offset); 172#endif 173 174 if (node_depth < 0 || node_depth > 255) { 175 PyErr_SetString(PyExc_ValueError, 176 "node_depth must be between 0 and 255"); 177 goto error; 178 } 179 self->param.node_depth = node_depth; 180 181 if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) { 182 PyErr_Format(PyExc_ValueError, 183 "inner_size must be between 0 and is %d", 184 BLAKE2S_OUTBYTES); 185 goto error; 186 } 187 self->param.inner_length = inner_size; 188 189 /* Set key length. */ 190 if ((key->obj != NULL) && key->len) { 191 if (key->len > BLAKE2S_KEYBYTES) { 192 PyErr_Format(PyExc_ValueError, 193 "maximum key length is %d bytes", 194 BLAKE2S_KEYBYTES); 195 goto error; 196 } 197 self->param.key_length = (uint8_t)key->len; 198 } 199 200 /* Initialize hash state. */ 201 if (blake2s_init_param(&self->state, &self->param) < 0) { 202 PyErr_SetString(PyExc_RuntimeError, 203 "error initializing hash state"); 204 goto error; 205 } 206 207 /* Set last node flag (must come after initialization). */ 208 self->state.last_node = last_node; 209 210 /* Process key block if any. */ 211 if (self->param.key_length) { 212 uint8_t block[BLAKE2S_BLOCKBYTES]; 213 memset(block, 0, sizeof(block)); 214 memcpy(block, key->buf, key->len); 215 blake2s_update(&self->state, block, sizeof(block)); 216 secure_zero_memory(block, sizeof(block)); 217 } 218 219 /* Process initial data if any. */ 220 if (data != NULL) { 221 GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); 222 223 if (buf.len >= HASHLIB_GIL_MINSIZE) { 224 Py_BEGIN_ALLOW_THREADS 225 blake2s_update(&self->state, buf.buf, buf.len); 226 Py_END_ALLOW_THREADS 227 } else { 228 blake2s_update(&self->state, buf.buf, buf.len); 229 } 230 PyBuffer_Release(&buf); 231 } 232 233 return (PyObject *)self; 234 235 error: 236 if (self != NULL) { 237 Py_DECREF(self); 238 } 239 return NULL; 240} 241 242/*[clinic input] 243_blake2.blake2s.copy 244 245Return a copy of the hash object. 246[clinic start generated code]*/ 247 248static PyObject * 249_blake2_blake2s_copy_impl(BLAKE2sObject *self) 250/*[clinic end generated code: output=5b90131c4eae275e input=0b9d44942f0fe4b2]*/ 251{ 252 BLAKE2sObject *cpy; 253 254 if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL) 255 return NULL; 256 257 ENTER_HASHLIB(self); 258 cpy->param = self->param; 259 cpy->state = self->state; 260 LEAVE_HASHLIB(self); 261 return (PyObject *)cpy; 262} 263 264/*[clinic input] 265_blake2.blake2s.update 266 267 data: object 268 / 269 270Update this hash object's state with the provided bytes-like object. 271[clinic start generated code]*/ 272 273static PyObject * 274_blake2_blake2s_update(BLAKE2sObject *self, PyObject *data) 275/*[clinic end generated code: output=757dc087fec37815 input=97500db2f9de4aaa]*/ 276{ 277 Py_buffer buf; 278 279 GET_BUFFER_VIEW_OR_ERROUT(data, &buf); 280 281 if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) 282 self->lock = PyThread_allocate_lock(); 283 284 if (self->lock != NULL) { 285 Py_BEGIN_ALLOW_THREADS 286 PyThread_acquire_lock(self->lock, 1); 287 blake2s_update(&self->state, buf.buf, buf.len); 288 PyThread_release_lock(self->lock); 289 Py_END_ALLOW_THREADS 290 } else { 291 blake2s_update(&self->state, buf.buf, buf.len); 292 } 293 PyBuffer_Release(&buf); 294 295 Py_RETURN_NONE; 296} 297 298/*[clinic input] 299_blake2.blake2s.digest 300 301Return the digest value as a bytes object. 302[clinic start generated code]*/ 303 304static PyObject * 305_blake2_blake2s_digest_impl(BLAKE2sObject *self) 306/*[clinic end generated code: output=40c566ca4bc6bc51 input=f41e0b8d6d937454]*/ 307{ 308 uint8_t digest[BLAKE2S_OUTBYTES]; 309 blake2s_state state_cpy; 310 311 ENTER_HASHLIB(self); 312 state_cpy = self->state; 313 blake2s_final(&state_cpy, digest, self->param.digest_length); 314 LEAVE_HASHLIB(self); 315 return PyBytes_FromStringAndSize((const char *)digest, 316 self->param.digest_length); 317} 318 319/*[clinic input] 320_blake2.blake2s.hexdigest 321 322Return the digest value as a string of hexadecimal digits. 323[clinic start generated code]*/ 324 325static PyObject * 326_blake2_blake2s_hexdigest_impl(BLAKE2sObject *self) 327/*[clinic end generated code: output=15153eb5e59c52eb input=c77a1321567e8952]*/ 328{ 329 uint8_t digest[BLAKE2S_OUTBYTES]; 330 blake2s_state state_cpy; 331 332 ENTER_HASHLIB(self); 333 state_cpy = self->state; 334 blake2s_final(&state_cpy, digest, self->param.digest_length); 335 LEAVE_HASHLIB(self); 336 return _Py_strhex((const char *)digest, self->param.digest_length); 337} 338 339 340static PyMethodDef py_blake2s_methods[] = { 341 _BLAKE2_BLAKE2S_COPY_METHODDEF 342 _BLAKE2_BLAKE2S_DIGEST_METHODDEF 343 _BLAKE2_BLAKE2S_HEXDIGEST_METHODDEF 344 _BLAKE2_BLAKE2S_UPDATE_METHODDEF 345 {NULL, NULL} 346}; 347 348 349 350static PyObject * 351py_blake2s_get_name(BLAKE2sObject *self, void *closure) 352{ 353 return PyUnicode_FromString("blake2s"); 354} 355 356 357 358static PyObject * 359py_blake2s_get_block_size(BLAKE2sObject *self, void *closure) 360{ 361 return PyLong_FromLong(BLAKE2S_BLOCKBYTES); 362} 363 364 365 366static PyObject * 367py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure) 368{ 369 return PyLong_FromLong(self->param.digest_length); 370} 371 372 373static PyGetSetDef py_blake2s_getsetters[] = { 374 {"name", (getter)py_blake2s_get_name, 375 NULL, NULL, NULL}, 376 {"block_size", (getter)py_blake2s_get_block_size, 377 NULL, NULL, NULL}, 378 {"digest_size", (getter)py_blake2s_get_digest_size, 379 NULL, NULL, NULL}, 380 {NULL} 381}; 382 383 384static void 385py_blake2s_dealloc(PyObject *self) 386{ 387 BLAKE2sObject *obj = (BLAKE2sObject *)self; 388 389 /* Try not to leave state in memory. */ 390 secure_zero_memory(&obj->param, sizeof(obj->param)); 391 secure_zero_memory(&obj->state, sizeof(obj->state)); 392 if (obj->lock) { 393 PyThread_free_lock(obj->lock); 394 obj->lock = NULL; 395 } 396 397 PyTypeObject *type = Py_TYPE(self); 398 PyObject_Free(self); 399 Py_DECREF(type); 400} 401 402static PyType_Slot blake2s_type_slots[] = { 403 {Py_tp_dealloc, py_blake2s_dealloc}, 404 {Py_tp_doc, (char *)py_blake2s_new__doc__}, 405 {Py_tp_methods, py_blake2s_methods}, 406 {Py_tp_getset, py_blake2s_getsetters}, 407 {Py_tp_new, py_blake2s_new}, 408 {0,0} 409}; 410 411PyType_Spec blake2s_type_spec = { 412 .name = "_blake2.blake2s", 413 .basicsize = sizeof(BLAKE2sObject), 414 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, 415 .slots = blake2s_type_slots 416}; 417