mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-28 01:28:05 -04:00
Use thread_local EVP_MD_CTX in isc_iterated_hash()
As this code is on hot path (NSEC3) this introduces an additional optimization of the EVP_MD API - instead of calling EVP_MD_CTX_new() on every call to isc_iterated_hash(), we create two thread_local objects for each thread - a basectx and mdctx, initialize basectx once and then use EVP_MD_CTX_copy_ex() to flip the initialized state into mdctx. This saves us couple more valuable microseconds from the isc_iterated_hash() call.
This commit is contained in:
parent
25db8d0103
commit
f3753d591f
4 changed files with 71 additions and 13 deletions
|
|
@ -35,4 +35,13 @@ isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
|
|||
const int saltlength, const unsigned char *in,
|
||||
const int inlength);
|
||||
|
||||
/*
|
||||
* Private
|
||||
*/
|
||||
|
||||
void
|
||||
isc__iterated_hash_initialize(void);
|
||||
void
|
||||
isc__iterated_hash_shutdown(void);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -65,26 +65,39 @@ isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
|
|||
return (SHA_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
isc__iterated_hash_initialize(void) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
void
|
||||
isc__iterated_hash_shutdown(void) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
#else /* HAVE_SHA1_INIT */
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <isc/md.h>
|
||||
|
||||
static thread_local bool initialized = false;
|
||||
static thread_local EVP_MD_CTX *mdctx = NULL;
|
||||
static thread_local EVP_MD_CTX *basectx = NULL;
|
||||
|
||||
int
|
||||
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
|
||||
const int iterations, const unsigned char *salt,
|
||||
const int saltlength, const unsigned char *in,
|
||||
const int inlength) {
|
||||
REQUIRE(out != NULL);
|
||||
REQUIRE(mdctx != NULL);
|
||||
REQUIRE(basectx != NULL);
|
||||
|
||||
int n = 0;
|
||||
size_t len;
|
||||
unsigned int outlength = 0;
|
||||
const unsigned char *buf;
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
|
||||
|
||||
RUNTIME_CHECK(ctx != NULL);
|
||||
|
||||
if (hashalg != 1) {
|
||||
return (0);
|
||||
|
|
@ -92,21 +105,20 @@ isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
|
|||
|
||||
buf = in;
|
||||
len = inlength;
|
||||
|
||||
do {
|
||||
if (EVP_DigestInit_ex(ctx, ISC_MD_SHA1, NULL) != 1) {
|
||||
if (EVP_MD_CTX_copy_ex(mdctx, basectx) != 1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (EVP_DigestUpdate(ctx, buf, len) != 1) {
|
||||
if (EVP_DigestUpdate(mdctx, buf, len) != 1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (EVP_DigestUpdate(ctx, salt, saltlength) != 1) {
|
||||
if (EVP_DigestUpdate(mdctx, salt, saltlength) != 1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (EVP_DigestFinal_ex(ctx, out, &outlength) != 1) {
|
||||
if (EVP_DigestFinal_ex(mdctx, out, &outlength) != 1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -114,13 +126,41 @@ isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
|
|||
len = outlength;
|
||||
} while (n++ < iterations);
|
||||
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
return (outlength);
|
||||
|
||||
fail:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
void
|
||||
isc__iterated_hash_initialize(void) {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
basectx = EVP_MD_CTX_new();
|
||||
INSIST(basectx != NULL);
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
INSIST(mdctx != NULL);
|
||||
|
||||
RUNTIME_CHECK(EVP_DigestInit_ex(basectx, ISC_MD_SHA1, NULL) == 1);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void
|
||||
isc__iterated_hash_shutdown(void) {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE(mdctx != NULL);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
mdctx = NULL;
|
||||
REQUIRE(basectx != NULL);
|
||||
EVP_MD_CTX_free(basectx);
|
||||
basectx = NULL;
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SHA1_INIT */
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
/*! \file */
|
||||
|
||||
#include <isc/bind9.h>
|
||||
#include <isc/iterated_hash.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
|
|
@ -51,11 +52,13 @@ isc__initialize(void) {
|
|||
isc__uv_initialize();
|
||||
isc__xml_initialize();
|
||||
isc__md_initialize();
|
||||
isc__iterated_hash_initialize();
|
||||
(void)isc_os_ncpus();
|
||||
}
|
||||
|
||||
void
|
||||
isc__shutdown(void) {
|
||||
isc__iterated_hash_shutdown();
|
||||
isc__md_shutdown();
|
||||
isc__xml_shutdown();
|
||||
isc__uv_shutdown();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/iterated_hash.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/thread.h>
|
||||
|
|
@ -194,9 +196,13 @@ isc__trampoline_run(isc_threadarg_t arg) {
|
|||
|
||||
isc__trampoline_attach(trampoline);
|
||||
|
||||
isc__iterated_hash_initialize();
|
||||
|
||||
/* Run the main function */
|
||||
result = (trampoline->start)(trampoline->arg);
|
||||
|
||||
isc__iterated_hash_shutdown();
|
||||
|
||||
isc__trampoline_detach(trampoline);
|
||||
|
||||
return (result);
|
||||
|
|
|
|||
Loading…
Reference in a new issue