/* SHA2 module */

/* This provides an interface to NIST's SHA2 224, 256, 384, & 512 Algorithms */

/* See below for information about the original code this module was
   based upon. Additional work performed by:

   Andrew Kuchling (amk@amk.ca)
   Greg Stein (gstein@lyra.org)
   Trevor Perrin (trevp@trevp.net)
   Jonathan Protzenko (jonathan@protzenko.fr)

   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]*/


/* The SHA block sizes and maximum message digest sizes, in bytes */

#define SHA256_BLOCKSIZE   64
#define SHA256_DIGESTSIZE  32
#define SHA512_BLOCKSIZE   128
#define SHA512_DIGESTSIZE  64

/* Our SHA2 implementations defer to the HACL* verified library. */

#include "_hacl/Hacl_Hash_SHA2.h"

// TODO: Get rid of int digestsize in favor of Hacl state info?

typedef struct {
    PyObject_HEAD
    int digestsize;
    // Prevents undefined behavior via multiple threads entering the C API.
    // The lock will be NULL before threaded access has been enabled.
    PyThread_type_lock lock;
    Hacl_Streaming_SHA2_state_sha2_256 *state;
} SHA256object;

typedef struct {
    PyObject_HEAD
    int digestsize;
    // Prevents undefined behavior via multiple threads entering the C API.
    // The lock will be NULL before threaded access has been enabled.
    PyThread_type_lock lock;
    Hacl_Streaming_SHA2_state_sha2_512 *state;
} SHA512object;

#include "clinic/sha2module.c.h"

/* We shall use run-time type information in the remainder of this module to
 * tell apart SHA2-224 and SHA2-256 */
typedef struct {
    PyTypeObject* sha224_type;
    PyTypeObject* sha256_type;
    PyTypeObject* sha384_type;
    PyTypeObject* sha512_type;
} sha2_state;

static inline sha2_state*
sha2_get_state(PyObject *module)
{
    void *state = _PyModule_GetState(module);
    assert(state != NULL);
    return (sha2_state *)state;
}

static void SHA256copy(SHA256object *src, SHA256object *dest)
{
    dest->digestsize = src->digestsize;
    dest->state = Hacl_Streaming_SHA2_copy_256(src->state);
}

static void SHA512copy(SHA512object *src, SHA512object *dest)
{
    dest->digestsize = src->digestsize;
    dest->state = Hacl_Streaming_SHA2_copy_512(src->state);
}

static SHA256object *
newSHA224object(sha2_state *state)
{
    SHA256object *sha = (SHA256object *)PyObject_GC_New(
        SHA256object, state->sha224_type);
    if (!sha) {
        return NULL;
    }
    sha->lock = NULL;
    PyObject_GC_Track(sha);
    return sha;
}

static SHA256object *
newSHA256object(sha2_state *state)
{
    SHA256object *sha = (SHA256object *)PyObject_GC_New(
        SHA256object, state->sha256_type);
    if (!sha) {
        return NULL;
    }
    sha->lock = NULL;
    PyObject_GC_Track(sha);
    return sha;
}

static SHA512object *
newSHA384object(sha2_state *state)
{
    SHA512object *sha = (SHA512object *)PyObject_GC_New(
        SHA512object, state->sha384_type);
    if (!sha) {
        return NULL;
    }
    sha->lock = NULL;
    PyObject_GC_Track(sha);
    return sha;
}

static SHA512object *
newSHA512object(sha2_state *state)
{
    SHA512object *sha = (SHA512object *)PyObject_GC_New(
        SHA512object, state->sha512_type);
    if (!sha) {
        return NULL;
    }
    sha->lock = NULL;
    PyObject_GC_Track(sha);
    return sha;
}

/* Internal methods for our hash objects. */

static int
SHA2_traverse(PyObject *ptr, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(ptr));
    return 0;
}

