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)
53 * While VirtualLock is available under the app partition (e.g. UWP),
54 * the headers do not define the API. Define it ourselves instead.
60 _In_ LPVOID lpAddress,
65 #if defined(OPENSSL_SYS_LINUX)
66 # include <sys/mman.h>
69 #include <openssl/bn.h>
70 #include <openssl/rsa.h>
71 #include "./testrsa.h"
73 # include <openssl/dh.h>
75 #include <openssl/x509.h>
76 #include <openssl/dsa.h>
77 #include "./testdsa.h"
78 #include <openssl/modes.h>
81 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
85 # include <sys/wait.h>
95 #define MAX_MISALIGNMENT 63
96 #define MAX_ECDH_SIZE 256
98 #define MAX_FFDH_SIZE 1024
100 #ifndef RSA_DEFAULT_PRIME_NUM
101 # define RSA_DEFAULT_PRIME_NUM 2
104 typedef struct openssl_speed_sec_st {
115 } openssl_speed_sec_t;
117 static volatile int run = 0;
119 static int mr = 0; /* machine-readeable output format to merge fork results */
120 static int usertime = 1;
122 static double Time_F(int s);
123 static void print_message(const char *s, int length, int tm);
124 static void pkey_print_message(const char *str, const char *str2,
125 unsigned int bits, int sec);
126 static void kskey_print_message(const char *str, const char *str2, int tm);
127 static void print_result(int alg, int run_no, int count, double time_used);
129 static int do_multi(int multi, int size_num);
132 static int domlock = 0;
134 static const int lengths_list[] = {
135 16, 64, 256, 1024, 8 * 1024, 16 * 1024
137 #define SIZE_NUM OSSL_NELEM(lengths_list)
138 static const int *lengths = lengths_list;
140 static const int aead_lengths_list[] = {
141 2, 31, 136, 1024, 8 * 1024, 16 * 1024
149 static void alarmed(ossl_unused int sig)
151 signal(SIGALRM, alarmed);
155 static double Time_F(int s)
157 double ret = app_tminterval(s, usertime);
163 #elif defined(_WIN32)
167 static unsigned int lapse;
168 static volatile unsigned int schlock;
169 static void alarm_win32(unsigned int secs)
174 # define alarm alarm_win32
176 static DWORD WINAPI sleepy(VOID * arg)
184 static double Time_F(int s)
191 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
193 DWORD err = GetLastError();
194 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
198 Sleep(0); /* scheduler spinlock */
199 ret = app_tminterval(s, usertime);
201 ret = app_tminterval(s, usertime);
203 TerminateThread(thr, 0);
210 # error "SIGALRM not defined and the platform is not Windows"
213 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
214 const openssl_speed_sec_t *seconds);
216 static int opt_found(const char *name, unsigned int *result,
217 const OPT_PAIR pairs[], unsigned int nbelem)
221 for (idx = 0; idx < nbelem; ++idx, pairs++)
222 if (strcmp(name, pairs->name) == 0) {
223 *result = pairs->retval;
228 #define opt_found(value, pairs, result)\
229 opt_found(value, result, pairs, OSSL_NELEM(pairs))
231 typedef enum OPTION_choice {
233 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
234 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG,
235 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK, OPT_KEM, OPT_SIG
238 const OPTIONS speed_options[] = {
239 {OPT_HELP_STR, 1, '-',
240 "Usage: %s [options] [algorithm...]\n"
241 "All +int options consider prefix '0' as base-8 input, "
242 "prefix '0x'/'0X' as base-16 input.\n"
245 OPT_SECTION("General"),
246 {"help", OPT_HELP, '-', "Display this summary"},
248 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
249 {"mr", OPT_MR, '-', "Produce machine readable output"},
251 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
253 #ifndef OPENSSL_NO_ASYNC
254 {"async_jobs", OPT_ASYNCJOBS, 'p',
255 "Enable async mode and start specified number of jobs"},
257 #ifndef OPENSSL_NO_ENGINE
258 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
260 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
261 {"mlock", OPT_MLOCK, '-', "Lock memory for better result determinism"},
264 OPT_SECTION("Selection"),
265 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
266 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
267 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
268 {"decrypt", OPT_DECRYPT, '-',
269 "Time decryption instead of encryption (only EVP)"},
270 {"aead", OPT_AEAD, '-',
271 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
272 {"kem-algorithms", OPT_KEM, '-',
273 "Benchmark KEM algorithms"},
274 {"signature-algorithms", OPT_SIG, '-',
275 "Benchmark signature algorithms"},
277 OPT_SECTION("Timing"),
278 {"elapsed", OPT_ELAPSED, '-',
279 "Use wall-clock time instead of CPU user time as divisor"},
280 {"seconds", OPT_SECONDS, 'p',
281 "Run benchmarks for specified amount of seconds"},
282 {"bytes", OPT_BYTES, 'p',
283 "Run [non-PKI] benchmarks on custom-sized buffer"},
284 {"misalign", OPT_MISALIGN, 'p',
285 "Use specified offset to mis-align buffers"},
291 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
296 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
297 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
298 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
299 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
300 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
301 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
302 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, D_KMAC128, D_KMAC256,
305 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
306 static const char *names[ALGOR_NUM] = {
307 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
308 "sha256", "sha512", "whirlpool", "hmac(sha256)",
309 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
310 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
311 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
312 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
313 "evp", "ghash", "rand", "cmac", "kmac128", "kmac256"
316 /* list of configured algorithm (remaining), with some few alias */
317 static const OPT_PAIR doit_choices[] = {
324 {"sha256", D_SHA256},
325 {"sha512", D_SHA512},
326 {"whirlpool", D_WHIRLPOOL},
327 {"ripemd", D_RMD160},
328 {"rmd160", D_RMD160},
329 {"ripemd160", D_RMD160},
331 {"des-cbc", D_CBC_DES},
332 {"des-ede3", D_EDE3_DES},
333 {"aes-128-cbc", D_CBC_128_AES},
334 {"aes-192-cbc", D_CBC_192_AES},
335 {"aes-256-cbc", D_CBC_256_AES},
336 {"camellia-128-cbc", D_CBC_128_CML},
337 {"camellia-192-cbc", D_CBC_192_CML},
338 {"camellia-256-cbc", D_CBC_256_CML},
339 {"rc2-cbc", D_CBC_RC2},
341 {"rc5-cbc", D_CBC_RC5},
343 {"idea-cbc", D_CBC_IDEA},
344 {"idea", D_CBC_IDEA},
345 {"seed-cbc", D_CBC_SEED},
346 {"seed", D_CBC_SEED},
347 {"bf-cbc", D_CBC_BF},
348 {"blowfish", D_CBC_BF},
350 {"cast-cbc", D_CBC_CAST},
351 {"cast", D_CBC_CAST},
352 {"cast5", D_CBC_CAST},
355 {"kmac128", D_KMAC128},
356 {"kmac256", D_KMAC256},
359 static double results[ALGOR_NUM][SIZE_NUM];
361 enum { R_DSA_1024, R_DSA_2048, DSA_NUM };
362 static const OPT_PAIR dsa_choices[DSA_NUM] = {
363 {"dsa1024", R_DSA_1024},
364 {"dsa2048", R_DSA_2048}
366 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
369 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
372 static const OPT_PAIR rsa_choices[RSA_NUM] = {
373 {"rsa512", R_RSA_512},
374 {"rsa1024", R_RSA_1024},
375 {"rsa2048", R_RSA_2048},
376 {"rsa3072", R_RSA_3072},
377 {"rsa4096", R_RSA_4096},
378 {"rsa7680", R_RSA_7680},
379 {"rsa15360", R_RSA_15360}
382 static double rsa_results[RSA_NUM][4]; /* 4 ops: sign, verify, encrypt, decrypt */
384 #ifndef OPENSSL_NO_DH
386 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
389 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
390 {"ffdh2048", R_FFDH_2048},
391 {"ffdh3072", R_FFDH_3072},
392 {"ffdh4096", R_FFDH_4096},
393 {"ffdh6144", R_FFDH_6144},
394 {"ffdh8192", R_FFDH_8192},
397 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
398 #endif /* OPENSSL_NO_DH */
401 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
402 #ifndef OPENSSL_NO_EC2M
403 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
404 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
406 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
407 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
409 /* list of ecdsa curves */
410 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
411 {"ecdsap160", R_EC_P160},
412 {"ecdsap192", R_EC_P192},
413 {"ecdsap224", R_EC_P224},
414 {"ecdsap256", R_EC_P256},
415 {"ecdsap384", R_EC_P384},
416 {"ecdsap521", R_EC_P521},
417 #ifndef OPENSSL_NO_EC2M
418 {"ecdsak163", R_EC_K163},
419 {"ecdsak233", R_EC_K233},
420 {"ecdsak283", R_EC_K283},
421 {"ecdsak409", R_EC_K409},
422 {"ecdsak571", R_EC_K571},
423 {"ecdsab163", R_EC_B163},
424 {"ecdsab233", R_EC_B233},
425 {"ecdsab283", R_EC_B283},
426 {"ecdsab409", R_EC_B409},
427 {"ecdsab571", R_EC_B571},
429 {"ecdsabrp256r1", R_EC_BRP256R1},
430 {"ecdsabrp256t1", R_EC_BRP256T1},
431 {"ecdsabrp384r1", R_EC_BRP384R1},
432 {"ecdsabrp384t1", R_EC_BRP384T1},
433 {"ecdsabrp512r1", R_EC_BRP512R1},
434 {"ecdsabrp512t1", R_EC_BRP512T1}
437 #ifndef OPENSSL_NO_ECX
438 R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM
443 /* list of ecdh curves, extension of |ecdsa_choices| list above */
444 static const OPT_PAIR ecdh_choices[EC_NUM] = {
445 {"ecdhp160", R_EC_P160},
446 {"ecdhp192", R_EC_P192},
447 {"ecdhp224", R_EC_P224},
448 {"ecdhp256", R_EC_P256},
449 {"ecdhp384", R_EC_P384},
450 {"ecdhp521", R_EC_P521},
451 #ifndef OPENSSL_NO_EC2M
452 {"ecdhk163", R_EC_K163},
453 {"ecdhk233", R_EC_K233},
454 {"ecdhk283", R_EC_K283},
455 {"ecdhk409", R_EC_K409},
456 {"ecdhk571", R_EC_K571},
457 {"ecdhb163", R_EC_B163},
458 {"ecdhb233", R_EC_B233},
459 {"ecdhb283", R_EC_B283},
460 {"ecdhb409", R_EC_B409},
461 {"ecdhb571", R_EC_B571},
463 {"ecdhbrp256r1", R_EC_BRP256R1},
464 {"ecdhbrp256t1", R_EC_BRP256T1},
465 {"ecdhbrp384r1", R_EC_BRP384R1},
466 {"ecdhbrp384t1", R_EC_BRP384T1},
467 {"ecdhbrp512r1", R_EC_BRP512R1},
468 {"ecdhbrp512t1", R_EC_BRP512T1},
469 #ifndef OPENSSL_NO_ECX
470 {"ecdhx25519", R_EC_X25519},
471 {"ecdhx448", R_EC_X448}
475 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
476 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
478 #ifndef OPENSSL_NO_ECX
479 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
480 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
481 {"ed25519", R_EC_Ed25519},
482 {"ed448", R_EC_Ed448}
485 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
486 #endif /* OPENSSL_NO_ECX */
488 #ifndef OPENSSL_NO_SM2
489 enum { R_EC_CURVESM2, SM2_NUM };
490 static const OPT_PAIR sm2_choices[SM2_NUM] = {
491 {"curveSM2", R_EC_CURVESM2}
493 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
494 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
495 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
496 #endif /* OPENSSL_NO_SM2 */
498 #define MAX_KEM_NUM 111
499 static size_t kems_algs_len = 0;
500 static char *kems_algname[MAX_KEM_NUM] = { NULL };
501 static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
503 #define MAX_SIG_NUM 111
504 static size_t sigs_algs_len = 0;
505 static char *sigs_algname[MAX_SIG_NUM] = { NULL };
506 static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
508 #define COND(unused_cond) (run && count < INT_MAX)
509 #define COUNT(d) (count)
511 typedef struct loopargs_st {
512 ASYNC_JOB *inprogress_job;
513 ASYNC_WAIT_CTX *wait_ctx;
516 unsigned char *buf_malloc;
517 unsigned char *buf2_malloc;
522 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
523 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
524 EVP_PKEY_CTX *rsa_encrypt_ctx[RSA_NUM];
525 EVP_PKEY_CTX *rsa_decrypt_ctx[RSA_NUM];
526 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
527 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
528 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
529 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
530 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
531 #ifndef OPENSSL_NO_ECX
532 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
533 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
534 #endif /* OPENSSL_NO_ECX */
535 #ifndef OPENSSL_NO_SM2
536 EVP_MD_CTX *sm2_ctx[SM2_NUM];
537 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
538 EVP_PKEY *sm2_pkey[SM2_NUM];
540 unsigned char *secret_a;
541 unsigned char *secret_b;
542 size_t outlen[EC_NUM];
543 #ifndef OPENSSL_NO_DH
544 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
545 unsigned char *secret_ff_a;
546 unsigned char *secret_ff_b;
550 EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM];
551 EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM];
552 EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM];
553 size_t kem_out_len[MAX_KEM_NUM];
554 size_t kem_secret_len[MAX_KEM_NUM];
555 unsigned char *kem_out[MAX_KEM_NUM];
556 unsigned char *kem_send_secret[MAX_KEM_NUM];
557 unsigned char *kem_rcv_secret[MAX_KEM_NUM];
558 EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM];
559 EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM];
560 EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM];
561 size_t sig_max_sig_len[MAX_KEM_NUM];
562 size_t sig_act_sig_len[MAX_KEM_NUM];
563 unsigned char *sig_sig[MAX_KEM_NUM];
565 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
566 loopargs_t *loopargs);
568 static unsigned int testnum;
570 static char *evp_mac_mdname = "sha256";
571 static char *evp_hmac_name = NULL;
572 static const char *evp_md_name = NULL;
573 static char *evp_mac_ciphername = "aes-128-cbc";
574 static char *evp_cmac_name = NULL;
576 static int have_md(const char *name)
581 if (opt_md_silent(name, &md)) {
582 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
584 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
586 EVP_MD_CTX_free(ctx);
592 static int have_cipher(const char *name)
595 EVP_CIPHER *cipher = NULL;
597 if (opt_cipher_silent(name, &cipher)) {
598 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
601 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
603 EVP_CIPHER_CTX_free(ctx);
604 EVP_CIPHER_free(cipher);
609 static int EVP_Digest_loop(const char *mdname, ossl_unused int algindex, void *args)
611 loopargs_t *tempargs = *(loopargs_t **) args;
612 unsigned char *buf = tempargs->buf;
613 unsigned char digest[EVP_MAX_MD_SIZE];
617 if (!opt_md_silent(mdname, &md))
619 for (count = 0; COND(c[algindex][testnum]); count++) {
620 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
630 static int EVP_Digest_md_loop(void *args)
632 return EVP_Digest_loop(evp_md_name, D_EVP, args);
635 static int EVP_Digest_MD2_loop(void *args)
637 return EVP_Digest_loop("md2", D_MD2, args);
640 static int EVP_Digest_MDC2_loop(void *args)
642 return EVP_Digest_loop("mdc2", D_MDC2, args);
645 static int EVP_Digest_MD4_loop(void *args)
647 return EVP_Digest_loop("md4", D_MD4, args);
650 static int MD5_loop(void *args)
652 return EVP_Digest_loop("md5", D_MD5, args);
655 static int mac_setup(const char *name,
656 EVP_MAC **mac, OSSL_PARAM params[],
657 loopargs_t *loopargs, unsigned int loopargs_len)
661 *mac = EVP_MAC_fetch(app_get0_libctx(), name, app_get0_propq());
665 for (i = 0; i < loopargs_len; i++) {
666 loopargs[i].mctx = EVP_MAC_CTX_new(*mac);
667 if (loopargs[i].mctx == NULL)
670 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
677 static void mac_teardown(EVP_MAC **mac,
678 loopargs_t *loopargs, unsigned int loopargs_len)
682 for (i = 0; i < loopargs_len; i++)
683 EVP_MAC_CTX_free(loopargs[i].mctx);
690 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
692 loopargs_t *tempargs = *(loopargs_t **) args;
693 unsigned char *buf = tempargs->buf;
694 EVP_MAC_CTX *mctx = tempargs->mctx;
695 unsigned char mac[EVP_MAX_MD_SIZE];
698 for (count = 0; COND(c[algindex][testnum]); count++) {
701 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
702 || !EVP_MAC_update(mctx, buf, lengths[testnum])
703 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
709 static int HMAC_loop(void *args)
711 return EVP_MAC_loop(D_HMAC, args);
714 static int CMAC_loop(void *args)
716 return EVP_MAC_loop(D_EVP_CMAC, args);
719 static int KMAC128_loop(void *args)
721 return EVP_MAC_loop(D_KMAC128, args);
724 static int KMAC256_loop(void *args)
726 return EVP_MAC_loop(D_KMAC256, args);
729 static int SHA1_loop(void *args)
731 return EVP_Digest_loop("sha1", D_SHA1, args);
734 static int SHA256_loop(void *args)
736 return EVP_Digest_loop("sha256", D_SHA256, args);
739 static int SHA512_loop(void *args)
741 return EVP_Digest_loop("sha512", D_SHA512, args);
744 static int WHIRLPOOL_loop(void *args)
746 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
749 static int EVP_Digest_RMD160_loop(void *args)
751 return EVP_Digest_loop("ripemd160", D_RMD160, args);
756 static int EVP_Cipher_loop(void *args)
758 loopargs_t *tempargs = *(loopargs_t **) args;
759 unsigned char *buf = tempargs->buf;
762 if (tempargs->ctx == NULL)
764 for (count = 0; COND(c[algindex][testnum]); count++)
765 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
770 static int GHASH_loop(void *args)
772 loopargs_t *tempargs = *(loopargs_t **) args;
773 unsigned char *buf = tempargs->buf;
774 EVP_MAC_CTX *mctx = tempargs->mctx;
777 /* just do the update in the loop to be comparable with 1.1.1 */
778 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
779 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
785 #define MAX_BLOCK_SIZE 128
787 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
789 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
790 const unsigned char *key,
793 EVP_CIPHER_CTX *ctx = NULL;
794 EVP_CIPHER *cipher = NULL;
796 if (!opt_cipher_silent(ciphername, &cipher))
799 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
802 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
803 EVP_CIPHER_CTX_free(ctx);
808 if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) {
809 EVP_CIPHER_CTX_free(ctx);
814 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
815 EVP_CIPHER_CTX_free(ctx);
821 EVP_CIPHER_free(cipher);
825 static int RAND_bytes_loop(void *args)
827 loopargs_t *tempargs = *(loopargs_t **) args;
828 unsigned char *buf = tempargs->buf;
831 for (count = 0; COND(c[D_RAND][testnum]); count++)
832 RAND_bytes(buf, lengths[testnum]);
836 static int decrypt = 0;
837 static int EVP_Update_loop(void *args)
839 loopargs_t *tempargs = *(loopargs_t **) args;
840 unsigned char *buf = tempargs->buf;
841 EVP_CIPHER_CTX *ctx = tempargs->ctx;
843 unsigned char faketag[16] = { 0xcc };
846 if (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) {
847 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(faketag), faketag);
849 for (count = 0; COND(c[D_EVP][testnum]); count++) {
850 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
852 /* reset iv in case of counter overflow */
853 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
857 for (count = 0; COND(c[D_EVP][testnum]); count++) {
858 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
860 /* reset iv in case of counter overflow */
861 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
866 rc = EVP_DecryptFinal_ex(ctx, buf, &outl);
868 rc = EVP_EncryptFinal_ex(ctx, buf, &outl);
871 BIO_printf(bio_err, "Error finalizing cipher loop\n");
876 * CCM does not support streaming. For the purpose of performance measurement,
877 * each message is encrypted using the same (key,iv)-pair. Do not use this
878 * code in your application.
880 static int EVP_Update_loop_ccm(void *args)
882 loopargs_t *tempargs = *(loopargs_t **) args;
883 unsigned char *buf = tempargs->buf;
884 EVP_CIPHER_CTX *ctx = tempargs->ctx;
885 int outl, count, realcount = 0, final;
886 unsigned char tag[12];
889 for (count = 0; COND(c[D_EVP][testnum]); count++) {
890 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
893 && EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
894 /* counter is reset on every update */
895 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
899 for (count = 0; COND(c[D_EVP][testnum]); count++) {
900 /* restore iv length field */
901 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]) > 0
902 /* counter is reset on every update */
903 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
908 final = EVP_DecryptFinal_ex(ctx, buf, &outl);
910 final = EVP_EncryptFinal_ex(ctx, buf, &outl);
913 BIO_printf(bio_err, "Error finalizing ccm loop\n");
918 * To make AEAD benchmarking more relevant perform TLS-like operations,
919 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
920 * payload length is not actually limited by 16KB...
922 static int EVP_Update_loop_aead(void *args)
924 loopargs_t *tempargs = *(loopargs_t **) args;
925 unsigned char *buf = tempargs->buf;
926 EVP_CIPHER_CTX *ctx = tempargs->ctx;
927 int outl, count, realcount = 0;
928 unsigned char aad[13] = { 0xcc };
929 unsigned char faketag[16] = { 0xcc };
932 for (count = 0; COND(c[D_EVP][testnum]); count++) {
933 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
934 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
935 sizeof(faketag), faketag) > 0
936 && EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
937 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
938 && EVP_DecryptFinal_ex(ctx, buf + outl, &outl) > 0)
942 for (count = 0; COND(c[D_EVP][testnum]); count++) {
943 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
944 && EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
945 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
946 && EVP_EncryptFinal_ex(ctx, buf + outl, &outl) > 0)
953 static int RSA_sign_loop(void *args)
955 loopargs_t *tempargs = *(loopargs_t **) args;
956 unsigned char *buf = tempargs->buf;
957 unsigned char *buf2 = tempargs->buf2;
958 size_t *rsa_num = &tempargs->sigsize;
959 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
962 for (count = 0; COND(rsa_c[testnum][0]); count++) {
963 *rsa_num = tempargs->buflen;
964 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
966 BIO_printf(bio_err, "RSA sign failure\n");
967 ERR_print_errors(bio_err);
975 static int RSA_verify_loop(void *args)
977 loopargs_t *tempargs = *(loopargs_t **) args;
978 unsigned char *buf = tempargs->buf;
979 unsigned char *buf2 = tempargs->buf2;
980 size_t rsa_num = tempargs->sigsize;
981 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
984 for (count = 0; COND(rsa_c[testnum][1]); count++) {
985 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
987 BIO_printf(bio_err, "RSA verify failure\n");
988 ERR_print_errors(bio_err);
996 static int RSA_encrypt_loop(void *args)
998 loopargs_t *tempargs = *(loopargs_t **) args;
999 unsigned char *buf = tempargs->buf;
1000 unsigned char *buf2 = tempargs->buf2;
1001 size_t *rsa_num = &tempargs->encsize;
1002 EVP_PKEY_CTX **rsa_encrypt_ctx = tempargs->rsa_encrypt_ctx;
1005 for (count = 0; COND(rsa_c[testnum][2]); count++) {
1006 *rsa_num = tempargs->buflen;
1007 ret = EVP_PKEY_encrypt(rsa_encrypt_ctx[testnum], buf2, rsa_num, buf, 36);
1009 BIO_printf(bio_err, "RSA encrypt failure\n");
1010 ERR_print_errors(bio_err);
1018 static int RSA_decrypt_loop(void *args)
1020 loopargs_t *tempargs = *(loopargs_t **) args;
1021 unsigned char *buf = tempargs->buf;
1022 unsigned char *buf2 = tempargs->buf2;
1024 EVP_PKEY_CTX **rsa_decrypt_ctx = tempargs->rsa_decrypt_ctx;
1027 for (count = 0; COND(rsa_c[testnum][3]); count++) {
1028 rsa_num = tempargs->buflen;
1029 ret = EVP_PKEY_decrypt(rsa_decrypt_ctx[testnum], buf, &rsa_num, buf2, tempargs->encsize);
1031 BIO_printf(bio_err, "RSA decrypt failure\n");
1032 ERR_print_errors(bio_err);
1040 #ifndef OPENSSL_NO_DH
1042 static int FFDH_derive_key_loop(void *args)
1044 loopargs_t *tempargs = *(loopargs_t **) args;
1045 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
1046 unsigned char *derived_secret = tempargs->secret_ff_a;
1049 for (count = 0; COND(ffdh_c[testnum][0]); count++) {
1050 /* outlen can be overwritten with a too small value (no padding used) */
1051 size_t outlen = MAX_FFDH_SIZE;
1053 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
1057 #endif /* OPENSSL_NO_DH */
1059 static int DSA_sign_loop(void *args)
1061 loopargs_t *tempargs = *(loopargs_t **) args;
1062 unsigned char *buf = tempargs->buf;
1063 unsigned char *buf2 = tempargs->buf2;
1064 size_t *dsa_num = &tempargs->sigsize;
1065 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
1068 for (count = 0; COND(dsa_c[testnum][0]); count++) {
1069 *dsa_num = tempargs->buflen;
1070 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
1072 BIO_printf(bio_err, "DSA sign failure\n");
1073 ERR_print_errors(bio_err);
1081 static int DSA_verify_loop(void *args)
1083 loopargs_t *tempargs = *(loopargs_t **) args;
1084 unsigned char *buf = tempargs->buf;
1085 unsigned char *buf2 = tempargs->buf2;
1086 size_t dsa_num = tempargs->sigsize;
1087 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
1090 for (count = 0; COND(dsa_c[testnum][1]); count++) {
1091 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
1093 BIO_printf(bio_err, "DSA verify failure\n");
1094 ERR_print_errors(bio_err);
1102 static int ECDSA_sign_loop(void *args)
1104 loopargs_t *tempargs = *(loopargs_t **) args;
1105 unsigned char *buf = tempargs->buf;
1106 unsigned char *buf2 = tempargs->buf2;
1107 size_t *ecdsa_num = &tempargs->sigsize;
1108 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
1111 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
1112 *ecdsa_num = tempargs->buflen;
1113 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
1115 BIO_printf(bio_err, "ECDSA sign failure\n");
1116 ERR_print_errors(bio_err);
1124 static int ECDSA_verify_loop(void *args)
1126 loopargs_t *tempargs = *(loopargs_t **) args;
1127 unsigned char *buf = tempargs->buf;
1128 unsigned char *buf2 = tempargs->buf2;
1129 size_t ecdsa_num = tempargs->sigsize;
1130 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
1133 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
1134 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
1137 BIO_printf(bio_err, "ECDSA verify failure\n");
1138 ERR_print_errors(bio_err);
1146 /* ******************************************************************** */
1148 static int ECDH_EVP_derive_key_loop(void *args)
1150 loopargs_t *tempargs = *(loopargs_t **) args;
1151 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
1152 unsigned char *derived_secret = tempargs->secret_a;
1154 size_t *outlen = &(tempargs->outlen[testnum]);
1156 for (count = 0; COND(ecdh_c[testnum][0]); count++)
1157 EVP_PKEY_derive(ctx, derived_secret, outlen);
1162 #ifndef OPENSSL_NO_ECX
1163 static int EdDSA_sign_loop(void *args)
1165 loopargs_t *tempargs = *(loopargs_t **) args;
1166 unsigned char *buf = tempargs->buf;
1167 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1168 unsigned char *eddsasig = tempargs->buf2;
1169 size_t *eddsasigsize = &tempargs->sigsize;
1172 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1173 ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
1175 BIO_printf(bio_err, "EdDSA sign init failure\n");
1176 ERR_print_errors(bio_err);
1180 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1182 BIO_printf(bio_err, "EdDSA sign failure\n");
1183 ERR_print_errors(bio_err);
1191 static int EdDSA_verify_loop(void *args)
1193 loopargs_t *tempargs = *(loopargs_t **) args;
1194 unsigned char *buf = tempargs->buf;
1195 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1196 unsigned char *eddsasig = tempargs->buf2;
1197 size_t eddsasigsize = tempargs->sigsize;
1200 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1201 ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
1203 BIO_printf(bio_err, "EdDSA verify init failure\n");
1204 ERR_print_errors(bio_err);
1208 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1210 BIO_printf(bio_err, "EdDSA verify failure\n");
1211 ERR_print_errors(bio_err);
1218 #endif /* OPENSSL_NO_ECX */
1220 #ifndef OPENSSL_NO_SM2
1221 static int SM2_sign_loop(void *args)
1223 loopargs_t *tempargs = *(loopargs_t **) args;
1224 unsigned char *buf = tempargs->buf;
1225 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1226 unsigned char *sm2sig = tempargs->buf2;
1229 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1230 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1232 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1233 sm2sigsize = max_size;
1235 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1236 NULL, sm2_pkey[testnum])) {
1237 BIO_printf(bio_err, "SM2 init sign failure\n");
1238 ERR_print_errors(bio_err);
1242 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1245 BIO_printf(bio_err, "SM2 sign failure\n");
1246 ERR_print_errors(bio_err);
1250 /* update the latest returned size and always use the fixed buffer size */
1251 tempargs->sigsize = sm2sigsize;
1257 static int SM2_verify_loop(void *args)
1259 loopargs_t *tempargs = *(loopargs_t **) args;
1260 unsigned char *buf = tempargs->buf;
1261 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1262 unsigned char *sm2sig = tempargs->buf2;
1263 size_t sm2sigsize = tempargs->sigsize;
1265 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1267 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1268 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1269 NULL, sm2_pkey[testnum])) {
1270 BIO_printf(bio_err, "SM2 verify init failure\n");
1271 ERR_print_errors(bio_err);
1275 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1278 BIO_printf(bio_err, "SM2 verify failure\n");
1279 ERR_print_errors(bio_err);
1286 #endif /* OPENSSL_NO_SM2 */
1288 static int KEM_keygen_loop(void *args)
1290 loopargs_t *tempargs = *(loopargs_t **) args;
1291 EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum];
1292 EVP_PKEY *pkey = NULL;
1295 for (count = 0; COND(kems_c[testnum][0]); count++) {
1296 if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
1299 * runtime defined to quite some degree by randomness,
1300 * so performance overhead of _free doesn't impact
1301 * results significantly. In any case this test is
1302 * meant to permit relative algorithm performance
1305 EVP_PKEY_free(pkey);
1311 static int KEM_encaps_loop(void *args)
1313 loopargs_t *tempargs = *(loopargs_t **) args;
1314 EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum];
1315 size_t out_len = tempargs->kem_out_len[testnum];
1316 size_t secret_len = tempargs->kem_secret_len[testnum];
1317 unsigned char *out = tempargs->kem_out[testnum];
1318 unsigned char *secret = tempargs->kem_send_secret[testnum];
1321 for (count = 0; COND(kems_c[testnum][1]); count++) {
1322 if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0)
1328 static int KEM_decaps_loop(void *args)
1330 loopargs_t *tempargs = *(loopargs_t **) args;
1331 EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum];
1332 size_t out_len = tempargs->kem_out_len[testnum];
1333 size_t secret_len = tempargs->kem_secret_len[testnum];
1334 unsigned char *out = tempargs->kem_out[testnum];
1335 unsigned char *secret = tempargs->kem_send_secret[testnum];
1338 for (count = 0; COND(kems_c[testnum][2]); count++) {
1339 if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0)
1345 static int SIG_keygen_loop(void *args)
1347 loopargs_t *tempargs = *(loopargs_t **) args;
1348 EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum];
1349 EVP_PKEY *pkey = NULL;
1352 for (count = 0; COND(kems_c[testnum][0]); count++) {
1353 EVP_PKEY_keygen(ctx, &pkey);
1354 /* TBD: How much does free influence runtime? */
1355 EVP_PKEY_free(pkey);
1361 static int SIG_sign_loop(void *args)
1363 loopargs_t *tempargs = *(loopargs_t **) args;
1364 EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum];
1365 /* be sure to not change stored sig: */
1366 unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum],
1368 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1369 size_t md_len = SHA256_DIGEST_LENGTH;
1372 for (count = 0; COND(kems_c[testnum][1]); count++) {
1373 size_t sig_len = tempargs->sig_max_sig_len[testnum];
1374 int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len);
1377 BIO_printf(bio_err, "SIG sign failure at count %d\n", count);
1378 ERR_print_errors(bio_err);
1387 static int SIG_verify_loop(void *args)
1389 loopargs_t *tempargs = *(loopargs_t **) args;
1390 EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum];
1391 size_t sig_len = tempargs->sig_act_sig_len[testnum];
1392 unsigned char *sig = tempargs->sig_sig[testnum];
1393 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1394 size_t md_len = SHA256_DIGEST_LENGTH;
1397 for (count = 0; COND(kems_c[testnum][2]); count++) {
1398 int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len);
1401 BIO_printf(bio_err, "SIG verify failure at count %d\n", count);
1402 ERR_print_errors(bio_err);
1411 static int run_benchmark(int async_jobs,
1412 int (*loop_function) (void *), loopargs_t *loopargs)
1414 int job_op_count = 0;
1415 int total_op_count = 0;
1416 int num_inprogress = 0;
1417 int error = 0, i = 0, ret = 0;
1418 OSSL_ASYNC_FD job_fd = 0;
1419 size_t num_job_fds = 0;
1421 if (async_jobs == 0) {
1422 return loop_function((void *)&loopargs);
1425 for (i = 0; i < async_jobs && !error; i++) {
1426 loopargs_t *looparg_item = loopargs + i;
1428 /* Copy pointer content (looparg_t item address) into async context */
1429 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1430 &job_op_count, loop_function,
1431 (void *)&looparg_item, sizeof(looparg_item));
1437 if (job_op_count == -1) {
1440 total_op_count += job_op_count;
1445 BIO_printf(bio_err, "Failure in the job\n");
1446 ERR_print_errors(bio_err);
1452 while (num_inprogress > 0) {
1453 #if defined(OPENSSL_SYS_WINDOWS)
1455 #elif defined(OPENSSL_SYS_UNIX)
1456 int select_result = 0;
1457 OSSL_ASYNC_FD max_fd = 0;
1460 FD_ZERO(&waitfdset);
1462 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1463 if (loopargs[i].inprogress_job == NULL)
1466 if (!ASYNC_WAIT_CTX_get_all_fds
1467 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1468 || num_job_fds > 1) {
1469 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1470 ERR_print_errors(bio_err);
1474 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1476 FD_SET(job_fd, &waitfdset);
1477 if (job_fd > max_fd)
1481 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1483 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1484 "Decrease the value of async_jobs\n",
1485 max_fd, FD_SETSIZE);
1486 ERR_print_errors(bio_err);
1491 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1492 if (select_result == -1 && errno == EINTR)
1495 if (select_result == -1) {
1496 BIO_printf(bio_err, "Failure in the select\n");
1497 ERR_print_errors(bio_err);
1502 if (select_result == 0)
1506 for (i = 0; i < async_jobs; i++) {
1507 if (loopargs[i].inprogress_job == NULL)
1510 if (!ASYNC_WAIT_CTX_get_all_fds
1511 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1512 || num_job_fds > 1) {
1513 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1514 ERR_print_errors(bio_err);
1518 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1521 #if defined(OPENSSL_SYS_UNIX)
1522 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1524 #elif defined(OPENSSL_SYS_WINDOWS)
1525 if (num_job_fds == 1
1526 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1531 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1532 loopargs[i].wait_ctx, &job_op_count,
1533 loop_function, (void *)(loopargs + i),
1534 sizeof(loopargs_t));
1539 if (job_op_count == -1) {
1542 total_op_count += job_op_count;
1545 loopargs[i].inprogress_job = NULL;
1550 loopargs[i].inprogress_job = NULL;
1551 BIO_printf(bio_err, "Failure in the job\n");
1552 ERR_print_errors(bio_err);
1559 return error ? -1 : total_op_count;
1562 typedef struct ec_curve_st {
1566 size_t sigsize; /* only used for EdDSA curves */
1569 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1571 EVP_PKEY_CTX *kctx = NULL;
1572 EVP_PKEY *key = NULL;
1574 /* Ensure that the error queue is empty */
1575 if (ERR_peek_error()) {
1577 "WARNING: the error queue contains previous unhandled errors.\n");
1578 ERR_print_errors(bio_err);
1582 * Let's try to create a ctx directly from the NID: this works for
1583 * curves like Curve25519 that are not implemented through the low
1584 * level EC interface.
1585 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1586 * then we set the curve by NID before deriving the actual keygen
1587 * ctx for that specific curve.
1589 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1591 EVP_PKEY_CTX *pctx = NULL;
1592 EVP_PKEY *params = NULL;
1594 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1595 * "int_ctx_new:unsupported algorithm" error was added to the
1597 * We remove it from the error queue as we are handling it.
1599 unsigned long error = ERR_peek_error();
1601 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1602 /* check that the error origin matches */
1603 && ERR_GET_LIB(error) == ERR_LIB_EVP
1604 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1605 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1606 ERR_get_error(); /* pop error from queue */
1607 if (ERR_peek_error()) {
1609 "Unhandled error in the error queue during EC key setup.\n");
1610 ERR_print_errors(bio_err);
1614 /* Create the context for parameter generation */
1615 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1616 || EVP_PKEY_paramgen_init(pctx) <= 0
1617 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1619 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) {
1620 BIO_printf(bio_err, "EC params init failure.\n");
1621 ERR_print_errors(bio_err);
1622 EVP_PKEY_CTX_free(pctx);
1625 EVP_PKEY_CTX_free(pctx);
1627 /* Create the context for the key generation */
1628 kctx = EVP_PKEY_CTX_new(params, NULL);
1629 EVP_PKEY_free(params);
1632 || EVP_PKEY_keygen_init(kctx) <= 0
1633 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1634 BIO_printf(bio_err, "EC key generation failure.\n");
1635 ERR_print_errors(bio_err);
1638 EVP_PKEY_CTX_free(kctx);
1642 #define stop_it(do_it, test_num)\
1643 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1645 /* Checks to see if algorithms are fetchable */
1646 #define IS_FETCHABLE(type, TYPE) \
1647 static int is_ ## type ## _fetchable(const TYPE *alg) \
1650 const char *propq = app_get0_propq(); \
1651 OSSL_LIB_CTX *libctx = app_get0_libctx(); \
1652 const char *name = TYPE ## _get0_name(alg); \
1655 impl = TYPE ## _fetch(libctx, name, propq); \
1656 ERR_pop_to_mark(); \
1659 TYPE ## _free(impl); \
1663 IS_FETCHABLE(signature, EVP_SIGNATURE)
1664 IS_FETCHABLE(kem, EVP_KEM)
1666 DEFINE_STACK_OF(EVP_KEM)
1668 static int kems_cmp(const EVP_KEM * const *a,
1669 const EVP_KEM * const *b)
1671 return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
1672 OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
1675 static void collect_kem(EVP_KEM *kem, void *stack)
1677 STACK_OF(EVP_KEM) *kem_stack = stack;
1679 if (is_kem_fetchable(kem)
1680 && sk_EVP_KEM_push(kem_stack, kem) > 0) {
1681 EVP_KEM_up_ref(kem);
1685 static int kem_locate(const char *algo, unsigned int *idx)
1689 for (i = 0; i < kems_algs_len; i++) {
1690 if (strcmp(kems_algname[i], algo) == 0) {
1698 DEFINE_STACK_OF(EVP_SIGNATURE)
1700 static int signatures_cmp(const EVP_SIGNATURE * const *a,
1701 const EVP_SIGNATURE * const *b)
1703 return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
1704 OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
1707 static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
1709 STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
1711 if (is_signature_fetchable(sig)
1712 && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
1713 EVP_SIGNATURE_up_ref(sig);
1716 static int sig_locate(const char *algo, unsigned int *idx)
1720 for (i = 0; i < sigs_algs_len; i++) {
1721 if (strcmp(sigs_algname[i], algo) == 0) {
1729 static int get_max(const uint8_t doit[], size_t algs_len) {
1733 for (i = 0; i < algs_len; i++)
1734 if (maxcnt < doit[i]) maxcnt = doit[i];
1738 int speed_main(int argc, char **argv)
1742 loopargs_t *loopargs = NULL;
1744 const char *engine_id = NULL;
1745 EVP_CIPHER *evp_cipher = NULL;
1746 EVP_MAC *mac = NULL;
1749 int async_init = 0, multiblock = 0, pr_header = 0;
1750 uint8_t doit[ALGOR_NUM] = { 0 };
1751 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1752 STACK_OF(EVP_KEM) *kem_stack = NULL;
1753 STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
1755 unsigned int size_num = SIZE_NUM;
1756 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1762 EVP_PKEY_CTX *genctx = NULL;
1767 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1768 ECDSA_SECONDS, ECDH_SECONDS,
1769 EdDSA_SECONDS, SM2_SECONDS,
1770 FFDH_SECONDS, KEM_SECONDS,
1773 static const unsigned char key32[32] = {
1774 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1775 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1776 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1777 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1779 static const unsigned char deskey[] = {
1780 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1781 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1782 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1784 static const struct {
1785 const unsigned char *data;
1786 unsigned int length;
1789 { test512, sizeof(test512), 512 },
1790 { test1024, sizeof(test1024), 1024 },
1791 { test2048, sizeof(test2048), 2048 },
1792 { test3072, sizeof(test3072), 3072 },
1793 { test4096, sizeof(test4096), 4096 },
1794 { test7680, sizeof(test7680), 7680 },
1795 { test15360, sizeof(test15360), 15360 }
1797 uint8_t rsa_doit[RSA_NUM] = { 0 };
1798 int primes = RSA_DEFAULT_PRIME_NUM;
1799 #ifndef OPENSSL_NO_DH
1800 typedef struct ffdh_params_st {
1806 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1807 {"ffdh2048", NID_ffdhe2048, 2048},
1808 {"ffdh3072", NID_ffdhe3072, 3072},
1809 {"ffdh4096", NID_ffdhe4096, 4096},
1810 {"ffdh6144", NID_ffdhe6144, 6144},
1811 {"ffdh8192", NID_ffdhe8192, 8192}
1813 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1815 #endif /* OPENSSL_NO_DH */
1816 static const unsigned int dsa_bits[DSA_NUM] = { 1024, 2048 };
1817 uint8_t dsa_doit[DSA_NUM] = { 0 };
1819 * We only test over the following curves as they are representative, To
1820 * add tests over more curves, simply add the curve NID and curve name to
1821 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1822 * lists accordingly.
1824 static const EC_CURVE ec_curves[EC_NUM] = {
1826 {"secp160r1", NID_secp160r1, 160},
1827 {"nistp192", NID_X9_62_prime192v1, 192},
1828 {"nistp224", NID_secp224r1, 224},
1829 {"nistp256", NID_X9_62_prime256v1, 256},
1830 {"nistp384", NID_secp384r1, 384},
1831 {"nistp521", NID_secp521r1, 521},
1832 #ifndef OPENSSL_NO_EC2M
1834 {"nistk163", NID_sect163k1, 163},
1835 {"nistk233", NID_sect233k1, 233},
1836 {"nistk283", NID_sect283k1, 283},
1837 {"nistk409", NID_sect409k1, 409},
1838 {"nistk571", NID_sect571k1, 571},
1839 {"nistb163", NID_sect163r2, 163},
1840 {"nistb233", NID_sect233r1, 233},
1841 {"nistb283", NID_sect283r1, 283},
1842 {"nistb409", NID_sect409r1, 409},
1843 {"nistb571", NID_sect571r1, 571},
1845 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1846 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1847 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1848 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1849 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1850 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1851 #ifndef OPENSSL_NO_ECX
1852 /* Other and ECDH only ones */
1853 {"X25519", NID_X25519, 253},
1854 {"X448", NID_X448, 448}
1857 #ifndef OPENSSL_NO_ECX
1858 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1860 {"Ed25519", NID_ED25519, 253, 64},
1861 {"Ed448", NID_ED448, 456, 114}
1863 #endif /* OPENSSL_NO_ECX */
1864 #ifndef OPENSSL_NO_SM2
1865 static const EC_CURVE sm2_curves[SM2_NUM] = {
1867 {"CurveSM2", NID_sm2, 256}
1869 uint8_t sm2_doit[SM2_NUM] = { 0 };
1871 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1872 uint8_t ecdh_doit[EC_NUM] = { 0 };
1873 #ifndef OPENSSL_NO_ECX
1874 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1875 #endif /* OPENSSL_NO_ECX */
1877 uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
1878 uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
1880 uint8_t do_kems = 0;
1881 uint8_t do_sigs = 0;
1883 /* checks declared curves against choices list. */
1884 #ifndef OPENSSL_NO_ECX
1885 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1886 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1888 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1889 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1891 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1892 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1893 #endif /* OPENSSL_NO_ECX */
1895 #ifndef OPENSSL_NO_SM2
1896 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1897 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1900 prog = opt_init(argc, argv, speed_options);
1901 while ((o = opt_next()) != OPT_EOF) {
1906 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1909 opt_help(speed_options);
1917 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1921 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1922 if (have_md(opt_arg()))
1923 evp_md_name = opt_arg();
1925 if (evp_cipher == NULL && evp_md_name == NULL) {
1926 ERR_clear_last_mark();
1928 "%s: %s is an unknown cipher or digest\n",
1936 if (!have_md(opt_arg())) {
1937 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1941 evp_mac_mdname = opt_arg();
1945 if (!have_cipher(opt_arg())) {
1946 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1950 evp_mac_ciphername = opt_arg();
1951 doit[D_EVP_CMAC] = 1;
1958 * In a forked execution, an engine might need to be
1959 * initialised by each child process, not by the parent.
1960 * So store the name here and run setup_engine() later on.
1962 engine_id = opt_arg();
1966 multi = opt_int_arg();
1967 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1968 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1974 #ifndef OPENSSL_NO_ASYNC
1975 async_jobs = opt_int_arg();
1976 if (!ASYNC_is_capable()) {
1978 "%s: async_jobs specified but async not supported\n",
1982 if (async_jobs > 99999) {
1983 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1989 misalign = opt_int_arg();
1990 if (misalign > MISALIGN) {
1992 "%s: Maximum offset is %d\n", prog, MISALIGN);
2001 #ifdef OPENSSL_NO_MULTIBLOCK
2003 "%s: -mb specified but multi-block support is disabled\n",
2012 case OPT_PROV_CASES:
2013 if (!opt_provider(o))
2017 conf = app_load_config_modules(opt_arg());
2022 primes = opt_int_arg();
2025 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
2026 = seconds.ecdh = seconds.eddsa
2027 = seconds.sm2 = seconds.ffdh
2028 = seconds.kem = seconds.sig = opt_int_arg();
2031 lengths_single = opt_int_arg();
2032 lengths = &lengths_single;
2046 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
2048 "%s: -mlock not supported on this platform\n",
2056 /* find all KEMs currently available */
2057 kem_stack = sk_EVP_KEM_new(kems_cmp);
2058 EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
2062 for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) {
2063 EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx);
2065 if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) {
2066 if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) {
2068 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2071 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2072 kems_doit[kems_algs_len] = 1;
2073 kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2075 } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) {
2076 if (kems_algs_len + 3 >= MAX_KEM_NUM) {
2078 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2081 kems_doit[kems_algs_len] = 1;
2082 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256");
2083 kems_doit[kems_algs_len] = 1;
2084 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384");
2085 kems_doit[kems_algs_len] = 1;
2086 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521");
2088 if (kems_algs_len + 1 >= MAX_KEM_NUM) {
2090 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2093 kems_doit[kems_algs_len] = 1;
2094 kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem));
2097 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
2100 /* find all SIGNATUREs currently available */
2101 sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp);
2102 EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack);
2106 for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) {
2107 EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx);
2108 const char *sig_name = EVP_SIGNATURE_get0_name(s);
2110 if (strcmp(sig_name, "RSA") == 0) {
2111 if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) {
2113 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2116 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2117 sigs_doit[sigs_algs_len] = 1;
2118 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2121 else if (strcmp(sig_name, "DSA") == 0) {
2122 if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) {
2124 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2127 for (i = 0; i < DSA_NUM; i++) {
2128 sigs_doit[sigs_algs_len] = 1;
2129 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name);
2132 /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2133 else if (strcmp(sig_name, "ED25519") &&
2134 strcmp(sig_name, "ED448") &&
2135 strcmp(sig_name, "ECDSA") &&
2136 strcmp(sig_name, "HMAC") &&
2137 strcmp(sig_name, "SIPHASH") &&
2138 strcmp(sig_name, "POLY1305") &&
2139 strcmp(sig_name, "CMAC") &&
2140 strcmp(sig_name, "SM2")) { /* skip alg */
2141 if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
2143 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2146 /* activate this provider algorithm */
2147 sigs_doit[sigs_algs_len] = 1;
2148 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name);
2151 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
2154 /* Remaining arguments are algorithms. */
2155 argc = opt_num_rest();
2158 if (!app_RAND_load())
2161 for (; *argv; argv++) {
2162 const char *algo = *argv;
2165 if (opt_found(algo, doit_choices, &i)) {
2169 if (strcmp(algo, "des") == 0) {
2170 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
2173 if (strcmp(algo, "sha") == 0) {
2174 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
2177 #ifndef OPENSSL_NO_DEPRECATED_3_0
2178 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
2181 if (HAS_PREFIX(algo, "rsa")) {
2182 if (algo[sizeof("rsa") - 1] == '\0') {
2183 memset(rsa_doit, 1, sizeof(rsa_doit));
2186 if (opt_found(algo, rsa_choices, &i)) {
2191 #ifndef OPENSSL_NO_DH
2192 if (HAS_PREFIX(algo, "ffdh")) {
2193 if (algo[sizeof("ffdh") - 1] == '\0') {
2194 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2197 if (opt_found(algo, ffdh_choices, &i)) {
2203 if (HAS_PREFIX(algo, "dsa")) {
2204 if (algo[sizeof("dsa") - 1] == '\0') {
2205 memset(dsa_doit, 1, sizeof(dsa_doit));
2208 if (opt_found(algo, dsa_choices, &i)) {
2213 if (strcmp(algo, "aes") == 0) {
2214 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
2217 if (strcmp(algo, "camellia") == 0) {
2218 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
2221 if (HAS_PREFIX(algo, "ecdsa")) {
2222 if (algo[sizeof("ecdsa") - 1] == '\0') {
2223 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2226 if (opt_found(algo, ecdsa_choices, &i)) {
2231 if (HAS_PREFIX(algo, "ecdh")) {
2232 if (algo[sizeof("ecdh") - 1] == '\0') {
2233 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2236 if (opt_found(algo, ecdh_choices, &i)) {
2241 #ifndef OPENSSL_NO_ECX
2242 if (strcmp(algo, "eddsa") == 0) {
2243 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2246 if (opt_found(algo, eddsa_choices, &i)) {
2250 #endif /* OPENSSL_NO_ECX */
2251 #ifndef OPENSSL_NO_SM2
2252 if (strcmp(algo, "sm2") == 0) {
2253 memset(sm2_doit, 1, sizeof(sm2_doit));
2256 if (opt_found(algo, sm2_choices, &i)) {
2261 if (kem_locate(algo, &idx)) {
2266 if (sig_locate(algo, &idx)) {
2271 if (strcmp(algo, "kmac") == 0) {
2272 doit[D_KMAC128] = doit[D_KMAC256] = 1;
2275 if (strcmp(algo, "cmac") == 0) {
2276 doit[D_EVP_CMAC] = 1;
2281 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
2288 if (evp_cipher == NULL) {
2289 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
2291 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2292 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2293 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
2294 EVP_CIPHER_get0_name(evp_cipher));
2298 if (kems_algs_len > 0) {
2299 int maxcnt = get_max(kems_doit, kems_algs_len);
2302 /* some algs explicitly selected */
2303 for (i = 0; i < kems_algs_len; i++) {
2304 /* disable the rest */
2309 if (sigs_algs_len > 0) {
2310 int maxcnt = get_max(sigs_doit, sigs_algs_len);
2313 /* some algs explicitly selected */
2314 for (i = 0; i < sigs_algs_len; i++) {
2315 /* disable the rest */
2321 if (evp_cipher == NULL) {
2322 BIO_printf(bio_err, "-mb can be used only with a multi-block"
2323 " capable cipher\n");
2325 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2326 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2327 BIO_printf(bio_err, "%s is not a multi-block capable\n",
2328 EVP_CIPHER_get0_name(evp_cipher));
2330 } else if (async_jobs > 0) {
2331 BIO_printf(bio_err, "Async mode is not supported with -mb");
2336 /* Initialize the job pool if async mode is enabled */
2337 if (async_jobs > 0) {
2338 async_init = ASYNC_init_thread(async_jobs, async_jobs);
2340 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
2345 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
2347 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
2348 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
2350 buflen = lengths[size_num - 1];
2351 if (buflen < 36) /* size of random vector in RSA benchmark */
2353 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
2354 BIO_printf(bio_err, "Error: buffer size too large\n");
2357 buflen += MAX_MISALIGNMENT + 1;
2358 for (i = 0; i < loopargs_len; i++) {
2359 if (async_jobs > 0) {
2360 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
2361 if (loopargs[i].wait_ctx == NULL) {
2362 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
2367 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
2368 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
2370 /* Align the start of buffers on a 64 byte boundary */
2371 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
2372 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
2373 loopargs[i].buflen = buflen - misalign;
2374 loopargs[i].sigsize = buflen - misalign;
2375 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
2376 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
2377 #ifndef OPENSSL_NO_DH
2378 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
2379 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
2384 if (multi && do_multi(multi, size_num))
2388 for (i = 0; i < loopargs_len; ++i) {
2391 (void)VirtualLock(loopargs[i].buf_malloc, buflen);
2392 (void)VirtualLock(loopargs[i].buf2_malloc, buflen);
2393 #elif defined(OPENSSL_SYS_LINUX)
2394 (void)mlock(loopargs[i].buf_malloc, buflen);
2395 (void)mlock(loopargs[i].buf_malloc, buflen);
2398 memset(loopargs[i].buf_malloc, 0, buflen);
2399 memset(loopargs[i].buf2_malloc, 0, buflen);
2402 /* Initialize the engine after the fork */
2403 e = setup_engine(engine_id, 0);
2405 /* No parameters; turn on everything. */
2406 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC]
2407 && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) {
2408 memset(doit, 1, sizeof(doit));
2409 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
2411 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
2412 if (!have_md(names[i]))
2415 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
2416 if (!have_cipher(names[i]))
2419 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2420 app_get0_propq())) != NULL) {
2426 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2427 app_get0_propq())) != NULL) {
2434 memset(rsa_doit, 1, sizeof(rsa_doit));
2435 #ifndef OPENSSL_NO_DH
2436 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2438 memset(dsa_doit, 1, sizeof(dsa_doit));
2439 #ifndef OPENSSL_NO_ECX
2440 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2441 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2442 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2443 #endif /* OPENSSL_NO_ECX */
2444 #ifndef OPENSSL_NO_SM2
2445 memset(sm2_doit, 1, sizeof(sm2_doit));
2447 memset(kems_doit, 1, sizeof(kems_doit));
2449 memset(sigs_doit, 1, sizeof(sigs_doit));
2452 for (i = 0; i < ALGOR_NUM; i++)
2456 if (usertime == 0 && !mr)
2458 "You have chosen to measure elapsed time "
2459 "instead of user CPU time.\n");
2462 signal(SIGALRM, alarmed);
2466 for (testnum = 0; testnum < size_num; testnum++) {
2467 print_message(names[D_MD2], lengths[testnum], seconds.sym);
2469 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
2471 print_result(D_MD2, testnum, count, d);
2478 for (testnum = 0; testnum < size_num; testnum++) {
2479 print_message(names[D_MDC2], lengths[testnum], seconds.sym);
2481 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
2483 print_result(D_MDC2, testnum, count, d);
2490 for (testnum = 0; testnum < size_num; testnum++) {
2491 print_message(names[D_MD4], lengths[testnum], seconds.sym);
2493 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
2495 print_result(D_MD4, testnum, count, d);
2502 for (testnum = 0; testnum < size_num; testnum++) {
2503 print_message(names[D_MD5], lengths[testnum], seconds.sym);
2505 count = run_benchmark(async_jobs, MD5_loop, loopargs);
2507 print_result(D_MD5, testnum, count, d);
2514 for (testnum = 0; testnum < size_num; testnum++) {
2515 print_message(names[D_SHA1], lengths[testnum], seconds.sym);
2517 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
2519 print_result(D_SHA1, testnum, count, d);
2525 if (doit[D_SHA256]) {
2526 for (testnum = 0; testnum < size_num; testnum++) {
2527 print_message(names[D_SHA256], lengths[testnum], seconds.sym);
2529 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
2531 print_result(D_SHA256, testnum, count, d);
2537 if (doit[D_SHA512]) {
2538 for (testnum = 0; testnum < size_num; testnum++) {
2539 print_message(names[D_SHA512], lengths[testnum], seconds.sym);
2541 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
2543 print_result(D_SHA512, testnum, count, d);
2549 if (doit[D_WHIRLPOOL]) {
2550 for (testnum = 0; testnum < size_num; testnum++) {
2551 print_message(names[D_WHIRLPOOL], lengths[testnum], seconds.sym);
2553 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
2555 print_result(D_WHIRLPOOL, testnum, count, d);
2561 if (doit[D_RMD160]) {
2562 for (testnum = 0; testnum < size_num; testnum++) {
2563 print_message(names[D_RMD160], lengths[testnum], seconds.sym);
2565 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
2567 print_result(D_RMD160, testnum, count, d);
2574 static const char hmac_key[] = "This is a key...";
2575 int len = strlen(hmac_key);
2576 OSSL_PARAM params[3];
2578 if (evp_mac_mdname == NULL)
2580 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
2582 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
2583 names[D_HMAC] = evp_hmac_name;
2586 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2589 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2590 (char *)hmac_key, len);
2591 params[2] = OSSL_PARAM_construct_end();
2593 if (mac_setup("HMAC", &mac, params, loopargs, loopargs_len) < 1)
2595 for (testnum = 0; testnum < size_num; testnum++) {
2596 print_message(names[D_HMAC], lengths[testnum], seconds.sym);
2598 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2600 print_result(D_HMAC, testnum, count, d);
2604 mac_teardown(&mac, loopargs, loopargs_len);
2607 if (doit[D_CBC_DES]) {
2610 for (i = 0; st && i < loopargs_len; i++) {
2611 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2612 sizeof(deskey) / 3);
2613 st = loopargs[i].ctx != NULL;
2615 algindex = D_CBC_DES;
2616 for (testnum = 0; st && testnum < size_num; testnum++) {
2617 print_message(names[D_CBC_DES], lengths[testnum], seconds.sym);
2619 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2621 print_result(D_CBC_DES, testnum, count, d);
2623 for (i = 0; i < loopargs_len; i++)
2624 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2627 if (doit[D_EDE3_DES]) {
2630 for (i = 0; st && i < loopargs_len; i++) {
2631 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2633 st = loopargs[i].ctx != NULL;
2635 algindex = D_EDE3_DES;
2636 for (testnum = 0; st && testnum < size_num; testnum++) {
2637 print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym);
2640 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2642 print_result(D_EDE3_DES, testnum, count, d);
2644 for (i = 0; i < loopargs_len; i++)
2645 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2648 for (k = 0; k < 3; k++) {
2649 algindex = D_CBC_128_AES + k;
2650 if (doit[algindex]) {
2653 keylen = 16 + k * 8;
2654 for (i = 0; st && i < loopargs_len; i++) {
2655 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2657 st = loopargs[i].ctx != NULL;
2660 for (testnum = 0; st && testnum < size_num; testnum++) {
2661 print_message(names[algindex], lengths[testnum], seconds.sym);
2664 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2666 print_result(algindex, testnum, count, d);
2668 for (i = 0; i < loopargs_len; i++)
2669 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2673 for (k = 0; k < 3; k++) {
2674 algindex = D_CBC_128_CML + k;
2675 if (doit[algindex]) {
2678 keylen = 16 + k * 8;
2679 for (i = 0; st && i < loopargs_len; i++) {
2680 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2682 st = loopargs[i].ctx != NULL;
2685 for (testnum = 0; st && testnum < size_num; testnum++) {
2686 print_message(names[algindex], lengths[testnum], seconds.sym);
2689 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2691 print_result(algindex, testnum, count, d);
2693 for (i = 0; i < loopargs_len; i++)
2694 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2698 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2699 if (doit[algindex]) {
2703 for (i = 0; st && i < loopargs_len; i++) {
2704 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2706 st = loopargs[i].ctx != NULL;
2709 for (testnum = 0; st && testnum < size_num; testnum++) {
2710 print_message(names[algindex], lengths[testnum], seconds.sym);
2713 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2715 print_result(algindex, testnum, count, d);
2717 for (i = 0; i < loopargs_len; i++)
2718 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2721 if (doit[D_GHASH]) {
2722 static const char gmac_iv[] = "0123456789ab";
2723 OSSL_PARAM params[4];
2725 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2727 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2729 sizeof(gmac_iv) - 1);
2730 params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2732 params[3] = OSSL_PARAM_construct_end();
2734 if (mac_setup("GMAC", &mac, params, loopargs, loopargs_len) < 1)
2736 /* b/c of the definition of GHASH_loop(), init() calls are needed here */
2737 for (i = 0; i < loopargs_len; i++) {
2738 if (!EVP_MAC_init(loopargs[i].mctx, NULL, 0, NULL))
2741 for (testnum = 0; testnum < size_num; testnum++) {
2742 print_message(names[D_GHASH], lengths[testnum], seconds.sym);
2744 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2746 print_result(D_GHASH, testnum, count, d);
2750 mac_teardown(&mac, loopargs, loopargs_len);
2754 for (testnum = 0; testnum < size_num; testnum++) {
2755 print_message(names[D_RAND], lengths[testnum], seconds.sym);
2757 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2759 print_result(D_RAND, testnum, count, d);
2764 if (evp_cipher != NULL) {
2765 int (*loopfunc) (void *) = EVP_Update_loop;
2767 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2768 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2769 multiblock_speed(evp_cipher, lengths_single, &seconds);
2774 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2776 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2777 loopfunc = EVP_Update_loop_ccm;
2778 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2779 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2780 loopfunc = EVP_Update_loop_aead;
2781 if (lengths == lengths_list) {
2782 lengths = aead_lengths_list;
2783 size_num = OSSL_NELEM(aead_lengths_list);
2787 for (testnum = 0; testnum < size_num; testnum++) {
2788 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2790 for (k = 0; k < loopargs_len; k++) {
2791 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2792 if (loopargs[k].ctx == NULL) {
2793 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2796 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2797 NULL, iv, decrypt ? 0 : 1)) {
2798 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2799 ERR_print_errors(bio_err);
2803 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2805 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2806 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2807 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2808 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2809 loopargs[k].key, NULL, -1)) {
2810 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2811 ERR_print_errors(bio_err);
2814 OPENSSL_clear_free(loopargs[k].key, keylen);
2816 /* GCM-SIV/SIV mode only allows for a single Update operation */
2817 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE
2818 || EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_GCM_SIV_MODE)
2819 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2820 EVP_CTRL_SET_SPEED, 1, NULL);
2824 count = run_benchmark(async_jobs, loopfunc, loopargs);
2826 for (k = 0; k < loopargs_len; k++)
2827 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2828 print_result(D_EVP, testnum, count, d);
2830 } else if (evp_md_name != NULL) {
2831 names[D_EVP] = evp_md_name;
2833 for (testnum = 0; testnum < size_num; testnum++) {
2834 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2836 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2838 print_result(D_EVP, testnum, count, d);
2845 if (doit[D_EVP_CMAC]) {
2846 OSSL_PARAM params[3];
2847 EVP_CIPHER *cipher = NULL;
2849 if (!opt_cipher(evp_mac_ciphername, &cipher))
2852 keylen = EVP_CIPHER_get_key_length(cipher);
2853 EVP_CIPHER_free(cipher);
2854 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2855 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2858 evp_cmac_name = app_malloc(sizeof("cmac()")
2859 + strlen(evp_mac_ciphername), "CMAC name");
2860 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2861 names[D_EVP_CMAC] = evp_cmac_name;
2863 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2864 evp_mac_ciphername, 0);
2865 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2866 (char *)key32, keylen);
2867 params[2] = OSSL_PARAM_construct_end();
2869 if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
2871 for (testnum = 0; testnum < size_num; testnum++) {
2872 print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
2874 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2876 print_result(D_EVP_CMAC, testnum, count, d);
2880 mac_teardown(&mac, loopargs, loopargs_len);
2883 if (doit[D_KMAC128]) {
2884 OSSL_PARAM params[2];
2886 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2888 params[1] = OSSL_PARAM_construct_end();
2890 if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
2892 for (testnum = 0; testnum < size_num; testnum++) {
2893 print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
2895 count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
2897 print_result(D_KMAC128, testnum, count, d);
2901 mac_teardown(&mac, loopargs, loopargs_len);
2904 if (doit[D_KMAC256]) {
2905 OSSL_PARAM params[2];
2907 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2909 params[1] = OSSL_PARAM_construct_end();
2911 if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
2913 for (testnum = 0; testnum < size_num; testnum++) {
2914 print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
2916 count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
2918 print_result(D_KMAC256, testnum, count, d);
2922 mac_teardown(&mac, loopargs, loopargs_len);
2925 for (i = 0; i < loopargs_len; i++)
2926 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2929 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2930 EVP_PKEY *rsa_key = NULL;
2933 if (!rsa_doit[testnum])
2936 if (primes > RSA_DEFAULT_PRIME_NUM) {
2937 /* we haven't set keys yet, generate multi-prime RSA keys */
2940 && BN_set_word(bn, RSA_F4)
2941 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2942 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2943 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2944 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2945 && EVP_PKEY_keygen(genctx, &rsa_key);
2948 EVP_PKEY_CTX_free(genctx);
2951 const unsigned char *p = rsa_keys[testnum].data;
2953 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2954 rsa_keys[testnum].length)) != NULL;
2957 for (i = 0; st && i < loopargs_len; i++) {
2958 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2959 loopargs[i].sigsize = loopargs[i].buflen;
2960 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2961 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2962 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2964 &loopargs[i].sigsize,
2965 loopargs[i].buf, 36) <= 0)
2970 "RSA sign setup failure. No RSA sign will be done.\n");
2971 ERR_print_errors(bio_err);
2974 pkey_print_message("private", "rsa sign",
2975 rsa_keys[testnum].bits, seconds.rsa);
2976 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2978 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2981 mr ? "+R1:%ld:%d:%.2f\n"
2982 : "%ld %u bits private RSA sign ops in %.2fs\n",
2983 count, rsa_keys[testnum].bits, d);
2984 rsa_results[testnum][0] = (double)count / d;
2988 for (i = 0; st && i < loopargs_len; i++) {
2989 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2991 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2992 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2993 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2995 loopargs[i].sigsize,
2996 loopargs[i].buf, 36) <= 0)
3001 "RSA verify setup failure. No RSA verify will be done.\n");
3002 ERR_print_errors(bio_err);
3003 rsa_doit[testnum] = 0;
3005 pkey_print_message("public", "rsa verify",
3006 rsa_keys[testnum].bits, seconds.rsa);
3008 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
3011 mr ? "+R2:%ld:%d:%.2f\n"
3012 : "%ld %u bits public RSA verify ops in %.2fs\n",
3013 count, rsa_keys[testnum].bits, d);
3014 rsa_results[testnum][1] = (double)count / d;
3017 for (i = 0; st && i < loopargs_len; i++) {
3018 loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3019 loopargs[i].encsize = loopargs[i].buflen;
3020 if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
3021 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
3022 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
3024 &loopargs[i].encsize,
3025 loopargs[i].buf, 36) <= 0)
3030 "RSA encrypt setup failure. No RSA encrypt will be done.\n");
3031 ERR_print_errors(bio_err);
3034 pkey_print_message("private", "rsa encrypt",
3035 rsa_keys[testnum].bits, seconds.rsa);
3036 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3038 count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
3041 mr ? "+R3:%ld:%d:%.2f\n"
3042 : "%ld %u bits public RSA encrypt ops in %.2fs\n",
3043 count, rsa_keys[testnum].bits, d);
3044 rsa_results[testnum][2] = (double)count / d;
3048 for (i = 0; st && i < loopargs_len; i++) {
3049 loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3050 declen = loopargs[i].buflen;
3051 if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
3052 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
3053 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
3057 loopargs[i].encsize) <= 0)
3062 "RSA decrypt setup failure. No RSA decrypt will be done.\n");
3063 ERR_print_errors(bio_err);
3066 pkey_print_message("private", "rsa decrypt",
3067 rsa_keys[testnum].bits, seconds.rsa);
3068 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3070 count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3073 mr ? "+R4:%ld:%d:%.2f\n"
3074 : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3075 count, rsa_keys[testnum].bits, d);
3076 rsa_results[testnum][3] = (double)count / d;
3080 if (op_count <= 1) {
3081 /* if longer than 10s, don't do any more */
3082 stop_it(rsa_doit, testnum);
3084 EVP_PKEY_free(rsa_key);
3087 for (testnum = 0; testnum < DSA_NUM; testnum++) {
3088 EVP_PKEY *dsa_key = NULL;
3091 if (!dsa_doit[testnum])
3094 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3096 for (i = 0; st && i < loopargs_len; i++) {
3097 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3099 loopargs[i].sigsize = loopargs[i].buflen;
3100 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3101 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3103 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3105 &loopargs[i].sigsize,
3106 loopargs[i].buf, 20) <= 0)
3111 "DSA sign setup failure. No DSA sign will be done.\n");
3112 ERR_print_errors(bio_err);
3115 pkey_print_message("sign", "dsa",
3116 dsa_bits[testnum], seconds.dsa);
3118 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3121 mr ? "+R5:%ld:%u:%.2f\n"
3122 : "%ld %u bits DSA sign ops in %.2fs\n",
3123 count, dsa_bits[testnum], d);
3124 dsa_results[testnum][0] = (double)count / d;
3128 for (i = 0; st && i < loopargs_len; i++) {
3129 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3131 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3132 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3133 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3135 loopargs[i].sigsize,
3136 loopargs[i].buf, 36) <= 0)
3141 "DSA verify setup failure. No DSA verify will be done.\n");
3142 ERR_print_errors(bio_err);
3143 dsa_doit[testnum] = 0;
3145 pkey_print_message("verify", "dsa",
3146 dsa_bits[testnum], seconds.dsa);
3148 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3151 mr ? "+R6:%ld:%u:%.2f\n"
3152 : "%ld %u bits DSA verify ops in %.2fs\n",
3153 count, dsa_bits[testnum], d);
3154 dsa_results[testnum][1] = (double)count / d;
3157 if (op_count <= 1) {
3158 /* if longer than 10s, don't do any more */
3159 stop_it(dsa_doit, testnum);
3161 EVP_PKEY_free(dsa_key);
3164 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3165 EVP_PKEY *ecdsa_key = NULL;
3168 if (!ecdsa_doit[testnum])
3171 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3173 for (i = 0; st && i < loopargs_len; i++) {
3174 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3176 loopargs[i].sigsize = loopargs[i].buflen;
3177 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3178 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3180 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3182 &loopargs[i].sigsize,
3183 loopargs[i].buf, 20) <= 0)
3188 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
3189 ERR_print_errors(bio_err);
3192 pkey_print_message("sign", "ecdsa",
3193 ec_curves[testnum].bits, seconds.ecdsa);
3195 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3198 mr ? "+R7:%ld:%u:%.2f\n"
3199 : "%ld %u bits ECDSA sign ops in %.2fs\n",
3200 count, ec_curves[testnum].bits, d);
3201 ecdsa_results[testnum][0] = (double)count / d;
3205 for (i = 0; st && i < loopargs_len; i++) {
3206 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3208 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3209 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3210 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3212 loopargs[i].sigsize,
3213 loopargs[i].buf, 20) <= 0)
3218 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3219 ERR_print_errors(bio_err);
3220 ecdsa_doit[testnum] = 0;
3222 pkey_print_message("verify", "ecdsa",
3223 ec_curves[testnum].bits, seconds.ecdsa);
3225 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3228 mr ? "+R8:%ld:%u:%.2f\n"
3229 : "%ld %u bits ECDSA verify ops in %.2fs\n",
3230 count, ec_curves[testnum].bits, d);
3231 ecdsa_results[testnum][1] = (double)count / d;
3234 if (op_count <= 1) {
3235 /* if longer than 10s, don't do any more */
3236 stop_it(ecdsa_doit, testnum);
3240 for (testnum = 0; testnum < EC_NUM; testnum++) {
3241 int ecdh_checks = 1;
3243 if (!ecdh_doit[testnum])
3246 for (i = 0; i < loopargs_len; i++) {
3247 EVP_PKEY_CTX *test_ctx = NULL;
3248 EVP_PKEY_CTX *ctx = NULL;
3249 EVP_PKEY *key_A = NULL;
3250 EVP_PKEY *key_B = NULL;
3254 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3255 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3256 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3257 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3258 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3259 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3260 || outlen == 0 /* ensure outlen is a valid size */
3261 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3263 BIO_printf(bio_err, "ECDH key generation failure.\n");
3264 ERR_print_errors(bio_err);
3270 * Here we perform a test run, comparing the output of a*B and b*A;
3271 * we try this here and assume that further EVP_PKEY_derive calls
3272 * never fail, so we can skip checks in the actually benchmarked
3273 * code, for maximum performance.
3275 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3276 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3277 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3278 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3279 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3280 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3281 || test_outlen != outlen /* compare output length */) {
3283 BIO_printf(bio_err, "ECDH computation failure.\n");
3284 ERR_print_errors(bio_err);
3289 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3290 if (CRYPTO_memcmp(loopargs[i].secret_a,
3291 loopargs[i].secret_b, outlen)) {
3293 BIO_printf(bio_err, "ECDH computations don't match.\n");
3294 ERR_print_errors(bio_err);
3299 loopargs[i].ecdh_ctx[testnum] = ctx;
3300 loopargs[i].outlen[testnum] = outlen;
3302 EVP_PKEY_free(key_A);
3303 EVP_PKEY_free(key_B);
3304 EVP_PKEY_CTX_free(test_ctx);
3307 if (ecdh_checks != 0) {
3308 pkey_print_message("", "ecdh",
3309 ec_curves[testnum].bits, seconds.ecdh);
3312 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3315 mr ? "+R9:%ld:%d:%.2f\n" :
3316 "%ld %u-bits ECDH ops in %.2fs\n", count,
3317 ec_curves[testnum].bits, d);
3318 ecdh_results[testnum][0] = (double)count / d;
3322 if (op_count <= 1) {
3323 /* if longer than 10s, don't do any more */
3324 stop_it(ecdh_doit, testnum);
3328 #ifndef OPENSSL_NO_ECX
3329 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3331 EVP_PKEY *ed_pkey = NULL;
3332 EVP_PKEY_CTX *ed_pctx = NULL;
3334 if (!eddsa_doit[testnum])
3335 continue; /* Ignore Curve */
3336 for (i = 0; i < loopargs_len; i++) {
3337 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3338 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3342 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3343 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3348 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3350 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3351 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3353 EVP_PKEY_CTX_free(ed_pctx);
3356 EVP_PKEY_CTX_free(ed_pctx);
3358 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3361 EVP_PKEY_free(ed_pkey);
3364 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3365 NULL, NULL, ed_pkey)) {
3367 EVP_PKEY_free(ed_pkey);
3371 EVP_PKEY_free(ed_pkey);
3375 BIO_printf(bio_err, "EdDSA failure.\n");
3376 ERR_print_errors(bio_err);
3379 for (i = 0; i < loopargs_len; i++) {
3380 /* Perform EdDSA signature test */
3381 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3382 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3383 loopargs[i].buf2, &loopargs[i].sigsize,
3384 loopargs[i].buf, 20);
3390 "EdDSA sign failure. No EdDSA sign will be done.\n");
3391 ERR_print_errors(bio_err);
3394 pkey_print_message("sign", ed_curves[testnum].name,
3395 ed_curves[testnum].bits, seconds.eddsa);
3397 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3401 mr ? "+R10:%ld:%u:%s:%.2f\n" :
3402 "%ld %u bits %s sign ops in %.2fs \n",
3403 count, ed_curves[testnum].bits,
3404 ed_curves[testnum].name, d);
3405 eddsa_results[testnum][0] = (double)count / d;
3408 /* Perform EdDSA verification test */
3409 for (i = 0; i < loopargs_len; i++) {
3410 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3411 loopargs[i].buf2, loopargs[i].sigsize,
3412 loopargs[i].buf, 20);
3418 "EdDSA verify failure. No EdDSA verify will be done.\n");
3419 ERR_print_errors(bio_err);
3420 eddsa_doit[testnum] = 0;
3422 pkey_print_message("verify", ed_curves[testnum].name,
3423 ed_curves[testnum].bits, seconds.eddsa);
3425 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3428 mr ? "+R11:%ld:%u:%s:%.2f\n"
3429 : "%ld %u bits %s verify ops in %.2fs\n",
3430 count, ed_curves[testnum].bits,
3431 ed_curves[testnum].name, d);
3432 eddsa_results[testnum][1] = (double)count / d;
3435 if (op_count <= 1) {
3436 /* if longer than 10s, don't do any more */
3437 stop_it(eddsa_doit, testnum);
3441 #endif /* OPENSSL_NO_ECX */
3443 #ifndef OPENSSL_NO_SM2
3444 for (testnum = 0; testnum < SM2_NUM; testnum++) {
3446 EVP_PKEY *sm2_pkey = NULL;
3448 if (!sm2_doit[testnum])
3449 continue; /* Ignore Curve */
3450 /* Init signing and verification */
3451 for (i = 0; i < loopargs_len; i++) {
3452 EVP_PKEY_CTX *sm2_pctx = NULL;
3453 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3454 EVP_PKEY_CTX *pctx = NULL;
3457 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3458 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3459 if (loopargs[i].sm2_ctx[testnum] == NULL
3460 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3465 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3466 || EVP_PKEY_keygen_init(pctx) <= 0
3467 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3468 sm2_curves[testnum].nid) <= 0
3469 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3470 EVP_PKEY_CTX_free(pctx);
3474 st = 0; /* set back to zero */
3475 /* attach it sooner to rely on main final cleanup */
3476 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3477 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3479 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3480 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3481 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3482 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3486 /* attach them directly to respective ctx */
3487 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3488 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3491 * No need to allow user to set an explicit ID here, just use
3492 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3494 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3495 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3498 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3499 EVP_sm3(), NULL, sm2_pkey))
3501 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3502 EVP_sm3(), NULL, sm2_pkey))
3504 st = 1; /* mark loop as succeeded */
3507 BIO_printf(bio_err, "SM2 init failure.\n");
3508 ERR_print_errors(bio_err);
3511 for (i = 0; i < loopargs_len; i++) {
3512 /* Perform SM2 signature test */
3513 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3514 loopargs[i].buf2, &loopargs[i].sigsize,
3515 loopargs[i].buf, 20);
3521 "SM2 sign failure. No SM2 sign will be done.\n");
3522 ERR_print_errors(bio_err);
3525 pkey_print_message("sign", sm2_curves[testnum].name,
3526 sm2_curves[testnum].bits, seconds.sm2);
3528 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3532 mr ? "+R12:%ld:%u:%s:%.2f\n" :
3533 "%ld %u bits %s sign ops in %.2fs \n",
3534 count, sm2_curves[testnum].bits,
3535 sm2_curves[testnum].name, d);
3536 sm2_results[testnum][0] = (double)count / d;
3540 /* Perform SM2 verification test */
3541 for (i = 0; i < loopargs_len; i++) {
3542 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3543 loopargs[i].buf2, loopargs[i].sigsize,
3544 loopargs[i].buf, 20);
3550 "SM2 verify failure. No SM2 verify will be done.\n");
3551 ERR_print_errors(bio_err);
3552 sm2_doit[testnum] = 0;
3554 pkey_print_message("verify", sm2_curves[testnum].name,
3555 sm2_curves[testnum].bits, seconds.sm2);
3557 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3560 mr ? "+R13:%ld:%u:%s:%.2f\n"
3561 : "%ld %u bits %s verify ops in %.2fs\n",
3562 count, sm2_curves[testnum].bits,
3563 sm2_curves[testnum].name, d);
3564 sm2_results[testnum][1] = (double)count / d;
3567 if (op_count <= 1) {
3568 /* if longer than 10s, don't do any more */
3569 for (testnum++; testnum < SM2_NUM; testnum++)
3570 sm2_doit[testnum] = 0;
3574 #endif /* OPENSSL_NO_SM2 */
3576 #ifndef OPENSSL_NO_DH
3577 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3578 int ffdh_checks = 1;
3580 if (!ffdh_doit[testnum])
3583 for (i = 0; i < loopargs_len; i++) {
3584 EVP_PKEY *pkey_A = NULL;
3585 EVP_PKEY *pkey_B = NULL;
3586 EVP_PKEY_CTX *ffdh_ctx = NULL;
3587 EVP_PKEY_CTX *test_ctx = NULL;
3591 /* Ensure that the error queue is empty */
3592 if (ERR_peek_error()) {
3594 "WARNING: the error queue contains previous unhandled errors.\n");
3595 ERR_print_errors(bio_err);
3598 pkey_A = EVP_PKEY_new();
3600 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3601 ERR_print_errors(bio_err);
3606 pkey_B = EVP_PKEY_new();
3608 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3609 ERR_print_errors(bio_err);
3615 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3617 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3618 ERR_print_errors(bio_err);
3624 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3625 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3626 ERR_print_errors(bio_err);
3631 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3632 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3633 ERR_print_errors(bio_err);
3639 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
3640 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
3641 BIO_printf(bio_err, "FFDH key generation failure.\n");
3642 ERR_print_errors(bio_err);
3648 EVP_PKEY_CTX_free(ffdh_ctx);
3651 * check if the derivation works correctly both ways so that
3652 * we know if future derive calls will fail, and we can skip
3653 * error checking in benchmarked code
3655 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3656 if (ffdh_ctx == NULL) {
3657 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3658 ERR_print_errors(bio_err);
3663 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3664 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3665 ERR_print_errors(bio_err);
3670 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3671 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3672 ERR_print_errors(bio_err);
3677 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3678 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3679 ERR_print_errors(bio_err);
3684 if (secret_size > MAX_FFDH_SIZE) {
3685 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3690 if (EVP_PKEY_derive(ffdh_ctx,
3691 loopargs[i].secret_ff_a,
3692 &secret_size) <= 0) {
3693 BIO_printf(bio_err, "Shared secret derive failure.\n");
3694 ERR_print_errors(bio_err);
3699 /* Now check from side B */
3700 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3702 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3703 ERR_print_errors(bio_err);
3708 if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3709 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3710 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3711 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3712 test_out != secret_size) {
3713 BIO_printf(bio_err, "FFDH computation failure.\n");
3719 /* compare the computed secrets */
3720 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3721 loopargs[i].secret_ff_b, secret_size)) {
3722 BIO_printf(bio_err, "FFDH computations don't match.\n");
3723 ERR_print_errors(bio_err);
3729 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3731 EVP_PKEY_free(pkey_A);
3733 EVP_PKEY_free(pkey_B);
3735 EVP_PKEY_CTX_free(test_ctx);
3738 if (ffdh_checks != 0) {
3739 pkey_print_message("", "ffdh",
3740 ffdh_params[testnum].bits, seconds.ffdh);
3743 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3746 mr ? "+R14:%ld:%d:%.2f\n" :
3747 "%ld %u-bits FFDH ops in %.2fs\n", count,
3748 ffdh_params[testnum].bits, d);
3749 ffdh_results[testnum][0] = (double)count / d;
3752 if (op_count <= 1) {
3753 /* if longer than 10s, don't do any more */
3754 stop_it(ffdh_doit, testnum);
3757 #endif /* OPENSSL_NO_DH */
3759 for (testnum = 0; testnum < kems_algs_len; testnum++) {
3761 const char *kem_name = kems_algname[testnum];
3763 if (!kems_doit[testnum] || !do_kems)
3766 for (i = 0; i < loopargs_len; i++) {
3767 EVP_PKEY *pkey = NULL;
3768 EVP_PKEY_CTX *kem_gen_ctx = NULL;
3769 EVP_PKEY_CTX *kem_encaps_ctx = NULL;
3770 EVP_PKEY_CTX *kem_decaps_ctx = NULL;
3771 size_t send_secret_len, out_len;
3772 size_t rcv_secret_len;
3773 unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
3776 char sfx[MAX_ALGNAME_SUFFIX];
3777 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3779 enum kem_type_t { KEM_RSA = 1, KEM_EC, KEM_X25519, KEM_X448 } kem_type;
3781 /* no string after rsa<bitcnt> permitted: */
3782 if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3783 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
3785 else if (strncmp(kem_name, "EC", 2) == 0)
3787 else if (strcmp(kem_name, "X25519") == 0)
3788 kem_type = KEM_X25519;
3789 else if (strcmp(kem_name, "X448") == 0)
3790 kem_type = KEM_X448;
3793 if (ERR_peek_error()) {
3795 "WARNING: the error queue contains previous unhandled errors.\n");
3796 ERR_print_errors(bio_err);
3799 if (kem_type == KEM_RSA) {
3800 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3803 } else if (kem_type == KEM_EC) {
3804 name = (char *)(kem_name + 2);
3805 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3810 kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3811 (kem_type == KEM_RSA) ? "RSA":
3812 (kem_type == KEM_EC) ? "EC":
3816 if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
3818 && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
3819 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
3823 if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
3824 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
3827 /* Now prepare encaps data structs */
3828 kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3831 if (kem_encaps_ctx == NULL
3832 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
3833 || (kem_type == KEM_RSA
3834 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
3835 || ((kem_type == KEM_EC
3836 || kem_type == KEM_X25519
3837 || kem_type == KEM_X448)
3838 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
3839 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
3840 NULL, &send_secret_len) <= 0) {
3842 "Error while initializing encaps data structs for %s.\n",
3846 out = app_malloc(out_len, "encaps result");
3847 send_secret = app_malloc(send_secret_len, "encaps secret");
3848 if (out == NULL || send_secret == NULL) {
3849 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
3852 if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
3853 send_secret, &send_secret_len) <= 0) {
3854 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
3857 /* Now prepare decaps data structs */
3858 kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3861 if (kem_decaps_ctx == NULL
3862 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
3863 || (kem_type == KEM_RSA
3864 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
3865 || ((kem_type == KEM_EC
3866 || kem_type == KEM_X25519
3867 || kem_type == KEM_X448)
3868 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
3869 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
3870 out, out_len) <= 0) {
3872 "Error while initializing decaps data structs for %s.\n",
3876 rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
3877 if (rcv_secret == NULL) {
3878 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
3882 if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
3883 &rcv_secret_len, out, out_len) <= 0
3884 || rcv_secret_len != send_secret_len
3885 || memcmp(send_secret, rcv_secret, send_secret_len)) {
3886 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
3889 loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
3890 loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
3891 loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
3892 loopargs[i].kem_out_len[testnum] = out_len;
3893 loopargs[i].kem_secret_len[testnum] = send_secret_len;
3894 loopargs[i].kem_out[testnum] = out;
3895 loopargs[i].kem_send_secret[testnum] = send_secret;
3896 loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
3897 EVP_PKEY_free(pkey);
3902 ERR_print_errors(bio_err);
3903 EVP_PKEY_free(pkey);
3908 if (kem_checks != 0) {
3909 kskey_print_message(kem_name, "keygen", seconds.kem);
3912 run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
3915 mr ? "+R15:%ld:%s:%.2f\n" :
3916 "%ld %s KEM keygen ops in %.2fs\n", count,
3918 kems_results[testnum][0] = (double)count / d;
3920 kskey_print_message(kem_name, "encaps", seconds.kem);
3923 run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
3926 mr ? "+R16:%ld:%s:%.2f\n" :
3927 "%ld %s KEM encaps ops in %.2fs\n", count,
3929 kems_results[testnum][1] = (double)count / d;
3931 kskey_print_message(kem_name, "decaps", seconds.kem);
3934 run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
3937 mr ? "+R17:%ld:%s:%.2f\n" :
3938 "%ld %s KEM decaps ops in %.2fs\n", count,
3940 kems_results[testnum][2] = (double)count / d;
3943 if (op_count <= 1) {
3944 /* if longer than 10s, don't do any more */
3945 stop_it(kems_doit, testnum);
3949 for (testnum = 0; testnum < sigs_algs_len; testnum++) {
3951 const char *sig_name = sigs_algname[testnum];
3953 if (!sigs_doit[testnum] || !do_sigs)
3956 for (i = 0; i < loopargs_len; i++) {
3957 EVP_PKEY *pkey = NULL;
3958 EVP_PKEY_CTX *ctx_params = NULL;
3959 EVP_PKEY* pkey_params = NULL;
3960 EVP_PKEY_CTX *sig_gen_ctx = NULL;
3961 EVP_PKEY_CTX *sig_sign_ctx = NULL;
3962 EVP_PKEY_CTX *sig_verify_ctx = NULL;
3963 unsigned char md[SHA256_DIGEST_LENGTH];
3965 char sfx[MAX_ALGNAME_SUFFIX];
3966 size_t md_len = SHA256_DIGEST_LENGTH;
3967 size_t max_sig_len, sig_len;
3969 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3972 /* only sign little data to avoid measuring digest performance */
3973 memset(md, 0, SHA256_DIGEST_LENGTH);
3975 if (ERR_peek_error()) {
3977 "WARNING: the error queue contains previous unhandled errors.\n");
3978 ERR_print_errors(bio_err);
3981 /* no string after rsa<bitcnt> permitted: */
3982 if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3983 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
3984 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3989 if (strncmp(sig_name, "dsa", 3) == 0) {
3990 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
3991 if (ctx_params == NULL
3992 || EVP_PKEY_paramgen_init(ctx_params) <= 0
3993 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
3994 atoi(sig_name + 3)) <= 0
3995 || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
3996 || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
3997 || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
3999 "Error initializing classic keygen ctx for %s.\n",
4005 if (sig_gen_ctx == NULL)
4006 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4007 use_params == 1 ? "RSA" : sig_name,
4010 if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
4012 EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
4013 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4017 if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
4019 "Error while generating signature EVP_PKEY for %s.\n",
4023 /* Now prepare signature data structs */
4024 sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4027 if (sig_sign_ctx == NULL
4028 || EVP_PKEY_sign_init(sig_sign_ctx) <= 0
4030 && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx,
4031 RSA_PKCS1_PADDING) <= 0))
4032 || EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len,
4035 "Error while initializing signing data structs for %s.\n",
4039 sig = app_malloc(sig_len = max_sig_len, "signature buffer");
4041 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
4044 if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
4045 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
4048 /* Now prepare verify data structs */
4049 memset(md, 0, SHA256_DIGEST_LENGTH);
4050 sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4053 if (sig_verify_ctx == NULL
4054 || EVP_PKEY_verify_init(sig_verify_ctx) <= 0
4056 && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx,
4057 RSA_PKCS1_PADDING) <= 0))) {
4059 "Error while initializing verify data structs for %s.\n",
4063 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4064 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
4067 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4068 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4071 loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4072 loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4073 loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4074 loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4075 loopargs[i].sig_act_sig_len[testnum] = sig_len;
4076 loopargs[i].sig_sig[testnum] = sig;
4077 EVP_PKEY_free(pkey);
4082 ERR_print_errors(bio_err);
4083 EVP_PKEY_free(pkey);
4089 if (sig_checks != 0) {
4090 kskey_print_message(sig_name, "keygen", seconds.sig);
4092 count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4095 mr ? "+R18:%ld:%s:%.2f\n" :
4096 "%ld %s signature keygen ops in %.2fs\n", count,
4098 sigs_results[testnum][0] = (double)count / d;
4100 kskey_print_message(sig_name, "signs", seconds.sig);
4103 run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4106 mr ? "+R19:%ld:%s:%.2f\n" :
4107 "%ld %s signature sign ops in %.2fs\n", count,
4109 sigs_results[testnum][1] = (double)count / d;
4112 kskey_print_message(sig_name, "verify", seconds.sig);
4115 run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4118 mr ? "+R20:%ld:%s:%.2f\n" :
4119 "%ld %s signature verify ops in %.2fs\n", count,
4121 sigs_results[testnum][2] = (double)count / d;
4125 stop_it(sigs_doit, testnum);
4132 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4133 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4134 printf("options: %s\n", BN_options());
4135 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4136 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4143 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4146 for (testnum = 0; testnum < size_num; testnum++)
4147 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4151 for (k = 0; k < ALGOR_NUM; k++) {
4152 const char *alg_name = names[k];
4158 if (evp_cipher == NULL)
4159 alg_name = evp_md_name;
4160 else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4161 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4165 printf("+F:%u:%s", k, alg_name);
4167 printf("%-13s", alg_name);
4168 for (testnum = 0; testnum < size_num; testnum++) {
4169 if (results[k][testnum] > 10000 && !mr)
4170 printf(" %11.2fk", results[k][testnum] / 1e3);
4172 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4177 for (k = 0; k < RSA_NUM; k++) {
4180 if (testnum && !mr) {
4181 printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " ");
4185 printf("+F2:%u:%u:%f:%f:%f:%f\n",
4186 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4187 rsa_results[k][2], rsa_results[k][3]);
4189 printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4190 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4191 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4192 1.0 / rsa_results[k][3],
4193 rsa_results[k][0], rsa_results[k][1],
4194 rsa_results[k][2], rsa_results[k][3]);
4197 for (k = 0; k < DSA_NUM; k++) {
4200 if (testnum && !mr) {
4201 printf("%18ssign verify sign/s verify/s\n", " ");
4205 printf("+F3:%u:%u:%f:%f\n",
4206 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4208 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4209 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4210 dsa_results[k][0], dsa_results[k][1]);
4213 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4216 if (testnum && !mr) {
4217 printf("%30ssign verify sign/s verify/s\n", " ");
4222 printf("+F4:%u:%u:%f:%f\n",
4223 k, ec_curves[k].bits,
4224 ecdsa_results[k][0], ecdsa_results[k][1]);
4226 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4227 ec_curves[k].bits, ec_curves[k].name,
4228 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4229 ecdsa_results[k][0], ecdsa_results[k][1]);
4233 for (k = 0; k < EC_NUM; k++) {
4236 if (testnum && !mr) {
4237 printf("%30sop op/s\n", " ");
4241 printf("+F5:%u:%u:%f:%f\n",
4242 k, ec_curves[k].bits,
4243 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4246 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4247 ec_curves[k].bits, ec_curves[k].name,
4248 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4251 #ifndef OPENSSL_NO_ECX
4253 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4256 if (testnum && !mr) {
4257 printf("%30ssign verify sign/s verify/s\n", " ");
4262 printf("+F6:%u:%u:%s:%f:%f\n",
4263 k, ed_curves[k].bits, ed_curves[k].name,
4264 eddsa_results[k][0], eddsa_results[k][1]);
4266 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4267 ed_curves[k].bits, ed_curves[k].name,
4268 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4269 eddsa_results[k][0], eddsa_results[k][1]);
4271 #endif /* OPENSSL_NO_ECX */
4273 #ifndef OPENSSL_NO_SM2
4275 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4278 if (testnum && !mr) {
4279 printf("%30ssign verify sign/s verify/s\n", " ");
4284 printf("+F7:%u:%u:%s:%f:%f\n",
4285 k, sm2_curves[k].bits, sm2_curves[k].name,
4286 sm2_results[k][0], sm2_results[k][1]);
4288 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4289 sm2_curves[k].bits, sm2_curves[k].name,
4290 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4291 sm2_results[k][0], sm2_results[k][1]);
4294 #ifndef OPENSSL_NO_DH
4296 for (k = 0; k < FFDH_NUM; k++) {
4299 if (testnum && !mr) {
4300 printf("%23sop op/s\n", " ");
4304 printf("+F8:%u:%u:%f:%f\n",
4305 k, ffdh_params[k].bits,
4306 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4309 printf("%4u bits ffdh %8.4fs %8.1f\n",
4310 ffdh_params[k].bits,
4311 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4313 #endif /* OPENSSL_NO_DH */
4316 for (k = 0; k < kems_algs_len; k++) {
4317 const char *kem_name = kems_algname[k];
4319 if (!kems_doit[k] || !do_kems)
4321 if (testnum && !mr) {
4322 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4326 printf("+F9:%u:%f:%f:%f\n",
4327 k, kems_results[k][0], kems_results[k][1],
4328 kems_results[k][2]);
4330 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4331 1.0 / kems_results[k][0],
4332 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4333 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4338 for (k = 0; k < sigs_algs_len; k++) {
4339 const char *sig_name = sigs_algname[k];
4341 if (!sigs_doit[k] || !do_sigs)
4343 if (testnum && !mr) {
4344 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4348 printf("+F10:%u:%f:%f:%f\n",
4349 k, sigs_results[k][0], sigs_results[k][1],
4350 sigs_results[k][2]);
4352 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4353 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4354 1.0 / sigs_results[k][2], sigs_results[k][0],
4355 sigs_results[k][1], sigs_results[k][2]);
4360 ERR_print_errors(bio_err);
4361 for (i = 0; i < loopargs_len; i++) {
4362 OPENSSL_free(loopargs[i].buf_malloc);
4363 OPENSSL_free(loopargs[i].buf2_malloc);
4366 EVP_PKEY_CTX_free(genctx);
4367 for (k = 0; k < RSA_NUM; k++) {
4368 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4369 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4370 EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]);
4371 EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]);
4373 #ifndef OPENSSL_NO_DH
4374 OPENSSL_free(loopargs[i].secret_ff_a);
4375 OPENSSL_free(loopargs[i].secret_ff_b);
4376 for (k = 0; k < FFDH_NUM; k++)
4377 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4379 for (k = 0; k < DSA_NUM; k++) {
4380 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4381 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4383 for (k = 0; k < ECDSA_NUM; k++) {
4384 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4385 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4387 for (k = 0; k < EC_NUM; k++)
4388 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4389 #ifndef OPENSSL_NO_ECX
4390 for (k = 0; k < EdDSA_NUM; k++) {
4391 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4392 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4394 #endif /* OPENSSL_NO_ECX */
4395 #ifndef OPENSSL_NO_SM2
4396 for (k = 0; k < SM2_NUM; k++) {
4397 EVP_PKEY_CTX *pctx = NULL;
4399 /* free signing ctx */
4400 if (loopargs[i].sm2_ctx[k] != NULL
4401 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4402 EVP_PKEY_CTX_free(pctx);
4403 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4404 /* free verification ctx */
4405 if (loopargs[i].sm2_vfy_ctx[k] != NULL
4406 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4407 EVP_PKEY_CTX_free(pctx);
4408 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4410 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4413 for (k = 0; k < kems_algs_len; k++) {
4414 EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4415 EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4416 EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4417 OPENSSL_free(loopargs[i].kem_out[k]);
4418 OPENSSL_free(loopargs[i].kem_send_secret[k]);
4419 OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4421 for (k = 0; k < sigs_algs_len; k++) {
4422 EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4423 EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4424 EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4425 OPENSSL_free(loopargs[i].sig_sig[k]);
4427 OPENSSL_free(loopargs[i].secret_a);
4428 OPENSSL_free(loopargs[i].secret_b);
4430 OPENSSL_free(evp_hmac_name);
4431 OPENSSL_free(evp_cmac_name);
4432 for (k = 0; k < kems_algs_len; k++)
4433 OPENSSL_free(kems_algname[k]);
4434 if (kem_stack != NULL)
4435 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4436 for (k = 0; k < sigs_algs_len; k++)
4437 OPENSSL_free(sigs_algname[k]);
4438 if (sig_stack != NULL)
4439 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4441 if (async_jobs > 0) {
4442 for (i = 0; i < loopargs_len; i++)
4443 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4447 ASYNC_cleanup_thread();
4449 OPENSSL_free(loopargs);
4451 EVP_CIPHER_free(evp_cipher);
4457 static void print_message(const char *s, int length, int tm)
4460 mr ? "+DT:%s:%d:%d\n"
4461 : "Doing %s ops for %ds on %d size blocks: ", s, tm, length);
4462 (void)BIO_flush(bio_err);
4467 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4471 mr ? "+DTP:%d:%s:%s:%d\n"
4472 : "Doing %u bits %s %s ops for %ds: ", bits, str, str2, tm);
4473 (void)BIO_flush(bio_err);
4478 static void kskey_print_message(const char *str, const char *str2, int tm)
4481 mr ? "+DTP:%s:%s:%d\n"
4482 : "Doing %s %s ops for %ds: ", str, str2, tm);
4483 (void)BIO_flush(bio_err);
4488 static void print_result(int alg, int run_no, int count, double time_used)
4491 BIO_printf(bio_err, "%s error!\n", names[alg]);
4492 ERR_print_errors(bio_err);
4496 mr ? "+R:%d:%s:%f\n"
4497 : "%d %s ops in %.2fs\n", count, names[alg], time_used);
4498 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4502 static char *sstrsep(char **string, const char *delim)
4505 char *token = *string;
4507 memset(isdelim, 0, sizeof(isdelim));
4511 isdelim[(unsigned char)(*delim)] = 1;
4515 while (!isdelim[(unsigned char)(**string)])
4526 static int strtoint(const char *str, const int min_val, const int upper_val,
4533 val = strtol(str, &end, 10);
4534 if (errno == 0 && end != str && *end == 0
4535 && min_val <= val && val < upper_val) {
4543 static int do_multi(int multi, int size_num)
4549 static char sep[] = ":";
4551 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4552 for (n = 0; n < multi; ++n) {
4553 if (pipe(fd) == -1) {
4554 BIO_printf(bio_err, "pipe failure\n");
4558 (void)BIO_flush(bio_err);
4565 if (dup(fd[1]) == -1) {
4566 BIO_printf(bio_err, "dup failed\n");
4575 printf("Forked child %d\n", n);
4578 /* for now, assume the pipe is long enough to take all the output */
4579 for (n = 0; n < multi; ++n) {
4587 if ((f = fdopen(fds[n], "r")) == NULL) {
4588 BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4593 while (fgets(buf, sizeof(buf), f)) {
4594 p = strchr(buf, '\n');
4597 if (buf[0] != '+') {
4599 "Don't understand line '%s' from child %d\n", buf,
4603 printf("Got: %s from %d\n", buf, n);
4605 if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
4609 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
4611 for (j = 0; j < size_num; ++j)
4612 results[alg][j] += atof(sstrsep(&p, sep));
4614 } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
4615 tk = sstrsep(&p, sep);
4616 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
4619 d = atof(sstrsep(&p, sep));
4620 rsa_results[k][0] += d;
4622 d = atof(sstrsep(&p, sep));
4623 rsa_results[k][1] += d;
4625 d = atof(sstrsep(&p, sep));
4626 rsa_results[k][2] += d;
4628 d = atof(sstrsep(&p, sep));
4629 rsa_results[k][3] += d;
4631 } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
4632 tk = sstrsep(&p, sep);
4633 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
4636 d = atof(sstrsep(&p, sep));
4637 dsa_results[k][0] += d;
4639 d = atof(sstrsep(&p, sep));
4640 dsa_results[k][1] += d;
4642 } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
4643 tk = sstrsep(&p, sep);
4644 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
4647 d = atof(sstrsep(&p, sep));
4648 ecdsa_results[k][0] += d;
4650 d = atof(sstrsep(&p, sep));
4651 ecdsa_results[k][1] += d;
4653 } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
4654 tk = sstrsep(&p, sep);
4655 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
4658 d = atof(sstrsep(&p, sep));
4659 ecdh_results[k][0] += d;
4661 # ifndef OPENSSL_NO_ECX
4662 } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
4663 tk = sstrsep(&p, sep);
4664 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
4668 d = atof(sstrsep(&p, sep));
4669 eddsa_results[k][0] += d;
4671 d = atof(sstrsep(&p, sep));
4672 eddsa_results[k][1] += d;
4674 # endif /* OPENSSL_NO_ECX */
4675 # ifndef OPENSSL_NO_SM2
4676 } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
4677 tk = sstrsep(&p, sep);
4678 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
4682 d = atof(sstrsep(&p, sep));
4683 sm2_results[k][0] += d;
4685 d = atof(sstrsep(&p, sep));
4686 sm2_results[k][1] += d;
4688 # endif /* OPENSSL_NO_SM2 */
4689 # ifndef OPENSSL_NO_DH
4690 } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
4691 tk = sstrsep(&p, sep);
4692 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
4695 d = atof(sstrsep(&p, sep));
4696 ffdh_results[k][0] += d;
4698 # endif /* OPENSSL_NO_DH */
4699 } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
4700 tk = sstrsep(&p, sep);
4701 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
4702 d = atof(sstrsep(&p, sep));
4703 kems_results[k][0] += d;
4705 d = atof(sstrsep(&p, sep));
4706 kems_results[k][1] += d;
4708 d = atof(sstrsep(&p, sep));
4709 kems_results[k][2] += d;
4711 } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
4712 tk = sstrsep(&p, sep);
4713 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
4714 d = atof(sstrsep(&p, sep));
4715 sigs_results[k][0] += d;
4717 d = atof(sstrsep(&p, sep));
4718 sigs_results[k][1] += d;
4720 d = atof(sstrsep(&p, sep));
4721 sigs_results[k][2] += d;
4723 } else if (!HAS_PREFIX(buf, "+H:")) {
4724 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
4732 for (n = 0; n < multi; ++n) {
4733 while (wait(&status) == -1)
4734 if (errno != EINTR) {
4735 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
4739 if (WIFEXITED(status) && WEXITSTATUS(status)) {
4740 BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
4741 } else if (WIFSIGNALED(status)) {
4742 BIO_printf(bio_err, "Child terminated by signal %d\n",
4750 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
4751 const openssl_speed_sec_t *seconds)
4753 static const int mblengths_list[] =
4754 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
4755 const int *mblengths = mblengths_list;
4756 int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
4757 const char *alg_name;
4758 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
4759 EVP_CIPHER_CTX *ctx = NULL;
4762 if (lengths_single) {
4763 mblengths = &lengths_single;
4767 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
4768 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
4769 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
4770 app_bail_out("failed to allocate cipher context\n");
4771 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
4772 app_bail_out("failed to initialise cipher context\n");
4774 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
4775 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
4778 key = app_malloc(keylen, "evp_cipher key");
4779 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
4780 app_bail_out("failed to generate random cipher key\n");
4781 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
4782 app_bail_out("failed to set cipher key\n");
4783 OPENSSL_clear_free(key, keylen);
4785 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
4786 sizeof(no_key), no_key) <= 0)
4787 app_bail_out("failed to set AEAD key\n");
4788 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4789 app_bail_out("failed to get cipher name\n");
4791 for (j = 0; j < num; j++) {
4792 print_message(alg_name, mblengths[j], seconds->sym);
4794 for (count = 0; run && count < INT_MAX; count++) {
4795 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
4796 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
4797 size_t len = mblengths[j];
4800 memset(aad, 0, 8); /* avoid uninitialized values */
4801 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
4802 aad[9] = 3; /* version */
4804 aad[11] = 0; /* length */
4806 mb_param.out = NULL;
4809 mb_param.interleave = 8;
4811 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
4812 sizeof(mb_param), &mb_param);
4818 (void)EVP_CIPHER_CTX_ctrl(ctx,
4819 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
4820 sizeof(mb_param), &mb_param);
4824 if (RAND_bytes(inp, 16) <= 0)
4825 app_bail_out("error setting random bytes\n");
4827 aad[11] = (unsigned char)(len >> 8);
4828 aad[12] = (unsigned char)(len);
4829 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
4830 EVP_AEAD_TLS1_AAD_LEN, aad);
4831 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
4835 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
4836 : "%d %s ops in %.2fs\n", count, "evp", d);
4837 if ((ciph_success <= 0) && (mr == 0))
4838 BIO_printf(bio_err, "Error performing cipher op\n");
4839 results[D_EVP][j] = ((double)count) / d * mblengths[j];
4843 fprintf(stdout, "+H");
4844 for (j = 0; j < num; j++)
4845 fprintf(stdout, ":%d", mblengths[j]);
4846 fprintf(stdout, "\n");
4847 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
4848 for (j = 0; j < num; j++)
4849 fprintf(stdout, ":%.2f", results[D_EVP][j]);
4850 fprintf(stdout, "\n");
4853 "The 'numbers' are in 1000s of bytes per second processed.\n");
4854 fprintf(stdout, "type ");
4855 for (j = 0; j < num; j++)
4856 fprintf(stdout, "%7d bytes", mblengths[j]);
4857 fprintf(stdout, "\n");
4858 fprintf(stdout, "%-24s", alg_name);
4860 for (j = 0; j < num; j++) {
4861 if (results[D_EVP][j] > 10000)
4862 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
4864 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
4866 fprintf(stdout, "\n");
4872 EVP_CIPHER_CTX_free(ctx);