• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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