static void
SHA256_dealloc(SHA256object *ptr)
{
    Hacl_Streaming_SHA2_free_256(ptr->state);
    if (ptr->lock != NULL) {
        PyThread_free_lock(ptr->lock);
    }
    PyTypeObject *tp = Py_TYPE(ptr);
    PyObject_GC_UnTrack(ptr);
    PyObject_GC_Del(ptr);
    Py_DECREF(tp);
}

static void
SHA512_dealloc(SHA512object *ptr)
{
    Hacl_Streaming_SHA2_free_512(ptr->state);
    if (ptr->lock != NULL) {
        PyThread_free_lock(ptr->lock);
    }
    PyTypeObject *tp = Py_TYPE(ptr);
    PyObject_GC_UnTrack(ptr);
    PyObject_GC_Del(ptr);
    Py_DECREF(tp);
}

/* HACL* takes a uint32_t for the length of its parameter, but Py_ssize_t can be
 * 64 bits so we loop in <4gig chunks when needed. */

static void update_256(Hacl_Streaming_SHA2_state_sha2_256 *state, uint8_t *buf, Py_ssize_t len) {
  /* Note: we explicitly ignore the error code on the basis that it would take >
   * 1 billion years to overflow the maximum admissible length for SHA2-256
   * (namely, 2^61-1 bytes). */
#if PY_SSIZE_T_MAX > UINT32_MAX
  while (len > UINT32_MAX) {
    Hacl_Streaming_SHA2_update_256(state, buf, UINT32_MAX);
    len -= UINT32_MAX;
    buf += UINT32_MAX;
  }
#endif
  /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */
  Hacl_Streaming_SHA2_update_256(state, buf, (uint32_t) len);
}

static void update_512(Hacl_Streaming_SHA2_state_sha2_512 *state, uint8_t *buf, Py_ssize_t len) {
  /* Note: we explicitly ignore the error code on the basis that it would take >
   * 1 billion years to overflow the maximum admissible length for this API
   * (namely, 2^64-1 bytes). */
#if PY_SSIZE_T_MAX > UINT32_MAX
  while (len > UINT32_MAX) {
    Hacl_Streaming_SHA2_update_512(state, buf, UINT32_MAX);
    len -= UINT32_MAX;
    buf += UINT32_MAX;
  }
#endif
  /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */
  Hacl_Streaming_SHA2_update_512(state, buf, (uint32_t) len);
}


/* External methods for our hash objects */

/*[clinic input]
SHA256Type.copy

    cls:defining_class

Return a copy of the hash object.
[clinic start generated code]*/

static PyObject *
SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls)
/*[clinic end generated code: output=fabd515577805cd3 input=3137146fcb88e212]*/
{
    SHA256object *newobj;
    sha2_state *state = _PyType_GetModuleState(cls);
    if (Py_IS_TYPE(self, state->sha256_type)) {
        if ((newobj = newSHA256object(state)) == NULL) {
            return NULL;
        }
    } else {
        if ((newobj = newSHA224object(state)) == NULL) {
            return NULL;
        }
    }

    ENTER_HASHLIB(self);
    SHA256copy(self, newobj);
    LEAVE_HASHLIB(self);
    return (PyObject *)newobj;
}

/*[clinic input]
SHA512Type.copy

    cls: defining_class

Return a copy of the hash object.
[clinic start generated code]*/

static PyObject *
SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls)
/*[clinic end generated code: output=66d2a8ef20de8302 input=f673a18f66527c90]*/
{
    SHA512object *newobj;
    sha2_state *state = _PyType_GetModuleState(cls);

    if (Py_IS_TYPE((PyObject*)self, state->sha512_type)) {
        if ((newobj = newSHA512object(state)) == NULL) {
            return NULL;
        }
    }
    else {
        if ((newobj = newSHA384object(state)) == NULL) {
            return NULL;
        }
    }

    ENTER_HASHLIB(self);
    SHA512copy(self, newobj);
    LEAVE_HASHLIB(self);
    return (PyObject *)newobj;
}

