17db96d56Sopenharmony_ci/* Module that wraps all OpenSSL hash algorithms */
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci/*
47db96d56Sopenharmony_ci * Copyright (C) 2005-2010   Gregory P. Smith (greg@krypto.org)
57db96d56Sopenharmony_ci * Licensed to PSF under a Contributor Agreement.
67db96d56Sopenharmony_ci *
77db96d56Sopenharmony_ci * Derived from a skeleton of shamodule.c containing work performed by:
87db96d56Sopenharmony_ci *
97db96d56Sopenharmony_ci * Andrew Kuchling (amk@amk.ca)
107db96d56Sopenharmony_ci * Greg Stein (gstein@lyra.org)
117db96d56Sopenharmony_ci *
127db96d56Sopenharmony_ci */
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ci/* Don't warn about deprecated functions, */
157db96d56Sopenharmony_ci#ifndef OPENSSL_API_COMPAT
167db96d56Sopenharmony_ci  // 0x10101000L == 1.1.1, 30000 == 3.0.0
177db96d56Sopenharmony_ci  #define OPENSSL_API_COMPAT 0x10101000L
187db96d56Sopenharmony_ci#endif
197db96d56Sopenharmony_ci#define OPENSSL_NO_DEPRECATED 1
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN
227db96d56Sopenharmony_ci#  define Py_BUILD_CORE_MODULE 1
237db96d56Sopenharmony_ci#endif
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci#include "Python.h"
287db96d56Sopenharmony_ci#include "pycore_hashtable.h"
297db96d56Sopenharmony_ci#include "hashlib.h"
307db96d56Sopenharmony_ci#include "pycore_strhex.h"        // _Py_strhex()
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci/* EVP is the preferred interface to hashing in OpenSSL */
337db96d56Sopenharmony_ci#include <openssl/evp.h>
347db96d56Sopenharmony_ci#include <openssl/hmac.h>
357db96d56Sopenharmony_ci#include <openssl/crypto.h>
367db96d56Sopenharmony_ci/* We use the object interface to discover what hashes OpenSSL supports. */
377db96d56Sopenharmony_ci#include <openssl/objects.h>
387db96d56Sopenharmony_ci#include <openssl/err.h>
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci#include <openssl/crypto.h>       // FIPS_mode()
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci#ifndef OPENSSL_THREADS
437db96d56Sopenharmony_ci#  error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL"
447db96d56Sopenharmony_ci#endif
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci#define MUNCH_SIZE INT_MAX
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_ci#define PY_OPENSSL_HAS_SCRYPT 1
497db96d56Sopenharmony_ci#define PY_OPENSSL_HAS_SHA3 1
507db96d56Sopenharmony_ci#define PY_OPENSSL_HAS_SHAKE 1
517db96d56Sopenharmony_ci#define PY_OPENSSL_HAS_BLAKE2 1
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci#if OPENSSL_VERSION_NUMBER >= 0x30000000L
547db96d56Sopenharmony_ci#define PY_EVP_MD EVP_MD
557db96d56Sopenharmony_ci#define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties)
567db96d56Sopenharmony_ci#define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md)
577db96d56Sopenharmony_ci#define PY_EVP_MD_free(md) EVP_MD_free(md)
587db96d56Sopenharmony_ci#else
597db96d56Sopenharmony_ci#define PY_EVP_MD const EVP_MD
607db96d56Sopenharmony_ci#define PY_EVP_MD_fetch(algorithm, properties) EVP_get_digestbyname(algorithm)
617db96d56Sopenharmony_ci#define PY_EVP_MD_up_ref(md) do {} while(0)
627db96d56Sopenharmony_ci#define PY_EVP_MD_free(md) do {} while(0)
637db96d56Sopenharmony_ci#endif
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci/* hash alias map and fast lookup
667db96d56Sopenharmony_ci *
677db96d56Sopenharmony_ci * Map between Python's preferred names and OpenSSL internal names. Maintain
687db96d56Sopenharmony_ci * cache of fetched EVP MD objects. The EVP_get_digestbyname() and
697db96d56Sopenharmony_ci * EVP_MD_fetch() API calls have a performance impact.
707db96d56Sopenharmony_ci *
717db96d56Sopenharmony_ci * The py_hashentry_t items are stored in a _Py_hashtable_t with py_name and
727db96d56Sopenharmony_ci * py_alias as keys.
737db96d56Sopenharmony_ci */
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_cienum Py_hash_type {
767db96d56Sopenharmony_ci    Py_ht_evp,            // usedforsecurity=True / default
777db96d56Sopenharmony_ci    Py_ht_evp_nosecurity, // usedforsecurity=False
787db96d56Sopenharmony_ci    Py_ht_mac,            // HMAC
797db96d56Sopenharmony_ci    Py_ht_pbkdf2,         // PKBDF2
807db96d56Sopenharmony_ci};
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_citypedef struct {
837db96d56Sopenharmony_ci    const char *py_name;
847db96d56Sopenharmony_ci    const char *py_alias;
857db96d56Sopenharmony_ci    const char *ossl_name;
867db96d56Sopenharmony_ci    int ossl_nid;
877db96d56Sopenharmony_ci    int refcnt;
887db96d56Sopenharmony_ci    PY_EVP_MD *evp;
897db96d56Sopenharmony_ci    PY_EVP_MD *evp_nosecurity;
907db96d56Sopenharmony_ci} py_hashentry_t;
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci#define Py_hash_md5 "md5"
937db96d56Sopenharmony_ci#define Py_hash_sha1 "sha1"
947db96d56Sopenharmony_ci#define Py_hash_sha224 "sha224"
957db96d56Sopenharmony_ci#define Py_hash_sha256 "sha256"
967db96d56Sopenharmony_ci#define Py_hash_sha384 "sha384"
977db96d56Sopenharmony_ci#define Py_hash_sha512 "sha512"
987db96d56Sopenharmony_ci#define Py_hash_sha512_224 "sha512_224"
997db96d56Sopenharmony_ci#define Py_hash_sha512_256 "sha512_256"
1007db96d56Sopenharmony_ci#define Py_hash_sha3_224 "sha3_224"
1017db96d56Sopenharmony_ci#define Py_hash_sha3_256 "sha3_256"
1027db96d56Sopenharmony_ci#define Py_hash_sha3_384 "sha3_384"
1037db96d56Sopenharmony_ci#define Py_hash_sha3_512 "sha3_512"
1047db96d56Sopenharmony_ci#define Py_hash_shake_128 "shake_128"
1057db96d56Sopenharmony_ci#define Py_hash_shake_256 "shake_256"
1067db96d56Sopenharmony_ci#define Py_hash_blake2s "blake2s"
1077db96d56Sopenharmony_ci#define Py_hash_blake2b "blake2b"
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci#define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \
1107db96d56Sopenharmony_ci    {py_name, py_alias, ossl_name, ossl_nid, 0, NULL, NULL}
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_cistatic const py_hashentry_t py_hashes[] = {
1137db96d56Sopenharmony_ci    /* md5 */
1147db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_md5, "MD5", SN_md5, NID_md5),
1157db96d56Sopenharmony_ci    /* sha1 */
1167db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha1, "SHA1", SN_sha1, NID_sha1),
1177db96d56Sopenharmony_ci    /* sha2 family */
1187db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha224, "SHA224", SN_sha224, NID_sha224),
1197db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha256, "SHA256", SN_sha256, NID_sha256),
1207db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384),
1217db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512),
1227db96d56Sopenharmony_ci    /* truncated sha2 */
1237db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224),
1247db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256),
1257db96d56Sopenharmony_ci    /* sha3 */
1267db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224),
1277db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256),
1287db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384),
1297db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512),
1307db96d56Sopenharmony_ci    /* sha3 shake */
1317db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128),
1327db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256),
1337db96d56Sopenharmony_ci    /* blake2 digest */
1347db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256),
1357db96d56Sopenharmony_ci    PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512),
1367db96d56Sopenharmony_ci    PY_HASH_ENTRY(NULL, NULL, NULL, 0),
1377db96d56Sopenharmony_ci};
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_cistatic Py_uhash_t
1407db96d56Sopenharmony_cipy_hashentry_t_hash_name(const void *key) {
1417db96d56Sopenharmony_ci    return _Py_HashBytes(key, strlen((const char *)key));
1427db96d56Sopenharmony_ci}
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_cistatic int
1457db96d56Sopenharmony_cipy_hashentry_t_compare_name(const void *key1, const void *key2) {
1467db96d56Sopenharmony_ci    return strcmp((const char *)key1, (const char *)key2) == 0;
1477db96d56Sopenharmony_ci}
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_cistatic void
1507db96d56Sopenharmony_cipy_hashentry_t_destroy_value(void *entry) {
1517db96d56Sopenharmony_ci    py_hashentry_t *h = (py_hashentry_t *)entry;
1527db96d56Sopenharmony_ci    if (--(h->refcnt) == 0) {
1537db96d56Sopenharmony_ci        if (h->evp != NULL) {
1547db96d56Sopenharmony_ci            PY_EVP_MD_free(h->evp);
1557db96d56Sopenharmony_ci            h->evp = NULL;
1567db96d56Sopenharmony_ci        }
1577db96d56Sopenharmony_ci        if (h->evp_nosecurity != NULL) {
1587db96d56Sopenharmony_ci            PY_EVP_MD_free(h->evp_nosecurity);
1597db96d56Sopenharmony_ci            h->evp_nosecurity = NULL;
1607db96d56Sopenharmony_ci        }
1617db96d56Sopenharmony_ci        PyMem_Free(entry);
1627db96d56Sopenharmony_ci    }
1637db96d56Sopenharmony_ci}
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_cistatic _Py_hashtable_t *
1667db96d56Sopenharmony_cipy_hashentry_table_new(void) {
1677db96d56Sopenharmony_ci    _Py_hashtable_t *ht = _Py_hashtable_new_full(
1687db96d56Sopenharmony_ci        py_hashentry_t_hash_name,
1697db96d56Sopenharmony_ci        py_hashentry_t_compare_name,
1707db96d56Sopenharmony_ci        NULL,
1717db96d56Sopenharmony_ci        py_hashentry_t_destroy_value,
1727db96d56Sopenharmony_ci        NULL
1737db96d56Sopenharmony_ci    );
1747db96d56Sopenharmony_ci    if (ht == NULL) {
1757db96d56Sopenharmony_ci        return NULL;
1767db96d56Sopenharmony_ci    }
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci    for (const py_hashentry_t *h = py_hashes; h->py_name != NULL; h++) {
1797db96d56Sopenharmony_ci        py_hashentry_t *entry = (py_hashentry_t *)PyMem_Malloc(sizeof(py_hashentry_t));
1807db96d56Sopenharmony_ci        if (entry == NULL) {
1817db96d56Sopenharmony_ci            goto error;
1827db96d56Sopenharmony_ci        }
1837db96d56Sopenharmony_ci        memcpy(entry, h, sizeof(py_hashentry_t));
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci        if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) {
1867db96d56Sopenharmony_ci            PyMem_Free(entry);
1877db96d56Sopenharmony_ci            goto error;
1887db96d56Sopenharmony_ci        }
1897db96d56Sopenharmony_ci        entry->refcnt = 1;
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci        if (h->py_alias != NULL) {
1927db96d56Sopenharmony_ci            if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) {
1937db96d56Sopenharmony_ci                PyMem_Free(entry);
1947db96d56Sopenharmony_ci                goto error;
1957db96d56Sopenharmony_ci            }
1967db96d56Sopenharmony_ci            entry->refcnt++;
1977db96d56Sopenharmony_ci        }
1987db96d56Sopenharmony_ci    }
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci    return ht;
2017db96d56Sopenharmony_ci  error:
2027db96d56Sopenharmony_ci    _Py_hashtable_destroy(ht);
2037db96d56Sopenharmony_ci    return NULL;
2047db96d56Sopenharmony_ci}
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci/* Module state */
2077db96d56Sopenharmony_cistatic PyModuleDef _hashlibmodule;
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_citypedef struct {
2107db96d56Sopenharmony_ci    PyTypeObject *EVPtype;
2117db96d56Sopenharmony_ci    PyTypeObject *HMACtype;
2127db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
2137db96d56Sopenharmony_ci    PyTypeObject *EVPXOFtype;
2147db96d56Sopenharmony_ci#endif
2157db96d56Sopenharmony_ci    PyObject *constructs;
2167db96d56Sopenharmony_ci    PyObject *unsupported_digestmod_error;
2177db96d56Sopenharmony_ci    _Py_hashtable_t *hashtable;
2187db96d56Sopenharmony_ci} _hashlibstate;
2197db96d56Sopenharmony_ci
2207db96d56Sopenharmony_cistatic inline _hashlibstate*
2217db96d56Sopenharmony_ciget_hashlib_state(PyObject *module)
2227db96d56Sopenharmony_ci{
2237db96d56Sopenharmony_ci    void *state = PyModule_GetState(module);
2247db96d56Sopenharmony_ci    assert(state != NULL);
2257db96d56Sopenharmony_ci    return (_hashlibstate *)state;
2267db96d56Sopenharmony_ci}
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_citypedef struct {
2297db96d56Sopenharmony_ci    PyObject_HEAD
2307db96d56Sopenharmony_ci    EVP_MD_CTX          *ctx;   /* OpenSSL message digest context */
2317db96d56Sopenharmony_ci    PyThread_type_lock   lock;  /* OpenSSL context lock */
2327db96d56Sopenharmony_ci} EVPobject;
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_citypedef struct {
2357db96d56Sopenharmony_ci    PyObject_HEAD
2367db96d56Sopenharmony_ci    HMAC_CTX *ctx;            /* OpenSSL hmac context */
2377db96d56Sopenharmony_ci    PyThread_type_lock lock;  /* HMAC context lock */
2387db96d56Sopenharmony_ci} HMACobject;
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci#include "clinic/_hashopenssl.c.h"
2417db96d56Sopenharmony_ci/*[clinic input]
2427db96d56Sopenharmony_cimodule _hashlib
2437db96d56Sopenharmony_ciclass _hashlib.HASH "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPtype"
2447db96d56Sopenharmony_ciclass _hashlib.HASHXOF "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))->EVPXOFtype"
2457db96d56Sopenharmony_ciclass _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module))->HMACtype"
2467db96d56Sopenharmony_ci[clinic start generated code]*/
2477db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7df1bcf6f75cb8ef]*/
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci/* LCOV_EXCL_START */
2517db96d56Sopenharmony_cistatic PyObject *
2527db96d56Sopenharmony_ci_setException(PyObject *exc, const char* altmsg, ...)
2537db96d56Sopenharmony_ci{
2547db96d56Sopenharmony_ci    unsigned long errcode = ERR_peek_last_error();
2557db96d56Sopenharmony_ci    const char *lib, *func, *reason;
2567db96d56Sopenharmony_ci    va_list vargs;
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES
2597db96d56Sopenharmony_ci    va_start(vargs, altmsg);
2607db96d56Sopenharmony_ci#else
2617db96d56Sopenharmony_ci    va_start(vargs);
2627db96d56Sopenharmony_ci#endif
2637db96d56Sopenharmony_ci    if (!errcode) {
2647db96d56Sopenharmony_ci        if (altmsg == NULL) {
2657db96d56Sopenharmony_ci            PyErr_SetString(exc, "no reason supplied");
2667db96d56Sopenharmony_ci        } else {
2677db96d56Sopenharmony_ci            PyErr_FormatV(exc, altmsg, vargs);
2687db96d56Sopenharmony_ci        }
2697db96d56Sopenharmony_ci        va_end(vargs);
2707db96d56Sopenharmony_ci        return NULL;
2717db96d56Sopenharmony_ci    }
2727db96d56Sopenharmony_ci    va_end(vargs);
2737db96d56Sopenharmony_ci    ERR_clear_error();
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ci    lib = ERR_lib_error_string(errcode);
2767db96d56Sopenharmony_ci    func = ERR_func_error_string(errcode);
2777db96d56Sopenharmony_ci    reason = ERR_reason_error_string(errcode);
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci    if (lib && func) {
2807db96d56Sopenharmony_ci        PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
2817db96d56Sopenharmony_ci    }
2827db96d56Sopenharmony_ci    else if (lib) {
2837db96d56Sopenharmony_ci        PyErr_Format(exc, "[%s] %s", lib, reason);
2847db96d56Sopenharmony_ci    }
2857db96d56Sopenharmony_ci    else {
2867db96d56Sopenharmony_ci        PyErr_SetString(exc, reason);
2877db96d56Sopenharmony_ci    }
2887db96d56Sopenharmony_ci    return NULL;
2897db96d56Sopenharmony_ci}
2907db96d56Sopenharmony_ci/* LCOV_EXCL_STOP */
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_cistatic PyObject*
2937db96d56Sopenharmony_cipy_digest_name(const EVP_MD *md)
2947db96d56Sopenharmony_ci{
2957db96d56Sopenharmony_ci    int nid = EVP_MD_nid(md);
2967db96d56Sopenharmony_ci    const char *name = NULL;
2977db96d56Sopenharmony_ci    const py_hashentry_t *h;
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci    for (h = py_hashes; h->py_name != NULL; h++) {
3007db96d56Sopenharmony_ci        if (h->ossl_nid == nid) {
3017db96d56Sopenharmony_ci            name = h->py_name;
3027db96d56Sopenharmony_ci            break;
3037db96d56Sopenharmony_ci        }
3047db96d56Sopenharmony_ci    }
3057db96d56Sopenharmony_ci    if (name == NULL) {
3067db96d56Sopenharmony_ci        /* Ignore aliased names and only use long, lowercase name. The aliases
3077db96d56Sopenharmony_ci         * pollute the list and OpenSSL appears to have its own definition of
3087db96d56Sopenharmony_ci         * alias as the resulting list still contains duplicate and alternate
3097db96d56Sopenharmony_ci         * names for several algorithms.
3107db96d56Sopenharmony_ci         */
3117db96d56Sopenharmony_ci        name = OBJ_nid2ln(nid);
3127db96d56Sopenharmony_ci        if (name == NULL)
3137db96d56Sopenharmony_ci            name = OBJ_nid2sn(nid);
3147db96d56Sopenharmony_ci    }
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci    return PyUnicode_FromString(name);
3177db96d56Sopenharmony_ci}
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci/* Get EVP_MD by HID and purpose */
3207db96d56Sopenharmony_cistatic PY_EVP_MD*
3217db96d56Sopenharmony_cipy_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht)
3227db96d56Sopenharmony_ci{
3237db96d56Sopenharmony_ci    PY_EVP_MD *digest = NULL;
3247db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
3257db96d56Sopenharmony_ci    py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get(
3267db96d56Sopenharmony_ci        state->hashtable, (const void*)name
3277db96d56Sopenharmony_ci    );
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci    if (entry != NULL) {
3307db96d56Sopenharmony_ci        switch (py_ht) {
3317db96d56Sopenharmony_ci        case Py_ht_evp:
3327db96d56Sopenharmony_ci        case Py_ht_mac:
3337db96d56Sopenharmony_ci        case Py_ht_pbkdf2:
3347db96d56Sopenharmony_ci            if (entry->evp == NULL) {
3357db96d56Sopenharmony_ci                entry->evp = PY_EVP_MD_fetch(entry->ossl_name, NULL);
3367db96d56Sopenharmony_ci            }
3377db96d56Sopenharmony_ci            digest = entry->evp;
3387db96d56Sopenharmony_ci            break;
3397db96d56Sopenharmony_ci        case Py_ht_evp_nosecurity:
3407db96d56Sopenharmony_ci            if (entry->evp_nosecurity == NULL) {
3417db96d56Sopenharmony_ci                entry->evp_nosecurity = PY_EVP_MD_fetch(entry->ossl_name, "-fips");
3427db96d56Sopenharmony_ci            }
3437db96d56Sopenharmony_ci            digest = entry->evp_nosecurity;
3447db96d56Sopenharmony_ci            break;
3457db96d56Sopenharmony_ci        }
3467db96d56Sopenharmony_ci        if (digest != NULL) {
3477db96d56Sopenharmony_ci            PY_EVP_MD_up_ref(digest);
3487db96d56Sopenharmony_ci        }
3497db96d56Sopenharmony_ci    } else {
3507db96d56Sopenharmony_ci        // Fall back for looking up an unindexed OpenSSL specific name.
3517db96d56Sopenharmony_ci        switch (py_ht) {
3527db96d56Sopenharmony_ci        case Py_ht_evp:
3537db96d56Sopenharmony_ci        case Py_ht_mac:
3547db96d56Sopenharmony_ci        case Py_ht_pbkdf2:
3557db96d56Sopenharmony_ci            digest = PY_EVP_MD_fetch(name, NULL);
3567db96d56Sopenharmony_ci            break;
3577db96d56Sopenharmony_ci        case Py_ht_evp_nosecurity:
3587db96d56Sopenharmony_ci            digest = PY_EVP_MD_fetch(name, "-fips");
3597db96d56Sopenharmony_ci            break;
3607db96d56Sopenharmony_ci        }
3617db96d56Sopenharmony_ci    }
3627db96d56Sopenharmony_ci    if (digest == NULL) {
3637db96d56Sopenharmony_ci        _setException(state->unsupported_digestmod_error, "unsupported hash type %s", name);
3647db96d56Sopenharmony_ci        return NULL;
3657db96d56Sopenharmony_ci    }
3667db96d56Sopenharmony_ci    return digest;
3677db96d56Sopenharmony_ci}
3687db96d56Sopenharmony_ci
3697db96d56Sopenharmony_ci/* Get digest EVP from object
3707db96d56Sopenharmony_ci *
3717db96d56Sopenharmony_ci * * string
3727db96d56Sopenharmony_ci * * _hashopenssl builtin function
3737db96d56Sopenharmony_ci *
3747db96d56Sopenharmony_ci * on error returns NULL with exception set.
3757db96d56Sopenharmony_ci */
3767db96d56Sopenharmony_cistatic PY_EVP_MD*
3777db96d56Sopenharmony_cipy_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type py_ht) {
3787db96d56Sopenharmony_ci    PY_EVP_MD* evp;
3797db96d56Sopenharmony_ci    PyObject *name_obj = NULL;
3807db96d56Sopenharmony_ci    const char *name;
3817db96d56Sopenharmony_ci
3827db96d56Sopenharmony_ci    if (PyUnicode_Check(digestmod)) {
3837db96d56Sopenharmony_ci        name_obj = digestmod;
3847db96d56Sopenharmony_ci    } else {
3857db96d56Sopenharmony_ci        _hashlibstate *state = get_hashlib_state(module);
3867db96d56Sopenharmony_ci        // borrowed ref
3877db96d56Sopenharmony_ci        name_obj = PyDict_GetItem(state->constructs, digestmod);
3887db96d56Sopenharmony_ci    }
3897db96d56Sopenharmony_ci    if (name_obj == NULL) {
3907db96d56Sopenharmony_ci        _hashlibstate *state = get_hashlib_state(module);
3917db96d56Sopenharmony_ci        PyErr_Clear();
3927db96d56Sopenharmony_ci        PyErr_Format(
3937db96d56Sopenharmony_ci            state->unsupported_digestmod_error,
3947db96d56Sopenharmony_ci            "Unsupported digestmod %R", digestmod);
3957db96d56Sopenharmony_ci        return NULL;
3967db96d56Sopenharmony_ci    }
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci    name = PyUnicode_AsUTF8(name_obj);
3997db96d56Sopenharmony_ci    if (name == NULL) {
4007db96d56Sopenharmony_ci        return NULL;
4017db96d56Sopenharmony_ci    }
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci    evp = py_digest_by_name(module, name, py_ht);
4047db96d56Sopenharmony_ci    if (evp == NULL) {
4057db96d56Sopenharmony_ci        return NULL;
4067db96d56Sopenharmony_ci    }
4077db96d56Sopenharmony_ci
4087db96d56Sopenharmony_ci    return evp;
4097db96d56Sopenharmony_ci}
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_cistatic EVPobject *
4127db96d56Sopenharmony_cinewEVPobject(PyTypeObject *type)
4137db96d56Sopenharmony_ci{
4147db96d56Sopenharmony_ci    EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, type);
4157db96d56Sopenharmony_ci    if (retval == NULL) {
4167db96d56Sopenharmony_ci        return NULL;
4177db96d56Sopenharmony_ci    }
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci    retval->lock = NULL;
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci    retval->ctx = EVP_MD_CTX_new();
4227db96d56Sopenharmony_ci    if (retval->ctx == NULL) {
4237db96d56Sopenharmony_ci        Py_DECREF(retval);
4247db96d56Sopenharmony_ci        PyErr_NoMemory();
4257db96d56Sopenharmony_ci        return NULL;
4267db96d56Sopenharmony_ci    }
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci    return retval;
4297db96d56Sopenharmony_ci}
4307db96d56Sopenharmony_ci
4317db96d56Sopenharmony_cistatic int
4327db96d56Sopenharmony_ciEVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
4337db96d56Sopenharmony_ci{
4347db96d56Sopenharmony_ci    unsigned int process;
4357db96d56Sopenharmony_ci    const unsigned char *cp = (const unsigned char *)vp;
4367db96d56Sopenharmony_ci    while (0 < len) {
4377db96d56Sopenharmony_ci        if (len > (Py_ssize_t)MUNCH_SIZE)
4387db96d56Sopenharmony_ci            process = MUNCH_SIZE;
4397db96d56Sopenharmony_ci        else
4407db96d56Sopenharmony_ci            process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
4417db96d56Sopenharmony_ci        if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) {
4427db96d56Sopenharmony_ci            _setException(PyExc_ValueError, NULL);
4437db96d56Sopenharmony_ci            return -1;
4447db96d56Sopenharmony_ci        }
4457db96d56Sopenharmony_ci        len -= process;
4467db96d56Sopenharmony_ci        cp += process;
4477db96d56Sopenharmony_ci    }
4487db96d56Sopenharmony_ci    return 0;
4497db96d56Sopenharmony_ci}
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci/* Internal methods for a hash object */
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_cistatic void
4547db96d56Sopenharmony_ciEVP_dealloc(EVPobject *self)
4557db96d56Sopenharmony_ci{
4567db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
4577db96d56Sopenharmony_ci    if (self->lock != NULL)
4587db96d56Sopenharmony_ci        PyThread_free_lock(self->lock);
4597db96d56Sopenharmony_ci    EVP_MD_CTX_free(self->ctx);
4607db96d56Sopenharmony_ci    PyObject_Free(self);
4617db96d56Sopenharmony_ci    Py_DECREF(tp);
4627db96d56Sopenharmony_ci}
4637db96d56Sopenharmony_ci
4647db96d56Sopenharmony_cistatic int
4657db96d56Sopenharmony_cilocked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
4667db96d56Sopenharmony_ci{
4677db96d56Sopenharmony_ci    int result;
4687db96d56Sopenharmony_ci    ENTER_HASHLIB(self);
4697db96d56Sopenharmony_ci    result = EVP_MD_CTX_copy(new_ctx_p, self->ctx);
4707db96d56Sopenharmony_ci    LEAVE_HASHLIB(self);
4717db96d56Sopenharmony_ci    return result;
4727db96d56Sopenharmony_ci}
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci/* External methods for a hash object */
4757db96d56Sopenharmony_ci
4767db96d56Sopenharmony_ci/*[clinic input]
4777db96d56Sopenharmony_ci_hashlib.HASH.copy as EVP_copy
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_ciReturn a copy of the hash object.
4807db96d56Sopenharmony_ci[clinic start generated code]*/
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_cistatic PyObject *
4837db96d56Sopenharmony_ciEVP_copy_impl(EVPobject *self)
4847db96d56Sopenharmony_ci/*[clinic end generated code: output=b370c21cdb8ca0b4 input=31455b6a3e638069]*/
4857db96d56Sopenharmony_ci{
4867db96d56Sopenharmony_ci    EVPobject *newobj;
4877db96d56Sopenharmony_ci
4887db96d56Sopenharmony_ci    if ((newobj = newEVPobject(Py_TYPE(self))) == NULL)
4897db96d56Sopenharmony_ci        return NULL;
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci    if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
4927db96d56Sopenharmony_ci        Py_DECREF(newobj);
4937db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
4947db96d56Sopenharmony_ci    }
4957db96d56Sopenharmony_ci    return (PyObject *)newobj;
4967db96d56Sopenharmony_ci}
4977db96d56Sopenharmony_ci
4987db96d56Sopenharmony_ci/*[clinic input]
4997db96d56Sopenharmony_ci_hashlib.HASH.digest as EVP_digest
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ciReturn the digest value as a bytes object.
5027db96d56Sopenharmony_ci[clinic start generated code]*/
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_cistatic PyObject *
5057db96d56Sopenharmony_ciEVP_digest_impl(EVPobject *self)
5067db96d56Sopenharmony_ci/*[clinic end generated code: output=0f6a3a0da46dc12d input=03561809a419bf00]*/
5077db96d56Sopenharmony_ci{
5087db96d56Sopenharmony_ci    unsigned char digest[EVP_MAX_MD_SIZE];
5097db96d56Sopenharmony_ci    EVP_MD_CTX *temp_ctx;
5107db96d56Sopenharmony_ci    PyObject *retval;
5117db96d56Sopenharmony_ci    unsigned int digest_size;
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ci    temp_ctx = EVP_MD_CTX_new();
5147db96d56Sopenharmony_ci    if (temp_ctx == NULL) {
5157db96d56Sopenharmony_ci        PyErr_NoMemory();
5167db96d56Sopenharmony_ci        return NULL;
5177db96d56Sopenharmony_ci    }
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
5207db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
5217db96d56Sopenharmony_ci    }
5227db96d56Sopenharmony_ci    digest_size = EVP_MD_CTX_size(temp_ctx);
5237db96d56Sopenharmony_ci    if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
5247db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
5257db96d56Sopenharmony_ci        return NULL;
5267db96d56Sopenharmony_ci    }
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ci    retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
5297db96d56Sopenharmony_ci    EVP_MD_CTX_free(temp_ctx);
5307db96d56Sopenharmony_ci    return retval;
5317db96d56Sopenharmony_ci}
5327db96d56Sopenharmony_ci
5337db96d56Sopenharmony_ci/*[clinic input]
5347db96d56Sopenharmony_ci_hashlib.HASH.hexdigest as EVP_hexdigest
5357db96d56Sopenharmony_ci
5367db96d56Sopenharmony_ciReturn the digest value as a string of hexadecimal digits.
5377db96d56Sopenharmony_ci[clinic start generated code]*/
5387db96d56Sopenharmony_ci
5397db96d56Sopenharmony_cistatic PyObject *
5407db96d56Sopenharmony_ciEVP_hexdigest_impl(EVPobject *self)
5417db96d56Sopenharmony_ci/*[clinic end generated code: output=18e6decbaf197296 input=aff9cf0e4c741a9a]*/
5427db96d56Sopenharmony_ci{
5437db96d56Sopenharmony_ci    unsigned char digest[EVP_MAX_MD_SIZE];
5447db96d56Sopenharmony_ci    EVP_MD_CTX *temp_ctx;
5457db96d56Sopenharmony_ci    unsigned int digest_size;
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci    temp_ctx = EVP_MD_CTX_new();
5487db96d56Sopenharmony_ci    if (temp_ctx == NULL) {
5497db96d56Sopenharmony_ci        PyErr_NoMemory();
5507db96d56Sopenharmony_ci        return NULL;
5517db96d56Sopenharmony_ci    }
5527db96d56Sopenharmony_ci
5537db96d56Sopenharmony_ci    /* Get the raw (binary) digest value */
5547db96d56Sopenharmony_ci    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
5557db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
5567db96d56Sopenharmony_ci    }
5577db96d56Sopenharmony_ci    digest_size = EVP_MD_CTX_size(temp_ctx);
5587db96d56Sopenharmony_ci    if (!EVP_DigestFinal(temp_ctx, digest, NULL)) {
5597db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
5607db96d56Sopenharmony_ci        return NULL;
5617db96d56Sopenharmony_ci    }
5627db96d56Sopenharmony_ci
5637db96d56Sopenharmony_ci    EVP_MD_CTX_free(temp_ctx);
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci    return _Py_strhex((const char *)digest, (Py_ssize_t)digest_size);
5667db96d56Sopenharmony_ci}
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci/*[clinic input]
5697db96d56Sopenharmony_ci_hashlib.HASH.update as EVP_update
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci    obj: object
5727db96d56Sopenharmony_ci    /
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ciUpdate this hash object's state with the provided string.
5757db96d56Sopenharmony_ci[clinic start generated code]*/
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_cistatic PyObject *
5787db96d56Sopenharmony_ciEVP_update(EVPobject *self, PyObject *obj)
5797db96d56Sopenharmony_ci/*[clinic end generated code: output=ec1d55ed2432e966 input=9b30ec848f015501]*/
5807db96d56Sopenharmony_ci{
5817db96d56Sopenharmony_ci    int result;
5827db96d56Sopenharmony_ci    Py_buffer view;
5837db96d56Sopenharmony_ci
5847db96d56Sopenharmony_ci    GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci    if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
5877db96d56Sopenharmony_ci        self->lock = PyThread_allocate_lock();
5887db96d56Sopenharmony_ci        /* fail? lock = NULL and we fail over to non-threaded code. */
5897db96d56Sopenharmony_ci    }
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci    if (self->lock != NULL) {
5927db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
5937db96d56Sopenharmony_ci        PyThread_acquire_lock(self->lock, 1);
5947db96d56Sopenharmony_ci        result = EVP_hash(self, view.buf, view.len);
5957db96d56Sopenharmony_ci        PyThread_release_lock(self->lock);
5967db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
5977db96d56Sopenharmony_ci    } else {
5987db96d56Sopenharmony_ci        result = EVP_hash(self, view.buf, view.len);
5997db96d56Sopenharmony_ci    }
6007db96d56Sopenharmony_ci
6017db96d56Sopenharmony_ci    PyBuffer_Release(&view);
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci    if (result == -1)
6047db96d56Sopenharmony_ci        return NULL;
6057db96d56Sopenharmony_ci    Py_RETURN_NONE;
6067db96d56Sopenharmony_ci}
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_cistatic PyMethodDef EVP_methods[] = {
6097db96d56Sopenharmony_ci    EVP_UPDATE_METHODDEF
6107db96d56Sopenharmony_ci    EVP_DIGEST_METHODDEF
6117db96d56Sopenharmony_ci    EVP_HEXDIGEST_METHODDEF
6127db96d56Sopenharmony_ci    EVP_COPY_METHODDEF
6137db96d56Sopenharmony_ci    {NULL, NULL}  /* sentinel */
6147db96d56Sopenharmony_ci};
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_cistatic PyObject *
6177db96d56Sopenharmony_ciEVP_get_block_size(EVPobject *self, void *closure)
6187db96d56Sopenharmony_ci{
6197db96d56Sopenharmony_ci    long block_size;
6207db96d56Sopenharmony_ci    block_size = EVP_MD_CTX_block_size(self->ctx);
6217db96d56Sopenharmony_ci    return PyLong_FromLong(block_size);
6227db96d56Sopenharmony_ci}
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_cistatic PyObject *
6257db96d56Sopenharmony_ciEVP_get_digest_size(EVPobject *self, void *closure)
6267db96d56Sopenharmony_ci{
6277db96d56Sopenharmony_ci    long size;
6287db96d56Sopenharmony_ci    size = EVP_MD_CTX_size(self->ctx);
6297db96d56Sopenharmony_ci    return PyLong_FromLong(size);
6307db96d56Sopenharmony_ci}
6317db96d56Sopenharmony_ci
6327db96d56Sopenharmony_cistatic PyObject *
6337db96d56Sopenharmony_ciEVP_get_name(EVPobject *self, void *closure)
6347db96d56Sopenharmony_ci{
6357db96d56Sopenharmony_ci    return py_digest_name(EVP_MD_CTX_md(self->ctx));
6367db96d56Sopenharmony_ci}
6377db96d56Sopenharmony_ci
6387db96d56Sopenharmony_cistatic PyGetSetDef EVP_getseters[] = {
6397db96d56Sopenharmony_ci    {"digest_size",
6407db96d56Sopenharmony_ci     (getter)EVP_get_digest_size, NULL,
6417db96d56Sopenharmony_ci     NULL,
6427db96d56Sopenharmony_ci     NULL},
6437db96d56Sopenharmony_ci    {"block_size",
6447db96d56Sopenharmony_ci     (getter)EVP_get_block_size, NULL,
6457db96d56Sopenharmony_ci     NULL,
6467db96d56Sopenharmony_ci     NULL},
6477db96d56Sopenharmony_ci    {"name",
6487db96d56Sopenharmony_ci     (getter)EVP_get_name, NULL,
6497db96d56Sopenharmony_ci     NULL,
6507db96d56Sopenharmony_ci     PyDoc_STR("algorithm name.")},
6517db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
6527db96d56Sopenharmony_ci};
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci
6557db96d56Sopenharmony_cistatic PyObject *
6567db96d56Sopenharmony_ciEVP_repr(EVPobject *self)
6577db96d56Sopenharmony_ci{
6587db96d56Sopenharmony_ci    PyObject *name_obj, *repr;
6597db96d56Sopenharmony_ci    name_obj = py_digest_name(EVP_MD_CTX_md(self->ctx));
6607db96d56Sopenharmony_ci    if (!name_obj) {
6617db96d56Sopenharmony_ci        return NULL;
6627db96d56Sopenharmony_ci    }
6637db96d56Sopenharmony_ci    repr = PyUnicode_FromFormat("<%U %s object @ %p>",
6647db96d56Sopenharmony_ci                                name_obj, Py_TYPE(self)->tp_name, self);
6657db96d56Sopenharmony_ci    Py_DECREF(name_obj);
6667db96d56Sopenharmony_ci    return repr;
6677db96d56Sopenharmony_ci}
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ciPyDoc_STRVAR(hashtype_doc,
6707db96d56Sopenharmony_ci"HASH(name, string=b\'\')\n"
6717db96d56Sopenharmony_ci"--\n"
6727db96d56Sopenharmony_ci"\n"
6737db96d56Sopenharmony_ci"A hash is an object used to calculate a checksum of a string of information.\n"
6747db96d56Sopenharmony_ci"\n"
6757db96d56Sopenharmony_ci"Methods:\n"
6767db96d56Sopenharmony_ci"\n"
6777db96d56Sopenharmony_ci"update() -- updates the current digest with an additional string\n"
6787db96d56Sopenharmony_ci"digest() -- return the current digest value\n"
6797db96d56Sopenharmony_ci"hexdigest() -- return the current digest as a string of hexadecimal digits\n"
6807db96d56Sopenharmony_ci"copy() -- return a copy of the current hash object\n"
6817db96d56Sopenharmony_ci"\n"
6827db96d56Sopenharmony_ci"Attributes:\n"
6837db96d56Sopenharmony_ci"\n"
6847db96d56Sopenharmony_ci"name -- the hash algorithm being used by this object\n"
6857db96d56Sopenharmony_ci"digest_size -- number of bytes in this hashes output");
6867db96d56Sopenharmony_ci
6877db96d56Sopenharmony_cistatic PyType_Slot EVPtype_slots[] = {
6887db96d56Sopenharmony_ci    {Py_tp_dealloc, EVP_dealloc},
6897db96d56Sopenharmony_ci    {Py_tp_repr, EVP_repr},
6907db96d56Sopenharmony_ci    {Py_tp_doc, (char *)hashtype_doc},
6917db96d56Sopenharmony_ci    {Py_tp_methods, EVP_methods},
6927db96d56Sopenharmony_ci    {Py_tp_getset, EVP_getseters},
6937db96d56Sopenharmony_ci    {0, 0},
6947db96d56Sopenharmony_ci};
6957db96d56Sopenharmony_ci
6967db96d56Sopenharmony_cistatic PyType_Spec EVPtype_spec = {
6977db96d56Sopenharmony_ci    "_hashlib.HASH",    /*tp_name*/
6987db96d56Sopenharmony_ci    sizeof(EVPobject),  /*tp_basicsize*/
6997db96d56Sopenharmony_ci    0,                  /*tp_itemsize*/
7007db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
7017db96d56Sopenharmony_ci    EVPtype_slots
7027db96d56Sopenharmony_ci};
7037db96d56Sopenharmony_ci
7047db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_ci/*[clinic input]
7077db96d56Sopenharmony_ci_hashlib.HASHXOF.digest as EVPXOF_digest
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_ci  length: Py_ssize_t
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ciReturn the digest value as a bytes object.
7127db96d56Sopenharmony_ci[clinic start generated code]*/
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_cistatic PyObject *
7157db96d56Sopenharmony_ciEVPXOF_digest_impl(EVPobject *self, Py_ssize_t length)
7167db96d56Sopenharmony_ci/*[clinic end generated code: output=ef9320c23280efad input=816a6537cea3d1db]*/
7177db96d56Sopenharmony_ci{
7187db96d56Sopenharmony_ci    EVP_MD_CTX *temp_ctx;
7197db96d56Sopenharmony_ci    PyObject *retval = PyBytes_FromStringAndSize(NULL, length);
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ci    if (retval == NULL) {
7227db96d56Sopenharmony_ci        return NULL;
7237db96d56Sopenharmony_ci    }
7247db96d56Sopenharmony_ci
7257db96d56Sopenharmony_ci    temp_ctx = EVP_MD_CTX_new();
7267db96d56Sopenharmony_ci    if (temp_ctx == NULL) {
7277db96d56Sopenharmony_ci        Py_DECREF(retval);
7287db96d56Sopenharmony_ci        PyErr_NoMemory();
7297db96d56Sopenharmony_ci        return NULL;
7307db96d56Sopenharmony_ci    }
7317db96d56Sopenharmony_ci
7327db96d56Sopenharmony_ci    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
7337db96d56Sopenharmony_ci        Py_DECREF(retval);
7347db96d56Sopenharmony_ci        EVP_MD_CTX_free(temp_ctx);
7357db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
7367db96d56Sopenharmony_ci    }
7377db96d56Sopenharmony_ci    if (!EVP_DigestFinalXOF(temp_ctx,
7387db96d56Sopenharmony_ci                            (unsigned char*)PyBytes_AS_STRING(retval),
7397db96d56Sopenharmony_ci                            length)) {
7407db96d56Sopenharmony_ci        Py_DECREF(retval);
7417db96d56Sopenharmony_ci        EVP_MD_CTX_free(temp_ctx);
7427db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
7437db96d56Sopenharmony_ci        return NULL;
7447db96d56Sopenharmony_ci    }
7457db96d56Sopenharmony_ci
7467db96d56Sopenharmony_ci    EVP_MD_CTX_free(temp_ctx);
7477db96d56Sopenharmony_ci    return retval;
7487db96d56Sopenharmony_ci}
7497db96d56Sopenharmony_ci
7507db96d56Sopenharmony_ci/*[clinic input]
7517db96d56Sopenharmony_ci_hashlib.HASHXOF.hexdigest as EVPXOF_hexdigest
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci    length: Py_ssize_t
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ciReturn the digest value as a string of hexadecimal digits.
7567db96d56Sopenharmony_ci[clinic start generated code]*/
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_cistatic PyObject *
7597db96d56Sopenharmony_ciEVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length)
7607db96d56Sopenharmony_ci/*[clinic end generated code: output=eb3e6ee7788bf5b2 input=5f9d6a8f269e34df]*/
7617db96d56Sopenharmony_ci{
7627db96d56Sopenharmony_ci    unsigned char *digest;
7637db96d56Sopenharmony_ci    EVP_MD_CTX *temp_ctx;
7647db96d56Sopenharmony_ci    PyObject *retval;
7657db96d56Sopenharmony_ci
7667db96d56Sopenharmony_ci    digest = (unsigned char*)PyMem_Malloc(length);
7677db96d56Sopenharmony_ci    if (digest == NULL) {
7687db96d56Sopenharmony_ci        PyErr_NoMemory();
7697db96d56Sopenharmony_ci        return NULL;
7707db96d56Sopenharmony_ci    }
7717db96d56Sopenharmony_ci
7727db96d56Sopenharmony_ci    temp_ctx = EVP_MD_CTX_new();
7737db96d56Sopenharmony_ci    if (temp_ctx == NULL) {
7747db96d56Sopenharmony_ci        PyMem_Free(digest);
7757db96d56Sopenharmony_ci        PyErr_NoMemory();
7767db96d56Sopenharmony_ci        return NULL;
7777db96d56Sopenharmony_ci    }
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ci    /* Get the raw (binary) digest value */
7807db96d56Sopenharmony_ci    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
7817db96d56Sopenharmony_ci        PyMem_Free(digest);
7827db96d56Sopenharmony_ci        EVP_MD_CTX_free(temp_ctx);
7837db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
7847db96d56Sopenharmony_ci    }
7857db96d56Sopenharmony_ci    if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) {
7867db96d56Sopenharmony_ci        PyMem_Free(digest);
7877db96d56Sopenharmony_ci        EVP_MD_CTX_free(temp_ctx);
7887db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
7897db96d56Sopenharmony_ci        return NULL;
7907db96d56Sopenharmony_ci    }
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci    EVP_MD_CTX_free(temp_ctx);
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci    retval = _Py_strhex((const char *)digest, length);
7957db96d56Sopenharmony_ci    PyMem_Free(digest);
7967db96d56Sopenharmony_ci    return retval;
7977db96d56Sopenharmony_ci}
7987db96d56Sopenharmony_ci
7997db96d56Sopenharmony_cistatic PyMethodDef EVPXOF_methods[] = {
8007db96d56Sopenharmony_ci    EVPXOF_DIGEST_METHODDEF
8017db96d56Sopenharmony_ci    EVPXOF_HEXDIGEST_METHODDEF
8027db96d56Sopenharmony_ci    {NULL, NULL}  /* sentinel */
8037db96d56Sopenharmony_ci};
8047db96d56Sopenharmony_ci
8057db96d56Sopenharmony_ci
8067db96d56Sopenharmony_cistatic PyObject *
8077db96d56Sopenharmony_ciEVPXOF_get_digest_size(EVPobject *self, void *closure)
8087db96d56Sopenharmony_ci{
8097db96d56Sopenharmony_ci    return PyLong_FromLong(0);
8107db96d56Sopenharmony_ci}
8117db96d56Sopenharmony_ci
8127db96d56Sopenharmony_cistatic PyGetSetDef EVPXOF_getseters[] = {
8137db96d56Sopenharmony_ci    {"digest_size",
8147db96d56Sopenharmony_ci     (getter)EVPXOF_get_digest_size, NULL,
8157db96d56Sopenharmony_ci     NULL,
8167db96d56Sopenharmony_ci     NULL},
8177db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
8187db96d56Sopenharmony_ci};
8197db96d56Sopenharmony_ci
8207db96d56Sopenharmony_ciPyDoc_STRVAR(hashxoftype_doc,
8217db96d56Sopenharmony_ci"HASHXOF(name, string=b\'\')\n"
8227db96d56Sopenharmony_ci"--\n"
8237db96d56Sopenharmony_ci"\n"
8247db96d56Sopenharmony_ci"A hash is an object used to calculate a checksum of a string of information.\n"
8257db96d56Sopenharmony_ci"\n"
8267db96d56Sopenharmony_ci"Methods:\n"
8277db96d56Sopenharmony_ci"\n"
8287db96d56Sopenharmony_ci"update() -- updates the current digest with an additional string\n"
8297db96d56Sopenharmony_ci"digest(length) -- return the current digest value\n"
8307db96d56Sopenharmony_ci"hexdigest(length) -- return the current digest as a string of hexadecimal digits\n"
8317db96d56Sopenharmony_ci"copy() -- return a copy of the current hash object\n"
8327db96d56Sopenharmony_ci"\n"
8337db96d56Sopenharmony_ci"Attributes:\n"
8347db96d56Sopenharmony_ci"\n"
8357db96d56Sopenharmony_ci"name -- the hash algorithm being used by this object\n"
8367db96d56Sopenharmony_ci"digest_size -- number of bytes in this hashes output");
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_cistatic PyType_Slot EVPXOFtype_slots[] = {
8397db96d56Sopenharmony_ci    {Py_tp_doc, (char *)hashxoftype_doc},
8407db96d56Sopenharmony_ci    {Py_tp_methods, EVPXOF_methods},
8417db96d56Sopenharmony_ci    {Py_tp_getset, EVPXOF_getseters},
8427db96d56Sopenharmony_ci    {0, 0},
8437db96d56Sopenharmony_ci};
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_cistatic PyType_Spec EVPXOFtype_spec = {
8467db96d56Sopenharmony_ci    "_hashlib.HASHXOF",    /*tp_name*/
8477db96d56Sopenharmony_ci    sizeof(EVPobject),  /*tp_basicsize*/
8487db96d56Sopenharmony_ci    0,                  /*tp_itemsize*/
8497db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
8507db96d56Sopenharmony_ci    EVPXOFtype_slots
8517db96d56Sopenharmony_ci};
8527db96d56Sopenharmony_ci
8537db96d56Sopenharmony_ci
8547db96d56Sopenharmony_ci#endif
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_cistatic PyObject*
8577db96d56Sopenharmony_cipy_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj,
8587db96d56Sopenharmony_ci                int usedforsecurity)
8597db96d56Sopenharmony_ci{
8607db96d56Sopenharmony_ci    Py_buffer view = { 0 };
8617db96d56Sopenharmony_ci    PY_EVP_MD *digest = NULL;
8627db96d56Sopenharmony_ci    PyTypeObject *type;
8637db96d56Sopenharmony_ci    EVPobject *self = NULL;
8647db96d56Sopenharmony_ci
8657db96d56Sopenharmony_ci    if (data_obj != NULL) {
8667db96d56Sopenharmony_ci        GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
8677db96d56Sopenharmony_ci    }
8687db96d56Sopenharmony_ci
8697db96d56Sopenharmony_ci    digest = py_digest_by_name(
8707db96d56Sopenharmony_ci        module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity
8717db96d56Sopenharmony_ci    );
8727db96d56Sopenharmony_ci    if (digest == NULL) {
8737db96d56Sopenharmony_ci        goto exit;
8747db96d56Sopenharmony_ci    }
8757db96d56Sopenharmony_ci
8767db96d56Sopenharmony_ci    if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) {
8777db96d56Sopenharmony_ci        type = get_hashlib_state(module)->EVPXOFtype;
8787db96d56Sopenharmony_ci    } else {
8797db96d56Sopenharmony_ci        type = get_hashlib_state(module)->EVPtype;
8807db96d56Sopenharmony_ci    }
8817db96d56Sopenharmony_ci
8827db96d56Sopenharmony_ci    self = newEVPobject(type);
8837db96d56Sopenharmony_ci    if (self == NULL) {
8847db96d56Sopenharmony_ci        goto exit;
8857db96d56Sopenharmony_ci    }
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_ci#if defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) && OPENSSL_VERSION_NUMBER < 0x30000000L
8887db96d56Sopenharmony_ci    // In OpenSSL 1.1.1 the non FIPS allowed flag is context specific while
8897db96d56Sopenharmony_ci    // in 3.0.0 it is a different EVP_MD provider.
8907db96d56Sopenharmony_ci    if (!usedforsecurity) {
8917db96d56Sopenharmony_ci        EVP_MD_CTX_set_flags(self->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
8927db96d56Sopenharmony_ci    }
8937db96d56Sopenharmony_ci#endif
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci    int result = EVP_DigestInit_ex(self->ctx, digest, NULL);
8967db96d56Sopenharmony_ci    if (!result) {
8977db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
8987db96d56Sopenharmony_ci        Py_CLEAR(self);
8997db96d56Sopenharmony_ci        goto exit;
9007db96d56Sopenharmony_ci    }
9017db96d56Sopenharmony_ci
9027db96d56Sopenharmony_ci    if (view.buf && view.len) {
9037db96d56Sopenharmony_ci        if (view.len >= HASHLIB_GIL_MINSIZE) {
9047db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
9057db96d56Sopenharmony_ci            result = EVP_hash(self, view.buf, view.len);
9067db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
9077db96d56Sopenharmony_ci        } else {
9087db96d56Sopenharmony_ci            result = EVP_hash(self, view.buf, view.len);
9097db96d56Sopenharmony_ci        }
9107db96d56Sopenharmony_ci        if (result == -1) {
9117db96d56Sopenharmony_ci            Py_CLEAR(self);
9127db96d56Sopenharmony_ci            goto exit;
9137db96d56Sopenharmony_ci        }
9147db96d56Sopenharmony_ci    }
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci  exit:
9177db96d56Sopenharmony_ci    if (data_obj != NULL) {
9187db96d56Sopenharmony_ci        PyBuffer_Release(&view);
9197db96d56Sopenharmony_ci    }
9207db96d56Sopenharmony_ci    if (digest != NULL) {
9217db96d56Sopenharmony_ci        PY_EVP_MD_free(digest);
9227db96d56Sopenharmony_ci    }
9237db96d56Sopenharmony_ci
9247db96d56Sopenharmony_ci    return (PyObject *)self;
9257db96d56Sopenharmony_ci}
9267db96d56Sopenharmony_ci
9277db96d56Sopenharmony_ci
9287db96d56Sopenharmony_ci/* The module-level function: new() */
9297db96d56Sopenharmony_ci
9307db96d56Sopenharmony_ci/*[clinic input]
9317db96d56Sopenharmony_ci_hashlib.new as EVP_new
9327db96d56Sopenharmony_ci
9337db96d56Sopenharmony_ci    name as name_obj: object
9347db96d56Sopenharmony_ci    string as data_obj: object(c_default="NULL") = b''
9357db96d56Sopenharmony_ci    *
9367db96d56Sopenharmony_ci    usedforsecurity: bool = True
9377db96d56Sopenharmony_ci
9387db96d56Sopenharmony_ciReturn a new hash object using the named algorithm.
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_ciAn optional string argument may be provided and will be
9417db96d56Sopenharmony_ciautomatically hashed.
9427db96d56Sopenharmony_ci
9437db96d56Sopenharmony_ciThe MD5 and SHA1 algorithms are always supported.
9447db96d56Sopenharmony_ci[clinic start generated code]*/
9457db96d56Sopenharmony_ci
9467db96d56Sopenharmony_cistatic PyObject *
9477db96d56Sopenharmony_ciEVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj,
9487db96d56Sopenharmony_ci             int usedforsecurity)
9497db96d56Sopenharmony_ci/*[clinic end generated code: output=ddd5053f92dffe90 input=c24554d0337be1b0]*/
9507db96d56Sopenharmony_ci{
9517db96d56Sopenharmony_ci    char *name;
9527db96d56Sopenharmony_ci    if (!PyArg_Parse(name_obj, "s", &name)) {
9537db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "name must be a string");
9547db96d56Sopenharmony_ci        return NULL;
9557db96d56Sopenharmony_ci    }
9567db96d56Sopenharmony_ci    return py_evp_fromname(module, name, data_obj, usedforsecurity);
9577db96d56Sopenharmony_ci}
9587db96d56Sopenharmony_ci
9597db96d56Sopenharmony_ci
9607db96d56Sopenharmony_ci/*[clinic input]
9617db96d56Sopenharmony_ci_hashlib.openssl_md5
9627db96d56Sopenharmony_ci
9637db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
9647db96d56Sopenharmony_ci    *
9657db96d56Sopenharmony_ci    usedforsecurity: bool = True
9667db96d56Sopenharmony_ci
9677db96d56Sopenharmony_ciReturns a md5 hash object; optionally initialized with a string
9687db96d56Sopenharmony_ci
9697db96d56Sopenharmony_ci[clinic start generated code]*/
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_cistatic PyObject *
9727db96d56Sopenharmony_ci_hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj,
9737db96d56Sopenharmony_ci                          int usedforsecurity)
9747db96d56Sopenharmony_ci/*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/
9757db96d56Sopenharmony_ci{
9767db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity);
9777db96d56Sopenharmony_ci}
9787db96d56Sopenharmony_ci
9797db96d56Sopenharmony_ci
9807db96d56Sopenharmony_ci/*[clinic input]
9817db96d56Sopenharmony_ci_hashlib.openssl_sha1
9827db96d56Sopenharmony_ci
9837db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
9847db96d56Sopenharmony_ci    *
9857db96d56Sopenharmony_ci    usedforsecurity: bool = True
9867db96d56Sopenharmony_ci
9877db96d56Sopenharmony_ciReturns a sha1 hash object; optionally initialized with a string
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci[clinic start generated code]*/
9907db96d56Sopenharmony_ci
9917db96d56Sopenharmony_cistatic PyObject *
9927db96d56Sopenharmony_ci_hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj,
9937db96d56Sopenharmony_ci                           int usedforsecurity)
9947db96d56Sopenharmony_ci/*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/
9957db96d56Sopenharmony_ci{
9967db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity);
9977db96d56Sopenharmony_ci}
9987db96d56Sopenharmony_ci
9997db96d56Sopenharmony_ci
10007db96d56Sopenharmony_ci/*[clinic input]
10017db96d56Sopenharmony_ci_hashlib.openssl_sha224
10027db96d56Sopenharmony_ci
10037db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
10047db96d56Sopenharmony_ci    *
10057db96d56Sopenharmony_ci    usedforsecurity: bool = True
10067db96d56Sopenharmony_ci
10077db96d56Sopenharmony_ciReturns a sha224 hash object; optionally initialized with a string
10087db96d56Sopenharmony_ci
10097db96d56Sopenharmony_ci[clinic start generated code]*/
10107db96d56Sopenharmony_ci
10117db96d56Sopenharmony_cistatic PyObject *
10127db96d56Sopenharmony_ci_hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj,
10137db96d56Sopenharmony_ci                             int usedforsecurity)
10147db96d56Sopenharmony_ci/*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/
10157db96d56Sopenharmony_ci{
10167db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity);
10177db96d56Sopenharmony_ci}
10187db96d56Sopenharmony_ci
10197db96d56Sopenharmony_ci
10207db96d56Sopenharmony_ci/*[clinic input]
10217db96d56Sopenharmony_ci_hashlib.openssl_sha256
10227db96d56Sopenharmony_ci
10237db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
10247db96d56Sopenharmony_ci    *
10257db96d56Sopenharmony_ci    usedforsecurity: bool = True
10267db96d56Sopenharmony_ci
10277db96d56Sopenharmony_ciReturns a sha256 hash object; optionally initialized with a string
10287db96d56Sopenharmony_ci
10297db96d56Sopenharmony_ci[clinic start generated code]*/
10307db96d56Sopenharmony_ci
10317db96d56Sopenharmony_cistatic PyObject *
10327db96d56Sopenharmony_ci_hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj,
10337db96d56Sopenharmony_ci                             int usedforsecurity)
10347db96d56Sopenharmony_ci/*[clinic end generated code: output=1f874a34870f0a68 input=549fad9d2930d4c5]*/
10357db96d56Sopenharmony_ci{
10367db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha256, data_obj, usedforsecurity);
10377db96d56Sopenharmony_ci}
10387db96d56Sopenharmony_ci
10397db96d56Sopenharmony_ci
10407db96d56Sopenharmony_ci/*[clinic input]
10417db96d56Sopenharmony_ci_hashlib.openssl_sha384
10427db96d56Sopenharmony_ci
10437db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
10447db96d56Sopenharmony_ci    *
10457db96d56Sopenharmony_ci    usedforsecurity: bool = True
10467db96d56Sopenharmony_ci
10477db96d56Sopenharmony_ciReturns a sha384 hash object; optionally initialized with a string
10487db96d56Sopenharmony_ci
10497db96d56Sopenharmony_ci[clinic start generated code]*/
10507db96d56Sopenharmony_ci
10517db96d56Sopenharmony_cistatic PyObject *
10527db96d56Sopenharmony_ci_hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj,
10537db96d56Sopenharmony_ci                             int usedforsecurity)
10547db96d56Sopenharmony_ci/*[clinic end generated code: output=58529eff9ca457b2 input=48601a6e3bf14ad7]*/
10557db96d56Sopenharmony_ci{
10567db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha384, data_obj, usedforsecurity);
10577db96d56Sopenharmony_ci}
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ci
10607db96d56Sopenharmony_ci/*[clinic input]
10617db96d56Sopenharmony_ci_hashlib.openssl_sha512
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
10647db96d56Sopenharmony_ci    *
10657db96d56Sopenharmony_ci    usedforsecurity: bool = True
10667db96d56Sopenharmony_ci
10677db96d56Sopenharmony_ciReturns a sha512 hash object; optionally initialized with a string
10687db96d56Sopenharmony_ci
10697db96d56Sopenharmony_ci[clinic start generated code]*/
10707db96d56Sopenharmony_ci
10717db96d56Sopenharmony_cistatic PyObject *
10727db96d56Sopenharmony_ci_hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj,
10737db96d56Sopenharmony_ci                             int usedforsecurity)
10747db96d56Sopenharmony_ci/*[clinic end generated code: output=2c744c9e4a40d5f6 input=c5c46a2a817aa98f]*/
10757db96d56Sopenharmony_ci{
10767db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha512, data_obj, usedforsecurity);
10777db96d56Sopenharmony_ci}
10787db96d56Sopenharmony_ci
10797db96d56Sopenharmony_ci
10807db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHA3
10817db96d56Sopenharmony_ci
10827db96d56Sopenharmony_ci/*[clinic input]
10837db96d56Sopenharmony_ci_hashlib.openssl_sha3_224
10847db96d56Sopenharmony_ci
10857db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
10867db96d56Sopenharmony_ci    *
10877db96d56Sopenharmony_ci    usedforsecurity: bool = True
10887db96d56Sopenharmony_ci
10897db96d56Sopenharmony_ciReturns a sha3-224 hash object; optionally initialized with a string
10907db96d56Sopenharmony_ci
10917db96d56Sopenharmony_ci[clinic start generated code]*/
10927db96d56Sopenharmony_ci
10937db96d56Sopenharmony_cistatic PyObject *
10947db96d56Sopenharmony_ci_hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj,
10957db96d56Sopenharmony_ci                               int usedforsecurity)
10967db96d56Sopenharmony_ci/*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/
10977db96d56Sopenharmony_ci{
10987db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha3_224, data_obj, usedforsecurity);
10997db96d56Sopenharmony_ci}
11007db96d56Sopenharmony_ci
11017db96d56Sopenharmony_ci/*[clinic input]
11027db96d56Sopenharmony_ci_hashlib.openssl_sha3_256
11037db96d56Sopenharmony_ci
11047db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
11057db96d56Sopenharmony_ci    *
11067db96d56Sopenharmony_ci    usedforsecurity: bool = True
11077db96d56Sopenharmony_ci
11087db96d56Sopenharmony_ciReturns a sha3-256 hash object; optionally initialized with a string
11097db96d56Sopenharmony_ci
11107db96d56Sopenharmony_ci[clinic start generated code]*/
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_cistatic PyObject *
11137db96d56Sopenharmony_ci_hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj,
11147db96d56Sopenharmony_ci                               int usedforsecurity)
11157db96d56Sopenharmony_ci/*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/
11167db96d56Sopenharmony_ci{
11177db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha3_256, data_obj , usedforsecurity);
11187db96d56Sopenharmony_ci}
11197db96d56Sopenharmony_ci
11207db96d56Sopenharmony_ci/*[clinic input]
11217db96d56Sopenharmony_ci_hashlib.openssl_sha3_384
11227db96d56Sopenharmony_ci
11237db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
11247db96d56Sopenharmony_ci    *
11257db96d56Sopenharmony_ci    usedforsecurity: bool = True
11267db96d56Sopenharmony_ci
11277db96d56Sopenharmony_ciReturns a sha3-384 hash object; optionally initialized with a string
11287db96d56Sopenharmony_ci
11297db96d56Sopenharmony_ci[clinic start generated code]*/
11307db96d56Sopenharmony_ci
11317db96d56Sopenharmony_cistatic PyObject *
11327db96d56Sopenharmony_ci_hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj,
11337db96d56Sopenharmony_ci                               int usedforsecurity)
11347db96d56Sopenharmony_ci/*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/
11357db96d56Sopenharmony_ci{
11367db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha3_384, data_obj , usedforsecurity);
11377db96d56Sopenharmony_ci}
11387db96d56Sopenharmony_ci
11397db96d56Sopenharmony_ci/*[clinic input]
11407db96d56Sopenharmony_ci_hashlib.openssl_sha3_512
11417db96d56Sopenharmony_ci
11427db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
11437db96d56Sopenharmony_ci    *
11447db96d56Sopenharmony_ci    usedforsecurity: bool = True
11457db96d56Sopenharmony_ci
11467db96d56Sopenharmony_ciReturns a sha3-512 hash object; optionally initialized with a string
11477db96d56Sopenharmony_ci
11487db96d56Sopenharmony_ci[clinic start generated code]*/
11497db96d56Sopenharmony_ci
11507db96d56Sopenharmony_cistatic PyObject *
11517db96d56Sopenharmony_ci_hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj,
11527db96d56Sopenharmony_ci                               int usedforsecurity)
11537db96d56Sopenharmony_ci/*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/
11547db96d56Sopenharmony_ci{
11557db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_sha3_512, data_obj , usedforsecurity);
11567db96d56Sopenharmony_ci}
11577db96d56Sopenharmony_ci#endif /* PY_OPENSSL_HAS_SHA3 */
11587db96d56Sopenharmony_ci
11597db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
11607db96d56Sopenharmony_ci/*[clinic input]
11617db96d56Sopenharmony_ci_hashlib.openssl_shake_128
11627db96d56Sopenharmony_ci
11637db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
11647db96d56Sopenharmony_ci    *
11657db96d56Sopenharmony_ci    usedforsecurity: bool = True
11667db96d56Sopenharmony_ci
11677db96d56Sopenharmony_ciReturns a shake-128 variable hash object; optionally initialized with a string
11687db96d56Sopenharmony_ci
11697db96d56Sopenharmony_ci[clinic start generated code]*/
11707db96d56Sopenharmony_ci
11717db96d56Sopenharmony_cistatic PyObject *
11727db96d56Sopenharmony_ci_hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj,
11737db96d56Sopenharmony_ci                                int usedforsecurity)
11747db96d56Sopenharmony_ci/*[clinic end generated code: output=bc49cdd8ada1fa97 input=6c9d67440eb33ec8]*/
11757db96d56Sopenharmony_ci{
11767db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_shake_128, data_obj , usedforsecurity);
11777db96d56Sopenharmony_ci}
11787db96d56Sopenharmony_ci
11797db96d56Sopenharmony_ci/*[clinic input]
11807db96d56Sopenharmony_ci_hashlib.openssl_shake_256
11817db96d56Sopenharmony_ci
11827db96d56Sopenharmony_ci    string as data_obj: object(py_default="b''") = NULL
11837db96d56Sopenharmony_ci    *
11847db96d56Sopenharmony_ci    usedforsecurity: bool = True
11857db96d56Sopenharmony_ci
11867db96d56Sopenharmony_ciReturns a shake-256 variable hash object; optionally initialized with a string
11877db96d56Sopenharmony_ci
11887db96d56Sopenharmony_ci[clinic start generated code]*/
11897db96d56Sopenharmony_ci
11907db96d56Sopenharmony_cistatic PyObject *
11917db96d56Sopenharmony_ci_hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj,
11927db96d56Sopenharmony_ci                                int usedforsecurity)
11937db96d56Sopenharmony_ci/*[clinic end generated code: output=358d213be8852df7 input=479cbe9fefd4a9f8]*/
11947db96d56Sopenharmony_ci{
11957db96d56Sopenharmony_ci    return py_evp_fromname(module, Py_hash_shake_256, data_obj , usedforsecurity);
11967db96d56Sopenharmony_ci}
11977db96d56Sopenharmony_ci#endif /* PY_OPENSSL_HAS_SHAKE */
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci/*[clinic input]
12007db96d56Sopenharmony_ci_hashlib.pbkdf2_hmac as pbkdf2_hmac
12017db96d56Sopenharmony_ci
12027db96d56Sopenharmony_ci    hash_name: str
12037db96d56Sopenharmony_ci    password: Py_buffer
12047db96d56Sopenharmony_ci    salt: Py_buffer
12057db96d56Sopenharmony_ci    iterations: long
12067db96d56Sopenharmony_ci    dklen as dklen_obj: object = None
12077db96d56Sopenharmony_ci
12087db96d56Sopenharmony_ciPassword based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function.
12097db96d56Sopenharmony_ci[clinic start generated code]*/
12107db96d56Sopenharmony_ci
12117db96d56Sopenharmony_cistatic PyObject *
12127db96d56Sopenharmony_cipbkdf2_hmac_impl(PyObject *module, const char *hash_name,
12137db96d56Sopenharmony_ci                 Py_buffer *password, Py_buffer *salt, long iterations,
12147db96d56Sopenharmony_ci                 PyObject *dklen_obj)
12157db96d56Sopenharmony_ci/*[clinic end generated code: output=144b76005416599b input=ed3ab0d2d28b5d5c]*/
12167db96d56Sopenharmony_ci{
12177db96d56Sopenharmony_ci    PyObject *key_obj = NULL;
12187db96d56Sopenharmony_ci    char *key;
12197db96d56Sopenharmony_ci    long dklen;
12207db96d56Sopenharmony_ci    int retval;
12217db96d56Sopenharmony_ci
12227db96d56Sopenharmony_ci    PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2);
12237db96d56Sopenharmony_ci    if (digest == NULL) {
12247db96d56Sopenharmony_ci        goto end;
12257db96d56Sopenharmony_ci    }
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ci    if (password->len > INT_MAX) {
12287db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
12297db96d56Sopenharmony_ci                        "password is too long.");
12307db96d56Sopenharmony_ci        goto end;
12317db96d56Sopenharmony_ci    }
12327db96d56Sopenharmony_ci
12337db96d56Sopenharmony_ci    if (salt->len > INT_MAX) {
12347db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
12357db96d56Sopenharmony_ci                        "salt is too long.");
12367db96d56Sopenharmony_ci        goto end;
12377db96d56Sopenharmony_ci    }
12387db96d56Sopenharmony_ci
12397db96d56Sopenharmony_ci    if (iterations < 1) {
12407db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
12417db96d56Sopenharmony_ci                        "iteration value must be greater than 0.");
12427db96d56Sopenharmony_ci        goto end;
12437db96d56Sopenharmony_ci    }
12447db96d56Sopenharmony_ci    if (iterations > INT_MAX) {
12457db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
12467db96d56Sopenharmony_ci                        "iteration value is too great.");
12477db96d56Sopenharmony_ci        goto end;
12487db96d56Sopenharmony_ci    }
12497db96d56Sopenharmony_ci
12507db96d56Sopenharmony_ci    if (dklen_obj == Py_None) {
12517db96d56Sopenharmony_ci        dklen = EVP_MD_size(digest);
12527db96d56Sopenharmony_ci    } else {
12537db96d56Sopenharmony_ci        dklen = PyLong_AsLong(dklen_obj);
12547db96d56Sopenharmony_ci        if ((dklen == -1) && PyErr_Occurred()) {
12557db96d56Sopenharmony_ci            goto end;
12567db96d56Sopenharmony_ci        }
12577db96d56Sopenharmony_ci    }
12587db96d56Sopenharmony_ci    if (dklen < 1) {
12597db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
12607db96d56Sopenharmony_ci                        "key length must be greater than 0.");
12617db96d56Sopenharmony_ci        goto end;
12627db96d56Sopenharmony_ci    }
12637db96d56Sopenharmony_ci    if (dklen > INT_MAX) {
12647db96d56Sopenharmony_ci        /* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */
12657db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
12667db96d56Sopenharmony_ci                        "key length is too great.");
12677db96d56Sopenharmony_ci        goto end;
12687db96d56Sopenharmony_ci    }
12697db96d56Sopenharmony_ci
12707db96d56Sopenharmony_ci    key_obj = PyBytes_FromStringAndSize(NULL, dklen);
12717db96d56Sopenharmony_ci    if (key_obj == NULL) {
12727db96d56Sopenharmony_ci        goto end;
12737db96d56Sopenharmony_ci    }
12747db96d56Sopenharmony_ci    key = PyBytes_AS_STRING(key_obj);
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
12777db96d56Sopenharmony_ci    retval = PKCS5_PBKDF2_HMAC((char*)password->buf, (int)password->len,
12787db96d56Sopenharmony_ci                               (unsigned char *)salt->buf, (int)salt->len,
12797db96d56Sopenharmony_ci                               iterations, digest, dklen,
12807db96d56Sopenharmony_ci                               (unsigned char *)key);
12817db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
12827db96d56Sopenharmony_ci
12837db96d56Sopenharmony_ci    if (!retval) {
12847db96d56Sopenharmony_ci        Py_CLEAR(key_obj);
12857db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
12867db96d56Sopenharmony_ci        goto end;
12877db96d56Sopenharmony_ci    }
12887db96d56Sopenharmony_ci
12897db96d56Sopenharmony_ci  end:
12907db96d56Sopenharmony_ci    if (digest != NULL) {
12917db96d56Sopenharmony_ci        PY_EVP_MD_free(digest);
12927db96d56Sopenharmony_ci    }
12937db96d56Sopenharmony_ci    return key_obj;
12947db96d56Sopenharmony_ci}
12957db96d56Sopenharmony_ci
12967db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SCRYPT
12977db96d56Sopenharmony_ci
12987db96d56Sopenharmony_ci/* XXX: Parameters salt, n, r and p should be required keyword-only parameters.
12997db96d56Sopenharmony_ci   They are optional in the Argument Clinic declaration only due to a
13007db96d56Sopenharmony_ci   limitation of PyArg_ParseTupleAndKeywords. */
13017db96d56Sopenharmony_ci
13027db96d56Sopenharmony_ci/*[clinic input]
13037db96d56Sopenharmony_ci_hashlib.scrypt
13047db96d56Sopenharmony_ci
13057db96d56Sopenharmony_ci    password: Py_buffer
13067db96d56Sopenharmony_ci    *
13077db96d56Sopenharmony_ci    salt: Py_buffer = None
13087db96d56Sopenharmony_ci    n as n_obj: object(subclass_of='&PyLong_Type') = None
13097db96d56Sopenharmony_ci    r as r_obj: object(subclass_of='&PyLong_Type') = None
13107db96d56Sopenharmony_ci    p as p_obj: object(subclass_of='&PyLong_Type') = None
13117db96d56Sopenharmony_ci    maxmem: long = 0
13127db96d56Sopenharmony_ci    dklen: long = 64
13137db96d56Sopenharmony_ci
13147db96d56Sopenharmony_ci
13157db96d56Sopenharmony_ciscrypt password-based key derivation function.
13167db96d56Sopenharmony_ci[clinic start generated code]*/
13177db96d56Sopenharmony_ci
13187db96d56Sopenharmony_cistatic PyObject *
13197db96d56Sopenharmony_ci_hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
13207db96d56Sopenharmony_ci                     PyObject *n_obj, PyObject *r_obj, PyObject *p_obj,
13217db96d56Sopenharmony_ci                     long maxmem, long dklen)
13227db96d56Sopenharmony_ci/*[clinic end generated code: output=14849e2aa2b7b46c input=48a7d63bf3f75c42]*/
13237db96d56Sopenharmony_ci{
13247db96d56Sopenharmony_ci    PyObject *key_obj = NULL;
13257db96d56Sopenharmony_ci    char *key;
13267db96d56Sopenharmony_ci    int retval;
13277db96d56Sopenharmony_ci    unsigned long n, r, p;
13287db96d56Sopenharmony_ci
13297db96d56Sopenharmony_ci    if (password->len > INT_MAX) {
13307db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
13317db96d56Sopenharmony_ci                        "password is too long.");
13327db96d56Sopenharmony_ci        return NULL;
13337db96d56Sopenharmony_ci    }
13347db96d56Sopenharmony_ci
13357db96d56Sopenharmony_ci    if (salt->buf == NULL) {
13367db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
13377db96d56Sopenharmony_ci                        "salt is required");
13387db96d56Sopenharmony_ci        return NULL;
13397db96d56Sopenharmony_ci    }
13407db96d56Sopenharmony_ci    if (salt->len > INT_MAX) {
13417db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
13427db96d56Sopenharmony_ci                        "salt is too long.");
13437db96d56Sopenharmony_ci        return NULL;
13447db96d56Sopenharmony_ci    }
13457db96d56Sopenharmony_ci
13467db96d56Sopenharmony_ci    n = PyLong_AsUnsignedLong(n_obj);
13477db96d56Sopenharmony_ci    if (n == (unsigned long) -1 && PyErr_Occurred()) {
13487db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
13497db96d56Sopenharmony_ci                        "n is required and must be an unsigned int");
13507db96d56Sopenharmony_ci        return NULL;
13517db96d56Sopenharmony_ci    }
13527db96d56Sopenharmony_ci    if (n < 2 || n & (n - 1)) {
13537db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
13547db96d56Sopenharmony_ci                        "n must be a power of 2.");
13557db96d56Sopenharmony_ci        return NULL;
13567db96d56Sopenharmony_ci    }
13577db96d56Sopenharmony_ci
13587db96d56Sopenharmony_ci    r = PyLong_AsUnsignedLong(r_obj);
13597db96d56Sopenharmony_ci    if (r == (unsigned long) -1 && PyErr_Occurred()) {
13607db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
13617db96d56Sopenharmony_ci                         "r is required and must be an unsigned int");
13627db96d56Sopenharmony_ci        return NULL;
13637db96d56Sopenharmony_ci    }
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ci    p = PyLong_AsUnsignedLong(p_obj);
13667db96d56Sopenharmony_ci    if (p == (unsigned long) -1 && PyErr_Occurred()) {
13677db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
13687db96d56Sopenharmony_ci                         "p is required and must be an unsigned int");
13697db96d56Sopenharmony_ci        return NULL;
13707db96d56Sopenharmony_ci    }
13717db96d56Sopenharmony_ci
13727db96d56Sopenharmony_ci    if (maxmem < 0 || maxmem > INT_MAX) {
13737db96d56Sopenharmony_ci        /* OpenSSL 1.1.0 restricts maxmem to 32 MiB. It may change in the
13747db96d56Sopenharmony_ci           future. The maxmem constant is private to OpenSSL. */
13757db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
13767db96d56Sopenharmony_ci                     "maxmem must be positive and smaller than %d",
13777db96d56Sopenharmony_ci                      INT_MAX);
13787db96d56Sopenharmony_ci        return NULL;
13797db96d56Sopenharmony_ci    }
13807db96d56Sopenharmony_ci
13817db96d56Sopenharmony_ci    if (dklen < 1 || dklen > INT_MAX) {
13827db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
13837db96d56Sopenharmony_ci                    "dklen must be greater than 0 and smaller than %d",
13847db96d56Sopenharmony_ci                    INT_MAX);
13857db96d56Sopenharmony_ci        return NULL;
13867db96d56Sopenharmony_ci    }
13877db96d56Sopenharmony_ci
13887db96d56Sopenharmony_ci    /* let OpenSSL validate the rest */
13897db96d56Sopenharmony_ci    retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0);
13907db96d56Sopenharmony_ci    if (!retval) {
13917db96d56Sopenharmony_ci        _setException(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem.");
13927db96d56Sopenharmony_ci        return NULL;
13937db96d56Sopenharmony_ci   }
13947db96d56Sopenharmony_ci
13957db96d56Sopenharmony_ci    key_obj = PyBytes_FromStringAndSize(NULL, dklen);
13967db96d56Sopenharmony_ci    if (key_obj == NULL) {
13977db96d56Sopenharmony_ci        return NULL;
13987db96d56Sopenharmony_ci    }
13997db96d56Sopenharmony_ci    key = PyBytes_AS_STRING(key_obj);
14007db96d56Sopenharmony_ci
14017db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14027db96d56Sopenharmony_ci    retval = EVP_PBE_scrypt(
14037db96d56Sopenharmony_ci        (const char*)password->buf, (size_t)password->len,
14047db96d56Sopenharmony_ci        (const unsigned char *)salt->buf, (size_t)salt->len,
14057db96d56Sopenharmony_ci        n, r, p, maxmem,
14067db96d56Sopenharmony_ci        (unsigned char *)key, (size_t)dklen
14077db96d56Sopenharmony_ci    );
14087db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14097db96d56Sopenharmony_ci
14107db96d56Sopenharmony_ci    if (!retval) {
14117db96d56Sopenharmony_ci        Py_CLEAR(key_obj);
14127db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
14137db96d56Sopenharmony_ci        return NULL;
14147db96d56Sopenharmony_ci    }
14157db96d56Sopenharmony_ci    return key_obj;
14167db96d56Sopenharmony_ci}
14177db96d56Sopenharmony_ci#endif  /* PY_OPENSSL_HAS_SCRYPT */
14187db96d56Sopenharmony_ci
14197db96d56Sopenharmony_ci/* Fast HMAC for hmac.digest()
14207db96d56Sopenharmony_ci */
14217db96d56Sopenharmony_ci
14227db96d56Sopenharmony_ci/*[clinic input]
14237db96d56Sopenharmony_ci_hashlib.hmac_digest as _hashlib_hmac_singleshot
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ci    key: Py_buffer
14267db96d56Sopenharmony_ci    msg: Py_buffer
14277db96d56Sopenharmony_ci    digest: object
14287db96d56Sopenharmony_ci
14297db96d56Sopenharmony_ciSingle-shot HMAC.
14307db96d56Sopenharmony_ci[clinic start generated code]*/
14317db96d56Sopenharmony_ci
14327db96d56Sopenharmony_cistatic PyObject *
14337db96d56Sopenharmony_ci_hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key,
14347db96d56Sopenharmony_ci                              Py_buffer *msg, PyObject *digest)
14357db96d56Sopenharmony_ci/*[clinic end generated code: output=82f19965d12706ac input=0a0790cc3db45c2e]*/
14367db96d56Sopenharmony_ci{
14377db96d56Sopenharmony_ci    unsigned char md[EVP_MAX_MD_SIZE] = {0};
14387db96d56Sopenharmony_ci    unsigned int md_len = 0;
14397db96d56Sopenharmony_ci    unsigned char *result;
14407db96d56Sopenharmony_ci    PY_EVP_MD *evp;
14417db96d56Sopenharmony_ci
14427db96d56Sopenharmony_ci    if (key->len > INT_MAX) {
14437db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
14447db96d56Sopenharmony_ci                        "key is too long.");
14457db96d56Sopenharmony_ci        return NULL;
14467db96d56Sopenharmony_ci    }
14477db96d56Sopenharmony_ci    if (msg->len > INT_MAX) {
14487db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
14497db96d56Sopenharmony_ci                        "msg is too long.");
14507db96d56Sopenharmony_ci        return NULL;
14517db96d56Sopenharmony_ci    }
14527db96d56Sopenharmony_ci
14537db96d56Sopenharmony_ci    evp = py_digest_by_digestmod(module, digest, Py_ht_mac);
14547db96d56Sopenharmony_ci    if (evp == NULL) {
14557db96d56Sopenharmony_ci        return NULL;
14567db96d56Sopenharmony_ci    }
14577db96d56Sopenharmony_ci
14587db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
14597db96d56Sopenharmony_ci    result = HMAC(
14607db96d56Sopenharmony_ci        evp,
14617db96d56Sopenharmony_ci        (const void*)key->buf, (int)key->len,
14627db96d56Sopenharmony_ci        (const unsigned char*)msg->buf, (int)msg->len,
14637db96d56Sopenharmony_ci        md, &md_len
14647db96d56Sopenharmony_ci    );
14657db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
14667db96d56Sopenharmony_ci    PY_EVP_MD_free(evp);
14677db96d56Sopenharmony_ci
14687db96d56Sopenharmony_ci    if (result == NULL) {
14697db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
14707db96d56Sopenharmony_ci        return NULL;
14717db96d56Sopenharmony_ci    }
14727db96d56Sopenharmony_ci    return PyBytes_FromStringAndSize((const char*)md, md_len);
14737db96d56Sopenharmony_ci}
14747db96d56Sopenharmony_ci
14757db96d56Sopenharmony_ci/* OpenSSL-based HMAC implementation
14767db96d56Sopenharmony_ci */
14777db96d56Sopenharmony_ci
14787db96d56Sopenharmony_cistatic int _hmac_update(HMACobject*, PyObject*);
14797db96d56Sopenharmony_ci
14807db96d56Sopenharmony_ci/*[clinic input]
14817db96d56Sopenharmony_ci_hashlib.hmac_new
14827db96d56Sopenharmony_ci
14837db96d56Sopenharmony_ci    key: Py_buffer
14847db96d56Sopenharmony_ci    msg as msg_obj: object(c_default="NULL") = b''
14857db96d56Sopenharmony_ci    digestmod: object(c_default="NULL") = None
14867db96d56Sopenharmony_ci
14877db96d56Sopenharmony_ciReturn a new hmac object.
14887db96d56Sopenharmony_ci[clinic start generated code]*/
14897db96d56Sopenharmony_ci
14907db96d56Sopenharmony_cistatic PyObject *
14917db96d56Sopenharmony_ci_hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
14927db96d56Sopenharmony_ci                       PyObject *digestmod)
14937db96d56Sopenharmony_ci/*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/
14947db96d56Sopenharmony_ci{
14957db96d56Sopenharmony_ci    PyTypeObject *type = get_hashlib_state(module)->HMACtype;
14967db96d56Sopenharmony_ci    PY_EVP_MD *digest;
14977db96d56Sopenharmony_ci    HMAC_CTX *ctx = NULL;
14987db96d56Sopenharmony_ci    HMACobject *self = NULL;
14997db96d56Sopenharmony_ci    int r;
15007db96d56Sopenharmony_ci
15017db96d56Sopenharmony_ci    if (key->len > INT_MAX) {
15027db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError,
15037db96d56Sopenharmony_ci                        "key is too long.");
15047db96d56Sopenharmony_ci        return NULL;
15057db96d56Sopenharmony_ci    }
15067db96d56Sopenharmony_ci
15077db96d56Sopenharmony_ci    if (digestmod == NULL) {
15087db96d56Sopenharmony_ci        PyErr_SetString(
15097db96d56Sopenharmony_ci            PyExc_TypeError, "Missing required parameter 'digestmod'.");
15107db96d56Sopenharmony_ci        return NULL;
15117db96d56Sopenharmony_ci    }
15127db96d56Sopenharmony_ci
15137db96d56Sopenharmony_ci    digest = py_digest_by_digestmod(module, digestmod, Py_ht_mac);
15147db96d56Sopenharmony_ci    if (digest == NULL) {
15157db96d56Sopenharmony_ci        return NULL;
15167db96d56Sopenharmony_ci    }
15177db96d56Sopenharmony_ci
15187db96d56Sopenharmony_ci    ctx = HMAC_CTX_new();
15197db96d56Sopenharmony_ci    if (ctx == NULL) {
15207db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
15217db96d56Sopenharmony_ci        goto error;
15227db96d56Sopenharmony_ci    }
15237db96d56Sopenharmony_ci
15247db96d56Sopenharmony_ci    r = HMAC_Init_ex(
15257db96d56Sopenharmony_ci        ctx,
15267db96d56Sopenharmony_ci        (const char*)key->buf,
15277db96d56Sopenharmony_ci        (int)key->len,
15287db96d56Sopenharmony_ci        digest,
15297db96d56Sopenharmony_ci        NULL /*impl*/);
15307db96d56Sopenharmony_ci    PY_EVP_MD_free(digest);
15317db96d56Sopenharmony_ci    if (r == 0) {
15327db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
15337db96d56Sopenharmony_ci        goto error;
15347db96d56Sopenharmony_ci    }
15357db96d56Sopenharmony_ci
15367db96d56Sopenharmony_ci    self = (HMACobject *)PyObject_New(HMACobject, type);
15377db96d56Sopenharmony_ci    if (self == NULL) {
15387db96d56Sopenharmony_ci        goto error;
15397db96d56Sopenharmony_ci    }
15407db96d56Sopenharmony_ci
15417db96d56Sopenharmony_ci    self->ctx = ctx;
15427db96d56Sopenharmony_ci    self->lock = NULL;
15437db96d56Sopenharmony_ci
15447db96d56Sopenharmony_ci    if ((msg_obj != NULL) && (msg_obj != Py_None)) {
15457db96d56Sopenharmony_ci        if (!_hmac_update(self, msg_obj))
15467db96d56Sopenharmony_ci            goto error;
15477db96d56Sopenharmony_ci    }
15487db96d56Sopenharmony_ci
15497db96d56Sopenharmony_ci    return (PyObject*)self;
15507db96d56Sopenharmony_ci
15517db96d56Sopenharmony_cierror:
15527db96d56Sopenharmony_ci    if (ctx) HMAC_CTX_free(ctx);
15537db96d56Sopenharmony_ci    if (self) PyObject_Free(self);
15547db96d56Sopenharmony_ci    return NULL;
15557db96d56Sopenharmony_ci}
15567db96d56Sopenharmony_ci
15577db96d56Sopenharmony_ci/* helper functions */
15587db96d56Sopenharmony_cistatic int
15597db96d56Sopenharmony_cilocked_HMAC_CTX_copy(HMAC_CTX *new_ctx_p, HMACobject *self)
15607db96d56Sopenharmony_ci{
15617db96d56Sopenharmony_ci    int result;
15627db96d56Sopenharmony_ci    ENTER_HASHLIB(self);
15637db96d56Sopenharmony_ci    result = HMAC_CTX_copy(new_ctx_p, self->ctx);
15647db96d56Sopenharmony_ci    LEAVE_HASHLIB(self);
15657db96d56Sopenharmony_ci    return result;
15667db96d56Sopenharmony_ci}
15677db96d56Sopenharmony_ci
15687db96d56Sopenharmony_cistatic unsigned int
15697db96d56Sopenharmony_ci_hmac_digest_size(HMACobject *self)
15707db96d56Sopenharmony_ci{
15717db96d56Sopenharmony_ci    unsigned int digest_size = EVP_MD_size(HMAC_CTX_get_md(self->ctx));
15727db96d56Sopenharmony_ci    assert(digest_size <= EVP_MAX_MD_SIZE);
15737db96d56Sopenharmony_ci    return digest_size;
15747db96d56Sopenharmony_ci}
15757db96d56Sopenharmony_ci
15767db96d56Sopenharmony_cistatic int
15777db96d56Sopenharmony_ci_hmac_update(HMACobject *self, PyObject *obj)
15787db96d56Sopenharmony_ci{
15797db96d56Sopenharmony_ci    int r;
15807db96d56Sopenharmony_ci    Py_buffer view = {0};
15817db96d56Sopenharmony_ci
15827db96d56Sopenharmony_ci    GET_BUFFER_VIEW_OR_ERROR(obj, &view, return 0);
15837db96d56Sopenharmony_ci
15847db96d56Sopenharmony_ci    if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
15857db96d56Sopenharmony_ci        self->lock = PyThread_allocate_lock();
15867db96d56Sopenharmony_ci        /* fail? lock = NULL and we fail over to non-threaded code. */
15877db96d56Sopenharmony_ci    }
15887db96d56Sopenharmony_ci
15897db96d56Sopenharmony_ci    if (self->lock != NULL) {
15907db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
15917db96d56Sopenharmony_ci        PyThread_acquire_lock(self->lock, 1);
15927db96d56Sopenharmony_ci        r = HMAC_Update(self->ctx, (const unsigned char*)view.buf, view.len);
15937db96d56Sopenharmony_ci        PyThread_release_lock(self->lock);
15947db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
15957db96d56Sopenharmony_ci    } else {
15967db96d56Sopenharmony_ci        r = HMAC_Update(self->ctx, (const unsigned char*)view.buf, view.len);
15977db96d56Sopenharmony_ci    }
15987db96d56Sopenharmony_ci
15997db96d56Sopenharmony_ci    PyBuffer_Release(&view);
16007db96d56Sopenharmony_ci
16017db96d56Sopenharmony_ci    if (r == 0) {
16027db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
16037db96d56Sopenharmony_ci        return 0;
16047db96d56Sopenharmony_ci    }
16057db96d56Sopenharmony_ci    return 1;
16067db96d56Sopenharmony_ci}
16077db96d56Sopenharmony_ci
16087db96d56Sopenharmony_ci/*[clinic input]
16097db96d56Sopenharmony_ci_hashlib.HMAC.copy
16107db96d56Sopenharmony_ci
16117db96d56Sopenharmony_ciReturn a copy ("clone") of the HMAC object.
16127db96d56Sopenharmony_ci[clinic start generated code]*/
16137db96d56Sopenharmony_ci
16147db96d56Sopenharmony_cistatic PyObject *
16157db96d56Sopenharmony_ci_hashlib_HMAC_copy_impl(HMACobject *self)
16167db96d56Sopenharmony_ci/*[clinic end generated code: output=29aa28b452833127 input=e2fa6a05db61a4d6]*/
16177db96d56Sopenharmony_ci{
16187db96d56Sopenharmony_ci    HMACobject *retval;
16197db96d56Sopenharmony_ci
16207db96d56Sopenharmony_ci    HMAC_CTX *ctx = HMAC_CTX_new();
16217db96d56Sopenharmony_ci    if (ctx == NULL) {
16227db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
16237db96d56Sopenharmony_ci    }
16247db96d56Sopenharmony_ci    if (!locked_HMAC_CTX_copy(ctx, self)) {
16257db96d56Sopenharmony_ci        HMAC_CTX_free(ctx);
16267db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
16277db96d56Sopenharmony_ci    }
16287db96d56Sopenharmony_ci
16297db96d56Sopenharmony_ci    retval = (HMACobject *)PyObject_New(HMACobject, Py_TYPE(self));
16307db96d56Sopenharmony_ci    if (retval == NULL) {
16317db96d56Sopenharmony_ci        HMAC_CTX_free(ctx);
16327db96d56Sopenharmony_ci        return NULL;
16337db96d56Sopenharmony_ci    }
16347db96d56Sopenharmony_ci    retval->ctx = ctx;
16357db96d56Sopenharmony_ci    retval->lock = NULL;
16367db96d56Sopenharmony_ci
16377db96d56Sopenharmony_ci    return (PyObject *)retval;
16387db96d56Sopenharmony_ci}
16397db96d56Sopenharmony_ci
16407db96d56Sopenharmony_cistatic void
16417db96d56Sopenharmony_ci_hmac_dealloc(HMACobject *self)
16427db96d56Sopenharmony_ci{
16437db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
16447db96d56Sopenharmony_ci    if (self->lock != NULL) {
16457db96d56Sopenharmony_ci        PyThread_free_lock(self->lock);
16467db96d56Sopenharmony_ci    }
16477db96d56Sopenharmony_ci    HMAC_CTX_free(self->ctx);
16487db96d56Sopenharmony_ci    PyObject_Free(self);
16497db96d56Sopenharmony_ci    Py_DECREF(tp);
16507db96d56Sopenharmony_ci}
16517db96d56Sopenharmony_ci
16527db96d56Sopenharmony_cistatic PyObject *
16537db96d56Sopenharmony_ci_hmac_repr(HMACobject *self)
16547db96d56Sopenharmony_ci{
16557db96d56Sopenharmony_ci    PyObject *digest_name = py_digest_name(HMAC_CTX_get_md(self->ctx));
16567db96d56Sopenharmony_ci    if (digest_name == NULL) {
16577db96d56Sopenharmony_ci        return NULL;
16587db96d56Sopenharmony_ci    }
16597db96d56Sopenharmony_ci    PyObject *repr = PyUnicode_FromFormat(
16607db96d56Sopenharmony_ci        "<%U HMAC object @ %p>", digest_name, self
16617db96d56Sopenharmony_ci    );
16627db96d56Sopenharmony_ci    Py_DECREF(digest_name);
16637db96d56Sopenharmony_ci    return repr;
16647db96d56Sopenharmony_ci}
16657db96d56Sopenharmony_ci
16667db96d56Sopenharmony_ci/*[clinic input]
16677db96d56Sopenharmony_ci_hashlib.HMAC.update
16687db96d56Sopenharmony_ci    msg: object
16697db96d56Sopenharmony_ci
16707db96d56Sopenharmony_ciUpdate the HMAC object with msg.
16717db96d56Sopenharmony_ci[clinic start generated code]*/
16727db96d56Sopenharmony_ci
16737db96d56Sopenharmony_cistatic PyObject *
16747db96d56Sopenharmony_ci_hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg)
16757db96d56Sopenharmony_ci/*[clinic end generated code: output=f31f0ace8c625b00 input=1829173bb3cfd4e6]*/
16767db96d56Sopenharmony_ci{
16777db96d56Sopenharmony_ci    if (!_hmac_update(self, msg)) {
16787db96d56Sopenharmony_ci        return NULL;
16797db96d56Sopenharmony_ci    }
16807db96d56Sopenharmony_ci    Py_RETURN_NONE;
16817db96d56Sopenharmony_ci}
16827db96d56Sopenharmony_ci
16837db96d56Sopenharmony_cistatic int
16847db96d56Sopenharmony_ci_hmac_digest(HMACobject *self, unsigned char *buf, unsigned int len)
16857db96d56Sopenharmony_ci{
16867db96d56Sopenharmony_ci    HMAC_CTX *temp_ctx = HMAC_CTX_new();
16877db96d56Sopenharmony_ci    if (temp_ctx == NULL) {
16887db96d56Sopenharmony_ci        PyErr_NoMemory();
16897db96d56Sopenharmony_ci        return 0;
16907db96d56Sopenharmony_ci    }
16917db96d56Sopenharmony_ci    if (!locked_HMAC_CTX_copy(temp_ctx, self)) {
16927db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
16937db96d56Sopenharmony_ci        return 0;
16947db96d56Sopenharmony_ci    }
16957db96d56Sopenharmony_ci    int r = HMAC_Final(temp_ctx, buf, &len);
16967db96d56Sopenharmony_ci    HMAC_CTX_free(temp_ctx);
16977db96d56Sopenharmony_ci    if (r == 0) {
16987db96d56Sopenharmony_ci        _setException(PyExc_ValueError, NULL);
16997db96d56Sopenharmony_ci        return 0;
17007db96d56Sopenharmony_ci    }
17017db96d56Sopenharmony_ci    return 1;
17027db96d56Sopenharmony_ci}
17037db96d56Sopenharmony_ci
17047db96d56Sopenharmony_ci/*[clinic input]
17057db96d56Sopenharmony_ci_hashlib.HMAC.digest
17067db96d56Sopenharmony_ciReturn the digest of the bytes passed to the update() method so far.
17077db96d56Sopenharmony_ci[clinic start generated code]*/
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_cistatic PyObject *
17107db96d56Sopenharmony_ci_hashlib_HMAC_digest_impl(HMACobject *self)
17117db96d56Sopenharmony_ci/*[clinic end generated code: output=1b1424355af7a41e input=bff07f74da318fb4]*/
17127db96d56Sopenharmony_ci{
17137db96d56Sopenharmony_ci    unsigned char digest[EVP_MAX_MD_SIZE];
17147db96d56Sopenharmony_ci    unsigned int digest_size = _hmac_digest_size(self);
17157db96d56Sopenharmony_ci    if (digest_size == 0) {
17167db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
17177db96d56Sopenharmony_ci    }
17187db96d56Sopenharmony_ci    int r = _hmac_digest(self, digest, digest_size);
17197db96d56Sopenharmony_ci    if (r == 0) {
17207db96d56Sopenharmony_ci        return NULL;
17217db96d56Sopenharmony_ci    }
17227db96d56Sopenharmony_ci    return PyBytes_FromStringAndSize((const char *)digest, digest_size);
17237db96d56Sopenharmony_ci}
17247db96d56Sopenharmony_ci
17257db96d56Sopenharmony_ci/*[clinic input]
17267db96d56Sopenharmony_ci_hashlib.HMAC.hexdigest
17277db96d56Sopenharmony_ci
17287db96d56Sopenharmony_ciReturn hexadecimal digest of the bytes passed to the update() method so far.
17297db96d56Sopenharmony_ci
17307db96d56Sopenharmony_ciThis may be used to exchange the value safely in email or other non-binary
17317db96d56Sopenharmony_cienvironments.
17327db96d56Sopenharmony_ci[clinic start generated code]*/
17337db96d56Sopenharmony_ci
17347db96d56Sopenharmony_cistatic PyObject *
17357db96d56Sopenharmony_ci_hashlib_HMAC_hexdigest_impl(HMACobject *self)
17367db96d56Sopenharmony_ci/*[clinic end generated code: output=80d825be1eaae6a7 input=5abc42702874ddcf]*/
17377db96d56Sopenharmony_ci{
17387db96d56Sopenharmony_ci    unsigned char digest[EVP_MAX_MD_SIZE];
17397db96d56Sopenharmony_ci    unsigned int digest_size = _hmac_digest_size(self);
17407db96d56Sopenharmony_ci    if (digest_size == 0) {
17417db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
17427db96d56Sopenharmony_ci    }
17437db96d56Sopenharmony_ci    int r = _hmac_digest(self, digest, digest_size);
17447db96d56Sopenharmony_ci    if (r == 0) {
17457db96d56Sopenharmony_ci        return NULL;
17467db96d56Sopenharmony_ci    }
17477db96d56Sopenharmony_ci    return _Py_strhex((const char *)digest, digest_size);
17487db96d56Sopenharmony_ci}
17497db96d56Sopenharmony_ci
17507db96d56Sopenharmony_cistatic PyObject *
17517db96d56Sopenharmony_ci_hashlib_hmac_get_digest_size(HMACobject *self, void *closure)
17527db96d56Sopenharmony_ci{
17537db96d56Sopenharmony_ci    unsigned int digest_size = _hmac_digest_size(self);
17547db96d56Sopenharmony_ci    if (digest_size == 0) {
17557db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
17567db96d56Sopenharmony_ci    }
17577db96d56Sopenharmony_ci    return PyLong_FromLong(digest_size);
17587db96d56Sopenharmony_ci}
17597db96d56Sopenharmony_ci
17607db96d56Sopenharmony_cistatic PyObject *
17617db96d56Sopenharmony_ci_hashlib_hmac_get_block_size(HMACobject *self, void *closure)
17627db96d56Sopenharmony_ci{
17637db96d56Sopenharmony_ci    const EVP_MD *md = HMAC_CTX_get_md(self->ctx);
17647db96d56Sopenharmony_ci    if (md == NULL) {
17657db96d56Sopenharmony_ci        return _setException(PyExc_ValueError, NULL);
17667db96d56Sopenharmony_ci    }
17677db96d56Sopenharmony_ci    return PyLong_FromLong(EVP_MD_block_size(md));
17687db96d56Sopenharmony_ci}
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_cistatic PyObject *
17717db96d56Sopenharmony_ci_hashlib_hmac_get_name(HMACobject *self, void *closure)
17727db96d56Sopenharmony_ci{
17737db96d56Sopenharmony_ci    PyObject *digest_name = py_digest_name(HMAC_CTX_get_md(self->ctx));
17747db96d56Sopenharmony_ci    if (digest_name == NULL) {
17757db96d56Sopenharmony_ci        return NULL;
17767db96d56Sopenharmony_ci    }
17777db96d56Sopenharmony_ci    PyObject *name = PyUnicode_FromFormat("hmac-%U", digest_name);
17787db96d56Sopenharmony_ci    Py_DECREF(digest_name);
17797db96d56Sopenharmony_ci    return name;
17807db96d56Sopenharmony_ci}
17817db96d56Sopenharmony_ci
17827db96d56Sopenharmony_cistatic PyMethodDef HMAC_methods[] = {
17837db96d56Sopenharmony_ci    _HASHLIB_HMAC_UPDATE_METHODDEF
17847db96d56Sopenharmony_ci    _HASHLIB_HMAC_DIGEST_METHODDEF
17857db96d56Sopenharmony_ci    _HASHLIB_HMAC_HEXDIGEST_METHODDEF
17867db96d56Sopenharmony_ci    _HASHLIB_HMAC_COPY_METHODDEF
17877db96d56Sopenharmony_ci    {NULL, NULL}  /* sentinel */
17887db96d56Sopenharmony_ci};
17897db96d56Sopenharmony_ci
17907db96d56Sopenharmony_cistatic PyGetSetDef HMAC_getset[] = {
17917db96d56Sopenharmony_ci    {"digest_size", (getter)_hashlib_hmac_get_digest_size, NULL, NULL, NULL},
17927db96d56Sopenharmony_ci    {"block_size", (getter)_hashlib_hmac_get_block_size, NULL, NULL, NULL},
17937db96d56Sopenharmony_ci    {"name", (getter)_hashlib_hmac_get_name, NULL, NULL, NULL},
17947db96d56Sopenharmony_ci    {NULL}  /* Sentinel */
17957db96d56Sopenharmony_ci};
17967db96d56Sopenharmony_ci
17977db96d56Sopenharmony_ci
17987db96d56Sopenharmony_ciPyDoc_STRVAR(hmactype_doc,
17997db96d56Sopenharmony_ci"The object used to calculate HMAC of a message.\n\
18007db96d56Sopenharmony_ci\n\
18017db96d56Sopenharmony_ciMethods:\n\
18027db96d56Sopenharmony_ci\n\
18037db96d56Sopenharmony_ciupdate() -- updates the current digest with an additional string\n\
18047db96d56Sopenharmony_cidigest() -- return the current digest value\n\
18057db96d56Sopenharmony_cihexdigest() -- return the current digest as a string of hexadecimal digits\n\
18067db96d56Sopenharmony_cicopy() -- return a copy of the current hash object\n\
18077db96d56Sopenharmony_ci\n\
18087db96d56Sopenharmony_ciAttributes:\n\
18097db96d56Sopenharmony_ci\n\
18107db96d56Sopenharmony_ciname -- the name, including the hash algorithm used by this object\n\
18117db96d56Sopenharmony_cidigest_size -- number of bytes in digest() output\n");
18127db96d56Sopenharmony_ci
18137db96d56Sopenharmony_cistatic PyType_Slot HMACtype_slots[] = {
18147db96d56Sopenharmony_ci    {Py_tp_doc, (char *)hmactype_doc},
18157db96d56Sopenharmony_ci    {Py_tp_repr, (reprfunc)_hmac_repr},
18167db96d56Sopenharmony_ci    {Py_tp_dealloc,(destructor)_hmac_dealloc},
18177db96d56Sopenharmony_ci    {Py_tp_methods, HMAC_methods},
18187db96d56Sopenharmony_ci    {Py_tp_getset, HMAC_getset},
18197db96d56Sopenharmony_ci    {0, NULL}
18207db96d56Sopenharmony_ci};
18217db96d56Sopenharmony_ci
18227db96d56Sopenharmony_ciPyType_Spec HMACtype_spec = {
18237db96d56Sopenharmony_ci    "_hashlib.HMAC",    /* name */
18247db96d56Sopenharmony_ci    sizeof(HMACobject),     /* basicsize */
18257db96d56Sopenharmony_ci    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
18267db96d56Sopenharmony_ci    .slots = HMACtype_slots,
18277db96d56Sopenharmony_ci};
18287db96d56Sopenharmony_ci
18297db96d56Sopenharmony_ci
18307db96d56Sopenharmony_ci/* State for our callback function so that it can accumulate a result. */
18317db96d56Sopenharmony_citypedef struct _internal_name_mapper_state {
18327db96d56Sopenharmony_ci    PyObject *set;
18337db96d56Sopenharmony_ci    int error;
18347db96d56Sopenharmony_ci} _InternalNameMapperState;
18357db96d56Sopenharmony_ci
18367db96d56Sopenharmony_ci
18377db96d56Sopenharmony_ci/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
18387db96d56Sopenharmony_cistatic void
18397db96d56Sopenharmony_ci#if OPENSSL_VERSION_NUMBER >= 0x30000000L
18407db96d56Sopenharmony_ci_openssl_hash_name_mapper(EVP_MD *md, void *arg)
18417db96d56Sopenharmony_ci#else
18427db96d56Sopenharmony_ci_openssl_hash_name_mapper(const EVP_MD *md, const char *from,
18437db96d56Sopenharmony_ci                          const char *to, void *arg)
18447db96d56Sopenharmony_ci#endif
18457db96d56Sopenharmony_ci{
18467db96d56Sopenharmony_ci    _InternalNameMapperState *state = (_InternalNameMapperState *)arg;
18477db96d56Sopenharmony_ci    PyObject *py_name;
18487db96d56Sopenharmony_ci
18497db96d56Sopenharmony_ci    assert(state != NULL);
18507db96d56Sopenharmony_ci    // ignore all undefined providers
18517db96d56Sopenharmony_ci    if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) {
18527db96d56Sopenharmony_ci        return;
18537db96d56Sopenharmony_ci    }
18547db96d56Sopenharmony_ci
18557db96d56Sopenharmony_ci    py_name = py_digest_name(md);
18567db96d56Sopenharmony_ci    if (py_name == NULL) {
18577db96d56Sopenharmony_ci        state->error = 1;
18587db96d56Sopenharmony_ci    } else {
18597db96d56Sopenharmony_ci        if (PySet_Add(state->set, py_name) != 0) {
18607db96d56Sopenharmony_ci            state->error = 1;
18617db96d56Sopenharmony_ci        }
18627db96d56Sopenharmony_ci        Py_DECREF(py_name);
18637db96d56Sopenharmony_ci    }
18647db96d56Sopenharmony_ci}
18657db96d56Sopenharmony_ci
18667db96d56Sopenharmony_ci
18677db96d56Sopenharmony_ci/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
18687db96d56Sopenharmony_cistatic int
18697db96d56Sopenharmony_cihashlib_md_meth_names(PyObject *module)
18707db96d56Sopenharmony_ci{
18717db96d56Sopenharmony_ci    _InternalNameMapperState state = {
18727db96d56Sopenharmony_ci        .set = PyFrozenSet_New(NULL),
18737db96d56Sopenharmony_ci        .error = 0
18747db96d56Sopenharmony_ci    };
18757db96d56Sopenharmony_ci    if (state.set == NULL) {
18767db96d56Sopenharmony_ci        return -1;
18777db96d56Sopenharmony_ci    }
18787db96d56Sopenharmony_ci
18797db96d56Sopenharmony_ci#if OPENSSL_VERSION_NUMBER >= 0x30000000L
18807db96d56Sopenharmony_ci    // get algorithms from all activated providers in default context
18817db96d56Sopenharmony_ci    EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state);
18827db96d56Sopenharmony_ci#else
18837db96d56Sopenharmony_ci    EVP_MD_do_all(&_openssl_hash_name_mapper, &state);
18847db96d56Sopenharmony_ci#endif
18857db96d56Sopenharmony_ci
18867db96d56Sopenharmony_ci    if (state.error) {
18877db96d56Sopenharmony_ci        Py_DECREF(state.set);
18887db96d56Sopenharmony_ci        return -1;
18897db96d56Sopenharmony_ci    }
18907db96d56Sopenharmony_ci
18917db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "openssl_md_meth_names", state.set) < 0) {
18927db96d56Sopenharmony_ci        Py_DECREF(state.set);
18937db96d56Sopenharmony_ci        return -1;
18947db96d56Sopenharmony_ci    }
18957db96d56Sopenharmony_ci
18967db96d56Sopenharmony_ci    return 0;
18977db96d56Sopenharmony_ci}
18987db96d56Sopenharmony_ci
18997db96d56Sopenharmony_ci/*[clinic input]
19007db96d56Sopenharmony_ci_hashlib.get_fips_mode -> int
19017db96d56Sopenharmony_ci
19027db96d56Sopenharmony_ciDetermine the OpenSSL FIPS mode of operation.
19037db96d56Sopenharmony_ci
19047db96d56Sopenharmony_ciFor OpenSSL 3.0.0 and newer it returns the state of the default provider
19057db96d56Sopenharmony_ciin the default OSSL context. It's not quite the same as FIPS_mode() but good
19067db96d56Sopenharmony_cienough for unittests.
19077db96d56Sopenharmony_ci
19087db96d56Sopenharmony_ciEffectively any non-zero return value indicates FIPS mode;
19097db96d56Sopenharmony_civalues other than 1 may have additional significance.
19107db96d56Sopenharmony_ci[clinic start generated code]*/
19117db96d56Sopenharmony_ci
19127db96d56Sopenharmony_cistatic int
19137db96d56Sopenharmony_ci_hashlib_get_fips_mode_impl(PyObject *module)
19147db96d56Sopenharmony_ci/*[clinic end generated code: output=87eece1bab4d3fa9 input=2db61538c41c6fef]*/
19157db96d56Sopenharmony_ci
19167db96d56Sopenharmony_ci{
19177db96d56Sopenharmony_ci#if OPENSSL_VERSION_NUMBER >= 0x30000000L
19187db96d56Sopenharmony_ci    return EVP_default_properties_is_fips_enabled(NULL);
19197db96d56Sopenharmony_ci#else
19207db96d56Sopenharmony_ci    ERR_clear_error();
19217db96d56Sopenharmony_ci    int result = FIPS_mode();
19227db96d56Sopenharmony_ci    if (result == 0) {
19237db96d56Sopenharmony_ci        // "If the library was built without support of the FIPS Object Module,
19247db96d56Sopenharmony_ci        // then the function will return 0 with an error code of
19257db96d56Sopenharmony_ci        // CRYPTO_R_FIPS_MODE_NOT_SUPPORTED (0x0f06d065)."
19267db96d56Sopenharmony_ci        // But 0 is also a valid result value.
19277db96d56Sopenharmony_ci        unsigned long errcode = ERR_peek_last_error();
19287db96d56Sopenharmony_ci        if (errcode) {
19297db96d56Sopenharmony_ci            _setException(PyExc_ValueError, NULL);
19307db96d56Sopenharmony_ci            return -1;
19317db96d56Sopenharmony_ci        }
19327db96d56Sopenharmony_ci    }
19337db96d56Sopenharmony_ci    return result;
19347db96d56Sopenharmony_ci#endif
19357db96d56Sopenharmony_ci}
19367db96d56Sopenharmony_ci
19377db96d56Sopenharmony_ci
19387db96d56Sopenharmony_cistatic int
19397db96d56Sopenharmony_ci_tscmp(const unsigned char *a, const unsigned char *b,
19407db96d56Sopenharmony_ci        Py_ssize_t len_a, Py_ssize_t len_b)
19417db96d56Sopenharmony_ci{
19427db96d56Sopenharmony_ci    /* loop count depends on length of b. Might leak very little timing
19437db96d56Sopenharmony_ci     * information if sizes are different.
19447db96d56Sopenharmony_ci     */
19457db96d56Sopenharmony_ci    Py_ssize_t length = len_b;
19467db96d56Sopenharmony_ci    const void *left = a;
19477db96d56Sopenharmony_ci    const void *right = b;
19487db96d56Sopenharmony_ci    int result = 0;
19497db96d56Sopenharmony_ci
19507db96d56Sopenharmony_ci    if (len_a != length) {
19517db96d56Sopenharmony_ci        left = b;
19527db96d56Sopenharmony_ci        result = 1;
19537db96d56Sopenharmony_ci    }
19547db96d56Sopenharmony_ci
19557db96d56Sopenharmony_ci    result |= CRYPTO_memcmp(left, right, length);
19567db96d56Sopenharmony_ci
19577db96d56Sopenharmony_ci    return (result == 0);
19587db96d56Sopenharmony_ci}
19597db96d56Sopenharmony_ci
19607db96d56Sopenharmony_ci/* NOTE: Keep in sync with _operator.c implementation. */
19617db96d56Sopenharmony_ci
19627db96d56Sopenharmony_ci/*[clinic input]
19637db96d56Sopenharmony_ci_hashlib.compare_digest
19647db96d56Sopenharmony_ci
19657db96d56Sopenharmony_ci    a: object
19667db96d56Sopenharmony_ci    b: object
19677db96d56Sopenharmony_ci    /
19687db96d56Sopenharmony_ci
19697db96d56Sopenharmony_ciReturn 'a == b'.
19707db96d56Sopenharmony_ci
19717db96d56Sopenharmony_ciThis function uses an approach designed to prevent
19727db96d56Sopenharmony_citiming analysis, making it appropriate for cryptography.
19737db96d56Sopenharmony_ci
19747db96d56Sopenharmony_cia and b must both be of the same type: either str (ASCII only),
19757db96d56Sopenharmony_cior any bytes-like object.
19767db96d56Sopenharmony_ci
19777db96d56Sopenharmony_ciNote: If a and b are of different lengths, or if an error occurs,
19787db96d56Sopenharmony_cia timing attack could theoretically reveal information about the
19797db96d56Sopenharmony_citypes and lengths of a and b--but not their values.
19807db96d56Sopenharmony_ci[clinic start generated code]*/
19817db96d56Sopenharmony_ci
19827db96d56Sopenharmony_cistatic PyObject *
19837db96d56Sopenharmony_ci_hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
19847db96d56Sopenharmony_ci/*[clinic end generated code: output=6f1c13927480aed9 input=9c40c6e566ca12f5]*/
19857db96d56Sopenharmony_ci{
19867db96d56Sopenharmony_ci    int rc;
19877db96d56Sopenharmony_ci
19887db96d56Sopenharmony_ci    /* ASCII unicode string */
19897db96d56Sopenharmony_ci    if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
19907db96d56Sopenharmony_ci        if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
19917db96d56Sopenharmony_ci            return NULL;
19927db96d56Sopenharmony_ci        }
19937db96d56Sopenharmony_ci        if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
19947db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
19957db96d56Sopenharmony_ci                            "comparing strings with non-ASCII characters is "
19967db96d56Sopenharmony_ci                            "not supported");
19977db96d56Sopenharmony_ci            return NULL;
19987db96d56Sopenharmony_ci        }
19997db96d56Sopenharmony_ci
20007db96d56Sopenharmony_ci        rc = _tscmp(PyUnicode_DATA(a),
20017db96d56Sopenharmony_ci                    PyUnicode_DATA(b),
20027db96d56Sopenharmony_ci                    PyUnicode_GET_LENGTH(a),
20037db96d56Sopenharmony_ci                    PyUnicode_GET_LENGTH(b));
20047db96d56Sopenharmony_ci    }
20057db96d56Sopenharmony_ci    /* fallback to buffer interface for bytes, bytearray and other */
20067db96d56Sopenharmony_ci    else {
20077db96d56Sopenharmony_ci        Py_buffer view_a;
20087db96d56Sopenharmony_ci        Py_buffer view_b;
20097db96d56Sopenharmony_ci
20107db96d56Sopenharmony_ci        if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
20117db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
20127db96d56Sopenharmony_ci                         "unsupported operand types(s) or combination of types: "
20137db96d56Sopenharmony_ci                         "'%.100s' and '%.100s'",
20147db96d56Sopenharmony_ci                         Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
20157db96d56Sopenharmony_ci            return NULL;
20167db96d56Sopenharmony_ci        }
20177db96d56Sopenharmony_ci
20187db96d56Sopenharmony_ci        if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
20197db96d56Sopenharmony_ci            return NULL;
20207db96d56Sopenharmony_ci        }
20217db96d56Sopenharmony_ci        if (view_a.ndim > 1) {
20227db96d56Sopenharmony_ci            PyErr_SetString(PyExc_BufferError,
20237db96d56Sopenharmony_ci                            "Buffer must be single dimension");
20247db96d56Sopenharmony_ci            PyBuffer_Release(&view_a);
20257db96d56Sopenharmony_ci            return NULL;
20267db96d56Sopenharmony_ci        }
20277db96d56Sopenharmony_ci
20287db96d56Sopenharmony_ci        if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
20297db96d56Sopenharmony_ci            PyBuffer_Release(&view_a);
20307db96d56Sopenharmony_ci            return NULL;
20317db96d56Sopenharmony_ci        }
20327db96d56Sopenharmony_ci        if (view_b.ndim > 1) {
20337db96d56Sopenharmony_ci            PyErr_SetString(PyExc_BufferError,
20347db96d56Sopenharmony_ci                            "Buffer must be single dimension");
20357db96d56Sopenharmony_ci            PyBuffer_Release(&view_a);
20367db96d56Sopenharmony_ci            PyBuffer_Release(&view_b);
20377db96d56Sopenharmony_ci            return NULL;
20387db96d56Sopenharmony_ci        }
20397db96d56Sopenharmony_ci
20407db96d56Sopenharmony_ci        rc = _tscmp((const unsigned char*)view_a.buf,
20417db96d56Sopenharmony_ci                    (const unsigned char*)view_b.buf,
20427db96d56Sopenharmony_ci                    view_a.len,
20437db96d56Sopenharmony_ci                    view_b.len);
20447db96d56Sopenharmony_ci
20457db96d56Sopenharmony_ci        PyBuffer_Release(&view_a);
20467db96d56Sopenharmony_ci        PyBuffer_Release(&view_b);
20477db96d56Sopenharmony_ci    }
20487db96d56Sopenharmony_ci
20497db96d56Sopenharmony_ci    return PyBool_FromLong(rc);
20507db96d56Sopenharmony_ci}
20517db96d56Sopenharmony_ci
20527db96d56Sopenharmony_ci/* List of functions exported by this module */
20537db96d56Sopenharmony_ci
20547db96d56Sopenharmony_cistatic struct PyMethodDef EVP_functions[] = {
20557db96d56Sopenharmony_ci    EVP_NEW_METHODDEF
20567db96d56Sopenharmony_ci    PBKDF2_HMAC_METHODDEF
20577db96d56Sopenharmony_ci    _HASHLIB_SCRYPT_METHODDEF
20587db96d56Sopenharmony_ci    _HASHLIB_GET_FIPS_MODE_METHODDEF
20597db96d56Sopenharmony_ci    _HASHLIB_COMPARE_DIGEST_METHODDEF
20607db96d56Sopenharmony_ci    _HASHLIB_HMAC_SINGLESHOT_METHODDEF
20617db96d56Sopenharmony_ci    _HASHLIB_HMAC_NEW_METHODDEF
20627db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_MD5_METHODDEF
20637db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA1_METHODDEF
20647db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA224_METHODDEF
20657db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA256_METHODDEF
20667db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA384_METHODDEF
20677db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA512_METHODDEF
20687db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA3_224_METHODDEF
20697db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA3_256_METHODDEF
20707db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA3_384_METHODDEF
20717db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHA3_512_METHODDEF
20727db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHAKE_128_METHODDEF
20737db96d56Sopenharmony_ci    _HASHLIB_OPENSSL_SHAKE_256_METHODDEF
20747db96d56Sopenharmony_ci    {NULL,      NULL}            /* Sentinel */
20757db96d56Sopenharmony_ci};
20767db96d56Sopenharmony_ci
20777db96d56Sopenharmony_ci
20787db96d56Sopenharmony_ci/* Initialize this module. */
20797db96d56Sopenharmony_ci
20807db96d56Sopenharmony_cistatic int
20817db96d56Sopenharmony_cihashlib_traverse(PyObject *m, visitproc visit, void *arg)
20827db96d56Sopenharmony_ci{
20837db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(m);
20847db96d56Sopenharmony_ci    Py_VISIT(state->EVPtype);
20857db96d56Sopenharmony_ci    Py_VISIT(state->HMACtype);
20867db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
20877db96d56Sopenharmony_ci    Py_VISIT(state->EVPXOFtype);
20887db96d56Sopenharmony_ci#endif
20897db96d56Sopenharmony_ci    Py_VISIT(state->constructs);
20907db96d56Sopenharmony_ci    Py_VISIT(state->unsupported_digestmod_error);
20917db96d56Sopenharmony_ci    return 0;
20927db96d56Sopenharmony_ci}
20937db96d56Sopenharmony_ci
20947db96d56Sopenharmony_cistatic int
20957db96d56Sopenharmony_cihashlib_clear(PyObject *m)
20967db96d56Sopenharmony_ci{
20977db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(m);
20987db96d56Sopenharmony_ci    Py_CLEAR(state->EVPtype);
20997db96d56Sopenharmony_ci    Py_CLEAR(state->HMACtype);
21007db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
21017db96d56Sopenharmony_ci    Py_CLEAR(state->EVPXOFtype);
21027db96d56Sopenharmony_ci#endif
21037db96d56Sopenharmony_ci    Py_CLEAR(state->constructs);
21047db96d56Sopenharmony_ci    Py_CLEAR(state->unsupported_digestmod_error);
21057db96d56Sopenharmony_ci
21067db96d56Sopenharmony_ci    if (state->hashtable != NULL) {
21077db96d56Sopenharmony_ci        _Py_hashtable_destroy(state->hashtable);
21087db96d56Sopenharmony_ci        state->hashtable = NULL;
21097db96d56Sopenharmony_ci    }
21107db96d56Sopenharmony_ci
21117db96d56Sopenharmony_ci    return 0;
21127db96d56Sopenharmony_ci}
21137db96d56Sopenharmony_ci
21147db96d56Sopenharmony_cistatic void
21157db96d56Sopenharmony_cihashlib_free(void *m)
21167db96d56Sopenharmony_ci{
21177db96d56Sopenharmony_ci    hashlib_clear((PyObject *)m);
21187db96d56Sopenharmony_ci}
21197db96d56Sopenharmony_ci
21207db96d56Sopenharmony_ci/* Py_mod_exec functions */
21217db96d56Sopenharmony_cistatic int
21227db96d56Sopenharmony_cihashlib_init_hashtable(PyObject *module)
21237db96d56Sopenharmony_ci{
21247db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
21257db96d56Sopenharmony_ci
21267db96d56Sopenharmony_ci    state->hashtable = py_hashentry_table_new();
21277db96d56Sopenharmony_ci    if (state->hashtable == NULL) {
21287db96d56Sopenharmony_ci        PyErr_NoMemory();
21297db96d56Sopenharmony_ci        return -1;
21307db96d56Sopenharmony_ci    }
21317db96d56Sopenharmony_ci    return 0;
21327db96d56Sopenharmony_ci}
21337db96d56Sopenharmony_ci
21347db96d56Sopenharmony_cistatic int
21357db96d56Sopenharmony_cihashlib_init_evptype(PyObject *module)
21367db96d56Sopenharmony_ci{
21377db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
21387db96d56Sopenharmony_ci
21397db96d56Sopenharmony_ci    state->EVPtype = (PyTypeObject *)PyType_FromSpec(&EVPtype_spec);
21407db96d56Sopenharmony_ci    if (state->EVPtype == NULL) {
21417db96d56Sopenharmony_ci        return -1;
21427db96d56Sopenharmony_ci    }
21437db96d56Sopenharmony_ci    if (PyModule_AddType(module, state->EVPtype) < 0) {
21447db96d56Sopenharmony_ci        return -1;
21457db96d56Sopenharmony_ci    }
21467db96d56Sopenharmony_ci    return 0;
21477db96d56Sopenharmony_ci}
21487db96d56Sopenharmony_ci
21497db96d56Sopenharmony_cistatic int
21507db96d56Sopenharmony_cihashlib_init_evpxoftype(PyObject *module)
21517db96d56Sopenharmony_ci{
21527db96d56Sopenharmony_ci#ifdef PY_OPENSSL_HAS_SHAKE
21537db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
21547db96d56Sopenharmony_ci
21557db96d56Sopenharmony_ci    if (state->EVPtype == NULL) {
21567db96d56Sopenharmony_ci        return -1;
21577db96d56Sopenharmony_ci    }
21587db96d56Sopenharmony_ci
21597db96d56Sopenharmony_ci    state->EVPXOFtype = (PyTypeObject *)PyType_FromSpecWithBases(
21607db96d56Sopenharmony_ci        &EVPXOFtype_spec, (PyObject *)state->EVPtype
21617db96d56Sopenharmony_ci    );
21627db96d56Sopenharmony_ci    if (state->EVPXOFtype == NULL) {
21637db96d56Sopenharmony_ci        return -1;
21647db96d56Sopenharmony_ci    }
21657db96d56Sopenharmony_ci    if (PyModule_AddType(module, state->EVPXOFtype) < 0) {
21667db96d56Sopenharmony_ci        return -1;
21677db96d56Sopenharmony_ci    }
21687db96d56Sopenharmony_ci#endif
21697db96d56Sopenharmony_ci    return 0;
21707db96d56Sopenharmony_ci}
21717db96d56Sopenharmony_ci
21727db96d56Sopenharmony_cistatic int
21737db96d56Sopenharmony_cihashlib_init_hmactype(PyObject *module)
21747db96d56Sopenharmony_ci{
21757db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
21767db96d56Sopenharmony_ci
21777db96d56Sopenharmony_ci    state->HMACtype = (PyTypeObject *)PyType_FromSpec(&HMACtype_spec);
21787db96d56Sopenharmony_ci    if (state->HMACtype == NULL) {
21797db96d56Sopenharmony_ci        return -1;
21807db96d56Sopenharmony_ci    }
21817db96d56Sopenharmony_ci    if (PyModule_AddType(module, state->HMACtype) < 0) {
21827db96d56Sopenharmony_ci        return -1;
21837db96d56Sopenharmony_ci    }
21847db96d56Sopenharmony_ci    return 0;
21857db96d56Sopenharmony_ci}
21867db96d56Sopenharmony_ci
21877db96d56Sopenharmony_cistatic int
21887db96d56Sopenharmony_cihashlib_init_constructors(PyObject *module)
21897db96d56Sopenharmony_ci{
21907db96d56Sopenharmony_ci    /* Create dict from builtin openssl_hash functions to name
21917db96d56Sopenharmony_ci     * {_hashlib.openssl_sha256: "sha256", ...}
21927db96d56Sopenharmony_ci     */
21937db96d56Sopenharmony_ci    PyModuleDef *mdef;
21947db96d56Sopenharmony_ci    PyMethodDef *fdef;
21957db96d56Sopenharmony_ci    PyObject *proxy;
21967db96d56Sopenharmony_ci    PyObject *func, *name_obj;
21977db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
21987db96d56Sopenharmony_ci
21997db96d56Sopenharmony_ci    mdef = PyModule_GetDef(module);
22007db96d56Sopenharmony_ci    if (mdef == NULL) {
22017db96d56Sopenharmony_ci        return -1;
22027db96d56Sopenharmony_ci    }
22037db96d56Sopenharmony_ci
22047db96d56Sopenharmony_ci    state->constructs = PyDict_New();
22057db96d56Sopenharmony_ci    if (state->constructs == NULL) {
22067db96d56Sopenharmony_ci        return -1;
22077db96d56Sopenharmony_ci    }
22087db96d56Sopenharmony_ci
22097db96d56Sopenharmony_ci    for (fdef = mdef->m_methods; fdef->ml_name != NULL; fdef++) {
22107db96d56Sopenharmony_ci        if (strncmp(fdef->ml_name, "openssl_", 8)) {
22117db96d56Sopenharmony_ci            continue;
22127db96d56Sopenharmony_ci        }
22137db96d56Sopenharmony_ci        name_obj = PyUnicode_FromString(fdef->ml_name + 8);
22147db96d56Sopenharmony_ci        if (name_obj == NULL) {
22157db96d56Sopenharmony_ci            return -1;
22167db96d56Sopenharmony_ci        }
22177db96d56Sopenharmony_ci        func  = PyObject_GetAttrString(module, fdef->ml_name);
22187db96d56Sopenharmony_ci        if (func == NULL) {
22197db96d56Sopenharmony_ci            Py_DECREF(name_obj);
22207db96d56Sopenharmony_ci            return -1;
22217db96d56Sopenharmony_ci        }
22227db96d56Sopenharmony_ci        int rc = PyDict_SetItem(state->constructs, func, name_obj);
22237db96d56Sopenharmony_ci        Py_DECREF(func);
22247db96d56Sopenharmony_ci        Py_DECREF(name_obj);
22257db96d56Sopenharmony_ci        if (rc < 0) {
22267db96d56Sopenharmony_ci            return -1;
22277db96d56Sopenharmony_ci        }
22287db96d56Sopenharmony_ci    }
22297db96d56Sopenharmony_ci
22307db96d56Sopenharmony_ci    proxy = PyDictProxy_New(state->constructs);
22317db96d56Sopenharmony_ci    if (proxy == NULL) {
22327db96d56Sopenharmony_ci        return -1;
22337db96d56Sopenharmony_ci    }
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_ci    int rc = PyModule_AddObjectRef(module, "_constructors", proxy);
22367db96d56Sopenharmony_ci    Py_DECREF(proxy);
22377db96d56Sopenharmony_ci    if (rc < 0) {
22387db96d56Sopenharmony_ci        return -1;
22397db96d56Sopenharmony_ci    }
22407db96d56Sopenharmony_ci    return 0;
22417db96d56Sopenharmony_ci}
22427db96d56Sopenharmony_ci
22437db96d56Sopenharmony_cistatic int
22447db96d56Sopenharmony_cihashlib_exception(PyObject *module)
22457db96d56Sopenharmony_ci{
22467db96d56Sopenharmony_ci    _hashlibstate *state = get_hashlib_state(module);
22477db96d56Sopenharmony_ci    state->unsupported_digestmod_error = PyErr_NewException(
22487db96d56Sopenharmony_ci        "_hashlib.UnsupportedDigestmodError", PyExc_ValueError, NULL);
22497db96d56Sopenharmony_ci    if (state->unsupported_digestmod_error == NULL) {
22507db96d56Sopenharmony_ci        return -1;
22517db96d56Sopenharmony_ci    }
22527db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(module, "UnsupportedDigestmodError",
22537db96d56Sopenharmony_ci                              state->unsupported_digestmod_error) < 0) {
22547db96d56Sopenharmony_ci        return -1;
22557db96d56Sopenharmony_ci    }
22567db96d56Sopenharmony_ci    return 0;
22577db96d56Sopenharmony_ci}
22587db96d56Sopenharmony_ci
22597db96d56Sopenharmony_ci
22607db96d56Sopenharmony_cistatic PyModuleDef_Slot hashlib_slots[] = {
22617db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_init_hashtable},
22627db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_init_evptype},
22637db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_init_evpxoftype},
22647db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_init_hmactype},
22657db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_md_meth_names},
22667db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_init_constructors},
22677db96d56Sopenharmony_ci    {Py_mod_exec, hashlib_exception},
22687db96d56Sopenharmony_ci    {0, NULL}
22697db96d56Sopenharmony_ci};
22707db96d56Sopenharmony_ci
22717db96d56Sopenharmony_cistatic struct PyModuleDef _hashlibmodule = {
22727db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
22737db96d56Sopenharmony_ci    .m_name = "_hashlib",
22747db96d56Sopenharmony_ci    .m_doc = "OpenSSL interface for hashlib module",
22757db96d56Sopenharmony_ci    .m_size = sizeof(_hashlibstate),
22767db96d56Sopenharmony_ci    .m_methods = EVP_functions,
22777db96d56Sopenharmony_ci    .m_slots = hashlib_slots,
22787db96d56Sopenharmony_ci    .m_traverse = hashlib_traverse,
22797db96d56Sopenharmony_ci    .m_clear = hashlib_clear,
22807db96d56Sopenharmony_ci    .m_free = hashlib_free
22817db96d56Sopenharmony_ci};
22827db96d56Sopenharmony_ci
22837db96d56Sopenharmony_ciPyMODINIT_FUNC
22847db96d56Sopenharmony_ciPyInit__hashlib(void)
22857db96d56Sopenharmony_ci{
22867db96d56Sopenharmony_ci    return PyModuleDef_Init(&_hashlibmodule);
22877db96d56Sopenharmony_ci}
2288