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