/*[clinic input]
SHA256Type.digest

Return the digest value as a bytes object.
[clinic start generated code]*/

static PyObject *
SHA256Type_digest_impl(SHA256object *self)
/*[clinic end generated code: output=3a2e3997a98ee792 input=f1f4cfea5cbde35c]*/
{
    uint8_t digest[SHA256_DIGESTSIZE];
    assert(self->digestsize <= SHA256_DIGESTSIZE);
    ENTER_HASHLIB(self);
    // HACL* performs copies under the hood so that self->state remains valid
    // after this call.
    Hacl_Streaming_SHA2_finish_256(self->state, digest);
    LEAVE_HASHLIB(self);
    return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
}

/*[clinic input]
SHA512Type.digest

Return the digest value as a bytes object.
[clinic start generated code]*/

static PyObject *
SHA512Type_digest_impl(SHA512object *self)
/*[clinic end generated code: output=dd8c6320070458e0 input=f6470dd359071f4b]*/
{
    uint8_t digest[SHA512_DIGESTSIZE];
    assert(self->digestsize <= SHA512_DIGESTSIZE);
    ENTER_HASHLIB(self);
    // HACL* performs copies under the hood so that self->state remains valid
    // after this call.
    Hacl_Streaming_SHA2_finish_512(self->state, digest);
    LEAVE_HASHLIB(self);
    return PyBytes_FromStringAndSize((const char *)digest, self->digestsize);
}

/*[clinic input]
SHA256Type.hexdigest

Return the digest value as a string of hexadecimal digits.
[clinic start generated code]*/

static PyObject *
SHA256Type_hexdigest_impl(SHA256object *self)
/*[clinic end generated code: output=96cb68996a780ab3 input=0cc4c714693010d1]*/
{
    uint8_t digest[SHA256_DIGESTSIZE];
    assert(self->digestsize <= SHA256_DIGESTSIZE);
    ENTER_HASHLIB(self);
    Hacl_Streaming_SHA2_finish_256(self->state, digest);
    LEAVE_HASHLIB(self);
    return _Py_strhex((const char *)digest, self->digestsize);
}

/*[clinic input]
SHA512Type.hexdigest

Return the digest value as a string of hexadecimal digits.
[clinic start generated code]*/

static PyObject *
SHA512Type_hexdigest_impl(SHA512object *self)
/*[clinic end generated code: output=cbd6f844aba1fe7c input=498b877b25cbe0a2]*/
{
    uint8_t digest[SHA512_DIGESTSIZE];
    assert(self->digestsize <= SHA512_DIGESTSIZE);
    ENTER_HASHLIB(self);
    Hacl_Streaming_SHA2_finish_512(self->state, digest);
    LEAVE_HASHLIB(self);
    return _Py_strhex((const char *)digest, self->digestsize);
}

/*[clinic input]
SHA256Type.update

    obj: object
    /

Update this hash object's state with the provided string.
[clinic start generated code]*/

static PyObject *
SHA256Type_update(SHA256object *self, PyObject *obj)
/*[clinic end generated code: output=1b240f965ddbd8c6 input=b2d449d5b30f0f5a]*/
{
    Py_buffer buf;

    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);

    if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) {
        self->lock = PyThread_allocate_lock();
    }
    if (self->lock != NULL) {
        Py_BEGIN_ALLOW_THREADS
        PyThread_acquire_lock(self->lock, 1);
        update_256(self->state, buf.buf, buf.len);
        PyThread_release_lock(self->lock);
        Py_END_ALLOW_THREADS
    } else {
        update_256(self->state, buf.buf, buf.len);
    }

    PyBuffer_Release(&buf);
    Py_RETURN_NONE;
}

/*[clinic input]
SHA512Type.update

    obj: object
    /

Update this hash object's state with the provided string.
[clinic start generated code]*/

