]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Avoid implicit algorithm fetch for OpenSSL EVP_MD family
authorOndřej Surý <ondrej@isc.org>
Mon, 16 Jan 2023 08:16:35 +0000 (09:16 +0100)
committerOndřej Surý <ondrej@isc.org>
Wed, 18 Jan 2023 17:32:57 +0000 (18:32 +0100)
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.

lib/isc/include/isc/md.h
lib/isc/lib.c
lib/isc/md.c

index f52424b3b8d669526749fafb117ca171565fb3d5..2c7213db49e1b787af42efbddf6bbe3da78b9724 100644 (file)
@@ -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);
index a04352622cf0571730f381139ba5215ae3d08a6b..33c874906d3549fa32ba0e18b8c573e8a3cef0f4 100644 (file)
@@ -14,6 +14,7 @@
 /*! \file */
 
 #include <isc/bind9.h>
+#include <isc/md.h>
 #include <isc/mem.h>
 #include <isc/os.h>
 #include <isc/tls.h>
@@ -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();
index d094cfa0ecb3563a4318591954229f49ff295443..725fef04c7c3c9e65bf457f25524d8454e88600b 100644 (file)
@@ -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 */