/* Module that wraps all OpenSSL hash algorithms */

/*
 * Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
 * 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)
 *
 */

/* Don't warn about deprecated functions, */
#ifndef OPENSSL_API_COMPAT
  // 0x10101000L == 1.1.1, 30000 == 3.0.0
  #define OPENSSL_API_COMPAT 0x10101000L
#endif
#define OPENSSL_NO_DEPRECATED 1

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"
#include "pycore_hashtable.h"
#include "pycore_strhex.h"               // _Py_strhex()
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_RELAXED
#include "hashlib.h"

/* EVP is the preferred interface to hashing in OpenSSL */
#include <openssl/evp.h>
#include <openssl/crypto.h>              // FIPS_mode()
/* We use the object interface to discover what hashes OpenSSL supports. */
#include <openssl/objects.h>
#include <openssl/err.h>

#include <stdbool.h>

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#  define Py_HAS_OPENSSL3_SUPPORT
#  include <openssl/core_names.h>           // OSSL_MAC_PARAM_DIGEST
#  include <openssl/params.h>               // OSSL_PARAM_*()
#else
#  include <openssl/hmac.h>                 // HMAC()
#endif

#ifndef OPENSSL_THREADS
#  error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL"
#endif

#define MUNCH_SIZE INT_MAX

#if defined(NID_sha3_224) && defined(NID_sha3_256) && defined(NID_sha3_384) && defined(NID_sha3_512)
#define PY_OPENSSL_HAS_SHA3 1
#endif
#if defined(NID_shake128) || defined(NID_shake256)
#define PY_OPENSSL_HAS_SHAKE 1
#endif
#if defined(NID_blake2s256) || defined(NID_blake2b512)
#define PY_OPENSSL_HAS_BLAKE2 1
#endif

#ifdef Py_HAS_OPENSSL3_SUPPORT
#define PY_EVP_MD EVP_MD
#define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties)
#define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md)
#define PY_EVP_MD_free(md) EVP_MD_free(md)

#define PY_EVP_MD_CTX_md(CTX)   EVP_MD_CTX_get0_md(CTX)

#define PY_HMAC_CTX_TYPE    EVP_MAC_CTX
#define PY_HMAC_CTX_free    EVP_MAC_CTX_free
#define PY_HMAC_update      EVP_MAC_update
#else
#define PY_EVP_MD const EVP_MD
#define PY_EVP_MD_fetch(algorithm, properties) EVP_get_digestbyname(algorithm)
#define PY_EVP_MD_up_ref(md) do {} while(0)
#define PY_EVP_MD_free(md) do {} while(0)

#define PY_EVP_MD_CTX_md(CTX)   EVP_MD_CTX_md(CTX)

#define PY_HMAC_CTX_TYPE    HMAC_CTX
#define PY_HMAC_CTX_free    HMAC_CTX_free
#define PY_HMAC_update      HMAC_Update
#endif

/*
 * Return 1 if *md* is an extendable-output Function (XOF) and 0 otherwise.
 * SHAKE128 and SHAKE256 are XOF functions but not BLAKE2B algorithms.
 *
 * This is a backport of the EVP_MD_xof() helper added in OpenSSL 3.4.
 */
static inline int
PY_EVP_MD_xof(PY_EVP_MD *md)
{
    return md != NULL && ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0);
}

/* hash alias map and fast lookup
 *
 * Map between Python's preferred names and OpenSSL internal names. Maintain
 * cache of fetched EVP MD objects. The EVP_get_digestbyname() and
 * EVP_MD_fetch() API calls have a performance impact.
 *
 * The py_hashentry_t items are stored in a _Py_hashtable_t with py_name and
 * py_alias as keys.
 */

typedef enum Py_hash_type {
    Py_ht_evp,              // usedforsecurity=True / default
    Py_ht_evp_nosecurity,   // usedforsecurity=False
    Py_ht_mac,              // HMAC
    Py_ht_pbkdf2,           // PKBDF2
} Py_hash_type;

typedef struct {
    const char *py_name;
    const char *py_alias;
    const char *ossl_name;
    int ossl_nid;
    int refcnt;
    PY_EVP_MD *evp;
    PY_EVP_MD *evp_nosecurity;
} py_hashentry_t;

// Fundamental to TLS, assumed always present in any libcrypto:
#define Py_hash_md5 "md5"
#define Py_hash_sha1 "sha1"
#define Py_hash_sha224 "sha224"
#define Py_hash_sha256 "sha256"
#define Py_hash_sha384 "sha384"
#define Py_hash_sha512 "sha512"

// Not all OpenSSL-like libcrypto libraries provide these:
#if defined(NID_sha512_224)
# define Py_hash_sha512_224 "sha512_224"
#endif
#if defined(NID_sha512_256)
# define Py_hash_sha512_256 "sha512_256"
#endif
#if defined(NID_sha3_224)
# define Py_hash_sha3_224 "sha3_224"
#endif
#if defined(NID_sha3_256)
# define Py_hash_sha3_256 "sha3_256"
#endif
#if defined(NID_sha3_384)
# define Py_hash_sha3_384 "sha3_384"
#endif
#if defined(NID_sha3_512)
# define Py_hash_sha3_512 "sha3_512"
#endif
#if defined(NID_shake128)
# define Py_hash_shake_128 "shake_128"
#endif
#if defined(NID_shake256)
# define Py_hash_shake_256 "shake_256"
#endif
#if defined(NID_blake2s256)
# define Py_hash_blake2s "blake2s"
#endif
#if defined(NID_blake2b512)
# 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, NULL}

static const py_hashentry_t py_hashes[] = {
    /* md5 */
    PY_HASH_ENTRY(Py_hash_md5, "MD5", SN_md5, NID_md5),
    /* sha1 */
    PY_HASH_ENTRY(Py_hash_sha1, "SHA1", SN_sha1, NID_sha1),
    /* sha2 family */
    PY_HASH_ENTRY(Py_hash_sha224, "SHA224", SN_sha224, NID_sha224),
    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),
    /* truncated sha2 */
#ifdef Py_hash_sha512_224
    PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224),
#endif
#ifdef Py_hash_sha512_256
    PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256),
#endif
    /* sha3 */
#ifdef Py_hash_sha3_224
    PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224),
#endif
#ifdef Py_hash_sha3_256
    PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256),
#endif
#ifdef Py_hash_sha3_384
    PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384),
#endif
#ifdef Py_hash_sha3_512
    PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512),
#endif
    /* sha3 shake */
#ifdef Py_hash_shake_128
    PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128),
#endif
#ifdef Py_hash_shake_256
    PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256),
#endif
    /* blake2 digest */
#ifdef Py_hash_blake2s
    PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256),
#endif
#ifdef Py_hash_blake2b
    PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512),
#endif
    PY_HASH_ENTRY(NULL, NULL, NULL, 0),
};

static Py_uhash_t
py_hashentry_t_hash_name(const void *key) {
    return Py_HashBuffer(key, strlen((const char *)key));
}

static int
py_hashentry_t_compare_name(const void *key1, const void *key2) {
    return strcmp((const char *)key1, (const char *)key2) == 0;
}

static void
py_hashentry_t_destroy_value(void *entry) {
    py_hashentry_t *h = (py_hashentry_t *)entry;
    if (--(h->refcnt) == 0) {
        if (h->evp != NULL) {
            PY_EVP_MD_free(h->evp);
            h->evp = NULL;
        }
        if (h->evp_nosecurity != NULL) {
            PY_EVP_MD_free(h->evp_nosecurity);
            h->evp_nosecurity = NULL;
        }
        PyMem_Free(entry);
    }
}

static _Py_hashtable_t *
py_hashentry_table_new(void) {
    _Py_hashtable_t *ht = _Py_hashtable_new_full(
        py_hashentry_t_hash_name,
        py_hashentry_t_compare_name,
        NULL,
        py_hashentry_t_destroy_value,
        NULL
    );
    if (ht == NULL) {
        return NULL;
    }

    for (const py_hashentry_t *h = py_hashes; h->py_name != NULL; h++) {
        py_hashentry_t *entry = (py_hashentry_t *)PyMem_Malloc(sizeof(py_hashentry_t));
        if (entry == NULL) {
            goto error;
        }
        memcpy(entry, h, sizeof(py_hashentry_t));

        if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) {
            PyMem_Free(entry);
            goto error;
        }
        entry->refcnt = 1;

        if (h->py_alias != NULL) {
            if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) {
                PyMem_Free(entry);
                goto error;
            }
            entry->refcnt++;
        }
    }

    return ht;
  error:
    _Py_hashtable_destroy(ht);
    return NULL;
}

// --- Module state -----------------------------------------------------------

static PyModuleDef _hashlibmodule;

typedef struct {
    PyTypeObject *HASH_type;    // based on EVP_MD
    PyTypeObject *HMAC_type;
#ifdef PY_OPENSSL_HAS_SHAKE
    PyTypeObject *HASHXOF_type; // based on EVP_MD
#endif
    PyObject *constructs;
    PyObject *unsupported_digestmod_error;
    _Py_hashtable_t *hashtable;
#ifdef Py_HAS_OPENSSL3_SUPPORT
    EVP_MAC *evp_hmac;
#endif
} _hashlibstate;

static inline _hashlibstate*
get_hashlib_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (_hashlibstate *)state;
}

// --- Module objects ---------------------------------------------------------

typedef struct {
    HASHLIB_OBJECT_HEAD
    EVP_MD_CTX *ctx;    /* OpenSSL message digest context */
} HASHobject;

#define HASHobject_CAST(op) ((HASHobject *)(op))

typedef struct {
    HASHLIB_OBJECT_HEAD
#ifdef Py_HAS_OPENSSL3_SUPPORT
    EVP_MAC_CTX *ctx;   /* OpenSSL HMAC EVP-based context */
    int evp_md_nid;     /* needed to find the message digest name */
#else
    HMAC_CTX *ctx;      /* OpenSSL HMAC plain context */
#endif
} HMACobject;

#define HMACobject_CAST(op) ((HMACobject *)(op))

// --- Module clinic configuration --------------------------------------------

