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 // Prevents undefined behavior via multiple threads entering the C API.
52 bool use_mutex;
53 PyMutex mutex;
54 PyThread_type_lock lock;
55 Hacl_Hash_SHA1_state_t *hash_state;
56 } SHA1object;
57
58 #include "clinic/sha1module.c.h"
59
60
61 typedef struct {
62 PyTypeObject* sha1_type;
63 } SHA1State;
64
65 static inline SHA1State*
sha1_get_state(PyObject * module)66 sha1_get_state(PyObject *module)
67 {
68 void *state = PyModule_GetState(module);
69 assert(state != NULL);
70 return (SHA1State *)state;
71 }
72
73 static SHA1object *
newSHA1object(SHA1State * st)74 newSHA1object(SHA1State *st)
75 {
76 SHA1object *sha = (SHA1object *)PyObject_GC_New(SHA1object, st->sha1_type);
77 if (sha == NULL) {
78 return NULL;
79 }
80 HASHLIB_INIT_MUTEX(sha);
81
82 PyObject_GC_Track(sha);
83 return sha;
84 }
85
86
87 /* Internal methods for a hash object */
88 static int
SHA1_traverse(PyObject * ptr,visitproc visit,void * arg)89 SHA1_traverse(PyObject *ptr, visitproc visit, void *arg)
90 {
91 Py_VISIT(Py_TYPE(ptr));
92 return 0;
93 }
94
95 static void
SHA1_dealloc(SHA1object * ptr)96 SHA1_dealloc(SHA1object *ptr)
97 {
98 Hacl_Hash_SHA1_free(ptr->hash_state);
99 PyTypeObject *tp = Py_TYPE(ptr);
100 PyObject_GC_UnTrack(ptr);
101 PyObject_GC_Del(ptr);
102 Py_DECREF(tp);
103 }
104
105
106 /* External methods for a hash object */
107
108 /*[clinic input]
109 SHA1Type.copy
110
111 cls: defining_class
112
113 Return a copy of the hash object.
114 [clinic start generated code]*/
115
116 static PyObject *
SHA1Type_copy_impl(SHA1object * self,PyTypeObject * cls)117 SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls)
118 /*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/
119 {
120 SHA1State *st = _PyType_GetModuleState(cls);
121
122 SHA1object *newobj;
123 if ((newobj = newSHA1object(st)) == NULL)
124 return NULL;
125
126 ENTER_HASHLIB(self);
127 newobj->hash_state = Hacl_Hash_SHA1_copy(self->hash_state);
128 LEAVE_HASHLIB(self);
129 return (PyObject *)newobj;
130 }
131
132 /*[clinic input]
133 SHA1Type.digest
134
135 Return the digest value as a bytes object.
136 [clinic start generated code]*/
137
138 static PyObject *
SHA1Type_digest_impl(SHA1object * self)139 SHA1Type_digest_impl(SHA1object *self)
140 /*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/
141 {
142 unsigned char digest[SHA1_DIGESTSIZE];
143 ENTER_HASHLIB(self);
144 Hacl_Hash_SHA1_digest(self->hash_state, digest);
145 LEAVE_HASHLIB(self);
146 return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE);
147 }
148
149 /*[clinic input]
150 SHA1Type.hexdigest
151
152 Return the digest value as a string of hexadecimal digits.
153 [clinic start generated code]*/
154
155 static PyObject *
SHA1Type_hexdigest_impl(SHA1object * self)156 SHA1Type_hexdigest_impl(SHA1object *self)
157 /*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/
158 {
159 unsigned char digest[SHA1_DIGESTSIZE];
160 ENTER_HASHLIB(self);
161 Hacl_Hash_SHA1_digest(self->hash_state, digest);
162 LEAVE_HASHLIB(self);
163 return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE);
164 }
165
update(Hacl_Hash_SHA1_state_t * state,uint8_t * buf,Py_ssize_t len)166 static void update(Hacl_Hash_SHA1_state_t *state, uint8_t *buf, Py_ssize_t len) {
167 #if PY_SSIZE_T_MAX > UINT32_MAX
168 while (len > UINT32_MAX) {
169 Hacl_Hash_SHA1_update(state, buf, UINT32_MAX);
170 len -= UINT32_MAX;
171 buf += UINT32_MAX;
172 }
173 #endif
174 Hacl_Hash_SHA1_update(state, buf, (uint32_t) len);
175 }
176
177 /*[clinic input]
178 SHA1Type.update
179
180 obj: object
181 /
182
183 Update this hash object's state with the provided string.
184 [clinic start generated code]*/
185
186 static PyObject *
SHA1Type_update(SHA1object * self,PyObject * obj)187 SHA1Type_update(SHA1object *self, PyObject *obj)
188 /*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/
189 {
190 Py_buffer buf;
191
192 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
193
194 if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) {
195 self->use_mutex = true;
196 }
197 if (self->use_mutex) {
198 Py_BEGIN_ALLOW_THREADS
199 PyMutex_Lock(&self->mutex);
200 update(self->hash_state, buf.buf, buf.len);
201 PyMutex_Unlock(&self->mutex);
202 Py_END_ALLOW_THREADS
203 } else {
204 update(self->hash_state, buf.buf, buf.len);
205 }
206
207 PyBuffer_Release(&buf);
208 Py_RETURN_NONE;
209 }
210
211 static PyMethodDef SHA1_methods[] = {
212 SHA1TYPE_COPY_METHODDEF
213 SHA1TYPE_DIGEST_METHODDEF
214 SHA1TYPE_HEXDIGEST_METHODDEF
215 SHA1TYPE_UPDATE_METHODDEF
216 {NULL, NULL} /* sentinel */
217 };
218
219 static PyObject *
SHA1_get_block_size(PyObject * self,void * closure)220 SHA1_get_block_size(PyObject *self, void *closure)
221 {
222 return PyLong_FromLong(SHA1_BLOCKSIZE);
223 }
224
225 static PyObject *
SHA1_get_name(PyObject * self,void * closure)226 SHA1_get_name(PyObject *self, void *closure)
227 {
228 return PyUnicode_FromStringAndSize("sha1", 4);
229 }
230
231 static PyObject *
sha1_get_digest_size(PyObject * self,void * closure)232 sha1_get_digest_size(PyObject *self, void *closure)
233 {
234 return PyLong_FromLong(SHA1_DIGESTSIZE);
235 }
236
237 static PyGetSetDef SHA1_getseters[] = {
238 {"block_size",
239 (getter)SHA1_get_block_size, NULL,
240 NULL,
241 NULL},
242 {"name",
243 (getter)SHA1_get_name, NULL,
244 NULL,
245 NULL},
246 {"digest_size",
247 (getter)sha1_get_digest_size, NULL,
248 NULL,
249 NULL},
250 {NULL} /* Sentinel */
251 };
252
253 static PyType_Slot sha1_type_slots[] = {
254 {Py_tp_dealloc, SHA1_dealloc},
255 {Py_tp_methods, SHA1_methods},
256 {Py_tp_getset, SHA1_getseters},
257 {Py_tp_traverse, SHA1_traverse},
258 {0,0}
259 };
260
261 static PyType_Spec sha1_type_spec = {
262 .name = "_sha1.sha1",
263 .basicsize = sizeof(SHA1object),
264 .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
265 Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
266 .slots = sha1_type_slots
267 };
268
269 /* The single module-level function: new() */
270
271 /*[clinic input]
272 _sha1.sha1
273
274 string: object(c_default="NULL") = b''
275 *
276 usedforsecurity: bool = True
277
278 Return a new SHA1 hash object; optionally initialized with a string.
279 [clinic start generated code]*/
280
281 static PyObject *
_sha1_sha1_impl(PyObject * module,PyObject * string,int usedforsecurity)282 _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity)
283 /*[clinic end generated code: output=6f8b3af05126e18e input=bd54b68e2bf36a8a]*/
284 {
285 SHA1object *new;
286 Py_buffer buf;
287
288 if (string)
289 GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
290
291 SHA1State *st = sha1_get_state(module);
292 if ((new = newSHA1object(st)) == NULL) {
293 if (string)
294 PyBuffer_Release(&buf);
295 return NULL;
296 }
297
298 new->hash_state = Hacl_Hash_SHA1_malloc();
299
300 if (PyErr_Occurred()) {
301 Py_DECREF(new);
302 if (string)
303 PyBuffer_Release(&buf);
304 return NULL;
305 }
306 if (string) {
307 if (buf.len >= HASHLIB_GIL_MINSIZE) {
308 /* We do not initialize self->lock here as this is the constructor
309 * where it is not yet possible to have concurrent access. */
310 Py_BEGIN_ALLOW_THREADS
311 update(new->hash_state, buf.buf, buf.len);
312 Py_END_ALLOW_THREADS
313 } else {
314 update(new->hash_state, buf.buf, buf.len);
315 }
316 PyBuffer_Release(&buf);
317 }
318
319 return (PyObject *)new;
320 }
321
322
323 /* List of functions exported by this module */
324
325 static struct PyMethodDef SHA1_functions[] = {
326 _SHA1_SHA1_METHODDEF
327 {NULL, NULL} /* Sentinel */
328 };
329
330 static int
_sha1_traverse(PyObject * module,visitproc visit,void * arg)331 _sha1_traverse(PyObject *module, visitproc visit, void *arg)
332 {
333 SHA1State *state = sha1_get_state(module);
334 Py_VISIT(state->sha1_type);
335 return 0;
336 }
337
338 static int
_sha1_clear(PyObject * module)339 _sha1_clear(PyObject *module)
340 {
341 SHA1State *state = sha1_get_state(module);
342 Py_CLEAR(state->sha1_type);
343 return 0;
344 }
345
346 static void
_sha1_free(void * module)347 _sha1_free(void *module)
348 {
349 _sha1_clear((PyObject *)module);
350 }
351
352 static int
_sha1_exec(PyObject * module)353 _sha1_exec(PyObject *module)
354 {
355 SHA1State* st = sha1_get_state(module);
356
357 st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec(
358 module, &sha1_type_spec, NULL);
359 if (PyModule_AddObjectRef(module,
360 "SHA1Type",
361 (PyObject *)st->sha1_type) < 0) {
362 return -1;
363 }
364
365 return 0;
366 }
367
368
369 /* Initialize this module. */
370
371 static PyModuleDef_Slot _sha1_slots[] = {
372 {Py_mod_exec, _sha1_exec},
373 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
374 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
375 {0, NULL}
376 };
377
378 static struct PyModuleDef _sha1module = {
379 PyModuleDef_HEAD_INIT,
380 .m_name = "_sha1",
381 .m_size = sizeof(SHA1State),
382 .m_methods = SHA1_functions,
383 .m_slots = _sha1_slots,
384 .m_traverse = _sha1_traverse,
385 .m_clear = _sha1_clear,
386 .m_free = _sha1_free
387 };
388
389 PyMODINIT_FUNC
PyInit__sha1(void)390 PyInit__sha1(void)
391 {
392 return PyModuleDef_Init(&_sha1module);
393 }
394