Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15545)

Side by Side Diff: Modules/_blake2/blake2b_impl.c

Issue 26798: add BLAKE2 to hashlib
Patch Set: Created 3 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Modules/_blake2/blake2b2s.py ('k') | Modules/_blake2/blake2module.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "Python.h"
17 #include "pystrhex.h"
18 #ifdef WITH_THREAD
19 #include "pythread.h"
20 #endif
21
22 #include "../hashlib.h"
23 #include "blake2ns.h"
24
25 #define HAVE_BLAKE2B 1
26 #define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type)
27
28 #include "impl/blake2.h"
29 #include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */
30
31 #ifdef BLAKE2_USE_SSE
32 #include "impl/blake2b.c"
33 #else
34 #include "impl/blake2b-ref.c"
35 #endif
36
37
38 extern PyTypeObject PyBlake2_BLAKE2bType;
39
40 typedef struct {
41 PyObject_HEAD
42 blake2b_param param;
43 blake2b_state state;
44 #ifdef WITH_THREAD
45 PyThread_type_lock lock;
46 #endif
47 } BLAKE2bObject;
48
49 #include "clinic/blake2b_impl.c.h"
50
51 /*[clinic input]
52 module _blake2b
53 class _blake2b.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
54 [clinic start generated code]*/
55 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6893358c6622aecf]*/
56
57
58 static BLAKE2bObject *
59 new_BLAKE2bObject(PyTypeObject *type)
60 {
61 BLAKE2bObject *self;
62 self = (BLAKE2bObject *)type->tp_alloc(type, 0);
63 #ifdef WITH_THREAD
64 if (self != NULL) {
65 self->lock = NULL;
66 }
67 #endif
68 return self;
69 }
70
71 /*[clinic input]
72 @classmethod
73 _blake2b.blake2b.__new__ as py_blake2b_new
74 string as data: object = NULL
75 *
76 digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2b.blake2b.MAX_DIGEST _SIZE
77 key: Py_buffer = None
78 salt: Py_buffer = None
79 person: Py_buffer = None
80 fanout: int = 1
81 depth: int = 1
82 leaf_size as leaf_size_obj: object = NULL
83 node_offset as node_offset_obj: object = NULL
84 node_depth: int = 0
85 inner_size: int = 0
86 last_node: bool = False
87
88 Return a new BLAKE2b hash object.
89 [clinic start generated code]*/
90
91 static PyObject *
92 py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
93 Py_buffer *key, Py_buffer *salt, Py_buffer *person,
94 int fanout, int depth, PyObject *leaf_size_obj,
95 PyObject *node_offset_obj, int node_depth,
96 int inner_size, int last_node)
97 /*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/
98 {
99 BLAKE2bObject *self = NULL;
100 Py_buffer buf;
101
102 unsigned long leaf_size = 0;
103 unsigned PY_LONG_LONG node_offset = 0;
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_obj != NULL) {
160 leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
161 if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
162 goto error;
163 }
164 if (leaf_size > 0xFFFFFFFFU) {
165 PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
166 goto error;
167 }
168 }
169 self->param.leaf_length = (unsigned int)leaf_size;
170
171 if (node_offset_obj != NULL) {
172 node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
173 if (node_offset == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred()) {
174 goto error;
175 }
176 }
177 #ifdef HAVE_BLAKE2S
178 if (node_offset > 0xFFFFFFFFFFFFULL) {
179 /* maximum 2**48 - 1 */
180 PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
181 goto error;
182 }
183 store48(&(self->param.node_offset), node_offset);
184 #else
185 self->param.node_offset = node_offset;
186 #endif
187
188 if (node_depth < 0 || node_depth > 255) {
189 PyErr_SetString(PyExc_ValueError,
190 "node_depth must be between 0 and 255");
191 goto error;
192 }
193 self->param.node_depth = node_depth;
194
195 if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) {
196 PyErr_Format(PyExc_ValueError,
197 "inner_size must be between 0 and is %d",
198 BLAKE2B_OUTBYTES);
199 goto error;
200 }
201 self->param.inner_length = inner_size;
202
203 /* Set key length. */
204 if ((key->obj != NULL) && key->len) {
205 if (key->len > BLAKE2B_KEYBYTES) {
206 PyErr_Format(PyExc_ValueError,
207 "maximum key length is %d bytes",
208 BLAKE2B_KEYBYTES);
209 goto error;
210 }
211 self->param.key_length = key->len;
212 }
213
214 /* Initialize hash state. */
215 if (blake2b_init_param(&self->state, &self->param) < 0) {
216 PyErr_SetString(PyExc_RuntimeError,
217 "error initializing hash state");
218 goto error;
219 }
220
221 /* Set last node flag (must come after initialization). */
222 self->state.last_node = last_node;
223
224 /* Process key block if any. */
225 if (self->param.key_length) {
226 uint8_t block[BLAKE2B_BLOCKBYTES];
227 memset(block, 0, sizeof(block));
228 memcpy(block, key->buf, key->len);
229 blake2b_update(&self->state, block, sizeof(block));
230 secure_zero_memory(block, sizeof(block));
231 }
232
233 /* Process initial data if any. */
234 if (data != NULL) {
235 GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
236
237 if (buf.len >= HASHLIB_GIL_MINSIZE) {
238 Py_BEGIN_ALLOW_THREADS
239 blake2b_update(&self->state, buf.buf, buf.len);
240 Py_END_ALLOW_THREADS
241 } else {
242 blake2b_update(&self->state, buf.buf, buf.len);
243 }
244 PyBuffer_Release(&buf);
245 }
246
247 return (PyObject *)self;
248
249 error:
250 if (self != NULL) {
251 Py_DECREF(self);
252 }
253 return NULL;
254 }
255
256 /*[clinic input]
257 _blake2b.blake2b.copy
258
259 Return a copy of the hash object.
260 [clinic start generated code]*/
261
262 static PyObject *
263 _blake2b_blake2b_copy_impl(BLAKE2bObject *self)
264 /*[clinic end generated code: output=c89cd33550ab1543 input=4c9c319f18f10747]*/
265 {
266 BLAKE2bObject *cpy;
267
268 if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL)
269 return NULL;
270
271 ENTER_HASHLIB(self);
272 cpy->param = self->param;
273 cpy->state = self->state;
274 LEAVE_HASHLIB(self);
275 return (PyObject *)cpy;
276 }
277
278 /*[clinic input]
279 _blake2b.blake2b.update
280
281 obj: object
282 /
283
284 Update this hash object's state with the provided string.
285 [clinic start generated code]*/
286
287 static PyObject *
288 _blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
289 /*[clinic end generated code: output=a888f07c4cddbe94 input=3ecb8c13ee4260f2]*/
290 {
291 Py_buffer buf;
292
293 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
294
295 #ifdef WITH_THREAD
296 if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
297 self->lock = PyThread_allocate_lock();
298
299 if (self->lock != NULL) {
300 Py_BEGIN_ALLOW_THREADS
301 PyThread_acquire_lock(self->lock, 1);
302 blake2b_update(&self->state, buf.buf, buf.len);
303 PyThread_release_lock(self->lock);
304 Py_END_ALLOW_THREADS
305 } else {
306 blake2b_update(&self->state, buf.buf, buf.len);
307 }
308 #else
309 blake2b_update(&self->state, buf.buf, buf.len);
310 #endif /* !WITH_THREAD */
311 PyBuffer_Release(&buf);
312
313 Py_INCREF(Py_None);
314 return Py_None;
315 }
316
317 /*[clinic input]
318 _blake2b.blake2b.digest
319
320 Return the digest value as a string of binary data.
321 [clinic start generated code]*/
322
323 static PyObject *
324 _blake2b_blake2b_digest_impl(BLAKE2bObject *self)
325 /*[clinic end generated code: output=b13a79360d984740 input=ac2fa462ebb1b9c7]*/
326 {
327 uint8_t digest[BLAKE2B_OUTBYTES];
328 blake2b_state state_cpy;
329
330 ENTER_HASHLIB(self);
331 state_cpy = self->state;
332 blake2b_final(&state_cpy, digest, self->param.digest_length);
333 LEAVE_HASHLIB(self);
334 return PyBytes_FromStringAndSize((const char *)digest,
335 self->param.digest_length);
336 }
337
338 /*[clinic input]
339 _blake2b.blake2b.hexdigest
340
341 Return the digest value as a string of hexadecimal digits.
342 [clinic start generated code]*/
343
344 static PyObject *
345 _blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self)
346 /*[clinic end generated code: output=6a503611715b24bd input=d58f0b2f37812e33]*/
347 {
348 uint8_t digest[BLAKE2B_OUTBYTES];
349 blake2b_state state_cpy;
350
351 ENTER_HASHLIB(self);
352 state_cpy = self->state;
353 blake2b_final(&state_cpy, digest, self->param.digest_length);
354 LEAVE_HASHLIB(self);
355 return _Py_strhex((const char *)digest, self->param.digest_length);
356 }
357
358
359 static PyMethodDef py_blake2b_methods[] = {
360 _BLAKE2B_BLAKE2B_COPY_METHODDEF
361 _BLAKE2B_BLAKE2B_DIGEST_METHODDEF
362 _BLAKE2B_BLAKE2B_HEXDIGEST_METHODDEF
363 _BLAKE2B_BLAKE2B_UPDATE_METHODDEF
364 {NULL, NULL}
365 };
366
367
368
369 static PyObject *
370 py_blake2b_get_name(BLAKE2bObject *self, void *closure)
371 {
372 return PyUnicode_FromString("blake2b");
373 }
374
375
376
377 static PyObject *
378 py_blake2b_get_block_size(BLAKE2bObject *self, void *closure)
379 {
380 return PyLong_FromLong(BLAKE2B_BLOCKBYTES);
381 }
382
383
384
385 static PyObject *
386 py_blake2b_get_digest_size(BLAKE2bObject *self, void *closure)
387 {
388 return PyLong_FromLong(self->param.digest_length);
389 }
390
391
392 static PyGetSetDef py_blake2b_getsetters[] = {
393 {"name", (getter)py_blake2b_get_name,
394 NULL, NULL, NULL},
395 {"block_size", (getter)py_blake2b_get_block_size,
396 NULL, NULL, NULL},
397 {"digest_size", (getter)py_blake2b_get_digest_size,
398 NULL, NULL, NULL},
399 {NULL}
400 };
401
402
403 static void
404 py_blake2b_dealloc(PyObject *self)
405 {
406 BLAKE2bObject *obj = (BLAKE2bObject *)self;
407
408 /* Try not to leave state in memory. */
409 secure_zero_memory(&obj->param, sizeof(obj->param));
410 secure_zero_memory(&obj->state, sizeof(obj->state));
411 #ifdef WITH_THREAD
412 if (obj->lock) {
413 PyThread_free_lock(obj->lock);
414 obj->lock = NULL;
415 }
416 #endif
417 PyObject_Del(self);
418 }
419
420
421 PyTypeObject PyBlake2_BLAKE2bType = {
422 PyVarObject_HEAD_INIT(NULL, 0)
423 "_blake2.blake2b", /* tp_name */
424 sizeof(BLAKE2bObject), /* tp_size */
425 0, /* tp_itemsize */
426 py_blake2b_dealloc, /* tp_dealloc */
427 0, /* tp_print */
428 0, /* tp_getattr */
429 0, /* tp_setattr */
430 0, /* tp_compare */
431 0, /* tp_repr */
432 0, /* tp_as_number */
433 0, /* tp_as_sequence */
434 0, /* tp_as_mapping */
435 0, /* tp_hash */
436 0, /* tp_call */
437 0, /* tp_str */
438 0, /* tp_getattro */
439 0, /* tp_setattro */
440 0, /* tp_as_buffer */
441 Py_TPFLAGS_DEFAULT, /* tp_flags */
442 py_blake2b_new__doc__, /* tp_doc */
443 0, /* tp_traverse */
444 0, /* tp_clear */
445 0, /* tp_richcompare */
446 0, /* tp_weaklistoffset */
447 0, /* tp_iter */
448 0, /* tp_iternext */
449 py_blake2b_methods, /* tp_methods */
450 0, /* tp_members */
451 py_blake2b_getsetters, /* tp_getset */
452 0, /* tp_base */
453 0, /* tp_dict */
454 0, /* tp_descr_get */
455 0, /* tp_descr_set */
456 0, /* tp_dictoffset */
457 0, /* tp_init */
458 0, /* tp_alloc */
459 py_blake2b_new, /* tp_new */
460 };
OLDNEW
« no previous file with comments | « Modules/_blake2/blake2b2s.py ('k') | Modules/_blake2/blake2module.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+