Skip to content
Prev Previous commit
Next Next commit
Address review comment
  • Loading branch information
tiran committed Jan 8, 2022
commit 733b7896c88d379184562c38bd7305719e1063fc
142 changes: 61 additions & 81 deletions Modules/_hashopenssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ typedef struct {
const char *py_alias;
const char *ossl_name;
int ossl_nid;
Py_ssize_t refcnt;
int refcnt;
PY_EVP_MD *evp;
PY_EVP_MD *evp_nosecurity;
} py_hashentry_t;
Expand All @@ -95,27 +95,19 @@ typedef struct {
#define Py_hash_sha256 "sha256"
#define Py_hash_sha384 "sha384"
#define Py_hash_sha512 "sha512"
#ifdef NID_sha512_224
#define Py_hash_sha512_224 "sha512_224"
#define Py_hash_sha512_256 "sha512_256"
#endif
#ifdef PY_OPENSSL_HAS_SHA3
#define Py_hash_sha3_224 "sha3_224"
#define Py_hash_sha3_256 "sha3_256"
#define Py_hash_sha3_384 "sha3_384"
#define Py_hash_sha3_512 "sha3_512"
#endif
#ifdef PY_OPENSSL_HAS_SHAKE
#define Py_hash_shake_128 "shake_128"
#define Py_hash_shake_256 "shake_256"
#endif
#ifdef PY_OPENSSL_HAS_BLAKE2
#define Py_hash_blake2s "blake2s"
#define Py_hash_blake2b "blake2b"
#endif

#define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \
{py_name, py_alias, ossl_name, ossl_nid, 0, NULL}
{py_name, py_alias, ossl_name, ossl_nid, 0, NULL, NULL}

static const py_hashentry_t py_hashes[] = {
/* md5 */
Expand All @@ -127,28 +119,20 @@ static const py_hashentry_t py_hashes[] = {
PY_HASH_ENTRY(Py_hash_sha256, "SHA256", SN_sha256, NID_sha256),
PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384),
PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512),
#ifdef NID_sha512_224
/* truncated sha2 */
PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224),
PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256),
#endif
#ifdef PY_OPENSSL_HAS_SHA3
/* sha3 */
PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224),
PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256),
PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384),
PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512),
#endif
#ifdef PY_OPENSSL_HAS_SHAKE
/* sha3 shake */
PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128),
PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256),
#endif
#ifdef PY_OPENSSL_HAS_BLAKE2
/* blake2 digest */
PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256),
PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512),
#endif
PY_HASH_ENTRY(NULL, NULL, NULL, 0),
};

