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) <= 0) {
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;
880 for (count = 0; COND(ffdh_c[testnum][0]); count++) {
881 /* outlen can be overwritten with a too small value (no padding used) */
882 size_t outlen = MAX_FFDH_SIZE;
884 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
888 #endif /* OPENSSL_NO_DH */
890 static long dsa_c[DSA_NUM][2];
891 static int DSA_sign_loop(void *args)
893 loopargs_t *tempargs = *(loopargs_t **) args;
894 unsigned char *buf = tempargs->buf;
895 unsigned char *buf2 = tempargs->buf2;
896 size_t *dsa_num = &tempargs->sigsize;
897 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
900 for (count = 0; COND(dsa_c[testnum][0]); count++) {
901 *dsa_num = tempargs->buflen;
902 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
904 BIO_printf(bio_err, "DSA sign failure\n");
905 ERR_print_errors(bio_err);
913 static int DSA_verify_loop(void *args)
915 loopargs_t *tempargs = *(loopargs_t **) args;
916 unsigned char *buf = tempargs->buf;
917 unsigned char *buf2 = tempargs->buf2;
918 size_t dsa_num = tempargs->sigsize;
919 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
922 for (count = 0; COND(dsa_c[testnum][1]); count++) {
923 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
925 BIO_printf(bio_err, "DSA verify failure\n");
926 ERR_print_errors(bio_err);
934 static long ecdsa_c[ECDSA_NUM][2];
935 static int ECDSA_sign_loop(void *args)
937 loopargs_t *tempargs = *(loopargs_t **) args;
938 unsigned char *buf = tempargs->buf;
939 unsigned char *buf2 = tempargs->buf2;
940 size_t *ecdsa_num = &tempargs->sigsize;
941 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
944 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
945 *ecdsa_num = tempargs->buflen;
946 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
948 BIO_printf(bio_err, "ECDSA sign failure\n");
949 ERR_print_errors(bio_err);
957 static int ECDSA_verify_loop(void *args)
959 loopargs_t *tempargs = *(loopargs_t **) args;
960 unsigned char *buf = tempargs->buf;
961 unsigned char *buf2 = tempargs->buf2;
962 size_t ecdsa_num = tempargs->sigsize;
963 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
966 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
967 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
970 BIO_printf(bio_err, "ECDSA verify failure\n");
971 ERR_print_errors(bio_err);
979 /* ******************************************************************** */
980 static long ecdh_c[EC_NUM][1];
982 static int ECDH_EVP_derive_key_loop(void *args)
984 loopargs_t *tempargs = *(loopargs_t **) args;
985 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
986 unsigned char *derived_secret = tempargs->secret_a;
988 size_t *outlen = &(tempargs->outlen[testnum]);
990 for (count = 0; COND(ecdh_c[testnum][0]); count++)
991 EVP_PKEY_derive(ctx, derived_secret, outlen);
996 static long eddsa_c[EdDSA_NUM][2];
997 static int EdDSA_sign_loop(void *args)
999 loopargs_t *tempargs = *(loopargs_t **) args;
1000 unsigned char *buf = tempargs->buf;
1001 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1002 unsigned char *eddsasig = tempargs->buf2;
1003 size_t *eddsasigsize = &tempargs->sigsize;
1006 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1007 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1009 BIO_printf(bio_err, "EdDSA sign failure\n");
1010 ERR_print_errors(bio_err);
1018 static int EdDSA_verify_loop(void *args)
1020 loopargs_t *tempargs = *(loopargs_t **) args;
1021 unsigned char *buf = tempargs->buf;
1022 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1023 unsigned char *eddsasig = tempargs->buf2;
1024 size_t eddsasigsize = tempargs->sigsize;
1027 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1028 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1030 BIO_printf(bio_err, "EdDSA verify failure\n");
1031 ERR_print_errors(bio_err);
1039 #ifndef OPENSSL_NO_SM2
1040 static long sm2_c[SM2_NUM][2];
1041 static int SM2_sign_loop(void *args)
1043 loopargs_t *tempargs = *(loopargs_t **) args;
1044 unsigned char *buf = tempargs->buf;
1045 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1046 unsigned char *sm2sig = tempargs->buf2;
1049 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1050 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1052 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1053 sm2sigsize = max_size;
1055 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1056 NULL, sm2_pkey[testnum])) {
1057 BIO_printf(bio_err, "SM2 init sign failure\n");
1058 ERR_print_errors(bio_err);
1062 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1065 BIO_printf(bio_err, "SM2 sign failure\n");
1066 ERR_print_errors(bio_err);
1070 /* update the latest returned size and always use the fixed buffer size */
1071 tempargs->sigsize = sm2sigsize;
1077 static int SM2_verify_loop(void *args)
1079 loopargs_t *tempargs = *(loopargs_t **) args;
1080 unsigned char *buf = tempargs->buf;
1081 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1082 unsigned char *sm2sig = tempargs->buf2;
1083 size_t sm2sigsize = tempargs->sigsize;
1085 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1087 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1088 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1089 NULL, sm2_pkey[testnum])) {
1090 BIO_printf(bio_err, "SM2 verify init failure\n");
1091 ERR_print_errors(bio_err);
1095 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1098 BIO_printf(bio_err, "SM2 verify failure\n");
1099 ERR_print_errors(bio_err);
1106 #endif /* OPENSSL_NO_SM2 */
1108 static int run_benchmark(int async_jobs,
1109 int (*loop_function) (void *), loopargs_t * loopargs)
1111 int job_op_count = 0;
1112 int total_op_count = 0;
1113 int num_inprogress = 0;
1114 int error = 0, i = 0, ret = 0;
1115 OSSL_ASYNC_FD job_fd = 0;
1116 size_t num_job_fds = 0;
1118 if (async_jobs == 0) {
1119 return loop_function((void *)&loopargs);
1122 for (i = 0; i < async_jobs && !error; i++) {
1123 loopargs_t *looparg_item = loopargs + i;
1125 /* Copy pointer content (looparg_t item address) into async context */
1126 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1127 &job_op_count, loop_function,
1128 (void *)&looparg_item, sizeof(looparg_item));
1134 if (job_op_count == -1) {
1137 total_op_count += job_op_count;
1142 BIO_printf(bio_err, "Failure in the job\n");
1143 ERR_print_errors(bio_err);
1149 while (num_inprogress > 0) {
1150 #if defined(OPENSSL_SYS_WINDOWS)
1152 #elif defined(OPENSSL_SYS_UNIX)
1153 int select_result = 0;
1154 OSSL_ASYNC_FD max_fd = 0;
1157 FD_ZERO(&waitfdset);
1159 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1160 if (loopargs[i].inprogress_job == NULL)
1163 if (!ASYNC_WAIT_CTX_get_all_fds
1164 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1165 || num_job_fds > 1) {
1166 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1167 ERR_print_errors(bio_err);
1171 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1173 FD_SET(job_fd, &waitfdset);
1174 if (job_fd > max_fd)
1178 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1180 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1181 "Decrease the value of async_jobs\n",
1182 max_fd, FD_SETSIZE);
1183 ERR_print_errors(bio_err);
1188 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1189 if (select_result == -1 && errno == EINTR)
1192 if (select_result == -1) {
1193 BIO_printf(bio_err, "Failure in the select\n");
1194 ERR_print_errors(bio_err);
1199 if (select_result == 0)
1203 for (i = 0; i < async_jobs; i++) {
1204 if (loopargs[i].inprogress_job == NULL)
1207 if (!ASYNC_WAIT_CTX_get_all_fds
1208 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1209 || num_job_fds > 1) {
1210 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1211 ERR_print_errors(bio_err);
1215 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1218 #if defined(OPENSSL_SYS_UNIX)
1219 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1221 #elif defined(OPENSSL_SYS_WINDOWS)
1222 if (num_job_fds == 1
1223 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1228 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1229 loopargs[i].wait_ctx, &job_op_count,
1230 loop_function, (void *)(loopargs + i),
1231 sizeof(loopargs_t));
1236 if (job_op_count == -1) {
1239 total_op_count += job_op_count;
1242 loopargs[i].inprogress_job = NULL;
1247 loopargs[i].inprogress_job = NULL;
1248 BIO_printf(bio_err, "Failure in the job\n");
1249 ERR_print_errors(bio_err);
1256 return error ? -1 : total_op_count;
1259 typedef struct ec_curve_st {
1263 size_t sigsize; /* only used for EdDSA curves */
1266 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1268 EVP_PKEY_CTX *kctx = NULL;
1269 EVP_PKEY *key = NULL;
1271 /* Ensure that the error queue is empty */
1272 if (ERR_peek_error()) {
1274 "WARNING: the error queue contains previous unhandled errors.\n");
1275 ERR_print_errors(bio_err);
1279 * Let's try to create a ctx directly from the NID: this works for
1280 * curves like Curve25519 that are not implemented through the low
1281 * level EC interface.
1282 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1283 * then we set the curve by NID before deriving the actual keygen
1284 * ctx for that specific curve.
1286 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1288 EVP_PKEY_CTX *pctx = NULL;
1289 EVP_PKEY *params = NULL;
1291 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1292 * "int_ctx_new:unsupported algorithm" error was added to the
1294 * We remove it from the error queue as we are handling it.
1296 unsigned long error = ERR_peek_error();
1298 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1299 /* check that the error origin matches */
1300 && ERR_GET_LIB(error) == ERR_LIB_EVP
1301 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1302 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1303 ERR_get_error(); /* pop error from queue */
1304 if (ERR_peek_error()) {
1306 "Unhandled error in the error queue during EC key setup.\n");
1307 ERR_print_errors(bio_err);
1311 /* Create the context for parameter generation */
1312 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1313 || EVP_PKEY_paramgen_init(pctx) <= 0
1314 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1316 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) {
1317 BIO_printf(bio_err, "EC params init failure.\n");
1318 ERR_print_errors(bio_err);
1319 EVP_PKEY_CTX_free(pctx);
1322 EVP_PKEY_CTX_free(pctx);
1324 /* Create the context for the key generation */
1325 kctx = EVP_PKEY_CTX_new(params, NULL);
1326 EVP_PKEY_free(params);
1329 || EVP_PKEY_keygen_init(kctx) <= 0
1330 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1331 BIO_printf(bio_err, "EC key generation failure.\n");
1332 ERR_print_errors(bio_err);
1335 EVP_PKEY_CTX_free(kctx);
1339 #define stop_it(do_it, test_num)\
1340 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1342 int speed_main(int argc, char **argv)
1345 loopargs_t *loopargs = NULL;
1347 const char *engine_id = NULL;
1348 EVP_CIPHER *evp_cipher = NULL;
1349 EVP_MAC *mac = NULL;
1352 int async_init = 0, multiblock = 0, pr_header = 0;
1353 uint8_t doit[ALGOR_NUM] = { 0 };
1354 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1356 unsigned int size_num = SIZE_NUM;
1357 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1361 EVP_PKEY_CTX *genctx = NULL;
1366 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1367 ECDSA_SECONDS, ECDH_SECONDS,
1368 EdDSA_SECONDS, SM2_SECONDS,
1371 static const unsigned char key32[32] = {
1372 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1373 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1374 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1375 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1377 static const unsigned char deskey[] = {
1378 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1379 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1380 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1382 static const struct {
1383 const unsigned char *data;
1384 unsigned int length;
1387 { test512, sizeof(test512), 512 },
1388 { test1024, sizeof(test1024), 1024 },
1389 { test2048, sizeof(test2048), 2048 },
1390 { test3072, sizeof(test3072), 3072 },
1391 { test4096, sizeof(test4096), 4096 },
1392 { test7680, sizeof(test7680), 7680 },
1393 { test15360, sizeof(test15360), 15360 }
1395 uint8_t rsa_doit[RSA_NUM] = { 0 };
1396 int primes = RSA_DEFAULT_PRIME_NUM;
1397 #ifndef OPENSSL_NO_DH
1398 typedef struct ffdh_params_st {
1404 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1405 {"ffdh2048", NID_ffdhe2048, 2048},
1406 {"ffdh3072", NID_ffdhe3072, 3072},
1407 {"ffdh4096", NID_ffdhe4096, 4096},
1408 {"ffdh6144", NID_ffdhe6144, 6144},
1409 {"ffdh8192", NID_ffdhe8192, 8192}
1411 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1413 #endif /* OPENSSL_NO_DH */
1414 static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1415 uint8_t dsa_doit[DSA_NUM] = { 0 };
1417 * We only test over the following curves as they are representative, To
1418 * add tests over more curves, simply add the curve NID and curve name to
1419 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1420 * lists accordingly.
1422 static const EC_CURVE ec_curves[EC_NUM] = {
1424 {"secp160r1", NID_secp160r1, 160},
1425 {"nistp192", NID_X9_62_prime192v1, 192},
1426 {"nistp224", NID_secp224r1, 224},
1427 {"nistp256", NID_X9_62_prime256v1, 256},
1428 {"nistp384", NID_secp384r1, 384},
1429 {"nistp521", NID_secp521r1, 521},
1430 #ifndef OPENSSL_NO_EC2M
1432 {"nistk163", NID_sect163k1, 163},
1433 {"nistk233", NID_sect233k1, 233},
1434 {"nistk283", NID_sect283k1, 283},
1435 {"nistk409", NID_sect409k1, 409},
1436 {"nistk571", NID_sect571k1, 571},
1437 {"nistb163", NID_sect163r2, 163},
1438 {"nistb233", NID_sect233r1, 233},
1439 {"nistb283", NID_sect283r1, 283},
1440 {"nistb409", NID_sect409r1, 409},
1441 {"nistb571", NID_sect571r1, 571},
1443 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1444 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1445 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1446 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1447 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1448 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1449 /* Other and ECDH only ones */
1450 {"X25519", NID_X25519, 253},
1451 {"X448", NID_X448, 448}
1453 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1455 {"Ed25519", NID_ED25519, 253, 64},
1456 {"Ed448", NID_ED448, 456, 114}
1458 #ifndef OPENSSL_NO_SM2
1459 static const EC_CURVE sm2_curves[SM2_NUM] = {
1461 {"CurveSM2", NID_sm2, 256}
1463 uint8_t sm2_doit[SM2_NUM] = { 0 };
1465 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1466 uint8_t ecdh_doit[EC_NUM] = { 0 };
1467 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1469 /* checks declarated curves against choices list. */
1470 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1471 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1473 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1474 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1476 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1477 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1479 #ifndef OPENSSL_NO_SM2
1480 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1481 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1484 prog = opt_init(argc, argv, speed_options);
1485 while ((o = opt_next()) != OPT_EOF) {
1490 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1493 opt_help(speed_options);
1501 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1505 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1506 if (have_md(opt_arg()))
1507 evp_md_name = opt_arg();
1509 if (evp_cipher == NULL && evp_md_name == NULL) {
1510 ERR_clear_last_mark();
1512 "%s: %s is an unknown cipher or digest\n",
1520 if (!have_md(opt_arg())) {
1521 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1525 evp_mac_mdname = opt_arg();
1529 if (!have_cipher(opt_arg())) {
1530 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1534 evp_mac_ciphername = opt_arg();
1535 doit[D_EVP_CMAC] = 1;
1542 * In a forked execution, an engine might need to be
1543 * initialised by each child process, not by the parent.
1544 * So store the name here and run setup_engine() later on.
1546 engine_id = opt_arg();
1550 multi = atoi(opt_arg());
1551 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1552 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1558 #ifndef OPENSSL_NO_ASYNC
1559 async_jobs = atoi(opt_arg());
1560 if (!ASYNC_is_capable()) {
1562 "%s: async_jobs specified but async not supported\n",
1566 if (async_jobs > 99999) {
1567 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1573 misalign = opt_int_arg();
1574 if (misalign > MISALIGN) {
1576 "%s: Maximum offset is %d\n", prog, MISALIGN);
1585 #ifdef OPENSSL_NO_MULTIBLOCK
1587 "%s: -mb specified but multi-block support is disabled\n",
1596 case OPT_PROV_CASES:
1597 if (!opt_provider(o))
1601 primes = opt_int_arg();
1604 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1605 = seconds.ecdh = seconds.eddsa
1606 = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1609 lengths_single = atoi(opt_arg());
1610 lengths = &lengths_single;
1619 /* Remaining arguments are algorithms. */
1620 argc = opt_num_rest();
1623 if (!app_RAND_load())
1626 for (; *argv; argv++) {
1627 const char *algo = *argv;
1629 if (opt_found(algo, doit_choices, &i)) {
1633 if (strcmp(algo, "des") == 0) {
1634 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1637 if (strcmp(algo, "sha") == 0) {
1638 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1641 #ifndef OPENSSL_NO_DEPRECATED_3_0
1642 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1645 if (strncmp(algo, "rsa", 3) == 0) {
1646 if (algo[3] == '\0') {
1647 memset(rsa_doit, 1, sizeof(rsa_doit));
1650 if (opt_found(algo, rsa_choices, &i)) {
1655 #ifndef OPENSSL_NO_DH
1656 if (strncmp(algo, "ffdh", 4) == 0) {
1657 if (algo[4] == '\0') {
1658 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1661 if (opt_found(algo, ffdh_choices, &i)) {
1667 if (strncmp(algo, "dsa", 3) == 0) {
1668 if (algo[3] == '\0') {
1669 memset(dsa_doit, 1, sizeof(dsa_doit));
1672 if (opt_found(algo, dsa_choices, &i)) {
1677 if (strcmp(algo, "aes") == 0) {
1678 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1681 if (strcmp(algo, "camellia") == 0) {
1682 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1685 if (strncmp(algo, "ecdsa", 5) == 0) {
1686 if (algo[5] == '\0') {
1687 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1690 if (opt_found(algo, ecdsa_choices, &i)) {
1695 if (strncmp(algo, "ecdh", 4) == 0) {
1696 if (algo[4] == '\0') {
1697 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1700 if (opt_found(algo, ecdh_choices, &i)) {
1705 if (strcmp(algo, "eddsa") == 0) {
1706 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1709 if (opt_found(algo, eddsa_choices, &i)) {
1713 #ifndef OPENSSL_NO_SM2
1714 if (strcmp(algo, "sm2") == 0) {
1715 memset(sm2_doit, 1, sizeof(sm2_doit));
1718 if (opt_found(algo, sm2_choices, &i)) {
1723 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1729 if (evp_cipher == NULL) {
1730 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1732 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1733 EVP_CIPH_FLAG_AEAD_CIPHER)) {
1734 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1735 EVP_CIPHER_get0_name(evp_cipher));
1740 if (evp_cipher == NULL) {
1741 BIO_printf(bio_err, "-mb can be used only with a multi-block"
1742 " capable cipher\n");
1744 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1745 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1746 BIO_printf(bio_err, "%s is not a multi-block capable\n",
1747 EVP_CIPHER_get0_name(evp_cipher));
1749 } else if (async_jobs > 0) {
1750 BIO_printf(bio_err, "Async mode is not supported with -mb");
1755 /* Initialize the job pool if async mode is enabled */
1756 if (async_jobs > 0) {
1757 async_init = ASYNC_init_thread(async_jobs, async_jobs);
1759 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1764 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1766 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1767 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1769 for (i = 0; i < loopargs_len; i++) {
1770 if (async_jobs > 0) {
1771 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1772 if (loopargs[i].wait_ctx == NULL) {
1773 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1778 buflen = lengths[size_num - 1];
1779 if (buflen < 36) /* size of random vector in RSA benchmark */
1781 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1782 BIO_printf(bio_err, "Error: buffer size too large\n");
1785 buflen += MAX_MISALIGNMENT + 1;
1786 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1787 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1788 memset(loopargs[i].buf_malloc, 0, buflen);
1789 memset(loopargs[i].buf2_malloc, 0, buflen);
1791 /* Align the start of buffers on a 64 byte boundary */
1792 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1793 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1794 loopargs[i].buflen = buflen - misalign;
1795 loopargs[i].sigsize = buflen - misalign;
1796 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1797 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1798 #ifndef OPENSSL_NO_DH
1799 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1800 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1805 if (multi && do_multi(multi, size_num))
1809 /* Initialize the engine after the fork */
1810 e = setup_engine(engine_id, 0);
1812 /* No parameters; turn on everything. */
1813 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1814 memset(doit, 1, sizeof(doit));
1815 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1817 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1818 if (!have_md(names[i]))
1821 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1822 if (!have_cipher(names[i]))
1825 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1826 app_get0_propq())) != NULL) {
1832 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1833 app_get0_propq())) != NULL) {
1840 memset(rsa_doit, 1, sizeof(rsa_doit));
1841 #ifndef OPENSSL_NO_DH
1842 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1844 memset(dsa_doit, 1, sizeof(dsa_doit));
1845 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1846 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1847 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1848 #ifndef OPENSSL_NO_SM2
1849 memset(sm2_doit, 1, sizeof(sm2_doit));
1852 for (i = 0; i < ALGOR_NUM; i++)
1856 if (usertime == 0 && !mr)
1858 "You have chosen to measure elapsed time "
1859 "instead of user CPU time.\n");
1862 signal(SIGALRM, alarmed);
1866 for (testnum = 0; testnum < size_num; testnum++) {
1867 print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1870 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1872 print_result(D_MD2, testnum, count, d);
1879 for (testnum = 0; testnum < size_num; testnum++) {
1880 print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1883 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1885 print_result(D_MDC2, testnum, count, d);
1892 for (testnum = 0; testnum < size_num; testnum++) {
1893 print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1896 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1898 print_result(D_MD4, testnum, count, d);
1905 for (testnum = 0; testnum < size_num; testnum++) {
1906 print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1909 count = run_benchmark(async_jobs, MD5_loop, loopargs);
1911 print_result(D_MD5, testnum, count, d);
1918 for (testnum = 0; testnum < size_num; testnum++) {
1919 print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1922 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1924 print_result(D_SHA1, testnum, count, d);
1930 if (doit[D_SHA256]) {
1931 for (testnum = 0; testnum < size_num; testnum++) {
1932 print_message(names[D_SHA256], c[D_SHA256][testnum],
1933 lengths[testnum], seconds.sym);
1935 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1937 print_result(D_SHA256, testnum, count, d);
1943 if (doit[D_SHA512]) {
1944 for (testnum = 0; testnum < size_num; testnum++) {
1945 print_message(names[D_SHA512], c[D_SHA512][testnum],
1946 lengths[testnum], seconds.sym);
1948 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1950 print_result(D_SHA512, testnum, count, d);
1956 if (doit[D_WHIRLPOOL]) {
1957 for (testnum = 0; testnum < size_num; testnum++) {
1958 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
1959 lengths[testnum], seconds.sym);
1961 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
1963 print_result(D_WHIRLPOOL, testnum, count, d);
1969 if (doit[D_RMD160]) {
1970 for (testnum = 0; testnum < size_num; testnum++) {
1971 print_message(names[D_RMD160], c[D_RMD160][testnum],
1972 lengths[testnum], seconds.sym);
1974 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
1976 print_result(D_RMD160, testnum, count, d);
1983 static const char hmac_key[] = "This is a key...";
1984 int len = strlen(hmac_key);
1985 OSSL_PARAM params[3];
1987 mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1988 if (mac == NULL || evp_mac_mdname == NULL)
1991 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
1993 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
1994 names[D_HMAC] = evp_hmac_name;
1997 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2000 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2001 (char *)hmac_key, len);
2002 params[2] = OSSL_PARAM_construct_end();
2004 for (i = 0; i < loopargs_len; i++) {
2005 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2006 if (loopargs[i].mctx == NULL)
2009 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2012 for (testnum = 0; testnum < size_num; testnum++) {
2013 print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
2016 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2018 print_result(D_HMAC, testnum, count, d);
2022 for (i = 0; i < loopargs_len; i++)
2023 EVP_MAC_CTX_free(loopargs[i].mctx);
2028 if (doit[D_CBC_DES]) {
2031 for (i = 0; st && i < loopargs_len; i++) {
2032 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2033 sizeof(deskey) / 3);
2034 st = loopargs[i].ctx != NULL;
2036 algindex = D_CBC_DES;
2037 for (testnum = 0; st && testnum < size_num; testnum++) {
2038 print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2039 lengths[testnum], seconds.sym);
2041 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2043 print_result(D_CBC_DES, testnum, count, d);
2045 for (i = 0; i < loopargs_len; i++)
2046 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2049 if (doit[D_EDE3_DES]) {
2052 for (i = 0; st && i < loopargs_len; i++) {
2053 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2055 st = loopargs[i].ctx != NULL;
2057 algindex = D_EDE3_DES;
2058 for (testnum = 0; st && testnum < size_num; testnum++) {
2059 print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2060 lengths[testnum], seconds.sym);
2063 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2065 print_result(D_EDE3_DES, testnum, count, d);
2067 for (i = 0; i < loopargs_len; i++)
2068 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2071 for (k = 0; k < 3; k++) {
2072 algindex = D_CBC_128_AES + k;
2073 if (doit[algindex]) {
2076 keylen = 16 + k * 8;
2077 for (i = 0; st && i < loopargs_len; i++) {
2078 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2080 st = loopargs[i].ctx != NULL;
2083 for (testnum = 0; st && testnum < size_num; testnum++) {
2084 print_message(names[algindex], c[algindex][testnum],
2085 lengths[testnum], seconds.sym);
2088 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2090 print_result(algindex, testnum, count, d);
2092 for (i = 0; i < loopargs_len; i++)
2093 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2097 for (k = 0; k < 3; k++) {
2098 algindex = D_CBC_128_CML + k;
2099 if (doit[algindex]) {
2102 keylen = 16 + k * 8;
2103 for (i = 0; st && i < loopargs_len; i++) {
2104 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2106 st = loopargs[i].ctx != NULL;
2109 for (testnum = 0; st && testnum < size_num; testnum++) {
2110 print_message(names[algindex], c[algindex][testnum],
2111 lengths[testnum], seconds.sym);
2114 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2116 print_result(algindex, testnum, count, d);
2118 for (i = 0; i < loopargs_len; i++)
2119 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2123 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2124 if (doit[algindex]) {
2128 for (i = 0; st && i < loopargs_len; i++) {
2129 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2131 st = loopargs[i].ctx != NULL;
2134 for (testnum = 0; st && testnum < size_num; testnum++) {
2135 print_message(names[algindex], c[algindex][testnum],
2136 lengths[testnum], seconds.sym);
2139 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2141 print_result(algindex, testnum, count, d);
2143 for (i = 0; i < loopargs_len; i++)
2144 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2147 if (doit[D_GHASH]) {
2148 static const char gmac_iv[] = "0123456789ab";
2149 OSSL_PARAM params[3];
2151 mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2155 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2157 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2159 sizeof(gmac_iv) - 1);
2160 params[2] = OSSL_PARAM_construct_end();
2162 for (i = 0; i < loopargs_len; i++) {
2163 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2164 if (loopargs[i].mctx == NULL)
2167 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2170 for (testnum = 0; testnum < size_num; testnum++) {
2171 print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2174 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2176 print_result(D_GHASH, testnum, count, d);
2180 for (i = 0; i < loopargs_len; i++)
2181 EVP_MAC_CTX_free(loopargs[i].mctx);
2187 for (testnum = 0; testnum < size_num; testnum++) {
2188 print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2191 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2193 print_result(D_RAND, testnum, count, d);
2198 if (evp_cipher != NULL) {
2199 int (*loopfunc) (void *) = EVP_Update_loop;
2201 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2202 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2203 multiblock_speed(evp_cipher, lengths_single, &seconds);
2208 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2210 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2211 loopfunc = EVP_Update_loop_ccm;
2212 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2213 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2214 loopfunc = EVP_Update_loop_aead;
2215 if (lengths == lengths_list) {
2216 lengths = aead_lengths_list;
2217 size_num = OSSL_NELEM(aead_lengths_list);
2221 for (testnum = 0; testnum < size_num; testnum++) {
2222 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2225 for (k = 0; k < loopargs_len; k++) {
2226 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2227 if (loopargs[k].ctx == NULL) {
2228 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2231 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2232 NULL, iv, decrypt ? 0 : 1)) {
2233 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2234 ERR_print_errors(bio_err);
2238 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2240 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2241 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2242 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2243 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2244 loopargs[k].key, NULL, -1)) {
2245 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2246 ERR_print_errors(bio_err);
2249 OPENSSL_clear_free(loopargs[k].key, keylen);
2251 /* SIV mode only allows for a single Update operation */
2252 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2253 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2254 EVP_CTRL_SET_SPEED, 1, NULL);
2258 count = run_benchmark(async_jobs, loopfunc, loopargs);
2260 for (k = 0; k < loopargs_len; k++)
2261 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2262 print_result(D_EVP, testnum, count, d);
2264 } else if (evp_md_name != NULL) {
2265 names[D_EVP] = evp_md_name;
2267 for (testnum = 0; testnum < size_num; testnum++) {
2268 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2271 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2273 print_result(D_EVP, testnum, count, d);
2280 if (doit[D_EVP_CMAC]) {
2281 OSSL_PARAM params[3];
2282 EVP_CIPHER *cipher = NULL;
2284 mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2285 if (mac == NULL || evp_mac_ciphername == NULL)
2287 if (!opt_cipher(evp_mac_ciphername, &cipher))
2290 keylen = EVP_CIPHER_get_key_length(cipher);
2291 EVP_CIPHER_free(cipher);
2292 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2293 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2296 evp_cmac_name = app_malloc(sizeof("cmac()")
2297 + strlen(evp_mac_ciphername), "CMAC name");
2298 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2299 names[D_EVP_CMAC] = evp_cmac_name;
2301 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2302 evp_mac_ciphername, 0);
2303 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2304 (char *)key32, keylen);
2305 params[2] = OSSL_PARAM_construct_end();
2307 for (i = 0; i < loopargs_len; i++) {
2308 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2309 if (loopargs[i].mctx == NULL)
2312 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2316 for (testnum = 0; testnum < size_num; testnum++) {
2317 print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2318 lengths[testnum], seconds.sym);
2320 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2322 print_result(D_EVP_CMAC, testnum, count, d);
2326 for (i = 0; i < loopargs_len; i++)
2327 EVP_MAC_CTX_free(loopargs[i].mctx);
2332 for (i = 0; i < loopargs_len; i++)
2333 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2336 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2337 EVP_PKEY *rsa_key = NULL;
2340 if (!rsa_doit[testnum])
2343 if (primes > RSA_DEFAULT_PRIME_NUM) {
2344 /* we haven't set keys yet, generate multi-prime RSA keys */
2347 && BN_set_word(bn, RSA_F4)
2348 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2349 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2350 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2351 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2352 && EVP_PKEY_keygen(genctx, &rsa_key);
2355 EVP_PKEY_CTX_free(genctx);
2358 const unsigned char *p = rsa_keys[testnum].data;
2360 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2361 rsa_keys[testnum].length)) != NULL;
2364 for (i = 0; st && i < loopargs_len; i++) {
2365 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2366 loopargs[i].sigsize = loopargs[i].buflen;
2367 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2368 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2369 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2371 &loopargs[i].sigsize,
2372 loopargs[i].buf, 36) <= 0)
2377 "RSA sign setup failure. No RSA sign will be done.\n");
2378 ERR_print_errors(bio_err);
2381 pkey_print_message("private", "rsa",
2382 rsa_c[testnum][0], rsa_keys[testnum].bits,
2384 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2386 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2389 mr ? "+R1:%ld:%d:%.2f\n"
2390 : "%ld %u bits private RSA's in %.2fs\n",
2391 count, rsa_keys[testnum].bits, d);
2392 rsa_results[testnum][0] = (double)count / d;
2396 for (i = 0; st && i < loopargs_len; i++) {
2397 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2399 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2400 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2401 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2403 loopargs[i].sigsize,
2404 loopargs[i].buf, 36) <= 0)
2409 "RSA verify setup failure. No RSA verify will be done.\n");
2410 ERR_print_errors(bio_err);
2411 rsa_doit[testnum] = 0;
2413 pkey_print_message("public", "rsa",
2414 rsa_c[testnum][1], rsa_keys[testnum].bits,
2417 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2420 mr ? "+R2:%ld:%d:%.2f\n"
2421 : "%ld %u bits public RSA's in %.2fs\n",
2422 count, rsa_keys[testnum].bits, d);
2423 rsa_results[testnum][1] = (double)count / d;
2426 if (op_count <= 1) {
2427 /* if longer than 10s, don't do any more */
2428 stop_it(rsa_doit, testnum);
2430 EVP_PKEY_free(rsa_key);
2433 for (testnum = 0; testnum < DSA_NUM; testnum++) {
2434 EVP_PKEY *dsa_key = NULL;
2437 if (!dsa_doit[testnum])
2440 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2442 for (i = 0; st && i < loopargs_len; i++) {
2443 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2445 loopargs[i].sigsize = loopargs[i].buflen;
2446 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2447 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2449 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2451 &loopargs[i].sigsize,
2452 loopargs[i].buf, 20) <= 0)
2457 "DSA sign setup failure. No DSA sign will be done.\n");
2458 ERR_print_errors(bio_err);
2461 pkey_print_message("sign", "dsa",
2462 dsa_c[testnum][0], dsa_bits[testnum],
2465 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2468 mr ? "+R3:%ld:%u:%.2f\n"
2469 : "%ld %u bits DSA signs in %.2fs\n",
2470 count, dsa_bits[testnum], d);
2471 dsa_results[testnum][0] = (double)count / d;
2475 for (i = 0; st && i < loopargs_len; i++) {
2476 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2478 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2479 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2480 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2482 loopargs[i].sigsize,
2483 loopargs[i].buf, 36) <= 0)
2488 "DSA verify setup failure. No DSA verify will be done.\n");
2489 ERR_print_errors(bio_err);
2490 dsa_doit[testnum] = 0;
2492 pkey_print_message("verify", "dsa",
2493 dsa_c[testnum][1], dsa_bits[testnum],
2496 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2499 mr ? "+R4:%ld:%u:%.2f\n"
2500 : "%ld %u bits DSA verify in %.2fs\n",
2501 count, dsa_bits[testnum], d);
2502 dsa_results[testnum][1] = (double)count / d;
2505 if (op_count <= 1) {
2506 /* if longer than 10s, don't do any more */
2507 stop_it(dsa_doit, testnum);
2509 EVP_PKEY_free(dsa_key);
2512 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2513 EVP_PKEY *ecdsa_key = NULL;
2516 if (!ecdsa_doit[testnum])
2519 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2521 for (i = 0; st && i < loopargs_len; i++) {
2522 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2524 loopargs[i].sigsize = loopargs[i].buflen;
2525 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2526 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2528 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2530 &loopargs[i].sigsize,
2531 loopargs[i].buf, 20) <= 0)
2536 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2537 ERR_print_errors(bio_err);
2540 pkey_print_message("sign", "ecdsa",
2541 ecdsa_c[testnum][0], ec_curves[testnum].bits,
2544 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2547 mr ? "+R5:%ld:%u:%.2f\n"
2548 : "%ld %u bits ECDSA signs in %.2fs\n",
2549 count, ec_curves[testnum].bits, d);
2550 ecdsa_results[testnum][0] = (double)count / d;
2554 for (i = 0; st && i < loopargs_len; i++) {
2555 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2557 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2558 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2559 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2561 loopargs[i].sigsize,
2562 loopargs[i].buf, 20) <= 0)
2567 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2568 ERR_print_errors(bio_err);
2569 ecdsa_doit[testnum] = 0;
2571 pkey_print_message("verify", "ecdsa",
2572 ecdsa_c[testnum][1], ec_curves[testnum].bits,
2575 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2578 mr ? "+R6:%ld:%u:%.2f\n"
2579 : "%ld %u bits ECDSA verify in %.2fs\n",
2580 count, ec_curves[testnum].bits, d);
2581 ecdsa_results[testnum][1] = (double)count / d;
2584 if (op_count <= 1) {
2585 /* if longer than 10s, don't do any more */
2586 stop_it(ecdsa_doit, testnum);
2590 for (testnum = 0; testnum < EC_NUM; testnum++) {
2591 int ecdh_checks = 1;
2593 if (!ecdh_doit[testnum])
2596 for (i = 0; i < loopargs_len; i++) {
2597 EVP_PKEY_CTX *test_ctx = NULL;
2598 EVP_PKEY_CTX *ctx = NULL;
2599 EVP_PKEY *key_A = NULL;
2600 EVP_PKEY *key_B = NULL;
2604 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2605 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2606 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2607 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2608 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2609 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2610 || outlen == 0 /* ensure outlen is a valid size */
2611 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2613 BIO_printf(bio_err, "ECDH key generation failure.\n");
2614 ERR_print_errors(bio_err);
2620 * Here we perform a test run, comparing the output of a*B and b*A;
2621 * we try this here and assume that further EVP_PKEY_derive calls
2622 * never fail, so we can skip checks in the actually benchmarked
2623 * code, for maximum performance.
2625 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2626 || !EVP_PKEY_derive_init(test_ctx) /* init derivation test_ctx */
2627 || !EVP_PKEY_derive_set_peer(test_ctx, key_A) /* set peer pubkey in test_ctx */
2628 || !EVP_PKEY_derive(test_ctx, NULL, &test_outlen) /* determine max length */
2629 || !EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) /* compute a*B */
2630 || !EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) /* compute b*A */
2631 || test_outlen != outlen /* compare output length */) {
2633 BIO_printf(bio_err, "ECDH computation failure.\n");
2634 ERR_print_errors(bio_err);
2639 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2640 if (CRYPTO_memcmp(loopargs[i].secret_a,
2641 loopargs[i].secret_b, outlen)) {
2643 BIO_printf(bio_err, "ECDH computations don't match.\n");
2644 ERR_print_errors(bio_err);
2649 loopargs[i].ecdh_ctx[testnum] = ctx;
2650 loopargs[i].outlen[testnum] = outlen;
2652 EVP_PKEY_free(key_A);
2653 EVP_PKEY_free(key_B);
2654 EVP_PKEY_CTX_free(test_ctx);
2657 if (ecdh_checks != 0) {
2658 pkey_print_message("", "ecdh",
2660 ec_curves[testnum].bits, seconds.ecdh);
2663 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2666 mr ? "+R7:%ld:%d:%.2f\n" :
2667 "%ld %u-bits ECDH ops in %.2fs\n", count,
2668 ec_curves[testnum].bits, d);
2669 ecdh_results[testnum][0] = (double)count / d;
2673 if (op_count <= 1) {
2674 /* if longer than 10s, don't do any more */
2675 stop_it(ecdh_doit, testnum);
2679 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2681 EVP_PKEY *ed_pkey = NULL;
2682 EVP_PKEY_CTX *ed_pctx = NULL;
2684 if (!eddsa_doit[testnum])
2685 continue; /* Ignore Curve */
2686 for (i = 0; i < loopargs_len; i++) {
2687 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2688 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2692 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2693 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2698 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2700 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2701 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2703 EVP_PKEY_CTX_free(ed_pctx);
2706 EVP_PKEY_CTX_free(ed_pctx);
2708 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2711 EVP_PKEY_free(ed_pkey);
2714 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2715 NULL, NULL, ed_pkey)) {
2717 EVP_PKEY_free(ed_pkey);
2721 EVP_PKEY_free(ed_pkey);
2725 BIO_printf(bio_err, "EdDSA failure.\n");
2726 ERR_print_errors(bio_err);
2729 for (i = 0; i < loopargs_len; i++) {
2730 /* Perform EdDSA signature test */
2731 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2732 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2733 loopargs[i].buf2, &loopargs[i].sigsize,
2734 loopargs[i].buf, 20);
2740 "EdDSA sign failure. No EdDSA sign will be done.\n");
2741 ERR_print_errors(bio_err);
2744 pkey_print_message("sign", ed_curves[testnum].name,
2745 eddsa_c[testnum][0],
2746 ed_curves[testnum].bits, seconds.eddsa);
2748 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2752 mr ? "+R8:%ld:%u:%s:%.2f\n" :
2753 "%ld %u bits %s signs in %.2fs \n",
2754 count, ed_curves[testnum].bits,
2755 ed_curves[testnum].name, d);
2756 eddsa_results[testnum][0] = (double)count / d;
2759 /* Perform EdDSA verification test */
2760 for (i = 0; i < loopargs_len; i++) {
2761 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2762 loopargs[i].buf2, loopargs[i].sigsize,
2763 loopargs[i].buf, 20);
2769 "EdDSA verify failure. No EdDSA verify will be done.\n");
2770 ERR_print_errors(bio_err);
2771 eddsa_doit[testnum] = 0;
2773 pkey_print_message("verify", ed_curves[testnum].name,
2774 eddsa_c[testnum][1],
2775 ed_curves[testnum].bits, seconds.eddsa);
2777 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2780 mr ? "+R9:%ld:%u:%s:%.2f\n"
2781 : "%ld %u bits %s verify in %.2fs\n",
2782 count, ed_curves[testnum].bits,
2783 ed_curves[testnum].name, d);
2784 eddsa_results[testnum][1] = (double)count / d;
2787 if (op_count <= 1) {
2788 /* if longer than 10s, don't do any more */
2789 stop_it(eddsa_doit, testnum);
2794 #ifndef OPENSSL_NO_SM2
2795 for (testnum = 0; testnum < SM2_NUM; testnum++) {
2797 EVP_PKEY *sm2_pkey = NULL;
2799 if (!sm2_doit[testnum])
2800 continue; /* Ignore Curve */
2801 /* Init signing and verification */
2802 for (i = 0; i < loopargs_len; i++) {
2803 EVP_PKEY_CTX *sm2_pctx = NULL;
2804 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2805 EVP_PKEY_CTX *pctx = NULL;
2808 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2809 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2810 if (loopargs[i].sm2_ctx[testnum] == NULL
2811 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2816 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2817 || EVP_PKEY_keygen_init(pctx) <= 0
2818 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2819 sm2_curves[testnum].nid) <= 0
2820 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2821 EVP_PKEY_CTX_free(pctx);
2825 st = 0; /* set back to zero */
2826 /* attach it sooner to rely on main final cleanup */
2827 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2828 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2830 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2831 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2832 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2833 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2837 /* attach them directly to respective ctx */
2838 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2839 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2842 * No need to allow user to set an explicit ID here, just use
2843 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2845 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2846 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2849 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2850 EVP_sm3(), NULL, sm2_pkey))
2852 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2853 EVP_sm3(), NULL, sm2_pkey))
2855 st = 1; /* mark loop as succeeded */
2858 BIO_printf(bio_err, "SM2 init failure.\n");
2859 ERR_print_errors(bio_err);
2862 for (i = 0; i < loopargs_len; i++) {
2863 /* Perform SM2 signature test */
2864 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2865 loopargs[i].buf2, &loopargs[i].sigsize,
2866 loopargs[i].buf, 20);
2872 "SM2 sign failure. No SM2 sign will be done.\n");
2873 ERR_print_errors(bio_err);
2876 pkey_print_message("sign", sm2_curves[testnum].name,
2878 sm2_curves[testnum].bits, seconds.sm2);
2880 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2884 mr ? "+R10:%ld:%u:%s:%.2f\n" :
2885 "%ld %u bits %s signs in %.2fs \n",
2886 count, sm2_curves[testnum].bits,
2887 sm2_curves[testnum].name, d);
2888 sm2_results[testnum][0] = (double)count / d;
2892 /* Perform SM2 verification test */
2893 for (i = 0; i < loopargs_len; i++) {
2894 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2895 loopargs[i].buf2, loopargs[i].sigsize,
2896 loopargs[i].buf, 20);
2902 "SM2 verify failure. No SM2 verify will be done.\n");
2903 ERR_print_errors(bio_err);
2904 sm2_doit[testnum] = 0;
2906 pkey_print_message("verify", sm2_curves[testnum].name,
2908 sm2_curves[testnum].bits, seconds.sm2);
2910 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2913 mr ? "+R11:%ld:%u:%s:%.2f\n"
2914 : "%ld %u bits %s verify in %.2fs\n",
2915 count, sm2_curves[testnum].bits,
2916 sm2_curves[testnum].name, d);
2917 sm2_results[testnum][1] = (double)count / d;
2920 if (op_count <= 1) {
2921 /* if longer than 10s, don't do any more */
2922 for (testnum++; testnum < SM2_NUM; testnum++)
2923 sm2_doit[testnum] = 0;
2927 #endif /* OPENSSL_NO_SM2 */
2929 #ifndef OPENSSL_NO_DH
2930 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2931 int ffdh_checks = 1;
2933 if (!ffdh_doit[testnum])
2936 for (i = 0; i < loopargs_len; i++) {
2937 EVP_PKEY *pkey_A = NULL;
2938 EVP_PKEY *pkey_B = NULL;
2939 EVP_PKEY_CTX *ffdh_ctx = NULL;
2940 EVP_PKEY_CTX *test_ctx = NULL;
2944 /* Ensure that the error queue is empty */
2945 if (ERR_peek_error()) {
2947 "WARNING: the error queue contains previous unhandled errors.\n");
2948 ERR_print_errors(bio_err);
2951 pkey_A = EVP_PKEY_new();
2953 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2954 ERR_print_errors(bio_err);
2959 pkey_B = EVP_PKEY_new();
2961 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2962 ERR_print_errors(bio_err);
2968 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2970 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2971 ERR_print_errors(bio_err);
2977 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
2978 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
2979 ERR_print_errors(bio_err);
2984 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
2985 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
2986 ERR_print_errors(bio_err);
2992 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
2993 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
2994 BIO_printf(bio_err, "FFDH key generation failure.\n");
2995 ERR_print_errors(bio_err);
3001 EVP_PKEY_CTX_free(ffdh_ctx);
3004 * check if the derivation works correctly both ways so that
3005 * we know if future derive calls will fail, and we can skip
3006 * error checking in benchmarked code
3008 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3009 if (ffdh_ctx == NULL) {
3010 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3011 ERR_print_errors(bio_err);
3016 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3017 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3018 ERR_print_errors(bio_err);
3023 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3024 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3025 ERR_print_errors(bio_err);
3030 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3031 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3032 ERR_print_errors(bio_err);
3037 if (secret_size > MAX_FFDH_SIZE) {
3038 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3043 if (EVP_PKEY_derive(ffdh_ctx,
3044 loopargs[i].secret_ff_a,
3045 &secret_size) <= 0) {
3046 BIO_printf(bio_err, "Shared secret derive failure.\n");
3047 ERR_print_errors(bio_err);
3052 /* Now check from side B */
3053 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3055 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3056 ERR_print_errors(bio_err);
3061 if (!EVP_PKEY_derive_init(test_ctx) ||
3062 !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) ||
3063 !EVP_PKEY_derive(test_ctx, NULL, &test_out) ||
3064 !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) ||
3065 test_out != secret_size) {
3066 BIO_printf(bio_err, "FFDH computation failure.\n");
3072 /* compare the computed secrets */
3073 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3074 loopargs[i].secret_ff_b, secret_size)) {
3075 BIO_printf(bio_err, "FFDH computations don't match.\n");
3076 ERR_print_errors(bio_err);
3082 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3084 EVP_PKEY_free(pkey_A);
3086 EVP_PKEY_free(pkey_B);
3088 EVP_PKEY_CTX_free(test_ctx);
3091 if (ffdh_checks != 0) {
3092 pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3093 ffdh_params[testnum].bits, seconds.ffdh);
3096 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3099 mr ? "+R12:%ld:%d:%.2f\n" :
3100 "%ld %u-bits FFDH ops in %.2fs\n", count,
3101 ffdh_params[testnum].bits, d);
3102 ffdh_results[testnum][0] = (double)count / d;
3105 if (op_count <= 1) {
3106 /* if longer than 10s, don't do any more */
3107 stop_it(ffdh_doit, testnum);
3110 #endif /* OPENSSL_NO_DH */
3115 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3116 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3117 printf("options: %s\n", BN_options());
3118 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3119 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3126 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3129 for (testnum = 0; testnum < size_num; testnum++)
3130 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3134 for (k = 0; k < ALGOR_NUM; k++) {
3138 printf("+F:%u:%s", k, names[k]);
3140 printf("%-13s", names[k]);
3141 for (testnum = 0; testnum < size_num; testnum++) {
3142 if (results[k][testnum] > 10000 && !mr)
3143 printf(" %11.2fk", results[k][testnum] / 1e3);
3145 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3150 for (k = 0; k < RSA_NUM; k++) {
3153 if (testnum && !mr) {
3154 printf("%18ssign verify sign/s verify/s\n", " ");
3158 printf("+F2:%u:%u:%f:%f\n",
3159 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3161 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3162 rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3163 rsa_results[k][0], rsa_results[k][1]);
3166 for (k = 0; k < DSA_NUM; k++) {
3169 if (testnum && !mr) {
3170 printf("%18ssign verify sign/s verify/s\n", " ");
3174 printf("+F3:%u:%u:%f:%f\n",
3175 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3177 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3178 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3179 dsa_results[k][0], dsa_results[k][1]);
3182 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3185 if (testnum && !mr) {
3186 printf("%30ssign verify sign/s verify/s\n", " ");
3191 printf("+F4:%u:%u:%f:%f\n",
3192 k, ec_curves[k].bits,
3193 ecdsa_results[k][0], ecdsa_results[k][1]);
3195 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3196 ec_curves[k].bits, ec_curves[k].name,
3197 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3198 ecdsa_results[k][0], ecdsa_results[k][1]);
3202 for (k = 0; k < EC_NUM; k++) {
3205 if (testnum && !mr) {
3206 printf("%30sop op/s\n", " ");
3210 printf("+F5:%u:%u:%f:%f\n",
3211 k, ec_curves[k].bits,
3212 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3215 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3216 ec_curves[k].bits, ec_curves[k].name,
3217 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3221 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3224 if (testnum && !mr) {
3225 printf("%30ssign verify sign/s verify/s\n", " ");
3230 printf("+F6:%u:%u:%s:%f:%f\n",
3231 k, ed_curves[k].bits, ed_curves[k].name,
3232 eddsa_results[k][0], eddsa_results[k][1]);
3234 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3235 ed_curves[k].bits, ed_curves[k].name,
3236 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3237 eddsa_results[k][0], eddsa_results[k][1]);
3240 #ifndef OPENSSL_NO_SM2
3242 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3245 if (testnum && !mr) {
3246 printf("%30ssign verify sign/s verify/s\n", " ");
3251 printf("+F7:%u:%u:%s:%f:%f\n",
3252 k, sm2_curves[k].bits, sm2_curves[k].name,
3253 sm2_results[k][0], sm2_results[k][1]);
3255 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3256 sm2_curves[k].bits, sm2_curves[k].name,
3257 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3258 sm2_results[k][0], sm2_results[k][1]);
3261 #ifndef OPENSSL_NO_DH
3263 for (k = 0; k < FFDH_NUM; k++) {
3266 if (testnum && !mr) {
3267 printf("%23sop op/s\n", " ");
3271 printf("+F8:%u:%u:%f:%f\n",
3272 k, ffdh_params[k].bits,
3273 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3276 printf("%4u bits ffdh %8.4fs %8.1f\n",
3277 ffdh_params[k].bits,
3278 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3280 #endif /* OPENSSL_NO_DH */
3285 ERR_print_errors(bio_err);
3286 for (i = 0; i < loopargs_len; i++) {
3287 OPENSSL_free(loopargs[i].buf_malloc);
3288 OPENSSL_free(loopargs[i].buf2_malloc);
3291 EVP_PKEY_CTX_free(genctx);
3292 for (k = 0; k < RSA_NUM; k++) {
3293 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3294 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3296 #ifndef OPENSSL_NO_DH
3297 OPENSSL_free(loopargs[i].secret_ff_a);
3298 OPENSSL_free(loopargs[i].secret_ff_b);
3299 for (k = 0; k < FFDH_NUM; k++)
3300 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3302 for (k = 0; k < DSA_NUM; k++) {
3303 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3304 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3306 for (k = 0; k < ECDSA_NUM; k++) {
3307 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3308 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3310 for (k = 0; k < EC_NUM; k++)
3311 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3312 for (k = 0; k < EdDSA_NUM; k++) {
3313 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3314 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3316 #ifndef OPENSSL_NO_SM2
3317 for (k = 0; k < SM2_NUM; k++) {
3318 EVP_PKEY_CTX *pctx = NULL;
3320 /* free signing ctx */
3321 if (loopargs[i].sm2_ctx[k] != NULL
3322 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3323 EVP_PKEY_CTX_free(pctx);
3324 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3325 /* free verification ctx */
3326 if (loopargs[i].sm2_vfy_ctx[k] != NULL
3327 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3328 EVP_PKEY_CTX_free(pctx);
3329 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3331 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3334 OPENSSL_free(loopargs[i].secret_a);
3335 OPENSSL_free(loopargs[i].secret_b);
3337 OPENSSL_free(evp_hmac_name);
3338 OPENSSL_free(evp_cmac_name);
3340 if (async_jobs > 0) {
3341 for (i = 0; i < loopargs_len; i++)
3342 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3346 ASYNC_cleanup_thread();
3348 OPENSSL_free(loopargs);
3350 EVP_CIPHER_free(evp_cipher);
3355 static void print_message(const char *s, long num, int length, int tm)
3358 mr ? "+DT:%s:%d:%d\n"
3359 : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3360 (void)BIO_flush(bio_err);
3365 static void pkey_print_message(const char *str, const char *str2, long num,
3366 unsigned int bits, int tm)
3369 mr ? "+DTP:%d:%s:%s:%d\n"
3370 : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3371 (void)BIO_flush(bio_err);
3376 static void print_result(int alg, int run_no, int count, double time_used)
3379 BIO_printf(bio_err, "%s error!\n", names[alg]);
3380 ERR_print_errors(bio_err);
3384 mr ? "+R:%d:%s:%f\n"
3385 : "%d %s's in %.2fs\n", count, names[alg], time_used);
3386 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3390 static char *sstrsep(char **string, const char *delim)
3393 char *token = *string;
3398 memset(isdelim, 0, sizeof(isdelim));
3402 isdelim[(unsigned char)(*delim)] = 1;
3406 while (!isdelim[(unsigned char)(**string)])
3417 static int do_multi(int multi, int size_num)
3422 static char sep[] = ":";
3424 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3425 for (n = 0; n < multi; ++n) {
3426 if (pipe(fd) == -1) {
3427 BIO_printf(bio_err, "pipe failure\n");
3431 (void)BIO_flush(bio_err);
3438 if (dup(fd[1]) == -1) {
3439 BIO_printf(bio_err, "dup failed\n");
3448 printf("Forked child %d\n", n);
3451 /* for now, assume the pipe is long enough to take all the output */
3452 for (n = 0; n < multi; ++n) {
3457 f = fdopen(fds[n], "r");
3458 while (fgets(buf, sizeof(buf), f)) {
3459 p = strchr(buf, '\n');
3462 if (buf[0] != '+') {
3464 "Don't understand line '%s' from child %d\n", buf,
3468 printf("Got: %s from %d\n", buf, n);
3469 if (strncmp(buf, "+F:", 3) == 0) {
3474 alg = atoi(sstrsep(&p, sep));
3476 for (j = 0; j < size_num; ++j)
3477 results[alg][j] += atof(sstrsep(&p, sep));
3478 } else if (strncmp(buf, "+F2:", 4) == 0) {
3483 k = atoi(sstrsep(&p, sep));
3486 d = atof(sstrsep(&p, sep));
3487 rsa_results[k][0] += d;
3489 d = atof(sstrsep(&p, sep));
3490 rsa_results[k][1] += d;
3491 } else if (strncmp(buf, "+F3:", 4) == 0) {
3496 k = atoi(sstrsep(&p, sep));
3499 d = atof(sstrsep(&p, sep));
3500 dsa_results[k][0] += d;
3502 d = atof(sstrsep(&p, sep));
3503 dsa_results[k][1] += d;
3504 } else if (strncmp(buf, "+F4:", 4) == 0) {
3509 k = atoi(sstrsep(&p, sep));
3512 d = atof(sstrsep(&p, sep));
3513 ecdsa_results[k][0] += d;
3515 d = atof(sstrsep(&p, sep));
3516 ecdsa_results[k][1] += d;
3517 } else if (strncmp(buf, "+F5:", 4) == 0) {
3522 k = atoi(sstrsep(&p, sep));
3525 d = atof(sstrsep(&p, sep));
3526 ecdh_results[k][0] += d;
3527 } else if (strncmp(buf, "+F6:", 4) == 0) {
3532 k = atoi(sstrsep(&p, sep));
3536 d = atof(sstrsep(&p, sep));
3537 eddsa_results[k][0] += d;
3539 d = atof(sstrsep(&p, sep));
3540 eddsa_results[k][1] += d;
3541 # ifndef OPENSSL_NO_SM2
3542 } else if (strncmp(buf, "+F7:", 4) == 0) {
3547 k = atoi(sstrsep(&p, sep));
3551 d = atof(sstrsep(&p, sep));
3552 sm2_results[k][0] += d;
3554 d = atof(sstrsep(&p, sep));
3555 sm2_results[k][1] += d;
3556 # endif /* OPENSSL_NO_SM2 */
3557 # ifndef OPENSSL_NO_DH
3558 } else if (strncmp(buf, "+F8:", 4) == 0) {
3563 k = atoi(sstrsep(&p, sep));
3566 d = atof(sstrsep(&p, sep));
3567 ffdh_results[k][0] += d;
3568 # endif /* OPENSSL_NO_DH */
3569 } else if (strncmp(buf, "+H:", 3) == 0) {
3572 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3584 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3585 const openssl_speed_sec_t *seconds)
3587 static const int mblengths_list[] =
3588 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3589 const int *mblengths = mblengths_list;
3590 int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3591 const char *alg_name;
3592 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3593 EVP_CIPHER_CTX *ctx = NULL;
3596 if (lengths_single) {
3597 mblengths = &lengths_single;
3601 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3602 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3603 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3604 app_bail_out("failed to allocate cipher context\n");
3605 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3606 app_bail_out("failed to initialise cipher context\n");
3608 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3609 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3612 key = app_malloc(keylen, "evp_cipher key");
3613 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
3614 app_bail_out("failed to generate random cipher key\n");
3615 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3616 app_bail_out("failed to set cipher key\n");
3617 OPENSSL_clear_free(key, keylen);
3619 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3620 sizeof(no_key), no_key) <= 0)
3621 app_bail_out("failed to set AEAD key\n");
3622 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3623 app_bail_out("failed to get cipher name\n");
3625 for (j = 0; j < num; j++) {
3626 print_message(alg_name, 0, mblengths[j], seconds->sym);
3628 for (count = 0; run && count < INT_MAX; count++) {
3629 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3630 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3631 size_t len = mblengths[j];
3634 memset(aad, 0, 8); /* avoid uninitialized values */
3635 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3636 aad[9] = 3; /* version */
3638 aad[11] = 0; /* length */
3640 mb_param.out = NULL;
3643 mb_param.interleave = 8;
3645 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3646 sizeof(mb_param), &mb_param);
3652 (void)EVP_CIPHER_CTX_ctrl(ctx,
3653 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3654 sizeof(mb_param), &mb_param);
3658 RAND_bytes(out, 16);
3660 aad[11] = (unsigned char)(len >> 8);
3661 aad[12] = (unsigned char)(len);
3662 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3663 EVP_AEAD_TLS1_AAD_LEN, aad);
3664 EVP_Cipher(ctx, out, inp, len + pad);
3668 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3669 : "%d %s's in %.2fs\n", count, "evp", d);
3670 results[D_EVP][j] = ((double)count) / d * mblengths[j];
3674 fprintf(stdout, "+H");
3675 for (j = 0; j < num; j++)
3676 fprintf(stdout, ":%d", mblengths[j]);
3677 fprintf(stdout, "\n");
3678 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3679 for (j = 0; j < num; j++)
3680 fprintf(stdout, ":%.2f", results[D_EVP][j]);
3681 fprintf(stdout, "\n");
3684 "The 'numbers' are in 1000s of bytes per second processed.\n");
3685 fprintf(stdout, "type ");
3686 for (j = 0; j < num; j++)
3687 fprintf(stdout, "%7d bytes", mblengths[j]);
3688 fprintf(stdout, "\n");
3689 fprintf(stdout, "%-24s", alg_name);
3691 for (j = 0; j < num; j++) {
3692 if (results[D_EVP][j] > 10000)
3693 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3695 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3697 fprintf(stdout, "\n");
3703 EVP_CIPHER_CTX_free(ctx);