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 :
19 : #include "Python.h"
20 : #include "hashlib.h"
21 :
22 :
23 : /* Some useful types */
24 :
25 : #if SIZEOF_INT == 4
26 : typedef unsigned int SHA1_INT32; /* 32-bit integer */
27 : typedef PY_LONG_LONG SHA1_INT64; /* 64-bit integer */
28 : #else
29 : /* not defined. compilation will die. */
30 : #endif
31 :
32 : /* The SHA1 block size and message digest sizes, in bytes */
33 :
34 : #define SHA1_BLOCKSIZE 64
35 : #define SHA1_DIGESTSIZE 20
36 :
37 : /* The structure for storing SHA1 info */
38 :
39 : struct sha1_state {
40 : SHA1_INT64 length;
41 : SHA1_INT32 state[5], curlen;
42 : unsigned char buf[SHA1_BLOCKSIZE];
43 : };
44 :
45 : typedef struct {
46 : PyObject_HEAD
47 :
48 : struct sha1_state hash_state;
49 : } SHA1object;
50 :
51 :
52 : /* ------------------------------------------------------------------------
53 : *
54 : * This code for the SHA1 algorithm was noted as public domain. The
55 : * original headers are pasted below.
56 : *
57 : * Several changes have been made to make it more compatible with the
58 : * Python environment and desired interface.
59 : *
60 : */
61 :
62 : /* LibTomCrypt, modular cryptographic library -- Tom St Denis
63 : *
64 : * LibTomCrypt is a library that provides various cryptographic
65 : * algorithms in a highly modular and flexible manner.
66 : *
67 : * The library is free for all purposes without any express
68 : * guarantee it works.
69 : *
70 : * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
71 : */
72 :
73 : /* rotate the hard way (platform optimizations could be done) */
74 : #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
75 : #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
76 :
77 : /* Endian Neutral macros that work on all platforms */
78 :
79 : #define STORE32H(x, y) \
80 : { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
81 : (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
82 :
83 : #define LOAD32H(x, y) \
84 : { x = ((unsigned long)((y)[0] & 255)<<24) | \
85 : ((unsigned long)((y)[1] & 255)<<16) | \
86 : ((unsigned long)((y)[2] & 255)<<8) | \
87 : ((unsigned long)((y)[3] & 255)); }
88 :
89 : #define STORE64H(x, y) \
90 : { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
91 : (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
92 : (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
93 : (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
94 :
95 : #ifndef MIN
96 : #define MIN(x, y) ( ((x)<(y))?(x):(y) )
97 : #endif
98 :
99 :
100 : /* SHA1 macros */
101 :
102 : #define F0(x,y,z) (z ^ (x & (y ^ z)))
103 : #define F1(x,y,z) (x ^ y ^ z)
104 : #define F2(x,y,z) ((x & y) | (z & (x | y)))
105 : #define F3(x,y,z) (x ^ y ^ z)
106 :
107 0 : static void sha1_compress(struct sha1_state *sha1, unsigned char *buf)
108 : {
109 : SHA1_INT32 a,b,c,d,e,W[80],i;
110 :
111 : /* copy the state into 512-bits into W[0..15] */
112 0 : for (i = 0; i < 16; i++) {
113 0 : LOAD32H(W[i], buf + (4*i));
114 : }
115 :
116 : /* copy state */
117 0 : a = sha1->state[0];
118 0 : b = sha1->state[1];
119 0 : c = sha1->state[2];
120 0 : d = sha1->state[3];
121 0 : e = sha1->state[4];
122 :
123 : /* expand it */
124 0 : for (i = 16; i < 80; i++) {
125 0 : W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
126 : }
127 :
128 : /* compress */
129 : /* round one */
130 : #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);
131 : #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);
132 : #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);
133 : #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);
134 :
135 0 : for (i = 0; i < 20; ) {
136 0 : FF_0(a,b,c,d,e,i++);
137 0 : FF_0(e,a,b,c,d,i++);
138 0 : FF_0(d,e,a,b,c,i++);
139 0 : FF_0(c,d,e,a,b,i++);
140 0 : FF_0(b,c,d,e,a,i++);
141 : }
142 :
143 : /* round two */
144 0 : for (; i < 40; ) {
145 0 : FF_1(a,b,c,d,e,i++);
146 0 : FF_1(e,a,b,c,d,i++);
147 0 : FF_1(d,e,a,b,c,i++);
148 0 : FF_1(c,d,e,a,b,i++);
149 0 : FF_1(b,c,d,e,a,i++);
150 : }
151 :
152 : /* round three */
153 0 : for (; i < 60; ) {
154 0 : FF_2(a,b,c,d,e,i++);
155 0 : FF_2(e,a,b,c,d,i++);
156 0 : FF_2(d,e,a,b,c,i++);
157 0 : FF_2(c,d,e,a,b,i++);
158 0 : FF_2(b,c,d,e,a,i++);
159 : }
160 :
161 : /* round four */
162 0 : for (; i < 80; ) {
163 0 : FF_3(a,b,c,d,e,i++);
164 0 : FF_3(e,a,b,c,d,i++);
165 0 : FF_3(d,e,a,b,c,i++);
166 0 : FF_3(c,d,e,a,b,i++);
167 0 : FF_3(b,c,d,e,a,i++);
168 : }
169 :
170 : #undef FF_0
171 : #undef FF_1
172 : #undef FF_2
173 : #undef FF_3
174 :
175 : /* store */
176 0 : sha1->state[0] = sha1->state[0] + a;
177 0 : sha1->state[1] = sha1->state[1] + b;
178 0 : sha1->state[2] = sha1->state[2] + c;
179 0 : sha1->state[3] = sha1->state[3] + d;
180 0 : sha1->state[4] = sha1->state[4] + e;
181 0 : }
182 :
183 : /**
184 : Initialize the hash state
185 : @param sha1 The hash state you wish to initialize
186 : */
187 : static void
188 0 : sha1_init(struct sha1_state *sha1)
189 : {
190 : assert(sha1 != NULL);
191 0 : sha1->state[0] = 0x67452301UL;
192 0 : sha1->state[1] = 0xefcdab89UL;
193 0 : sha1->state[2] = 0x98badcfeUL;
194 0 : sha1->state[3] = 0x10325476UL;
195 0 : sha1->state[4] = 0xc3d2e1f0UL;
196 0 : sha1->curlen = 0;
197 0 : sha1->length = 0;
198 0 : }
199 :
200 : /**
201 : Process a block of memory though the hash
202 : @param sha1 The hash state
203 : @param in The data to hash
204 : @param inlen The length of the data (octets)
205 : */
206 : static void
207 0 : sha1_process(struct sha1_state *sha1,
208 : const unsigned char *in, Py_ssize_t inlen)
209 : {
210 : Py_ssize_t n;
211 :
212 : assert(sha1 != NULL);
213 : assert(in != NULL);
214 : assert(sha1->curlen <= sizeof(sha1->buf));
215 :
216 0 : while (inlen > 0) {
217 0 : if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) {
218 0 : sha1_compress(sha1, (unsigned char *)in);
219 0 : sha1->length += SHA1_BLOCKSIZE * 8;
220 0 : in += SHA1_BLOCKSIZE;
221 0 : inlen -= SHA1_BLOCKSIZE;
222 : } else {
223 0 : n = MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen));
224 0 : memcpy(sha1->buf + sha1->curlen, in, (size_t)n);
225 0 : sha1->curlen += n;
226 0 : in += n;
227 0 : inlen -= n;
228 0 : if (sha1->curlen == SHA1_BLOCKSIZE) {
229 0 : sha1_compress(sha1, sha1->buf);
230 0 : sha1->length += 8*SHA1_BLOCKSIZE;
231 0 : sha1->curlen = 0;
232 : }
233 : }
234 : }
235 0 : }
236 :
237 : /**
238 : Terminate the hash to get the digest
239 : @param sha1 The hash state
240 : @param out [out] The destination of the hash (20 bytes)
241 : */
242 : static void
243 0 : sha1_done(struct sha1_state *sha1, unsigned char *out)
244 : {
245 : int i;
246 :
247 : assert(sha1 != NULL);
248 : assert(out != NULL);
249 : assert(sha1->curlen < sizeof(sha1->buf));
250 :
251 : /* increase the length of the message */
252 0 : sha1->length += sha1->curlen * 8;
253 :
254 : /* append the '1' bit */
255 0 : sha1->buf[sha1->curlen++] = (unsigned char)0x80;
256 :
257 : /* if the length is currently above 56 bytes we append zeros
258 : * then compress. Then we can fall back to padding zeros and length
259 : * encoding like normal.
260 : */
261 0 : if (sha1->curlen > 56) {
262 0 : while (sha1->curlen < 64) {
263 0 : sha1->buf[sha1->curlen++] = (unsigned char)0;
264 : }
265 0 : sha1_compress(sha1, sha1->buf);
266 0 : sha1->curlen = 0;
267 : }
268 :
269 : /* pad upto 56 bytes of zeroes */
270 0 : while (sha1->curlen < 56) {
271 0 : sha1->buf[sha1->curlen++] = (unsigned char)0;
272 : }
273 :
274 : /* store length */
275 0 : STORE64H(sha1->length, sha1->buf+56);
276 0 : sha1_compress(sha1, sha1->buf);
277 :
278 : /* copy output */
279 0 : for (i = 0; i < 5; i++) {
280 0 : STORE32H(sha1->state[i], out+(4*i));
281 : }
282 0 : }
283 :
284 :
285 : /* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
286 : /* .Revision: 1.10 $ */
287 : /* .Date: 2007/05/12 14:25:28 $ */
288 :
289 : /*
290 : * End of copied SHA1 code.
291 : *
292 : * ------------------------------------------------------------------------
293 : */
294 :
295 : static PyTypeObject SHA1type;
296 :
297 :
298 : static SHA1object *
299 0 : newSHA1object(void)
300 : {
301 0 : return (SHA1object *)PyObject_New(SHA1object, &SHA1type);
302 : }
303 :
304 :
305 : /* Internal methods for a hash object */
306 :
307 : static void
308 0 : SHA1_dealloc(PyObject *ptr)
309 : {
310 0 : PyObject_Del(ptr);
311 0 : }
312 :
313 :
314 : /* External methods for a hash object */
315 :
316 : PyDoc_STRVAR(SHA1_copy__doc__, "Return a copy of the hash object.");
317 :
318 : static PyObject *
319 0 : SHA1_copy(SHA1object *self, PyObject *unused)
320 : {
321 : SHA1object *newobj;
322 :
323 0 : if (Py_TYPE(self) == &SHA1type) {
324 0 : if ( (newobj = newSHA1object())==NULL)
325 0 : return NULL;
326 : } else {
327 0 : if ( (newobj = newSHA1object())==NULL)
328 0 : return NULL;
329 : }
330 :
331 0 : newobj->hash_state = self->hash_state;
332 0 : return (PyObject *)newobj;
333 : }
334 :
335 : PyDoc_STRVAR(SHA1_digest__doc__,
336 : "Return the digest value as a string of binary data.");
337 :
338 : static PyObject *
339 0 : SHA1_digest(SHA1object *self, PyObject *unused)
340 : {
341 : unsigned char digest[SHA1_DIGESTSIZE];
342 : struct sha1_state temp;
343 :
344 0 : temp = self->hash_state;
345 0 : sha1_done(&temp, digest);
346 0 : return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE);
347 : }
348 :
349 : PyDoc_STRVAR(SHA1_hexdigest__doc__,
350 : "Return the digest value as a string of hexadecimal digits.");
351 :
352 : static PyObject *
353 0 : SHA1_hexdigest(SHA1object *self, PyObject *unused)
354 : {
355 : unsigned char digest[SHA1_DIGESTSIZE];
356 : struct sha1_state temp;
357 : PyObject *retval;
358 : Py_UCS1 *hex_digest;
359 : int i, j;
360 :
361 : /* Get the raw (binary) digest value */
362 0 : temp = self->hash_state;
363 0 : sha1_done(&temp, digest);
364 :
365 : /* Create a new string */
366 0 : retval = PyUnicode_New(SHA1_DIGESTSIZE * 2, 127);
367 0 : if (!retval)
368 0 : return NULL;
369 0 : hex_digest = PyUnicode_1BYTE_DATA(retval);
370 :
371 : /* Make hex version of the digest */
372 0 : for(i=j=0; i<SHA1_DIGESTSIZE; i++) {
373 : unsigned char c;
374 0 : c = (digest[i] >> 4) & 0xf;
375 0 : hex_digest[j++] = Py_hexdigits[c];
376 0 : c = (digest[i] & 0xf);
377 0 : hex_digest[j++] = Py_hexdigits[c];
378 : }
379 : assert(_PyUnicode_CheckConsistency(retval, 1));
380 0 : return retval;
381 : }
382 :
383 : PyDoc_STRVAR(SHA1_update__doc__,
384 : "Update this hash object's state with the provided string.");
385 :
386 : static PyObject *
387 0 : SHA1_update(SHA1object *self, PyObject *args)
388 : {
389 : PyObject *obj;
390 : Py_buffer buf;
391 :
392 0 : if (!PyArg_ParseTuple(args, "O:update", &obj))
393 0 : return NULL;
394 :
395 0 : GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
396 :
397 0 : sha1_process(&self->hash_state, buf.buf, buf.len);
398 :
399 0 : PyBuffer_Release(&buf);
400 0 : Py_INCREF(Py_None);
401 0 : return Py_None;
402 : }
403 :
404 : static PyMethodDef SHA1_methods[] = {
405 : {"copy", (PyCFunction)SHA1_copy, METH_NOARGS, SHA1_copy__doc__},
406 : {"digest", (PyCFunction)SHA1_digest, METH_NOARGS, SHA1_digest__doc__},
407 : {"hexdigest", (PyCFunction)SHA1_hexdigest, METH_NOARGS, SHA1_hexdigest__doc__},
408 : {"update", (PyCFunction)SHA1_update, METH_VARARGS, SHA1_update__doc__},
409 : {NULL, NULL} /* sentinel */
410 : };
411 :
412 : static PyObject *
413 0 : SHA1_get_block_size(PyObject *self, void *closure)
414 : {
415 0 : return PyLong_FromLong(SHA1_BLOCKSIZE);
416 : }
417 :
418 : static PyObject *
419 0 : SHA1_get_name(PyObject *self, void *closure)
420 : {
421 0 : return PyUnicode_FromStringAndSize("SHA1", 3);
422 : }
423 :
424 : static PyObject *
425 0 : sha1_get_digest_size(PyObject *self, void *closure)
426 : {
427 0 : return PyLong_FromLong(SHA1_DIGESTSIZE);
428 : }
429 :
430 :
431 : static PyGetSetDef SHA1_getseters[] = {
432 : {"block_size",
433 : (getter)SHA1_get_block_size, NULL,
434 : NULL,
435 : NULL},
436 : {"name",
437 : (getter)SHA1_get_name, NULL,
438 : NULL,
439 : NULL},
440 : {"digest_size",
441 : (getter)sha1_get_digest_size, NULL,
442 : NULL,
443 : NULL},
444 : {NULL} /* Sentinel */
445 : };
446 :
447 : static PyTypeObject SHA1type = {
448 : PyVarObject_HEAD_INIT(NULL, 0)
449 : "_sha1.sha1", /*tp_name*/
450 : sizeof(SHA1object), /*tp_size*/
451 : 0, /*tp_itemsize*/
452 : /* methods */
453 : SHA1_dealloc, /*tp_dealloc*/
454 : 0, /*tp_print*/
455 : 0, /*tp_getattr*/
456 : 0, /*tp_setattr*/
457 : 0, /*tp_reserved*/
458 : 0, /*tp_repr*/
459 : 0, /*tp_as_number*/
460 : 0, /*tp_as_sequence*/
461 : 0, /*tp_as_mapping*/
462 : 0, /*tp_hash*/
463 : 0, /*tp_call*/
464 : 0, /*tp_str*/
465 : 0, /*tp_getattro*/
466 : 0, /*tp_setattro*/
467 : 0, /*tp_as_buffer*/
468 : Py_TPFLAGS_DEFAULT, /*tp_flags*/
469 : 0, /*tp_doc*/
470 : 0, /*tp_traverse*/
471 : 0, /*tp_clear*/
472 : 0, /*tp_richcompare*/
473 : 0, /*tp_weaklistoffset*/
474 : 0, /*tp_iter*/
475 : 0, /*tp_iternext*/
476 : SHA1_methods, /* tp_methods */
477 : NULL, /* tp_members */
478 : SHA1_getseters, /* tp_getset */
479 : };
480 :
481 :
482 : /* The single module-level function: new() */
483 :
484 : PyDoc_STRVAR(SHA1_new__doc__,
485 : "Return a new SHA1 hash object; optionally initialized with a string.");
486 :
487 : static PyObject *
488 0 : SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict)
489 : {
490 : static char *kwlist[] = {"string", NULL};
491 : SHA1object *new;
492 0 : PyObject *data_obj = NULL;
493 : Py_buffer buf;
494 :
495 0 : if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
496 : &data_obj)) {
497 0 : return NULL;
498 : }
499 :
500 0 : if (data_obj)
501 0 : GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
502 :
503 0 : if ((new = newSHA1object()) == NULL) {
504 0 : if (data_obj)
505 0 : PyBuffer_Release(&buf);
506 0 : return NULL;
507 : }
508 :
509 0 : sha1_init(&new->hash_state);
510 :
511 0 : if (PyErr_Occurred()) {
512 0 : Py_DECREF(new);
513 0 : if (data_obj)
514 0 : PyBuffer_Release(&buf);
515 0 : return NULL;
516 : }
517 0 : if (data_obj) {
518 0 : sha1_process(&new->hash_state, buf.buf, buf.len);
519 0 : PyBuffer_Release(&buf);
520 : }
521 :
522 0 : return (PyObject *)new;
523 : }
524 :
525 :
526 : /* List of functions exported by this module */
527 :
528 : static struct PyMethodDef SHA1_functions[] = {
529 : {"sha1",(PyCFunction)SHA1_new, METH_VARARGS|METH_KEYWORDS,SHA1_new__doc__},
530 : {NULL, NULL} /* Sentinel */
531 : };
532 :
533 :
534 : /* Initialize this module. */
535 :
536 : #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
537 :
538 :
539 : static struct PyModuleDef _sha1module = {
540 : PyModuleDef_HEAD_INIT,
541 : "_sha1",
542 : NULL,
543 : -1,
544 : SHA1_functions,
545 : NULL,
546 : NULL,
547 : NULL,
548 : NULL
549 : };
550 :
551 : PyMODINIT_FUNC
552 0 : PyInit__sha1(void)
553 : {
554 0 : Py_TYPE(&SHA1type) = &PyType_Type;
555 0 : if (PyType_Ready(&SHA1type) < 0)
556 0 : return NULL;
557 0 : return PyModule_Create(&_sha1module);
558 : }
|