Merge branch '3795-speed-up-EVP_DigestInit_ex-v9_18' into 'v9_18'

[9.18] Avoid implicit algorithm fetch for OpenSSL EVP_MD family

See merge request isc-projects/bind9!7398
This commit is contained in:
Ondřej Surý 2023-01-18 23:33:53 +00:00
commit adfa48ed39
3 changed files with 95 additions and 28 deletions

View file

@ -1,3 +1,9 @@
6072. [bug] Avoid the OpenSSL lock contention when initializing
Message Digest Contexts by using explicit algorithm
fetching, initializing static contexts for every
supported algorithms, and initializing the new context
by copying the static copy. [GL #3795]
6069. [bug] Detach from the view in zone_shutdown() to
release the memory held by the dead view
early. [GL #3801]

View file

@ -39,6 +39,9 @@ Bug Fixes
cause increased memory consumption due to delayed cleaning of view memory.
This has been fixed. :gl:`#3801`
- Improve the speed of the message digest algorithms (MD5, SHA-1,
SHA-2) and NSEC3 hashing. :gl:`#3795`
Known Issues
~~~~~~~~~~~~

View file

@ -13,64 +13,122 @@
#include <stdio.h>
#include <openssl/opensslv.h>
#include <isc/iterated_hash.h>
#include <isc/md.h>
#include <isc/util.h>
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
#include <openssl/sha.h>
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) {
isc_md_t *md;
isc_result_t result;
REQUIRE(out != NULL);
int n = 0;
unsigned int outlength = 0;
size_t len;
const unsigned char *buf;
REQUIRE(out != NULL);
SHA_CTX ctx;
if (hashalg != 1) {
return (0);
}
if ((md = isc_md_new()) == NULL) {
buf = in;
len = inlength;
do {
if (SHA1_Init(&ctx) != 1) {
return (0);
}
if (SHA1_Update(&ctx, buf, len) != 1) {
return (0);
}
if (SHA1_Update(&ctx, salt, saltlength) != 1) {
return (0);
}
if (SHA1_Final(out, &ctx) != 1) {
return (0);
}
buf = out;
len = SHA_DIGEST_LENGTH;
} while (n++ < iterations);
return (SHA_DIGEST_LENGTH);
}
#else
#include <openssl/evp.h>
#include <isc/md.h>
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);
int n = 0;
size_t len;
unsigned int outlength = 0;
const unsigned char *buf;
EVP_MD_CTX *ctx;
;
EVP_MD *md;
if (hashalg != 1) {
return (0);
}
len = inlength;
ctx = EVP_MD_CTX_new();
RUNTIME_CHECK(ctx != NULL);
md = EVP_MD_fetch(NULL, "SHA1", NULL);
RUNTIME_CHECK(md != NULL);
buf = in;
len = inlength;
do {
result = isc_md_init(md, ISC_MD_SHA1);
if (result != ISC_R_SUCCESS) {
goto md_fail;
if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
goto fail;
}
result = isc_md_update(md, buf, len);
if (result != ISC_R_SUCCESS) {
goto md_fail;
if (EVP_DigestUpdate(ctx, buf, len) != 1) {
goto fail;
}
result = isc_md_update(md, salt, saltlength);
if (result != ISC_R_SUCCESS) {
goto md_fail;
if (EVP_DigestUpdate(ctx, salt, saltlength) != 1) {
goto fail;
}
result = isc_md_final(md, out, &outlength);
if (result != ISC_R_SUCCESS) {
goto md_fail;
}
result = isc_md_reset(md);
if (result != ISC_R_SUCCESS) {
goto md_fail;
if (EVP_DigestFinal_ex(ctx, out, &outlength) != 1) {
goto fail;
}
buf = out;
len = outlength;
} while (n++ < iterations);
isc_md_free(md);
EVP_MD_CTX_free(ctx);
EVP_MD_free(md);
return (outlength);
md_fail:
isc_md_free(md);
fail:
EVP_MD_CTX_free(ctx);
EVP_MD_free(md);
return (0);
}
#undef RETERR
#endif