From: Ondřej Surý Date: Mon, 16 Jan 2023 08:16:35 +0000 (+0100) Subject: Avoid implicit algorithm fetch for OpenSSL EVP_MD family X-Git-Tag: v9.19.10~34^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e6bfb8e45626e58a1cca687c798ee00973bf26d3;p=thirdparty%2Fbind9.git Avoid implicit algorithm fetch for OpenSSL EVP_MD family The implicit algorithm fetch causes a lock contention and significant slowdown for small input buffers. For more details, see: https://github.com/openssl/openssl/issues/19612 Instead of using EVP_DigestInit_ex() initialize empty MD_CTX objects for each algorithm and use EVP_MD_CTX_copy_ex() to initialize MD_CTX from a static copy. Additionally avoid implicit algorithm fetching by using EVP_MD_fetch() for OpenSSL 3.0. --- diff --git a/lib/isc/include/isc/md.h b/lib/isc/include/isc/md.h index f52424b3b8d..2c7213db49e 100644 --- a/lib/isc/include/isc/md.h +++ b/lib/isc/include/isc/md.h @@ -37,25 +37,19 @@ typedef void isc_md_t; */ typedef void isc_md_type_t; -#define ISC_MD_MD5 isc__md_md5() -#define ISC_MD_SHA1 isc__md_sha1() -#define ISC_MD_SHA224 isc__md_sha224() -#define ISC_MD_SHA256 isc__md_sha256() -#define ISC_MD_SHA384 isc__md_sha384() -#define ISC_MD_SHA512 isc__md_sha512() - -const isc_md_type_t * -isc__md_md5(void); -const isc_md_type_t * -isc__md_sha1(void); -const isc_md_type_t * -isc__md_sha224(void); -const isc_md_type_t * -isc__md_sha256(void); -const isc_md_type_t * -isc__md_sha384(void); -const isc_md_type_t * -isc__md_sha512(void); +extern const isc_md_type_t *isc__md_md5; +extern const isc_md_type_t *isc__md_sha1; +extern const isc_md_type_t *isc__md_sha224; +extern const isc_md_type_t *isc__md_sha256; +extern const isc_md_type_t *isc__md_sha384; +extern const isc_md_type_t *isc__md_sha512; + +#define ISC_MD_MD5 isc__md_md5 +#define ISC_MD_SHA1 isc__md_sha1 +#define ISC_MD_SHA224 isc__md_sha224 +#define ISC_MD_SHA256 isc__md_sha256 +#define ISC_MD_SHA384 isc__md_sha384 +#define ISC_MD_SHA512 isc__md_sha512 #define ISC_MD5_DIGESTLENGTH isc_md_type_get_size(ISC_MD_MD5) #define ISC_MD5_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_MD5) @@ -202,3 +196,13 @@ isc_md_type_get_size(const isc_md_type_t *md_type); */ size_t isc_md_type_get_block_size(const isc_md_type_t *md_type); + +/** + * Private + */ + +void +isc__md_initialize(void); + +void +isc__md_shutdown(void); diff --git a/lib/isc/lib.c b/lib/isc/lib.c index a04352622cf..33c874906d3 100644 --- a/lib/isc/lib.c +++ b/lib/isc/lib.c @@ -14,6 +14,7 @@ /*! \file */ #include +#include #include #include #include @@ -49,11 +50,13 @@ isc__initialize(void) { isc__trampoline_initialize(); isc__uv_initialize(); isc__xml_initialize(); + isc__md_initialize(); (void)isc_os_ncpus(); } void isc__shutdown(void) { + isc__md_shutdown(); isc__xml_shutdown(); isc__uv_shutdown(); isc__trampoline_shutdown(); diff --git a/lib/isc/md.c b/lib/isc/md.c index d094cfa0ecb..725fef04c7c 100644 --- a/lib/isc/md.c +++ b/lib/isc/md.c @@ -164,12 +164,56 @@ end: return (res); } -#define md_register_algorithm(alg) \ - const isc_md_type_t *isc__md_##alg(void) { return (EVP_##alg()); } - -md_register_algorithm(md5); -md_register_algorithm(sha1); -md_register_algorithm(sha224); -md_register_algorithm(sha256); -md_register_algorithm(sha384); -md_register_algorithm(sha512); +#ifndef UNIT_TESTING +const isc_md_type_t *isc__md_md5 = NULL; +const isc_md_type_t *isc__md_sha1 = NULL; +const isc_md_type_t *isc__md_sha224 = NULL; +const isc_md_type_t *isc__md_sha256 = NULL; +const isc_md_type_t *isc__md_sha384 = NULL; +const isc_md_type_t *isc__md_sha512 = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#define md_register_algorithm(alg, algname) \ + { \ + REQUIRE(isc__md_##alg == NULL); \ + isc__md_##alg = EVP_MD_fetch(NULL, algname, NULL); \ + RUNTIME_CHECK(isc__md_##alg != NULL); \ + } + +#define md_unregister_algorithm(alg) \ + { \ + REQUIRE(isc__md_##alg != NULL); \ + EVP_MD_free(*(isc_md_type_t **)&isc__md_##alg); \ + isc__md_##alg = NULL; \ + } + +#else +#define md_register_algorithm(alg, algname) \ + { \ + isc__md_##alg = EVP_##alg(); \ + RUNTIME_CHECK(isc__md_##alg != NULL); \ + } +#define md_unregister_algorithm(alg) +#endif + +void +isc__md_initialize(void) { + md_register_algorithm(md5, "MD5"); + md_register_algorithm(sha1, "SHA1"); + md_register_algorithm(sha224, "SHA224"); + md_register_algorithm(sha256, "SHA256"); + md_register_algorithm(sha384, "SHA384"); + md_register_algorithm(sha512, "SHA512"); +} + +void +isc__md_shutdown(void) { + md_unregister_algorithm(sha512); + md_unregister_algorithm(sha384); + md_unregister_algorithm(sha256); + md_unregister_algorithm(sha224); + md_unregister_algorithm(sha1); + md_unregister_algorithm(md5); +} + +#endif /* UNIT_TESTING */