2 * Copyright 1995-2022 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
23 /* We need to use some deprecated APIs */
24 #define OPENSSL_SUPPRESS_DEPRECATED
32 #include "internal/numbers.h"
33 #include <openssl/crypto.h>
34 #include <openssl/rand.h>
35 #include <openssl/err.h>
36 #include <openssl/evp.h>
37 #include <openssl/objects.h>
38 #include <openssl/core_names.h>
39 #include <openssl/async.h>
40 #if !defined(OPENSSL_SYS_MSDOS)
45 # if defined(OPENSSL_TANDEM_FLOSS)
46 # include <floss.h(floss_fork)>
54 #include <openssl/bn.h>
55 #include <openssl/rsa.h>
56 #include "./testrsa.h"
58 # include <openssl/dh.h>
60 #include <openssl/x509.h>
61 #include <openssl/dsa.h>
62 #include "./testdsa.h"
63 #include <openssl/modes.h>
66 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
79 #define MAX_MISALIGNMENT 63
80 #define MAX_ECDH_SIZE 256
82 #define MAX_FFDH_SIZE 1024
84 #ifndef RSA_DEFAULT_PRIME_NUM
85 # define RSA_DEFAULT_PRIME_NUM 2
88 typedef struct openssl_speed_sec_st {
97 } openssl_speed_sec_t;
99 static volatile int run = 0;
101 static int mr = 0; /* machine-readeable output format to merge fork results */
102 static int usertime = 1;
104 static double Time_F(int s);
105 static void print_message(const char *s, long num, int length, int tm);
106 static void pkey_print_message(const char *str, const char *str2,
107 long num, unsigned int bits, int sec);
108 static void print_result(int alg, int run_no, int count, double time_used);
110 static int do_multi(int multi, int size_num);
113 static const int lengths_list[] = {
114 16, 64, 256, 1024, 8 * 1024, 16 * 1024
116 #define SIZE_NUM OSSL_NELEM(lengths_list)
117 static const int *lengths = lengths_list;
119 static const int aead_lengths_list[] = {
120 2, 31, 136, 1024, 8 * 1024, 16 * 1024
128 static void alarmed(int sig)
130 signal(SIGALRM, alarmed);
134 static double Time_F(int s)
136 double ret = app_tminterval(s, usertime);
142 #elif defined(_WIN32)
146 static unsigned int lapse;
147 static volatile unsigned int schlock;
148 static void alarm_win32(unsigned int secs)
153 # define alarm alarm_win32
155 static DWORD WINAPI sleepy(VOID * arg)
163 static double Time_F(int s)
170 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
172 DWORD err = GetLastError();
173 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
177 Sleep(0); /* scheduler spinlock */
178 ret = app_tminterval(s, usertime);
180 ret = app_tminterval(s, usertime);
182 TerminateThread(thr, 0);
189 # error "SIGALRM not defined and the platform is not Windows"
192 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
193 const openssl_speed_sec_t *seconds);
195 static int opt_found(const char *name, unsigned int *result,
196 const OPT_PAIR pairs[], unsigned int nbelem)
200 for (idx = 0; idx < nbelem; ++idx, pairs++)
201 if (strcmp(name, pairs->name) == 0) {
202 *result = pairs->retval;
207 #define opt_found(value, pairs, result)\
208 opt_found(value, result, pairs, OSSL_NELEM(pairs))
210 typedef enum OPTION_choice {
212 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
213 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM,
214 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC
217 const OPTIONS speed_options[] = {
218 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"},
220 OPT_SECTION("General"),
221 {"help", OPT_HELP, '-', "Display this summary"},
223 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
224 {"mr", OPT_MR, '-', "Produce machine readable output"},
226 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
228 #ifndef OPENSSL_NO_ASYNC
229 {"async_jobs", OPT_ASYNCJOBS, 'p',
230 "Enable async mode and start specified number of jobs"},
232 #ifndef OPENSSL_NO_ENGINE
233 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
235 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
237 OPT_SECTION("Selection"),
238 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
239 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
240 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
241 {"decrypt", OPT_DECRYPT, '-',
242 "Time decryption instead of encryption (only EVP)"},
243 {"aead", OPT_AEAD, '-',
244 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
246 OPT_SECTION("Timing"),
247 {"elapsed", OPT_ELAPSED, '-',
248 "Use wall-clock time instead of CPU user time as divisor"},
249 {"seconds", OPT_SECONDS, 'p',
250 "Run benchmarks for specified amount of seconds"},
251 {"bytes", OPT_BYTES, 'p',
252 "Run [non-PKI] benchmarks on custom-sized buffer"},
253 {"misalign", OPT_MISALIGN, 'p',
254 "Use specified offset to mis-align buffers"},
260 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
265 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
266 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
267 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
268 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
269 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
270 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
271 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
273 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
274 static const char *names[ALGOR_NUM] = {
275 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
276 "sha256", "sha512", "whirlpool", "hmac(md5)",
277 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
278 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
279 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
280 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
281 "evp", "ghash", "rand", "cmac"
284 /* list of configured algorithm (remaining), with some few alias */
285 static const OPT_PAIR doit_choices[] = {
292 {"sha256", D_SHA256},
293 {"sha512", D_SHA512},
294 {"whirlpool", D_WHIRLPOOL},
295 {"ripemd", D_RMD160},
296 {"rmd160", D_RMD160},
297 {"ripemd160", D_RMD160},
299 {"des-cbc", D_CBC_DES},
300 {"des-ede3", D_EDE3_DES},
301 {"aes-128-cbc", D_CBC_128_AES},
302 {"aes-192-cbc", D_CBC_192_AES},
303 {"aes-256-cbc", D_CBC_256_AES},
304 {"camellia-128-cbc", D_CBC_128_CML},
305 {"camellia-192-cbc", D_CBC_192_CML},
306 {"camellia-256-cbc", D_CBC_256_CML},
307 {"rc2-cbc", D_CBC_RC2},
309 {"rc5-cbc", D_CBC_RC5},
311 {"idea-cbc", D_CBC_IDEA},
312 {"idea", D_CBC_IDEA},
313 {"seed-cbc", D_CBC_SEED},
314 {"seed", D_CBC_SEED},
315 {"bf-cbc", D_CBC_BF},
316 {"blowfish", D_CBC_BF},
318 {"cast-cbc", D_CBC_CAST},
319 {"cast", D_CBC_CAST},
320 {"cast5", D_CBC_CAST},
325 static double results[ALGOR_NUM][SIZE_NUM];
327 enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM };
328 static const OPT_PAIR dsa_choices[DSA_NUM] = {
329 {"dsa512", R_DSA_512},
330 {"dsa1024", R_DSA_1024},
331 {"dsa2048", R_DSA_2048}
333 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
336 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
339 static const OPT_PAIR rsa_choices[RSA_NUM] = {
340 {"rsa512", R_RSA_512},
341 {"rsa1024", R_RSA_1024},
342 {"rsa2048", R_RSA_2048},
343 {"rsa3072", R_RSA_3072},
344 {"rsa4096", R_RSA_4096},
345 {"rsa7680", R_RSA_7680},
346 {"rsa15360", R_RSA_15360}
349 static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */
351 #ifndef OPENSSL_NO_DH
353 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
356 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
357 {"ffdh2048", R_FFDH_2048},
358 {"ffdh3072", R_FFDH_3072},
359 {"ffdh4096", R_FFDH_4096},
360 {"ffdh6144", R_FFDH_6144},
361 {"ffdh8192", R_FFDH_8192},
364 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
365 #endif /* OPENSSL_NO_DH */
368 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
369 #ifndef OPENSSL_NO_EC2M
370 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
371 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
373 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
374 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
376 /* list of ecdsa curves */
377 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
378 {"ecdsap160", R_EC_P160},
379 {"ecdsap192", R_EC_P192},
380 {"ecdsap224", R_EC_P224},
381 {"ecdsap256", R_EC_P256},
382 {"ecdsap384", R_EC_P384},
383 {"ecdsap521", R_EC_P521},
384 #ifndef OPENSSL_NO_EC2M
385 {"ecdsak163", R_EC_K163},
386 {"ecdsak233", R_EC_K233},
387 {"ecdsak283", R_EC_K283},
388 {"ecdsak409", R_EC_K409},
389 {"ecdsak571", R_EC_K571},
390 {"ecdsab163", R_EC_B163},
391 {"ecdsab233", R_EC_B233},
392 {"ecdsab283", R_EC_B283},
393 {"ecdsab409", R_EC_B409},
394 {"ecdsab571", R_EC_B571},
396 {"ecdsabrp256r1", R_EC_BRP256R1},
397 {"ecdsabrp256t1", R_EC_BRP256T1},
398 {"ecdsabrp384r1", R_EC_BRP384R1},
399 {"ecdsabrp384t1", R_EC_BRP384T1},
400 {"ecdsabrp512r1", R_EC_BRP512R1},
401 {"ecdsabrp512t1", R_EC_BRP512T1}
403 enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM };
404 /* list of ecdh curves, extension of |ecdsa_choices| list above */
405 static const OPT_PAIR ecdh_choices[EC_NUM] = {
406 {"ecdhp160", R_EC_P160},
407 {"ecdhp192", R_EC_P192},
408 {"ecdhp224", R_EC_P224},
409 {"ecdhp256", R_EC_P256},
410 {"ecdhp384", R_EC_P384},
411 {"ecdhp521", R_EC_P521},
412 #ifndef OPENSSL_NO_EC2M
413 {"ecdhk163", R_EC_K163},
414 {"ecdhk233", R_EC_K233},
415 {"ecdhk283", R_EC_K283},
416 {"ecdhk409", R_EC_K409},
417 {"ecdhk571", R_EC_K571},
418 {"ecdhb163", R_EC_B163},
419 {"ecdhb233", R_EC_B233},
420 {"ecdhb283", R_EC_B283},
421 {"ecdhb409", R_EC_B409},
422 {"ecdhb571", R_EC_B571},
424 {"ecdhbrp256r1", R_EC_BRP256R1},
425 {"ecdhbrp256t1", R_EC_BRP256T1},
426 {"ecdhbrp384r1", R_EC_BRP384R1},
427 {"ecdhbrp384t1", R_EC_BRP384T1},
428 {"ecdhbrp512r1", R_EC_BRP512R1},
429 {"ecdhbrp512t1", R_EC_BRP512T1},
430 {"ecdhx25519", R_EC_X25519},
431 {"ecdhx448", R_EC_X448}
434 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
435 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
437 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
438 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
439 {"ed25519", R_EC_Ed25519},
440 {"ed448", R_EC_Ed448}
443 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
445 #ifndef OPENSSL_NO_SM2
446 enum { R_EC_CURVESM2, SM2_NUM };
447 static const OPT_PAIR sm2_choices[SM2_NUM] = {
448 {"curveSM2", R_EC_CURVESM2}
450 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
451 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
452 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
453 #endif /* OPENSSL_NO_SM2 */
455 #define COND(unused_cond) (run && count < INT_MAX)
456 #define COUNT(d) (count)
458 typedef struct loopargs_st {
459 ASYNC_JOB *inprogress_job;
460 ASYNC_WAIT_CTX *wait_ctx;
463 unsigned char *buf_malloc;
464 unsigned char *buf2_malloc;
468 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
469 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
470 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
471 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
472 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
473 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
474 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
475 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
476 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
477 #ifndef OPENSSL_NO_SM2
478 EVP_MD_CTX *sm2_ctx[SM2_NUM];
479 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
480 EVP_PKEY *sm2_pkey[SM2_NUM];
482 unsigned char *secret_a;
483 unsigned char *secret_b;
484 size_t outlen[EC_NUM];
485 #ifndef OPENSSL_NO_DH
486 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
487 unsigned char *secret_ff_a;
488 unsigned char *secret_ff_b;
493 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
494 loopargs_t * loopargs);
496 static unsigned int testnum;
498 /* Nb of iterations to do per algorithm and key-size */
499 static long c[ALGOR_NUM][SIZE_NUM];
501 static char *evp_mac_mdname = "md5";
502 static char *evp_hmac_name = NULL;
503 static const char *evp_md_name = NULL;
504 static char *evp_mac_ciphername = "aes-128-cbc";
505 static char *evp_cmac_name = NULL;
507 static int have_md(const char *name)
512 if (opt_md_silent(name, &md)) {
513 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
515 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
517 EVP_MD_CTX_free(ctx);
523 static int have_cipher(const char *name)
526 EVP_CIPHER *cipher = NULL;
528 if (opt_cipher_silent(name, &cipher)) {
529 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
532 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
534 EVP_CIPHER_CTX_free(ctx);
535 EVP_CIPHER_free(cipher);
540 static int EVP_Digest_loop(const char *mdname, int algindex, void *args)
542 loopargs_t *tempargs = *(loopargs_t **) args;
543 unsigned char *buf = tempargs->buf;
544 unsigned char digest[EVP_MAX_MD_SIZE];
548 if (!opt_md_silent(mdname, &md))
550 for (count = 0; COND(c[algindex][testnum]); count++) {
551 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
561 static int EVP_Digest_md_loop(void *args)
563 return EVP_Digest_loop(evp_md_name, D_EVP, args);
566 static int EVP_Digest_MD2_loop(void *args)
568 return EVP_Digest_loop("md2", D_MD2, args);
571 static int EVP_Digest_MDC2_loop(void *args)
573 return EVP_Digest_loop("mdc2", D_MDC2, args);
576 static int EVP_Digest_MD4_loop(void *args)
578 return EVP_Digest_loop("md4", D_MD4, args);
581 static int MD5_loop(void *args)
583 return EVP_Digest_loop("md5", D_MD5, args);
586 static int EVP_MAC_loop(int algindex, void *args)
588 loopargs_t *tempargs = *(loopargs_t **) args;
589 unsigned char *buf = tempargs->buf;
590 EVP_MAC_CTX *mctx = tempargs->mctx;
591 unsigned char mac[EVP_MAX_MD_SIZE];
594 for (count = 0; COND(c[algindex][testnum]); count++) {
597 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
598 || !EVP_MAC_update(mctx, buf, lengths[testnum])
599 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
605 static int HMAC_loop(void *args)
607 return EVP_MAC_loop(D_HMAC, args);
610 static int CMAC_loop(void *args)
612 return EVP_MAC_loop(D_EVP_CMAC, args);
615 static int SHA1_loop(void *args)
617 return EVP_Digest_loop("sha1", D_SHA1, args);
620 static int SHA256_loop(void *args)
622 return EVP_Digest_loop("sha256", D_SHA256, args);
625 static int SHA512_loop(void *args)
627 return EVP_Digest_loop("sha512", D_SHA512, args);
630 static int WHIRLPOOL_loop(void *args)
632 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
635 static int EVP_Digest_RMD160_loop(void *args)
637 return EVP_Digest_loop("ripemd160", D_RMD160, args);
642 static int EVP_Cipher_loop(void *args)
644 loopargs_t *tempargs = *(loopargs_t **) args;
645 unsigned char *buf = tempargs->buf;
648 if (tempargs->ctx == NULL)
650 for (count = 0; COND(c[algindex][testnum]); count++)
651 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
656 static int GHASH_loop(void *args)
658 loopargs_t *tempargs = *(loopargs_t **) args;
659 unsigned char *buf = tempargs->buf;
660 EVP_MAC_CTX *mctx = tempargs->mctx;
663 /* just do the update in the loop to be comparable with 1.1.1 */
664 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
665 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
671 #define MAX_BLOCK_SIZE 128
673 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
675 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
676 const unsigned char *key,
679 EVP_CIPHER_CTX *ctx = NULL;
680 EVP_CIPHER *cipher = NULL;
682 if (!opt_cipher_silent(ciphername, &cipher))
685 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
688 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
689 EVP_CIPHER_CTX_free(ctx);
694 if (!EVP_CIPHER_CTX_set_key_length(ctx, keylen)) {
695 EVP_CIPHER_CTX_free(ctx);
700 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
701 EVP_CIPHER_CTX_free(ctx);
707 EVP_CIPHER_free(cipher);
711 static int RAND_bytes_loop(void *args)
713 loopargs_t *tempargs = *(loopargs_t **) args;
714 unsigned char *buf = tempargs->buf;
717 for (count = 0; COND(c[D_RAND][testnum]); count++)
718 RAND_bytes(buf, lengths[testnum]);
722 static int decrypt = 0;
723 static int EVP_Update_loop(void *args)
725 loopargs_t *tempargs = *(loopargs_t **) args;
726 unsigned char *buf = tempargs->buf;
727 EVP_CIPHER_CTX *ctx = tempargs->ctx;
731 for (count = 0; COND(c[D_EVP][testnum]); count++) {
732 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
734 /* reset iv in case of counter overflow */
735 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
739 for (count = 0; COND(c[D_EVP][testnum]); count++) {
740 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
742 /* reset iv in case of counter overflow */
743 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
748 EVP_DecryptFinal_ex(ctx, buf, &outl);
750 EVP_EncryptFinal_ex(ctx, buf, &outl);
755 * CCM does not support streaming. For the purpose of performance measurement,
756 * each message is encrypted using the same (key,iv)-pair. Do not use this
757 * code in your application.
759 static int EVP_Update_loop_ccm(void *args)
761 loopargs_t *tempargs = *(loopargs_t **) args;
762 unsigned char *buf = tempargs->buf;
763 EVP_CIPHER_CTX *ctx = tempargs->ctx;
765 unsigned char tag[12];
768 for (count = 0; COND(c[D_EVP][testnum]); count++) {
769 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
772 (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
773 /* counter is reset on every update */
774 (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
777 for (count = 0; COND(c[D_EVP][testnum]); count++) {
778 /* restore iv length field */
779 (void)EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
780 /* counter is reset on every update */
781 (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
785 (void)EVP_DecryptFinal_ex(ctx, buf, &outl);
787 (void)EVP_EncryptFinal_ex(ctx, buf, &outl);
792 * To make AEAD benchmarking more relevant perform TLS-like operations,
793 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
794 * payload length is not actually limited by 16KB...
796 static int EVP_Update_loop_aead(void *args)
798 loopargs_t *tempargs = *(loopargs_t **) args;
799 unsigned char *buf = tempargs->buf;
800 EVP_CIPHER_CTX *ctx = tempargs->ctx;
802 unsigned char aad[13] = { 0xcc };
803 unsigned char faketag[16] = { 0xcc };
806 for (count = 0; COND(c[D_EVP][testnum]); count++) {
807 (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
808 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
809 sizeof(faketag), faketag);
810 (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
811 (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
812 (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl);
815 for (count = 0; COND(c[D_EVP][testnum]); count++) {
816 (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv);
817 (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
818 (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
819 (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl);
825 static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */
827 static int RSA_sign_loop(void *args)
829 loopargs_t *tempargs = *(loopargs_t **) args;
830 unsigned char *buf = tempargs->buf;
831 unsigned char *buf2 = tempargs->buf2;
832 size_t *rsa_num = &tempargs->sigsize;
833 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
836 for (count = 0; COND(rsa_c[testnum][0]); count++) {
837 *rsa_num = tempargs->buflen;
838 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
840 BIO_printf(bio_err, "RSA sign failure\n");
841 ERR_print_errors(bio_err);
849 static int RSA_verify_loop(void *args)
851 loopargs_t *tempargs = *(loopargs_t **) args;
852 unsigned char *buf = tempargs->buf;
853 unsigned char *buf2 = tempargs->buf2;
854 size_t rsa_num = tempargs->sigsize;
855 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
858 for (count = 0; COND(rsa_c[testnum][1]); count++) {
859 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
861 BIO_printf(bio_err, "RSA verify failure\n");
862 ERR_print_errors(bio_err);
870 #ifndef OPENSSL_NO_DH
871 static long ffdh_c[FFDH_NUM][1];
873 static int FFDH_derive_key_loop(void *args)
875 loopargs_t *tempargs = *(loopargs_t **) args;
876 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
877 unsigned char *derived_secret = tempargs->secret_ff_a;
878 size_t outlen = MAX_FFDH_SIZE;
881 for (count = 0; COND(ffdh_c[testnum][0]); count++)
882 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
885 #endif /* OPENSSL_NO_DH */
887 static long dsa_c[DSA_NUM][2];
888 static int DSA_sign_loop(void *args)
890 loopargs_t *tempargs = *(loopargs_t **) args;
891 unsigned char *buf = tempargs->buf;
892 unsigned char *buf2 = tempargs->buf2;
893 size_t *dsa_num = &tempargs->sigsize;
894 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
897 for (count = 0; COND(dsa_c[testnum][0]); count++) {
898 *dsa_num = tempargs->buflen;
899 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
901 BIO_printf(bio_err, "DSA sign failure\n");
902 ERR_print_errors(bio_err);
910 static int DSA_verify_loop(void *args)
912 loopargs_t *tempargs = *(loopargs_t **) args;
913 unsigned char *buf = tempargs->buf;
914 unsigned char *buf2 = tempargs->buf2;
915 size_t dsa_num = tempargs->sigsize;
916 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
919 for (count = 0; COND(dsa_c[testnum][1]); count++) {
920 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
922 BIO_printf(bio_err, "DSA verify failure\n");
923 ERR_print_errors(bio_err);
931 static long ecdsa_c[ECDSA_NUM][2];
932 static int ECDSA_sign_loop(void *args)
934 loopargs_t *tempargs = *(loopargs_t **) args;
935 unsigned char *buf = tempargs->buf;
936 unsigned char *buf2 = tempargs->buf2;
937 size_t *ecdsa_num = &tempargs->sigsize;
938 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
941 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
942 *ecdsa_num = tempargs->buflen;
943 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
945 BIO_printf(bio_err, "ECDSA sign failure\n");
946 ERR_print_errors(bio_err);
954 static int ECDSA_verify_loop(void *args)
956 loopargs_t *tempargs = *(loopargs_t **) args;
957 unsigned char *buf = tempargs->buf;
958 unsigned char *buf2 = tempargs->buf2;
959 size_t ecdsa_num = tempargs->sigsize;
960 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
963 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
964 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
967 BIO_printf(bio_err, "ECDSA verify failure\n");
968 ERR_print_errors(bio_err);
976 /* ******************************************************************** */
977 static long ecdh_c[EC_NUM][1];
979 static int ECDH_EVP_derive_key_loop(void *args)
981 loopargs_t *tempargs = *(loopargs_t **) args;
982 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
983 unsigned char *derived_secret = tempargs->secret_a;
985 size_t *outlen = &(tempargs->outlen[testnum]);
987 for (count = 0; COND(ecdh_c[testnum][0]); count++)
988 EVP_PKEY_derive(ctx, derived_secret, outlen);
993 static long eddsa_c[EdDSA_NUM][2];
994 static int EdDSA_sign_loop(void *args)
996 loopargs_t *tempargs = *(loopargs_t **) args;
997 unsigned char *buf = tempargs->buf;
998 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
999 unsigned char *eddsasig = tempargs->buf2;
1000 size_t *eddsasigsize = &tempargs->sigsize;
1003 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1004 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1006 BIO_printf(bio_err, "EdDSA sign failure\n");
1007 ERR_print_errors(bio_err);
1015 static int EdDSA_verify_loop(void *args)
1017 loopargs_t *tempargs = *(loopargs_t **) args;
1018 unsigned char *buf = tempargs->buf;
1019 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1020 unsigned char *eddsasig = tempargs->buf2;
1021 size_t eddsasigsize = tempargs->sigsize;
1024 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1025 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1027 BIO_printf(bio_err, "EdDSA verify failure\n");
1028 ERR_print_errors(bio_err);
1036 #ifndef OPENSSL_NO_SM2
1037 static long sm2_c[SM2_NUM][2];
1038 static int SM2_sign_loop(void *args)
1040 loopargs_t *tempargs = *(loopargs_t **) args;
1041 unsigned char *buf = tempargs->buf;
1042 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1043 unsigned char *sm2sig = tempargs->buf2;
1046 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1047 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1049 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1050 sm2sigsize = max_size;
1052 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1053 NULL, sm2_pkey[testnum])) {
1054 BIO_printf(bio_err, "SM2 init sign failure\n");
1055 ERR_print_errors(bio_err);
1059 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1062 BIO_printf(bio_err, "SM2 sign failure\n");
1063 ERR_print_errors(bio_err);
1067 /* update the latest returned size and always use the fixed buffer size */
1068 tempargs->sigsize = sm2sigsize;
1074 static int SM2_verify_loop(void *args)
1076 loopargs_t *tempargs = *(loopargs_t **) args;
1077 unsigned char *buf = tempargs->buf;
1078 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1079 unsigned char *sm2sig = tempargs->buf2;
1080 size_t sm2sigsize = tempargs->sigsize;
1082 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1084 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1085 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1086 NULL, sm2_pkey[testnum])) {
1087 BIO_printf(bio_err, "SM2 verify init failure\n");
1088 ERR_print_errors(bio_err);
1092 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1095 BIO_printf(bio_err, "SM2 verify failure\n");
1096 ERR_print_errors(bio_err);
1103 #endif /* OPENSSL_NO_SM2 */
1105 static int run_benchmark(int async_jobs,
1106 int (*loop_function) (void *), loopargs_t * loopargs)
1108 int job_op_count = 0;
1109 int total_op_count = 0;
1110 int num_inprogress = 0;
1111 int error = 0, i = 0, ret = 0;
1112 OSSL_ASYNC_FD job_fd = 0;
1113 size_t num_job_fds = 0;
1115 if (async_jobs == 0) {
1116 return loop_function((void *)&loopargs);
1119 for (i = 0; i < async_jobs && !error; i++) {
1120 loopargs_t *looparg_item = loopargs + i;
1122 /* Copy pointer content (looparg_t item address) into async context */
1123 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1124 &job_op_count, loop_function,
1125 (void *)&looparg_item, sizeof(looparg_item));
1131 if (job_op_count == -1) {
1134 total_op_count += job_op_count;
1139 BIO_printf(bio_err, "Failure in the job\n");
1140 ERR_print_errors(bio_err);
1146 while (num_inprogress > 0) {
1147 #if defined(OPENSSL_SYS_WINDOWS)
1149 #elif defined(OPENSSL_SYS_UNIX)
1150 int select_result = 0;
1151 OSSL_ASYNC_FD max_fd = 0;
1154 FD_ZERO(&waitfdset);
1156 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1157 if (loopargs[i].inprogress_job == NULL)
1160 if (!ASYNC_WAIT_CTX_get_all_fds
1161 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1162 || num_job_fds > 1) {
1163 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1164 ERR_print_errors(bio_err);
1168 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1170 FD_SET(job_fd, &waitfdset);
1171 if (job_fd > max_fd)
1175 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1177 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1178 "Decrease the value of async_jobs\n",
1179 max_fd, FD_SETSIZE);
1180 ERR_print_errors(bio_err);
1185 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1186 if (select_result == -1 && errno == EINTR)
1189 if (select_result == -1) {
1190 BIO_printf(bio_err, "Failure in the select\n");
1191 ERR_print_errors(bio_err);
1196 if (select_result == 0)
1200 for (i = 0; i < async_jobs; i++) {
1201 if (loopargs[i].inprogress_job == NULL)
1204 if (!ASYNC_WAIT_CTX_get_all_fds
1205 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1206 || num_job_fds > 1) {
1207 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1208 ERR_print_errors(bio_err);
1212 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1215 #if defined(OPENSSL_SYS_UNIX)
1216 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1218 #elif defined(OPENSSL_SYS_WINDOWS)
1219 if (num_job_fds == 1
1220 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1225 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1226 loopargs[i].wait_ctx, &job_op_count,
1227 loop_function, (void *)(loopargs + i),
1228 sizeof(loopargs_t));
1233 if (job_op_count == -1) {
1236 total_op_count += job_op_count;
1239 loopargs[i].inprogress_job = NULL;
1244 loopargs[i].inprogress_job = NULL;
1245 BIO_printf(bio_err, "Failure in the job\n");
1246 ERR_print_errors(bio_err);
1253 return error ? -1 : total_op_count;
1256 typedef struct ec_curve_st {
1260 size_t sigsize; /* only used for EdDSA curves */
1263 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1265 EVP_PKEY_CTX *kctx = NULL;
1266 EVP_PKEY *key = NULL;
1268 /* Ensure that the error queue is empty */
1269 if (ERR_peek_error()) {
1271 "WARNING: the error queue contains previous unhandled errors.\n");
1272 ERR_print_errors(bio_err);
1276 * Let's try to create a ctx directly from the NID: this works for
1277 * curves like Curve25519 that are not implemented through the low
1278 * level EC interface.
1279 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1280 * then we set the curve by NID before deriving the actual keygen
1281 * ctx for that specific curve.
1283 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1285 EVP_PKEY_CTX *pctx = NULL;
1286 EVP_PKEY *params = NULL;
1288 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1289 * "int_ctx_new:unsupported algorithm" error was added to the
1291 * We remove it from the error queue as we are handling it.
1293 unsigned long error = ERR_peek_error();
1295 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1296 /* check that the error origin matches */
1297 && ERR_GET_LIB(error) == ERR_LIB_EVP
1298 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1299 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1300 ERR_get_error(); /* pop error from queue */
1301 if (ERR_peek_error()) {
1303 "Unhandled error in the error queue during EC key setup.\n");
1304 ERR_print_errors(bio_err);
1308 /* Create the context for parameter generation */
1309 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1310 || EVP_PKEY_paramgen_init(pctx) <= 0
1311 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1313 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) {
1314 BIO_printf(bio_err, "EC params init failure.\n");
1315 ERR_print_errors(bio_err);
1316 EVP_PKEY_CTX_free(pctx);
1319 EVP_PKEY_CTX_free(pctx);
1321 /* Create the context for the key generation */
1322 kctx = EVP_PKEY_CTX_new(params, NULL);
1323 EVP_PKEY_free(params);
1326 || EVP_PKEY_keygen_init(kctx) <= 0
1327 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1328 BIO_printf(bio_err, "EC key generation failure.\n");
1329 ERR_print_errors(bio_err);
1332 EVP_PKEY_CTX_free(kctx);
1336 #define stop_it(do_it, test_num)\
1337 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1339 int speed_main(int argc, char **argv)
1342 loopargs_t *loopargs = NULL;
1344 const char *engine_id = NULL;
1345 EVP_CIPHER *evp_cipher = NULL;
1346 EVP_MAC *mac = NULL;
1349 int async_init = 0, multiblock = 0, pr_header = 0;
1350 uint8_t doit[ALGOR_NUM] = { 0 };
1351 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1353 unsigned int size_num = SIZE_NUM;
1354 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1358 EVP_PKEY_CTX *genctx = NULL;
1363 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1364 ECDSA_SECONDS, ECDH_SECONDS,
1365 EdDSA_SECONDS, SM2_SECONDS,
1368 static const unsigned char key32[32] = {
1369 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1370 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1371 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1372 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1374 static const unsigned char deskey[] = {
1375 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1376 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1377 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1379 static const struct {
1380 const unsigned char *data;
1381 unsigned int length;
1384 { test512, sizeof(test512), 512 },
1385 { test1024, sizeof(test1024), 1024 },
1386 { test2048, sizeof(test2048), 2048 },
1387 { test3072, sizeof(test3072), 3072 },
1388 { test4096, sizeof(test4096), 4096 },
1389 { test7680, sizeof(test7680), 7680 },
1390 { test15360, sizeof(test15360), 15360 }
1392 uint8_t rsa_doit[RSA_NUM] = { 0 };
1393 int primes = RSA_DEFAULT_PRIME_NUM;
1394 #ifndef OPENSSL_NO_DH
1395 typedef struct ffdh_params_st {
1401 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1402 {"ffdh2048", NID_ffdhe2048, 2048},
1403 {"ffdh3072", NID_ffdhe3072, 3072},
1404 {"ffdh4096", NID_ffdhe4096, 4096},
1405 {"ffdh6144", NID_ffdhe6144, 6144},
1406 {"ffdh8192", NID_ffdhe8192, 8192}
1408 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1410 #endif /* OPENSSL_NO_DH */
1411 static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1412 uint8_t dsa_doit[DSA_NUM] = { 0 };
1414 * We only test over the following curves as they are representative, To
1415 * add tests over more curves, simply add the curve NID and curve name to
1416 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1417 * lists accordingly.
1419 static const EC_CURVE ec_curves[EC_NUM] = {
1421 {"secp160r1", NID_secp160r1, 160},
1422 {"nistp192", NID_X9_62_prime192v1, 192},
1423 {"nistp224", NID_secp224r1, 224},
1424 {"nistp256", NID_X9_62_prime256v1, 256},
1425 {"nistp384", NID_secp384r1, 384},
1426 {"nistp521", NID_secp521r1, 521},
1427 #ifndef OPENSSL_NO_EC2M
1429 {"nistk163", NID_sect163k1, 163},
1430 {"nistk233", NID_sect233k1, 233},
1431 {"nistk283", NID_sect283k1, 283},
1432 {"nistk409", NID_sect409k1, 409},
1433 {"nistk571", NID_sect571k1, 571},
1434 {"nistb163", NID_sect163r2, 163},
1435 {"nistb233", NID_sect233r1, 233},
1436 {"nistb283", NID_sect283r1, 283},
1437 {"nistb409", NID_sect409r1, 409},
1438 {"nistb571", NID_sect571r1, 571},
1440 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1441 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1442 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1443 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1444 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1445 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1446 /* Other and ECDH only ones */
1447 {"X25519", NID_X25519, 253},
1448 {"X448", NID_X448, 448}
1450 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1452 {"Ed25519", NID_ED25519, 253, 64},
1453 {"Ed448", NID_ED448, 456, 114}
1455 #ifndef OPENSSL_NO_SM2
1456 static const EC_CURVE sm2_curves[SM2_NUM] = {
1458 {"CurveSM2", NID_sm2, 256}
1460 uint8_t sm2_doit[SM2_NUM] = { 0 };
1462 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1463 uint8_t ecdh_doit[EC_NUM] = { 0 };
1464 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1466 /* checks declarated curves against choices list. */
1467 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1468 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1470 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1471 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1473 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1474 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1476 #ifndef OPENSSL_NO_SM2
1477 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1478 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1481 prog = opt_init(argc, argv, speed_options);
1482 while ((o = opt_next()) != OPT_EOF) {
1487 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1490 opt_help(speed_options);
1498 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1502 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1503 if (have_md(opt_arg()))
1504 evp_md_name = opt_arg();
1506 if (evp_cipher == NULL && evp_md_name == NULL) {
1507 ERR_clear_last_mark();
1509 "%s: %s is an unknown cipher or digest\n",
1517 if (!have_md(opt_arg())) {
1518 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1522 evp_mac_mdname = opt_arg();
1526 if (!have_cipher(opt_arg())) {
1527 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1531 evp_mac_ciphername = opt_arg();
1532 doit[D_EVP_CMAC] = 1;
1539 * In a forked execution, an engine might need to be
1540 * initialised by each child process, not by the parent.
1541 * So store the name here and run setup_engine() later on.
1543 engine_id = opt_arg();
1547 multi = atoi(opt_arg());
1548 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1549 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1555 #ifndef OPENSSL_NO_ASYNC
1556 async_jobs = atoi(opt_arg());
1557 if (!ASYNC_is_capable()) {
1559 "%s: async_jobs specified but async not supported\n",
1563 if (async_jobs > 99999) {
1564 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1570 misalign = opt_int_arg();
1571 if (misalign > MISALIGN) {
1573 "%s: Maximum offset is %d\n", prog, MISALIGN);
1582 #ifdef OPENSSL_NO_MULTIBLOCK
1584 "%s: -mb specified but multi-block support is disabled\n",
1593 case OPT_PROV_CASES:
1594 if (!opt_provider(o))
1598 primes = opt_int_arg();
1601 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1602 = seconds.ecdh = seconds.eddsa
1603 = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1606 lengths_single = atoi(opt_arg());
1607 lengths = &lengths_single;
1616 /* Remaining arguments are algorithms. */
1617 argc = opt_num_rest();
1620 if (!app_RAND_load())
1623 for (; *argv; argv++) {
1624 const char *algo = *argv;
1626 if (opt_found(algo, doit_choices, &i)) {
1630 if (strcmp(algo, "des") == 0) {
1631 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1634 if (strcmp(algo, "sha") == 0) {
1635 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1638 #ifndef OPENSSL_NO_DEPRECATED_3_0
1639 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1642 if (strncmp(algo, "rsa", 3) == 0) {
1643 if (algo[3] == '\0') {
1644 memset(rsa_doit, 1, sizeof(rsa_doit));
1647 if (opt_found(algo, rsa_choices, &i)) {
1652 #ifndef OPENSSL_NO_DH
1653 if (strncmp(algo, "ffdh", 4) == 0) {
1654 if (algo[4] == '\0') {
1655 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1658 if (opt_found(algo, ffdh_choices, &i)) {
1664 if (strncmp(algo, "dsa", 3) == 0) {
1665 if (algo[3] == '\0') {
1666 memset(dsa_doit, 1, sizeof(dsa_doit));
1669 if (opt_found(algo, dsa_choices, &i)) {
1674 if (strcmp(algo, "aes") == 0) {
1675 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1678 if (strcmp(algo, "camellia") == 0) {
1679 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1682 if (strncmp(algo, "ecdsa", 5) == 0) {
1683 if (algo[5] == '\0') {
1684 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1687 if (opt_found(algo, ecdsa_choices, &i)) {
1692 if (strncmp(algo, "ecdh", 4) == 0) {
1693 if (algo[4] == '\0') {
1694 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1697 if (opt_found(algo, ecdh_choices, &i)) {
1702 if (strcmp(algo, "eddsa") == 0) {
1703 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1706 if (opt_found(algo, eddsa_choices, &i)) {
1710 #ifndef OPENSSL_NO_SM2
1711 if (strcmp(algo, "sm2") == 0) {
1712 memset(sm2_doit, 1, sizeof(sm2_doit));
1715 if (opt_found(algo, sm2_choices, &i)) {
1720 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1726 if (evp_cipher == NULL) {
1727 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1729 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1730 EVP_CIPH_FLAG_AEAD_CIPHER)) {
1731 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1732 EVP_CIPHER_get0_name(evp_cipher));
1737 if (evp_cipher == NULL) {
1738 BIO_printf(bio_err, "-mb can be used only with a multi-block"
1739 " capable cipher\n");
1741 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1742 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1743 BIO_printf(bio_err, "%s is not a multi-block capable\n",
1744 EVP_CIPHER_get0_name(evp_cipher));
1746 } else if (async_jobs > 0) {
1747 BIO_printf(bio_err, "Async mode is not supported with -mb");
1752 /* Initialize the job pool if async mode is enabled */
1753 if (async_jobs > 0) {
1754 async_init = ASYNC_init_thread(async_jobs, async_jobs);
1756 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1761 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1763 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1764 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1766 for (i = 0; i < loopargs_len; i++) {
1767 if (async_jobs > 0) {
1768 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1769 if (loopargs[i].wait_ctx == NULL) {
1770 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1775 buflen = lengths[size_num - 1];
1776 if (buflen < 36) /* size of random vector in RSA benchmark */
1778 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1779 BIO_printf(bio_err, "Error: buffer size too large\n");
1782 buflen += MAX_MISALIGNMENT + 1;
1783 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1784 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1785 memset(loopargs[i].buf_malloc, 0, buflen);
1786 memset(loopargs[i].buf2_malloc, 0, buflen);
1788 /* Align the start of buffers on a 64 byte boundary */
1789 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1790 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1791 loopargs[i].buflen = buflen - misalign;
1792 loopargs[i].sigsize = buflen - misalign;
1793 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1794 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1795 #ifndef OPENSSL_NO_DH
1796 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1797 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1802 if (multi && do_multi(multi, size_num))
1806 /* Initialize the engine after the fork */
1807 e = setup_engine(engine_id, 0);
1809 /* No parameters; turn on everything. */
1810 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1811 memset(doit, 1, sizeof(doit));
1812 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1814 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1815 if (!have_md(names[i]))
1818 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1819 if (!have_cipher(names[i]))
1822 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1823 app_get0_propq())) != NULL) {
1829 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1830 app_get0_propq())) != NULL) {
1837 memset(rsa_doit, 1, sizeof(rsa_doit));
1838 #ifndef OPENSSL_NO_DH
1839 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1841 memset(dsa_doit, 1, sizeof(dsa_doit));
1842 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1843 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1844 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1845 #ifndef OPENSSL_NO_SM2
1846 memset(sm2_doit, 1, sizeof(sm2_doit));
1849 for (i = 0; i < ALGOR_NUM; i++)
1853 if (usertime == 0 && !mr)
1855 "You have chosen to measure elapsed time "
1856 "instead of user CPU time.\n");
1859 signal(SIGALRM, alarmed);
1863 for (testnum = 0; testnum < size_num; testnum++) {
1864 print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1867 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1869 print_result(D_MD2, testnum, count, d);
1876 for (testnum = 0; testnum < size_num; testnum++) {
1877 print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1880 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1882 print_result(D_MDC2, testnum, count, d);
1889 for (testnum = 0; testnum < size_num; testnum++) {
1890 print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1893 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1895 print_result(D_MD4, testnum, count, d);
1902 for (testnum = 0; testnum < size_num; testnum++) {
1903 print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1906 count = run_benchmark(async_jobs, MD5_loop, loopargs);
1908 print_result(D_MD5, testnum, count, d);
1915 for (testnum = 0; testnum < size_num; testnum++) {
1916 print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1919 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1921 print_result(D_SHA1, testnum, count, d);
1927 if (doit[D_SHA256]) {
1928 for (testnum = 0; testnum < size_num; testnum++) {
1929 print_message(names[D_SHA256], c[D_SHA256][testnum],
1930 lengths[testnum], seconds.sym);
1932 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1934 print_result(D_SHA256, testnum, count, d);
1940 if (doit[D_SHA512]) {
1941 for (testnum = 0; testnum < size_num; testnum++) {
1942 print_message(names[D_SHA512], c[D_SHA512][testnum],
1943 lengths[testnum], seconds.sym);
1945 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1947 print_result(D_SHA512, testnum, count, d);
1953 if (doit[D_WHIRLPOOL]) {
1954 for (testnum = 0; testnum < size_num; testnum++) {
1955 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
1956 lengths[testnum], seconds.sym);
1958 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
1960 print_result(D_WHIRLPOOL, testnum, count, d);
1966 if (doit[D_RMD160]) {
1967 for (testnum = 0; testnum < size_num; testnum++) {
1968 print_message(names[D_RMD160], c[D_RMD160][testnum],
1969 lengths[testnum], seconds.sym);
1971 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
1973 print_result(D_RMD160, testnum, count, d);
1980 static const char hmac_key[] = "This is a key...";
1981 int len = strlen(hmac_key);
1982 OSSL_PARAM params[3];
1984 mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1985 if (mac == NULL || evp_mac_mdname == NULL)
1988 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
1990 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
1991 names[D_HMAC] = evp_hmac_name;
1994 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
1997 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
1998 (char *)hmac_key, len);
1999 params[2] = OSSL_PARAM_construct_end();
2001 for (i = 0; i < loopargs_len; i++) {
2002 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2003 if (loopargs[i].mctx == NULL)
2006 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2009 for (testnum = 0; testnum < size_num; testnum++) {
2010 print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
2013 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2015 print_result(D_HMAC, testnum, count, d);
2019 for (i = 0; i < loopargs_len; i++)
2020 EVP_MAC_CTX_free(loopargs[i].mctx);
2025 if (doit[D_CBC_DES]) {
2028 for (i = 0; st && i < loopargs_len; i++) {
2029 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2030 sizeof(deskey) / 3);
2031 st = loopargs[i].ctx != NULL;
2033 algindex = D_CBC_DES;
2034 for (testnum = 0; st && testnum < size_num; testnum++) {
2035 print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2036 lengths[testnum], seconds.sym);
2038 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2040 print_result(D_CBC_DES, testnum, count, d);
2042 for (i = 0; i < loopargs_len; i++)
2043 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2046 if (doit[D_EDE3_DES]) {
2049 for (i = 0; st && i < loopargs_len; i++) {
2050 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2052 st = loopargs[i].ctx != NULL;
2054 algindex = D_EDE3_DES;
2055 for (testnum = 0; st && testnum < size_num; testnum++) {
2056 print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2057 lengths[testnum], seconds.sym);
2060 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2062 print_result(D_EDE3_DES, testnum, count, d);
2064 for (i = 0; i < loopargs_len; i++)
2065 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2068 for (k = 0; k < 3; k++) {
2069 algindex = D_CBC_128_AES + k;
2070 if (doit[algindex]) {
2073 keylen = 16 + k * 8;
2074 for (i = 0; st && i < loopargs_len; i++) {
2075 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2077 st = loopargs[i].ctx != NULL;
2080 for (testnum = 0; st && testnum < size_num; testnum++) {
2081 print_message(names[algindex], c[algindex][testnum],
2082 lengths[testnum], seconds.sym);
2085 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2087 print_result(algindex, testnum, count, d);
2089 for (i = 0; i < loopargs_len; i++)
2090 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2094 for (k = 0; k < 3; k++) {
2095 algindex = D_CBC_128_CML + k;
2096 if (doit[algindex]) {
2099 keylen = 16 + k * 8;
2100 for (i = 0; st && i < loopargs_len; i++) {
2101 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2103 st = loopargs[i].ctx != NULL;
2106 for (testnum = 0; st && testnum < size_num; testnum++) {
2107 print_message(names[algindex], c[algindex][testnum],
2108 lengths[testnum], seconds.sym);
2111 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2113 print_result(algindex, testnum, count, d);
2115 for (i = 0; i < loopargs_len; i++)
2116 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2120 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2121 if (doit[algindex]) {
2125 for (i = 0; st && i < loopargs_len; i++) {
2126 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2128 st = loopargs[i].ctx != NULL;
2131 for (testnum = 0; st && testnum < size_num; testnum++) {
2132 print_message(names[algindex], c[algindex][testnum],
2133 lengths[testnum], seconds.sym);
2136 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2138 print_result(algindex, testnum, count, d);
2140 for (i = 0; i < loopargs_len; i++)
2141 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2144 if (doit[D_GHASH]) {
2145 static const char gmac_iv[] = "0123456789ab";
2146 OSSL_PARAM params[3];
2148 mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2152 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2154 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2156 sizeof(gmac_iv) - 1);
2157 params[2] = OSSL_PARAM_construct_end();
2159 for (i = 0; i < loopargs_len; i++) {
2160 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2161 if (loopargs[i].mctx == NULL)
2164 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2167 for (testnum = 0; testnum < size_num; testnum++) {
2168 print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2171 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2173 print_result(D_GHASH, testnum, count, d);
2177 for (i = 0; i < loopargs_len; i++)
2178 EVP_MAC_CTX_free(loopargs[i].mctx);
2184 for (testnum = 0; testnum < size_num; testnum++) {
2185 print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2188 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2190 print_result(D_RAND, testnum, count, d);
2195 if (evp_cipher != NULL) {
2196 int (*loopfunc) (void *) = EVP_Update_loop;
2198 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2199 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2200 multiblock_speed(evp_cipher, lengths_single, &seconds);
2205 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2207 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2208 loopfunc = EVP_Update_loop_ccm;
2209 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2210 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2211 loopfunc = EVP_Update_loop_aead;
2212 if (lengths == lengths_list) {
2213 lengths = aead_lengths_list;
2214 size_num = OSSL_NELEM(aead_lengths_list);
2218 for (testnum = 0; testnum < size_num; testnum++) {
2219 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2222 for (k = 0; k < loopargs_len; k++) {
2223 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2224 if (loopargs[k].ctx == NULL) {
2225 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2228 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2229 NULL, iv, decrypt ? 0 : 1)) {
2230 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2231 ERR_print_errors(bio_err);
2235 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2237 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2238 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2239 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2240 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2241 loopargs[k].key, NULL, -1)) {
2242 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2243 ERR_print_errors(bio_err);
2246 OPENSSL_clear_free(loopargs[k].key, keylen);
2248 /* SIV mode only allows for a single Update operation */
2249 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2250 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2251 EVP_CTRL_SET_SPEED, 1, NULL);
2255 count = run_benchmark(async_jobs, loopfunc, loopargs);
2257 for (k = 0; k < loopargs_len; k++)
2258 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2259 print_result(D_EVP, testnum, count, d);
2261 } else if (evp_md_name != NULL) {
2262 names[D_EVP] = evp_md_name;
2264 for (testnum = 0; testnum < size_num; testnum++) {
2265 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2268 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2270 print_result(D_EVP, testnum, count, d);
2277 if (doit[D_EVP_CMAC]) {
2278 OSSL_PARAM params[3];
2279 EVP_CIPHER *cipher = NULL;
2281 mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2282 if (mac == NULL || evp_mac_ciphername == NULL)
2284 if (!opt_cipher(evp_mac_ciphername, &cipher))
2287 keylen = EVP_CIPHER_get_key_length(cipher);
2288 EVP_CIPHER_free(cipher);
2289 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2290 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2293 evp_cmac_name = app_malloc(sizeof("cmac()")
2294 + strlen(evp_mac_ciphername), "CMAC name");
2295 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2296 names[D_EVP_CMAC] = evp_cmac_name;
2298 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2299 evp_mac_ciphername, 0);
2300 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2301 (char *)key32, keylen);
2302 params[2] = OSSL_PARAM_construct_end();
2304 for (i = 0; i < loopargs_len; i++) {
2305 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2306 if (loopargs[i].mctx == NULL)
2309 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2313 for (testnum = 0; testnum < size_num; testnum++) {
2314 print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2315 lengths[testnum], seconds.sym);
2317 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2319 print_result(D_EVP_CMAC, testnum, count, d);
2323 for (i = 0; i < loopargs_len; i++)
2324 EVP_MAC_CTX_free(loopargs[i].mctx);
2329 for (i = 0; i < loopargs_len; i++)
2330 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2333 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2334 EVP_PKEY *rsa_key = NULL;
2337 if (!rsa_doit[testnum])
2340 if (primes > RSA_DEFAULT_PRIME_NUM) {
2341 /* we haven't set keys yet, generate multi-prime RSA keys */
2344 && BN_set_word(bn, RSA_F4)
2345 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2346 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2347 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2348 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2349 && EVP_PKEY_keygen(genctx, &rsa_key);
2352 EVP_PKEY_CTX_free(genctx);
2355 const unsigned char *p = rsa_keys[testnum].data;
2357 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2358 rsa_keys[testnum].length)) != NULL;
2361 for (i = 0; st && i < loopargs_len; i++) {
2362 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2363 loopargs[i].sigsize = loopargs[i].buflen;
2364 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2365 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2366 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2368 &loopargs[i].sigsize,
2369 loopargs[i].buf, 36) <= 0)
2374 "RSA sign setup failure. No RSA sign will be done.\n");
2375 ERR_print_errors(bio_err);
2378 pkey_print_message("private", "rsa",
2379 rsa_c[testnum][0], rsa_keys[testnum].bits,
2381 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2383 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2386 mr ? "+R1:%ld:%d:%.2f\n"
2387 : "%ld %u bits private RSA's in %.2fs\n",
2388 count, rsa_keys[testnum].bits, d);
2389 rsa_results[testnum][0] = (double)count / d;
2393 for (i = 0; st && i < loopargs_len; i++) {
2394 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2396 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2397 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2398 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2400 loopargs[i].sigsize,
2401 loopargs[i].buf, 36) <= 0)
2406 "RSA verify setup failure. No RSA verify will be done.\n");
2407 ERR_print_errors(bio_err);
2408 rsa_doit[testnum] = 0;
2410 pkey_print_message("public", "rsa",
2411 rsa_c[testnum][1], rsa_keys[testnum].bits,
2414 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2417 mr ? "+R2:%ld:%d:%.2f\n"
2418 : "%ld %u bits public RSA's in %.2fs\n",
2419 count, rsa_keys[testnum].bits, d);
2420 rsa_results[testnum][1] = (double)count / d;
2423 if (op_count <= 1) {
2424 /* if longer than 10s, don't do any more */
2425 stop_it(rsa_doit, testnum);
2427 EVP_PKEY_free(rsa_key);
2430 for (testnum = 0; testnum < DSA_NUM; testnum++) {
2431 EVP_PKEY *dsa_key = NULL;
2434 if (!dsa_doit[testnum])
2437 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2439 for (i = 0; st && i < loopargs_len; i++) {
2440 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2442 loopargs[i].sigsize = loopargs[i].buflen;
2443 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2444 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2446 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2448 &loopargs[i].sigsize,
2449 loopargs[i].buf, 20) <= 0)
2454 "DSA sign setup failure. No DSA sign will be done.\n");
2455 ERR_print_errors(bio_err);
2458 pkey_print_message("sign", "dsa",
2459 dsa_c[testnum][0], dsa_bits[testnum],
2462 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2465 mr ? "+R3:%ld:%u:%.2f\n"
2466 : "%ld %u bits DSA signs in %.2fs\n",
2467 count, dsa_bits[testnum], d);
2468 dsa_results[testnum][0] = (double)count / d;
2472 for (i = 0; st && i < loopargs_len; i++) {
2473 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2475 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2476 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2477 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2479 loopargs[i].sigsize,
2480 loopargs[i].buf, 36) <= 0)
2485 "DSA verify setup failure. No DSA verify will be done.\n");
2486 ERR_print_errors(bio_err);
2487 dsa_doit[testnum] = 0;
2489 pkey_print_message("verify", "dsa",
2490 dsa_c[testnum][1], dsa_bits[testnum],
2493 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2496 mr ? "+R4:%ld:%u:%.2f\n"
2497 : "%ld %u bits DSA verify in %.2fs\n",
2498 count, dsa_bits[testnum], d);
2499 dsa_results[testnum][1] = (double)count / d;
2502 if (op_count <= 1) {
2503 /* if longer than 10s, don't do any more */
2504 stop_it(dsa_doit, testnum);
2506 EVP_PKEY_free(dsa_key);
2509 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2510 EVP_PKEY *ecdsa_key = NULL;
2513 if (!ecdsa_doit[testnum])
2516 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2518 for (i = 0; st && i < loopargs_len; i++) {
2519 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2521 loopargs[i].sigsize = loopargs[i].buflen;
2522 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2523 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2525 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2527 &loopargs[i].sigsize,
2528 loopargs[i].buf, 20) <= 0)
2533 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2534 ERR_print_errors(bio_err);
2537 pkey_print_message("sign", "ecdsa",
2538 ecdsa_c[testnum][0], ec_curves[testnum].bits,
2541 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2544 mr ? "+R5:%ld:%u:%.2f\n"
2545 : "%ld %u bits ECDSA signs in %.2fs\n",
2546 count, ec_curves[testnum].bits, d);
2547 ecdsa_results[testnum][0] = (double)count / d;
2551 for (i = 0; st && i < loopargs_len; i++) {
2552 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2554 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2555 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2556 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2558 loopargs[i].sigsize,
2559 loopargs[i].buf, 20) <= 0)
2564 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2565 ERR_print_errors(bio_err);
2566 ecdsa_doit[testnum] = 0;
2568 pkey_print_message("verify", "ecdsa",
2569 ecdsa_c[testnum][1], ec_curves[testnum].bits,
2572 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2575 mr ? "+R6:%ld:%u:%.2f\n"
2576 : "%ld %u bits ECDSA verify in %.2fs\n",
2577 count, ec_curves[testnum].bits, d);
2578 ecdsa_results[testnum][1] = (double)count / d;
2581 if (op_count <= 1) {
2582 /* if longer than 10s, don't do any more */
2583 stop_it(ecdsa_doit, testnum);
2587 for (testnum = 0; testnum < EC_NUM; testnum++) {
2588 int ecdh_checks = 1;
2590 if (!ecdh_doit[testnum])
2593 for (i = 0; i < loopargs_len; i++) {
2594 EVP_PKEY_CTX *test_ctx = NULL;
2595 EVP_PKEY_CTX *ctx = NULL;
2596 EVP_PKEY *key_A = NULL;
2597 EVP_PKEY *key_B = NULL;
2601 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2602 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2603 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2604 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2605 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2606 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2607 || outlen == 0 /* ensure outlen is a valid size */
2608 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2610 BIO_printf(bio_err, "ECDH key generation failure.\n");
2611 ERR_print_errors(bio_err);
2617 * Here we perform a test run, comparing the output of a*B and b*A;
2618 * we try this here and assume that further EVP_PKEY_derive calls
2619 * never fail, so we can skip checks in the actually benchmarked
2620 * code, for maximum performance.
2622 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2623 || !EVP_PKEY_derive_init(test_ctx) /* init derivation test_ctx */
2624 || !EVP_PKEY_derive_set_peer(test_ctx, key_A) /* set peer pubkey in test_ctx */
2625 || !EVP_PKEY_derive(test_ctx, NULL, &test_outlen) /* determine max length */
2626 || !EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) /* compute a*B */
2627 || !EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) /* compute b*A */
2628 || test_outlen != outlen /* compare output length */) {
2630 BIO_printf(bio_err, "ECDH computation failure.\n");
2631 ERR_print_errors(bio_err);
2636 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2637 if (CRYPTO_memcmp(loopargs[i].secret_a,
2638 loopargs[i].secret_b, outlen)) {
2640 BIO_printf(bio_err, "ECDH computations don't match.\n");
2641 ERR_print_errors(bio_err);
2646 loopargs[i].ecdh_ctx[testnum] = ctx;
2647 loopargs[i].outlen[testnum] = outlen;
2649 EVP_PKEY_free(key_A);
2650 EVP_PKEY_free(key_B);
2651 EVP_PKEY_CTX_free(test_ctx);
2654 if (ecdh_checks != 0) {
2655 pkey_print_message("", "ecdh",
2657 ec_curves[testnum].bits, seconds.ecdh);
2660 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2663 mr ? "+R7:%ld:%d:%.2f\n" :
2664 "%ld %u-bits ECDH ops in %.2fs\n", count,
2665 ec_curves[testnum].bits, d);
2666 ecdh_results[testnum][0] = (double)count / d;
2670 if (op_count <= 1) {
2671 /* if longer than 10s, don't do any more */
2672 stop_it(ecdh_doit, testnum);
2676 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2678 EVP_PKEY *ed_pkey = NULL;
2679 EVP_PKEY_CTX *ed_pctx = NULL;
2681 if (!eddsa_doit[testnum])
2682 continue; /* Ignore Curve */
2683 for (i = 0; i < loopargs_len; i++) {
2684 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2685 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2689 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2690 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2695 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2697 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2698 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2700 EVP_PKEY_CTX_free(ed_pctx);
2703 EVP_PKEY_CTX_free(ed_pctx);
2705 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2708 EVP_PKEY_free(ed_pkey);
2711 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2712 NULL, NULL, ed_pkey)) {
2714 EVP_PKEY_free(ed_pkey);
2718 EVP_PKEY_free(ed_pkey);
2722 BIO_printf(bio_err, "EdDSA failure.\n");
2723 ERR_print_errors(bio_err);
2726 for (i = 0; i < loopargs_len; i++) {
2727 /* Perform EdDSA signature test */
2728 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2729 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2730 loopargs[i].buf2, &loopargs[i].sigsize,
2731 loopargs[i].buf, 20);
2737 "EdDSA sign failure. No EdDSA sign will be done.\n");
2738 ERR_print_errors(bio_err);
2741 pkey_print_message("sign", ed_curves[testnum].name,
2742 eddsa_c[testnum][0],
2743 ed_curves[testnum].bits, seconds.eddsa);
2745 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2749 mr ? "+R8:%ld:%u:%s:%.2f\n" :
2750 "%ld %u bits %s signs in %.2fs \n",
2751 count, ed_curves[testnum].bits,
2752 ed_curves[testnum].name, d);
2753 eddsa_results[testnum][0] = (double)count / d;
2756 /* Perform EdDSA verification test */
2757 for (i = 0; i < loopargs_len; i++) {
2758 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2759 loopargs[i].buf2, loopargs[i].sigsize,
2760 loopargs[i].buf, 20);
2766 "EdDSA verify failure. No EdDSA verify will be done.\n");
2767 ERR_print_errors(bio_err);
2768 eddsa_doit[testnum] = 0;
2770 pkey_print_message("verify", ed_curves[testnum].name,
2771 eddsa_c[testnum][1],
2772 ed_curves[testnum].bits, seconds.eddsa);
2774 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2777 mr ? "+R9:%ld:%u:%s:%.2f\n"
2778 : "%ld %u bits %s verify in %.2fs\n",
2779 count, ed_curves[testnum].bits,
2780 ed_curves[testnum].name, d);
2781 eddsa_results[testnum][1] = (double)count / d;
2784 if (op_count <= 1) {
2785 /* if longer than 10s, don't do any more */
2786 stop_it(eddsa_doit, testnum);
2791 #ifndef OPENSSL_NO_SM2
2792 for (testnum = 0; testnum < SM2_NUM; testnum++) {
2794 EVP_PKEY *sm2_pkey = NULL;
2796 if (!sm2_doit[testnum])
2797 continue; /* Ignore Curve */
2798 /* Init signing and verification */
2799 for (i = 0; i < loopargs_len; i++) {
2800 EVP_PKEY_CTX *sm2_pctx = NULL;
2801 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2802 EVP_PKEY_CTX *pctx = NULL;
2805 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2806 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2807 if (loopargs[i].sm2_ctx[testnum] == NULL
2808 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2813 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2814 || EVP_PKEY_keygen_init(pctx) <= 0
2815 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2816 sm2_curves[testnum].nid) <= 0
2817 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2818 EVP_PKEY_CTX_free(pctx);
2822 st = 0; /* set back to zero */
2823 /* attach it sooner to rely on main final cleanup */
2824 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2825 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2827 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2828 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2829 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2830 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2834 /* attach them directly to respective ctx */
2835 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2836 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2839 * No need to allow user to set an explicit ID here, just use
2840 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2842 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2843 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2846 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2847 EVP_sm3(), NULL, sm2_pkey))
2849 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2850 EVP_sm3(), NULL, sm2_pkey))
2852 st = 1; /* mark loop as succeeded */
2855 BIO_printf(bio_err, "SM2 init failure.\n");
2856 ERR_print_errors(bio_err);
2859 for (i = 0; i < loopargs_len; i++) {
2860 /* Perform SM2 signature test */
2861 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2862 loopargs[i].buf2, &loopargs[i].sigsize,
2863 loopargs[i].buf, 20);
2869 "SM2 sign failure. No SM2 sign will be done.\n");
2870 ERR_print_errors(bio_err);
2873 pkey_print_message("sign", sm2_curves[testnum].name,
2875 sm2_curves[testnum].bits, seconds.sm2);
2877 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2881 mr ? "+R10:%ld:%u:%s:%.2f\n" :
2882 "%ld %u bits %s signs in %.2fs \n",
2883 count, sm2_curves[testnum].bits,
2884 sm2_curves[testnum].name, d);
2885 sm2_results[testnum][0] = (double)count / d;
2889 /* Perform SM2 verification test */
2890 for (i = 0; i < loopargs_len; i++) {
2891 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2892 loopargs[i].buf2, loopargs[i].sigsize,
2893 loopargs[i].buf, 20);
2899 "SM2 verify failure. No SM2 verify will be done.\n");
2900 ERR_print_errors(bio_err);
2901 sm2_doit[testnum] = 0;
2903 pkey_print_message("verify", sm2_curves[testnum].name,
2905 sm2_curves[testnum].bits, seconds.sm2);
2907 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2910 mr ? "+R11:%ld:%u:%s:%.2f\n"
2911 : "%ld %u bits %s verify in %.2fs\n",
2912 count, sm2_curves[testnum].bits,
2913 sm2_curves[testnum].name, d);
2914 sm2_results[testnum][1] = (double)count / d;
2917 if (op_count <= 1) {
2918 /* if longer than 10s, don't do any more */
2919 for (testnum++; testnum < SM2_NUM; testnum++)
2920 sm2_doit[testnum] = 0;
2924 #endif /* OPENSSL_NO_SM2 */
2926 #ifndef OPENSSL_NO_DH
2927 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2928 int ffdh_checks = 1;
2930 if (!ffdh_doit[testnum])
2933 for (i = 0; i < loopargs_len; i++) {
2934 EVP_PKEY *pkey_A = NULL;
2935 EVP_PKEY *pkey_B = NULL;
2936 EVP_PKEY_CTX *ffdh_ctx = NULL;
2937 EVP_PKEY_CTX *test_ctx = NULL;
2941 /* Ensure that the error queue is empty */
2942 if (ERR_peek_error()) {
2944 "WARNING: the error queue contains previous unhandled errors.\n");
2945 ERR_print_errors(bio_err);
2948 pkey_A = EVP_PKEY_new();
2950 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2951 ERR_print_errors(bio_err);
2956 pkey_B = EVP_PKEY_new();
2958 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2959 ERR_print_errors(bio_err);
2965 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2967 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2968 ERR_print_errors(bio_err);
2974 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
2975 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
2976 ERR_print_errors(bio_err);
2981 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
2982 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
2983 ERR_print_errors(bio_err);
2989 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
2990 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
2991 BIO_printf(bio_err, "FFDH key generation failure.\n");
2992 ERR_print_errors(bio_err);
2998 EVP_PKEY_CTX_free(ffdh_ctx);
3001 * check if the derivation works correctly both ways so that
3002 * we know if future derive calls will fail, and we can skip
3003 * error checking in benchmarked code
3005 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3006 if (ffdh_ctx == NULL) {
3007 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3008 ERR_print_errors(bio_err);
3013 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3014 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3015 ERR_print_errors(bio_err);
3020 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3021 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3022 ERR_print_errors(bio_err);
3027 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3028 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3029 ERR_print_errors(bio_err);
3034 if (secret_size > MAX_FFDH_SIZE) {
3035 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3040 if (EVP_PKEY_derive(ffdh_ctx,
3041 loopargs[i].secret_ff_a,
3042 &secret_size) <= 0) {
3043 BIO_printf(bio_err, "Shared secret derive failure.\n");
3044 ERR_print_errors(bio_err);
3049 /* Now check from side B */
3050 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3052 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3053 ERR_print_errors(bio_err);
3058 if (!EVP_PKEY_derive_init(test_ctx) ||
3059 !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) ||
3060 !EVP_PKEY_derive(test_ctx, NULL, &test_out) ||
3061 !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) ||
3062 test_out != secret_size) {
3063 BIO_printf(bio_err, "FFDH computation failure.\n");
3069 /* compare the computed secrets */
3070 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3071 loopargs[i].secret_ff_b, secret_size)) {
3072 BIO_printf(bio_err, "FFDH computations don't match.\n");
3073 ERR_print_errors(bio_err);
3079 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3081 EVP_PKEY_free(pkey_A);
3083 EVP_PKEY_free(pkey_B);
3085 EVP_PKEY_CTX_free(test_ctx);
3088 if (ffdh_checks != 0) {
3089 pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3090 ffdh_params[testnum].bits, seconds.ffdh);
3093 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3096 mr ? "+R12:%ld:%d:%.2f\n" :
3097 "%ld %u-bits FFDH ops in %.2fs\n", count,
3098 ffdh_params[testnum].bits, d);
3099 ffdh_results[testnum][0] = (double)count / d;
3102 if (op_count <= 1) {
3103 /* if longer than 10s, don't do any more */
3104 stop_it(ffdh_doit, testnum);
3107 #endif /* OPENSSL_NO_DH */
3112 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3113 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3114 printf("options: %s\n", BN_options());
3115 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3116 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3123 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3126 for (testnum = 0; testnum < size_num; testnum++)
3127 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3131 for (k = 0; k < ALGOR_NUM; k++) {
3135 printf("+F:%u:%s", k, names[k]);
3137 printf("%-13s", names[k]);
3138 for (testnum = 0; testnum < size_num; testnum++) {
3139 if (results[k][testnum] > 10000 && !mr)
3140 printf(" %11.2fk", results[k][testnum] / 1e3);
3142 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3147 for (k = 0; k < RSA_NUM; k++) {
3150 if (testnum && !mr) {
3151 printf("%18ssign verify sign/s verify/s\n", " ");
3155 printf("+F2:%u:%u:%f:%f\n",
3156 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3158 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3159 rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3160 rsa_results[k][0], rsa_results[k][1]);
3163 for (k = 0; k < DSA_NUM; k++) {
3166 if (testnum && !mr) {
3167 printf("%18ssign verify sign/s verify/s\n", " ");
3171 printf("+F3:%u:%u:%f:%f\n",
3172 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3174 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3175 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3176 dsa_results[k][0], dsa_results[k][1]);
3179 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3182 if (testnum && !mr) {
3183 printf("%30ssign verify sign/s verify/s\n", " ");
3188 printf("+F4:%u:%u:%f:%f\n",
3189 k, ec_curves[k].bits,
3190 ecdsa_results[k][0], ecdsa_results[k][1]);
3192 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3193 ec_curves[k].bits, ec_curves[k].name,
3194 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3195 ecdsa_results[k][0], ecdsa_results[k][1]);
3199 for (k = 0; k < EC_NUM; k++) {
3202 if (testnum && !mr) {
3203 printf("%30sop op/s\n", " ");
3207 printf("+F5:%u:%u:%f:%f\n",
3208 k, ec_curves[k].bits,
3209 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3212 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3213 ec_curves[k].bits, ec_curves[k].name,
3214 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3218 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3221 if (testnum && !mr) {
3222 printf("%30ssign verify sign/s verify/s\n", " ");
3227 printf("+F6:%u:%u:%s:%f:%f\n",
3228 k, ed_curves[k].bits, ed_curves[k].name,
3229 eddsa_results[k][0], eddsa_results[k][1]);
3231 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3232 ed_curves[k].bits, ed_curves[k].name,
3233 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3234 eddsa_results[k][0], eddsa_results[k][1]);
3237 #ifndef OPENSSL_NO_SM2
3239 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3242 if (testnum && !mr) {
3243 printf("%30ssign verify sign/s verify/s\n", " ");
3248 printf("+F7:%u:%u:%s:%f:%f\n",
3249 k, sm2_curves[k].bits, sm2_curves[k].name,
3250 sm2_results[k][0], sm2_results[k][1]);
3252 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3253 sm2_curves[k].bits, sm2_curves[k].name,
3254 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3255 sm2_results[k][0], sm2_results[k][1]);
3258 #ifndef OPENSSL_NO_DH
3260 for (k = 0; k < FFDH_NUM; k++) {
3263 if (testnum && !mr) {
3264 printf("%23sop op/s\n", " ");
3268 printf("+F8:%u:%u:%f:%f\n",
3269 k, ffdh_params[k].bits,
3270 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3273 printf("%4u bits ffdh %8.4fs %8.1f\n",
3274 ffdh_params[k].bits,
3275 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3277 #endif /* OPENSSL_NO_DH */
3282 ERR_print_errors(bio_err);
3283 for (i = 0; i < loopargs_len; i++) {
3284 OPENSSL_free(loopargs[i].buf_malloc);
3285 OPENSSL_free(loopargs[i].buf2_malloc);
3288 EVP_PKEY_CTX_free(genctx);
3289 for (k = 0; k < RSA_NUM; k++) {
3290 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3291 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3293 #ifndef OPENSSL_NO_DH
3294 OPENSSL_free(loopargs[i].secret_ff_a);
3295 OPENSSL_free(loopargs[i].secret_ff_b);
3296 for (k = 0; k < FFDH_NUM; k++)
3297 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3299 for (k = 0; k < DSA_NUM; k++) {
3300 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3301 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3303 for (k = 0; k < ECDSA_NUM; k++) {
3304 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3305 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3307 for (k = 0; k < EC_NUM; k++)
3308 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3309 for (k = 0; k < EdDSA_NUM; k++) {
3310 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3311 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3313 #ifndef OPENSSL_NO_SM2
3314 for (k = 0; k < SM2_NUM; k++) {
3315 EVP_PKEY_CTX *pctx = NULL;
3317 /* free signing ctx */
3318 if (loopargs[i].sm2_ctx[k] != NULL
3319 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3320 EVP_PKEY_CTX_free(pctx);
3321 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3322 /* free verification ctx */
3323 if (loopargs[i].sm2_vfy_ctx[k] != NULL
3324 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3325 EVP_PKEY_CTX_free(pctx);
3326 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3328 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3331 OPENSSL_free(loopargs[i].secret_a);
3332 OPENSSL_free(loopargs[i].secret_b);
3334 OPENSSL_free(evp_hmac_name);
3335 OPENSSL_free(evp_cmac_name);
3337 if (async_jobs > 0) {
3338 for (i = 0; i < loopargs_len; i++)
3339 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3343 ASYNC_cleanup_thread();
3345 OPENSSL_free(loopargs);
3347 EVP_CIPHER_free(evp_cipher);
3352 static void print_message(const char *s, long num, int length, int tm)
3355 mr ? "+DT:%s:%d:%d\n"
3356 : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3357 (void)BIO_flush(bio_err);
3362 static void pkey_print_message(const char *str, const char *str2, long num,
3363 unsigned int bits, int tm)
3366 mr ? "+DTP:%d:%s:%s:%d\n"
3367 : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3368 (void)BIO_flush(bio_err);
3373 static void print_result(int alg, int run_no, int count, double time_used)
3376 BIO_printf(bio_err, "%s error!\n", names[alg]);
3377 ERR_print_errors(bio_err);
3381 mr ? "+R:%d:%s:%f\n"
3382 : "%d %s's in %.2fs\n", count, names[alg], time_used);
3383 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3387 static char *sstrsep(char **string, const char *delim)
3390 char *token = *string;
3395 memset(isdelim, 0, sizeof(isdelim));
3399 isdelim[(unsigned char)(*delim)] = 1;
3403 while (!isdelim[(unsigned char)(**string)])
3414 static int do_multi(int multi, int size_num)
3419 static char sep[] = ":";
3421 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3422 for (n = 0; n < multi; ++n) {
3423 if (pipe(fd) == -1) {
3424 BIO_printf(bio_err, "pipe failure\n");
3428 (void)BIO_flush(bio_err);
3435 if (dup(fd[1]) == -1) {
3436 BIO_printf(bio_err, "dup failed\n");
3445 printf("Forked child %d\n", n);
3448 /* for now, assume the pipe is long enough to take all the output */
3449 for (n = 0; n < multi; ++n) {
3454 f = fdopen(fds[n], "r");
3455 while (fgets(buf, sizeof(buf), f)) {
3456 p = strchr(buf, '\n');
3459 if (buf[0] != '+') {
3461 "Don't understand line '%s' from child %d\n", buf,
3465 printf("Got: %s from %d\n", buf, n);
3466 if (strncmp(buf, "+F:", 3) == 0) {
3471 alg = atoi(sstrsep(&p, sep));
3473 for (j = 0; j < size_num; ++j)
3474 results[alg][j] += atof(sstrsep(&p, sep));
3475 } else if (strncmp(buf, "+F2:", 4) == 0) {
3480 k = atoi(sstrsep(&p, sep));
3483 d = atof(sstrsep(&p, sep));
3484 rsa_results[k][0] += d;
3486 d = atof(sstrsep(&p, sep));
3487 rsa_results[k][1] += d;
3488 } else if (strncmp(buf, "+F3:", 4) == 0) {
3493 k = atoi(sstrsep(&p, sep));
3496 d = atof(sstrsep(&p, sep));
3497 dsa_results[k][0] += d;
3499 d = atof(sstrsep(&p, sep));
3500 dsa_results[k][1] += d;
3501 } else if (strncmp(buf, "+F4:", 4) == 0) {
3506 k = atoi(sstrsep(&p, sep));
3509 d = atof(sstrsep(&p, sep));
3510 ecdsa_results[k][0] += d;
3512 d = atof(sstrsep(&p, sep));
3513 ecdsa_results[k][1] += d;
3514 } else if (strncmp(buf, "+F5:", 4) == 0) {
3519 k = atoi(sstrsep(&p, sep));
3522 d = atof(sstrsep(&p, sep));
3523 ecdh_results[k][0] += d;
3524 } else if (strncmp(buf, "+F6:", 4) == 0) {
3529 k = atoi(sstrsep(&p, sep));
3533 d = atof(sstrsep(&p, sep));
3534 eddsa_results[k][0] += d;
3536 d = atof(sstrsep(&p, sep));
3537 eddsa_results[k][1] += d;
3538 # ifndef OPENSSL_NO_SM2
3539 } else if (strncmp(buf, "+F7:", 4) == 0) {
3544 k = atoi(sstrsep(&p, sep));
3548 d = atof(sstrsep(&p, sep));
3549 sm2_results[k][0] += d;
3551 d = atof(sstrsep(&p, sep));
3552 sm2_results[k][1] += d;
3553 # endif /* OPENSSL_NO_SM2 */
3554 # ifndef OPENSSL_NO_DH
3555 } else if (strncmp(buf, "+F8:", 4) == 0) {
3560 k = atoi(sstrsep(&p, sep));
3563 d = atof(sstrsep(&p, sep));
3564 ffdh_results[k][0] += d;
3565 # endif /* OPENSSL_NO_DH */
3566 } else if (strncmp(buf, "+H:", 3) == 0) {
3569 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3581 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3582 const openssl_speed_sec_t *seconds)
3584 static const int mblengths_list[] =
3585 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3586 const int *mblengths = mblengths_list;
3587 int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3588 const char *alg_name;
3589 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3590 EVP_CIPHER_CTX *ctx = NULL;
3593 if (lengths_single) {
3594 mblengths = &lengths_single;
3598 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3599 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3600 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3601 app_bail_out("failed to allocate cipher context\n");
3602 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3603 app_bail_out("failed to initialise cipher context\n");
3605 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3606 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3609 key = app_malloc(keylen, "evp_cipher key");
3610 if (!EVP_CIPHER_CTX_rand_key(ctx, key))
3611 app_bail_out("failed to generate random cipher key\n");
3612 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3613 app_bail_out("failed to set cipher key\n");
3614 OPENSSL_clear_free(key, keylen);
3616 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3617 sizeof(no_key), no_key))
3618 app_bail_out("failed to set AEAD key\n");
3619 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3620 app_bail_out("failed to get cipher name\n");
3622 for (j = 0; j < num; j++) {
3623 print_message(alg_name, 0, mblengths[j], seconds->sym);
3625 for (count = 0; run && count < INT_MAX; count++) {
3626 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3627 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3628 size_t len = mblengths[j];
3631 memset(aad, 0, 8); /* avoid uninitialized values */
3632 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3633 aad[9] = 3; /* version */
3635 aad[11] = 0; /* length */
3637 mb_param.out = NULL;
3640 mb_param.interleave = 8;
3642 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3643 sizeof(mb_param), &mb_param);
3649 (void)EVP_CIPHER_CTX_ctrl(ctx,
3650 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3651 sizeof(mb_param), &mb_param);
3655 RAND_bytes(out, 16);
3657 aad[11] = (unsigned char)(len >> 8);
3658 aad[12] = (unsigned char)(len);
3659 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3660 EVP_AEAD_TLS1_AAD_LEN, aad);
3661 EVP_Cipher(ctx, out, inp, len + pad);
3665 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3666 : "%d %s's in %.2fs\n", count, "evp", d);
3667 results[D_EVP][j] = ((double)count) / d * mblengths[j];
3671 fprintf(stdout, "+H");
3672 for (j = 0; j < num; j++)
3673 fprintf(stdout, ":%d", mblengths[j]);
3674 fprintf(stdout, "\n");
3675 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3676 for (j = 0; j < num; j++)
3677 fprintf(stdout, ":%.2f", results[D_EVP][j]);
3678 fprintf(stdout, "\n");
3681 "The 'numbers' are in 1000s of bytes per second processed.\n");
3682 fprintf(stdout, "type ");
3683 for (j = 0; j < num; j++)
3684 fprintf(stdout, "%7d bytes", mblengths[j]);
3685 fprintf(stdout, "\n");
3686 fprintf(stdout, "%-24s", alg_name);
3688 for (j = 0; j < num; j++) {
3689 if (results[D_EVP][j] > 10000)
3690 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3692 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3694 fprintf(stdout, "\n");
3700 EVP_CIPHER_CTX_free(ctx);