1 /*
2 * Written in 2013 by Dmitry Chestnykh <[email protected]>
3 * Modified for CPython by Christian Heimes <[email protected]>
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 *
new_BLAKE2bObject(PyTypeObject * type)58 new_BLAKE2bObject(PyTypeObject *type)
59 {
60 BLAKE2bObject *self;
61 self = (BLAKE2bObject *)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.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 *
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)91 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 BLAKE2bObject *self = NULL;
99 Py_buffer buf;
100
101 self = new_BLAKE2bObject(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 > BLAKE2B_OUTBYTES) {
111 PyErr_Format(PyExc_ValueError,
112 "digest_size must be between 1 and %d bytes",
113 BLAKE2B_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 > BLAKE2B_SALTBYTES) {
121 PyErr_Format(PyExc_ValueError,
122 "maximum salt length is %d bytes",
123 BLAKE2B_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 > BLAKE2B_PERSONALBYTES) {
132 PyErr_Format(PyExc_ValueError,
133 "maximum person length is %d bytes",
134 BLAKE2B_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 > BLAKE2B_OUTBYTES) {
182 PyErr_Format(PyExc_ValueError,
183 "inner_size must be between 0 and is %d",
184 BLAKE2B_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 > BLAKE2B_KEYBYTES) {
192 PyErr_Format(PyExc_ValueError,
193 "maximum key length is %d bytes",
194 BLAKE2B_KEYBYTES);
195 goto error;
196 }
197 self->param.key_length = (uint8_t)key->len;
198 }
199
200 /* Initialize hash state. */
201 if (blake2b_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[BLAKE2B_BLOCKBYTES];
213 memset(block, 0, sizeof(block));
214 memcpy(block, key->buf, key->len);
215 blake2b_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 blake2b_update(&self->state, buf.buf, buf.len);
226 Py_END_ALLOW_THREADS
227 } else {
228 blake2b_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.blake2b.copy
244
245 Return a copy of the hash object.
246 [clinic start generated code]*/
247
248 static PyObject *
_blake2_blake2b_copy_impl(BLAKE2bObject * self)249 _blake2_blake2b_copy_impl(BLAKE2bObject *self)
250 /*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/
251 {
252 BLAKE2bObject *cpy;
253
254 if ((cpy = new_BLAKE2bObject(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.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 *
_blake2_blake2b_update(BLAKE2bObject * self,PyObject * data)274 _blake2_blake2b_update(BLAKE2bObject *self, PyObject *data)
275 /*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/
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 blake2b_update(&self->state, buf.buf, buf.len);
288 PyThread_release_lock(self->lock);
289 Py_END_ALLOW_THREADS
290 } else {
291 blake2b_update(&self->state, buf.buf, buf.len);
292 }
293 PyBuffer_Release(&buf);
294
295 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 *
_blake2_blake2b_digest_impl(BLAKE2bObject * self)305 _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 ENTER_HASHLIB(self);
312 state_cpy = self->state;
313 blake2b_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.blake2b.hexdigest
321
322 Return the digest value as a string of hexadecimal digits.
323 [clinic start generated code]*/
324
325 static PyObject *
_blake2_blake2b_hexdigest_impl(BLAKE2bObject * self)326 _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 ENTER_HASHLIB(self);
333 state_cpy = self->state;
334 blake2b_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
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 *
py_blake2b_get_name(BLAKE2bObject * self,void * closure)351 py_blake2b_get_name(BLAKE2bObject *self, void *closure)
352 {
353 return PyUnicode_FromString("blake2b");
354 }
355
356
357
358 static PyObject *
py_blake2b_get_block_size(BLAKE2bObject * self,void * closure)359 py_blake2b_get_block_size(BLAKE2bObject *self, void *closure)
360 {
361 return PyLong_FromLong(BLAKE2B_BLOCKBYTES);
362 }
363
364
365
366 static PyObject *
py_blake2b_get_digest_size(BLAKE2bObject * self,void * closure)367 py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure)
368 {
369 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
py_blake2b_dealloc(PyObject * self)385 py_blake2b_dealloc(PyObject *self)
386 {
387 BLAKE2bObject *obj = (BLAKE2bObject *)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
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 };
417