mirror of https://github.com/openssl/tools
Add a performance test for PEM_read_bio_PrivateKey()
We repeatedly attempt to load an RSA Private Key and measure performance. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/tools/pull/161)
This commit is contained in:
parent
2e35e54163
commit
4307d538d9
|
@ -1,7 +1,7 @@
|
|||
all: randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall
|
||||
all: randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall pemread
|
||||
|
||||
clean:
|
||||
rm libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall
|
||||
rm libperf.a *.o randbytes handshake sslnew newrawkey rsasign x509storeissuer providerdoall pemread
|
||||
|
||||
libperf.a: perflib/*.c perflib/*.h
|
||||
gcc -I$(TARGET_OSSL_INCLUDE_PATH) -I. -c perflib/*.c
|
||||
|
@ -27,3 +27,6 @@ x509storeissuer: x509storeissuer.c libperf.a
|
|||
|
||||
providerdoall: providerdoall.c libperf.a
|
||||
gcc -L$(TARGET_OSSL_LIBRARY_PATH) -L. -I$(TARGET_OSSL_INCLUDE_PATH) -I. -o providerdoall providerdoall.c -lperf -lcrypto
|
||||
|
||||
pemread: pemread.c libperf.a
|
||||
gcc -L$(TARGET_OSSL_LIBRARY_PATH) -L. -I$(TARGET_OSSL_INCLUDE_PATH) -I. -o pemread pemread.c -lperf -lcrypto
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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 <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "perflib/perflib.h"
|
||||
|
||||
#define NUM_CALLS_PER_BLOCK 100
|
||||
#define NUM_CALL_BLOCKS_PER_THREAD 100
|
||||
#define NUM_CALLS_PER_THREAD (NUM_CALLS_PER_BLOCK * NUM_CALL_BLOCKS_PER_THREAD)
|
||||
|
||||
int err = 0;
|
||||
|
||||
const char *pemdataraw[] = {
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n",
|
||||
"MIIBOgIBAAJBAMFcGsaxxdgiuuGmCkVImy4h99CqT7jwY3pexPGcnUFtR2Fh36Bp\n",
|
||||
"oncwtkZ4cAgtvd4Qs8PkxUdp6p/DlUmObdkCAwEAAQJAUR44xX6zB3eaeyvTRzms\n",
|
||||
"kHADrPCmPWnr8dxsNwiDGHzrMKLN+i/HAam+97HxIKVWNDH2ba9Mf1SA8xu9dcHZ\n",
|
||||
"AQIhAOHPCLxbtQFVxlnhSyxYeb7O323c3QulPNn3bhOipElpAiEA2zZpBE8ZXVnL\n",
|
||||
"74QjG4zINlDfH+EOEtjJJ3RtaYDugvECIBtsQDxXytChsRgDQ1TcXdStXPcDppie\n",
|
||||
"dZhm8yhRTTBZAiAZjE/U9rsIDC0ebxIAZfn3iplWh84yGB3pgUI3J5WkoQIhAInE\n",
|
||||
"HTUY5WRj5riZtkyGnbm3DvF+1eMtO2lYV+OuLcfE\n",
|
||||
"-----END RSA PRIVATE KEY-----\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
void do_pemread(size_t num)
|
||||
{
|
||||
EVP_PKEY *key;
|
||||
BIO *pem;
|
||||
int i;
|
||||
char *pemdata;
|
||||
size_t len;
|
||||
|
||||
pemdata = perflib_glue_strings(pemdataraw, &len);
|
||||
if (pemdata == NULL) {
|
||||
printf("Cannot create PEM data\n");
|
||||
err = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
pem = BIO_new_mem_buf(pemdata, len);
|
||||
if (pem == NULL) {
|
||||
printf("Cannot create mem BIO\n");
|
||||
err = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Technically this includes the EVP_PKEY_free() in the timing - but I
|
||||
* think we can live with that
|
||||
*/
|
||||
for (i = 0; i < NUM_CALLS_PER_THREAD; i++) {
|
||||
key = PEM_read_bio_PrivateKey(pem, NULL, NULL, NULL);
|
||||
if (key == NULL) {
|
||||
printf("Failed to create key: %d\n", i);
|
||||
err = 1;
|
||||
BIO_free(pem);
|
||||
return;
|
||||
}
|
||||
EVP_PKEY_free(key);
|
||||
BIO_reset(pem);
|
||||
}
|
||||
|
||||
BIO_free(pem);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int threadcount;
|
||||
OSSL_TIME duration;
|
||||
uint64_t us;
|
||||
double avcalltime;
|
||||
int terse = 0;
|
||||
int argnext;
|
||||
|
||||
if ((argc != 2 && argc != 3)
|
||||
|| (argc == 3 && strcmp("--terse", argv[1]) != 0)) {
|
||||
printf("Usage: pemread [--terse] threadcount\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
terse = 1;
|
||||
argnext = 2;
|
||||
} else {
|
||||
argnext = 1;
|
||||
}
|
||||
|
||||
threadcount = atoi(argv[argnext]);
|
||||
if (threadcount < 1) {
|
||||
printf("threadcount must be > 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!perflib_run_multi_thread_test(do_pemread, threadcount, &duration)) {
|
||||
printf("Failed to run the test\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
printf("Error during test\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
us = ossl_time2us(duration);
|
||||
|
||||
avcalltime = (double)us / (NUM_CALL_BLOCKS_PER_THREAD * threadcount);
|
||||
|
||||
if (terse)
|
||||
printf("%lf\n", avcalltime);
|
||||
else
|
||||
printf("Average time per %d PEM_read_bio_PrivateKey() calls: %lfus\n",
|
||||
NUM_CALLS_PER_BLOCK, avcalltime);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -31,3 +31,29 @@ 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;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef pthread_t thread_t;
|
|||
int perflib_run_multi_thread_test(void (*f)(size_t), size_t threadcount,
|
||||
OSSL_TIME *duration);
|
||||
char *perflib_mk_file_path(const char *dir, const char *file);
|
||||
char *perflib_glue_strings(const char *list[], size_t *out_len);
|
||||
|
||||
int perflib_create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
|
||||
int min_proto_version, int max_proto_version,
|
||||
|
|
Loading…
Reference in New Issue