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