static PyObject *
SHA512Type_update(SHA512object *self, PyObject *obj)
/*[clinic end generated code: output=745f51057a985884 input=ded2b46656566283]*/
{
    Py_buffer buf;

    GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);

    if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) {
        self->lock = PyThread_allocate_lock();
    }
    if (self->lock != NULL) {
        Py_BEGIN_ALLOW_THREADS
        PyThread_acquire_lock(self->lock, 1);
        update_512(self->state, buf.buf, buf.len);
        PyThread_release_lock(self->lock);
        Py_END_ALLOW_THREADS
    } else {
        update_512(self->state, buf.buf, buf.len);
    }

    PyBuffer_Release(&buf);
    Py_RETURN_NONE;
}

static PyMethodDef SHA256_methods[] = {
    SHA256TYPE_COPY_METHODDEF
    SHA256TYPE_DIGEST_METHODDEF
    SHA256TYPE_HEXDIGEST_METHODDEF
    SHA256TYPE_UPDATE_METHODDEF
    {NULL,        NULL}         /* sentinel */
};

static PyMethodDef SHA512_methods[] = {
    SHA512TYPE_COPY_METHODDEF
    SHA512TYPE_DIGEST_METHODDEF
    SHA512TYPE_HEXDIGEST_METHODDEF
    SHA512TYPE_UPDATE_METHODDEF
    {NULL,        NULL}         /* sentinel */
};

static PyObject *
SHA256_get_block_size(PyObject *self, void *closure)
{
    return PyLong_FromLong(SHA256_BLOCKSIZE);
}

static PyObject *
SHA512_get_block_size(PyObject *self, void *closure)
{
    return PyLong_FromLong(SHA512_BLOCKSIZE);
}

static PyObject *
SHA256_get_digest_size(SHA256object *self, void *closure)
{
    return PyLong_FromLong(self->digestsize);
}

static PyObject *
SHA512_get_digest_size(SHA512object *self, void *closure)
{
    return PyLong_FromLong(self->digestsize);
}

static PyObject *
SHA256_get_name(SHA256object *self, void *closure)
{
    if (self->digestsize == 28) {
        return PyUnicode_FromStringAndSize("sha224", 6);
    }
    return PyUnicode_FromStringAndSize("sha256", 6);
}

static PyObject *
SHA512_get_name(SHA512object *self, void *closure)
{
    if (self->digestsize == 64) {
        return PyUnicode_FromStringAndSize("sha512", 6);
    }
    return PyUnicode_FromStringAndSize("sha384", 6);
}

static PyGetSetDef SHA256_getseters[] = {
    {"block_size",
     (getter)SHA256_get_block_size, NULL,
     NULL,
     NULL},
    {"name",
     (getter)SHA256_get_name, NULL,
     NULL,
     NULL},
    {"digest_size",
     (getter)SHA256_get_digest_size, NULL,
     NULL,
     NULL},
    {NULL}  /* Sentinel */
};

static PyGetSetDef SHA512_getseters[] = {
    {"block_size",
     (getter)SHA512_get_block_size, NULL,
     NULL,
     NULL},
    {"name",
     (getter)SHA512_get_name, NULL,
     NULL,
     NULL},
    {"digest_size",
     (getter)SHA512_get_digest_size, NULL,
     NULL,
     NULL},
    {NULL}  /* Sentinel */
};

static PyType_Slot sha256_types_slots[] = {
    {Py_tp_dealloc, SHA256_dealloc},
    {Py_tp_methods, SHA256_methods},
    {Py_tp_getset, SHA256_getseters},
    {Py_tp_traverse, SHA2_traverse},
    {0,0}
};

static PyType_Slot sha512_type_slots[] = {
    {Py_tp_dealloc, SHA512_dealloc},
    {Py_tp_methods, SHA512_methods},
    {Py_tp_getset, SHA512_getseters},
    {Py_tp_traverse, SHA2_traverse},
    {0,0}
};