/*[clinic input]
module _hashlib
class _hashlib.HASH "HASHobject *" "&PyType_Type"
class _hashlib.HASHXOF "HASHobject *" "&PyType_Type"
class _hashlib.HMAC "HMACobject *" "&PyType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6b5c9ce5c28bdc58]*/

#include "clinic/_hashopenssl.c.h"

/* LCOV_EXCL_START */

/* Thin wrapper around ERR_reason_error_string() returning non-NULL text. */
static const char *
py_wrapper_ERR_reason_error_string(unsigned long errcode)
{
    const char *reason = ERR_reason_error_string(errcode);
    return reason ? reason : "no reason";
}

#ifdef Py_HAS_OPENSSL3_SUPPORT
/*
 * Set an exception with additional information.
 *
 * This is only useful in OpenSSL 3.0 and later as the default reason
 * usually lacks information and function locations are no longer encoded
 * in the error code.
 */
static void
set_exception_with_ssl_errinfo(PyObject *exc_type, PyObject *exc_text,
                               const char *lib, const char *reason)
{
    assert(exc_type != NULL);
    assert(exc_text != NULL);
    if (lib && reason) {
        PyErr_Format(exc_type, "[%s] %U (reason: %s)", lib, exc_text, reason);
    }
    else if (lib) {
        PyErr_Format(exc_type, "[%s] %U", lib, exc_text);
    }
    else if (reason) {
        PyErr_Format(exc_type, "%U (reason: %s)", exc_text, reason);
    }
    else {
        PyErr_SetObject(exc_type, exc_text);
    }
}
#endif

/* Set an exception of given type using the given OpenSSL error code. */
static void
set_ssl_exception_from_errcode(PyObject *exc_type, unsigned long errcode)
{
    assert(exc_type != NULL);
    assert(errcode != 0);

    /* ERR_ERROR_STRING(3) ensures that the messages below are ASCII */
    const char *lib = ERR_lib_error_string(errcode);
#ifdef Py_HAS_OPENSSL3_SUPPORT
    // Since OpenSSL 3.0, ERR_func_error_string() always returns NULL.
    const char *func = NULL;
#else
    const char *func = ERR_func_error_string(errcode);
#endif
    const char *reason = py_wrapper_ERR_reason_error_string(errcode);

    if (lib && func) {
        PyErr_Format(exc_type, "[%s: %s] %s", lib, func, reason);
    }
    else if (lib) {
        PyErr_Format(exc_type, "[%s] %s", lib, reason);
    }
    else {
        PyErr_SetString(exc_type, reason);
    }
}

/*
 * Get an appropriate exception type for the given OpenSSL error code.
 *
 * The exception type depends on the error code reason.
 */
static PyObject *
get_smart_ssl_exception_type(unsigned long errcode, PyObject *default_exc_type)
{
    switch (ERR_GET_REASON(errcode)) {
        case ERR_R_MALLOC_FAILURE:
            return PyExc_MemoryError;
        default:
            return default_exc_type;
    }
}

/*
 * Set an exception of given type.
 *
 * By default, the exception's message is constructed by using the last SSL
 * error that occurred. If no error occurred, the 'fallback_message' is used
 * to create an exception message.
 */
static void
raise_ssl_error(PyObject *exc_type, const char *fallback_message)
{
    assert(fallback_message != NULL);
    unsigned long errcode = ERR_peek_last_error();
    if (errcode) {
        ERR_clear_error();
        set_ssl_exception_from_errcode(exc_type, errcode);
    }
    else {
        PyErr_SetString(exc_type, fallback_message);
    }
}

/* Same as raise_ssl_error() but with a C-style formatted message. */
static void
raise_ssl_error_f(PyObject *exc_type, const char *fallback_format, ...)
{
    assert(fallback_format != NULL);
    unsigned long errcode = ERR_peek_last_error();
    if (errcode) {
        ERR_clear_error();
        set_ssl_exception_from_errcode(exc_type, errcode);
    }
    else {
        va_list vargs;
        va_start(vargs, fallback_format);
        PyErr_FormatV(exc_type, fallback_format, vargs);
        va_end(vargs);
    }
}

/* Same as raise_ssl_error_f() with smart exception types. */
static void
raise_smart_ssl_error_f(PyObject *exc_type, const char *fallback_format, ...)
{
    unsigned long errcode = ERR_peek_last_error();
    if (errcode) {
        ERR_clear_error();
        exc_type = get_smart_ssl_exception_type(errcode, exc_type);
        set_ssl_exception_from_errcode(exc_type, errcode);
    }
    else {
        va_list vargs;
        va_start(vargs, fallback_format);
        PyErr_FormatV(exc_type, fallback_format, vargs);
        va_end(vargs);
    }
}

/*
 * Raise a ValueError with a default message after an error occurred.
 * It can also be used without previous calls to SSL built-in functions.
 */
static inline void
notify_ssl_error_occurred(const char *message)
{
    raise_ssl_error(PyExc_ValueError, message);
}

/* Same as notify_ssl_error_occurred() for failed OpenSSL functions. */
static inline void
notify_ssl_error_occurred_in(const char *funcname)
{
    raise_ssl_error_f(PyExc_ValueError,
                      "error in OpenSSL function %s()", funcname);
}

/* Same as notify_ssl_error_occurred_in() with smart exception types. */
static inline void
notify_smart_ssl_error_occurred_in(const char *funcname)
{
    raise_smart_ssl_error_f(PyExc_ValueError,
                            "error in OpenSSL function %s()", funcname);
}

#ifdef Py_HAS_OPENSSL3_SUPPORT
static void
raise_unsupported_algorithm_impl(PyObject *exc_type,
                                 const char *fallback_format,
                                 const void *format_arg)
{
    // Since OpenSSL 3.0, if the algorithm is not supported or fetching fails,
    // the reason lacks the algorithm name.
    int errcode = ERR_peek_last_error();
    switch (ERR_GET_REASON(errcode)) {
        case ERR_R_UNSUPPORTED: {
            PyObject *text = PyUnicode_FromFormat(fallback_format, format_arg);
            if (text != NULL) {
                const char *lib = ERR_lib_error_string(errcode);
                set_exception_with_ssl_errinfo(exc_type, text, lib, NULL);
                Py_DECREF(text);
            }
            break;
        }
        case ERR_R_FETCH_FAILED: {
            PyObject *text = PyUnicode_FromFormat(fallback_format, format_arg);
            if (text != NULL) {
                const char *lib = ERR_lib_error_string(errcode);
                const char *reason = ERR_reason_error_string(errcode);
                set_exception_with_ssl_errinfo(exc_type, text, lib, reason);
                Py_DECREF(text);
            }
            break;
        }
        default:
            raise_ssl_error_f(exc_type, fallback_format, format_arg);
            break;
    }
    assert(PyErr_Occurred());
}
#else
/* Before OpenSSL 3.0, error messages included enough information. */
#define raise_unsupported_algorithm_impl    raise_ssl_error_f
#endif

static inline void
raise_unsupported_algorithm_error(_hashlibstate *state, PyObject *digestmod)
{
    raise_unsupported_algorithm_impl(
        state->unsupported_digestmod_error,
        HASHLIB_UNSUPPORTED_ALGORITHM,
        digestmod
    );
}

static inline void
raise_unsupported_str_algorithm_error(_hashlibstate *state, const char *name)
{
    raise_unsupported_algorithm_impl(
        state->unsupported_digestmod_error,
        HASHLIB_UNSUPPORTED_STR_ALGORITHM,
        name
    );
}

#undef raise_unsupported_algorithm_impl
/* LCOV_EXCL_STOP */

/*
 * OpenSSL provides a way to go from NIDs to digest names for hash functions
 * but lacks this granularity for MAC objects where it is not possible to get
 * the underlying digest name (only the block size and digest size are allowed
 * to be recovered).
 *
 * In addition, OpenSSL aliases pollute the list of known digest names
 * as OpenSSL appears to have its own definition of alias. In particular,
 * the resulting list still contains duplicate and alternate names for several
 * algorithms.
 *
 * Therefore, digest names, whether they are used by hash functions or HMAC,
 * are handled through EVP_MD objects or directly by using some NID.
 */

/* Get a cached entry by OpenSSL NID. */
static const py_hashentry_t *
get_hashentry_by_nid(int nid)
{
    for (const py_hashentry_t *h = py_hashes; h->py_name != NULL; h++) {
        if (h->ossl_nid == nid) {
            return h;
        }
    }
    return NULL;
}

/*
 * Convert the NID to a string via OBJ_nid2*() functions.
 *
 * If 'nid' cannot be resolved, set an exception and return NULL.
 */
static const char *
get_asn1_utf8name_by_nid(int nid)
{
    const char *name = OBJ_nid2ln(nid);
    if (name == NULL) {
        /* In OpenSSL 3.0 and later, OBJ_nid*() are thread-safe and may raise.
         * However, not all versions of OpenSSL set a last error, so we simply
         * ignore the last error if none exists.
         *
         * See https://github.com/python/cpython/issues/142451.
         */
        unsigned long errcode = ERR_peek_last_error();
        if (errcode && ERR_GET_REASON(errcode) != OBJ_R_UNKNOWN_NID) {
            goto error;
        }
        // fallback to short name and unconditionally propagate errors
        name = OBJ_nid2sn(nid);
        if (name == NULL) {
            goto error;
        }
    }
    return name;

error:
    raise_ssl_error_f(PyExc_ValueError, "cannot resolve NID %d", nid);
    return NULL;
}

/*
 * Convert the NID to an OpenSSL digest name.
 *
 * On error, set an exception and return NULL.
 */
static const char *
get_hashlib_utf8name_by_nid(int nid)
{
    const py_hashentry_t *e = get_hashentry_by_nid(nid);
    return e ? e->py_name : get_asn1_utf8name_by_nid(nid);
}

#ifdef Py_HAS_OPENSSL3_SUPPORT
/*
 * Convert the NID to an OpenSSL "canonical" cached, SN_* or LN_* digest name.
 *
 * On error, set an exception and return NULL.
 */
static const char *
get_openssl_utf8name_by_nid(int nid)
{
    const py_hashentry_t *e = get_hashentry_by_nid(nid);
    return e ? e->ossl_name : get_asn1_utf8name_by_nid(nid);
}
#endif

