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