From 1a1fe9e267fddc45f80ca53c5516bceeee3deb69 Mon Sep 17 00:00:00 2001 From: Nikola Pajkovsky Date: Thu, 12 Feb 2026 11:49:09 +0100 Subject: [PATCH 1/2] evp_hash: add freeze option $ ./evp_hash -o evp_isolated -a SHA1 64 Average time per hash: 20.361076us $ ./evp_hash -o evp_isolated -a SHA1 64 -f Average time per hash: 4.336028us Fixes https://github.com/openssl/project/issues/1728 Signed-off-by: Nikola Pajkovsky --- README.md | 1 + source/CMakeLists.txt | 15 +++++++++++++++ source/config.h.in | 4 ++++ source/evp_hash.c | 29 ++++++++++++++++++++++++++++- 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 source/config.h.in diff --git a/README.md b/README.md index 5227a958..2f29283e 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,7 @@ Three modes of operation: Usage: evp_hash [-h] [-t] [-o operation] [-u update-times] [-a algorithm] thread-count -h - print this help output -t - terse output +-f - freeze default context (available only with openssl >= 4.x.x) -o operation - mode of operation. One of [deprecated, evp_isolated, evp_shared] (default: evp_shared) -u update-times - times to update digest. 1 for one-shot (default: 1) -a algorithm - One of: [SHA1, SHA224, SHA256, SHA384, SHA512] (default: SHA1) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a71d58f6..25e15008 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -116,6 +116,7 @@ cmake_minimum_required(VERSION 3.10) project(perf-tools) +include(CheckSymbolExists) if(WIN32) set(CFLAGS_WARNINGS "/Wall" CACHE STRING "Compiler options for warnings") @@ -153,6 +154,8 @@ endif() target_include_directories(perf PUBLIC "${PROJECT_SOURCE_DIR}") target_link_libraries(perf PUBLIC OpenSSL::SSL OpenSSL::Crypto) +set(CMAKE_REQUIRED_LIBRARIES OpenSSL::Crypto) +set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") if( OPENSSL_VERSION VERSION_GREATER_EQUAL 3 ) add_executable(evp_fetch evp_fetch.c) @@ -163,6 +166,8 @@ if( OPENSSL_VERSION VERSION_GREATER_EQUAL 3 ) endif() +check_symbol_exists(OSSL_LIB_CTX_freeze "openssl/crypto.h" HAVE_OSSL_LIB_CTX_FREEZE) + if( OPENSSL_VERSION VERSION_GREATER_EQUAL 3.6 ) add_executable(ssl_poll_perf ssl_poll_perf.c) if(WIN32) @@ -260,6 +265,9 @@ set(run_evp_hash_update_times set(run_evp_hash_algorithms evp_hash "" "" "-a SHA1" "-a SHA224" "-a SHA256" "-a SHA384" "-a SHA512" CACHE STRING "Digest hash algorithms for evp_hash") +set(run_evp_hash_freeze + evp_hash "" "" "-f" + CACHE STRING "Freeze LIB_CTX for evp_hash") set(run_evp_cipher_operations evp_cipher "" "" "-o evp_isolated" "-o evp_shared" CACHE STRING "Modes of operation for evp_cipher") @@ -332,6 +340,10 @@ set(run_opts run_evp_fetch_pqs run_writeread_buffers CACHE STRING "List of per-text options") +if(HAVE_OSSL_LIB_CTX_FREEZE) + list(APPEND run_opts run_evp_hash_freeze) +endif() + # Used across multiple tests set(run_certdir_tests handshake writeread x509storeissuer CACHE STRING "List of tests that require certdir parameter") @@ -378,6 +390,9 @@ if (WIN32) endforeach() endif() +# Generate config.h from config.h.in +configure_file(config.h.in ${CMAKE_SOURCE_DIR}/config.h) + # # gen_run_target( [VAR ] [NAME ]) # diff --git a/source/config.h.in b/source/config.h.in new file mode 100644 index 00000000..80bc9ea4 --- /dev/null +++ b/source/config.h.in @@ -0,0 +1,4 @@ +/* config.h.in */ + +/* Define to 1 if you have the `OSSL_LIB_CTX_freeze' function. */ +#cmakedefine HAVE_OSSL_LIB_CTX_FREEZE diff --git a/source/evp_hash.c b/source/evp_hash.c index 80d6ee52..f3305f46 100644 --- a/source/evp_hash.c +++ b/source/evp_hash.c @@ -15,6 +15,7 @@ #define OPENSSL_SUPPRESS_DEPRECATED +#include "config.h" #include #include #ifndef _WIN32 @@ -248,9 +249,16 @@ static void do_hash_evp_shared(size_t num) static void print_help() { +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + printf("Usage: evp_hash [-h] [-t] [-f] [-o operation] [-u update-times] [-a algorithm] [-V] thread-count\n"); +#else printf("Usage: evp_hash [-h] [-t] [-o operation] [-u update-times] [-a algorithm] [-V] thread-count\n"); +#endif printf("-h - print this help output\n"); printf("-t - terse output\n"); +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + printf("-f - freeze default context\n"); +#endif printf("-o operation - mode of operation. One of [deprecated, evp_isolated, evp_shared] (default: evp_shared)\n"); printf("-u update-times - times to update digest. 1 for one-shot (default: 1)\n"); printf("-a algorithm - One of: [SHA1, SHA224, SHA256, SHA384, SHA512] (default: SHA1)\n"); @@ -265,9 +273,19 @@ int main(int argc, char *argv[]) double av; int terse = 0, operation = EVP_SHARED, hash_algorithm = SHA1_ALG; int j, opt, rc = EXIT_FAILURE; + char *getopt_options = "hto:u:a:V"; +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + int freeze = 0; + getopt_options = "hto:u:a:Vf"; +#endif - while ((opt = getopt(argc, argv, "hto:u:a:V")) != -1) { + while ((opt = getopt(argc, argv, getopt_options)) != -1) { switch (opt) { +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + case 'f': + freeze = 1; + break; +#endif case 't': terse = 1; break; @@ -345,6 +363,15 @@ int main(int argc, char *argv[]) max_time = ossl_time_add(ossl_time_now(), ossl_seconds2time(RUN_TIME)); +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + if (freeze) { + if (OSSL_LIB_CTX_freeze(NULL, NULL) == 0) { + fprintf(stderr, "Freezing LIB CTX failed\n"); + goto out; + } + } +#endif + switch (operation) { case DEPRECATED: switch (hash_algorithm) { From 4e1557a3716d706d9d7706965664add0174c5160 Mon Sep 17 00:00:00 2001 From: Nikola Pajkovsky Date: Fri, 13 Feb 2026 12:55:29 +0100 Subject: [PATCH 2/2] fixup! evp_hash: add freeze option --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f29283e..1df56dbd 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ Three modes of operation: - evp_shared (default): Use EVP API and allow shared data between threads ``` -Usage: evp_hash [-h] [-t] [-o operation] [-u update-times] [-a algorithm] thread-count +Usage: evp_hash [-h] [-t] [-f] [-o operation] [-u update-times] [-a algorithm] thread-count -h - print this help output -t - terse output -f - freeze default context (available only with openssl >= 4.x.x)