/* Same as get_hashlib_utf8name_by_nid() but using an EVP_MD object. */
static const char *
get_hashlib_utf8name_by_evp_md(const EVP_MD *md)
{
    assert(md != NULL);
    return get_hashlib_utf8name_by_nid(EVP_MD_nid(md));
}

/*
 * Return 1 if the property query clause [1] must be "-fips" and 0 otherwise.
 *
 * [1] https://docs.openssl.org/master/man7/property
 */
static inline int
disable_fips_property(Py_hash_type py_ht)
{
    switch (py_ht) {
        case Py_ht_evp:
        case Py_ht_mac:
        case Py_ht_pbkdf2:
            return 0;
        case Py_ht_evp_nosecurity:
            return 1;
        default:
            Py_FatalError("unsupported hash type");
    }
}

/*
 * Get a new reference to an EVP_MD object described by name and purpose.
 *
 * If 'name' is an OpenSSL indexed name, the return value is cached.
 */
static PY_EVP_MD *
get_openssl_evp_md_by_utf8name(_hashlibstate *state, const char *name,
                               Py_hash_type py_ht)
{
    PY_EVP_MD *digest = NULL, *other_digest = NULL;
    py_hashentry_t *entry = _Py_hashtable_get(state->hashtable, name);

    if (entry != NULL) {
        if (!disable_fips_property(py_ht)) {
            digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp);
            if (digest == NULL) {
                digest = PY_EVP_MD_fetch(entry->ossl_name, NULL);
#ifdef Py_GIL_DISABLED
                // exchange just in case another thread did same thing at same time
                other_digest = _Py_atomic_exchange_ptr(&entry->evp, (void *)digest);
#else
                entry->evp = digest;
#endif
            }
        }
        else {
            digest = FT_ATOMIC_LOAD_PTR_RELAXED(entry->evp_nosecurity);
            if (digest == NULL) {
                digest = PY_EVP_MD_fetch(entry->ossl_name, "-fips");
#ifdef Py_GIL_DISABLED
                // exchange just in case another thread did same thing at same time
                other_digest = _Py_atomic_exchange_ptr(&entry->evp_nosecurity, (void *)digest);
#else
                entry->evp_nosecurity = digest;
#endif
            }
        }
        // if another thread same thing at same time make sure we got same ptr
        assert(other_digest == NULL || other_digest == digest);
        if (digest != NULL && other_digest == NULL) {
            PY_EVP_MD_up_ref(digest);
        }
    }
    else {
        // Fall back for looking up an unindexed OpenSSL specific name.
        const char *props = disable_fips_property(py_ht) ? "-fips" : NULL;
        (void)props;  // will only be used in OpenSSL 3.0 and later
        digest = PY_EVP_MD_fetch(name, props);
    }
    if (digest == NULL) {
        raise_unsupported_str_algorithm_error(state, name);
        return NULL;
    }
    return digest;
}

/*
 * Get a new reference to an EVP_MD described by 'digestmod' and purpose.
 *
 * On error, set an exception and return NULL.
 *
 * Parameters
 *
 *      digestmod   A digest name or a _hashopenssl builtin function
 *      py_ht       The message digest purpose.
 */
static PY_EVP_MD *
get_openssl_evp_md(_hashlibstate *state, PyObject *digestmod, Py_hash_type py_ht)
{
    const char *name;
    if (PyUnicode_Check(digestmod)) {
        name = PyUnicode_AsUTF8(digestmod);
    }
    else {
        PyObject *dict = state->constructs;
        assert(dict != NULL);
        PyObject *borrowed_ref = PyDict_GetItemWithError(dict, digestmod);
        name = borrowed_ref == NULL ? NULL : PyUnicode_AsUTF8(borrowed_ref);
    }
    if (name == NULL) {
        if (!PyErr_Occurred()) {
            raise_unsupported_algorithm_error(state, digestmod);
        }
        return NULL;
    }
    return get_openssl_evp_md_by_utf8name(state, name, py_ht);
}

#ifdef Py_HAS_OPENSSL3_SUPPORT
/*
 * Get the "canonical" name of an EVP_MD described by 'digestmod' and purpose.
 *
 * On error, set an exception and return NULL.
 *
 * This function should not be used to construct the exposed Python name,
 * but rather to invoke OpenSSL EVP_* functions.
 */
static const char *
get_openssl_digest_name(_hashlibstate *state,
                        PyObject *digestmod, Py_hash_type py_ht,
                        EVP_MD **evp_md)
{
    PY_EVP_MD *md = get_openssl_evp_md(state, digestmod, py_ht);
    if (md == NULL) {
        if (evp_md != NULL) {
            *evp_md = NULL;
        }
        return NULL;
    }
    int nid = EVP_MD_nid(md);
    const char *name = get_openssl_utf8name_by_nid(nid);
    if (name == NULL) {
        if (evp_md != NULL) {
            *evp_md = NULL;
        }
        PY_EVP_MD_free(md);
        raise_unsupported_algorithm_error(state, digestmod);
        return NULL;
    }
    if (evp_md != NULL) {
        *evp_md = md;
    }
    else {
        PY_EVP_MD_free(md);
    }
    return name;
}
#endif

// --- OpenSSL HASH wrappers --------------------------------------------------

/* Thin wrapper around EVP_MD_CTX_new() which sets an exception on failure. */
static EVP_MD_CTX *
py_wrapper_EVP_MD_CTX_new(void)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    if (ctx == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    return ctx;
}

// --- HASH interface ---------------------------------------------------------

static HASHobject *
new_hash_object(PyTypeObject *type)
{
    HASHobject *retval = PyObject_New(HASHobject, type);
    if (retval == NULL) {
        return NULL;
    }
    HASHLIB_INIT_MUTEX(retval);

    retval->ctx = py_wrapper_EVP_MD_CTX_new();
    if (retval->ctx == NULL) {
        Py_DECREF(retval);
        return NULL;
    }

    return retval;
}

static int
_hashlib_HASH_hash(HASHobject *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);
        if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
            notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestUpdate));
            return -1;
        }
        len -= process;
        cp += process;
    }
    return 0;
}

/* Internal methods for a hash object */

static void
_hashlib_HASH_dealloc(PyObject *op)
{
    HASHobject *self = HASHobject_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    EVP_MD_CTX_free(self->ctx);
    PyObject_Free(self);
    Py_DECREF(tp);
}

static int
_hashlib_HASH_copy_locked(HASHobject *self, EVP_MD_CTX *new_ctx_p)
{
    int result;
    HASHLIB_ACQUIRE_LOCK(self);
    result = EVP_MD_CTX_copy(new_ctx_p, self->ctx);
    HASHLIB_RELEASE_LOCK(self);
    if (result == 0) {
        notify_smart_ssl_error_occurred_in(Py_STRINGIFY(EVP_MD_CTX_copy));
        return -1;
    }
    return 0;
}

/* External methods for a hash object */

/*[clinic input]
_hashlib.HASH.copy

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

static PyObject *
_hashlib_HASH_copy_impl(HASHobject *self)
/*[clinic end generated code: output=2545541af18d53d7 input=814b19202cd08a26]*/
{
    HASHobject *newobj;

    if ((newobj = new_hash_object(Py_TYPE(self))) == NULL)
        return NULL;

    if (_hashlib_HASH_copy_locked(self, newobj->ctx) < 0) {
        Py_DECREF(newobj);
        return NULL;
    }
    return (PyObject *)newobj;
}

static Py_ssize_t
_hashlib_HASH_digest_compute(HASHobject *self, unsigned char *digest)
{
    EVP_MD_CTX *ctx = py_wrapper_EVP_MD_CTX_new();
    if (ctx == NULL) {
        return -1;
    }
    if (_hashlib_HASH_copy_locked(self, ctx) < 0) {
        goto error;
    }
    Py_ssize_t digest_size = EVP_MD_CTX_size(ctx);
    if (!EVP_DigestFinal(ctx, digest, NULL)) {
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestFinal));
        goto error;
    }
    EVP_MD_CTX_free(ctx);
    return digest_size;

error:
    EVP_MD_CTX_free(ctx);
    return -1;
}

/*[clinic input]
_hashlib.HASH.digest

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

static PyObject *
_hashlib_HASH_digest_impl(HASHobject *self)
/*[clinic end generated code: output=3fc6f9671d712850 input=d8d528d6e50af0de]*/
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    Py_ssize_t n = _hashlib_HASH_digest_compute(self, digest);
    return n < 0 ? NULL : PyBytes_FromStringAndSize((const char *)digest, n);
}

/*[clinic input]
_hashlib.HASH.hexdigest

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

static PyObject *
_hashlib_HASH_hexdigest_impl(HASHobject *self)
/*[clinic end generated code: output=1b8e60d9711e7f4d input=ae7553f78f8372d8]*/
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    Py_ssize_t n = _hashlib_HASH_digest_compute(self, digest);
    return n < 0 ? NULL : _Py_strhex((const char *)digest, n);
}

/*[clinic input]
_hashlib.HASH.update

    obj: object
    /

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

static PyObject *
_hashlib_HASH_update_impl(HASHobject *self, PyObject *obj)
/*[clinic end generated code: output=62ad989754946b86 input=aa1ce20e3f92ceb6]*/
{
    int result;
    Py_buffer view;
    GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
    HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(
        self, view.len,
        result = _hashlib_HASH_hash(self, view.buf, view.len)
    );
    PyBuffer_Release(&view);
    return result < 0 ? NULL : Py_None;
}

static PyMethodDef HASH_methods[] = {
    _HASHLIB_HASH_COPY_METHODDEF
    _HASHLIB_HASH_DIGEST_METHODDEF
    _HASHLIB_HASH_HEXDIGEST_METHODDEF
    _HASHLIB_HASH_UPDATE_METHODDEF
    {NULL, NULL}  /* sentinel */
};

static PyObject *
_hashlib_HASH_get_blocksize(PyObject *op, void *Py_UNUSED(closure))
{
    HASHobject *self = HASHobject_CAST(op);
    long block_size = EVP_MD_CTX_block_size(self->ctx);
    return PyLong_FromLong(block_size);
}

static PyObject *
_hashlib_HASH_get_digestsize(PyObject *op, void *Py_UNUSED(closure))
{
    HASHobject *self = HASHobject_CAST(op);
    long size = EVP_MD_CTX_size(self->ctx);
    return PyLong_FromLong(size);
}

