From d3d470952d3f6f4dd96ad5bd5ffa1dccd4d334b5 Mon Sep 17 00:00:00 2001 From: Nikola Pajkovsky Date: Wed, 25 Feb 2026 09:46:40 +0100 Subject: [PATCH] evp_fetch: add freeze option $ ./evp_fetch -f CIPHER:AES-128-GCM 64 -F Average time per fetch call: 1.244238us $ ./evp_fetch -f CIPHER:AES-128-GCM 64 Average time per fetch call: 23.303556us ./evp_fetch -f MD:SHA2-256 64 -F Average time per fetch call: 1.197693us $ ./evp_fetch -f MD:SHA2-256 64 Average time per fetch call: 24.295191us Signed-off-by: Nikola Pajkovsky --- README.md | 31 +++++++++++++++++++++++++++++++ source/CMakeLists.txt | 6 +++++- source/evp_fetch.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 62761d1e..e3697ea5 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,37 @@ thread-count - number of threads evp_hash -u 10 -a SHA512 -o evp_isolated 15 ``` +## evp_fetch + +Tool that measures the cost of [EVP_*_fetch()](https://docs.openssl.org/master/man3/EVP_MD_fetch/) calls. +Runs for 5 seconds and prints the average execution time per fetch. + +By default it cycles over a built-in list of TYPE:ALGORITHM combinations. You can +limit the run to one combination using `-f TYPE:ALGORITHM` or by setting the +`EVP_FETCH_TYPE` environment variable. + +``` +Usage: evp_fetch [-t] [-f TYPE:ALGORITHM] [-V] [-q] [-F] threadcount +-t - terse output +-f - fetch only the specified algorithm +-q - include post-quantum algorithms (available with OpenSSL >= 3.5 and PQ enabled) +-F - freeze context (available only with openssl >= 4.x.x) +-V - print version information and exit +threadcount - number of threads +``` + +Environment variables: + +``` +EVP_FETCH_TYPE - if no -f option is provided, fetch only the specified TYPE:ALGORITHM +``` +```sh +./evp_fetch 4 +./evp_fetch -f CIPHER:AES-256-GCM 4 +EVP_FETCH_TYPE=MD:SHA3-256 ./evp_fetch 4 +./evp_fetch -q 4 +``` + ## evp_cipher Tool that encrypts random data using the specified algorithm. diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index b1bc82bf..8dc79099 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -262,6 +262,9 @@ set(run_add_version_dep ON set(run_evp_fetch_pqs evp_fetch "" "" "-q" CACHE STRING "Post-quantum option for evp_fetch") +set(run_evp_fetch_freeze + evp_fetch "" "" "-F" + CACHE STRING "Freeze LIB_CTX for evp_fetch") set(run_evp_hash_operations evp_hash "" "" "-o deprecated" "-o evp_isolated" "-o evp_shared" CACHE STRING "Modes of operation for evp_hash") @@ -363,7 +366,8 @@ set(run_opts run_evp_fetch_pqs if(HAVE_OSSL_LIB_CTX_FREEZE) list(APPEND run_opts run_evp_hash_freeze run_evp_cipher_freeze - run_evp_rand_freeze) + run_evp_rand_freeze + run_evp_fetch_freeze) endif() # Used across multiple tests diff --git a/source/evp_fetch.c b/source/evp_fetch.c index 3ec64083..851e2a84 100644 --- a/source/evp_fetch.c +++ b/source/evp_fetch.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include "config.h" #include #include #include @@ -38,6 +39,16 @@ # define PQ_USAGE_DESC "" #endif +#ifdef HAVE_OSSL_LIB_CTX_FREEZE +#define FREEZE_GETOPT "F" +#define FREEZE_USAGE_OPT " [-F]" +#define FREEZE_USAGE_DESC "-F - freeze context\n" +#else +#define FREEZE_GETOPT "" +#define FREEZE_USAGE_OPT "" +#define FREEZE_USAGE_DESC "" +#endif + #define RUN_TIME 5 /* @@ -290,11 +301,12 @@ void do_fetch(size_t num) static void usage(const char *progname) { - printf("Usage: %s [-t] [-f TYPE:ALGORITHM]" PQ_USAGE_OPT " [-V]" + printf("Usage: %s [-t] [-f TYPE:ALGORITHM]" PQ_USAGE_OPT " [-V]" FREEZE_USAGE_OPT " threadcount\n" "-t - terse output\n" "-f - fetch only the specified algorithm\n" PQ_USAGE_DESC + FREEZE_USAGE_DESC "-V - print version information and exit\n" "\nEnvironment variables:\n" " EVP_FETCH_TYPE - if no -f option is provided, fetch only\n" @@ -321,9 +333,17 @@ int main(int argc, char *argv[]) int rc = EXIT_FAILURE; char *fetch_type = getenv("EVP_FETCH_TYPE"); int opt; +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + int freeze = 0; +#endif - while ((opt = getopt(argc, argv, "tf:" PQ_GETOPT "V")) != -1) { + while ((opt = getopt(argc, argv, "tf:" PQ_GETOPT "V" FREEZE_GETOPT)) != -1) { switch (opt) { +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + case 'F': + freeze = 1; + break; +#endif case 't': terse = 1; break; @@ -381,6 +401,15 @@ int main(int argc, char *argv[]) if (ctx == NULL) return EXIT_FAILURE; +#ifdef HAVE_OSSL_LIB_CTX_FREEZE + if (freeze) { + if (OSSL_LIB_CTX_freeze(ctx, NULL) == 0) { + fprintf(stderr, "Freezing LIB CTX failed\n"); + goto out; + } + } +#endif + counts = OPENSSL_malloc(sizeof(size_t) * threadcount); if (counts == NULL) { printf("Failed to create counts array\n");