# perftools **Repository Path**: mirrors_openssl/perftools ## Basic Information - **Project Name**: perftools - **Description**: Performance testing tools - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-07-05 - **Last Updated**: 2026-06-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OpenSSL performance testing tools This directory holds tools for carrying out performance tests on OpenSSL. The various performance test applications are held within this directory, and various helper files are held in perflib. The performance test applications are intended to be linked against a supported OpenSSL version, e.g. 3.1, 3.0, 1.1.1 - which is the version of OpenSSL that is to be tested. Typically we would expect the apps to be built multiple times (once for each target OpenSSL version to be tested). ## Build To build the tests we assume that the target OpenSSL has already been built. ```sh cmake -S . -B -DOPENSSL_ROOT_DIR= cmake --build --config Release ``` ## Run The performance testing apps must be run ensuring that `libcrypto.so` and `libssl.so` are on the library path. For example: ```sh LD_LIBRARY_PATH= ./randbytes 10 ``` Each performance testing app will take different parameters. They are described individually below. All performance testing apps take the `--terse` option which has the affect of just printing bare performance numbers without any labels. ## randbytes The randbytes test does 10000 calls of the [RAND_bytes()](https://docs.openssl.org/master/man3/RAND_bytes/) function divided evenly among multiple threads. The number of threads to use is provided as an argument and the test reports the average time take to execute a block of 1000 [RAND_bytes()](https://docs.openssl.org/master/man3/RAND_bytes/) calls. ## handshake Performs a combined in-memory client and server handshake. In total 100000 handshakes are performed divided evenly among each thread. It take 2 optional and two required arguments: ``` handshake [-t] [-s] [-f] -t - produce terse output -s - create an ssl_ctx per connection, rather than a single thread-shared ctx -p - use ossl_lib_ctx per thread -P - use ossl_lib_ctx pool (can be combined with -s. If sharing is enabled, ssl_ctx is shared within single thread) -o - set ossl_lib_ctx pool size (use only with -P) -l - use ssl_ctx pool certsdir - Directory where the test can locate servercert.pem and serverkey.pem threadcount - Number of concurrent threads to run in test ``` The output is two values: the average time taken for a single handshake in us, and the average number of simultaneous handshakes per second performed over the course of the test. Note: Note on OpenSSL earlier than 3.6 you might hit the thread key local storage limit with higher number of threads. ## sslnew The `sslnew` test repeatedly constructs a new SSL object and associates it with a newly constructed read BIO and a newly constructed write BIO, and finally frees them again. It does 100000 repetitions divided evenly among each thread. The number of threads to use is provided as an argument and the test reports the average time taken to execute a block of 1000 construction/free calls. ## newrawkey The `newrawkey` test repeatedly calls the [EVP_PKEY_new_raw_public_key_ex()](https://docs.openssl.org/master/man3/EVP_PKEY_new/) function. It does 100000 repetitions divided evenly among each thread. The number of threads to use is provided as an argument and the test reports the average time take to execute a block of 1000 [EVP_PKEY_new_raw_public_key_ex()](https://docs.openssl.org/master/man3/EVP_PKEY_new/) calls. Note that this test does not support OpenSSL 1.1.1. ## rsasign The `rsasign` test repeatedly calls the [EVP_PKEY_sign_init()/EVP_PKEY_sign()](https://docs.openssl.org/master/man3/EVP_PKEY_sign/) functions, using a 512 bit RSA key. It does 100000 repetitions divided evenly among each thread. The number of threads to use is provided as an argument and the test reports the average time take to execute a block of 1000 [EVP_PKEY_sign_init()/EVP_PKEY_sign()](https://docs.openssl.org/master/man3/EVP_PKEY_sign/) calls. ## x509storeissuer Runs the function call [X509_STORE_CTX_get1_issuer()](https://docs.openssl.org/master/man3/X509_STORE_set_verify_cb_func/) repeatedly in a loop (which is used in certificate chain building as part of a verify operation). The test assumes that the default certificates directly exists but is empty. For a default configuration this is "/usr/local/ssl/certs". The test takes the number of threads to use as an argument and the test reports the average time take to execute a block of 1000 [X509_STORE_CTX_get1_issuer()](https://docs.openssl.org/master/man3/X509_STORE_set_verify_cb_func/) calls. ## providerdoall The `providerdoall` test repeatedly calls the [OSSL_PROVIDER_do_all()](https://docs.openssl.org/master/man3/OSSL_PROVIDER) function. It does 100000 repetitions divided evenly among each thread. The number of threads to use is provided as an argument and the test reports the average time take to execute a block of 1000 [OSSL_PROVIDER_do_all()](https://docs.openssl.org/master/man3/OSSL_PROVIDER) calls. ## rwlocks The `rwlocks` test creates the command line specified number of threads, splitting them evenly between read and write functions (though this is adjustable via the LOCK_WRITERS environment variable). Threads then iteratively acquire a shared rwlock to read or update some shared data. The number of read and write lock/unlock pairs are reported as a performance measurement ## pkeyread The `pkeyread` test repeatedly calls the [PEM_read_bio_PrivateKey()](https://docs.openssl.org/master/man3/PEM_read_bio_PrivateKey/) function on a memory BIO with a private key of desired type, when it is running in pem mode (-f pem). If test is running in der mode (-f der) it calls to [d2i_PrivateKey_ex()](https://docs.openssl.org/master/man3/d2i_PrivateKey/) function to repeatedly read private key of desired type. It does 10000 repetitions divided evenly among each thread. The number of threads to use is provided by option `-t`. The test reports average time per call. Use option `-k` to select key type for benchmark. The list of keys for testing is as follows: dh, dhx, dsa, ec, rsa, xkey. To run benchmark for all keys and formats using 4 threads run pkeyread as follows: ```sh ./pkeyread -f all -k all -t 4 ``` ## evp_setpeer The `evp_setpeer` test repeatedly calls the [EVP_PKEY_derive_set_peer()](https://docs.openssl.org/master/man3/EVP_PKEY_derive/) function on a memory BIO with a private key of desired type. It does 10000 repetitions divided evenly among each thread. The last argument will be the number of threads run. The test reports average time per call. Use option `-k` to select key type for benchmark. The list of keys for testing is as follows: dh, ec256, ec521, x25519. To run benchmark for all keys using 4 threads, run evp_setpeer as follows: ```sh ./evp_setpeer -k all -t 4 ``` ## writeread Performs an in-memory client and server handshake and measures the average time taken for a single sequence of calling [SSL_write_ex()](https://docs.openssl.org/master/man3/SSL_write/) on the client and [SSL_write_ex()](https://docs.openssl.org/master/man3/SSL_write/) on the server. In total 1000000 writes and reads are performed divided evenly among each thread. It take 4 optional and 2 required arguments: ``` writeread [-t] [-s] [-d] [-b size] -t - produce terse output. -s - create an ssl_ctx per connection, rather than a single thread-shared ctx. -d - use DTLS as connection method. -b - size of buffer to write and read, default is 1024 bytes. certsdir - directory where the test can locate servercert.pem and serverkey.pem. threadcount - number of concurrent threads to run in test. ``` ## ssl_poll_perf Tool to evaluate performance of QUIC client and server which both use [SSL_poll](https://docs.openssl.org/master/man3/SSL_poll/)(3ossl). Application runs in self-test mode by default. In self-test mode two threads are created, one for client the other for server. Server and client can both accept/create simultaneous connections. Each connection then can carry multiple unidirectional/bidirectional streams. The streams handle HTTP/1.0 GET request/responses only. Server always drains the incoming stream initiated by client. It answers to any GET request. The default reply is 200 OK with 12345 bytes of payload. Client may request desired payload with URL as follows: ``` /any/path/to_8192whatever/foo_4096.txt ``` In which case the server will send response with 8kB http/1.0 body. The URL parser attempts to find leftmost number, which denotes the number of bytes client expects in response. To run client in standalone mode use command as follows: ``` ./ssl_poll_perf -m c -a 0 -c 10 -b 1 -u 0 http://your_server:port/desired_url ``` Command above runs http/0.9 client which creates 10 concurrent connections, each connection uses 1 bi-directional stream to send URL-request to desired server. Similarly one one can use command here to run standalone server: ``` ./ssl_poll_perf -p 8080 -m s -a 0 servercert.pem serverkey.pem ``` Command above runs http/0.9 server at port 8080. You need to specify server's certificate and key. The test program supports options as follows: ``` -c - number of connections to create (default 10) -b - number of bidirectional streams each connection creates (default 10) -u - number of unidirectional streams each connection creates (default 10) -s - the size of reply body, the maximum size is 100MB. The default size is 64. -w - the size of request body, the maximum size is 100MB. The default size is 64. -p - port number to use -t - terse output -m - mode {client|server} (option also accepts short variant 'c' or 's'), self-test mode when ommitted -a - alpn {0|1} (0 = http/0.9, 1 = http/1.0), default is http/1.0 ``` ## evp_hash Tool that computes hashes using the specified algorithm. Runs for 5 seconds and prints the average execution time per hash. Prints out the average time per hash computation. Three modes of operation: - deprecated: Use deprecated, legacy API's to do hash (e.g. SHA1_Init) - evp_isolated: Use EVP API and don't allow shared data between threads - evp_shared (default): Use EVP API and allow shared data between threads ``` Usage: evp_hash [-h] [-t] [-f] [-o operation] [-u update-times] [-a algorithm] thread-count -h - print this help output -t - terse output -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) thread-count - number of threads ``` ```sh 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) -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. Runs for 5 seconds and prints the average execution time per encryption. Two modes of operation: - evp_isolated: Use EVP API and don't allow shared data between threads - evp_shared (default): Use EVP API and allow shared data between threads ``` Usage: evp_cipher [-h] [-t] [-f] [-o operation] [-u update-times] [-a algorithm] thread-count -h - print this help output -t - terse output -o operation - mode of operation. One of [evp_isolated, evp_shared] (default: evp_shared) -u update-times - times to update (default: 1) -a algorithm - One of: [AES-128-CBC, AES-256-CBC] (default: AES-128-CBC) thread-count - number of threads ``` ```sh evp_cipher -a AES-128-CBC -o evp_isolated 10 ``` ## evp_mac Tool that computes an HMAC of random data using SHA-256 digest. Runs for 5 seconds and prints the average execution time per computation. Four modes of operation: - evp_shared (default): Use EVP API and allow shared data between computations - evp_isolated: Use EVP API and don't allow shared data between computations - deprecated_shared: Use legacy API and allow shared data between computations - deprecated_isolated: Use legacy API and don't allow shared data between computations ``` Usage: evp_mac [-h] [-t] [-o operation] [-u update-times] [-V] thread-count -h - print this help output -t - terse output -o operation - mode of operation. One of [evp_isolated, evp_shared, deprecated_isolated, deprecated_shared] (default: evp_shared) -u update-times - times to update (default: 1) -V - print version information and exit thread-count - number of threads ``` ```sh evp_mac -o evp_shared 10 ``` ## evp_kdf This CLI tool derives keys from random data with SHA-256 digest. Runs for 5 seconds and prints the average execution time per computation. Four modes of operation: - evp_shared (default): Use EVP API and allow shared data between computations - evp_isolated: Use EVP API and don't allow shared data between computations - deprecated_shared: Use legacy API and allow shared data between computations - deprecated_isolated: Use legacy API and don't allow shared data between computations ``` Usage: evp_kdf [-h] [-t] [-f] [-o operation] [-V] thread-count -h - print this help output -t - terse output -o operation - mode of operation. One of [evp_isolated, evp_shared, deprecated_isolated, deprecated_shared] (default: evp_shared) -V - print version information and exit thread-count - number of threads ``` ```sh ./evp_kdf -o evp_shared 10 ``` ## evp_rand This CLI tool generates random data with HASH-DRGB. Runs for 5 seconds and prints the average execution time per computation. Two modes of operation: - evp_shared (default): Use EVP API and allow shared data between computations - evp_isolated: Use EVP API and don't allow shared data between computations ``` Usage: evp_rand [-h] [-t] [-f] [-o operation] [-V] thread-count -h - print this help output -t - terse output -o operation - mode of operation. One of [evp_isolated, evp_shared] (default: evp_shared) -V - print version information and exit thread-count - number of threads ``` ```sh ./evp_rand -o evp_shared 10 ``` ## evp_pkey This CLI tool that generates keys using a given algorithm. Runs for 5 seconds and prints the average execution time per key generation. Two modes of operation: - evp_shared (default): Use EVP API and allow shared data between computations - evp_isolated: Use EVP API and don't allow shared data between computations ``` Usage: evp_pkey [-h] [-t] [-o operation] [-V] thread-count -h - print this help output -t - terse output -o operation - mode of operation. One of [evp_isolated, evp_shared] (default: evp_shared) -a algorithm - algorithm for generated key. One of [RSA, X25519, X448, ED25519, ED448] (default: ED25519) -V - print version information and exit thread-count - number of threads ``` ```sh ./evp_pkey -o evp_shared -a RSA 10 ```