static PyObject *
_hashlib_HASH_get_name(PyObject *op, void *Py_UNUSED(closure))
{
    HASHobject *self = HASHobject_CAST(op);
    const EVP_MD *md = PY_EVP_MD_CTX_md(self->ctx);
    if (md == NULL) {
        notify_ssl_error_occurred("missing EVP_MD for HASH context");
        return NULL;
    }
    const char *name = get_hashlib_utf8name_by_evp_md(md);
    assert(name != NULL || PyErr_Occurred());
    return name == NULL ? NULL : PyUnicode_FromString(name);
}

static PyGetSetDef HASH_getsets[] = {
    {"digest_size", _hashlib_HASH_get_digestsize, NULL, NULL, NULL},
    {"block_size", _hashlib_HASH_get_blocksize, NULL, NULL, NULL},
    {"name", _hashlib_HASH_get_name, NULL, NULL, PyDoc_STR("algorithm name.")},
    {NULL}  /* Sentinel */
};


static PyObject *
_hashlib_HASH_repr(PyObject *self)
{
    PyObject *name = _hashlib_HASH_get_name(self, NULL);
    if (name == NULL) {
        return NULL;
    }
    PyObject *repr = PyUnicode_FromFormat("<%U %T object @ %p>",
                                          name, self, self);
    Py_DECREF(name);
    return repr;
}

PyDoc_STRVAR(HASHobject_type_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");

static PyType_Slot HASHobject_type_slots[] = {
    {Py_tp_dealloc, _hashlib_HASH_dealloc},
    {Py_tp_repr, _hashlib_HASH_repr},
    {Py_tp_doc, (char *)HASHobject_type_doc},
    {Py_tp_methods, HASH_methods},
    {Py_tp_getset, HASH_getsets},
    {0, 0},
};

static PyType_Spec HASHobject_type_spec = {
    .name = "_hashlib.HASH",
    .basicsize = sizeof(HASHobject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_BASETYPE
        | Py_TPFLAGS_DISALLOW_INSTANTIATION
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = HASHobject_type_slots
};

#ifdef PY_OPENSSL_HAS_SHAKE

/*[clinic input]
_hashlib.HASHXOF.digest

  length: Py_ssize_t(allow_negative=False)

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

static PyObject *
_hashlib_HASHXOF_digest_impl(HASHobject *self, Py_ssize_t length)
/*[clinic end generated code: output=dcb09335dd2fe908 input=224d047da2c12a42]*/
{
    EVP_MD_CTX *temp_ctx;

    if (length == 0) {
        return Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
    }

    PyBytesWriter *writer = PyBytesWriter_Create(length);
    if (writer == NULL) {
        return NULL;
    }

    temp_ctx = py_wrapper_EVP_MD_CTX_new();
    if (temp_ctx == NULL) {
        PyBytesWriter_Discard(writer);
        return NULL;
    }

    if (_hashlib_HASH_copy_locked(self, temp_ctx) < 0) {
        goto error;
    }
    if (!EVP_DigestFinalXOF(temp_ctx,
                            (unsigned char*)PyBytesWriter_GetData(writer),
                            length))
    {
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestFinalXOF));
        goto error;
    }

    EVP_MD_CTX_free(temp_ctx);
    return PyBytesWriter_Finish(writer);

error:
    PyBytesWriter_Discard(writer);
    EVP_MD_CTX_free(temp_ctx);
    return NULL;
}

/*[clinic input]
_hashlib.HASHXOF.hexdigest

    length: Py_ssize_t(allow_negative=False)

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

static PyObject *
_hashlib_HASHXOF_hexdigest_impl(HASHobject *self, Py_ssize_t length)
/*[clinic end generated code: output=519431cafa014f39 input=4a41b8ab5d3bfee2]*/
{
    unsigned char *digest;
    EVP_MD_CTX *temp_ctx;
    PyObject *retval;

    if (length == 0) {
        return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    }

    digest = (unsigned char*)PyMem_Malloc(length);
    if (digest == NULL) {
        (void)PyErr_NoMemory();
        return NULL;
    }

    temp_ctx = py_wrapper_EVP_MD_CTX_new();
    if (temp_ctx == NULL) {
        PyMem_Free(digest);
        return NULL;
    }

    /* Get the raw (binary) digest value */
    if (_hashlib_HASH_copy_locked(self, temp_ctx) < 0) {
        goto error;
    }
    if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) {
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestFinalXOF));
        goto error;
    }

    EVP_MD_CTX_free(temp_ctx);

    retval = _Py_strhex((const char *)digest, length);
    PyMem_Free(digest);
    return retval;

error:
    PyMem_Free(digest);
    EVP_MD_CTX_free(temp_ctx);
    return NULL;
}

static PyMethodDef HASHXOFobject_methods[] = {
    _HASHLIB_HASHXOF_DIGEST_METHODDEF
    _HASHLIB_HASHXOF_HEXDIGEST_METHODDEF
    {NULL, NULL}  /* sentinel */
};


static PyObject *
_hashlib_HASHXOF_digest_size(PyObject *Py_UNUSED(self),
                             void *Py_UNUSED(closure))
{
    return PyLong_FromLong(0);
}

static PyGetSetDef HASHXOFobject_getsets[] = {
    {"digest_size", _hashlib_HASHXOF_digest_size, NULL, NULL, NULL},
    {NULL}  /* Sentinel */
};

PyDoc_STRVAR(HASHXOFobject_type_doc,
"HASHXOF(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(length) -- return the current digest value\n"
"hexdigest(length) -- 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");

static PyType_Slot HASHXOFobject_type_slots[] = {
    {Py_tp_doc, (char *)HASHXOFobject_type_doc},
    {Py_tp_methods, HASHXOFobject_methods},
    {Py_tp_getset, HASHXOFobject_getsets},
    {0, 0},
};

static PyType_Spec HASHXOFobject_type_spec = {
    .name = "_hashlib.HASHXOF",
    .basicsize = sizeof(HASHobject),
    .flags = (
        Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_BASETYPE
        | Py_TPFLAGS_DISALLOW_INSTANTIATION
        | Py_TPFLAGS_IMMUTABLETYPE
    ),
    .slots = HASHXOFobject_type_slots
};


#endif

static PyObject *
_hashlib_HASH(_hashlibstate *state, const char *digestname, PyObject *data_obj,
              int usedforsecurity)
{
    Py_buffer view = { 0 };
    PY_EVP_MD *digest = NULL;
    PyTypeObject *type;
    HASHobject *self = NULL;

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

    Py_hash_type purpose = usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity;
    digest = get_openssl_evp_md_by_utf8name(state, digestname, purpose);
    if (digest == NULL) {
        goto exit;
    }

    type = PY_EVP_MD_xof(digest) ? state->HASHXOF_type : state->HASH_type;
    self = new_hash_object(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) {
        EVP_MD_CTX_set_flags(self->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
    }
#endif

    int result = EVP_DigestInit_ex(self->ctx, digest, NULL);
    if (!result) {
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_DigestInit_ex));
        Py_CLEAR(self);
        goto exit;
    }

    if (view.buf && view.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(
            view.len,
            result = _hashlib_HASH_hash(self, view.buf, view.len)
        );
        if (result == -1) {
            assert(PyErr_Occurred());
            Py_CLEAR(self);
            goto exit;
        }
    }

exit:
    if (data_obj != NULL) {
        PyBuffer_Release(&view);
    }
    if (digest != NULL) {
        PY_EVP_MD_free(digest);
    }

    return (PyObject *)self;
}

// In Python 3.19, we can remove the "STRING" argument and would also be able
// to remove the macro (or keep it as an alias for better naming) since calls
// to _hashlib_HASH_new_impl() would fit on 80 characters.
#define CALL_HASHLIB_NEW(MODULE, NAME, DATA, STRING, USEDFORSECURITY)   \
    return _hashlib_HASH_new_impl(MODULE, NAME, DATA, USEDFORSECURITY, STRING)

/* The module-level function: new() */

/*[clinic input]
_hashlib.new as _hashlib_HASH_new

    name: str
    data: object(c_default="NULL") = b''
    *
    usedforsecurity: bool = True
    string: object(c_default="NULL") = None

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

static PyObject *
_hashlib_HASH_new_impl(PyObject *module, const char *name, PyObject *data,
                       int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=b905aaf9840c1bbd input=c34af6c6e696d44e]*/
{
    PyObject *data_obj;
    if (_Py_hashlib_data_argument(&data_obj, data, string) < 0) {
        return NULL;
    }
    _hashlibstate *state = get_hashlib_state(module);
    return _hashlib_HASH(state, name, data_obj, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_md5

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

Returns a md5 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_md5_impl(PyObject *module, PyObject *data,
                          int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=ca8cf184d90f7432 input=e7c0adbd6a867db1]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_md5, data, string, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_sha1

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

Returns a sha1 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data,
                           int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=1736fb7b310d64be input=f7e5bb1711e952d8]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha1, data, string, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_sha224

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

Returns a sha224 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data,
                             int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=0d6ff57be5e5c140 input=3820fff7ed3a53b8]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha224, data, string, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_sha256

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

Returns a sha256 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data,
                             int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=412ea7111555b6e7 input=9a2f115cf1f7e0eb]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha256, data, string, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_sha384

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

Returns a sha384 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data,
                             int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=2e0dc395b59ed726 input=1ea48f6f01e77cfb]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha384, data, string, usedforsecurity);
}


/*[clinic input]
_hashlib.openssl_sha512

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

Returns a sha512 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data,
                             int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=4bdd760388dbfc0f input=3cf56903e07d1f5c]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha512, data, string, usedforsecurity);
}


#ifdef PY_OPENSSL_HAS_SHA3

/*[clinic input]
_hashlib.openssl_sha3_224

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

Returns a sha3-224 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data,
                               int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=6d8dc2a924f3ba35 input=7f14f16a9f6a3158]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha3_224, data, string, usedforsecurity);
}

/*[clinic input]
_hashlib.openssl_sha3_256

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

Returns a sha3-256 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data,
                               int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=9e520f537b3a4622 input=7987150939d5e352]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha3_256, data, string, usedforsecurity);
}

/*[clinic input]
_hashlib.openssl_sha3_384

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

Returns a sha3-384 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data,
                               int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=d239ba0463fd6138 input=fc943401f67e3b81]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha3_384, data, string, usedforsecurity);
}

/*[clinic input]
_hashlib.openssl_sha3_512

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

Returns a sha3-512 hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data,
                               int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=17662f21038c2278 input=6601ddd2c6c1516d]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_sha3_512, data, string, usedforsecurity);
}
#endif /* PY_OPENSSL_HAS_SHA3 */

