• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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*
blake2_get_state(PyObject * module)31 blake2_get_state(PyObject *module)
32 {
33     void *state = PyModule_GetState(module);
34     assert(state != NULL);
35     return (Blake2State *)state;
36 }
37 
38 static struct PyMethodDef blake2mod_functions[] = {
39     {NULL, NULL}
40 };
41 
42 static int
_blake2_traverse(PyObject * module,visitproc visit,void * arg)43 _blake2_traverse(PyObject *module, visitproc visit, void *arg)
44 {
45     Blake2State *state = blake2_get_state(module);
46     Py_VISIT(state->blake2b_type);
47     Py_VISIT(state->blake2s_type);
48     return 0;
49 }
50 
51 static int
_blake2_clear(PyObject * module)52 _blake2_clear(PyObject *module)
53 {
54     Blake2State *state = blake2_get_state(module);
55     Py_CLEAR(state->blake2b_type);
56     Py_CLEAR(state->blake2s_type);
57     return 0;
58 }
59 
60 static void
_blake2_free(void * module)61 _blake2_free(void *module)
62 {
63     _blake2_clear((PyObject *)module);
64 }
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 #define ADD_INT_CONST(NAME, VALUE) do { \
78     if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \
79         return -1; \
80     } \
81 } while (0)
82 
83 static int
blake2_exec(PyObject * m)84 blake2_exec(PyObject *m)
85 {
86     Blake2State* st = blake2_get_state(m);
87 
88     st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec(
89         m, &blake2b_type_spec, NULL);
90 
91     if (NULL == st->blake2b_type)
92         return -1;
93     /* BLAKE2b */
94     if (PyModule_AddType(m, st->blake2b_type) < 0) {
95         return -1;
96     }
97 
98     PyObject *d = st->blake2b_type->tp_dict;
99     ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES);
100     ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES);
101     ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES);
102     ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES);
103 
104     ADD_INT_CONST("BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES);
105     ADD_INT_CONST("BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES);
106     ADD_INT_CONST("BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES);
107     ADD_INT_CONST("BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES);
108 
109     /* BLAKE2s */
110     st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec(
111         m, &blake2s_type_spec, NULL);
112 
113     if (NULL == st->blake2s_type)
114         return -1;
115 
116     if (PyModule_AddType(m, st->blake2s_type) < 0) {
117         return -1;
118     }
119 
120     d = st->blake2s_type->tp_dict;
121     ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES);
122     ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES);
123     ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
124     ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES);
125 
126     ADD_INT_CONST("BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES);
127     ADD_INT_CONST("BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES);
128     ADD_INT_CONST("BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
129     ADD_INT_CONST("BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES);
130 
131     return 0;
132 }
133 
134 #undef ADD_INT
135 #undef ADD_INT_CONST
136 
137 static PyModuleDef_Slot _blake2_slots[] = {
138     {Py_mod_exec, blake2_exec},
139     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
140     {Py_mod_gil, Py_MOD_GIL_NOT_USED},
141     {0, NULL}
142 };
143 
144 static struct PyModuleDef blake2_module = {
145     PyModuleDef_HEAD_INIT,
146     "_blake2",
147     .m_doc = blake2mod__doc__,
148     .m_size = sizeof(Blake2State),
149     .m_methods = blake2mod_functions,
150     .m_slots = _blake2_slots,
151     .m_traverse = _blake2_traverse,
152     .m_clear = _blake2_clear,
153     .m_free = _blake2_free,
154 };
155 
156 PyMODINIT_FUNC
PyInit__blake2(void)157 PyInit__blake2(void)
158 {
159     return PyModuleDef_Init(&blake2_module);
160 }
161