// Using _PyType_GetModuleState() on these types is safe since they
// cannot be subclassed: they don't have the Py_TPFLAGS_BASETYPE flag.
static PyType_Spec sha224_type_spec = {
    .name = "_sha2.SHA224Type",
    .basicsize = sizeof(SHA256object),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
    .slots = sha256_types_slots
};

static PyType_Spec sha256_type_spec = {
    .name = "_sha2.SHA256Type",
    .basicsize = sizeof(SHA256object),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
    .slots = sha256_types_slots
};

static PyType_Spec sha384_type_spec = {
    .name = "_sha2.SHA384Type",
    .basicsize =  sizeof(SHA512object),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
    .slots = sha512_type_slots
};

static PyType_Spec sha512_type_spec = {
    .name = "_sha2.SHA512Type",
    .basicsize =  sizeof(SHA512object),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
    .slots = sha512_type_slots
};

/* The module-level constructors. */

/*[clinic input]
_sha2.sha256

    string: object(c_default="NULL") = b''
    *
    usedforsecurity: bool = True

Return a new SHA-256 hash object; optionally initialized with a string.
[clinic start generated code]*/

static PyObject *
_sha2_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity)
/*[clinic end generated code: output=243c9dd289931f87 input=6249da1de607280a]*/
{
    Py_buffer buf;

    if (string) {
        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
    }

    sha2_state *state = sha2_get_state(module);

    SHA256object *new;
    if ((new = newSHA256object(state)) == NULL) {
        if (string) {
            PyBuffer_Release(&buf);
        }
        return NULL;
    }

    new->state = Hacl_Streaming_SHA2_create_in_256();
    new->digestsize = 32;

    if (PyErr_Occurred()) {
        Py_DECREF(new);
        if (string) {
            PyBuffer_Release(&buf);
        }
        return NULL;
    }
    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);
        }
        PyBuffer_Release(&buf);
    }

    return (PyObject *)new;
}

/*[clinic input]
_sha2.sha224

    string: object(c_default="NULL") = b''
    *
    usedforsecurity: bool = True

Return a new SHA-224 hash object; optionally initialized with a string.
[clinic start generated code]*/

static PyObject *
_sha2_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity)
/*[clinic end generated code: output=68191f232e4a3843 input=c42bcba47fd7d2b7]*/
{
    Py_buffer buf;
    if (string) {
        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
    }

    sha2_state *state = sha2_get_state(module);
    SHA256object *new;
    if ((new = newSHA224object(state)) == NULL) {
        if (string) {
            PyBuffer_Release(&buf);
        }
        return NULL;
    }

    new->state = Hacl_Streaming_SHA2_create_in_224();
    new->digestsize = 28;

    if (PyErr_Occurred()) {
        Py_DECREF(new);
        if (string) {
            PyBuffer_Release(&buf);
        }
        return NULL;
    }
    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);
        }
        PyBuffer_Release(&buf);
    }

    return (PyObject *)new;
}

/*[clinic input]
_sha2.sha512

    string: object(c_default="NULL") = b''
    *
    usedforsecurity: bool = True

Return a new SHA-512 hash object; optionally initialized with a string.
[clinic start generated code]*/

static PyObject *
_sha2_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity)
/*[clinic end generated code: output=d55c8996eca214d7 input=0576ae2a6ebfad25]*/
{
    SHA512object *new;
    Py_buffer buf;

    sha2_state *state = sha2_get_state(module);

    if (string)
        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);

    if ((new = newSHA512object(state)) == NULL) {
        if (string)
            PyBuffer_Release(&buf);
        return NULL;
    }

    new->state = Hacl_Streaming_SHA2_create_in_512();
    new->digestsize = 64;

    if (PyErr_Occurred()) {
        Py_DECREF(new);
        if (string)
            PyBuffer_Release(&buf);
        return NULL;
    }
    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);
        }
        PyBuffer_Release(&buf);
    }

    return (PyObject *)new;
}