#ifdef PY_OPENSSL_HAS_SHAKE
/*[clinic input]
@permit_long_summary
_hashlib.openssl_shake_128

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

Returns a shake-128 variable hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data,
                                int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=4e6afed8d18980ad input=0d2803af1158b23c]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_shake_128, data, string, usedforsecurity);
}

/*[clinic input]
@permit_long_summary
_hashlib.openssl_shake_256

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

Returns a shake-256 variable hash object; optionally initialized with a string

[clinic start generated code]*/

static PyObject *
_hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data,
                                int usedforsecurity, PyObject *string)
/*[clinic end generated code: output=62481bce4a77d16c input=f27b98d9c749f55d]*/
{
    CALL_HASHLIB_NEW(module, Py_hash_shake_256, data, string, usedforsecurity);
}
#endif /* PY_OPENSSL_HAS_SHAKE */

#undef CALL_HASHLIB_NEW

/*[clinic input]
@permit_long_summary
_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]*/

static PyObject *
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=83417fbd9ec2b8a3]*/
{
    _hashlibstate *state = get_hashlib_state(module);
    PyObject *key_obj = NULL;
    long dklen;
    int retval;

    PY_EVP_MD *digest = get_openssl_evp_md_by_utf8name(state, hash_name,
                                                       Py_ht_pbkdf2);
    if (digest == NULL) {
        goto end;
    }

    if (password->len > INT_MAX) {
        PyErr_SetString(PyExc_OverflowError,
                        "password is too long.");
        goto end;
    }

    if (salt->len > INT_MAX) {
        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;
    }

    PyBytesWriter *writer = PyBytesWriter_Create(dklen);
    if (writer == NULL) {
        goto end;
    }

    Py_BEGIN_ALLOW_THREADS
    retval = PKCS5_PBKDF2_HMAC((const char *)password->buf, (int)password->len,
                               (const unsigned char *)salt->buf, (int)salt->len,
                               iterations, digest, dklen,
                               (unsigned char *)PyBytesWriter_GetData(writer));
    Py_END_ALLOW_THREADS

    if (!retval) {
        PyBytesWriter_Discard(writer);
        notify_ssl_error_occurred_in(Py_STRINGIFY(PKCS5_PBKDF2_HMAC));
        goto end;
    }
    key_obj = PyBytesWriter_Finish(writer);

end:
    if (digest != NULL) {
        PY_EVP_MD_free(digest);
    }
    return key_obj;
}

// --- PBKDF: scrypt (RFC 7914) -----------------------------------------------

/*
 * By default, OpenSSL 1.1.0 restricts 'maxmem' in EVP_PBE_scrypt()
 * to 32 MiB (1024 * 1024 * 32) but only if 'maxmem = 0' and allows
 * for an arbitrary large limit fitting on an uint64_t otherwise.
 *
 * For legacy reasons, we limited 'maxmem' to be at most INTMAX,
 * but if users need a more relaxed value, we will revisit this
 * limit in the future.
 */
#define HASHLIB_SCRYPT_MAX_MAXMEM   INT_MAX

/*
 * Limit 'dklen' to INT_MAX even if it can be at most (32 * UINT32_MAX).
 *
 * See https://datatracker.ietf.org/doc/html/rfc7914.html for details.
 */
#define HASHLIB_SCRYPT_MAX_DKLEN    INT_MAX

/*[clinic input]
_hashlib.scrypt

    password: Py_buffer
    *
    salt: Py_buffer
    n: unsigned_long
    r: unsigned_long
    p: unsigned_long
    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,
                     unsigned long n, unsigned long r, unsigned long p,
                     long maxmem, long dklen)
/*[clinic end generated code: output=d424bc3e8c6b9654 input=bdeac9628d07f7a1]*/
{
    int retval;

    if (password->len > INT_MAX) {
        PyErr_SetString(PyExc_OverflowError, "password is too long");
        return NULL;
    }

    if (salt->len > INT_MAX) {
        PyErr_SetString(PyExc_OverflowError, "salt is too long");
        return NULL;
    }

    if (n < 2 || n & (n - 1)) {
        PyErr_SetString(PyExc_ValueError, "n must be a power of 2");
        return NULL;
    }

    if (maxmem < 0 || maxmem > HASHLIB_SCRYPT_MAX_MAXMEM) {
        PyErr_Format(PyExc_ValueError,
                     "maxmem must be positive and at most %d",
                     HASHLIB_SCRYPT_MAX_MAXMEM);
        return NULL;
    }

    if (dklen < 1 || dklen > HASHLIB_SCRYPT_MAX_DKLEN) {
        PyErr_Format(PyExc_ValueError,
                     "dklen must be at least 1 and at most %d",
                     HASHLIB_SCRYPT_MAX_DKLEN);
        return NULL;
    }

    /* let OpenSSL validate the rest */
    retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p,
                            (uint64_t)maxmem, NULL, 0);
    if (!retval) {
        notify_ssl_error_occurred("invalid parameter combination for "
                                  "n, r, p, and maxmem");
        return NULL;
   }

    PyBytesWriter *writer = PyBytesWriter_Create(dklen);
    if (writer == NULL) {
        return NULL;
    }

    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,
        (uint64_t)n, (uint64_t)r, (uint64_t)p, (uint64_t)maxmem,
        (unsigned char *)PyBytesWriter_GetData(writer), (size_t)dklen
    );
    Py_END_ALLOW_THREADS

    if (!retval) {
        PyBytesWriter_Discard(writer);
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_PBE_scrypt));
        return NULL;
    }
    return PyBytesWriter_Finish(writer);
}

#undef HASHLIB_SCRYPT_MAX_DKLEN
#undef HASHLIB_SCRYPT_MAX_MAXMEM

// --- OpenSSL HMAC interface -------------------------------------------------

/*
 * Functions prefixed by hashlib_openssl_HMAC_* are wrappers around OpenSSL
 * and implement "atomic" operations (e.g., "free"). These functions are used
 * by those prefixed by _hashlib_HMAC_* that are methods for HMAC objects, or
 * other (local) helper functions prefixed by hashlib_HMAC_*.
 */

#ifdef Py_HAS_OPENSSL3_SUPPORT
/* EVP_MAC_CTX array of parameters specifying the "digest" */
#define HASHLIB_HMAC_OSSL_PARAMS(DIGEST)                        \
    (const OSSL_PARAM []) {                                     \
        OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST,           \
                               (char *)DIGEST, strlen(DIGEST)), \
        OSSL_PARAM_END                                          \
    }
#endif

// --- One-shot HMAC interface ------------------------------------------------

/*[clinic input]
_hashlib.hmac_digest as _hashlib_hmac_singleshot

    key: Py_buffer
    msg: Py_buffer
    digest: object

Single-shot HMAC.
[clinic start generated code]*/

static PyObject *
_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
                              Py_buffer *msg, PyObject *digest)
/*[clinic end generated code: output=82f19965d12706ac input=0a0790cc3db45c2e]*/
{
    _hashlibstate *state = get_hashlib_state(module);
    unsigned char md[EVP_MAX_MD_SIZE] = {0};
#ifdef Py_HAS_OPENSSL3_SUPPORT
    size_t md_len = 0;
    const char *digest_name = NULL;
#else
    unsigned int md_len = 0;
#endif
    unsigned char *result = NULL;
    PY_EVP_MD *evp = NULL;
    int is_xof;

    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;
    }

#ifdef Py_HAS_OPENSSL3_SUPPORT
    digest_name = get_openssl_digest_name(state, digest, Py_ht_mac, &evp);
    if (digest_name == NULL) {
        assert(evp == NULL);
        return NULL;
    }
    assert(evp != NULL);
    is_xof = PY_EVP_MD_xof(evp);

    Py_BEGIN_ALLOW_THREADS
    result = EVP_Q_mac(
        NULL, OSSL_MAC_NAME_HMAC, NULL, NULL,
        HASHLIB_HMAC_OSSL_PARAMS(digest_name),
        (const void *)key->buf, (size_t)key->len,
        (const unsigned char *)msg->buf, (size_t)msg->len,
        md, sizeof(md), &md_len
    );
    Py_END_ALLOW_THREADS
    PY_EVP_MD_free(evp);
    assert(md_len < (size_t)PY_SSIZE_T_MAX);
#else
    evp = get_openssl_evp_md(state, digest, Py_ht_mac);
    if (evp == NULL) {
        return NULL;
    }
    is_xof = PY_EVP_MD_xof(evp);

    Py_BEGIN_ALLOW_THREADS
    result = HMAC(
        evp,
        (const void *)key->buf, (int)key->len,
        (const unsigned char *)msg->buf, (size_t)msg->len,
        md, &md_len
    );
    Py_END_ALLOW_THREADS
    PY_EVP_MD_free(evp);
#endif
    if (result == NULL) {
        if (is_xof) {
            /* use a better default error message if an XOF is used */
            raise_unsupported_algorithm_error(state, digest);
        }
        else {
#ifdef Py_HAS_OPENSSL3_SUPPORT
            notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_Q_mac));
#else
            notify_ssl_error_occurred_in(Py_STRINGIFY(HMAC));
#endif
        }
        return NULL;
    }
    return PyBytes_FromStringAndSize((const char*)md, md_len);
}

// --- HMAC Object ------------------------------------------------------------

#ifndef Py_HAS_OPENSSL3_SUPPORT
/* Thin wrapper around HMAC_CTX_new() which sets an exception on failure. */
static HMAC_CTX *
py_openssl_wrapper_HMAC_CTX_new(void)
{
    HMAC_CTX *ctx = HMAC_CTX_new();
    if (ctx == NULL) {
        PyErr_NoMemory();
        return NULL;
    }
    return ctx;
}
#endif

