ยปCore Development>Code coverage>Modules/_blake2/blake2b_impl.c

Python code coverage for Modules/_blake2/blake2b_impl.c

#countcontent
1n/a/*
2n/a * Written in 2013 by Dmitry Chestnykh <dmitry@codingrobots.com>
3n/a * Modified for CPython by Christian Heimes <christian@python.org>
4n/a *
5n/a * To the extent possible under law, the author have dedicated all
6n/a * copyright and related and neighboring rights to this software to
7n/a * the public domain worldwide. This software is distributed without
8n/a * any warranty. http://creativecommons.org/publicdomain/zero/1.0/
9n/a */
10n/a
11n/a/* WARNING: autogenerated file!
12n/a *
13n/a * The blake2s_impl.c is autogenerated from blake2b_impl.c.
14n/a */
15n/a
16n/a#include "Python.h"
17n/a#include "pystrhex.h"
18n/a#ifdef WITH_THREAD
19n/a#include "pythread.h"
20n/a#endif
21n/a
22n/a#include "../hashlib.h"
23n/a#include "blake2ns.h"
24n/a
25n/a#define HAVE_BLAKE2B 1
26n/a#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type)
27n/a
28n/a#include "impl/blake2.h"
29n/a#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */
30n/a
31n/a#ifdef BLAKE2_USE_SSE
32n/a#include "impl/blake2b.c"
33n/a#else
34n/a#include "impl/blake2b-ref.c"
35n/a#endif
36n/a
37n/a
38n/aextern PyTypeObject PyBlake2_BLAKE2bType;
39n/a
40n/atypedef struct {
41n/a PyObject_HEAD
42n/a blake2b_param param;
43n/a blake2b_state state;
44n/a#ifdef WITH_THREAD
45n/a PyThread_type_lock lock;
46n/a#endif
47n/a} BLAKE2bObject;
48n/a
49n/a#include "clinic/blake2b_impl.c.h"
50n/a
51n/a/*[clinic input]
52n/amodule _blake2b
53n/aclass _blake2b.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
54n/a[clinic start generated code]*/
55n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6893358c6622aecf]*/
56n/a
57n/a
58n/astatic BLAKE2bObject *
59n/anew_BLAKE2bObject(PyTypeObject *type)
60n/a{
61n/a BLAKE2bObject *self;
62n/a self = (BLAKE2bObject *)type->tp_alloc(type, 0);
63n/a#ifdef WITH_THREAD
64n/a if (self != NULL) {
65n/a self->lock = NULL;
66n/a }
67n/a#endif
68n/a return self;
69n/a}
70n/a
71n/a/*[clinic input]
72n/a@classmethod
73n/a_blake2b.blake2b.__new__ as py_blake2b_new
74n/a string as data: object = NULL
75n/a *
76n/a digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2b.blake2b.MAX_DIGEST_SIZE
77n/a key: Py_buffer = None
78n/a salt: Py_buffer = None
79n/a person: Py_buffer = None
80n/a fanout: int = 1
81n/a depth: int = 1
82n/a leaf_size as leaf_size_obj: object = NULL
83n/a node_offset as node_offset_obj: object = NULL
84n/a node_depth: int = 0
85n/a inner_size: int = 0
86n/a last_node: bool = False
87n/a
88n/aReturn a new BLAKE2b hash object.
89n/a[clinic start generated code]*/
90n/a
91n/astatic PyObject *
92n/apy_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
93n/a Py_buffer *key, Py_buffer *salt, Py_buffer *person,
94n/a int fanout, int depth, PyObject *leaf_size_obj,
95n/a PyObject *node_offset_obj, int node_depth,
96n/a int inner_size, int last_node)
97n/a/*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/
98n/a{
99n/a BLAKE2bObject *self = NULL;
100n/a Py_buffer buf;
101n/a
102n/a unsigned long leaf_size = 0;
103n/a unsigned long long node_offset = 0;
104n/a
105n/a self = new_BLAKE2bObject(type);
106n/a if (self == NULL) {
107n/a goto error;
108n/a }
109n/a
110n/a /* Zero parameter block. */
111n/a memset(&self->param, 0, sizeof(self->param));
112n/a
113n/a /* Set digest size. */
114n/a if (digest_size <= 0 || digest_size > BLAKE2B_OUTBYTES) {
115n/a PyErr_Format(PyExc_ValueError,
116n/a "digest_size must be between 1 and %d bytes",
117n/a BLAKE2B_OUTBYTES);
118n/a goto error;
119n/a }
120n/a self->param.digest_length = digest_size;
121n/a
122n/a /* Set salt parameter. */
123n/a if ((salt->obj != NULL) && salt->len) {
124n/a if (salt->len > BLAKE2B_SALTBYTES) {
125n/a PyErr_Format(PyExc_ValueError,
126n/a "maximum salt length is %d bytes",
127n/a BLAKE2B_SALTBYTES);
128n/a goto error;
129n/a }
130n/a memcpy(self->param.salt, salt->buf, salt->len);
131n/a }
132n/a
133n/a /* Set personalization parameter. */
134n/a if ((person->obj != NULL) && person->len) {
135n/a if (person->len > BLAKE2B_PERSONALBYTES) {
136n/a PyErr_Format(PyExc_ValueError,
137n/a "maximum person length is %d bytes",
138n/a BLAKE2B_PERSONALBYTES);
139n/a goto error;
140n/a }
141n/a memcpy(self->param.personal, person->buf, person->len);
142n/a }
143n/a
144n/a /* Set tree parameters. */
145n/a if (fanout < 0 || fanout > 255) {
146n/a PyErr_SetString(PyExc_ValueError,
147n/a "fanout must be between 0 and 255");
148n/a goto error;
149n/a }
150n/a self->param.fanout = (uint8_t)fanout;
151n/a
152n/a if (depth <= 0 || depth > 255) {
153n/a PyErr_SetString(PyExc_ValueError,
154n/a "depth must be between 1 and 255");
155n/a goto error;
156n/a }
157n/a self->param.depth = (uint8_t)depth;
158n/a
159n/a if (leaf_size_obj != NULL) {
160n/a leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
161n/a if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
162n/a goto error;
163n/a }
164n/a if (leaf_size > 0xFFFFFFFFU) {
165n/a PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
166n/a goto error;
167n/a }
168n/a }
169n/a self->param.leaf_length = (unsigned int)leaf_size;
170n/a
171n/a if (node_offset_obj != NULL) {
172n/a node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
173n/a if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) {
174n/a goto error;
175n/a }
176n/a }
177n/a#ifdef HAVE_BLAKE2S
178n/a if (node_offset > 0xFFFFFFFFFFFFULL) {
179n/a /* maximum 2**48 - 1 */
180n/a PyErr_SetString(PyExc_OverflowError, "node_offset is too large");
181n/a goto error;
182n/a }
183n/a store48(&(self->param.node_offset), node_offset);
184n/a#else
185n/a self->param.node_offset = node_offset;
186n/a#endif
187n/a
188n/a if (node_depth < 0 || node_depth > 255) {
189n/a PyErr_SetString(PyExc_ValueError,
190n/a "node_depth must be between 0 and 255");
191n/a goto error;
192n/a }
193n/a self->param.node_depth = node_depth;
194n/a
195n/a if (inner_size < 0 || inner_size > BLAKE2B_OUTBYTES) {
196n/a PyErr_Format(PyExc_ValueError,
197n/a "inner_size must be between 0 and is %d",
198n/a BLAKE2B_OUTBYTES);
199n/a goto error;
200n/a }
201n/a self->param.inner_length = inner_size;
202n/a
203n/a /* Set key length. */
204n/a if ((key->obj != NULL) && key->len) {
205n/a if (key->len > BLAKE2B_KEYBYTES) {
206n/a PyErr_Format(PyExc_ValueError,
207n/a "maximum key length is %d bytes",
208n/a BLAKE2B_KEYBYTES);
209n/a goto error;
210n/a }
211n/a self->param.key_length = (uint8_t)key->len;
212n/a }
213n/a
214n/a /* Initialize hash state. */
215n/a if (blake2b_init_param(&self->state, &self->param) < 0) {
216n/a PyErr_SetString(PyExc_RuntimeError,
217n/a "error initializing hash state");
218n/a goto error;
219n/a }
220n/a
221n/a /* Set last node flag (must come after initialization). */
222n/a self->state.last_node = last_node;
223n/a
224n/a /* Process key block if any. */
225n/a if (self->param.key_length) {
226n/a uint8_t block[BLAKE2B_BLOCKBYTES];
227n/a memset(block, 0, sizeof(block));
228n/a memcpy(block, key->buf, key->len);
229n/a blake2b_update(&self->state, block, sizeof(block));
230n/a secure_zero_memory(block, sizeof(block));
231n/a }
232n/a
233n/a /* Process initial data if any. */
234n/a if (data != NULL) {
235n/a GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error);
236n/a
237n/a if (buf.len >= HASHLIB_GIL_MINSIZE) {
238n/a Py_BEGIN_ALLOW_THREADS
239n/a blake2b_update(&self->state, buf.buf, buf.len);
240n/a Py_END_ALLOW_THREADS
241n/a } else {
242n/a blake2b_update(&self->state, buf.buf, buf.len);
243n/a }
244n/a PyBuffer_Release(&buf);
245n/a }
246n/a
247n/a return (PyObject *)self;
248n/a
249n/a error:
250n/a if (self != NULL) {
251n/a Py_DECREF(self);
252n/a }
253n/a return NULL;
254n/a}
255n/a
256n/a/*[clinic input]
257n/a_blake2b.blake2b.copy
258n/a
259n/aReturn a copy of the hash object.
260n/a[clinic start generated code]*/
261n/a
262n/astatic PyObject *
263n/a_blake2b_blake2b_copy_impl(BLAKE2bObject *self)
264n/a/*[clinic end generated code: output=c89cd33550ab1543 input=4c9c319f18f10747]*/
265n/a{
266n/a BLAKE2bObject *cpy;
267n/a
268n/a if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL)
269n/a return NULL;
270n/a
271n/a ENTER_HASHLIB(self);
272n/a cpy->param = self->param;
273n/a cpy->state = self->state;
274n/a LEAVE_HASHLIB(self);
275n/a return (PyObject *)cpy;
276n/a}
277n/a
278n/a/*[clinic input]
279n/a_blake2b.blake2b.update
280n/a
281n/a obj: object
282n/a /
283n/a
284n/aUpdate this hash object's state with the provided string.
285n/a[clinic start generated code]*/
286n/a
287n/astatic PyObject *
288n/a_blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
289n/a/*[clinic end generated code: output=a888f07c4cddbe94 input=3ecb8c13ee4260f2]*/
290n/a{
291n/a Py_buffer buf;
292n/a
293n/a GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
294n/a
295n/a#ifdef WITH_THREAD
296n/a if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
297n/a self->lock = PyThread_allocate_lock();
298n/a
299n/a if (self->lock != NULL) {
300n/a Py_BEGIN_ALLOW_THREADS
301n/a PyThread_acquire_lock(self->lock, 1);
302n/a blake2b_update(&self->state, buf.buf, buf.len);
303n/a PyThread_release_lock(self->lock);
304n/a Py_END_ALLOW_THREADS
305n/a } else {
306n/a blake2b_update(&self->state, buf.buf, buf.len);
307n/a }
308n/a#else
309n/a blake2b_update(&self->state, buf.buf, buf.len);
310n/a#endif /* !WITH_THREAD */
311n/a PyBuffer_Release(&buf);
312n/a
313n/a Py_RETURN_NONE;
314n/a}
315n/a
316n/a/*[clinic input]
317n/a_blake2b.blake2b.digest
318n/a
319n/aReturn the digest value as a string of binary data.
320n/a[clinic start generated code]*/
321n/a
322n/astatic PyObject *
323n/a_blake2b_blake2b_digest_impl(BLAKE2bObject *self)
324n/a/*[clinic end generated code: output=b13a79360d984740 input=ac2fa462ebb1b9c7]*/
325n/a{
326n/a uint8_t digest[BLAKE2B_OUTBYTES];
327n/a blake2b_state state_cpy;
328n/a
329n/a ENTER_HASHLIB(self);
330n/a state_cpy = self->state;
331n/a blake2b_final(&state_cpy, digest, self->param.digest_length);
332n/a LEAVE_HASHLIB(self);
333n/a return PyBytes_FromStringAndSize((const char *)digest,
334n/a self->param.digest_length);
335n/a}
336n/a
337n/a/*[clinic input]
338n/a_blake2b.blake2b.hexdigest
339n/a
340n/aReturn the digest value as a string of hexadecimal digits.
341n/a[clinic start generated code]*/
342n/a
343n/astatic PyObject *
344n/a_blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self)
345n/a/*[clinic end generated code: output=6a503611715b24bd input=d58f0b2f37812e33]*/
346n/a{
347n/a uint8_t digest[BLAKE2B_OUTBYTES];
348n/a blake2b_state state_cpy;
349n/a
350n/a ENTER_HASHLIB(self);
351n/a state_cpy = self->state;
352n/a blake2b_final(&state_cpy, digest, self->param.digest_length);
353n/a LEAVE_HASHLIB(self);
354n/a return _Py_strhex((const char *)digest, self->param.digest_length);
355n/a}
356n/a
357n/a
358n/astatic PyMethodDef py_blake2b_methods[] = {
359n/a _BLAKE2B_BLAKE2B_COPY_METHODDEF
360n/a _BLAKE2B_BLAKE2B_DIGEST_METHODDEF
361n/a _BLAKE2B_BLAKE2B_HEXDIGEST_METHODDEF
362n/a _BLAKE2B_BLAKE2B_UPDATE_METHODDEF
363n/a {NULL, NULL}
364n/a};
365n/a
366n/a
367n/a
368n/astatic PyObject *
369n/apy_blake2b_get_name(BLAKE2bObject *self, void *closure)
370n/a{
371n/a return PyUnicode_FromString("blake2b");
372n/a}
373n/a
374n/a
375n/a
376n/astatic PyObject *
377n/apy_blake2b_get_block_size(BLAKE2bObject *self, void *closure)
378n/a{
379n/a return PyLong_FromLong(BLAKE2B_BLOCKBYTES);
380n/a}
381n/a
382n/a
383n/a
384n/astatic PyObject *
385n/apy_blake2b_get_digest_size(BLAKE2bObject *self, void *closure)
386n/a{
387n/a return PyLong_FromLong(self->param.digest_length);
388n/a}
389n/a
390n/a
391n/astatic PyGetSetDef py_blake2b_getsetters[] = {
392n/a {"name", (getter)py_blake2b_get_name,
393n/a NULL, NULL, NULL},
394n/a {"block_size", (getter)py_blake2b_get_block_size,
395n/a NULL, NULL, NULL},
396n/a {"digest_size", (getter)py_blake2b_get_digest_size,
397n/a NULL, NULL, NULL},
398n/a {NULL}
399n/a};
400n/a
401n/a
402n/astatic void
403n/apy_blake2b_dealloc(PyObject *self)
404n/a{
405n/a BLAKE2bObject *obj = (BLAKE2bObject *)self;
406n/a
407n/a /* Try not to leave state in memory. */
408n/a secure_zero_memory(&obj->param, sizeof(obj->param));
409n/a secure_zero_memory(&obj->state, sizeof(obj->state));
410n/a#ifdef WITH_THREAD
411n/a if (obj->lock) {
412n/a PyThread_free_lock(obj->lock);
413n/a obj->lock = NULL;
414n/a }
415n/a#endif
416n/a PyObject_Del(self);
417n/a}
418n/a
419n/a
420n/aPyTypeObject PyBlake2_BLAKE2bType = {
421n/a PyVarObject_HEAD_INIT(NULL, 0)
422n/a "_blake2.blake2b", /* tp_name */
423n/a sizeof(BLAKE2bObject), /* tp_size */
424n/a 0, /* tp_itemsize */
425n/a py_blake2b_dealloc, /* tp_dealloc */
426n/a 0, /* tp_print */
427n/a 0, /* tp_getattr */
428n/a 0, /* tp_setattr */
429n/a 0, /* tp_compare */
430n/a 0, /* tp_repr */
431n/a 0, /* tp_as_number */
432n/a 0, /* tp_as_sequence */
433n/a 0, /* tp_as_mapping */
434n/a 0, /* tp_hash */
435n/a 0, /* tp_call */
436n/a 0, /* tp_str */
437n/a 0, /* tp_getattro */
438n/a 0, /* tp_setattro */
439n/a 0, /* tp_as_buffer */
440n/a Py_TPFLAGS_DEFAULT, /* tp_flags */
441n/a py_blake2b_new__doc__, /* tp_doc */
442n/a 0, /* tp_traverse */
443n/a 0, /* tp_clear */
444n/a 0, /* tp_richcompare */
445n/a 0, /* tp_weaklistoffset */
446n/a 0, /* tp_iter */
447n/a 0, /* tp_iternext */
448n/a py_blake2b_methods, /* tp_methods */
449n/a 0, /* tp_members */
450n/a py_blake2b_getsetters, /* tp_getset */
451n/a 0, /* tp_base */
452n/a 0, /* tp_dict */
453n/a 0, /* tp_descr_get */
454n/a 0, /* tp_descr_set */
455n/a 0, /* tp_dictoffset */
456n/a 0, /* tp_init */
457n/a 0, /* tp_alloc */
458n/a py_blake2b_new, /* tp_new */
459n/a};