Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ssl_ctx test #196

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions perf/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
all: randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch
all: randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch ssl_ctx
# Build target for OpenSSL 1.1.1 builds
all111: randbytes handshake sslnew newrawkey rsasign x509storeissuer rwlocks pkeyread

clean:
rm -f libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch
rm -f libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall rwlocks pkeyread evp_fetch ssl_ctx

CPPFLAGS += -I$(TARGET_OSSL_INCLUDE_PATH) -I.
# For second include path, i.e. out of tree build of OpenSSL uncomment this:
Expand All @@ -17,6 +17,9 @@ libperf.a: perflib/*.c perflib/*.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c perflib/*.c
ar rcs libperf.a *.o

ssl_ctx: ssl_ctx.c libperf.a
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o ssl_ctx ssl_ctx.c -lperf -lcrypto -lssl

evp_fetch: evp_fetch.c libperf.a
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o evp_fetch evp_fetch.c -lperf -lcrypto

Expand Down
17 changes: 17 additions & 0 deletions perf/README
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@ 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.

ssl_ctx
-------

The ssl_ctx test repeatedly constructs either a client or sever SSL_CTX
object, initializing it appropriately (setting a cert/key for the server, or a
cert store for the client), measuring how long each iteration takes.

Usage:
./ssl_ctx -m [server|client] -c <cert> -k <key> -s <store> <threadcount>

Options:
* -m [server|client] - Selects client or server mode of operation
* -c <cert> - The path to the PEM encoded server certificate
* -k <key> - The path to the PEM encoded server private key
* -s <store> - The path to the client certificate store dir
* -t - Terse output

newrawkey
---------

Expand Down
181 changes: 181 additions & 0 deletions perf/ssl_ctx.c
nhorman marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include "perflib/perflib.h"

#define NUM_CTX_PER_RUN 100000

int err = 0;

OSSL_TIME *times;
static char *certpath = NULL;
static char *keypath = NULL;
static char *storepath = NULL;

static int threadcount;
static int adj_ctx_per_run = 0;

typedef enum {
OP_SERVER,
OP_CLIENT
} op_mode;

op_mode mode = OP_SERVER;

static void do_create_ctx(size_t num)
{
int i;
SSL_CTX *ctx = NULL;
OSSL_TIME start, end;

start = ossl_time_now();

for (i = 0; i < adj_ctx_per_run / threadcount; i++) {
ctx = SSL_CTX_new(mode == OP_SERVER ? TLS_server_method() :
TLS_client_method());
if (ctx == NULL)
goto out;
if (mode == OP_SERVER) {
if ((SSL_CTX_use_certificate_file(ctx, certpath,
SSL_FILETYPE_PEM) != 1) ||
(SSL_CTX_use_PrivateKey_file(ctx, keypath,
SSL_FILETYPE_PEM) != 1)) {
err = 1;
nhorman marked this conversation as resolved.
Show resolved Hide resolved
goto out;
}
} else {
if (SSL_CTX_load_verify_dir(ctx, storepath) != 1) {
err = 1;
goto out;
}
}
SSL_CTX_free(ctx);
}

out:
end = ossl_time_now();
times[num] = ossl_time_subtract(end, start);
}

static void usage(char *name)
{
fprintf(stderr, "usage\n");
fprintf(stderr, "%s [-m <server|client>] [-c <cert>] [-k <key>] [-s <store>] <threadcount> \n", name);
fprintf(stderr, "-m <server|client> - create a client or server method in context\n");
fprintf(stderr, "-c <cert> - path to certificate for server context\n");
fprintf(stderr, "-k <key> - path to key for server context\n");
fprintf(stderr, "-s <store> - path to cert store for client context\n");
}

int main(int argc, char *argv[])
{
OSSL_TIME duration, ttime;
uint64_t us;
double avcalltime;
int ret = EXIT_FAILURE;
int i;
int terse = 0;
int ch = 0;

while ((ch = getopt(argc, argv, "tm:c:k:s:")) != -1) {
switch(ch) {
case 'm':
if (!strcmp(optarg, "server")) {
mode = OP_SERVER;
} else if (!strcmp(optarg, "client")) {
mode = OP_CLIENT;
} else {
printf("-m must select one of client|server\n");
usage(argv[0]);
}
break;
case 'c':
certpath = optarg;
break;
case 'k':
keypath = optarg;
break;
case 's':
storepath = optarg;
break;
case 't':
terse = 1;
break;
default:
usage(argv[0]);
exit(1);
}
}

if (argv[optind] == NULL) {
printf("Missing threadcount argument\n");
usage(argv[0]);
goto err;
}

threadcount = atoi(argv[optind]);
if (threadcount < 1) {
printf("threadcount must be > 0\n");
goto err;
}

nhorman marked this conversation as resolved.
Show resolved Hide resolved
/* Adjust the number of iterations so we divide evenly among threads */
adj_ctx_per_run = (NUM_CTX_PER_RUN / threadcount) * threadcount;

if (mode == OP_SERVER) {
if (certpath == NULL | keypath == NULL) {
printf("server mode requires both -c and -k options\n");
usage(argv[0]);
goto err;
}
} else {
if (storepath == NULL) {
printf("client mode requires -s option\n");
usage(argv[0]);
goto err;
}
}

times = OPENSSL_malloc(sizeof(OSSL_TIME) * threadcount);
if (times == NULL) {
printf("Failed to create times array\n");
goto err;
}

if (!perflib_run_multi_thread_test(do_create_ctx, threadcount, &duration)) {
printf("Failed to run the test\n");
goto err;
}

if (err) {
printf("Error during test\n");
goto err;
}

ttime = times[0];
for (i = 1; i < threadcount; i++)
ttime = ossl_time_add(ttime, times[i]);

avcalltime = ((double)ossl_time2ticks(ttime) / (double)adj_ctx_per_run) / (double)OSSL_TIME_US;

if (terse)
printf("%lf\n", avcalltime);
else
printf("Average time per ssl ctx setup: %lfus\n", avcalltime);

ret = EXIT_SUCCESS;
err:
OPENSSL_free(times);
return ret;
}