static int _hmac_update(HMACobject*, PyObject*);

#ifndef Py_HAS_OPENSSL3_SUPPORT
static const EVP_MD *
_hashlib_hmac_get_md(HMACobject *self)
{
    assert(self->ctx != NULL);
    const EVP_MD *md = HMAC_CTX_get_md(self->ctx);
    if (md == NULL) {
        notify_ssl_error_occurred("missing EVP_MD for HMAC context");
    }
    return md;
}
#endif

static const char *
hashlib_HMAC_get_hashlib_digest_name(HMACobject *self)
{
#ifdef Py_HAS_OPENSSL3_SUPPORT
    return get_hashlib_utf8name_by_nid(self->evp_md_nid);
#else
    const EVP_MD *md = _hashlib_hmac_get_md(self);
    return md == NULL ? NULL : get_hashlib_utf8name_by_evp_md(md);
#endif
}

static int
hashlib_openssl_HMAC_update_once(PY_HMAC_CTX_TYPE *ctx, const Py_buffer *v)
{
    if (!PY_HMAC_update(ctx, (const unsigned char *)v->buf, (size_t)v->len)) {
        notify_smart_ssl_error_occurred_in(Py_STRINGIFY(PY_HMAC_update));
        return -1;
    }
    return 0;
}

/* Thin wrapper around PY_HMAC_CTX_free that allows to pass a NULL 'ctx'. */
static inline void
hashlib_openssl_HMAC_CTX_free(PY_HMAC_CTX_TYPE *ctx)
{
    /* The NULL check was not present in every OpenSSL versions. */
    if (ctx) {
        PY_HMAC_CTX_free(ctx);
    }
}

static PY_HMAC_CTX_TYPE *
hashlib_openssl_HMAC_ctx_copy_with_lock(HMACobject *self)
{
    PY_HMAC_CTX_TYPE *ctx = NULL;
#ifdef Py_HAS_OPENSSL3_SUPPORT
    HASHLIB_ACQUIRE_LOCK(self);
    ctx = EVP_MAC_CTX_dup(self->ctx);
    HASHLIB_RELEASE_LOCK(self);
    if (ctx == NULL) {
        notify_smart_ssl_error_occurred_in(Py_STRINGIFY(EVP_MAC_CTX_dup));
        goto error;
    }
#else
    int r;
    ctx = py_openssl_wrapper_HMAC_CTX_new();
    if (ctx == NULL) {
        return NULL;
    }
    HASHLIB_ACQUIRE_LOCK(self);
    r = HMAC_CTX_copy(ctx, self->ctx);
    HASHLIB_RELEASE_LOCK(self);
    if (r == 0) {
        notify_smart_ssl_error_occurred_in(Py_STRINGIFY(HMAC_CTX_copy));
        goto error;
    }
#endif
    return ctx;

error:
    hashlib_openssl_HMAC_CTX_free(ctx);
    return NULL;
}

static PY_HMAC_CTX_TYPE *
hashlib_HMAC_CTX_new_from_digestmod(_hashlibstate *state,
                                    Py_buffer *key, PyObject *digestmod,
                                    int *nid)
{
    PY_HMAC_CTX_TYPE *ctx = NULL;
    PY_EVP_MD *md = NULL;
    int is_xof, r;
#ifdef Py_HAS_OPENSSL3_SUPPORT
    const char *digest = NULL;
#endif

#ifdef Py_HAS_OPENSSL3_SUPPORT
    /*
     * OpenSSL 3.0 does not provide a way to extract the NID from an EVP_MAC
     * object and does not expose the underlying digest name. The reason is
     * that OpenSSL 3.0 treats HMAC objects as being the "same", differing
     * only by their *context* parameters. While it is *required* to set
     * the digest name when constructing EVP_MAC_CTX objects, that name
     * is unfortunately not recoverable through EVP_MAC_CTX_get_params().
     *
     * On the other hand, the (deprecated) interface based on HMAC_CTX is
     * based on EVP_MD, which allows to treat HMAC objects as if they were
     * hash functions when querying the digest name.
     *
     * Since HMAC objects are constructed from DIGESTMOD values and since
     * we have a way to map DIGESTMOD to EVP_MD objects, and then to NIDs,
     * HMAC objects based on EVP_MAC will store the NID of the EVP_MD we
     * used to deduce the digest name to pass to EVP_MAC_CTX_set_params().
     */
    assert(nid != NULL);
    digest = get_openssl_digest_name(state, digestmod, Py_ht_mac, &md);
    assert((digest == NULL && md == NULL) || (digest != NULL && md != NULL));
    if (digest == NULL) {
        *nid = NID_undef;
        return NULL;
    }
    *nid = EVP_MD_nid(md);
    is_xof = PY_EVP_MD_xof(md);
    PY_EVP_MD_free(md);

    /*
     * OpenSSL is responsible for managing the EVP_MAC object's ref. count
     * by calling EVP_MAC_up_ref() and EVP_MAC_free() in EVP_MAC_CTX_new()
     * and EVP_MAC_CTX_free() respectively.
     */
    ctx = EVP_MAC_CTX_new(state->evp_hmac);
    if (ctx == NULL) {
        /* EVP_MAC_CTX_new() may also set an ERR_R_EVP_LIB error */
        notify_smart_ssl_error_occurred_in(Py_STRINGIFY(EVP_MAC_CTX_new));
        return NULL;
    }

    r = EVP_MAC_init(
        ctx,
        (const unsigned char *)key->buf,
        (size_t)key->len,
        HASHLIB_HMAC_OSSL_PARAMS(digest)
    );
#else
    assert(nid == NULL);
    md = get_openssl_evp_md(state, digestmod, Py_ht_mac);
    if (md == NULL) {
        return NULL;
    }
    is_xof = PY_EVP_MD_xof(md);

    ctx = py_openssl_wrapper_HMAC_CTX_new();
    if (ctx == NULL) {
        PY_EVP_MD_free(md);
        return NULL;
    }

    r = HMAC_Init_ex(ctx, key->buf, (int)key->len, md, NULL /* impl */);
    PY_EVP_MD_free(md);
#endif
    if (r == 0) {
        if (is_xof) {
            /* use a better default error message if an XOF is used */
            raise_unsupported_algorithm_error(state, digestmod);
        }
        else {
#ifdef Py_HAS_OPENSSL3_SUPPORT
            notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_MAC_init));
#else
            notify_ssl_error_occurred_in(Py_STRINGIFY(HMAC_Init_ex));
#endif
        }
        return NULL;
    }
    return ctx;
}

/*[clinic input]
_hashlib.hmac_new

    key: Py_buffer
    msg as msg_obj: object(c_default="NULL") = b''
    digestmod: object(c_default="NULL") = None

Return a new hmac object.
[clinic start generated code]*/

static PyObject *
_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
                       PyObject *digestmod)
/*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/
{
    _hashlibstate *state = get_hashlib_state(module);
    PY_HMAC_CTX_TYPE *ctx = NULL;
    HMACobject *self = NULL;
#ifdef Py_HAS_OPENSSL3_SUPPORT
    int nid;
#endif

    if (key->len > INT_MAX) {
        PyErr_SetString(PyExc_OverflowError,
                        "key is too long.");
        return NULL;
    }

    if (digestmod == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Missing required parameter 'digestmod'.");
        return NULL;
    }

#ifdef Py_HAS_OPENSSL3_SUPPORT
    ctx = hashlib_HMAC_CTX_new_from_digestmod(state, key, digestmod, &nid);
#else
    ctx = hashlib_HMAC_CTX_new_from_digestmod(state, key, digestmod, NULL);
#endif

    if (ctx == NULL) {
        assert(PyErr_Occurred());
        return NULL;
    }

    self = PyObject_New(HMACobject, state->HMAC_type);
    if (self == NULL) {
        goto error;
    }

    self->ctx = ctx;
    ctx = NULL;  // 'ctx' is now owned by 'self'
#ifdef Py_HAS_OPENSSL3_SUPPORT
    assert(nid != NID_undef);
    self->evp_md_nid = nid;
#endif
    HASHLIB_INIT_MUTEX(self);

    /* feed initial data */
    if ((msg_obj != NULL) && (msg_obj != Py_None)) {
        if (_hmac_update(self, msg_obj) < 0) {
            goto error;
        }
    }
    return (PyObject *)self;

error:
    hashlib_openssl_HMAC_CTX_free(ctx);
    Py_XDECREF(self);
    return NULL;
}

/* helper functions */
#define BAD_DIGEST_SIZE 0

/*
 * Return the digest size in bytes.
 *
 * On error, set an exception and return BAD_DIGEST_SIZE.
 */
static unsigned int
_hashlib_hmac_digest_size(HMACobject *self)
{
    assert(EVP_MAX_MD_SIZE < INT_MAX);
#ifdef Py_HAS_OPENSSL3_SUPPORT
    assert(self->ctx != NULL);
    size_t digest_size = EVP_MAC_CTX_get_mac_size(self->ctx);
    assert(digest_size <= (size_t)EVP_MAX_MD_SIZE);
#else
    const EVP_MD *md = _hashlib_hmac_get_md(self);
    if (md == NULL) {
        return BAD_DIGEST_SIZE;
    }
    int digest_size = EVP_MD_size(md);
    /* digest_size < 0 iff EVP_MD context is NULL (which is impossible here) */
    assert(digest_size >= 0);
    assert(digest_size <= (int)EVP_MAX_MD_SIZE);
#endif
    /* digest_size == 0 means that the context is not entirely initialized */
    if (digest_size == 0) {
        raise_ssl_error(PyExc_ValueError, "missing digest size");
        return BAD_DIGEST_SIZE;
    }
    return (unsigned int)digest_size;
}

static int
_hmac_update(HMACobject *self, PyObject *obj)
{
    int r;
    Py_buffer view = {0};
    GET_BUFFER_VIEW_OR_ERROR(obj, &view, return -1);
    HASHLIB_EXTERNAL_INSTRUCTIONS_LOCKED(
        self, view.len,
        r = hashlib_openssl_HMAC_update_once(self->ctx, &view)
    );
    PyBuffer_Release(&view);
    return r;
}

