| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | /* Module that wraps all OpenSSL hash algorithms */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-01-09 18:45:30 +00:00
										 |  |  |  * Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |  * Licensed to PSF under a Contributor Agreement. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Derived from a skeleton of shamodule.c containing work performed by: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Andrew Kuchling (amk@amk.ca) | 
					
						
							|  |  |  |  * Greg Stein (gstein@lyra.org) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-01 21:50:07 +00:00
										 |  |  | #define PY_SSIZE_T_CLEAN
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | #include "structmember.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-12 07:35:29 +00:00
										 |  |  | #include "hashlib.h"
 | 
					
						
							| 
									
										
										
										
											2015-04-25 23:42:38 +00:00
										 |  |  | #include "pystrhex.h"
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | /* EVP is the preferred interface to hashing in OpenSSL */ | 
					
						
							|  |  |  | #include <openssl/evp.h>
 | 
					
						
							| 
									
										
										
										
											2018-01-27 09:53:43 +01:00
										 |  |  | #include <openssl/hmac.h>
 | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  | /* We use the object interface to discover what hashes OpenSSL supports. */ | 
					
						
							|  |  |  | #include <openssl/objects.h>
 | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | #include "openssl/err.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MUNCH_SIZE INT_MAX
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
 | 
					
						
							|  |  |  | /* OpenSSL < 1.1.0 */ | 
					
						
							|  |  |  | #define EVP_MD_CTX_new EVP_MD_CTX_create
 | 
					
						
							|  |  |  | #define EVP_MD_CTX_free EVP_MD_CTX_destroy
 | 
					
						
							|  |  |  | #define HAS_FAST_PKCS5_PBKDF2_HMAC 0
 | 
					
						
							|  |  |  | #include <openssl/hmac.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | /* OpenSSL >= 1.1.0 */ | 
					
						
							|  |  |  | #define HAS_FAST_PKCS5_PBKDF2_HMAC 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | typedef struct { | 
					
						
							|  |  |  |     PyObject_HEAD | 
					
						
							|  |  |  |     PyObject            *name;  /* name of this hash algorithm */ | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX          *ctx;   /* OpenSSL message digest context */ | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     PyThread_type_lock   lock;  /* OpenSSL context lock */ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } EVPobject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject EVPtype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DEFINE_CONSTS_FOR_NEW(Name)  \
 | 
					
						
							| 
									
										
										
										
											2013-02-01 17:05:29 -08:00
										 |  |  |     static PyObject *CONST_ ## Name ## _name_obj = NULL; \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-07 21:20:24 +00:00
										 |  |  | DEFINE_CONSTS_FOR_NEW(md5) | 
					
						
							|  |  |  | DEFINE_CONSTS_FOR_NEW(sha1) | 
					
						
							|  |  |  | DEFINE_CONSTS_FOR_NEW(sha224) | 
					
						
							|  |  |  | DEFINE_CONSTS_FOR_NEW(sha256) | 
					
						
							|  |  |  | DEFINE_CONSTS_FOR_NEW(sha384) | 
					
						
							|  |  |  | DEFINE_CONSTS_FOR_NEW(sha512) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | #include "clinic/_hashopenssl.c.h"
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | module _hashlib | 
					
						
							|  |  |  | class _hashlib.HASH "EVPobject *" "&EVPtype" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a881a5092eecad28]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | /* LCOV_EXCL_START */ | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _setException(PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned long errcode; | 
					
						
							|  |  |  |     const char *lib, *func, *reason; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     errcode = ERR_peek_last_error(); | 
					
						
							|  |  |  |     if (!errcode) { | 
					
						
							|  |  |  |         PyErr_SetString(exc, "unknown reasons"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ERR_clear_error(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lib = ERR_lib_error_string(errcode); | 
					
						
							|  |  |  |     func = ERR_func_error_string(errcode); | 
					
						
							|  |  |  |     reason = ERR_reason_error_string(errcode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (lib && func) { | 
					
						
							|  |  |  |         PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (lib) { | 
					
						
							|  |  |  |         PyErr_Format(exc, "[%s] %s", lib, reason); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(exc, reason); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* LCOV_EXCL_STOP */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | static EVPobject * | 
					
						
							|  |  |  | newEVPobject(PyObject *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     if (retval == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 16:45:41 +01:00
										 |  |  |     /* save the name for .name to return */ | 
					
						
							|  |  |  |     Py_INCREF(name); | 
					
						
							|  |  |  |     retval->name = name; | 
					
						
							|  |  |  |     retval->lock = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     retval->ctx = EVP_MD_CTX_new(); | 
					
						
							|  |  |  |     if (retval->ctx == NULL) { | 
					
						
							| 
									
										
										
										
											2019-03-04 16:45:41 +01:00
										 |  |  |         Py_DECREF(retval); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |         PyErr_NoMemory(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  | static void | 
					
						
							|  |  |  | EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned int process; | 
					
						
							|  |  |  |     const unsigned char *cp = (const unsigned char *)vp; | 
					
						
							|  |  |  |     while (0 < len) { | 
					
						
							|  |  |  |         if (len > (Py_ssize_t)MUNCH_SIZE) | 
					
						
							|  |  |  |             process = MUNCH_SIZE; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |         if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { | 
					
						
							|  |  |  |             _setException(PyExc_ValueError); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |         len -= process; | 
					
						
							|  |  |  |         cp += process; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | /* Internal methods for a hash object */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  | EVP_dealloc(EVPobject *self) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     if (self->lock != NULL) | 
					
						
							|  |  |  |         PyThread_free_lock(self->lock); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX_free(self->ctx); | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     Py_XDECREF(self->name); | 
					
						
							|  |  |  |     PyObject_Del(self); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | static int | 
					
						
							|  |  |  | locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     int result; | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  |     ENTER_HASHLIB(self); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     result = EVP_MD_CTX_copy(new_ctx_p, self->ctx); | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  |     LEAVE_HASHLIB(self); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     return result; | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* External methods for a hash object */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.HASH.copy as EVP_copy | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | Return a copy of the hash object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | EVP_copy_impl(EVPobject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     EVPobject *newobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( (newobj = newEVPobject(self->name))==NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { | 
					
						
							| 
									
										
										
										
											2019-03-04 16:45:41 +01:00
										 |  |  |         Py_DECREF(newobj); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |         return _setException(PyExc_ValueError); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     return (PyObject *)newobj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.HASH.digest as EVP_digest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return the digest value as a bytes object. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | EVP_digest_impl(EVPobject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=0f6a3a0da46dc12d input=03561809a419bf00]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char digest[EVP_MAX_MD_SIZE]; | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX *temp_ctx; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     PyObject *retval; | 
					
						
							|  |  |  |     unsigned int digest_size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     temp_ctx = EVP_MD_CTX_new(); | 
					
						
							|  |  |  |     if (temp_ctx == NULL) { | 
					
						
							|  |  |  |         PyErr_NoMemory(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { | 
					
						
							|  |  |  |         return _setException(PyExc_ValueError); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     digest_size = EVP_MD_CTX_size(temp_ctx); | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |     if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { | 
					
						
							|  |  |  |         _setException(PyExc_ValueError); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-26 13:28:38 +00:00
										 |  |  |     retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX_free(temp_ctx); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     return retval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.HASH.hexdigest as EVP_hexdigest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return the digest value as a string of hexadecimal digits. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | EVP_hexdigest_impl(EVPobject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=18e6decbaf197296 input=aff9cf0e4c741a9a]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char digest[EVP_MAX_MD_SIZE]; | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX *temp_ctx; | 
					
						
							| 
									
										
										
										
											2015-04-25 23:42:38 +00:00
										 |  |  |     unsigned int digest_size; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     temp_ctx = EVP_MD_CTX_new(); | 
					
						
							|  |  |  |     if (temp_ctx == NULL) { | 
					
						
							|  |  |  |         PyErr_NoMemory(); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     /* Get the raw (binary) digest value */ | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { | 
					
						
							|  |  |  |         return _setException(PyExc_ValueError); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     digest_size = EVP_MD_CTX_size(temp_ctx); | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |     if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { | 
					
						
							|  |  |  |         _setException(PyExc_ValueError); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     EVP_MD_CTX_free(temp_ctx); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-12 12:06:42 -07:00
										 |  |  |     return _Py_strhex((const char *)digest, (Py_ssize_t)digest_size); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.HASH.update as EVP_update | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     obj: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Update this hash object's state with the provided string. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | EVP_update(EVPobject *self, PyObject *obj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=ec1d55ed2432e966 input=9b30ec848f015501]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-23 02:00:13 +00:00
										 |  |  |     Py_buffer view; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-12 07:35:29 +00:00
										 |  |  |     GET_BUFFER_VIEW_OR_ERROUT(obj, &view); | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { | 
					
						
							|  |  |  |         self->lock = PyThread_allocate_lock(); | 
					
						
							| 
									
										
										
										
											2009-05-04 00:45:33 +00:00
										 |  |  |         /* fail? lock = NULL and we fail over to non-threaded code. */ | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     if (self->lock != NULL) { | 
					
						
							|  |  |  |         Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |         PyThread_acquire_lock(self->lock, 1); | 
					
						
							|  |  |  |         EVP_hash(self, view.buf, view.len); | 
					
						
							|  |  |  |         PyThread_release_lock(self->lock); | 
					
						
							|  |  |  |         Py_END_ALLOW_THREADS | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         EVP_hash(self, view.buf, view.len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PyBuffer_Release(&view); | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef EVP_methods[] = { | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     EVP_UPDATE_METHODDEF | 
					
						
							|  |  |  |     EVP_DIGEST_METHODDEF | 
					
						
							|  |  |  |     EVP_HEXDIGEST_METHODDEF | 
					
						
							|  |  |  |     EVP_COPY_METHODDEF | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     {NULL, NULL}  /* sentinel */ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | EVP_get_block_size(EVPobject *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     long block_size; | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     block_size = EVP_MD_CTX_block_size(self->ctx); | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     return PyLong_FromLong(block_size); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | EVP_get_digest_size(EVPobject *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     long size; | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |     size = EVP_MD_CTX_size(self->ctx); | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     return PyLong_FromLong(size); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMemberDef EVP_members[] = { | 
					
						
							|  |  |  |     {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")}, | 
					
						
							|  |  |  |     {NULL}  /* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyGetSetDef EVP_getseters[] = { | 
					
						
							|  |  |  |     {"digest_size", | 
					
						
							|  |  |  |      (getter)EVP_get_digest_size, NULL, | 
					
						
							|  |  |  |      NULL, | 
					
						
							|  |  |  |      NULL}, | 
					
						
							|  |  |  |     {"block_size", | 
					
						
							|  |  |  |      (getter)EVP_get_block_size, NULL, | 
					
						
							|  |  |  |      NULL, | 
					
						
							|  |  |  |      NULL}, | 
					
						
							|  |  |  |     {NULL}  /* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  | EVP_repr(EVPobject *self) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-03-12 17:00:41 +00:00
										 |  |  |     return PyUnicode_FromFormat("<%U HASH object @ %p>", self->name, self); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-30 17:54:53 -08:00
										 |  |  | PyDoc_STRVAR(hashtype_doc, | 
					
						
							|  |  |  | "HASH(name, string=b\'\')\n" | 
					
						
							|  |  |  | "--\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "A hash is an object used to calculate a checksum of a string of information.\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Methods:\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "update() -- updates the current digest with an additional string\n" | 
					
						
							|  |  |  | "digest() -- return the current digest value\n" | 
					
						
							|  |  |  | "hexdigest() -- return the current digest as a string of hexadecimal digits\n" | 
					
						
							|  |  |  | "copy() -- return a copy of the current hash object\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "Attributes:\n" | 
					
						
							|  |  |  | "\n" | 
					
						
							|  |  |  | "name -- the hash algorithm being used by this object\n" | 
					
						
							|  |  |  | "digest_size -- number of bytes in this hashes output"); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject EVPtype = { | 
					
						
							| 
									
										
											  
											
												Merged revisions 56467-56482 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk
................
  r56477 | martin.v.loewis | 2007-07-21 09:04:38 +0200 (Sa, 21 Jul 2007) | 11 lines
  Merged revisions 56466-56476 via svnmerge from
  svn+ssh://pythondev@svn.python.org/python/trunk
  ........
    r56476 | martin.v.loewis | 2007-07-21 08:55:02 +0200 (Sa, 21 Jul 2007) | 4 lines
    PEP 3123: Provide forward compatibility with Python 3.0, while keeping
    backwards compatibility. Add Py_Refcnt, Py_Type, Py_Size, and
    PyVarObject_HEAD_INIT.
  ........
................
  r56478 | martin.v.loewis | 2007-07-21 09:47:23 +0200 (Sa, 21 Jul 2007) | 2 lines
  PEP 3123: Use proper C inheritance for PyObject.
................
  r56479 | martin.v.loewis | 2007-07-21 10:06:55 +0200 (Sa, 21 Jul 2007) | 3 lines
  Add longintrepr.h to Python.h, so that the compiler can
  see that PyFalse is really some kind of PyObject*.
................
  r56480 | martin.v.loewis | 2007-07-21 10:47:18 +0200 (Sa, 21 Jul 2007) | 2 lines
  Qualify SHIFT, MASK, BASE.
................
  r56482 | martin.v.loewis | 2007-07-21 19:10:57 +0200 (Sa, 21 Jul 2007) | 2 lines
  Correctly refer to _ob_next.
................
											
										 
											2007-07-21 17:22:18 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     "_hashlib.HASH",    /*tp_name*/ | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     sizeof(EVPobject),  /*tp_basicsize*/ | 
					
						
							|  |  |  |     0,                  /*tp_itemsize*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     /* methods */ | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     (destructor)EVP_dealloc, /*tp_dealloc*/ | 
					
						
							|  |  |  |     0,                  /*tp_print*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     0,                  /*tp_getattr*/ | 
					
						
							|  |  |  |     0,                  /*tp_setattr*/ | 
					
						
							| 
									
										
										
										
											2009-02-02 20:36:42 +00:00
										 |  |  |     0,                  /*tp_reserved*/ | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     (reprfunc)EVP_repr, /*tp_repr*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     0,                  /*tp_as_number*/ | 
					
						
							|  |  |  |     0,                  /*tp_as_sequence*/ | 
					
						
							|  |  |  |     0,                  /*tp_as_mapping*/ | 
					
						
							|  |  |  |     0,                  /*tp_hash*/ | 
					
						
							|  |  |  |     0,                  /*tp_call*/ | 
					
						
							|  |  |  |     0,                  /*tp_str*/ | 
					
						
							|  |  |  |     0,                  /*tp_getattro*/ | 
					
						
							|  |  |  |     0,                  /*tp_setattro*/ | 
					
						
							|  |  |  |     0,                  /*tp_as_buffer*/ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | 
					
						
							| 
									
										
										
										
											2018-12-30 17:54:53 -08:00
										 |  |  |     hashtype_doc,       /*tp_doc*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     0,                  /*tp_traverse*/ | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     0,                  /*tp_clear*/ | 
					
						
							|  |  |  |     0,                  /*tp_richcompare*/ | 
					
						
							|  |  |  |     0,                  /*tp_weaklistoffset*/ | 
					
						
							|  |  |  |     0,                  /*tp_iter*/ | 
					
						
							|  |  |  |     0,                  /*tp_iternext*/ | 
					
						
							|  |  |  |     EVP_methods,        /* tp_methods */ | 
					
						
							|  |  |  |     EVP_members,        /* tp_members */ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     EVP_getseters,      /* tp_getset */ | 
					
						
							|  |  |  |     0,                  /* tp_base */ | 
					
						
							|  |  |  |     0,                  /* tp_dict */ | 
					
						
							|  |  |  |     0,                  /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                  /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                  /* tp_dictoffset */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | EVPnew(PyObject *name_obj, | 
					
						
							|  |  |  |        const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |        const unsigned char *cp, Py_ssize_t len) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     EVPobject *self; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!digest && !initial_ctx) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, "unsupported hash type"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((self = newEVPobject(name_obj)) == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (initial_ctx) { | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |         EVP_MD_CTX_copy(self->ctx, initial_ctx); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |         if (!EVP_DigestInit(self->ctx, digest)) { | 
					
						
							|  |  |  |             _setException(PyExc_ValueError); | 
					
						
							|  |  |  |             Py_DECREF(self); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |     if (cp && len) { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |         if (len >= HASHLIB_GIL_MINSIZE) { | 
					
						
							|  |  |  |             Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |             EVP_hash(self, cp, len); | 
					
						
							|  |  |  |             Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |             EVP_hash(self, cp, len); | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The module-level function: new() */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.new as EVP_new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     name as name_obj: object | 
					
						
							|  |  |  |     string as data_obj: object(py_default="b''") = NULL | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return a new hash object using the named algorithm. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An optional string argument may be provided and will be | 
					
						
							|  |  |  | automatically hashed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The MD5 and SHA1 algorithms are always supported. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=9e7cf664e04b0226 input=1c46e40e0fec91f3]*/ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-23 02:00:13 +00:00
										 |  |  |     Py_buffer view = { 0 }; | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |     PyObject *ret_obj; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     char *name; | 
					
						
							|  |  |  |     const EVP_MD *digest; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_Parse(name_obj, "s", &name)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "name must be a string"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |     if (data_obj) | 
					
						
							| 
									
										
										
										
											2009-02-12 07:35:29 +00:00
										 |  |  |         GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     digest = EVP_get_digestbyname(name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |     ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len); | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (data_obj) | 
					
						
							| 
									
										
										
										
											2008-08-13 15:53:07 +00:00
										 |  |  |         PyBuffer_Release(&view); | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |     return ret_obj; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-19 17:59:48 +02:00
										 |  |  | #if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \
 | 
					
						
							|  |  |  |      && !defined(OPENSSL_NO_SHA)) | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | #define PY_PBKDF2_HMAC 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | #if !HAS_FAST_PKCS5_PBKDF2_HMAC
 | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  | /* Improved implementation of PKCS5_PBKDF2_HMAC()
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of | 
					
						
							|  |  |  |  * `iter` times. Today (2013) the iteration count is typically 100,000 or | 
					
						
							|  |  |  |  * more. The improved algorithm is not subject to a Denial-of-Service | 
					
						
							|  |  |  |  * vulnerability with overly large passwords. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Also OpenSSL < 1.0 don't provide PKCS5_PBKDF2_HMAC(), only | 
					
						
							|  |  |  |  * PKCS5_PBKDF2_SHA1. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-10-20 13:23:03 +02:00
										 |  |  | static int | 
					
						
							|  |  |  | PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, | 
					
						
							|  |  |  |                        const unsigned char *salt, int saltlen, | 
					
						
							|  |  |  |                        int iter, const EVP_MD *digest, | 
					
						
							|  |  |  |                        int keylen, unsigned char *out) | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; | 
					
						
							|  |  |  |     int cplen, j, k, tkeylen, mdlen; | 
					
						
							|  |  |  |     unsigned long i = 1; | 
					
						
							|  |  |  |     HMAC_CTX hctx_tpl, hctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mdlen = EVP_MD_size(digest); | 
					
						
							|  |  |  |     if (mdlen < 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HMAC_CTX_init(&hctx_tpl); | 
					
						
							|  |  |  |     HMAC_CTX_init(&hctx); | 
					
						
							|  |  |  |     p = out; | 
					
						
							|  |  |  |     tkeylen = keylen; | 
					
						
							|  |  |  |     if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { | 
					
						
							|  |  |  |         HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-27 02:13:40 -07:00
										 |  |  |     while (tkeylen) { | 
					
						
							|  |  |  |         if (tkeylen > mdlen) | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  |             cplen = mdlen; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             cplen = tkeylen; | 
					
						
							|  |  |  |         /* We are unlikely to ever use more than 256 blocks (5120 bits!)
 | 
					
						
							|  |  |  |          * but just in case... | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         itmp[0] = (unsigned char)((i >> 24) & 0xff); | 
					
						
							|  |  |  |         itmp[1] = (unsigned char)((i >> 16) & 0xff); | 
					
						
							|  |  |  |         itmp[2] = (unsigned char)((i >> 8) & 0xff); | 
					
						
							|  |  |  |         itmp[3] = (unsigned char)(i & 0xff); | 
					
						
							|  |  |  |         if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { | 
					
						
							|  |  |  |             HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!HMAC_Update(&hctx, salt, saltlen) | 
					
						
							|  |  |  |                 || !HMAC_Update(&hctx, itmp, 4) | 
					
						
							|  |  |  |                 || !HMAC_Final(&hctx, digtmp, NULL)) { | 
					
						
							|  |  |  |             HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |             HMAC_CTX_cleanup(&hctx); | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-11-06 17:25:17 +01:00
										 |  |  |         HMAC_CTX_cleanup(&hctx); | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  |         memcpy(p, digtmp, cplen); | 
					
						
							|  |  |  |         for (j = 1; j < iter; j++) { | 
					
						
							|  |  |  |             if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { | 
					
						
							|  |  |  |                 HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!HMAC_Update(&hctx, digtmp, mdlen) | 
					
						
							|  |  |  |                     || !HMAC_Final(&hctx, digtmp, NULL)) { | 
					
						
							|  |  |  |                 HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |                 HMAC_CTX_cleanup(&hctx); | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             HMAC_CTX_cleanup(&hctx); | 
					
						
							|  |  |  |             for (k = 0; k < cplen; k++) { | 
					
						
							|  |  |  |                 p[k] ^= digtmp[k]; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         tkeylen-= cplen; | 
					
						
							|  |  |  |         i++; | 
					
						
							|  |  |  |         p+= cplen; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     HMAC_CTX_cleanup(&hctx_tpl); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.pbkdf2_hmac as pbkdf2_hmac | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hash_name: str | 
					
						
							|  |  |  |     password: Py_buffer | 
					
						
							|  |  |  |     salt: Py_buffer | 
					
						
							|  |  |  |     iterations: long | 
					
						
							|  |  |  |     dklen as dklen_obj: object = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  | pbkdf2_hmac_impl(PyObject *module, const char *hash_name, | 
					
						
							|  |  |  |                  Py_buffer *password, Py_buffer *salt, long iterations, | 
					
						
							|  |  |  |                  PyObject *dklen_obj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=144b76005416599b input=ed3ab0d2d28b5d5c]*/ | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     PyObject *key_obj = NULL; | 
					
						
							|  |  |  |     char *key; | 
					
						
							|  |  |  |     long dklen; | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  |     int retval; | 
					
						
							|  |  |  |     const EVP_MD *digest; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     digest = EVP_get_digestbyname(hash_name); | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  |     if (digest == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, "unsupported hash type"); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     if (password->len > INT_MAX) { | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "password is too long."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     if (salt->len > INT_MAX) { | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "salt is too long."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (iterations < 1) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                         "iteration value must be greater than 0."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (iterations > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "iteration value is too great."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dklen_obj == Py_None) { | 
					
						
							|  |  |  |         dklen = EVP_MD_size(digest); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         dklen = PyLong_AsLong(dklen_obj); | 
					
						
							|  |  |  |         if ((dklen == -1) && PyErr_Occurred()) { | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dklen < 1) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                         "key length must be greater than 0."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dklen > INT_MAX) { | 
					
						
							|  |  |  |         /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */ | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "key length is too great."); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_obj = PyBytes_FromStringAndSize(NULL, dklen); | 
					
						
							|  |  |  |     if (key_obj == NULL) { | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     key = PyBytes_AS_STRING(key_obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_BEGIN_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | #if HAS_FAST_PKCS5_PBKDF2_HMAC
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     retval = PKCS5_PBKDF2_HMAC((char*)password->buf, (int)password->len, | 
					
						
							|  |  |  |                                (unsigned char *)salt->buf, (int)salt->len, | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  |                                iterations, digest, dklen, | 
					
						
							|  |  |  |                                (unsigned char *)key); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     retval = PKCS5_PBKDF2_HMAC_fast((char*)password->buf, (int)password->len, | 
					
						
							|  |  |  |                                     (unsigned char *)salt->buf, (int)salt->len, | 
					
						
							| 
									
										
										
										
											2013-10-19 14:24:44 +02:00
										 |  |  |                                     iterations, digest, dklen, | 
					
						
							|  |  |  |                                     (unsigned char *)key); | 
					
						
							| 
									
										
										
										
											2016-09-05 23:19:05 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  |     Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!retval) { | 
					
						
							|  |  |  |         Py_CLEAR(key_obj); | 
					
						
							|  |  |  |         _setException(PyExc_ValueError); | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   end: | 
					
						
							|  |  |  |     return key_obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 20:22:28 +02:00
										 |  |  | #if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)
 | 
					
						
							|  |  |  | #define PY_SCRYPT 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 09:50:16 +03:00
										 |  |  | /* XXX: Parameters salt, n, r and p should be required keyword-only parameters.
 | 
					
						
							|  |  |  |    They are optional in the Argument Clinic declaration only due to a | 
					
						
							|  |  |  |    limitation of PyArg_ParseTupleAndKeywords. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 20:22:28 +02:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.scrypt | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     password: Py_buffer | 
					
						
							|  |  |  |     * | 
					
						
							|  |  |  |     salt: Py_buffer = None | 
					
						
							|  |  |  |     n as n_obj: object(subclass_of='&PyLong_Type') = None | 
					
						
							|  |  |  |     r as r_obj: object(subclass_of='&PyLong_Type') = None | 
					
						
							|  |  |  |     p as p_obj: object(subclass_of='&PyLong_Type') = None | 
					
						
							|  |  |  |     maxmem: long = 0 | 
					
						
							|  |  |  |     dklen: long = 64 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | scrypt password-based key derivation function. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, | 
					
						
							|  |  |  |                      PyObject *n_obj, PyObject *r_obj, PyObject *p_obj, | 
					
						
							|  |  |  |                      long maxmem, long dklen) | 
					
						
							|  |  |  | /*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *key_obj = NULL; | 
					
						
							|  |  |  |     char *key; | 
					
						
							|  |  |  |     int retval; | 
					
						
							|  |  |  |     unsigned long n, r, p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (password->len > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "password is too long."); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (salt->buf == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "salt is required"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (salt->len > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "salt is too long."); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     n = PyLong_AsUnsignedLong(n_obj); | 
					
						
							|  |  |  |     if (n == (unsigned long) -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "n is required and must be an unsigned int"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (n < 2 || n & (n - 1)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, | 
					
						
							|  |  |  |                         "n must be a power of 2."); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     r = PyLong_AsUnsignedLong(r_obj); | 
					
						
							|  |  |  |     if (r == (unsigned long) -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                          "r is required and must be an unsigned int"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p = PyLong_AsUnsignedLong(p_obj); | 
					
						
							|  |  |  |     if (p == (unsigned long) -1 && PyErr_Occurred()) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                          "p is required and must be an unsigned int"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (maxmem < 0 || maxmem > INT_MAX) { | 
					
						
							| 
									
										
										
										
											2017-11-08 14:44:44 -08:00
										 |  |  |         /* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the
 | 
					
						
							| 
									
										
										
										
											2016-09-06 20:22:28 +02:00
										 |  |  |            future. The maxmem constant is private to OpenSSL. */ | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                      "maxmem must be positive and smaller than %d", | 
					
						
							|  |  |  |                       INT_MAX); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (dklen < 1 || dklen > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                     "dklen must be greater than 0 and smaller than %d", | 
					
						
							|  |  |  |                     INT_MAX); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* let OpenSSL validate the rest */ | 
					
						
							|  |  |  |     retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); | 
					
						
							|  |  |  |     if (!retval) { | 
					
						
							|  |  |  |         /* sorry, can't do much better */ | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, | 
					
						
							| 
									
										
										
										
											2019-03-06 11:35:35 -03:00
										 |  |  |                         "Invalid parameter combination for n, r, p, maxmem."); | 
					
						
							| 
									
										
										
										
											2016-09-06 20:22:28 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_obj = PyBytes_FromStringAndSize(NULL, dklen); | 
					
						
							|  |  |  |     if (key_obj == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     key = PyBytes_AS_STRING(key_obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |     retval = EVP_PBE_scrypt( | 
					
						
							|  |  |  |         (const char*)password->buf, (size_t)password->len, | 
					
						
							|  |  |  |         (const unsigned char *)salt->buf, (size_t)salt->len, | 
					
						
							|  |  |  |         n, r, p, maxmem, | 
					
						
							|  |  |  |         (unsigned char *)key, (size_t)dklen | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!retval) { | 
					
						
							|  |  |  |         Py_CLEAR(key_obj); | 
					
						
							|  |  |  |         _setException(PyExc_ValueError); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return key_obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-27 09:53:43 +01:00
										 |  |  | /* Fast HMAC for hmac.digest()
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _hashlib.hmac_digest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key: Py_buffer | 
					
						
							|  |  |  |     msg: Py_buffer | 
					
						
							|  |  |  |     digest: str | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-31 09:50:16 +03:00
										 |  |  | Single-shot HMAC. | 
					
						
							| 
									
										
										
										
											2018-01-27 09:53:43 +01:00
										 |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _hashlib_hmac_digest_impl(PyObject *module, Py_buffer *key, Py_buffer *msg, | 
					
						
							|  |  |  |                           const char *digest) | 
					
						
							| 
									
										
										
										
											2018-07-31 09:50:16 +03:00
										 |  |  | /*[clinic end generated code: output=75630e684cdd8762 input=562d2f4249511bd3]*/ | 
					
						
							| 
									
										
										
										
											2018-01-27 09:53:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char md[EVP_MAX_MD_SIZE] = {0}; | 
					
						
							|  |  |  |     unsigned int md_len = 0; | 
					
						
							|  |  |  |     unsigned char *result; | 
					
						
							|  |  |  |     const EVP_MD *evp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     evp = EVP_get_digestbyname(digest); | 
					
						
							|  |  |  |     if (evp == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, "unsupported hash type"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (key->len > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "key is too long."); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (msg->len > INT_MAX) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                         "msg is too long."); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  |     result = HMAC( | 
					
						
							|  |  |  |         evp, | 
					
						
							|  |  |  |         (const void*)key->buf, (int)key->len, | 
					
						
							|  |  |  |         (const unsigned char*)msg->buf, (int)msg->len, | 
					
						
							|  |  |  |         md, &md_len | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (result == NULL) { | 
					
						
							|  |  |  |         _setException(PyExc_ValueError); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyBytes_FromStringAndSize((const char*)md, md_len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  | /* State for our callback function so that it can accumulate a result. */ | 
					
						
							|  |  |  | typedef struct _internal_name_mapper_state { | 
					
						
							|  |  |  |     PyObject *set; | 
					
						
							|  |  |  |     int error; | 
					
						
							|  |  |  | } _InternalNameMapperState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _InternalNameMapperState *state = (_InternalNameMapperState *)arg; | 
					
						
							|  |  |  |     PyObject *py_name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(state != NULL); | 
					
						
							|  |  |  |     if (openssl_obj_name == NULL) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     /* Ignore aliased names, they pollute the list and OpenSSL appears to
 | 
					
						
							| 
									
										
										
										
											2015-11-02 03:37:02 +00:00
										 |  |  |      * have its own definition of alias as the resulting list still | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  |      * contains duplicate and alternate names for several algorithms.     */ | 
					
						
							|  |  |  |     if (openssl_obj_name->alias) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     py_name = PyUnicode_FromString(openssl_obj_name->name); | 
					
						
							|  |  |  |     if (py_name == NULL) { | 
					
						
							|  |  |  |         state->error = 1; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         if (PySet_Add(state->set, py_name) != 0) { | 
					
						
							|  |  |  |             state->error = 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-10-29 12:14:55 +01:00
										 |  |  |         Py_DECREF(py_name); | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */ | 
					
						
							|  |  |  | static PyObject* | 
					
						
							|  |  |  | generate_hash_name_list(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _InternalNameMapperState state; | 
					
						
							|  |  |  |     state.set = PyFrozenSet_New(NULL); | 
					
						
							|  |  |  |     if (state.set == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     state.error = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (state.error) { | 
					
						
							|  |  |  |         Py_DECREF(state.set); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return state.set; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  This macro generates constructor function definitions for specific | 
					
						
							|  |  |  |  *  hash algorithms.  These constructors are much faster than calling | 
					
						
							| 
									
										
										
										
											2016-08-30 10:47:49 -07:00
										 |  |  |  *  the generic one passing it a python string and are noticeably | 
					
						
							| 
									
										
										
										
											2018-02-03 18:36:10 -06:00
										 |  |  |  *  faster than calling a python new() wrapper.  That is important for | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |  *  code that wants to make hashes of a bunch of small strings. | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |  *  The first call will lazy-initialize, which reports an exception | 
					
						
							|  |  |  |  *  if initialization fails. | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | #define GEN_CONSTRUCTOR(NAME)  \
 | 
					
						
							|  |  |  |     static PyObject * \ | 
					
						
							| 
									
										
										
										
											2017-12-15 13:11:11 +02:00
										 |  |  |     EVP_new_ ## NAME (PyObject *self, PyObject *const *args, Py_ssize_t nargs) \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     { \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |         PyObject *data_obj = NULL; \ | 
					
						
							| 
									
										
										
										
											2007-09-23 02:00:13 +00:00
										 |  |  |         Py_buffer view = { 0 }; \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |         PyObject *ret_obj; \ | 
					
						
							| 
									
										
										
										
											2017-01-17 04:20:26 +01:00
										 |  |  |      \ | 
					
						
							| 
									
										
										
										
											2017-06-15 17:05:23 +02:00
										 |  |  |         if (!_PyArg_ParseStack(args, nargs, "|O:" #NAME , &data_obj)) { \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |             return NULL; \ | 
					
						
							|  |  |  |         } \ | 
					
						
							| 
									
										
										
										
											2017-05-24 00:04:38 -07:00
										 |  |  |      \ | 
					
						
							|  |  |  |         if (CONST_new_ ## NAME ## _ctx_p == NULL) { \ | 
					
						
							|  |  |  |             EVP_MD_CTX *ctx_p = EVP_MD_CTX_new(); \ | 
					
						
							|  |  |  |             if (!EVP_get_digestbyname(#NAME) || \ | 
					
						
							|  |  |  |                 !EVP_DigestInit(ctx_p, EVP_get_digestbyname(#NAME))) { \ | 
					
						
							|  |  |  |                 _setException(PyExc_ValueError); \ | 
					
						
							|  |  |  |                 EVP_MD_CTX_free(ctx_p); \ | 
					
						
							|  |  |  |                 return NULL; \ | 
					
						
							|  |  |  |             } \ | 
					
						
							|  |  |  |             CONST_new_ ## NAME ## _ctx_p = ctx_p; \ | 
					
						
							|  |  |  |         } \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |      \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |         if (data_obj) \ | 
					
						
							| 
									
										
										
										
											2009-02-12 07:35:29 +00:00
										 |  |  |             GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |      \ | 
					
						
							|  |  |  |         ret_obj = EVPnew( \ | 
					
						
							|  |  |  |                     CONST_ ## NAME ## _name_obj, \ | 
					
						
							|  |  |  |                     NULL, \ | 
					
						
							|  |  |  |                     CONST_new_ ## NAME ## _ctx_p, \ | 
					
						
							|  |  |  |                     (unsigned char*)view.buf, \ | 
					
						
							| 
									
										
										
										
											2008-09-24 22:53:33 +00:00
										 |  |  |                     view.len); \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |      \ | 
					
						
							|  |  |  |         if (data_obj) \ | 
					
						
							| 
									
										
										
										
											2008-08-13 15:53:07 +00:00
										 |  |  |             PyBuffer_Release(&view); \ | 
					
						
							| 
									
										
										
										
											2007-08-26 02:58:36 +00:00
										 |  |  |         return ret_obj; \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* a PyMethodDef structure for the constructor */ | 
					
						
							|  |  |  | #define CONSTRUCTOR_METH_DEF(NAME)  \
 | 
					
						
							| 
									
										
										
										
											2018-11-27 13:27:31 +02:00
										 |  |  |     {"openssl_" #NAME, (PyCFunction)(void(*)(void))EVP_new_ ## NAME, METH_FASTCALL, \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |         PyDoc_STR("Returns a " #NAME \ | 
					
						
							|  |  |  |                   " hash object; optionally initialized with a string") \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-01 17:05:29 -08:00
										 |  |  | /* used in the init function to setup a constructor: initialize OpenSSL
 | 
					
						
							|  |  |  |    constructor constants if they haven't been initialized already.  */ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | #define INIT_CONSTRUCTOR_CONSTANTS(NAME)  do { \
 | 
					
						
							| 
									
										
										
										
											2013-02-01 17:05:29 -08:00
										 |  |  |     if (CONST_ ## NAME ## _name_obj == NULL) { \ | 
					
						
							|  |  |  |         CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     } \ | 
					
						
							|  |  |  | } while (0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(md5) | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(sha1) | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(sha224) | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(sha256) | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(sha384) | 
					
						
							|  |  |  | GEN_CONSTRUCTOR(sha512) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* List of functions exported by this module */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef EVP_functions[] = { | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     EVP_NEW_METHODDEF | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | #ifdef PY_PBKDF2_HMAC
 | 
					
						
							| 
									
										
										
										
											2018-12-27 15:43:43 +02:00
										 |  |  |     PBKDF2_HMAC_METHODDEF | 
					
						
							| 
									
										
										
										
											2013-10-13 00:52:43 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-06 20:22:28 +02:00
										 |  |  |     _HASHLIB_SCRYPT_METHODDEF | 
					
						
							| 
									
										
										
										
											2018-01-27 09:53:43 +01:00
										 |  |  |     _HASHLIB_HMAC_DIGEST_METHODDEF | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     CONSTRUCTOR_METH_DEF(md5), | 
					
						
							|  |  |  |     CONSTRUCTOR_METH_DEF(sha1), | 
					
						
							|  |  |  |     CONSTRUCTOR_METH_DEF(sha224), | 
					
						
							|  |  |  |     CONSTRUCTOR_METH_DEF(sha256), | 
					
						
							|  |  |  |     CONSTRUCTOR_METH_DEF(sha384), | 
					
						
							|  |  |  |     CONSTRUCTOR_METH_DEF(sha512), | 
					
						
							| 
									
										
										
										
											2010-08-11 17:31:17 +00:00
										 |  |  |     {NULL,      NULL}            /* Sentinel */ | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Initialize this module. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef _hashlibmodule = { | 
					
						
							| 
									
										
										
										
											2009-01-08 21:17:16 +00:00
										 |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     "_hashlib", | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     -1, | 
					
						
							|  |  |  |     EVP_functions, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | PyMODINIT_FUNC | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | PyInit__hashlib(void) | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  |     PyObject *m, *openssl_md_meth_names; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-05 15:47:11 +02:00
										 |  |  | #ifndef OPENSSL_VERSION_1_1
 | 
					
						
							|  |  |  |     /* Load all digest algorithms and initialize cpuid */ | 
					
						
							|  |  |  |     OPENSSL_add_all_algorithms_noconf(); | 
					
						
							| 
									
										
										
										
											2013-10-21 19:48:22 +02:00
										 |  |  |     ERR_load_crypto_strings(); | 
					
						
							| 
									
										
										
										
											2017-09-05 15:47:11 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* TODO build EVP_functions openssl_* entries dynamically based
 | 
					
						
							|  |  |  |      * on what hashes are supported rather than listing many | 
					
						
							|  |  |  |      * but having some be unsupported.  Only init appropriate | 
					
						
							|  |  |  |      * constants. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-19 02:45:37 +00:00
										 |  |  |     Py_TYPE(&EVPtype) = &PyType_Type; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     if (PyType_Ready(&EVPtype) < 0) | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  |     m = PyModule_Create(&_hashlibmodule); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     if (m == NULL) | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-06 08:30:23 +00:00
										 |  |  |     openssl_md_meth_names = generate_hash_name_list(); | 
					
						
							|  |  |  |     if (openssl_md_meth_names == NULL) { | 
					
						
							|  |  |  |         Py_DECREF(m); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) { | 
					
						
							|  |  |  |         Py_DECREF(m); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-22 15:05:23 +02:00
										 |  |  |     Py_INCREF((PyObject *)&EVPtype); | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  |     PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* these constants are used by the convenience constructors */ | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(md5); | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(sha1); | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(sha224); | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(sha256); | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(sha384); | 
					
						
							|  |  |  |     INIT_CONSTRUCTOR_CONSTANTS(sha512); | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  |     return m; | 
					
						
							| 
									
										
										
										
											2005-08-21 18:45:59 +00:00
										 |  |  | } |