Branch data Line data Source code
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 : : #ifndef Py_BUILD_CORE_BUILTIN
12 : : # define Py_BUILD_CORE_MODULE 1
13 : : #endif
14 : :
15 : : #include "Python.h"
16 : : #include "blake2module.h"
17 : :
18 : : extern PyType_Spec blake2b_type_spec;
19 : : extern PyType_Spec blake2s_type_spec;
20 : :
21 : : PyDoc_STRVAR(blake2mod__doc__,
22 : : "_blake2b provides BLAKE2b for hashlib\n"
23 : : );
24 : :
25 : : typedef struct {
26 : : PyTypeObject* blake2b_type;
27 : : PyTypeObject* blake2s_type;
28 : : } Blake2State;
29 : :
30 : : static inline Blake2State*
31 : 7050 : blake2_get_state(PyObject *module)
32 : : {
33 : 7050 : void *state = PyModule_GetState(module);
34 : : assert(state != NULL);
35 : 7050 : return (Blake2State *)state;
36 : : }
37 : :
38 : : static struct PyMethodDef blake2mod_functions[] = {
39 : : {NULL, NULL}
40 : : };
41 : :
42 : : static int
43 : 5824 : _blake2_traverse(PyObject *module, visitproc visit, void *arg)
44 : : {
45 : 5824 : Blake2State *state = blake2_get_state(module);
46 [ + + - + ]: 5824 : Py_VISIT(state->blake2b_type);
47 [ + + - + ]: 5824 : Py_VISIT(state->blake2s_type);
48 : 5824 : return 0;
49 : : }
50 : :
51 : : static int
52 : 805 : _blake2_clear(PyObject *module)
53 : : {
54 : 805 : Blake2State *state = blake2_get_state(module);
55 [ + + ]: 805 : Py_CLEAR(state->blake2b_type);
56 [ + + ]: 805 : Py_CLEAR(state->blake2s_type);
57 : 805 : return 0;
58 : : }
59 : :
60 : : static void
61 : 421 : _blake2_free(void *module)
62 : : {
63 : 421 : _blake2_clear((PyObject *)module);
64 : 421 : }
65 : :
66 : : #define ADD_INT(d, name, value) do { \
67 : : PyObject *x = PyLong_FromLong(value); \
68 : : if (!x) \
69 : : return -1; \
70 : : if (PyDict_SetItemString(d, name, x) < 0) { \
71 : : Py_DECREF(x); \
72 : : return -1; \
73 : : } \
74 : : Py_DECREF(x); \
75 : : } while(0)
76 : :
77 : : static int
78 : 421 : blake2_exec(PyObject *m)
79 : : {
80 : 421 : Blake2State* st = blake2_get_state(m);
81 : :
82 : 421 : st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec(
83 : : m, &blake2b_type_spec, NULL);
84 : :
85 [ - + ]: 421 : if (NULL == st->blake2b_type)
86 : 0 : return -1;
87 : : /* BLAKE2b */
88 [ - + ]: 421 : if (PyModule_AddType(m, st->blake2b_type) < 0) {
89 : 0 : return -1;
90 : : }
91 : :
92 : 421 : PyObject *d = st->blake2b_type->tp_dict;
93 [ - + - + ]: 421 : ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES);
94 [ - + - + ]: 421 : ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES);
95 [ - + - + ]: 421 : ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES);
96 [ - + - + ]: 421 : ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES);
97 : :
98 : 421 : PyModule_AddIntConstant(m, "BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES);
99 : 421 : PyModule_AddIntConstant(m, "BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES);
100 : 421 : PyModule_AddIntConstant(m, "BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES);
101 : 421 : PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES);
102 : :
103 : : /* BLAKE2s */
104 : 421 : st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec(
105 : : m, &blake2s_type_spec, NULL);
106 : :
107 [ - + ]: 421 : if (NULL == st->blake2s_type)
108 : 0 : return -1;
109 : :
110 [ - + ]: 421 : if (PyModule_AddType(m, st->blake2s_type) < 0) {
111 : 0 : return -1;
112 : : }
113 : :
114 : 421 : d = st->blake2s_type->tp_dict;
115 [ - + - + ]: 421 : ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES);
116 [ - + - + ]: 421 : ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES);
117 [ - + - + ]: 421 : ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
118 [ - + - + ]: 421 : ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES);
119 : :
120 : 421 : PyModule_AddIntConstant(m, "BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES);
121 : 421 : PyModule_AddIntConstant(m, "BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES);
122 : 421 : PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
123 : 421 : PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES);
124 : :
125 : 421 : return 0;
126 : : }
127 : :
128 : : static PyModuleDef_Slot _blake2_slots[] = {
129 : : {Py_mod_exec, blake2_exec},
130 : : {0, NULL}
131 : : };
132 : :
133 : : static struct PyModuleDef blake2_module = {
134 : : PyModuleDef_HEAD_INIT,
135 : : "_blake2",
136 : : .m_doc = blake2mod__doc__,
137 : : .m_size = sizeof(Blake2State),
138 : : .m_methods = blake2mod_functions,
139 : : .m_slots = _blake2_slots,
140 : : .m_traverse = _blake2_traverse,
141 : : .m_clear = _blake2_clear,
142 : : .m_free = _blake2_free,
143 : : };
144 : :
145 : : PyMODINIT_FUNC
146 : 421 : PyInit__blake2(void)
147 : : {
148 : 421 : return PyModuleDef_Init(&blake2_module);
149 : : }
|