xref: /freebsd/crypto/openssl/apps/speed.c (revision fac71e4e09885bb2afa3d984a0c239a52e1a7418)
1 /*
2  * Copyright 1995-2022 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_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1009         if (ret == 0) {
1010             BIO_printf(bio_err, "EdDSA sign failure\n");
1011             ERR_print_errors(bio_err);
1012             count = -1;
1013             break;
1014         }
1015     }
1016     return count;
1017 }
1018 
1019 static int EdDSA_verify_loop(void *args)
1020 {
1021     loopargs_t *tempargs = *(loopargs_t **) args;
1022     unsigned char *buf = tempargs->buf;
1023     EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1024     unsigned char *eddsasig = tempargs->buf2;
1025     size_t eddsasigsize = tempargs->sigsize;
1026     int ret, count;
1027 
1028     for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1029         ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1030         if (ret != 1) {
1031             BIO_printf(bio_err, "EdDSA verify failure\n");
1032             ERR_print_errors(bio_err);
1033             count = -1;
1034             break;
1035         }
1036     }
1037     return count;
1038 }
1039 
1040 #ifndef OPENSSL_NO_SM2
1041 static long sm2_c[SM2_NUM][2];
1042 static int SM2_sign_loop(void *args)
1043 {
1044     loopargs_t *tempargs = *(loopargs_t **) args;
1045     unsigned char *buf = tempargs->buf;
1046     EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1047     unsigned char *sm2sig = tempargs->buf2;
1048     size_t sm2sigsize;
1049     int ret, count;
1050     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1051     const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1052 
1053     for (count = 0; COND(sm2_c[testnum][0]); count++) {
1054         sm2sigsize = max_size;
1055 
1056         if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1057                                 NULL, sm2_pkey[testnum])) {
1058             BIO_printf(bio_err, "SM2 init sign failure\n");
1059             ERR_print_errors(bio_err);
1060             count = -1;
1061             break;
1062         }
1063         ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1064                              buf, 20);
1065         if (ret == 0) {
1066             BIO_printf(bio_err, "SM2 sign failure\n");
1067             ERR_print_errors(bio_err);
1068             count = -1;
1069             break;
1070         }
1071         /* update the latest returned size and always use the fixed buffer size */
1072         tempargs->sigsize = sm2sigsize;
1073     }
1074 
1075     return count;
1076 }
1077 
1078 static int SM2_verify_loop(void *args)
1079 {
1080     loopargs_t *tempargs = *(loopargs_t **) args;
1081     unsigned char *buf = tempargs->buf;
1082     EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1083     unsigned char *sm2sig = tempargs->buf2;
1084     size_t sm2sigsize = tempargs->sigsize;
1085     int ret, count;
1086     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1087 
1088     for (count = 0; COND(sm2_c[testnum][1]); count++) {
1089         if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1090                                   NULL, sm2_pkey[testnum])) {
1091             BIO_printf(bio_err, "SM2 verify init failure\n");
1092             ERR_print_errors(bio_err);
1093             count = -1;
1094             break;
1095         }
1096         ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1097                                buf, 20);
1098         if (ret != 1) {
1099             BIO_printf(bio_err, "SM2 verify failure\n");
1100             ERR_print_errors(bio_err);
1101             count = -1;
1102             break;
1103         }
1104     }
1105     return count;
1106 }
1107 #endif                         /* OPENSSL_NO_SM2 */
1108 
1109 static int run_benchmark(int async_jobs,
1110                          int (*loop_function) (void *), loopargs_t * loopargs)
1111 {
1112     int job_op_count = 0;
1113     int total_op_count = 0;
1114     int num_inprogress = 0;
1115     int error = 0, i = 0, ret = 0;
1116     OSSL_ASYNC_FD job_fd = 0;
1117     size_t num_job_fds = 0;
1118 
1119     if (async_jobs == 0) {
1120         return loop_function((void *)&loopargs);
1121     }
1122 
1123     for (i = 0; i < async_jobs && !error; i++) {
1124         loopargs_t *looparg_item = loopargs + i;
1125 
1126         /* Copy pointer content (looparg_t item address) into async context */
1127         ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1128                               &job_op_count, loop_function,
1129                               (void *)&looparg_item, sizeof(looparg_item));
1130         switch (ret) {
1131         case ASYNC_PAUSE:
1132             ++num_inprogress;
1133             break;
1134         case ASYNC_FINISH:
1135             if (job_op_count == -1) {
1136                 error = 1;
1137             } else {
1138                 total_op_count += job_op_count;
1139             }
1140             break;
1141         case ASYNC_NO_JOBS:
1142         case ASYNC_ERR:
1143             BIO_printf(bio_err, "Failure in the job\n");
1144             ERR_print_errors(bio_err);
1145             error = 1;
1146             break;
1147         }
1148     }
1149 
1150     while (num_inprogress > 0) {
1151 #if defined(OPENSSL_SYS_WINDOWS)
1152         DWORD avail = 0;
1153 #elif defined(OPENSSL_SYS_UNIX)
1154         int select_result = 0;
1155         OSSL_ASYNC_FD max_fd = 0;
1156         fd_set waitfdset;
1157 
1158         FD_ZERO(&waitfdset);
1159 
1160         for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1161             if (loopargs[i].inprogress_job == NULL)
1162                 continue;
1163 
1164             if (!ASYNC_WAIT_CTX_get_all_fds
1165                 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1166                 || num_job_fds > 1) {
1167                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1168                 ERR_print_errors(bio_err);
1169                 error = 1;
1170                 break;
1171             }
1172             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1173                                        &num_job_fds);
1174             FD_SET(job_fd, &waitfdset);
1175             if (job_fd > max_fd)
1176                 max_fd = job_fd;
1177         }
1178 
1179         if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1180             BIO_printf(bio_err,
1181                        "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1182                        "Decrease the value of async_jobs\n",
1183                        max_fd, FD_SETSIZE);
1184             ERR_print_errors(bio_err);
1185             error = 1;
1186             break;
1187         }
1188 
1189         select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1190         if (select_result == -1 && errno == EINTR)
1191             continue;
1192 
1193         if (select_result == -1) {
1194             BIO_printf(bio_err, "Failure in the select\n");
1195             ERR_print_errors(bio_err);
1196             error = 1;
1197             break;
1198         }
1199 
1200         if (select_result == 0)
1201             continue;
1202 #endif
1203 
1204         for (i = 0; i < async_jobs; i++) {
1205             if (loopargs[i].inprogress_job == NULL)
1206                 continue;
1207 
1208             if (!ASYNC_WAIT_CTX_get_all_fds
1209                 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1210                 || num_job_fds > 1) {
1211                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1212                 ERR_print_errors(bio_err);
1213                 error = 1;
1214                 break;
1215             }
1216             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1217                                        &num_job_fds);
1218 
1219 #if defined(OPENSSL_SYS_UNIX)
1220             if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1221                 continue;
1222 #elif defined(OPENSSL_SYS_WINDOWS)
1223             if (num_job_fds == 1
1224                 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1225                 && avail > 0)
1226                 continue;
1227 #endif
1228 
1229             ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1230                                   loopargs[i].wait_ctx, &job_op_count,
1231                                   loop_function, (void *)(loopargs + i),
1232                                   sizeof(loopargs_t));
1233             switch (ret) {
1234             case ASYNC_PAUSE:
1235                 break;
1236             case ASYNC_FINISH:
1237                 if (job_op_count == -1) {
1238                     error = 1;
1239                 } else {
1240                     total_op_count += job_op_count;
1241                 }
1242                 --num_inprogress;
1243                 loopargs[i].inprogress_job = NULL;
1244                 break;
1245             case ASYNC_NO_JOBS:
1246             case ASYNC_ERR:
1247                 --num_inprogress;
1248                 loopargs[i].inprogress_job = NULL;
1249                 BIO_printf(bio_err, "Failure in the job\n");
1250                 ERR_print_errors(bio_err);
1251                 error = 1;
1252                 break;
1253             }
1254         }
1255     }
1256 
1257     return error ? -1 : total_op_count;
1258 }
1259 
1260 typedef struct ec_curve_st {
1261     const char *name;
1262     unsigned int nid;
1263     unsigned int bits;
1264     size_t sigsize; /* only used for EdDSA curves */
1265 } EC_CURVE;
1266 
1267 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1268 {
1269     EVP_PKEY_CTX *kctx = NULL;
1270     EVP_PKEY *key = NULL;
1271 
1272     /* Ensure that the error queue is empty */
1273     if (ERR_peek_error()) {
1274         BIO_printf(bio_err,
1275                    "WARNING: the error queue contains previous unhandled errors.\n");
1276         ERR_print_errors(bio_err);
1277     }
1278 
1279     /*
1280      * Let's try to create a ctx directly from the NID: this works for
1281      * curves like Curve25519 that are not implemented through the low
1282      * level EC interface.
1283      * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1284      * then we set the curve by NID before deriving the actual keygen
1285      * ctx for that specific curve.
1286      */
1287     kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1288     if (kctx == NULL) {
1289         EVP_PKEY_CTX *pctx = NULL;
1290         EVP_PKEY *params = NULL;
1291         /*
1292          * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1293          * "int_ctx_new:unsupported algorithm" error was added to the
1294          * error queue.
1295          * We remove it from the error queue as we are handling it.
1296          */
1297         unsigned long error = ERR_peek_error();
1298 
1299         if (error == ERR_peek_last_error() /* oldest and latest errors match */
1300             /* check that the error origin matches */
1301             && ERR_GET_LIB(error) == ERR_LIB_EVP
1302             && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1303                 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1304             ERR_get_error(); /* pop error from queue */
1305         if (ERR_peek_error()) {
1306             BIO_printf(bio_err,
1307                        "Unhandled error in the error queue during EC key setup.\n");
1308             ERR_print_errors(bio_err);
1309             return NULL;
1310         }
1311 
1312         /* Create the context for parameter generation */
1313         if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1314             || EVP_PKEY_paramgen_init(pctx) <= 0
1315             || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1316                                                       curve->nid) <= 0
1317             || EVP_PKEY_paramgen(pctx, &params) <= 0) {
1318             BIO_printf(bio_err, "EC params init failure.\n");
1319             ERR_print_errors(bio_err);
1320             EVP_PKEY_CTX_free(pctx);
1321             return NULL;
1322         }
1323         EVP_PKEY_CTX_free(pctx);
1324 
1325         /* Create the context for the key generation */
1326         kctx = EVP_PKEY_CTX_new(params, NULL);
1327         EVP_PKEY_free(params);
1328     }
1329     if (kctx == NULL
1330         || EVP_PKEY_keygen_init(kctx) <= 0
1331         || EVP_PKEY_keygen(kctx, &key) <= 0) {
1332         BIO_printf(bio_err, "EC key generation failure.\n");
1333         ERR_print_errors(bio_err);
1334         key = NULL;
1335     }
1336     EVP_PKEY_CTX_free(kctx);
1337     return key;
1338 }
1339 
1340 #define stop_it(do_it, test_num)\
1341     memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1342 
1343 int speed_main(int argc, char **argv)
1344 {
1345     ENGINE *e = NULL;
1346     loopargs_t *loopargs = NULL;
1347     const char *prog;
1348     const char *engine_id = NULL;
1349     EVP_CIPHER *evp_cipher = NULL;
1350     EVP_MAC *mac = NULL;
1351     double d = 0.0;
1352     OPTION_CHOICE o;
1353     int async_init = 0, multiblock = 0, pr_header = 0;
1354     uint8_t doit[ALGOR_NUM] = { 0 };
1355     int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1356     long count = 0;
1357     unsigned int size_num = SIZE_NUM;
1358     unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1359     int keylen;
1360     int buflen;
1361     BIGNUM *bn = NULL;
1362     EVP_PKEY_CTX *genctx = NULL;
1363 #ifndef NO_FORK
1364     int multi = 0;
1365 #endif
1366     long op_count = 1;
1367     openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1368                                     ECDSA_SECONDS, ECDH_SECONDS,
1369                                     EdDSA_SECONDS, SM2_SECONDS,
1370                                     FFDH_SECONDS };
1371 
1372     static const unsigned char key32[32] = {
1373         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1374         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1375         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1376         0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1377     };
1378     static const unsigned char deskey[] = {
1379         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1380         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1381         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34  /* key3 */
1382     };
1383     static const struct {
1384         const unsigned char *data;
1385         unsigned int length;
1386         unsigned int bits;
1387     } rsa_keys[] = {
1388         {   test512,   sizeof(test512),   512 },
1389         {  test1024,  sizeof(test1024),  1024 },
1390         {  test2048,  sizeof(test2048),  2048 },
1391         {  test3072,  sizeof(test3072),  3072 },
1392         {  test4096,  sizeof(test4096),  4096 },
1393         {  test7680,  sizeof(test7680),  7680 },
1394         { test15360, sizeof(test15360), 15360 }
1395     };
1396     uint8_t rsa_doit[RSA_NUM] = { 0 };
1397     int primes = RSA_DEFAULT_PRIME_NUM;
1398 #ifndef OPENSSL_NO_DH
1399     typedef struct ffdh_params_st {
1400         const char *name;
1401         unsigned int nid;
1402         unsigned int bits;
1403     } FFDH_PARAMS;
1404 
1405     static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1406         {"ffdh2048", NID_ffdhe2048, 2048},
1407         {"ffdh3072", NID_ffdhe3072, 3072},
1408         {"ffdh4096", NID_ffdhe4096, 4096},
1409         {"ffdh6144", NID_ffdhe6144, 6144},
1410         {"ffdh8192", NID_ffdhe8192, 8192}
1411     };
1412     uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1413 
1414 #endif /* OPENSSL_NO_DH */
1415     static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1416     uint8_t dsa_doit[DSA_NUM] = { 0 };
1417     /*
1418      * We only test over the following curves as they are representative, To
1419      * add tests over more curves, simply add the curve NID and curve name to
1420      * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1421      * lists accordingly.
1422      */
1423     static const EC_CURVE ec_curves[EC_NUM] = {
1424         /* Prime Curves */
1425         {"secp160r1", NID_secp160r1, 160},
1426         {"nistp192", NID_X9_62_prime192v1, 192},
1427         {"nistp224", NID_secp224r1, 224},
1428         {"nistp256", NID_X9_62_prime256v1, 256},
1429         {"nistp384", NID_secp384r1, 384},
1430         {"nistp521", NID_secp521r1, 521},
1431 #ifndef OPENSSL_NO_EC2M
1432         /* Binary Curves */
1433         {"nistk163", NID_sect163k1, 163},
1434         {"nistk233", NID_sect233k1, 233},
1435         {"nistk283", NID_sect283k1, 283},
1436         {"nistk409", NID_sect409k1, 409},
1437         {"nistk571", NID_sect571k1, 571},
1438         {"nistb163", NID_sect163r2, 163},
1439         {"nistb233", NID_sect233r1, 233},
1440         {"nistb283", NID_sect283r1, 283},
1441         {"nistb409", NID_sect409r1, 409},
1442         {"nistb571", NID_sect571r1, 571},
1443 #endif
1444         {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1445         {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1446         {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1447         {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1448         {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1449         {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1450         /* Other and ECDH only ones */
1451         {"X25519", NID_X25519, 253},
1452         {"X448", NID_X448, 448}
1453     };
1454     static const EC_CURVE ed_curves[EdDSA_NUM] = {
1455         /* EdDSA */
1456         {"Ed25519", NID_ED25519, 253, 64},
1457         {"Ed448", NID_ED448, 456, 114}
1458     };
1459 #ifndef OPENSSL_NO_SM2
1460     static const EC_CURVE sm2_curves[SM2_NUM] = {
1461         /* SM2 */
1462         {"CurveSM2", NID_sm2, 256}
1463     };
1464     uint8_t sm2_doit[SM2_NUM] = { 0 };
1465 #endif
1466     uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1467     uint8_t ecdh_doit[EC_NUM] = { 0 };
1468     uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1469 
1470     /* checks declarated curves against choices list. */
1471     OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1472     OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1473 
1474     OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1475     OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1476 
1477     OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1478     OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1479 
1480 #ifndef OPENSSL_NO_SM2
1481     OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1482     OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1483 #endif
1484 
1485     prog = opt_init(argc, argv, speed_options);
1486     while ((o = opt_next()) != OPT_EOF) {
1487         switch (o) {
1488         case OPT_EOF:
1489         case OPT_ERR:
1490  opterr:
1491             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1492             goto end;
1493         case OPT_HELP:
1494             opt_help(speed_options);
1495             ret = 0;
1496             goto end;
1497         case OPT_ELAPSED:
1498             usertime = 0;
1499             break;
1500         case OPT_EVP:
1501             if (doit[D_EVP]) {
1502                 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1503                 goto opterr;
1504             }
1505             ERR_set_mark();
1506             if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1507                 if (have_md(opt_arg()))
1508                     evp_md_name = opt_arg();
1509             }
1510             if (evp_cipher == NULL && evp_md_name == NULL) {
1511                 ERR_clear_last_mark();
1512                 BIO_printf(bio_err,
1513                            "%s: %s is an unknown cipher or digest\n",
1514                            prog, opt_arg());
1515                 goto end;
1516             }
1517             ERR_pop_to_mark();
1518             doit[D_EVP] = 1;
1519             break;
1520         case OPT_HMAC:
1521             if (!have_md(opt_arg())) {
1522                 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1523                            prog, opt_arg());
1524                 goto end;
1525             }
1526             evp_mac_mdname = opt_arg();
1527             doit[D_HMAC] = 1;
1528             break;
1529         case OPT_CMAC:
1530             if (!have_cipher(opt_arg())) {
1531                 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1532                            prog, opt_arg());
1533                 goto end;
1534             }
1535             evp_mac_ciphername = opt_arg();
1536             doit[D_EVP_CMAC] = 1;
1537             break;
1538         case OPT_DECRYPT:
1539             decrypt = 1;
1540             break;
1541         case OPT_ENGINE:
1542             /*
1543              * In a forked execution, an engine might need to be
1544              * initialised by each child process, not by the parent.
1545              * So store the name here and run setup_engine() later on.
1546              */
1547             engine_id = opt_arg();
1548             break;
1549         case OPT_MULTI:
1550 #ifndef NO_FORK
1551             multi = atoi(opt_arg());
1552             if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1553                 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1554                 return 0;
1555             }
1556 #endif
1557             break;
1558         case OPT_ASYNCJOBS:
1559 #ifndef OPENSSL_NO_ASYNC
1560             async_jobs = atoi(opt_arg());
1561             if (!ASYNC_is_capable()) {
1562                 BIO_printf(bio_err,
1563                            "%s: async_jobs specified but async not supported\n",
1564                            prog);
1565                 goto opterr;
1566             }
1567             if (async_jobs > 99999) {
1568                 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1569                 goto opterr;
1570             }
1571 #endif
1572             break;
1573         case OPT_MISALIGN:
1574             misalign = opt_int_arg();
1575             if (misalign > MISALIGN) {
1576                 BIO_printf(bio_err,
1577                            "%s: Maximum offset is %d\n", prog, MISALIGN);
1578                 goto opterr;
1579             }
1580             break;
1581         case OPT_MR:
1582             mr = 1;
1583             break;
1584         case OPT_MB:
1585             multiblock = 1;
1586 #ifdef OPENSSL_NO_MULTIBLOCK
1587             BIO_printf(bio_err,
1588                        "%s: -mb specified but multi-block support is disabled\n",
1589                        prog);
1590             goto end;
1591 #endif
1592             break;
1593         case OPT_R_CASES:
1594             if (!opt_rand(o))
1595                 goto end;
1596             break;
1597         case OPT_PROV_CASES:
1598             if (!opt_provider(o))
1599                 goto end;
1600             break;
1601         case OPT_PRIMES:
1602             primes = opt_int_arg();
1603             break;
1604         case OPT_SECONDS:
1605             seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1606                         = seconds.ecdh = seconds.eddsa
1607                         = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1608             break;
1609         case OPT_BYTES:
1610             lengths_single = atoi(opt_arg());
1611             lengths = &lengths_single;
1612             size_num = 1;
1613             break;
1614         case OPT_AEAD:
1615             aead = 1;
1616             break;
1617         }
1618     }
1619 
1620     /* Remaining arguments are algorithms. */
1621     argc = opt_num_rest();
1622     argv = opt_rest();
1623 
1624     if (!app_RAND_load())
1625         goto end;
1626 
1627     for (; *argv; argv++) {
1628         const char *algo = *argv;
1629 
1630         if (opt_found(algo, doit_choices, &i)) {
1631             doit[i] = 1;
1632             continue;
1633         }
1634         if (strcmp(algo, "des") == 0) {
1635             doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1636             continue;
1637         }
1638         if (strcmp(algo, "sha") == 0) {
1639             doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1640             continue;
1641         }
1642 #ifndef OPENSSL_NO_DEPRECATED_3_0
1643         if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1644             continue;
1645 #endif
1646         if (strncmp(algo, "rsa", 3) == 0) {
1647             if (algo[3] == '\0') {
1648                 memset(rsa_doit, 1, sizeof(rsa_doit));
1649                 continue;
1650             }
1651             if (opt_found(algo, rsa_choices, &i)) {
1652                 rsa_doit[i] = 1;
1653                 continue;
1654             }
1655         }
1656 #ifndef OPENSSL_NO_DH
1657         if (strncmp(algo, "ffdh", 4) == 0) {
1658             if (algo[4] == '\0') {
1659                 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1660                 continue;
1661             }
1662             if (opt_found(algo, ffdh_choices, &i)) {
1663                 ffdh_doit[i] = 2;
1664                 continue;
1665             }
1666         }
1667 #endif
1668         if (strncmp(algo, "dsa", 3) == 0) {
1669             if (algo[3] == '\0') {
1670                 memset(dsa_doit, 1, sizeof(dsa_doit));
1671                 continue;
1672             }
1673             if (opt_found(algo, dsa_choices, &i)) {
1674                 dsa_doit[i] = 2;
1675                 continue;
1676             }
1677         }
1678         if (strcmp(algo, "aes") == 0) {
1679             doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1680             continue;
1681         }
1682         if (strcmp(algo, "camellia") == 0) {
1683             doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1684             continue;
1685         }
1686         if (strncmp(algo, "ecdsa", 5) == 0) {
1687             if (algo[5] == '\0') {
1688                 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1689                 continue;
1690             }
1691             if (opt_found(algo, ecdsa_choices, &i)) {
1692                 ecdsa_doit[i] = 2;
1693                 continue;
1694             }
1695         }
1696         if (strncmp(algo, "ecdh", 4) == 0) {
1697             if (algo[4] == '\0') {
1698                 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1699                 continue;
1700             }
1701             if (opt_found(algo, ecdh_choices, &i)) {
1702                 ecdh_doit[i] = 2;
1703                 continue;
1704             }
1705         }
1706         if (strcmp(algo, "eddsa") == 0) {
1707             memset(eddsa_doit, 1, sizeof(eddsa_doit));
1708             continue;
1709         }
1710         if (opt_found(algo, eddsa_choices, &i)) {
1711             eddsa_doit[i] = 2;
1712             continue;
1713         }
1714 #ifndef OPENSSL_NO_SM2
1715         if (strcmp(algo, "sm2") == 0) {
1716             memset(sm2_doit, 1, sizeof(sm2_doit));
1717             continue;
1718         }
1719         if (opt_found(algo, sm2_choices, &i)) {
1720             sm2_doit[i] = 2;
1721             continue;
1722         }
1723 #endif
1724         BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1725         goto end;
1726     }
1727 
1728     /* Sanity checks */
1729     if (aead) {
1730         if (evp_cipher == NULL) {
1731             BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1732             goto end;
1733         } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1734                      EVP_CIPH_FLAG_AEAD_CIPHER)) {
1735             BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1736                        EVP_CIPHER_get0_name(evp_cipher));
1737             goto end;
1738         }
1739     }
1740     if (multiblock) {
1741         if (evp_cipher == NULL) {
1742             BIO_printf(bio_err, "-mb can be used only with a multi-block"
1743                                 " capable cipher\n");
1744             goto end;
1745         } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1746                      EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1747             BIO_printf(bio_err, "%s is not a multi-block capable\n",
1748                        EVP_CIPHER_get0_name(evp_cipher));
1749             goto end;
1750         } else if (async_jobs > 0) {
1751             BIO_printf(bio_err, "Async mode is not supported with -mb");
1752             goto end;
1753         }
1754     }
1755 
1756     /* Initialize the job pool if async mode is enabled */
1757     if (async_jobs > 0) {
1758         async_init = ASYNC_init_thread(async_jobs, async_jobs);
1759         if (!async_init) {
1760             BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1761             goto end;
1762         }
1763     }
1764 
1765     loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1766     loopargs =
1767         app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1768     memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1769 
1770     for (i = 0; i < loopargs_len; i++) {
1771         if (async_jobs > 0) {
1772             loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1773             if (loopargs[i].wait_ctx == NULL) {
1774                 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1775                 goto end;
1776             }
1777         }
1778 
1779         buflen = lengths[size_num - 1];
1780         if (buflen < 36)    /* size of random vector in RSA benchmark */
1781             buflen = 36;
1782         if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1783             BIO_printf(bio_err, "Error: buffer size too large\n");
1784             goto end;
1785         }
1786         buflen += MAX_MISALIGNMENT + 1;
1787         loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1788         loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1789         memset(loopargs[i].buf_malloc, 0, buflen);
1790         memset(loopargs[i].buf2_malloc, 0, buflen);
1791 
1792         /* Align the start of buffers on a 64 byte boundary */
1793         loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1794         loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1795         loopargs[i].buflen = buflen - misalign;
1796         loopargs[i].sigsize = buflen - misalign;
1797         loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1798         loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1799 #ifndef OPENSSL_NO_DH
1800         loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1801         loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1802 #endif
1803     }
1804 
1805 #ifndef NO_FORK
1806     if (multi && do_multi(multi, size_num))
1807         goto show_res;
1808 #endif
1809 
1810     /* Initialize the engine after the fork */
1811     e = setup_engine(engine_id, 0);
1812 
1813     /* No parameters; turn on everything. */
1814     if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1815         memset(doit, 1, sizeof(doit));
1816         doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1817         ERR_set_mark();
1818         for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1819             if (!have_md(names[i]))
1820                 doit[i] = 0;
1821         }
1822         for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1823             if (!have_cipher(names[i]))
1824                 doit[i] = 0;
1825         }
1826         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1827                                  app_get0_propq())) != NULL) {
1828             EVP_MAC_free(mac);
1829             mac = NULL;
1830         } else {
1831             doit[D_GHASH] = 0;
1832         }
1833         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1834                                  app_get0_propq())) != NULL) {
1835             EVP_MAC_free(mac);
1836             mac = NULL;
1837         } else {
1838             doit[D_HMAC] = 0;
1839         }
1840         ERR_pop_to_mark();
1841         memset(rsa_doit, 1, sizeof(rsa_doit));
1842 #ifndef OPENSSL_NO_DH
1843         memset(ffdh_doit, 1, sizeof(ffdh_doit));
1844 #endif
1845         memset(dsa_doit, 1, sizeof(dsa_doit));
1846         memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1847         memset(ecdh_doit, 1, sizeof(ecdh_doit));
1848         memset(eddsa_doit, 1, sizeof(eddsa_doit));
1849 #ifndef OPENSSL_NO_SM2
1850         memset(sm2_doit, 1, sizeof(sm2_doit));
1851 #endif
1852     }
1853     for (i = 0; i < ALGOR_NUM; i++)
1854         if (doit[i])
1855             pr_header++;
1856 
1857     if (usertime == 0 && !mr)
1858         BIO_printf(bio_err,
1859                    "You have chosen to measure elapsed time "
1860                    "instead of user CPU time.\n");
1861 
1862 #if SIGALRM > 0
1863     signal(SIGALRM, alarmed);
1864 #endif
1865 
1866     if (doit[D_MD2]) {
1867         for (testnum = 0; testnum < size_num; testnum++) {
1868             print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1869                           seconds.sym);
1870             Time_F(START);
1871             count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1872             d = Time_F(STOP);
1873             print_result(D_MD2, testnum, count, d);
1874             if (count < 0)
1875                 break;
1876         }
1877     }
1878 
1879     if (doit[D_MDC2]) {
1880         for (testnum = 0; testnum < size_num; testnum++) {
1881             print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1882                           seconds.sym);
1883             Time_F(START);
1884             count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1885             d = Time_F(STOP);
1886             print_result(D_MDC2, testnum, count, d);
1887             if (count < 0)
1888                 break;
1889         }
1890     }
1891 
1892     if (doit[D_MD4]) {
1893         for (testnum = 0; testnum < size_num; testnum++) {
1894             print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1895                           seconds.sym);
1896             Time_F(START);
1897             count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1898             d = Time_F(STOP);
1899             print_result(D_MD4, testnum, count, d);
1900             if (count < 0)
1901                 break;
1902         }
1903     }
1904 
1905     if (doit[D_MD5]) {
1906         for (testnum = 0; testnum < size_num; testnum++) {
1907             print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1908                           seconds.sym);
1909             Time_F(START);
1910             count = run_benchmark(async_jobs, MD5_loop, loopargs);
1911             d = Time_F(STOP);
1912             print_result(D_MD5, testnum, count, d);
1913             if (count < 0)
1914                 break;
1915         }
1916     }
1917 
1918     if (doit[D_SHA1]) {
1919         for (testnum = 0; testnum < size_num; testnum++) {
1920             print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1921                           seconds.sym);
1922             Time_F(START);
1923             count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1924             d = Time_F(STOP);
1925             print_result(D_SHA1, testnum, count, d);
1926             if (count < 0)
1927                 break;
1928         }
1929     }
1930 
1931     if (doit[D_SHA256]) {
1932         for (testnum = 0; testnum < size_num; testnum++) {
1933             print_message(names[D_SHA256], c[D_SHA256][testnum],
1934                           lengths[testnum], seconds.sym);
1935             Time_F(START);
1936             count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1937             d = Time_F(STOP);
1938             print_result(D_SHA256, testnum, count, d);
1939             if (count < 0)
1940                 break;
1941         }
1942     }
1943 
1944     if (doit[D_SHA512]) {
1945         for (testnum = 0; testnum < size_num; testnum++) {
1946             print_message(names[D_SHA512], c[D_SHA512][testnum],
1947                           lengths[testnum], seconds.sym);
1948             Time_F(START);
1949             count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1950             d = Time_F(STOP);
1951             print_result(D_SHA512, testnum, count, d);
1952             if (count < 0)
1953                 break;
1954         }
1955     }
1956 
1957     if (doit[D_WHIRLPOOL]) {
1958         for (testnum = 0; testnum < size_num; testnum++) {
1959             print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
1960                           lengths[testnum], seconds.sym);
1961             Time_F(START);
1962             count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
1963             d = Time_F(STOP);
1964             print_result(D_WHIRLPOOL, testnum, count, d);
1965             if (count < 0)
1966                 break;
1967         }
1968     }
1969 
1970     if (doit[D_RMD160]) {
1971         for (testnum = 0; testnum < size_num; testnum++) {
1972             print_message(names[D_RMD160], c[D_RMD160][testnum],
1973                           lengths[testnum], seconds.sym);
1974             Time_F(START);
1975             count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
1976             d = Time_F(STOP);
1977             print_result(D_RMD160, testnum, count, d);
1978             if (count < 0)
1979                 break;
1980         }
1981     }
1982 
1983     if (doit[D_HMAC]) {
1984         static const char hmac_key[] = "This is a key...";
1985         int len = strlen(hmac_key);
1986         OSSL_PARAM params[3];
1987 
1988         mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1989         if (mac == NULL || evp_mac_mdname == NULL)
1990             goto end;
1991 
1992         evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
1993                                    "HMAC name");
1994         sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
1995         names[D_HMAC] = evp_hmac_name;
1996 
1997         params[0] =
1998             OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
1999                                              evp_mac_mdname, 0);
2000         params[1] =
2001             OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2002                                               (char *)hmac_key, len);
2003         params[2] = OSSL_PARAM_construct_end();
2004 
2005         for (i = 0; i < loopargs_len; i++) {
2006             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2007             if (loopargs[i].mctx == NULL)
2008                 goto end;
2009 
2010             if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2011                 goto skip_hmac; /* Digest not found */
2012         }
2013         for (testnum = 0; testnum < size_num; testnum++) {
2014             print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
2015                           seconds.sym);
2016             Time_F(START);
2017             count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2018             d = Time_F(STOP);
2019             print_result(D_HMAC, testnum, count, d);
2020             if (count < 0)
2021                 break;
2022         }
2023         for (i = 0; i < loopargs_len; i++)
2024             EVP_MAC_CTX_free(loopargs[i].mctx);
2025         EVP_MAC_free(mac);
2026         mac = NULL;
2027     }
2028 skip_hmac:
2029     if (doit[D_CBC_DES]) {
2030         int st = 1;
2031 
2032         for (i = 0; st && i < loopargs_len; i++) {
2033             loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2034                                                   sizeof(deskey) / 3);
2035             st = loopargs[i].ctx != NULL;
2036         }
2037         algindex = D_CBC_DES;
2038         for (testnum = 0; st && testnum < size_num; testnum++) {
2039             print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2040                           lengths[testnum], seconds.sym);
2041             Time_F(START);
2042             count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2043             d = Time_F(STOP);
2044             print_result(D_CBC_DES, testnum, count, d);
2045         }
2046         for (i = 0; i < loopargs_len; i++)
2047             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2048     }
2049 
2050     if (doit[D_EDE3_DES]) {
2051         int st = 1;
2052 
2053         for (i = 0; st && i < loopargs_len; i++) {
2054             loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2055                                                   sizeof(deskey));
2056             st = loopargs[i].ctx != NULL;
2057         }
2058         algindex = D_EDE3_DES;
2059         for (testnum = 0; st && testnum < size_num; testnum++) {
2060             print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2061                           lengths[testnum], seconds.sym);
2062             Time_F(START);
2063             count =
2064                 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2065             d = Time_F(STOP);
2066             print_result(D_EDE3_DES, testnum, count, d);
2067         }
2068         for (i = 0; i < loopargs_len; i++)
2069             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2070     }
2071 
2072     for (k = 0; k < 3; k++) {
2073         algindex = D_CBC_128_AES + k;
2074         if (doit[algindex]) {
2075             int st = 1;
2076 
2077             keylen = 16 + k * 8;
2078             for (i = 0; st && i < loopargs_len; i++) {
2079                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2080                                                       key32, keylen);
2081                 st = loopargs[i].ctx != NULL;
2082             }
2083 
2084             for (testnum = 0; st && testnum < size_num; testnum++) {
2085                 print_message(names[algindex], c[algindex][testnum],
2086                               lengths[testnum], seconds.sym);
2087                 Time_F(START);
2088                 count =
2089                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2090                 d = Time_F(STOP);
2091                 print_result(algindex, testnum, count, d);
2092             }
2093             for (i = 0; i < loopargs_len; i++)
2094                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2095         }
2096     }
2097 
2098     for (k = 0; k < 3; k++) {
2099         algindex = D_CBC_128_CML + k;
2100         if (doit[algindex]) {
2101             int st = 1;
2102 
2103             keylen = 16 + k * 8;
2104             for (i = 0; st && i < loopargs_len; i++) {
2105                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2106                                                       key32, keylen);
2107                 st = loopargs[i].ctx != NULL;
2108             }
2109 
2110             for (testnum = 0; st && testnum < size_num; testnum++) {
2111                 print_message(names[algindex], c[algindex][testnum],
2112                               lengths[testnum], seconds.sym);
2113                 Time_F(START);
2114                 count =
2115                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2116                 d = Time_F(STOP);
2117                 print_result(algindex, testnum, count, d);
2118             }
2119             for (i = 0; i < loopargs_len; i++)
2120                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2121         }
2122     }
2123 
2124     for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2125         if (doit[algindex]) {
2126             int st = 1;
2127 
2128             keylen = 16;
2129             for (i = 0; st && i < loopargs_len; i++) {
2130                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2131                                                       key32, keylen);
2132                 st = loopargs[i].ctx != NULL;
2133             }
2134 
2135             for (testnum = 0; st && testnum < size_num; testnum++) {
2136                 print_message(names[algindex], c[algindex][testnum],
2137                               lengths[testnum], seconds.sym);
2138                 Time_F(START);
2139                 count =
2140                     run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2141                 d = Time_F(STOP);
2142                 print_result(algindex, testnum, count, d);
2143             }
2144             for (i = 0; i < loopargs_len; i++)
2145                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2146         }
2147     }
2148     if (doit[D_GHASH]) {
2149         static const char gmac_iv[] = "0123456789ab";
2150         OSSL_PARAM params[3];
2151 
2152         mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2153         if (mac == NULL)
2154             goto end;
2155 
2156         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2157                                                      "aes-128-gcm", 0);
2158         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2159                                                       (char *)gmac_iv,
2160                                                       sizeof(gmac_iv) - 1);
2161         params[2] = OSSL_PARAM_construct_end();
2162 
2163         for (i = 0; i < loopargs_len; i++) {
2164             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2165             if (loopargs[i].mctx == NULL)
2166                 goto end;
2167 
2168             if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2169                 goto end;
2170         }
2171         for (testnum = 0; testnum < size_num; testnum++) {
2172             print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2173                           seconds.sym);
2174             Time_F(START);
2175             count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2176             d = Time_F(STOP);
2177             print_result(D_GHASH, testnum, count, d);
2178             if (count < 0)
2179                 break;
2180         }
2181         for (i = 0; i < loopargs_len; i++)
2182             EVP_MAC_CTX_free(loopargs[i].mctx);
2183         EVP_MAC_free(mac);
2184         mac = NULL;
2185     }
2186 
2187     if (doit[D_RAND]) {
2188         for (testnum = 0; testnum < size_num; testnum++) {
2189             print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2190                           seconds.sym);
2191             Time_F(START);
2192             count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2193             d = Time_F(STOP);
2194             print_result(D_RAND, testnum, count, d);
2195         }
2196     }
2197 
2198     if (doit[D_EVP]) {
2199         if (evp_cipher != NULL) {
2200             int (*loopfunc) (void *) = EVP_Update_loop;
2201 
2202             if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2203                                EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2204                 multiblock_speed(evp_cipher, lengths_single, &seconds);
2205                 ret = 0;
2206                 goto end;
2207             }
2208 
2209             names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2210 
2211             if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2212                 loopfunc = EVP_Update_loop_ccm;
2213             } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2214                                 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2215                 loopfunc = EVP_Update_loop_aead;
2216                 if (lengths == lengths_list) {
2217                     lengths = aead_lengths_list;
2218                     size_num = OSSL_NELEM(aead_lengths_list);
2219                 }
2220             }
2221 
2222             for (testnum = 0; testnum < size_num; testnum++) {
2223                 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2224                               seconds.sym);
2225 
2226                 for (k = 0; k < loopargs_len; k++) {
2227                     loopargs[k].ctx = EVP_CIPHER_CTX_new();
2228                     if (loopargs[k].ctx == NULL) {
2229                         BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2230                         exit(1);
2231                     }
2232                     if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2233                                            NULL, iv, decrypt ? 0 : 1)) {
2234                         BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2235                         ERR_print_errors(bio_err);
2236                         exit(1);
2237                     }
2238 
2239                     EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2240 
2241                     keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2242                     loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2243                     EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2244                     if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2245                                            loopargs[k].key, NULL, -1)) {
2246                         BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2247                         ERR_print_errors(bio_err);
2248                         exit(1);
2249                     }
2250                     OPENSSL_clear_free(loopargs[k].key, keylen);
2251 
2252                     /* SIV mode only allows for a single Update operation */
2253                     if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2254                         (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2255                                                   EVP_CTRL_SET_SPEED, 1, NULL);
2256                 }
2257 
2258                 Time_F(START);
2259                 count = run_benchmark(async_jobs, loopfunc, loopargs);
2260                 d = Time_F(STOP);
2261                 for (k = 0; k < loopargs_len; k++)
2262                     EVP_CIPHER_CTX_free(loopargs[k].ctx);
2263                 print_result(D_EVP, testnum, count, d);
2264             }
2265         } else if (evp_md_name != NULL) {
2266             names[D_EVP] = evp_md_name;
2267 
2268             for (testnum = 0; testnum < size_num; testnum++) {
2269                 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2270                               seconds.sym);
2271                 Time_F(START);
2272                 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2273                 d = Time_F(STOP);
2274                 print_result(D_EVP, testnum, count, d);
2275                 if (count < 0)
2276                     break;
2277             }
2278         }
2279     }
2280 
2281     if (doit[D_EVP_CMAC]) {
2282         OSSL_PARAM params[3];
2283         EVP_CIPHER *cipher = NULL;
2284 
2285         mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2286         if (mac == NULL || evp_mac_ciphername == NULL)
2287             goto end;
2288         if (!opt_cipher(evp_mac_ciphername, &cipher))
2289             goto end;
2290 
2291         keylen = EVP_CIPHER_get_key_length(cipher);
2292         EVP_CIPHER_free(cipher);
2293         if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2294             BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2295             goto end;
2296         }
2297         evp_cmac_name = app_malloc(sizeof("cmac()")
2298                                    + strlen(evp_mac_ciphername), "CMAC name");
2299         sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2300         names[D_EVP_CMAC] = evp_cmac_name;
2301 
2302         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2303                                                      evp_mac_ciphername, 0);
2304         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2305                                                       (char *)key32, keylen);
2306         params[2] = OSSL_PARAM_construct_end();
2307 
2308         for (i = 0; i < loopargs_len; i++) {
2309             loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2310             if (loopargs[i].mctx == NULL)
2311                 goto end;
2312 
2313             if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2314                 goto end;
2315         }
2316 
2317         for (testnum = 0; testnum < size_num; testnum++) {
2318             print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2319                           lengths[testnum], seconds.sym);
2320             Time_F(START);
2321             count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2322             d = Time_F(STOP);
2323             print_result(D_EVP_CMAC, testnum, count, d);
2324             if (count < 0)
2325                 break;
2326         }
2327         for (i = 0; i < loopargs_len; i++)
2328             EVP_MAC_CTX_free(loopargs[i].mctx);
2329         EVP_MAC_free(mac);
2330         mac = NULL;
2331     }
2332 
2333     for (i = 0; i < loopargs_len; i++)
2334         if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2335             goto end;
2336 
2337     for (testnum = 0; testnum < RSA_NUM; testnum++) {
2338         EVP_PKEY *rsa_key = NULL;
2339         int st = 0;
2340 
2341         if (!rsa_doit[testnum])
2342             continue;
2343 
2344         if (primes > RSA_DEFAULT_PRIME_NUM) {
2345             /* we haven't set keys yet,  generate multi-prime RSA keys */
2346             bn = BN_new();
2347             st = bn != NULL
2348                 && BN_set_word(bn, RSA_F4)
2349                 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2350                 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2351                 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2352                 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2353                 && EVP_PKEY_keygen(genctx, &rsa_key);
2354             BN_free(bn);
2355             bn = NULL;
2356             EVP_PKEY_CTX_free(genctx);
2357             genctx = NULL;
2358         } else {
2359             const unsigned char *p = rsa_keys[testnum].data;
2360 
2361             st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2362                                            rsa_keys[testnum].length)) != NULL;
2363         }
2364 
2365         for (i = 0; st && i < loopargs_len; i++) {
2366             loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2367             loopargs[i].sigsize = loopargs[i].buflen;
2368             if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2369                 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2370                 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2371                                  loopargs[i].buf2,
2372                                  &loopargs[i].sigsize,
2373                                  loopargs[i].buf, 36) <= 0)
2374                 st = 0;
2375         }
2376         if (!st) {
2377             BIO_printf(bio_err,
2378                        "RSA sign setup failure.  No RSA sign will be done.\n");
2379             ERR_print_errors(bio_err);
2380             op_count = 1;
2381         } else {
2382             pkey_print_message("private", "rsa",
2383                                rsa_c[testnum][0], rsa_keys[testnum].bits,
2384                                seconds.rsa);
2385             /* RSA_blinding_on(rsa_key[testnum],NULL); */
2386             Time_F(START);
2387             count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2388             d = Time_F(STOP);
2389             BIO_printf(bio_err,
2390                        mr ? "+R1:%ld:%d:%.2f\n"
2391                        : "%ld %u bits private RSA's in %.2fs\n",
2392                        count, rsa_keys[testnum].bits, d);
2393             rsa_results[testnum][0] = (double)count / d;
2394             op_count = count;
2395         }
2396 
2397         for (i = 0; st && i < loopargs_len; i++) {
2398             loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2399                                                                    NULL);
2400             if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2401                 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2402                 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2403                                    loopargs[i].buf2,
2404                                    loopargs[i].sigsize,
2405                                    loopargs[i].buf, 36) <= 0)
2406                 st = 0;
2407         }
2408         if (!st) {
2409             BIO_printf(bio_err,
2410                        "RSA verify setup failure.  No RSA verify will be done.\n");
2411             ERR_print_errors(bio_err);
2412             rsa_doit[testnum] = 0;
2413         } else {
2414             pkey_print_message("public", "rsa",
2415                                rsa_c[testnum][1], rsa_keys[testnum].bits,
2416                                seconds.rsa);
2417             Time_F(START);
2418             count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2419             d = Time_F(STOP);
2420             BIO_printf(bio_err,
2421                        mr ? "+R2:%ld:%d:%.2f\n"
2422                        : "%ld %u bits public RSA's in %.2fs\n",
2423                        count, rsa_keys[testnum].bits, d);
2424             rsa_results[testnum][1] = (double)count / d;
2425         }
2426 
2427         if (op_count <= 1) {
2428             /* if longer than 10s, don't do any more */
2429             stop_it(rsa_doit, testnum);
2430         }
2431         EVP_PKEY_free(rsa_key);
2432     }
2433 
2434     for (testnum = 0; testnum < DSA_NUM; testnum++) {
2435         EVP_PKEY *dsa_key = NULL;
2436         int st;
2437 
2438         if (!dsa_doit[testnum])
2439             continue;
2440 
2441         st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2442 
2443         for (i = 0; st && i < loopargs_len; i++) {
2444             loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2445                                                                  NULL);
2446             loopargs[i].sigsize = loopargs[i].buflen;
2447             if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2448                 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2449 
2450                 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2451                                  loopargs[i].buf2,
2452                                  &loopargs[i].sigsize,
2453                                  loopargs[i].buf, 20) <= 0)
2454                 st = 0;
2455         }
2456         if (!st) {
2457             BIO_printf(bio_err,
2458                        "DSA sign setup failure.  No DSA sign will be done.\n");
2459             ERR_print_errors(bio_err);
2460             op_count = 1;
2461         } else {
2462             pkey_print_message("sign", "dsa",
2463                                dsa_c[testnum][0], dsa_bits[testnum],
2464                                seconds.dsa);
2465             Time_F(START);
2466             count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2467             d = Time_F(STOP);
2468             BIO_printf(bio_err,
2469                        mr ? "+R3:%ld:%u:%.2f\n"
2470                        : "%ld %u bits DSA signs in %.2fs\n",
2471                        count, dsa_bits[testnum], d);
2472             dsa_results[testnum][0] = (double)count / d;
2473             op_count = count;
2474         }
2475 
2476         for (i = 0; st && i < loopargs_len; i++) {
2477             loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2478                                                                    NULL);
2479             if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2480                 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2481                 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2482                                    loopargs[i].buf2,
2483                                    loopargs[i].sigsize,
2484                                    loopargs[i].buf, 36) <= 0)
2485                 st = 0;
2486         }
2487         if (!st) {
2488             BIO_printf(bio_err,
2489                        "DSA verify setup failure.  No DSA verify will be done.\n");
2490             ERR_print_errors(bio_err);
2491             dsa_doit[testnum] = 0;
2492         } else {
2493             pkey_print_message("verify", "dsa",
2494                                dsa_c[testnum][1], dsa_bits[testnum],
2495                                seconds.dsa);
2496             Time_F(START);
2497             count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2498             d = Time_F(STOP);
2499             BIO_printf(bio_err,
2500                        mr ? "+R4:%ld:%u:%.2f\n"
2501                        : "%ld %u bits DSA verify in %.2fs\n",
2502                        count, dsa_bits[testnum], d);
2503             dsa_results[testnum][1] = (double)count / d;
2504         }
2505 
2506         if (op_count <= 1) {
2507             /* if longer than 10s, don't do any more */
2508             stop_it(dsa_doit, testnum);
2509         }
2510         EVP_PKEY_free(dsa_key);
2511     }
2512 
2513     for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2514         EVP_PKEY *ecdsa_key = NULL;
2515         int st;
2516 
2517         if (!ecdsa_doit[testnum])
2518             continue;
2519 
2520         st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2521 
2522         for (i = 0; st && i < loopargs_len; i++) {
2523             loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2524                                                                    NULL);
2525             loopargs[i].sigsize = loopargs[i].buflen;
2526             if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2527                 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2528 
2529                 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2530                                  loopargs[i].buf2,
2531                                  &loopargs[i].sigsize,
2532                                  loopargs[i].buf, 20) <= 0)
2533                 st = 0;
2534         }
2535         if (!st) {
2536             BIO_printf(bio_err,
2537                        "ECDSA sign setup failure.  No ECDSA sign will be done.\n");
2538             ERR_print_errors(bio_err);
2539             op_count = 1;
2540         } else {
2541             pkey_print_message("sign", "ecdsa",
2542                                ecdsa_c[testnum][0], ec_curves[testnum].bits,
2543                                seconds.ecdsa);
2544             Time_F(START);
2545             count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2546             d = Time_F(STOP);
2547             BIO_printf(bio_err,
2548                        mr ? "+R5:%ld:%u:%.2f\n"
2549                        : "%ld %u bits ECDSA signs in %.2fs\n",
2550                        count, ec_curves[testnum].bits, d);
2551             ecdsa_results[testnum][0] = (double)count / d;
2552             op_count = count;
2553         }
2554 
2555         for (i = 0; st && i < loopargs_len; i++) {
2556             loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2557                                                                      NULL);
2558             if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2559                 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2560                 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2561                                    loopargs[i].buf2,
2562                                    loopargs[i].sigsize,
2563                                    loopargs[i].buf, 20) <= 0)
2564                 st = 0;
2565         }
2566         if (!st) {
2567             BIO_printf(bio_err,
2568                        "ECDSA verify setup failure.  No ECDSA verify will be done.\n");
2569             ERR_print_errors(bio_err);
2570             ecdsa_doit[testnum] = 0;
2571         } else {
2572             pkey_print_message("verify", "ecdsa",
2573                                ecdsa_c[testnum][1], ec_curves[testnum].bits,
2574                                seconds.ecdsa);
2575             Time_F(START);
2576             count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2577             d = Time_F(STOP);
2578             BIO_printf(bio_err,
2579                        mr ? "+R6:%ld:%u:%.2f\n"
2580                        : "%ld %u bits ECDSA verify in %.2fs\n",
2581                        count, ec_curves[testnum].bits, d);
2582             ecdsa_results[testnum][1] = (double)count / d;
2583         }
2584 
2585         if (op_count <= 1) {
2586             /* if longer than 10s, don't do any more */
2587             stop_it(ecdsa_doit, testnum);
2588         }
2589     }
2590 
2591     for (testnum = 0; testnum < EC_NUM; testnum++) {
2592         int ecdh_checks = 1;
2593 
2594         if (!ecdh_doit[testnum])
2595             continue;
2596 
2597         for (i = 0; i < loopargs_len; i++) {
2598             EVP_PKEY_CTX *test_ctx = NULL;
2599             EVP_PKEY_CTX *ctx = NULL;
2600             EVP_PKEY *key_A = NULL;
2601             EVP_PKEY *key_B = NULL;
2602             size_t outlen;
2603             size_t test_outlen;
2604 
2605             if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2606                 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2607                 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2608                 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2609                 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2610                 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2611                 || outlen == 0 /* ensure outlen is a valid size */
2612                 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2613                 ecdh_checks = 0;
2614                 BIO_printf(bio_err, "ECDH key generation failure.\n");
2615                 ERR_print_errors(bio_err);
2616                 op_count = 1;
2617                 break;
2618             }
2619 
2620             /*
2621              * Here we perform a test run, comparing the output of a*B and b*A;
2622              * we try this here and assume that further EVP_PKEY_derive calls
2623              * never fail, so we can skip checks in the actually benchmarked
2624              * code, for maximum performance.
2625              */
2626             if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2627                 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
2628                 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
2629                 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
2630                 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
2631                 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
2632                 || test_outlen != outlen /* compare output length */) {
2633                 ecdh_checks = 0;
2634                 BIO_printf(bio_err, "ECDH computation failure.\n");
2635                 ERR_print_errors(bio_err);
2636                 op_count = 1;
2637                 break;
2638             }
2639 
2640             /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2641             if (CRYPTO_memcmp(loopargs[i].secret_a,
2642                               loopargs[i].secret_b, outlen)) {
2643                 ecdh_checks = 0;
2644                 BIO_printf(bio_err, "ECDH computations don't match.\n");
2645                 ERR_print_errors(bio_err);
2646                 op_count = 1;
2647                 break;
2648             }
2649 
2650             loopargs[i].ecdh_ctx[testnum] = ctx;
2651             loopargs[i].outlen[testnum] = outlen;
2652 
2653             EVP_PKEY_free(key_A);
2654             EVP_PKEY_free(key_B);
2655             EVP_PKEY_CTX_free(test_ctx);
2656             test_ctx = NULL;
2657         }
2658         if (ecdh_checks != 0) {
2659             pkey_print_message("", "ecdh",
2660                                ecdh_c[testnum][0],
2661                                ec_curves[testnum].bits, seconds.ecdh);
2662             Time_F(START);
2663             count =
2664                 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2665             d = Time_F(STOP);
2666             BIO_printf(bio_err,
2667                        mr ? "+R7:%ld:%d:%.2f\n" :
2668                        "%ld %u-bits ECDH ops in %.2fs\n", count,
2669                        ec_curves[testnum].bits, d);
2670             ecdh_results[testnum][0] = (double)count / d;
2671             op_count = count;
2672         }
2673 
2674         if (op_count <= 1) {
2675             /* if longer than 10s, don't do any more */
2676             stop_it(ecdh_doit, testnum);
2677         }
2678     }
2679 
2680     for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2681         int st = 1;
2682         EVP_PKEY *ed_pkey = NULL;
2683         EVP_PKEY_CTX *ed_pctx = NULL;
2684 
2685         if (!eddsa_doit[testnum])
2686             continue;           /* Ignore Curve */
2687         for (i = 0; i < loopargs_len; i++) {
2688             loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2689             if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2690                 st = 0;
2691                 break;
2692             }
2693             loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2694             if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2695                 st = 0;
2696                 break;
2697             }
2698 
2699             if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2700                                                NULL)) == NULL
2701                 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2702                 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2703                 st = 0;
2704                 EVP_PKEY_CTX_free(ed_pctx);
2705                 break;
2706             }
2707             EVP_PKEY_CTX_free(ed_pctx);
2708 
2709             if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2710                                     NULL, ed_pkey)) {
2711                 st = 0;
2712                 EVP_PKEY_free(ed_pkey);
2713                 break;
2714             }
2715             if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2716                                       NULL, NULL, ed_pkey)) {
2717                 st = 0;
2718                 EVP_PKEY_free(ed_pkey);
2719                 break;
2720             }
2721 
2722             EVP_PKEY_free(ed_pkey);
2723             ed_pkey = NULL;
2724         }
2725         if (st == 0) {
2726             BIO_printf(bio_err, "EdDSA failure.\n");
2727             ERR_print_errors(bio_err);
2728             op_count = 1;
2729         } else {
2730             for (i = 0; i < loopargs_len; i++) {
2731                 /* Perform EdDSA signature test */
2732                 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2733                 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2734                                     loopargs[i].buf2, &loopargs[i].sigsize,
2735                                     loopargs[i].buf, 20);
2736                 if (st == 0)
2737                     break;
2738             }
2739             if (st == 0) {
2740                 BIO_printf(bio_err,
2741                            "EdDSA sign failure.  No EdDSA sign will be done.\n");
2742                 ERR_print_errors(bio_err);
2743                 op_count = 1;
2744             } else {
2745                 pkey_print_message("sign", ed_curves[testnum].name,
2746                                    eddsa_c[testnum][0],
2747                                    ed_curves[testnum].bits, seconds.eddsa);
2748                 Time_F(START);
2749                 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2750                 d = Time_F(STOP);
2751 
2752                 BIO_printf(bio_err,
2753                            mr ? "+R8:%ld:%u:%s:%.2f\n" :
2754                            "%ld %u bits %s signs in %.2fs \n",
2755                            count, ed_curves[testnum].bits,
2756                            ed_curves[testnum].name, d);
2757                 eddsa_results[testnum][0] = (double)count / d;
2758                 op_count = count;
2759             }
2760             /* Perform EdDSA verification test */
2761             for (i = 0; i < loopargs_len; i++) {
2762                 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2763                                       loopargs[i].buf2, loopargs[i].sigsize,
2764                                       loopargs[i].buf, 20);
2765                 if (st != 1)
2766                     break;
2767             }
2768             if (st != 1) {
2769                 BIO_printf(bio_err,
2770                            "EdDSA verify failure.  No EdDSA verify will be done.\n");
2771                 ERR_print_errors(bio_err);
2772                 eddsa_doit[testnum] = 0;
2773             } else {
2774                 pkey_print_message("verify", ed_curves[testnum].name,
2775                                    eddsa_c[testnum][1],
2776                                    ed_curves[testnum].bits, seconds.eddsa);
2777                 Time_F(START);
2778                 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2779                 d = Time_F(STOP);
2780                 BIO_printf(bio_err,
2781                            mr ? "+R9:%ld:%u:%s:%.2f\n"
2782                            : "%ld %u bits %s verify in %.2fs\n",
2783                            count, ed_curves[testnum].bits,
2784                            ed_curves[testnum].name, d);
2785                 eddsa_results[testnum][1] = (double)count / d;
2786             }
2787 
2788             if (op_count <= 1) {
2789                 /* if longer than 10s, don't do any more */
2790                 stop_it(eddsa_doit, testnum);
2791             }
2792         }
2793     }
2794 
2795 #ifndef OPENSSL_NO_SM2
2796     for (testnum = 0; testnum < SM2_NUM; testnum++) {
2797         int st = 1;
2798         EVP_PKEY *sm2_pkey = NULL;
2799 
2800         if (!sm2_doit[testnum])
2801             continue;           /* Ignore Curve */
2802         /* Init signing and verification */
2803         for (i = 0; i < loopargs_len; i++) {
2804             EVP_PKEY_CTX *sm2_pctx = NULL;
2805             EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2806             EVP_PKEY_CTX *pctx = NULL;
2807             st = 0;
2808 
2809             loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2810             loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2811             if (loopargs[i].sm2_ctx[testnum] == NULL
2812                     || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2813                 break;
2814 
2815             sm2_pkey = NULL;
2816 
2817             st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2818                 || EVP_PKEY_keygen_init(pctx) <= 0
2819                 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2820                     sm2_curves[testnum].nid) <= 0
2821                 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2822             EVP_PKEY_CTX_free(pctx);
2823             if (st == 0)
2824                 break;
2825 
2826             st = 0; /* set back to zero */
2827             /* attach it sooner to rely on main final cleanup */
2828             loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2829             loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2830 
2831             sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2832             sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2833             if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2834                 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2835                 break;
2836             }
2837 
2838             /* attach them directly to respective ctx */
2839             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2840             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2841 
2842             /*
2843              * No need to allow user to set an explicit ID here, just use
2844              * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2845              */
2846             if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2847                 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2848                 break;
2849 
2850             if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2851                                     EVP_sm3(), NULL, sm2_pkey))
2852                 break;
2853             if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2854                                       EVP_sm3(), NULL, sm2_pkey))
2855                 break;
2856             st = 1;         /* mark loop as succeeded */
2857         }
2858         if (st == 0) {
2859             BIO_printf(bio_err, "SM2 init failure.\n");
2860             ERR_print_errors(bio_err);
2861             op_count = 1;
2862         } else {
2863             for (i = 0; i < loopargs_len; i++) {
2864                 /* Perform SM2 signature test */
2865                 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2866                                     loopargs[i].buf2, &loopargs[i].sigsize,
2867                                     loopargs[i].buf, 20);
2868                 if (st == 0)
2869                     break;
2870             }
2871             if (st == 0) {
2872                 BIO_printf(bio_err,
2873                            "SM2 sign failure.  No SM2 sign will be done.\n");
2874                 ERR_print_errors(bio_err);
2875                 op_count = 1;
2876             } else {
2877                 pkey_print_message("sign", sm2_curves[testnum].name,
2878                                    sm2_c[testnum][0],
2879                                    sm2_curves[testnum].bits, seconds.sm2);
2880                 Time_F(START);
2881                 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2882                 d = Time_F(STOP);
2883 
2884                 BIO_printf(bio_err,
2885                            mr ? "+R10:%ld:%u:%s:%.2f\n" :
2886                            "%ld %u bits %s signs in %.2fs \n",
2887                            count, sm2_curves[testnum].bits,
2888                            sm2_curves[testnum].name, d);
2889                 sm2_results[testnum][0] = (double)count / d;
2890                 op_count = count;
2891             }
2892 
2893             /* Perform SM2 verification test */
2894             for (i = 0; i < loopargs_len; i++) {
2895                 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2896                                       loopargs[i].buf2, loopargs[i].sigsize,
2897                                       loopargs[i].buf, 20);
2898                 if (st != 1)
2899                     break;
2900             }
2901             if (st != 1) {
2902                 BIO_printf(bio_err,
2903                            "SM2 verify failure.  No SM2 verify will be done.\n");
2904                 ERR_print_errors(bio_err);
2905                 sm2_doit[testnum] = 0;
2906             } else {
2907                 pkey_print_message("verify", sm2_curves[testnum].name,
2908                                    sm2_c[testnum][1],
2909                                    sm2_curves[testnum].bits, seconds.sm2);
2910                 Time_F(START);
2911                 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2912                 d = Time_F(STOP);
2913                 BIO_printf(bio_err,
2914                            mr ? "+R11:%ld:%u:%s:%.2f\n"
2915                            : "%ld %u bits %s verify in %.2fs\n",
2916                            count, sm2_curves[testnum].bits,
2917                            sm2_curves[testnum].name, d);
2918                 sm2_results[testnum][1] = (double)count / d;
2919             }
2920 
2921             if (op_count <= 1) {
2922                 /* if longer than 10s, don't do any more */
2923                 for (testnum++; testnum < SM2_NUM; testnum++)
2924                     sm2_doit[testnum] = 0;
2925             }
2926         }
2927     }
2928 #endif                         /* OPENSSL_NO_SM2 */
2929 
2930 #ifndef OPENSSL_NO_DH
2931     for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2932         int ffdh_checks = 1;
2933 
2934         if (!ffdh_doit[testnum])
2935             continue;
2936 
2937         for (i = 0; i < loopargs_len; i++) {
2938             EVP_PKEY *pkey_A = NULL;
2939             EVP_PKEY *pkey_B = NULL;
2940             EVP_PKEY_CTX *ffdh_ctx = NULL;
2941             EVP_PKEY_CTX *test_ctx = NULL;
2942             size_t secret_size;
2943             size_t test_out;
2944 
2945             /* Ensure that the error queue is empty */
2946             if (ERR_peek_error()) {
2947                 BIO_printf(bio_err,
2948                            "WARNING: the error queue contains previous unhandled errors.\n");
2949                 ERR_print_errors(bio_err);
2950             }
2951 
2952             pkey_A = EVP_PKEY_new();
2953             if (!pkey_A) {
2954                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2955                 ERR_print_errors(bio_err);
2956                 op_count = 1;
2957                 ffdh_checks = 0;
2958                 break;
2959             }
2960             pkey_B = EVP_PKEY_new();
2961             if (!pkey_B) {
2962                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
2963                 ERR_print_errors(bio_err);
2964                 op_count = 1;
2965                 ffdh_checks = 0;
2966                 break;
2967             }
2968 
2969             ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
2970             if (!ffdh_ctx) {
2971                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
2972                 ERR_print_errors(bio_err);
2973                 op_count = 1;
2974                 ffdh_checks = 0;
2975                 break;
2976             }
2977 
2978             if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
2979                 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
2980                 ERR_print_errors(bio_err);
2981                 op_count = 1;
2982                 ffdh_checks = 0;
2983                 break;
2984             }
2985             if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
2986                 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
2987                 ERR_print_errors(bio_err);
2988                 op_count = 1;
2989                 ffdh_checks = 0;
2990                 break;
2991             }
2992 
2993             if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
2994                 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
2995                 BIO_printf(bio_err, "FFDH key generation failure.\n");
2996                 ERR_print_errors(bio_err);
2997                 op_count = 1;
2998                 ffdh_checks = 0;
2999                 break;
3000             }
3001 
3002             EVP_PKEY_CTX_free(ffdh_ctx);
3003 
3004             /*
3005              * check if the derivation works correctly both ways so that
3006              * we know if future derive calls will fail, and we can skip
3007              * error checking in benchmarked code
3008              */
3009             ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3010             if (ffdh_ctx == NULL) {
3011                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3012                 ERR_print_errors(bio_err);
3013                 op_count = 1;
3014                 ffdh_checks = 0;
3015                 break;
3016             }
3017             if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3018                 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3019                 ERR_print_errors(bio_err);
3020                 op_count = 1;
3021                 ffdh_checks = 0;
3022                 break;
3023             }
3024             if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3025                 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3026                 ERR_print_errors(bio_err);
3027                 op_count = 1;
3028                 ffdh_checks = 0;
3029                 break;
3030             }
3031             if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3032                 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3033                 ERR_print_errors(bio_err);
3034                 op_count = 1;
3035                 ffdh_checks = 0;
3036                 break;
3037             }
3038             if (secret_size > MAX_FFDH_SIZE) {
3039                 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3040                 op_count = 1;
3041                 ffdh_checks = 0;
3042                 break;
3043             }
3044             if (EVP_PKEY_derive(ffdh_ctx,
3045                                 loopargs[i].secret_ff_a,
3046                                 &secret_size) <= 0) {
3047                 BIO_printf(bio_err, "Shared secret derive failure.\n");
3048                 ERR_print_errors(bio_err);
3049                 op_count = 1;
3050                 ffdh_checks = 0;
3051                 break;
3052             }
3053             /* Now check from side B */
3054             test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3055             if (!test_ctx) {
3056                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3057                 ERR_print_errors(bio_err);
3058                 op_count = 1;
3059                 ffdh_checks = 0;
3060                 break;
3061             }
3062             if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3063                 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3064                 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3065                 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3066                 test_out != secret_size) {
3067                 BIO_printf(bio_err, "FFDH computation failure.\n");
3068                 op_count = 1;
3069                 ffdh_checks = 0;
3070                 break;
3071             }
3072 
3073             /* compare the computed secrets */
3074             if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3075                               loopargs[i].secret_ff_b, secret_size)) {
3076                 BIO_printf(bio_err, "FFDH computations don't match.\n");
3077                 ERR_print_errors(bio_err);
3078                 op_count = 1;
3079                 ffdh_checks = 0;
3080                 break;
3081             }
3082 
3083             loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3084 
3085             EVP_PKEY_free(pkey_A);
3086             pkey_A = NULL;
3087             EVP_PKEY_free(pkey_B);
3088             pkey_B = NULL;
3089             EVP_PKEY_CTX_free(test_ctx);
3090             test_ctx = NULL;
3091         }
3092         if (ffdh_checks != 0) {
3093             pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3094                                ffdh_params[testnum].bits, seconds.ffdh);
3095             Time_F(START);
3096             count =
3097                 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3098             d = Time_F(STOP);
3099             BIO_printf(bio_err,
3100                        mr ? "+R12:%ld:%d:%.2f\n" :
3101                        "%ld %u-bits FFDH ops in %.2fs\n", count,
3102                        ffdh_params[testnum].bits, d);
3103             ffdh_results[testnum][0] = (double)count / d;
3104             op_count = count;
3105         }
3106         if (op_count <= 1) {
3107             /* if longer than 10s, don't do any more */
3108             stop_it(ffdh_doit, testnum);
3109         }
3110     }
3111 #endif  /* OPENSSL_NO_DH */
3112 #ifndef NO_FORK
3113  show_res:
3114 #endif
3115     if (!mr) {
3116         printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3117         printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3118         printf("options: %s\n", BN_options());
3119         printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3120         printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3121     }
3122 
3123     if (pr_header) {
3124         if (mr) {
3125             printf("+H");
3126         } else {
3127             printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3128             printf("type        ");
3129         }
3130         for (testnum = 0; testnum < size_num; testnum++)
3131             printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3132         printf("\n");
3133     }
3134 
3135     for (k = 0; k < ALGOR_NUM; k++) {
3136         if (!doit[k])
3137             continue;
3138         if (mr)
3139             printf("+F:%u:%s", k, names[k]);
3140         else
3141             printf("%-13s", names[k]);
3142         for (testnum = 0; testnum < size_num; testnum++) {
3143             if (results[k][testnum] > 10000 && !mr)
3144                 printf(" %11.2fk", results[k][testnum] / 1e3);
3145             else
3146                 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3147         }
3148         printf("\n");
3149     }
3150     testnum = 1;
3151     for (k = 0; k < RSA_NUM; k++) {
3152         if (!rsa_doit[k])
3153             continue;
3154         if (testnum && !mr) {
3155             printf("%18ssign    verify    sign/s verify/s\n", " ");
3156             testnum = 0;
3157         }
3158         if (mr)
3159             printf("+F2:%u:%u:%f:%f\n",
3160                    k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3161         else
3162             printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3163                    rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3164                    rsa_results[k][0], rsa_results[k][1]);
3165     }
3166     testnum = 1;
3167     for (k = 0; k < DSA_NUM; k++) {
3168         if (!dsa_doit[k])
3169             continue;
3170         if (testnum && !mr) {
3171             printf("%18ssign    verify    sign/s verify/s\n", " ");
3172             testnum = 0;
3173         }
3174         if (mr)
3175             printf("+F3:%u:%u:%f:%f\n",
3176                    k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3177         else
3178             printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3179                    dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3180                    dsa_results[k][0], dsa_results[k][1]);
3181     }
3182     testnum = 1;
3183     for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3184         if (!ecdsa_doit[k])
3185             continue;
3186         if (testnum && !mr) {
3187             printf("%30ssign    verify    sign/s verify/s\n", " ");
3188             testnum = 0;
3189         }
3190 
3191         if (mr)
3192             printf("+F4:%u:%u:%f:%f\n",
3193                    k, ec_curves[k].bits,
3194                    ecdsa_results[k][0], ecdsa_results[k][1]);
3195         else
3196             printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3197                    ec_curves[k].bits, ec_curves[k].name,
3198                    1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3199                    ecdsa_results[k][0], ecdsa_results[k][1]);
3200     }
3201 
3202     testnum = 1;
3203     for (k = 0; k < EC_NUM; k++) {
3204         if (!ecdh_doit[k])
3205             continue;
3206         if (testnum && !mr) {
3207             printf("%30sop      op/s\n", " ");
3208             testnum = 0;
3209         }
3210         if (mr)
3211             printf("+F5:%u:%u:%f:%f\n",
3212                    k, ec_curves[k].bits,
3213                    ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3214 
3215         else
3216             printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3217                    ec_curves[k].bits, ec_curves[k].name,
3218                    1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3219     }
3220 
3221     testnum = 1;
3222     for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3223         if (!eddsa_doit[k])
3224             continue;
3225         if (testnum && !mr) {
3226             printf("%30ssign    verify    sign/s verify/s\n", " ");
3227             testnum = 0;
3228         }
3229 
3230         if (mr)
3231             printf("+F6:%u:%u:%s:%f:%f\n",
3232                    k, ed_curves[k].bits, ed_curves[k].name,
3233                    eddsa_results[k][0], eddsa_results[k][1]);
3234         else
3235             printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3236                    ed_curves[k].bits, ed_curves[k].name,
3237                    1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3238                    eddsa_results[k][0], eddsa_results[k][1]);
3239     }
3240 
3241 #ifndef OPENSSL_NO_SM2
3242     testnum = 1;
3243     for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3244         if (!sm2_doit[k])
3245             continue;
3246         if (testnum && !mr) {
3247             printf("%30ssign    verify    sign/s verify/s\n", " ");
3248             testnum = 0;
3249         }
3250 
3251         if (mr)
3252             printf("+F7:%u:%u:%s:%f:%f\n",
3253                    k, sm2_curves[k].bits, sm2_curves[k].name,
3254                    sm2_results[k][0], sm2_results[k][1]);
3255         else
3256             printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3257                    sm2_curves[k].bits, sm2_curves[k].name,
3258                    1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3259                    sm2_results[k][0], sm2_results[k][1]);
3260     }
3261 #endif
3262 #ifndef OPENSSL_NO_DH
3263     testnum = 1;
3264     for (k = 0; k < FFDH_NUM; k++) {
3265         if (!ffdh_doit[k])
3266             continue;
3267         if (testnum && !mr) {
3268             printf("%23sop     op/s\n", " ");
3269             testnum = 0;
3270         }
3271         if (mr)
3272             printf("+F8:%u:%u:%f:%f\n",
3273                    k, ffdh_params[k].bits,
3274                    ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3275 
3276         else
3277             printf("%4u bits ffdh %8.4fs %8.1f\n",
3278                    ffdh_params[k].bits,
3279                    1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3280     }
3281 #endif /* OPENSSL_NO_DH */
3282 
3283     ret = 0;
3284 
3285  end:
3286     ERR_print_errors(bio_err);
3287     for (i = 0; i < loopargs_len; i++) {
3288         OPENSSL_free(loopargs[i].buf_malloc);
3289         OPENSSL_free(loopargs[i].buf2_malloc);
3290 
3291         BN_free(bn);
3292         EVP_PKEY_CTX_free(genctx);
3293         for (k = 0; k < RSA_NUM; k++) {
3294             EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3295             EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3296         }
3297 #ifndef OPENSSL_NO_DH
3298         OPENSSL_free(loopargs[i].secret_ff_a);
3299         OPENSSL_free(loopargs[i].secret_ff_b);
3300         for (k = 0; k < FFDH_NUM; k++)
3301             EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3302 #endif
3303         for (k = 0; k < DSA_NUM; k++) {
3304             EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3305             EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3306         }
3307         for (k = 0; k < ECDSA_NUM; k++) {
3308             EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3309             EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3310         }
3311         for (k = 0; k < EC_NUM; k++)
3312             EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3313         for (k = 0; k < EdDSA_NUM; k++) {
3314             EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3315             EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3316         }
3317 #ifndef OPENSSL_NO_SM2
3318         for (k = 0; k < SM2_NUM; k++) {
3319             EVP_PKEY_CTX *pctx = NULL;
3320 
3321             /* free signing ctx */
3322             if (loopargs[i].sm2_ctx[k] != NULL
3323                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3324                 EVP_PKEY_CTX_free(pctx);
3325             EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3326             /* free verification ctx */
3327             if (loopargs[i].sm2_vfy_ctx[k] != NULL
3328                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3329                 EVP_PKEY_CTX_free(pctx);
3330             EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3331             /* free pkey */
3332             EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3333         }
3334 #endif
3335         OPENSSL_free(loopargs[i].secret_a);
3336         OPENSSL_free(loopargs[i].secret_b);
3337     }
3338     OPENSSL_free(evp_hmac_name);
3339     OPENSSL_free(evp_cmac_name);
3340 
3341     if (async_jobs > 0) {
3342         for (i = 0; i < loopargs_len; i++)
3343             ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3344     }
3345 
3346     if (async_init) {
3347         ASYNC_cleanup_thread();
3348     }
3349     OPENSSL_free(loopargs);
3350     release_engine(e);
3351     EVP_CIPHER_free(evp_cipher);
3352     EVP_MAC_free(mac);
3353     return ret;
3354 }
3355 
3356 static void print_message(const char *s, long num, int length, int tm)
3357 {
3358     BIO_printf(bio_err,
3359                mr ? "+DT:%s:%d:%d\n"
3360                : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3361     (void)BIO_flush(bio_err);
3362     run = 1;
3363     alarm(tm);
3364 }
3365 
3366 static void pkey_print_message(const char *str, const char *str2, long num,
3367                                unsigned int bits, int tm)
3368 {
3369     BIO_printf(bio_err,
3370                mr ? "+DTP:%d:%s:%s:%d\n"
3371                : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3372     (void)BIO_flush(bio_err);
3373     run = 1;
3374     alarm(tm);
3375 }
3376 
3377 static void print_result(int alg, int run_no, int count, double time_used)
3378 {
3379     if (count == -1) {
3380         BIO_printf(bio_err, "%s error!\n", names[alg]);
3381         ERR_print_errors(bio_err);
3382         return;
3383     }
3384     BIO_printf(bio_err,
3385                mr ? "+R:%d:%s:%f\n"
3386                : "%d %s's in %.2fs\n", count, names[alg], time_used);
3387     results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3388 }
3389 
3390 #ifndef NO_FORK
3391 static char *sstrsep(char **string, const char *delim)
3392 {
3393     char isdelim[256];
3394     char *token = *string;
3395 
3396     if (**string == 0)
3397         return NULL;
3398 
3399     memset(isdelim, 0, sizeof(isdelim));
3400     isdelim[0] = 1;
3401 
3402     while (*delim) {
3403         isdelim[(unsigned char)(*delim)] = 1;
3404         delim++;
3405     }
3406 
3407     while (!isdelim[(unsigned char)(**string)])
3408         (*string)++;
3409 
3410     if (**string) {
3411         **string = 0;
3412         (*string)++;
3413     }
3414 
3415     return token;
3416 }
3417 
3418 static int do_multi(int multi, int size_num)
3419 {
3420     int n;
3421     int fd[2];
3422     int *fds;
3423     int status;
3424     static char sep[] = ":";
3425 
3426     fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3427     for (n = 0; n < multi; ++n) {
3428         if (pipe(fd) == -1) {
3429             BIO_printf(bio_err, "pipe failure\n");
3430             exit(1);
3431         }
3432         fflush(stdout);
3433         (void)BIO_flush(bio_err);
3434         if (fork()) {
3435             close(fd[1]);
3436             fds[n] = fd[0];
3437         } else {
3438             close(fd[0]);
3439             close(1);
3440             if (dup(fd[1]) == -1) {
3441                 BIO_printf(bio_err, "dup failed\n");
3442                 exit(1);
3443             }
3444             close(fd[1]);
3445             mr = 1;
3446             usertime = 0;
3447             OPENSSL_free(fds);
3448             return 0;
3449         }
3450         printf("Forked child %d\n", n);
3451     }
3452 
3453     /* for now, assume the pipe is long enough to take all the output */
3454     for (n = 0; n < multi; ++n) {
3455         FILE *f;
3456         char buf[1024];
3457         char *p;
3458 
3459         if ((f = fdopen(fds[n], "r")) == NULL) {
3460             BIO_printf(bio_err, "fdopen failure with 0x%x\n",
3461                        errno);
3462             OPENSSL_free(fds);
3463             return 1;
3464         }
3465         while (fgets(buf, sizeof(buf), f)) {
3466             p = strchr(buf, '\n');
3467             if (p)
3468                 *p = '\0';
3469             if (buf[0] != '+') {
3470                 BIO_printf(bio_err,
3471                            "Don't understand line '%s' from child %d\n", buf,
3472                            n);
3473                 continue;
3474             }
3475             printf("Got: %s from %d\n", buf, n);
3476             if (strncmp(buf, "+F:", 3) == 0) {
3477                 int alg;
3478                 int j;
3479 
3480                 p = buf + 3;
3481                 alg = atoi(sstrsep(&p, sep));
3482                 sstrsep(&p, sep);
3483                 for (j = 0; j < size_num; ++j)
3484                     results[alg][j] += atof(sstrsep(&p, sep));
3485             } else if (strncmp(buf, "+F2:", 4) == 0) {
3486                 int k;
3487                 double d;
3488 
3489                 p = buf + 4;
3490                 k = atoi(sstrsep(&p, sep));
3491                 sstrsep(&p, sep);
3492 
3493                 d = atof(sstrsep(&p, sep));
3494                 rsa_results[k][0] += d;
3495 
3496                 d = atof(sstrsep(&p, sep));
3497                 rsa_results[k][1] += d;
3498             } else if (strncmp(buf, "+F3:", 4) == 0) {
3499                 int k;
3500                 double d;
3501 
3502                 p = buf + 4;
3503                 k = atoi(sstrsep(&p, sep));
3504                 sstrsep(&p, sep);
3505 
3506                 d = atof(sstrsep(&p, sep));
3507                 dsa_results[k][0] += d;
3508 
3509                 d = atof(sstrsep(&p, sep));
3510                 dsa_results[k][1] += d;
3511             } else if (strncmp(buf, "+F4:", 4) == 0) {
3512                 int k;
3513                 double d;
3514 
3515                 p = buf + 4;
3516                 k = atoi(sstrsep(&p, sep));
3517                 sstrsep(&p, sep);
3518 
3519                 d = atof(sstrsep(&p, sep));
3520                 ecdsa_results[k][0] += d;
3521 
3522                 d = atof(sstrsep(&p, sep));
3523                 ecdsa_results[k][1] += d;
3524             } else if (strncmp(buf, "+F5:", 4) == 0) {
3525                 int k;
3526                 double d;
3527 
3528                 p = buf + 4;
3529                 k = atoi(sstrsep(&p, sep));
3530                 sstrsep(&p, sep);
3531 
3532                 d = atof(sstrsep(&p, sep));
3533                 ecdh_results[k][0] += d;
3534             } else if (strncmp(buf, "+F6:", 4) == 0) {
3535                 int k;
3536                 double d;
3537 
3538                 p = buf + 4;
3539                 k = atoi(sstrsep(&p, sep));
3540                 sstrsep(&p, sep);
3541                 sstrsep(&p, sep);
3542 
3543                 d = atof(sstrsep(&p, sep));
3544                 eddsa_results[k][0] += d;
3545 
3546                 d = atof(sstrsep(&p, sep));
3547                 eddsa_results[k][1] += d;
3548 # ifndef OPENSSL_NO_SM2
3549             } else if (strncmp(buf, "+F7:", 4) == 0) {
3550                 int k;
3551                 double d;
3552 
3553                 p = buf + 4;
3554                 k = atoi(sstrsep(&p, sep));
3555                 sstrsep(&p, sep);
3556                 sstrsep(&p, sep);
3557 
3558                 d = atof(sstrsep(&p, sep));
3559                 sm2_results[k][0] += d;
3560 
3561                 d = atof(sstrsep(&p, sep));
3562                 sm2_results[k][1] += d;
3563 # endif /* OPENSSL_NO_SM2 */
3564 # ifndef OPENSSL_NO_DH
3565             } else if (strncmp(buf, "+F8:", 4) == 0) {
3566                 int k;
3567                 double d;
3568 
3569                 p = buf + 4;
3570                 k = atoi(sstrsep(&p, sep));
3571                 sstrsep(&p, sep);
3572 
3573                 d = atof(sstrsep(&p, sep));
3574                 ffdh_results[k][0] += d;
3575 # endif /* OPENSSL_NO_DH */
3576             } else if (strncmp(buf, "+H:", 3) == 0) {
3577                 ;
3578             } else {
3579                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3580                            n);
3581             }
3582         }
3583 
3584         fclose(f);
3585     }
3586     OPENSSL_free(fds);
3587     for (n = 0; n < multi; ++n) {
3588         while (wait(&status) == -1)
3589             if (errno != EINTR) {
3590                 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
3591                            errno);
3592                 return 1;
3593             }
3594         if (WIFEXITED(status) && WEXITSTATUS(status)) {
3595             BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
3596         } else if (WIFSIGNALED(status)) {
3597             BIO_printf(bio_err, "Child terminated by signal %d\n",
3598                        WTERMSIG(status));
3599         }
3600     }
3601     return 1;
3602 }
3603 #endif
3604 
3605 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3606                              const openssl_speed_sec_t *seconds)
3607 {
3608     static const int mblengths_list[] =
3609         { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3610     const int *mblengths = mblengths_list;
3611     int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3612     const char *alg_name;
3613     unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3614     EVP_CIPHER_CTX *ctx = NULL;
3615     double d = 0.0;
3616 
3617     if (lengths_single) {
3618         mblengths = &lengths_single;
3619         num = 1;
3620     }
3621 
3622     inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3623     out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3624     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3625         app_bail_out("failed to allocate cipher context\n");
3626     if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3627         app_bail_out("failed to initialise cipher context\n");
3628 
3629     if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3630         BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3631         goto err;
3632     }
3633     key = app_malloc(keylen, "evp_cipher key");
3634     if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
3635         app_bail_out("failed to generate random cipher key\n");
3636     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3637         app_bail_out("failed to set cipher key\n");
3638     OPENSSL_clear_free(key, keylen);
3639 
3640     if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3641                              sizeof(no_key), no_key) <= 0)
3642         app_bail_out("failed to set AEAD key\n");
3643     if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3644         app_bail_out("failed to get cipher name\n");
3645 
3646     for (j = 0; j < num; j++) {
3647         print_message(alg_name, 0, mblengths[j], seconds->sym);
3648         Time_F(START);
3649         for (count = 0; run && count < INT_MAX; count++) {
3650             unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3651             EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3652             size_t len = mblengths[j];
3653             int packlen;
3654 
3655             memset(aad, 0, 8);  /* avoid uninitialized values */
3656             aad[8] = 23;        /* SSL3_RT_APPLICATION_DATA */
3657             aad[9] = 3;         /* version */
3658             aad[10] = 2;
3659             aad[11] = 0;        /* length */
3660             aad[12] = 0;
3661             mb_param.out = NULL;
3662             mb_param.inp = aad;
3663             mb_param.len = len;
3664             mb_param.interleave = 8;
3665 
3666             packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3667                                           sizeof(mb_param), &mb_param);
3668 
3669             if (packlen > 0) {
3670                 mb_param.out = out;
3671                 mb_param.inp = inp;
3672                 mb_param.len = len;
3673                 (void)EVP_CIPHER_CTX_ctrl(ctx,
3674                                           EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3675                                           sizeof(mb_param), &mb_param);
3676             } else {
3677                 int pad;
3678 
3679                 RAND_bytes(out, 16);
3680                 len += 16;
3681                 aad[11] = (unsigned char)(len >> 8);
3682                 aad[12] = (unsigned char)(len);
3683                 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3684                                           EVP_AEAD_TLS1_AAD_LEN, aad);
3685                 EVP_Cipher(ctx, out, inp, len + pad);
3686             }
3687         }
3688         d = Time_F(STOP);
3689         BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3690                    : "%d %s's in %.2fs\n", count, "evp", d);
3691         results[D_EVP][j] = ((double)count) / d * mblengths[j];
3692     }
3693 
3694     if (mr) {
3695         fprintf(stdout, "+H");
3696         for (j = 0; j < num; j++)
3697             fprintf(stdout, ":%d", mblengths[j]);
3698         fprintf(stdout, "\n");
3699         fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3700         for (j = 0; j < num; j++)
3701             fprintf(stdout, ":%.2f", results[D_EVP][j]);
3702         fprintf(stdout, "\n");
3703     } else {
3704         fprintf(stdout,
3705                 "The 'numbers' are in 1000s of bytes per second processed.\n");
3706         fprintf(stdout, "type                    ");
3707         for (j = 0; j < num; j++)
3708             fprintf(stdout, "%7d bytes", mblengths[j]);
3709         fprintf(stdout, "\n");
3710         fprintf(stdout, "%-24s", alg_name);
3711 
3712         for (j = 0; j < num; j++) {
3713             if (results[D_EVP][j] > 10000)
3714                 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3715             else
3716                 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3717         }
3718         fprintf(stdout, "\n");
3719     }
3720 
3721  err:
3722     OPENSSL_free(inp);
3723     OPENSSL_free(out);
3724     EVP_CIPHER_CTX_free(ctx);
3725 }
3726