aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/sha2module.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/sha2module.c')
-rw-r--r--Modules/sha2module.c166
1 files changed, 63 insertions, 103 deletions
diff --git a/Modules/sha2module.c b/Modules/sha2module.c
index 72931910c5d..36300ba899f 100644
--- a/Modules/sha2module.c
+++ b/Modules/sha2module.c
@@ -9,32 +9,25 @@
Greg Stein (gstein@lyra.org)
Trevor Perrin (trevp@trevp.net)
Jonathan Protzenko (jonathan@protzenko.fr)
+ Bénédikt Tran (10796600+picnixz@users.noreply.github.com)
Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org)
Licensed to PSF under a Contributor Agreement.
*/
-/* SHA objects */
#ifndef Py_BUILD_CORE_BUILTIN
# define Py_BUILD_CORE_MODULE 1
#endif
#include "Python.h"
-#include "pycore_bitutils.h" // _Py_bswap32()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_typeobject.h" // _PyType_GetModuleState()
#include "pycore_strhex.h" // _Py_strhex()
#include "hashlib.h"
-/*[clinic input]
-module _sha2
-class SHA256Type "SHA256object *" "&PyType_Type"
-class SHA512Type "SHA512object *" "&PyType_Type"
-[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5315a7b611c9afc]*/
-
+#include "_hacl/Hacl_Hash_SHA2.h"
/* The SHA block sizes and maximum message digest sizes, in bytes */
@@ -43,34 +36,26 @@ class SHA512Type "SHA512object *" "&PyType_Type"
#define SHA512_BLOCKSIZE 128
#define SHA512_DIGESTSIZE 64
-/* Our SHA2 implementations defer to the HACL* verified library. */
-
-#include "_hacl/Hacl_Hash_SHA2.h"
+// --- Module objects ---------------------------------------------------------
// TODO: Get rid of int digestsize in favor of Hacl state info?
typedef struct {
- PyObject_HEAD
+ HASHLIB_OBJECT_HEAD
int digestsize;
- // Prevents undefined behavior via multiple threads entering the C API.
- bool use_mutex;
- PyMutex mutex;
Hacl_Hash_SHA2_state_t_256 *state;
} SHA256object;
typedef struct {
- PyObject_HEAD
+ HASHLIB_OBJECT_HEAD
int digestsize;
- // Prevents undefined behavior via multiple threads entering the C API.
- bool use_mutex;
- PyMutex mutex;
Hacl_Hash_SHA2_state_t_512 *state;
} SHA512object;
#define _SHA256object_CAST(op) ((SHA256object *)(op))
#define _SHA512object_CAST(op) ((SHA512object *)(op))
-#include "clinic/sha2module.c.h"
+// --- Module state -----------------------------------------------------------
/* We shall use run-time type information in the remainder of this module to
* tell apart SHA2-224 and SHA2-256 */
@@ -89,6 +74,19 @@ sha2_get_state(PyObject *module)
return (sha2_state *)state;
}
+// --- Module clinic configuration --------------------------------------------
+
+/*[clinic input]
+module _sha2
+class SHA256Type "SHA256object *" "&PyType_Type"
+class SHA512Type "SHA512object *" "&PyType_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5315a7b611c9afc]*/
+
+#include "clinic/sha2module.c.h"
+
+// --- SHA-2 object interface -------------------------------------------------
+
static int
SHA256copy(SHA256object *src, SHA256object *dest)
{
@@ -272,9 +270,9 @@ SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls)
}
}
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
rc = SHA256copy(self, newobj);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
if (rc < 0) {
Py_DECREF(newobj);
return NULL;
@@ -309,9 +307,9 @@ SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls)
}
}
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
rc = SHA512copy(self, newobj);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
if (rc < 0) {
Py_DECREF(newobj);
return NULL;
@@ -331,11 +329,11 @@ SHA256Type_digest_impl(SHA256object *self)
{
uint8_t digest[SHA256_DIGESTSIZE];
assert(self->digestsize <= SHA256_DIGESTSIZE);
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
// HACL* performs copies under the hood so that self->state remains valid
// after this call.
Hacl_Hash_SHA2_digest_256(self->state, digest);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
}
@@ -351,11 +349,11 @@ SHA512Type_digest_impl(SHA512object *self)
{
uint8_t digest[SHA512_DIGESTSIZE];
assert(self->digestsize <= SHA512_DIGESTSIZE);
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
// HACL* performs copies under the hood so that self->state remains valid
// after this call.
Hacl_Hash_SHA2_digest_512(self->state, digest);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
}
@@ -371,9 +369,9 @@ SHA256Type_hexdigest_impl(SHA256object *self)
{
uint8_t digest[SHA256_DIGESTSIZE];
assert(self->digestsize <= SHA256_DIGESTSIZE);
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
Hacl_Hash_SHA2_digest_256(self->state, digest);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
return _Py_strhex((const char *)digest, self->digestsize);
}
@@ -389,9 +387,9 @@ SHA512Type_hexdigest_impl(SHA512object *self)
{
uint8_t digest[SHA512_DIGESTSIZE];
assert(self->digestsize <= SHA512_DIGESTSIZE);
- ENTER_HASHLIB(self);
+ HASHLIB_ACQUIRE_LOCK(self);
Hacl_Hash_SHA2_digest_512(self->state, digest);
- LEAVE_HASHLIB(self);
+ HASHLIB_RELEASE_LOCK(self);
return _Py_strhex((const char *)digest, self->digestsize);
}
@@ -409,22 +407,11 @@ SHA256Type_update_impl(SHA256object *self, PyObject *obj)
/*[clinic end generated code: output=dc58a580cf8905a5 input=b2d449d5b30f0f5a]*/
{
Py_buffer buf;
-
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
-
- if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) {
- self->use_mutex = true;
- }
- if (self->use_mutex) {
- Py_BEGIN_ALLOW_THREADS
- PyMutex_Lock(&self->mutex);
- update_256(self->state, buf.buf, buf.len);
- PyMutex_Unlock(&self->mutex);
- Py_END_ALLOW_THREADS
- } else {
- update_256(self->state, buf.buf, buf.len);
- }
-
+ HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(
+ self, buf.len,
+ update_256(self->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
Py_RETURN_NONE;
}
@@ -443,22 +430,11 @@ SHA512Type_update_impl(SHA512object *self, PyObject *obj)
/*[clinic end generated code: output=9af211766c0b7365 input=ded2b46656566283]*/
{
Py_buffer buf;
-
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
-
- if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) {
- self->use_mutex = true;
- }
- if (self->use_mutex) {
- Py_BEGIN_ALLOW_THREADS
- PyMutex_Lock(&self->mutex);
- update_512(self->state, buf.buf, buf.len);
- PyMutex_Unlock(&self->mutex);
- Py_END_ALLOW_THREADS
- } else {
- update_512(self->state, buf.buf, buf.len);
- }
-
+ HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(
+ self, buf.len,
+ update_512(self->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
Py_RETURN_NONE;
}
@@ -638,16 +614,12 @@ _sha2_sha256_impl(PyObject *module, PyObject *data, int usedforsecurity,
return PyErr_NoMemory();
}
if (string) {
- if (buf.len >= HASHLIB_GIL_MINSIZE) {
- /* We do not initialize self->lock here as this is the constructor
- * where it is not yet possible to have concurrent access. */
- Py_BEGIN_ALLOW_THREADS
- update_256(new->state, buf.buf, buf.len);
- Py_END_ALLOW_THREADS
- }
- else {
- update_256(new->state, buf.buf, buf.len);
- }
+ /* Do not use self->mutex here as this is the constructor
+ * where it is not yet possible to have concurrent access. */
+ HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(
+ buf.len,
+ update_256(new->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
}
@@ -700,16 +672,12 @@ _sha2_sha224_impl(PyObject *module, PyObject *data, int usedforsecurity,
return PyErr_NoMemory();
}
if (string) {
- if (buf.len >= HASHLIB_GIL_MINSIZE) {
- /* We do not initialize self->lock here as this is the constructor
- * where it is not yet possible to have concurrent access. */
- Py_BEGIN_ALLOW_THREADS
- update_256(new->state, buf.buf, buf.len);
- Py_END_ALLOW_THREADS
- }
- else {
- update_256(new->state, buf.buf, buf.len);
- }
+ /* Do not use self->mutex here as this is the constructor
+ * where it is not yet possible to have concurrent access. */
+ HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(
+ buf.len,
+ update_256(new->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
}
@@ -763,16 +731,12 @@ _sha2_sha512_impl(PyObject *module, PyObject *data, int usedforsecurity,
return PyErr_NoMemory();
}
if (string) {
- if (buf.len >= HASHLIB_GIL_MINSIZE) {
- /* We do not initialize self->lock here as this is the constructor
- * where it is not yet possible to have concurrent access. */
- Py_BEGIN_ALLOW_THREADS
- update_512(new->state, buf.buf, buf.len);
- Py_END_ALLOW_THREADS
- }
- else {
- update_512(new->state, buf.buf, buf.len);
- }
+ /* Do not use self->mutex here as this is the constructor
+ * where it is not yet possible to have concurrent access. */
+ HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(
+ buf.len,
+ update_512(new->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
}
@@ -826,16 +790,12 @@ _sha2_sha384_impl(PyObject *module, PyObject *data, int usedforsecurity,
return PyErr_NoMemory();
}
if (string) {
- if (buf.len >= HASHLIB_GIL_MINSIZE) {
- /* We do not initialize self->lock here as this is the constructor
- * where it is not yet possible to have concurrent access. */
- Py_BEGIN_ALLOW_THREADS
- update_512(new->state, buf.buf, buf.len);
- Py_END_ALLOW_THREADS
- }
- else {
- update_512(new->state, buf.buf, buf.len);
- }
+ /* Do not use self->mutex here as this is the constructor
+ * where it is not yet possible to have concurrent access. */
+ HASHLIB_EXTERNAL_INSTRUCTIONS_UNLOCKED(
+ buf.len,
+ update_512(new->state, buf.buf, buf.len)
+ );
PyBuffer_Release(&buf);
}