summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Baentsch <57787676+baentsch@users.noreply.github.com>2022-12-24 09:20:44 +0100
committerTodd Short <todd.short@me.com>2023-03-31 20:19:18 +0200
commit4557e280086d9e300c56183b8ad0671857530dc5 (patch)
treefcc9c4ae73297c0436b82eb2601cd9f78d8932da
parent/dev/crypto: Suppress warning when open /dev/crypto fails with ENXIO. (diff)
downloadopenssl-4557e280086d9e300c56183b8ad0671857530dc5.tar.xz
openssl-4557e280086d9e300c56183b8ad0671857530dc5.zip
Provider-based KEM and SIG alg speed testing added
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Todd Short <todd.short@me.com> (Merged from https://github.com/openssl/openssl/pull/19968)
-rw-r--r--apps/speed.c922
-rw-r--r--doc/man1/openssl-speed.pod.in10
2 files changed, 905 insertions, 27 deletions
diff --git a/apps/speed.c b/apps/speed.c
index 489548f5ca..025c4eedc4 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -19,6 +19,8 @@
#define EdDSA_SECONDS PKEY_SECONDS
#define SM2_SECONDS PKEY_SECONDS
#define FFDH_SECONDS PKEY_SECONDS
+#define KEM_SECONDS PKEY_SECONDS
+#define SIG_SECONDS PKEY_SECONDS
/* We need to use some deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED
@@ -38,6 +40,7 @@
#include <openssl/objects.h>
#include <openssl/core_names.h>
#include <openssl/async.h>
+#include <openssl/provider.h>
#if !defined(OPENSSL_SYS_MSDOS)
# include <unistd.h>
#endif
@@ -111,6 +114,8 @@ typedef struct openssl_speed_sec_st {
int eddsa;
int sm2;
int ffdh;
+ int kem;
+ int sig;
} openssl_speed_sec_t;
static volatile int run = 0;
@@ -122,6 +127,8 @@ static double Time_F(int s);
static void print_message(const char *s, long num, int length, int tm);
static void pkey_print_message(const char *str, const char *str2,
long num, unsigned int bits, int sec);
+static void kskey_print_message(const char *str, const char *str2, long num,
+ int tm);
static void print_result(int alg, int run_no, int count, double time_used);
#ifndef NO_FORK
static int do_multi(int multi, int size_num);
@@ -230,7 +237,7 @@ typedef enum OPTION_choice {
OPT_COMMON,
OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG,
- OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK
+ OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK, OPT_KEM, OPT_SIG
} OPTION_CHOICE;
const OPTIONS speed_options[] = {
@@ -267,6 +274,10 @@ const OPTIONS speed_options[] = {
"Time decryption instead of encryption (only EVP)"},
{"aead", OPT_AEAD, '-',
"Benchmark EVP-named AEAD cipher in TLS-like sequence"},
+ {"kem-algorithms", OPT_KEM, '-',
+ "Benchmark KEM algorithms"},
+ {"signature-algorithms", OPT_SIG, '-',
+ "Benchmark signature algorithms"},
OPT_SECTION("Timing"),
{"elapsed", OPT_ELAPSED, '-',
@@ -476,6 +487,16 @@ static const OPT_PAIR sm2_choices[SM2_NUM] = {
static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
#endif /* OPENSSL_NO_SM2 */
+#define MAX_KEM_NUM 111
+static size_t kems_algs_len = 0;
+static char *kems_algname[MAX_KEM_NUM] = { NULL };
+static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
+
+#define MAX_SIG_NUM 111
+static size_t sigs_algs_len = 0;
+static char *sigs_algname[MAX_SIG_NUM] = { NULL };
+static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
+
#define COND(unused_cond) (run && count < INT_MAX)
#define COUNT(d) (count)
@@ -513,6 +534,20 @@ typedef struct loopargs_st {
#endif
EVP_CIPHER_CTX *ctx;
EVP_MAC_CTX *mctx;
+ EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM];
+ EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM];
+ EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM];
+ size_t kem_out_len[MAX_KEM_NUM];
+ size_t kem_secret_len[MAX_KEM_NUM];
+ unsigned char *kem_out[MAX_KEM_NUM];
+ unsigned char *kem_send_secret[MAX_KEM_NUM];
+ unsigned char *kem_rcv_secret[MAX_KEM_NUM];
+ EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM];
+ EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM];
+ EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM];
+ size_t sig_max_sig_len[MAX_KEM_NUM];
+ size_t sig_act_sig_len[MAX_KEM_NUM];
+ unsigned char *sig_sig[MAX_KEM_NUM];
} loopargs_t;
static int run_benchmark(int async_jobs, int (*loop_function) (void *),
loopargs_t * loopargs);
@@ -1139,6 +1174,131 @@ static int SM2_verify_loop(void *args)
}
#endif /* OPENSSL_NO_SM2 */
+static long kems_c[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
+static int KEM_keygen_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum];
+ EVP_PKEY *pkey = NULL;
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][0]); count++) {
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ return -1;
+ /*
+ * runtime defined to quite some degree by randomness,
+ * so performance overhead of _free doesn't impact
+ * results significantly. In any case this test is
+ * meant to permit relative algorithm performance
+ * comparison.
+ */
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+ return count;
+}
+
+static int KEM_encaps_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum];
+ size_t out_len = tempargs->kem_out_len[testnum];
+ size_t secret_len = tempargs->kem_secret_len[testnum];
+ unsigned char *out = tempargs->kem_out[testnum];
+ unsigned char *secret = tempargs->kem_send_secret[testnum];
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][1]); count++) {
+ if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0)
+ return -1;
+ }
+ return count;
+}
+
+static int KEM_decaps_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum];
+ size_t out_len = tempargs->kem_out_len[testnum];
+ size_t secret_len = tempargs->kem_secret_len[testnum];
+ unsigned char *out = tempargs->kem_out[testnum];
+ unsigned char *secret = tempargs->kem_send_secret[testnum];
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][2]); count++) {
+ if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0)
+ return -1;
+ }
+ return count;
+}
+
+static long sigs_c[MAX_SIG_NUM][3]; /* keygen, sign, verify */
+static int SIG_keygen_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum];
+ EVP_PKEY *pkey = NULL;
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][0]); count++) {
+ EVP_PKEY_keygen(ctx, &pkey);
+ /* TBD: How much does free influence runtime? */
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
+ }
+ return count;
+}
+
+static int SIG_sign_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum];
+ /* be sure to not change stored sig: */
+ unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum],
+ "sig sign loop");
+ unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
+ size_t md_len = SHA256_DIGEST_LENGTH;
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][1]); count++) {
+ size_t sig_len = tempargs->sig_max_sig_len[testnum];
+ int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len);
+
+ if (ret <= 0) {
+ BIO_printf(bio_err, "SIG sign failure at count %d\n", count);
+ ERR_print_errors(bio_err);
+ count = -1;
+ break;
+ }
+ }
+ OPENSSL_free(sig);
+ return count;
+}
+
+static int SIG_verify_loop(void *args)
+{
+ loopargs_t *tempargs = *(loopargs_t **) args;
+ EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum];
+ size_t sig_len = tempargs->sig_act_sig_len[testnum];
+ unsigned char *sig = tempargs->sig_sig[testnum];
+ unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
+ size_t md_len = SHA256_DIGEST_LENGTH;
+ int count;
+
+ for (count = 0; COND(kems_c[testnum][2]); count++) {
+ int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len);
+
+ if (ret <= 0) {
+ BIO_printf(bio_err, "SIG verify failure at count %d\n", count);
+ ERR_print_errors(bio_err);
+ count = -1;
+ break;
+ }
+
+ }
+ return count;
+}
+
static int run_benchmark(int async_jobs,
int (*loop_function) (void *), loopargs_t * loopargs)
{
@@ -1373,6 +1533,99 @@ static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
#define stop_it(do_it, test_num)\
memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
+/* Checks to see if algorithms are fetchable */
+#define IS_FETCHABLE(type, TYPE) \
+ static int is_ ## type ## _fetchable(const TYPE *alg) \
+ { \
+ TYPE *impl; \
+ const char *propq = app_get0_propq(); \
+ OSSL_LIB_CTX *libctx = app_get0_libctx(); \
+ const char *name = TYPE ## _get0_name(alg); \
+ \
+ ERR_set_mark(); \
+ impl = TYPE ## _fetch(libctx, name, propq); \
+ ERR_pop_to_mark(); \
+ if (impl == NULL) \
+ return 0; \
+ TYPE ## _free(impl); \
+ return 1; \
+ }
+
+IS_FETCHABLE(signature, EVP_SIGNATURE)
+IS_FETCHABLE(kem, EVP_KEM)
+
+DEFINE_STACK_OF(EVP_KEM)
+
+static int kems_cmp(const EVP_KEM * const *a,
+ const EVP_KEM * const *b)
+{
+ return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
+ OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
+}
+
+static void collect_kem(EVP_KEM *kem, void *stack)
+{
+ STACK_OF(EVP_KEM) *kem_stack = stack;
+
+ if (is_kem_fetchable(kem)
+ && sk_EVP_KEM_push(kem_stack, kem) > 0) {
+ EVP_KEM_up_ref(kem);
+ }
+}
+
+static int kem_locate(const char *algo, unsigned int *idx)
+{
+ unsigned int i;
+
+ for (i = 0; i < kems_algs_len; i++) {
+ if (strcmp(kems_algname[i], algo) == 0) {
+ *idx = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+DEFINE_STACK_OF(EVP_SIGNATURE)
+
+static int signatures_cmp(const EVP_SIGNATURE * const *a,
+ const EVP_SIGNATURE * const *b)
+{
+ return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
+ OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
+}
+
+static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
+{
+ STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
+
+ if (is_signature_fetchable(sig)
+ && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
+ EVP_SIGNATURE_up_ref(sig);
+}
+
+static int sig_locate(const char *algo, unsigned int *idx)
+{
+ unsigned int i;
+
+ for (i = 0; i < sigs_algs_len; i++) {
+ if (strcmp(sigs_algname[i], algo) == 0) {
+ *idx = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int get_max(const uint8_t doit[], size_t algs_len) {
+ size_t i = 0;
+ int maxcnt = 0;
+
+ for (i = 0; i < algs_len; i++)
+ if (maxcnt < doit[i]) maxcnt = doit[i];
+ return maxcnt;
+}
+
int speed_main(int argc, char **argv)
{
CONF *conf = NULL;
@@ -1387,9 +1640,12 @@ int speed_main(int argc, char **argv)
int async_init = 0, multiblock = 0, pr_header = 0;
uint8_t doit[ALGOR_NUM] = { 0 };
int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
+ STACK_OF(EVP_KEM) *kem_stack = NULL;
+ STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
long count = 0;
unsigned int size_num = SIZE_NUM;
unsigned int i, k, loopargs_len = 0, async_jobs = 0;
+ unsigned int idx;
int keylen;
int buflen;
BIGNUM *bn = NULL;
@@ -1401,7 +1657,8 @@ int speed_main(int argc, char **argv)
openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
ECDSA_SECONDS, ECDH_SECONDS,
EdDSA_SECONDS, SM2_SECONDS,
- FFDH_SECONDS };
+ FFDH_SECONDS, KEM_SECONDS,
+ SIG_SECONDS };
static const unsigned char key32[32] = {
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
@@ -1501,6 +1758,12 @@ int speed_main(int argc, char **argv)
uint8_t ecdh_doit[EC_NUM] = { 0 };
uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
+ uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
+ uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
+
+ uint8_t do_kems = 0;
+ uint8_t do_sigs = 0;
+
/* checks declared curves against choices list. */
OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
@@ -1643,7 +1906,8 @@ int speed_main(int argc, char **argv)
case OPT_SECONDS:
seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
= seconds.ecdh = seconds.eddsa
- = seconds.sm2 = seconds.ffdh = opt_int_arg();
+ = seconds.sm2 = seconds.ffdh
+ = seconds.kem = seconds.sig = opt_int_arg();
break;
case OPT_BYTES:
lengths_single = opt_int_arg();
@@ -1653,6 +1917,12 @@ int speed_main(int argc, char **argv)
case OPT_AEAD:
aead = 1;
break;
+ case OPT_KEM:
+ do_kems = 1;
+ break;
+ case OPT_SIG:
+ do_sigs = 1;
+ break;
case OPT_MLOCK:
domlock = 1;
#if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
@@ -1665,6 +1935,102 @@ int speed_main(int argc, char **argv)
}
}
+ /* find all KEMs currently available */
+ kem_stack = sk_EVP_KEM_new(kems_cmp);
+ EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
+
+ kems_algs_len = 0;
+
+ for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) {
+ EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx);
+
+ if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) {
+ if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) {
+ BIO_printf(bio_err,
+ "Too many KEMs registered. Change MAX_KEM_NUM.\n");
+ goto end;
+ }
+ for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
+ kems_doit[kems_algs_len] = 1;
+ kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
+ }
+ } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) {
+ if (kems_algs_len + 3 >= MAX_KEM_NUM) {
+ BIO_printf(bio_err,
+ "Too many KEMs registered. Change MAX_KEM_NUM.\n");
+ goto end;
+ }
+ kems_doit[kems_algs_len] = 1;
+ kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256");
+ kems_doit[kems_algs_len] = 1;
+ kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384");
+ kems_doit[kems_algs_len] = 1;
+ kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521");
+ } else {
+ if (kems_algs_len + 1 >= MAX_KEM_NUM) {
+ BIO_printf(bio_err,
+ "Too many KEMs registered. Change MAX_KEM_NUM.\n");
+ goto end;
+ }
+ kems_doit[kems_algs_len] = 1;
+ kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem));
+ }
+ }
+ sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
+ kem_stack = NULL;
+
+ /* find all SIGNATUREs currently available */
+ sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp);
+ EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack);
+
+ sigs_algs_len = 0;
+
+ for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) {
+ EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx);
+ const char *sig_name = EVP_SIGNATURE_get0_name(s);
+
+ if (strcmp(sig_name, "RSA") == 0) {
+ if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) {
+ BIO_printf(bio_err,
+ "Too many signatures registered. Change MAX_SIG_NUM.\n");
+ goto end;
+ }
+ for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
+ sigs_doit[sigs_algs_len] = 1;
+ sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
+ }
+ }
+ else if (strcmp(sig_name, "DSA") == 0) {
+ if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) {
+ BIO_printf(bio_err,
+ "Too many signatures registered. Change MAX_SIG_NUM.\n");
+ goto end;
+ }
+ for (i = 0; i < DSA_NUM; i++) {
+ sigs_doit[sigs_algs_len] = 1;
+ sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name);
+ }
+ }
+ /* skipping these algs as tested elsewhere - and b/o setup is a pain */
+ else if (strcmp(sig_name, "ED25519") &&
+ strcmp(sig_name, "ED448") &&
+ strcmp(sig_name, "ECDSA") &&
+ strcmp(sig_name, "HMAC") &&
+ strcmp(sig_name, "SIPHASH") &&
+ strcmp(sig_name, "POLY1305") &&
+ strcmp(sig_name, "CMAC") &&
+ strcmp(sig_name, "SM2")) { /* skip alg */
+ if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
+ BIO_printf(bio_err,
+ "Too many signatures registered. Change MAX_SIG_NUM.\n");
+ goto end;
+ }
+ /* activate this provider algorithm */
+ sigs_doit[sigs_algs_len] = 1;
+ sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name);
+ }
+ }
+
/* Remaining arguments are algorithms. */
argc = opt_num_rest();
argv = opt_rest();
@@ -1674,103 +2040,117 @@ int speed_main(int argc, char **argv)
for (; *argv; argv++) {
const char *algo = *argv;
+ int algo_found = 0;
if (opt_found(algo, doit_choices, &i)) {
doit[i] = 1;
- continue;
+ algo_found = 1;
}
if (strcmp(algo, "des") == 0) {
doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
- continue;
+ algo_found = 1;
}
if (strcmp(algo, "sha") == 0) {
doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
- continue;
+ algo_found = 1;
}
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (strcmp(algo, "openssl") == 0) /* just for compatibility */
- continue;
+ algo_found = 1;
#endif
if (HAS_PREFIX(algo, "rsa")) {
if (algo[sizeof("rsa") - 1] == '\0') {
memset(rsa_doit, 1, sizeof(rsa_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, rsa_choices, &i)) {
rsa_doit[i] = 1;
- continue;
+ algo_found = 1;
}
}
#ifndef OPENSSL_NO_DH
if (HAS_PREFIX(algo, "ffdh")) {
if (algo[sizeof("ffdh") - 1] == '\0') {
memset(ffdh_doit, 1, sizeof(ffdh_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, ffdh_choices, &i)) {
ffdh_doit[i] = 2;
- continue;
+ algo_found = 1;
}
}
#endif
if (HAS_PREFIX(algo, "dsa")) {
if (algo[sizeof("dsa") - 1] == '\0') {
memset(dsa_doit, 1, sizeof(dsa_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, dsa_choices, &i)) {
dsa_doit[i] = 2;
- continue;
+ algo_found = 1;
}
}
if (strcmp(algo, "aes") == 0) {
doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
- continue;
+ algo_found = 1;
}
if (strcmp(algo, "camellia") == 0) {
doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
- continue;
+ algo_found = 1;
}
if (HAS_PREFIX(algo, "ecdsa")) {
if (algo[sizeof("ecdsa") - 1] == '\0') {
memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, ecdsa_choices, &i)) {
ecdsa_doit[i] = 2;
- continue;
+ algo_found = 1;
}
}
if (HAS_PREFIX(algo, "ecdh")) {
if (algo[sizeof("ecdh") - 1] == '\0') {
memset(ecdh_doit, 1, sizeof(ecdh_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, ecdh_choices, &i)) {
ecdh_doit[i] = 2;
- continue;
+ algo_found = 1;
}
}
if (strcmp(algo, "eddsa") == 0) {
memset(eddsa_doit, 1, sizeof(eddsa_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, eddsa_choices, &i)) {
eddsa_doit[i] = 2;
- continue;
+ algo_found = 1;
}
#ifndef OPENSSL_NO_SM2
if (strcmp(algo, "sm2") == 0) {
memset(sm2_doit, 1, sizeof(sm2_doit));
- continue;
+ algo_found = 1;
}
if (opt_found(algo, sm2_choices, &i)) {
sm2_doit[i] = 2;
- continue;
+ algo_found = 1;
}
#endif
- BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
- goto end;
+ if (kem_locate(algo, &idx)) {
+ kems_doit[idx]++;
+ do_kems = 1;
+ algo_found = 1;
+ }
+ if (sig_locate(algo, &idx)) {
+ sigs_doit[idx]++;
+ do_sigs = 1;
+ algo_found = 1;
+ }
+
+ if (!algo_found) {
+ BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
+ goto end;
+ }
}
/* Sanity checks */
@@ -1785,6 +2165,28 @@ int speed_main(int argc, char **argv)
goto end;
}
}
+ if (kems_algs_len > 0) {
+ int maxcnt = get_max(kems_doit, kems_algs_len);
+
+ if (maxcnt > 1) {
+ /* some algs explicitly selected */
+ for (i = 0; i < kems_algs_len; i++) {
+ /* disable the rest */
+ kems_doit[i]--;
+ }
+ }
+ }
+ if (sigs_algs_len > 0) {
+ int maxcnt = get_max(sigs_doit, sigs_algs_len);
+
+ if (maxcnt > 1) {
+ /* some algs explicitly selected */
+ for (i = 0; i < sigs_algs_len; i++) {
+ /* disable the rest */
+ sigs_doit[i]--;
+ }
+ }
+ }
if (multiblock) {
if (evp_cipher == NULL) {
BIO_printf(bio_err, "-mb can be used only with a multi-block"
@@ -1871,7 +2273,8 @@ int speed_main(int argc, char **argv)
e = setup_engine(engine_id, 0);
/* No parameters; turn on everything. */
- if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
+ if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC]
+ && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) {
memset(doit, 1, sizeof(doit));
doit[D_EVP] = doit[D_EVP_CMAC] = 0;
ERR_set_mark();
@@ -1909,6 +2312,10 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_SM2
memset(sm2_doit, 1, sizeof(sm2_doit));
#endif
+ memset(kems_doit, 1, sizeof(kems_doit));
+ do_kems = 1;
+ memset(sigs_doit, 1, sizeof(sigs_doit));
+ do_sigs = 1;
}
for (i = 0; i < ALGOR_NUM; i++)
if (doit[i])
@@ -3170,6 +3577,371 @@ skip_hmac:
}
}
#endif /* OPENSSL_NO_DH */
+
+ for (testnum = 0; testnum < kems_algs_len; testnum++) {
+ int kem_checks = 1;
+ const char *kem_name = kems_algname[testnum];
+
+ if (!kems_doit[testnum] || !do_kems)
+ continue;
+
+ for (i = 0; i < loopargs_len; i++) {
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *kem_gen_ctx = NULL;
+ EVP_PKEY_CTX *kem_encaps_ctx = NULL;
+ EVP_PKEY_CTX *kem_decaps_ctx = NULL;
+ size_t send_secret_len, out_len;
+ size_t rcv_secret_len;
+ unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
+ size_t bits;
+ char *name;
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ int use_params = 0;
+ enum kem_type_t { KEM_RSA = 1, KEM_EC, KEM_X25519, KEM_X448 } kem_type;
+
+ if (strncmp(kem_name, "rsa", 3) == 0)
+ kem_type = KEM_RSA;
+ else if (strncmp(kem_name, "EC", 2) == 0)
+ kem_type = KEM_EC;
+ else if (strcmp(kem_name, "X25519") == 0)
+ kem_type = KEM_X25519;
+ else if (strcmp(kem_name, "X448") == 0)
+ kem_type = KEM_X448;
+ else kem_type = 0;
+
+ if (ERR_peek_error()) {
+ BIO_printf(bio_err,
+ "WARNING: the error queue contains previous unhandled errors.\n");
+ ERR_print_errors(bio_err);
+ }
+
+ if (kem_type == KEM_RSA) {
+ bits = atoi(kem_name + 3);
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS,
+ &bits);
+ use_params = 1;
+ } else if (kem_type == KEM_EC) {
+ name = (char *)(kem_name + 2);
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
+ name, 0);
+ use_params = 1;
+ }
+
+ kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
+ (kem_type == KEM_RSA) ? "RSA":
+ (kem_type == KEM_EC) ? "EC":
+ kem_name,
+ app_get0_propq());
+
+ if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
+ || (use_params
+ && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
+ BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
+ kem_name);
+ goto kem_err_break;
+ }
+ if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
+ BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
+ goto kem_err_break;
+ }
+ /* Now prepare encaps data structs */
+ kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
+ pkey,
+ app_get0_propq());
+ if (kem_encaps_ctx == NULL
+ || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
+ || (kem_type == KEM_RSA
+ && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
+ || ((kem_type == KEM_EC
+ || kem_type == KEM_X25519
+ || kem_type == KEM_X448)
+ && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
+ || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
+ NULL, &send_secret_len) <= 0) {
+ BIO_printf(bio_err,
+ "Error while initializing encaps data structs for %s.\n",
+ kem_name);
+ goto kem_err_break;
+ }
+ out = app_malloc(out_len, "encaps result");
+ send_secret = app_malloc(send_secret_len, "encaps secret");
+ if (out == NULL || send_secret == NULL) {
+ BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
+ goto kem_err_break;
+ }
+ if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
+ send_secret, &send_secret_len) <= 0) {
+ BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
+ goto kem_err_break;
+ }
+ /* Now prepare decaps data structs */
+ kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
+ pkey,
+ app_get0_propq());
+ if (kem_decaps_ctx == NULL
+ || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
+ || (kem_type == KEM_RSA
+ && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
+ || ((kem_type == KEM_EC
+ || kem_type == KEM_X25519
+ || kem_type == KEM_X448)
+ && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
+ || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
+ out, out_len) <= 0) {
+ BIO_printf(bio_err,
+ "Error while initializing decaps data structs for %s.\n",
+ kem_name);
+ goto kem_err_break;
+ }
+ rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
+ if (rcv_secret == NULL) {
+ BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
+ kem_name);
+ goto kem_err_break;
+ }
+ if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
+ &rcv_secret_len, out, out_len) <= 0
+ || rcv_secret_len != send_secret_len
+ || memcmp(send_secret, rcv_secret, send_secret_len)) {
+ BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
+ goto kem_err_break;
+ }
+ loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
+ loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
+ loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
+ loopargs[i].kem_out_len[testnum] = out_len;
+ loopargs[i].kem_secret_len[testnum] = send_secret_len;
+ loopargs[i].kem_out[testnum] = out;
+ loopargs[i].kem_send_secret[testnum] = send_secret;
+ loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
+ break;
+
+ kem_err_break:
+ ERR_print_errors(bio_err);
+ op_count = 1;
+ kem_checks = 0;
+ break;
+ }
+ if (kem_checks != 0) {
+ kskey_print_message(kem_name, "keygen", kems_c[testnum][0],
+ seconds.kem);
+ Time_F(START);
+ count =
+ run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R13:%ld:%s:%.2f\n" :
+ "%ld %s KEM keygens in %.2fs\n", count,
+ kem_name, d);
+ kems_results[testnum][0] = (double)count / d;
+ op_count = count;
+ kskey_print_message(kem_name, "encaps", kems_c[testnum][1],
+ seconds.kem);
+ Time_F(START);
+ count =
+ run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R14:%ld:%s:%.2f\n" :
+ "%ld %s KEM encaps in %.2fs\n", count,
+ kem_name, d);
+ kems_results[testnum][1] = (double)count / d;
+ op_count = count;
+ kskey_print_message(kem_name, "decaps", kems_c[testnum][2],
+ seconds.kem);
+ Time_F(START);
+ count =
+ run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R15:%ld:%s:%.2f\n" :
+ "%ld %s KEM decaps in %.2fs\n", count,
+ kem_name, d);
+ kems_results[testnum][2] = (double)count / d;
+ op_count = count;
+ }
+ if (op_count <= 1) {
+ /* if longer than 10s, don't do any more */
+ stop_it(kems_doit, testnum);
+ }
+ }
+
+ for (testnum = 0; testnum < sigs_algs_len; testnum++) {
+ int sig_checks = 1;
+ const char *sig_name = sigs_algname[testnum];
+
+ if (!sigs_doit[testnum] || !do_sigs)
+ continue;
+
+ for (i = 0; i < loopargs_len; i++) {
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx_params = NULL;
+ EVP_PKEY* pkey_params = NULL;
+ EVP_PKEY_CTX *sig_gen_ctx = NULL;
+ EVP_PKEY_CTX *sig_sign_ctx = NULL;
+ EVP_PKEY_CTX *sig_verify_ctx = NULL;
+ unsigned char md[SHA256_DIGEST_LENGTH];
+ unsigned char *sig;
+ size_t md_len = SHA256_DIGEST_LENGTH;
+ size_t max_sig_len, sig_len;
+ size_t bits;
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ int use_params = 0;
+
+ /* only sign little data to avoid measuring digest performance */
+ memset(md, 0, SHA256_DIGEST_LENGTH);
+
+ if (ERR_peek_error()) {
+ BIO_printf(bio_err,
+ "WARNING: the error queue contains previous unhandled errors.\n");
+ ERR_print_errors(bio_err);
+ }
+
+ if (strncmp(sig_name, "rsa", 3) == 0) {
+ bits = atoi(sig_name + 3);
+ params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS,
+ &bits);
+ use_params = 1;
+ }
+
+ if (strncmp(sig_name, "dsa", 3) == 0) {
+ ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
+ if (ctx_params == NULL
+ || EVP_PKEY_paramgen_init(ctx_params) <= 0
+ || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
+ atoi(sig_name + 3)) <= 0
+ || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
+ || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
+ || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
+ BIO_printf(bio_err,
+ "Error initializing classic keygen ctx for %s.\n",
+ sig_name);
+ goto sig_err_break;
+ }
+ }
+
+ if (sig_gen_ctx == NULL)
+ sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
+ (strncmp(sig_name, "rsa", 3) == 0) ? "RSA" : sig_name,
+ app_get0_propq());
+
+ if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
+ || (use_params &&
+ EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
+ BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
+ sig_name);
+ goto sig_err_break;
+ }
+ if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
+ BIO_printf(bio_err,
+ "Error while generating signature EVP_PKEY for %s.\n",
+ sig_name);
+ goto sig_err_break;
+ }
+ /* Now prepare signature data structs */
+ sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
+ pkey,
+ app_get0_propq());
+ if (sig_sign_ctx == NULL
+ || EVP_PKEY_sign_init(sig_sign_ctx) <= 0
+ || (strncmp(sig_name, "rsa", 3) == 0
+ && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx,
+ RSA_PKCS1_PADDING) <= 0))
+ || EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len,
+ md, md_len) <= 0) {
+ BIO_printf(bio_err,
+ "Error while initializing signing data structs for %s.\n",
+ sig_name);
+ goto sig_err_break;
+ }
+ sig = app_malloc(sig_len = max_sig_len, "signature buffer");
+ if (sig == NULL) {
+ BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
+ goto sig_err_break;
+ }
+ if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
+ BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
+ goto sig_err_break;
+ }
+ /* Now prepare verify data structs */
+ memset(md, 0, SHA256_DIGEST_LENGTH);
+ sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
+ pkey,
+ app_get0_propq());
+ if (sig_verify_ctx == NULL
+ || EVP_PKEY_verify_init(sig_verify_ctx) <= 0
+ || (strncmp(sig_name, "rsa", 3) == 0
+ && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx,
+ RSA_PKCS1_PADDING) <= 0))) {
+ BIO_printf(bio_err,
+ "Error while initializing verify data structs for %s.\n",
+ sig_name);
+ goto sig_err_break;
+ }
+ if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
+ BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
+ goto sig_err_break;
+ }
+ if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
+ BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
+ goto sig_err_break;
+ }
+ loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
+ loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
+ loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
+ loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
+ loopargs[i].sig_act_sig_len[testnum] = sig_len;
+ loopargs[i].sig_sig[testnum] = sig;
+ break;
+
+ sig_err_break:
+ ERR_print_errors(bio_err);
+ op_count = 1;
+ sig_checks = 0;
+ break;
+ }
+
+ if (sig_checks != 0) {
+ kskey_print_message(sig_name, "keygen", sigs_c[testnum][0], seconds.sig);
+ Time_F(START);
+ count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R16:%ld:%s:%.2f\n" :
+ "%ld %s signature keygens in %.2fs\n", count,
+ sig_name, d);
+ sigs_results[testnum][0] = (double)count / d;
+ op_count = count;
+ kskey_print_message(sig_name, "signs", sigs_c[testnum][1],
+ seconds.sig);
+ Time_F(START);
+ count =
+ run_benchmark(async_jobs, SIG_sign_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R17:%ld:%s:%.2f\n" :
+ "%ld %s signature signs in %.2fs\n", count,
+ sig_name, d);
+ sigs_results[testnum][1] = (double)count / d;
+ op_count = count;
+
+ kskey_print_message(sig_name, "verify", sigs_c[testnum][2],
+ seconds.sig);
+ Time_F(START);
+ count =
+ run_benchmark(async_jobs, SIG_verify_loop, loopargs);
+ d = Time_F(STOP);
+ BIO_printf(bio_err,
+ mr ? "+R18:%ld:%s:%.2f\n" :
+ "%ld %s signature verifys in %.2fs\n", count,
+ sig_name, d);
+ sigs_results[testnum][2] = (double)count / d;
+ op_count = count;
+ }
+ if (op_count <= 1)
+ stop_it(sigs_doit, testnum);
+ }
+
#ifndef NO_FORK
show_res:
#endif
@@ -3221,7 +3993,8 @@ skip_hmac:
k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
else
printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
- rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
+ rsa_keys[k].bits, 1.0 / rsa_results[k][0],
+ 1.0 / rsa_results[k][1],
rsa_results[k][0], rsa_results[k][1]);
}
testnum = 1;
@@ -3341,6 +4114,48 @@ skip_hmac:
}
#endif /* OPENSSL_NO_DH */
+ testnum = 1;
+ for (k = 0; k < kems_algs_len; k++) {
+ const char *kem_name = kems_algname[k];
+
+ if (!kems_doit[k] || !do_kems)
+ continue;
+ if (testnum && !mr) {
+ printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
+ testnum = 0;
+ }
+ if (mr)
+ printf("+F9:%u:%f:%f:%f\n",
+ k, kems_results[k][0], kems_results[k][1],
+ kems_results[k][2]);
+ else
+ printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
+ 1.0 / kems_results[k][0],
+ 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
+ kems_results[k][0], kems_results[k][1], kems_results[k][2]);
+ }
+ ret = 0;
+
+ testnum = 1;
+ for (k = 0; k < sigs_algs_len; k++) {
+ const char *sig_name = sigs_algname[k];
+
+ if (!sigs_doit[k] || !do_sigs)
+ continue;
+ if (testnum && !mr) {
+ printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
+ testnum = 0;
+ }
+ if (mr)
+ printf("+F10:%u:%f:%f:%f\n",
+ k, sigs_results[k][0], sigs_results[k][1],
+ sigs_results[k][2]);
+ else
+ printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
+ 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
+ 1.0 / sigs_results[k][2], sigs_results[k][0],
+ sigs_results[k][1], sigs_results[k][2]);
+ }
ret = 0;
end:
@@ -3393,11 +4208,29 @@ skip_hmac:
EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
}
#endif
+ for (k = 0; k < kems_algs_len; k++) {
+ EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
+ EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
+ EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
+ OPENSSL_free(loopargs[i].kem_out[k]);
+ OPENSSL_free(loopargs[i].kem_send_secret[k]);
+ OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
+ }
+ for (k = 0; k < sigs_algs_len; k++) {
+ EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
+ EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
+ EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
+ OPENSSL_free(loopargs[i].sig_sig[k]);
+ }
OPENSSL_free(loopargs[i].secret_a);
OPENSSL_free(loopargs[i].secret_b);
}
OPENSSL_free(evp_hmac_name);
OPENSSL_free(evp_cmac_name);
+ for (k = 0; k < kems_algs_len; k++)
+ OPENSSL_free(kems_algname[k]);
+ for (k = 0; k < sigs_algs_len; k++)
+ OPENSSL_free(sigs_algname[k]);
if (async_jobs > 0) {
for (i = 0; i < loopargs_len; i++)
@@ -3436,6 +4269,17 @@ static void pkey_print_message(const char *str, const char *str2, long num,
alarm(tm);
}
+static void kskey_print_message(const char *str, const char *str2,
+ long num, int tm)
+{
+ BIO_printf(bio_err,
+ mr ? "+DTP:%s:%s:%d\n"
+ : "Doing %s %s's for %ds: ", str, str2, tm);
+ (void)BIO_flush(bio_err);
+ run = 1;
+ alarm(tm);
+}
+
static void print_result(int alg, int run_no, int count, double time_used)
{
if (count == -1) {
@@ -3639,6 +4483,30 @@ static int do_multi(int multi, int size_num)
ffdh_results[k][0] += d;
}
# endif /* OPENSSL_NO_DH */
+ } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
+ tk = sstrsep(&p, sep);
+ if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
+ d = atof(sstrsep(&p, sep));
+ kems_results[k][0] += d;
+
+ d = atof(sstrsep(&p, sep));
+ kems_results[k][1] += d;
+
+ d = atof(sstrsep(&p, sep));
+ kems_results[k][2] += d;
+ }
+ } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
+ tk = sstrsep(&p, sep);
+ if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
+ d = atof(sstrsep(&p, sep));
+ sigs_results[k][0] += d;
+
+ d = atof(sstrsep(&p, sep));
+ sigs_results[k][1] += d;
+
+ d = atof(sstrsep(&p, sep));
+ sigs_results[k][2] += d;
+ }
} else if (!HAS_PREFIX(buf, "+H:")) {
BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
n);
diff --git a/doc/man1/openssl-speed.pod.in b/doc/man1/openssl-speed.pod.in
index ab76ca6f13..38e95720a3 100644
--- a/doc/man1/openssl-speed.pod.in
+++ b/doc/man1/openssl-speed.pod.in
@@ -16,6 +16,8 @@ B<openssl speed>
[B<-cmac> I<algo>]
[B<-mb>]
[B<-aead>]
+[B<-kem-algorithms>]
+[B<-signature-algorithms>]
[B<-multi> I<num>]
[B<-async_jobs> I<num>]
[B<-misalign> I<num>]
@@ -97,6 +99,14 @@ Enable multi-block mode on EVP-named cipher.
Benchmark EVP-named AEAD cipher in TLS-like sequence.
+=item B<-kem-algorithms>
+
+Benchmark KEM algorithms: key generation, encapsulation, decapsulation.
+
+=item B<-signature-algorithms>
+
+Benchmark signature algorithms: key generation, signature, verification.
+
=item B<-primes> I<num>
Generate a I<num>-prime RSA key and use it to run the benchmarks. This option