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 ([email protected]) |
9 | Greg Stein ([email protected]) |
10 | Trevor Perrin ([email protected]) |
11 | |
12 | Copyright (C) 2005-2007 Gregory P. Smith ([email protected]) |
13 | Licensed to PSF under a Contributor Agreement. |
14 | |
15 | */ |
16 | |
17 | /* SHA1 objects */ |
18 | |
19 | #include "Python.h" |
20 | #include "hashlib.h" |
21 | #include "pystrhex.h" |
22 | |
23 | /*[clinic input] |
24 | module _sha1 |
25 | class SHA1Type "SHA1object *" "&PyType_Type" |
26 | [clinic start generated code]*/ |
27 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/ |
28 | |
29 | /* Some useful types */ |
30 | |
31 | #if SIZEOF_INT == 4 |
32 | typedef unsigned int SHA1_INT32; /* 32-bit integer */ |
33 | typedef long long SHA1_INT64; /* 64-bit integer */ |
34 | #else |
35 | /* not defined. compilation will die. */ |
36 | #endif |
37 | |
38 | /* The SHA1 block size and message digest sizes, in bytes */ |
39 | |
40 | #define SHA1_BLOCKSIZE 64 |
41 | #define SHA1_DIGESTSIZE 20 |
42 | |
43 | /* The structure for storing SHA1 info */ |
44 | |
45 | struct sha1_state { |
46 | SHA1_INT64 length; |
47 | SHA1_INT32 state[5], curlen; |
48 | unsigned char buf[SHA1_BLOCKSIZE]; |
49 | }; |
50 | |
51 | typedef struct { |
52 | PyObject_HEAD |
53 | |
54 | struct sha1_state hash_state; |
55 | } SHA1object; |
56 | |
57 | #include "clinic/sha1module.c.h" |
58 | |
59 | /* ------------------------------------------------------------------------ |
60 | * |
61 | * This code for the SHA1 algorithm was noted as public domain. The |
62 | * original headers are pasted below. |
63 | * |
64 | * Several changes have been made to make it more compatible with the |
65 | * Python environment and desired interface. |
66 | * |
67 | */ |
68 | |
69 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis |
70 | * |
71 | * LibTomCrypt is a library that provides various cryptographic |
72 | * algorithms in a highly modular and flexible manner. |
73 | * |
74 | * The library is free for all purposes without any express |
75 | * guarantee it works. |
76 | * |
77 | * Tom St Denis, [email protected], https://www.libtom.net |
78 | */ |
79 | |
80 | /* rotate the hard way (platform optimizations could be done) */ |
81 | #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) |
82 | #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) |
83 | |
84 | /* Endian Neutral macros that work on all platforms */ |
85 | |
86 | #define STORE32H(x, y) \ |
87 | { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ |
88 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } |
89 | |
90 | #define LOAD32H(x, y) \ |
91 | { x = ((unsigned long)((y)[0] & 255)<<24) | \ |
92 | ((unsigned long)((y)[1] & 255)<<16) | \ |
93 | ((unsigned long)((y)[2] & 255)<<8) | \ |
94 | ((unsigned long)((y)[3] & 255)); } |
95 | |
96 | #define STORE64H(x, y) \ |
97 | { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ |
98 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ |
99 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ |
100 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } |
101 | |
102 | |
103 | /* SHA1 macros */ |
104 | |
105 | #define F0(x,y,z) (z ^ (x & (y ^ z))) |
106 | #define F1(x,y,z) (x ^ y ^ z) |
107 | #define F2(x,y,z) ((x & y) | (z & (x | y))) |
108 | #define F3(x,y,z) (x ^ y ^ z) |
109 | |
110 | static void sha1_compress(struct sha1_state *sha1, unsigned char *buf) |
111 | { |
112 | SHA1_INT32 a,b,c,d,e,W[80],i; |
113 | |
114 | /* copy the state into 512-bits into W[0..15] */ |
115 | for (i = 0; i < 16; i++) { |
116 | LOAD32H(W[i], buf + (4*i)); |
117 | } |
118 | |
119 | /* copy state */ |
120 | a = sha1->state[0]; |
121 | b = sha1->state[1]; |
122 | c = sha1->state[2]; |
123 | d = sha1->state[3]; |
124 | e = sha1->state[4]; |
125 | |
126 | /* expand it */ |
127 | for (i = 16; i < 80; i++) { |
128 | W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); |
129 | } |
130 | |
131 | /* compress */ |
132 | /* round one */ |
133 | #define FF_0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); |
134 | #define FF_1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); |
135 | #define FF_2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); |
136 | #define FF_3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); |
137 | |
138 | for (i = 0; i < 20; ) { |
139 | FF_0(a,b,c,d,e,i++); |
140 | FF_0(e,a,b,c,d,i++); |
141 | FF_0(d,e,a,b,c,i++); |
142 | FF_0(c,d,e,a,b,i++); |
143 | FF_0(b,c,d,e,a,i++); |
144 | } |
145 | |
146 | /* round two */ |
147 | for (; i < 40; ) { |
148 | FF_1(a,b,c,d,e,i++); |
149 | FF_1(e,a,b,c,d,i++); |
150 | FF_1(d,e,a,b,c,i++); |
151 | FF_1(c,d,e,a,b,i++); |
152 | FF_1(b,c,d,e,a,i++); |
153 | } |
154 | |
155 | /* round three */ |
156 | for (; i < 60; ) { |
157 | FF_2(a,b,c,d,e,i++); |
158 | FF_2(e,a,b,c,d,i++); |
159 | FF_2(d,e,a,b,c,i++); |
160 | FF_2(c,d,e,a,b,i++); |
161 | FF_2(b,c,d,e,a,i++); |
162 | } |
163 | |
164 | /* round four */ |
165 | for (; i < 80; ) { |
166 | FF_3(a,b,c,d,e,i++); |
167 | FF_3(e,a,b,c,d,i++); |
168 | FF_3(d,e,a,b,c,i++); |
169 | FF_3(c,d,e,a,b,i++); |
170 | FF_3(b,c,d,e,a,i++); |
171 | } |
172 | |
173 | #undef FF_0 |
174 | #undef FF_1 |
175 | #undef FF_2 |
176 | #undef FF_3 |
177 | |
178 | /* store */ |
179 | sha1->state[0] = sha1->state[0] + a; |
180 | sha1->state[1] = sha1->state[1] + b; |
181 | sha1->state[2] = sha1->state[2] + c; |
182 | sha1->state[3] = sha1->state[3] + d; |
183 | sha1->state[4] = sha1->state[4] + e; |
184 | } |
185 | |
186 | /** |
187 | Initialize the hash state |
188 | @param sha1 The hash state you wish to initialize |
189 | */ |
190 | static void |
191 | sha1_init(struct sha1_state *sha1) |
192 | { |
193 | assert(sha1 != NULL); |
194 | sha1->state[0] = 0x67452301UL; |
195 | sha1->state[1] = 0xefcdab89UL; |
196 | sha1->state[2] = 0x98badcfeUL; |
197 | sha1->state[3] = 0x10325476UL; |
198 | sha1->state[4] = 0xc3d2e1f0UL; |
199 | sha1->curlen = 0; |
200 | sha1->length = 0; |
201 | } |
202 | |
203 | /** |
204 | Process a block of memory though the hash |
205 | @param sha1 The hash state |
206 | @param in The data to hash |
207 | @param inlen The length of the data (octets) |
208 | */ |
209 | static void |
210 | sha1_process(struct sha1_state *sha1, |
211 | const unsigned char *in, Py_ssize_t inlen) |
212 | { |
213 | Py_ssize_t n; |
214 | |
215 | assert(sha1 != NULL); |
216 | assert(in != NULL); |
217 | assert(sha1->curlen <= sizeof(sha1->buf)); |
218 | |
219 | while (inlen > 0) { |
220 | if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) { |
221 | sha1_compress(sha1, (unsigned char *)in); |
222 | sha1->length += SHA1_BLOCKSIZE * 8; |
223 | in += SHA1_BLOCKSIZE; |
224 | inlen -= SHA1_BLOCKSIZE; |
225 | } else { |
226 | n = Py_MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen)); |
227 | memcpy(sha1->buf + sha1->curlen, in, (size_t)n); |
228 | sha1->curlen += (SHA1_INT32)n; |
229 | in += n; |
230 | inlen -= n; |
231 | if (sha1->curlen == SHA1_BLOCKSIZE) { |
232 | sha1_compress(sha1, sha1->buf); |
233 | sha1->length += 8*SHA1_BLOCKSIZE; |
234 | sha1->curlen = 0; |
235 | } |
236 | } |
237 | } |
238 | } |
239 | |
240 | /** |
241 | Terminate the hash to get the digest |
242 | @param sha1 The hash state |
243 | @param out [out] The destination of the hash (20 bytes) |
244 | */ |
245 | static void |
246 | sha1_done(struct sha1_state *sha1, unsigned char *out) |
247 | { |
248 | int i; |
249 | |
250 | assert(sha1 != NULL); |
251 | assert(out != NULL); |
252 | assert(sha1->curlen < sizeof(sha1->buf)); |
253 | |
254 | /* increase the length of the message */ |
255 | sha1->length += sha1->curlen * 8; |
256 | |
257 | /* append the '1' bit */ |
258 | sha1->buf[sha1->curlen++] = (unsigned char)0x80; |
259 | |
260 | /* if the length is currently above 56 bytes we append zeros |
261 | * then compress. Then we can fall back to padding zeros and length |
262 | * encoding like normal. |
263 | */ |
264 | if (sha1->curlen > 56) { |
265 | while (sha1->curlen < 64) { |
266 | sha1->buf[sha1->curlen++] = (unsigned char)0; |
267 | } |
268 | sha1_compress(sha1, sha1->buf); |
269 | sha1->curlen = 0; |
270 | } |
271 | |
272 | /* pad up to 56 bytes of zeroes */ |
273 | while (sha1->curlen < 56) { |
274 | sha1->buf[sha1->curlen++] = (unsigned char)0; |
275 | } |
276 | |
277 | /* store length */ |
278 | STORE64H(sha1->length, sha1->buf+56); |
279 | sha1_compress(sha1, sha1->buf); |
280 | |
281 | /* copy output */ |
282 | for (i = 0; i < 5; i++) { |
283 | STORE32H(sha1->state[i], out+(4*i)); |
284 | } |
285 | } |
286 | |
287 | |
288 | /* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ |
289 | /* .Revision: 1.10 $ */ |
290 | /* .Date: 2007/05/12 14:25:28 $ */ |
291 | |
292 | /* |
293 | * End of copied SHA1 code. |
294 | * |
295 | * ------------------------------------------------------------------------ |
296 | */ |
297 | |
298 | typedef struct { |
299 | PyTypeObject* sha1_type; |
300 | } SHA1State; |
301 | |
302 | static inline SHA1State* |
303 | sha1_get_state(PyObject *module) |
304 | { |
305 | void *state = PyModule_GetState(module); |
306 | assert(state != NULL); |
307 | return (SHA1State *)state; |
308 | } |
309 | |
310 | static SHA1object * |
311 | newSHA1object(SHA1State *st) |
312 | { |
313 | SHA1object *sha = (SHA1object *)PyObject_GC_New(SHA1object, st->sha1_type); |
314 | PyObject_GC_Track(sha); |
315 | return sha; |
316 | } |
317 | |
318 | |
319 | /* Internal methods for a hash object */ |
320 | static int |
321 | SHA1_traverse(PyObject *ptr, visitproc visit, void *arg) |
322 | { |
323 | Py_VISIT(Py_TYPE(ptr)); |
324 | return 0; |
325 | } |
326 | |
327 | static void |
328 | SHA1_dealloc(PyObject *ptr) |
329 | { |
330 | PyTypeObject *tp = Py_TYPE(ptr); |
331 | PyObject_GC_UnTrack(ptr); |
332 | PyObject_GC_Del(ptr); |
333 | Py_DECREF(tp); |
334 | } |
335 | |
336 | |
337 | /* External methods for a hash object */ |
338 | |
339 | /*[clinic input] |
340 | SHA1Type.copy |
341 | |
342 | cls: defining_class |
343 | |
344 | Return a copy of the hash object. |
345 | [clinic start generated code]*/ |
346 | |
347 | static PyObject * |
348 | SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls) |
349 | /*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/ |
350 | { |
351 | SHA1State *st = PyType_GetModuleState(cls); |
352 | |
353 | SHA1object *newobj; |
354 | if ((newobj = newSHA1object(st)) == NULL) |
355 | return NULL; |
356 | |
357 | newobj->hash_state = self->hash_state; |
358 | return (PyObject *)newobj; |
359 | } |
360 | |
361 | /*[clinic input] |
362 | SHA1Type.digest |
363 | |
364 | Return the digest value as a bytes object. |
365 | [clinic start generated code]*/ |
366 | |
367 | static PyObject * |
368 | SHA1Type_digest_impl(SHA1object *self) |
369 | /*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/ |
370 | { |
371 | unsigned char digest[SHA1_DIGESTSIZE]; |
372 | struct sha1_state temp; |
373 | |
374 | temp = self->hash_state; |
375 | sha1_done(&temp, digest); |
376 | return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); |
377 | } |
378 | |
379 | /*[clinic input] |
380 | SHA1Type.hexdigest |
381 | |
382 | Return the digest value as a string of hexadecimal digits. |
383 | [clinic start generated code]*/ |
384 | |
385 | static PyObject * |
386 | SHA1Type_hexdigest_impl(SHA1object *self) |
387 | /*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/ |
388 | { |
389 | unsigned char digest[SHA1_DIGESTSIZE]; |
390 | struct sha1_state temp; |
391 | |
392 | /* Get the raw (binary) digest value */ |
393 | temp = self->hash_state; |
394 | sha1_done(&temp, digest); |
395 | |
396 | return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE); |
397 | } |
398 | |
399 | /*[clinic input] |
400 | SHA1Type.update |
401 | |
402 | obj: object |
403 | / |
404 | |
405 | Update this hash object's state with the provided string. |
406 | [clinic start generated code]*/ |
407 | |
408 | static PyObject * |
409 | SHA1Type_update(SHA1object *self, PyObject *obj) |
410 | /*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/ |
411 | { |
412 | Py_buffer buf; |
413 | |
414 | GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); |
415 | |
416 | sha1_process(&self->hash_state, buf.buf, buf.len); |
417 | |
418 | PyBuffer_Release(&buf); |
419 | Py_RETURN_NONE; |
420 | } |
421 | |
422 | static PyMethodDef SHA1_methods[] = { |
423 | SHA1TYPE_COPY_METHODDEF |
424 | SHA1TYPE_DIGEST_METHODDEF |
425 | SHA1TYPE_HEXDIGEST_METHODDEF |
426 | SHA1TYPE_UPDATE_METHODDEF |
427 | {NULL, NULL} /* sentinel */ |
428 | }; |
429 | |
430 | static PyObject * |
431 | SHA1_get_block_size(PyObject *self, void *closure) |
432 | { |
433 | return PyLong_FromLong(SHA1_BLOCKSIZE); |
434 | } |
435 | |
436 | static PyObject * |
437 | SHA1_get_name(PyObject *self, void *closure) |
438 | { |
439 | return PyUnicode_FromStringAndSize("sha1" , 4); |
440 | } |
441 | |
442 | static PyObject * |
443 | sha1_get_digest_size(PyObject *self, void *closure) |
444 | { |
445 | return PyLong_FromLong(SHA1_DIGESTSIZE); |
446 | } |
447 | |
448 | static PyGetSetDef SHA1_getseters[] = { |
449 | {"block_size" , |
450 | (getter)SHA1_get_block_size, NULL, |
451 | NULL, |
452 | NULL}, |
453 | {"name" , |
454 | (getter)SHA1_get_name, NULL, |
455 | NULL, |
456 | NULL}, |
457 | {"digest_size" , |
458 | (getter)sha1_get_digest_size, NULL, |
459 | NULL, |
460 | NULL}, |
461 | {NULL} /* Sentinel */ |
462 | }; |
463 | |
464 | static PyType_Slot sha1_type_slots[] = { |
465 | {Py_tp_dealloc, SHA1_dealloc}, |
466 | {Py_tp_methods, SHA1_methods}, |
467 | {Py_tp_getset, SHA1_getseters}, |
468 | {Py_tp_traverse, SHA1_traverse}, |
469 | {0,0} |
470 | }; |
471 | |
472 | static PyType_Spec sha1_type_spec = { |
473 | .name = "_sha1.sha1" , |
474 | .basicsize = sizeof(SHA1object), |
475 | .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | |
476 | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), |
477 | .slots = sha1_type_slots |
478 | }; |
479 | |
480 | /* The single module-level function: new() */ |
481 | |
482 | /*[clinic input] |
483 | _sha1.sha1 |
484 | |
485 | string: object(c_default="NULL") = b'' |
486 | * |
487 | usedforsecurity: bool = True |
488 | |
489 | Return a new SHA1 hash object; optionally initialized with a string. |
490 | [clinic start generated code]*/ |
491 | |
492 | static PyObject * |
493 | _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) |
494 | /*[clinic end generated code: output=6f8b3af05126e18e input=bd54b68e2bf36a8a]*/ |
495 | { |
496 | SHA1object *new; |
497 | Py_buffer buf; |
498 | |
499 | if (string) |
500 | GET_BUFFER_VIEW_OR_ERROUT(string, &buf); |
501 | |
502 | SHA1State *st = sha1_get_state(module); |
503 | if ((new = newSHA1object(st)) == NULL) { |
504 | if (string) |
505 | PyBuffer_Release(&buf); |
506 | return NULL; |
507 | } |
508 | |
509 | sha1_init(&new->hash_state); |
510 | |
511 | if (PyErr_Occurred()) { |
512 | Py_DECREF(new); |
513 | if (string) |
514 | PyBuffer_Release(&buf); |
515 | return NULL; |
516 | } |
517 | if (string) { |
518 | sha1_process(&new->hash_state, buf.buf, buf.len); |
519 | PyBuffer_Release(&buf); |
520 | } |
521 | |
522 | return (PyObject *)new; |
523 | } |
524 | |
525 | |
526 | /* List of functions exported by this module */ |
527 | |
528 | static struct PyMethodDef SHA1_functions[] = { |
529 | _SHA1_SHA1_METHODDEF |
530 | {NULL, NULL} /* Sentinel */ |
531 | }; |
532 | |
533 | static int |
534 | _sha1_traverse(PyObject *module, visitproc visit, void *arg) |
535 | { |
536 | SHA1State *state = sha1_get_state(module); |
537 | Py_VISIT(state->sha1_type); |
538 | return 0; |
539 | } |
540 | |
541 | static int |
542 | _sha1_clear(PyObject *module) |
543 | { |
544 | SHA1State *state = sha1_get_state(module); |
545 | Py_CLEAR(state->sha1_type); |
546 | return 0; |
547 | } |
548 | |
549 | static void |
550 | _sha1_free(void *module) |
551 | { |
552 | _sha1_clear((PyObject *)module); |
553 | } |
554 | |
555 | static int |
556 | _sha1_exec(PyObject *module) |
557 | { |
558 | SHA1State* st = sha1_get_state(module); |
559 | |
560 | st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec( |
561 | module, &sha1_type_spec, NULL); |
562 | |
563 | if (st->sha1_type == NULL) { |
564 | return -1; |
565 | } |
566 | |
567 | Py_INCREF(st->sha1_type); |
568 | if (PyModule_AddObject(module, |
569 | "SHA1Type" , |
570 | (PyObject *)st->sha1_type) < 0) { |
571 | Py_DECREF(st->sha1_type); |
572 | return -1; |
573 | } |
574 | |
575 | return 0; |
576 | } |
577 | |
578 | |
579 | /* Initialize this module. */ |
580 | |
581 | static PyModuleDef_Slot _sha1_slots[] = { |
582 | {Py_mod_exec, _sha1_exec}, |
583 | {0, NULL} |
584 | }; |
585 | |
586 | static struct PyModuleDef _sha1module = { |
587 | PyModuleDef_HEAD_INIT, |
588 | .m_name = "_sha1" , |
589 | .m_size = sizeof(SHA1State), |
590 | .m_methods = SHA1_functions, |
591 | .m_slots = _sha1_slots, |
592 | .m_traverse = _sha1_traverse, |
593 | .m_clear = _sha1_clear, |
594 | .m_free = _sha1_free |
595 | }; |
596 | |
597 | PyMODINIT_FUNC |
598 | PyInit__sha1(void) |
599 | { |
600 | return PyModuleDef_Init(&_sha1module); |
601 | } |
602 | |