From 036e808bce992da3f0500ce6b53ca518e50d4ea1 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Wed, 24 Apr 2024 14:47:10 +0100 Subject: [PATCH] [3.9] gh-118224: Load default OpenSSL provider for nonsecurity algorithms When OpenSSL is configured to only load "base+fips" providers into the Null library context, md5 might not be available at all. In such cases currently CPython fallsback to internal hashlib implementation is there is one - as there might not be if one compiles python with --with-builtin-hashlib-hashes=blake2. With this change "default" provider is attempted to be loaded to access nonsecurity hashes. --- .../2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst | 1 + Modules/_hashopenssl.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst diff --git a/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst b/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst new file mode 100644 index 00000000000000..c63b71ecbafc58 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2024-04-24-16-58-45.gh-issue-118224.wnjFHn.rst @@ -0,0 +1 @@ +Hashlib now supports using default OpenSSL provider instead of builtin fallback for nonsecurity hashes on hosts otherwise only using base and fips providers. This makes build configuration ``--with-builtin-hashlib-hashes=blake2`` fully supported on OpenSSL FIPS hosts. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 4db058c06275ff..ef0e34438d89c6 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -90,6 +90,7 @@ HMAC_CTX_get_md(const HMAC_CTX *ctx) #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include #define PY_EVP_MD EVP_MD #define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties) #define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md) @@ -262,6 +263,17 @@ typedef struct { _Py_hashtable_t *hashtable; } _hashlibstate; +static void try_load_default_provider(void) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + /* Load the default config file, and expected providers */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (!OSSL_PROVIDER_available(NULL, "default")) { + /* System is configured without the default provider */ + OSSL_PROVIDER_load(NULL, "default"); + } +#endif +} + static inline _hashlibstate* get_hashlib_state(PyObject *module) { @@ -392,6 +404,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) break; case Py_ht_evp_nosecurity: if (entry->evp_nosecurity == NULL) { + try_load_default_provider(); entry->evp_nosecurity = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); } digest = entry->evp_nosecurity; @@ -409,6 +422,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) digest = PY_EVP_MD_fetch(name, NULL); break; case Py_ht_evp_nosecurity: + try_load_default_provider(); digest = PY_EVP_MD_fetch(name, "-fips"); break; }