aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdutils
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2025-04-05 23:30:55 +0300
committerlevlam <levlam@telegram.org>2025-04-05 23:30:55 +0300
commit4303aacceb599d2b0bbaa2a2c4ab110869f95bef (patch)
treedb350c5570f82cc8ef5a07ebf87dc90c20388018 /tdutils
parent9e53edda0f74f696e66bdc6fe768b9028d0eec2d (diff)
Optimize HMAC OpenSSL 3 implementation.
Diffstat (limited to 'tdutils')
-rw-r--r--tdutils/td/utils/crypto.cpp51
-rw-r--r--tdutils/td/utils/simple_tests.h2
2 files changed, 36 insertions, 17 deletions
diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp
index 844a1ef15..bbaef2466 100644
--- a/tdutils/td/utils/crypto.cpp
+++ b/tdutils/td/utils/crypto.cpp
@@ -752,6 +752,22 @@ static void init_thread_local_evp_md_ctx(const EVP_MD_CTX *&evp_md_ctx, const ch
evp_md_ctx = nullptr;
}));
}
+
+static void init_thread_local_evp_mac_ctx(EVP_MAC_CTX *&evp_mac_ctx, const char *digest) {
+ EVP_MAC *hmac = EVP_MAC_fetch(nullptr, "HMAC", nullptr);
+ LOG_IF(FATAL, hmac == nullptr);
+ evp_mac_ctx = EVP_MAC_CTX_new(hmac);
+ LOG_IF(FATAL, evp_mac_ctx == nullptr);
+ OSSL_PARAM params[2];
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, const_cast<char *>(digest), 0);
+ params[1] = OSSL_PARAM_construct_end();
+ EVP_MAC_CTX_set_params(evp_mac_ctx, params);
+ EVP_MAC_free(hmac);
+ detail::add_thread_local_destructor(create_destructor([&evp_mac_ctx]() mutable {
+ EVP_MAC_CTX_free(const_cast<EVP_MAC_CTX *>(evp_mac_ctx));
+ evp_mac_ctx = nullptr;
+ }));
+}
#endif
void sha1(Slice data, unsigned char output[20]) {
@@ -967,26 +983,29 @@ void pbkdf2_sha512(Slice password, Slice salt, int iteration_count, MutableSlice
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
-static void hmac_impl(const char *digest, Slice key, Slice message, MutableSlice dest) {
- EVP_MAC *hmac = EVP_MAC_fetch(nullptr, "HMAC", nullptr);
- LOG_IF(FATAL, hmac == nullptr);
-
- EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(hmac);
- LOG_IF(FATAL, ctx == nullptr);
-
- OSSL_PARAM params[2];
- params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, const_cast<char *>(digest), 0);
- params[1] = OSSL_PARAM_construct_end();
-
- int res = EVP_MAC_init(ctx, const_cast<unsigned char *>(key.ubegin()), key.size(), params);
+static void hmac_impl_finish(EVP_MAC_CTX *ctx, Slice key, Slice message, MutableSlice dest) {
+ int res = EVP_MAC_init(ctx, const_cast<unsigned char *>(key.ubegin()), key.size(), nullptr);
LOG_IF(FATAL, res != 1);
res = EVP_MAC_update(ctx, message.ubegin(), message.size());
LOG_IF(FATAL, res != 1);
res = EVP_MAC_final(ctx, dest.ubegin(), nullptr, dest.size());
LOG_IF(FATAL, res != 1);
+}
- EVP_MAC_CTX_free(ctx);
- EVP_MAC_free(hmac);
+static void hmac_impl_sha256(Slice key, Slice message, MutableSlice dest) {
+ static TD_THREAD_LOCAL EVP_MAC_CTX *ctx = nullptr;
+ if (ctx == nullptr) {
+ init_thread_local_evp_mac_ctx(ctx, "SHA256");
+ }
+ hmac_impl_finish(ctx, key, message, dest);
+}
+
+static void hmac_impl_sha512(Slice key, Slice message, MutableSlice dest) {
+ static TD_THREAD_LOCAL EVP_MAC_CTX *ctx = nullptr;
+ if (ctx == nullptr) {
+ init_thread_local_evp_mac_ctx(ctx, "SHA512");
+ }
+ hmac_impl_finish(ctx, key, message, dest);
}
#else
static void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSlice dest) {
@@ -1001,7 +1020,7 @@ static void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSli
void hmac_sha256(Slice key, Slice message, MutableSlice dest) {
CHECK(dest.size() == 256 / 8);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- hmac_impl("SHA256", key, message, dest);
+ hmac_impl_sha256(key, message, dest);
#else
hmac_impl(EVP_sha256(), key, message, dest);
#endif
@@ -1010,7 +1029,7 @@ void hmac_sha256(Slice key, Slice message, MutableSlice dest) {
void hmac_sha512(Slice key, Slice message, MutableSlice dest) {
CHECK(dest.size() == 512 / 8);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- hmac_impl("SHA512", key, message, dest);
+ hmac_impl_sha512(key, message, dest);
#else
hmac_impl(EVP_sha512(), key, message, dest);
#endif
diff --git a/tdutils/td/utils/simple_tests.h b/tdutils/td/utils/simple_tests.h
index ba390389d..a232f2aa5 100644
--- a/tdutils/td/utils/simple_tests.h
+++ b/tdutils/td/utils/simple_tests.h
@@ -95,7 +95,7 @@ class StatusTest : public Test {
LOG(INFO) << "Test " << get_test_name() << " PASSED";
} else {
// Include debug context in error message if available
- LOG(ERROR) << "Test " << get_test_name() << " FAILED: " << status.message()
+ LOG(FATAL) << "Test " << get_test_name() << " FAILED: " << status.message()
<< simple_test::DebugContext::instance();
}
}