2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
13 #define PKEY_SECONDS 10
15 #define RSA_SECONDS PKEY_SECONDS
16 #define DSA_SECONDS PKEY_SECONDS
17 #define ECDSA_SECONDS PKEY_SECONDS
18 #define ECDH_SECONDS PKEY_SECONDS
19 #define EdDSA_SECONDS PKEY_SECONDS
20 #define SM2_SECONDS PKEY_SECONDS
21 #define FFDH_SECONDS PKEY_SECONDS
22 #define KEM_SECONDS PKEY_SECONDS
23 #define SIG_SECONDS PKEY_SECONDS
25 #define MAX_ALGNAME_SUFFIX 100
27 /* We need to use some deprecated APIs */
28 #define OPENSSL_SUPPRESS_DEPRECATED
36 #include "internal/nelem.h"
37 #include "internal/numbers.h"
38 #include <openssl/crypto.h>
39 #include <openssl/rand.h>
40 #include <openssl/err.h>
41 #include <openssl/evp.h>
42 #include <openssl/objects.h>
43 #include <openssl/core_names.h>
44 #include <openssl/async.h>
45 #include <openssl/provider.h>
46 #if !defined(OPENSSL_SYS_MSDOS)
51 # if defined(OPENSSL_TANDEM_FLOSS)
52 # include <floss.h(floss_fork)>
59 * While VirtualLock is available under the app partition (e.g. UWP),
60 * the headers do not define the API. Define it ourselves instead.
66 _In_ LPVOID lpAddress,
71 #if defined(OPENSSL_SYS_LINUX)
72 # include <sys/mman.h>
75 #include <openssl/bn.h>
76 #include <openssl/rsa.h>
77 #include "./testrsa.h"
79 # include <openssl/dh.h>
81 #include <openssl/x509.h>
82 #include <openssl/dsa.h>
83 #include "./testdsa.h"
84 #include <openssl/modes.h>
87 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
91 # include <sys/wait.h>
101 #define MAX_MISALIGNMENT 63
102 #define MAX_ECDH_SIZE 256
104 #define MAX_FFDH_SIZE 1024
106 #ifndef RSA_DEFAULT_PRIME_NUM
107 # define RSA_DEFAULT_PRIME_NUM 2
110 typedef struct openssl_speed_sec_st {
121 } openssl_speed_sec_t;
123 static volatile int run = 0;
125 static int mr = 0; /* machine-readeable output format to merge fork results */
126 static int usertime = 1;
128 static double Time_F(int s);
129 static void print_message(const char *s, int length, int tm);
130 static void pkey_print_message(const char *str, const char *str2,
131 unsigned int bits, int sec);
132 static void kskey_print_message(const char *str, const char *str2, int tm);
133 static void print_result(int alg, int run_no, int count, double time_used);
135 static int do_multi(int multi, int size_num);
138 static int domlock = 0;
140 static const int lengths_list[] = {
141 16, 64, 256, 1024, 8 * 1024, 16 * 1024
143 #define SIZE_NUM OSSL_NELEM(lengths_list)
144 static const int *lengths = lengths_list;
146 static const int aead_lengths_list[] = {
147 2, 31, 136, 1024, 8 * 1024, 16 * 1024
155 static void alarmed(ossl_unused int sig)
157 signal(SIGALRM, alarmed);
161 static double Time_F(int s)
163 double ret = app_tminterval(s, usertime);
169 #elif defined(_WIN32)
173 static unsigned int lapse;
174 static volatile unsigned int schlock;
175 static void alarm_win32(unsigned int secs)
180 # define alarm alarm_win32
182 static DWORD WINAPI sleepy(VOID * arg)
190 static double Time_F(int s)
197 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
199 DWORD err = GetLastError();
200 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
204 Sleep(0); /* scheduler spinlock */
205 ret = app_tminterval(s, usertime);
207 ret = app_tminterval(s, usertime);
209 TerminateThread(thr, 0);
216 # error "SIGALRM not defined and the platform is not Windows"
219 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
220 const openssl_speed_sec_t *seconds);
222 static int opt_found(const char *name, unsigned int *result,
223 const OPT_PAIR pairs[], unsigned int nbelem)
227 for (idx = 0; idx < nbelem; ++idx, pairs++)
228 if (strcmp(name, pairs->name) == 0) {
229 *result = pairs->retval;
234 #define opt_found(value, pairs, result)\
235 opt_found(value, result, pairs, OSSL_NELEM(pairs))
237 typedef enum OPTION_choice {
239 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
240 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG,
241 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK, OPT_KEM, OPT_SIG
244 const OPTIONS speed_options[] = {
245 {OPT_HELP_STR, 1, '-',
246 "Usage: %s [options] [algorithm...]\n"
247 "All +int options consider prefix '0' as base-8 input, "
248 "prefix '0x'/'0X' as base-16 input.\n"
251 OPT_SECTION("General"),
252 {"help", OPT_HELP, '-', "Display this summary"},
254 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
255 {"mr", OPT_MR, '-', "Produce machine readable output"},
257 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
259 #ifndef OPENSSL_NO_ASYNC
260 {"async_jobs", OPT_ASYNCJOBS, 'p',
261 "Enable async mode and start specified number of jobs"},
263 #ifndef OPENSSL_NO_ENGINE
264 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
266 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
267 {"mlock", OPT_MLOCK, '-', "Lock memory for better result determinism"},
270 OPT_SECTION("Selection"),
271 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
272 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
273 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
274 {"decrypt", OPT_DECRYPT, '-',
275 "Time decryption instead of encryption (only EVP)"},
276 {"aead", OPT_AEAD, '-',
277 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
278 {"kem-algorithms", OPT_KEM, '-',
279 "Benchmark KEM algorithms"},
280 {"signature-algorithms", OPT_SIG, '-',
281 "Benchmark signature algorithms"},
283 OPT_SECTION("Timing"),
284 {"elapsed", OPT_ELAPSED, '-',
285 "Use wall-clock time instead of CPU user time as divisor"},
286 {"seconds", OPT_SECONDS, 'p',
287 "Run benchmarks for specified amount of seconds"},
288 {"bytes", OPT_BYTES, 'p',
289 "Run [non-PKI] benchmarks on custom-sized buffer"},
290 {"misalign", OPT_MISALIGN, 'p',
291 "Use specified offset to mis-align buffers"},
297 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
302 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
303 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
304 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
305 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
306 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
307 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
308 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_KMAC128, D_KMAC256,
311 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
312 static const char *names[ALGOR_NUM] = {
313 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
314 "sha256", "sha512", "whirlpool", "hmac(sha256)",
315 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
316 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
317 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
318 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
319 "evp", "ghash", "rand", "cmac", "kmac128", "kmac256"
322 /* list of configured algorithm (remaining), with some few alias */
323 static const OPT_PAIR doit_choices[] = {
330 {"sha256", D_SHA256},
331 {"sha512", D_SHA512},
332 {"whirlpool", D_WHIRLPOOL},
333 {"ripemd", D_RMD160},
334 {"rmd160", D_RMD160},
335 {"ripemd160", D_RMD160},
337 {"des-cbc", D_CBC_DES},
338 {"des-ede3", D_EDE3_DES},
339 {"aes-128-cbc", D_CBC_128_AES},
340 {"aes-192-cbc", D_CBC_192_AES},
341 {"aes-256-cbc", D_CBC_256_AES},
342 {"camellia-128-cbc", D_CBC_128_CML},
343 {"camellia-192-cbc", D_CBC_192_CML},
344 {"camellia-256-cbc", D_CBC_256_CML},
345 {"rc2-cbc", D_CBC_RC2},
347 {"rc5-cbc", D_CBC_RC5},
349 {"idea-cbc", D_CBC_IDEA},
350 {"idea", D_CBC_IDEA},
351 {"seed-cbc", D_CBC_SEED},
352 {"seed", D_CBC_SEED},
353 {"bf-cbc", D_CBC_BF},
354 {"blowfish", D_CBC_BF},
356 {"cast-cbc", D_CBC_CAST},
357 {"cast", D_CBC_CAST},
358 {"cast5", D_CBC_CAST},
361 {"kmac128", D_KMAC128},
362 {"kmac256", D_KMAC256},
365 static double results[ALGOR_NUM][SIZE_NUM];
367 enum { R_DSA_1024, R_DSA_2048, DSA_NUM };
368 static const OPT_PAIR dsa_choices[DSA_NUM] = {
369 {"dsa1024", R_DSA_1024},
370 {"dsa2048", R_DSA_2048}
372 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
375 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
378 static const OPT_PAIR rsa_choices[RSA_NUM] = {
379 {"rsa512", R_RSA_512},
380 {"rsa1024", R_RSA_1024},
381 {"rsa2048", R_RSA_2048},
382 {"rsa3072", R_RSA_3072},
383 {"rsa4096", R_RSA_4096},
384 {"rsa7680", R_RSA_7680},
385 {"rsa15360", R_RSA_15360}
388 static double rsa_results[RSA_NUM][4]; /* 4 ops: sign, verify, encrypt, decrypt */
390 #ifndef OPENSSL_NO_DH
392 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
395 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
396 {"ffdh2048", R_FFDH_2048},
397 {"ffdh3072", R_FFDH_3072},
398 {"ffdh4096", R_FFDH_4096},
399 {"ffdh6144", R_FFDH_6144},
400 {"ffdh8192", R_FFDH_8192},
403 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
404 #endif /* OPENSSL_NO_DH */
407 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
408 #ifndef OPENSSL_NO_EC2M
409 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
410 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
412 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
413 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
415 /* list of ecdsa curves */
416 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
417 {"ecdsap160", R_EC_P160},
418 {"ecdsap192", R_EC_P192},
419 {"ecdsap224", R_EC_P224},
420 {"ecdsap256", R_EC_P256},
421 {"ecdsap384", R_EC_P384},
422 {"ecdsap521", R_EC_P521},
423 #ifndef OPENSSL_NO_EC2M
424 {"ecdsak163", R_EC_K163},
425 {"ecdsak233", R_EC_K233},
426 {"ecdsak283", R_EC_K283},
427 {"ecdsak409", R_EC_K409},
428 {"ecdsak571", R_EC_K571},
429 {"ecdsab163", R_EC_B163},
430 {"ecdsab233", R_EC_B233},
431 {"ecdsab283", R_EC_B283},
432 {"ecdsab409", R_EC_B409},
433 {"ecdsab571", R_EC_B571},
435 {"ecdsabrp256r1", R_EC_BRP256R1},
436 {"ecdsabrp256t1", R_EC_BRP256T1},
437 {"ecdsabrp384r1", R_EC_BRP384R1},
438 {"ecdsabrp384t1", R_EC_BRP384T1},
439 {"ecdsabrp512r1", R_EC_BRP512R1},
440 {"ecdsabrp512t1", R_EC_BRP512T1}
443 #ifndef OPENSSL_NO_ECX
444 R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM
449 /* list of ecdh curves, extension of |ecdsa_choices| list above */
450 static const OPT_PAIR ecdh_choices[EC_NUM] = {
451 {"ecdhp160", R_EC_P160},
452 {"ecdhp192", R_EC_P192},
453 {"ecdhp224", R_EC_P224},
454 {"ecdhp256", R_EC_P256},
455 {"ecdhp384", R_EC_P384},
456 {"ecdhp521", R_EC_P521},
457 #ifndef OPENSSL_NO_EC2M
458 {"ecdhk163", R_EC_K163},
459 {"ecdhk233", R_EC_K233},
460 {"ecdhk283", R_EC_K283},
461 {"ecdhk409", R_EC_K409},
462 {"ecdhk571", R_EC_K571},
463 {"ecdhb163", R_EC_B163},
464 {"ecdhb233", R_EC_B233},
465 {"ecdhb283", R_EC_B283},
466 {"ecdhb409", R_EC_B409},
467 {"ecdhb571", R_EC_B571},
469 {"ecdhbrp256r1", R_EC_BRP256R1},
470 {"ecdhbrp256t1", R_EC_BRP256T1},
471 {"ecdhbrp384r1", R_EC_BRP384R1},
472 {"ecdhbrp384t1", R_EC_BRP384T1},
473 {"ecdhbrp512r1", R_EC_BRP512R1},
474 {"ecdhbrp512t1", R_EC_BRP512T1},
475 #ifndef OPENSSL_NO_ECX
476 {"ecdhx25519", R_EC_X25519},
477 {"ecdhx448", R_EC_X448}
481 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
482 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
484 #ifndef OPENSSL_NO_ECX
485 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
486 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
487 {"ed25519", R_EC_Ed25519},
488 {"ed448", R_EC_Ed448}
491 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
492 #endif /* OPENSSL_NO_ECX */
494 #ifndef OPENSSL_NO_SM2
495 enum { R_EC_CURVESM2, SM2_NUM };
496 static const OPT_PAIR sm2_choices[SM2_NUM] = {
497 {"curveSM2", R_EC_CURVESM2}
499 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
500 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
501 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
502 #endif /* OPENSSL_NO_SM2 */
504 #define MAX_KEM_NUM 111
505 static size_t kems_algs_len = 0;
506 static char *kems_algname[MAX_KEM_NUM] = { NULL };
507 static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
509 #define MAX_SIG_NUM 111
510 static size_t sigs_algs_len = 0;
511 static char *sigs_algname[MAX_SIG_NUM] = { NULL };
512 static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
514 #define COND(unused_cond) (run && count < INT_MAX)
515 #define COUNT(d) (count)
517 typedef struct loopargs_st {
518 ASYNC_JOB *inprogress_job;
519 ASYNC_WAIT_CTX *wait_ctx;
522 unsigned char *buf_malloc;
523 unsigned char *buf2_malloc;
528 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
529 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
530 EVP_PKEY_CTX *rsa_encrypt_ctx[RSA_NUM];
531 EVP_PKEY_CTX *rsa_decrypt_ctx[RSA_NUM];
532 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
533 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
534 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
535 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
536 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
537 #ifndef OPENSSL_NO_ECX
538 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
539 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
540 #endif /* OPENSSL_NO_ECX */
541 #ifndef OPENSSL_NO_SM2
542 EVP_MD_CTX *sm2_ctx[SM2_NUM];
543 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
544 EVP_PKEY *sm2_pkey[SM2_NUM];
546 unsigned char *secret_a;
547 unsigned char *secret_b;
548 size_t outlen[EC_NUM];
549 #ifndef OPENSSL_NO_DH
550 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
551 unsigned char *secret_ff_a;
552 unsigned char *secret_ff_b;
556 EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM];
557 EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM];
558 EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM];
559 size_t kem_out_len[MAX_KEM_NUM];
560 size_t kem_secret_len[MAX_KEM_NUM];
561 unsigned char *kem_out[MAX_KEM_NUM];
562 unsigned char *kem_send_secret[MAX_KEM_NUM];
563 unsigned char *kem_rcv_secret[MAX_KEM_NUM];
564 EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM];
565 EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM];
566 EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM];
567 size_t sig_max_sig_len[MAX_KEM_NUM];
568 size_t sig_act_sig_len[MAX_KEM_NUM];
569 unsigned char *sig_sig[MAX_KEM_NUM];
571 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
572 loopargs_t *loopargs);
574 static unsigned int testnum;
576 static char *evp_mac_mdname = "sha256";
577 static char *evp_hmac_name = NULL;
578 static const char *evp_md_name = NULL;
579 static char *evp_mac_ciphername = "aes-128-cbc";
580 static char *evp_cmac_name = NULL;
582 static int have_md(const char *name)
587 if (opt_md_silent(name, &md)) {
588 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
590 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
592 EVP_MD_CTX_free(ctx);
598 static int have_cipher(const char *name)
601 EVP_CIPHER *cipher = NULL;
603 if (opt_cipher_silent(name, &cipher)) {
604 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
607 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
609 EVP_CIPHER_CTX_free(ctx);
610 EVP_CIPHER_free(cipher);
615 static int EVP_Digest_loop(const char *mdname, ossl_unused int algindex, void *args)
617 loopargs_t *tempargs = *(loopargs_t **) args;
618 unsigned char *buf = tempargs->buf;
619 unsigned char digest[EVP_MAX_MD_SIZE];
623 if (!opt_md_silent(mdname, &md))
625 for (count = 0; COND(c[algindex][testnum]); count++) {
626 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
636 static int EVP_Digest_md_loop(void *args)
638 return EVP_Digest_loop(evp_md_name, D_EVP, args);
641 static int EVP_Digest_MD2_loop(void *args)
643 return EVP_Digest_loop("md2", D_MD2, args);
646 static int EVP_Digest_MDC2_loop(void *args)
648 return EVP_Digest_loop("mdc2", D_MDC2, args);
651 static int EVP_Digest_MD4_loop(void *args)
653 return EVP_Digest_loop("md4", D_MD4, args);
656 static int MD5_loop(void *args)
658 return EVP_Digest_loop("md5", D_MD5, args);
661 static int mac_setup(const char *name,
662 EVP_MAC **mac, OSSL_PARAM params[],
663 loopargs_t *loopargs, unsigned int loopargs_len)
667 *mac = EVP_MAC_fetch(app_get0_libctx(), name, app_get0_propq());
671 for (i = 0; i < loopargs_len; i++) {
672 loopargs[i].mctx = EVP_MAC_CTX_new(*mac);
673 if (loopargs[i].mctx == NULL)
676 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
683 static void mac_teardown(EVP_MAC **mac,
684 loopargs_t *loopargs, unsigned int loopargs_len)
688 for (i = 0; i < loopargs_len; i++)
689 EVP_MAC_CTX_free(loopargs[i].mctx);
696 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
698 loopargs_t *tempargs = *(loopargs_t **) args;
699 unsigned char *buf = tempargs->buf;
700 EVP_MAC_CTX *mctx = tempargs->mctx;
701 unsigned char mac[EVP_MAX_MD_SIZE];
704 for (count = 0; COND(c[algindex][testnum]); count++) {
707 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
708 || !EVP_MAC_update(mctx, buf, lengths[testnum])
709 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
715 static int HMAC_loop(void *args)
717 return EVP_MAC_loop(D_HMAC, args);
720 static int CMAC_loop(void *args)
722 return EVP_MAC_loop(D_EVP_CMAC, args);
725 static int KMAC128_loop(void *args)
727 return EVP_MAC_loop(D_KMAC128, args);
730 static int KMAC256_loop(void *args)
732 return EVP_MAC_loop(D_KMAC256, args);
735 static int SHA1_loop(void *args)
737 return EVP_Digest_loop("sha1", D_SHA1, args);
740 static int SHA256_loop(void *args)
742 return EVP_Digest_loop("sha256", D_SHA256, args);
745 static int SHA512_loop(void *args)
747 return EVP_Digest_loop("sha512", D_SHA512, args);
750 static int WHIRLPOOL_loop(void *args)
752 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
755 static int EVP_Digest_RMD160_loop(void *args)
757 return EVP_Digest_loop("ripemd160", D_RMD160, args);
762 static int EVP_Cipher_loop(void *args)
764 loopargs_t *tempargs = *(loopargs_t **) args;
765 unsigned char *buf = tempargs->buf;
768 if (tempargs->ctx == NULL)
770 for (count = 0; COND(c[algindex][testnum]); count++)
771 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
776 static int GHASH_loop(void *args)
778 loopargs_t *tempargs = *(loopargs_t **) args;
779 unsigned char *buf = tempargs->buf;
780 EVP_MAC_CTX *mctx = tempargs->mctx;
783 /* just do the update in the loop to be comparable with 1.1.1 */
784 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
785 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
791 #define MAX_BLOCK_SIZE 128
793 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
795 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
796 const unsigned char *key,
799 EVP_CIPHER_CTX *ctx = NULL;
800 EVP_CIPHER *cipher = NULL;
802 if (!opt_cipher_silent(ciphername, &cipher))
805 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
808 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
809 EVP_CIPHER_CTX_free(ctx);
814 if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) {
815 EVP_CIPHER_CTX_free(ctx);
820 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
821 EVP_CIPHER_CTX_free(ctx);
827 EVP_CIPHER_free(cipher);
831 static int RAND_bytes_loop(void *args)
833 loopargs_t *tempargs = *(loopargs_t **) args;
834 unsigned char *buf = tempargs->buf;
837 for (count = 0; COND(c[D_RAND][testnum]); count++)
838 RAND_bytes(buf, lengths[testnum]);
842 static int decrypt = 0;
843 static int EVP_Update_loop(void *args)
845 loopargs_t *tempargs = *(loopargs_t **) args;
846 unsigned char *buf = tempargs->buf;
847 EVP_CIPHER_CTX *ctx = tempargs->ctx;
849 unsigned char faketag[16] = { 0xcc };
852 if (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) {
853 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(faketag), faketag);
855 for (count = 0; COND(c[D_EVP][testnum]); count++) {
856 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
858 /* reset iv in case of counter overflow */
859 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
863 for (count = 0; COND(c[D_EVP][testnum]); count++) {
864 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
866 /* reset iv in case of counter overflow */
867 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
872 rc = EVP_DecryptFinal_ex(ctx, buf, &outl);
874 rc = EVP_EncryptFinal_ex(ctx, buf, &outl);
877 BIO_printf(bio_err, "Error finalizing cipher loop\n");
882 * CCM does not support streaming. For the purpose of performance measurement,
883 * each message is encrypted using the same (key,iv)-pair. Do not use this
884 * code in your application.
886 static int EVP_Update_loop_ccm(void *args)
888 loopargs_t *tempargs = *(loopargs_t **) args;
889 unsigned char *buf = tempargs->buf;
890 EVP_CIPHER_CTX *ctx = tempargs->ctx;
891 int outl, count, realcount = 0, final;
892 unsigned char tag[12];
895 for (count = 0; COND(c[D_EVP][testnum]); count++) {
896 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
899 && EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
900 /* counter is reset on every update */
901 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
905 for (count = 0; COND(c[D_EVP][testnum]); count++) {
906 /* restore iv length field */
907 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]) > 0
908 /* counter is reset on every update */
909 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
914 final = EVP_DecryptFinal_ex(ctx, buf, &outl);
916 final = EVP_EncryptFinal_ex(ctx, buf, &outl);
919 BIO_printf(bio_err, "Error finalizing ccm loop\n");
924 * To make AEAD benchmarking more relevant perform TLS-like operations,
925 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
926 * payload length is not actually limited by 16KB...
928 static int EVP_Update_loop_aead(void *args)
930 loopargs_t *tempargs = *(loopargs_t **) args;
931 unsigned char *buf = tempargs->buf;
932 EVP_CIPHER_CTX *ctx = tempargs->ctx;
933 int outl, count, realcount = 0;
934 unsigned char aad[13] = { 0xcc };
935 unsigned char faketag[16] = { 0xcc };
938 for (count = 0; COND(c[D_EVP][testnum]); count++) {
939 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
940 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
941 sizeof(faketag), faketag) > 0
942 && EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
943 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
944 && EVP_DecryptFinal_ex(ctx, buf + outl, &outl) > 0)
948 for (count = 0; COND(c[D_EVP][testnum]); count++) {
949 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
950 && EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
951 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
952 && EVP_EncryptFinal_ex(ctx, buf + outl, &outl) > 0)
959 static int RSA_sign_loop(void *args)
961 loopargs_t *tempargs = *(loopargs_t **) args;
962 unsigned char *buf = tempargs->buf;
963 unsigned char *buf2 = tempargs->buf2;
964 size_t *rsa_num = &tempargs->sigsize;
965 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
968 for (count = 0; COND(rsa_c[testnum][0]); count++) {
969 *rsa_num = tempargs->buflen;
970 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
972 BIO_printf(bio_err, "RSA sign failure\n");
973 ERR_print_errors(bio_err);
981 static int RSA_verify_loop(void *args)
983 loopargs_t *tempargs = *(loopargs_t **) args;
984 unsigned char *buf = tempargs->buf;
985 unsigned char *buf2 = tempargs->buf2;
986 size_t rsa_num = tempargs->sigsize;
987 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
990 for (count = 0; COND(rsa_c[testnum][1]); count++) {
991 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
993 BIO_printf(bio_err, "RSA verify failure\n");
994 ERR_print_errors(bio_err);
1002 static int RSA_encrypt_loop(void *args)
1004 loopargs_t *tempargs = *(loopargs_t **) args;
1005 unsigned char *buf = tempargs->buf;
1006 unsigned char *buf2 = tempargs->buf2;
1007 size_t *rsa_num = &tempargs->encsize;
1008 EVP_PKEY_CTX **rsa_encrypt_ctx = tempargs->rsa_encrypt_ctx;
1011 for (count = 0; COND(rsa_c[testnum][2]); count++) {
1012 *rsa_num = tempargs->buflen;
1013 ret = EVP_PKEY_encrypt(rsa_encrypt_ctx[testnum], buf2, rsa_num, buf, 36);
1015 BIO_printf(bio_err, "RSA encrypt failure\n");
1016 ERR_print_errors(bio_err);
1024 static int RSA_decrypt_loop(void *args)
1026 loopargs_t *tempargs = *(loopargs_t **) args;
1027 unsigned char *buf = tempargs->buf;
1028 unsigned char *buf2 = tempargs->buf2;
1030 EVP_PKEY_CTX **rsa_decrypt_ctx = tempargs->rsa_decrypt_ctx;
1033 for (count = 0; COND(rsa_c[testnum][3]); count++) {
1034 rsa_num = tempargs->buflen;
1035 ret = EVP_PKEY_decrypt(rsa_decrypt_ctx[testnum], buf, &rsa_num, buf2, tempargs->encsize);
1037 BIO_printf(bio_err, "RSA decrypt failure\n");
1038 ERR_print_errors(bio_err);
1046 #ifndef OPENSSL_NO_DH
1048 static int FFDH_derive_key_loop(void *args)
1050 loopargs_t *tempargs = *(loopargs_t **) args;
1051 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
1052 unsigned char *derived_secret = tempargs->secret_ff_a;
1055 for (count = 0; COND(ffdh_c[testnum][0]); count++) {
1056 /* outlen can be overwritten with a too small value (no padding used) */
1057 size_t outlen = MAX_FFDH_SIZE;
1059 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
1063 #endif /* OPENSSL_NO_DH */
1065 static int DSA_sign_loop(void *args)
1067 loopargs_t *tempargs = *(loopargs_t **) args;
1068 unsigned char *buf = tempargs->buf;
1069 unsigned char *buf2 = tempargs->buf2;
1070 size_t *dsa_num = &tempargs->sigsize;
1071 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
1074 for (count = 0; COND(dsa_c[testnum][0]); count++) {
1075 *dsa_num = tempargs->buflen;
1076 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
1078 BIO_printf(bio_err, "DSA sign failure\n");
1079 ERR_print_errors(bio_err);
1087 static int DSA_verify_loop(void *args)
1089 loopargs_t *tempargs = *(loopargs_t **) args;
1090 unsigned char *buf = tempargs->buf;
1091 unsigned char *buf2 = tempargs->buf2;
1092 size_t dsa_num = tempargs->sigsize;
1093 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
1096 for (count = 0; COND(dsa_c[testnum][1]); count++) {
1097 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
1099 BIO_printf(bio_err, "DSA verify failure\n");
1100 ERR_print_errors(bio_err);
1108 static int ECDSA_sign_loop(void *args)
1110 loopargs_t *tempargs = *(loopargs_t **) args;
1111 unsigned char *buf = tempargs->buf;
1112 unsigned char *buf2 = tempargs->buf2;
1113 size_t *ecdsa_num = &tempargs->sigsize;
1114 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
1117 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
1118 *ecdsa_num = tempargs->buflen;
1119 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
1121 BIO_printf(bio_err, "ECDSA sign failure\n");
1122 ERR_print_errors(bio_err);
1130 static int ECDSA_verify_loop(void *args)
1132 loopargs_t *tempargs = *(loopargs_t **) args;
1133 unsigned char *buf = tempargs->buf;
1134 unsigned char *buf2 = tempargs->buf2;
1135 size_t ecdsa_num = tempargs->sigsize;
1136 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
1139 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
1140 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
1143 BIO_printf(bio_err, "ECDSA verify failure\n");
1144 ERR_print_errors(bio_err);
1152 /* ******************************************************************** */
1154 static int ECDH_EVP_derive_key_loop(void *args)
1156 loopargs_t *tempargs = *(loopargs_t **) args;
1157 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
1158 unsigned char *derived_secret = tempargs->secret_a;
1160 size_t *outlen = &(tempargs->outlen[testnum]);
1162 for (count = 0; COND(ecdh_c[testnum][0]); count++)
1163 EVP_PKEY_derive(ctx, derived_secret, outlen);
1168 #ifndef OPENSSL_NO_ECX
1169 static int EdDSA_sign_loop(void *args)
1171 loopargs_t *tempargs = *(loopargs_t **) args;
1172 unsigned char *buf = tempargs->buf;
1173 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1174 unsigned char *eddsasig = tempargs->buf2;
1175 size_t *eddsasigsize = &tempargs->sigsize;
1178 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1179 ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
1181 BIO_printf(bio_err, "EdDSA sign init failure\n");
1182 ERR_print_errors(bio_err);
1186 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1188 BIO_printf(bio_err, "EdDSA sign failure\n");
1189 ERR_print_errors(bio_err);
1197 static int EdDSA_verify_loop(void *args)
1199 loopargs_t *tempargs = *(loopargs_t **) args;
1200 unsigned char *buf = tempargs->buf;
1201 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1202 unsigned char *eddsasig = tempargs->buf2;
1203 size_t eddsasigsize = tempargs->sigsize;
1206 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1207 ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
1209 BIO_printf(bio_err, "EdDSA verify init failure\n");
1210 ERR_print_errors(bio_err);
1214 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1216 BIO_printf(bio_err, "EdDSA verify failure\n");
1217 ERR_print_errors(bio_err);
1224 #endif /* OPENSSL_NO_ECX */
1226 #ifndef OPENSSL_NO_SM2
1227 static int SM2_sign_loop(void *args)
1229 loopargs_t *tempargs = *(loopargs_t **) args;
1230 unsigned char *buf = tempargs->buf;
1231 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1232 unsigned char *sm2sig = tempargs->buf2;
1235 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1236 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1238 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1239 sm2sigsize = max_size;
1241 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1242 NULL, sm2_pkey[testnum])) {
1243 BIO_printf(bio_err, "SM2 init sign failure\n");
1244 ERR_print_errors(bio_err);
1248 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1251 BIO_printf(bio_err, "SM2 sign failure\n");
1252 ERR_print_errors(bio_err);
1256 /* update the latest returned size and always use the fixed buffer size */
1257 tempargs->sigsize = sm2sigsize;
1263 static int SM2_verify_loop(void *args)
1265 loopargs_t *tempargs = *(loopargs_t **) args;
1266 unsigned char *buf = tempargs->buf;
1267 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1268 unsigned char *sm2sig = tempargs->buf2;
1269 size_t sm2sigsize = tempargs->sigsize;
1271 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1273 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1274 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1275 NULL, sm2_pkey[testnum])) {
1276 BIO_printf(bio_err, "SM2 verify init failure\n");
1277 ERR_print_errors(bio_err);
1281 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1284 BIO_printf(bio_err, "SM2 verify failure\n");
1285 ERR_print_errors(bio_err);
1292 #endif /* OPENSSL_NO_SM2 */
1294 static int KEM_keygen_loop(void *args)
1296 loopargs_t *tempargs = *(loopargs_t **) args;
1297 EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum];
1298 EVP_PKEY *pkey = NULL;
1301 for (count = 0; COND(kems_c[testnum][0]); count++) {
1302 if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
1305 * runtime defined to quite some degree by randomness,
1306 * so performance overhead of _free doesn't impact
1307 * results significantly. In any case this test is
1308 * meant to permit relative algorithm performance
1311 EVP_PKEY_free(pkey);
1317 static int KEM_encaps_loop(void *args)
1319 loopargs_t *tempargs = *(loopargs_t **) args;
1320 EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum];
1321 size_t out_len = tempargs->kem_out_len[testnum];
1322 size_t secret_len = tempargs->kem_secret_len[testnum];
1323 unsigned char *out = tempargs->kem_out[testnum];
1324 unsigned char *secret = tempargs->kem_send_secret[testnum];
1327 for (count = 0; COND(kems_c[testnum][1]); count++) {
1328 if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0)
1334 static int KEM_decaps_loop(void *args)
1336 loopargs_t *tempargs = *(loopargs_t **) args;
1337 EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum];
1338 size_t out_len = tempargs->kem_out_len[testnum];
1339 size_t secret_len = tempargs->kem_secret_len[testnum];
1340 unsigned char *out = tempargs->kem_out[testnum];
1341 unsigned char *secret = tempargs->kem_send_secret[testnum];
1344 for (count = 0; COND(kems_c[testnum][2]); count++) {
1345 if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0)
1351 static int SIG_keygen_loop(void *args)
1353 loopargs_t *tempargs = *(loopargs_t **) args;
1354 EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum];
1355 EVP_PKEY *pkey = NULL;
1358 for (count = 0; COND(kems_c[testnum][0]); count++) {
1359 EVP_PKEY_keygen(ctx, &pkey);
1360 /* TBD: How much does free influence runtime? */
1361 EVP_PKEY_free(pkey);
1367 static int SIG_sign_loop(void *args)
1369 loopargs_t *tempargs = *(loopargs_t **) args;
1370 EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum];
1371 /* be sure to not change stored sig: */
1372 unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum],
1374 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1375 size_t md_len = SHA256_DIGEST_LENGTH;
1378 for (count = 0; COND(kems_c[testnum][1]); count++) {
1379 size_t sig_len = tempargs->sig_max_sig_len[testnum];
1380 int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len);
1383 BIO_printf(bio_err, "SIG sign failure at count %d\n", count);
1384 ERR_print_errors(bio_err);
1393 static int SIG_verify_loop(void *args)
1395 loopargs_t *tempargs = *(loopargs_t **) args;
1396 EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum];
1397 size_t sig_len = tempargs->sig_act_sig_len[testnum];
1398 unsigned char *sig = tempargs->sig_sig[testnum];
1399 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1400 size_t md_len = SHA256_DIGEST_LENGTH;
1403 for (count = 0; COND(kems_c[testnum][2]); count++) {
1404 int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len);
1407 BIO_printf(bio_err, "SIG verify failure at count %d\n", count);
1408 ERR_print_errors(bio_err);
1417 static int run_benchmark(int async_jobs,
1418 int (*loop_function) (void *), loopargs_t *loopargs)
1420 int job_op_count = 0;
1421 int total_op_count = 0;
1422 int num_inprogress = 0;
1423 int error = 0, i = 0, ret = 0;
1424 OSSL_ASYNC_FD job_fd = 0;
1425 size_t num_job_fds = 0;
1427 if (async_jobs == 0) {
1428 return loop_function((void *)&loopargs);
1431 for (i = 0; i < async_jobs && !error; i++) {
1432 loopargs_t *looparg_item = loopargs + i;
1434 /* Copy pointer content (looparg_t item address) into async context */
1435 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1436 &job_op_count, loop_function,
1437 (void *)&looparg_item, sizeof(looparg_item));
1443 if (job_op_count == -1) {
1446 total_op_count += job_op_count;
1451 BIO_printf(bio_err, "Failure in the job\n");
1452 ERR_print_errors(bio_err);
1458 while (num_inprogress > 0) {
1459 #if defined(OPENSSL_SYS_WINDOWS)
1461 #elif defined(OPENSSL_SYS_UNIX)
1462 int select_result = 0;
1463 OSSL_ASYNC_FD max_fd = 0;
1466 FD_ZERO(&waitfdset);
1468 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1469 if (loopargs[i].inprogress_job == NULL)
1472 if (!ASYNC_WAIT_CTX_get_all_fds
1473 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1474 || num_job_fds > 1) {
1475 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1476 ERR_print_errors(bio_err);
1480 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1482 FD_SET(job_fd, &waitfdset);
1483 if (job_fd > max_fd)
1487 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1489 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1490 "Decrease the value of async_jobs\n",
1491 max_fd, FD_SETSIZE);
1492 ERR_print_errors(bio_err);
1497 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1498 if (select_result == -1 && errno == EINTR)
1501 if (select_result == -1) {
1502 BIO_printf(bio_err, "Failure in the select\n");
1503 ERR_print_errors(bio_err);
1508 if (select_result == 0)
1512 for (i = 0; i < async_jobs; i++) {
1513 if (loopargs[i].inprogress_job == NULL)
1516 if (!ASYNC_WAIT_CTX_get_all_fds
1517 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1518 || num_job_fds > 1) {
1519 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1520 ERR_print_errors(bio_err);
1524 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1527 #if defined(OPENSSL_SYS_UNIX)
1528 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1530 #elif defined(OPENSSL_SYS_WINDOWS)
1531 if (num_job_fds == 1
1532 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1537 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1538 loopargs[i].wait_ctx, &job_op_count,
1539 loop_function, (void *)(loopargs + i),
1540 sizeof(loopargs_t));
1545 if (job_op_count == -1) {
1548 total_op_count += job_op_count;
1551 loopargs[i].inprogress_job = NULL;
1556 loopargs[i].inprogress_job = NULL;
1557 BIO_printf(bio_err, "Failure in the job\n");
1558 ERR_print_errors(bio_err);
1565 return error ? -1 : total_op_count;
1568 typedef struct ec_curve_st {
1572 size_t sigsize; /* only used for EdDSA curves */
1575 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1577 EVP_PKEY_CTX *kctx = NULL;
1578 EVP_PKEY *key = NULL;
1580 /* Ensure that the error queue is empty */
1581 if (ERR_peek_error()) {
1583 "WARNING: the error queue contains previous unhandled errors.\n");
1584 ERR_print_errors(bio_err);
1588 * Let's try to create a ctx directly from the NID: this works for
1589 * curves like Curve25519 that are not implemented through the low
1590 * level EC interface.
1591 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1592 * then we set the curve by NID before deriving the actual keygen
1593 * ctx for that specific curve.
1595 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1597 EVP_PKEY_CTX *pctx = NULL;
1598 EVP_PKEY *params = NULL;
1600 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1601 * "int_ctx_new:unsupported algorithm" error was added to the
1603 * We remove it from the error queue as we are handling it.
1605 unsigned long error = ERR_peek_error();
1607 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1608 /* check that the error origin matches */
1609 && ERR_GET_LIB(error) == ERR_LIB_EVP
1610 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1611 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1612 ERR_get_error(); /* pop error from queue */
1613 if (ERR_peek_error()) {
1615 "Unhandled error in the error queue during EC key setup.\n");
1616 ERR_print_errors(bio_err);
1620 /* Create the context for parameter generation */
1621 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1622 || EVP_PKEY_paramgen_init(pctx) <= 0
1623 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1625 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) {
1626 BIO_printf(bio_err, "EC params init failure.\n");
1627 ERR_print_errors(bio_err);
1628 EVP_PKEY_CTX_free(pctx);
1631 EVP_PKEY_CTX_free(pctx);
1633 /* Create the context for the key generation */
1634 kctx = EVP_PKEY_CTX_new(params, NULL);
1635 EVP_PKEY_free(params);
1638 || EVP_PKEY_keygen_init(kctx) <= 0
1639 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1640 BIO_printf(bio_err, "EC key generation failure.\n");
1641 ERR_print_errors(bio_err);
1644 EVP_PKEY_CTX_free(kctx);
1648 #define stop_it(do_it, test_num)\
1649 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1651 /* Checks to see if algorithms are fetchable */
1652 #define IS_FETCHABLE(type, TYPE) \
1653 static int is_ ## type ## _fetchable(const TYPE *alg) \
1656 const char *propq = app_get0_propq(); \
1657 OSSL_LIB_CTX *libctx = app_get0_libctx(); \
1658 const char *name = TYPE ## _get0_name(alg); \
1661 impl = TYPE ## _fetch(libctx, name, propq); \
1662 ERR_pop_to_mark(); \
1665 TYPE ## _free(impl); \
1669 IS_FETCHABLE(signature, EVP_SIGNATURE)
1670 IS_FETCHABLE(kem, EVP_KEM)
1672 DEFINE_STACK_OF(EVP_KEM)
1674 static int kems_cmp(const EVP_KEM * const *a,
1675 const EVP_KEM * const *b)
1677 return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
1678 OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
1681 static void collect_kem(EVP_KEM *kem, void *stack)
1683 STACK_OF(EVP_KEM) *kem_stack = stack;
1685 if (is_kem_fetchable(kem)
1686 && sk_EVP_KEM_push(kem_stack, kem) > 0) {
1687 EVP_KEM_up_ref(kem);
1691 static int kem_locate(const char *algo, unsigned int *idx)
1695 for (i = 0; i < kems_algs_len; i++) {
1696 if (strcmp(kems_algname[i], algo) == 0) {
1704 DEFINE_STACK_OF(EVP_SIGNATURE)
1706 static int signatures_cmp(const EVP_SIGNATURE * const *a,
1707 const EVP_SIGNATURE * const *b)
1709 return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
1710 OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
1713 static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
1715 STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
1717 if (is_signature_fetchable(sig)
1718 && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
1719 EVP_SIGNATURE_up_ref(sig);
1722 static int sig_locate(const char *algo, unsigned int *idx)
1726 for (i = 0; i < sigs_algs_len; i++) {
1727 if (strcmp(sigs_algname[i], algo) == 0) {
1735 static int get_max(const uint8_t doit[], size_t algs_len) {
1739 for (i = 0; i < algs_len; i++)
1740 if (maxcnt < doit[i]) maxcnt = doit[i];
1744 int speed_main(int argc, char **argv)
1748 loopargs_t *loopargs = NULL;
1750 const char *engine_id = NULL;
1751 EVP_CIPHER *evp_cipher = NULL;
1752 EVP_MAC *mac = NULL;
1755 int async_init = 0, multiblock = 0, pr_header = 0;
1756 uint8_t doit[ALGOR_NUM] = { 0 };
1757 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1758 STACK_OF(EVP_KEM) *kem_stack = NULL;
1759 STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
1761 unsigned int size_num = SIZE_NUM;
1762 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1768 EVP_PKEY_CTX *genctx = NULL;
1773 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1774 ECDSA_SECONDS, ECDH_SECONDS,
1775 EdDSA_SECONDS, SM2_SECONDS,
1776 FFDH_SECONDS, KEM_SECONDS,
1779 static const unsigned char key32[32] = {
1780 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1781 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1782 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1783 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1785 static const unsigned char deskey[] = {
1786 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1787 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1788 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1790 static const struct {
1791 const unsigned char *data;
1792 unsigned int length;
1795 { test512, sizeof(test512), 512 },
1796 { test1024, sizeof(test1024), 1024 },
1797 { test2048, sizeof(test2048), 2048 },
1798 { test3072, sizeof(test3072), 3072 },
1799 { test4096, sizeof(test4096), 4096 },
1800 { test7680, sizeof(test7680), 7680 },
1801 { test15360, sizeof(test15360), 15360 }
1803 uint8_t rsa_doit[RSA_NUM] = { 0 };
1804 int primes = RSA_DEFAULT_PRIME_NUM;
1805 #ifndef OPENSSL_NO_DH
1806 typedef struct ffdh_params_st {
1812 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1813 {"ffdh2048", NID_ffdhe2048, 2048},
1814 {"ffdh3072", NID_ffdhe3072, 3072},
1815 {"ffdh4096", NID_ffdhe4096, 4096},
1816 {"ffdh6144", NID_ffdhe6144, 6144},
1817 {"ffdh8192", NID_ffdhe8192, 8192}
1819 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1821 #endif /* OPENSSL_NO_DH */
1822 static const unsigned int dsa_bits[DSA_NUM] = { 1024, 2048 };
1823 uint8_t dsa_doit[DSA_NUM] = { 0 };
1825 * We only test over the following curves as they are representative, To
1826 * add tests over more curves, simply add the curve NID and curve name to
1827 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1828 * lists accordingly.
1830 static const EC_CURVE ec_curves[EC_NUM] = {
1832 {"secp160r1", NID_secp160r1, 160},
1833 {"nistp192", NID_X9_62_prime192v1, 192},
1834 {"nistp224", NID_secp224r1, 224},
1835 {"nistp256", NID_X9_62_prime256v1, 256},
1836 {"nistp384", NID_secp384r1, 384},
1837 {"nistp521", NID_secp521r1, 521},
1838 #ifndef OPENSSL_NO_EC2M
1840 {"nistk163", NID_sect163k1, 163},
1841 {"nistk233", NID_sect233k1, 233},
1842 {"nistk283", NID_sect283k1, 283},
1843 {"nistk409", NID_sect409k1, 409},
1844 {"nistk571", NID_sect571k1, 571},
1845 {"nistb163", NID_sect163r2, 163},
1846 {"nistb233", NID_sect233r1, 233},
1847 {"nistb283", NID_sect283r1, 283},
1848 {"nistb409", NID_sect409r1, 409},
1849 {"nistb571", NID_sect571r1, 571},
1851 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1852 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1853 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1854 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1855 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1856 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1857 #ifndef OPENSSL_NO_ECX
1858 /* Other and ECDH only ones */
1859 {"X25519", NID_X25519, 253},
1860 {"X448", NID_X448, 448}
1863 #ifndef OPENSSL_NO_ECX
1864 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1866 {"Ed25519", NID_ED25519, 253, 64},
1867 {"Ed448", NID_ED448, 456, 114}
1869 #endif /* OPENSSL_NO_ECX */
1870 #ifndef OPENSSL_NO_SM2
1871 static const EC_CURVE sm2_curves[SM2_NUM] = {
1873 {"CurveSM2", NID_sm2, 256}
1875 uint8_t sm2_doit[SM2_NUM] = { 0 };
1877 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1878 uint8_t ecdh_doit[EC_NUM] = { 0 };
1879 #ifndef OPENSSL_NO_ECX
1880 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1881 #endif /* OPENSSL_NO_ECX */
1883 uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
1884 uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
1886 uint8_t do_kems = 0;
1887 uint8_t do_sigs = 0;
1889 /* checks declared curves against choices list. */
1890 #ifndef OPENSSL_NO_ECX
1891 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1892 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1894 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1895 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1897 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1898 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1899 #endif /* OPENSSL_NO_ECX */
1901 #ifndef OPENSSL_NO_SM2
1902 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1903 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1906 prog = opt_init(argc, argv, speed_options);
1907 while ((o = opt_next()) != OPT_EOF) {
1912 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1915 opt_help(speed_options);
1923 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1927 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1928 if (have_md(opt_arg()))
1929 evp_md_name = opt_arg();
1931 if (evp_cipher == NULL && evp_md_name == NULL) {
1932 ERR_clear_last_mark();
1934 "%s: %s is an unknown cipher or digest\n",
1942 if (!have_md(opt_arg())) {
1943 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1947 evp_mac_mdname = opt_arg();
1951 if (!have_cipher(opt_arg())) {
1952 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1956 evp_mac_ciphername = opt_arg();
1957 doit[D_EVP_CMAC] = 1;
1964 * In a forked execution, an engine might need to be
1965 * initialised by each child process, not by the parent.
1966 * So store the name here and run setup_engine() later on.
1968 engine_id = opt_arg();
1972 multi = opt_int_arg();
1973 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1974 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1980 #ifndef OPENSSL_NO_ASYNC
1981 async_jobs = opt_int_arg();
1982 if (!ASYNC_is_capable()) {
1984 "%s: async_jobs specified but async not supported\n",
1988 if (async_jobs > 99999) {
1989 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1995 misalign = opt_int_arg();
1996 if (misalign > MISALIGN) {
1998 "%s: Maximum offset is %d\n", prog, MISALIGN);
2007 #ifdef OPENSSL_NO_MULTIBLOCK
2009 "%s: -mb specified but multi-block support is disabled\n",
2018 case OPT_PROV_CASES:
2019 if (!opt_provider(o))
2023 conf = app_load_config_modules(opt_arg());
2028 primes = opt_int_arg();
2031 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
2032 = seconds.ecdh = seconds.eddsa
2033 = seconds.sm2 = seconds.ffdh
2034 = seconds.kem = seconds.sig = opt_int_arg();
2037 lengths_single = opt_int_arg();
2038 lengths = &lengths_single;
2052 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
2054 "%s: -mlock not supported on this platform\n",
2062 /* find all KEMs currently available */
2063 kem_stack = sk_EVP_KEM_new(kems_cmp);
2064 EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
2068 for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) {
2069 EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx);
2071 if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) {
2072 if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) {
2074 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2077 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2078 kems_doit[kems_algs_len] = 1;
2079 kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2081 } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) {
2082 if (kems_algs_len + 3 >= MAX_KEM_NUM) {
2084 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2087 kems_doit[kems_algs_len] = 1;
2088 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256");
2089 kems_doit[kems_algs_len] = 1;
2090 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384");
2091 kems_doit[kems_algs_len] = 1;
2092 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521");
2094 if (kems_algs_len + 1 >= MAX_KEM_NUM) {
2096 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2099 kems_doit[kems_algs_len] = 1;
2100 kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem));
2103 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
2106 /* find all SIGNATUREs currently available */
2107 sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp);
2108 EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack);
2112 for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) {
2113 EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx);
2114 const char *sig_name = EVP_SIGNATURE_get0_name(s);
2116 if (strcmp(sig_name, "RSA") == 0) {
2117 if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) {
2119 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2122 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2123 sigs_doit[sigs_algs_len] = 1;
2124 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2127 else if (strcmp(sig_name, "DSA") == 0) {
2128 if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) {
2130 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2133 for (i = 0; i < DSA_NUM; i++) {
2134 sigs_doit[sigs_algs_len] = 1;
2135 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name);
2138 /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2139 else if (strcmp(sig_name, "ED25519") &&
2140 strcmp(sig_name, "ED448") &&
2141 strcmp(sig_name, "ECDSA") &&
2142 strcmp(sig_name, "HMAC") &&
2143 strcmp(sig_name, "SIPHASH") &&
2144 strcmp(sig_name, "POLY1305") &&
2145 strcmp(sig_name, "CMAC") &&
2146 strcmp(sig_name, "SM2")) { /* skip alg */
2147 if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
2149 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2152 /* activate this provider algorithm */
2153 sigs_doit[sigs_algs_len] = 1;
2154 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name);
2157 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
2160 /* Remaining arguments are algorithms. */
2161 argc = opt_num_rest();
2164 if (!app_RAND_load())
2167 for (; *argv; argv++) {
2168 const char *algo = *argv;
2171 if (opt_found(algo, doit_choices, &i)) {
2175 if (strcmp(algo, "des") == 0) {
2176 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
2179 if (strcmp(algo, "sha") == 0) {
2180 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
2183 #ifndef OPENSSL_NO_DEPRECATED_3_0
2184 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
2187 if (HAS_PREFIX(algo, "rsa")) {
2188 if (algo[sizeof("rsa") - 1] == '\0') {
2189 memset(rsa_doit, 1, sizeof(rsa_doit));
2192 if (opt_found(algo, rsa_choices, &i)) {
2197 #ifndef OPENSSL_NO_DH
2198 if (HAS_PREFIX(algo, "ffdh")) {
2199 if (algo[sizeof("ffdh") - 1] == '\0') {
2200 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2203 if (opt_found(algo, ffdh_choices, &i)) {
2209 if (HAS_PREFIX(algo, "dsa")) {
2210 if (algo[sizeof("dsa") - 1] == '\0') {
2211 memset(dsa_doit, 1, sizeof(dsa_doit));
2214 if (opt_found(algo, dsa_choices, &i)) {
2219 if (strcmp(algo, "aes") == 0) {
2220 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
2223 if (strcmp(algo, "camellia") == 0) {
2224 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
2227 if (HAS_PREFIX(algo, "ecdsa")) {
2228 if (algo[sizeof("ecdsa") - 1] == '\0') {
2229 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2232 if (opt_found(algo, ecdsa_choices, &i)) {
2237 if (HAS_PREFIX(algo, "ecdh")) {
2238 if (algo[sizeof("ecdh") - 1] == '\0') {
2239 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2242 if (opt_found(algo, ecdh_choices, &i)) {
2247 #ifndef OPENSSL_NO_ECX
2248 if (strcmp(algo, "eddsa") == 0) {
2249 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2252 if (opt_found(algo, eddsa_choices, &i)) {
2256 #endif /* OPENSSL_NO_ECX */
2257 #ifndef OPENSSL_NO_SM2
2258 if (strcmp(algo, "sm2") == 0) {
2259 memset(sm2_doit, 1, sizeof(sm2_doit));
2262 if (opt_found(algo, sm2_choices, &i)) {
2267 if (kem_locate(algo, &idx)) {
2272 if (sig_locate(algo, &idx)) {
2277 if (strcmp(algo, "kmac") == 0) {
2278 doit[D_KMAC128] = doit[D_KMAC256] = 1;
2281 if (strcmp(algo, "cmac") == 0) {
2282 doit[D_EVP_CMAC] = 1;
2287 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
2294 if (evp_cipher == NULL) {
2295 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
2297 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2298 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2299 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
2300 EVP_CIPHER_get0_name(evp_cipher));
2304 if (kems_algs_len > 0) {
2305 int maxcnt = get_max(kems_doit, kems_algs_len);
2308 /* some algs explicitly selected */
2309 for (i = 0; i < kems_algs_len; i++) {
2310 /* disable the rest */
2315 if (sigs_algs_len > 0) {
2316 int maxcnt = get_max(sigs_doit, sigs_algs_len);
2319 /* some algs explicitly selected */
2320 for (i = 0; i < sigs_algs_len; i++) {
2321 /* disable the rest */
2327 if (evp_cipher == NULL) {
2328 BIO_printf(bio_err, "-mb can be used only with a multi-block"
2329 " capable cipher\n");
2331 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2332 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2333 BIO_printf(bio_err, "%s is not a multi-block capable\n",
2334 EVP_CIPHER_get0_name(evp_cipher));
2336 } else if (async_jobs > 0) {
2337 BIO_printf(bio_err, "Async mode is not supported with -mb");
2342 /* Initialize the job pool if async mode is enabled */
2343 if (async_jobs > 0) {
2344 async_init = ASYNC_init_thread(async_jobs, async_jobs);
2346 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
2351 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
2353 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
2354 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
2356 buflen = lengths[size_num - 1];
2357 if (buflen < 36) /* size of random vector in RSA benchmark */
2359 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
2360 BIO_printf(bio_err, "Error: buffer size too large\n");
2363 buflen += MAX_MISALIGNMENT + 1;
2364 for (i = 0; i < loopargs_len; i++) {
2365 if (async_jobs > 0) {
2366 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
2367 if (loopargs[i].wait_ctx == NULL) {
2368 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
2373 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
2374 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
2376 /* Align the start of buffers on a 64 byte boundary */
2377 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
2378 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
2379 loopargs[i].buflen = buflen - misalign;
2380 loopargs[i].sigsize = buflen - misalign;
2381 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
2382 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
2383 #ifndef OPENSSL_NO_DH
2384 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
2385 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
2390 if (multi && do_multi(multi, size_num))
2394 for (i = 0; i < loopargs_len; ++i) {
2397 (void)VirtualLock(loopargs[i].buf_malloc, buflen);
2398 (void)VirtualLock(loopargs[i].buf2_malloc, buflen);
2399 #elif defined(OPENSSL_SYS_LINUX)
2400 (void)mlock(loopargs[i].buf_malloc, buflen);
2401 (void)mlock(loopargs[i].buf_malloc, buflen);
2404 memset(loopargs[i].buf_malloc, 0, buflen);
2405 memset(loopargs[i].buf2_malloc, 0, buflen);
2408 /* Initialize the engine after the fork */
2409 e = setup_engine(engine_id, 0);
2411 /* No parameters; turn on everything. */
2412 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC]
2413 && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) {
2414 memset(doit, 1, sizeof(doit));
2415 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
2417 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
2418 if (!have_md(names[i]))
2421 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
2422 if (!have_cipher(names[i]))
2425 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2426 app_get0_propq())) != NULL) {
2432 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2433 app_get0_propq())) != NULL) {
2440 memset(rsa_doit, 1, sizeof(rsa_doit));
2441 #ifndef OPENSSL_NO_DH
2442 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2444 memset(dsa_doit, 1, sizeof(dsa_doit));
2445 #ifndef OPENSSL_NO_ECX
2446 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2447 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2448 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2449 #endif /* OPENSSL_NO_ECX */
2450 #ifndef OPENSSL_NO_SM2
2451 memset(sm2_doit, 1, sizeof(sm2_doit));
2453 memset(kems_doit, 1, sizeof(kems_doit));
2455 memset(sigs_doit, 1, sizeof(sigs_doit));
2458 for (i = 0; i < ALGOR_NUM; i++)
2462 if (usertime == 0 && !mr)
2464 "You have chosen to measure elapsed time "
2465 "instead of user CPU time.\n");
2468 signal(SIGALRM, alarmed);
2472 for (testnum = 0; testnum < size_num; testnum++) {
2473 print_message(names[D_MD2], lengths[testnum], seconds.sym);
2475 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
2477 print_result(D_MD2, testnum, count, d);
2484 for (testnum = 0; testnum < size_num; testnum++) {
2485 print_message(names[D_MDC2], lengths[testnum], seconds.sym);
2487 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
2489 print_result(D_MDC2, testnum, count, d);
2496 for (testnum = 0; testnum < size_num; testnum++) {
2497 print_message(names[D_MD4], lengths[testnum], seconds.sym);
2499 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
2501 print_result(D_MD4, testnum, count, d);
2508 for (testnum = 0; testnum < size_num; testnum++) {
2509 print_message(names[D_MD5], lengths[testnum], seconds.sym);
2511 count = run_benchmark(async_jobs, MD5_loop, loopargs);
2513 print_result(D_MD5, testnum, count, d);
2520 for (testnum = 0; testnum < size_num; testnum++) {
2521 print_message(names[D_SHA1], lengths[testnum], seconds.sym);
2523 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
2525 print_result(D_SHA1, testnum, count, d);
2531 if (doit[D_SHA256]) {
2532 for (testnum = 0; testnum < size_num; testnum++) {
2533 print_message(names[D_SHA256], lengths[testnum], seconds.sym);
2535 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
2537 print_result(D_SHA256, testnum, count, d);
2543 if (doit[D_SHA512]) {
2544 for (testnum = 0; testnum < size_num; testnum++) {
2545 print_message(names[D_SHA512], lengths[testnum], seconds.sym);
2547 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
2549 print_result(D_SHA512, testnum, count, d);
2555 if (doit[D_WHIRLPOOL]) {
2556 for (testnum = 0; testnum < size_num; testnum++) {
2557 print_message(names[D_WHIRLPOOL], lengths[testnum], seconds.sym);
2559 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
2561 print_result(D_WHIRLPOOL, testnum, count, d);
2567 if (doit[D_RMD160]) {
2568 for (testnum = 0; testnum < size_num; testnum++) {
2569 print_message(names[D_RMD160], lengths[testnum], seconds.sym);
2571 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
2573 print_result(D_RMD160, testnum, count, d);
2580 static const char hmac_key[] = "This is a key...";
2581 int len = strlen(hmac_key);
2582 OSSL_PARAM params[3];
2584 if (evp_mac_mdname == NULL)
2586 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
2588 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
2589 names[D_HMAC] = evp_hmac_name;
2592 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2595 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2596 (char *)hmac_key, len);
2597 params[2] = OSSL_PARAM_construct_end();
2599 if (mac_setup("HMAC", &mac, params, loopargs, loopargs_len) < 1)
2601 for (testnum = 0; testnum < size_num; testnum++) {
2602 print_message(names[D_HMAC], lengths[testnum], seconds.sym);
2604 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2606 print_result(D_HMAC, testnum, count, d);
2610 mac_teardown(&mac, loopargs, loopargs_len);
2613 if (doit[D_CBC_DES]) {
2616 for (i = 0; st && i < loopargs_len; i++) {
2617 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2618 sizeof(deskey) / 3);
2619 st = loopargs[i].ctx != NULL;
2621 algindex = D_CBC_DES;
2622 for (testnum = 0; st && testnum < size_num; testnum++) {
2623 print_message(names[D_CBC_DES], lengths[testnum], seconds.sym);
2625 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2627 print_result(D_CBC_DES, testnum, count, d);
2629 for (i = 0; i < loopargs_len; i++)
2630 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2633 if (doit[D_EDE3_DES]) {
2636 for (i = 0; st && i < loopargs_len; i++) {
2637 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2639 st = loopargs[i].ctx != NULL;
2641 algindex = D_EDE3_DES;
2642 for (testnum = 0; st && testnum < size_num; testnum++) {
2643 print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym);
2646 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2648 print_result(D_EDE3_DES, testnum, count, d);
2650 for (i = 0; i < loopargs_len; i++)
2651 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2654 for (k = 0; k < 3; k++) {
2655 algindex = D_CBC_128_AES + k;
2656 if (doit[algindex]) {
2659 keylen = 16 + k * 8;
2660 for (i = 0; st && i < loopargs_len; i++) {
2661 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2663 st = loopargs[i].ctx != NULL;
2666 for (testnum = 0; st && testnum < size_num; testnum++) {
2667 print_message(names[algindex], lengths[testnum], seconds.sym);
2670 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2672 print_result(algindex, testnum, count, d);
2674 for (i = 0; i < loopargs_len; i++)
2675 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2679 for (k = 0; k < 3; k++) {
2680 algindex = D_CBC_128_CML + k;
2681 if (doit[algindex]) {
2684 keylen = 16 + k * 8;
2685 for (i = 0; st && i < loopargs_len; i++) {
2686 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2688 st = loopargs[i].ctx != NULL;
2691 for (testnum = 0; st && testnum < size_num; testnum++) {
2692 print_message(names[algindex], lengths[testnum], seconds.sym);
2695 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2697 print_result(algindex, testnum, count, d);
2699 for (i = 0; i < loopargs_len; i++)
2700 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2704 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2705 if (doit[algindex]) {
2709 for (i = 0; st && i < loopargs_len; i++) {
2710 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2712 st = loopargs[i].ctx != NULL;
2715 for (testnum = 0; st && testnum < size_num; testnum++) {
2716 print_message(names[algindex], lengths[testnum], seconds.sym);
2719 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2721 print_result(algindex, testnum, count, d);
2723 for (i = 0; i < loopargs_len; i++)
2724 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2727 if (doit[D_GHASH]) {
2728 static const char gmac_iv[] = "0123456789ab";
2729 OSSL_PARAM params[4];
2731 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2733 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2735 sizeof(gmac_iv) - 1);
2736 params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2738 params[3] = OSSL_PARAM_construct_end();
2740 if (mac_setup("GMAC", &mac, params, loopargs, loopargs_len) < 1)
2742 /* b/c of the definition of GHASH_loop(), init() calls are needed here */
2743 for (i = 0; i < loopargs_len; i++) {
2744 if (!EVP_MAC_init(loopargs[i].mctx, NULL, 0, NULL))
2747 for (testnum = 0; testnum < size_num; testnum++) {
2748 print_message(names[D_GHASH], lengths[testnum], seconds.sym);
2750 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2752 print_result(D_GHASH, testnum, count, d);
2756 mac_teardown(&mac, loopargs, loopargs_len);
2760 for (testnum = 0; testnum < size_num; testnum++) {
2761 print_message(names[D_RAND], lengths[testnum], seconds.sym);
2763 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2765 print_result(D_RAND, testnum, count, d);
2770 if (evp_cipher != NULL) {
2771 int (*loopfunc) (void *) = EVP_Update_loop;
2773 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2774 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2775 multiblock_speed(evp_cipher, lengths_single, &seconds);
2780 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2782 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2783 loopfunc = EVP_Update_loop_ccm;
2784 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2785 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2786 loopfunc = EVP_Update_loop_aead;
2787 if (lengths == lengths_list) {
2788 lengths = aead_lengths_list;
2789 size_num = OSSL_NELEM(aead_lengths_list);
2793 for (testnum = 0; testnum < size_num; testnum++) {
2794 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2796 for (k = 0; k < loopargs_len; k++) {
2797 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2798 if (loopargs[k].ctx == NULL) {
2799 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2802 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2803 NULL, iv, decrypt ? 0 : 1)) {
2804 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2805 ERR_print_errors(bio_err);
2809 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2811 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2812 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2813 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2814 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2815 loopargs[k].key, NULL, -1)) {
2816 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2817 ERR_print_errors(bio_err);
2820 OPENSSL_clear_free(loopargs[k].key, keylen);
2822 /* GCM-SIV/SIV mode only allows for a single Update operation */
2823 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE
2824 || EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_GCM_SIV_MODE)
2825 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2826 EVP_CTRL_SET_SPEED, 1, NULL);
2830 count = run_benchmark(async_jobs, loopfunc, loopargs);
2832 for (k = 0; k < loopargs_len; k++)
2833 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2834 print_result(D_EVP, testnum, count, d);
2836 } else if (evp_md_name != NULL) {
2837 names[D_EVP] = evp_md_name;
2839 for (testnum = 0; testnum < size_num; testnum++) {
2840 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2842 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2844 print_result(D_EVP, testnum, count, d);
2851 if (doit[D_EVP_CMAC]) {
2852 OSSL_PARAM params[3];
2853 EVP_CIPHER *cipher = NULL;
2855 if (!opt_cipher(evp_mac_ciphername, &cipher))
2858 keylen = EVP_CIPHER_get_key_length(cipher);
2859 EVP_CIPHER_free(cipher);
2860 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2861 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2864 evp_cmac_name = app_malloc(sizeof("cmac()")
2865 + strlen(evp_mac_ciphername), "CMAC name");
2866 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2867 names[D_EVP_CMAC] = evp_cmac_name;
2869 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2870 evp_mac_ciphername, 0);
2871 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2872 (char *)key32, keylen);
2873 params[2] = OSSL_PARAM_construct_end();
2875 if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
2877 for (testnum = 0; testnum < size_num; testnum++) {
2878 print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
2880 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2882 print_result(D_EVP_CMAC, testnum, count, d);
2886 mac_teardown(&mac, loopargs, loopargs_len);
2889 if (doit[D_KMAC128]) {
2890 OSSL_PARAM params[2];
2892 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2894 params[1] = OSSL_PARAM_construct_end();
2896 if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
2898 for (testnum = 0; testnum < size_num; testnum++) {
2899 print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
2901 count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
2903 print_result(D_KMAC128, testnum, count, d);
2907 mac_teardown(&mac, loopargs, loopargs_len);
2910 if (doit[D_KMAC256]) {
2911 OSSL_PARAM params[2];
2913 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2915 params[1] = OSSL_PARAM_construct_end();
2917 if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
2919 for (testnum = 0; testnum < size_num; testnum++) {
2920 print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
2922 count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
2924 print_result(D_KMAC256, testnum, count, d);
2928 mac_teardown(&mac, loopargs, loopargs_len);
2931 for (i = 0; i < loopargs_len; i++)
2932 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2935 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2936 EVP_PKEY *rsa_key = NULL;
2939 if (!rsa_doit[testnum])
2942 if (primes > RSA_DEFAULT_PRIME_NUM) {
2943 /* we haven't set keys yet, generate multi-prime RSA keys */
2946 && BN_set_word(bn, RSA_F4)
2947 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2948 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2949 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2950 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2951 && EVP_PKEY_keygen(genctx, &rsa_key);
2954 EVP_PKEY_CTX_free(genctx);
2957 const unsigned char *p = rsa_keys[testnum].data;
2959 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2960 rsa_keys[testnum].length)) != NULL;
2963 for (i = 0; st && i < loopargs_len; i++) {
2964 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2965 loopargs[i].sigsize = loopargs[i].buflen;
2966 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2967 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2968 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2970 &loopargs[i].sigsize,
2971 loopargs[i].buf, 36) <= 0)
2976 "RSA sign setup failure. No RSA sign will be done.\n");
2977 ERR_print_errors(bio_err);
2980 pkey_print_message("private", "rsa sign",
2981 rsa_keys[testnum].bits, seconds.rsa);
2982 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2984 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2987 mr ? "+R1:%ld:%d:%.2f\n"
2988 : "%ld %u bits private RSA sign ops in %.2fs\n",
2989 count, rsa_keys[testnum].bits, d);
2990 rsa_results[testnum][0] = (double)count / d;
2994 for (i = 0; st && i < loopargs_len; i++) {
2995 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2997 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2998 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2999 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
3001 loopargs[i].sigsize,
3002 loopargs[i].buf, 36) <= 0)
3007 "RSA verify setup failure. No RSA verify will be done.\n");
3008 ERR_print_errors(bio_err);
3009 rsa_doit[testnum] = 0;
3011 pkey_print_message("public", "rsa verify",
3012 rsa_keys[testnum].bits, seconds.rsa);
3014 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
3017 mr ? "+R2:%ld:%d:%.2f\n"
3018 : "%ld %u bits public RSA verify ops in %.2fs\n",
3019 count, rsa_keys[testnum].bits, d);
3020 rsa_results[testnum][1] = (double)count / d;
3023 for (i = 0; st && i < loopargs_len; i++) {
3024 loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3025 loopargs[i].encsize = loopargs[i].buflen;
3026 if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
3027 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
3028 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
3030 &loopargs[i].encsize,
3031 loopargs[i].buf, 36) <= 0)
3036 "RSA encrypt setup failure. No RSA encrypt will be done.\n");
3037 ERR_print_errors(bio_err);
3040 pkey_print_message("private", "rsa encrypt",
3041 rsa_keys[testnum].bits, seconds.rsa);
3042 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3044 count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
3047 mr ? "+R3:%ld:%d:%.2f\n"
3048 : "%ld %u bits public RSA encrypt ops in %.2fs\n",
3049 count, rsa_keys[testnum].bits, d);
3050 rsa_results[testnum][2] = (double)count / d;
3054 for (i = 0; st && i < loopargs_len; i++) {
3055 loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3056 declen = loopargs[i].buflen;
3057 if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
3058 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
3059 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
3063 loopargs[i].encsize) <= 0)
3068 "RSA decrypt setup failure. No RSA decrypt will be done.\n");
3069 ERR_print_errors(bio_err);
3072 pkey_print_message("private", "rsa decrypt",
3073 rsa_keys[testnum].bits, seconds.rsa);
3074 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3076 count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3079 mr ? "+R4:%ld:%d:%.2f\n"
3080 : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3081 count, rsa_keys[testnum].bits, d);
3082 rsa_results[testnum][3] = (double)count / d;
3086 if (op_count <= 1) {
3087 /* if longer than 10s, don't do any more */
3088 stop_it(rsa_doit, testnum);
3090 EVP_PKEY_free(rsa_key);
3093 for (testnum = 0; testnum < DSA_NUM; testnum++) {
3094 EVP_PKEY *dsa_key = NULL;
3097 if (!dsa_doit[testnum])
3100 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3102 for (i = 0; st && i < loopargs_len; i++) {
3103 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3105 loopargs[i].sigsize = loopargs[i].buflen;
3106 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3107 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3109 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3111 &loopargs[i].sigsize,
3112 loopargs[i].buf, 20) <= 0)
3117 "DSA sign setup failure. No DSA sign will be done.\n");
3118 ERR_print_errors(bio_err);
3121 pkey_print_message("sign", "dsa",
3122 dsa_bits[testnum], seconds.dsa);
3124 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3127 mr ? "+R5:%ld:%u:%.2f\n"
3128 : "%ld %u bits DSA sign ops in %.2fs\n",
3129 count, dsa_bits[testnum], d);
3130 dsa_results[testnum][0] = (double)count / d;
3134 for (i = 0; st && i < loopargs_len; i++) {
3135 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3137 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3138 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3139 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3141 loopargs[i].sigsize,
3142 loopargs[i].buf, 36) <= 0)
3147 "DSA verify setup failure. No DSA verify will be done.\n");
3148 ERR_print_errors(bio_err);
3149 dsa_doit[testnum] = 0;
3151 pkey_print_message("verify", "dsa",
3152 dsa_bits[testnum], seconds.dsa);
3154 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3157 mr ? "+R6:%ld:%u:%.2f\n"
3158 : "%ld %u bits DSA verify ops in %.2fs\n",
3159 count, dsa_bits[testnum], d);
3160 dsa_results[testnum][1] = (double)count / d;
3163 if (op_count <= 1) {
3164 /* if longer than 10s, don't do any more */
3165 stop_it(dsa_doit, testnum);
3167 EVP_PKEY_free(dsa_key);
3170 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3171 EVP_PKEY *ecdsa_key = NULL;
3174 if (!ecdsa_doit[testnum])
3177 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3179 for (i = 0; st && i < loopargs_len; i++) {
3180 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3182 loopargs[i].sigsize = loopargs[i].buflen;
3183 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3184 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3186 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3188 &loopargs[i].sigsize,
3189 loopargs[i].buf, 20) <= 0)
3194 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
3195 ERR_print_errors(bio_err);
3198 pkey_print_message("sign", "ecdsa",
3199 ec_curves[testnum].bits, seconds.ecdsa);
3201 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3204 mr ? "+R7:%ld:%u:%.2f\n"
3205 : "%ld %u bits ECDSA sign ops in %.2fs\n",
3206 count, ec_curves[testnum].bits, d);
3207 ecdsa_results[testnum][0] = (double)count / d;
3211 for (i = 0; st && i < loopargs_len; i++) {
3212 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3214 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3215 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3216 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3218 loopargs[i].sigsize,
3219 loopargs[i].buf, 20) <= 0)
3224 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3225 ERR_print_errors(bio_err);
3226 ecdsa_doit[testnum] = 0;
3228 pkey_print_message("verify", "ecdsa",
3229 ec_curves[testnum].bits, seconds.ecdsa);
3231 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3234 mr ? "+R8:%ld:%u:%.2f\n"
3235 : "%ld %u bits ECDSA verify ops in %.2fs\n",
3236 count, ec_curves[testnum].bits, d);
3237 ecdsa_results[testnum][1] = (double)count / d;
3240 if (op_count <= 1) {
3241 /* if longer than 10s, don't do any more */
3242 stop_it(ecdsa_doit, testnum);
3246 for (testnum = 0; testnum < EC_NUM; testnum++) {
3247 int ecdh_checks = 1;
3249 if (!ecdh_doit[testnum])
3252 for (i = 0; i < loopargs_len; i++) {
3253 EVP_PKEY_CTX *test_ctx = NULL;
3254 EVP_PKEY_CTX *ctx = NULL;
3255 EVP_PKEY *key_A = NULL;
3256 EVP_PKEY *key_B = NULL;
3260 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3261 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3262 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3263 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3264 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3265 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3266 || outlen == 0 /* ensure outlen is a valid size */
3267 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3269 BIO_printf(bio_err, "ECDH key generation failure.\n");
3270 ERR_print_errors(bio_err);
3276 * Here we perform a test run, comparing the output of a*B and b*A;
3277 * we try this here and assume that further EVP_PKEY_derive calls
3278 * never fail, so we can skip checks in the actually benchmarked
3279 * code, for maximum performance.
3281 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3282 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3283 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3284 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3285 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3286 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3287 || test_outlen != outlen /* compare output length */) {
3289 BIO_printf(bio_err, "ECDH computation failure.\n");
3290 ERR_print_errors(bio_err);
3295 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3296 if (CRYPTO_memcmp(loopargs[i].secret_a,
3297 loopargs[i].secret_b, outlen)) {
3299 BIO_printf(bio_err, "ECDH computations don't match.\n");
3300 ERR_print_errors(bio_err);
3305 loopargs[i].ecdh_ctx[testnum] = ctx;
3306 loopargs[i].outlen[testnum] = outlen;
3308 EVP_PKEY_free(key_A);
3309 EVP_PKEY_free(key_B);
3310 EVP_PKEY_CTX_free(test_ctx);
3313 if (ecdh_checks != 0) {
3314 pkey_print_message("", "ecdh",
3315 ec_curves[testnum].bits, seconds.ecdh);
3318 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3321 mr ? "+R9:%ld:%d:%.2f\n" :
3322 "%ld %u-bits ECDH ops in %.2fs\n", count,
3323 ec_curves[testnum].bits, d);
3324 ecdh_results[testnum][0] = (double)count / d;
3328 if (op_count <= 1) {
3329 /* if longer than 10s, don't do any more */
3330 stop_it(ecdh_doit, testnum);
3334 #ifndef OPENSSL_NO_ECX
3335 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3337 EVP_PKEY *ed_pkey = NULL;
3338 EVP_PKEY_CTX *ed_pctx = NULL;
3340 if (!eddsa_doit[testnum])
3341 continue; /* Ignore Curve */
3342 for (i = 0; i < loopargs_len; i++) {
3343 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3344 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3348 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3349 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3354 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3356 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3357 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3359 EVP_PKEY_CTX_free(ed_pctx);
3362 EVP_PKEY_CTX_free(ed_pctx);
3364 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3367 EVP_PKEY_free(ed_pkey);
3370 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3371 NULL, NULL, ed_pkey)) {
3373 EVP_PKEY_free(ed_pkey);
3377 EVP_PKEY_free(ed_pkey);
3381 BIO_printf(bio_err, "EdDSA failure.\n");
3382 ERR_print_errors(bio_err);
3385 for (i = 0; i < loopargs_len; i++) {
3386 /* Perform EdDSA signature test */
3387 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3388 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3389 loopargs[i].buf2, &loopargs[i].sigsize,
3390 loopargs[i].buf, 20);
3396 "EdDSA sign failure. No EdDSA sign will be done.\n");
3397 ERR_print_errors(bio_err);
3400 pkey_print_message("sign", ed_curves[testnum].name,
3401 ed_curves[testnum].bits, seconds.eddsa);
3403 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3407 mr ? "+R10:%ld:%u:%s:%.2f\n" :
3408 "%ld %u bits %s sign ops in %.2fs \n",
3409 count, ed_curves[testnum].bits,
3410 ed_curves[testnum].name, d);
3411 eddsa_results[testnum][0] = (double)count / d;
3414 /* Perform EdDSA verification test */
3415 for (i = 0; i < loopargs_len; i++) {
3416 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3417 loopargs[i].buf2, loopargs[i].sigsize,
3418 loopargs[i].buf, 20);
3424 "EdDSA verify failure. No EdDSA verify will be done.\n");
3425 ERR_print_errors(bio_err);
3426 eddsa_doit[testnum] = 0;
3428 pkey_print_message("verify", ed_curves[testnum].name,
3429 ed_curves[testnum].bits, seconds.eddsa);
3431 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3434 mr ? "+R11:%ld:%u:%s:%.2f\n"
3435 : "%ld %u bits %s verify ops in %.2fs\n",
3436 count, ed_curves[testnum].bits,
3437 ed_curves[testnum].name, d);
3438 eddsa_results[testnum][1] = (double)count / d;
3441 if (op_count <= 1) {
3442 /* if longer than 10s, don't do any more */
3443 stop_it(eddsa_doit, testnum);
3447 #endif /* OPENSSL_NO_ECX */
3449 #ifndef OPENSSL_NO_SM2
3450 for (testnum = 0; testnum < SM2_NUM; testnum++) {
3452 EVP_PKEY *sm2_pkey = NULL;
3454 if (!sm2_doit[testnum])
3455 continue; /* Ignore Curve */
3456 /* Init signing and verification */
3457 for (i = 0; i < loopargs_len; i++) {
3458 EVP_PKEY_CTX *sm2_pctx = NULL;
3459 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3460 EVP_PKEY_CTX *pctx = NULL;
3463 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3464 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3465 if (loopargs[i].sm2_ctx[testnum] == NULL
3466 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3471 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3472 || EVP_PKEY_keygen_init(pctx) <= 0
3473 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3474 sm2_curves[testnum].nid) <= 0
3475 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3476 EVP_PKEY_CTX_free(pctx);
3480 st = 0; /* set back to zero */
3481 /* attach it sooner to rely on main final cleanup */
3482 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3483 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3485 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3486 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3487 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3488 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3492 /* attach them directly to respective ctx */
3493 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3494 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3497 * No need to allow user to set an explicit ID here, just use
3498 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3500 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3501 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3504 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3505 EVP_sm3(), NULL, sm2_pkey))
3507 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3508 EVP_sm3(), NULL, sm2_pkey))
3510 st = 1; /* mark loop as succeeded */
3513 BIO_printf(bio_err, "SM2 init failure.\n");
3514 ERR_print_errors(bio_err);
3517 for (i = 0; i < loopargs_len; i++) {
3518 /* Perform SM2 signature test */
3519 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3520 loopargs[i].buf2, &loopargs[i].sigsize,
3521 loopargs[i].buf, 20);
3527 "SM2 sign failure. No SM2 sign will be done.\n");
3528 ERR_print_errors(bio_err);
3531 pkey_print_message("sign", sm2_curves[testnum].name,
3532 sm2_curves[testnum].bits, seconds.sm2);
3534 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3538 mr ? "+R12:%ld:%u:%s:%.2f\n" :
3539 "%ld %u bits %s sign ops in %.2fs \n",
3540 count, sm2_curves[testnum].bits,
3541 sm2_curves[testnum].name, d);
3542 sm2_results[testnum][0] = (double)count / d;
3546 /* Perform SM2 verification test */
3547 for (i = 0; i < loopargs_len; i++) {
3548 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3549 loopargs[i].buf2, loopargs[i].sigsize,
3550 loopargs[i].buf, 20);
3556 "SM2 verify failure. No SM2 verify will be done.\n");
3557 ERR_print_errors(bio_err);
3558 sm2_doit[testnum] = 0;
3560 pkey_print_message("verify", sm2_curves[testnum].name,
3561 sm2_curves[testnum].bits, seconds.sm2);
3563 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3566 mr ? "+R13:%ld:%u:%s:%.2f\n"
3567 : "%ld %u bits %s verify ops in %.2fs\n",
3568 count, sm2_curves[testnum].bits,
3569 sm2_curves[testnum].name, d);
3570 sm2_results[testnum][1] = (double)count / d;
3573 if (op_count <= 1) {
3574 /* if longer than 10s, don't do any more */
3575 for (testnum++; testnum < SM2_NUM; testnum++)
3576 sm2_doit[testnum] = 0;
3580 #endif /* OPENSSL_NO_SM2 */
3582 #ifndef OPENSSL_NO_DH
3583 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3584 int ffdh_checks = 1;
3586 if (!ffdh_doit[testnum])
3589 for (i = 0; i < loopargs_len; i++) {
3590 EVP_PKEY *pkey_A = NULL;
3591 EVP_PKEY *pkey_B = NULL;
3592 EVP_PKEY_CTX *ffdh_ctx = NULL;
3593 EVP_PKEY_CTX *test_ctx = NULL;
3597 /* Ensure that the error queue is empty */
3598 if (ERR_peek_error()) {
3600 "WARNING: the error queue contains previous unhandled errors.\n");
3601 ERR_print_errors(bio_err);
3604 pkey_A = EVP_PKEY_new();
3606 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3607 ERR_print_errors(bio_err);
3612 pkey_B = EVP_PKEY_new();
3614 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3615 ERR_print_errors(bio_err);
3621 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3623 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3624 ERR_print_errors(bio_err);
3630 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3631 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3632 ERR_print_errors(bio_err);
3637 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3638 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3639 ERR_print_errors(bio_err);
3645 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
3646 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
3647 BIO_printf(bio_err, "FFDH key generation failure.\n");
3648 ERR_print_errors(bio_err);
3654 EVP_PKEY_CTX_free(ffdh_ctx);
3657 * check if the derivation works correctly both ways so that
3658 * we know if future derive calls will fail, and we can skip
3659 * error checking in benchmarked code
3661 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3662 if (ffdh_ctx == NULL) {
3663 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3664 ERR_print_errors(bio_err);
3669 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3670 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3671 ERR_print_errors(bio_err);
3676 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3677 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3678 ERR_print_errors(bio_err);
3683 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3684 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3685 ERR_print_errors(bio_err);
3690 if (secret_size > MAX_FFDH_SIZE) {
3691 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3696 if (EVP_PKEY_derive(ffdh_ctx,
3697 loopargs[i].secret_ff_a,
3698 &secret_size) <= 0) {
3699 BIO_printf(bio_err, "Shared secret derive failure.\n");
3700 ERR_print_errors(bio_err);
3705 /* Now check from side B */
3706 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3708 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3709 ERR_print_errors(bio_err);
3714 if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3715 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3716 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3717 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3718 test_out != secret_size) {
3719 BIO_printf(bio_err, "FFDH computation failure.\n");
3725 /* compare the computed secrets */
3726 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3727 loopargs[i].secret_ff_b, secret_size)) {
3728 BIO_printf(bio_err, "FFDH computations don't match.\n");
3729 ERR_print_errors(bio_err);
3735 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3737 EVP_PKEY_free(pkey_A);
3739 EVP_PKEY_free(pkey_B);
3741 EVP_PKEY_CTX_free(test_ctx);
3744 if (ffdh_checks != 0) {
3745 pkey_print_message("", "ffdh",
3746 ffdh_params[testnum].bits, seconds.ffdh);
3749 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3752 mr ? "+R14:%ld:%d:%.2f\n" :
3753 "%ld %u-bits FFDH ops in %.2fs\n", count,
3754 ffdh_params[testnum].bits, d);
3755 ffdh_results[testnum][0] = (double)count / d;
3758 if (op_count <= 1) {
3759 /* if longer than 10s, don't do any more */
3760 stop_it(ffdh_doit, testnum);
3763 #endif /* OPENSSL_NO_DH */
3765 for (testnum = 0; testnum < kems_algs_len; testnum++) {
3767 const char *kem_name = kems_algname[testnum];
3769 if (!kems_doit[testnum] || !do_kems)
3772 for (i = 0; i < loopargs_len; i++) {
3773 EVP_PKEY *pkey = NULL;
3774 EVP_PKEY_CTX *kem_gen_ctx = NULL;
3775 EVP_PKEY_CTX *kem_encaps_ctx = NULL;
3776 EVP_PKEY_CTX *kem_decaps_ctx = NULL;
3777 size_t send_secret_len, out_len;
3778 size_t rcv_secret_len;
3779 unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
3782 char sfx[MAX_ALGNAME_SUFFIX];
3783 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3785 enum kem_type_t { KEM_RSA = 1, KEM_EC, KEM_X25519, KEM_X448 } kem_type;
3787 /* no string after rsa<bitcnt> permitted: */
3788 if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3789 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
3791 else if (strncmp(kem_name, "EC", 2) == 0)
3793 else if (strcmp(kem_name, "X25519") == 0)
3794 kem_type = KEM_X25519;
3795 else if (strcmp(kem_name, "X448") == 0)
3796 kem_type = KEM_X448;
3799 if (ERR_peek_error()) {
3801 "WARNING: the error queue contains previous unhandled errors.\n");
3802 ERR_print_errors(bio_err);
3805 if (kem_type == KEM_RSA) {
3806 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3809 } else if (kem_type == KEM_EC) {
3810 name = (char *)(kem_name + 2);
3811 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3816 kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3817 (kem_type == KEM_RSA) ? "RSA":
3818 (kem_type == KEM_EC) ? "EC":
3822 if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
3824 && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
3825 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
3829 if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
3830 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
3833 /* Now prepare encaps data structs */
3834 kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3837 if (kem_encaps_ctx == NULL
3838 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
3839 || (kem_type == KEM_RSA
3840 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
3841 || ((kem_type == KEM_EC
3842 || kem_type == KEM_X25519
3843 || kem_type == KEM_X448)
3844 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
3845 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
3846 NULL, &send_secret_len) <= 0) {
3848 "Error while initializing encaps data structs for %s.\n",
3852 out = app_malloc(out_len, "encaps result");
3853 send_secret = app_malloc(send_secret_len, "encaps secret");
3854 if (out == NULL || send_secret == NULL) {
3855 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
3858 if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
3859 send_secret, &send_secret_len) <= 0) {
3860 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
3863 /* Now prepare decaps data structs */
3864 kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3867 if (kem_decaps_ctx == NULL
3868 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
3869 || (kem_type == KEM_RSA
3870 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
3871 || ((kem_type == KEM_EC
3872 || kem_type == KEM_X25519
3873 || kem_type == KEM_X448)
3874 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
3875 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
3876 out, out_len) <= 0) {
3878 "Error while initializing decaps data structs for %s.\n",
3882 rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
3883 if (rcv_secret == NULL) {
3884 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
3888 if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
3889 &rcv_secret_len, out, out_len) <= 0
3890 || rcv_secret_len != send_secret_len
3891 || memcmp(send_secret, rcv_secret, send_secret_len)) {
3892 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
3895 loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
3896 loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
3897 loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
3898 loopargs[i].kem_out_len[testnum] = out_len;
3899 loopargs[i].kem_secret_len[testnum] = send_secret_len;
3900 loopargs[i].kem_out[testnum] = out;
3901 loopargs[i].kem_send_secret[testnum] = send_secret;
3902 loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
3903 EVP_PKEY_free(pkey);
3908 ERR_print_errors(bio_err);
3909 EVP_PKEY_free(pkey);
3914 if (kem_checks != 0) {
3915 kskey_print_message(kem_name, "keygen", seconds.kem);
3918 run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
3921 mr ? "+R15:%ld:%s:%.2f\n" :
3922 "%ld %s KEM keygen ops in %.2fs\n", count,
3924 kems_results[testnum][0] = (double)count / d;
3926 kskey_print_message(kem_name, "encaps", seconds.kem);
3929 run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
3932 mr ? "+R16:%ld:%s:%.2f\n" :
3933 "%ld %s KEM encaps ops in %.2fs\n", count,
3935 kems_results[testnum][1] = (double)count / d;
3937 kskey_print_message(kem_name, "decaps", seconds.kem);
3940 run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
3943 mr ? "+R17:%ld:%s:%.2f\n" :
3944 "%ld %s KEM decaps ops in %.2fs\n", count,
3946 kems_results[testnum][2] = (double)count / d;
3949 if (op_count <= 1) {
3950 /* if longer than 10s, don't do any more */
3951 stop_it(kems_doit, testnum);
3955 for (testnum = 0; testnum < sigs_algs_len; testnum++) {
3957 const char *sig_name = sigs_algname[testnum];
3959 if (!sigs_doit[testnum] || !do_sigs)
3962 for (i = 0; i < loopargs_len; i++) {
3963 EVP_PKEY *pkey = NULL;
3964 EVP_PKEY_CTX *ctx_params = NULL;
3965 EVP_PKEY* pkey_params = NULL;
3966 EVP_PKEY_CTX *sig_gen_ctx = NULL;
3967 EVP_PKEY_CTX *sig_sign_ctx = NULL;
3968 EVP_PKEY_CTX *sig_verify_ctx = NULL;
3969 unsigned char md[SHA256_DIGEST_LENGTH];
3971 char sfx[MAX_ALGNAME_SUFFIX];
3972 size_t md_len = SHA256_DIGEST_LENGTH;
3973 size_t max_sig_len, sig_len;
3975 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3978 /* only sign little data to avoid measuring digest performance */
3979 memset(md, 0, SHA256_DIGEST_LENGTH);
3981 if (ERR_peek_error()) {
3983 "WARNING: the error queue contains previous unhandled errors.\n");
3984 ERR_print_errors(bio_err);
3987 /* no string after rsa<bitcnt> permitted: */
3988 if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3989 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
3990 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3995 if (strncmp(sig_name, "dsa", 3) == 0) {
3996 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
3997 if (ctx_params == NULL
3998 || EVP_PKEY_paramgen_init(ctx_params) <= 0
3999 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
4000 atoi(sig_name + 3)) <= 0
4001 || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
4002 || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
4003 || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
4005 "Error initializing classic keygen ctx for %s.\n",
4011 if (sig_gen_ctx == NULL)
4012 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4013 use_params == 1 ? "RSA" : sig_name,
4016 if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
4018 EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
4019 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4023 if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
4025 "Error while generating signature EVP_PKEY for %s.\n",
4029 /* Now prepare signature data structs */
4030 sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4033 if (sig_sign_ctx == NULL
4034 || EVP_PKEY_sign_init(sig_sign_ctx) <= 0
4036 && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx,
4037 RSA_PKCS1_PADDING) <= 0))
4038 || EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len,
4041 "Error while initializing signing data structs for %s.\n",
4045 sig = app_malloc(sig_len = max_sig_len, "signature buffer");
4047 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
4050 if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
4051 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
4054 /* Now prepare verify data structs */
4055 memset(md, 0, SHA256_DIGEST_LENGTH);
4056 sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4059 if (sig_verify_ctx == NULL
4060 || EVP_PKEY_verify_init(sig_verify_ctx) <= 0
4062 && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx,
4063 RSA_PKCS1_PADDING) <= 0))) {
4065 "Error while initializing verify data structs for %s.\n",
4069 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4070 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
4073 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4074 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4077 loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4078 loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4079 loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4080 loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4081 loopargs[i].sig_act_sig_len[testnum] = sig_len;
4082 loopargs[i].sig_sig[testnum] = sig;
4083 EVP_PKEY_free(pkey);
4088 ERR_print_errors(bio_err);
4089 EVP_PKEY_free(pkey);
4095 if (sig_checks != 0) {
4096 kskey_print_message(sig_name, "keygen", seconds.sig);
4098 count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4101 mr ? "+R18:%ld:%s:%.2f\n" :
4102 "%ld %s signature keygen ops in %.2fs\n", count,
4104 sigs_results[testnum][0] = (double)count / d;
4106 kskey_print_message(sig_name, "signs", seconds.sig);
4109 run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4112 mr ? "+R19:%ld:%s:%.2f\n" :
4113 "%ld %s signature sign ops in %.2fs\n", count,
4115 sigs_results[testnum][1] = (double)count / d;
4118 kskey_print_message(sig_name, "verify", seconds.sig);
4121 run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4124 mr ? "+R20:%ld:%s:%.2f\n" :
4125 "%ld %s signature verify ops in %.2fs\n", count,
4127 sigs_results[testnum][2] = (double)count / d;
4131 stop_it(sigs_doit, testnum);
4138 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4139 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4140 printf("options: %s\n", BN_options());
4141 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4142 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4149 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4152 for (testnum = 0; testnum < size_num; testnum++)
4153 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4157 for (k = 0; k < ALGOR_NUM; k++) {
4158 const char *alg_name = names[k];
4164 if (evp_cipher == NULL)
4165 alg_name = evp_md_name;
4166 else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4167 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4171 printf("+F:%u:%s", k, alg_name);
4173 printf("%-13s", alg_name);
4174 for (testnum = 0; testnum < size_num; testnum++) {
4175 if (results[k][testnum] > 10000 && !mr)
4176 printf(" %11.2fk", results[k][testnum] / 1e3);
4178 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4183 for (k = 0; k < RSA_NUM; k++) {
4186 if (testnum && !mr) {
4187 printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " ");
4191 printf("+F2:%u:%u:%f:%f:%f:%f\n",
4192 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4193 rsa_results[k][2], rsa_results[k][3]);
4195 printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4196 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4197 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4198 1.0 / rsa_results[k][3],
4199 rsa_results[k][0], rsa_results[k][1],
4200 rsa_results[k][2], rsa_results[k][3]);
4203 for (k = 0; k < DSA_NUM; k++) {
4206 if (testnum && !mr) {
4207 printf("%18ssign verify sign/s verify/s\n", " ");
4211 printf("+F3:%u:%u:%f:%f\n",
4212 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4214 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4215 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4216 dsa_results[k][0], dsa_results[k][1]);
4219 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4222 if (testnum && !mr) {
4223 printf("%30ssign verify sign/s verify/s\n", " ");
4228 printf("+F4:%u:%u:%f:%f\n",
4229 k, ec_curves[k].bits,
4230 ecdsa_results[k][0], ecdsa_results[k][1]);
4232 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4233 ec_curves[k].bits, ec_curves[k].name,
4234 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4235 ecdsa_results[k][0], ecdsa_results[k][1]);
4239 for (k = 0; k < EC_NUM; k++) {
4242 if (testnum && !mr) {
4243 printf("%30sop op/s\n", " ");
4247 printf("+F5:%u:%u:%f:%f\n",
4248 k, ec_curves[k].bits,
4249 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4252 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4253 ec_curves[k].bits, ec_curves[k].name,
4254 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4257 #ifndef OPENSSL_NO_ECX
4259 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4262 if (testnum && !mr) {
4263 printf("%30ssign verify sign/s verify/s\n", " ");
4268 printf("+F6:%u:%u:%s:%f:%f\n",
4269 k, ed_curves[k].bits, ed_curves[k].name,
4270 eddsa_results[k][0], eddsa_results[k][1]);
4272 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4273 ed_curves[k].bits, ed_curves[k].name,
4274 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4275 eddsa_results[k][0], eddsa_results[k][1]);
4277 #endif /* OPENSSL_NO_ECX */
4279 #ifndef OPENSSL_NO_SM2
4281 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4284 if (testnum && !mr) {
4285 printf("%30ssign verify sign/s verify/s\n", " ");
4290 printf("+F7:%u:%u:%s:%f:%f\n",
4291 k, sm2_curves[k].bits, sm2_curves[k].name,
4292 sm2_results[k][0], sm2_results[k][1]);
4294 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4295 sm2_curves[k].bits, sm2_curves[k].name,
4296 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4297 sm2_results[k][0], sm2_results[k][1]);
4300 #ifndef OPENSSL_NO_DH
4302 for (k = 0; k < FFDH_NUM; k++) {
4305 if (testnum && !mr) {
4306 printf("%23sop op/s\n", " ");
4310 printf("+F8:%u:%u:%f:%f\n",
4311 k, ffdh_params[k].bits,
4312 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4315 printf("%4u bits ffdh %8.4fs %8.1f\n",
4316 ffdh_params[k].bits,
4317 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4319 #endif /* OPENSSL_NO_DH */
4322 for (k = 0; k < kems_algs_len; k++) {
4323 const char *kem_name = kems_algname[k];
4325 if (!kems_doit[k] || !do_kems)
4327 if (testnum && !mr) {
4328 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4332 printf("+F9:%u:%f:%f:%f\n",
4333 k, kems_results[k][0], kems_results[k][1],
4334 kems_results[k][2]);
4336 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4337 1.0 / kems_results[k][0],
4338 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4339 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4344 for (k = 0; k < sigs_algs_len; k++) {
4345 const char *sig_name = sigs_algname[k];
4347 if (!sigs_doit[k] || !do_sigs)
4349 if (testnum && !mr) {
4350 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4354 printf("+F10:%u:%f:%f:%f\n",
4355 k, sigs_results[k][0], sigs_results[k][1],
4356 sigs_results[k][2]);
4358 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4359 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4360 1.0 / sigs_results[k][2], sigs_results[k][0],
4361 sigs_results[k][1], sigs_results[k][2]);
4366 ERR_print_errors(bio_err);
4367 for (i = 0; i < loopargs_len; i++) {
4368 OPENSSL_free(loopargs[i].buf_malloc);
4369 OPENSSL_free(loopargs[i].buf2_malloc);
4372 EVP_PKEY_CTX_free(genctx);
4373 for (k = 0; k < RSA_NUM; k++) {
4374 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4375 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4376 EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]);
4377 EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]);
4379 #ifndef OPENSSL_NO_DH
4380 OPENSSL_free(loopargs[i].secret_ff_a);
4381 OPENSSL_free(loopargs[i].secret_ff_b);
4382 for (k = 0; k < FFDH_NUM; k++)
4383 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4385 for (k = 0; k < DSA_NUM; k++) {
4386 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4387 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4389 for (k = 0; k < ECDSA_NUM; k++) {
4390 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4391 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4393 for (k = 0; k < EC_NUM; k++)
4394 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4395 #ifndef OPENSSL_NO_ECX
4396 for (k = 0; k < EdDSA_NUM; k++) {
4397 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4398 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4400 #endif /* OPENSSL_NO_ECX */
4401 #ifndef OPENSSL_NO_SM2
4402 for (k = 0; k < SM2_NUM; k++) {
4403 EVP_PKEY_CTX *pctx = NULL;
4405 /* free signing ctx */
4406 if (loopargs[i].sm2_ctx[k] != NULL
4407 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4408 EVP_PKEY_CTX_free(pctx);
4409 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4410 /* free verification ctx */
4411 if (loopargs[i].sm2_vfy_ctx[k] != NULL
4412 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4413 EVP_PKEY_CTX_free(pctx);
4414 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4416 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4419 for (k = 0; k < kems_algs_len; k++) {
4420 EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4421 EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4422 EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4423 OPENSSL_free(loopargs[i].kem_out[k]);
4424 OPENSSL_free(loopargs[i].kem_send_secret[k]);
4425 OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4427 for (k = 0; k < sigs_algs_len; k++) {
4428 EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4429 EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4430 EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4431 OPENSSL_free(loopargs[i].sig_sig[k]);
4433 OPENSSL_free(loopargs[i].secret_a);
4434 OPENSSL_free(loopargs[i].secret_b);
4436 OPENSSL_free(evp_hmac_name);
4437 OPENSSL_free(evp_cmac_name);
4438 for (k = 0; k < kems_algs_len; k++)
4439 OPENSSL_free(kems_algname[k]);
4440 if (kem_stack != NULL)
4441 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4442 for (k = 0; k < sigs_algs_len; k++)
4443 OPENSSL_free(sigs_algname[k]);
4444 if (sig_stack != NULL)
4445 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4447 if (async_jobs > 0) {
4448 for (i = 0; i < loopargs_len; i++)
4449 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4453 ASYNC_cleanup_thread();
4455 OPENSSL_free(loopargs);
4457 EVP_CIPHER_free(evp_cipher);
4463 static void print_message(const char *s, int length, int tm)
4466 mr ? "+DT:%s:%d:%d\n"
4467 : "Doing %s ops for %ds on %d size blocks: ", s, tm, length);
4468 (void)BIO_flush(bio_err);
4473 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4477 mr ? "+DTP:%d:%s:%s:%d\n"
4478 : "Doing %u bits %s %s ops for %ds: ", bits, str, str2, tm);
4479 (void)BIO_flush(bio_err);
4484 static void kskey_print_message(const char *str, const char *str2, int tm)
4487 mr ? "+DTP:%s:%s:%d\n"
4488 : "Doing %s %s ops for %ds: ", str, str2, tm);
4489 (void)BIO_flush(bio_err);
4494 static void print_result(int alg, int run_no, int count, double time_used)
4497 BIO_printf(bio_err, "%s error!\n", names[alg]);
4498 ERR_print_errors(bio_err);
4502 mr ? "+R:%d:%s:%f\n"
4503 : "%d %s ops in %.2fs\n", count, names[alg], time_used);
4504 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4508 static char *sstrsep(char **string, const char *delim)
4511 char *token = *string;
4513 memset(isdelim, 0, sizeof(isdelim));
4517 isdelim[(unsigned char)(*delim)] = 1;
4521 while (!isdelim[(unsigned char)(**string)])
4532 static int strtoint(const char *str, const int min_val, const int upper_val,
4539 val = strtol(str, &end, 10);
4540 if (errno == 0 && end != str && *end == 0
4541 && min_val <= val && val < upper_val) {
4549 static int do_multi(int multi, int size_num)
4555 static char sep[] = ":";
4557 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4558 for (n = 0; n < multi; ++n) {
4559 if (pipe(fd) == -1) {
4560 BIO_printf(bio_err, "pipe failure\n");
4564 (void)BIO_flush(bio_err);
4571 if (dup(fd[1]) == -1) {
4572 BIO_printf(bio_err, "dup failed\n");
4581 printf("Forked child %d\n", n);
4584 /* for now, assume the pipe is long enough to take all the output */
4585 for (n = 0; n < multi; ++n) {
4593 if ((f = fdopen(fds[n], "r")) == NULL) {
4594 BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4599 while (fgets(buf, sizeof(buf), f)) {
4600 p = strchr(buf, '\n');
4603 if (buf[0] != '+') {
4605 "Don't understand line '%s' from child %d\n", buf,
4609 printf("Got: %s from %d\n", buf, n);
4611 if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
4615 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
4617 for (j = 0; j < size_num; ++j)
4618 results[alg][j] += atof(sstrsep(&p, sep));
4620 } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
4621 tk = sstrsep(&p, sep);
4622 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
4625 d = atof(sstrsep(&p, sep));
4626 rsa_results[k][0] += d;
4628 d = atof(sstrsep(&p, sep));
4629 rsa_results[k][1] += d;
4631 d = atof(sstrsep(&p, sep));
4632 rsa_results[k][2] += d;
4634 d = atof(sstrsep(&p, sep));
4635 rsa_results[k][3] += d;
4637 } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
4638 tk = sstrsep(&p, sep);
4639 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
4642 d = atof(sstrsep(&p, sep));
4643 dsa_results[k][0] += d;
4645 d = atof(sstrsep(&p, sep));
4646 dsa_results[k][1] += d;
4648 } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
4649 tk = sstrsep(&p, sep);
4650 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
4653 d = atof(sstrsep(&p, sep));
4654 ecdsa_results[k][0] += d;
4656 d = atof(sstrsep(&p, sep));
4657 ecdsa_results[k][1] += d;
4659 } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
4660 tk = sstrsep(&p, sep);
4661 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
4664 d = atof(sstrsep(&p, sep));
4665 ecdh_results[k][0] += d;
4667 # ifndef OPENSSL_NO_ECX
4668 } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
4669 tk = sstrsep(&p, sep);
4670 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
4674 d = atof(sstrsep(&p, sep));
4675 eddsa_results[k][0] += d;
4677 d = atof(sstrsep(&p, sep));
4678 eddsa_results[k][1] += d;
4680 # endif /* OPENSSL_NO_ECX */
4681 # ifndef OPENSSL_NO_SM2
4682 } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
4683 tk = sstrsep(&p, sep);
4684 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
4688 d = atof(sstrsep(&p, sep));
4689 sm2_results[k][0] += d;
4691 d = atof(sstrsep(&p, sep));
4692 sm2_results[k][1] += d;
4694 # endif /* OPENSSL_NO_SM2 */
4695 # ifndef OPENSSL_NO_DH
4696 } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
4697 tk = sstrsep(&p, sep);
4698 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
4701 d = atof(sstrsep(&p, sep));
4702 ffdh_results[k][0] += d;
4704 # endif /* OPENSSL_NO_DH */
4705 } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
4706 tk = sstrsep(&p, sep);
4707 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
4708 d = atof(sstrsep(&p, sep));
4709 kems_results[k][0] += d;
4711 d = atof(sstrsep(&p, sep));
4712 kems_results[k][1] += d;
4714 d = atof(sstrsep(&p, sep));
4715 kems_results[k][2] += d;
4717 } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
4718 tk = sstrsep(&p, sep);
4719 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
4720 d = atof(sstrsep(&p, sep));
4721 sigs_results[k][0] += d;
4723 d = atof(sstrsep(&p, sep));
4724 sigs_results[k][1] += d;
4726 d = atof(sstrsep(&p, sep));
4727 sigs_results[k][2] += d;
4729 } else if (!HAS_PREFIX(buf, "+H:")) {
4730 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
4738 for (n = 0; n < multi; ++n) {
4739 while (wait(&status) == -1)
4740 if (errno != EINTR) {
4741 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
4745 if (WIFEXITED(status) && WEXITSTATUS(status)) {
4746 BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
4747 } else if (WIFSIGNALED(status)) {
4748 BIO_printf(bio_err, "Child terminated by signal %d\n",
4756 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
4757 const openssl_speed_sec_t *seconds)
4759 static const int mblengths_list[] =
4760 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
4761 const int *mblengths = mblengths_list;
4762 int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
4763 const char *alg_name;
4764 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
4765 EVP_CIPHER_CTX *ctx = NULL;
4768 if (lengths_single) {
4769 mblengths = &lengths_single;
4773 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
4774 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
4775 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
4776 app_bail_out("failed to allocate cipher context\n");
4777 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
4778 app_bail_out("failed to initialise cipher context\n");
4780 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
4781 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
4784 key = app_malloc(keylen, "evp_cipher key");
4785 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
4786 app_bail_out("failed to generate random cipher key\n");
4787 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
4788 app_bail_out("failed to set cipher key\n");
4789 OPENSSL_clear_free(key, keylen);
4791 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
4792 sizeof(no_key), no_key) <= 0)
4793 app_bail_out("failed to set AEAD key\n");
4794 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4795 app_bail_out("failed to get cipher name\n");
4797 for (j = 0; j < num; j++) {
4798 print_message(alg_name, mblengths[j], seconds->sym);
4800 for (count = 0; run && count < INT_MAX; count++) {
4801 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
4802 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
4803 size_t len = mblengths[j];
4806 memset(aad, 0, 8); /* avoid uninitialized values */
4807 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
4808 aad[9] = 3; /* version */
4810 aad[11] = 0; /* length */
4812 mb_param.out = NULL;
4815 mb_param.interleave = 8;
4817 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
4818 sizeof(mb_param), &mb_param);
4824 (void)EVP_CIPHER_CTX_ctrl(ctx,
4825 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
4826 sizeof(mb_param), &mb_param);
4830 if (RAND_bytes(inp, 16) <= 0)
4831 app_bail_out("error setting random bytes\n");
4833 aad[11] = (unsigned char)(len >> 8);
4834 aad[12] = (unsigned char)(len);
4835 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
4836 EVP_AEAD_TLS1_AAD_LEN, aad);
4837 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
4841 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
4842 : "%d %s ops in %.2fs\n", count, "evp", d);
4843 if ((ciph_success <= 0) && (mr == 0))
4844 BIO_printf(bio_err, "Error performing cipher op\n");
4845 results[D_EVP][j] = ((double)count) / d * mblengths[j];
4849 fprintf(stdout, "+H");
4850 for (j = 0; j < num; j++)
4851 fprintf(stdout, ":%d", mblengths[j]);
4852 fprintf(stdout, "\n");
4853 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
4854 for (j = 0; j < num; j++)
4855 fprintf(stdout, ":%.2f", results[D_EVP][j]);
4856 fprintf(stdout, "\n");
4859 "The 'numbers' are in 1000s of bytes per second processed.\n");
4860 fprintf(stdout, "type ");
4861 for (j = 0; j < num; j++)
4862 fprintf(stdout, "%7d bytes", mblengths[j]);
4863 fprintf(stdout, "\n");
4864 fprintf(stdout, "%-24s", alg_name);
4866 for (j = 0; j < num; j++) {
4867 if (results[D_EVP][j] > 10000)
4868 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
4870 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
4872 fprintf(stdout, "\n");
4878 EVP_CIPHER_CTX_free(ctx);