/*[clinic input]
_hashlib.HMAC.copy

Return a copy ("clone") of the HMAC object.
[clinic start generated code]*/

static PyObject *
_hashlib_HMAC_copy_impl(HMACobject *self)
/*[clinic end generated code: output=29aa28b452833127 input=e2fa6a05db61a4d6]*/
{
    HMACobject *retval;
    PY_HMAC_CTX_TYPE *ctx = hashlib_openssl_HMAC_ctx_copy_with_lock(self);
    if (ctx == NULL) {
        return NULL;
    }
    retval = PyObject_New(HMACobject, Py_TYPE(self));
    if (retval == NULL) {
        PY_HMAC_CTX_free(ctx);
        return NULL;
    }
    retval->ctx = ctx;
#ifdef Py_HAS_OPENSSL3_SUPPORT
    retval->evp_md_nid = self->evp_md_nid;
#endif
    HASHLIB_INIT_MUTEX(retval);
    return (PyObject *)retval;
}

static void
_hmac_dealloc(PyObject *op)
{
    HMACobject *self = HMACobject_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    if (self->ctx != NULL) {
        PY_HMAC_CTX_free(self->ctx);
        self->ctx = NULL;
    }
    PyObject_Free(self);
    Py_DECREF(tp);
}

static PyObject *
_hmac_repr(PyObject *op)
{
    HMACobject *self = HMACobject_CAST(op);
    const char *digest_name = hashlib_HMAC_get_hashlib_digest_name(self);
    if (digest_name == NULL) {
        assert(PyErr_Occurred());
        return NULL;
    }
    return PyUnicode_FromFormat("<%s HMAC object @ %p>", digest_name, self);
}

/*[clinic input]
_hashlib.HMAC.update
    msg: object

Update the HMAC object with msg.
[clinic start generated code]*/

static PyObject *
_hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg)
/*[clinic end generated code: output=f31f0ace8c625b00 input=1829173bb3cfd4e6]*/
{
    if (_hmac_update(self, msg) < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

/*
 * Extract the MAC value to 'buf' and return the digest size.
 *
 * The buffer 'buf' must have at least _hashlib_hmac_digest_size(self)
 * bytes. Smaller buffers lead to undefined behaviors.
 *
 * On error, set an exception and return -1.
 */
static Py_ssize_t
_hmac_digest(HMACobject *self, unsigned char *buf)
{
    unsigned int digest_size = _hashlib_hmac_digest_size(self);
    assert(digest_size <= EVP_MAX_MD_SIZE);
    if (digest_size == BAD_DIGEST_SIZE) {
        assert(PyErr_Occurred());
        return -1;
    }
    PY_HMAC_CTX_TYPE *ctx = hashlib_openssl_HMAC_ctx_copy_with_lock(self);
    if (ctx == NULL) {
        return -1;
    }
#ifdef Py_HAS_OPENSSL3_SUPPORT
    int r = EVP_MAC_final(ctx, buf, NULL, digest_size);
#else
    int r = HMAC_Final(ctx, buf, NULL);
#endif
    PY_HMAC_CTX_free(ctx);
    if (r == 0) {
#ifdef Py_HAS_OPENSSL3_SUPPORT
        notify_ssl_error_occurred_in(Py_STRINGIFY(EVP_MAC_final));
#else
        notify_ssl_error_occurred_in(Py_STRINGIFY(HMAC_Final));
#endif
        return -1;
    }
    return digest_size;
}

/*[clinic input]
_hashlib.HMAC.digest
Return the digest of the bytes passed to the update() method so far.
[clinic start generated code]*/

static PyObject *
_hashlib_HMAC_digest_impl(HMACobject *self)
/*[clinic end generated code: output=1b1424355af7a41e input=bff07f74da318fb4]*/
{
    unsigned char buf[EVP_MAX_MD_SIZE];
    Py_ssize_t n = _hmac_digest(self, buf);
    return n < 0 ? NULL : PyBytes_FromStringAndSize((const char *)buf, n);
}

/*[clinic input]
@permit_long_summary
@permit_long_docstring_body
_hashlib.HMAC.hexdigest

Return hexadecimal digest of the bytes passed to the update() method so far.

This may be used to exchange the value safely in email or other non-binary
environments.
[clinic start generated code]*/

static PyObject *
_hashlib_HMAC_hexdigest_impl(HMACobject *self)
/*[clinic end generated code: output=80d825be1eaae6a7 input=5e48db83ab1a4d19]*/
{
    unsigned char buf[EVP_MAX_MD_SIZE];
    Py_ssize_t n = _hmac_digest(self, buf);
    return n < 0 ? NULL : _Py_strhex((const char *)buf, n);
}

static PyObject *
_hashlib_hmac_get_digest_size(PyObject *op, void *Py_UNUSED(closure))
{
    HMACobject *self = HMACobject_CAST(op);
    unsigned int size = _hashlib_hmac_digest_size(self);
    return size == BAD_DIGEST_SIZE ? NULL : PyLong_FromLong(size);
}

static PyObject *
_hashlib_hmac_get_block_size(PyObject *op, void *Py_UNUSED(closure))
{
    HMACobject *self = HMACobject_CAST(op);
#ifdef Py_HAS_OPENSSL3_SUPPORT
    assert(self->ctx != NULL);
    return PyLong_FromSize_t(EVP_MAC_CTX_get_block_size(self->ctx));
#else
    const EVP_MD *md = _hashlib_hmac_get_md(self);
    return md == NULL ? NULL : PyLong_FromLong(EVP_MD_block_size(md));
#endif
}

static PyObject *
_hashlib_hmac_get_name(PyObject *op, void *Py_UNUSED(closure))
{
    HMACobject *self = HMACobject_CAST(op);
    const char *digest_name = hashlib_HMAC_get_hashlib_digest_name(self);
    if (digest_name == NULL) {
        assert(PyErr_Occurred());
        return NULL;
    }
    return PyUnicode_FromFormat("hmac-%s", digest_name);
}

static PyMethodDef HMAC_methods[] = {
    _HASHLIB_HMAC_UPDATE_METHODDEF
    _HASHLIB_HMAC_DIGEST_METHODDEF
    _HASHLIB_HMAC_HEXDIGEST_METHODDEF
    _HASHLIB_HMAC_COPY_METHODDEF
    {NULL, NULL}  /* sentinel */
};

static PyGetSetDef HMAC_getset[] = {
    {"digest_size", _hashlib_hmac_get_digest_size, NULL, NULL, NULL},
    {"block_size", _hashlib_hmac_get_block_size, NULL, NULL, NULL},
    {"name", _hashlib_hmac_get_name, NULL, NULL, NULL},
    {NULL}  /* Sentinel */
};


PyDoc_STRVAR(hmactype_doc,
"The object used to calculate HMAC of a message.\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 name, including the hash algorithm used by this object\n\
digest_size -- number of bytes in digest() output\n");

static PyType_Slot HMACtype_slots[] = {
    {Py_tp_doc, (char *)hmactype_doc},
    {Py_tp_repr, _hmac_repr},
    {Py_tp_dealloc, _hmac_dealloc},
    {Py_tp_methods, HMAC_methods},
    {Py_tp_getset, HMAC_getset},
    {0, NULL}
};

PyType_Spec HMACtype_spec = {
    "_hashlib.HMAC",    /* name */
    sizeof(HMACobject),     /* basicsize */
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
    .slots = HMACtype_slots,
};


/* 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
#ifdef Py_HAS_OPENSSL3_SUPPORT
_openssl_hash_name_mapper(EVP_MD *md, void *arg)
#else
_openssl_hash_name_mapper(const EVP_MD *md, const char *from,
                          const char *to, void *arg)
#endif
{
    _InternalNameMapperState *state = (_InternalNameMapperState *)arg;
    PyObject *py_name;

    assert(state != NULL);
    // ignore all undefined providers
    if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) {
        return;
    }

    const char *name = get_hashlib_utf8name_by_evp_md(md);
    assert(name != NULL || PyErr_Occurred());
    py_name = name == NULL ? NULL : PyUnicode_FromString(name);
    if (py_name == NULL) {
        state->error = 1;
    } else {
        if (PySet_Add(state->set, py_name) != 0) {
            state->error = 1;
        }
        Py_DECREF(py_name);
    }
}


/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
static int
hashlib_md_meth_names(PyObject *module)
{
    _InternalNameMapperState state = {
        .set = PyFrozenSet_New(NULL),
        .error = 0
    };
    if (state.set == NULL) {
        return -1;
    }

#ifdef Py_HAS_OPENSSL3_SUPPORT
    // get algorithms from all activated providers in default context
    EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state);
#else
    EVP_MD_do_all(&_openssl_hash_name_mapper, &state);
#endif

    if (state.error) {
        Py_DECREF(state.set);
        return -1;
    }

    return PyModule_Add(module, "openssl_md_meth_names", state.set);
}

/*[clinic input]
_hashlib.get_fips_mode -> int

Determine the OpenSSL FIPS mode of operation.

For OpenSSL 3.0.0 and newer it returns the state of the default provider
in the default OSSL context. It's not quite the same as FIPS_mode() but good
enough for unittests.

Effectively any non-zero return value indicates FIPS mode;
values other than 1 may have additional significance.
[clinic start generated code]*/

static int
_hashlib_get_fips_mode_impl(PyObject *module)
/*[clinic end generated code: output=87eece1bab4d3fa9 input=2db61538c41c6fef]*/

{
#ifdef Py_HAS_OPENSSL3_SUPPORT
    return EVP_default_properties_is_fips_enabled(NULL);
#else
    ERR_clear_error();
    int result = FIPS_mode();
    if (result == 0 && ERR_peek_last_error()) {
        // "If the library was built without support of the FIPS Object Module,
        // then the function will return 0 with an error code of
        // CRYPTO_R_FIPS_MODE_NOT_SUPPORTED (0x0f06d065)."
        // But 0 is also a valid result value.
        notify_ssl_error_occurred_in(Py_STRINGIFY(FIPS_mode));
        return -1;
    }
    return result;
#endif
}


static int
_tscmp(const unsigned char *a, const unsigned char *b,
        Py_ssize_t len_a, Py_ssize_t len_b)
{
    /* loop count depends on length of b. Might leak very little timing
     * information if sizes are different.
     */
    Py_ssize_t length = len_b;
    const void *left = a;
    const void *right = b;
    int result = 0;

    if (len_a != length) {
        left = b;
        result = 1;
    }

    result |= CRYPTO_memcmp(left, right, length);

    return (result == 0);
}

/* NOTE: Keep in sync with _operator.c implementation. */

/*[clinic input]
_hashlib.compare_digest

    a: object
    b: object
    /

Return 'a == b'.

This function uses an approach designed to prevent
timing analysis, making it appropriate for cryptography.

a and b must both be of the same type: either str (ASCII only),
or any bytes-like object.

Note: If a and b are of different lengths, or if an error occurs,
a timing attack could theoretically reveal information about the
types and lengths of a and b--but not their values.
[clinic start generated code]*/

static PyObject *
_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
/*[clinic end generated code: output=6f1c13927480aed9 input=9c40c6e566ca12f5]*/
{
    int rc;

    /* ASCII unicode string */
    if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
        if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
            PyErr_SetString(PyExc_TypeError,
                            "comparing strings with non-ASCII characters is "
                            "not supported");
            return NULL;
        }

        rc = _tscmp(PyUnicode_DATA(a),
                    PyUnicode_DATA(b),
                    PyUnicode_GET_LENGTH(a),
                    PyUnicode_GET_LENGTH(b));
    }
    /* fallback to buffer interface for bytes, bytearray and other */
    else {
        Py_buffer view_a;
        Py_buffer view_b;

        if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
            PyErr_Format(PyExc_TypeError,
                         "unsupported operand types(s) or combination of types: "
                         "'%.100s' and '%.100s'",
                         Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
            return NULL;
        }

        if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
            return NULL;
        }
        if (view_a.ndim > 1) {
            PyErr_SetString(PyExc_BufferError,
                            "Buffer must be single dimension");
            PyBuffer_Release(&view_a);
            return NULL;
        }

        if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
            PyBuffer_Release(&view_a);
            return NULL;
        }
        if (view_b.ndim > 1) {
            PyErr_SetString(PyExc_BufferError,
                            "Buffer must be single dimension");
            PyBuffer_Release(&view_a);
            PyBuffer_Release(&view_b);
            return NULL;
        }

        rc = _tscmp((const unsigned char*)view_a.buf,
                    (const unsigned char*)view_b.buf,
                    view_a.len,
                    view_b.len);

        PyBuffer_Release(&view_a);
        PyBuffer_Release(&view_b);
    }

    return PyBool_FromLong(rc);
}

