Branch data Line data Source code
1 : : /* SHA1 module */
2 : :
3 : : /* This module provides an interface to the SHA1 algorithm */
4 : :
5 : : /* See below for information about the original code this module was
6 : : based upon. Additional work performed by:
7 : :
8 : : Andrew Kuchling (amk@amk.ca)
9 : : Greg Stein (gstein@lyra.org)
10 : : Trevor Perrin (trevp@trevp.net)
11 : :
12 : : Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
13 : : Licensed to PSF under a Contributor Agreement.
14 : :
15 : : */
16 : :
17 : : /* SHA1 objects */
18 : : #ifndef Py_BUILD_CORE_BUILTIN
19 : : # define Py_BUILD_CORE_MODULE 1
20 : : #endif
21 : :
22 : : #include "Python.h"
23 : : #include "hashlib.h"
24 : : #include "pycore_strhex.h" // _Py_strhex()
25 : : #include "pycore_typeobject.h" // _PyType_GetModuleState()
26 : :
27 : : /*[clinic input]
28 : : module _sha1
29 : : class SHA1Type "SHA1object *" "&PyType_Type"
30 : : [clinic start generated code]*/
31 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/
32 : :
33 : : /* Some useful types */
34 : :
35 : : #if SIZEOF_INT == 4
36 : : typedef unsigned int SHA1_INT32; /* 32-bit integer */
37 : : typedef long long SHA1_INT64; /* 64-bit integer */
38 : : #else
39 : : /* not defined. compilation will die. */
40 : : #endif
41 : :
42 : : /* The SHA1 block size and message digest sizes, in bytes */
43 : :
44 : : #define SHA1_BLOCKSIZE 64
45 : : #define SHA1_DIGESTSIZE 20
46 : :
47 : : #include "_hacl/Hacl_Hash_SHA1.h"
48 : :
49 : : typedef struct {
50 : : PyObject_HEAD
51 : :
52 : : Hacl_Streaming_SHA1_state *hash_state;
53 : : } SHA1object;
54 : :
55 : : #include "clinic/sha1module.c.h"
56 : :
57 : :
58 : : typedef struct {
59 : : PyTypeObject* sha1_type;
60 : : } SHA1State;
61 : :
62 : : static inline SHA1State*
63 : 11 : sha1_get_state(PyObject *module)
64 : : {
65 : 11 : void *state = PyModule_GetState(module);
66 : : assert(state != NULL);
67 : 11 : return (SHA1State *)state;
68 : : }
69 : :
70 : : static SHA1object *
71 : 0 : newSHA1object(SHA1State *st)
72 : : {
73 : 0 : SHA1object *sha = (SHA1object *)PyObject_GC_New(SHA1object, st->sha1_type);
74 : 0 : PyObject_GC_Track(sha);
75 : 0 : return sha;
76 : : }
77 : :
78 : :
79 : : /* Internal methods for a hash object */
80 : : static int
81 : 0 : SHA1_traverse(PyObject *ptr, visitproc visit, void *arg)
82 : : {
83 [ # # # # ]: 0 : Py_VISIT(Py_TYPE(ptr));
84 : 0 : return 0;
85 : : }
86 : :
87 : : static void
88 : 0 : SHA1_dealloc(SHA1object *ptr)
89 : : {
90 : 0 : Hacl_Streaming_SHA1_legacy_free(ptr->hash_state);
91 : 0 : PyTypeObject *tp = Py_TYPE(ptr);
92 : 0 : PyObject_GC_UnTrack(ptr);
93 : 0 : PyObject_GC_Del(ptr);
94 : 0 : Py_DECREF(tp);
95 : 0 : }
96 : :
97 : :
98 : : /* External methods for a hash object */
99 : :
100 : : /*[clinic input]
101 : : SHA1Type.copy
102 : :
103 : : cls: defining_class
104 : :
105 : : Return a copy of the hash object.
106 : : [clinic start generated code]*/
107 : :
108 : : static PyObject *
109 : 0 : SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls)
110 : : /*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/
111 : : {
112 : 0 : SHA1State *st = _PyType_GetModuleState(cls);
113 : :
114 : : SHA1object *newobj;
115 [ # # ]: 0 : if ((newobj = newSHA1object(st)) == NULL)
116 : 0 : return NULL;
117 : :
118 : 0 : newobj->hash_state = Hacl_Streaming_SHA1_legacy_copy(self->hash_state);
119 : 0 : return (PyObject *)newobj;
120 : : }
121 : :
122 : : /*[clinic input]
123 : : SHA1Type.digest
124 : :
125 : : Return the digest value as a bytes object.
126 : : [clinic start generated code]*/
127 : :
128 : : static PyObject *
129 : 0 : SHA1Type_digest_impl(SHA1object *self)
130 : : /*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/
131 : : {
132 : : unsigned char digest[SHA1_DIGESTSIZE];
133 : 0 : Hacl_Streaming_SHA1_legacy_finish(self->hash_state, digest);
134 : 0 : return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE);
135 : : }
136 : :
137 : : /*[clinic input]
138 : : SHA1Type.hexdigest
139 : :
140 : : Return the digest value as a string of hexadecimal digits.
141 : : [clinic start generated code]*/
142 : :
143 : : static PyObject *
144 : 0 : SHA1Type_hexdigest_impl(SHA1object *self)
145 : : /*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/
146 : : {
147 : : unsigned char digest[SHA1_DIGESTSIZE];
148 : 0 : Hacl_Streaming_SHA1_legacy_finish(self->hash_state, digest);
149 : 0 : return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE);
150 : : }
151 : :
152 : 0 : static void update(Hacl_Streaming_SHA1_state *state, uint8_t *buf, Py_ssize_t len) {
153 : : #if PY_SSIZE_T_MAX > UINT32_MAX
154 [ # # ]: 0 : while (len > UINT32_MAX) {
155 : 0 : Hacl_Streaming_SHA1_legacy_update(state, buf, UINT32_MAX);
156 : 0 : len -= UINT32_MAX;
157 : 0 : buf += UINT32_MAX;
158 : : }
159 : : #endif
160 : 0 : Hacl_Streaming_SHA1_legacy_update(state, buf, (uint32_t) len);
161 : 0 : }
162 : :
163 : : /*[clinic input]
164 : : SHA1Type.update
165 : :
166 : : obj: object
167 : : /
168 : :
169 : : Update this hash object's state with the provided string.
170 : : [clinic start generated code]*/
171 : :
172 : : static PyObject *
173 : 0 : SHA1Type_update(SHA1object *self, PyObject *obj)
174 : : /*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/
175 : : {
176 : : Py_buffer buf;
177 : :
178 [ # # # # : 0 : GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
# # # # ]
179 : :
180 : 0 : update(self->hash_state, buf.buf, buf.len);
181 : :
182 : 0 : PyBuffer_Release(&buf);
183 : 0 : Py_RETURN_NONE;
184 : : }
185 : :
186 : : static PyMethodDef SHA1_methods[] = {
187 : : SHA1TYPE_COPY_METHODDEF
188 : : SHA1TYPE_DIGEST_METHODDEF
189 : : SHA1TYPE_HEXDIGEST_METHODDEF
190 : : SHA1TYPE_UPDATE_METHODDEF
191 : : {NULL, NULL} /* sentinel */
192 : : };
193 : :
194 : : static PyObject *
195 : 0 : SHA1_get_block_size(PyObject *self, void *closure)
196 : : {
197 : 0 : return PyLong_FromLong(SHA1_BLOCKSIZE);
198 : : }
199 : :
200 : : static PyObject *
201 : 0 : SHA1_get_name(PyObject *self, void *closure)
202 : : {
203 : 0 : return PyUnicode_FromStringAndSize("sha1", 4);
204 : : }
205 : :
206 : : static PyObject *
207 : 0 : sha1_get_digest_size(PyObject *self, void *closure)
208 : : {
209 : 0 : return PyLong_FromLong(SHA1_DIGESTSIZE);
210 : : }
211 : :
212 : : static PyGetSetDef SHA1_getseters[] = {
213 : : {"block_size",
214 : : (getter)SHA1_get_block_size, NULL,
215 : : NULL,
216 : : NULL},
217 : : {"name",
218 : : (getter)SHA1_get_name, NULL,
219 : : NULL,
220 : : NULL},
221 : : {"digest_size",
222 : : (getter)sha1_get_digest_size, NULL,
223 : : NULL,
224 : : NULL},
225 : : {NULL} /* Sentinel */
226 : : };
227 : :
228 : : static PyType_Slot sha1_type_slots[] = {
229 : : {Py_tp_dealloc, SHA1_dealloc},
230 : : {Py_tp_methods, SHA1_methods},
231 : : {Py_tp_getset, SHA1_getseters},
232 : : {Py_tp_traverse, SHA1_traverse},
233 : : {0,0}
234 : : };
235 : :
236 : : static PyType_Spec sha1_type_spec = {
237 : : .name = "_sha1.sha1",
238 : : .basicsize = sizeof(SHA1object),
239 : : .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
240 : : Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
241 : : .slots = sha1_type_slots
242 : : };
243 : :
244 : : /* The single module-level function: new() */
245 : :
246 : : /*[clinic input]
247 : : _sha1.sha1
248 : :
249 : : string: object(c_default="NULL") = b''
250 : : *
251 : : usedforsecurity: bool = True
252 : :
253 : : Return a new SHA1 hash object; optionally initialized with a string.
254 : : [clinic start generated code]*/
255 : :
256 : : static PyObject *
257 : 0 : _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity)
258 : : /*[clinic end generated code: output=6f8b3af05126e18e input=bd54b68e2bf36a8a]*/
259 : : {
260 : : SHA1object *new;
261 : : Py_buffer buf;
262 : :
263 [ # # ]: 0 : if (string)
264 [ # # # # : 0 : GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
# # # # ]
265 : :
266 : 0 : SHA1State *st = sha1_get_state(module);
267 [ # # ]: 0 : if ((new = newSHA1object(st)) == NULL) {
268 [ # # ]: 0 : if (string)
269 : 0 : PyBuffer_Release(&buf);
270 : 0 : return NULL;
271 : : }
272 : :
273 : 0 : new->hash_state = Hacl_Streaming_SHA1_legacy_create_in();
274 : :
275 [ # # ]: 0 : if (PyErr_Occurred()) {
276 : 0 : Py_DECREF(new);
277 [ # # ]: 0 : if (string)
278 : 0 : PyBuffer_Release(&buf);
279 : 0 : return NULL;
280 : : }
281 [ # # ]: 0 : if (string) {
282 : 0 : update(new->hash_state, buf.buf, buf.len);
283 : 0 : PyBuffer_Release(&buf);
284 : : }
285 : :
286 : 0 : return (PyObject *)new;
287 : : }
288 : :
289 : :
290 : : /* List of functions exported by this module */
291 : :
292 : : static struct PyMethodDef SHA1_functions[] = {
293 : : _SHA1_SHA1_METHODDEF
294 : : {NULL, NULL} /* Sentinel */
295 : : };
296 : :
297 : : static int
298 : 8 : _sha1_traverse(PyObject *module, visitproc visit, void *arg)
299 : : {
300 : 8 : SHA1State *state = sha1_get_state(module);
301 [ + - - + ]: 8 : Py_VISIT(state->sha1_type);
302 : 8 : return 0;
303 : : }
304 : :
305 : : static int
306 : 2 : _sha1_clear(PyObject *module)
307 : : {
308 : 2 : SHA1State *state = sha1_get_state(module);
309 [ + + ]: 2 : Py_CLEAR(state->sha1_type);
310 : 2 : return 0;
311 : : }
312 : :
313 : : static void
314 : 1 : _sha1_free(void *module)
315 : : {
316 : 1 : _sha1_clear((PyObject *)module);
317 : 1 : }
318 : :
319 : : static int
320 : 1 : _sha1_exec(PyObject *module)
321 : : {
322 : 1 : SHA1State* st = sha1_get_state(module);
323 : :
324 : 1 : st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec(
325 : : module, &sha1_type_spec, NULL);
326 : :
327 [ - + ]: 1 : if (st->sha1_type == NULL) {
328 : 0 : return -1;
329 : : }
330 : :
331 : 1 : Py_INCREF(st->sha1_type);
332 [ - + ]: 1 : if (PyModule_AddObject(module,
333 : : "SHA1Type",
334 : 1 : (PyObject *)st->sha1_type) < 0) {
335 : 0 : Py_DECREF(st->sha1_type);
336 : 0 : return -1;
337 : : }
338 : :
339 : 1 : return 0;
340 : : }
341 : :
342 : :
343 : : /* Initialize this module. */
344 : :
345 : : static PyModuleDef_Slot _sha1_slots[] = {
346 : : {Py_mod_exec, _sha1_exec},
347 : : {0, NULL}
348 : : };
349 : :
350 : : static struct PyModuleDef _sha1module = {
351 : : PyModuleDef_HEAD_INIT,
352 : : .m_name = "_sha1",
353 : : .m_size = sizeof(SHA1State),
354 : : .m_methods = SHA1_functions,
355 : : .m_slots = _sha1_slots,
356 : : .m_traverse = _sha1_traverse,
357 : : .m_clear = _sha1_clear,
358 : : .m_free = _sha1_free
359 : : };
360 : :
361 : : PyMODINIT_FUNC
362 : 1 : PyInit__sha1(void)
363 : : {
364 : 1 : return PyModuleDef_Init(&_sha1module);
365 : : }
|