blob: 5cb3d36c9b09c21ffd844751da04fc79a8c3a319 [file] [log] [blame]
Gregory P. Smith2f21eb32007-09-09 06:44:34 +00001/* MD5 module */
2
3/* This module provides an interface to the MD5 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/* MD5 objects */
18
19#include "Python.h"
Gregory P. Smith365a1862009-02-12 07:35:29 +000020#include "hashlib.h"
Gregory P. Smith2f21eb32007-09-09 06:44:34 +000021
22
23/* Some useful types */
24
25#if SIZEOF_INT == 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026typedef unsigned int MD5_INT32; /* 32-bit integer */
27typedef PY_LONG_LONG MD5_INT64; /* 64-bit integer */
Gregory P. Smith2f21eb32007-09-09 06:44:34 +000028#else
29/* not defined. compilation will die. */
30#endif
31
32/* The MD5 block size and message digest sizes, in bytes */
33
34#define MD5_BLOCKSIZE 64
35#define MD5_DIGESTSIZE 16
36
37/* The structure for storing MD5 info */
38
39struct md5_state {
40 MD5_INT64 length;
41 MD5_INT32 state[4], curlen;
42 unsigned char buf[MD5_BLOCKSIZE];
43};
44
45typedef struct {
46 PyObject_HEAD
47
48 struct md5_state hash_state;
49} MD5object;
50
51
52/* ------------------------------------------------------------------------
53 *
54 * This code for the MD5 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 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 STORE32L(x, y) \
79 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
80 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
81
82#define LOAD32L(x, y) \
83 { x = ((unsigned long)((y)[3] & 255)<<24) | \
84 ((unsigned long)((y)[2] & 255)<<16) | \
85 ((unsigned long)((y)[1] & 255)<<8) | \
86 ((unsigned long)((y)[0] & 255)); }
87
88#define STORE64L(x, y) \
89 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
90 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
91 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
92 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
93
Gregory P. Smith2f21eb32007-09-09 06:44:34 +000094
95/* MD5 macros */
96
97#define F(x,y,z) (z ^ (x & (y ^ z)))
98#define G(x,y,z) (y ^ (z & (y ^ x)))
99#define H(x,y,z) (x^y^z)
100#define I(x,y,z) (y^(x|(~z)))
101
102#define FF(a,b,c,d,M,s,t) \
103 a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
104
105#define GG(a,b,c,d,M,s,t) \
106 a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
107
108#define HH(a,b,c,d,M,s,t) \
109 a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
110
111#define II(a,b,c,d,M,s,t) \
112 a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
113
114
115static void md5_compress(struct md5_state *md5, unsigned char *buf)
116{
117 MD5_INT32 i, W[16], a, b, c, d;
118
119 assert(md5 != NULL);
120 assert(buf != NULL);
121
122 /* copy the state into 512-bits into W[0..15] */
123 for (i = 0; i < 16; i++) {
124 LOAD32L(W[i], buf + (4*i));
125 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000127 /* copy state */
128 a = md5->state[0];
129 b = md5->state[1];
130 c = md5->state[2];
131 d = md5->state[3];
132
133 FF(a,b,c,d,W[0],7,0xd76aa478UL)
134 FF(d,a,b,c,W[1],12,0xe8c7b756UL)
135 FF(c,d,a,b,W[2],17,0x242070dbUL)
136 FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
137 FF(a,b,c,d,W[4],7,0xf57c0fafUL)
138 FF(d,a,b,c,W[5],12,0x4787c62aUL)
139 FF(c,d,a,b,W[6],17,0xa8304613UL)
140 FF(b,c,d,a,W[7],22,0xfd469501UL)
141 FF(a,b,c,d,W[8],7,0x698098d8UL)
142 FF(d,a,b,c,W[9],12,0x8b44f7afUL)
143 FF(c,d,a,b,W[10],17,0xffff5bb1UL)
144 FF(b,c,d,a,W[11],22,0x895cd7beUL)
145 FF(a,b,c,d,W[12],7,0x6b901122UL)
146 FF(d,a,b,c,W[13],12,0xfd987193UL)
147 FF(c,d,a,b,W[14],17,0xa679438eUL)
148 FF(b,c,d,a,W[15],22,0x49b40821UL)
149 GG(a,b,c,d,W[1],5,0xf61e2562UL)
150 GG(d,a,b,c,W[6],9,0xc040b340UL)
151 GG(c,d,a,b,W[11],14,0x265e5a51UL)
152 GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
153 GG(a,b,c,d,W[5],5,0xd62f105dUL)
154 GG(d,a,b,c,W[10],9,0x02441453UL)
155 GG(c,d,a,b,W[15],14,0xd8a1e681UL)
156 GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
157 GG(a,b,c,d,W[9],5,0x21e1cde6UL)
158 GG(d,a,b,c,W[14],9,0xc33707d6UL)
159 GG(c,d,a,b,W[3],14,0xf4d50d87UL)
160 GG(b,c,d,a,W[8],20,0x455a14edUL)
161 GG(a,b,c,d,W[13],5,0xa9e3e905UL)
162 GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
163 GG(c,d,a,b,W[7],14,0x676f02d9UL)
164 GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
165 HH(a,b,c,d,W[5],4,0xfffa3942UL)
166 HH(d,a,b,c,W[8],11,0x8771f681UL)
167 HH(c,d,a,b,W[11],16,0x6d9d6122UL)
168 HH(b,c,d,a,W[14],23,0xfde5380cUL)
169 HH(a,b,c,d,W[1],4,0xa4beea44UL)
170 HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
171 HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
172 HH(b,c,d,a,W[10],23,0xbebfbc70UL)
173 HH(a,b,c,d,W[13],4,0x289b7ec6UL)
174 HH(d,a,b,c,W[0],11,0xeaa127faUL)
175 HH(c,d,a,b,W[3],16,0xd4ef3085UL)
176 HH(b,c,d,a,W[6],23,0x04881d05UL)
177 HH(a,b,c,d,W[9],4,0xd9d4d039UL)
178 HH(d,a,b,c,W[12],11,0xe6db99e5UL)
179 HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
180 HH(b,c,d,a,W[2],23,0xc4ac5665UL)
181 II(a,b,c,d,W[0],6,0xf4292244UL)
182 II(d,a,b,c,W[7],10,0x432aff97UL)
183 II(c,d,a,b,W[14],15,0xab9423a7UL)
184 II(b,c,d,a,W[5],21,0xfc93a039UL)
185 II(a,b,c,d,W[12],6,0x655b59c3UL)
186 II(d,a,b,c,W[3],10,0x8f0ccc92UL)
187 II(c,d,a,b,W[10],15,0xffeff47dUL)
188 II(b,c,d,a,W[1],21,0x85845dd1UL)
189 II(a,b,c,d,W[8],6,0x6fa87e4fUL)
190 II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
191 II(c,d,a,b,W[6],15,0xa3014314UL)
192 II(b,c,d,a,W[13],21,0x4e0811a1UL)
193 II(a,b,c,d,W[4],6,0xf7537e82UL)
194 II(d,a,b,c,W[11],10,0xbd3af235UL)
195 II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
196 II(b,c,d,a,W[9],21,0xeb86d391UL)
197
198 md5->state[0] = md5->state[0] + a;
199 md5->state[1] = md5->state[1] + b;
200 md5->state[2] = md5->state[2] + c;
201 md5->state[3] = md5->state[3] + d;
202}
203
204
205/**
206 Initialize the hash state
207 @param sha1 The hash state you wish to initialize
208*/
doko@ubuntu.comc2b46732012-06-21 17:26:06 +0200209static void
210md5_init(struct md5_state *md5)
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000211{
212 assert(md5 != NULL);
213 md5->state[0] = 0x67452301UL;
214 md5->state[1] = 0xefcdab89UL;
215 md5->state[2] = 0x98badcfeUL;
216 md5->state[3] = 0x10325476UL;
217 md5->curlen = 0;
218 md5->length = 0;
219}
220
221/**
222 Process a block of memory though the hash
223 @param sha1 The hash state
224 @param in The data to hash
225 @param inlen The length of the data (octets)
226*/
doko@ubuntu.comc2b46732012-06-21 17:26:06 +0200227static void
228md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen)
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000229{
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000230 Py_ssize_t n;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000231
232 assert(md5 != NULL);
233 assert(in != NULL);
234 assert(md5->curlen <= sizeof(md5->buf));
235
236 while (inlen > 0) {
237 if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) {
238 md5_compress(md5, (unsigned char *)in);
239 md5->length += MD5_BLOCKSIZE * 8;
240 in += MD5_BLOCKSIZE;
241 inlen -= MD5_BLOCKSIZE;
242 } else {
Victor Stinner640c35c2013-06-04 23:14:37 +0200243 n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen));
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000244 memcpy(md5->buf + md5->curlen, in, (size_t)n);
Victor Stinner56cb1252012-10-31 00:33:57 +0100245 md5->curlen += (MD5_INT32)n;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000246 in += n;
247 inlen -= n;
248 if (md5->curlen == MD5_BLOCKSIZE) {
249 md5_compress(md5, md5->buf);
250 md5->length += 8*MD5_BLOCKSIZE;
251 md5->curlen = 0;
252 }
253 }
254 }
255}
256
257/**
258 Terminate the hash to get the digest
259 @param sha1 The hash state
260 @param out [out] The destination of the hash (16 bytes)
261*/
doko@ubuntu.comc2b46732012-06-21 17:26:06 +0200262static void
263md5_done(struct md5_state *md5, unsigned char *out)
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000264{
265 int i;
266
267 assert(md5 != NULL);
268 assert(out != NULL);
269 assert(md5->curlen < sizeof(md5->buf));
270
271 /* increase the length of the message */
272 md5->length += md5->curlen * 8;
273
274 /* append the '1' bit */
275 md5->buf[md5->curlen++] = (unsigned char)0x80;
276
277 /* if the length is currently above 56 bytes we append zeros
278 * then compress. Then we can fall back to padding zeros and length
279 * encoding like normal.
280 */
281 if (md5->curlen > 56) {
282 while (md5->curlen < 64) {
283 md5->buf[md5->curlen++] = (unsigned char)0;
284 }
285 md5_compress(md5, md5->buf);
286 md5->curlen = 0;
287 }
288
289 /* pad upto 56 bytes of zeroes */
290 while (md5->curlen < 56) {
291 md5->buf[md5->curlen++] = (unsigned char)0;
292 }
293
294 /* store length */
295 STORE64L(md5->length, md5->buf+56);
296 md5_compress(md5, md5->buf);
297
298 /* copy output */
299 for (i = 0; i < 4; i++) {
300 STORE32L(md5->state[i], out+(4*i));
301 }
302}
303
304/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */
305/* .Revision: 1.10 $ */
306/* .Date: 2007/05/12 14:25:28 $ */
307
308/*
309 * End of copied MD5 code.
310 *
311 * ------------------------------------------------------------------------
312 */
313
314static PyTypeObject MD5type;
315
316
317static MD5object *
318newMD5object(void)
319{
320 return (MD5object *)PyObject_New(MD5object, &MD5type);
321}
322
323
324/* Internal methods for a hash object */
325
326static void
327MD5_dealloc(PyObject *ptr)
328{
329 PyObject_Del(ptr);
330}
331
332
333/* External methods for a hash object */
334
335PyDoc_STRVAR(MD5_copy__doc__, "Return a copy of the hash object.");
336
337static PyObject *
338MD5_copy(MD5object *self, PyObject *unused)
339{
340 MD5object *newobj;
341
Christian Heimes90aa7642007-12-19 02:45:37 +0000342 if (Py_TYPE(self) == &MD5type) {
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000343 if ( (newobj = newMD5object())==NULL)
344 return NULL;
345 } else {
346 if ( (newobj = newMD5object())==NULL)
347 return NULL;
348 }
349
350 newobj->hash_state = self->hash_state;
351 return (PyObject *)newobj;
352}
353
354PyDoc_STRVAR(MD5_digest__doc__,
355"Return the digest value as a string of binary data.");
356
357static PyObject *
358MD5_digest(MD5object *self, PyObject *unused)
359{
360 unsigned char digest[MD5_DIGESTSIZE];
361 struct md5_state temp;
362
363 temp = self->hash_state;
364 md5_done(&temp, digest);
Christian Heimes72b710a2008-05-26 13:28:38 +0000365 return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000366}
367
368PyDoc_STRVAR(MD5_hexdigest__doc__,
369"Return the digest value as a string of hexadecimal digits.");
370
371static PyObject *
372MD5_hexdigest(MD5object *self, PyObject *unused)
373{
374 unsigned char digest[MD5_DIGESTSIZE];
375 struct md5_state temp;
376 PyObject *retval;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200377 Py_UCS1 *hex_digest;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000378 int i, j;
379
380 /* Get the raw (binary) digest value */
381 temp = self->hash_state;
382 md5_done(&temp, digest);
383
384 /* Create a new string */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200385 retval = PyUnicode_New(MD5_DIGESTSIZE * 2, 127);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000386 if (!retval)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200388 hex_digest = PyUnicode_1BYTE_DATA(retval);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000389
390 /* Make hex version of the digest */
391 for(i=j=0; i<MD5_DIGESTSIZE; i++) {
Victor Stinnerf5cff562011-10-14 02:13:11 +0200392 unsigned char c;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000393 c = (digest[i] >> 4) & 0xf;
Victor Stinnerf5cff562011-10-14 02:13:11 +0200394 hex_digest[j++] = Py_hexdigits[c];
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000395 c = (digest[i] & 0xf);
Victor Stinnerf5cff562011-10-14 02:13:11 +0200396 hex_digest[j++] = Py_hexdigits[c];
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000397 }
Christian Heimesf402e922013-01-03 09:21:55 +0100398#ifdef Py_DEBUG
Victor Stinner8f825062012-04-27 13:55:39 +0200399 assert(_PyUnicode_CheckConsistency(retval, 1));
Christian Heimesf402e922013-01-03 09:21:55 +0100400#endif
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000401 return retval;
402}
403
404PyDoc_STRVAR(MD5_update__doc__,
405"Update this hash object's state with the provided string.");
406
407static PyObject *
408MD5_update(MD5object *self, PyObject *args)
409{
Gregory P. Smith365a1862009-02-12 07:35:29 +0000410 PyObject *obj;
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000411 Py_buffer buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412
Gregory P. Smith365a1862009-02-12 07:35:29 +0000413 if (!PyArg_ParseTuple(args, "O:update", &obj))
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000414 return NULL;
415
Gregory P. Smith365a1862009-02-12 07:35:29 +0000416 GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
417
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000418 md5_process(&self->hash_state, buf.buf, buf.len);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000419
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000420 PyBuffer_Release(&buf);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000421 Py_INCREF(Py_None);
422 return Py_None;
423}
424
425static PyMethodDef MD5_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 {"copy", (PyCFunction)MD5_copy, METH_NOARGS, MD5_copy__doc__},
427 {"digest", (PyCFunction)MD5_digest, METH_NOARGS, MD5_digest__doc__},
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000428 {"hexdigest", (PyCFunction)MD5_hexdigest, METH_NOARGS, MD5_hexdigest__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 {"update", (PyCFunction)MD5_update, METH_VARARGS, MD5_update__doc__},
430 {NULL, NULL} /* sentinel */
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000431};
432
433static PyObject *
434MD5_get_block_size(PyObject *self, void *closure)
435{
Christian Heimes217cfd12007-12-02 14:31:20 +0000436 return PyLong_FromLong(MD5_BLOCKSIZE);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000437}
438
439static PyObject *
440MD5_get_name(PyObject *self, void *closure)
441{
Christian Heimes37d5ceb2013-08-15 18:31:48 +0200442 return PyUnicode_FromStringAndSize("md5", 3);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000443}
444
445static PyObject *
446md5_get_digest_size(PyObject *self, void *closure)
447{
Christian Heimes217cfd12007-12-02 14:31:20 +0000448 return PyLong_FromLong(MD5_DIGESTSIZE);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000449}
450
451
452static PyGetSetDef MD5_getseters[] = {
453 {"block_size",
454 (getter)MD5_get_block_size, NULL,
455 NULL,
456 NULL},
457 {"name",
458 (getter)MD5_get_name, NULL,
459 NULL,
460 NULL},
461 {"digest_size",
462 (getter)md5_get_digest_size, NULL,
463 NULL,
464 NULL},
465 {NULL} /* Sentinel */
466};
467
468static PyTypeObject MD5type = {
469 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 "_md5.md5", /*tp_name*/
471 sizeof(MD5object), /*tp_size*/
472 0, /*tp_itemsize*/
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000473 /* methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 MD5_dealloc, /*tp_dealloc*/
475 0, /*tp_print*/
476 0, /*tp_getattr*/
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000477 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000478 0, /*tp_reserved*/
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000479 0, /*tp_repr*/
480 0, /*tp_as_number*/
481 0, /*tp_as_sequence*/
482 0, /*tp_as_mapping*/
483 0, /*tp_hash*/
484 0, /*tp_call*/
485 0, /*tp_str*/
486 0, /*tp_getattro*/
487 0, /*tp_setattro*/
488 0, /*tp_as_buffer*/
489 Py_TPFLAGS_DEFAULT, /*tp_flags*/
490 0, /*tp_doc*/
491 0, /*tp_traverse*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 0, /*tp_clear*/
493 0, /*tp_richcompare*/
494 0, /*tp_weaklistoffset*/
495 0, /*tp_iter*/
496 0, /*tp_iternext*/
497 MD5_methods, /* tp_methods */
498 NULL, /* tp_members */
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000499 MD5_getseters, /* tp_getset */
500};
501
502
503/* The single module-level function: new() */
504
505PyDoc_STRVAR(MD5_new__doc__,
506"Return a new MD5 hash object; optionally initialized with a string.");
507
508static PyObject *
509MD5_new(PyObject *self, PyObject *args, PyObject *kwdict)
510{
511 static char *kwlist[] = {"string", NULL};
512 MD5object *new;
Gregory P. Smith365a1862009-02-12 07:35:29 +0000513 PyObject *data_obj = NULL;
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000514 Py_buffer buf;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000515
Gregory P. Smith365a1862009-02-12 07:35:29 +0000516 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist,
517 &data_obj)) {
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000518 return NULL;
519 }
520
Gregory P. Smith365a1862009-02-12 07:35:29 +0000521 if (data_obj)
522 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf);
523
Hirokazu Yamamoto84047492009-03-03 07:49:01 +0000524 if ((new = newMD5object()) == NULL) {
525 if (data_obj)
526 PyBuffer_Release(&buf);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000527 return NULL;
Hirokazu Yamamoto84047492009-03-03 07:49:01 +0000528 }
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000529
530 md5_init(&new->hash_state);
531
532 if (PyErr_Occurred()) {
533 Py_DECREF(new);
Hirokazu Yamamoto84047492009-03-03 07:49:01 +0000534 if (data_obj)
535 PyBuffer_Release(&buf);
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000536 return NULL;
537 }
Gregory P. Smith365a1862009-02-12 07:35:29 +0000538 if (data_obj) {
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000539 md5_process(&new->hash_state, buf.buf, buf.len);
Hirokazu Yamamoto84047492009-03-03 07:49:01 +0000540 PyBuffer_Release(&buf);
Martin v. Löwis7b9cb252008-08-14 15:52:23 +0000541 }
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000542
543 return (PyObject *)new;
544}
545
546
547/* List of functions exported by this module */
548
549static struct PyMethodDef MD5_functions[] = {
550 {"md5", (PyCFunction)MD5_new, METH_VARARGS|METH_KEYWORDS, MD5_new__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 {NULL, NULL} /* Sentinel */
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000552};
553
554
555/* Initialize this module. */
556
557#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
558
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000559
Martin v. Löwis1a214512008-06-11 05:26:20 +0000560static struct PyModuleDef _md5module = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 PyModuleDef_HEAD_INIT,
562 "_md5",
563 NULL,
564 -1,
565 MD5_functions,
566 NULL,
567 NULL,
568 NULL,
569 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000570};
571
572PyMODINIT_FUNC
573PyInit__md5(void)
574{
Christian Heimes327dd732013-10-22 15:05:23 +0200575 PyObject *m;
576
Christian Heimes90aa7642007-12-19 02:45:37 +0000577 Py_TYPE(&MD5type) = &PyType_Type;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000578 if (PyType_Ready(&MD5type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000579 return NULL;
Christian Heimes327dd732013-10-22 15:05:23 +0200580
581 m = PyModule_Create(&_md5module);
582 if (m == NULL)
583 return NULL;
584
585 Py_INCREF((PyObject *)&MD5type);
586 PyModule_AddObject(m, "MD5Type", (PyObject *)&MD5type);
587 return m;
Gregory P. Smith2f21eb32007-09-09 06:44:34 +0000588}