/* List of functions exported by this module */

static struct PyMethodDef EVP_functions[] = {
    _HASHLIB_HASH_NEW_METHODDEF
    PBKDF2_HMAC_METHODDEF
    _HASHLIB_SCRYPT_METHODDEF
    _HASHLIB_GET_FIPS_MODE_METHODDEF
    _HASHLIB_COMPARE_DIGEST_METHODDEF
    _HASHLIB_HMAC_SINGLESHOT_METHODDEF
    _HASHLIB_HMAC_NEW_METHODDEF
    _HASHLIB_OPENSSL_MD5_METHODDEF
    _HASHLIB_OPENSSL_SHA1_METHODDEF
    _HASHLIB_OPENSSL_SHA224_METHODDEF
    _HASHLIB_OPENSSL_SHA256_METHODDEF
    _HASHLIB_OPENSSL_SHA384_METHODDEF
    _HASHLIB_OPENSSL_SHA512_METHODDEF
    _HASHLIB_OPENSSL_SHA3_224_METHODDEF
    _HASHLIB_OPENSSL_SHA3_256_METHODDEF
    _HASHLIB_OPENSSL_SHA3_384_METHODDEF
    _HASHLIB_OPENSSL_SHA3_512_METHODDEF
    _HASHLIB_OPENSSL_SHAKE_128_METHODDEF
    _HASHLIB_OPENSSL_SHAKE_256_METHODDEF
    {NULL,      NULL}            /* Sentinel */
};


/* Initialize this module. */

static int
hashlib_traverse(PyObject *m, visitproc visit, void *arg)
{
    _hashlibstate *state = get_hashlib_state(m);
    Py_VISIT(state->HASH_type);
    Py_VISIT(state->HMAC_type);
#ifdef PY_OPENSSL_HAS_SHAKE
    Py_VISIT(state->HASHXOF_type);
#endif
    Py_VISIT(state->constructs);
    Py_VISIT(state->unsupported_digestmod_error);
    return 0;
}

static int
hashlib_clear(PyObject *m)
{
    _hashlibstate *state = get_hashlib_state(m);
    Py_CLEAR(state->HASH_type);
    Py_CLEAR(state->HMAC_type);
#ifdef PY_OPENSSL_HAS_SHAKE
    Py_CLEAR(state->HASHXOF_type);
#endif
    Py_CLEAR(state->constructs);
    Py_CLEAR(state->unsupported_digestmod_error);

    if (state->hashtable != NULL) {
        _Py_hashtable_destroy(state->hashtable);
        state->hashtable = NULL;
    }
#ifdef Py_HAS_OPENSSL3_SUPPORT
    if (state->evp_hmac != NULL) {
        EVP_MAC_free(state->evp_hmac);
        state->evp_hmac = NULL;
    }
#endif

    return 0;
}

static void
hashlib_free(void *m)
{
    (void)hashlib_clear((PyObject *)m);
}

/* Py_mod_exec functions */
static int
hashlib_init_hashtable(PyObject *module)
{
    _hashlibstate *state = get_hashlib_state(module);

    state->hashtable = py_hashentry_table_new();
    if (state->hashtable == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    return 0;
}

static int
hashlib_init_HASH_type(PyObject *module)
{
    _hashlibstate *state = get_hashlib_state(module);

    state->HASH_type = (PyTypeObject *)PyType_FromSpec(&HASHobject_type_spec);
    if (state->HASH_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->HASH_type) < 0) {
        return -1;
    }
    return 0;
}

static int
hashlib_init_HASHXOF_type(PyObject *module)
{
#ifdef PY_OPENSSL_HAS_SHAKE
    _hashlibstate *state = get_hashlib_state(module);

    if (state->HASH_type == NULL) {
        return -1;
    }

    state->HASHXOF_type = (PyTypeObject *)PyType_FromSpecWithBases(
        &HASHXOFobject_type_spec, (PyObject *)state->HASH_type
    );
    if (state->HASHXOF_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->HASHXOF_type) < 0) {
        return -1;
    }
#endif
    return 0;
}

static int
hashlib_init_hmactype(PyObject *module)
{
    _hashlibstate *state = get_hashlib_state(module);

    state->HMAC_type = (PyTypeObject *)PyType_FromSpec(&HMACtype_spec);
    if (state->HMAC_type == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, state->HMAC_type) < 0) {
        return -1;
    }
#ifdef Py_HAS_OPENSSL3_SUPPORT
    state->evp_hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
    if (state->evp_hmac == NULL) {
        ERR_clear_error();
        PyErr_SetString(PyExc_ImportError, "cannot initialize EVP_MAC HMAC");
        return -1;
    }
#endif

    return 0;
}

static int
hashlib_init_constructors(PyObject *module)
{
    /* Create dict from builtin openssl_hash functions to name
     * {_hashlib.openssl_sha256: "sha256", ...}
     */
    PyModuleDef *mdef;
    PyMethodDef *fdef;
    PyObject *func, *name_obj;
    _hashlibstate *state = get_hashlib_state(module);

    mdef = PyModule_GetDef(module);
    if (mdef == NULL) {
        return -1;
    }

    state->constructs = PyDict_New();
    if (state->constructs == NULL) {
        return -1;
    }

    for (fdef = mdef->m_methods; fdef->ml_name != NULL; fdef++) {
        if (strncmp(fdef->ml_name, "openssl_", 8)) {
            continue;
        }
        name_obj = PyUnicode_FromString(fdef->ml_name + 8);
        if (name_obj == NULL) {
            return -1;
        }
        func  = PyObject_GetAttrString(module, fdef->ml_name);
        if (func == NULL) {
            Py_DECREF(name_obj);
            return -1;
        }
        int rc = PyDict_SetItem(state->constructs, func, name_obj);
        Py_DECREF(func);
        Py_DECREF(name_obj);
        if (rc < 0) {
            return -1;
        }
    }

    return PyModule_Add(module, "_constructors",
                        PyDictProxy_New(state->constructs));
}

static int
hashlib_exception(PyObject *module)
{
    _hashlibstate *state = get_hashlib_state(module);
    state->unsupported_digestmod_error = PyErr_NewException(
        "_hashlib.UnsupportedDigestmodError", PyExc_ValueError, NULL);
    if (state->unsupported_digestmod_error == NULL) {
        return -1;
    }
    if (PyModule_AddObjectRef(module, "UnsupportedDigestmodError",
                              state->unsupported_digestmod_error) < 0) {
        return -1;
    }
    return 0;
}

static int
hashlib_constants(PyObject *module)
{
    if (PyModule_AddIntConstant(module, "_GIL_MINSIZE",
                                HASHLIB_GIL_MINSIZE) < 0)
    {
        return -1;
    }
    return 0;
}

static PyModuleDef_Slot hashlib_slots[] = {
    {Py_mod_exec, hashlib_init_hashtable},
    {Py_mod_exec, hashlib_init_HASH_type},
    {Py_mod_exec, hashlib_init_HASHXOF_type},
    {Py_mod_exec, hashlib_init_hmactype},
    {Py_mod_exec, hashlib_md_meth_names},
    {Py_mod_exec, hashlib_init_constructors},
    {Py_mod_exec, hashlib_exception},
    {Py_mod_exec, hashlib_constants},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _hashlibmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_hashlib",
    .m_doc = "OpenSSL interface for hashlib module",
    .m_size = sizeof(_hashlibstate),
    .m_methods = EVP_functions,
    .m_slots = hashlib_slots,
    .m_traverse = hashlib_traverse,
    .m_clear = hashlib_clear,
    .m_free = hashlib_free
};

PyMODINIT_FUNC
PyInit__hashlib(void)
{
    return PyModuleDef_Init(&_hashlibmodule);
}
