2 * Copyright 1995-2021 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 <openssl/crypto.h>
33 #include <openssl/rand.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/objects.h>
37 #include <openssl/core_names.h>
38 #include <openssl/async.h>
39 #if !defined(OPENSSL_SYS_MSDOS)
44 # if defined(OPENSSL_TANDEM_FLOSS)
45 # include <floss.h(floss_fork)>
53 #include <openssl/bn.h>
54 #include <openssl/rsa.h>
55 #include "./testrsa.h"
57 # include <openssl/dh.h>
59 #include <openssl/x509.h>
60 #include <openssl/dsa.h>
61 #include "./testdsa.h"
62 #include <openssl/modes.h>
65 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
78 #define MAX_MISALIGNMENT 63
79 #define MAX_ECDH_SIZE 256
81 #define MAX_FFDH_SIZE 1024
83 #ifndef RSA_DEFAULT_PRIME_NUM
84 # define RSA_DEFAULT_PRIME_NUM 2
87 typedef struct openssl_speed_sec_st {
96 } openssl_speed_sec_t;
98 static volatile int run = 0;
100 static int mr = 0; /* machine-readeable output format to merge fork results */
101 static int usertime = 1;
103 static double Time_F(int s);
104 static void print_message(const char *s, long num, int length, int tm);
105 static void pkey_print_message(const char *str, const char *str2,
106 long num, unsigned int bits, int sec);
107 static void print_result(int alg, int run_no, int count, double time_used);
109 static int do_multi(int multi, int size_num);
112 static const int lengths_list[] = {
113 16, 64, 256, 1024, 8 * 1024, 16 * 1024
115 #define SIZE_NUM OSSL_NELEM(lengths_list)
116 static const int *lengths = lengths_list;
118 static const int aead_lengths_list[] = {
119 2, 31, 136, 1024, 8 * 1024, 16 * 1024
127 static void alarmed(int sig)
129 signal(SIGALRM, alarmed);
133 static double Time_F(int s)
135 double ret = app_tminterval(s, usertime);
141 #elif defined(_WIN32)
145 static unsigned int lapse;
146 static volatile unsigned int schlock;
147 static void alarm_win32(unsigned int secs)
152 # define alarm alarm_win32
154 static DWORD WINAPI sleepy(VOID * arg)
162 static double Time_F(int s)
169 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
171 DWORD err = GetLastError();
172 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
176 Sleep(0); /* scheduler spinlock */
177 ret = app_tminterval(s, usertime);
179 ret = app_tminterval(s, usertime);
181 TerminateThread(thr, 0);
188 # error "SIGALRM not defined and the platform is not Windows"
191 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
192 const openssl_speed_sec_t *seconds);
194 static int opt_found(const char *name, unsigned int *result,
195 const OPT_PAIR pairs[], unsigned int nbelem)
199 for (idx = 0; idx < nbelem; ++idx, pairs++)
200 if (strcmp(name, pairs->name) == 0) {
201 *result = pairs->retval;
206 #define opt_found(value, pairs, result)\
207 opt_found(value, result, pairs, OSSL_NELEM(pairs))
209 typedef enum OPTION_choice {
211 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
212 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM,
213 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC
216 const OPTIONS speed_options[] = {
217 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"},
219 OPT_SECTION("General"),
220 {"help", OPT_HELP, '-', "Display this summary"},
222 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
223 {"mr", OPT_MR, '-', "Produce machine readable output"},
225 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
227 #ifndef OPENSSL_NO_ASYNC
228 {"async_jobs", OPT_ASYNCJOBS, 'p',
229 "Enable async mode and start specified number of jobs"},
231 #ifndef OPENSSL_NO_ENGINE
232 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
234 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
236 OPT_SECTION("Selection"),
237 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
238 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
239 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
240 {"decrypt", OPT_DECRYPT, '-',
241 "Time decryption instead of encryption (only EVP)"},
242 {"aead", OPT_AEAD, '-',
243 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
245 OPT_SECTION("Timing"),
246 {"elapsed", OPT_ELAPSED, '-',
247 "Use wall-clock time instead of CPU user time as divisor"},
248 {"seconds", OPT_SECONDS, 'p',
249 "Run benchmarks for specified amount of seconds"},
250 {"bytes", OPT_BYTES, 'p',
251 "Run [non-PKI] benchmarks on custom-sized buffer"},
252 {"misalign", OPT_MISALIGN, 'p',
253 "Use specified offset to mis-align buffers"},
259 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
264 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
265 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
266 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
267 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
268 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
269 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
270 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
272 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
273 static const char *names[ALGOR_NUM] = {
274 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
275 "sha256", "sha512", "whirlpool", "hmac(md5)",
276 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
277 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
278 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
279 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
280 "evp", "ghash", "rand", "cmac"
283 /* list of configured algorithm (remaining), with some few alias */
284 static const OPT_PAIR doit_choices[] = {
291 {"sha256", D_SHA256},
292 {"sha512", D_SHA512},
293 {"whirlpool", D_WHIRLPOOL},
294 {"ripemd", D_RMD160},
295 {"rmd160", D_RMD160},
296 {"ripemd160", D_RMD160},
298 {"des-cbc", D_CBC_DES},
299 {"des-ede3", D_EDE3_DES},
300 {"aes-128-cbc", D_CBC_128_AES},
301 {"aes-192-cbc", D_CBC_192_AES},
302 {"aes-256-cbc", D_CBC_256_AES},
303 {"camellia-128-cbc", D_CBC_128_CML},
304 {"camellia-192-cbc", D_CBC_192_CML},
305 {"camellia-256-cbc", D_CBC_256_CML},
306 {"rc2-cbc", D_CBC_RC2},
308 {"rc5-cbc", D_CBC_RC5},
310 {"idea-cbc", D_CBC_IDEA},
311 {"idea", D_CBC_IDEA},
312 {"seed-cbc", D_CBC_SEED},
313 {"seed", D_CBC_SEED},
314 {"bf-cbc", D_CBC_BF},
315 {"blowfish", D_CBC_BF},
317 {"cast-cbc", D_CBC_CAST},
318 {"cast", D_CBC_CAST},
319 {"cast5", D_CBC_CAST},
324 static double results[ALGOR_NUM][SIZE_NUM];
326 enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM };
327 static const OPT_PAIR dsa_choices[DSA_NUM] = {
328 {"dsa512", R_DSA_512},
329 {"dsa1024", R_DSA_1024},
330 {"dsa2048", R_DSA_2048}
332 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
335 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
338 static const OPT_PAIR rsa_choices[RSA_NUM] = {
339 {"rsa512", R_RSA_512},
340 {"rsa1024", R_RSA_1024},
341 {"rsa2048", R_RSA_2048},
342 {"rsa3072", R_RSA_3072},
343 {"rsa4096", R_RSA_4096},
344 {"rsa7680", R_RSA_7680},
345 {"rsa15360", R_RSA_15360}
348 static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */
350 #ifndef OPENSSL_NO_DH
352 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
355 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
356 {"ffdh2048", R_FFDH_2048},
357 {"ffdh3072", R_FFDH_3072},
358 {"ffdh4096", R_FFDH_4096},
359 {"ffdh6144", R_FFDH_6144},
360 {"ffdh8192", R_FFDH_8192},
363 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
364 #endif /* OPENSSL_NO_DH */
367 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
368 #ifndef OPENSSL_NO_EC2M
369 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
370 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
372 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
373 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
375 /* list of ecdsa curves */
376 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
377 {"ecdsap160", R_EC_P160},
378 {"ecdsap192", R_EC_P192},
379 {"ecdsap224", R_EC_P224},
380 {"ecdsap256", R_EC_P256},
381 {"ecdsap384", R_EC_P384},
382 {"ecdsap521", R_EC_P521},
383 #ifndef OPENSSL_NO_EC2M
384 {"ecdsak163", R_EC_K163},
385 {"ecdsak233", R_EC_K233},
386 {"ecdsak283", R_EC_K283},
387 {"ecdsak409", R_EC_K409},
388 {"ecdsak571", R_EC_K571},
389 {"ecdsab163", R_EC_B163},
390 {"ecdsab233", R_EC_B233},
391 {"ecdsab283", R_EC_B283},
392 {"ecdsab409", R_EC_B409},
393 {"ecdsab571", R_EC_B571},
395 {"ecdsabrp256r1", R_EC_BRP256R1},
396 {"ecdsabrp256t1", R_EC_BRP256T1},
397 {"ecdsabrp384r1", R_EC_BRP384R1},
398 {"ecdsabrp384t1", R_EC_BRP384T1},
399 {"ecdsabrp512r1", R_EC_BRP512R1},
400 {"ecdsabrp512t1", R_EC_BRP512T1}
402 enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM };
403 /* list of ecdh curves, extension of |ecdsa_choices| list above */
404 static const OPT_PAIR ecdh_choices[EC_NUM] = {
405 {"ecdhp160", R_EC_P160},
406 {"ecdhp192", R_EC_P192},
407 {"ecdhp224", R_EC_P224},
408 {"ecdhp256", R_EC_P256},
409 {"ecdhp384", R_EC_P384},
410 {"ecdhp521", R_EC_P521},
411 #ifndef OPENSSL_NO_EC2M
412 {"ecdhk163", R_EC_K163},
413 {"ecdhk233", R_EC_K233},
414 {"ecdhk283", R_EC_K283},
415 {"ecdhk409", R_EC_K409},
416 {"ecdhk571", R_EC_K571},
417 {"ecdhb163", R_EC_B163},
418 {"ecdhb233", R_EC_B233},
419 {"ecdhb283", R_EC_B283},
420 {"ecdhb409", R_EC_B409},
421 {"ecdhb571", R_EC_B571},
423 {"ecdhbrp256r1", R_EC_BRP256R1},
424 {"ecdhbrp256t1", R_EC_BRP256T1},
425 {"ecdhbrp384r1", R_EC_BRP384R1},
426 {"ecdhbrp384t1", R_EC_BRP384T1},
427 {"ecdhbrp512r1", R_EC_BRP512R1},
428 {"ecdhbrp512t1", R_EC_BRP512T1},
429 {"ecdhx25519", R_EC_X25519},
430 {"ecdhx448", R_EC_X448}
433 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
434 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
436 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
437 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
438 {"ed25519", R_EC_Ed25519},
439 {"ed448", R_EC_Ed448}
442 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
444 #ifndef OPENSSL_NO_SM2
445 enum { R_EC_CURVESM2, SM2_NUM };
446 static const OPT_PAIR sm2_choices[SM2_NUM] = {
447 {"curveSM2", R_EC_CURVESM2}
449 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
450 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
451 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
452 #endif /* OPENSSL_NO_SM2 */
454 #define COND(unused_cond) (run && count < 0x7fffffff)
455 #define COUNT(d) (count)
457 typedef struct loopargs_st {
458 ASYNC_JOB *inprogress_job;
459 ASYNC_WAIT_CTX *wait_ctx;
462 unsigned char *buf_malloc;
463 unsigned char *buf2_malloc;
466 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
467 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
468 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
469 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
470 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
471 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
472 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
473 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
474 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
475 #ifndef OPENSSL_NO_SM2
476 EVP_MD_CTX *sm2_ctx[SM2_NUM];
477 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
478 EVP_PKEY *sm2_pkey[SM2_NUM];
480 unsigned char *secret_a;
481 unsigned char *secret_b;
482 size_t outlen[EC_NUM];
483 #ifndef OPENSSL_NO_DH
484 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
485 unsigned char *secret_ff_a;
486 unsigned char *secret_ff_b;
491 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
492 loopargs_t * loopargs);
494 static unsigned int testnum;
496 /* Nb of iterations to do per algorithm and key-size */
497 static long c[ALGOR_NUM][SIZE_NUM];
499 static char *evp_mac_mdname = "md5";
500 static char *evp_hmac_name = NULL;
501 static const char *evp_md_name = NULL;
502 static char *evp_mac_ciphername = "aes-128-cbc";
503 static char *evp_cmac_name = NULL;
505 static int have_md(const char *name)
510 if (opt_md_silent(name, &md)) {
511 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
513 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
515 EVP_MD_CTX_free(ctx);
521 static int have_cipher(const char *name)
524 EVP_CIPHER *cipher = NULL;
526 if (opt_cipher_silent(name, &cipher)) {
527 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
530 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
532 EVP_CIPHER_CTX_free(ctx);
533 EVP_CIPHER_free(cipher);
538 static int EVP_Digest_loop(const char *mdname, int algindex, void *args)
540 loopargs_t *tempargs = *(loopargs_t **) args;
541 unsigned char *buf = tempargs->buf;
542 unsigned char digest[EVP_MAX_MD_SIZE];
546 if (!opt_md_silent(mdname, &md))
548 for (count = 0; COND(c[algindex][testnum]); count++) {
549 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
559 static int EVP_Digest_md_loop(void *args)
561 return EVP_Digest_loop(evp_md_name, D_EVP, args);
564 static int EVP_Digest_MD2_loop(void *args)
566 return EVP_Digest_loop("md2", D_MD2, args);
569 static int EVP_Digest_MDC2_loop(void *args)
571 return EVP_Digest_loop("mdc2", D_MDC2, args);
574 static int EVP_Digest_MD4_loop(void *args)
576 return EVP_Digest_loop("md4", D_MD4, args);
579 static int MD5_loop(void *args)
581 return EVP_Digest_loop("md5", D_MD5, args);
584 static int EVP_MAC_loop(int algindex, void *args)
586 loopargs_t *tempargs = *(loopargs_t **) args;
587 unsigned char *buf = tempargs->buf;
588 EVP_MAC_CTX *mctx = tempargs->mctx;
589 unsigned char mac[EVP_MAX_MD_SIZE];
592 for (count = 0; COND(c[algindex][testnum]); count++) {
595 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
596 || !EVP_MAC_update(mctx, buf, lengths[testnum])
597 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
603 static int HMAC_loop(void *args)
605 return EVP_MAC_loop(D_HMAC, args);
608 static int CMAC_loop(void *args)
610 return EVP_MAC_loop(D_EVP_CMAC, args);
613 static int SHA1_loop(void *args)
615 return EVP_Digest_loop("sha1", D_SHA1, args);
618 static int SHA256_loop(void *args)
620 return EVP_Digest_loop("sha256", D_SHA256, args);
623 static int SHA512_loop(void *args)
625 return EVP_Digest_loop("sha512", D_SHA512, args);
628 static int WHIRLPOOL_loop(void *args)
630 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
633 static int EVP_Digest_RMD160_loop(void *args)
635 return EVP_Digest_loop("ripemd160", D_RMD160, args);
640 static int EVP_Cipher_loop(void *args)
642 loopargs_t *tempargs = *(loopargs_t **) args;
643 unsigned char *buf = tempargs->buf;
646 if (tempargs->ctx == NULL)
648 for (count = 0; COND(c[algindex][testnum]); count++)
649 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
654 static int GHASH_loop(void *args)
656 loopargs_t *tempargs = *(loopargs_t **) args;
657 unsigned char *buf = tempargs->buf;
658 EVP_MAC_CTX *mctx = tempargs->mctx;
661 /* just do the update in the loop to be comparable with 1.1.1 */
662 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
663 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
669 #define MAX_BLOCK_SIZE 128
671 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
673 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
674 const unsigned char *key,
677 EVP_CIPHER_CTX *ctx = NULL;
678 EVP_CIPHER *cipher = NULL;
680 if (!opt_cipher_silent(ciphername, &cipher))
683 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
686 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
687 EVP_CIPHER_CTX_free(ctx);
692 if (!EVP_CIPHER_CTX_set_key_length(ctx, keylen)) {
693 EVP_CIPHER_CTX_free(ctx);
698 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
699 EVP_CIPHER_CTX_free(ctx);
705 EVP_CIPHER_free(cipher);
709 static int RAND_bytes_loop(void *args)
711 loopargs_t *tempargs = *(loopargs_t **) args;
712 unsigned char *buf = tempargs->buf;
715 for (count = 0; COND(c[D_RAND][testnum]); count++)
716 RAND_bytes(buf, lengths[testnum]);
720 static int decrypt = 0;
721 static int EVP_Update_loop(void *args)
723 loopargs_t *tempargs = *(loopargs_t **) args;
724 unsigned char *buf = tempargs->buf;
725 EVP_CIPHER_CTX *ctx = tempargs->ctx;
729 for (count = 0; COND(c[D_EVP][testnum]); count++) {
730 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
732 /* reset iv in case of counter overflow */
733 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
737 for (count = 0; COND(c[D_EVP][testnum]); count++) {
738 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
740 /* reset iv in case of counter overflow */
741 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
746 EVP_DecryptFinal_ex(ctx, buf, &outl);
748 EVP_EncryptFinal_ex(ctx, buf, &outl);
753 * CCM does not support streaming. For the purpose of performance measurement,
754 * each message is encrypted using the same (key,iv)-pair. Do not use this
755 * code in your application.
757 static int EVP_Update_loop_ccm(void *args)
759 loopargs_t *tempargs = *(loopargs_t **) args;
760 unsigned char *buf = tempargs->buf;
761 EVP_CIPHER_CTX *ctx = tempargs->ctx;
763 unsigned char tag[12];
766 for (count = 0; COND(c[D_EVP][testnum]); count++) {
767 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag);
769 EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
770 /* counter is reset on every update */
771 EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
774 for (count = 0; COND(c[D_EVP][testnum]); count++) {
775 /* restore iv length field */
776 EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
777 /* counter is reset on every update */
778 EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
782 EVP_DecryptFinal_ex(ctx, buf, &outl);
784 EVP_EncryptFinal_ex(ctx, buf, &outl);
789 * To make AEAD benchmarking more relevant perform TLS-like operations,
790 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
791 * payload length is not actually limited by 16KB...
793 static int EVP_Update_loop_aead(void *args)
795 loopargs_t *tempargs = *(loopargs_t **) args;
796 unsigned char *buf = tempargs->buf;
797 EVP_CIPHER_CTX *ctx = tempargs->ctx;
799 unsigned char aad[13] = { 0xcc };
800 unsigned char faketag[16] = { 0xcc };
803 for (count = 0; COND(c[D_EVP][testnum]); count++) {
804 (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
805 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
806 sizeof(faketag), faketag);
807 (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
808 (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
809 (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl);
812 for (count = 0; COND(c[D_EVP][testnum]); count++) {
813 (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv);
814 (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
815 (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
816 (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl);
822 static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */
824 static int RSA_sign_loop(void *args)
826 loopargs_t *tempargs = *(loopargs_t **) args;
827 unsigned char *buf = tempargs->buf;
828 unsigned char *buf2 = tempargs->buf2;
829 size_t *rsa_num = &tempargs->sigsize;
830 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
833 for (count = 0; COND(rsa_c[testnum][0]); count++) {
834 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
836 BIO_printf(bio_err, "RSA sign failure\n");
837 ERR_print_errors(bio_err);
845 static int RSA_verify_loop(void *args)
847 loopargs_t *tempargs = *(loopargs_t **) args;
848 unsigned char *buf = tempargs->buf;
849 unsigned char *buf2 = tempargs->buf2;
850 size_t rsa_num = tempargs->sigsize;
851 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
854 for (count = 0; COND(rsa_c[testnum][1]); count++) {
855 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
857 BIO_printf(bio_err, "RSA verify failure\n");
858 ERR_print_errors(bio_err);
866 #ifndef OPENSSL_NO_DH
867 static long ffdh_c[FFDH_NUM][1];
869 static int FFDH_derive_key_loop(void *args)
871 loopargs_t *tempargs = *(loopargs_t **) args;
872 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
873 unsigned char *derived_secret = tempargs->secret_ff_a;
874 size_t outlen = MAX_FFDH_SIZE;
877 for (count = 0; COND(ffdh_c[testnum][0]); count++)
878 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
881 #endif /* OPENSSL_NO_DH */
883 static long dsa_c[DSA_NUM][2];
884 static int DSA_sign_loop(void *args)
886 loopargs_t *tempargs = *(loopargs_t **) args;
887 unsigned char *buf = tempargs->buf;
888 unsigned char *buf2 = tempargs->buf2;
889 size_t *dsa_num = &tempargs->sigsize;
890 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
893 for (count = 0; COND(dsa_c[testnum][0]); count++) {
894 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
896 BIO_printf(bio_err, "DSA sign failure\n");
897 ERR_print_errors(bio_err);
905 static int DSA_verify_loop(void *args)
907 loopargs_t *tempargs = *(loopargs_t **) args;
908 unsigned char *buf = tempargs->buf;
909 unsigned char *buf2 = tempargs->buf2;
910 size_t dsa_num = tempargs->sigsize;
911 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
914 for (count = 0; COND(dsa_c[testnum][1]); count++) {
915 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
917 BIO_printf(bio_err, "DSA verify failure\n");
918 ERR_print_errors(bio_err);
926 static long ecdsa_c[ECDSA_NUM][2];
927 static int ECDSA_sign_loop(void *args)
929 loopargs_t *tempargs = *(loopargs_t **) args;
930 unsigned char *buf = tempargs->buf;
931 unsigned char *buf2 = tempargs->buf2;
932 size_t *ecdsa_num = &tempargs->sigsize;
933 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
936 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
937 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
939 BIO_printf(bio_err, "ECDSA sign failure\n");
940 ERR_print_errors(bio_err);
948 static int ECDSA_verify_loop(void *args)
950 loopargs_t *tempargs = *(loopargs_t **) args;
951 unsigned char *buf = tempargs->buf;
952 unsigned char *buf2 = tempargs->buf2;
953 size_t ecdsa_num = tempargs->sigsize;
954 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
957 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
958 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
961 BIO_printf(bio_err, "ECDSA verify failure\n");
962 ERR_print_errors(bio_err);
970 /* ******************************************************************** */
971 static long ecdh_c[EC_NUM][1];
973 static int ECDH_EVP_derive_key_loop(void *args)
975 loopargs_t *tempargs = *(loopargs_t **) args;
976 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
977 unsigned char *derived_secret = tempargs->secret_a;
979 size_t *outlen = &(tempargs->outlen[testnum]);
981 for (count = 0; COND(ecdh_c[testnum][0]); count++)
982 EVP_PKEY_derive(ctx, derived_secret, outlen);
987 static long eddsa_c[EdDSA_NUM][2];
988 static int EdDSA_sign_loop(void *args)
990 loopargs_t *tempargs = *(loopargs_t **) args;
991 unsigned char *buf = tempargs->buf;
992 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
993 unsigned char *eddsasig = tempargs->buf2;
994 size_t *eddsasigsize = &tempargs->sigsize;
997 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
998 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1000 BIO_printf(bio_err, "EdDSA sign failure\n");
1001 ERR_print_errors(bio_err);
1009 static int EdDSA_verify_loop(void *args)
1011 loopargs_t *tempargs = *(loopargs_t **) args;
1012 unsigned char *buf = tempargs->buf;
1013 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1014 unsigned char *eddsasig = tempargs->buf2;
1015 size_t eddsasigsize = tempargs->sigsize;
1018 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1019 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1021 BIO_printf(bio_err, "EdDSA verify failure\n");
1022 ERR_print_errors(bio_err);
1030 #ifndef OPENSSL_NO_SM2
1031 static long sm2_c[SM2_NUM][2];
1032 static int SM2_sign_loop(void *args)
1034 loopargs_t *tempargs = *(loopargs_t **) args;
1035 unsigned char *buf = tempargs->buf;
1036 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1037 unsigned char *sm2sig = tempargs->buf2;
1040 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1041 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1043 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1044 sm2sigsize = max_size;
1046 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1047 NULL, sm2_pkey[testnum])) {
1048 BIO_printf(bio_err, "SM2 init sign failure\n");
1049 ERR_print_errors(bio_err);
1053 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1056 BIO_printf(bio_err, "SM2 sign failure\n");
1057 ERR_print_errors(bio_err);
1061 /* update the latest returned size and always use the fixed buffer size */
1062 tempargs->sigsize = sm2sigsize;
1068 static int SM2_verify_loop(void *args)
1070 loopargs_t *tempargs = *(loopargs_t **) args;
1071 unsigned char *buf = tempargs->buf;
1072 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1073 unsigned char *sm2sig = tempargs->buf2;
1074 size_t sm2sigsize = tempargs->sigsize;
1076 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1078 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1079 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1080 NULL, sm2_pkey[testnum])) {
1081 BIO_printf(bio_err, "SM2 verify init failure\n");
1082 ERR_print_errors(bio_err);
1086 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1089 BIO_printf(bio_err, "SM2 verify failure\n");
1090 ERR_print_errors(bio_err);
1097 #endif /* OPENSSL_NO_SM2 */
1099 static int run_benchmark(int async_jobs,
1100 int (*loop_function) (void *), loopargs_t * loopargs)
1102 int job_op_count = 0;
1103 int total_op_count = 0;
1104 int num_inprogress = 0;
1105 int error = 0, i = 0, ret = 0;
1106 OSSL_ASYNC_FD job_fd = 0;
1107 size_t num_job_fds = 0;
1109 if (async_jobs == 0) {
1110 return loop_function((void *)&loopargs);
1113 for (i = 0; i < async_jobs && !error; i++) {
1114 loopargs_t *looparg_item = loopargs + i;
1116 /* Copy pointer content (looparg_t item address) into async context */
1117 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1118 &job_op_count, loop_function,
1119 (void *)&looparg_item, sizeof(looparg_item));
1125 if (job_op_count == -1) {
1128 total_op_count += job_op_count;
1133 BIO_printf(bio_err, "Failure in the job\n");
1134 ERR_print_errors(bio_err);
1140 while (num_inprogress > 0) {
1141 #if defined(OPENSSL_SYS_WINDOWS)
1143 #elif defined(OPENSSL_SYS_UNIX)
1144 int select_result = 0;
1145 OSSL_ASYNC_FD max_fd = 0;
1148 FD_ZERO(&waitfdset);
1150 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1151 if (loopargs[i].inprogress_job == NULL)
1154 if (!ASYNC_WAIT_CTX_get_all_fds
1155 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1156 || num_job_fds > 1) {
1157 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1158 ERR_print_errors(bio_err);
1162 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1164 FD_SET(job_fd, &waitfdset);
1165 if (job_fd > max_fd)
1169 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1171 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1172 "Decrease the value of async_jobs\n",
1173 max_fd, FD_SETSIZE);
1174 ERR_print_errors(bio_err);
1179 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1180 if (select_result == -1 && errno == EINTR)
1183 if (select_result == -1) {
1184 BIO_printf(bio_err, "Failure in the select\n");
1185 ERR_print_errors(bio_err);
1190 if (select_result == 0)
1194 for (i = 0; i < async_jobs; i++) {
1195 if (loopargs[i].inprogress_job == NULL)
1198 if (!ASYNC_WAIT_CTX_get_all_fds
1199 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1200 || num_job_fds > 1) {
1201 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1202 ERR_print_errors(bio_err);
1206 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1209 #if defined(OPENSSL_SYS_UNIX)
1210 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1212 #elif defined(OPENSSL_SYS_WINDOWS)
1213 if (num_job_fds == 1
1214 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1219 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1220 loopargs[i].wait_ctx, &job_op_count,
1221 loop_function, (void *)(loopargs + i),
1222 sizeof(loopargs_t));
1227 if (job_op_count == -1) {
1230 total_op_count += job_op_count;
1233 loopargs[i].inprogress_job = NULL;
1238 loopargs[i].inprogress_job = NULL;
1239 BIO_printf(bio_err, "Failure in the job\n");
1240 ERR_print_errors(bio_err);
1247 return error ? -1 : total_op_count;
1250 typedef struct ec_curve_st {
1254 size_t sigsize; /* only used for EdDSA curves */
1257 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1259 EVP_PKEY_CTX *kctx = NULL;
1260 EVP_PKEY *key = NULL;
1262 /* Ensure that the error queue is empty */
1263 if (ERR_peek_error()) {
1265 "WARNING: the error queue contains previous unhandled errors.\n");
1266 ERR_print_errors(bio_err);
1270 * Let's try to create a ctx directly from the NID: this works for
1271 * curves like Curve25519 that are not implemented through the low
1272 * level EC interface.
1273 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1274 * then we set the curve by NID before deriving the actual keygen
1275 * ctx for that specific curve.
1277 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1279 EVP_PKEY_CTX *pctx = NULL;
1280 EVP_PKEY *params = NULL;
1282 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1283 * "int_ctx_new:unsupported algorithm" error was added to the
1285 * We remove it from the error queue as we are handling it.
1287 unsigned long error = ERR_peek_error();
1289 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1290 /* check that the error origin matches */
1291 && ERR_GET_LIB(error) == ERR_LIB_EVP
1292 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1293 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1294 ERR_get_error(); /* pop error from queue */
1295 if (ERR_peek_error()) {
1297 "Unhandled error in the error queue during EC key setup.\n");
1298 ERR_print_errors(bio_err);
1302 /* Create the context for parameter generation */
1303 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1304 || EVP_PKEY_paramgen_init(pctx) <= 0
1305 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1307 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) {
1308 BIO_printf(bio_err, "EC params init failure.\n");
1309 ERR_print_errors(bio_err);
1310 EVP_PKEY_CTX_free(pctx);
1313 EVP_PKEY_CTX_free(pctx);
1315 /* Create the context for the key generation */
1316 kctx = EVP_PKEY_CTX_new(params, NULL);
1317 EVP_PKEY_free(params);
1320 || EVP_PKEY_keygen_init(kctx) <= 0
1321 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1322 BIO_printf(bio_err, "EC key generation failure.\n");
1323 ERR_print_errors(bio_err);
1326 EVP_PKEY_CTX_free(kctx);
1330 #define stop_it(do_it, test_num)\
1331 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1333 int speed_main(int argc, char **argv)
1336 loopargs_t *loopargs = NULL;
1338 const char *engine_id = NULL;
1339 EVP_CIPHER *evp_cipher = NULL;
1342 int async_init = 0, multiblock = 0, pr_header = 0;
1343 uint8_t doit[ALGOR_NUM] = { 0 };
1344 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1346 unsigned int size_num = SIZE_NUM;
1347 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1351 EVP_PKEY_CTX *genctx = NULL;
1356 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1357 ECDSA_SECONDS, ECDH_SECONDS,
1358 EdDSA_SECONDS, SM2_SECONDS,
1361 static const unsigned char key32[32] = {
1362 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1363 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1364 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1365 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1367 static const unsigned char deskey[] = {
1368 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1369 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1370 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1372 static const struct {
1373 const unsigned char *data;
1374 unsigned int length;
1377 { test512, sizeof(test512), 512 },
1378 { test1024, sizeof(test1024), 1024 },
1379 { test2048, sizeof(test2048), 2048 },
1380 { test3072, sizeof(test3072), 3072 },
1381 { test4096, sizeof(test4096), 4096 },
1382 { test7680, sizeof(test7680), 7680 },
1383 { test15360, sizeof(test15360), 15360 }
1385 uint8_t rsa_doit[RSA_NUM] = { 0 };
1386 int primes = RSA_DEFAULT_PRIME_NUM;
1387 #ifndef OPENSSL_NO_DH
1388 typedef struct ffdh_params_st {
1394 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1395 {"ffdh2048", NID_ffdhe2048, 2048},
1396 {"ffdh3072", NID_ffdhe3072, 3072},
1397 {"ffdh4096", NID_ffdhe4096, 4096},
1398 {"ffdh6144", NID_ffdhe6144, 6144},
1399 {"ffdh8192", NID_ffdhe8192, 8192}
1401 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1403 #endif /* OPENSSL_NO_DH */
1404 static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1405 uint8_t dsa_doit[DSA_NUM] = { 0 };
1407 * We only test over the following curves as they are representative, To
1408 * add tests over more curves, simply add the curve NID and curve name to
1409 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1410 * lists accordingly.
1412 static const EC_CURVE ec_curves[EC_NUM] = {
1414 {"secp160r1", NID_secp160r1, 160},
1415 {"nistp192", NID_X9_62_prime192v1, 192},
1416 {"nistp224", NID_secp224r1, 224},
1417 {"nistp256", NID_X9_62_prime256v1, 256},
1418 {"nistp384", NID_secp384r1, 384},
1419 {"nistp521", NID_secp521r1, 521},
1420 #ifndef OPENSSL_NO_EC2M
1422 {"nistk163", NID_sect163k1, 163},
1423 {"nistk233", NID_sect233k1, 233},
1424 {"nistk283", NID_sect283k1, 283},
1425 {"nistk409", NID_sect409k1, 409},
1426 {"nistk571", NID_sect571k1, 571},
1427 {"nistb163", NID_sect163r2, 163},
1428 {"nistb233", NID_sect233r1, 233},
1429 {"nistb283", NID_sect283r1, 283},
1430 {"nistb409", NID_sect409r1, 409},
1431 {"nistb571", NID_sect571r1, 571},
1433 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1434 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1435 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1436 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1437 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1438 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1439 /* Other and ECDH only ones */
1440 {"X25519", NID_X25519, 253},
1441 {"X448", NID_X448, 448}
1443 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1445 {"Ed25519", NID_ED25519, 253, 64},
1446 {"Ed448", NID_ED448, 456, 114}
1448 #ifndef OPENSSL_NO_SM2
1449 static const EC_CURVE sm2_curves[SM2_NUM] = {
1451 {"CurveSM2", NID_sm2, 256}
1453 uint8_t sm2_doit[SM2_NUM] = { 0 };
1455 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1456 uint8_t ecdh_doit[EC_NUM] = { 0 };
1457 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1459 /* checks declarated curves against choices list. */
1460 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1461 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1463 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1464 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1466 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1467 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1469 #ifndef OPENSSL_NO_SM2
1470 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1471 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1474 prog = opt_init(argc, argv, speed_options);
1475 while ((o = opt_next()) != OPT_EOF) {
1480 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1483 opt_help(speed_options);
1491 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1495 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1496 if (have_md(opt_arg()))
1497 evp_md_name = opt_arg();
1499 if (evp_cipher == NULL && evp_md_name == NULL) {
1500 ERR_clear_last_mark();
1502 "%s: %s is an unknown cipher or digest\n",
1510 if (!have_md(opt_arg())) {
1511 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1515 evp_mac_mdname = opt_arg();
1519 if (!have_cipher(opt_arg())) {
1520 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1524 evp_mac_ciphername = opt_arg();
1525 doit[D_EVP_CMAC] = 1;
1532 * In a forked execution, an engine might need to be
1533 * initialised by each child process, not by the parent.
1534 * So store the name here and run setup_engine() later on.
1536 engine_id = opt_arg();
1540 multi = atoi(opt_arg());
1544 #ifndef OPENSSL_NO_ASYNC
1545 async_jobs = atoi(opt_arg());
1546 if (!ASYNC_is_capable()) {
1548 "%s: async_jobs specified but async not supported\n",
1552 if (async_jobs > 99999) {
1553 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1559 misalign = opt_int_arg();
1560 if (misalign > MISALIGN) {
1562 "%s: Maximum offset is %d\n", prog, MISALIGN);
1571 #ifdef OPENSSL_NO_MULTIBLOCK
1573 "%s: -mb specified but multi-block support is disabled\n",
1582 case OPT_PROV_CASES:
1583 if (!opt_provider(o))
1587 primes = opt_int_arg();
1590 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1591 = seconds.ecdh = seconds.eddsa
1592 = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1595 lengths_single = atoi(opt_arg());
1596 lengths = &lengths_single;
1605 /* Remaining arguments are algorithms. */
1606 argc = opt_num_rest();
1609 if (!app_RAND_load())
1612 for (; *argv; argv++) {
1613 const char *algo = *argv;
1615 if (opt_found(algo, doit_choices, &i)) {
1619 if (strcmp(algo, "des") == 0) {
1620 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1623 if (strcmp(algo, "sha") == 0) {
1624 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1627 #ifndef OPENSSL_NO_DEPRECATED_3_0
1628 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1631 if (strncmp(algo, "rsa", 3) == 0) {
1632 if (algo[3] == '\0') {
1633 memset(rsa_doit, 1, sizeof(rsa_doit));
1636 if (opt_found(algo, rsa_choices, &i)) {
1641 #ifndef OPENSSL_NO_DH
1642 if (strncmp(algo, "ffdh", 4) == 0) {
1643 if (algo[4] == '\0') {
1644 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1647 if (opt_found(algo, ffdh_choices, &i)) {
1653 if (strncmp(algo, "dsa", 3) == 0) {
1654 if (algo[3] == '\0') {
1655 memset(dsa_doit, 1, sizeof(dsa_doit));
1658 if (opt_found(algo, dsa_choices, &i)) {
1663 if (strcmp(algo, "aes") == 0) {
1664 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1667 if (strcmp(algo, "camellia") == 0) {
1668 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1671 if (strncmp(algo, "ecdsa", 5) == 0) {
1672 if (algo[5] == '\0') {
1673 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1676 if (opt_found(algo, ecdsa_choices, &i)) {
1681 if (strncmp(algo, "ecdh", 4) == 0) {
1682 if (algo[4] == '\0') {
1683 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1686 if (opt_found(algo, ecdh_choices, &i)) {
1691 if (strcmp(algo, "eddsa") == 0) {
1692 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1695 if (opt_found(algo, eddsa_choices, &i)) {
1699 #ifndef OPENSSL_NO_SM2
1700 if (strcmp(algo, "sm2") == 0) {
1701 memset(sm2_doit, 1, sizeof(sm2_doit));
1704 if (opt_found(algo, sm2_choices, &i)) {
1709 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1715 if (evp_cipher == NULL) {
1716 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1718 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1719 EVP_CIPH_FLAG_AEAD_CIPHER)) {
1720 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1721 EVP_CIPHER_get0_name(evp_cipher));
1726 if (evp_cipher == NULL) {
1727 BIO_printf(bio_err, "-mb can be used only with a multi-block"
1728 " capable cipher\n");
1730 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1731 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1732 BIO_printf(bio_err, "%s is not a multi-block capable\n",
1733 EVP_CIPHER_get0_name(evp_cipher));
1735 } else if (async_jobs > 0) {
1736 BIO_printf(bio_err, "Async mode is not supported with -mb");
1741 /* Initialize the job pool if async mode is enabled */
1742 if (async_jobs > 0) {
1743 async_init = ASYNC_init_thread(async_jobs, async_jobs);
1745 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1750 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1752 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1753 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1755 for (i = 0; i < loopargs_len; i++) {
1756 if (async_jobs > 0) {
1757 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1758 if (loopargs[i].wait_ctx == NULL) {
1759 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1764 buflen = lengths[size_num - 1];
1765 if (buflen < 36) /* size of random vector in RSA benchmark */
1767 buflen += MAX_MISALIGNMENT + 1;
1768 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1769 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1770 memset(loopargs[i].buf_malloc, 0, buflen);
1771 memset(loopargs[i].buf2_malloc, 0, buflen);
1773 /* Align the start of buffers on a 64 byte boundary */
1774 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1775 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1776 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1777 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1778 #ifndef OPENSSL_NO_DH
1779 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1780 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1785 if (multi && do_multi(multi, size_num))
1789 /* Initialize the engine after the fork */
1790 e = setup_engine(engine_id, 0);
1792 /* No parameters; turn on everything. */
1793 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1796 memset(doit, 1, sizeof(doit));
1797 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1799 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1800 if (!have_md(names[i]))
1803 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1804 if (!have_cipher(names[i]))
1807 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1808 app_get0_propq())) != NULL)
1812 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1813 app_get0_propq())) != NULL)
1818 memset(rsa_doit, 1, sizeof(rsa_doit));
1819 #ifndef OPENSSL_NO_DH
1820 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1822 memset(dsa_doit, 1, sizeof(dsa_doit));
1823 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1824 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1825 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1826 #ifndef OPENSSL_NO_SM2
1827 memset(sm2_doit, 1, sizeof(sm2_doit));
1830 for (i = 0; i < ALGOR_NUM; i++)
1834 if (usertime == 0 && !mr)
1836 "You have chosen to measure elapsed time "
1837 "instead of user CPU time.\n");
1840 signal(SIGALRM, alarmed);
1844 for (testnum = 0; testnum < size_num; testnum++) {
1845 print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1848 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1850 print_result(D_MD2, testnum, count, d);
1857 for (testnum = 0; testnum < size_num; testnum++) {
1858 print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1861 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1863 print_result(D_MDC2, testnum, count, d);
1870 for (testnum = 0; testnum < size_num; testnum++) {
1871 print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1874 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1876 print_result(D_MD4, testnum, count, d);
1883 for (testnum = 0; testnum < size_num; testnum++) {
1884 print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1887 count = run_benchmark(async_jobs, MD5_loop, loopargs);
1889 print_result(D_MD5, testnum, count, d);
1896 for (testnum = 0; testnum < size_num; testnum++) {
1897 print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1900 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1902 print_result(D_SHA1, testnum, count, d);
1908 if (doit[D_SHA256]) {
1909 for (testnum = 0; testnum < size_num; testnum++) {
1910 print_message(names[D_SHA256], c[D_SHA256][testnum],
1911 lengths[testnum], seconds.sym);
1913 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1915 print_result(D_SHA256, testnum, count, d);
1921 if (doit[D_SHA512]) {
1922 for (testnum = 0; testnum < size_num; testnum++) {
1923 print_message(names[D_SHA512], c[D_SHA512][testnum],
1924 lengths[testnum], seconds.sym);
1926 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1928 print_result(D_SHA512, testnum, count, d);
1934 if (doit[D_WHIRLPOOL]) {
1935 for (testnum = 0; testnum < size_num; testnum++) {
1936 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
1937 lengths[testnum], seconds.sym);
1939 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
1941 print_result(D_WHIRLPOOL, testnum, count, d);
1947 if (doit[D_RMD160]) {
1948 for (testnum = 0; testnum < size_num; testnum++) {
1949 print_message(names[D_RMD160], c[D_RMD160][testnum],
1950 lengths[testnum], seconds.sym);
1952 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
1954 print_result(D_RMD160, testnum, count, d);
1961 static const char hmac_key[] = "This is a key...";
1962 int len = strlen(hmac_key);
1963 EVP_MAC *mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1965 OSSL_PARAM params[3];
1967 if (mac == NULL || evp_mac_mdname == NULL)
1970 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
1972 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
1973 names[D_HMAC] = evp_hmac_name;
1976 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
1979 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
1980 (char *)hmac_key, len);
1981 params[2] = OSSL_PARAM_construct_end();
1983 for (i = 0; i < loopargs_len; i++) {
1984 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
1985 if (loopargs[i].mctx == NULL)
1988 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
1991 for (testnum = 0; testnum < size_num; testnum++) {
1992 print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
1995 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
1997 print_result(D_HMAC, testnum, count, d);
2001 for (i = 0; i < loopargs_len; i++)
2002 EVP_MAC_CTX_free(loopargs[i].mctx);
2006 if (doit[D_CBC_DES]) {
2009 for (i = 0; st && i < loopargs_len; i++) {
2010 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2011 sizeof(deskey) / 3);
2012 st = loopargs[i].ctx != NULL;
2014 algindex = D_CBC_DES;
2015 for (testnum = 0; st && testnum < size_num; testnum++) {
2016 print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2017 lengths[testnum], seconds.sym);
2019 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2021 print_result(D_CBC_DES, testnum, count, d);
2023 for (i = 0; i < loopargs_len; i++)
2024 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2027 if (doit[D_EDE3_DES]) {
2030 for (i = 0; st && i < loopargs_len; i++) {
2031 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2033 st = loopargs[i].ctx != NULL;
2035 algindex = D_EDE3_DES;
2036 for (testnum = 0; st && testnum < size_num; testnum++) {
2037 print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2038 lengths[testnum], seconds.sym);
2041 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2043 print_result(D_EDE3_DES, testnum, count, d);
2045 for (i = 0; i < loopargs_len; i++)
2046 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2049 for (k = 0; k < 3; k++) {
2050 algindex = D_CBC_128_AES + k;
2051 if (doit[algindex]) {
2054 keylen = 16 + k * 8;
2055 for (i = 0; st && i < loopargs_len; i++) {
2056 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2058 st = loopargs[i].ctx != NULL;
2061 for (testnum = 0; st && testnum < size_num; testnum++) {
2062 print_message(names[algindex], c[algindex][testnum],
2063 lengths[testnum], seconds.sym);
2066 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2068 print_result(algindex, testnum, count, d);
2070 for (i = 0; i < loopargs_len; i++)
2071 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2075 for (k = 0; k < 3; k++) {
2076 algindex = D_CBC_128_CML + k;
2077 if (doit[algindex]) {
2080 keylen = 16 + k * 8;
2081 for (i = 0; st && i < loopargs_len; i++) {
2082 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2084 st = loopargs[i].ctx != NULL;
2087 for (testnum = 0; st && testnum < size_num; testnum++) {
2088 print_message(names[algindex], c[algindex][testnum],
2089 lengths[testnum], seconds.sym);
2092 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2094 print_result(algindex, testnum, count, d);
2096 for (i = 0; i < loopargs_len; i++)
2097 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2101 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2102 if (doit[algindex]) {
2106 for (i = 0; st && i < loopargs_len; i++) {
2107 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2109 st = loopargs[i].ctx != NULL;
2112 for (testnum = 0; st && testnum < size_num; testnum++) {
2113 print_message(names[algindex], c[algindex][testnum],
2114 lengths[testnum], seconds.sym);
2117 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2119 print_result(algindex, testnum, count, d);
2121 for (i = 0; i < loopargs_len; i++)
2122 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2125 if (doit[D_GHASH]) {
2126 static const char gmac_iv[] = "0123456789ab";
2127 EVP_MAC *mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2129 OSSL_PARAM params[3];
2134 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2136 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2138 sizeof(gmac_iv) - 1);
2139 params[2] = OSSL_PARAM_construct_end();
2141 for (i = 0; i < loopargs_len; i++) {
2142 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2143 if (loopargs[i].mctx == NULL)
2146 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2149 for (testnum = 0; testnum < size_num; testnum++) {
2150 print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2153 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2155 print_result(D_GHASH, testnum, count, d);
2159 for (i = 0; i < loopargs_len; i++)
2160 EVP_MAC_CTX_free(loopargs[i].mctx);
2165 for (testnum = 0; testnum < size_num; testnum++) {
2166 print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2169 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2171 print_result(D_RAND, testnum, count, d);
2176 if (evp_cipher != NULL) {
2177 int (*loopfunc) (void *) = EVP_Update_loop;
2179 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2180 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2181 multiblock_speed(evp_cipher, lengths_single, &seconds);
2186 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2188 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2189 loopfunc = EVP_Update_loop_ccm;
2190 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2191 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2192 loopfunc = EVP_Update_loop_aead;
2193 if (lengths == lengths_list) {
2194 lengths = aead_lengths_list;
2195 size_num = OSSL_NELEM(aead_lengths_list);
2199 for (testnum = 0; testnum < size_num; testnum++) {
2200 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2203 for (k = 0; k < loopargs_len; k++) {
2204 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2205 if (loopargs[k].ctx == NULL) {
2206 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2209 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2210 NULL, iv, decrypt ? 0 : 1)) {
2211 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2212 ERR_print_errors(bio_err);
2216 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2218 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2219 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2220 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2221 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2222 loopargs[k].key, NULL, -1)) {
2223 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2224 ERR_print_errors(bio_err);
2227 OPENSSL_clear_free(loopargs[k].key, keylen);
2229 /* SIV mode only allows for a single Update operation */
2230 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2231 EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_SET_SPEED,
2236 count = run_benchmark(async_jobs, loopfunc, loopargs);
2238 for (k = 0; k < loopargs_len; k++)
2239 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2240 print_result(D_EVP, testnum, count, d);
2242 } else if (evp_md_name != NULL) {
2243 names[D_EVP] = evp_md_name;
2245 for (testnum = 0; testnum < size_num; testnum++) {
2246 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2249 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2251 print_result(D_EVP, testnum, count, d);
2258 if (doit[D_EVP_CMAC]) {
2259 EVP_MAC *mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC",
2261 OSSL_PARAM params[3];
2262 EVP_CIPHER *cipher = NULL;
2264 if (mac == NULL || evp_mac_ciphername == NULL)
2266 if (!opt_cipher(evp_mac_ciphername, &cipher))
2269 keylen = EVP_CIPHER_get_key_length(cipher);
2270 EVP_CIPHER_free(cipher);
2271 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2272 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2275 evp_cmac_name = app_malloc(sizeof("cmac()")
2276 + strlen(evp_mac_ciphername), "CMAC name");
2277 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2278 names[D_EVP_CMAC] = evp_cmac_name;
2280 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2281 evp_mac_ciphername, 0);
2282 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2283 (char *)key32, keylen);
2284 params[2] = OSSL_PARAM_construct_end();
2286 for (i = 0; i < loopargs_len; i++) {
2287 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2288 if (loopargs[i].mctx == NULL)
2291 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2295 for (testnum = 0; testnum < size_num; testnum++) {
2296 print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2297 lengths[testnum], seconds.sym);
2299 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2301 print_result(D_EVP_CMAC, testnum, count, d);
2305 for (i = 0; i < loopargs_len; i++)
2306 EVP_MAC_CTX_free(loopargs[i].mctx);
2310 for (i = 0; i < loopargs_len; i++)
2311 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2314 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2315 EVP_PKEY *rsa_key = NULL;
2318 if (!rsa_doit[testnum])
2321 if (primes > RSA_DEFAULT_PRIME_NUM) {
2322 /* we haven't set keys yet, generate multi-prime RSA keys */
2325 && BN_set_word(bn, RSA_F4)
2326 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2327 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2328 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2329 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2330 && EVP_PKEY_keygen(genctx, &rsa_key);
2333 EVP_PKEY_CTX_free(genctx);
2336 const unsigned char *p = rsa_keys[testnum].data;
2338 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2339 rsa_keys[testnum].length)) != NULL;
2342 for (i = 0; st && i < loopargs_len; i++) {
2343 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2344 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2345 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2346 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2348 &loopargs[i].sigsize,
2349 loopargs[i].buf, 36) <= 0)
2354 "RSA sign setup failure. No RSA sign will be done.\n");
2355 ERR_print_errors(bio_err);
2358 pkey_print_message("private", "rsa",
2359 rsa_c[testnum][0], rsa_keys[testnum].bits,
2361 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2363 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2366 mr ? "+R1:%ld:%d:%.2f\n"
2367 : "%ld %u bits private RSA's in %.2fs\n",
2368 count, rsa_keys[testnum].bits, d);
2369 rsa_results[testnum][0] = (double)count / d;
2373 for (i = 0; st && i < loopargs_len; i++) {
2374 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2376 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2377 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2378 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2380 loopargs[i].sigsize,
2381 loopargs[i].buf, 36) <= 0)
2386 "RSA verify setup failure. No RSA verify will be done.\n");
2387 ERR_print_errors(bio_err);
2388 rsa_doit[testnum] = 0;
2390 pkey_print_message("public", "rsa",
2391 rsa_c[testnum][1], rsa_keys[testnum].bits,
2394 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2397 mr ? "+R2:%ld:%d:%.2f\n"
2398 : "%ld %u bits public RSA's in %.2fs\n",
2399 count, rsa_keys[testnum].bits, d);
2400 rsa_results[testnum][1] = (double)count / d;
2403 if (op_count <= 1) {
2404 /* if longer than 10s, don't do any more */
2405 stop_it(rsa_doit, testnum);
2407 EVP_PKEY_free(rsa_key);
2410 for (testnum = 0; testnum < DSA_NUM; testnum++) {
2411 EVP_PKEY *dsa_key = NULL;
2414 if (!dsa_doit[testnum])
2417 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2419 for (i = 0; st && i < loopargs_len; i++) {
2420 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2422 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2423 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2425 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2427 &loopargs[i].sigsize,
2428 loopargs[i].buf, 20) <= 0)
2433 "DSA sign setup failure. No DSA sign will be done.\n");
2434 ERR_print_errors(bio_err);
2437 pkey_print_message("sign", "dsa",
2438 dsa_c[testnum][0], dsa_bits[testnum],
2441 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2444 mr ? "+R3:%ld:%u:%.2f\n"
2445 : "%ld %u bits DSA signs in %.2fs\n",
2446 count, dsa_bits[testnum], d);
2447 dsa_results[testnum][0] = (double)count / d;
2451 for (i = 0; st && i < loopargs_len; i++) {
2452 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2454 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2455 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2456 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2458 loopargs[i].sigsize,
2459 loopargs[i].buf, 36) <= 0)
2464 "DSA verify setup failure. No DSA verify will be done.\n");
2465 ERR_print_errors(bio_err);
2466 dsa_doit[testnum] = 0;
2468 pkey_print_message("verify", "dsa",
2469 dsa_c[testnum][1], dsa_bits[testnum],
2472 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2475 mr ? "+R4:%ld:%u:%.2f\n"
2476 : "%ld %u bits DSA verify in %.2fs\n",
2477 count, dsa_bits[testnum], d);
2478 dsa_results[testnum][1] = (double)count / d;
2481 if (op_count <= 1) {
2482 /* if longer than 10s, don't do any more */
2483 stop_it(dsa_doit, testnum);
2485 EVP_PKEY_free(dsa_key);
2488 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2489 EVP_PKEY *ecdsa_key = NULL;
2492 if (!ecdsa_doit[testnum])
2495 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2497 for (i = 0; st && i < loopargs_len; i++) {
2498 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2500 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2501 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2503 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2505 &loopargs[i].sigsize,
2506 loopargs[i].buf, 20) <= 0)
2511 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2512 ERR_print_errors(bio_err);
2515 pkey_print_message("sign", "ecdsa",
2516 ecdsa_c[testnum][0], ec_curves[testnum].bits,
2519 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2522 mr ? "+R5:%ld:%u:%.2f\n"
2523 : "%ld %u bits ECDSA signs in %.2fs\n",
2524 count, ec_curves[testnum].bits, d);
2525 ecdsa_results[testnum][0] = (double)count / d;
2529 for (i = 0; st && i < loopargs_len; i++) {
2530 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2532 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2533 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2534 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2536 loopargs[i].sigsize,
2537 loopargs[i].buf, 20) <= 0)
2542 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2543 ERR_print_errors(bio_err);
2544 ecdsa_doit[testnum] = 0;
2546 pkey_print_message("verify", "ecdsa",
2547 ecdsa_c[testnum][1], ec_curves[testnum].bits,
2550 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2553 mr ? "+R6:%ld:%u:%.2f\n"
2554 : "%ld %u bits ECDSA verify in %.2fs\n",
2555 count, ec_curves[testnum].bits, d);
2556 ecdsa_results[testnum][1] = (double)count / d;
2559 if (op_count <= 1) {
2560 /* if longer than 10s, don't do any more */
2561 stop_it(ecdsa_doit, testnum);
2565 for (testnum = 0; testnum < EC_NUM; testnum++) {
2566 int ecdh_checks = 1;
2568 if (!ecdh_doit[testnum])
2571 for (i = 0; i < loopargs_len; i++) {
2572 EVP_PKEY_CTX *test_ctx = NULL;
2573 EVP_PKEY_CTX *ctx = NULL;
2574 EVP_PKEY *key_A = NULL;
2575 EVP_PKEY *key_B = NULL;
2579 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2580 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2581 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2582 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2583 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2584 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2585 || outlen == 0 /* ensure outlen is a valid size */
2586 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2588 BIO_printf(bio_err, "ECDH key generation failure.\n");
2589 ERR_print_errors(bio_err);
2595 * Here we perform a test run, comparing the output of a*B and b*A;
2596 * we try this here and assume that further EVP_PKEY_derive calls
2597 * never fail, so we can skip checks in the actually benchmarked
2598 * code, for maximum performance.
2600 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2601 || !EVP_PKEY_derive_init(test_ctx) /* init derivation test_ctx */
2602 || !EVP_PKEY_derive_set_peer(test_ctx, key_A) /* set peer pubkey in test_ctx */
2603 || !EVP_PKEY_derive(test_ctx, NULL, &test_outlen) /* determine max length */
2604 || !EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) /* compute a*B */
2605 || !EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) /* compute b*A */
2606 || test_outlen != outlen /* compare output length */) {
2608 BIO_printf(bio_err, "ECDH computation failure.\n");
2609 ERR_print_errors(bio_err);
2614 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2615 if (CRYPTO_memcmp(loopargs[i].secret_a,
2616 loopargs[i].secret_b, outlen)) {
2618 BIO_printf(bio_err, "ECDH computations don't match.\n");
2619 ERR_print_errors(bio_err);
2624 loopargs[i].ecdh_ctx[testnum] = ctx;
2625 loopargs[i].outlen[testnum] = outlen;
2627 EVP_PKEY_free(key_A);
2628 EVP_PKEY_free(key_B);
2629 EVP_PKEY_CTX_free(test_ctx);
2632 if (ecdh_checks != 0) {
2633 pkey_print_message("", "ecdh",
2635 ec_curves[testnum].bits, seconds.ecdh);
2638 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2641 mr ? "+R7:%ld:%d:%.2f\n" :
2642 "%ld %u-bits ECDH ops in %.2fs\n", count,
2643 ec_curves[testnum].bits, d);
2644 ecdh_results[testnum][0] = (double)count / d;
2648 if (op_count <= 1) {
2649 /* if longer than 10s, don't do any more */
2650 stop_it(ecdh_doit, testnum);
2654 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2656 EVP_PKEY *ed_pkey = NULL;
2657 EVP_PKEY_CTX *ed_pctx = NULL;
2659 if (!eddsa_doit[testnum])
2660 continue; /* Ignore Curve */
2661 for (i = 0; i < loopargs_len; i++) {
2662 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2663 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2667 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2668 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2673 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2675 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2676 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2678 EVP_PKEY_CTX_free(ed_pctx);
2681 EVP_PKEY_CTX_free(ed_pctx);
2683 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2686 EVP_PKEY_free(ed_pkey);
2689 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2690 NULL, NULL, ed_pkey)) {
2692 EVP_PKEY_free(ed_pkey);
2696 EVP_PKEY_free(ed_pkey);
2700 BIO_printf(bio_err, "EdDSA failure.\n");
2701 ERR_print_errors(bio_err);
2704 for (i = 0; i < loopargs_len; i++) {
2705 /* Perform EdDSA signature test */
2706 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2707 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2708 loopargs[i].buf2, &loopargs[i].sigsize,
2709 loopargs[i].buf, 20);
2715 "EdDSA sign failure. No EdDSA sign will be done.\n");
2716 ERR_print_errors(bio_err);
2719 pkey_print_message("sign", ed_curves[testnum].name,
2720 eddsa_c[testnum][0],
2721 ed_curves[testnum].bits, seconds.eddsa);
2723 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2727 mr ? "+R8:%ld:%u:%s:%.2f\n" :
2728 "%ld %u bits %s signs in %.2fs \n",
2729 count, ed_curves[testnum].bits,
2730 ed_curves[testnum].name, d);
2731 eddsa_results[testnum][0] = (double)count / d;
2734 /* Perform EdDSA verification test */
2735 for (i = 0; i < loopargs_len; i++) {
2736 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2737 loopargs[i].buf2, loopargs[i].sigsize,
2738 loopargs[i].buf, 20);
2744 "EdDSA verify failure. No EdDSA verify will be done.\n");
2745 ERR_print_errors(bio_err);
2746 eddsa_doit[testnum] = 0;
2748 pkey_print_message("verify", ed_curves[testnum].name,
2749 eddsa_c[testnum][1],
2750 ed_curves[testnum].bits, seconds.eddsa);
2752 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2755 mr ? "+R9:%ld:%u:%s:%.2f\n"
2756 : "%ld %u bits %s verify in %.2fs\n",
2757 count, ed_curves[testnum].bits,
2758 ed_curves[testnum].name, d);
2759 eddsa_results[testnum][1] = (double)count / d;
2762 if (op_count <= 1) {
2763 /* if longer than 10s, don't do any more */
2764 stop_it(eddsa_doit, testnum);
2769 #ifndef OPENSSL_NO_SM2
2770 for (testnum = 0; testnum < SM2_NUM; testnum++) {
2772 EVP_PKEY *sm2_pkey = NULL;
2774 if (!sm2_doit[testnum])
2775 continue; /* Ignore Curve */
2776 /* Init signing and verification */
2777 for (i = 0; i < loopargs_len; i++) {
2778 EVP_PKEY_CTX *sm2_pctx = NULL;
2779 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2780 EVP_PKEY_CTX *pctx = NULL;
2783 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2784 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2785 if (loopargs[i].sm2_ctx[testnum] == NULL
2786 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2791 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2792 || EVP_PKEY_keygen_init(pctx) <= 0
2793 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2794 sm2_curves[testnum].nid) <= 0
2795 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2796 EVP_PKEY_CTX_free(pctx);
2800 st = 0; /* set back to zero */
2801 /* attach it sooner to rely on main final cleanup */
2802 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2803 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2805 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2806 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2807 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2808 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2812 /* attach them directly to respective ctx */
2813 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2814 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2817 * No need to allow user to set an explicit ID here, just use
2818 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2820 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2821 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2824 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2825 EVP_sm3(), NULL, sm2_pkey))
2827 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2828 EVP_sm3(), NULL, sm2_pkey))
2830 st = 1; /* mark loop as succeeded */
2833 BIO_printf(bio_err, "SM2 init failure.\n");
2834 ERR_print_errors(bio_err);
2837 for (i = 0; i < loopargs_len; i++) {
2838 /* Perform SM2 signature test */
2839 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2840 loopargs[i].buf2, &loopargs[i].sigsize,
2841 loopargs[i].buf, 20);
2847 "SM2 sign failure. No SM2 sign will be done.\n");
2848 ERR_print_errors(bio_err);
2851 pkey_print_message("sign", sm2_curves[testnum].name,
2853 sm2_curves[testnum].bits, seconds.sm2);
2855 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2859 mr ? "+R10:%ld:%u:%s:%.2f\n" :
2860 "%ld %u bits %s signs in %.2fs \n",
2861 count, sm2_curves[testnum].bits,
2862 sm2_curves[testnum].name, d);
2863 sm2_results[testnum][0] = (double)count / d;
2867 /* Perform SM2 verification test */
2868 for (i = 0; i < loopargs_len; i++) {
2869 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2870 loopargs[i].buf2, loopargs[i].sigsize,
2871 loopargs[i].buf, 20);
2877 "SM2 verify failure. No SM2 verify will be done.\n");
2878 ERR_print_errors(bio_err);
2879 sm2_doit[testnum] = 0;
2881 pkey_print_message("verify", sm2_curves[testnum].name,
2883 sm2_curves[testnum].bits, seconds.sm2);
2885 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2888 mr ? "+R11:%ld:%u:%s:%.2f\n"
2889 : "%ld %u bits %s verify in %.2fs\n",
2890 count, sm2_curves[testnum].bits,
2891 sm2_curves[testnum].name, d);
2892 sm2_results[testnum][1] = (double)count / d;
2895 if (op_count <= 1) {
2896 /* if longer than 10s, don't do any more */
2897 for (testnum++; testnum < SM2_NUM; testnum++)
2898 sm2_doit[testnum] = 0;
2902 #endif /* OPENSSL_NO_SM2 */
2904 #ifndef OPENSSL_NO_DH
2905 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2906 int ffdh_checks = 1;
2908 if (!ffdh_doit[testnum])
2911 for (i = 0; i < loopargs_len; i++) {
2912 EVP_PKEY *pkey_A = NULL;
2913 EVP_PKEY *pkey_B = NULL;
2914 EVP_PKEY_CTX *ffdh_ctx = NULL;
2915 EVP_PKEY_CTX *test_ctx = NULL;
2919 /* Ensure that the error queue is empty */
2920 if (ERR_peek_error()) {
2922 "WARNING: the error queue contains previous unhandled errors.\n");
2923 ERR_print_errors(bio_err);
2926 pkey_A = EVP_PKEY_new();
2928 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2929 ERR_print_errors(bio_err);
2934 pkey_B = EVP_PKEY_new();
2936 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2937 ERR_print_errors(bio_err);
2943 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2945 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2946 ERR_print_errors(bio_err);
2952 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
2953 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
2954 ERR_print_errors(bio_err);
2959 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
2960 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
2961 ERR_print_errors(bio_err);
2967 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
2968 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
2969 BIO_printf(bio_err, "FFDH key generation failure.\n");
2970 ERR_print_errors(bio_err);
2976 EVP_PKEY_CTX_free(ffdh_ctx);
2979 * check if the derivation works correctly both ways so that
2980 * we know if future derive calls will fail, and we can skip
2981 * error checking in benchmarked code
2983 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
2984 if (ffdh_ctx == NULL) {
2985 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2986 ERR_print_errors(bio_err);
2991 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
2992 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
2993 ERR_print_errors(bio_err);
2998 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
2999 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3000 ERR_print_errors(bio_err);
3005 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3006 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3007 ERR_print_errors(bio_err);
3012 if (secret_size > MAX_FFDH_SIZE) {
3013 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3018 if (EVP_PKEY_derive(ffdh_ctx,
3019 loopargs[i].secret_ff_a,
3020 &secret_size) <= 0) {
3021 BIO_printf(bio_err, "Shared secret derive failure.\n");
3022 ERR_print_errors(bio_err);
3027 /* Now check from side B */
3028 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3030 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3031 ERR_print_errors(bio_err);
3036 if (!EVP_PKEY_derive_init(test_ctx) ||
3037 !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) ||
3038 !EVP_PKEY_derive(test_ctx, NULL, &test_out) ||
3039 !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) ||
3040 test_out != secret_size) {
3041 BIO_printf(bio_err, "FFDH computation failure.\n");
3047 /* compare the computed secrets */
3048 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3049 loopargs[i].secret_ff_b, secret_size)) {
3050 BIO_printf(bio_err, "FFDH computations don't match.\n");
3051 ERR_print_errors(bio_err);
3057 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3059 EVP_PKEY_free(pkey_A);
3061 EVP_PKEY_free(pkey_B);
3063 EVP_PKEY_CTX_free(test_ctx);
3066 if (ffdh_checks != 0) {
3067 pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3068 ffdh_params[testnum].bits, seconds.ffdh);
3071 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3074 mr ? "+R12:%ld:%d:%.2f\n" :
3075 "%ld %u-bits FFDH ops in %.2fs\n", count,
3076 ffdh_params[testnum].bits, d);
3077 ffdh_results[testnum][0] = (double)count / d;
3080 if (op_count <= 1) {
3081 /* if longer than 10s, don't do any more */
3082 stop_it(ffdh_doit, testnum);
3085 #endif /* OPENSSL_NO_DH */
3090 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3091 printf("built on: %s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3093 printf("%s ", BN_options());
3094 printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3095 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3102 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3105 for (testnum = 0; testnum < size_num; testnum++)
3106 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3110 for (k = 0; k < ALGOR_NUM; k++) {
3114 printf("+F:%u:%s", k, names[k]);
3116 printf("%-13s", names[k]);
3117 for (testnum = 0; testnum < size_num; testnum++) {
3118 if (results[k][testnum] > 10000 && !mr)
3119 printf(" %11.2fk", results[k][testnum] / 1e3);
3121 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3126 for (k = 0; k < RSA_NUM; k++) {
3129 if (testnum && !mr) {
3130 printf("%18ssign verify sign/s verify/s\n", " ");
3134 printf("+F2:%u:%u:%f:%f\n",
3135 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3137 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3138 rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3139 rsa_results[k][0], rsa_results[k][1]);
3142 for (k = 0; k < DSA_NUM; k++) {
3145 if (testnum && !mr) {
3146 printf("%18ssign verify sign/s verify/s\n", " ");
3150 printf("+F3:%u:%u:%f:%f\n",
3151 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3153 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3154 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3155 dsa_results[k][0], dsa_results[k][1]);
3158 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3161 if (testnum && !mr) {
3162 printf("%30ssign verify sign/s verify/s\n", " ");
3167 printf("+F4:%u:%u:%f:%f\n",
3168 k, ec_curves[k].bits,
3169 ecdsa_results[k][0], ecdsa_results[k][1]);
3171 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3172 ec_curves[k].bits, ec_curves[k].name,
3173 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3174 ecdsa_results[k][0], ecdsa_results[k][1]);
3178 for (k = 0; k < EC_NUM; k++) {
3181 if (testnum && !mr) {
3182 printf("%30sop op/s\n", " ");
3186 printf("+F5:%u:%u:%f:%f\n",
3187 k, ec_curves[k].bits,
3188 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3191 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3192 ec_curves[k].bits, ec_curves[k].name,
3193 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3197 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3200 if (testnum && !mr) {
3201 printf("%30ssign verify sign/s verify/s\n", " ");
3206 printf("+F6:%u:%u:%s:%f:%f\n",
3207 k, ed_curves[k].bits, ed_curves[k].name,
3208 eddsa_results[k][0], eddsa_results[k][1]);
3210 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3211 ed_curves[k].bits, ed_curves[k].name,
3212 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3213 eddsa_results[k][0], eddsa_results[k][1]);
3216 #ifndef OPENSSL_NO_SM2
3218 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3221 if (testnum && !mr) {
3222 printf("%30ssign verify sign/s verify/s\n", " ");
3227 printf("+F7:%u:%u:%s:%f:%f\n",
3228 k, sm2_curves[k].bits, sm2_curves[k].name,
3229 sm2_results[k][0], sm2_results[k][1]);
3231 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3232 sm2_curves[k].bits, sm2_curves[k].name,
3233 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3234 sm2_results[k][0], sm2_results[k][1]);
3237 #ifndef OPENSSL_NO_DH
3239 for (k = 0; k < FFDH_NUM; k++) {
3242 if (testnum && !mr) {
3243 printf("%23sop op/s\n", " ");
3247 printf("+F8:%u:%u:%f:%f\n",
3248 k, ffdh_params[k].bits,
3249 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3252 printf("%4u bits ffdh %8.4fs %8.1f\n",
3253 ffdh_params[k].bits,
3254 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3256 #endif /* OPENSSL_NO_DH */
3261 ERR_print_errors(bio_err);
3262 for (i = 0; i < loopargs_len; i++) {
3263 OPENSSL_free(loopargs[i].buf_malloc);
3264 OPENSSL_free(loopargs[i].buf2_malloc);
3267 EVP_PKEY_CTX_free(genctx);
3268 for (k = 0; k < RSA_NUM; k++) {
3269 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3270 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3272 #ifndef OPENSSL_NO_DH
3273 OPENSSL_free(loopargs[i].secret_ff_a);
3274 OPENSSL_free(loopargs[i].secret_ff_b);
3275 for (k = 0; k < FFDH_NUM; k++)
3276 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3278 for (k = 0; k < DSA_NUM; k++) {
3279 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3280 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3282 for (k = 0; k < ECDSA_NUM; k++) {
3283 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3284 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3286 for (k = 0; k < EC_NUM; k++)
3287 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3288 for (k = 0; k < EdDSA_NUM; k++) {
3289 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3290 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3292 #ifndef OPENSSL_NO_SM2
3293 for (k = 0; k < SM2_NUM; k++) {
3294 EVP_PKEY_CTX *pctx = NULL;
3296 /* free signing ctx */
3297 if (loopargs[i].sm2_ctx[k] != NULL
3298 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3299 EVP_PKEY_CTX_free(pctx);
3300 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3301 /* free verification ctx */
3302 if (loopargs[i].sm2_vfy_ctx[k] != NULL
3303 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3304 EVP_PKEY_CTX_free(pctx);
3305 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3307 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3310 OPENSSL_free(loopargs[i].secret_a);
3311 OPENSSL_free(loopargs[i].secret_b);
3313 OPENSSL_free(evp_hmac_name);
3314 OPENSSL_free(evp_cmac_name);
3316 if (async_jobs > 0) {
3317 for (i = 0; i < loopargs_len; i++)
3318 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3322 ASYNC_cleanup_thread();
3324 OPENSSL_free(loopargs);
3326 EVP_CIPHER_free(evp_cipher);
3330 static void print_message(const char *s, long num, int length, int tm)
3333 mr ? "+DT:%s:%d:%d\n"
3334 : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3335 (void)BIO_flush(bio_err);
3340 static void pkey_print_message(const char *str, const char *str2, long num,
3341 unsigned int bits, int tm)
3344 mr ? "+DTP:%d:%s:%s:%d\n"
3345 : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3346 (void)BIO_flush(bio_err);
3351 static void print_result(int alg, int run_no, int count, double time_used)
3354 BIO_printf(bio_err, "%s error!\n", names[alg]);
3355 ERR_print_errors(bio_err);
3359 mr ? "+R:%d:%s:%f\n"
3360 : "%d %s's in %.2fs\n", count, names[alg], time_used);
3361 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3365 static char *sstrsep(char **string, const char *delim)
3368 char *token = *string;
3373 memset(isdelim, 0, sizeof(isdelim));
3377 isdelim[(unsigned char)(*delim)] = 1;
3381 while (!isdelim[(unsigned char)(**string)])
3392 static int do_multi(int multi, int size_num)
3397 static char sep[] = ":";
3399 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3400 for (n = 0; n < multi; ++n) {
3401 if (pipe(fd) == -1) {
3402 BIO_printf(bio_err, "pipe failure\n");
3406 (void)BIO_flush(bio_err);
3413 if (dup(fd[1]) == -1) {
3414 BIO_printf(bio_err, "dup failed\n");
3423 printf("Forked child %d\n", n);
3426 /* for now, assume the pipe is long enough to take all the output */
3427 for (n = 0; n < multi; ++n) {
3432 f = fdopen(fds[n], "r");
3433 while (fgets(buf, sizeof(buf), f)) {
3434 p = strchr(buf, '\n');
3437 if (buf[0] != '+') {
3439 "Don't understand line '%s' from child %d\n", buf,
3443 printf("Got: %s from %d\n", buf, n);
3444 if (strncmp(buf, "+F:", 3) == 0) {
3449 alg = atoi(sstrsep(&p, sep));
3451 for (j = 0; j < size_num; ++j)
3452 results[alg][j] += atof(sstrsep(&p, sep));
3453 } else if (strncmp(buf, "+F2:", 4) == 0) {
3458 k = atoi(sstrsep(&p, sep));
3461 d = atof(sstrsep(&p, sep));
3462 rsa_results[k][0] += d;
3464 d = atof(sstrsep(&p, sep));
3465 rsa_results[k][1] += d;
3466 } else if (strncmp(buf, "+F3:", 4) == 0) {
3471 k = atoi(sstrsep(&p, sep));
3474 d = atof(sstrsep(&p, sep));
3475 dsa_results[k][0] += d;
3477 d = atof(sstrsep(&p, sep));
3478 dsa_results[k][1] += d;
3479 } else if (strncmp(buf, "+F4:", 4) == 0) {
3484 k = atoi(sstrsep(&p, sep));
3487 d = atof(sstrsep(&p, sep));
3488 ecdsa_results[k][0] += d;
3490 d = atof(sstrsep(&p, sep));
3491 ecdsa_results[k][1] += d;
3492 } else if (strncmp(buf, "+F5:", 4) == 0) {
3497 k = atoi(sstrsep(&p, sep));
3500 d = atof(sstrsep(&p, sep));
3501 ecdh_results[k][0] += d;
3502 } else if (strncmp(buf, "+F6:", 4) == 0) {
3507 k = atoi(sstrsep(&p, sep));
3511 d = atof(sstrsep(&p, sep));
3512 eddsa_results[k][0] += d;
3514 d = atof(sstrsep(&p, sep));
3515 eddsa_results[k][1] += d;
3516 # ifndef OPENSSL_NO_SM2
3517 } else if (strncmp(buf, "+F7:", 4) == 0) {
3522 k = atoi(sstrsep(&p, sep));
3526 d = atof(sstrsep(&p, sep));
3527 sm2_results[k][0] += d;
3529 d = atof(sstrsep(&p, sep));
3530 sm2_results[k][1] += d;
3531 # endif /* OPENSSL_NO_SM2 */
3532 # ifndef OPENSSL_NO_DH
3533 } else if (strncmp(buf, "+F8:", 4) == 0) {
3538 k = atoi(sstrsep(&p, sep));
3541 d = atof(sstrsep(&p, sep));
3542 ffdh_results[k][0] += d;
3543 # endif /* OPENSSL_NO_DH */
3544 } else if (strncmp(buf, "+H:", 3) == 0) {
3547 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3559 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3560 const openssl_speed_sec_t *seconds)
3562 static const int mblengths_list[] =
3563 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3564 const int *mblengths = mblengths_list;
3565 int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3566 const char *alg_name;
3567 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3568 EVP_CIPHER_CTX *ctx = NULL;
3571 if (lengths_single) {
3572 mblengths = &lengths_single;
3576 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3577 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3578 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3579 app_bail_out("failed to allocate cipher context\n");
3580 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3581 app_bail_out("failed to initialise cipher context\n");
3583 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3584 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3587 key = app_malloc(keylen, "evp_cipher key");
3588 if (!EVP_CIPHER_CTX_rand_key(ctx, key))
3589 app_bail_out("failed to generate random cipher key\n");
3590 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3591 app_bail_out("failed to set cipher key\n");
3592 OPENSSL_clear_free(key, keylen);
3594 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3595 sizeof(no_key), no_key))
3596 app_bail_out("failed to set AEAD key\n");
3597 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3598 app_bail_out("failed to get cipher name\n");
3600 for (j = 0; j < num; j++) {
3601 print_message(alg_name, 0, mblengths[j], seconds->sym);
3603 for (count = 0; run && count < 0x7fffffff; count++) {
3604 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3605 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3606 size_t len = mblengths[j];
3609 memset(aad, 0, 8); /* avoid uninitialized values */
3610 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3611 aad[9] = 3; /* version */
3613 aad[11] = 0; /* length */
3615 mb_param.out = NULL;
3618 mb_param.interleave = 8;
3620 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3621 sizeof(mb_param), &mb_param);
3627 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3628 sizeof(mb_param), &mb_param);
3632 RAND_bytes(out, 16);
3634 aad[11] = (unsigned char)(len >> 8);
3635 aad[12] = (unsigned char)(len);
3636 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3637 EVP_AEAD_TLS1_AAD_LEN, aad);
3638 EVP_Cipher(ctx, out, inp, len + pad);
3642 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3643 : "%d %s's in %.2fs\n", count, "evp", d);
3644 results[D_EVP][j] = ((double)count) / d * mblengths[j];
3648 fprintf(stdout, "+H");
3649 for (j = 0; j < num; j++)
3650 fprintf(stdout, ":%d", mblengths[j]);
3651 fprintf(stdout, "\n");
3652 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3653 for (j = 0; j < num; j++)
3654 fprintf(stdout, ":%.2f", results[D_EVP][j]);
3655 fprintf(stdout, "\n");
3658 "The 'numbers' are in 1000s of bytes per second processed.\n");
3659 fprintf(stdout, "type ");
3660 for (j = 0; j < num; j++)
3661 fprintf(stdout, "%7d bytes", mblengths[j]);
3662 fprintf(stdout, "\n");
3663 fprintf(stdout, "%-24s", alg_name);
3665 for (j = 0; j < num; j++) {
3666 if (results[D_EVP][j] > 10000)
3667 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3669 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3671 fprintf(stdout, "\n");
3677 EVP_CIPHER_CTX_free(ctx);