/*[clinic input]
_sha2.sha384

    string: object(c_default="NULL") = b''
    *
    usedforsecurity: bool = True

Return a new SHA-384 hash object; optionally initialized with a string.
[clinic start generated code]*/

static PyObject *
_sha2_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity)
/*[clinic end generated code: output=b29a0d81d51d1368 input=4e9199d8de0d2f9b]*/
{
    SHA512object *new;
    Py_buffer buf;

    sha2_state *state = sha2_get_state(module);

    if (string)
        GET_BUFFER_VIEW_OR_ERROUT(string, &buf);

    if ((new = newSHA384object(state)) == NULL) {
        if (string)
            PyBuffer_Release(&buf);
        return NULL;
    }

    new->state = Hacl_Streaming_SHA2_create_in_384();
    new->digestsize = 48;

    if (PyErr_Occurred()) {
        Py_DECREF(new);
        if (string)
            PyBuffer_Release(&buf);
        return NULL;
    }
    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);
        }
        PyBuffer_Release(&buf);
    }

    return (PyObject *)new;
}

/* List of functions exported by this module */

static struct PyMethodDef SHA2_functions[] = {
    _SHA2_SHA256_METHODDEF
    _SHA2_SHA224_METHODDEF
    _SHA2_SHA512_METHODDEF
    _SHA2_SHA384_METHODDEF
    {NULL,      NULL}            /* Sentinel */
};

static int
_sha2_traverse(PyObject *module, visitproc visit, void *arg)
{
    sha2_state *state = sha2_get_state(module);
    Py_VISIT(state->sha224_type);
    Py_VISIT(state->sha256_type);
    Py_VISIT(state->sha384_type);
    Py_VISIT(state->sha512_type);
    return 0;
}

static int
_sha2_clear(PyObject *module)
{
    sha2_state *state = sha2_get_state(module);
    Py_CLEAR(state->sha224_type);
    Py_CLEAR(state->sha256_type);
    Py_CLEAR(state->sha384_type);
    Py_CLEAR(state->sha512_type);
    return 0;
}

static void
_sha2_free(void *module)
{
    _sha2_clear((PyObject *)module);
}

/* Initialize this module. */
static int sha2_exec(PyObject *module)
{
    sha2_state *state = sha2_get_state(module);

    state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &sha224_type_spec, NULL);
    if (state->sha224_type == NULL) {
        return -1;
    }
    state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &sha256_type_spec, NULL);
    if (state->sha256_type == NULL) {
        return -1;
    }
    state->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &sha384_type_spec, NULL);
    if (state->sha384_type == NULL) {
        return -1;
    }
    state->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec(
        module, &sha512_type_spec, NULL);
    if (state->sha512_type == NULL) {
        return -1;
    }

    if (PyModule_AddType(module, state->sha224_type) < 0) {
        return -1;
    }
    if (PyModule_AddType(module, state->sha256_type) < 0) {
        return -1;
    }
    if (PyModule_AddType(module, state->sha384_type) < 0) {
        return -1;
    }
    if (PyModule_AddType(module, state->sha512_type) < 0) {
        return -1;
    }

    return 0;
}

static PyModuleDef_Slot _sha2_slots[] = {
    {Py_mod_exec, sha2_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {0, NULL}
};

static struct PyModuleDef _sha2module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_sha2",
    .m_size = sizeof(sha2_state),
    .m_methods = SHA2_functions,
    .m_slots = _sha2_slots,
    .m_traverse = _sha2_traverse,
    .m_clear = _sha2_clear,
    .m_free = _sha2_free
};

PyMODINIT_FUNC
PyInit__sha2(void)
{
    return PyModuleDef_Init(&_sha2module);
}
