xref: /freebsd/crypto/openssl/apps/speed.c (revision e5b786625f7f82a1fa91e41823332459ea5550f9)
1 /*
2  * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4  *
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
9  */
10 
11 #undef SECONDS
12 #define SECONDS          3
13 #define PKEY_SECONDS    10
14 
15 #define RSA_SECONDS     PKEY_SECONDS
16 #define DSA_SECONDS     PKEY_SECONDS
17 #define ECDSA_SECONDS   PKEY_SECONDS
18 #define ECDH_SECONDS    PKEY_SECONDS
19 #define EdDSA_SECONDS   PKEY_SECONDS
20 #define SM2_SECONDS     PKEY_SECONDS
21 #define FFDH_SECONDS    PKEY_SECONDS
22 
23 /* We need to use some deprecated APIs */
24 #define OPENSSL_SUPPRESS_DEPRECATED
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30 #include "apps.h"
31 #include "progs.h"
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)
41 # include <unistd.h>
42 #endif
43 
44 #if defined(__TANDEM)
45 # if defined(OPENSSL_TANDEM_FLOSS)
46 #  include <floss.h(floss_fork)>
47 # endif
48 #endif
49 
50 #if defined(_WIN32)
51 # include <windows.h>
52 #endif
53 
54 #include <openssl/bn.h>
55 #include <openssl/rsa.h>
56 #include "./testrsa.h"
57 #ifndef OPENSSL_NO_DH
58 # include <openssl/dh.h>
59 #endif
60 #include <openssl/x509.h>
61 #include <openssl/dsa.h>
62 #include "./testdsa.h"
63 #include <openssl/modes.h>
64 
65 #ifndef HAVE_FORK
66 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
67 #  define HAVE_FORK 0
68 # else
69 #  define HAVE_FORK 1
70 #  include <sys/wait.h>
71 # endif
72 #endif
73 
74 #if HAVE_FORK
75 # undef NO_FORK
76 #else
77 # define NO_FORK
78 #endif
79 
80 #define MAX_MISALIGNMENT 63
81 #define MAX_ECDH_SIZE   256
82 #define MISALIGN        64
83 #define MAX_FFDH_SIZE 1024
84 
85 #ifndef RSA_DEFAULT_PRIME_NUM
86 # define RSA_DEFAULT_PRIME_NUM 2
87 #endif
88 
89 typedef struct openssl_speed_sec_st {
90     int sym;
91     int rsa;
92     int dsa;
93     int ecdsa;
94     int ecdh;
95     int eddsa;
96     int sm2;
97     int ffdh;
98 } openssl_speed_sec_t;
99 
100 static volatile int run = 0;
101 
102 static int mr = 0;  /* machine-readeable output format to merge fork results */
103 static int usertime = 1;
104 
105 static double Time_F(int s);
106 static void print_message(const char *s, long num, int length, int tm);
107 static void pkey_print_message(const char *str, const char *str2,
108                                long num, unsigned int bits, int sec);
109 static void print_result(int alg, int run_no, int count, double time_used);
110 #ifndef NO_FORK
111 static int do_multi(int multi, int size_num);
112 #endif
113 
114 static const int lengths_list[] = {
115     16, 64, 256, 1024, 8 * 1024, 16 * 1024
116 };
117 #define SIZE_NUM         OSSL_NELEM(lengths_list)
118 static const int *lengths = lengths_list;
119 
120 static const int aead_lengths_list[] = {
121     2, 31, 136, 1024, 8 * 1024, 16 * 1024
122 };
123 
124 #define START   0
125 #define STOP    1
126 
127 #ifdef SIGALRM
128 
129 static void alarmed(int sig)
130 {
131     signal(SIGALRM, alarmed);
132     run = 0;
133 }
134 
135 static double Time_F(int s)
136 {
137     double ret = app_tminterval(s, usertime);
138     if (s == STOP)
139         alarm(0);
140     return ret;
141 }
142 
143 #elif defined(_WIN32)
144 
145 # define SIGALRM -1
146 
147 static unsigned int lapse;
148 static volatile unsigned int schlock;
149 static void alarm_win32(unsigned int secs)
150 {
151     lapse = secs * 1000;
152 }
153 
154 # define alarm alarm_win32
155 
156 static DWORD WINAPI sleepy(VOID * arg)
157 {
158     schlock = 1;
159     Sleep(lapse);
160     run = 0;
161     return 0;
162 }
163 
164 static double Time_F(int s)
165 {
166     double ret;
167     static HANDLE thr;
168 
169     if (s == START) {
170         schlock = 0;
171         thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
172         if (thr == NULL) {
173             DWORD err = GetLastError();
174             BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
175             ExitProcess(err);
176         }
177         while (!schlock)
178             Sleep(0);           /* scheduler spinlock */
179         ret = app_tminterval(s, usertime);
180     } else {
181         ret = app_tminterval(s, usertime);
182         if (run)
183             TerminateThread(thr, 0);
184         CloseHandle(thr);
185     }
186 
187     return ret;
188 }
189 #else
190 # error "SIGALRM not defined and the platform is not Windows"
191 #endif
192 
193 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
194                              const openssl_speed_sec_t *seconds);
195 
196 static int opt_found(const char *name, unsigned int *result,
197                      const OPT_PAIR pairs[], unsigned int nbelem)
198 {
199     unsigned int idx;
200 
201     for (idx = 0; idx < nbelem; ++idx, pairs++)
202         if (strcmp(name, pairs->name) == 0) {
203             *result = pairs->retval;
204             return 1;
205         }
206     return 0;
207 }
208 #define opt_found(value, pairs, result)\
209     opt_found(value, result, pairs, OSSL_NELEM(pairs))
210 
211 typedef enum OPTION_choice {
212     OPT_COMMON,
213     OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
214     OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM,
215     OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC
216 } OPTION_CHOICE;
217 
218 const OPTIONS speed_options[] = {
219     {OPT_HELP_STR, 1, '-', "Usage: %s [options] [algorithm...]\n"},
220 
221     OPT_SECTION("General"),
222     {"help", OPT_HELP, '-', "Display this summary"},
223     {"mb", OPT_MB, '-',
224      "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
225     {"mr", OPT_MR, '-', "Produce machine readable output"},
226 #ifndef NO_FORK
227     {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
228 #endif
229 #ifndef OPENSSL_NO_ASYNC
230     {"async_jobs", OPT_ASYNCJOBS, 'p',
231      "Enable async mode and start specified number of jobs"},
232 #endif
233 #ifndef OPENSSL_NO_ENGINE
234     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
235 #endif
236     {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
237 
238     OPT_SECTION("Selection"),
239     {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
240     {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
241     {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
242     {"decrypt", OPT_DECRYPT, '-',
243      "Time decryption instead of encryption (only EVP)"},
244     {"aead", OPT_AEAD, '-',
245      "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
246 
247     OPT_SECTION("Timing"),
248     {"elapsed", OPT_ELAPSED, '-',
249      "Use wall-clock time instead of CPU user time as divisor"},
250     {"seconds", OPT_SECONDS, 'p',
251      "Run benchmarks for specified amount of seconds"},
252     {"bytes", OPT_BYTES, 'p',
253      "Run [non-PKI] benchmarks on custom-sized buffer"},
254     {"misalign", OPT_MISALIGN, 'p',
255      "Use specified offset to mis-align buffers"},
256 
257     OPT_R_OPTIONS,
258     OPT_PROV_OPTIONS,
259 
260     OPT_PARAMETERS(),
261     {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
262     {NULL}
263 };
264 
265 enum {
266     D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
267     D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
268     D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
269     D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
270     D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
271     D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
272     D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
273 };
274 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
275 static const char *names[ALGOR_NUM] = {
276     "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
277     "sha256", "sha512", "whirlpool", "hmac(md5)",
278     "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
279     "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
280     "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
281     "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
282     "evp", "ghash", "rand", "cmac"
283 };
284 
285 /* list of configured algorithm (remaining), with some few alias */
286 static const OPT_PAIR doit_choices[] = {
287     {"md2", D_MD2},
288     {"mdc2", D_MDC2},
289     {"md4", D_MD4},
290     {"md5", D_MD5},
291     {"hmac", D_HMAC},
292     {"sha1", D_SHA1},
293     {"sha256", D_SHA256},
294     {"sha512", D_SHA512},
295     {"whirlpool", D_WHIRLPOOL},
296     {"ripemd", D_RMD160},
297     {"rmd160", D_RMD160},
298     {"ripemd160", D_RMD160},
299     {"rc4", D_RC4},
300     {"des-cbc", D_CBC_DES},
301     {"des-ede3", D_EDE3_DES},
302     {"aes-128-cbc", D_CBC_128_AES},
303     {"aes-192-cbc", D_CBC_192_AES},
304     {"aes-256-cbc", D_CBC_256_AES},
305     {"camellia-128-cbc", D_CBC_128_CML},
306     {"camellia-192-cbc", D_CBC_192_CML},
307     {"camellia-256-cbc", D_CBC_256_CML},
308     {"rc2-cbc", D_CBC_RC2},
309     {"rc2", D_CBC_RC2},
310     {"rc5-cbc", D_CBC_RC5},
311     {"rc5", D_CBC_RC5},
312     {"idea-cbc", D_CBC_IDEA},
313     {"idea", D_CBC_IDEA},
314     {"seed-cbc", D_CBC_SEED},
315     {"seed", D_CBC_SEED},
316     {"bf-cbc", D_CBC_BF},
317     {"blowfish", D_CBC_BF},
318     {"bf", D_CBC_BF},
319     {"cast-cbc", D_CBC_CAST},
320     {"cast", D_CBC_CAST},
321     {"cast5", D_CBC_CAST},
322     {"ghash", D_GHASH},
323     {"rand", D_RAND}
324 };
325 
326 static double results[ALGOR_NUM][SIZE_NUM];
327 
328 enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM };
329 static const OPT_PAIR dsa_choices[DSA_NUM] = {
330     {"dsa512", R_DSA_512},
331     {"dsa1024", R_DSA_1024},
332     {"dsa2048", R_DSA_2048}
333 };
334 static double dsa_results[DSA_NUM][2];  /* 2 ops: sign then verify */
335 
336 enum {
337     R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
338     R_RSA_15360, RSA_NUM
339 };
340 static const OPT_PAIR rsa_choices[RSA_NUM] = {
341     {"rsa512", R_RSA_512},
342     {"rsa1024", R_RSA_1024},
343     {"rsa2048", R_RSA_2048},
344     {"rsa3072", R_RSA_3072},
345     {"rsa4096", R_RSA_4096},
346     {"rsa7680", R_RSA_7680},
347     {"rsa15360", R_RSA_15360}
348 };
349 
350 static double rsa_results[RSA_NUM][2];  /* 2 ops: sign then verify */
351 
352 #ifndef OPENSSL_NO_DH
353 enum ff_params_t {
354     R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
355 };
356 
357 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
358     {"ffdh2048", R_FFDH_2048},
359     {"ffdh3072", R_FFDH_3072},
360     {"ffdh4096", R_FFDH_4096},
361     {"ffdh6144", R_FFDH_6144},
362     {"ffdh8192", R_FFDH_8192},
363 };
364 
365 static double ffdh_results[FFDH_NUM][1];  /* 1 op: derivation */
366 #endif /* OPENSSL_NO_DH */
367 
368 enum ec_curves_t {
369     R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
370 #ifndef OPENSSL_NO_EC2M
371     R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
372     R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
373 #endif
374     R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
375     R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
376 };
377 /* list of ecdsa curves */
378 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
379     {"ecdsap160", R_EC_P160},
380     {"ecdsap192", R_EC_P192},
381     {"ecdsap224", R_EC_P224},
382     {"ecdsap256", R_EC_P256},
383     {"ecdsap384", R_EC_P384},
384     {"ecdsap521", R_EC_P521},
385 #ifndef OPENSSL_NO_EC2M
386     {"ecdsak163", R_EC_K163},
387     {"ecdsak233", R_EC_K233},
388     {"ecdsak283", R_EC_K283},
389     {"ecdsak409", R_EC_K409},
390     {"ecdsak571", R_EC_K571},
391     {"ecdsab163", R_EC_B163},
392     {"ecdsab233", R_EC_B233},
393     {"ecdsab283", R_EC_B283},
394     {"ecdsab409", R_EC_B409},
395     {"ecdsab571", R_EC_B571},
396 #endif
397     {"ecdsabrp256r1", R_EC_BRP256R1},
398     {"ecdsabrp256t1", R_EC_BRP256T1},
399     {"ecdsabrp384r1", R_EC_BRP384R1},
400     {"ecdsabrp384t1", R_EC_BRP384T1},
401     {"ecdsabrp512r1", R_EC_BRP512R1},
402     {"ecdsabrp512t1", R_EC_BRP512T1}
403 };
404 enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM };
405 /* list of ecdh curves, extension of |ecdsa_choices| list above */
406 static const OPT_PAIR ecdh_choices[EC_NUM] = {
407     {"ecdhp160", R_EC_P160},
408     {"ecdhp192", R_EC_P192},
409     {"ecdhp224", R_EC_P224},
410     {"ecdhp256", R_EC_P256},
411     {"ecdhp384", R_EC_P384},
412     {"ecdhp521", R_EC_P521},
413 #ifndef OPENSSL_NO_EC2M
414     {"ecdhk163", R_EC_K163},
415     {"ecdhk233", R_EC_K233},
416     {"ecdhk283", R_EC_K283},
417     {"ecdhk409", R_EC_K409},
418     {"ecdhk571", R_EC_K571},
419     {"ecdhb163", R_EC_B163},
420     {"ecdhb233", R_EC_B233},
421     {"ecdhb283", R_EC_B283},
422     {"ecdhb409", R_EC_B409},
423     {"ecdhb571", R_EC_B571},
424 #endif
425     {"ecdhbrp256r1", R_EC_BRP256R1},
426     {"ecdhbrp256t1", R_EC_BRP256T1},
427     {"ecdhbrp384r1", R_EC_BRP384R1},
428     {"ecdhbrp384t1", R_EC_BRP384T1},
429     {"ecdhbrp512r1", R_EC_BRP512R1},
430     {"ecdhbrp512t1", R_EC_BRP512T1},
431     {"ecdhx25519", R_EC_X25519},
432     {"ecdhx448", R_EC_X448}
433 };
434 
435 static double ecdh_results[EC_NUM][1];      /* 1 op: derivation */
436 static double ecdsa_results[ECDSA_NUM][2];  /* 2 ops: sign then verify */
437 
438 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
439 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
440     {"ed25519", R_EC_Ed25519},
441     {"ed448", R_EC_Ed448}
442 
443 };
444 static double eddsa_results[EdDSA_NUM][2];    /* 2 ops: sign then verify */
445 
446 #ifndef OPENSSL_NO_SM2
447 enum { R_EC_CURVESM2, SM2_NUM };
448 static const OPT_PAIR sm2_choices[SM2_NUM] = {
449     {"curveSM2", R_EC_CURVESM2}
450 };
451 # define SM2_ID        "TLSv1.3+GM+Cipher+Suite"
452 # define SM2_ID_LEN    sizeof("TLSv1.3+GM+Cipher+Suite") - 1
453 static double sm2_results[SM2_NUM][2];    /* 2 ops: sign then verify */
454 #endif /* OPENSSL_NO_SM2 */
455 
456 #define COND(unused_cond) (run && count < INT_MAX)
457 #define COUNT(d) (count)
458 
459 typedef struct loopargs_st {
460     ASYNC_JOB *inprogress_job;
461     ASYNC_WAIT_CTX *wait_ctx;
462     unsigned char *buf;
463     unsigned char *buf2;
464     unsigned char *buf_malloc;
465     unsigned char *buf2_malloc;
466     unsigned char *key;
467     size_t buflen;
468     size_t sigsize;
469     EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
470     EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
471     EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
472     EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
473     EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
474     EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
475     EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
476     EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
477     EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
478 #ifndef OPENSSL_NO_SM2
479     EVP_MD_CTX *sm2_ctx[SM2_NUM];
480     EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
481     EVP_PKEY *sm2_pkey[SM2_NUM];
482 #endif
483     unsigned char *secret_a;
484     unsigned char *secret_b;
485     size_t outlen[EC_NUM];
486 #ifndef OPENSSL_NO_DH
487     EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
488     unsigned char *secret_ff_a;
489     unsigned char *secret_ff_b;
490 #endif
491     EVP_CIPHER_CTX *ctx;
492     EVP_MAC_CTX *mctx;
493 } loopargs_t;
494 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
495                          loopargs_t * loopargs);
496 
497 static unsigned int testnum;
498 
499 /* Nb of iterations to do per algorithm and key-size */
500 static long c[ALGOR_NUM][SIZE_NUM];
501 
502 static char *evp_mac_mdname = "md5";
503 static char *evp_hmac_name = NULL;
504 static const char *evp_md_name = NULL;
505 static char *evp_mac_ciphername = "aes-128-cbc";
506 static char *evp_cmac_name = NULL;
507 
508 static int have_md(const char *name)
509 {
510     int ret = 0;
511     EVP_MD *md = NULL;
512 
513     if (opt_md_silent(name, &md)) {
514         EVP_MD_CTX *ctx = EVP_MD_CTX_new();
515 
516         if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
517             ret = 1;
518         EVP_MD_CTX_free(ctx);
519         EVP_MD_free(md);
520     }
521     return ret;
522 }
523 
524 static int have_cipher(const char *name)
525 {
526     int ret = 0;
527     EVP_CIPHER *cipher = NULL;
528 
529     if (opt_cipher_silent(name, &cipher)) {
530         EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
531 
532         if (ctx != NULL
533             && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
534             ret = 1;
535         EVP_CIPHER_CTX_free(ctx);
536         EVP_CIPHER_free(cipher);
537     }
538     return ret;
539 }
540 
541 static int EVP_Digest_loop(const char *mdname, int algindex, void *args)
542 {
543     loopargs_t *tempargs = *(loopargs_t **) args;
544     unsigned char *buf = tempargs->buf;
545     unsigned char digest[EVP_MAX_MD_SIZE];
546     int count;
547     EVP_MD *md = NULL;
548 
549     if (!opt_md_silent(mdname, &md))
550         return -1;
551     for (count = 0; COND(c[algindex][testnum]); count++) {
552         if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
553                         NULL)) {
554             count = -1;
555             break;
556         }
557     }
558     EVP_MD_free(md);
559     return count;
560 }
561 
562 static int EVP_Digest_md_loop(void *args)
563 {
564     return EVP_Digest_loop(evp_md_name, D_EVP, args);
565 }
566 
567 static int EVP_Digest_MD2_loop(void *args)
568 {
569     return EVP_Digest_loop("md2", D_MD2, args);
570 }
571 
572 static int EVP_Digest_MDC2_loop(void *args)
573 {
574     return EVP_Digest_loop("mdc2", D_MDC2, args);
575 }
576 
577 static int EVP_Digest_MD4_loop(void *args)
578 {
579     return EVP_Digest_loop("md4", D_MD4, args);
580 }
581 
582 static int MD5_loop(void *args)
583 {
584     return EVP_Digest_loop("md5", D_MD5, args);
585 }
586 
587 static int EVP_MAC_loop(int algindex, void *args)
588 {
589     loopargs_t *tempargs = *(loopargs_t **) args;
590     unsigned char *buf = tempargs->buf;
591     EVP_MAC_CTX *mctx = tempargs->mctx;
592     unsigned char mac[EVP_MAX_MD_SIZE];
593     int count;
594 
595     for (count = 0; COND(c[algindex][testnum]); count++) {
596         size_t outl;
597 
598         if (!EVP_MAC_init(mctx, NULL, 0, NULL)
599             || !EVP_MAC_update(mctx, buf, lengths[testnum])
600             || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
601             return -1;
602     }
603     return count;
604 }
605 
606 static int HMAC_loop(void *args)
607 {
608     return EVP_MAC_loop(D_HMAC, args);
609 }
610 
611 static int CMAC_loop(void *args)
612 {
613     return EVP_MAC_loop(D_EVP_CMAC, args);
614 }
615 
616 static int SHA1_loop(void *args)
617 {
618     return EVP_Digest_loop("sha1", D_SHA1, args);
619 }
620 
621 static int SHA256_loop(void *args)
622 {
623     return EVP_Digest_loop("sha256", D_SHA256, args);
624 }
625 
626 static int SHA512_loop(void *args)
627 {
628     return EVP_Digest_loop("sha512", D_SHA512, args);
629 }
630 
631 static int WHIRLPOOL_loop(void *args)
632 {
633     return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
634 }
635 
636 static int EVP_Digest_RMD160_loop(void *args)
637 {
638     return EVP_Digest_loop("ripemd160", D_RMD160, args);
639 }
640 
641 static int algindex;
642 
643 static int EVP_Cipher_loop(void *args)
644 {
645     loopargs_t *tempargs = *(loopargs_t **) args;
646     unsigned char *buf = tempargs->buf;
647     int count;
648 
649     if (tempargs->ctx == NULL)
650         return -1;
651     for (count = 0; COND(c[algindex][testnum]); count++)
652         if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
653             return -1;
654     return count;
655 }
656 
657 static int GHASH_loop(void *args)
658 {
659     loopargs_t *tempargs = *(loopargs_t **) args;
660     unsigned char *buf = tempargs->buf;
661     EVP_MAC_CTX *mctx = tempargs->mctx;
662     int count;
663 
664     /* just do the update in the loop to be comparable with 1.1.1 */
665     for (count = 0; COND(c[D_GHASH][testnum]); count++) {
666         if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
667             return -1;
668     }
669     return count;
670 }
671 
672 #define MAX_BLOCK_SIZE 128
673 
674 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
675 
676 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
677                                            const unsigned char *key,
678                                            int keylen)
679 {
680     EVP_CIPHER_CTX *ctx = NULL;
681     EVP_CIPHER *cipher = NULL;
682 
683     if (!opt_cipher_silent(ciphername, &cipher))
684         return NULL;
685 
686     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
687         goto end;
688 
689     if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
690         EVP_CIPHER_CTX_free(ctx);
691         ctx = NULL;
692         goto end;
693     }
694 
695     if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) {
696         EVP_CIPHER_CTX_free(ctx);
697         ctx = NULL;
698         goto end;
699     }
700 
701     if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
702         EVP_CIPHER_CTX_free(ctx);
703         ctx = NULL;
704         goto end;
705     }
706 
707 end:
708     EVP_CIPHER_free(cipher);
709     return ctx;
710 }
711 
712 static int RAND_bytes_loop(void *args)
713 {
714     loopargs_t *tempargs = *(loopargs_t **) args;
715     unsigned char *buf = tempargs->buf;
716     int count;
717 
718     for (count = 0; COND(c[D_RAND][testnum]); count++)
719         RAND_bytes(buf, lengths[testnum]);
720     return count;
721 }
722 
723 static int decrypt = 0;
724 static int EVP_Update_loop(void *args)
725 {
726     loopargs_t *tempargs = *(loopargs_t **) args;
727     unsigned char *buf = tempargs->buf;
728     EVP_CIPHER_CTX *ctx = tempargs->ctx;
729     int outl, count, rc;
730 
731     if (decrypt) {
732         for (count = 0; COND(c[D_EVP][testnum]); count++) {
733             rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
734             if (rc != 1) {
735                 /* reset iv in case of counter overflow */
736                 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
737             }
738         }
739     } else {
740         for (count = 0; COND(c[D_EVP][testnum]); count++) {
741             rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
742             if (rc != 1) {
743                 /* reset iv in case of counter overflow */
744                 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
745             }
746         }
747     }
748     if (decrypt)
749         EVP_DecryptFinal_ex(ctx, buf, &outl);
750     else
751         EVP_EncryptFinal_ex(ctx, buf, &outl);
752     return count;
753 }
754 
755 /*
756  * CCM does not support streaming. For the purpose of performance measurement,
757  * each message is encrypted using the same (key,iv)-pair. Do not use this
758  * code in your application.
759  */
760 static int EVP_Update_loop_ccm(void *args)
761 {
762     loopargs_t *tempargs = *(loopargs_t **) args;
763     unsigned char *buf = tempargs->buf;
764     EVP_CIPHER_CTX *ctx = tempargs->ctx;
765     int outl, count;
766     unsigned char tag[12];
767 
768     if (decrypt) {
769         for (count = 0; COND(c[D_EVP][testnum]); count++) {
770             (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
771                                       tag);
772             /* reset iv */
773             (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
774             /* counter is reset on every update */
775             (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
776         }
777     } else {
778         for (count = 0; COND(c[D_EVP][testnum]); count++) {
779             /* restore iv length field */
780             (void)EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
781             /* counter is reset on every update */
782             (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
783         }
784     }
785     if (decrypt)
786         (void)EVP_DecryptFinal_ex(ctx, buf, &outl);
787     else
788         (void)EVP_EncryptFinal_ex(ctx, buf, &outl);
789     return count;
790 }
791 
792 /*
793  * To make AEAD benchmarking more relevant perform TLS-like operations,
794  * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
795  * payload length is not actually limited by 16KB...
796  */
797 static int EVP_Update_loop_aead(void *args)
798 {
799     loopargs_t *tempargs = *(loopargs_t **) args;
800     unsigned char *buf = tempargs->buf;
801     EVP_CIPHER_CTX *ctx = tempargs->ctx;
802     int outl, count;
803     unsigned char aad[13] = { 0xcc };
804     unsigned char faketag[16] = { 0xcc };
805 
806     if (decrypt) {
807         for (count = 0; COND(c[D_EVP][testnum]); count++) {
808             (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
809             (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
810                                       sizeof(faketag), faketag);
811             (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
812             (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
813             (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl);
814         }
815     } else {
816         for (count = 0; COND(c[D_EVP][testnum]); count++) {
817             (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv);
818             (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
819             (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
820             (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl);
821         }
822     }
823     return count;
824 }
825 
826 static long rsa_c[RSA_NUM][2];  /* # RSA iteration test */
827 
828 static int RSA_sign_loop(void *args)
829 {
830     loopargs_t *tempargs = *(loopargs_t **) args;
831     unsigned char *buf = tempargs->buf;
832     unsigned char *buf2 = tempargs->buf2;
833     size_t *rsa_num = &tempargs->sigsize;
834     EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
835     int ret, count;
836 
837     for (count = 0; COND(rsa_c[testnum][0]); count++) {
838         *rsa_num = tempargs->buflen;
839         ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
840         if (ret <= 0) {
841             BIO_printf(bio_err, "RSA sign failure\n");
842             ERR_print_errors(bio_err);
843             count = -1;
844             break;
845         }
846     }
847     return count;
848 }
849 
850 static int RSA_verify_loop(void *args)
851 {
852     loopargs_t *tempargs = *(loopargs_t **) args;
853     unsigned char *buf = tempargs->buf;
854     unsigned char *buf2 = tempargs->buf2;
855     size_t rsa_num = tempargs->sigsize;
856     EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
857     int ret, count;
858 
859     for (count = 0; COND(rsa_c[testnum][1]); count++) {
860         ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
861         if (ret <= 0) {
862             BIO_printf(bio_err, "RSA verify failure\n");
863             ERR_print_errors(bio_err);
864             count = -1;
865             break;
866         }
867     }
868     return count;
869 }
870 
871 #ifndef OPENSSL_NO_DH
872 static long ffdh_c[FFDH_NUM][1];
873 
874 static int FFDH_derive_key_loop(void *args)
875 {
876     loopargs_t *tempargs = *(loopargs_t **) args;
877     EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
878     unsigned char *derived_secret = tempargs->secret_ff_a;
879     int count;
880 
881     for (count = 0; COND(ffdh_c[testnum][0]); count++) {
882         /* outlen can be overwritten with a too small value (no padding used) */
883         size_t outlen = MAX_FFDH_SIZE;
884 
885         EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
886     }
887     return count;
888 }
889 #endif /* OPENSSL_NO_DH */
890 
891 static long dsa_c[DSA_NUM][2];
892 static int DSA_sign_loop(void *args)
893 {
894     loopargs_t *tempargs = *(loopargs_t **) args;
895     unsigned char *buf = tempargs->buf;
896     unsigned char *buf2 = tempargs->buf2;
897     size_t *dsa_num = &tempargs->sigsize;
898     EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
899     int ret, count;
900 
901     for (count = 0; COND(dsa_c[testnum][0]); count++) {
902         *dsa_num = tempargs->buflen;
903         ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
904         if (ret <= 0) {
905             BIO_printf(bio_err, "DSA sign failure\n");
906             ERR_print_errors(bio_err);
907             count = -1;
908             break;
909         }
910     }
911     return count;
912 }
913 
914 static int DSA_verify_loop(void *args)
915 {
916     loopargs_t *tempargs = *(loopargs_t **) args;
917     unsigned char *buf = tempargs->buf;
918     unsigned char *buf2 = tempargs->buf2;
919     size_t dsa_num = tempargs->sigsize;
920     EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
921     int ret, count;
922 
923     for (count = 0; COND(dsa_c[testnum][1]); count++) {
924         ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
925         if (ret <= 0) {
926             BIO_printf(bio_err, "DSA verify failure\n");
927             ERR_print_errors(bio_err);
928             count = -1;
929             break;
930         }
931     }
932     return count;
933 }
934 
935 static long ecdsa_c[ECDSA_NUM][2];
936 static int ECDSA_sign_loop(void *args)
937 {
938     loopargs_t *tempargs = *(loopargs_t **) args;
939     unsigned char *buf = tempargs->buf;
940     unsigned char *buf2 = tempargs->buf2;
941     size_t *ecdsa_num = &tempargs->sigsize;
942     EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
943     int ret, count;
944 
945     for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
946         *ecdsa_num = tempargs->buflen;
947         ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
948         if (ret <= 0) {
949             BIO_printf(bio_err, "ECDSA sign failure\n");
950             ERR_print_errors(bio_err);
951             count = -1;
952             break;
953         }
954     }
955     return count;
956 }
957 
958 static int ECDSA_verify_loop(void *args)
959 {
960     loopargs_t *tempargs = *(loopargs_t **) args;
961     unsigned char *buf = tempargs->buf;
962     unsigned char *buf2 = tempargs->buf2;
963     size_t ecdsa_num = tempargs->sigsize;
964     EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
965     int ret, count;
966 
967     for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
968         ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
969                               buf, 20);
970         if (ret <= 0) {
971             BIO_printf(bio_err, "ECDSA verify failure\n");
972             ERR_print_errors(bio_err);
973             count = -1;
974             break;
975         }
976     }
977     return count;
978 }
979 
980 /* ******************************************************************** */
981 static long ecdh_c[EC_NUM][1];
982 
983 static int ECDH_EVP_derive_key_loop(void *args)
984 {
985     loopargs_t *tempargs = *(loopargs_t **) args;
986     EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
987     unsigned char *derived_secret = tempargs->secret_a;
988     int count;
989     size_t *outlen = &(tempargs->outlen[testnum]);
990 
991     for (count = 0; COND(ecdh_c[testnum][0]); count++)
992         EVP_PKEY_derive(ctx, derived_secret, outlen);
993 
994     return count;
995 }
996 
997 static long eddsa_c[EdDSA_NUM][2];
998 static int EdDSA_sign_loop(void *args)
999 {
1000     loopargs_t *tempargs = *(loopargs_t **) args;
1001     unsigned char *buf = tempargs->buf;
1002     EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1003     unsigned char *eddsasig = tempargs->buf2;
1004     size_t *eddsasigsize = &tempargs->sigsize;
1005     int ret, count;
1006 
1007     for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1008         ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
1009         if (ret == 0) {
1010             BIO_printf(bio_err, "EdDSA sign init failure\n");
1011             ERR_print_errors(bio_err);
1012             count = -1;
1013             break;
1014         }
1015         ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1016         if (ret == 0) {
1017             BIO_printf(bio_err, "EdDSA sign failure\n");
1018             ERR_print_errors(bio_err);
1019             count = -1;
1020             break;
1021         }
1022     }
1023     return count;
1024 }
1025 
1026 static int EdDSA_verify_loop(void *args)
1027 {
1028     loopargs_t *tempargs = *(loopargs_t **) args;
1029     unsigned char *buf = tempargs->buf;
1030     EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1031     unsigned char *eddsasig = tempargs->buf2;
1032     size_t eddsasigsize = tempargs->sigsize;
1033     int ret, count;
1034 
1035     for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1036         ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
1037         if (ret == 0) {
1038             BIO_printf(bio_err, "EdDSA verify init failure\n");
1039             ERR_print_errors(bio_err);
1040             count = -1;
1041             break;
1042         }
1043         ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1044         if (ret != 1) {
1045             BIO_printf(bio_err, "EdDSA verify failure\n");
1046             ERR_print_errors(bio_err);
1047             count = -1;
1048             break;
1049         }
1050     }
1051     return count;
1052 }
1053 
1054 #ifndef OPENSSL_NO_SM2
1055 static long sm2_c[SM2_NUM][2];
1056 static int SM2_sign_loop(void *args)
1057 {
1058     loopargs_t *tempargs = *(loopargs_t **) args;
1059     unsigned char *buf = tempargs->buf;
1060     EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1061     unsigned char *sm2sig = tempargs->buf2;
1062     size_t sm2sigsize;
1063     int ret, count;
1064     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1065     const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1066 
1067     for (count = 0; COND(sm2_c[testnum][0]); count++) {
1068         sm2sigsize = max_size;
1069 
1070         if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1071                                 NULL, sm2_pkey[testnum])) {
1072             BIO_printf(bio_err, "SM2 init sign failure\n");
1073             ERR_print_errors(bio_err);
1074             count = -1;
1075             break;
1076         }
1077         ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1078                              buf, 20);
1079         if (ret == 0) {
1080             BIO_printf(bio_err, "SM2 sign failure\n");
1081             ERR_print_errors(bio_err);
1082             count = -1;
1083             break;
1084         }
1085         /* update the latest returned size and always use the fixed buffer size */
1086         tempargs->sigsize = sm2sigsize;
1087     }
1088 
1089     return count;
1090 }
1091 
1092 static int SM2_verify_loop(void *args)
1093 {
1094     loopargs_t *tempargs = *(loopargs_t **) args;
1095     unsigned char *buf = tempargs->buf;
1096     EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1097     unsigned char *sm2sig = tempargs->buf2;
1098     size_t sm2sigsize = tempargs->sigsize;
1099     int ret, count;
1100     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1101 
1102     for (count = 0; COND(sm2_c[testnum][1]); count++) {
1103         if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1104                                   NULL, sm2_pkey[testnum])) {
1105             BIO_printf(bio_err, "SM2 verify init failure\n");
1106             ERR_print_errors(bio_err);
1107             count = -1;
1108             break;
1109         }
1110         ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1111                                buf, 20);
1112         if (ret != 1) {
1113             BIO_printf(bio_err, "SM2 verify failure\n");
1114             ERR_print_errors(bio_err);
1115             count = -1;
1116             break;
1117         }
1118     }
1119     return count;
1120 }
1121 #endif                         /* OPENSSL_NO_SM2 */
1122 
1123 static int run_benchmark(int async_jobs,
1124                          int (*loop_function) (void *), loopargs_t * loopargs)
1125 {
1126     int job_op_count = 0;
1127     int total_op_count = 0;
1128     int num_inprogress = 0;
1129     int error = 0, i = 0, ret = 0;
1130     OSSL_ASYNC_FD job_fd = 0;
1131     size_t num_job_fds = 0;
1132 
1133     if (async_jobs == 0) {
1134         return loop_function((void *)&loopargs);
1135     }
1136 
1137     for (i = 0; i < async_jobs && !error; i++) {
1138         loopargs_t *looparg_item = loopargs + i;
1139 
1140         /* Copy pointer content (looparg_t item address) into async context */
1141         ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1142                               &job_op_count, loop_function,
1143                               (void *)&looparg_item, sizeof(looparg_item));
1144         switch (ret) {
1145         case ASYNC_PAUSE:
1146             ++num_inprogress;
1147             break;
1148         case ASYNC_FINISH:
1149             if (job_op_count == -1) {
1150                 error = 1;
1151             } else {
1152                 total_op_count += job_op_count;
1153             }
1154             break;
1155         case ASYNC_NO_JOBS:
1156         case ASYNC_ERR:
1157             BIO_printf(bio_err, "Failure in the job\n");
1158             ERR_print_errors(bio_err);
1159             error = 1;
1160             break;
1161         }
1162     }
1163 
1164     while (num_inprogress > 0) {
1165 #if defined(OPENSSL_SYS_WINDOWS)
1166         DWORD avail = 0;
1167 #elif defined(OPENSSL_SYS_UNIX)
1168         int select_result = 0;
1169         OSSL_ASYNC_FD max_fd = 0;
1170         fd_set waitfdset;
1171 
1172         FD_ZERO(&waitfdset);
1173 
1174         for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1175             if (loopargs[i].inprogress_job == NULL)
1176                 continue;
1177 
1178             if (!ASYNC_WAIT_CTX_get_all_fds
1179                 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1180                 || num_job_fds > 1) {
1181                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1182                 ERR_print_errors(bio_err);
1183                 error = 1;
1184                 break;
1185             }
1186             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1187                                        &num_job_fds);
1188             FD_SET(job_fd, &waitfdset);
1189             if (job_fd > max_fd)
1190                 max_fd = job_fd;
1191         }
1192 
1193         if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1194             BIO_printf(bio_err,
1195                        "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1196                        "Decrease the value of async_jobs\n",
1197                        max_fd, FD_SETSIZE);
1198             ERR_print_errors(bio_err);
1199             error = 1;
1200             break;
1201         }
1202 
1203         select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1204         if (select_result == -1 && errno == EINTR)
1205             continue;
1206 
1207         if (select_result == -1) {
1208             BIO_printf(bio_err, "Failure in the select\n");
1209             ERR_print_errors(bio_err);
1210             error = 1;
1211             break;
1212         }
1213 
1214         if (select_result == 0)
1215             continue;
1216 #endif
1217 
1218         for (i = 0; i < async_jobs; i++) {
1219             if (loopargs[i].inprogress_job == NULL)
1220                 continue;
1221 
1222             if (!ASYNC_WAIT_CTX_get_all_fds
1223                 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1224                 || num_job_fds > 1) {
1225                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1226                 ERR_print_errors(bio_err);
1227                 error = 1;
1228                 break;
1229             }
1230             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1231                                        &num_job_fds);
1232 
1233 #if defined(OPENSSL_SYS_UNIX)
1234             if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1235                 continue;
1236 #elif defined(OPENSSL_SYS_WINDOWS)
1237             if (num_job_fds == 1
1238                 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1239                 && avail > 0)
1240                 continue;
1241 #endif
1242 
1243             ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1244                                   loopargs[i].wait_ctx, &job_op_count,
1245                                   loop_function, (void *)(loopargs + i),
1246                                   sizeof(loopargs_t));
1247             switch (ret) {
1248             case ASYNC_PAUSE:
1249                 break;
1250             case ASYNC_FINISH:
1251                 if (job_op_count == -1) {
1252                     error = 1;
1253                 } else {
1254                     total_op_count += job_op_count;
1255                 }
1256                 --num_inprogress;
1257                 loopargs[i].inprogress_job = NULL;
1258                 break;
1259             case ASYNC_NO_JOBS:
1260             case ASYNC_ERR:
1261                 --num_inprogress;
1262                 loopargs[i].inprogress_job = NULL;
1263                 BIO_printf(bio_err, "Failure in the job\n");
1264                 ERR_print_errors(bio_err);
1265                 error = 1;
1266                 break;
1267             }
1268         }
1269     }
1270 
1271     return error ? -1 : total_op_count;
1272 }
1273 
1274 typedef struct ec_curve_st {
1275     const char *name;
1276     unsigned int nid;
1277     unsigned int bits;
1278     size_t sigsize; /* only used for EdDSA curves */
1279 } EC_CURVE;
1280 
1281 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1282 {
1283     EVP_PKEY_CTX *kctx = NULL;
1284     EVP_PKEY *key = NULL;
1285 
1286     /* Ensure that the error queue is empty */
1287     if (ERR_peek_error()) {
1288         BIO_printf(bio_err,
1289                    "WARNING: the error queue contains previous unhandled errors.\n");
1290         ERR_print_errors(bio_err);
1291     }
1292 
1293     /*
1294      * Let's try to create a ctx directly from the NID: this works for
1295      * curves like Curve25519 that are not implemented through the low
1296      * level EC interface.
1297      * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1298      * then we set the curve by NID before deriving the actual keygen
1299      * ctx for that specific curve.
1300      */
1301     kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1302     if (kctx == NULL) {
1303         EVP_PKEY_CTX *pctx = NULL;
1304         EVP_PKEY *params = NULL;
1305         /*
1306          * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1307          * "int_ctx_new:unsupported algorithm" error was added to the
1308          * error queue.
1309          * We remove it from the error queue as we are handling it.
1310          */
1311         unsigned long error = ERR_peek_error();
1312 
1313         if (error == ERR_peek_last_error() /* oldest and latest errors match */
1314             /* check that the error origin matches */
1315             && ERR_GET_LIB(error) == ERR_LIB_EVP
1316             && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1317                 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1318             ERR_get_error(); /* pop error from queue */
1319         if (ERR_peek_error()) {
1320             BIO_printf(bio_err,
1321                        "Unhandled error in the error queue during EC key setup.\n");
1322             ERR_print_errors(bio_err);
1323             return NULL;
1324         }
1325 
1326         /* Create the context for parameter generation */
1327         if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1328             || EVP_PKEY_paramgen_init(pctx) <= 0
1329             || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1330                                                       curve->nid) <= 0
1331             || EVP_PKEY_paramgen(pctx, &params) <= 0) {
1332             BIO_printf(bio_err, "EC params init failure.\n");
1333             ERR_print_errors(bio_err);
1334             EVP_PKEY_CTX_free(pctx);
1335             return NULL;
1336         }
1337         EVP_PKEY_CTX_free(pctx);
1338 
1339         /* Create the context for the key generation */
1340         kctx = EVP_PKEY_CTX_new(params, NULL);
1341         EVP_PKEY_free(params);
1342     }
1343     if (kctx == NULL
1344         || EVP_PKEY_keygen_init(kctx) <= 0
1345         || EVP_PKEY_keygen(kctx, &key) <= 0) {
1346         BIO_printf(bio_err, "EC key generation failure.\n");
1347         ERR_print_errors(bio_err);
1348         key = NULL;
1349     }
1350     EVP_PKEY_CTX_free(kctx);
1351     return key;
1352 }
1353 
1354 #define stop_it(do_it, test_num)\
1355     memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1356 
1357 int speed_main(int argc, char **argv)
1358 {
1359     ENGINE *e = NULL;
1360     loopargs_t *loopargs = NULL;
1361     const char *prog;
1362     const char *engine_id = NULL;
1363     EVP_CIPHER *evp_cipher = NULL;
1364     EVP_MAC *mac = NULL;
1365     double d = 0.0;
1366     OPTION_CHOICE o;
1367     int async_init = 0, multiblock = 0, pr_header = 0;
1368     uint8_t doit[ALGOR_NUM] = { 0 };
1369     int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1370     long count = 0;
1371     unsigned int size_num = SIZE_NUM;
1372     unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1373     int keylen;
1374     int buflen;
1375     BIGNUM *bn = NULL;
1376     EVP_PKEY_CTX *genctx = NULL;
1377 #ifndef NO_FORK
1378     int multi = 0;
1379 #endif
1380     long op_count = 1;
1381     openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1382                                     ECDSA_SECONDS, ECDH_SECONDS,
1383                                     EdDSA_SECONDS, SM2_SECONDS,
1384                                     FFDH_SECONDS };
1385 
1386     static const unsigned char key32[32] = {
1387         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1388         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1389         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1390         0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1391     };
1392     static const unsigned char deskey[] = {
1393         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1394         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1395         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34  /* key3 */
1396     };
1397     static const struct {
1398         const unsigned char *data;
1399         unsigned int length;
1400         unsigned int bits;
1401     } rsa_keys[] = {
1402         {   test512,   sizeof(test512),   512 },
1403         {  test1024,  sizeof(test1024),  1024 },
1404         {  test2048,  sizeof(test2048),  2048 },
1405         {  test3072,  sizeof(test3072),  3072 },
1406         {  test4096,  sizeof(test4096),  4096 },
1407         {  test7680,  sizeof(test7680),  7680 },
1408         { test15360, sizeof(test15360), 15360 }
1409     };
1410     uint8_t rsa_doit[RSA_NUM] = { 0 };
1411     int primes = RSA_DEFAULT_PRIME_NUM;
1412 #ifndef OPENSSL_NO_DH
1413     typedef struct ffdh_params_st {
1414         const char *name;
1415         unsigned int nid;
1416         unsigned int bits;
1417     } FFDH_PARAMS;
1418 
1419     static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1420         {"ffdh2048", NID_ffdhe2048, 2048},
1421         {"ffdh3072", NID_ffdhe3072, 3072},
1422         {"ffdh4096", NID_ffdhe4096, 4096},
1423         {"ffdh6144", NID_ffdhe6144, 6144},
1424         {"ffdh8192", NID_ffdhe8192, 8192}
1425     };
1426     uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1427 
1428 #endif /* OPENSSL_NO_DH */
1429     static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1430     uint8_t dsa_doit[DSA_NUM] = { 0 };
1431     /*
1432      * We only test over the following curves as they are representative, To
1433      * add tests over more curves, simply add the curve NID and curve name to
1434      * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1435      * lists accordingly.
1436      */
1437     static const EC_CURVE ec_curves[EC_NUM] = {
1438         /* Prime Curves */
1439         {"secp160r1", NID_secp160r1, 160},
1440         {"nistp192", NID_X9_62_prime192v1, 192},
1441         {"nistp224", NID_secp224r1, 224},
1442         {"nistp256", NID_X9_62_prime256v1, 256},
1443         {"nistp384", NID_secp384r1, 384},
1444         {"nistp521", NID_secp521r1, 521},
1445 #ifndef OPENSSL_NO_EC2M
1446         /* Binary Curves */
1447         {"nistk163", NID_sect163k1, 163},
1448         {"nistk233", NID_sect233k1, 233},
1449         {"nistk283", NID_sect283k1, 283},
1450         {"nistk409", NID_sect409k1, 409},
1451         {"nistk571", NID_sect571k1, 571},
1452         {"nistb163", NID_sect163r2, 163},
1453         {"nistb233", NID_sect233r1, 233},
1454         {"nistb283", NID_sect283r1, 283},
1455         {"nistb409", NID_sect409r1, 409},
1456         {"nistb571", NID_sect571r1, 571},
1457 #endif
1458         {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1459         {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1460         {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1461         {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1462         {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1463         {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1464         /* Other and ECDH only ones */
1465         {"X25519", NID_X25519, 253},
1466         {"X448", NID_X448, 448}
1467     };
1468     static const EC_CURVE ed_curves[EdDSA_NUM] = {
1469         /* EdDSA */
1470         {"Ed25519", NID_ED25519, 253, 64},
1471         {"Ed448", NID_ED448, 456, 114}
1472     };
1473 #ifndef OPENSSL_NO_SM2
1474     static const EC_CURVE sm2_curves[SM2_NUM] = {
1475         /* SM2 */
1476         {"CurveSM2", NID_sm2, 256}
1477     };
1478     uint8_t sm2_doit[SM2_NUM] = { 0 };
1479 #endif
1480     uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1481     uint8_t ecdh_doit[EC_NUM] = { 0 };
1482     uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1483 
1484     /* checks declarated curves against choices list. */
1485     OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1486     OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1487 
1488     OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1489     OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1490 
1491     OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1492     OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1493 
1494 #ifndef OPENSSL_NO_SM2
1495     OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1496     OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1497 #endif
1498 
1499     prog = opt_init(argc, argv, speed_options);
1500     while ((o = opt_next()) != OPT_EOF) {
1501         switch (o) {
1502         case OPT_EOF:
1503         case OPT_ERR:
1504  opterr:
1505             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1506             goto end;
1507         case OPT_HELP:
1508             opt_help(speed_options);
1509             ret = 0;
1510             goto end;
1511         case OPT_ELAPSED:
1512             usertime = 0;
1513             break;
1514         case OPT_EVP:
1515             if (doit[D_EVP]) {
1516                 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1517                 goto opterr;
1518             }
1519             ERR_set_mark();
1520             if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1521                 if (have_md(opt_arg()))
1522                     evp_md_name = opt_arg();
1523             }
1524             if (evp_cipher == NULL && evp_md_name == NULL) {
1525                 ERR_clear_last_mark();
1526                 BIO_printf(bio_err,
1527                            "%s: %s is an unknown cipher or digest\n",
1528                            prog, opt_arg());
1529                 goto end;
1530             }
1531             ERR_pop_to_mark();
1532             doit[D_EVP] = 1;
1533             break;
1534         case OPT_HMAC:
1535             if (!have_md(opt_arg())) {
1536                 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1537                            prog, opt_arg());
1538                 goto end;
1539             }
1540             evp_mac_mdname = opt_arg();
1541             doit[D_HMAC] = 1;
1542             break;
1543         case OPT_CMAC:
1544             if (!have_cipher(opt_arg())) {
1545                 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1546                            prog, opt_arg());
1547                 goto end;
1548             }
1549             evp_mac_ciphername = opt_arg();
1550             doit[D_EVP_CMAC] = 1;
1551             break;
1552         case OPT_DECRYPT:
1553             decrypt = 1;
1554             break;
1555         case OPT_ENGINE:
1556             /*
1557              * In a forked execution, an engine might need to be
1558              * initialised by each child process, not by the parent.
1559              * So store the name here and run setup_engine() later on.
1560              */
1561             engine_id = opt_arg();
1562             break;
1563         case OPT_MULTI:
1564 #ifndef NO_FORK
1565             multi = atoi(opt_arg());
1566             if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1567                 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1568                 return 0;
1569             }
1570 #endif
1571             break;
1572         case OPT_ASYNCJOBS:
1573 #ifndef OPENSSL_NO_ASYNC
1574             async_jobs = atoi(opt_arg());
1575             if (!ASYNC_is_capable()) {
1576                 BIO_printf(bio_err,
1577                            "%s: async_jobs specified but async not supported\n",
1578                            prog);
1579                 goto opterr;
1580             }
1581             if (async_jobs > 99999) {
1582                 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1583                 goto opterr;
1584             }
1585 #endif
1586             break;
1587         case OPT_MISALIGN:
1588             misalign = opt_int_arg();
1589             if (misalign > MISALIGN) {
1590                 BIO_printf(bio_err,
1591                            "%s: Maximum offset is %d\n", prog, MISALIGN);
1592                 goto opterr;
1593             }
1594             break;
1595         case OPT_MR:
1596             mr = 1;
1597             break;
1598         case OPT_MB:
1599             multiblock = 1;
1600 #ifdef OPENSSL_NO_MULTIBLOCK
1601             BIO_printf(bio_err,
1602                        "%s: -mb specified but multi-block support is disabled\n",
1603                        prog);
1604             goto end;
1605 #endif
1606             break;
1607         case OPT_R_CASES:
1608             if (!opt_rand(o))
1609                 goto end;
1610             break;
1611         case OPT_PROV_CASES:
1612             if (!opt_provider(o))
1613                 goto end;
1614             break;
1615         case OPT_PRIMES:
1616             primes = opt_int_arg();
1617             break;
1618         case OPT_SECONDS:
1619             seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1620                         = seconds.ecdh = seconds.eddsa
1621                         = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1622             break;
1623         case OPT_BYTES:
1624             lengths_single = atoi(opt_arg());
1625             lengths = &lengths_single;
1626             size_num = 1;
1627             break;
1628         case OPT_AEAD:
1629             aead = 1;
1630             break;
1631         }
1632     }
1633 
1634     /* Remaining arguments are algorithms. */
1635     argc = opt_num_rest();
1636     argv = opt_rest();
1637 
1638     if (!app_RAND_load())
1639         goto end;
1640 
1641     for (; *argv; argv++) {
1642         const char *algo = *argv;
1643 
1644         if (opt_found(algo, doit_choices, &i)) {
1645             doit[i] = 1;
1646             continue;
1647         }
1648         if (strcmp(algo, "des") == 0) {
1649             doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1650             continue;
1651         }
1652         if (strcmp(algo, "sha") == 0) {
1653             doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1654             continue;
1655         }
1656 #ifndef OPENSSL_NO_DEPRECATED_3_0
1657         if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1658             continue;
1659 #endif
1660         if (strncmp(algo, "rsa", 3) == 0) {
1661             if (algo[3] == '\0') {
1662                 memset(rsa_doit, 1, sizeof(rsa_doit));
1663                 continue;
1664             }
1665             if (opt_found(algo, rsa_choices, &i)) {
1666                 rsa_doit[i] = 1;
1667                 continue;
1668             }
1669         }
1670 #ifndef OPENSSL_NO_DH
1671         if (strncmp(algo, "ffdh", 4) == 0) {
1672             if (algo[4] == '\0') {
1673                 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1674                 continue;
1675             }
1676             if (opt_found(algo, ffdh_choices, &i)) {
1677                 ffdh_doit[i] = 2;
1678                 continue;
1679             }
1680         }
1681 #endif
1682         if (strncmp(algo, "dsa", 3) == 0) {
1683             if (algo[3] == '\0') {
1684                 memset(dsa_doit, 1, sizeof(dsa_doit));
1685                 continue;
1686             }
1687             if (opt_found(algo, dsa_choices, &i)) {
1688                 dsa_doit[i] = 2;
1689                 continue;
1690             }
1691         }
1692         if (strcmp(algo, "aes") == 0) {
1693             doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1694             continue;
1695         }
1696         if (strcmp(algo, "camellia") == 0) {
1697             doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1698             continue;
1699         }
1700         if (strncmp(algo, "ecdsa", 5) == 0) {
1701             if (algo[5] == '\0') {
1702                 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1703                 continue;
1704             }
1705             if (opt_found(algo, ecdsa_choices, &i)) {
1706                 ecdsa_doit[i] = 2;
1707                 continue;
1708             }
1709         }
1710         if (strncmp(algo, "ecdh", 4) == 0) {
1711             if (algo[4] == '\0') {
1712                 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1713                 continue;
1714             }
1715             if (opt_found(algo, ecdh_choices, &i)) {
1716                 ecdh_doit[i] = 2;
1717                 continue;
1718             }
1719         }
1720         if (strcmp(algo, "eddsa") == 0) {
1721             memset(eddsa_doit, 1, sizeof(eddsa_doit));
1722             continue;
1723         }
1724         if (opt_found(algo, eddsa_choices, &i)) {
1725             eddsa_doit[i] = 2;
1726             continue;
1727         }
1728 #ifndef OPENSSL_NO_SM2
1729         if (strcmp(algo, "sm2") == 0) {
1730             memset(sm2_doit, 1, sizeof(sm2_doit));
1731             continue;
1732         }
1733         if (opt_found(algo, sm2_choices, &i)) {
1734             sm2_doit[i] = 2;
1735             continue;
1736         }
1737 #endif
1738         BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1739         goto end;
1740     }
1741 
1742     /* Sanity checks */
1743     if (aead) {
1744         if (evp_cipher == NULL) {
1745             BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1746             goto end;
1747         } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1748                      EVP_CIPH_FLAG_AEAD_CIPHER)) {
1749             BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1750                        EVP_CIPHER_get0_name(evp_cipher));
1751             goto end;
1752         }
1753     }
1754     if (multiblock) {
1755         if (evp_cipher == NULL) {
1756             BIO_printf(bio_err, "-mb can be used only with a multi-block"
1757                                 " capable cipher\n");
1758             goto end;
1759         } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1760                      EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1761             BIO_printf(bio_err, "%s is not a multi-block capable\n",
1762                        EVP_CIPHER_get0_name(evp_cipher));
1763             goto end;
1764         } else if (async_jobs > 0) {
1765             BIO_printf(bio_err, "Async mode is not supported with -mb");
1766             goto end;
1767         }
1768     }
1769 
1770     /* Initialize the job pool if async mode is enabled */
1771     if (async_jobs > 0) {
1772         async_init = ASYNC_init_thread(async_jobs, async_jobs);
1773         if (!async_init) {
1774             BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1775             goto end;
1776         }
1777     }
1778 
1779     loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1780     loopargs =
1781         app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1782     memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1783 
1784     for (i = 0; i < loopargs_len; i++) {
1785         if (async_jobs > 0) {
1786             loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1787             if (loopargs[i].wait_ctx == NULL) {
1788                 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1789                 goto end;
1790             }
1791         }
1792 
1793         buflen = lengths[size_num - 1];
1794         if (buflen < 36)    /* size of random vector in RSA benchmark */
1795             buflen = 36;
1796         if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1797             BIO_printf(bio_err, "Error: buffer size too large\n");
1798             goto end;
1799         }
1800         buflen += MAX_MISALIGNMENT + 1;
1801         loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1802         loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1803         memset(loopargs[i].buf_malloc, 0, buflen);
1804         memset(loopargs[i].buf2_malloc, 0, buflen);
1805 
1806         /* Align the start of buffers on a 64 byte boundary */
1807         loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1808         loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1809         loopargs[i].buflen = buflen - misalign;
1810         loopargs[i].sigsize = buflen - misalign;
1811         loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1812         loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1813 #ifndef OPENSSL_NO_DH
1814         loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1815         loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1816 #endif
1817     }
1818 
1819 #ifndef NO_FORK
1820     if (multi && do_multi(multi, size_num))
1821         goto show_res;
1822 #endif
1823 
1824     /* Initialize the engine after the fork */
1825     e = setup_engine(engine_id, 0);
1826 
1827     /* No parameters; turn on everything. */
1828     if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1829         memset(doit, 1, sizeof(doit));
1830         doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1831         ERR_set_mark();
1832         for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1833             if (!have_md(names[i]))
1834                 doit[i] = 0;
1835         }
1836         for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1837             if (!have_cipher(names[i]))
1838                 doit[i] = 0;
1839         }
1840         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1841                                  app_get0_propq())) != NULL) {
1842             EVP_MAC_free(mac);
1843             mac = NULL;
1844         } else {
1845             doit[D_GHASH] = 0;
1846         }
1847         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1848                                  app_get0_propq())) != NULL) {
1849             EVP_MAC_free(mac);
1850             mac = NULL;
1851         } else {
1852             doit[D_HMAC] = 0;
1853         }
1854         ERR_pop_to_mark();
1855         memset(rsa_doit, 1, sizeof(rsa_doit));
1856 #ifndef OPENSSL_NO_DH
1857         memset(ffdh_doit, 1, sizeof(ffdh_doit));
1858 #endif
1859         memset(dsa_doit, 1, sizeof(dsa_doit));
1860         memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1861         memset(ecdh_doit, 1, sizeof(ecdh_doit));
1862         memset(eddsa_doit, 1, sizeof(eddsa_doit));
1863 #ifndef OPENSSL_NO_SM2
1864         memset(sm2_doit, 1, sizeof(sm2_doit));
1865 #endif
1866     }
1867     for (i = 0; i < ALGOR_NUM; i++)
1868         if (doit[i])
1869             pr_header++;
1870 
1871     if (usertime == 0 && !mr)
1872         BIO_printf(bio_err,
1873                    "You have chosen to measure elapsed time "
1874                    "instead of user CPU time.\n");
1875 
1876 #if SIGALRM > 0
1877     signal(SIGALRM, alarmed);
1878 #endif
1879 
1880     if (doit[D_MD2]) {
1881         for (testnum = 0; testnum < size_num; testnum++) {
1882             print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1883                           seconds.sym);
1884             Time_F(START);
1885             count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1886             d = Time_F(STOP);
1887             print_result(D_MD2, testnum, count, d);
1888             if (count < 0)
1889                 break;
1890         }
1891     }
1892 
1893     if (doit[D_MDC2]) {
1894         for (testnum = 0; testnum < size_num; testnum++) {
1895             print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1896                           seconds.sym);
1897             Time_F(START);
1898             count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1899             d = Time_F(STOP);
1900             print_result(D_MDC2, testnum, count, d);
1901             if (count < 0)
1902                 break;
1903         }
1904     }
1905 
1906     if (doit[D_MD4]) {
1907         for (testnum = 0; testnum < size_num; testnum++) {
1908             print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1909                           seconds.sym);
1910             Time_F(START);
1911             count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1912             d = Time_F(STOP);
1913             print_result(D_MD4, testnum, count, d);
1914             if (count < 0)
1915                 break;
1916         }
1917     }
1918 
1919     if (doit[D_MD5]) {
1920         for (testnum = 0; testnum < size_num; testnum++) {
1921             print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1922                           seconds.sym);
1923             Time_F(START);
1924             count = run_benchmark(async_jobs, MD5_loop, loopargs);
1925             d = Time_F(STOP);
1926             print_result(D_MD5, testnum, count, d);
1927             if (count < 0)
1928                 break;
1929         }
1930     }
1931 
1932     if (doit[D_SHA1]) {
1933         for (testnum = 0; testnum < size_num; testnum++) {
1934             print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1935                           seconds.sym);
1936             Time_F(START);
1937             count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1938             d = Time_F(STOP);
1939             print_result(D_SHA1, testnum, count, d);
1940             if (count < 0)
1941                 break;
1942         }
1943     }
1944 
1945     if (doit[D_SHA256]) {
1946         for (testnum = 0; testnum < size_num; testnum++) {
1947             print_message(names[D_SHA256], c[D_SHA256][testnum],
1948                           lengths[testnum], seconds.sym);
1949             Time_F(START);
1950             count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1951             d = Time_F(STOP);
1952             print_result(D_SHA256, testnum, count, d);
1953             if (count < 0)
1954                 break;
1955         }
1956     }
1957 
1958     if (doit[D_SHA512]) {
1959         for (testnum = 0; testnum < size_num; testnum++) {
1960             print_message(names[D_SHA512], c[D_SHA512][testnum],
1961                           lengths[testnum], seconds.sym);
1962             Time_F(START);
1963             count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1964             d = Time_F(STOP);
1965             print_result(D_SHA512, testnum, count, d);
1966             if (count < 0)
1967                 break;
1968         }
1969     }
1970 
1971     if (doit[D_WHIRLPOOL]) {
1972         for (testnum = 0; testnum < size_num; testnum++) {
1973             print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
1974                           lengths[testnum], seconds.sym);
1975             Time_F(START);
1976             count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
1977             d = Time_F(STOP);
1978             print_result(D_WHIRLPOOL, testnum, count, d);
1979             if (count < 0)
1980                 break;
1981         }
1982     }
1983 
1984     if (doit[D_RMD160]) {
1985         for (testnum = 0; testnum < size_num; testnum++) {
1986             print_message(names[D_RMD160], c[D_RMD160][testnum],
1987                           lengths[testnum], seconds.sym);
1988             Time_F(START);
1989             count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
1990             d = Time_F(STOP);
1991             print_result(D_RMD160, testnum, count, d);
1992             if (count < 0)
1993                 break;
1994         }
1995     }
1996 
1997     if (doit[D_HMAC]) {
1998         static const char hmac_key[] = "This is a key...";
1999         int len = strlen(hmac_key);
2000         OSSL_PARAM params[3];
2001 
2002         mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
2003         if (mac == NULL || evp_mac_mdname == NULL)
2004             goto end;
2005 
2006         evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
2007                                    "HMAC name");
2008         sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
2009         names[D_HMAC] = evp_hmac_name;
2010 
2011         params[0] =
2012             OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2013                                              evp_mac_mdname, 0);
2014         params[1] =
2015             OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2016                                               (char *)hmac_key, len);
2017         params[2] = OSSL_PARAM_construct_end();
2018 
2019         for (i = 0; i < loopargs_len; i++) {
2020             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2021             if (loopargs[i].mctx == NULL)
2022                 goto end;
2023 
2024             if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2025                 goto skip_hmac; /* Digest not found */
2026         }
2027         for (testnum = 0; testnum < size_num; testnum++) {
2028             print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
2029                           seconds.sym);
2030             Time_F(START);
2031             count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2032             d = Time_F(STOP);
2033             print_result(D_HMAC, testnum, count, d);
2034             if (count < 0)
2035                 break;
2036         }
2037         for (i = 0; i < loopargs_len; i++)
2038             EVP_MAC_CTX_free(loopargs[i].mctx);
2039         EVP_MAC_free(mac);
2040         mac = NULL;
2041     }
2042 skip_hmac:
2043     if (doit[D_CBC_DES]) {
2044         int st = 1;
2045 
2046         for (i = 0; st && i < loopargs_len; i++) {
2047             loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2048                                                   sizeof(deskey) / 3);
2049             st = loopargs[i].ctx != NULL;
2050         }
2051         algindex = D_CBC_DES;
2052         for (testnum = 0; st && testnum < size_num; testnum++) {
2053             print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2054                           lengths[testnum], seconds.sym);
2055             Time_F(START);
2056             count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2057             d = Time_F(STOP);
2058             print_result(D_CBC_DES, testnum, count, d);
2059         }
2060         for (i = 0; i < loopargs_len; i++)
2061             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2062     }
2063 
2064     if (doit[D_EDE3_DES]) {
2065         int st = 1;
2066 
2067         for (i = 0; st && i < loopargs_len; i++) {
2068             loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2069                                                   sizeof(deskey));
2070             st = loopargs[i].ctx != NULL;
2071         }
2072         algindex = D_EDE3_DES;
2073         for (testnum = 0; st && testnum < size_num; testnum++) {
2074             print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2075                           lengths[testnum], seconds.sym);
2076             Time_F(START);
2077             count =
2078                 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2079             d = Time_F(STOP);
2080             print_result(D_EDE3_DES, testnum, count, d);
2081         }
2082         for (i = 0; i < loopargs_len; i++)
2083             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2084     }
2085 
2086     for (k = 0; k < 3; k++) {
2087         algindex = D_CBC_128_AES + k;
2088         if (doit[algindex]) {
2089             int st = 1;
2090 
2091             keylen = 16 + k * 8;
2092             for (i = 0; st && i < loopargs_len; i++) {
2093                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2094                                                       key32, keylen);
2095                 st = loopargs[i].ctx != NULL;
2096             }
2097 
2098             for (testnum = 0; st && testnum < size_num; testnum++) {
2099                 print_message(names[algindex], c[algindex][testnum],
2100                               lengths[testnum], seconds.sym);
2101                 Time_F(START);
2102                 count =
2103                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2104                 d = Time_F(STOP);
2105                 print_result(algindex, testnum, count, d);
2106             }
2107             for (i = 0; i < loopargs_len; i++)
2108                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2109         }
2110     }
2111 
2112     for (k = 0; k < 3; k++) {
2113         algindex = D_CBC_128_CML + k;
2114         if (doit[algindex]) {
2115             int st = 1;
2116 
2117             keylen = 16 + k * 8;
2118             for (i = 0; st && i < loopargs_len; i++) {
2119                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2120                                                       key32, keylen);
2121                 st = loopargs[i].ctx != NULL;
2122             }
2123 
2124             for (testnum = 0; st && testnum < size_num; testnum++) {
2125                 print_message(names[algindex], c[algindex][testnum],
2126                               lengths[testnum], seconds.sym);
2127                 Time_F(START);
2128                 count =
2129                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2130                 d = Time_F(STOP);
2131                 print_result(algindex, testnum, count, d);
2132             }
2133             for (i = 0; i < loopargs_len; i++)
2134                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2135         }
2136     }
2137 
2138     for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2139         if (doit[algindex]) {
2140             int st = 1;
2141 
2142             keylen = 16;
2143             for (i = 0; st && i < loopargs_len; i++) {
2144                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2145                                                       key32, keylen);
2146                 st = loopargs[i].ctx != NULL;
2147             }
2148 
2149             for (testnum = 0; st && testnum < size_num; testnum++) {
2150                 print_message(names[algindex], c[algindex][testnum],
2151                               lengths[testnum], seconds.sym);
2152                 Time_F(START);
2153                 count =
2154                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2155                 d = Time_F(STOP);
2156                 print_result(algindex, testnum, count, d);
2157             }
2158             for (i = 0; i < loopargs_len; i++)
2159                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2160         }
2161     }
2162     if (doit[D_GHASH]) {
2163         static const char gmac_iv[] = "0123456789ab";
2164         OSSL_PARAM params[3];
2165 
2166         mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2167         if (mac == NULL)
2168             goto end;
2169 
2170         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2171                                                      "aes-128-gcm", 0);
2172         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2173                                                       (char *)gmac_iv,
2174                                                       sizeof(gmac_iv) - 1);
2175         params[2] = OSSL_PARAM_construct_end();
2176 
2177         for (i = 0; i < loopargs_len; i++) {
2178             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2179             if (loopargs[i].mctx == NULL)
2180                 goto end;
2181 
2182             if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2183                 goto end;
2184         }
2185         for (testnum = 0; testnum < size_num; testnum++) {
2186             print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2187                           seconds.sym);
2188             Time_F(START);
2189             count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2190             d = Time_F(STOP);
2191             print_result(D_GHASH, testnum, count, d);
2192             if (count < 0)
2193                 break;
2194         }
2195         for (i = 0; i < loopargs_len; i++)
2196             EVP_MAC_CTX_free(loopargs[i].mctx);
2197         EVP_MAC_free(mac);
2198         mac = NULL;
2199     }
2200 
2201     if (doit[D_RAND]) {
2202         for (testnum = 0; testnum < size_num; testnum++) {
2203             print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2204                           seconds.sym);
2205             Time_F(START);
2206             count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2207             d = Time_F(STOP);
2208             print_result(D_RAND, testnum, count, d);
2209         }
2210     }
2211 
2212     if (doit[D_EVP]) {
2213         if (evp_cipher != NULL) {
2214             int (*loopfunc) (void *) = EVP_Update_loop;
2215 
2216             if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2217                                EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2218                 multiblock_speed(evp_cipher, lengths_single, &seconds);
2219                 ret = 0;
2220                 goto end;
2221             }
2222 
2223             names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2224 
2225             if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2226                 loopfunc = EVP_Update_loop_ccm;
2227             } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2228                                 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2229                 loopfunc = EVP_Update_loop_aead;
2230                 if (lengths == lengths_list) {
2231                     lengths = aead_lengths_list;
2232                     size_num = OSSL_NELEM(aead_lengths_list);
2233                 }
2234             }
2235 
2236             for (testnum = 0; testnum < size_num; testnum++) {
2237                 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2238                               seconds.sym);
2239 
2240                 for (k = 0; k < loopargs_len; k++) {
2241                     loopargs[k].ctx = EVP_CIPHER_CTX_new();
2242                     if (loopargs[k].ctx == NULL) {
2243                         BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2244                         exit(1);
2245                     }
2246                     if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2247                                            NULL, iv, decrypt ? 0 : 1)) {
2248                         BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2249                         ERR_print_errors(bio_err);
2250                         exit(1);
2251                     }
2252 
2253                     EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2254 
2255                     keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2256                     loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2257                     EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2258                     if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2259                                            loopargs[k].key, NULL, -1)) {
2260                         BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2261                         ERR_print_errors(bio_err);
2262                         exit(1);
2263                     }
2264                     OPENSSL_clear_free(loopargs[k].key, keylen);
2265 
2266                     /* SIV mode only allows for a single Update operation */
2267                     if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2268                         (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2269                                                   EVP_CTRL_SET_SPEED, 1, NULL);
2270                 }
2271 
2272                 Time_F(START);
2273                 count = run_benchmark(async_jobs, loopfunc, loopargs);
2274                 d = Time_F(STOP);
2275                 for (k = 0; k < loopargs_len; k++)
2276                     EVP_CIPHER_CTX_free(loopargs[k].ctx);
2277                 print_result(D_EVP, testnum, count, d);
2278             }
2279         } else if (evp_md_name != NULL) {
2280             names[D_EVP] = evp_md_name;
2281 
2282             for (testnum = 0; testnum < size_num; testnum++) {
2283                 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2284                               seconds.sym);
2285                 Time_F(START);
2286                 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2287                 d = Time_F(STOP);
2288                 print_result(D_EVP, testnum, count, d);
2289                 if (count < 0)
2290                     break;
2291             }
2292         }
2293     }
2294 
2295     if (doit[D_EVP_CMAC]) {
2296         OSSL_PARAM params[3];
2297         EVP_CIPHER *cipher = NULL;
2298 
2299         mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2300         if (mac == NULL || evp_mac_ciphername == NULL)
2301             goto end;
2302         if (!opt_cipher(evp_mac_ciphername, &cipher))
2303             goto end;
2304 
2305         keylen = EVP_CIPHER_get_key_length(cipher);
2306         EVP_CIPHER_free(cipher);
2307         if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2308             BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2309             goto end;
2310         }
2311         evp_cmac_name = app_malloc(sizeof("cmac()")
2312                                    + strlen(evp_mac_ciphername), "CMAC name");
2313         sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2314         names[D_EVP_CMAC] = evp_cmac_name;
2315 
2316         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2317                                                      evp_mac_ciphername, 0);
2318         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2319                                                       (char *)key32, keylen);
2320         params[2] = OSSL_PARAM_construct_end();
2321 
2322         for (i = 0; i < loopargs_len; i++) {
2323             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2324             if (loopargs[i].mctx == NULL)
2325                 goto end;
2326 
2327             if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2328                 goto end;
2329         }
2330 
2331         for (testnum = 0; testnum < size_num; testnum++) {
2332             print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2333                           lengths[testnum], seconds.sym);
2334             Time_F(START);
2335             count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2336             d = Time_F(STOP);
2337             print_result(D_EVP_CMAC, testnum, count, d);
2338             if (count < 0)
2339                 break;
2340         }
2341         for (i = 0; i < loopargs_len; i++)
2342             EVP_MAC_CTX_free(loopargs[i].mctx);
2343         EVP_MAC_free(mac);
2344         mac = NULL;
2345     }
2346 
2347     for (i = 0; i < loopargs_len; i++)
2348         if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2349             goto end;
2350 
2351     for (testnum = 0; testnum < RSA_NUM; testnum++) {
2352         EVP_PKEY *rsa_key = NULL;
2353         int st = 0;
2354 
2355         if (!rsa_doit[testnum])
2356             continue;
2357 
2358         if (primes > RSA_DEFAULT_PRIME_NUM) {
2359             /* we haven't set keys yet,  generate multi-prime RSA keys */
2360             bn = BN_new();
2361             st = bn != NULL
2362                 && BN_set_word(bn, RSA_F4)
2363                 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2364                 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2365                 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2366                 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2367                 && EVP_PKEY_keygen(genctx, &rsa_key);
2368             BN_free(bn);
2369             bn = NULL;
2370             EVP_PKEY_CTX_free(genctx);
2371             genctx = NULL;
2372         } else {
2373             const unsigned char *p = rsa_keys[testnum].data;
2374 
2375             st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2376                                            rsa_keys[testnum].length)) != NULL;
2377         }
2378 
2379         for (i = 0; st && i < loopargs_len; i++) {
2380             loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2381             loopargs[i].sigsize = loopargs[i].buflen;
2382             if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2383                 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2384                 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2385                                  loopargs[i].buf2,
2386                                  &loopargs[i].sigsize,
2387                                  loopargs[i].buf, 36) <= 0)
2388                 st = 0;
2389         }
2390         if (!st) {
2391             BIO_printf(bio_err,
2392                        "RSA sign setup failure.  No RSA sign will be done.\n");
2393             ERR_print_errors(bio_err);
2394             op_count = 1;
2395         } else {
2396             pkey_print_message("private", "rsa",
2397                                rsa_c[testnum][0], rsa_keys[testnum].bits,
2398                                seconds.rsa);
2399             /* RSA_blinding_on(rsa_key[testnum],NULL); */
2400             Time_F(START);
2401             count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2402             d = Time_F(STOP);
2403             BIO_printf(bio_err,
2404                        mr ? "+R1:%ld:%d:%.2f\n"
2405                        : "%ld %u bits private RSA's in %.2fs\n",
2406                        count, rsa_keys[testnum].bits, d);
2407             rsa_results[testnum][0] = (double)count / d;
2408             op_count = count;
2409         }
2410 
2411         for (i = 0; st && i < loopargs_len; i++) {
2412             loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2413                                                                    NULL);
2414             if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2415                 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2416                 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2417                                    loopargs[i].buf2,
2418                                    loopargs[i].sigsize,
2419                                    loopargs[i].buf, 36) <= 0)
2420                 st = 0;
2421         }
2422         if (!st) {
2423             BIO_printf(bio_err,
2424                        "RSA verify setup failure.  No RSA verify will be done.\n");
2425             ERR_print_errors(bio_err);
2426             rsa_doit[testnum] = 0;
2427         } else {
2428             pkey_print_message("public", "rsa",
2429                                rsa_c[testnum][1], rsa_keys[testnum].bits,
2430                                seconds.rsa);
2431             Time_F(START);
2432             count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2433             d = Time_F(STOP);
2434             BIO_printf(bio_err,
2435                        mr ? "+R2:%ld:%d:%.2f\n"
2436                        : "%ld %u bits public RSA's in %.2fs\n",
2437                        count, rsa_keys[testnum].bits, d);
2438             rsa_results[testnum][1] = (double)count / d;
2439         }
2440 
2441         if (op_count <= 1) {
2442             /* if longer than 10s, don't do any more */
2443             stop_it(rsa_doit, testnum);
2444         }
2445         EVP_PKEY_free(rsa_key);
2446     }
2447 
2448     for (testnum = 0; testnum < DSA_NUM; testnum++) {
2449         EVP_PKEY *dsa_key = NULL;
2450         int st;
2451 
2452         if (!dsa_doit[testnum])
2453             continue;
2454 
2455         st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2456 
2457         for (i = 0; st && i < loopargs_len; i++) {
2458             loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2459                                                                  NULL);
2460             loopargs[i].sigsize = loopargs[i].buflen;
2461             if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2462                 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2463 
2464                 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2465                                  loopargs[i].buf2,
2466                                  &loopargs[i].sigsize,
2467                                  loopargs[i].buf, 20) <= 0)
2468                 st = 0;
2469         }
2470         if (!st) {
2471             BIO_printf(bio_err,
2472                        "DSA sign setup failure.  No DSA sign will be done.\n");
2473             ERR_print_errors(bio_err);
2474             op_count = 1;
2475         } else {
2476             pkey_print_message("sign", "dsa",
2477                                dsa_c[testnum][0], dsa_bits[testnum],
2478                                seconds.dsa);
2479             Time_F(START);
2480             count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2481             d = Time_F(STOP);
2482             BIO_printf(bio_err,
2483                        mr ? "+R3:%ld:%u:%.2f\n"
2484                        : "%ld %u bits DSA signs in %.2fs\n",
2485                        count, dsa_bits[testnum], d);
2486             dsa_results[testnum][0] = (double)count / d;
2487             op_count = count;
2488         }
2489 
2490         for (i = 0; st && i < loopargs_len; i++) {
2491             loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2492                                                                    NULL);
2493             if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2494                 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2495                 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2496                                    loopargs[i].buf2,
2497                                    loopargs[i].sigsize,
2498                                    loopargs[i].buf, 36) <= 0)
2499                 st = 0;
2500         }
2501         if (!st) {
2502             BIO_printf(bio_err,
2503                        "DSA verify setup failure.  No DSA verify will be done.\n");
2504             ERR_print_errors(bio_err);
2505             dsa_doit[testnum] = 0;
2506         } else {
2507             pkey_print_message("verify", "dsa",
2508                                dsa_c[testnum][1], dsa_bits[testnum],
2509                                seconds.dsa);
2510             Time_F(START);
2511             count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2512             d = Time_F(STOP);
2513             BIO_printf(bio_err,
2514                        mr ? "+R4:%ld:%u:%.2f\n"
2515                        : "%ld %u bits DSA verify in %.2fs\n",
2516                        count, dsa_bits[testnum], d);
2517             dsa_results[testnum][1] = (double)count / d;
2518         }
2519 
2520         if (op_count <= 1) {
2521             /* if longer than 10s, don't do any more */
2522             stop_it(dsa_doit, testnum);
2523         }
2524         EVP_PKEY_free(dsa_key);
2525     }
2526 
2527     for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2528         EVP_PKEY *ecdsa_key = NULL;
2529         int st;
2530 
2531         if (!ecdsa_doit[testnum])
2532             continue;
2533 
2534         st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2535 
2536         for (i = 0; st && i < loopargs_len; i++) {
2537             loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2538                                                                    NULL);
2539             loopargs[i].sigsize = loopargs[i].buflen;
2540             if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2541                 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2542 
2543                 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2544                                  loopargs[i].buf2,
2545                                  &loopargs[i].sigsize,
2546                                  loopargs[i].buf, 20) <= 0)
2547                 st = 0;
2548         }
2549         if (!st) {
2550             BIO_printf(bio_err,
2551                        "ECDSA sign setup failure.  No ECDSA sign will be done.\n");
2552             ERR_print_errors(bio_err);
2553             op_count = 1;
2554         } else {
2555             pkey_print_message("sign", "ecdsa",
2556                                ecdsa_c[testnum][0], ec_curves[testnum].bits,
2557                                seconds.ecdsa);
2558             Time_F(START);
2559             count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2560             d = Time_F(STOP);
2561             BIO_printf(bio_err,
2562                        mr ? "+R5:%ld:%u:%.2f\n"
2563                        : "%ld %u bits ECDSA signs in %.2fs\n",
2564                        count, ec_curves[testnum].bits, d);
2565             ecdsa_results[testnum][0] = (double)count / d;
2566             op_count = count;
2567         }
2568 
2569         for (i = 0; st && i < loopargs_len; i++) {
2570             loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2571                                                                      NULL);
2572             if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2573                 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2574                 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2575                                    loopargs[i].buf2,
2576                                    loopargs[i].sigsize,
2577                                    loopargs[i].buf, 20) <= 0)
2578                 st = 0;
2579         }
2580         if (!st) {
2581             BIO_printf(bio_err,
2582                        "ECDSA verify setup failure.  No ECDSA verify will be done.\n");
2583             ERR_print_errors(bio_err);
2584             ecdsa_doit[testnum] = 0;
2585         } else {
2586             pkey_print_message("verify", "ecdsa",
2587                                ecdsa_c[testnum][1], ec_curves[testnum].bits,
2588                                seconds.ecdsa);
2589             Time_F(START);
2590             count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2591             d = Time_F(STOP);
2592             BIO_printf(bio_err,
2593                        mr ? "+R6:%ld:%u:%.2f\n"
2594                        : "%ld %u bits ECDSA verify in %.2fs\n",
2595                        count, ec_curves[testnum].bits, d);
2596             ecdsa_results[testnum][1] = (double)count / d;
2597         }
2598 
2599         if (op_count <= 1) {
2600             /* if longer than 10s, don't do any more */
2601             stop_it(ecdsa_doit, testnum);
2602         }
2603     }
2604 
2605     for (testnum = 0; testnum < EC_NUM; testnum++) {
2606         int ecdh_checks = 1;
2607 
2608         if (!ecdh_doit[testnum])
2609             continue;
2610 
2611         for (i = 0; i < loopargs_len; i++) {
2612             EVP_PKEY_CTX *test_ctx = NULL;
2613             EVP_PKEY_CTX *ctx = NULL;
2614             EVP_PKEY *key_A = NULL;
2615             EVP_PKEY *key_B = NULL;
2616             size_t outlen;
2617             size_t test_outlen;
2618 
2619             if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2620                 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2621                 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2622                 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2623                 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2624                 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2625                 || outlen == 0 /* ensure outlen is a valid size */
2626                 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2627                 ecdh_checks = 0;
2628                 BIO_printf(bio_err, "ECDH key generation failure.\n");
2629                 ERR_print_errors(bio_err);
2630                 op_count = 1;
2631                 break;
2632             }
2633 
2634             /*
2635              * Here we perform a test run, comparing the output of a*B and b*A;
2636              * we try this here and assume that further EVP_PKEY_derive calls
2637              * never fail, so we can skip checks in the actually benchmarked
2638              * code, for maximum performance.
2639              */
2640             if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2641                 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
2642                 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
2643                 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
2644                 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
2645                 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
2646                 || test_outlen != outlen /* compare output length */) {
2647                 ecdh_checks = 0;
2648                 BIO_printf(bio_err, "ECDH computation failure.\n");
2649                 ERR_print_errors(bio_err);
2650                 op_count = 1;
2651                 break;
2652             }
2653 
2654             /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2655             if (CRYPTO_memcmp(loopargs[i].secret_a,
2656                               loopargs[i].secret_b, outlen)) {
2657                 ecdh_checks = 0;
2658                 BIO_printf(bio_err, "ECDH computations don't match.\n");
2659                 ERR_print_errors(bio_err);
2660                 op_count = 1;
2661                 break;
2662             }
2663 
2664             loopargs[i].ecdh_ctx[testnum] = ctx;
2665             loopargs[i].outlen[testnum] = outlen;
2666 
2667             EVP_PKEY_free(key_A);
2668             EVP_PKEY_free(key_B);
2669             EVP_PKEY_CTX_free(test_ctx);
2670             test_ctx = NULL;
2671         }
2672         if (ecdh_checks != 0) {
2673             pkey_print_message("", "ecdh",
2674                                ecdh_c[testnum][0],
2675                                ec_curves[testnum].bits, seconds.ecdh);
2676             Time_F(START);
2677             count =
2678                 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2679             d = Time_F(STOP);
2680             BIO_printf(bio_err,
2681                        mr ? "+R7:%ld:%d:%.2f\n" :
2682                        "%ld %u-bits ECDH ops in %.2fs\n", count,
2683                        ec_curves[testnum].bits, d);
2684             ecdh_results[testnum][0] = (double)count / d;
2685             op_count = count;
2686         }
2687 
2688         if (op_count <= 1) {
2689             /* if longer than 10s, don't do any more */
2690             stop_it(ecdh_doit, testnum);
2691         }
2692     }
2693 
2694     for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2695         int st = 1;
2696         EVP_PKEY *ed_pkey = NULL;
2697         EVP_PKEY_CTX *ed_pctx = NULL;
2698 
2699         if (!eddsa_doit[testnum])
2700             continue;           /* Ignore Curve */
2701         for (i = 0; i < loopargs_len; i++) {
2702             loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2703             if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2704                 st = 0;
2705                 break;
2706             }
2707             loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2708             if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2709                 st = 0;
2710                 break;
2711             }
2712 
2713             if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2714                                                NULL)) == NULL
2715                 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2716                 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2717                 st = 0;
2718                 EVP_PKEY_CTX_free(ed_pctx);
2719                 break;
2720             }
2721             EVP_PKEY_CTX_free(ed_pctx);
2722 
2723             if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2724                                     NULL, ed_pkey)) {
2725                 st = 0;
2726                 EVP_PKEY_free(ed_pkey);
2727                 break;
2728             }
2729             if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2730                                       NULL, NULL, ed_pkey)) {
2731                 st = 0;
2732                 EVP_PKEY_free(ed_pkey);
2733                 break;
2734             }
2735 
2736             EVP_PKEY_free(ed_pkey);
2737             ed_pkey = NULL;
2738         }
2739         if (st == 0) {
2740             BIO_printf(bio_err, "EdDSA failure.\n");
2741             ERR_print_errors(bio_err);
2742             op_count = 1;
2743         } else {
2744             for (i = 0; i < loopargs_len; i++) {
2745                 /* Perform EdDSA signature test */
2746                 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2747                 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2748                                     loopargs[i].buf2, &loopargs[i].sigsize,
2749                                     loopargs[i].buf, 20);
2750                 if (st == 0)
2751                     break;
2752             }
2753             if (st == 0) {
2754                 BIO_printf(bio_err,
2755                            "EdDSA sign failure.  No EdDSA sign will be done.\n");
2756                 ERR_print_errors(bio_err);
2757                 op_count = 1;
2758             } else {
2759                 pkey_print_message("sign", ed_curves[testnum].name,
2760                                    eddsa_c[testnum][0],
2761                                    ed_curves[testnum].bits, seconds.eddsa);
2762                 Time_F(START);
2763                 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2764                 d = Time_F(STOP);
2765 
2766                 BIO_printf(bio_err,
2767                            mr ? "+R8:%ld:%u:%s:%.2f\n" :
2768                            "%ld %u bits %s signs in %.2fs \n",
2769                            count, ed_curves[testnum].bits,
2770                            ed_curves[testnum].name, d);
2771                 eddsa_results[testnum][0] = (double)count / d;
2772                 op_count = count;
2773             }
2774             /* Perform EdDSA verification test */
2775             for (i = 0; i < loopargs_len; i++) {
2776                 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2777                                       loopargs[i].buf2, loopargs[i].sigsize,
2778                                       loopargs[i].buf, 20);
2779                 if (st != 1)
2780                     break;
2781             }
2782             if (st != 1) {
2783                 BIO_printf(bio_err,
2784                            "EdDSA verify failure.  No EdDSA verify will be done.\n");
2785                 ERR_print_errors(bio_err);
2786                 eddsa_doit[testnum] = 0;
2787             } else {
2788                 pkey_print_message("verify", ed_curves[testnum].name,
2789                                    eddsa_c[testnum][1],
2790                                    ed_curves[testnum].bits, seconds.eddsa);
2791                 Time_F(START);
2792                 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2793                 d = Time_F(STOP);
2794                 BIO_printf(bio_err,
2795                            mr ? "+R9:%ld:%u:%s:%.2f\n"
2796                            : "%ld %u bits %s verify in %.2fs\n",
2797                            count, ed_curves[testnum].bits,
2798                            ed_curves[testnum].name, d);
2799                 eddsa_results[testnum][1] = (double)count / d;
2800             }
2801 
2802             if (op_count <= 1) {
2803                 /* if longer than 10s, don't do any more */
2804                 stop_it(eddsa_doit, testnum);
2805             }
2806         }
2807     }
2808 
2809 #ifndef OPENSSL_NO_SM2
2810     for (testnum = 0; testnum < SM2_NUM; testnum++) {
2811         int st = 1;
2812         EVP_PKEY *sm2_pkey = NULL;
2813 
2814         if (!sm2_doit[testnum])
2815             continue;           /* Ignore Curve */
2816         /* Init signing and verification */
2817         for (i = 0; i < loopargs_len; i++) {
2818             EVP_PKEY_CTX *sm2_pctx = NULL;
2819             EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2820             EVP_PKEY_CTX *pctx = NULL;
2821             st = 0;
2822 
2823             loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2824             loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2825             if (loopargs[i].sm2_ctx[testnum] == NULL
2826                     || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2827                 break;
2828 
2829             sm2_pkey = NULL;
2830 
2831             st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2832                 || EVP_PKEY_keygen_init(pctx) <= 0
2833                 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2834                     sm2_curves[testnum].nid) <= 0
2835                 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2836             EVP_PKEY_CTX_free(pctx);
2837             if (st == 0)
2838                 break;
2839 
2840             st = 0; /* set back to zero */
2841             /* attach it sooner to rely on main final cleanup */
2842             loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2843             loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2844 
2845             sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2846             sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2847             if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2848                 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2849                 break;
2850             }
2851 
2852             /* attach them directly to respective ctx */
2853             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2854             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2855 
2856             /*
2857              * No need to allow user to set an explicit ID here, just use
2858              * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2859              */
2860             if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2861                 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2862                 break;
2863 
2864             if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2865                                     EVP_sm3(), NULL, sm2_pkey))
2866                 break;
2867             if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2868                                       EVP_sm3(), NULL, sm2_pkey))
2869                 break;
2870             st = 1;         /* mark loop as succeeded */
2871         }
2872         if (st == 0) {
2873             BIO_printf(bio_err, "SM2 init failure.\n");
2874             ERR_print_errors(bio_err);
2875             op_count = 1;
2876         } else {
2877             for (i = 0; i < loopargs_len; i++) {
2878                 /* Perform SM2 signature test */
2879                 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2880                                     loopargs[i].buf2, &loopargs[i].sigsize,
2881                                     loopargs[i].buf, 20);
2882                 if (st == 0)
2883                     break;
2884             }
2885             if (st == 0) {
2886                 BIO_printf(bio_err,
2887                            "SM2 sign failure.  No SM2 sign will be done.\n");
2888                 ERR_print_errors(bio_err);
2889                 op_count = 1;
2890             } else {
2891                 pkey_print_message("sign", sm2_curves[testnum].name,
2892                                    sm2_c[testnum][0],
2893                                    sm2_curves[testnum].bits, seconds.sm2);
2894                 Time_F(START);
2895                 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2896                 d = Time_F(STOP);
2897 
2898                 BIO_printf(bio_err,
2899                            mr ? "+R10:%ld:%u:%s:%.2f\n" :
2900                            "%ld %u bits %s signs in %.2fs \n",
2901                            count, sm2_curves[testnum].bits,
2902                            sm2_curves[testnum].name, d);
2903                 sm2_results[testnum][0] = (double)count / d;
2904                 op_count = count;
2905             }
2906 
2907             /* Perform SM2 verification test */
2908             for (i = 0; i < loopargs_len; i++) {
2909                 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2910                                       loopargs[i].buf2, loopargs[i].sigsize,
2911                                       loopargs[i].buf, 20);
2912                 if (st != 1)
2913                     break;
2914             }
2915             if (st != 1) {
2916                 BIO_printf(bio_err,
2917                            "SM2 verify failure.  No SM2 verify will be done.\n");
2918                 ERR_print_errors(bio_err);
2919                 sm2_doit[testnum] = 0;
2920             } else {
2921                 pkey_print_message("verify", sm2_curves[testnum].name,
2922                                    sm2_c[testnum][1],
2923                                    sm2_curves[testnum].bits, seconds.sm2);
2924                 Time_F(START);
2925                 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2926                 d = Time_F(STOP);
2927                 BIO_printf(bio_err,
2928                            mr ? "+R11:%ld:%u:%s:%.2f\n"
2929                            : "%ld %u bits %s verify in %.2fs\n",
2930                            count, sm2_curves[testnum].bits,
2931                            sm2_curves[testnum].name, d);
2932                 sm2_results[testnum][1] = (double)count / d;
2933             }
2934 
2935             if (op_count <= 1) {
2936                 /* if longer than 10s, don't do any more */
2937                 for (testnum++; testnum < SM2_NUM; testnum++)
2938                     sm2_doit[testnum] = 0;
2939             }
2940         }
2941     }
2942 #endif                         /* OPENSSL_NO_SM2 */
2943 
2944 #ifndef OPENSSL_NO_DH
2945     for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2946         int ffdh_checks = 1;
2947 
2948         if (!ffdh_doit[testnum])
2949             continue;
2950 
2951         for (i = 0; i < loopargs_len; i++) {
2952             EVP_PKEY *pkey_A = NULL;
2953             EVP_PKEY *pkey_B = NULL;
2954             EVP_PKEY_CTX *ffdh_ctx = NULL;
2955             EVP_PKEY_CTX *test_ctx = NULL;
2956             size_t secret_size;
2957             size_t test_out;
2958 
2959             /* Ensure that the error queue is empty */
2960             if (ERR_peek_error()) {
2961                 BIO_printf(bio_err,
2962                            "WARNING: the error queue contains previous unhandled errors.\n");
2963                 ERR_print_errors(bio_err);
2964             }
2965 
2966             pkey_A = EVP_PKEY_new();
2967             if (!pkey_A) {
2968                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2969                 ERR_print_errors(bio_err);
2970                 op_count = 1;
2971                 ffdh_checks = 0;
2972                 break;
2973             }
2974             pkey_B = EVP_PKEY_new();
2975             if (!pkey_B) {
2976                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2977                 ERR_print_errors(bio_err);
2978                 op_count = 1;
2979                 ffdh_checks = 0;
2980                 break;
2981             }
2982 
2983             ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2984             if (!ffdh_ctx) {
2985                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2986                 ERR_print_errors(bio_err);
2987                 op_count = 1;
2988                 ffdh_checks = 0;
2989                 break;
2990             }
2991 
2992             if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
2993                 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
2994                 ERR_print_errors(bio_err);
2995                 op_count = 1;
2996                 ffdh_checks = 0;
2997                 break;
2998             }
2999             if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3000                 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3001                 ERR_print_errors(bio_err);
3002                 op_count = 1;
3003                 ffdh_checks = 0;
3004                 break;
3005             }
3006 
3007             if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
3008                 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
3009                 BIO_printf(bio_err, "FFDH key generation failure.\n");
3010                 ERR_print_errors(bio_err);
3011                 op_count = 1;
3012                 ffdh_checks = 0;
3013                 break;
3014             }
3015 
3016             EVP_PKEY_CTX_free(ffdh_ctx);
3017 
3018             /*
3019              * check if the derivation works correctly both ways so that
3020              * we know if future derive calls will fail, and we can skip
3021              * error checking in benchmarked code
3022              */
3023             ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3024             if (ffdh_ctx == NULL) {
3025                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3026                 ERR_print_errors(bio_err);
3027                 op_count = 1;
3028                 ffdh_checks = 0;
3029                 break;
3030             }
3031             if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3032                 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3033                 ERR_print_errors(bio_err);
3034                 op_count = 1;
3035                 ffdh_checks = 0;
3036                 break;
3037             }
3038             if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3039                 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3040                 ERR_print_errors(bio_err);
3041                 op_count = 1;
3042                 ffdh_checks = 0;
3043                 break;
3044             }
3045             if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3046                 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3047                 ERR_print_errors(bio_err);
3048                 op_count = 1;
3049                 ffdh_checks = 0;
3050                 break;
3051             }
3052             if (secret_size > MAX_FFDH_SIZE) {
3053                 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3054                 op_count = 1;
3055                 ffdh_checks = 0;
3056                 break;
3057             }
3058             if (EVP_PKEY_derive(ffdh_ctx,
3059                                 loopargs[i].secret_ff_a,
3060                                 &secret_size) <= 0) {
3061                 BIO_printf(bio_err, "Shared secret derive failure.\n");
3062                 ERR_print_errors(bio_err);
3063                 op_count = 1;
3064                 ffdh_checks = 0;
3065                 break;
3066             }
3067             /* Now check from side B */
3068             test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3069             if (!test_ctx) {
3070                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3071                 ERR_print_errors(bio_err);
3072                 op_count = 1;
3073                 ffdh_checks = 0;
3074                 break;
3075             }
3076             if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3077                 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3078                 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3079                 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3080                 test_out != secret_size) {
3081                 BIO_printf(bio_err, "FFDH computation failure.\n");
3082                 op_count = 1;
3083                 ffdh_checks = 0;
3084                 break;
3085             }
3086 
3087             /* compare the computed secrets */
3088             if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3089                               loopargs[i].secret_ff_b, secret_size)) {
3090                 BIO_printf(bio_err, "FFDH computations don't match.\n");
3091                 ERR_print_errors(bio_err);
3092                 op_count = 1;
3093                 ffdh_checks = 0;
3094                 break;
3095             }
3096 
3097             loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3098 
3099             EVP_PKEY_free(pkey_A);
3100             pkey_A = NULL;
3101             EVP_PKEY_free(pkey_B);
3102             pkey_B = NULL;
3103             EVP_PKEY_CTX_free(test_ctx);
3104             test_ctx = NULL;
3105         }
3106         if (ffdh_checks != 0) {
3107             pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3108                                ffdh_params[testnum].bits, seconds.ffdh);
3109             Time_F(START);
3110             count =
3111                 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3112             d = Time_F(STOP);
3113             BIO_printf(bio_err,
3114                        mr ? "+R12:%ld:%d:%.2f\n" :
3115                        "%ld %u-bits FFDH ops in %.2fs\n", count,
3116                        ffdh_params[testnum].bits, d);
3117             ffdh_results[testnum][0] = (double)count / d;
3118             op_count = count;
3119         }
3120         if (op_count <= 1) {
3121             /* if longer than 10s, don't do any more */
3122             stop_it(ffdh_doit, testnum);
3123         }
3124     }
3125 #endif  /* OPENSSL_NO_DH */
3126 #ifndef NO_FORK
3127  show_res:
3128 #endif
3129     if (!mr) {
3130         printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3131         printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3132         printf("options: %s\n", BN_options());
3133         printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3134         printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3135     }
3136 
3137     if (pr_header) {
3138         if (mr) {
3139             printf("+H");
3140         } else {
3141             printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3142             printf("type        ");
3143         }
3144         for (testnum = 0; testnum < size_num; testnum++)
3145             printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3146         printf("\n");
3147     }
3148 
3149     for (k = 0; k < ALGOR_NUM; k++) {
3150         const char *alg_name = names[k];
3151 
3152         if (!doit[k])
3153             continue;
3154 
3155         if (k == D_EVP) {
3156             if (evp_cipher == NULL)
3157                 alg_name = evp_md_name;
3158             else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3159                 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
3160         }
3161 
3162         if (mr)
3163             printf("+F:%u:%s", k, alg_name);
3164         else
3165             printf("%-13s", alg_name);
3166         for (testnum = 0; testnum < size_num; testnum++) {
3167             if (results[k][testnum] > 10000 && !mr)
3168                 printf(" %11.2fk", results[k][testnum] / 1e3);
3169             else
3170                 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3171         }
3172         printf("\n");
3173     }
3174     testnum = 1;
3175     for (k = 0; k < RSA_NUM; k++) {
3176         if (!rsa_doit[k])
3177             continue;
3178         if (testnum && !mr) {
3179             printf("%18ssign    verify    sign/s verify/s\n", " ");
3180             testnum = 0;
3181         }
3182         if (mr)
3183             printf("+F2:%u:%u:%f:%f\n",
3184                    k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3185         else
3186             printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3187                    rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3188                    rsa_results[k][0], rsa_results[k][1]);
3189     }
3190     testnum = 1;
3191     for (k = 0; k < DSA_NUM; k++) {
3192         if (!dsa_doit[k])
3193             continue;
3194         if (testnum && !mr) {
3195             printf("%18ssign    verify    sign/s verify/s\n", " ");
3196             testnum = 0;
3197         }
3198         if (mr)
3199             printf("+F3:%u:%u:%f:%f\n",
3200                    k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3201         else
3202             printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3203                    dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3204                    dsa_results[k][0], dsa_results[k][1]);
3205     }
3206     testnum = 1;
3207     for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3208         if (!ecdsa_doit[k])
3209             continue;
3210         if (testnum && !mr) {
3211             printf("%30ssign    verify    sign/s verify/s\n", " ");
3212             testnum = 0;
3213         }
3214 
3215         if (mr)
3216             printf("+F4:%u:%u:%f:%f\n",
3217                    k, ec_curves[k].bits,
3218                    ecdsa_results[k][0], ecdsa_results[k][1]);
3219         else
3220             printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3221                    ec_curves[k].bits, ec_curves[k].name,
3222                    1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3223                    ecdsa_results[k][0], ecdsa_results[k][1]);
3224     }
3225 
3226     testnum = 1;
3227     for (k = 0; k < EC_NUM; k++) {
3228         if (!ecdh_doit[k])
3229             continue;
3230         if (testnum && !mr) {
3231             printf("%30sop      op/s\n", " ");
3232             testnum = 0;
3233         }
3234         if (mr)
3235             printf("+F5:%u:%u:%f:%f\n",
3236                    k, ec_curves[k].bits,
3237                    ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3238 
3239         else
3240             printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3241                    ec_curves[k].bits, ec_curves[k].name,
3242                    1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3243     }
3244 
3245     testnum = 1;
3246     for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3247         if (!eddsa_doit[k])
3248             continue;
3249         if (testnum && !mr) {
3250             printf("%30ssign    verify    sign/s verify/s\n", " ");
3251             testnum = 0;
3252         }
3253 
3254         if (mr)
3255             printf("+F6:%u:%u:%s:%f:%f\n",
3256                    k, ed_curves[k].bits, ed_curves[k].name,
3257                    eddsa_results[k][0], eddsa_results[k][1]);
3258         else
3259             printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3260                    ed_curves[k].bits, ed_curves[k].name,
3261                    1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3262                    eddsa_results[k][0], eddsa_results[k][1]);
3263     }
3264 
3265 #ifndef OPENSSL_NO_SM2
3266     testnum = 1;
3267     for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3268         if (!sm2_doit[k])
3269             continue;
3270         if (testnum && !mr) {
3271             printf("%30ssign    verify    sign/s verify/s\n", " ");
3272             testnum = 0;
3273         }
3274 
3275         if (mr)
3276             printf("+F7:%u:%u:%s:%f:%f\n",
3277                    k, sm2_curves[k].bits, sm2_curves[k].name,
3278                    sm2_results[k][0], sm2_results[k][1]);
3279         else
3280             printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3281                    sm2_curves[k].bits, sm2_curves[k].name,
3282                    1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3283                    sm2_results[k][0], sm2_results[k][1]);
3284     }
3285 #endif
3286 #ifndef OPENSSL_NO_DH
3287     testnum = 1;
3288     for (k = 0; k < FFDH_NUM; k++) {
3289         if (!ffdh_doit[k])
3290             continue;
3291         if (testnum && !mr) {
3292             printf("%23sop     op/s\n", " ");
3293             testnum = 0;
3294         }
3295         if (mr)
3296             printf("+F8:%u:%u:%f:%f\n",
3297                    k, ffdh_params[k].bits,
3298                    ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3299 
3300         else
3301             printf("%4u bits ffdh %8.4fs %8.1f\n",
3302                    ffdh_params[k].bits,
3303                    1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3304     }
3305 #endif /* OPENSSL_NO_DH */
3306 
3307     ret = 0;
3308 
3309  end:
3310     ERR_print_errors(bio_err);
3311     for (i = 0; i < loopargs_len; i++) {
3312         OPENSSL_free(loopargs[i].buf_malloc);
3313         OPENSSL_free(loopargs[i].buf2_malloc);
3314 
3315         BN_free(bn);
3316         EVP_PKEY_CTX_free(genctx);
3317         for (k = 0; k < RSA_NUM; k++) {
3318             EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3319             EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3320         }
3321 #ifndef OPENSSL_NO_DH
3322         OPENSSL_free(loopargs[i].secret_ff_a);
3323         OPENSSL_free(loopargs[i].secret_ff_b);
3324         for (k = 0; k < FFDH_NUM; k++)
3325             EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3326 #endif
3327         for (k = 0; k < DSA_NUM; k++) {
3328             EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3329             EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3330         }
3331         for (k = 0; k < ECDSA_NUM; k++) {
3332             EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3333             EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3334         }
3335         for (k = 0; k < EC_NUM; k++)
3336             EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3337         for (k = 0; k < EdDSA_NUM; k++) {
3338             EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3339             EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3340         }
3341 #ifndef OPENSSL_NO_SM2
3342         for (k = 0; k < SM2_NUM; k++) {
3343             EVP_PKEY_CTX *pctx = NULL;
3344 
3345             /* free signing ctx */
3346             if (loopargs[i].sm2_ctx[k] != NULL
3347                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3348                 EVP_PKEY_CTX_free(pctx);
3349             EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3350             /* free verification ctx */
3351             if (loopargs[i].sm2_vfy_ctx[k] != NULL
3352                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3353                 EVP_PKEY_CTX_free(pctx);
3354             EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3355             /* free pkey */
3356             EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3357         }
3358 #endif
3359         OPENSSL_free(loopargs[i].secret_a);
3360         OPENSSL_free(loopargs[i].secret_b);
3361     }
3362     OPENSSL_free(evp_hmac_name);
3363     OPENSSL_free(evp_cmac_name);
3364 
3365     if (async_jobs > 0) {
3366         for (i = 0; i < loopargs_len; i++)
3367             ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3368     }
3369 
3370     if (async_init) {
3371         ASYNC_cleanup_thread();
3372     }
3373     OPENSSL_free(loopargs);
3374     release_engine(e);
3375     EVP_CIPHER_free(evp_cipher);
3376     EVP_MAC_free(mac);
3377     return ret;
3378 }
3379 
3380 static void print_message(const char *s, long num, int length, int tm)
3381 {
3382     BIO_printf(bio_err,
3383                mr ? "+DT:%s:%d:%d\n"
3384                : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3385     (void)BIO_flush(bio_err);
3386     run = 1;
3387     alarm(tm);
3388 }
3389 
3390 static void pkey_print_message(const char *str, const char *str2, long num,
3391                                unsigned int bits, int tm)
3392 {
3393     BIO_printf(bio_err,
3394                mr ? "+DTP:%d:%s:%s:%d\n"
3395                : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3396     (void)BIO_flush(bio_err);
3397     run = 1;
3398     alarm(tm);
3399 }
3400 
3401 static void print_result(int alg, int run_no, int count, double time_used)
3402 {
3403     if (count == -1) {
3404         BIO_printf(bio_err, "%s error!\n", names[alg]);
3405         ERR_print_errors(bio_err);
3406         return;
3407     }
3408     BIO_printf(bio_err,
3409                mr ? "+R:%d:%s:%f\n"
3410                : "%d %s's in %.2fs\n", count, names[alg], time_used);
3411     results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3412 }
3413 
3414 #ifndef NO_FORK
3415 static char *sstrsep(char **string, const char *delim)
3416 {
3417     char isdelim[256];
3418     char *token = *string;
3419 
3420     if (**string == 0)
3421         return NULL;
3422 
3423     memset(isdelim, 0, sizeof(isdelim));
3424     isdelim[0] = 1;
3425 
3426     while (*delim) {
3427         isdelim[(unsigned char)(*delim)] = 1;
3428         delim++;
3429     }
3430 
3431     while (!isdelim[(unsigned char)(**string)])
3432         (*string)++;
3433 
3434     if (**string) {
3435         **string = 0;
3436         (*string)++;
3437     }
3438 
3439     return token;
3440 }
3441 
3442 static int do_multi(int multi, int size_num)
3443 {
3444     int n;
3445     int fd[2];
3446     int *fds;
3447     int status;
3448     static char sep[] = ":";
3449 
3450     fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3451     for (n = 0; n < multi; ++n) {
3452         if (pipe(fd) == -1) {
3453             BIO_printf(bio_err, "pipe failure\n");
3454             exit(1);
3455         }
3456         fflush(stdout);
3457         (void)BIO_flush(bio_err);
3458         if (fork()) {
3459             close(fd[1]);
3460             fds[n] = fd[0];
3461         } else {
3462             close(fd[0]);
3463             close(1);
3464             if (dup(fd[1]) == -1) {
3465                 BIO_printf(bio_err, "dup failed\n");
3466                 exit(1);
3467             }
3468             close(fd[1]);
3469             mr = 1;
3470             usertime = 0;
3471             OPENSSL_free(fds);
3472             return 0;
3473         }
3474         printf("Forked child %d\n", n);
3475     }
3476 
3477     /* for now, assume the pipe is long enough to take all the output */
3478     for (n = 0; n < multi; ++n) {
3479         FILE *f;
3480         char buf[1024];
3481         char *p;
3482 
3483         if ((f = fdopen(fds[n], "r")) == NULL) {
3484             BIO_printf(bio_err, "fdopen failure with 0x%x\n",
3485                        errno);
3486             OPENSSL_free(fds);
3487             return 1;
3488         }
3489         while (fgets(buf, sizeof(buf), f)) {
3490             p = strchr(buf, '\n');
3491             if (p)
3492                 *p = '\0';
3493             if (buf[0] != '+') {
3494                 BIO_printf(bio_err,
3495                            "Don't understand line '%s' from child %d\n", buf,
3496                            n);
3497                 continue;
3498             }
3499             printf("Got: %s from %d\n", buf, n);
3500             if (strncmp(buf, "+F:", 3) == 0) {
3501                 int alg;
3502                 int j;
3503 
3504                 p = buf + 3;
3505                 alg = atoi(sstrsep(&p, sep));
3506                 sstrsep(&p, sep);
3507                 for (j = 0; j < size_num; ++j)
3508                     results[alg][j] += atof(sstrsep(&p, sep));
3509             } else if (strncmp(buf, "+F2:", 4) == 0) {
3510                 int k;
3511                 double d;
3512 
3513                 p = buf + 4;
3514                 k = atoi(sstrsep(&p, sep));
3515                 sstrsep(&p, sep);
3516 
3517                 d = atof(sstrsep(&p, sep));
3518                 rsa_results[k][0] += d;
3519 
3520                 d = atof(sstrsep(&p, sep));
3521                 rsa_results[k][1] += d;
3522             } else if (strncmp(buf, "+F3:", 4) == 0) {
3523                 int k;
3524                 double d;
3525 
3526                 p = buf + 4;
3527                 k = atoi(sstrsep(&p, sep));
3528                 sstrsep(&p, sep);
3529 
3530                 d = atof(sstrsep(&p, sep));
3531                 dsa_results[k][0] += d;
3532 
3533                 d = atof(sstrsep(&p, sep));
3534                 dsa_results[k][1] += d;
3535             } else if (strncmp(buf, "+F4:", 4) == 0) {
3536                 int k;
3537                 double d;
3538 
3539                 p = buf + 4;
3540                 k = atoi(sstrsep(&p, sep));
3541                 sstrsep(&p, sep);
3542 
3543                 d = atof(sstrsep(&p, sep));
3544                 ecdsa_results[k][0] += d;
3545 
3546                 d = atof(sstrsep(&p, sep));
3547                 ecdsa_results[k][1] += d;
3548             } else if (strncmp(buf, "+F5:", 4) == 0) {
3549                 int k;
3550                 double d;
3551 
3552                 p = buf + 4;
3553                 k = atoi(sstrsep(&p, sep));
3554                 sstrsep(&p, sep);
3555 
3556                 d = atof(sstrsep(&p, sep));
3557                 ecdh_results[k][0] += d;
3558             } else if (strncmp(buf, "+F6:", 4) == 0) {
3559                 int k;
3560                 double d;
3561 
3562                 p = buf + 4;
3563                 k = atoi(sstrsep(&p, sep));
3564                 sstrsep(&p, sep);
3565                 sstrsep(&p, sep);
3566 
3567                 d = atof(sstrsep(&p, sep));
3568                 eddsa_results[k][0] += d;
3569 
3570                 d = atof(sstrsep(&p, sep));
3571                 eddsa_results[k][1] += d;
3572 # ifndef OPENSSL_NO_SM2
3573             } else if (strncmp(buf, "+F7:", 4) == 0) {
3574                 int k;
3575                 double d;
3576 
3577                 p = buf + 4;
3578                 k = atoi(sstrsep(&p, sep));
3579                 sstrsep(&p, sep);
3580                 sstrsep(&p, sep);
3581 
3582                 d = atof(sstrsep(&p, sep));
3583                 sm2_results[k][0] += d;
3584 
3585                 d = atof(sstrsep(&p, sep));
3586                 sm2_results[k][1] += d;
3587 # endif /* OPENSSL_NO_SM2 */
3588 # ifndef OPENSSL_NO_DH
3589             } else if (strncmp(buf, "+F8:", 4) == 0) {
3590                 int k;
3591                 double d;
3592 
3593                 p = buf + 4;
3594                 k = atoi(sstrsep(&p, sep));
3595                 sstrsep(&p, sep);
3596 
3597                 d = atof(sstrsep(&p, sep));
3598                 ffdh_results[k][0] += d;
3599 # endif /* OPENSSL_NO_DH */
3600             } else if (strncmp(buf, "+H:", 3) == 0) {
3601                 ;
3602             } else {
3603                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3604                            n);
3605             }
3606         }
3607 
3608         fclose(f);
3609     }
3610     OPENSSL_free(fds);
3611     for (n = 0; n < multi; ++n) {
3612         while (wait(&status) == -1)
3613             if (errno != EINTR) {
3614                 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
3615                            errno);
3616                 return 1;
3617             }
3618         if (WIFEXITED(status) && WEXITSTATUS(status)) {
3619             BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
3620         } else if (WIFSIGNALED(status)) {
3621             BIO_printf(bio_err, "Child terminated by signal %d\n",
3622                        WTERMSIG(status));
3623         }
3624     }
3625     return 1;
3626 }
3627 #endif
3628 
3629 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3630                              const openssl_speed_sec_t *seconds)
3631 {
3632     static const int mblengths_list[] =
3633         { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3634     const int *mblengths = mblengths_list;
3635     int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3636     const char *alg_name;
3637     unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3638     EVP_CIPHER_CTX *ctx = NULL;
3639     double d = 0.0;
3640 
3641     if (lengths_single) {
3642         mblengths = &lengths_single;
3643         num = 1;
3644     }
3645 
3646     inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3647     out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3648     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3649         app_bail_out("failed to allocate cipher context\n");
3650     if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3651         app_bail_out("failed to initialise cipher context\n");
3652 
3653     if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3654         BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3655         goto err;
3656     }
3657     key = app_malloc(keylen, "evp_cipher key");
3658     if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
3659         app_bail_out("failed to generate random cipher key\n");
3660     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3661         app_bail_out("failed to set cipher key\n");
3662     OPENSSL_clear_free(key, keylen);
3663 
3664     if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3665                              sizeof(no_key), no_key) <= 0)
3666         app_bail_out("failed to set AEAD key\n");
3667     if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3668         app_bail_out("failed to get cipher name\n");
3669 
3670     for (j = 0; j < num; j++) {
3671         print_message(alg_name, 0, mblengths[j], seconds->sym);
3672         Time_F(START);
3673         for (count = 0; run && count < INT_MAX; count++) {
3674             unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3675             EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3676             size_t len = mblengths[j];
3677             int packlen;
3678 
3679             memset(aad, 0, 8);  /* avoid uninitialized values */
3680             aad[8] = 23;        /* SSL3_RT_APPLICATION_DATA */
3681             aad[9] = 3;         /* version */
3682             aad[10] = 2;
3683             aad[11] = 0;        /* length */
3684             aad[12] = 0;
3685             mb_param.out = NULL;
3686             mb_param.inp = aad;
3687             mb_param.len = len;
3688             mb_param.interleave = 8;
3689 
3690             packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3691                                           sizeof(mb_param), &mb_param);
3692 
3693             if (packlen > 0) {
3694                 mb_param.out = out;
3695                 mb_param.inp = inp;
3696                 mb_param.len = len;
3697                 (void)EVP_CIPHER_CTX_ctrl(ctx,
3698                                           EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3699                                           sizeof(mb_param), &mb_param);
3700             } else {
3701                 int pad;
3702 
3703                 if (RAND_bytes(inp, 16) <= 0)
3704                     app_bail_out("error setting random bytes\n");
3705                 len += 16;
3706                 aad[11] = (unsigned char)(len >> 8);
3707                 aad[12] = (unsigned char)(len);
3708                 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3709                                           EVP_AEAD_TLS1_AAD_LEN, aad);
3710                 EVP_Cipher(ctx, out, inp, len + pad);
3711             }
3712         }
3713         d = Time_F(STOP);
3714         BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3715                    : "%d %s's in %.2fs\n", count, "evp", d);
3716         results[D_EVP][j] = ((double)count) / d * mblengths[j];
3717     }
3718 
3719     if (mr) {
3720         fprintf(stdout, "+H");
3721         for (j = 0; j < num; j++)
3722             fprintf(stdout, ":%d", mblengths[j]);
3723         fprintf(stdout, "\n");
3724         fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3725         for (j = 0; j < num; j++)
3726             fprintf(stdout, ":%.2f", results[D_EVP][j]);
3727         fprintf(stdout, "\n");
3728     } else {
3729         fprintf(stdout,
3730                 "The 'numbers' are in 1000s of bytes per second processed.\n");
3731         fprintf(stdout, "type                    ");
3732         for (j = 0; j < num; j++)
3733             fprintf(stdout, "%7d bytes", mblengths[j]);
3734         fprintf(stdout, "\n");
3735         fprintf(stdout, "%-24s", alg_name);
3736 
3737         for (j = 0; j < num; j++) {
3738             if (results[D_EVP][j] > 10000)
3739                 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3740             else
3741                 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3742         }
3743         fprintf(stdout, "\n");
3744     }
3745 
3746  err:
3747     OPENSSL_free(inp);
3748     OPENSSL_free(out);
3749     EVP_CIPHER_CTX_free(ctx);
3750 }
3751