LCOV - code coverage report
Current view: top level - Modules - _hashopenssl.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 58 254 22.8 %
Date: 2017-04-19 Functions: 12 24 50.0 %

          Line data    Source code
       1             : /* Module that wraps all OpenSSL hash algorithms */
       2             : 
       3             : /*
       4             :  * Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
       5             :  * 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             : 
      14             : #define PY_SSIZE_T_CLEAN
      15             : 
      16             : #include "Python.h"
      17             : #include "structmember.h"
      18             : 
      19             : #ifdef WITH_THREAD
      20             : #include "pythread.h"
      21             :     #define ENTER_HASHLIB(obj) \
      22             :         if ((obj)->lock) { \
      23             :             if (!PyThread_acquire_lock((obj)->lock, 0)) { \
      24             :                 Py_BEGIN_ALLOW_THREADS \
      25             :                 PyThread_acquire_lock((obj)->lock, 1); \
      26             :                 Py_END_ALLOW_THREADS \
      27             :             } \
      28             :         }
      29             :     #define LEAVE_HASHLIB(obj) \
      30             :         if ((obj)->lock) { \
      31             :             PyThread_release_lock((obj)->lock); \
      32             :         }
      33             : #else
      34             :     #define ENTER_HASHLIB(obj)
      35             :     #define LEAVE_HASHLIB(obj)
      36             : #endif
      37             : 
      38             : /* EVP is the preferred interface to hashing in OpenSSL */
      39             : #include <openssl/evp.h>
      40             : #include <openssl/err.h>
      41             : /* We use the object interface to discover what hashes OpenSSL supports. */
      42             : #include <openssl/objects.h>
      43             : #include "openssl/err.h"
      44             : 
      45             : #define MUNCH_SIZE INT_MAX
      46             : 
      47             : /* TODO(gps): We should probably make this a module or EVPobject attribute
      48             :  * to allow the user to optimize based on the platform they're using. */
      49             : #define HASHLIB_GIL_MINSIZE 2048
      50             : 
      51             : #ifndef HASH_OBJ_CONSTRUCTOR
      52             : #define HASH_OBJ_CONSTRUCTOR 0
      53             : #endif
      54             : 
      55             : #if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000)
      56             : #define _OPENSSL_SUPPORTS_SHA2
      57             : #endif
      58             : 
      59             : #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
      60             : /* OpenSSL < 1.1.0 */
      61             : #define EVP_MD_CTX_new EVP_MD_CTX_create
      62             : #define EVP_MD_CTX_free EVP_MD_CTX_destroy
      63             : #define HAS_FAST_PKCS5_PBKDF2_HMAC 0
      64             : #include <openssl/hmac.h>
      65             : #else
      66             : /* OpenSSL >= 1.1.0 */
      67             : #define HAS_FAST_PKCS5_PBKDF2_HMAC 1
      68             : #endif
      69             : 
      70             : 
      71             : typedef struct {
      72             :     PyObject_HEAD
      73             :     PyObject            *name;  /* name of this hash algorithm */
      74             :     EVP_MD_CTX          *ctx;   /* OpenSSL message digest context */
      75             : #ifdef WITH_THREAD
      76             :     PyThread_type_lock  lock;   /* OpenSSL context lock */
      77             : #endif
      78             : } EVPobject;
      79             : 
      80             : 
      81             : static PyTypeObject EVPtype;
      82             : 
      83             : 
      84             : #define DEFINE_CONSTS_FOR_NEW(Name)  \
      85             :     static PyObject *CONST_ ## Name ## _name_obj = NULL; \
      86             :     static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
      87             : 
      88             : DEFINE_CONSTS_FOR_NEW(md5)
      89             : DEFINE_CONSTS_FOR_NEW(sha1)
      90             : #ifdef _OPENSSL_SUPPORTS_SHA2
      91             : DEFINE_CONSTS_FOR_NEW(sha224)
      92             : DEFINE_CONSTS_FOR_NEW(sha256)
      93             : DEFINE_CONSTS_FOR_NEW(sha384)
      94             : DEFINE_CONSTS_FOR_NEW(sha512)
      95             : #endif
      96             : 
      97             : 
      98             : /* LCOV_EXCL_START */
      99             : static PyObject *
     100             : _setException(PyObject *exc)
     101             : {
     102             :     unsigned long errcode;
     103             :     const char *lib, *func, *reason;
     104             : 
     105             :     errcode = ERR_peek_last_error();
     106             :     if (!errcode) {
     107             :         PyErr_SetString(exc, "unknown reasons");
     108             :         return NULL;
     109             :     }
     110             :     ERR_clear_error();
     111             : 
     112             :     lib = ERR_lib_error_string(errcode);
     113             :     func = ERR_func_error_string(errcode);
     114             :     reason = ERR_reason_error_string(errcode);
     115             : 
     116             :     if (lib && func) {
     117             :         PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
     118             :     }
     119             :     else if (lib) {
     120             :         PyErr_Format(exc, "[%s] %s", lib, reason);
     121             :     }
     122             :     else {
     123             :         PyErr_SetString(exc, reason);
     124             :     }
     125             :     return NULL;
     126             : }
     127             : /* LCOV_EXCL_STOP */
     128             : 
     129             : static EVPobject *
     130          18 : newEVPobject(PyObject *name)
     131             : {
     132          18 :     EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
     133          18 :     if (retval == NULL)
     134           0 :         return NULL;
     135             : 
     136          18 :     retval->ctx = EVP_MD_CTX_new();
     137          18 :     if (retval->ctx == NULL) {
     138           0 :         PyErr_NoMemory();
     139           0 :         return NULL;
     140             :     }
     141             : 
     142             :     /* save the name for .name to return */
     143          18 :     Py_INCREF(name);
     144          18 :     retval->name = name;
     145             : #ifdef WITH_THREAD
     146             :     retval->lock = NULL;
     147             : #endif
     148             : 
     149          18 :     return retval;
     150             : }
     151             : 
     152             : static void
     153           0 : EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
     154             : {
     155             :     unsigned int process;
     156           0 :     const unsigned char *cp = (const unsigned char *)vp;
     157           0 :     while (0 < len)
     158             :     {
     159           0 :         if (len > (Py_ssize_t)MUNCH_SIZE)
     160           0 :             process = MUNCH_SIZE;
     161             :         else
     162           0 :             process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
     163           0 :         EVP_DigestUpdate(self->ctx, (const void*)cp, process);
     164           0 :         len -= process;
     165           0 :         cp += process;
     166             :     }
     167           0 : }
     168             : 
     169             : /* Internal methods for a hash object */
     170             : 
     171             : static void
     172          18 : EVP_dealloc(EVPobject *self)
     173             : {
     174             : #ifdef WITH_THREAD
     175             :     if (self->lock != NULL)
     176             :         PyThread_free_lock(self->lock);
     177             : #endif
     178          18 :     EVP_MD_CTX_free(self->ctx);
     179          18 :     Py_XDECREF(self->name);
     180          18 :     PyObject_Del(self);
     181          18 : }
     182             : 
     183             : static int
     184           0 : locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
     185             : {
     186             :     int result;
     187             :     ENTER_HASHLIB(self);
     188             :     /* XXX no error reporting */
     189           0 :     result = EVP_MD_CTX_copy(new_ctx_p, self->ctx);
     190             :     LEAVE_HASHLIB(self);
     191           0 :     return result;
     192             : }
     193             : 
     194             : /* External methods for a hash object */
     195             : 
     196             : PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
     197             : 
     198             : 
     199             : static PyObject *
     200           0 : EVP_copy(EVPobject *self, PyObject *unused)
     201             : {
     202             :     EVPobject *newobj;
     203             : 
     204           0 :     if ( (newobj = newEVPobject(self->name))==NULL)
     205           0 :         return NULL;
     206             : 
     207           0 :     if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
     208           0 :         return _setException(PyExc_ValueError);
     209             :     }
     210           0 :     return (PyObject *)newobj;
     211             : }
     212             : 
     213             : PyDoc_STRVAR(EVP_digest__doc__,
     214             : "Return the digest value as a string of binary data.");
     215             : 
     216             : static PyObject *
     217           0 : EVP_digest(EVPobject *self, PyObject *unused)
     218             : {
     219             :     unsigned char digest[EVP_MAX_MD_SIZE];
     220             :     EVP_MD_CTX *temp_ctx;
     221             :     PyObject *retval;
     222             :     unsigned int digest_size;
     223             : 
     224           0 :     temp_ctx = EVP_MD_CTX_new();
     225           0 :     if (temp_ctx == NULL) {
     226           0 :         PyErr_NoMemory();
     227           0 :         return NULL;
     228             :     }
     229             : 
     230           0 :     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
     231           0 :         return _setException(PyExc_ValueError);
     232             :     }
     233           0 :     digest_size = EVP_MD_CTX_size(temp_ctx);
     234           0 :     EVP_DigestFinal(temp_ctx, digest, NULL);
     235             : 
     236           0 :     retval = PyString_FromStringAndSize((const char *)digest, digest_size);
     237           0 :     EVP_MD_CTX_free(temp_ctx);
     238           0 :     return retval;
     239             : }
     240             : 
     241             : PyDoc_STRVAR(EVP_hexdigest__doc__,
     242             : "Return the digest value as a string of hexadecimal digits.");
     243             : 
     244             : static PyObject *
     245           0 : EVP_hexdigest(EVPobject *self, PyObject *unused)
     246             : {
     247             :     unsigned char digest[EVP_MAX_MD_SIZE];
     248             :     EVP_MD_CTX *temp_ctx;
     249             :     PyObject *retval;
     250             :     char *hex_digest;
     251             :     unsigned int i, j, digest_size;
     252             : 
     253           0 :     temp_ctx = EVP_MD_CTX_new();
     254           0 :     if (temp_ctx == NULL) {
     255           0 :         PyErr_NoMemory();
     256           0 :         return NULL;
     257             :     }
     258             : 
     259             :     /* Get the raw (binary) digest value */
     260           0 :     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
     261           0 :         return _setException(PyExc_ValueError);
     262             :     }
     263           0 :     digest_size = EVP_MD_CTX_size(temp_ctx);
     264           0 :     EVP_DigestFinal(temp_ctx, digest, NULL);
     265             : 
     266           0 :     EVP_MD_CTX_free(temp_ctx);
     267             : 
     268             :     /* Create a new string */
     269             :     /* NOTE: not thread safe! modifying an already created string object */
     270             :     /* (not a problem because we hold the GIL by default) */
     271           0 :     retval = PyString_FromStringAndSize(NULL, digest_size * 2);
     272           0 :     if (!retval)
     273           0 :             return NULL;
     274           0 :     hex_digest = PyString_AsString(retval);
     275           0 :     if (!hex_digest) {
     276           0 :             Py_DECREF(retval);
     277           0 :             return NULL;
     278             :     }
     279             : 
     280             :     /* Make hex version of the digest */
     281           0 :     for(i=j=0; i<digest_size; i++) {
     282             :         char c;
     283           0 :         c = (digest[i] >> 4) & 0xf;
     284           0 :         c = (c>9) ? c+'a'-10 : c + '0';
     285           0 :         hex_digest[j++] = c;
     286           0 :         c = (digest[i] & 0xf);
     287           0 :         c = (c>9) ? c+'a'-10 : c + '0';
     288           0 :         hex_digest[j++] = c;
     289             :     }
     290           0 :     return retval;
     291             : }
     292             : 
     293             : PyDoc_STRVAR(EVP_update__doc__,
     294             : "Update this hash object's state with the provided string.");
     295             : 
     296             : static PyObject *
     297           0 : EVP_update(EVPobject *self, PyObject *args)
     298             : {
     299             :     Py_buffer view;
     300             : 
     301           0 :     if (!PyArg_ParseTuple(args, "s*:update", &view))
     302           0 :         return NULL;
     303             : 
     304             : #ifdef WITH_THREAD
     305             :     if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
     306             :         self->lock = PyThread_allocate_lock();
     307             :         /* fail? lock = NULL and we fail over to non-threaded code. */
     308             :     }
     309             : 
     310             :     if (self->lock != NULL) {
     311             :         Py_BEGIN_ALLOW_THREADS
     312             :         PyThread_acquire_lock(self->lock, 1);
     313             :         EVP_hash(self, view.buf, view.len);
     314             :         PyThread_release_lock(self->lock);
     315             :         Py_END_ALLOW_THREADS
     316             :     }
     317             :     else
     318             : #endif
     319             :     {
     320           0 :         EVP_hash(self, view.buf, view.len);
     321             :     }
     322             : 
     323           0 :     PyBuffer_Release(&view);
     324             : 
     325           0 :     Py_RETURN_NONE;
     326             : }
     327             : 
     328             : static PyMethodDef EVP_methods[] = {
     329             :     {"update",    (PyCFunction)EVP_update,    METH_VARARGS, EVP_update__doc__},
     330             :     {"digest",    (PyCFunction)EVP_digest,    METH_NOARGS,  EVP_digest__doc__},
     331             :     {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS,  EVP_hexdigest__doc__},
     332             :     {"copy",      (PyCFunction)EVP_copy,      METH_NOARGS,  EVP_copy__doc__},
     333             :     {NULL,        NULL}         /* sentinel */
     334             : };
     335             : 
     336             : static PyObject *
     337           0 : EVP_get_block_size(EVPobject *self, void *closure)
     338             : {
     339             :     long block_size;
     340           0 :     block_size = EVP_MD_CTX_block_size(self->ctx);
     341           0 :     return PyLong_FromLong(block_size);
     342             : }
     343             : 
     344             : static PyObject *
     345           0 : EVP_get_digest_size(EVPobject *self, void *closure)
     346             : {
     347             :     long size;
     348           0 :     size = EVP_MD_CTX_size(self->ctx);
     349           0 :     return PyLong_FromLong(size);
     350             : }
     351             : 
     352             : static PyMemberDef EVP_members[] = {
     353             :     {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
     354             :     {NULL}  /* Sentinel */
     355             : };
     356             : 
     357             : static PyGetSetDef EVP_getseters[] = {
     358             :     {"digest_size",
     359             :      (getter)EVP_get_digest_size, NULL,
     360             :      NULL,
     361             :      NULL},
     362             :     {"block_size",
     363             :      (getter)EVP_get_block_size, NULL,
     364             :      NULL,
     365             :      NULL},
     366             :     /* the old md5 and sha modules support 'digest_size' as in PEP 247.
     367             :      * the old sha module also supported 'digestsize'.  ugh. */
     368             :     {"digestsize",
     369             :      (getter)EVP_get_digest_size, NULL,
     370             :      NULL,
     371             :      NULL},
     372             :     {NULL}  /* Sentinel */
     373             : };
     374             : 
     375             : 
     376             : static PyObject *
     377           0 : EVP_repr(PyObject *self)
     378             : {
     379             :     char buf[100];
     380           0 :     PyOS_snprintf(buf, sizeof(buf), "<%s HASH object @ %p>",
     381             :             PyString_AsString(((EVPobject *)self)->name), self);
     382           0 :     return PyString_FromString(buf);
     383             : }
     384             : 
     385             : #if HASH_OBJ_CONSTRUCTOR
     386             : static int
     387             : EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
     388             : {
     389             :     static char *kwlist[] = {"name", "string", NULL};
     390             :     PyObject *name_obj = NULL;
     391             :     Py_buffer view = { 0 };
     392             :     char *nameStr;
     393             :     const EVP_MD *digest;
     394             : 
     395             :     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s*:HASH", kwlist,
     396             :                                      &name_obj, &view)) {
     397             :         return -1;
     398             :     }
     399             : 
     400             :     if (!PyArg_Parse(name_obj, "s", &nameStr)) {
     401             :         PyErr_SetString(PyExc_TypeError, "name must be a string");
     402             :         PyBuffer_Release(&view);
     403             :         return -1;
     404             :     }
     405             : 
     406             :     digest = EVP_get_digestbyname(nameStr);
     407             :     if (!digest) {
     408             :         PyErr_SetString(PyExc_ValueError, "unknown hash function");
     409             :         PyBuffer_Release(&view);
     410             :         return -1;
     411             :     }
     412             :     EVP_DigestInit(self->ctx, digest);
     413             : 
     414             :     self->name = name_obj;
     415             :     Py_INCREF(self->name);
     416             : 
     417             :     if (view.obj) {
     418             :         if (view.len >= HASHLIB_GIL_MINSIZE) {
     419             :             Py_BEGIN_ALLOW_THREADS
     420             :             EVP_hash(self, view.buf, view.len);
     421             :             Py_END_ALLOW_THREADS
     422             :         } else {
     423             :             EVP_hash(self, view.buf, view.len);
     424             :         }
     425             :         PyBuffer_Release(&view);
     426             :     }
     427             : 
     428             :     return 0;
     429             : }
     430             : #endif
     431             : 
     432             : 
     433             : PyDoc_STRVAR(hashtype_doc,
     434             : "A hash represents the object used to calculate a checksum of a\n\
     435             : string of information.\n\
     436             : \n\
     437             : Methods:\n\
     438             : \n\
     439             : update() -- updates the current digest with an additional string\n\
     440             : digest() -- return the current digest value\n\
     441             : hexdigest() -- return the current digest as a string of hexadecimal digits\n\
     442             : copy() -- return a copy of the current hash object\n\
     443             : \n\
     444             : Attributes:\n\
     445             : \n\
     446             : name -- the hash algorithm being used by this object\n\
     447             : digest_size -- number of bytes in this hashes output\n");
     448             : 
     449             : static PyTypeObject EVPtype = {
     450             :     PyVarObject_HEAD_INIT(NULL, 0)
     451             :     "_hashlib.HASH",    /*tp_name*/
     452             :     sizeof(EVPobject),  /*tp_basicsize*/
     453             :     0,                  /*tp_itemsize*/
     454             :     /* methods */
     455             :     (destructor)EVP_dealloc,    /*tp_dealloc*/
     456             :     0,                  /*tp_print*/
     457             :     0,                  /*tp_getattr*/
     458             :     0,                  /*tp_setattr*/
     459             :     0,                  /*tp_compare*/
     460             :     EVP_repr,           /*tp_repr*/
     461             :     0,                  /*tp_as_number*/
     462             :     0,                  /*tp_as_sequence*/
     463             :     0,                  /*tp_as_mapping*/
     464             :     0,                  /*tp_hash*/
     465             :     0,                  /*tp_call*/
     466             :     0,                  /*tp_str*/
     467             :     0,                  /*tp_getattro*/
     468             :     0,                  /*tp_setattro*/
     469             :     0,                  /*tp_as_buffer*/
     470             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
     471             :     hashtype_doc,       /*tp_doc*/
     472             :     0,                  /*tp_traverse*/
     473             :     0,                  /*tp_clear*/
     474             :     0,                  /*tp_richcompare*/
     475             :     0,                  /*tp_weaklistoffset*/
     476             :     0,                  /*tp_iter*/
     477             :     0,                  /*tp_iternext*/
     478             :     EVP_methods,        /* tp_methods */
     479             :     EVP_members,        /* tp_members */
     480             :     EVP_getseters,      /* tp_getset */
     481             : #if 1
     482             :     0,                  /* tp_base */
     483             :     0,                  /* tp_dict */
     484             :     0,                  /* tp_descr_get */
     485             :     0,                  /* tp_descr_set */
     486             :     0,                  /* tp_dictoffset */
     487             : #endif
     488             : #if HASH_OBJ_CONSTRUCTOR
     489             :     (initproc)EVP_tp_init, /* tp_init */
     490             : #endif
     491             : };
     492             : 
     493             : static PyObject *
     494          18 : EVPnew(PyObject *name_obj,
     495             :        const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
     496             :        const unsigned char *cp, Py_ssize_t len)
     497             : {
     498             :     EVPobject *self;
     499             : 
     500          18 :     if (!digest && !initial_ctx) {
     501           0 :         PyErr_SetString(PyExc_ValueError, "unsupported hash type");
     502           0 :         return NULL;
     503             :     }
     504             : 
     505          18 :     if ((self = newEVPobject(name_obj)) == NULL)
     506           0 :         return NULL;
     507             : 
     508          18 :     if (initial_ctx) {
     509          18 :         EVP_MD_CTX_copy(self->ctx, initial_ctx);
     510             :     } else {
     511           0 :         EVP_DigestInit(self->ctx, digest);
     512             :     }
     513             : 
     514          18 :     if (cp && len) {
     515           0 :         if (len >= HASHLIB_GIL_MINSIZE) {
     516             :             Py_BEGIN_ALLOW_THREADS
     517           0 :             EVP_hash(self, cp, len);
     518             :             Py_END_ALLOW_THREADS
     519             :         } else {
     520           0 :             EVP_hash(self, cp, len);
     521             :         }
     522             :     }
     523             : 
     524          18 :     return (PyObject *)self;
     525             : }
     526             : 
     527             : 
     528             : /* The module-level function: new() */
     529             : 
     530             : PyDoc_STRVAR(EVP_new__doc__,
     531             : "Return a new hash object using the named algorithm.\n\
     532             : An optional string argument may be provided and will be\n\
     533             : automatically hashed.\n\
     534             : \n\
     535             : The MD5 and SHA1 algorithms are always supported.\n");
     536             : 
     537             : static PyObject *
     538           0 : EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
     539             : {
     540             :     static char *kwlist[] = {"name", "string", NULL};
     541           0 :     PyObject *name_obj = NULL;
     542           0 :     Py_buffer view = { 0 };
     543             :     PyObject *ret_obj;
     544             :     char *name;
     545             :     const EVP_MD *digest;
     546             : 
     547           0 :     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s*:new", kwlist,
     548             :                                      &name_obj, &view)) {
     549           0 :         return NULL;
     550             :     }
     551             : 
     552           0 :     if (!PyArg_Parse(name_obj, "s", &name)) {
     553           0 :         PyBuffer_Release(&view);
     554           0 :         PyErr_SetString(PyExc_TypeError, "name must be a string");
     555           0 :         return NULL;
     556             :     }
     557             : 
     558           0 :     digest = EVP_get_digestbyname(name);
     559             : 
     560           0 :     ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf,
     561             :                      view.len);
     562           0 :     PyBuffer_Release(&view);
     563             : 
     564           0 :     return ret_obj;
     565             : }
     566             : 
     567             : 
     568             : #if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \
     569             :      && !defined(OPENSSL_NO_SHA))
     570             : 
     571             : #define PY_PBKDF2_HMAC 1
     572             : 
     573             : #if !HAS_FAST_PKCS5_PBKDF2_HMAC
     574             : /* Improved implementation of PKCS5_PBKDF2_HMAC()
     575             :  *
     576             :  * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of
     577             :  * `iter` times. Today (2013) the iteration count is typically 100,000 or
     578             :  * more. The improved algorithm is not subject to a Denial-of-Service
     579             :  * vulnerability with overly large passwords.
     580             :  *
     581             :  * Also OpenSSL < 1.0 don't provide PKCS5_PBKDF2_HMAC(), only
     582             :  * PKCS5_PBKDF2_SHA1.
     583             :  */
     584             : static int
     585           0 : PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
     586             :                        const unsigned char *salt, int saltlen,
     587             :                        int iter, const EVP_MD *digest,
     588             :                        int keylen, unsigned char *out)
     589             : {
     590             :     unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
     591             :     int cplen, j, k, tkeylen, mdlen;
     592           0 :     unsigned long i = 1;
     593             :     HMAC_CTX hctx_tpl, hctx;
     594             : 
     595           0 :     mdlen = EVP_MD_size(digest);
     596           0 :     if (mdlen < 0)
     597           0 :         return 0;
     598             : 
     599           0 :     HMAC_CTX_init(&hctx_tpl);
     600           0 :     HMAC_CTX_init(&hctx);
     601           0 :     p = out;
     602           0 :     tkeylen = keylen;
     603           0 :     if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
     604           0 :         HMAC_CTX_cleanup(&hctx_tpl);
     605           0 :         return 0;
     606             :     }
     607           0 :     while (tkeylen) {
     608           0 :         if (tkeylen > mdlen)
     609           0 :             cplen = mdlen;
     610             :         else
     611           0 :             cplen = tkeylen;
     612             :         /* We are unlikely to ever use more than 256 blocks (5120 bits!)
     613             :          * but just in case...
     614             :          */
     615           0 :         itmp[0] = (unsigned char)((i >> 24) & 0xff);
     616           0 :         itmp[1] = (unsigned char)((i >> 16) & 0xff);
     617           0 :         itmp[2] = (unsigned char)((i >> 8) & 0xff);
     618           0 :         itmp[3] = (unsigned char)(i & 0xff);
     619           0 :         if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
     620           0 :             HMAC_CTX_cleanup(&hctx_tpl);
     621           0 :             return 0;
     622             :         }
     623           0 :         if (!HMAC_Update(&hctx, salt, saltlen)
     624           0 :                 || !HMAC_Update(&hctx, itmp, 4)
     625           0 :                 || !HMAC_Final(&hctx, digtmp, NULL)) {
     626           0 :             HMAC_CTX_cleanup(&hctx_tpl);
     627           0 :             HMAC_CTX_cleanup(&hctx);
     628           0 :             return 0;
     629             :         }
     630           0 :         HMAC_CTX_cleanup(&hctx);
     631           0 :         memcpy(p, digtmp, cplen);
     632           0 :         for (j = 1; j < iter; j++) {
     633           0 :             if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
     634           0 :                 HMAC_CTX_cleanup(&hctx_tpl);
     635           0 :                 return 0;
     636             :             }
     637           0 :             if (!HMAC_Update(&hctx, digtmp, mdlen)
     638           0 :                     || !HMAC_Final(&hctx, digtmp, NULL)) {
     639           0 :                 HMAC_CTX_cleanup(&hctx_tpl);
     640           0 :                 HMAC_CTX_cleanup(&hctx);
     641           0 :                 return 0;
     642             :             }
     643           0 :             HMAC_CTX_cleanup(&hctx);
     644           0 :             for (k = 0; k < cplen; k++) {
     645           0 :                 p[k] ^= digtmp[k];
     646             :             }
     647             :         }
     648           0 :         tkeylen-= cplen;
     649           0 :         i++;
     650           0 :         p+= cplen;
     651             :     }
     652           0 :     HMAC_CTX_cleanup(&hctx_tpl);
     653           0 :     return 1;
     654             : }
     655             : #endif
     656             : 
     657             : 
     658             : PyDoc_STRVAR(pbkdf2_hmac__doc__,
     659             : "pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\
     660             : \n\
     661             : Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as\n\
     662             : pseudorandom function.");
     663             : 
     664             : static PyObject *
     665           0 : pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
     666             : {
     667             :     static char *kwlist[] = {"hash_name", "password", "salt", "iterations",
     668             :                              "dklen", NULL};
     669           0 :     PyObject *key_obj = NULL, *dklen_obj = Py_None;
     670             :     char *name, *key;
     671             :     Py_buffer password, salt;
     672             :     long iterations, dklen;
     673             :     int retval;
     674             :     const EVP_MD *digest;
     675             : 
     676           0 :     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "ss*s*l|O:pbkdf2_hmac",
     677             :                                      kwlist, &name, &password, &salt,
     678             :                                      &iterations, &dklen_obj)) {
     679           0 :         return NULL;
     680             :     }
     681             : 
     682           0 :     digest = EVP_get_digestbyname(name);
     683           0 :     if (digest == NULL) {
     684           0 :         PyErr_SetString(PyExc_ValueError, "unsupported hash type");
     685           0 :         goto end;
     686             :     }
     687             : 
     688           0 :     if (password.len > INT_MAX) {
     689           0 :         PyErr_SetString(PyExc_OverflowError,
     690             :                         "password is too long.");
     691           0 :         goto end;
     692             :     }
     693             : 
     694           0 :     if (salt.len > INT_MAX) {
     695           0 :         PyErr_SetString(PyExc_OverflowError,
     696             :                         "salt is too long.");
     697           0 :         goto end;
     698             :     }
     699             : 
     700           0 :     if (iterations < 1) {
     701           0 :         PyErr_SetString(PyExc_ValueError,
     702             :                         "iteration value must be greater than 0.");
     703           0 :         goto end;
     704             :     }
     705           0 :     if (iterations > INT_MAX) {
     706           0 :         PyErr_SetString(PyExc_OverflowError,
     707             :                         "iteration value is too great.");
     708           0 :         goto end;
     709             :     }
     710             : 
     711           0 :     if (dklen_obj == Py_None) {
     712           0 :         dklen = EVP_MD_size(digest);
     713             :     } else {
     714           0 :         dklen = PyLong_AsLong(dklen_obj);
     715           0 :         if ((dklen == -1) && PyErr_Occurred()) {
     716           0 :             goto end;
     717             :         }
     718             :     }
     719           0 :     if (dklen < 1) {
     720           0 :         PyErr_SetString(PyExc_ValueError,
     721             :                         "key length must be greater than 0.");
     722           0 :         goto end;
     723             :     }
     724           0 :     if (dklen > INT_MAX) {
     725             :         /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */
     726           0 :         PyErr_SetString(PyExc_OverflowError,
     727             :                         "key length is too great.");
     728           0 :         goto end;
     729             :     }
     730             : 
     731           0 :     key_obj = PyBytes_FromStringAndSize(NULL, dklen);
     732           0 :     if (key_obj == NULL) {
     733           0 :         goto end;
     734             :     }
     735           0 :     key = PyBytes_AS_STRING(key_obj);
     736             : 
     737             :     Py_BEGIN_ALLOW_THREADS
     738             : #if HAS_FAST_PKCS5_PBKDF2_HMAC
     739             :     retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len,
     740             :                                (unsigned char *)salt.buf, (int)salt.len,
     741             :                                iterations, digest, dklen,
     742             :                                (unsigned char *)key);
     743             : #else
     744           0 :     retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len,
     745           0 :                                     (unsigned char *)salt.buf, (int)salt.len,
     746             :                                     iterations, digest, dklen,
     747             :                                     (unsigned char *)key);
     748             : #endif
     749             :     Py_END_ALLOW_THREADS
     750             : 
     751           0 :     if (!retval) {
     752           0 :         Py_CLEAR(key_obj);
     753           0 :         _setException(PyExc_ValueError);
     754           0 :         goto end;
     755             :     }
     756             : 
     757             :   end:
     758           0 :     PyBuffer_Release(&password);
     759           0 :     PyBuffer_Release(&salt);
     760           0 :     return key_obj;
     761             : }
     762             : 
     763             : #endif
     764             : 
     765             : /* State for our callback function so that it can accumulate a result. */
     766             : typedef struct _internal_name_mapper_state {
     767             :     PyObject *set;
     768             :     int error;
     769             : } _InternalNameMapperState;
     770             : 
     771             : 
     772             : /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
     773             : static void
     774         159 : _openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg)
     775             : {
     776         159 :     _InternalNameMapperState *state = (_InternalNameMapperState *)arg;
     777             :     PyObject *py_name;
     778             : 
     779             :     assert(state != NULL);
     780         159 :     if (openssl_obj_name == NULL)
     781           0 :         return;
     782             :     /* Ignore aliased names, they pollute the list and OpenSSL appears to
     783             :      * have its own definition of alias as the resulting list still
     784             :      * contains duplicate and alternate names for several algorithms.     */
     785         159 :     if (openssl_obj_name->alias)
     786          87 :         return;
     787             : 
     788          72 :     py_name = PyString_FromString(openssl_obj_name->name);
     789          72 :     if (py_name == NULL) {
     790           0 :         state->error = 1;
     791             :     } else {
     792          72 :         if (PySet_Add(state->set, py_name) != 0) {
     793           0 :             state->error = 1;
     794             :         }
     795          72 :         Py_DECREF(py_name);
     796             :     }
     797             : }
     798             : 
     799             : 
     800             : /* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
     801             : static PyObject*
     802           3 : generate_hash_name_list(void)
     803             : {
     804             :     _InternalNameMapperState state;
     805           3 :     state.set = PyFrozenSet_New(NULL);
     806           3 :     if (state.set == NULL)
     807           0 :         return NULL;
     808           3 :     state.error = 0;
     809             : 
     810           3 :     OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state);
     811             : 
     812           3 :     if (state.error) {
     813           0 :         Py_DECREF(state.set);
     814           0 :         return NULL;
     815             :     }
     816           3 :     return state.set;
     817             : }
     818             : 
     819             : 
     820             : /*
     821             :  *  This macro generates constructor function definitions for specific
     822             :  *  hash algorithms.  These constructors are much faster than calling
     823             :  *  the generic one passing it a python string and are noticeably
     824             :  *  faster than calling a python new() wrapper.  Thats important for
     825             :  *  code that wants to make hashes of a bunch of small strings.
     826             :  */
     827             : #define GEN_CONSTRUCTOR(NAME)  \
     828             :     static PyObject * \
     829             :     EVP_new_ ## NAME (PyObject *self, PyObject *args) \
     830             :     { \
     831             :         Py_buffer view = { 0 }; \
     832             :         PyObject *ret_obj; \
     833             :      \
     834             :         if (!PyArg_ParseTuple(args, "|s*:" #NAME , &view)) { \
     835             :             return NULL; \
     836             :         } \
     837             :      \
     838             :         ret_obj = EVPnew( \
     839             :                     CONST_ ## NAME ## _name_obj, \
     840             :                     NULL, \
     841             :                     CONST_new_ ## NAME ## _ctx_p, \
     842             :                     (unsigned char*)view.buf, view.len); \
     843             :         PyBuffer_Release(&view); \
     844             :         return ret_obj; \
     845             :     }
     846             : 
     847             : /* a PyMethodDef structure for the constructor */
     848             : #define CONSTRUCTOR_METH_DEF(NAME)  \
     849             :     {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
     850             :         PyDoc_STR("Returns a " #NAME \
     851             :                   " hash object; optionally initialized with a string") \
     852             :     }
     853             : 
     854             : /* used in the init function to setup a constructor: initialize OpenSSL
     855             :    constructor constants if they haven't been initialized already.  */
     856             : #define INIT_CONSTRUCTOR_CONSTANTS(NAME)  do { \
     857             :     if (CONST_ ## NAME ## _name_obj == NULL) { \
     858             :     CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \
     859             :         if (EVP_get_digestbyname(#NAME)) { \
     860             :             CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \
     861             :             EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
     862             :         } \
     863             :     } \
     864             : } while (0);
     865             : 
     866           3 : GEN_CONSTRUCTOR(md5)
     867           3 : GEN_CONSTRUCTOR(sha1)
     868             : #ifdef _OPENSSL_SUPPORTS_SHA2
     869           3 : GEN_CONSTRUCTOR(sha224)
     870           3 : GEN_CONSTRUCTOR(sha256)
     871           3 : GEN_CONSTRUCTOR(sha384)
     872           3 : GEN_CONSTRUCTOR(sha512)
     873             : #endif
     874             : 
     875             : /* List of functions exported by this module */
     876             : 
     877             : static struct PyMethodDef EVP_functions[] = {
     878             :     {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
     879             :     CONSTRUCTOR_METH_DEF(md5),
     880             :     CONSTRUCTOR_METH_DEF(sha1),
     881             : #ifdef _OPENSSL_SUPPORTS_SHA2
     882             :     CONSTRUCTOR_METH_DEF(sha224),
     883             :     CONSTRUCTOR_METH_DEF(sha256),
     884             :     CONSTRUCTOR_METH_DEF(sha384),
     885             :     CONSTRUCTOR_METH_DEF(sha512),
     886             : #endif
     887             : #ifdef PY_PBKDF2_HMAC
     888             :     {"pbkdf2_hmac", (PyCFunction)pbkdf2_hmac, METH_VARARGS|METH_KEYWORDS,
     889             :      pbkdf2_hmac__doc__},
     890             : #endif
     891             :     {NULL,      NULL}            /* Sentinel */
     892             : };
     893             : 
     894             : 
     895             : /* Initialize this module. */
     896             : 
     897             : PyMODINIT_FUNC
     898           3 : init_hashlib(void)
     899             : {
     900             :     PyObject *m, *openssl_md_meth_names;
     901             : 
     902           3 :     OpenSSL_add_all_digests();
     903           3 :     ERR_load_crypto_strings();
     904             : 
     905             :     /* TODO build EVP_functions openssl_* entries dynamically based
     906             :      * on what hashes are supported rather than listing many
     907             :      * but having some be unsupported.  Only init appropriate
     908             :      * constants. */
     909             : 
     910           3 :     Py_TYPE(&EVPtype) = &PyType_Type;
     911           3 :     if (PyType_Ready(&EVPtype) < 0)
     912           0 :         return;
     913             : 
     914           3 :     m = Py_InitModule("_hashlib", EVP_functions);
     915           3 :     if (m == NULL)
     916           0 :         return;
     917             : 
     918           3 :     openssl_md_meth_names = generate_hash_name_list();
     919           3 :     if (openssl_md_meth_names == NULL) {
     920           0 :         return;
     921             :     }
     922           3 :     if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) {
     923           0 :         return;
     924             :     }
     925             : 
     926             : #if HASH_OBJ_CONSTRUCTOR
     927             :     Py_INCREF(&EVPtype);
     928             :     PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
     929             : #endif
     930             : 
     931             :     /* these constants are used by the convenience constructors */
     932           3 :     INIT_CONSTRUCTOR_CONSTANTS(md5);
     933           3 :     INIT_CONSTRUCTOR_CONSTANTS(sha1);
     934             : #ifdef _OPENSSL_SUPPORTS_SHA2
     935           3 :     INIT_CONSTRUCTOR_CONSTANTS(sha224);
     936           3 :     INIT_CONSTRUCTOR_CONSTANTS(sha256);
     937           3 :     INIT_CONSTRUCTOR_CONSTANTS(sha384);
     938           3 :     INIT_CONSTRUCTOR_CONSTANTS(sha512);
     939             : #endif
     940             : }

Generated by: LCOV version 1.10