xref: /freebsd/crypto/openssl/apps/speed.c (revision 1523ccfd9c8c254f7928143d31c305384b05fd11)
1 /*
2  * Copyright 1995-2026 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 #define KEM_SECONDS PKEY_SECONDS
23 #define SIG_SECONDS PKEY_SECONDS
24 
25 #define MAX_ALGNAME_SUFFIX 100
26 
27 /* We need to use some deprecated APIs */
28 #define OPENSSL_SUPPRESS_DEPRECATED
29 #include "internal/e_os.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <math.h>
35 #include "apps.h"
36 #include "progs.h"
37 #include "internal/nelem.h"
38 #include "internal/numbers.h"
39 #include <openssl/crypto.h>
40 #include <openssl/rand.h>
41 #include <openssl/err.h>
42 #include <openssl/evp.h>
43 #include <openssl/objects.h>
44 #include <openssl/core_names.h>
45 #include <openssl/async.h>
46 #include <openssl/provider.h>
47 #if !defined(OPENSSL_SYS_MSDOS)
48 #include <unistd.h>
49 #endif
50 
51 #if defined(_WIN32)
52 #include <windows.h>
53 /*
54  * While VirtualLock is available under the app partition (e.g. UWP),
55  * the headers do not define the API. Define it ourselves instead.
56  */
57 WINBASEAPI
58 BOOL
59     WINAPI
60     VirtualLock(
61         _In_ LPVOID lpAddress,
62         _In_ SIZE_T dwSize);
63 #endif
64 
65 #if defined(OPENSSL_SYS_LINUX)
66 #include <sys/mman.h>
67 #endif
68 
69 #include <openssl/bn.h>
70 #include <openssl/rsa.h>
71 #include "./testrsa.h"
72 #ifndef OPENSSL_NO_DH
73 #include <openssl/dh.h>
74 #endif
75 #include <openssl/x509.h>
76 #include <openssl/dsa.h>
77 #include "./testdsa.h"
78 #include <openssl/modes.h>
79 
80 #ifndef HAVE_FORK
81 #if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
82 #define HAVE_FORK 0
83 #else
84 #define HAVE_FORK 1
85 #include <sys/wait.h>
86 #endif
87 #endif
88 
89 #if HAVE_FORK
90 #undef NO_FORK
91 #else
92 #define NO_FORK
93 #endif
94 
95 #define MAX_MISALIGNMENT 63
96 #define MAX_ECDH_SIZE 256
97 #define MISALIGN 64
98 #define MAX_FFDH_SIZE 1024
99 
100 #ifndef RSA_DEFAULT_PRIME_NUM
101 #define RSA_DEFAULT_PRIME_NUM 2
102 #endif
103 
104 typedef struct openssl_speed_sec_st {
105     int sym;
106     int rsa;
107     int dsa;
108     int ecdsa;
109     int ecdh;
110     int eddsa;
111     int sm2;
112     int ffdh;
113     int kem;
114     int sig;
115 } openssl_speed_sec_t;
116 
117 static volatile int run = 0;
118 
119 static int mr = 0; /* machine-readeable output format to merge fork results */
120 static int usertime = 1;
121 
122 static double Time_F(int s);
123 static void print_message(const char *s, int length, int tm);
124 static void pkey_print_message(const char *str, const char *str2,
125     unsigned int bits, int sec);
126 static void kskey_print_message(const char *str, const char *str2, int tm);
127 static void print_result(int alg, int run_no, int count, double time_used);
128 #ifndef NO_FORK
129 static int do_multi(int multi, int size_num);
130 #endif
131 
132 static int domlock = 0;
133 static int testmode = 0;
134 static int testmoderesult = 0;
135 
136 static const int lengths_list[] = {
137     16, 64, 256, 1024, 8 * 1024, 16 * 1024
138 };
139 #define SIZE_NUM OSSL_NELEM(lengths_list)
140 static const int *lengths = lengths_list;
141 
142 static const int aead_lengths_list[] = {
143     2, 31, 136, 1024, 8 * 1024, 16 * 1024
144 };
145 
146 #define START 0
147 #define STOP 1
148 
149 #ifdef SIGALRM
150 
151 static void alarmed(ossl_unused int sig)
152 {
153     signal(SIGALRM, alarmed);
154     run = 0;
155 }
156 
157 static double Time_F(int s)
158 {
159     double ret = app_tminterval(s, usertime);
160     if (s == STOP)
161         alarm(0);
162     return ret;
163 }
164 
165 #elif defined(_WIN32)
166 
167 #define SIGALRM -1
168 
169 static unsigned int lapse;
170 static volatile unsigned int schlock;
171 static void alarm_win32(unsigned int secs)
172 {
173     lapse = secs * 1000;
174 }
175 
176 #define alarm alarm_win32
177 
178 static DWORD WINAPI sleepy(VOID *arg)
179 {
180     schlock = 1;
181     Sleep(lapse);
182     run = 0;
183     return 0;
184 }
185 
186 static double Time_F(int s)
187 {
188     double ret;
189     static HANDLE thr;
190 
191     if (s == START) {
192         schlock = 0;
193         thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
194         if (thr == NULL) {
195             DWORD err = GetLastError();
196             BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
197             ExitProcess(err);
198         }
199         while (!schlock)
200             Sleep(0); /* scheduler spinlock */
201         ret = app_tminterval(s, usertime);
202     } else {
203         ret = app_tminterval(s, usertime);
204         if (run)
205             TerminateThread(thr, 0);
206         CloseHandle(thr);
207     }
208 
209     return ret;
210 }
211 #else
212 #error "SIGALRM not defined and the platform is not Windows"
213 #endif
214 
215 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
216     const openssl_speed_sec_t *seconds);
217 
218 static int opt_found(const char *name, unsigned int *result,
219     const OPT_PAIR pairs[], unsigned int nbelem)
220 {
221     unsigned int idx;
222 
223     for (idx = 0; idx < nbelem; ++idx, pairs++)
224         if (strcmp(name, pairs->name) == 0) {
225             *result = pairs->retval;
226             return 1;
227         }
228     return 0;
229 }
230 #define opt_found(value, pairs, result) \
231     opt_found(value, result, pairs, OSSL_NELEM(pairs))
232 
233 typedef enum OPTION_choice {
234     OPT_COMMON,
235     OPT_ELAPSED,
236     OPT_EVP,
237     OPT_HMAC,
238     OPT_DECRYPT,
239     OPT_ENGINE,
240     OPT_MULTI,
241     OPT_MR,
242     OPT_MB,
243     OPT_MISALIGN,
244     OPT_ASYNCJOBS,
245     OPT_R_ENUM,
246     OPT_PROV_ENUM,
247     OPT_CONFIG,
248     OPT_PRIMES,
249     OPT_SECONDS,
250     OPT_BYTES,
251     OPT_AEAD,
252     OPT_CMAC,
253     OPT_MLOCK,
254     OPT_TESTMODE,
255     OPT_KEM,
256     OPT_SIG
257 } OPTION_CHOICE;
258 
259 const OPTIONS speed_options[] = {
260     { OPT_HELP_STR, 1, '-',
261         "Usage: %s [options] [algorithm...]\n"
262         "All +int options consider prefix '0' as base-8 input, "
263         "prefix '0x'/'0X' as base-16 input.\n" },
264 
265     OPT_SECTION("General"),
266     { "help", OPT_HELP, '-', "Display this summary" },
267     { "mb", OPT_MB, '-',
268         "Enable (tls1>=1) multi-block mode on EVP-named cipher" },
269     { "mr", OPT_MR, '-', "Produce machine readable output" },
270 #ifndef NO_FORK
271     { "multi", OPT_MULTI, 'p', "Run benchmarks in parallel" },
272 #endif
273 #ifndef OPENSSL_NO_ASYNC
274     { "async_jobs", OPT_ASYNCJOBS, 'p',
275         "Enable async mode and start specified number of jobs" },
276 #endif
277 #ifndef OPENSSL_NO_ENGINE
278     { "engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device" },
279 #endif
280     { "primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)" },
281     { "mlock", OPT_MLOCK, '-', "Lock memory for better result determinism" },
282     { "testmode", OPT_TESTMODE, '-', "Run the speed command in test mode" },
283     OPT_CONFIG_OPTION,
284 
285     OPT_SECTION("Selection"),
286     { "evp", OPT_EVP, 's', "Use EVP-named cipher or digest" },
287     { "hmac", OPT_HMAC, 's', "HMAC using EVP-named digest" },
288     { "cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher" },
289     { "decrypt", OPT_DECRYPT, '-',
290         "Time decryption instead of encryption (only EVP)" },
291     { "aead", OPT_AEAD, '-',
292         "Benchmark EVP-named AEAD cipher in TLS-like sequence" },
293     { "kem-algorithms", OPT_KEM, '-',
294         "Benchmark KEM algorithms" },
295     { "signature-algorithms", OPT_SIG, '-',
296         "Benchmark signature algorithms" },
297 
298     OPT_SECTION("Timing"),
299     { "elapsed", OPT_ELAPSED, '-',
300         "Use wall-clock time instead of CPU user time as divisor" },
301     { "seconds", OPT_SECONDS, 'p',
302         "Run benchmarks for specified amount of seconds" },
303     { "bytes", OPT_BYTES, 'p',
304         "Run [non-PKI] benchmarks on custom-sized buffer" },
305     { "misalign", OPT_MISALIGN, 'p',
306         "Use specified offset to mis-align buffers" },
307 
308     OPT_R_OPTIONS,
309     OPT_PROV_OPTIONS,
310 
311     OPT_PARAMETERS(),
312     { "algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)" },
313     { NULL }
314 };
315 
316 enum {
317     D_MD2,
318     D_MDC2,
319     D_MD4,
320     D_MD5,
321     D_SHA1,
322     D_RMD160,
323     D_SHA256,
324     D_SHA512,
325     D_WHIRLPOOL,
326     D_HMAC,
327     D_CBC_DES,
328     D_EDE3_DES,
329     D_RC4,
330     D_CBC_IDEA,
331     D_CBC_SEED,
332     D_CBC_RC2,
333     D_CBC_RC5,
334     D_CBC_BF,
335     D_CBC_CAST,
336     D_CBC_128_AES,
337     D_CBC_192_AES,
338     D_CBC_256_AES,
339     D_CBC_128_CML,
340     D_CBC_192_CML,
341     D_CBC_256_CML,
342     D_EVP,
343     D_GHASH,
344     D_RAND,
345     D_EVP_CMAC,
346     D_KMAC128,
347     D_KMAC256,
348     ALGOR_NUM
349 };
350 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
351 static const char *names[ALGOR_NUM] = {
352     "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
353     "sha256", "sha512", "whirlpool", "hmac(sha256)",
354     "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
355     "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
356     "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
357     "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
358     "evp", "ghash", "rand", "cmac", "kmac128", "kmac256"
359 };
360 
361 /* list of configured algorithm (remaining), with some few alias */
362 static const OPT_PAIR doit_choices[] = {
363     { "md2", D_MD2 },
364     { "mdc2", D_MDC2 },
365     { "md4", D_MD4 },
366     { "md5", D_MD5 },
367     { "hmac", D_HMAC },
368     { "sha1", D_SHA1 },
369     { "sha256", D_SHA256 },
370     { "sha512", D_SHA512 },
371     { "whirlpool", D_WHIRLPOOL },
372     { "ripemd", D_RMD160 },
373     { "rmd160", D_RMD160 },
374     { "ripemd160", D_RMD160 },
375     { "rc4", D_RC4 },
376     { "des-cbc", D_CBC_DES },
377     { "des-ede3", D_EDE3_DES },
378     { "aes-128-cbc", D_CBC_128_AES },
379     { "aes-192-cbc", D_CBC_192_AES },
380     { "aes-256-cbc", D_CBC_256_AES },
381     { "camellia-128-cbc", D_CBC_128_CML },
382     { "camellia-192-cbc", D_CBC_192_CML },
383     { "camellia-256-cbc", D_CBC_256_CML },
384     { "rc2-cbc", D_CBC_RC2 },
385     { "rc2", D_CBC_RC2 },
386     { "rc5-cbc", D_CBC_RC5 },
387     { "rc5", D_CBC_RC5 },
388     { "idea-cbc", D_CBC_IDEA },
389     { "idea", D_CBC_IDEA },
390     { "seed-cbc", D_CBC_SEED },
391     { "seed", D_CBC_SEED },
392     { "bf-cbc", D_CBC_BF },
393     { "blowfish", D_CBC_BF },
394     { "bf", D_CBC_BF },
395     { "cast-cbc", D_CBC_CAST },
396     { "cast", D_CBC_CAST },
397     { "cast5", D_CBC_CAST },
398     { "ghash", D_GHASH },
399     { "rand", D_RAND },
400     { "kmac128", D_KMAC128 },
401     { "kmac256", D_KMAC256 },
402 };
403 
404 static double results[ALGOR_NUM][SIZE_NUM];
405 
406 #ifndef OPENSSL_NO_DSA
407 enum { R_DSA_1024,
408     R_DSA_2048,
409     DSA_NUM };
410 static const OPT_PAIR dsa_choices[DSA_NUM] = {
411     { "dsa1024", R_DSA_1024 },
412     { "dsa2048", R_DSA_2048 }
413 };
414 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
415 #endif /* OPENSSL_NO_DSA */
416 
417 enum {
418     R_RSA_512,
419     R_RSA_1024,
420     R_RSA_2048,
421     R_RSA_3072,
422     R_RSA_4096,
423     R_RSA_7680,
424     R_RSA_15360,
425     RSA_NUM
426 };
427 static const OPT_PAIR rsa_choices[RSA_NUM] = {
428     { "rsa512", R_RSA_512 },
429     { "rsa1024", R_RSA_1024 },
430     { "rsa2048", R_RSA_2048 },
431     { "rsa3072", R_RSA_3072 },
432     { "rsa4096", R_RSA_4096 },
433     { "rsa7680", R_RSA_7680 },
434     { "rsa15360", R_RSA_15360 }
435 };
436 
437 static double rsa_results[RSA_NUM][4]; /* 4 ops: sign, verify, encrypt, decrypt */
438 
439 #ifndef OPENSSL_NO_DH
440 enum ff_params_t {
441     R_FFDH_2048,
442     R_FFDH_3072,
443     R_FFDH_4096,
444     R_FFDH_6144,
445     R_FFDH_8192,
446     FFDH_NUM
447 };
448 
449 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
450     { "ffdh2048", R_FFDH_2048 },
451     { "ffdh3072", R_FFDH_3072 },
452     { "ffdh4096", R_FFDH_4096 },
453     { "ffdh6144", R_FFDH_6144 },
454     { "ffdh8192", R_FFDH_8192 },
455 };
456 
457 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
458 #endif /* OPENSSL_NO_DH */
459 
460 enum ec_curves_t {
461     R_EC_P160,
462     R_EC_P192,
463     R_EC_P224,
464     R_EC_P256,
465     R_EC_P384,
466     R_EC_P521,
467 #ifndef OPENSSL_NO_EC2M
468     R_EC_K163,
469     R_EC_K233,
470     R_EC_K283,
471     R_EC_K409,
472     R_EC_K571,
473     R_EC_B163,
474     R_EC_B233,
475     R_EC_B283,
476     R_EC_B409,
477     R_EC_B571,
478 #endif
479     R_EC_BRP256R1,
480     R_EC_BRP256T1,
481     R_EC_BRP384R1,
482     R_EC_BRP384T1,
483     R_EC_BRP512R1,
484     R_EC_BRP512T1,
485     ECDSA_NUM
486 };
487 /* list of ecdsa curves */
488 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
489     { "ecdsap160", R_EC_P160 },
490     { "ecdsap192", R_EC_P192 },
491     { "ecdsap224", R_EC_P224 },
492     { "ecdsap256", R_EC_P256 },
493     { "ecdsap384", R_EC_P384 },
494     { "ecdsap521", R_EC_P521 },
495 #ifndef OPENSSL_NO_EC2M
496     { "ecdsak163", R_EC_K163 },
497     { "ecdsak233", R_EC_K233 },
498     { "ecdsak283", R_EC_K283 },
499     { "ecdsak409", R_EC_K409 },
500     { "ecdsak571", R_EC_K571 },
501     { "ecdsab163", R_EC_B163 },
502     { "ecdsab233", R_EC_B233 },
503     { "ecdsab283", R_EC_B283 },
504     { "ecdsab409", R_EC_B409 },
505     { "ecdsab571", R_EC_B571 },
506 #endif
507     { "ecdsabrp256r1", R_EC_BRP256R1 },
508     { "ecdsabrp256t1", R_EC_BRP256T1 },
509     { "ecdsabrp384r1", R_EC_BRP384R1 },
510     { "ecdsabrp384t1", R_EC_BRP384T1 },
511     { "ecdsabrp512r1", R_EC_BRP512R1 },
512     { "ecdsabrp512t1", R_EC_BRP512T1 }
513 };
514 enum {
515 #ifndef OPENSSL_NO_ECX
516     R_EC_X25519 = ECDSA_NUM,
517     R_EC_X448,
518     EC_NUM
519 #else
520     EC_NUM = ECDSA_NUM
521 #endif
522 };
523 /* list of ecdh curves, extension of |ecdsa_choices| list above */
524 static const OPT_PAIR ecdh_choices[EC_NUM] = {
525     { "ecdhp160", R_EC_P160 },
526     { "ecdhp192", R_EC_P192 },
527     { "ecdhp224", R_EC_P224 },
528     { "ecdhp256", R_EC_P256 },
529     { "ecdhp384", R_EC_P384 },
530     { "ecdhp521", R_EC_P521 },
531 #ifndef OPENSSL_NO_EC2M
532     { "ecdhk163", R_EC_K163 },
533     { "ecdhk233", R_EC_K233 },
534     { "ecdhk283", R_EC_K283 },
535     { "ecdhk409", R_EC_K409 },
536     { "ecdhk571", R_EC_K571 },
537     { "ecdhb163", R_EC_B163 },
538     { "ecdhb233", R_EC_B233 },
539     { "ecdhb283", R_EC_B283 },
540     { "ecdhb409", R_EC_B409 },
541     { "ecdhb571", R_EC_B571 },
542 #endif
543     { "ecdhbrp256r1", R_EC_BRP256R1 },
544     { "ecdhbrp256t1", R_EC_BRP256T1 },
545     { "ecdhbrp384r1", R_EC_BRP384R1 },
546     { "ecdhbrp384t1", R_EC_BRP384T1 },
547     { "ecdhbrp512r1", R_EC_BRP512R1 },
548     { "ecdhbrp512t1", R_EC_BRP512T1 },
549 #ifndef OPENSSL_NO_ECX
550     { "ecdhx25519", R_EC_X25519 },
551     { "ecdhx448", R_EC_X448 }
552 #endif
553 };
554 
555 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
556 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
557 
558 #ifndef OPENSSL_NO_ECX
559 enum { R_EC_Ed25519,
560     R_EC_Ed448,
561     EdDSA_NUM };
562 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
563     { "ed25519", R_EC_Ed25519 },
564     { "ed448", R_EC_Ed448 }
565 
566 };
567 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
568 #endif /* OPENSSL_NO_ECX */
569 
570 #ifndef OPENSSL_NO_SM2
571 enum { R_EC_CURVESM2,
572     SM2_NUM };
573 static const OPT_PAIR sm2_choices[SM2_NUM] = {
574     { "curveSM2", R_EC_CURVESM2 }
575 };
576 #define SM2_ID "TLSv1.3+GM+Cipher+Suite"
577 #define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
578 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
579 #endif /* OPENSSL_NO_SM2 */
580 
581 #define MAX_KEM_NUM 111
582 static size_t kems_algs_len = 0;
583 static char *kems_algname[MAX_KEM_NUM] = { NULL };
584 static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
585 
586 #define MAX_SIG_NUM 256
587 static size_t sigs_algs_len = 0;
588 static char *sigs_algname[MAX_SIG_NUM] = { NULL };
589 static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
590 
591 #define COND(unused_cond) (run && count < (testmode ? 1 : INT_MAX))
592 #define COUNT(d) (count)
593 
594 #define TAG_LEN 16 /* 16 bytes tag length works for all AEAD modes */
595 #define AEAD_IVLEN 12 /* 12 bytes iv length works for all AEAD modes */
596 
597 static unsigned int mode_op; /* AE Mode of operation */
598 static unsigned int aead = 0; /* AEAD flag */
599 static unsigned char aead_iv[AEAD_IVLEN]; /* For AEAD modes */
600 static unsigned char aad[EVP_AEAD_TLS1_AAD_LEN] = { 0xcc };
601 
602 typedef struct loopargs_st {
603     ASYNC_JOB *inprogress_job;
604     ASYNC_WAIT_CTX *wait_ctx;
605     unsigned char *buf;
606     unsigned char *buf2;
607     unsigned char *buf_malloc;
608     unsigned char *buf2_malloc;
609     unsigned char *key;
610     unsigned char tag[TAG_LEN];
611     size_t buflen;
612     size_t sigsize;
613     size_t encsize;
614     EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
615     EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
616     EVP_PKEY_CTX *rsa_encrypt_ctx[RSA_NUM];
617     EVP_PKEY_CTX *rsa_decrypt_ctx[RSA_NUM];
618 #ifndef OPENSSL_NO_DSA
619     EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
620     EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
621 #endif
622     EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
623     EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
624     EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
625 #ifndef OPENSSL_NO_ECX
626     EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
627     EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
628 #endif /* OPENSSL_NO_ECX */
629 #ifndef OPENSSL_NO_SM2
630     EVP_MD_CTX *sm2_ctx[SM2_NUM];
631     EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
632     EVP_PKEY *sm2_pkey[SM2_NUM];
633 #endif
634     unsigned char *secret_a;
635     unsigned char *secret_b;
636     size_t outlen[EC_NUM];
637 #ifndef OPENSSL_NO_DH
638     EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
639     unsigned char *secret_ff_a;
640     unsigned char *secret_ff_b;
641 #endif
642     EVP_CIPHER_CTX *ctx;
643     EVP_MAC_CTX *mctx;
644     EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM];
645     EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM];
646     EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM];
647     size_t kem_out_len[MAX_KEM_NUM];
648     size_t kem_secret_len[MAX_KEM_NUM];
649     unsigned char *kem_out[MAX_KEM_NUM];
650     unsigned char *kem_send_secret[MAX_KEM_NUM];
651     unsigned char *kem_rcv_secret[MAX_KEM_NUM];
652     EVP_PKEY_CTX *sig_gen_ctx[MAX_SIG_NUM];
653     EVP_PKEY_CTX *sig_sign_ctx[MAX_SIG_NUM];
654     EVP_PKEY_CTX *sig_verify_ctx[MAX_SIG_NUM];
655     size_t sig_max_sig_len[MAX_SIG_NUM];
656     size_t sig_act_sig_len[MAX_SIG_NUM];
657     unsigned char *sig_sig[MAX_SIG_NUM];
658 } loopargs_t;
659 static int run_benchmark(int async_jobs, int (*loop_function)(void *),
660     loopargs_t *loopargs);
661 
662 static unsigned int testnum;
663 
664 static char *evp_mac_mdname = "sha256";
665 static char *evp_hmac_name = NULL;
666 static const char *evp_md_name = NULL;
667 static char *evp_mac_ciphername = "aes-128-cbc";
668 static char *evp_cmac_name = NULL;
669 
670 static void dofail(void)
671 {
672     ERR_print_errors(bio_err);
673     testmoderesult = 1;
674 }
675 
676 static int have_md(const char *name)
677 {
678     int ret = 0;
679     EVP_MD *md = NULL;
680 
681     if (opt_md_silent(name, &md)) {
682         EVP_MD_CTX *ctx = EVP_MD_CTX_new();
683 
684         if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
685             ret = 1;
686         EVP_MD_CTX_free(ctx);
687         EVP_MD_free(md);
688     }
689     return ret;
690 }
691 
692 static int have_cipher(const char *name)
693 {
694     int ret = 0;
695     EVP_CIPHER *cipher = NULL;
696 
697     if (opt_cipher_silent(name, &cipher)) {
698         EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
699 
700         if (ctx != NULL
701             && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
702             ret = 1;
703         EVP_CIPHER_CTX_free(ctx);
704         EVP_CIPHER_free(cipher);
705     }
706     return ret;
707 }
708 
709 static int EVP_Digest_loop(const char *mdname, ossl_unused int algindex, void *args)
710 {
711     loopargs_t *tempargs = *(loopargs_t **)args;
712     unsigned char *buf = tempargs->buf;
713     unsigned char digest[EVP_MAX_MD_SIZE];
714     int count;
715     EVP_MD *md = NULL;
716     EVP_MD_CTX *ctx = NULL;
717 
718     if (!opt_md_silent(mdname, &md))
719         return -1;
720     if (EVP_MD_xof(md)) {
721         ctx = EVP_MD_CTX_new();
722         if (ctx == NULL) {
723             count = -1;
724             goto out;
725         }
726 
727         for (count = 0; COND(c[algindex][testnum]); count++) {
728             if (!EVP_DigestInit_ex2(ctx, md, NULL)
729                 || !EVP_DigestUpdate(ctx, buf, (size_t)lengths[testnum])
730                 || !EVP_DigestFinalXOF(ctx, digest, sizeof(digest))) {
731                 count = -1;
732                 break;
733             }
734         }
735     } else {
736         for (count = 0; COND(c[algindex][testnum]); count++) {
737             if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
738                     NULL)) {
739                 count = -1;
740                 break;
741             }
742         }
743     }
744 out:
745     EVP_MD_free(md);
746     EVP_MD_CTX_free(ctx);
747     return count;
748 }
749 
750 static int EVP_Digest_md_loop(void *args)
751 {
752     return EVP_Digest_loop(evp_md_name, D_EVP, args);
753 }
754 
755 static int EVP_Digest_MD2_loop(void *args)
756 {
757     return EVP_Digest_loop("md2", D_MD2, args);
758 }
759 
760 static int EVP_Digest_MDC2_loop(void *args)
761 {
762     return EVP_Digest_loop("mdc2", D_MDC2, args);
763 }
764 
765 static int EVP_Digest_MD4_loop(void *args)
766 {
767     return EVP_Digest_loop("md4", D_MD4, args);
768 }
769 
770 static int MD5_loop(void *args)
771 {
772     return EVP_Digest_loop("md5", D_MD5, args);
773 }
774 
775 static int mac_setup(const char *name,
776     EVP_MAC **mac, OSSL_PARAM params[],
777     loopargs_t *loopargs, unsigned int loopargs_len)
778 {
779     unsigned int i;
780 
781     *mac = EVP_MAC_fetch(app_get0_libctx(), name, app_get0_propq());
782     if (*mac == NULL)
783         return 0;
784 
785     for (i = 0; i < loopargs_len; i++) {
786         loopargs[i].mctx = EVP_MAC_CTX_new(*mac);
787         if (loopargs[i].mctx == NULL)
788             return 0;
789 
790         if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
791             return 0;
792     }
793 
794     return 1;
795 }
796 
797 static void mac_teardown(EVP_MAC **mac,
798     loopargs_t *loopargs, unsigned int loopargs_len)
799 {
800     unsigned int i;
801 
802     for (i = 0; i < loopargs_len; i++)
803         EVP_MAC_CTX_free(loopargs[i].mctx);
804     EVP_MAC_free(*mac);
805     *mac = NULL;
806 
807     return;
808 }
809 
810 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
811 {
812     loopargs_t *tempargs = *(loopargs_t **)args;
813     unsigned char *buf = tempargs->buf;
814     EVP_MAC_CTX *mctx = tempargs->mctx;
815     unsigned char mac[EVP_MAX_MD_SIZE];
816     int count;
817 
818     for (count = 0; COND(c[algindex][testnum]); count++) {
819         size_t outl;
820 
821         if (!EVP_MAC_init(mctx, NULL, 0, NULL)
822             || !EVP_MAC_update(mctx, buf, lengths[testnum])
823             || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
824             return -1;
825     }
826     return count;
827 }
828 
829 static int HMAC_loop(void *args)
830 {
831     return EVP_MAC_loop(D_HMAC, args);
832 }
833 
834 static int CMAC_loop(void *args)
835 {
836     return EVP_MAC_loop(D_EVP_CMAC, args);
837 }
838 
839 static int KMAC128_loop(void *args)
840 {
841     return EVP_MAC_loop(D_KMAC128, args);
842 }
843 
844 static int KMAC256_loop(void *args)
845 {
846     return EVP_MAC_loop(D_KMAC256, args);
847 }
848 
849 static int SHA1_loop(void *args)
850 {
851     return EVP_Digest_loop("sha1", D_SHA1, args);
852 }
853 
854 static int SHA256_loop(void *args)
855 {
856     return EVP_Digest_loop("sha256", D_SHA256, args);
857 }
858 
859 static int SHA512_loop(void *args)
860 {
861     return EVP_Digest_loop("sha512", D_SHA512, args);
862 }
863 
864 static int WHIRLPOOL_loop(void *args)
865 {
866     return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
867 }
868 
869 static int EVP_Digest_RMD160_loop(void *args)
870 {
871     return EVP_Digest_loop("ripemd160", D_RMD160, args);
872 }
873 
874 static int algindex;
875 
876 static int EVP_Cipher_loop(void *args)
877 {
878     loopargs_t *tempargs = *(loopargs_t **)args;
879     unsigned char *buf = tempargs->buf;
880     int count;
881 
882     if (tempargs->ctx == NULL)
883         return -1;
884     for (count = 0; COND(c[algindex][testnum]); count++)
885         if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
886             return -1;
887     return count;
888 }
889 
890 static int GHASH_loop(void *args)
891 {
892     loopargs_t *tempargs = *(loopargs_t **)args;
893     unsigned char *buf = tempargs->buf;
894     EVP_MAC_CTX *mctx = tempargs->mctx;
895     int count;
896 
897     /* just do the update in the loop to be comparable with 1.1.1 */
898     for (count = 0; COND(c[D_GHASH][testnum]); count++) {
899         if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
900             return -1;
901     }
902     return count;
903 }
904 
905 #define MAX_BLOCK_SIZE 128
906 
907 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
908 
909 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
910     const unsigned char *key,
911     int keylen)
912 {
913     EVP_CIPHER_CTX *ctx = NULL;
914     EVP_CIPHER *cipher = NULL;
915 
916     if (!opt_cipher_silent(ciphername, &cipher))
917         return NULL;
918 
919     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
920         goto end;
921 
922     if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
923         EVP_CIPHER_CTX_free(ctx);
924         ctx = NULL;
925         goto end;
926     }
927 
928     if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) {
929         EVP_CIPHER_CTX_free(ctx);
930         ctx = NULL;
931         goto end;
932     }
933 
934     if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
935         EVP_CIPHER_CTX_free(ctx);
936         ctx = NULL;
937         goto end;
938     }
939 
940 end:
941     EVP_CIPHER_free(cipher);
942     return ctx;
943 }
944 
945 static int RAND_bytes_loop(void *args)
946 {
947     loopargs_t *tempargs = *(loopargs_t **)args;
948     unsigned char *buf = tempargs->buf;
949     int count;
950 
951     for (count = 0; COND(c[D_RAND][testnum]); count++)
952         RAND_bytes(buf, lengths[testnum]);
953     return count;
954 }
955 
956 static int decrypt = 0;
957 static int EVP_Update_loop(void *args)
958 {
959     loopargs_t *tempargs = *(loopargs_t **)args;
960     unsigned char *buf = tempargs->buf;
961     EVP_CIPHER_CTX *ctx = tempargs->ctx;
962     int outl, count, rc;
963 
964     if (decrypt) {
965         for (count = 0; COND(c[D_EVP][testnum]); count++) {
966             rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
967             if (rc != 1) {
968                 /* reset iv in case of counter overflow */
969                 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
970             }
971         }
972     } else {
973         for (count = 0; COND(c[D_EVP][testnum]); count++) {
974             rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
975             if (rc != 1) {
976                 /* reset iv in case of counter overflow */
977                 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
978             }
979         }
980     }
981     if (decrypt)
982         rc = EVP_DecryptFinal_ex(ctx, buf, &outl);
983     else
984         rc = EVP_EncryptFinal_ex(ctx, buf, &outl);
985 
986     if (rc == 0)
987         BIO_printf(bio_err, "Error finalizing cipher loop\n");
988     return count;
989 }
990 
991 /*
992  * To make AEAD benchmarking more relevant perform TLS-like operations,
993  * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
994  * payload length is not actually limited by 16KB...
995  * CCM does not support streaming. For the purpose of performance measurement,
996  * each message is encrypted using the same (key,iv)-pair. Do not use this
997  * code in your application.
998  */
999 static int EVP_Update_loop_aead_enc(void *args)
1000 {
1001     loopargs_t *tempargs = *(loopargs_t **)args;
1002     unsigned char *buf = tempargs->buf;
1003     unsigned char *key = tempargs->key;
1004     EVP_CIPHER_CTX *ctx = tempargs->ctx;
1005     int outl, count, realcount = 0;
1006 
1007     for (count = 0; COND(c[D_EVP][testnum]); count++) {
1008         /* Set length of iv (Doesn't apply to SIV mode) */
1009         if (mode_op != EVP_CIPH_SIV_MODE) {
1010             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
1011                     sizeof(aead_iv), NULL)) {
1012                 BIO_printf(bio_err, "\nFailed to set iv length\n");
1013                 dofail();
1014                 exit(1);
1015             }
1016         }
1017         /* Set tag_len (Not for GCM/SIV at encryption stage) */
1018         if (mode_op != EVP_CIPH_GCM_MODE
1019             && mode_op != EVP_CIPH_SIV_MODE
1020             && mode_op != EVP_CIPH_GCM_SIV_MODE) {
1021             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
1022                     TAG_LEN, NULL)) {
1023                 BIO_printf(bio_err, "\nFailed to set tag length\n");
1024                 dofail();
1025                 exit(1);
1026             }
1027         }
1028         if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, aead_iv, -1)) {
1029             BIO_printf(bio_err, "\nFailed to set key and iv\n");
1030             dofail();
1031             exit(1);
1032         }
1033         /* Set total length of input. Only required for CCM */
1034         if (mode_op == EVP_CIPH_CCM_MODE) {
1035             if (!EVP_EncryptUpdate(ctx, NULL, &outl,
1036                     NULL, lengths[testnum])) {
1037                 BIO_printf(bio_err, "\nCouldn't set input text length\n");
1038                 dofail();
1039                 exit(1);
1040             }
1041         }
1042         if (aead) {
1043             if (!EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad))) {
1044                 BIO_printf(bio_err, "\nCouldn't insert AAD when encrypting\n");
1045                 dofail();
1046                 exit(1);
1047             }
1048         }
1049         if (!EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum])) {
1050             BIO_printf(bio_err, "\nFailed to encrypt the data\n");
1051             dofail();
1052             exit(1);
1053         }
1054         if (EVP_EncryptFinal_ex(ctx, buf, &outl))
1055             realcount++;
1056     }
1057     return realcount;
1058 }
1059 
1060 /*
1061  * To make AEAD benchmarking more relevant perform TLS-like operations,
1062  * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
1063  * payload length is not actually limited by 16KB...
1064  * CCM does not support streaming. For the purpose of performance measurement,
1065  * each message is decrypted using the same (key,iv)-pair. Do not use this
1066  * code in your application.
1067  * For decryption, we will use buf2 to preserve the input text in buf.
1068  */
1069 static int EVP_Update_loop_aead_dec(void *args)
1070 {
1071     loopargs_t *tempargs = *(loopargs_t **)args;
1072     unsigned char *buf = tempargs->buf;
1073     unsigned char *outbuf = tempargs->buf2;
1074     unsigned char *key = tempargs->key;
1075     unsigned char tag[TAG_LEN];
1076     EVP_CIPHER_CTX *ctx = tempargs->ctx;
1077     int outl, count, realcount = 0;
1078 
1079     for (count = 0; COND(c[D_EVP][testnum]); count++) {
1080         /* Set the length of iv (Doesn't apply to SIV mode) */
1081         if (mode_op != EVP_CIPH_SIV_MODE) {
1082             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN,
1083                     sizeof(aead_iv), NULL)) {
1084                 BIO_printf(bio_err, "\nFailed to set iv length\n");
1085                 dofail();
1086                 exit(1);
1087             }
1088         }
1089 
1090         /* Set the tag length (Doesn't apply to SIV mode) */
1091         if (mode_op != EVP_CIPH_SIV_MODE
1092             && mode_op != EVP_CIPH_GCM_MODE
1093             && mode_op != EVP_CIPH_GCM_SIV_MODE) {
1094             if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
1095                     TAG_LEN, NULL)) {
1096                 BIO_printf(bio_err, "\nFailed to set tag length\n");
1097                 dofail();
1098                 exit(1);
1099             }
1100         }
1101         if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, aead_iv, -1)) {
1102             BIO_printf(bio_err, "\nFailed to set key and iv\n");
1103             dofail();
1104             exit(1);
1105         }
1106         /* Set iv before decryption (Doesn't apply to SIV mode) */
1107         if (mode_op != EVP_CIPH_SIV_MODE) {
1108             if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, aead_iv)) {
1109                 BIO_printf(bio_err, "\nFailed to set iv\n");
1110                 dofail();
1111                 exit(1);
1112             }
1113         }
1114         memcpy(tag, tempargs->tag, TAG_LEN);
1115 
1116         if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
1117                 TAG_LEN, tag)) {
1118             BIO_printf(bio_err, "\nFailed to set tag\n");
1119             dofail();
1120             exit(1);
1121         }
1122         /* Set the total length of cipher text. Only required for CCM */
1123         if (mode_op == EVP_CIPH_CCM_MODE) {
1124             if (!EVP_DecryptUpdate(ctx, NULL, &outl,
1125                     NULL, lengths[testnum])) {
1126                 BIO_printf(bio_err, "\nCouldn't set cipher text length\n");
1127                 dofail();
1128                 exit(1);
1129             }
1130         }
1131         if (aead) {
1132             if (!EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad))) {
1133                 BIO_printf(bio_err, "\nCouldn't insert AAD when decrypting\n");
1134                 dofail();
1135                 exit(1);
1136             }
1137         }
1138         if (!EVP_DecryptUpdate(ctx, outbuf, &outl, buf, lengths[testnum])) {
1139             BIO_printf(bio_err, "\nFailed to decrypt the data\n");
1140             dofail();
1141             exit(1);
1142         }
1143         if (EVP_DecryptFinal_ex(ctx, outbuf, &outl))
1144             realcount++;
1145     }
1146     return realcount;
1147 }
1148 
1149 static int RSA_sign_loop(void *args)
1150 {
1151     loopargs_t *tempargs = *(loopargs_t **)args;
1152     unsigned char *buf = tempargs->buf;
1153     unsigned char *buf2 = tempargs->buf2;
1154     size_t *rsa_num = &tempargs->sigsize;
1155     EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
1156     int ret, count;
1157 
1158     for (count = 0; COND(rsa_c[testnum][0]); count++) {
1159         *rsa_num = tempargs->buflen;
1160         ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
1161         if (ret <= 0) {
1162             BIO_printf(bio_err, "RSA sign failure\n");
1163             dofail();
1164             count = -1;
1165             break;
1166         }
1167     }
1168     return count;
1169 }
1170 
1171 static int RSA_verify_loop(void *args)
1172 {
1173     loopargs_t *tempargs = *(loopargs_t **)args;
1174     unsigned char *buf = tempargs->buf;
1175     unsigned char *buf2 = tempargs->buf2;
1176     size_t rsa_num = tempargs->sigsize;
1177     EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
1178     int ret, count;
1179 
1180     for (count = 0; COND(rsa_c[testnum][1]); count++) {
1181         ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
1182         if (ret <= 0) {
1183             BIO_printf(bio_err, "RSA verify failure\n");
1184             dofail();
1185             count = -1;
1186             break;
1187         }
1188     }
1189     return count;
1190 }
1191 
1192 static int RSA_encrypt_loop(void *args)
1193 {
1194     loopargs_t *tempargs = *(loopargs_t **)args;
1195     unsigned char *buf = tempargs->buf;
1196     unsigned char *buf2 = tempargs->buf2;
1197     size_t *rsa_num = &tempargs->encsize;
1198     EVP_PKEY_CTX **rsa_encrypt_ctx = tempargs->rsa_encrypt_ctx;
1199     int ret, count;
1200 
1201     for (count = 0; COND(rsa_c[testnum][2]); count++) {
1202         *rsa_num = tempargs->buflen;
1203         ret = EVP_PKEY_encrypt(rsa_encrypt_ctx[testnum], buf2, rsa_num, buf, 36);
1204         if (ret <= 0) {
1205             BIO_printf(bio_err, "RSA encrypt failure\n");
1206             dofail();
1207             count = -1;
1208             break;
1209         }
1210     }
1211     return count;
1212 }
1213 
1214 static int RSA_decrypt_loop(void *args)
1215 {
1216     loopargs_t *tempargs = *(loopargs_t **)args;
1217     unsigned char *buf = tempargs->buf;
1218     unsigned char *buf2 = tempargs->buf2;
1219     size_t rsa_num;
1220     EVP_PKEY_CTX **rsa_decrypt_ctx = tempargs->rsa_decrypt_ctx;
1221     int ret, count;
1222 
1223     for (count = 0; COND(rsa_c[testnum][3]); count++) {
1224         rsa_num = tempargs->buflen;
1225         ret = EVP_PKEY_decrypt(rsa_decrypt_ctx[testnum], buf, &rsa_num, buf2, tempargs->encsize);
1226         if (ret <= 0) {
1227             BIO_printf(bio_err, "RSA decrypt failure\n");
1228             dofail();
1229             count = -1;
1230             break;
1231         }
1232     }
1233     return count;
1234 }
1235 
1236 #ifndef OPENSSL_NO_DH
1237 
1238 static int FFDH_derive_key_loop(void *args)
1239 {
1240     loopargs_t *tempargs = *(loopargs_t **)args;
1241     EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
1242     unsigned char *derived_secret = tempargs->secret_ff_a;
1243     int count;
1244 
1245     for (count = 0; COND(ffdh_c[testnum][0]); count++) {
1246         /* outlen can be overwritten with a too small value (no padding used) */
1247         size_t outlen = MAX_FFDH_SIZE;
1248 
1249         EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
1250     }
1251     return count;
1252 }
1253 #endif /* OPENSSL_NO_DH */
1254 
1255 #ifndef OPENSSL_NO_DSA
1256 static int DSA_sign_loop(void *args)
1257 {
1258     loopargs_t *tempargs = *(loopargs_t **)args;
1259     unsigned char *buf = tempargs->buf;
1260     unsigned char *buf2 = tempargs->buf2;
1261     size_t *dsa_num = &tempargs->sigsize;
1262     EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
1263     int ret, count;
1264 
1265     for (count = 0; COND(dsa_c[testnum][0]); count++) {
1266         *dsa_num = tempargs->buflen;
1267         ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
1268         if (ret <= 0) {
1269             BIO_printf(bio_err, "DSA sign failure\n");
1270             dofail();
1271             count = -1;
1272             break;
1273         }
1274     }
1275     return count;
1276 }
1277 
1278 static int DSA_verify_loop(void *args)
1279 {
1280     loopargs_t *tempargs = *(loopargs_t **)args;
1281     unsigned char *buf = tempargs->buf;
1282     unsigned char *buf2 = tempargs->buf2;
1283     size_t dsa_num = tempargs->sigsize;
1284     EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
1285     int ret, count;
1286 
1287     for (count = 0; COND(dsa_c[testnum][1]); count++) {
1288         ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
1289         if (ret <= 0) {
1290             BIO_printf(bio_err, "DSA verify failure\n");
1291             dofail();
1292             count = -1;
1293             break;
1294         }
1295     }
1296     return count;
1297 }
1298 #endif /* OPENSSL_NO_DSA */
1299 
1300 static int ECDSA_sign_loop(void *args)
1301 {
1302     loopargs_t *tempargs = *(loopargs_t **)args;
1303     unsigned char *buf = tempargs->buf;
1304     unsigned char *buf2 = tempargs->buf2;
1305     size_t *ecdsa_num = &tempargs->sigsize;
1306     EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
1307     int ret, count;
1308 
1309     for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
1310         *ecdsa_num = tempargs->buflen;
1311         ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
1312         if (ret <= 0) {
1313             BIO_printf(bio_err, "ECDSA sign failure\n");
1314             dofail();
1315             count = -1;
1316             break;
1317         }
1318     }
1319     return count;
1320 }
1321 
1322 static int ECDSA_verify_loop(void *args)
1323 {
1324     loopargs_t *tempargs = *(loopargs_t **)args;
1325     unsigned char *buf = tempargs->buf;
1326     unsigned char *buf2 = tempargs->buf2;
1327     size_t ecdsa_num = tempargs->sigsize;
1328     EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
1329     int ret, count;
1330 
1331     for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
1332         ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
1333             buf, 20);
1334         if (ret <= 0) {
1335             BIO_printf(bio_err, "ECDSA verify failure\n");
1336             dofail();
1337             count = -1;
1338             break;
1339         }
1340     }
1341     return count;
1342 }
1343 
1344 /* ******************************************************************** */
1345 
1346 static int ECDH_EVP_derive_key_loop(void *args)
1347 {
1348     loopargs_t *tempargs = *(loopargs_t **)args;
1349     EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
1350     unsigned char *derived_secret = tempargs->secret_a;
1351     int count;
1352     size_t *outlen = &(tempargs->outlen[testnum]);
1353 
1354     for (count = 0; COND(ecdh_c[testnum][0]); count++)
1355         EVP_PKEY_derive(ctx, derived_secret, outlen);
1356 
1357     return count;
1358 }
1359 
1360 #ifndef OPENSSL_NO_ECX
1361 static int EdDSA_sign_loop(void *args)
1362 {
1363     loopargs_t *tempargs = *(loopargs_t **)args;
1364     unsigned char *buf = tempargs->buf;
1365     EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1366     unsigned char *eddsasig = tempargs->buf2;
1367     size_t *eddsasigsize = &tempargs->sigsize;
1368     int ret, count;
1369 
1370     for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1371         ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
1372         if (ret == 0) {
1373             BIO_printf(bio_err, "EdDSA sign init failure\n");
1374             dofail();
1375             count = -1;
1376             break;
1377         }
1378         ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1379         if (ret == 0) {
1380             BIO_printf(bio_err, "EdDSA sign failure\n");
1381             dofail();
1382             count = -1;
1383             break;
1384         }
1385     }
1386     return count;
1387 }
1388 
1389 static int EdDSA_verify_loop(void *args)
1390 {
1391     loopargs_t *tempargs = *(loopargs_t **)args;
1392     unsigned char *buf = tempargs->buf;
1393     EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1394     unsigned char *eddsasig = tempargs->buf2;
1395     size_t eddsasigsize = tempargs->sigsize;
1396     int ret, count;
1397 
1398     for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1399         ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
1400         if (ret == 0) {
1401             BIO_printf(bio_err, "EdDSA verify init failure\n");
1402             dofail();
1403             count = -1;
1404             break;
1405         }
1406         ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1407         if (ret != 1) {
1408             BIO_printf(bio_err, "EdDSA verify failure\n");
1409             dofail();
1410             count = -1;
1411             break;
1412         }
1413     }
1414     return count;
1415 }
1416 #endif /* OPENSSL_NO_ECX */
1417 
1418 #ifndef OPENSSL_NO_SM2
1419 static int SM2_sign_loop(void *args)
1420 {
1421     loopargs_t *tempargs = *(loopargs_t **)args;
1422     unsigned char *buf = tempargs->buf;
1423     EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1424     unsigned char *sm2sig = tempargs->buf2;
1425     size_t sm2sigsize;
1426     int ret, count;
1427     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1428     const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1429 
1430     for (count = 0; COND(sm2_c[testnum][0]); count++) {
1431         sm2sigsize = max_size;
1432 
1433         if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1434                 NULL, sm2_pkey[testnum])) {
1435             BIO_printf(bio_err, "SM2 init sign failure\n");
1436             dofail();
1437             count = -1;
1438             break;
1439         }
1440         ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1441             buf, 20);
1442         if (ret == 0) {
1443             BIO_printf(bio_err, "SM2 sign failure\n");
1444             dofail();
1445             count = -1;
1446             break;
1447         }
1448         /* update the latest returned size and always use the fixed buffer size */
1449         tempargs->sigsize = sm2sigsize;
1450     }
1451 
1452     return count;
1453 }
1454 
1455 static int SM2_verify_loop(void *args)
1456 {
1457     loopargs_t *tempargs = *(loopargs_t **)args;
1458     unsigned char *buf = tempargs->buf;
1459     EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1460     unsigned char *sm2sig = tempargs->buf2;
1461     size_t sm2sigsize = tempargs->sigsize;
1462     int ret, count;
1463     EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1464 
1465     for (count = 0; COND(sm2_c[testnum][1]); count++) {
1466         if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1467                 NULL, sm2_pkey[testnum])) {
1468             BIO_printf(bio_err, "SM2 verify init failure\n");
1469             dofail();
1470             count = -1;
1471             break;
1472         }
1473         ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1474             buf, 20);
1475         if (ret != 1) {
1476             BIO_printf(bio_err, "SM2 verify failure\n");
1477             dofail();
1478             count = -1;
1479             break;
1480         }
1481     }
1482     return count;
1483 }
1484 #endif /* OPENSSL_NO_SM2 */
1485 
1486 static int KEM_keygen_loop(void *args)
1487 {
1488     loopargs_t *tempargs = *(loopargs_t **)args;
1489     EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum];
1490     EVP_PKEY *pkey = NULL;
1491     int count;
1492 
1493     for (count = 0; COND(kems_c[testnum][0]); count++) {
1494         if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
1495             return -1;
1496         /*
1497          * runtime defined to quite some degree by randomness,
1498          * so performance overhead of _free doesn't impact
1499          * results significantly. In any case this test is
1500          * meant to permit relative algorithm performance
1501          * comparison.
1502          */
1503         EVP_PKEY_free(pkey);
1504         pkey = NULL;
1505     }
1506     return count;
1507 }
1508 
1509 static int KEM_encaps_loop(void *args)
1510 {
1511     loopargs_t *tempargs = *(loopargs_t **)args;
1512     EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum];
1513     size_t out_len = tempargs->kem_out_len[testnum];
1514     size_t secret_len = tempargs->kem_secret_len[testnum];
1515     unsigned char *out = tempargs->kem_out[testnum];
1516     unsigned char *secret = tempargs->kem_send_secret[testnum];
1517     int count;
1518 
1519     for (count = 0; COND(kems_c[testnum][1]); count++) {
1520         if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0)
1521             return -1;
1522     }
1523     return count;
1524 }
1525 
1526 static int KEM_decaps_loop(void *args)
1527 {
1528     loopargs_t *tempargs = *(loopargs_t **)args;
1529     EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum];
1530     size_t out_len = tempargs->kem_out_len[testnum];
1531     size_t secret_len = tempargs->kem_secret_len[testnum];
1532     unsigned char *out = tempargs->kem_out[testnum];
1533     unsigned char *secret = tempargs->kem_send_secret[testnum];
1534     int count;
1535 
1536     for (count = 0; COND(kems_c[testnum][2]); count++) {
1537         if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0)
1538             return -1;
1539     }
1540     return count;
1541 }
1542 
1543 static int SIG_keygen_loop(void *args)
1544 {
1545     loopargs_t *tempargs = *(loopargs_t **)args;
1546     EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum];
1547     EVP_PKEY *pkey = NULL;
1548     int count;
1549 
1550     for (count = 0; COND(kems_c[testnum][0]); count++) {
1551         EVP_PKEY_keygen(ctx, &pkey);
1552         /* TBD: How much does free influence runtime? */
1553         EVP_PKEY_free(pkey);
1554         pkey = NULL;
1555     }
1556     return count;
1557 }
1558 
1559 static int SIG_sign_loop(void *args)
1560 {
1561     loopargs_t *tempargs = *(loopargs_t **)args;
1562     EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum];
1563     /* be sure to not change stored sig: */
1564     unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum],
1565         "sig sign loop");
1566     unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1567     size_t md_len = SHA256_DIGEST_LENGTH;
1568     int count;
1569 
1570     for (count = 0; COND(kems_c[testnum][1]); count++) {
1571         size_t sig_len = tempargs->sig_max_sig_len[testnum];
1572         int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len);
1573 
1574         if (ret <= 0) {
1575             BIO_printf(bio_err, "SIG sign failure at count %d\n", count);
1576             dofail();
1577             count = -1;
1578             break;
1579         }
1580     }
1581     OPENSSL_free(sig);
1582     return count;
1583 }
1584 
1585 static int SIG_verify_loop(void *args)
1586 {
1587     loopargs_t *tempargs = *(loopargs_t **)args;
1588     EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum];
1589     size_t sig_len = tempargs->sig_act_sig_len[testnum];
1590     unsigned char *sig = tempargs->sig_sig[testnum];
1591     unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1592     size_t md_len = SHA256_DIGEST_LENGTH;
1593     int count;
1594 
1595     for (count = 0; COND(kems_c[testnum][2]); count++) {
1596         int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len);
1597 
1598         if (ret <= 0) {
1599             BIO_printf(bio_err, "SIG verify failure at count %d\n", count);
1600             dofail();
1601             count = -1;
1602             break;
1603         }
1604     }
1605     return count;
1606 }
1607 
1608 static int check_block_size(EVP_CIPHER_CTX *ctx, int length)
1609 {
1610     const EVP_CIPHER *ciph = EVP_CIPHER_CTX_get0_cipher(ctx);
1611     int blocksize = EVP_CIPHER_CTX_get_block_size(ctx);
1612 
1613     if (ciph == NULL || blocksize <= 0) {
1614         BIO_printf(bio_err, "\nInvalid cipher!\n");
1615         return 0;
1616     }
1617     if (length % blocksize != 0) {
1618         BIO_printf(bio_err,
1619             "\nRequested encryption length not a multiple of block size for %s!\n",
1620             EVP_CIPHER_get0_name(ciph));
1621         return 0;
1622     }
1623     return 1;
1624 }
1625 
1626 static int run_benchmark(int async_jobs,
1627     int (*loop_function)(void *), loopargs_t *loopargs)
1628 {
1629     int job_op_count = 0;
1630     int total_op_count = 0;
1631     int num_inprogress = 0;
1632     int error = 0, i = 0, ret = 0;
1633     OSSL_ASYNC_FD job_fd = 0;
1634     size_t num_job_fds = 0;
1635 
1636     if (async_jobs == 0) {
1637         return loop_function((void *)&loopargs);
1638     }
1639 
1640     for (i = 0; i < async_jobs && !error; i++) {
1641         loopargs_t *looparg_item = loopargs + i;
1642 
1643         /* Copy pointer content (looparg_t item address) into async context */
1644         ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1645             &job_op_count, loop_function,
1646             (void *)&looparg_item, sizeof(looparg_item));
1647         switch (ret) {
1648         case ASYNC_PAUSE:
1649             ++num_inprogress;
1650             break;
1651         case ASYNC_FINISH:
1652             if (job_op_count == -1) {
1653                 error = 1;
1654             } else {
1655                 total_op_count += job_op_count;
1656             }
1657             break;
1658         case ASYNC_NO_JOBS:
1659         case ASYNC_ERR:
1660             BIO_printf(bio_err, "Failure in the job\n");
1661             dofail();
1662             error = 1;
1663             break;
1664         }
1665     }
1666 
1667     while (num_inprogress > 0) {
1668 #if defined(OPENSSL_SYS_WINDOWS)
1669         DWORD avail = 0;
1670 #elif defined(OPENSSL_SYS_UNIX)
1671         int select_result = 0;
1672         OSSL_ASYNC_FD max_fd = 0;
1673         fd_set waitfdset;
1674 
1675         FD_ZERO(&waitfdset);
1676 
1677         for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1678             if (loopargs[i].inprogress_job == NULL)
1679                 continue;
1680 
1681             if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
1682                 || num_job_fds > 1) {
1683                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1684                 dofail();
1685                 error = 1;
1686                 break;
1687             }
1688             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1689                 &num_job_fds);
1690             FD_SET(job_fd, &waitfdset);
1691             if (job_fd > max_fd)
1692                 max_fd = job_fd;
1693         }
1694 
1695         if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1696             BIO_printf(bio_err,
1697                 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1698                 "Decrease the value of async_jobs\n",
1699                 max_fd, FD_SETSIZE);
1700             dofail();
1701             error = 1;
1702             break;
1703         }
1704 
1705         select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1706         if (select_result == -1 && errno == EINTR)
1707             continue;
1708 
1709         if (select_result == -1) {
1710             BIO_printf(bio_err, "Failure in the select\n");
1711             dofail();
1712             error = 1;
1713             break;
1714         }
1715 
1716         if (select_result == 0)
1717             continue;
1718 #endif
1719 
1720         for (i = 0; i < async_jobs; i++) {
1721             if (loopargs[i].inprogress_job == NULL)
1722                 continue;
1723 
1724             if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
1725                 || num_job_fds > 1) {
1726                 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1727                 dofail();
1728                 error = 1;
1729                 break;
1730             }
1731             ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1732                 &num_job_fds);
1733 
1734 #if defined(OPENSSL_SYS_UNIX)
1735             if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1736                 continue;
1737 #elif defined(OPENSSL_SYS_WINDOWS)
1738             if (num_job_fds == 1
1739                 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1740                 && avail > 0)
1741                 continue;
1742 #endif
1743 
1744             ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1745                 loopargs[i].wait_ctx, &job_op_count,
1746                 loop_function, (void *)(loopargs + i),
1747                 sizeof(loopargs_t));
1748             switch (ret) {
1749             case ASYNC_PAUSE:
1750                 break;
1751             case ASYNC_FINISH:
1752                 if (job_op_count == -1) {
1753                     error = 1;
1754                 } else {
1755                     total_op_count += job_op_count;
1756                 }
1757                 --num_inprogress;
1758                 loopargs[i].inprogress_job = NULL;
1759                 break;
1760             case ASYNC_NO_JOBS:
1761             case ASYNC_ERR:
1762                 --num_inprogress;
1763                 loopargs[i].inprogress_job = NULL;
1764                 BIO_printf(bio_err, "Failure in the job\n");
1765                 dofail();
1766                 error = 1;
1767                 break;
1768             }
1769         }
1770     }
1771 
1772     return error ? -1 : total_op_count;
1773 }
1774 
1775 typedef struct ec_curve_st {
1776     const char *name;
1777     unsigned int nid;
1778     unsigned int bits;
1779     size_t sigsize; /* only used for EdDSA curves */
1780 } EC_CURVE;
1781 
1782 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1783 {
1784     EVP_PKEY_CTX *kctx = NULL;
1785     EVP_PKEY *key = NULL;
1786 
1787     /* Ensure that the error queue is empty */
1788     if (ERR_peek_error()) {
1789         BIO_printf(bio_err,
1790             "WARNING: the error queue contains previous unhandled errors.\n");
1791         dofail();
1792     }
1793 
1794     /*
1795      * Let's try to create a ctx directly from the NID: this works for
1796      * curves like Curve25519 that are not implemented through the low
1797      * level EC interface.
1798      * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1799      * then we set the curve by NID before deriving the actual keygen
1800      * ctx for that specific curve.
1801      */
1802     kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1803     if (kctx == NULL) {
1804         EVP_PKEY_CTX *pctx = NULL;
1805         EVP_PKEY *params = NULL;
1806         /*
1807          * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1808          * "int_ctx_new:unsupported algorithm" error was added to the
1809          * error queue.
1810          * We remove it from the error queue as we are handling it.
1811          */
1812         unsigned long error = ERR_peek_error();
1813 
1814         if (error == ERR_peek_last_error() /* oldest and latest errors match */
1815             /* check that the error origin matches */
1816             && ERR_GET_LIB(error) == ERR_LIB_EVP
1817             && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1818                 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1819             ERR_get_error(); /* pop error from queue */
1820         if (ERR_peek_error()) {
1821             BIO_printf(bio_err,
1822                 "Unhandled error in the error queue during EC key setup.\n");
1823             dofail();
1824             return NULL;
1825         }
1826 
1827         /* Create the context for parameter generation */
1828         if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1829             || EVP_PKEY_paramgen_init(pctx) <= 0
1830             || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1831                    curve->nid)
1832                 <= 0
1833             || EVP_PKEY_paramgen(pctx, &params) <= 0) {
1834             BIO_printf(bio_err, "EC params init failure.\n");
1835             dofail();
1836             EVP_PKEY_CTX_free(pctx);
1837             return NULL;
1838         }
1839         EVP_PKEY_CTX_free(pctx);
1840 
1841         /* Create the context for the key generation */
1842         kctx = EVP_PKEY_CTX_new(params, NULL);
1843         EVP_PKEY_free(params);
1844     }
1845     if (kctx == NULL
1846         || EVP_PKEY_keygen_init(kctx) <= 0
1847         || EVP_PKEY_keygen(kctx, &key) <= 0) {
1848         BIO_printf(bio_err, "EC key generation failure.\n");
1849         dofail();
1850         key = NULL;
1851     }
1852     EVP_PKEY_CTX_free(kctx);
1853     return key;
1854 }
1855 
1856 #define stop_it(do_it, test_num) \
1857     memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1858 
1859 /* Checks to see if algorithms are fetchable */
1860 #define IS_FETCHABLE(type, TYPE)                      \
1861     static int is_##type##_fetchable(const TYPE *alg) \
1862     {                                                 \
1863         TYPE *impl;                                   \
1864         const char *propq = app_get0_propq();         \
1865         OSSL_LIB_CTX *libctx = app_get0_libctx();     \
1866         const char *name = TYPE##_get0_name(alg);     \
1867                                                       \
1868         ERR_set_mark();                               \
1869         impl = TYPE##_fetch(libctx, name, propq);     \
1870         ERR_pop_to_mark();                            \
1871         if (impl == NULL)                             \
1872             return 0;                                 \
1873         TYPE##_free(impl);                            \
1874         return 1;                                     \
1875     }
1876 
1877 IS_FETCHABLE(signature, EVP_SIGNATURE)
1878 IS_FETCHABLE(kem, EVP_KEM)
1879 
1880 DEFINE_STACK_OF(EVP_KEM)
1881 
1882 static int kems_cmp(const EVP_KEM *const *a,
1883     const EVP_KEM *const *b)
1884 {
1885     return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
1886         OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
1887 }
1888 
1889 static void collect_kem(EVP_KEM *kem, void *stack)
1890 {
1891     STACK_OF(EVP_KEM) *kem_stack = stack;
1892 
1893     if (is_kem_fetchable(kem)
1894         && EVP_KEM_up_ref(kem)
1895         && sk_EVP_KEM_push(kem_stack, kem) <= 0)
1896         EVP_KEM_free(kem); /* up-ref successful but push to stack failed */
1897 }
1898 
1899 static int kem_locate(const char *algo, unsigned int *idx)
1900 {
1901     unsigned int i;
1902 
1903     for (i = 0; i < kems_algs_len; i++) {
1904         if (strcmp(kems_algname[i], algo) == 0) {
1905             *idx = i;
1906             return 1;
1907         }
1908     }
1909     return 0;
1910 }
1911 
1912 DEFINE_STACK_OF(EVP_SIGNATURE)
1913 
1914 static int signatures_cmp(const EVP_SIGNATURE *const *a,
1915     const EVP_SIGNATURE *const *b)
1916 {
1917     return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
1918         OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
1919 }
1920 
1921 static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
1922 {
1923     STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
1924 
1925     if (is_signature_fetchable(sig)
1926         && EVP_SIGNATURE_up_ref(sig)
1927         && sk_EVP_SIGNATURE_push(sig_stack, sig) <= 0)
1928         EVP_SIGNATURE_free(sig); /* up-ref successful but push to stack failed */
1929 }
1930 
1931 static int sig_locate(const char *algo, unsigned int *idx)
1932 {
1933     unsigned int i;
1934 
1935     for (i = 0; i < sigs_algs_len; i++) {
1936         if (strcmp(sigs_algname[i], algo) == 0) {
1937             *idx = i;
1938             return 1;
1939         }
1940     }
1941     return 0;
1942 }
1943 
1944 static int get_max(const uint8_t doit[], size_t algs_len)
1945 {
1946     size_t i = 0;
1947     int maxcnt = 0;
1948 
1949     for (i = 0; i < algs_len; i++)
1950         if (maxcnt < doit[i])
1951             maxcnt = doit[i];
1952     return maxcnt;
1953 }
1954 
1955 int speed_main(int argc, char **argv)
1956 {
1957     CONF *conf = NULL;
1958     ENGINE *e = NULL;
1959     loopargs_t *loopargs = NULL;
1960     const char *prog;
1961     const char *engine_id = NULL;
1962     EVP_CIPHER *evp_cipher = NULL;
1963     EVP_MAC *mac = NULL;
1964     double d = 0.0;
1965     OPTION_CHOICE o;
1966     int async_init = 0, multiblock = 0, pr_header = 0;
1967     uint8_t doit[ALGOR_NUM] = { 0 };
1968     int ret = 1, misalign = 0, lengths_single = 0;
1969     STACK_OF(EVP_KEM) *kem_stack = NULL;
1970     STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
1971     long count = 0;
1972     unsigned int size_num = SIZE_NUM;
1973     unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1974     unsigned int idx;
1975     int keylen = 0;
1976     int buflen;
1977     size_t declen;
1978     BIGNUM *bn = NULL;
1979     EVP_PKEY_CTX *genctx = NULL;
1980 #ifndef NO_FORK
1981     int multi = 0;
1982 #endif
1983     long op_count = 1;
1984     openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1985         ECDSA_SECONDS, ECDH_SECONDS,
1986         EdDSA_SECONDS, SM2_SECONDS,
1987         FFDH_SECONDS, KEM_SECONDS,
1988         SIG_SECONDS };
1989 
1990     static const unsigned char key32[32] = {
1991         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1992         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1993         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1994         0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1995     };
1996     static const unsigned char deskey[] = {
1997         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1998         0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1999         0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
2000     };
2001     static const struct {
2002         const unsigned char *data;
2003         unsigned int length;
2004         unsigned int bits;
2005     } rsa_keys[] = {
2006         { test512, sizeof(test512), 512 },
2007         { test1024, sizeof(test1024), 1024 },
2008         { test2048, sizeof(test2048), 2048 },
2009         { test3072, sizeof(test3072), 3072 },
2010         { test4096, sizeof(test4096), 4096 },
2011         { test7680, sizeof(test7680), 7680 },
2012         { test15360, sizeof(test15360), 15360 }
2013     };
2014     uint8_t rsa_doit[RSA_NUM] = { 0 };
2015     int primes = RSA_DEFAULT_PRIME_NUM;
2016 #ifndef OPENSSL_NO_DH
2017     typedef struct ffdh_params_st {
2018         const char *name;
2019         unsigned int nid;
2020         unsigned int bits;
2021     } FFDH_PARAMS;
2022 
2023     static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
2024         { "ffdh2048", NID_ffdhe2048, 2048 },
2025         { "ffdh3072", NID_ffdhe3072, 3072 },
2026         { "ffdh4096", NID_ffdhe4096, 4096 },
2027         { "ffdh6144", NID_ffdhe6144, 6144 },
2028         { "ffdh8192", NID_ffdhe8192, 8192 }
2029     };
2030     uint8_t ffdh_doit[FFDH_NUM] = { 0 };
2031 
2032 #endif /* OPENSSL_NO_DH */
2033 #ifndef OPENSSL_NO_DSA
2034     static const unsigned int dsa_bits[DSA_NUM] = { 1024, 2048 };
2035     uint8_t dsa_doit[DSA_NUM] = { 0 };
2036 #endif /* OPENSSL_NO_DSA */
2037     /*
2038      * We only test over the following curves as they are representative, To
2039      * add tests over more curves, simply add the curve NID and curve name to
2040      * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
2041      * lists accordingly.
2042      */
2043     static const EC_CURVE ec_curves[EC_NUM] = {
2044         /* Prime Curves */
2045         { "secp160r1", NID_secp160r1, 160 },
2046         { "nistp192", NID_X9_62_prime192v1, 192 },
2047         { "nistp224", NID_secp224r1, 224 },
2048         { "nistp256", NID_X9_62_prime256v1, 256 },
2049         { "nistp384", NID_secp384r1, 384 },
2050         { "nistp521", NID_secp521r1, 521 },
2051 #ifndef OPENSSL_NO_EC2M
2052         /* Binary Curves */
2053         { "nistk163", NID_sect163k1, 163 },
2054         { "nistk233", NID_sect233k1, 233 },
2055         { "nistk283", NID_sect283k1, 283 },
2056         { "nistk409", NID_sect409k1, 409 },
2057         { "nistk571", NID_sect571k1, 571 },
2058         { "nistb163", NID_sect163r2, 163 },
2059         { "nistb233", NID_sect233r1, 233 },
2060         { "nistb283", NID_sect283r1, 283 },
2061         { "nistb409", NID_sect409r1, 409 },
2062         { "nistb571", NID_sect571r1, 571 },
2063 #endif
2064         { "brainpoolP256r1", NID_brainpoolP256r1, 256 },
2065         { "brainpoolP256t1", NID_brainpoolP256t1, 256 },
2066         { "brainpoolP384r1", NID_brainpoolP384r1, 384 },
2067         { "brainpoolP384t1", NID_brainpoolP384t1, 384 },
2068         { "brainpoolP512r1", NID_brainpoolP512r1, 512 },
2069         { "brainpoolP512t1", NID_brainpoolP512t1, 512 },
2070 #ifndef OPENSSL_NO_ECX
2071         /* Other and ECDH only ones */
2072         { "X25519", NID_X25519, 253 },
2073         { "X448", NID_X448, 448 }
2074 #endif
2075     };
2076 #ifndef OPENSSL_NO_ECX
2077     static const EC_CURVE ed_curves[EdDSA_NUM] = {
2078         /* EdDSA */
2079         { "Ed25519", NID_ED25519, 253, 64 },
2080         { "Ed448", NID_ED448, 456, 114 }
2081     };
2082 #endif /* OPENSSL_NO_ECX */
2083 #ifndef OPENSSL_NO_SM2
2084     static const EC_CURVE sm2_curves[SM2_NUM] = {
2085         /* SM2 */
2086         { "CurveSM2", NID_sm2, 256 }
2087     };
2088     uint8_t sm2_doit[SM2_NUM] = { 0 };
2089 #endif
2090     uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
2091     uint8_t ecdh_doit[EC_NUM] = { 0 };
2092 #ifndef OPENSSL_NO_ECX
2093     uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
2094 #endif /* OPENSSL_NO_ECX */
2095 
2096     uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
2097     uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
2098 
2099     uint8_t do_kems = 0;
2100     uint8_t do_sigs = 0;
2101 
2102     /* checks declared curves against choices list. */
2103 #ifndef OPENSSL_NO_ECX
2104     OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
2105     OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
2106 
2107     OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
2108     OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
2109 
2110     OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
2111     OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
2112 #endif /* OPENSSL_NO_ECX */
2113 
2114 #ifndef OPENSSL_NO_SM2
2115     OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
2116     OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
2117 #endif
2118 
2119     prog = opt_init(argc, argv, speed_options);
2120     while ((o = opt_next()) != OPT_EOF) {
2121         switch (o) {
2122         case OPT_EOF:
2123         case OPT_ERR:
2124         opterr:
2125             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
2126             goto end;
2127         case OPT_HELP:
2128             opt_help(speed_options);
2129             ret = 0;
2130             goto end;
2131         case OPT_ELAPSED:
2132             usertime = 0;
2133             break;
2134         case OPT_EVP:
2135             if (doit[D_EVP]) {
2136                 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
2137                 goto opterr;
2138             }
2139             ERR_set_mark();
2140             if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
2141                 if (have_md(opt_arg()))
2142                     evp_md_name = opt_arg();
2143             }
2144             if (evp_cipher == NULL && evp_md_name == NULL) {
2145                 ERR_clear_last_mark();
2146                 BIO_printf(bio_err,
2147                     "%s: %s is an unknown cipher or digest\n",
2148                     prog, opt_arg());
2149                 goto end;
2150             }
2151             ERR_pop_to_mark();
2152             doit[D_EVP] = 1;
2153             break;
2154         case OPT_HMAC:
2155             if (!have_md(opt_arg())) {
2156                 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
2157                     prog, opt_arg());
2158                 goto end;
2159             }
2160             evp_mac_mdname = opt_arg();
2161             doit[D_HMAC] = 1;
2162             break;
2163         case OPT_CMAC:
2164             if (!have_cipher(opt_arg())) {
2165                 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
2166                     prog, opt_arg());
2167                 goto end;
2168             }
2169             evp_mac_ciphername = opt_arg();
2170             doit[D_EVP_CMAC] = 1;
2171             break;
2172         case OPT_DECRYPT:
2173             decrypt = 1;
2174             break;
2175         case OPT_ENGINE:
2176             /*
2177              * In a forked execution, an engine might need to be
2178              * initialised by each child process, not by the parent.
2179              * So store the name here and run setup_engine() later on.
2180              */
2181             engine_id = opt_arg();
2182             break;
2183         case OPT_MULTI:
2184 #ifndef NO_FORK
2185             multi = opt_int_arg();
2186             if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
2187                 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
2188                 return 0;
2189             }
2190 #endif
2191             break;
2192         case OPT_ASYNCJOBS:
2193 #ifndef OPENSSL_NO_ASYNC
2194             async_jobs = opt_int_arg();
2195             if (async_jobs > 99999) {
2196                 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
2197                 goto opterr;
2198             }
2199             if (!ASYNC_is_capable()) {
2200                 BIO_printf(bio_err,
2201                     "%s: async_jobs specified but async not supported\n",
2202                     prog);
2203                 if (testmode)
2204                     /* Return success in the testmode. */
2205                     return 0;
2206                 goto opterr;
2207             }
2208 #endif
2209             break;
2210         case OPT_MISALIGN:
2211             misalign = opt_int_arg();
2212             if (misalign > MISALIGN) {
2213                 BIO_printf(bio_err,
2214                     "%s: Maximum offset is %d\n", prog, MISALIGN);
2215                 goto opterr;
2216             }
2217             break;
2218         case OPT_MR:
2219             mr = 1;
2220             break;
2221         case OPT_MB:
2222             multiblock = 1;
2223 #ifdef OPENSSL_NO_MULTIBLOCK
2224             BIO_printf(bio_err,
2225                 "%s: -mb specified but multi-block support is disabled\n",
2226                 prog);
2227             goto end;
2228 #endif
2229             break;
2230         case OPT_R_CASES:
2231             if (!opt_rand(o))
2232                 goto end;
2233             break;
2234         case OPT_PROV_CASES:
2235             if (!opt_provider(o))
2236                 goto end;
2237             break;
2238         case OPT_CONFIG:
2239             conf = app_load_config_modules(opt_arg());
2240             if (conf == NULL)
2241                 goto end;
2242             break;
2243         case OPT_PRIMES:
2244             primes = opt_int_arg();
2245             break;
2246         case OPT_SECONDS:
2247             seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
2248                 = seconds.ecdh = seconds.eddsa
2249                 = seconds.sm2 = seconds.ffdh
2250                 = seconds.kem = seconds.sig = opt_int_arg();
2251             break;
2252         case OPT_BYTES:
2253             lengths_single = opt_int_arg();
2254             lengths = &lengths_single;
2255             size_num = 1;
2256             break;
2257         case OPT_AEAD:
2258             aead = 1;
2259             break;
2260         case OPT_KEM:
2261             do_kems = 1;
2262             break;
2263         case OPT_SIG:
2264             do_sigs = 1;
2265             break;
2266         case OPT_MLOCK:
2267             domlock = 1;
2268 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
2269             BIO_printf(bio_err,
2270                 "%s: -mlock not supported on this platform\n",
2271                 prog);
2272             goto end;
2273 #endif
2274             break;
2275         case OPT_TESTMODE:
2276             testmode = 1;
2277             break;
2278         }
2279     }
2280 
2281     /* find all KEMs currently available */
2282     kem_stack = sk_EVP_KEM_new(kems_cmp);
2283     EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
2284 
2285     kems_algs_len = 0;
2286 
2287     for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) {
2288         EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx);
2289 
2290         if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) {
2291             if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) {
2292                 BIO_printf(bio_err,
2293                     "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2294                 goto end;
2295             }
2296             for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2297                 kems_doit[kems_algs_len] = 1;
2298                 kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2299             }
2300         } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) {
2301             if (kems_algs_len + 3 >= MAX_KEM_NUM) {
2302                 BIO_printf(bio_err,
2303                     "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2304                 goto end;
2305             }
2306             kems_doit[kems_algs_len] = 1;
2307             kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256");
2308             kems_doit[kems_algs_len] = 1;
2309             kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384");
2310             kems_doit[kems_algs_len] = 1;
2311             kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521");
2312         } else {
2313             if (kems_algs_len + 1 >= MAX_KEM_NUM) {
2314                 BIO_printf(bio_err,
2315                     "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2316                 goto end;
2317             }
2318             kems_doit[kems_algs_len] = 1;
2319             kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem));
2320         }
2321     }
2322     sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
2323     kem_stack = NULL;
2324 
2325     /* find all SIGNATUREs currently available */
2326     sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp);
2327     EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack);
2328 
2329     sigs_algs_len = 0;
2330 
2331     for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) {
2332         EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx);
2333         const char *sig_name = EVP_SIGNATURE_get0_name(s);
2334 
2335         if (strcmp(sig_name, "RSA") == 0) {
2336             if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) {
2337                 BIO_printf(bio_err,
2338                     "Too many signatures registered. Change MAX_SIG_NUM.\n");
2339                 goto end;
2340             }
2341             for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2342                 sigs_doit[sigs_algs_len] = 1;
2343                 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2344             }
2345         }
2346 #ifndef OPENSSL_NO_DSA
2347         else if (strcmp(sig_name, "DSA") == 0) {
2348             if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) {
2349                 BIO_printf(bio_err,
2350                     "Too many signatures registered. Change MAX_SIG_NUM.\n");
2351                 goto end;
2352             }
2353             for (i = 0; i < DSA_NUM; i++) {
2354                 sigs_doit[sigs_algs_len] = 1;
2355                 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name);
2356             }
2357         }
2358 #endif /* OPENSSL_NO_DSA */
2359         /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2360         else if (strncmp(sig_name, "RSA", 3) && strncmp(sig_name, "DSA", 3) && strncmp(sig_name, "ED25519", 7) && strncmp(sig_name, "ED448", 5) && strncmp(sig_name, "ECDSA", 5) && strcmp(sig_name, "HMAC") && strcmp(sig_name, "SIPHASH") && strcmp(sig_name, "POLY1305") && strcmp(sig_name, "CMAC") && strcmp(sig_name, "SM2")) { /* skip alg */
2361             if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
2362                 BIO_printf(bio_err,
2363                     "Too many signatures registered. Change MAX_SIG_NUM.\n");
2364                 goto end;
2365             }
2366             /* activate this provider algorithm */
2367             sigs_doit[sigs_algs_len] = 1;
2368             sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name);
2369         }
2370     }
2371     sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
2372     sig_stack = NULL;
2373 
2374     /* Remaining arguments are algorithms. */
2375     argc = opt_num_rest();
2376     argv = opt_rest();
2377 
2378     if (!app_RAND_load())
2379         goto end;
2380 
2381     for (; *argv; argv++) {
2382         const char *algo = *argv;
2383         int algo_found = 0;
2384 
2385         if (opt_found(algo, doit_choices, &i)) {
2386             doit[i] = 1;
2387             algo_found = 1;
2388         }
2389         if (strcmp(algo, "des") == 0) {
2390             doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
2391             algo_found = 1;
2392         }
2393         if (strcmp(algo, "sha") == 0) {
2394             doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
2395             algo_found = 1;
2396         }
2397 #ifndef OPENSSL_NO_DEPRECATED_3_0
2398         if (strcmp(algo, "openssl") == 0) /* just for compatibility */
2399             algo_found = 1;
2400 #endif
2401         if (HAS_PREFIX(algo, "rsa")) {
2402             if (algo[sizeof("rsa") - 1] == '\0') {
2403                 memset(rsa_doit, 1, sizeof(rsa_doit));
2404                 algo_found = 1;
2405             }
2406             if (opt_found(algo, rsa_choices, &i)) {
2407                 rsa_doit[i] = 1;
2408                 algo_found = 1;
2409             }
2410         }
2411 #ifndef OPENSSL_NO_DH
2412         if (HAS_PREFIX(algo, "ffdh")) {
2413             if (algo[sizeof("ffdh") - 1] == '\0') {
2414                 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2415                 algo_found = 1;
2416             }
2417             if (opt_found(algo, ffdh_choices, &i)) {
2418                 ffdh_doit[i] = 2;
2419                 algo_found = 1;
2420             }
2421         }
2422 #endif
2423 #ifndef OPENSSL_NO_DSA
2424         if (HAS_PREFIX(algo, "dsa")) {
2425             if (algo[sizeof("dsa") - 1] == '\0') {
2426                 memset(dsa_doit, 1, sizeof(dsa_doit));
2427                 algo_found = 1;
2428             }
2429             if (opt_found(algo, dsa_choices, &i)) {
2430                 dsa_doit[i] = 2;
2431                 algo_found = 1;
2432             }
2433         }
2434 #endif
2435         if (strcmp(algo, "aes") == 0) {
2436             doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
2437             algo_found = 1;
2438         }
2439         if (strcmp(algo, "camellia") == 0) {
2440             doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
2441             algo_found = 1;
2442         }
2443         if (HAS_PREFIX(algo, "ecdsa")) {
2444             if (algo[sizeof("ecdsa") - 1] == '\0') {
2445                 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2446                 algo_found = 1;
2447             }
2448             if (opt_found(algo, ecdsa_choices, &i)) {
2449                 ecdsa_doit[i] = 2;
2450                 algo_found = 1;
2451             }
2452         }
2453         if (HAS_PREFIX(algo, "ecdh")) {
2454             if (algo[sizeof("ecdh") - 1] == '\0') {
2455                 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2456                 algo_found = 1;
2457             }
2458             if (opt_found(algo, ecdh_choices, &i)) {
2459                 ecdh_doit[i] = 2;
2460                 algo_found = 1;
2461             }
2462         }
2463 #ifndef OPENSSL_NO_ECX
2464         if (strcmp(algo, "eddsa") == 0) {
2465             memset(eddsa_doit, 1, sizeof(eddsa_doit));
2466             algo_found = 1;
2467         }
2468         if (opt_found(algo, eddsa_choices, &i)) {
2469             eddsa_doit[i] = 2;
2470             algo_found = 1;
2471         }
2472 #endif /* OPENSSL_NO_ECX */
2473 #ifndef OPENSSL_NO_SM2
2474         if (strcmp(algo, "sm2") == 0) {
2475             memset(sm2_doit, 1, sizeof(sm2_doit));
2476             algo_found = 1;
2477         }
2478         if (opt_found(algo, sm2_choices, &i)) {
2479             sm2_doit[i] = 2;
2480             algo_found = 1;
2481         }
2482 #endif
2483         if (kem_locate(algo, &idx)) {
2484             kems_doit[idx]++;
2485             do_kems = 1;
2486             algo_found = 1;
2487         }
2488         if (sig_locate(algo, &idx)) {
2489             sigs_doit[idx]++;
2490             do_sigs = 1;
2491             algo_found = 1;
2492         }
2493         if (strcmp(algo, "kmac") == 0) {
2494             doit[D_KMAC128] = doit[D_KMAC256] = 1;
2495             algo_found = 1;
2496         }
2497         if (strcmp(algo, "cmac") == 0) {
2498             doit[D_EVP_CMAC] = 1;
2499             algo_found = 1;
2500         }
2501 
2502         if (!algo_found) {
2503             BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
2504             goto end;
2505         }
2506     }
2507 
2508     /* Sanity checks */
2509     if (aead) {
2510         if (evp_cipher == NULL) {
2511             BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
2512             goto end;
2513         } else if (!(EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
2514             BIO_printf(bio_err, "%s is not an AEAD cipher\n",
2515                 EVP_CIPHER_get0_name(evp_cipher));
2516             goto end;
2517         }
2518     }
2519     if (kems_algs_len > 0) {
2520         int maxcnt = get_max(kems_doit, kems_algs_len);
2521 
2522         if (maxcnt > 1) {
2523             /* some algs explicitly selected */
2524             for (i = 0; i < kems_algs_len; i++) {
2525                 /* disable the rest */
2526                 kems_doit[i]--;
2527             }
2528         }
2529     }
2530     if (sigs_algs_len > 0) {
2531         int maxcnt = get_max(sigs_doit, sigs_algs_len);
2532 
2533         if (maxcnt > 1) {
2534             /* some algs explicitly selected */
2535             for (i = 0; i < sigs_algs_len; i++) {
2536                 /* disable the rest */
2537                 sigs_doit[i]--;
2538             }
2539         }
2540     }
2541     if (multiblock) {
2542         if (evp_cipher == NULL) {
2543             BIO_printf(bio_err, "-mb can be used only with a multi-block"
2544                                 " capable cipher\n");
2545             goto end;
2546         } else if (!(EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2547             BIO_printf(bio_err, "%s is not a multi-block capable\n",
2548                 EVP_CIPHER_get0_name(evp_cipher));
2549             goto end;
2550         } else if (async_jobs > 0) {
2551             BIO_printf(bio_err, "Async mode is not supported with -mb");
2552             goto end;
2553         }
2554     }
2555 
2556     /* Initialize the job pool if async mode is enabled */
2557     if (async_jobs > 0) {
2558         async_init = ASYNC_init_thread(async_jobs, async_jobs);
2559         if (!async_init) {
2560             BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
2561             goto end;
2562         }
2563     }
2564 
2565     loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
2566     loopargs = app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
2567     memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
2568 
2569     buflen = lengths[size_num - 1];
2570     if (buflen < 36) /* size of random vector in RSA benchmark */
2571         buflen = 36;
2572     if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
2573         BIO_printf(bio_err, "Error: buffer size too large\n");
2574         goto end;
2575     }
2576     buflen += MAX_MISALIGNMENT + 1;
2577     for (i = 0; i < loopargs_len; i++) {
2578         if (async_jobs > 0) {
2579             loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
2580             if (loopargs[i].wait_ctx == NULL) {
2581                 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
2582                 goto end;
2583             }
2584         }
2585 
2586         loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
2587         loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
2588 
2589         /* Align the start of buffers on a 64 byte boundary */
2590         loopargs[i].buf = loopargs[i].buf_malloc + misalign;
2591         loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
2592         loopargs[i].buflen = buflen - misalign;
2593         loopargs[i].sigsize = buflen - misalign;
2594         loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
2595         loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
2596 #ifndef OPENSSL_NO_DH
2597         loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
2598         loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
2599 #endif
2600     }
2601 
2602 #ifndef NO_FORK
2603     if (multi && do_multi(multi, size_num))
2604         goto show_res;
2605 #endif
2606 
2607     for (i = 0; i < loopargs_len; ++i) {
2608         if (domlock) {
2609 #if defined(_WIN32)
2610             (void)VirtualLock(loopargs[i].buf_malloc, buflen);
2611             (void)VirtualLock(loopargs[i].buf2_malloc, buflen);
2612 #elif defined(OPENSSL_SYS_LINUX)
2613             (void)mlock(loopargs[i].buf_malloc, buflen);
2614             (void)mlock(loopargs[i].buf_malloc, buflen);
2615 #endif
2616         }
2617         memset(loopargs[i].buf_malloc, 0, buflen);
2618         memset(loopargs[i].buf2_malloc, 0, buflen);
2619     }
2620 
2621     /* Initialize the engine after the fork */
2622     e = setup_engine(engine_id, 0);
2623 
2624     /* No parameters; turn on everything. */
2625     if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC]
2626         && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) {
2627         memset(doit, 1, sizeof(doit));
2628         doit[D_EVP] = doit[D_EVP_CMAC] = 0;
2629         ERR_set_mark();
2630         for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
2631             if (!have_md(names[i]))
2632                 doit[i] = 0;
2633         }
2634         for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
2635             if (!have_cipher(names[i]))
2636                 doit[i] = 0;
2637         }
2638         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2639                  app_get0_propq()))
2640             != NULL) {
2641             EVP_MAC_free(mac);
2642             mac = NULL;
2643         } else {
2644             doit[D_GHASH] = 0;
2645         }
2646         if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2647                  app_get0_propq()))
2648             != NULL) {
2649             EVP_MAC_free(mac);
2650             mac = NULL;
2651         } else {
2652             doit[D_HMAC] = 0;
2653         }
2654         ERR_pop_to_mark();
2655         memset(rsa_doit, 1, sizeof(rsa_doit));
2656 #ifndef OPENSSL_NO_DH
2657         memset(ffdh_doit, 1, sizeof(ffdh_doit));
2658 #endif
2659 #ifndef OPENSSL_NO_DSA
2660         memset(dsa_doit, 1, sizeof(dsa_doit));
2661 #endif
2662 #ifndef OPENSSL_NO_ECX
2663         memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2664         memset(ecdh_doit, 1, sizeof(ecdh_doit));
2665         memset(eddsa_doit, 1, sizeof(eddsa_doit));
2666 #endif /* OPENSSL_NO_ECX */
2667 #ifndef OPENSSL_NO_SM2
2668         memset(sm2_doit, 1, sizeof(sm2_doit));
2669 #endif
2670         memset(kems_doit, 1, sizeof(kems_doit));
2671         do_kems = 1;
2672         memset(sigs_doit, 1, sizeof(sigs_doit));
2673         do_sigs = 1;
2674     }
2675     for (i = 0; i < ALGOR_NUM; i++)
2676         if (doit[i])
2677             pr_header++;
2678 
2679     if (usertime == 0 && !mr)
2680         BIO_printf(bio_err,
2681             "You have chosen to measure elapsed time "
2682             "instead of user CPU time.\n");
2683 
2684 #if SIGALRM > 0
2685     signal(SIGALRM, alarmed);
2686 #endif
2687 
2688     if (doit[D_MD2]) {
2689         for (testnum = 0; testnum < size_num; testnum++) {
2690             print_message(names[D_MD2], lengths[testnum], seconds.sym);
2691             Time_F(START);
2692             count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
2693             d = Time_F(STOP);
2694             print_result(D_MD2, testnum, count, d);
2695             if (count < 0)
2696                 break;
2697         }
2698     }
2699 
2700     if (doit[D_MDC2]) {
2701         for (testnum = 0; testnum < size_num; testnum++) {
2702             print_message(names[D_MDC2], lengths[testnum], seconds.sym);
2703             Time_F(START);
2704             count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
2705             d = Time_F(STOP);
2706             print_result(D_MDC2, testnum, count, d);
2707             if (count < 0)
2708                 break;
2709         }
2710     }
2711 
2712     if (doit[D_MD4]) {
2713         for (testnum = 0; testnum < size_num; testnum++) {
2714             print_message(names[D_MD4], lengths[testnum], seconds.sym);
2715             Time_F(START);
2716             count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
2717             d = Time_F(STOP);
2718             print_result(D_MD4, testnum, count, d);
2719             if (count < 0)
2720                 break;
2721         }
2722     }
2723 
2724     if (doit[D_MD5]) {
2725         for (testnum = 0; testnum < size_num; testnum++) {
2726             print_message(names[D_MD5], lengths[testnum], seconds.sym);
2727             Time_F(START);
2728             count = run_benchmark(async_jobs, MD5_loop, loopargs);
2729             d = Time_F(STOP);
2730             print_result(D_MD5, testnum, count, d);
2731             if (count < 0)
2732                 break;
2733         }
2734     }
2735 
2736     if (doit[D_SHA1]) {
2737         for (testnum = 0; testnum < size_num; testnum++) {
2738             print_message(names[D_SHA1], lengths[testnum], seconds.sym);
2739             Time_F(START);
2740             count = run_benchmark(async_jobs, SHA1_loop, loopargs);
2741             d = Time_F(STOP);
2742             print_result(D_SHA1, testnum, count, d);
2743             if (count < 0)
2744                 break;
2745         }
2746     }
2747 
2748     if (doit[D_SHA256]) {
2749         for (testnum = 0; testnum < size_num; testnum++) {
2750             print_message(names[D_SHA256], lengths[testnum], seconds.sym);
2751             Time_F(START);
2752             count = run_benchmark(async_jobs, SHA256_loop, loopargs);
2753             d = Time_F(STOP);
2754             print_result(D_SHA256, testnum, count, d);
2755             if (count < 0)
2756                 break;
2757         }
2758     }
2759 
2760     if (doit[D_SHA512]) {
2761         for (testnum = 0; testnum < size_num; testnum++) {
2762             print_message(names[D_SHA512], lengths[testnum], seconds.sym);
2763             Time_F(START);
2764             count = run_benchmark(async_jobs, SHA512_loop, loopargs);
2765             d = Time_F(STOP);
2766             print_result(D_SHA512, testnum, count, d);
2767             if (count < 0)
2768                 break;
2769         }
2770     }
2771 
2772     if (doit[D_WHIRLPOOL]) {
2773         for (testnum = 0; testnum < size_num; testnum++) {
2774             print_message(names[D_WHIRLPOOL], lengths[testnum], seconds.sym);
2775             Time_F(START);
2776             count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
2777             d = Time_F(STOP);
2778             print_result(D_WHIRLPOOL, testnum, count, d);
2779             if (count < 0)
2780                 break;
2781         }
2782     }
2783 
2784     if (doit[D_RMD160]) {
2785         for (testnum = 0; testnum < size_num; testnum++) {
2786             print_message(names[D_RMD160], lengths[testnum], seconds.sym);
2787             Time_F(START);
2788             count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
2789             d = Time_F(STOP);
2790             print_result(D_RMD160, testnum, count, d);
2791             if (count < 0)
2792                 break;
2793         }
2794     }
2795 
2796     if (doit[D_HMAC]) {
2797         static const char hmac_key[] = "This is a key...";
2798         int len = strlen(hmac_key);
2799         size_t hmac_name_len = sizeof("hmac()") + strlen(evp_mac_mdname);
2800         OSSL_PARAM params[3];
2801 
2802         if (evp_mac_mdname == NULL)
2803             goto end;
2804         evp_hmac_name = app_malloc(hmac_name_len, "HMAC name");
2805         BIO_snprintf(evp_hmac_name, hmac_name_len, "hmac(%s)", evp_mac_mdname);
2806         names[D_HMAC] = evp_hmac_name;
2807 
2808         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2809             evp_mac_mdname, 0);
2810         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2811             (char *)hmac_key, len);
2812         params[2] = OSSL_PARAM_construct_end();
2813 
2814         if (mac_setup("HMAC", &mac, params, loopargs, loopargs_len) < 1)
2815             goto end;
2816         for (testnum = 0; testnum < size_num; testnum++) {
2817             print_message(names[D_HMAC], lengths[testnum], seconds.sym);
2818             Time_F(START);
2819             count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2820             d = Time_F(STOP);
2821             print_result(D_HMAC, testnum, count, d);
2822             if (count < 0)
2823                 break;
2824         }
2825         mac_teardown(&mac, loopargs, loopargs_len);
2826     }
2827 
2828     if (doit[D_CBC_DES]) {
2829         int st = 1;
2830 
2831         for (i = 0; st && i < loopargs_len; i++) {
2832             loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2833                 sizeof(deskey) / 3);
2834             st = loopargs[i].ctx != NULL;
2835         }
2836         algindex = D_CBC_DES;
2837         for (testnum = 0; st && testnum < size_num; testnum++) {
2838             if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
2839                 break;
2840             print_message(names[D_CBC_DES], lengths[testnum], seconds.sym);
2841             Time_F(START);
2842             count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2843             d = Time_F(STOP);
2844             print_result(D_CBC_DES, testnum, count, d);
2845         }
2846         for (i = 0; i < loopargs_len; i++)
2847             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2848     }
2849 
2850     if (doit[D_EDE3_DES]) {
2851         int st = 1;
2852 
2853         for (i = 0; st && i < loopargs_len; i++) {
2854             loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2855                 sizeof(deskey));
2856             st = loopargs[i].ctx != NULL;
2857         }
2858         algindex = D_EDE3_DES;
2859         for (testnum = 0; st && testnum < size_num; testnum++) {
2860             if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
2861                 break;
2862             print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym);
2863             Time_F(START);
2864             count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2865             d = Time_F(STOP);
2866             print_result(D_EDE3_DES, testnum, count, d);
2867         }
2868         for (i = 0; i < loopargs_len; i++)
2869             EVP_CIPHER_CTX_free(loopargs[i].ctx);
2870     }
2871 
2872     for (k = 0; k < 3; k++) {
2873         algindex = D_CBC_128_AES + k;
2874         if (doit[algindex]) {
2875             int st = 1;
2876 
2877             keylen = 16 + k * 8;
2878             for (i = 0; st && i < loopargs_len; i++) {
2879                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2880                     key32, keylen);
2881                 st = loopargs[i].ctx != NULL;
2882             }
2883 
2884             for (testnum = 0; st && testnum < size_num; testnum++) {
2885                 if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
2886                     break;
2887                 print_message(names[algindex], lengths[testnum], seconds.sym);
2888                 Time_F(START);
2889                 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2890                 d = Time_F(STOP);
2891                 print_result(algindex, testnum, count, d);
2892             }
2893             for (i = 0; i < loopargs_len; i++)
2894                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2895         }
2896     }
2897 
2898     for (k = 0; k < 3; k++) {
2899         algindex = D_CBC_128_CML + k;
2900         if (doit[algindex]) {
2901             int st = 1;
2902 
2903             keylen = 16 + k * 8;
2904             for (i = 0; st && i < loopargs_len; i++) {
2905                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2906                     key32, keylen);
2907                 st = loopargs[i].ctx != NULL;
2908             }
2909 
2910             for (testnum = 0; st && testnum < size_num; testnum++) {
2911                 if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
2912                     break;
2913                 print_message(names[algindex], lengths[testnum], seconds.sym);
2914                 Time_F(START);
2915                 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2916                 d = Time_F(STOP);
2917                 print_result(algindex, testnum, count, d);
2918             }
2919             for (i = 0; i < loopargs_len; i++)
2920                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2921         }
2922     }
2923 
2924     for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2925         if (doit[algindex]) {
2926             int st = 1;
2927 
2928             keylen = 16;
2929             for (i = 0; st && i < loopargs_len; i++) {
2930                 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2931                     key32, keylen);
2932                 st = loopargs[i].ctx != NULL;
2933             }
2934 
2935             for (testnum = 0; st && testnum < size_num; testnum++) {
2936                 if (!check_block_size(loopargs[0].ctx, lengths[testnum]))
2937                     break;
2938                 print_message(names[algindex], lengths[testnum], seconds.sym);
2939                 Time_F(START);
2940                 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2941                 d = Time_F(STOP);
2942                 print_result(algindex, testnum, count, d);
2943             }
2944             for (i = 0; i < loopargs_len; i++)
2945                 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2946         }
2947     }
2948     if (doit[D_GHASH]) {
2949         static const char gmac_iv[] = "0123456789ab";
2950         OSSL_PARAM params[4];
2951 
2952         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2953             "aes-128-gcm", 0);
2954         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2955             (char *)gmac_iv,
2956             sizeof(gmac_iv) - 1);
2957         params[2] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2958             (void *)key32, 16);
2959         params[3] = OSSL_PARAM_construct_end();
2960 
2961         if (mac_setup("GMAC", &mac, params, loopargs, loopargs_len) < 1)
2962             goto end;
2963         /* b/c of the definition of GHASH_loop(), init() calls are needed here */
2964         for (i = 0; i < loopargs_len; i++) {
2965             if (!EVP_MAC_init(loopargs[i].mctx, NULL, 0, NULL))
2966                 goto end;
2967         }
2968         for (testnum = 0; testnum < size_num; testnum++) {
2969             print_message(names[D_GHASH], lengths[testnum], seconds.sym);
2970             Time_F(START);
2971             count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2972             d = Time_F(STOP);
2973             print_result(D_GHASH, testnum, count, d);
2974             if (count < 0)
2975                 break;
2976         }
2977         mac_teardown(&mac, loopargs, loopargs_len);
2978     }
2979 
2980     if (doit[D_RAND]) {
2981         for (testnum = 0; testnum < size_num; testnum++) {
2982             print_message(names[D_RAND], lengths[testnum], seconds.sym);
2983             Time_F(START);
2984             count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2985             d = Time_F(STOP);
2986             print_result(D_RAND, testnum, count, d);
2987         }
2988     }
2989 
2990     /*-
2991      * There are three scenarios for D_EVP:
2992      * 1- Using authenticated encryption (AE) e.g. CCM, GCM, OCB etc.
2993      * 2- Using AE + associated data (AD) i.e. AEAD using CCM, GCM, OCB etc.
2994      * 3- Not using AE or AD e.g. ECB, CBC, CFB etc.
2995      */
2996     if (doit[D_EVP]) {
2997         if (evp_cipher != NULL) {
2998             int (*loopfunc)(void *);
2999             int outlen = 0;
3000             unsigned int ae_mode = 0;
3001 
3002             if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
3003                 multiblock_speed(evp_cipher, lengths_single, &seconds);
3004                 ret = 0;
3005                 goto end;
3006             }
3007 
3008             names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
3009 
3010             mode_op = EVP_CIPHER_get_mode(evp_cipher);
3011 
3012             if (aead) {
3013                 if (lengths == lengths_list) {
3014                     lengths = aead_lengths_list;
3015                     size_num = OSSL_NELEM(aead_lengths_list);
3016                 }
3017             }
3018             if (mode_op == EVP_CIPH_GCM_MODE
3019                 || mode_op == EVP_CIPH_CCM_MODE
3020                 || mode_op == EVP_CIPH_OCB_MODE
3021                 || mode_op == EVP_CIPH_SIV_MODE
3022                 || mode_op == EVP_CIPH_GCM_SIV_MODE) {
3023                 ae_mode = 1;
3024                 if (decrypt)
3025                     loopfunc = EVP_Update_loop_aead_dec;
3026                 else
3027                     loopfunc = EVP_Update_loop_aead_enc;
3028             } else {
3029                 loopfunc = EVP_Update_loop;
3030             }
3031 
3032             for (testnum = 0; testnum < size_num; testnum++) {
3033                 print_message(names[D_EVP], lengths[testnum], seconds.sym);
3034 
3035                 for (k = 0; k < loopargs_len; k++) {
3036                     loopargs[k].ctx = EVP_CIPHER_CTX_new();
3037                     if (loopargs[k].ctx == NULL) {
3038                         BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
3039                         exit(1);
3040                     }
3041 
3042                     /*
3043                      * For AE modes, we must first encrypt the data to get
3044                      * a valid tag that enables us to decrypt. If we don't
3045                      * encrypt first, we won't have a valid tag that enables
3046                      * authenticity and hence decryption will fail.
3047                      */
3048                     if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
3049                             NULL, NULL, ae_mode ? 1 : !decrypt)) {
3050                         BIO_printf(bio_err, "\nCouldn't init the context\n");
3051                         dofail();
3052                         exit(1);
3053                     }
3054 
3055                     /* Padding isn't needed */
3056                     EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
3057 
3058                     keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
3059                     loopargs[k].key = app_malloc(keylen, "evp_cipher key");
3060                     EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
3061 
3062                     if (!ae_mode) {
3063                         if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
3064                                 loopargs[k].key, iv, -1)) {
3065                             BIO_printf(bio_err, "\nFailed to set the key\n");
3066                             dofail();
3067                             exit(1);
3068                         }
3069                     } else if (mode_op == EVP_CIPH_SIV_MODE
3070                         || mode_op == EVP_CIPH_GCM_SIV_MODE) {
3071                         EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3072                             EVP_CTRL_SET_SPEED, 1, NULL);
3073                     }
3074                     if (ae_mode && decrypt) {
3075                         /* Set length of iv (Doesn't apply to SIV mode) */
3076                         if (mode_op != EVP_CIPH_SIV_MODE) {
3077                             if (!EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3078                                     EVP_CTRL_AEAD_SET_IVLEN,
3079                                     sizeof(aead_iv), NULL)) {
3080                                 BIO_printf(bio_err, "\nFailed to set iv length\n");
3081                                 dofail();
3082                                 exit(1);
3083                             }
3084                         }
3085                         /* Set tag_len (Not for GCM/SIV at encryption stage) */
3086                         if (mode_op != EVP_CIPH_GCM_MODE
3087                             && mode_op != EVP_CIPH_SIV_MODE
3088                             && mode_op != EVP_CIPH_GCM_SIV_MODE) {
3089                             if (!EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3090                                     EVP_CTRL_AEAD_SET_TAG,
3091                                     TAG_LEN, NULL)) {
3092                                 BIO_printf(bio_err,
3093                                     "\nFailed to set tag length\n");
3094                                 dofail();
3095                                 exit(1);
3096                             }
3097                         }
3098                         if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
3099                                 loopargs[k].key, aead_iv, -1)) {
3100                             BIO_printf(bio_err, "\nFailed to set the key\n");
3101                             dofail();
3102                             exit(1);
3103                         }
3104                         /* Set total length of input. Only required for CCM */
3105                         if (mode_op == EVP_CIPH_CCM_MODE) {
3106                             if (!EVP_EncryptUpdate(loopargs[k].ctx, NULL,
3107                                     &outlen, NULL,
3108                                     lengths[testnum])) {
3109                                 BIO_printf(bio_err,
3110                                     "\nCouldn't set input text length\n");
3111                                 dofail();
3112                                 exit(1);
3113                             }
3114                         }
3115                         if (aead) {
3116                             if (!EVP_EncryptUpdate(loopargs[k].ctx, NULL,
3117                                     &outlen, aad, sizeof(aad))) {
3118                                 BIO_printf(bio_err,
3119                                     "\nCouldn't insert AAD when encrypting\n");
3120                                 dofail();
3121                                 exit(1);
3122                             }
3123                         }
3124                         if (!EVP_EncryptUpdate(loopargs[k].ctx, loopargs[k].buf,
3125                                 &outlen, loopargs[k].buf,
3126                                 lengths[testnum])) {
3127                             BIO_printf(bio_err,
3128                                 "\nFailed to to encrypt the data\n");
3129                             dofail();
3130                             exit(1);
3131                         }
3132 
3133                         if (!EVP_EncryptFinal_ex(loopargs[k].ctx,
3134                                 loopargs[k].buf, &outlen)) {
3135                             BIO_printf(bio_err,
3136                                 "\nFailed finalize the encryption\n");
3137                             dofail();
3138                             exit(1);
3139                         }
3140 
3141                         if (EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_AEAD_GET_TAG,
3142                                 TAG_LEN, &loopargs[k].tag)
3143                             <= 0) {
3144                             BIO_printf(bio_err, "\nFailed to get the tag\n");
3145                             dofail();
3146                             exit(1);
3147                         }
3148 
3149                         EVP_CIPHER_CTX_free(loopargs[k].ctx);
3150                         loopargs[k].ctx = EVP_CIPHER_CTX_new();
3151                         if (loopargs[k].ctx == NULL) {
3152                             BIO_printf(bio_err,
3153                                 "\nEVP_CIPHER_CTX_new failure\n");
3154                             exit(1);
3155                         }
3156                         if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher,
3157                                 NULL, NULL, NULL, 0)) {
3158                             BIO_printf(bio_err,
3159                                 "\nFailed initializing the context\n");
3160                             dofail();
3161                             exit(1);
3162                         }
3163 
3164                         EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
3165 
3166                         /* GCM-SIV/SIV only allows for a single Update operation */
3167                         if (mode_op == EVP_CIPH_SIV_MODE
3168                             || mode_op == EVP_CIPH_GCM_SIV_MODE)
3169                             EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3170                                 EVP_CTRL_SET_SPEED, 1, NULL);
3171                     }
3172                 }
3173 
3174                 Time_F(START);
3175                 count = run_benchmark(async_jobs, loopfunc, loopargs);
3176                 d = Time_F(STOP);
3177                 for (k = 0; k < loopargs_len; k++) {
3178                     OPENSSL_clear_free(loopargs[k].key, keylen);
3179                     EVP_CIPHER_CTX_free(loopargs[k].ctx);
3180                 }
3181                 print_result(D_EVP, testnum, count, d);
3182             }
3183         } else if (evp_md_name != NULL) {
3184             names[D_EVP] = evp_md_name;
3185 
3186             for (testnum = 0; testnum < size_num; testnum++) {
3187                 print_message(names[D_EVP], lengths[testnum], seconds.sym);
3188                 Time_F(START);
3189                 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
3190                 d = Time_F(STOP);
3191                 print_result(D_EVP, testnum, count, d);
3192                 if (count < 0)
3193                     break;
3194             }
3195         }
3196     }
3197 
3198     if (doit[D_EVP_CMAC]) {
3199         size_t len = sizeof("cmac()") + strlen(evp_mac_ciphername);
3200         OSSL_PARAM params[3];
3201         EVP_CIPHER *cipher = NULL;
3202 
3203         if (!opt_cipher(evp_mac_ciphername, &cipher))
3204             goto end;
3205 
3206         keylen = EVP_CIPHER_get_key_length(cipher);
3207         EVP_CIPHER_free(cipher);
3208         if (keylen <= 0 || keylen > (int)sizeof(key32)) {
3209             BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
3210             goto end;
3211         }
3212         evp_cmac_name = app_malloc(len, "CMAC name");
3213         BIO_snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername);
3214         names[D_EVP_CMAC] = evp_cmac_name;
3215 
3216         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
3217             evp_mac_ciphername, 0);
3218         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3219             (char *)key32, keylen);
3220         params[2] = OSSL_PARAM_construct_end();
3221 
3222         if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
3223             goto end;
3224         for (testnum = 0; testnum < size_num; testnum++) {
3225             print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
3226             Time_F(START);
3227             count = run_benchmark(async_jobs, CMAC_loop, loopargs);
3228             d = Time_F(STOP);
3229             print_result(D_EVP_CMAC, testnum, count, d);
3230             if (count < 0)
3231                 break;
3232         }
3233         mac_teardown(&mac, loopargs, loopargs_len);
3234     }
3235 
3236     if (doit[D_KMAC128]) {
3237         OSSL_PARAM params[2];
3238 
3239         params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3240             (void *)key32, 16);
3241         params[1] = OSSL_PARAM_construct_end();
3242 
3243         if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
3244             goto end;
3245         for (testnum = 0; testnum < size_num; testnum++) {
3246             print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
3247             Time_F(START);
3248             count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
3249             d = Time_F(STOP);
3250             print_result(D_KMAC128, testnum, count, d);
3251             if (count < 0)
3252                 break;
3253         }
3254         mac_teardown(&mac, loopargs, loopargs_len);
3255     }
3256 
3257     if (doit[D_KMAC256]) {
3258         OSSL_PARAM params[2];
3259 
3260         params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3261             (void *)key32, 32);
3262         params[1] = OSSL_PARAM_construct_end();
3263 
3264         if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
3265             goto end;
3266         for (testnum = 0; testnum < size_num; testnum++) {
3267             print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
3268             Time_F(START);
3269             count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
3270             d = Time_F(STOP);
3271             print_result(D_KMAC256, testnum, count, d);
3272             if (count < 0)
3273                 break;
3274         }
3275         mac_teardown(&mac, loopargs, loopargs_len);
3276     }
3277 
3278     for (i = 0; i < loopargs_len; i++)
3279         if (RAND_bytes(loopargs[i].buf, 36) <= 0)
3280             goto end;
3281 
3282     for (testnum = 0; testnum < RSA_NUM; testnum++) {
3283         EVP_PKEY *rsa_key = NULL;
3284         int st = 0;
3285 
3286         if (!rsa_doit[testnum])
3287             continue;
3288 
3289         if (primes > RSA_DEFAULT_PRIME_NUM) {
3290             /* we haven't set keys yet,  generate multi-prime RSA keys */
3291             bn = BN_new();
3292             st = bn != NULL
3293                 && BN_set_word(bn, RSA_F4)
3294                 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
3295                 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
3296                 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
3297                 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
3298                 && EVP_PKEY_keygen(genctx, &rsa_key) > 0;
3299             BN_free(bn);
3300             bn = NULL;
3301             EVP_PKEY_CTX_free(genctx);
3302             genctx = NULL;
3303         } else {
3304             const unsigned char *p = rsa_keys[testnum].data;
3305 
3306             st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
3307                       rsa_keys[testnum].length))
3308                 != NULL;
3309         }
3310 
3311         for (i = 0; st && i < loopargs_len; i++) {
3312             loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3313             loopargs[i].sigsize = loopargs[i].buflen;
3314             if (loopargs[i].rsa_sign_ctx[testnum] == NULL
3315                 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
3316                 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
3317                        loopargs[i].buf2,
3318                        &loopargs[i].sigsize,
3319                        loopargs[i].buf, 36)
3320                     <= 0)
3321                 st = 0;
3322         }
3323         if (!st) {
3324             BIO_printf(bio_err,
3325                 "RSA sign setup failure.  No RSA sign will be done.\n");
3326             dofail();
3327             op_count = 1;
3328         } else {
3329             pkey_print_message("private", "rsa sign",
3330                 rsa_keys[testnum].bits, seconds.rsa);
3331             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3332             Time_F(START);
3333             count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
3334             d = Time_F(STOP);
3335             BIO_printf(bio_err,
3336                 mr ? "+R1:%ld:%d:%.2f\n"
3337                    : "%ld %u bits private RSA sign ops in %.2fs\n",
3338                 count, rsa_keys[testnum].bits, d);
3339             rsa_results[testnum][0] = (double)count / d;
3340             op_count = count;
3341         }
3342 
3343         for (i = 0; st && i < loopargs_len; i++) {
3344             loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
3345                 NULL);
3346             if (loopargs[i].rsa_verify_ctx[testnum] == NULL
3347                 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
3348                 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
3349                        loopargs[i].buf2,
3350                        loopargs[i].sigsize,
3351                        loopargs[i].buf, 36)
3352                     <= 0)
3353                 st = 0;
3354         }
3355         if (!st) {
3356             BIO_printf(bio_err,
3357                 "RSA verify setup failure.  No RSA verify will be done.\n");
3358             dofail();
3359             rsa_doit[testnum] = 0;
3360         } else {
3361             pkey_print_message("public", "rsa verify",
3362                 rsa_keys[testnum].bits, seconds.rsa);
3363             Time_F(START);
3364             count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
3365             d = Time_F(STOP);
3366             BIO_printf(bio_err,
3367                 mr ? "+R2:%ld:%d:%.2f\n"
3368                    : "%ld %u bits public RSA verify ops in %.2fs\n",
3369                 count, rsa_keys[testnum].bits, d);
3370             rsa_results[testnum][1] = (double)count / d;
3371         }
3372 
3373         for (i = 0; st && i < loopargs_len; i++) {
3374             loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3375             loopargs[i].encsize = loopargs[i].buflen;
3376             if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
3377                 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
3378                 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
3379                        loopargs[i].buf2,
3380                        &loopargs[i].encsize,
3381                        loopargs[i].buf, 36)
3382                     <= 0)
3383                 st = 0;
3384         }
3385         if (!st) {
3386             BIO_printf(bio_err,
3387                 "RSA encrypt setup failure.  No RSA encrypt will be done.\n");
3388             dofail();
3389             op_count = 1;
3390         } else {
3391             pkey_print_message("public", "rsa encrypt",
3392                 rsa_keys[testnum].bits, seconds.rsa);
3393             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3394             Time_F(START);
3395             count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
3396             d = Time_F(STOP);
3397             BIO_printf(bio_err,
3398                 mr ? "+R3:%ld:%d:%.2f\n"
3399                    : "%ld %u bits public RSA encrypt ops in %.2fs\n",
3400                 count, rsa_keys[testnum].bits, d);
3401             rsa_results[testnum][2] = (double)count / d;
3402             op_count = count;
3403         }
3404 
3405         for (i = 0; st && i < loopargs_len; i++) {
3406             loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3407             declen = loopargs[i].buflen;
3408             if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
3409                 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
3410                 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
3411                        loopargs[i].buf,
3412                        &declen,
3413                        loopargs[i].buf2,
3414                        loopargs[i].encsize)
3415                     <= 0)
3416                 st = 0;
3417         }
3418         if (!st) {
3419             BIO_printf(bio_err,
3420                 "RSA decrypt setup failure.  No RSA decrypt will be done.\n");
3421             dofail();
3422             op_count = 1;
3423         } else {
3424             pkey_print_message("private", "rsa decrypt",
3425                 rsa_keys[testnum].bits, seconds.rsa);
3426             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3427             Time_F(START);
3428             count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3429             d = Time_F(STOP);
3430             BIO_printf(bio_err,
3431                 mr ? "+R4:%ld:%d:%.2f\n"
3432                    : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3433                 count, rsa_keys[testnum].bits, d);
3434             rsa_results[testnum][3] = (double)count / d;
3435             op_count = count;
3436         }
3437 
3438         if (op_count <= 1) {
3439             /* if longer than 10s, don't do any more */
3440             stop_it(rsa_doit, testnum);
3441         }
3442         EVP_PKEY_free(rsa_key);
3443     }
3444 
3445 #ifndef OPENSSL_NO_DSA
3446     for (testnum = 0; testnum < DSA_NUM; testnum++) {
3447         EVP_PKEY *dsa_key = NULL;
3448         int st;
3449 
3450         if (!dsa_doit[testnum])
3451             continue;
3452 
3453         st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3454 
3455         for (i = 0; st && i < loopargs_len; i++) {
3456             loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3457                 NULL);
3458             loopargs[i].sigsize = loopargs[i].buflen;
3459             if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3460                 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3461                 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3462                        loopargs[i].buf2,
3463                        &loopargs[i].sigsize,
3464                        loopargs[i].buf, 20)
3465                     <= 0)
3466                 st = 0;
3467         }
3468         if (!st) {
3469             BIO_printf(bio_err,
3470                 "DSA sign setup failure.  No DSA sign will be done.\n");
3471             dofail();
3472             op_count = 1;
3473         } else {
3474             pkey_print_message("sign", "dsa",
3475                 dsa_bits[testnum], seconds.dsa);
3476             Time_F(START);
3477             count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3478             d = Time_F(STOP);
3479             BIO_printf(bio_err,
3480                 mr ? "+R5:%ld:%u:%.2f\n"
3481                    : "%ld %u bits DSA sign ops in %.2fs\n",
3482                 count, dsa_bits[testnum], d);
3483             dsa_results[testnum][0] = (double)count / d;
3484             op_count = count;
3485         }
3486 
3487         for (i = 0; st && i < loopargs_len; i++) {
3488             loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3489                 NULL);
3490             if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3491                 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3492                 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3493                        loopargs[i].buf2,
3494                        loopargs[i].sigsize,
3495                        loopargs[i].buf, 36)
3496                     <= 0)
3497                 st = 0;
3498         }
3499         if (!st) {
3500             BIO_printf(bio_err,
3501                 "DSA verify setup failure.  No DSA verify will be done.\n");
3502             dofail();
3503             dsa_doit[testnum] = 0;
3504         } else {
3505             pkey_print_message("verify", "dsa",
3506                 dsa_bits[testnum], seconds.dsa);
3507             Time_F(START);
3508             count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3509             d = Time_F(STOP);
3510             BIO_printf(bio_err,
3511                 mr ? "+R6:%ld:%u:%.2f\n"
3512                    : "%ld %u bits DSA verify ops in %.2fs\n",
3513                 count, dsa_bits[testnum], d);
3514             dsa_results[testnum][1] = (double)count / d;
3515         }
3516 
3517         if (op_count <= 1) {
3518             /* if longer than 10s, don't do any more */
3519             stop_it(dsa_doit, testnum);
3520         }
3521         EVP_PKEY_free(dsa_key);
3522     }
3523 #endif /* OPENSSL_NO_DSA */
3524 
3525     for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3526         EVP_PKEY *ecdsa_key = NULL;
3527         int st;
3528 
3529         if (!ecdsa_doit[testnum])
3530             continue;
3531 
3532         st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3533 
3534         for (i = 0; st && i < loopargs_len; i++) {
3535             loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3536                 NULL);
3537             loopargs[i].sigsize = loopargs[i].buflen;
3538             if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3539                 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3540                 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3541                        loopargs[i].buf2,
3542                        &loopargs[i].sigsize,
3543                        loopargs[i].buf, 20)
3544                     <= 0)
3545                 st = 0;
3546         }
3547         if (!st) {
3548             BIO_printf(bio_err,
3549                 "ECDSA sign setup failure.  No ECDSA sign will be done.\n");
3550             dofail();
3551             op_count = 1;
3552         } else {
3553             pkey_print_message("sign", "ecdsa",
3554                 ec_curves[testnum].bits, seconds.ecdsa);
3555             Time_F(START);
3556             count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3557             d = Time_F(STOP);
3558             BIO_printf(bio_err,
3559                 mr ? "+R7:%ld:%u:%.2f\n"
3560                    : "%ld %u bits ECDSA sign ops in %.2fs\n",
3561                 count, ec_curves[testnum].bits, d);
3562             ecdsa_results[testnum][0] = (double)count / d;
3563             op_count = count;
3564         }
3565 
3566         for (i = 0; st && i < loopargs_len; i++) {
3567             loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3568                 NULL);
3569             if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3570                 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3571                 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3572                        loopargs[i].buf2,
3573                        loopargs[i].sigsize,
3574                        loopargs[i].buf, 20)
3575                     <= 0)
3576                 st = 0;
3577         }
3578         if (!st) {
3579             BIO_printf(bio_err,
3580                 "ECDSA verify setup failure.  No ECDSA verify will be done.\n");
3581             dofail();
3582             ecdsa_doit[testnum] = 0;
3583         } else {
3584             pkey_print_message("verify", "ecdsa",
3585                 ec_curves[testnum].bits, seconds.ecdsa);
3586             Time_F(START);
3587             count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3588             d = Time_F(STOP);
3589             BIO_printf(bio_err,
3590                 mr ? "+R8:%ld:%u:%.2f\n"
3591                    : "%ld %u bits ECDSA verify ops in %.2fs\n",
3592                 count, ec_curves[testnum].bits, d);
3593             ecdsa_results[testnum][1] = (double)count / d;
3594         }
3595 
3596         if (op_count <= 1) {
3597             /* if longer than 10s, don't do any more */
3598             stop_it(ecdsa_doit, testnum);
3599         }
3600         EVP_PKEY_free(ecdsa_key);
3601     }
3602 
3603     for (testnum = 0; testnum < EC_NUM; testnum++) {
3604         int ecdh_checks = 1;
3605 
3606         if (!ecdh_doit[testnum])
3607             continue;
3608 
3609         for (i = 0; i < loopargs_len; i++) {
3610             EVP_PKEY_CTX *test_ctx = NULL;
3611             EVP_PKEY_CTX *ctx = NULL;
3612             EVP_PKEY *key_A = NULL;
3613             EVP_PKEY *key_B = NULL;
3614             size_t outlen;
3615             size_t test_outlen;
3616 
3617             if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3618                 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3619                 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3620                 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3621                 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3622                 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3623                 || outlen == 0 /* ensure outlen is a valid size */
3624                 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3625                 ecdh_checks = 0;
3626                 BIO_printf(bio_err, "ECDH key generation failure.\n");
3627                 dofail();
3628                 op_count = 1;
3629                 break;
3630             }
3631 
3632             /*
3633              * Here we perform a test run, comparing the output of a*B and b*A;
3634              * we try this here and assume that further EVP_PKEY_derive calls
3635              * never fail, so we can skip checks in the actually benchmarked
3636              * code, for maximum performance.
3637              */
3638             if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3639                 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3640                 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3641                 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3642                 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3643                 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3644                 || test_outlen != outlen /* compare output length */) {
3645                 ecdh_checks = 0;
3646                 BIO_printf(bio_err, "ECDH computation failure.\n");
3647                 dofail();
3648                 op_count = 1;
3649                 break;
3650             }
3651 
3652             /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3653             if (CRYPTO_memcmp(loopargs[i].secret_a,
3654                     loopargs[i].secret_b, outlen)) {
3655                 ecdh_checks = 0;
3656                 BIO_printf(bio_err, "ECDH computations don't match.\n");
3657                 dofail();
3658                 op_count = 1;
3659                 break;
3660             }
3661 
3662             loopargs[i].ecdh_ctx[testnum] = ctx;
3663             loopargs[i].outlen[testnum] = outlen;
3664 
3665             EVP_PKEY_free(key_A);
3666             EVP_PKEY_free(key_B);
3667             EVP_PKEY_CTX_free(test_ctx);
3668             test_ctx = NULL;
3669         }
3670         if (ecdh_checks != 0) {
3671             pkey_print_message("", "ecdh",
3672                 ec_curves[testnum].bits, seconds.ecdh);
3673             Time_F(START);
3674             count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3675             d = Time_F(STOP);
3676             BIO_printf(bio_err,
3677                 mr ? "+R9:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count,
3678                 ec_curves[testnum].bits, d);
3679             ecdh_results[testnum][0] = (double)count / d;
3680             op_count = count;
3681         }
3682 
3683         if (op_count <= 1) {
3684             /* if longer than 10s, don't do any more */
3685             stop_it(ecdh_doit, testnum);
3686         }
3687     }
3688 
3689 #ifndef OPENSSL_NO_ECX
3690     for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3691         int st = 1;
3692         EVP_PKEY *ed_pkey = NULL;
3693         EVP_PKEY_CTX *ed_pctx = NULL;
3694 
3695         if (!eddsa_doit[testnum])
3696             continue; /* Ignore Curve */
3697         for (i = 0; i < loopargs_len; i++) {
3698             loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3699             if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3700                 st = 0;
3701                 break;
3702             }
3703             loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3704             if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3705                 st = 0;
3706                 break;
3707             }
3708 
3709             if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3710                      NULL))
3711                     == NULL
3712                 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3713                 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3714                 st = 0;
3715                 EVP_PKEY_CTX_free(ed_pctx);
3716                 break;
3717             }
3718             EVP_PKEY_CTX_free(ed_pctx);
3719 
3720             if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3721                     NULL, ed_pkey)) {
3722                 st = 0;
3723                 EVP_PKEY_free(ed_pkey);
3724                 break;
3725             }
3726             if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3727                     NULL, NULL, ed_pkey)) {
3728                 st = 0;
3729                 EVP_PKEY_free(ed_pkey);
3730                 break;
3731             }
3732 
3733             EVP_PKEY_free(ed_pkey);
3734             ed_pkey = NULL;
3735         }
3736         if (st == 0) {
3737             BIO_printf(bio_err, "EdDSA failure.\n");
3738             dofail();
3739             op_count = 1;
3740         } else {
3741             for (i = 0; i < loopargs_len; i++) {
3742                 /* Perform EdDSA signature test */
3743                 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3744                 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3745                     loopargs[i].buf2, &loopargs[i].sigsize,
3746                     loopargs[i].buf, 20);
3747                 if (st == 0)
3748                     break;
3749             }
3750             if (st == 0) {
3751                 BIO_printf(bio_err,
3752                     "EdDSA sign failure.  No EdDSA sign will be done.\n");
3753                 dofail();
3754                 op_count = 1;
3755             } else {
3756                 pkey_print_message("sign", ed_curves[testnum].name,
3757                     ed_curves[testnum].bits, seconds.eddsa);
3758                 Time_F(START);
3759                 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3760                 d = Time_F(STOP);
3761 
3762                 BIO_printf(bio_err,
3763                     mr ? "+R10:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3764                     count, ed_curves[testnum].bits,
3765                     ed_curves[testnum].name, d);
3766                 eddsa_results[testnum][0] = (double)count / d;
3767                 op_count = count;
3768             }
3769             /* Perform EdDSA verification test */
3770             for (i = 0; i < loopargs_len; i++) {
3771                 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3772                     loopargs[i].buf2, loopargs[i].sigsize,
3773                     loopargs[i].buf, 20);
3774                 if (st != 1)
3775                     break;
3776             }
3777             if (st != 1) {
3778                 BIO_printf(bio_err,
3779                     "EdDSA verify failure.  No EdDSA verify will be done.\n");
3780                 dofail();
3781                 eddsa_doit[testnum] = 0;
3782             } else {
3783                 pkey_print_message("verify", ed_curves[testnum].name,
3784                     ed_curves[testnum].bits, seconds.eddsa);
3785                 Time_F(START);
3786                 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3787                 d = Time_F(STOP);
3788                 BIO_printf(bio_err,
3789                     mr ? "+R11:%ld:%u:%s:%.2f\n"
3790                        : "%ld %u bits %s verify ops in %.2fs\n",
3791                     count, ed_curves[testnum].bits,
3792                     ed_curves[testnum].name, d);
3793                 eddsa_results[testnum][1] = (double)count / d;
3794             }
3795 
3796             if (op_count <= 1) {
3797                 /* if longer than 10s, don't do any more */
3798                 stop_it(eddsa_doit, testnum);
3799             }
3800         }
3801     }
3802 #endif /* OPENSSL_NO_ECX */
3803 
3804 #ifndef OPENSSL_NO_SM2
3805     for (testnum = 0; testnum < SM2_NUM; testnum++) {
3806         int st = 1;
3807         EVP_PKEY *sm2_pkey = NULL;
3808 
3809         if (!sm2_doit[testnum])
3810             continue; /* Ignore Curve */
3811         /* Init signing and verification */
3812         for (i = 0; i < loopargs_len; i++) {
3813             EVP_PKEY_CTX *sm2_pctx = NULL;
3814             EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3815             EVP_PKEY_CTX *pctx = NULL;
3816             st = 0;
3817 
3818             loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3819             loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3820             if (loopargs[i].sm2_ctx[testnum] == NULL
3821                 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3822                 break;
3823 
3824             sm2_pkey = NULL;
3825 
3826             st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3827                 || EVP_PKEY_keygen_init(pctx) <= 0
3828                 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3829                        sm2_curves[testnum].nid)
3830                     <= 0
3831                 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3832             EVP_PKEY_CTX_free(pctx);
3833             if (st == 0)
3834                 break;
3835 
3836             st = 0; /* set back to zero */
3837             /* attach it sooner to rely on main final cleanup */
3838             loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3839             loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3840 
3841             sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3842             sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3843             if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3844                 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3845                 break;
3846             }
3847 
3848             /* attach them directly to respective ctx */
3849             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3850             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3851 
3852             /*
3853              * No need to allow user to set an explicit ID here, just use
3854              * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3855              */
3856             if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3857                 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3858                 break;
3859 
3860             if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3861                     EVP_sm3(), NULL, sm2_pkey))
3862                 break;
3863             if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3864                     EVP_sm3(), NULL, sm2_pkey))
3865                 break;
3866             st = 1; /* mark loop as succeeded */
3867         }
3868         if (st == 0) {
3869             BIO_printf(bio_err, "SM2 init failure.\n");
3870             dofail();
3871             op_count = 1;
3872         } else {
3873             for (i = 0; i < loopargs_len; i++) {
3874                 /* Perform SM2 signature test */
3875                 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3876                     loopargs[i].buf2, &loopargs[i].sigsize,
3877                     loopargs[i].buf, 20);
3878                 if (st == 0)
3879                     break;
3880             }
3881             if (st == 0) {
3882                 BIO_printf(bio_err,
3883                     "SM2 sign failure.  No SM2 sign will be done.\n");
3884                 dofail();
3885                 op_count = 1;
3886             } else {
3887                 pkey_print_message("sign", sm2_curves[testnum].name,
3888                     sm2_curves[testnum].bits, seconds.sm2);
3889                 Time_F(START);
3890                 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3891                 d = Time_F(STOP);
3892 
3893                 BIO_printf(bio_err,
3894                     mr ? "+R12:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3895                     count, sm2_curves[testnum].bits,
3896                     sm2_curves[testnum].name, d);
3897                 sm2_results[testnum][0] = (double)count / d;
3898                 op_count = count;
3899             }
3900 
3901             /* Perform SM2 verification test */
3902             for (i = 0; i < loopargs_len; i++) {
3903                 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3904                     loopargs[i].buf2, loopargs[i].sigsize,
3905                     loopargs[i].buf, 20);
3906                 if (st != 1)
3907                     break;
3908             }
3909             if (st != 1) {
3910                 BIO_printf(bio_err,
3911                     "SM2 verify failure.  No SM2 verify will be done.\n");
3912                 dofail();
3913                 sm2_doit[testnum] = 0;
3914             } else {
3915                 pkey_print_message("verify", sm2_curves[testnum].name,
3916                     sm2_curves[testnum].bits, seconds.sm2);
3917                 Time_F(START);
3918                 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3919                 d = Time_F(STOP);
3920                 BIO_printf(bio_err,
3921                     mr ? "+R13:%ld:%u:%s:%.2f\n"
3922                        : "%ld %u bits %s verify ops in %.2fs\n",
3923                     count, sm2_curves[testnum].bits,
3924                     sm2_curves[testnum].name, d);
3925                 sm2_results[testnum][1] = (double)count / d;
3926             }
3927 
3928             if (op_count <= 1) {
3929                 /* if longer than 10s, don't do any more */
3930                 for (testnum++; testnum < SM2_NUM; testnum++)
3931                     sm2_doit[testnum] = 0;
3932             }
3933         }
3934     }
3935 #endif /* OPENSSL_NO_SM2 */
3936 
3937 #ifndef OPENSSL_NO_DH
3938     for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3939         int ffdh_checks = 1;
3940 
3941         if (!ffdh_doit[testnum])
3942             continue;
3943 
3944         for (i = 0; i < loopargs_len; i++) {
3945             EVP_PKEY *pkey_A = NULL;
3946             EVP_PKEY *pkey_B = NULL;
3947             EVP_PKEY_CTX *ffdh_ctx = NULL;
3948             EVP_PKEY_CTX *test_ctx = NULL;
3949             size_t secret_size;
3950             size_t test_out;
3951 
3952             /* Ensure that the error queue is empty */
3953             if (ERR_peek_error()) {
3954                 BIO_printf(bio_err,
3955                     "WARNING: the error queue contains previous unhandled errors.\n");
3956                 dofail();
3957             }
3958 
3959             pkey_A = EVP_PKEY_new();
3960             if (!pkey_A) {
3961                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3962                 dofail();
3963                 op_count = 1;
3964                 ffdh_checks = 0;
3965                 break;
3966             }
3967             pkey_B = EVP_PKEY_new();
3968             if (!pkey_B) {
3969                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3970                 dofail();
3971                 op_count = 1;
3972                 ffdh_checks = 0;
3973                 break;
3974             }
3975 
3976             ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3977             if (!ffdh_ctx) {
3978                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3979                 dofail();
3980                 op_count = 1;
3981                 ffdh_checks = 0;
3982                 break;
3983             }
3984 
3985             if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3986                 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3987                 dofail();
3988                 op_count = 1;
3989                 ffdh_checks = 0;
3990                 break;
3991             }
3992             if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3993                 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3994                 dofail();
3995                 op_count = 1;
3996                 ffdh_checks = 0;
3997                 break;
3998             }
3999 
4000             if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
4001                 BIO_printf(bio_err, "FFDH key generation failure.\n");
4002                 dofail();
4003                 op_count = 1;
4004                 ffdh_checks = 0;
4005                 break;
4006             }
4007 
4008             EVP_PKEY_CTX_free(ffdh_ctx);
4009 
4010             /*
4011              * check if the derivation works correctly both ways so that
4012              * we know if future derive calls will fail, and we can skip
4013              * error checking in benchmarked code
4014              */
4015             ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
4016             if (ffdh_ctx == NULL) {
4017                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4018                 dofail();
4019                 op_count = 1;
4020                 ffdh_checks = 0;
4021                 break;
4022             }
4023             if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
4024                 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
4025                 dofail();
4026                 op_count = 1;
4027                 ffdh_checks = 0;
4028                 break;
4029             }
4030             if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
4031                 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
4032                 dofail();
4033                 op_count = 1;
4034                 ffdh_checks = 0;
4035                 break;
4036             }
4037             if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
4038                 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
4039                 dofail();
4040                 op_count = 1;
4041                 ffdh_checks = 0;
4042                 break;
4043             }
4044             if (secret_size > MAX_FFDH_SIZE) {
4045                 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
4046                 op_count = 1;
4047                 ffdh_checks = 0;
4048                 break;
4049             }
4050             if (EVP_PKEY_derive(ffdh_ctx,
4051                     loopargs[i].secret_ff_a,
4052                     &secret_size)
4053                 <= 0) {
4054                 BIO_printf(bio_err, "Shared secret derive failure.\n");
4055                 dofail();
4056                 op_count = 1;
4057                 ffdh_checks = 0;
4058                 break;
4059             }
4060             /* Now check from side B */
4061             test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
4062             if (!test_ctx) {
4063                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4064                 dofail();
4065                 op_count = 1;
4066                 ffdh_checks = 0;
4067                 break;
4068             }
4069             if (EVP_PKEY_derive_init(test_ctx) <= 0 || EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 || EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 || test_out != secret_size) {
4070                 BIO_printf(bio_err, "FFDH computation failure.\n");
4071                 op_count = 1;
4072                 ffdh_checks = 0;
4073                 break;
4074             }
4075 
4076             /* compare the computed secrets */
4077             if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
4078                     loopargs[i].secret_ff_b, secret_size)) {
4079                 BIO_printf(bio_err, "FFDH computations don't match.\n");
4080                 dofail();
4081                 op_count = 1;
4082                 ffdh_checks = 0;
4083                 break;
4084             }
4085 
4086             loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
4087 
4088             EVP_PKEY_free(pkey_A);
4089             pkey_A = NULL;
4090             EVP_PKEY_free(pkey_B);
4091             pkey_B = NULL;
4092             EVP_PKEY_CTX_free(test_ctx);
4093             test_ctx = NULL;
4094         }
4095         if (ffdh_checks != 0) {
4096             pkey_print_message("", "ffdh",
4097                 ffdh_params[testnum].bits, seconds.ffdh);
4098             Time_F(START);
4099             count = run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
4100             d = Time_F(STOP);
4101             BIO_printf(bio_err,
4102                 mr ? "+R14:%ld:%d:%.2f\n" : "%ld %u-bits FFDH ops in %.2fs\n", count,
4103                 ffdh_params[testnum].bits, d);
4104             ffdh_results[testnum][0] = (double)count / d;
4105             op_count = count;
4106         }
4107         if (op_count <= 1) {
4108             /* if longer than 10s, don't do any more */
4109             stop_it(ffdh_doit, testnum);
4110         }
4111     }
4112 #endif /* OPENSSL_NO_DH */
4113 
4114     for (testnum = 0; testnum < kems_algs_len; testnum++) {
4115         int kem_checks = 1;
4116         const char *kem_name = kems_algname[testnum];
4117 
4118         if (!kems_doit[testnum] || !do_kems)
4119             continue;
4120 
4121         for (i = 0; i < loopargs_len; i++) {
4122             EVP_PKEY *pkey = NULL;
4123             EVP_PKEY_CTX *kem_gen_ctx = NULL;
4124             EVP_PKEY_CTX *kem_encaps_ctx = NULL;
4125             EVP_PKEY_CTX *kem_decaps_ctx = NULL;
4126             size_t send_secret_len, out_len;
4127             size_t rcv_secret_len;
4128             unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
4129             unsigned int bits;
4130             char *name;
4131             char sfx[MAX_ALGNAME_SUFFIX];
4132             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4133             int use_params = 0;
4134             enum kem_type_t { KEM_RSA = 1,
4135                 KEM_EC,
4136                 KEM_X25519,
4137                 KEM_X448 } kem_type;
4138 
4139             /* no string after rsa<bitcnt> permitted: */
4140             if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4141                 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
4142                 kem_type = KEM_RSA;
4143             else if (strncmp(kem_name, "EC", 2) == 0)
4144                 kem_type = KEM_EC;
4145             else if (strcmp(kem_name, "X25519") == 0)
4146                 kem_type = KEM_X25519;
4147             else if (strcmp(kem_name, "X448") == 0)
4148                 kem_type = KEM_X448;
4149             else
4150                 kem_type = 0;
4151 
4152             if (ERR_peek_error()) {
4153                 BIO_printf(bio_err,
4154                     "WARNING: the error queue contains previous unhandled errors.\n");
4155                 dofail();
4156             }
4157 
4158             if (kem_type == KEM_RSA) {
4159                 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4160                     &bits);
4161                 use_params = 1;
4162             } else if (kem_type == KEM_EC) {
4163                 name = (char *)(kem_name + 2);
4164                 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
4165                     name, 0);
4166                 use_params = 1;
4167             }
4168 
4169             kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4170                 (kem_type == KEM_RSA) ? "RSA" : (kem_type == KEM_EC) ? "EC"
4171                                                                      : kem_name,
4172                 app_get0_propq());
4173 
4174             if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
4175                 || (use_params
4176                     && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
4177                 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4178                     kem_name);
4179                 goto kem_err_break;
4180             }
4181             if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
4182                 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
4183                 goto kem_err_break;
4184             }
4185             /* Now prepare encaps data structs */
4186             kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4187                 pkey,
4188                 app_get0_propq());
4189             if (kem_encaps_ctx == NULL
4190                 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
4191                 || (kem_type == KEM_RSA
4192                     && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
4193                 || ((kem_type == KEM_EC
4194                         || kem_type == KEM_X25519
4195                         || kem_type == KEM_X448)
4196                     && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
4197                 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
4198                        NULL, &send_secret_len)
4199                     <= 0) {
4200                 BIO_printf(bio_err,
4201                     "Error while initializing encaps data structs for %s.\n",
4202                     kem_name);
4203                 goto kem_err_break;
4204             }
4205             out = app_malloc(out_len, "encaps result");
4206             send_secret = app_malloc(send_secret_len, "encaps secret");
4207             if (out == NULL || send_secret == NULL) {
4208                 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
4209                 goto kem_err_break;
4210             }
4211             if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
4212                     send_secret, &send_secret_len)
4213                 <= 0) {
4214                 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
4215                 goto kem_err_break;
4216             }
4217             /* Now prepare decaps data structs */
4218             kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4219                 pkey,
4220                 app_get0_propq());
4221             if (kem_decaps_ctx == NULL
4222                 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
4223                 || (kem_type == KEM_RSA
4224                     && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
4225                 || ((kem_type == KEM_EC
4226                         || kem_type == KEM_X25519
4227                         || kem_type == KEM_X448)
4228                     && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
4229                 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
4230                        out, out_len)
4231                     <= 0) {
4232                 BIO_printf(bio_err,
4233                     "Error while initializing decaps data structs for %s.\n",
4234                     kem_name);
4235                 goto kem_err_break;
4236             }
4237             rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
4238             if (rcv_secret == NULL) {
4239                 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
4240                     kem_name);
4241                 goto kem_err_break;
4242             }
4243             if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
4244                     &rcv_secret_len, out, out_len)
4245                     <= 0
4246                 || rcv_secret_len != send_secret_len
4247                 || memcmp(send_secret, rcv_secret, send_secret_len)) {
4248                 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
4249                 goto kem_err_break;
4250             }
4251             loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
4252             loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
4253             loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
4254             loopargs[i].kem_out_len[testnum] = out_len;
4255             loopargs[i].kem_secret_len[testnum] = send_secret_len;
4256             loopargs[i].kem_out[testnum] = out;
4257             loopargs[i].kem_send_secret[testnum] = send_secret;
4258             loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
4259             EVP_PKEY_free(pkey);
4260             pkey = NULL;
4261             continue;
4262 
4263         kem_err_break:
4264             dofail();
4265             EVP_PKEY_free(pkey);
4266             op_count = 1;
4267             kem_checks = 0;
4268             break;
4269         }
4270         if (kem_checks != 0) {
4271             kskey_print_message(kem_name, "keygen", seconds.kem);
4272             Time_F(START);
4273             count = run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
4274             d = Time_F(STOP);
4275             BIO_printf(bio_err,
4276                 mr ? "+R15:%ld:%s:%.2f\n" : "%ld %s KEM keygen ops in %.2fs\n", count,
4277                 kem_name, d);
4278             kems_results[testnum][0] = (double)count / d;
4279             op_count = count;
4280             kskey_print_message(kem_name, "encaps", seconds.kem);
4281             Time_F(START);
4282             count = run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
4283             d = Time_F(STOP);
4284             BIO_printf(bio_err,
4285                 mr ? "+R16:%ld:%s:%.2f\n" : "%ld %s KEM encaps ops in %.2fs\n", count,
4286                 kem_name, d);
4287             kems_results[testnum][1] = (double)count / d;
4288             op_count = count;
4289             kskey_print_message(kem_name, "decaps", seconds.kem);
4290             Time_F(START);
4291             count = run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
4292             d = Time_F(STOP);
4293             BIO_printf(bio_err,
4294                 mr ? "+R17:%ld:%s:%.2f\n" : "%ld %s KEM decaps ops in %.2fs\n", count,
4295                 kem_name, d);
4296             kems_results[testnum][2] = (double)count / d;
4297             op_count = count;
4298         }
4299         if (op_count <= 1) {
4300             /* if longer than 10s, don't do any more */
4301             stop_it(kems_doit, testnum);
4302         }
4303     }
4304 
4305     for (testnum = 0; testnum < sigs_algs_len; testnum++) {
4306         int sig_checks = 1;
4307         const char *sig_name = sigs_algname[testnum];
4308 
4309         if (!sigs_doit[testnum] || !do_sigs)
4310             continue;
4311 
4312         for (i = 0; i < loopargs_len; i++) {
4313             EVP_PKEY *pkey = NULL;
4314             EVP_PKEY_CTX *ctx_params = NULL;
4315             EVP_PKEY *pkey_params = NULL;
4316             EVP_PKEY_CTX *sig_gen_ctx = NULL;
4317             EVP_PKEY_CTX *sig_sign_ctx = NULL;
4318             EVP_PKEY_CTX *sig_verify_ctx = NULL;
4319             EVP_SIGNATURE *alg = NULL;
4320             unsigned char md[SHA256_DIGEST_LENGTH];
4321             unsigned char *sig;
4322             char sfx[MAX_ALGNAME_SUFFIX];
4323             size_t md_len = SHA256_DIGEST_LENGTH;
4324             size_t max_sig_len, sig_len;
4325             unsigned int bits;
4326             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4327             int use_params = 0;
4328 
4329             /* only sign little data to avoid measuring digest performance */
4330             memset(md, 0, SHA256_DIGEST_LENGTH);
4331 
4332             if (ERR_peek_error()) {
4333                 BIO_printf(bio_err,
4334                     "WARNING: the error queue contains previous unhandled errors.\n");
4335                 dofail();
4336             }
4337 
4338             /* no string after rsa<bitcnt> permitted: */
4339             if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4340                 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
4341                 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4342                     &bits);
4343                 use_params = 1;
4344             }
4345 
4346             if (strncmp(sig_name, "dsa", 3) == 0) {
4347                 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
4348                 if (ctx_params == NULL
4349                     || EVP_PKEY_paramgen_init(ctx_params) <= 0
4350                     || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
4351                            atoi(sig_name + 3))
4352                         <= 0
4353                     || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
4354                     || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
4355                     || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
4356                     BIO_printf(bio_err,
4357                         "Error initializing classic keygen ctx for %s.\n",
4358                         sig_name);
4359                     goto sig_err_break;
4360                 }
4361             }
4362 
4363             if (sig_gen_ctx == NULL)
4364                 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4365                     use_params == 1 ? "RSA" : sig_name,
4366                     app_get0_propq());
4367 
4368             if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
4369                 || (use_params && EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
4370                 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4371                     sig_name);
4372                 goto sig_err_break;
4373             }
4374             if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
4375                 BIO_printf(bio_err,
4376                     "Error while generating signature EVP_PKEY for %s.\n",
4377                     sig_name);
4378                 goto sig_err_break;
4379             }
4380 
4381             /*
4382              * Try explicitly fetching the signature algorithm implementation to
4383              * use in case the algorithm does not support EVP_PKEY_sign_init
4384              */
4385             ERR_set_mark();
4386             alg = EVP_SIGNATURE_fetch(app_get0_libctx(), sig_name, app_get0_propq());
4387             ERR_pop_to_mark();
4388 
4389             /* Now prepare signature data structs */
4390             sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4391                 pkey,
4392                 app_get0_propq());
4393             if (sig_sign_ctx == NULL) {
4394                 BIO_printf(bio_err,
4395                     "Error while initializing signing ctx for %s.\n",
4396                     sig_name);
4397                 goto sig_err_break;
4398             }
4399             ERR_set_mark();
4400             if (EVP_PKEY_sign_init(sig_sign_ctx) <= 0
4401                 && (alg == NULL
4402                     || EVP_PKEY_sign_message_init(sig_sign_ctx, alg, NULL) <= 0)) {
4403                 ERR_clear_last_mark();
4404                 BIO_printf(bio_err,
4405                     "Error while initializing signing data structs for %s.\n",
4406                     sig_name);
4407                 goto sig_err_break;
4408             }
4409             ERR_pop_to_mark();
4410             if (use_params == 1 && EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx, RSA_PKCS1_PADDING) <= 0) {
4411                 BIO_printf(bio_err,
4412                     "Error while initializing padding for %s.\n",
4413                     sig_name);
4414                 goto sig_err_break;
4415             }
4416             if (EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len, md, md_len) <= 0) {
4417                 BIO_printf(bio_err,
4418                     "Error while obtaining signature buffer length for %s.\n",
4419                     sig_name);
4420                 goto sig_err_break;
4421             }
4422             sig = app_malloc(sig_len = max_sig_len, "signature buffer");
4423             if (sig == NULL) {
4424                 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
4425                 goto sig_err_break;
4426             }
4427             if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
4428                 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
4429                 goto sig_err_break;
4430             }
4431             /* Now prepare verify data structs */
4432             memset(md, 0, SHA256_DIGEST_LENGTH);
4433             sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4434                 pkey,
4435                 app_get0_propq());
4436             if (sig_verify_ctx == NULL) {
4437                 BIO_printf(bio_err,
4438                     "Error while initializing verify ctx for %s.\n",
4439                     sig_name);
4440                 goto sig_err_break;
4441             }
4442             ERR_set_mark();
4443             if (EVP_PKEY_verify_init(sig_verify_ctx) <= 0
4444                 && (alg == NULL
4445                     || EVP_PKEY_verify_message_init(sig_verify_ctx, alg, NULL) <= 0)) {
4446                 ERR_clear_last_mark();
4447                 BIO_printf(bio_err,
4448                     "Error while initializing verify data structs for %s.\n",
4449                     sig_name);
4450                 goto sig_err_break;
4451             }
4452             ERR_pop_to_mark();
4453             if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4454                 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
4455                 goto sig_err_break;
4456             }
4457             if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4458                 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4459                 goto sig_err_break;
4460             }
4461             loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4462             loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4463             loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4464             loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4465             loopargs[i].sig_act_sig_len[testnum] = sig_len;
4466             loopargs[i].sig_sig[testnum] = sig;
4467             EVP_PKEY_free(pkey);
4468             EVP_SIGNATURE_free(alg);
4469             pkey = NULL;
4470             continue;
4471 
4472         sig_err_break:
4473             dofail();
4474             EVP_PKEY_free(pkey);
4475             EVP_SIGNATURE_free(alg);
4476             op_count = 1;
4477             sig_checks = 0;
4478             break;
4479         }
4480 
4481         if (sig_checks != 0) {
4482             kskey_print_message(sig_name, "keygen", seconds.sig);
4483             Time_F(START);
4484             count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4485             d = Time_F(STOP);
4486             BIO_printf(bio_err,
4487                 mr ? "+R18:%ld:%s:%.2f\n" : "%ld %s signature keygen ops in %.2fs\n", count,
4488                 sig_name, d);
4489             sigs_results[testnum][0] = (double)count / d;
4490             op_count = count;
4491             kskey_print_message(sig_name, "signs", seconds.sig);
4492             Time_F(START);
4493             count = run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4494             d = Time_F(STOP);
4495             BIO_printf(bio_err,
4496                 mr ? "+R19:%ld:%s:%.2f\n" : "%ld %s signature sign ops in %.2fs\n", count,
4497                 sig_name, d);
4498             sigs_results[testnum][1] = (double)count / d;
4499             op_count = count;
4500 
4501             kskey_print_message(sig_name, "verify", seconds.sig);
4502             Time_F(START);
4503             count = run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4504             d = Time_F(STOP);
4505             BIO_printf(bio_err,
4506                 mr ? "+R20:%ld:%s:%.2f\n" : "%ld %s signature verify ops in %.2fs\n", count,
4507                 sig_name, d);
4508             sigs_results[testnum][2] = (double)count / d;
4509             op_count = count;
4510         }
4511         if (op_count <= 1)
4512             stop_it(sigs_doit, testnum);
4513     }
4514 
4515 #ifndef NO_FORK
4516 show_res:
4517 #endif
4518     if (!mr) {
4519         printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4520         printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4521         printf("options: %s\n", BN_options());
4522         printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4523         printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4524     }
4525 
4526     if (pr_header) {
4527         if (mr) {
4528             printf("+H");
4529         } else {
4530             printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4531             printf("type        ");
4532         }
4533         for (testnum = 0; testnum < size_num; testnum++)
4534             printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4535         printf("\n");
4536     }
4537 
4538     for (k = 0; k < ALGOR_NUM; k++) {
4539         const char *alg_name = names[k];
4540 
4541         if (!doit[k])
4542             continue;
4543 
4544         if (k == D_EVP) {
4545             if (evp_cipher == NULL)
4546                 alg_name = evp_md_name;
4547             else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4548                 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4549         }
4550 
4551         if (mr)
4552             printf("+F:%u:%s", k, alg_name);
4553         else
4554             printf("%-13s", alg_name);
4555         for (testnum = 0; testnum < size_num; testnum++) {
4556             if (results[k][testnum] > 10000 && !mr)
4557                 printf(" %11.2fk", results[k][testnum] / 1e3);
4558             else
4559                 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4560         }
4561         printf("\n");
4562     }
4563     testnum = 1;
4564     for (k = 0; k < RSA_NUM; k++) {
4565         if (!rsa_doit[k])
4566             continue;
4567         if (testnum && !mr) {
4568             printf("%19ssign    verify    encrypt   decrypt   sign/s verify/s  encr./s  decr./s\n", " ");
4569             testnum = 0;
4570         }
4571         if (mr)
4572             printf("+F2:%u:%u:%f:%f:%f:%f\n",
4573                 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4574                 rsa_results[k][2], rsa_results[k][3]);
4575         else
4576             printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4577                 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4578                 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4579                 1.0 / rsa_results[k][3],
4580                 rsa_results[k][0], rsa_results[k][1],
4581                 rsa_results[k][2], rsa_results[k][3]);
4582     }
4583     testnum = 1;
4584 #ifndef OPENSSL_NO_DSA
4585     for (k = 0; k < DSA_NUM; k++) {
4586         if (!dsa_doit[k])
4587             continue;
4588         if (testnum && !mr) {
4589             printf("%18ssign    verify    sign/s verify/s\n", " ");
4590             testnum = 0;
4591         }
4592         if (mr)
4593             printf("+F3:%u:%u:%f:%f\n",
4594                 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4595         else
4596             printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4597                 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4598                 dsa_results[k][0], dsa_results[k][1]);
4599     }
4600 #endif /* OPENSSL_NO_DSA */
4601     testnum = 1;
4602     for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4603         if (!ecdsa_doit[k])
4604             continue;
4605         if (testnum && !mr) {
4606             printf("%30ssign    verify    sign/s verify/s\n", " ");
4607             testnum = 0;
4608         }
4609 
4610         if (mr)
4611             printf("+F4:%u:%u:%f:%f\n",
4612                 k, ec_curves[k].bits,
4613                 ecdsa_results[k][0], ecdsa_results[k][1]);
4614         else
4615             printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4616                 ec_curves[k].bits, ec_curves[k].name,
4617                 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4618                 ecdsa_results[k][0], ecdsa_results[k][1]);
4619     }
4620 
4621     testnum = 1;
4622     for (k = 0; k < EC_NUM; k++) {
4623         if (!ecdh_doit[k])
4624             continue;
4625         if (testnum && !mr) {
4626             printf("%30sop      op/s\n", " ");
4627             testnum = 0;
4628         }
4629         if (mr)
4630             printf("+F5:%u:%u:%f:%f\n",
4631                 k, ec_curves[k].bits,
4632                 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4633 
4634         else
4635             printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4636                 ec_curves[k].bits, ec_curves[k].name,
4637                 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4638     }
4639 
4640 #ifndef OPENSSL_NO_ECX
4641     testnum = 1;
4642     for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4643         if (!eddsa_doit[k])
4644             continue;
4645         if (testnum && !mr) {
4646             printf("%30ssign    verify    sign/s verify/s\n", " ");
4647             testnum = 0;
4648         }
4649 
4650         if (mr)
4651             printf("+F6:%u:%u:%s:%f:%f\n",
4652                 k, ed_curves[k].bits, ed_curves[k].name,
4653                 eddsa_results[k][0], eddsa_results[k][1]);
4654         else
4655             printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4656                 ed_curves[k].bits, ed_curves[k].name,
4657                 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4658                 eddsa_results[k][0], eddsa_results[k][1]);
4659     }
4660 #endif /* OPENSSL_NO_ECX */
4661 
4662 #ifndef OPENSSL_NO_SM2
4663     testnum = 1;
4664     for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4665         if (!sm2_doit[k])
4666             continue;
4667         if (testnum && !mr) {
4668             printf("%30ssign    verify    sign/s verify/s\n", " ");
4669             testnum = 0;
4670         }
4671 
4672         if (mr)
4673             printf("+F7:%u:%u:%s:%f:%f\n",
4674                 k, sm2_curves[k].bits, sm2_curves[k].name,
4675                 sm2_results[k][0], sm2_results[k][1]);
4676         else
4677             printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4678                 sm2_curves[k].bits, sm2_curves[k].name,
4679                 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4680                 sm2_results[k][0], sm2_results[k][1]);
4681     }
4682 #endif
4683 #ifndef OPENSSL_NO_DH
4684     testnum = 1;
4685     for (k = 0; k < FFDH_NUM; k++) {
4686         if (!ffdh_doit[k])
4687             continue;
4688         if (testnum && !mr) {
4689             printf("%23sop     op/s\n", " ");
4690             testnum = 0;
4691         }
4692         if (mr)
4693             printf("+F8:%u:%u:%f:%f\n",
4694                 k, ffdh_params[k].bits,
4695                 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4696 
4697         else
4698             printf("%4u bits ffdh %8.4fs %8.1f\n",
4699                 ffdh_params[k].bits,
4700                 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4701     }
4702 #endif /* OPENSSL_NO_DH */
4703 
4704     testnum = 1;
4705     for (k = 0; k < kems_algs_len; k++) {
4706         const char *kem_name = kems_algname[k];
4707 
4708         if (!kems_doit[k] || !do_kems)
4709             continue;
4710         if (testnum && !mr) {
4711             printf("%31skeygen    encaps    decaps keygens/s  encaps/s  decaps/s\n", " ");
4712             testnum = 0;
4713         }
4714         if (mr)
4715             printf("+F9:%u:%f:%f:%f\n",
4716                 k, kems_results[k][0], kems_results[k][1],
4717                 kems_results[k][2]);
4718         else
4719             printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4720                 1.0 / kems_results[k][0],
4721                 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4722                 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4723     }
4724     ret = 0;
4725 
4726     testnum = 1;
4727     for (k = 0; k < sigs_algs_len; k++) {
4728         const char *sig_name = sigs_algname[k];
4729 
4730         if (!sigs_doit[k] || !do_sigs)
4731             continue;
4732         if (testnum && !mr) {
4733             printf("%31skeygen     signs    verify keygens/s    sign/s  verify/s\n", " ");
4734             testnum = 0;
4735         }
4736         if (mr)
4737             printf("+F10:%u:%f:%f:%f\n",
4738                 k, sigs_results[k][0], sigs_results[k][1],
4739                 sigs_results[k][2]);
4740         else
4741             printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4742                 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4743                 1.0 / sigs_results[k][2], sigs_results[k][0],
4744                 sigs_results[k][1], sigs_results[k][2]);
4745     }
4746     ret = 0;
4747 
4748 end:
4749     if (ret == 0 && testmode)
4750         ret = testmoderesult;
4751     ERR_print_errors(bio_err);
4752     for (i = 0; i < loopargs_len; i++) {
4753         OPENSSL_free(loopargs[i].buf_malloc);
4754         OPENSSL_free(loopargs[i].buf2_malloc);
4755 
4756         BN_free(bn);
4757         EVP_PKEY_CTX_free(genctx);
4758         for (k = 0; k < RSA_NUM; k++) {
4759             EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4760             EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4761             EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]);
4762             EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]);
4763         }
4764 #ifndef OPENSSL_NO_DH
4765         OPENSSL_free(loopargs[i].secret_ff_a);
4766         OPENSSL_free(loopargs[i].secret_ff_b);
4767         for (k = 0; k < FFDH_NUM; k++)
4768             EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4769 #endif
4770 #ifndef OPENSSL_NO_DSA
4771         for (k = 0; k < DSA_NUM; k++) {
4772             EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4773             EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4774         }
4775 #endif
4776         for (k = 0; k < ECDSA_NUM; k++) {
4777             EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4778             EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4779         }
4780         for (k = 0; k < EC_NUM; k++)
4781             EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4782 #ifndef OPENSSL_NO_ECX
4783         for (k = 0; k < EdDSA_NUM; k++) {
4784             EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4785             EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4786         }
4787 #endif /* OPENSSL_NO_ECX */
4788 #ifndef OPENSSL_NO_SM2
4789         for (k = 0; k < SM2_NUM; k++) {
4790             EVP_PKEY_CTX *pctx = NULL;
4791 
4792             /* free signing ctx */
4793             if (loopargs[i].sm2_ctx[k] != NULL
4794                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4795                 EVP_PKEY_CTX_free(pctx);
4796             EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4797             /* free verification ctx */
4798             if (loopargs[i].sm2_vfy_ctx[k] != NULL
4799                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4800                 EVP_PKEY_CTX_free(pctx);
4801             EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4802             /* free pkey */
4803             EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4804         }
4805 #endif
4806         for (k = 0; k < kems_algs_len; k++) {
4807             EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4808             EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4809             EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4810             OPENSSL_free(loopargs[i].kem_out[k]);
4811             OPENSSL_free(loopargs[i].kem_send_secret[k]);
4812             OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4813         }
4814         for (k = 0; k < sigs_algs_len; k++) {
4815             EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4816             EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4817             EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4818             OPENSSL_free(loopargs[i].sig_sig[k]);
4819         }
4820         OPENSSL_free(loopargs[i].secret_a);
4821         OPENSSL_free(loopargs[i].secret_b);
4822     }
4823     OPENSSL_free(evp_hmac_name);
4824     OPENSSL_free(evp_cmac_name);
4825     for (k = 0; k < kems_algs_len; k++)
4826         OPENSSL_free(kems_algname[k]);
4827     if (kem_stack != NULL)
4828         sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4829     for (k = 0; k < sigs_algs_len; k++)
4830         OPENSSL_free(sigs_algname[k]);
4831     if (sig_stack != NULL)
4832         sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4833 
4834     if (async_jobs > 0) {
4835         for (i = 0; i < loopargs_len; i++)
4836             ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4837     }
4838 
4839     if (async_init) {
4840         ASYNC_cleanup_thread();
4841     }
4842     OPENSSL_free(loopargs);
4843     release_engine(e);
4844     EVP_CIPHER_free(evp_cipher);
4845     EVP_MAC_free(mac);
4846     NCONF_free(conf);
4847     return ret;
4848 }
4849 
4850 static void print_message(const char *s, int length, int tm)
4851 {
4852     BIO_printf(bio_err,
4853         mr ? "+DT:%s:%d:%d\n"
4854            : "Doing %s ops for %ds on %d size blocks: ",
4855         s, tm, length);
4856     (void)BIO_flush(bio_err);
4857     run = 1;
4858     alarm(tm);
4859 }
4860 
4861 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4862     int tm)
4863 {
4864     BIO_printf(bio_err,
4865         mr ? "+DTP:%d:%s:%s:%d\n"
4866            : "Doing %u bits %s %s ops for %ds: ",
4867         bits, str, str2, tm);
4868     (void)BIO_flush(bio_err);
4869     run = 1;
4870     alarm(tm);
4871 }
4872 
4873 static void kskey_print_message(const char *str, const char *str2, int tm)
4874 {
4875     BIO_printf(bio_err,
4876         mr ? "+DTP:%s:%s:%d\n"
4877            : "Doing %s %s ops for %ds: ",
4878         str, str2, tm);
4879     (void)BIO_flush(bio_err);
4880     run = 1;
4881     alarm(tm);
4882 }
4883 
4884 static void print_result(int alg, int run_no, int count, double time_used)
4885 {
4886     if (count == -1) {
4887         BIO_printf(bio_err, "%s error!\n", names[alg]);
4888         dofail();
4889         return;
4890     }
4891     BIO_printf(bio_err,
4892         mr ? "+R:%d:%s:%f\n"
4893            : "%d %s ops in %.2fs\n",
4894         count, names[alg], time_used);
4895     results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4896 }
4897 
4898 #ifndef NO_FORK
4899 static char *sstrsep(char **string, const char *delim)
4900 {
4901     char isdelim[256];
4902     char *token = *string;
4903 
4904     memset(isdelim, 0, sizeof(isdelim));
4905     isdelim[0] = 1;
4906 
4907     while (*delim) {
4908         isdelim[(unsigned char)(*delim)] = 1;
4909         delim++;
4910     }
4911 
4912     while (!isdelim[(unsigned char)(**string)])
4913         (*string)++;
4914 
4915     if (**string) {
4916         **string = 0;
4917         (*string)++;
4918     }
4919 
4920     return token;
4921 }
4922 
4923 static int strtoint(const char *str, const int min_val, const int upper_val,
4924     int *res)
4925 {
4926     char *end = NULL;
4927     long int val = 0;
4928 
4929     errno = 0;
4930     val = strtol(str, &end, 10);
4931     if (errno == 0 && end != str && *end == 0
4932         && min_val <= val && val < upper_val) {
4933         *res = (int)val;
4934         return 1;
4935     } else {
4936         return 0;
4937     }
4938 }
4939 
4940 static int do_multi(int multi, int size_num)
4941 {
4942     int n;
4943     int fd[2];
4944     int *fds;
4945     int status;
4946     static char sep[] = ":";
4947 
4948     fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4949     for (n = 0; n < multi; ++n) {
4950         if (pipe(fd) == -1) {
4951             BIO_printf(bio_err, "pipe failure\n");
4952             exit(1);
4953         }
4954         fflush(stdout);
4955         (void)BIO_flush(bio_err);
4956         if (fork()) {
4957             close(fd[1]);
4958             fds[n] = fd[0];
4959         } else {
4960             close(fd[0]);
4961             close(1);
4962             if (dup(fd[1]) == -1) {
4963                 BIO_printf(bio_err, "dup failed\n");
4964                 exit(1);
4965             }
4966             close(fd[1]);
4967             mr = 1;
4968             usertime = 0;
4969             OPENSSL_free(fds);
4970             return 0;
4971         }
4972         printf("Forked child %d\n", n);
4973     }
4974 
4975     /* for now, assume the pipe is long enough to take all the output */
4976     for (n = 0; n < multi; ++n) {
4977         FILE *f;
4978         char buf[1024];
4979         char *p;
4980         char *tk;
4981         int k;
4982         double d;
4983 
4984         if ((f = fdopen(fds[n], "r")) == NULL) {
4985             BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4986                 errno);
4987             OPENSSL_free(fds);
4988             return 1;
4989         }
4990         while (fgets(buf, sizeof(buf), f)) {
4991             p = strchr(buf, '\n');
4992             if (p)
4993                 *p = '\0';
4994             if (buf[0] != '+') {
4995                 BIO_printf(bio_err,
4996                     "Don't understand line '%s' from child %d\n", buf,
4997                     n);
4998                 continue;
4999             }
5000             printf("Got: %s from %d\n", buf, n);
5001             p = buf;
5002             if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
5003                 int alg;
5004                 int j;
5005 
5006                 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
5007                     sstrsep(&p, sep);
5008                     for (j = 0; j < size_num; ++j)
5009                         results[alg][j] += atof(sstrsep(&p, sep));
5010                 }
5011             } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
5012                 tk = sstrsep(&p, sep);
5013                 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
5014                     sstrsep(&p, sep);
5015 
5016                     d = atof(sstrsep(&p, sep));
5017                     rsa_results[k][0] += d;
5018 
5019                     d = atof(sstrsep(&p, sep));
5020                     rsa_results[k][1] += d;
5021 
5022                     d = atof(sstrsep(&p, sep));
5023                     rsa_results[k][2] += d;
5024 
5025                     d = atof(sstrsep(&p, sep));
5026                     rsa_results[k][3] += d;
5027                 }
5028 #ifndef OPENSSL_NO_DSA
5029             } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
5030                 tk = sstrsep(&p, sep);
5031                 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
5032                     sstrsep(&p, sep);
5033 
5034                     d = atof(sstrsep(&p, sep));
5035                     dsa_results[k][0] += d;
5036 
5037                     d = atof(sstrsep(&p, sep));
5038                     dsa_results[k][1] += d;
5039                 }
5040 #endif /* OPENSSL_NO_DSA */
5041             } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
5042                 tk = sstrsep(&p, sep);
5043                 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
5044                     sstrsep(&p, sep);
5045 
5046                     d = atof(sstrsep(&p, sep));
5047                     ecdsa_results[k][0] += d;
5048 
5049                     d = atof(sstrsep(&p, sep));
5050                     ecdsa_results[k][1] += d;
5051                 }
5052             } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
5053                 tk = sstrsep(&p, sep);
5054                 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
5055                     sstrsep(&p, sep);
5056 
5057                     d = atof(sstrsep(&p, sep));
5058                     ecdh_results[k][0] += d;
5059                 }
5060 #ifndef OPENSSL_NO_ECX
5061             } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
5062                 tk = sstrsep(&p, sep);
5063                 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
5064                     sstrsep(&p, sep);
5065                     sstrsep(&p, sep);
5066 
5067                     d = atof(sstrsep(&p, sep));
5068                     eddsa_results[k][0] += d;
5069 
5070                     d = atof(sstrsep(&p, sep));
5071                     eddsa_results[k][1] += d;
5072                 }
5073 #endif /* OPENSSL_NO_ECX */
5074 #ifndef OPENSSL_NO_SM2
5075             } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
5076                 tk = sstrsep(&p, sep);
5077                 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
5078                     sstrsep(&p, sep);
5079                     sstrsep(&p, sep);
5080 
5081                     d = atof(sstrsep(&p, sep));
5082                     sm2_results[k][0] += d;
5083 
5084                     d = atof(sstrsep(&p, sep));
5085                     sm2_results[k][1] += d;
5086                 }
5087 #endif /* OPENSSL_NO_SM2 */
5088 #ifndef OPENSSL_NO_DH
5089             } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
5090                 tk = sstrsep(&p, sep);
5091                 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
5092                     sstrsep(&p, sep);
5093 
5094                     d = atof(sstrsep(&p, sep));
5095                     ffdh_results[k][0] += d;
5096                 }
5097 #endif /* OPENSSL_NO_DH */
5098             } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
5099                 tk = sstrsep(&p, sep);
5100                 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
5101                     d = atof(sstrsep(&p, sep));
5102                     kems_results[k][0] += d;
5103 
5104                     d = atof(sstrsep(&p, sep));
5105                     kems_results[k][1] += d;
5106 
5107                     d = atof(sstrsep(&p, sep));
5108                     kems_results[k][2] += d;
5109                 }
5110             } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
5111                 tk = sstrsep(&p, sep);
5112                 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
5113                     d = atof(sstrsep(&p, sep));
5114                     sigs_results[k][0] += d;
5115 
5116                     d = atof(sstrsep(&p, sep));
5117                     sigs_results[k][1] += d;
5118 
5119                     d = atof(sstrsep(&p, sep));
5120                     sigs_results[k][2] += d;
5121                 }
5122             } else if (!HAS_PREFIX(buf, "+H:")) {
5123                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
5124                     n);
5125             }
5126         }
5127 
5128         fclose(f);
5129     }
5130     OPENSSL_free(fds);
5131     for (n = 0; n < multi; ++n) {
5132         while (wait(&status) == -1)
5133             if (errno != EINTR) {
5134                 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
5135                     errno);
5136                 return 1;
5137             }
5138         if (WIFEXITED(status) && WEXITSTATUS(status)) {
5139             BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
5140         } else if (WIFSIGNALED(status)) {
5141             BIO_printf(bio_err, "Child terminated by signal %d\n",
5142                 WTERMSIG(status));
5143         }
5144     }
5145     return 1;
5146 }
5147 #endif
5148 
5149 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
5150     const openssl_speed_sec_t *seconds)
5151 {
5152     static const int mblengths_list[] = {
5153         8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024
5154     };
5155     const int *mblengths = mblengths_list;
5156     int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
5157     const char *alg_name;
5158     unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
5159     EVP_CIPHER_CTX *ctx = NULL;
5160     double d = 0.0;
5161 
5162     if (lengths_single) {
5163         mblengths = &lengths_single;
5164         num = 1;
5165     }
5166 
5167     inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
5168     out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
5169     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
5170         app_bail_out("failed to allocate cipher context\n");
5171     if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
5172         app_bail_out("failed to initialise cipher context\n");
5173 
5174     if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
5175         BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
5176         goto err;
5177     }
5178     key = app_malloc(keylen, "evp_cipher key");
5179     if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
5180         app_bail_out("failed to generate random cipher key\n");
5181     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
5182         app_bail_out("failed to set cipher key\n");
5183     OPENSSL_clear_free(key, keylen);
5184 
5185     if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
5186             sizeof(no_key), no_key)
5187         <= 0)
5188         app_bail_out("failed to set AEAD key\n");
5189     if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
5190         app_bail_out("failed to get cipher name\n");
5191 
5192     for (j = 0; j < num; j++) {
5193         print_message(alg_name, mblengths[j], seconds->sym);
5194         Time_F(START);
5195         for (count = 0; run && COND(count); count++) {
5196             EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
5197             size_t len = mblengths[j];
5198             int packlen;
5199 
5200             memset(aad, 0, 8); /* avoid uninitialized values */
5201             aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
5202             aad[9] = 3; /* version */
5203             aad[10] = 2;
5204             aad[11] = 0; /* length */
5205             aad[12] = 0;
5206             mb_param.out = NULL;
5207             mb_param.inp = aad;
5208             mb_param.len = len;
5209             mb_param.interleave = 8;
5210 
5211             packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
5212                 sizeof(mb_param), &mb_param);
5213 
5214             if (packlen > 0) {
5215                 mb_param.out = out;
5216                 mb_param.inp = inp;
5217                 mb_param.len = len;
5218                 (void)EVP_CIPHER_CTX_ctrl(ctx,
5219                     EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
5220                     sizeof(mb_param), &mb_param);
5221             } else {
5222                 int pad;
5223 
5224                 if (RAND_bytes(inp, 16) <= 0)
5225                     app_bail_out("error setting random bytes\n");
5226                 len += 16;
5227                 aad[11] = (unsigned char)(len >> 8);
5228                 aad[12] = (unsigned char)(len);
5229                 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
5230                     EVP_AEAD_TLS1_AAD_LEN, aad);
5231                 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
5232             }
5233         }
5234         d = Time_F(STOP);
5235         BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" : "%d %s ops in %.2fs\n", count, "evp", d);
5236         if ((ciph_success <= 0) && (mr == 0))
5237             BIO_printf(bio_err, "Error performing cipher op\n");
5238         results[D_EVP][j] = ((double)count) / d * mblengths[j];
5239     }
5240 
5241     if (mr) {
5242         fprintf(stdout, "+H");
5243         for (j = 0; j < num; j++)
5244             fprintf(stdout, ":%d", mblengths[j]);
5245         fprintf(stdout, "\n");
5246         fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
5247         for (j = 0; j < num; j++)
5248             fprintf(stdout, ":%.2f", results[D_EVP][j]);
5249         fprintf(stdout, "\n");
5250     } else {
5251         fprintf(stdout,
5252             "The 'numbers' are in 1000s of bytes per second processed.\n");
5253         fprintf(stdout, "type                    ");
5254         for (j = 0; j < num; j++)
5255             fprintf(stdout, "%7d bytes", mblengths[j]);
5256         fprintf(stdout, "\n");
5257         fprintf(stdout, "%-24s", alg_name);
5258 
5259         for (j = 0; j < num; j++) {
5260             if (results[D_EVP][j] > 10000)
5261                 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
5262             else
5263                 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
5264         }
5265         fprintf(stdout, "\n");
5266     }
5267 
5268 err:
5269     OPENSSL_free(inp);
5270     OPENSSL_free(out);
5271     EVP_CIPHER_CTX_free(ctx);
5272 }
5273