blob: dd4317fca04bd37b84b7e813f9e130920808dd5c [file] [log] [blame]
Gregory P. Smithf21a5f72005-08-21 18:45:59 +00001/* Module that wraps all OpenSSL hash algorithms */
2
3/*
Benjamin Peterson46a99002010-01-09 18:45:30 +00004 * Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +00005 * Licensed to PSF under a Contributor Agreement.
6 *
7 * Derived from a skeleton of shamodule.c containing work performed by:
8 *
9 * Andrew Kuchling (amk@amk.ca)
10 * Greg Stein (gstein@lyra.org)
11 *
12 */
13
Thomas Wouters9bc844e2006-03-01 21:50:07 +000014#define PY_SSIZE_T_CLEAN
15
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000016#include "Python.h"
17#include "structmember.h"
Gregory P. Smith365a1862009-02-12 07:35:29 +000018#include "hashlib.h"
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000019
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +000020#ifdef WITH_THREAD
Gregory P. Smith3f61d612009-05-04 00:45:33 +000021#include "pythread.h"
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +000022 #define ENTER_HASHLIB(obj) \
23 if ((obj)->lock) { \
24 if (!PyThread_acquire_lock((obj)->lock, 0)) { \
25 Py_BEGIN_ALLOW_THREADS \
26 PyThread_acquire_lock((obj)->lock, 1); \
27 Py_END_ALLOW_THREADS \
28 } \
29 }
30 #define LEAVE_HASHLIB(obj) \
31 if ((obj)->lock) { \
32 PyThread_release_lock((obj)->lock); \
33 }
34#else
35 #define ENTER_HASHLIB(obj)
36 #define LEAVE_HASHLIB(obj)
37#endif
38
Gregory P. Smith3f61d612009-05-04 00:45:33 +000039/* EVP is the preferred interface to hashing in OpenSSL */
40#include <openssl/evp.h>
Gregory P. Smith13b55292010-09-06 08:30:23 +000041/* We use the object interface to discover what hashes OpenSSL supports. */
42#include <openssl/objects.h>
Gregory P. Smith3f61d612009-05-04 00:45:33 +000043
44#define MUNCH_SIZE INT_MAX
45
46/* TODO(gps): We should probably make this a module or EVPobject attribute
47 * to allow the user to optimize based on the platform they're using. */
48#define HASHLIB_GIL_MINSIZE 2048
49
50#ifndef HASH_OBJ_CONSTRUCTOR
51#define HASH_OBJ_CONSTRUCTOR 0
52#endif
53
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +000054/* Minimum OpenSSL version needed to support sha224 and higher. */
55#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000)
56#define _OPENSSL_SUPPORTS_SHA2
57#endif
Gregory P. Smith3f61d612009-05-04 00:45:33 +000058
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000059typedef struct {
60 PyObject_HEAD
61 PyObject *name; /* name of this hash algorithm */
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +000062 EVP_MD_CTX ctx; /* OpenSSL message digest context */
63#ifdef WITH_THREAD
64 PyThread_type_lock lock; /* OpenSSL context lock */
65#endif
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000066} EVPobject;
67
68
69static PyTypeObject EVPtype;
70
71
72#define DEFINE_CONSTS_FOR_NEW(Name) \
73 static PyObject *CONST_ ## Name ## _name_obj; \
74 static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
75 static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
76
Neal Norwitzf0459142006-01-07 21:20:24 +000077DEFINE_CONSTS_FOR_NEW(md5)
78DEFINE_CONSTS_FOR_NEW(sha1)
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +000079#ifdef _OPENSSL_SUPPORTS_SHA2
Neal Norwitzf0459142006-01-07 21:20:24 +000080DEFINE_CONSTS_FOR_NEW(sha224)
81DEFINE_CONSTS_FOR_NEW(sha256)
82DEFINE_CONSTS_FOR_NEW(sha384)
83DEFINE_CONSTS_FOR_NEW(sha512)
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +000084#endif
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000085
86
87static EVPobject *
88newEVPobject(PyObject *name)
89{
90 EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
91
92 /* save the name for .name to return */
93 if (retval != NULL) {
94 Py_INCREF(name);
95 retval->name = name;
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +000096#ifdef WITH_THREAD
97 retval->lock = NULL;
98#endif
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000099 }
100
101 return retval;
102}
103
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000104static void
105EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
106{
107 unsigned int process;
108 const unsigned char *cp = (const unsigned char *)vp;
109 while (0 < len) {
110 if (len > (Py_ssize_t)MUNCH_SIZE)
111 process = MUNCH_SIZE;
112 else
113 process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
114 EVP_DigestUpdate(&self->ctx, (const void*)cp, process);
115 len -= process;
116 cp += process;
117 }
118}
119
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000120/* Internal methods for a hash object */
121
122static void
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000123EVP_dealloc(EVPobject *self)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000124{
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000125#ifdef WITH_THREAD
126 if (self->lock != NULL)
127 PyThread_free_lock(self->lock);
128#endif
129 EVP_MD_CTX_cleanup(&self->ctx);
130 Py_XDECREF(self->name);
131 PyObject_Del(self);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000132}
133
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000134static void locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
135{
136 ENTER_HASHLIB(self);
137 EVP_MD_CTX_copy(new_ctx_p, &self->ctx);
138 LEAVE_HASHLIB(self);
139}
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000140
141/* External methods for a hash object */
142
143PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
144
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000145
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000146static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000147EVP_copy(EVPobject *self, PyObject *unused)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000148{
149 EVPobject *newobj;
150
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000151 if ( (newobj = newEVPobject(self->name))==NULL)
152 return NULL;
153
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000154 locked_EVP_MD_CTX_copy(&newobj->ctx, self);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000155 return (PyObject *)newobj;
156}
157
158PyDoc_STRVAR(EVP_digest__doc__,
159"Return the digest value as a string of binary data.");
160
161static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000162EVP_digest(EVPobject *self, PyObject *unused)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000163{
164 unsigned char digest[EVP_MAX_MD_SIZE];
165 EVP_MD_CTX temp_ctx;
166 PyObject *retval;
167 unsigned int digest_size;
168
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000169 locked_EVP_MD_CTX_copy(&temp_ctx, self);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000170 digest_size = EVP_MD_CTX_size(&temp_ctx);
Neal Norwitzf0459142006-01-07 21:20:24 +0000171 EVP_DigestFinal(&temp_ctx, digest, NULL);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000172
Christian Heimes72b710a2008-05-26 13:28:38 +0000173 retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000174 EVP_MD_CTX_cleanup(&temp_ctx);
175 return retval;
176}
177
178PyDoc_STRVAR(EVP_hexdigest__doc__,
179"Return the digest value as a string of hexadecimal digits.");
180
181static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000182EVP_hexdigest(EVPobject *self, PyObject *unused)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000183{
184 unsigned char digest[EVP_MAX_MD_SIZE];
185 EVP_MD_CTX temp_ctx;
186 PyObject *retval;
187 char *hex_digest;
188 unsigned int i, j, digest_size;
189
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000190 /* Get the raw (binary) digest value */
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000191 locked_EVP_MD_CTX_copy(&temp_ctx, self);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000192 digest_size = EVP_MD_CTX_size(&temp_ctx);
193 EVP_DigestFinal(&temp_ctx, digest, NULL);
194
195 EVP_MD_CTX_cleanup(&temp_ctx);
196
Guido van Rossumf8953072007-07-10 13:20:29 +0000197 /* Allocate a new buffer */
198 hex_digest = PyMem_Malloc(digest_size * 2 + 1);
199 if (!hex_digest)
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000200 return PyErr_NoMemory();
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000201
202 /* Make hex version of the digest */
203 for(i=j=0; i<digest_size; i++) {
204 char c;
205 c = (digest[i] >> 4) & 0xf;
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000206 c = (c>9) ? c+'a'-10 : c + '0';
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000207 hex_digest[j++] = c;
208 c = (digest[i] & 0xf);
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000209 c = (c>9) ? c+'a'-10 : c + '0';
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000210 hex_digest[j++] = c;
211 }
Guido van Rossumf8953072007-07-10 13:20:29 +0000212 retval = PyUnicode_FromStringAndSize(hex_digest, digest_size * 2);
213 PyMem_Free(hex_digest);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000214 return retval;
215}
216
217PyDoc_STRVAR(EVP_update__doc__,
218"Update this hash object's state with the provided string.");
219
220static PyObject *
221EVP_update(EVPobject *self, PyObject *args)
222{
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000223 PyObject *obj;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000224 Py_buffer view;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000225
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000226 if (!PyArg_ParseTuple(args, "O:update", &obj))
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000227 return NULL;
228
Gregory P. Smith365a1862009-02-12 07:35:29 +0000229 GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000230
231#ifdef WITH_THREAD
232 if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
233 self->lock = PyThread_allocate_lock();
Gregory P. Smith3f61d612009-05-04 00:45:33 +0000234 /* fail? lock = NULL and we fail over to non-threaded code. */
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000235 }
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000236
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000237 if (self->lock != NULL) {
238 Py_BEGIN_ALLOW_THREADS
239 PyThread_acquire_lock(self->lock, 1);
240 EVP_hash(self, view.buf, view.len);
241 PyThread_release_lock(self->lock);
242 Py_END_ALLOW_THREADS
243 } else {
244 EVP_hash(self, view.buf, view.len);
245 }
246#else
247 EVP_hash(self, view.buf, view.len);
248#endif
249
250 PyBuffer_Release(&view);
251 Py_RETURN_NONE;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000252}
253
254static PyMethodDef EVP_methods[] = {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000255 {"update", (PyCFunction)EVP_update, METH_VARARGS, EVP_update__doc__},
256 {"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000257 {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__},
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000258 {"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__},
259 {NULL, NULL} /* sentinel */
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000260};
261
262static PyObject *
263EVP_get_block_size(EVPobject *self, void *closure)
264{
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000265 long block_size;
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000266 block_size = EVP_MD_CTX_block_size(&self->ctx);
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000267 return PyLong_FromLong(block_size);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000268}
269
270static PyObject *
271EVP_get_digest_size(EVPobject *self, void *closure)
272{
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000273 long size;
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000274 size = EVP_MD_CTX_size(&self->ctx);
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000275 return PyLong_FromLong(size);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000276}
277
278static PyMemberDef EVP_members[] = {
279 {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
280 {NULL} /* Sentinel */
281};
282
283static PyGetSetDef EVP_getseters[] = {
284 {"digest_size",
285 (getter)EVP_get_digest_size, NULL,
286 NULL,
287 NULL},
288 {"block_size",
289 (getter)EVP_get_block_size, NULL,
290 NULL,
291 NULL},
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000292 {NULL} /* Sentinel */
293};
294
295
296static PyObject *
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000297EVP_repr(EVPobject *self)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000298{
Victor Stinner3f1af5c2010-03-12 17:00:41 +0000299 return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000300}
301
302#if HASH_OBJ_CONSTRUCTOR
303static int
304EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
305{
Martin v. Löwis15e62742006-02-27 16:46:16 +0000306 static char *kwlist[] = {"name", "string", NULL};
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000307 PyObject *name_obj = NULL;
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000308 PyObject *data_obj = NULL;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000309 Py_buffer view;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000310 char *nameStr;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000311 const EVP_MD *digest;
312
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000313 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist,
314 &name_obj, &data_obj)) {
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000315 return -1;
316 }
317
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000318 if (data_obj)
Gregory P. Smith365a1862009-02-12 07:35:29 +0000319 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000320
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000321 if (!PyArg_Parse(name_obj, "s", &nameStr)) {
322 PyErr_SetString(PyExc_TypeError, "name must be a string");
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000323 if (data_obj)
Martin v. Löwis423be952008-08-13 15:53:07 +0000324 PyBuffer_Release(&view);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000325 return -1;
326 }
327
328 digest = EVP_get_digestbyname(nameStr);
329 if (!digest) {
330 PyErr_SetString(PyExc_ValueError, "unknown hash function");
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000331 if (data_obj)
Martin v. Löwis423be952008-08-13 15:53:07 +0000332 PyBuffer_Release(&view);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000333 return -1;
334 }
335 EVP_DigestInit(&self->ctx, digest);
336
337 self->name = name_obj;
338 Py_INCREF(self->name);
339
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000340 if (data_obj) {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000341 if (view.len >= HASHLIB_GIL_MINSIZE) {
342 Py_BEGIN_ALLOW_THREADS
343 EVP_hash(self, view.buf, view.len);
344 Py_END_ALLOW_THREADS
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000345 } else {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000346 EVP_hash(self, view.buf, view.len);
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000347 }
Martin v. Löwis423be952008-08-13 15:53:07 +0000348 PyBuffer_Release(&view);
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000349 }
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000350
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000351 return 0;
352}
353#endif
354
355
356PyDoc_STRVAR(hashtype_doc,
357"A hash represents the object used to calculate a checksum of a\n\
358string of information.\n\
359\n\
360Methods:\n\
361\n\
362update() -- updates the current digest with an additional string\n\
363digest() -- return the current digest value\n\
364hexdigest() -- return the current digest as a string of hexadecimal digits\n\
365copy() -- return a copy of the current hash object\n\
366\n\
367Attributes:\n\
368\n\
369name -- the hash algorithm being used by this object\n\
370digest_size -- number of bytes in this hashes output\n");
371
372static PyTypeObject EVPtype = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000373 PyVarObject_HEAD_INIT(NULL, 0)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000374 "_hashlib.HASH", /*tp_name*/
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000375 sizeof(EVPobject), /*tp_basicsize*/
376 0, /*tp_itemsize*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000377 /* methods */
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000378 (destructor)EVP_dealloc, /*tp_dealloc*/
379 0, /*tp_print*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000380 0, /*tp_getattr*/
381 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000382 0, /*tp_reserved*/
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000383 (reprfunc)EVP_repr, /*tp_repr*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000384 0, /*tp_as_number*/
385 0, /*tp_as_sequence*/
386 0, /*tp_as_mapping*/
387 0, /*tp_hash*/
388 0, /*tp_call*/
389 0, /*tp_str*/
390 0, /*tp_getattro*/
391 0, /*tp_setattro*/
392 0, /*tp_as_buffer*/
393 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
394 hashtype_doc, /*tp_doc*/
395 0, /*tp_traverse*/
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000396 0, /*tp_clear*/
397 0, /*tp_richcompare*/
398 0, /*tp_weaklistoffset*/
399 0, /*tp_iter*/
400 0, /*tp_iternext*/
401 EVP_methods, /* tp_methods */
402 EVP_members, /* tp_members */
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000403 EVP_getseters, /* tp_getset */
404#if 1
405 0, /* tp_base */
406 0, /* tp_dict */
407 0, /* tp_descr_get */
408 0, /* tp_descr_set */
409 0, /* tp_dictoffset */
410#endif
411#if HASH_OBJ_CONSTRUCTOR
412 (initproc)EVP_tp_init, /* tp_init */
413#endif
414};
415
416static PyObject *
417EVPnew(PyObject *name_obj,
418 const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000419 const unsigned char *cp, Py_ssize_t len)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000420{
421 EVPobject *self;
422
423 if (!digest && !initial_ctx) {
424 PyErr_SetString(PyExc_ValueError, "unsupported hash type");
425 return NULL;
426 }
427
428 if ((self = newEVPobject(name_obj)) == NULL)
429 return NULL;
430
431 if (initial_ctx) {
432 EVP_MD_CTX_copy(&self->ctx, initial_ctx);
433 } else {
434 EVP_DigestInit(&self->ctx, digest);
435 }
436
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000437 if (cp && len) {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000438 if (len >= HASHLIB_GIL_MINSIZE) {
439 Py_BEGIN_ALLOW_THREADS
440 EVP_hash(self, cp, len);
441 Py_END_ALLOW_THREADS
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000442 } else {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000443 EVP_hash(self, cp, len);
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000444 }
445 }
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000446
447 return (PyObject *)self;
448}
449
450
451/* The module-level function: new() */
452
453PyDoc_STRVAR(EVP_new__doc__,
454"Return a new hash object using the named algorithm.\n\
455An optional string argument may be provided and will be\n\
456automatically hashed.\n\
457\n\
458The MD5 and SHA1 algorithms are always supported.\n");
459
460static PyObject *
461EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
462{
Martin v. Löwis15e62742006-02-27 16:46:16 +0000463 static char *kwlist[] = {"name", "string", NULL};
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000464 PyObject *name_obj = NULL;
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000465 PyObject *data_obj = NULL;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000466 Py_buffer view = { 0 };
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000467 PyObject *ret_obj;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000468 char *name;
469 const EVP_MD *digest;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000470
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000471 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist,
472 &name_obj, &data_obj)) {
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000473 return NULL;
474 }
475
476 if (!PyArg_Parse(name_obj, "s", &name)) {
477 PyErr_SetString(PyExc_TypeError, "name must be a string");
478 return NULL;
479 }
480
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000481 if (data_obj)
Gregory P. Smith365a1862009-02-12 07:35:29 +0000482 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000483
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000484 digest = EVP_get_digestbyname(name);
485
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000486 ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000487
488 if (data_obj)
Martin v. Löwis423be952008-08-13 15:53:07 +0000489 PyBuffer_Release(&view);
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000490 return ret_obj;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000491}
492
Gregory P. Smith13b55292010-09-06 08:30:23 +0000493
494/* State for our callback function so that it can accumulate a result. */
495typedef struct _internal_name_mapper_state {
496 PyObject *set;
497 int error;
498} _InternalNameMapperState;
499
500
501/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
502static void
503_openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg)
504{
505 _InternalNameMapperState *state = (_InternalNameMapperState *)arg;
506 PyObject *py_name;
507
508 assert(state != NULL);
509 if (openssl_obj_name == NULL)
510 return;
511 /* Ignore aliased names, they pollute the list and OpenSSL appears to
512 * have a its own definition of alias as the resulting list still
513 * contains duplicate and alternate names for several algorithms. */
514 if (openssl_obj_name->alias)
515 return;
516
517 py_name = PyUnicode_FromString(openssl_obj_name->name);
518 if (py_name == NULL) {
519 state->error = 1;
520 } else {
521 if (PySet_Add(state->set, py_name) != 0) {
522 Py_DECREF(py_name);
523 state->error = 1;
524 }
525 }
526}
527
528
529/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
530static PyObject*
531generate_hash_name_list(void)
532{
533 _InternalNameMapperState state;
534 state.set = PyFrozenSet_New(NULL);
535 if (state.set == NULL)
536 return NULL;
537 state.error = 0;
538
539 OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state);
540
541 if (state.error) {
542 Py_DECREF(state.set);
543 return NULL;
544 }
545 return state.set;
546}
547
548
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000549/*
550 * This macro generates constructor function definitions for specific
551 * hash algorithms. These constructors are much faster than calling
552 * the generic one passing it a python string and are noticably
553 * faster than calling a python new() wrapper. Thats important for
554 * code that wants to make hashes of a bunch of small strings.
555 */
556#define GEN_CONSTRUCTOR(NAME) \
557 static PyObject * \
558 EVP_new_ ## NAME (PyObject *self, PyObject *args) \
559 { \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000560 PyObject *data_obj = NULL; \
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000561 Py_buffer view = { 0 }; \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000562 PyObject *ret_obj; \
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000563 \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000564 if (!PyArg_ParseTuple(args, "|O:" #NAME , &data_obj)) { \
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000565 return NULL; \
566 } \
567 \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000568 if (data_obj) \
Gregory P. Smith365a1862009-02-12 07:35:29 +0000569 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000570 \
571 ret_obj = EVPnew( \
572 CONST_ ## NAME ## _name_obj, \
573 NULL, \
574 CONST_new_ ## NAME ## _ctx_p, \
575 (unsigned char*)view.buf, \
Benjamin Peterson78cb4912008-09-24 22:53:33 +0000576 view.len); \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000577 \
578 if (data_obj) \
Martin v. Löwis423be952008-08-13 15:53:07 +0000579 PyBuffer_Release(&view); \
Gregory P. Smith9406f5c2007-08-26 02:58:36 +0000580 return ret_obj; \
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000581 }
582
583/* a PyMethodDef structure for the constructor */
584#define CONSTRUCTOR_METH_DEF(NAME) \
585 {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
586 PyDoc_STR("Returns a " #NAME \
587 " hash object; optionally initialized with a string") \
588 }
589
590/* used in the init function to setup a constructor */
591#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
Neal Norwitzd6d2f2f2007-08-23 20:28:10 +0000592 CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000593 if (EVP_get_digestbyname(#NAME)) { \
594 CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
595 EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
596 } \
597} while (0);
598
599GEN_CONSTRUCTOR(md5)
600GEN_CONSTRUCTOR(sha1)
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000601#ifdef _OPENSSL_SUPPORTS_SHA2
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000602GEN_CONSTRUCTOR(sha224)
603GEN_CONSTRUCTOR(sha256)
604GEN_CONSTRUCTOR(sha384)
605GEN_CONSTRUCTOR(sha512)
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000606#endif
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000607
608/* List of functions exported by this module */
609
610static struct PyMethodDef EVP_functions[] = {
611 {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
612 CONSTRUCTOR_METH_DEF(md5),
613 CONSTRUCTOR_METH_DEF(sha1),
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000614#ifdef _OPENSSL_SUPPORTS_SHA2
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000615 CONSTRUCTOR_METH_DEF(sha224),
616 CONSTRUCTOR_METH_DEF(sha256),
617 CONSTRUCTOR_METH_DEF(sha384),
618 CONSTRUCTOR_METH_DEF(sha512),
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000619#endif
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000620 {NULL, NULL} /* Sentinel */
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000621};
622
623
624/* Initialize this module. */
625
Martin v. Löwis1a214512008-06-11 05:26:20 +0000626
627static struct PyModuleDef _hashlibmodule = {
Antoine Pitroubcd5cbe2009-01-08 21:17:16 +0000628 PyModuleDef_HEAD_INIT,
629 "_hashlib",
630 NULL,
631 -1,
632 EVP_functions,
633 NULL,
634 NULL,
635 NULL,
636 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000637};
638
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000639PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000640PyInit__hashlib(void)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000641{
Gregory P. Smith13b55292010-09-06 08:30:23 +0000642 PyObject *m, *openssl_md_meth_names;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000643
644 OpenSSL_add_all_digests();
645
646 /* TODO build EVP_functions openssl_* entries dynamically based
647 * on what hashes are supported rather than listing many
648 * but having some be unsupported. Only init appropriate
649 * constants. */
650
Christian Heimes90aa7642007-12-19 02:45:37 +0000651 Py_TYPE(&EVPtype) = &PyType_Type;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000652 if (PyType_Ready(&EVPtype) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000653 return NULL;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000654
Martin v. Löwis1a214512008-06-11 05:26:20 +0000655 m = PyModule_Create(&_hashlibmodule);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000656 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000657 return NULL;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000658
Gregory P. Smith13b55292010-09-06 08:30:23 +0000659 openssl_md_meth_names = generate_hash_name_list();
660 if (openssl_md_meth_names == NULL) {
661 Py_DECREF(m);
662 return NULL;
663 }
664 if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) {
665 Py_DECREF(m);
666 return NULL;
667 }
668
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000669#if HASH_OBJ_CONSTRUCTOR
670 Py_INCREF(&EVPtype);
671 PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
672#endif
673
674 /* these constants are used by the convenience constructors */
675 INIT_CONSTRUCTOR_CONSTANTS(md5);
676 INIT_CONSTRUCTOR_CONSTANTS(sha1);
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000677#ifdef _OPENSSL_SUPPORTS_SHA2
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000678 INIT_CONSTRUCTOR_CONSTANTS(sha224);
679 INIT_CONSTRUCTOR_CONSTANTS(sha256);
680 INIT_CONSTRUCTOR_CONSTANTS(sha384);
681 INIT_CONSTRUCTOR_CONSTANTS(sha512);
Benjamin Peterson5e55b3e2010-02-03 02:35:45 +0000682#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +0000683 return m;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000684}