Expand Down Expand Up @@ -278,7 +262,7 @@ _setException(PyObject *exc, const char* altmsg, ...)
#endif
if (!errcode) {
if (altmsg == NULL) {
PyErr_SetString(exc, "unknown reasons");
PyErr_SetString(exc, "no reason supplied");
} else {
PyErr_FormatV(exc, altmsg, vargs);
}
Expand Down Expand Up @@ -336,10 +320,14 @@ static PY_EVP_MD*
py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht)
{
PY_EVP_MD *digest = NULL;
#if 1
_hashlibstate *state = get_hashlib_state(module);
py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get(
state->hashtable, (const void*)name
);
#else
py_hashentry_t *entry = NULL;
#endif

if (entry != NULL) {
switch (py_ht) {
Expand All @@ -362,7 +350,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht)
PY_EVP_MD_up_ref(digest);
}
} else {
// fall back for OpenSSL
// Fall back for looking up an unindexed OpenSSL specific name.
switch (py_ht) {
case Py_ht_evp:
case Py_ht_mac:
Expand Down Expand Up @@ -868,83 +856,75 @@ static PyType_Spec EVPXOFtype_spec = {

#endif

static PyObject *
EVPnew(PyObject *module, PY_EVP_MD *digest,
const unsigned char *cp, Py_ssize_t len, int usedforsecurity)
static PyObject*
py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj,
int usedforsecurity)
{
int result = 0;
Py_buffer view = { 0 };
PY_EVP_MD *digest = NULL;
PyTypeObject *type;
EVPobject *self = NULL;
PyTypeObject *type = get_hashlib_state(module)->EVPtype;

assert(digest != NULL);
if (data_obj != NULL) {
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
}

digest = py_digest_by_name(
module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity
);
if (digest == NULL) {
goto exit;
}

#ifdef PY_OPENSSL_HAS_SHAKE
if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) {
type = get_hashlib_state(module)->EVPXOFtype;
} else {
type = get_hashlib_state(module)->EVPtype;
}
#endif

if ((self = newEVPobject(type)) == NULL) {
PY_EVP_MD_free(digest);
return NULL;
self = newEVPobject(type);
if (self == NULL) {
goto exit;
}

#if defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) && OPENSSL_VERSION_NUMBER >= 0x30000000L
// In OpenSSL 1.1.1 the non FIPS allowed flag is context specific while
// in 3.0.0 it is a different EVP_MD provider.
if (!usedforsecurity) {
#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
EVP_MD_CTX_set_flags(self->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
#endif
}
#endif

result = EVP_DigestInit_ex(self->ctx, digest, NULL);
PY_EVP_MD_free(digest);
int result = EVP_DigestInit_ex(self->ctx, digest, NULL);
if (!result) {
_setException(PyExc_ValueError, NULL);
Py_DECREF(self);
return NULL;
Py_CLEAR(self);
goto exit;
}

if (cp && len) {
if (len >= HASHLIB_GIL_MINSIZE) {
if (view.buf && view.len) {
if (view.len >= HASHLIB_GIL_MINSIZE) {
Py_BEGIN_ALLOW_THREADS
result = EVP_hash(self, cp, len);
result = EVP_hash(self, view.buf, view.len);
Py_END_ALLOW_THREADS
} else {
result = EVP_hash(self, cp, len);
result = EVP_hash(self, view.buf, view.len);
}
if (result == -1) {
Py_DECREF(self);
return NULL;
Py_CLEAR(self);
goto exit;
}
}

return (PyObject *)self;
}

static PyObject*
EVP_raw_new(PyObject *module, PyObject *data_obj, const char *name,
int usedforsecurity)
{
Py_buffer view = { 0 };
PyObject *ret_obj = NULL;

if (data_obj)
GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);

PY_EVP_MD *digest = py_digest_by_name(
module, name,
usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity
);

exit:
if (data_obj != NULL) {
PyBuffer_Release(&view);
}
if (digest != NULL) {
ret_obj = EVPnew(module, digest,
(unsigned char*)view.buf, view.len,
usedforsecurity);
PY_EVP_MD_free(digest);
}

if (data_obj)
PyBuffer_Release(&view);

return ret_obj;
return (PyObject *)self;
}


Expand Down Expand Up @@ -976,7 +956,7 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj,
PyErr_SetString(PyExc_TypeError, "name must be a string");
return NULL;
}
return EVP_raw_new(module, data_obj, name, usedforsecurity);
return py_evp_fromname(module, name, data_obj, usedforsecurity);
}


Expand All @@ -996,7 +976,7 @@ _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/
{
return EVP_raw_new(module, data_obj, Py_hash_md5, usedforsecurity);
return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity);
}


Expand All @@ -1016,7 +996,7 @@ _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha1, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity);
}


Expand All @@ -1036,7 +1016,7 @@ _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha224, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity);
}


Expand All @@ -1056,7 +1036,7 @@ _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=1f874a34870f0a68 input=549fad9d2930d4c5]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha256, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha256, data_obj, usedforsecurity);
}


Expand All @@ -1076,7 +1056,7 @@ _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=58529eff9ca457b2 input=48601a6e3bf14ad7]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha384, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha384, data_obj, usedforsecurity);
}


Expand All @@ -1096,7 +1076,7 @@ _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=2c744c9e4a40d5f6 input=c5c46a2a817aa98f]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha512, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha512, data_obj, usedforsecurity);
}


Expand All @@ -1118,7 +1098,7 @@ _hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha3_224, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha3_224, data_obj, usedforsecurity);
}

/*[clinic input]
Expand All @@ -1137,7 +1117,7 @@ _hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha3_256, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha3_256, data_obj , usedforsecurity);
}

/*[clinic input]
Expand All @@ -1156,7 +1136,7 @@ _hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha3_384, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha3_384, data_obj , usedforsecurity);
}

/*[clinic input]
Expand All @@ -1175,7 +1155,7 @@ _hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/
{
return EVP_raw_new(module, data_obj, Py_hash_sha3_512, usedforsecurity);
return py_evp_fromname(module, Py_hash_sha3_512, data_obj , usedforsecurity);
}
#endif /* PY_OPENSSL_HAS_SHA3 */

Expand All @@ -1196,7 +1176,7 @@ _hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=bc49cdd8ada1fa97 input=6c9d67440eb33ec8]*/
{
return EVP_raw_new(module, data_obj, Py_hash_shake_128, usedforsecurity);
return py_evp_fromname(module, Py_hash_shake_128, data_obj , usedforsecurity);
}

/*[clinic input]
Expand All @@ -1215,7 +1195,7 @@ _hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj,
int usedforsecurity)
/*[clinic end generated code: output=358d213be8852df7 input=479cbe9fefd4a9f8]*/
{
return EVP_raw_new(module, data_obj, Py_hash_shake_256, usedforsecurity);
return py_evp_fromname(module, Py_hash_shake_256, data_obj , usedforsecurity);
}
#endif /* PY_OPENSSL_HAS_SHAKE */

Expand Down