Skip to content
61 changes: 36 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ labels.

## randbytes

The randbytes test does 10000 calls of the [RAND_bytes()](https://docs.openssl.org/master/man3/RAND_bytes/) function divided
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.
1000 [`RAND_bytes()`](https://docs.openssl.org/master/man3/RAND_bytes/) calls.

## handshake

Expand Down Expand Up @@ -79,65 +79,76 @@ calls.

## newrawkey

The `newrawkey` test repeatedly calls the [EVP_PKEY_new_raw_public_key_ex()](https://docs.openssl.org/master/man3/EVP_PKEY_new/)
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/)
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/)
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.
[`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
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.
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.
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.
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
`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:
The `pkeyread` test benchmarks reading of private keys of the specified type
in the specified format. If PEM format is specified (`-f pem`),
the [`PEM_read_bio_PrivateKey()`](https://docs.openssl.org/master/man3/PEM_read_bio_PrivateKey/)
function is called repeatedly on a memory BIO with a private key
of desired type; in case of DER format specification (`-f der`),
[`d2i_PrivateKey_ex()`](https://docs.openssl.org/master/man3/d2i_PrivateKey/)
is called repeatedly to read private key of the desired type.
The calls are performed repeatedly until the timeout (specified in the `-T`
option, 5 seconds by default) is reached.
The number of threads to use is provided by the only positional option.
By default, the test reports average time per call. If `-t` ("terse output")
option is specified, only the number is printed, without key type and format.
If `-v` ("verbose") option is specified, additional information is printed
for each run: median, minimum, maximum time among threads, as well as standard
deviation.
If `-b` ("bind") option is provided, thread affinity is set to the threads
so the available cores are assigned in a round robin manner.
The mandatory option `-k` selects the key type for benchmark. The list of keys
for testing is as follows: dh, dhx, dsa, ec, rsa, x25519. To run benchmark
for all keys and formats using 4 threads, run `pkeyread` as follows:

```sh
./pkeyread -f all -k all -t 4
./pkeyread -f all -k all 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
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`
Expand All @@ -152,8 +163,8 @@ evp_setpeer as follows:
## 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
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:

```
Expand All @@ -169,7 +180,7 @@ 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 creates two threads, one for client the
[`SSL_poll()`](https://docs.openssl.org/master/man3/SSL_poll/). Application creates two threads, one for client the
other for server. Server and client can both accept/create simultanous
connections. Each connection then can carry multiple unidirectional/bidirectional
streams. The streams handle HTTP/1.0 GET request/responses only.
Expand Down
14 changes: 8 additions & 6 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ if(WIN32)
target_sources(perf PRIVATE perflib/getopt.c perflib/basename.c perflib/err.c)
endif()

if(WIN32)
set(libm_dep)
else()
set(libm_dep PUBLIC m)
endif()

target_include_directories(perf PUBLIC "${PROJECT_SOURCE_DIR}")
target_link_libraries(perf PUBLIC OpenSSL::SSL OpenSSL::Crypto)

Expand Down Expand Up @@ -154,17 +160,13 @@ add_executable(rsasign rsasign.c)
target_link_libraries(rsasign PRIVATE perf)

add_executable(x509storeissuer x509storeissuer.c)
target_link_libraries(x509storeissuer PRIVATE perf)
target_link_libraries(x509storeissuer ${libm_dep} PRIVATE perf)

add_executable(rwlocks rwlocks.c)
target_link_libraries(rwlocks PRIVATE perf)

add_executable(pkeyread pkeyread.c)
if(WIN32)
target_link_libraries(pkeyread PRIVATE perf)
else()
target_link_libraries(pkeyread PUBLIC m PRIVATE perf)
endif()
target_link_libraries(pkeyread ${libm_dep} PRIVATE perf)

add_executable(evp_setpeer evp_setpeer.c)
target_link_libraries(evp_setpeer PRIVATE perf)
Expand Down
54 changes: 52 additions & 2 deletions source/perflib/err.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,50 @@
* https://www.openssl.org/source/license.html
*/

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

const char *progname;

static ossl_inline void *
get_progname(void)
{
if (progname != NULL)
return progname;

#if defined(__GLIBC__)
if (program_invocation_name && program_invocation_name[0])
return program_invocation_name;
#endif

return NULL;
}

void
vwarnx(const char *fmt, va_list ap)
{
if (progname != NULL)
fprintf(stderr, "%s: ", progname);
if (get_progname() != NULL)
fprintf(stderr, "%s: ", get_progname());
vfprintf(stderr, fmt, ap);
putc('\n', stderr);
}

void
vwarn(const char *fmt, va_list ap)
{
int saved_errno = errno;

if (get_progname() != NULL)
fprintf(stderr, "%s: ", get_progname());
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": ");

errno = saved_errno;
perror(NULL);
}

void
errx(int status, const char *fmt, ...)
{
Expand All @@ -33,6 +62,17 @@ errx(int status, const char *fmt, ...)
exit(status);
}

void
err(int status, const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
exit(status);
}

void
warnx(const char *fmt, ...)
{
Expand All @@ -42,3 +82,13 @@ warnx(const char *fmt, ...)
vwarnx(fmt, ap);
va_end(ap);
}

void
warn(const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
vwarn(fmt, ap);
va_end(ap);
}
38 changes: 37 additions & 1 deletion source/perflib/err.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,49 @@
# define OSSL_PERFLIB_ERR_H
# pragma once

#include <stdarg.h>
# include <stdio.h>

# if !defined(_WIN32)

# include <err.h>

# else /* _WIN32 */

# include <stdarg.h>

extern const char *progname;

extern void vwarnx(const char *, va_list);
extern void vwarn(const char *, va_list);

extern void errx(int, const char *, ...);
extern void err(int, const char *, ...);

extern void warnx(const char *, ...);
extern void warn(const char *, ...);

# endif /* !_WIN32 */

# define WARN(...) \
do { \
fprintf(stderr, "%s:%d(%s): ", __FILE__, __LINE__, __FUNCTION__); \
warn(__VA_ARGS__); \
} while (0)
# define WARNX(...) \
do { \
fprintf(stderr, "%s:%d(%s): ", __FILE__, __LINE__, __FUNCTION__); \
warnx(__VA_ARGS__); \
} while (0)
# define ERR(...) \
do { \
fprintf(stderr, "%s:%d(%s): ", __FILE__, __LINE__, __FUNCTION__); \
err(__VA_ARGS__); \
} while (0)
# define ERRX(...) \
do { \
fprintf(stderr, "%s:%d(%s): ", __FILE__, __LINE__, __FUNCTION__); \
errx(__VA_ARGS__); \
} while (0)

#endif

27 changes: 1 addition & 26 deletions source/perflib/perfhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <string.h>
#include <openssl/crypto.h>
#include <openssl/macros.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
Expand All @@ -31,29 +32,3 @@ char *perflib_mk_file_path(const char *dir, const char *file)

return full_file;
}

/*
* Glue an array of strings together and return it as an allocated string.
* Optionally return the whole length of this string in |out_len|
*/
char *perflib_glue_strings(const char *list[], size_t *out_len)
{
size_t len = 0;
char *p, *ret;
int i;

for (i = 0; list[i] != NULL; i++)
len += strlen(list[i]);

if (out_len != NULL)
*out_len = len;

ret = p = OPENSSL_malloc(len + 1);
if (p == NULL)
return NULL;

for (i = 0; list[i] != NULL; i++)
p += strlen(strcpy(p, list[i]));

return ret;
}
Loading
Loading