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