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

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

Issue 26798: add BLAKE2 to hashlib
Patch Set: Created 3 years, 6 months 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/blake2ns.h ('k') | Modules/_blake2/clinic/blake2b_impl.c.h » ('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 blake2s_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_BLAKE2S 1
26
27 #include "impl/blake2.h"
28 #include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */
29
30 #ifdef BLAKE2_USE_SSE
31 #include "impl/blake2s.c"
32 #else
33 #include "impl/blake2s-ref.c"
34 #endif
35
36
37 extern PyTypeObject PyBlake2_BLAKE2sType;
38
39 typedef struct {
40 PyObject_HEAD
41 blake2s_param param;
42 blake2s_state state;
43 #ifdef WITH_THREAD
44 PyThread_type_lock lock;
45 #endif
46 } BLAKE2sObject;
47
48 #include "clinic/blake2s_impl.c.h"
49
50 /*[clinic input]
51 module _blake2s
52 class _blake2s.blake2s "BLAKE2sObject *" "&PyBlake2_BLAKE2sType"
53 [clinic start generated code]*/
54 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=edbfcf7557a685a7]*/
55
56
57 static BLAKE2sObject *
58 new_BLAKE2sObject(PyTypeObject *type)
59 {
60 BLAKE2sObject *self;
61 self = (BLAKE2sObject *)type->tp_alloc(type, 0);
62 #ifdef WITH_THREAD
63 if (self != NULL) {
64 self->lock = NULL;
65 }
66 #endif
67 return self;
68 }
69
70 /*[clinic input]
71 @classmethod
72 _blake2s.blake2s.__new__ as py_blake2s_new
73 string as data: object = NULL
74 *
75 digest_size: int(c_default="BLAKE2S_OUTBYTES") = _blake2s.blake2s.MAX_DIGEST _SIZE
76 key: Py_buffer = None
77 salt: Py_buffer = None
78 person: Py_buffer = None
79 fanout: int = 1
80 depth: int = 1
81 leaf_size as leaf_size_obj: object = NULL
82 node_offset as node_offset_obj: object = NULL
83 node_depth: int = 0
84 inner_size: int = 0
85 last_node: bool = False
86
87 Return a new BLAKE2s hash object.
88 [clinic start generated code]*/
89
90 static PyObject *
91 py_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, PyObject *leaf_size_obj,
94 PyObject *node_offset_obj, int node_depth,
95 int inner_size, int last_node)
96 /*[clinic end generated code: output=fe060b258a8cbfc6 input=458cfdcb3d0d47ff]*/
97 {
98 BLAKE2sObject *self = NULL;
99 Py_buffer buf;
100
101 unsigned long leaf_size = 0;
102 unsigned PY_LONG_LONG node_offset = 0;
103
104 self = new_BLAKE2sObject(type);
105 if (self == NULL) {
106 goto error;
107 }
108
109 /* Zero parameter block. */
110 memset(&self->param, 0, sizeof(self->param));
111
112 /* Set digest size. */
113 if (digest_size <= 0 || digest_size > BLAKE2S_OUTBYTES) {
114 PyErr_Format(PyExc_ValueError,
115 "digest_size must be between 1 and %d bytes",
116 BLAKE2S_OUTBYTES);
117 goto error;
118 }
119 self->param.digest_length = digest_size;
120
121 /* Set salt parameter. */
122 if ((salt->obj != NULL) && salt->len) {
123 if (salt->len > BLAKE2S_SALTBYTES) {
124 PyErr_Format(PyExc_ValueError,
125 "maximum salt length is %d bytes",
126 BLAKE2S_SALTBYTES);
127 goto error;
128 }
129 memcpy(self->param.salt, salt->buf, salt->len);
130 }
131
132 /* Set personalization parameter. */
133 if ((person->obj != NULL) && person->len) {
134 if (person->len > BLAKE2S_PERSONALBYTES) {
135 PyErr_Format(PyExc_ValueError,
136 "maximum person length is %d bytes",
137 BLAKE2S_PERSONALBYTES);
138 goto error;
139 }
140 memcpy(self->param.personal, person->buf, person->len);
141 }
142
143 /* Set tree parameters. */
144 if (fanout < 0 || fanout > 255) {
145 PyErr_SetString(PyExc_ValueError,
146 "fanout must be between 0 and 255");
147 goto error;
148 }
149 self->param.fanout = (uint8_t)fanout;
150
151 if (depth <= 0 || depth > 255) {
152 PyErr_SetString(PyExc_ValueError,
153 "depth must be between 1 and 255");
154 goto error;
155 }
156 self->param.depth = (uint8_t)depth;
157
158 if (leaf_size_obj != NULL) {
159 leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
160 if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
161 goto error;
162 }
163 if (leaf_size > 0xFFFFFFFFU) {
164 PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
165 goto error;
166 }
167 }
168 self->param.leaf_length = (unsigned int)leaf_size;
169
170 if (node_offset_obj != NULL) {
171 node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
172 if (node_offset == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred()) {
173 goto error;
174 }
175 }
176 #ifdef HAVE_BLAKE2S
177 if (node_offset > 0xFFFFFFFFFFFFULL) {
178 /* maximum 2**48 - 1 */
179 PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
180 goto error;
181 }
182 store48(&(self->param.node_offset), node_offset);
183 #else
184 self->param.node_offset = node_offset;
185 #endif
186
187 if (node_depth < 0 || node_depth > 255) {
188 PyErr_SetString(PyExc_ValueError,
189 "node_depth must be between 0 and 255");
190 goto error;
191 }
192 self->param.node_depth = node_depth;
193
194 if (inner_size < 0 || inner_size > BLAKE2S_OUTBYTES) {
195 PyErr_Format(PyExc_ValueError,
196 "inner_size must be between 0 and is %d",
197 BLAKE2S_OUTBYTES);
198 goto error;
199 }
200 self->param.inner_length = inner_size;
201
202 /* Set key length. */
203 if ((key->obj != NULL) && key->len) {
204 if (key->len > BLAKE2S_KEYBYTES) {
205 PyErr_Format(PyExc_ValueError,
206 "maximum key length is %d bytes",
207 BLAKE2S_KEYBYTES);
208 goto error;
209 }
210 self->param.key_length = key->len;
211 }
212
213 /* Initialize hash state. */
214 if (blake2s_init_param(&self->state, &self->param) < 0) {
215 PyErr_SetString(PyExc_RuntimeError,
216 "error initializing hash state");
217 goto error;
218 }
219
220 /* Set last node flag (must come after initialization). */
221 self->state.last_node = last_node;
222
223 /* Process key block if any. */
224 if (self->param.key_length) {
225 uint8_t block[BLAKE2S_BLOCKBYTES];
226 memset(block, 0, sizeof(block));
227 memcpy(block, key->buf, key->len);
228 blake2s_update(&self->state, block, sizeof(block));
229 secure_zero_memory(block, sizeof(block));
230 }
231
232 /* Process initial data if any. */
233 if (data != NULL) {
234 GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
235
236 if (buf.len >= HASHLIB_GIL_MINSIZE) {
237 Py_BEGIN_ALLOW_THREADS
238 blake2s_update(&self->state, buf.buf, buf.len);
239 Py_END_ALLOW_THREADS
240 } else {
241 blake2s_update(&self->state, buf.buf, buf.len);
242 }
243 PyBuffer_Release(&buf);
244 }
245
246 return (PyObject *)self;
247
248 error:
249 if (self != NULL) {
250 Py_DECREF(self);
251 }
252 return NULL;
253 }
254
255 /*[clinic input]
256 _blake2s.blake2s.copy
257
258 Return a copy of the hash object.
259 [clinic start generated code]*/
260
261 static PyObject *
262 _blake2s_blake2s_copy_impl(BLAKE2sObject *self)
263 /*[clinic end generated code: output=6c5bada404b7aed7 input=c8858e887ae4a07a]*/
264 {
265 BLAKE2sObject *cpy;
266
267 if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL)
268 return NULL;
269
270 ENTER_HASHLIB(self);
271 cpy->param = self->param;
272 cpy->state = self->state;
273 LEAVE_HASHLIB(self);
274 return (PyObject *)cpy;
275 }
276
277 /*[clinic input]
278 _blake2s.blake2s.update
279
280 obj: object
281 /
282
283 Update this hash object's state with the provided string.
284 [clinic start generated code]*/
285
286 static PyObject *
287 _blake2s_blake2s_update(BLAKE2sObject *self, PyObject *obj)
288 /*[clinic end generated code: output=fe8438a1d3cede87 input=47a408b9a3cc05c5]*/
289 {
290 Py_buffer buf;
291
292 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
293
294 #ifdef WITH_THREAD
295 if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
296 self->lock = PyThread_allocate_lock();
297
298 if (self->lock != NULL) {
299 Py_BEGIN_ALLOW_THREADS
300 PyThread_acquire_lock(self->lock, 1);
301 blake2s_update(&self->state, buf.buf, buf.len);
302 PyThread_release_lock(self->lock);
303 Py_END_ALLOW_THREADS
304 } else {
305 blake2s_update(&self->state, buf.buf, buf.len);
306 }
307 #else
308 blake2s_update(&self->state, buf.buf, buf.len);
309 #endif /* !WITH_THREAD */
310 PyBuffer_Release(&buf);
311
312 Py_INCREF(Py_None);
313 return Py_None;
314 }
315
316 /*[clinic input]
317 _blake2s.blake2s.digest
318
319 Return the digest value as a string of binary data.
320 [clinic start generated code]*/
321
322 static PyObject *
323 _blake2s_blake2s_digest_impl(BLAKE2sObject *self)
324 /*[clinic end generated code: output=80e81a48c6f79cf9 input=feb9a220135bdeba]*/
325 {
326 uint8_t digest[BLAKE2S_OUTBYTES];
327 blake2s_state state_cpy;
328
329 ENTER_HASHLIB(self);
330 state_cpy = self->state;
331 blake2s_final(&state_cpy, digest, self->param.digest_length);
332 LEAVE_HASHLIB(self);
333 return PyBytes_FromStringAndSize((const char *)digest,
334 self->param.digest_length);
335 }
336
337 /*[clinic input]
338 _blake2s.blake2s.hexdigest
339
340 Return the digest value as a string of hexadecimal digits.
341 [clinic start generated code]*/
342
343 static PyObject *
344 _blake2s_blake2s_hexdigest_impl(BLAKE2sObject *self)
345 /*[clinic end generated code: output=db6c5028c0a3c2e5 input=4e4877b8bd7aea91]*/
346 {
347 uint8_t digest[BLAKE2S_OUTBYTES];
348 blake2s_state state_cpy;
349
350 ENTER_HASHLIB(self);
351 state_cpy = self->state;
352 blake2s_final(&state_cpy, digest, self->param.digest_length);
353 LEAVE_HASHLIB(self);
354 return _Py_strhex((const char *)digest, self->param.digest_length);
355 }
356
357
358 static PyMethodDef py_blake2s_methods[] = {
359 _BLAKE2S_BLAKE2S_COPY_METHODDEF
360 _BLAKE2S_BLAKE2S_DIGEST_METHODDEF
361 _BLAKE2S_BLAKE2S_HEXDIGEST_METHODDEF
362 _BLAKE2S_BLAKE2S_UPDATE_METHODDEF
363 {NULL, NULL}
364 };
365
366
367
368 static PyObject *
369 py_blake2s_get_name(BLAKE2sObject *self, void *closure)
370 {
371 return PyUnicode_FromString("blake2s");
372 }
373
374
375
376 static PyObject *
377 py_blake2s_get_block_size(BLAKE2sObject *self, void *closure)
378 {
379 return PyLong_FromLong(BLAKE2S_BLOCKBYTES);
380 }
381
382
383
384 static PyObject *
385 py_blake2s_get_digest_size(BLAKE2sObject *self, void *closure)
386 {
387 return PyLong_FromLong(self->param.digest_length);
388 }
389
390
391 static PyGetSetDef py_blake2s_getsetters[] = {
392 {"name", (getter)py_blake2s_get_name,
393 NULL, NULL, NULL},
394 {"block_size", (getter)py_blake2s_get_block_size,
395 NULL, NULL, NULL},
396 {"digest_size", (getter)py_blake2s_get_digest_size,
397 NULL, NULL, NULL},
398 {NULL}
399 };
400
401
402 static void
403 py_blake2s_dealloc(PyObject *self)
404 {
405 BLAKE2sObject *obj = (BLAKE2sObject *)self;
406
407 /* Try not to leave state in memory. */
408 secure_zero_memory(&obj->param, sizeof(obj->param));
409 secure_zero_memory(&obj->state, sizeof(obj->state));
410 #ifdef WITH_THREAD
411 if (obj->lock) {
412 PyThread_free_lock(obj->lock);
413 obj->lock = NULL;
414 }
415 #endif
416 PyObject_Del(self);
417 }
418
419
420 PyTypeObject PyBlake2_BLAKE2sType = {
421 PyVarObject_HEAD_INIT(NULL, 0)
422 "_blake2.blake2s", /* tp_name */
423 sizeof(BLAKE2sObject), /* tp_size */
424 0, /* tp_itemsize */
425 py_blake2s_dealloc, /* tp_dealloc */
426 0, /* tp_print */
427 0, /* tp_getattr */
428 0, /* tp_setattr */
429 0, /* tp_compare */
430 0, /* tp_repr */
431 0, /* tp_as_number */
432 0, /* tp_as_sequence */
433 0, /* tp_as_mapping */
434 0, /* tp_hash */
435 0, /* tp_call */
436 0, /* tp_str */
437 0, /* tp_getattro */
438 0, /* tp_setattro */
439 0, /* tp_as_buffer */
440 Py_TPFLAGS_DEFAULT, /* tp_flags */
441 py_blake2s_new__doc__, /* tp_doc */
442 0, /* tp_traverse */
443 0, /* tp_clear */
444 0, /* tp_richcompare */
445 0, /* tp_weaklistoffset */
446 0, /* tp_iter */
447 0, /* tp_iternext */
448 py_blake2s_methods, /* tp_methods */
449 0, /* tp_members */
450 py_blake2s_getsetters, /* tp_getset */
451 0, /* tp_base */
452 0, /* tp_dict */
453 0, /* tp_descr_get */
454 0, /* tp_descr_set */
455 0, /* tp_dictoffset */
456 0, /* tp_init */
457 0, /* tp_alloc */
458 py_blake2s_new, /* tp_new */
459 };
OLDNEW
« no previous file with comments | « Modules/_blake2/blake2ns.h ('k') | Modules/_blake2/clinic/blake2b_impl.c.h » ('j') | no next file with comments »

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