xref: /freebsd/crypto/openssl/apps/speed.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 1995-2025 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 
alarmed(ossl_unused int sig)151 static void alarmed(ossl_unused int sig)
152 {
153     signal(SIGALRM, alarmed);
154     run = 0;
155 }
156 
Time_F(int s)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;
alarm_win32(unsigned int secs)171 static void alarm_win32(unsigned int secs)
172 {
173     lapse = secs * 1000;
174 }
175 
176 #define alarm alarm_win32
177 
sleepy(VOID * arg)178 static DWORD WINAPI sleepy(VOID *arg)
179 {
180     schlock = 1;
181     Sleep(lapse);
182     run = 0;
183     return 0;
184 }
185 
Time_F(int s)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 
opt_found(const char * name,unsigned int * result,const OPT_PAIR pairs[],unsigned int nbelem)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 
dofail(void)670 static void dofail(void)
671 {
672     ERR_print_errors(bio_err);
673     testmoderesult = 1;
674 }
675 
have_md(const char * name)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 
have_cipher(const char * name)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 
EVP_Digest_loop(const char * mdname,ossl_unused int algindex,void * args)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 
EVP_Digest_md_loop(void * args)750 static int EVP_Digest_md_loop(void *args)
751 {
752     return EVP_Digest_loop(evp_md_name, D_EVP, args);
753 }
754 
EVP_Digest_MD2_loop(void * args)755 static int EVP_Digest_MD2_loop(void *args)
756 {
757     return EVP_Digest_loop("md2", D_MD2, args);
758 }
759 
EVP_Digest_MDC2_loop(void * args)760 static int EVP_Digest_MDC2_loop(void *args)
761 {
762     return EVP_Digest_loop("mdc2", D_MDC2, args);
763 }
764 
EVP_Digest_MD4_loop(void * args)765 static int EVP_Digest_MD4_loop(void *args)
766 {
767     return EVP_Digest_loop("md4", D_MD4, args);
768 }
769 
MD5_loop(void * args)770 static int MD5_loop(void *args)
771 {
772     return EVP_Digest_loop("md5", D_MD5, args);
773 }
774 
mac_setup(const char * name,EVP_MAC ** mac,OSSL_PARAM params[],loopargs_t * loopargs,unsigned int loopargs_len)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 
mac_teardown(EVP_MAC ** mac,loopargs_t * loopargs,unsigned int loopargs_len)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 
EVP_MAC_loop(ossl_unused int algindex,void * args)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 
HMAC_loop(void * args)829 static int HMAC_loop(void *args)
830 {
831     return EVP_MAC_loop(D_HMAC, args);
832 }
833 
CMAC_loop(void * args)834 static int CMAC_loop(void *args)
835 {
836     return EVP_MAC_loop(D_EVP_CMAC, args);
837 }
838 
KMAC128_loop(void * args)839 static int KMAC128_loop(void *args)
840 {
841     return EVP_MAC_loop(D_KMAC128, args);
842 }
843 
KMAC256_loop(void * args)844 static int KMAC256_loop(void *args)
845 {
846     return EVP_MAC_loop(D_KMAC256, args);
847 }
848 
SHA1_loop(void * args)849 static int SHA1_loop(void *args)
850 {
851     return EVP_Digest_loop("sha1", D_SHA1, args);
852 }
853 
SHA256_loop(void * args)854 static int SHA256_loop(void *args)
855 {
856     return EVP_Digest_loop("sha256", D_SHA256, args);
857 }
858 
SHA512_loop(void * args)859 static int SHA512_loop(void *args)
860 {
861     return EVP_Digest_loop("sha512", D_SHA512, args);
862 }
863 
WHIRLPOOL_loop(void * args)864 static int WHIRLPOOL_loop(void *args)
865 {
866     return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
867 }
868 
EVP_Digest_RMD160_loop(void * args)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 
EVP_Cipher_loop(void * args)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 
GHASH_loop(void * args)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 
init_evp_cipher_ctx(const char * ciphername,const unsigned char * key,int keylen)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 
RAND_bytes_loop(void * args)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;
EVP_Update_loop(void * args)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  */
EVP_Update_loop_aead_enc(void * args)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  */
EVP_Update_loop_aead_dec(void * args)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 
RSA_sign_loop(void * args)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 
RSA_verify_loop(void * args)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 
RSA_encrypt_loop(void * args)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 
RSA_decrypt_loop(void * args)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 
FFDH_derive_key_loop(void * args)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
DSA_sign_loop(void * args)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 
DSA_verify_loop(void * args)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 
ECDSA_sign_loop(void * args)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 
ECDSA_verify_loop(void * args)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 
ECDH_EVP_derive_key_loop(void * args)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
EdDSA_sign_loop(void * args)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 
EdDSA_verify_loop(void * args)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
SM2_sign_loop(void * args)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 
SM2_verify_loop(void * args)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 
KEM_keygen_loop(void * args)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 
KEM_encaps_loop(void * args)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 
KEM_decaps_loop(void * args)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 
SIG_keygen_loop(void * args)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 
SIG_sign_loop(void * args)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 
SIG_verify_loop(void * args)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 
check_block_size(EVP_CIPHER_CTX * ctx,int length)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 
run_benchmark(int async_jobs,int (* loop_function)(void *),loopargs_t * loopargs)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 
get_ecdsa(const EC_CURVE * curve)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 
IS_FETCHABLE(signature,EVP_SIGNATURE)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 
collect_kem(EVP_KEM * kem,void * stack)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 
kem_locate(const char * algo,unsigned int * idx)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 
DEFINE_STACK_OF(EVP_SIGNATURE)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 
collect_signatures(EVP_SIGNATURE * sig,void * stack)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 
sig_locate(const char * algo,unsigned int * idx)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 
get_max(const uint8_t doit[],size_t algs_len)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 
speed_main(int argc,char ** argv)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                             BIO_printf(bio_err, "\nFailed to get the tag\n");
3144                             dofail();
3145                             exit(1);
3146                         }
3147 
3148                         EVP_CIPHER_CTX_free(loopargs[k].ctx);
3149                         loopargs[k].ctx = EVP_CIPHER_CTX_new();
3150                         if (loopargs[k].ctx == NULL) {
3151                             BIO_printf(bio_err,
3152                                 "\nEVP_CIPHER_CTX_new failure\n");
3153                             exit(1);
3154                         }
3155                         if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher,
3156                                 NULL, NULL, NULL, 0)) {
3157                             BIO_printf(bio_err,
3158                                 "\nFailed initializing the context\n");
3159                             dofail();
3160                             exit(1);
3161                         }
3162 
3163                         EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
3164 
3165                         /* GCM-SIV/SIV only allows for a single Update operation */
3166                         if (mode_op == EVP_CIPH_SIV_MODE
3167                             || mode_op == EVP_CIPH_GCM_SIV_MODE)
3168                             EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3169                                 EVP_CTRL_SET_SPEED, 1, NULL);
3170                     }
3171                 }
3172 
3173                 Time_F(START);
3174                 count = run_benchmark(async_jobs, loopfunc, loopargs);
3175                 d = Time_F(STOP);
3176                 for (k = 0; k < loopargs_len; k++) {
3177                     OPENSSL_clear_free(loopargs[k].key, keylen);
3178                     EVP_CIPHER_CTX_free(loopargs[k].ctx);
3179                 }
3180                 print_result(D_EVP, testnum, count, d);
3181             }
3182         } else if (evp_md_name != NULL) {
3183             names[D_EVP] = evp_md_name;
3184 
3185             for (testnum = 0; testnum < size_num; testnum++) {
3186                 print_message(names[D_EVP], lengths[testnum], seconds.sym);
3187                 Time_F(START);
3188                 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
3189                 d = Time_F(STOP);
3190                 print_result(D_EVP, testnum, count, d);
3191                 if (count < 0)
3192                     break;
3193             }
3194         }
3195     }
3196 
3197     if (doit[D_EVP_CMAC]) {
3198         size_t len = sizeof("cmac()") + strlen(evp_mac_ciphername);
3199         OSSL_PARAM params[3];
3200         EVP_CIPHER *cipher = NULL;
3201 
3202         if (!opt_cipher(evp_mac_ciphername, &cipher))
3203             goto end;
3204 
3205         keylen = EVP_CIPHER_get_key_length(cipher);
3206         EVP_CIPHER_free(cipher);
3207         if (keylen <= 0 || keylen > (int)sizeof(key32)) {
3208             BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
3209             goto end;
3210         }
3211         evp_cmac_name = app_malloc(len, "CMAC name");
3212         BIO_snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername);
3213         names[D_EVP_CMAC] = evp_cmac_name;
3214 
3215         params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
3216             evp_mac_ciphername, 0);
3217         params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3218             (char *)key32, keylen);
3219         params[2] = OSSL_PARAM_construct_end();
3220 
3221         if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
3222             goto end;
3223         for (testnum = 0; testnum < size_num; testnum++) {
3224             print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
3225             Time_F(START);
3226             count = run_benchmark(async_jobs, CMAC_loop, loopargs);
3227             d = Time_F(STOP);
3228             print_result(D_EVP_CMAC, testnum, count, d);
3229             if (count < 0)
3230                 break;
3231         }
3232         mac_teardown(&mac, loopargs, loopargs_len);
3233     }
3234 
3235     if (doit[D_KMAC128]) {
3236         OSSL_PARAM params[2];
3237 
3238         params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3239             (void *)key32, 16);
3240         params[1] = OSSL_PARAM_construct_end();
3241 
3242         if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
3243             goto end;
3244         for (testnum = 0; testnum < size_num; testnum++) {
3245             print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
3246             Time_F(START);
3247             count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
3248             d = Time_F(STOP);
3249             print_result(D_KMAC128, testnum, count, d);
3250             if (count < 0)
3251                 break;
3252         }
3253         mac_teardown(&mac, loopargs, loopargs_len);
3254     }
3255 
3256     if (doit[D_KMAC256]) {
3257         OSSL_PARAM params[2];
3258 
3259         params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3260             (void *)key32, 32);
3261         params[1] = OSSL_PARAM_construct_end();
3262 
3263         if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
3264             goto end;
3265         for (testnum = 0; testnum < size_num; testnum++) {
3266             print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
3267             Time_F(START);
3268             count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
3269             d = Time_F(STOP);
3270             print_result(D_KMAC256, testnum, count, d);
3271             if (count < 0)
3272                 break;
3273         }
3274         mac_teardown(&mac, loopargs, loopargs_len);
3275     }
3276 
3277     for (i = 0; i < loopargs_len; i++)
3278         if (RAND_bytes(loopargs[i].buf, 36) <= 0)
3279             goto end;
3280 
3281     for (testnum = 0; testnum < RSA_NUM; testnum++) {
3282         EVP_PKEY *rsa_key = NULL;
3283         int st = 0;
3284 
3285         if (!rsa_doit[testnum])
3286             continue;
3287 
3288         if (primes > RSA_DEFAULT_PRIME_NUM) {
3289             /* we haven't set keys yet,  generate multi-prime RSA keys */
3290             bn = BN_new();
3291             st = bn != NULL
3292                 && BN_set_word(bn, RSA_F4)
3293                 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
3294                 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
3295                 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
3296                 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
3297                 && EVP_PKEY_keygen(genctx, &rsa_key) > 0;
3298             BN_free(bn);
3299             bn = NULL;
3300             EVP_PKEY_CTX_free(genctx);
3301             genctx = NULL;
3302         } else {
3303             const unsigned char *p = rsa_keys[testnum].data;
3304 
3305             st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
3306                       rsa_keys[testnum].length))
3307                 != NULL;
3308         }
3309 
3310         for (i = 0; st && i < loopargs_len; i++) {
3311             loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3312             loopargs[i].sigsize = loopargs[i].buflen;
3313             if (loopargs[i].rsa_sign_ctx[testnum] == NULL
3314                 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
3315                 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
3316                        loopargs[i].buf2,
3317                        &loopargs[i].sigsize,
3318                        loopargs[i].buf, 36)
3319                     <= 0)
3320                 st = 0;
3321         }
3322         if (!st) {
3323             BIO_printf(bio_err,
3324                 "RSA sign setup failure.  No RSA sign will be done.\n");
3325             dofail();
3326             op_count = 1;
3327         } else {
3328             pkey_print_message("private", "rsa sign",
3329                 rsa_keys[testnum].bits, seconds.rsa);
3330             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3331             Time_F(START);
3332             count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
3333             d = Time_F(STOP);
3334             BIO_printf(bio_err,
3335                 mr ? "+R1:%ld:%d:%.2f\n"
3336                    : "%ld %u bits private RSA sign ops in %.2fs\n",
3337                 count, rsa_keys[testnum].bits, d);
3338             rsa_results[testnum][0] = (double)count / d;
3339             op_count = count;
3340         }
3341 
3342         for (i = 0; st && i < loopargs_len; i++) {
3343             loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
3344                 NULL);
3345             if (loopargs[i].rsa_verify_ctx[testnum] == NULL
3346                 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
3347                 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
3348                        loopargs[i].buf2,
3349                        loopargs[i].sigsize,
3350                        loopargs[i].buf, 36)
3351                     <= 0)
3352                 st = 0;
3353         }
3354         if (!st) {
3355             BIO_printf(bio_err,
3356                 "RSA verify setup failure.  No RSA verify will be done.\n");
3357             dofail();
3358             rsa_doit[testnum] = 0;
3359         } else {
3360             pkey_print_message("public", "rsa verify",
3361                 rsa_keys[testnum].bits, seconds.rsa);
3362             Time_F(START);
3363             count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
3364             d = Time_F(STOP);
3365             BIO_printf(bio_err,
3366                 mr ? "+R2:%ld:%d:%.2f\n"
3367                    : "%ld %u bits public RSA verify ops in %.2fs\n",
3368                 count, rsa_keys[testnum].bits, d);
3369             rsa_results[testnum][1] = (double)count / d;
3370         }
3371 
3372         for (i = 0; st && i < loopargs_len; i++) {
3373             loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3374             loopargs[i].encsize = loopargs[i].buflen;
3375             if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
3376                 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
3377                 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
3378                        loopargs[i].buf2,
3379                        &loopargs[i].encsize,
3380                        loopargs[i].buf, 36)
3381                     <= 0)
3382                 st = 0;
3383         }
3384         if (!st) {
3385             BIO_printf(bio_err,
3386                 "RSA encrypt setup failure.  No RSA encrypt will be done.\n");
3387             dofail();
3388             op_count = 1;
3389         } else {
3390             pkey_print_message("public", "rsa encrypt",
3391                 rsa_keys[testnum].bits, seconds.rsa);
3392             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3393             Time_F(START);
3394             count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
3395             d = Time_F(STOP);
3396             BIO_printf(bio_err,
3397                 mr ? "+R3:%ld:%d:%.2f\n"
3398                    : "%ld %u bits public RSA encrypt ops in %.2fs\n",
3399                 count, rsa_keys[testnum].bits, d);
3400             rsa_results[testnum][2] = (double)count / d;
3401             op_count = count;
3402         }
3403 
3404         for (i = 0; st && i < loopargs_len; i++) {
3405             loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3406             declen = loopargs[i].buflen;
3407             if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
3408                 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
3409                 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
3410                        loopargs[i].buf,
3411                        &declen,
3412                        loopargs[i].buf2,
3413                        loopargs[i].encsize)
3414                     <= 0)
3415                 st = 0;
3416         }
3417         if (!st) {
3418             BIO_printf(bio_err,
3419                 "RSA decrypt setup failure.  No RSA decrypt will be done.\n");
3420             dofail();
3421             op_count = 1;
3422         } else {
3423             pkey_print_message("private", "rsa decrypt",
3424                 rsa_keys[testnum].bits, seconds.rsa);
3425             /* RSA_blinding_on(rsa_key[testnum],NULL); */
3426             Time_F(START);
3427             count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3428             d = Time_F(STOP);
3429             BIO_printf(bio_err,
3430                 mr ? "+R4:%ld:%d:%.2f\n"
3431                    : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3432                 count, rsa_keys[testnum].bits, d);
3433             rsa_results[testnum][3] = (double)count / d;
3434             op_count = count;
3435         }
3436 
3437         if (op_count <= 1) {
3438             /* if longer than 10s, don't do any more */
3439             stop_it(rsa_doit, testnum);
3440         }
3441         EVP_PKEY_free(rsa_key);
3442     }
3443 
3444 #ifndef OPENSSL_NO_DSA
3445     for (testnum = 0; testnum < DSA_NUM; testnum++) {
3446         EVP_PKEY *dsa_key = NULL;
3447         int st;
3448 
3449         if (!dsa_doit[testnum])
3450             continue;
3451 
3452         st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3453 
3454         for (i = 0; st && i < loopargs_len; i++) {
3455             loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3456                 NULL);
3457             loopargs[i].sigsize = loopargs[i].buflen;
3458             if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3459                 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3460                 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3461                        loopargs[i].buf2,
3462                        &loopargs[i].sigsize,
3463                        loopargs[i].buf, 20)
3464                     <= 0)
3465                 st = 0;
3466         }
3467         if (!st) {
3468             BIO_printf(bio_err,
3469                 "DSA sign setup failure.  No DSA sign will be done.\n");
3470             dofail();
3471             op_count = 1;
3472         } else {
3473             pkey_print_message("sign", "dsa",
3474                 dsa_bits[testnum], seconds.dsa);
3475             Time_F(START);
3476             count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3477             d = Time_F(STOP);
3478             BIO_printf(bio_err,
3479                 mr ? "+R5:%ld:%u:%.2f\n"
3480                    : "%ld %u bits DSA sign ops in %.2fs\n",
3481                 count, dsa_bits[testnum], d);
3482             dsa_results[testnum][0] = (double)count / d;
3483             op_count = count;
3484         }
3485 
3486         for (i = 0; st && i < loopargs_len; i++) {
3487             loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3488                 NULL);
3489             if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3490                 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3491                 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3492                        loopargs[i].buf2,
3493                        loopargs[i].sigsize,
3494                        loopargs[i].buf, 36)
3495                     <= 0)
3496                 st = 0;
3497         }
3498         if (!st) {
3499             BIO_printf(bio_err,
3500                 "DSA verify setup failure.  No DSA verify will be done.\n");
3501             dofail();
3502             dsa_doit[testnum] = 0;
3503         } else {
3504             pkey_print_message("verify", "dsa",
3505                 dsa_bits[testnum], seconds.dsa);
3506             Time_F(START);
3507             count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3508             d = Time_F(STOP);
3509             BIO_printf(bio_err,
3510                 mr ? "+R6:%ld:%u:%.2f\n"
3511                    : "%ld %u bits DSA verify ops in %.2fs\n",
3512                 count, dsa_bits[testnum], d);
3513             dsa_results[testnum][1] = (double)count / d;
3514         }
3515 
3516         if (op_count <= 1) {
3517             /* if longer than 10s, don't do any more */
3518             stop_it(dsa_doit, testnum);
3519         }
3520         EVP_PKEY_free(dsa_key);
3521     }
3522 #endif /* OPENSSL_NO_DSA */
3523 
3524     for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3525         EVP_PKEY *ecdsa_key = NULL;
3526         int st;
3527 
3528         if (!ecdsa_doit[testnum])
3529             continue;
3530 
3531         st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3532 
3533         for (i = 0; st && i < loopargs_len; i++) {
3534             loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3535                 NULL);
3536             loopargs[i].sigsize = loopargs[i].buflen;
3537             if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3538                 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3539                 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3540                        loopargs[i].buf2,
3541                        &loopargs[i].sigsize,
3542                        loopargs[i].buf, 20)
3543                     <= 0)
3544                 st = 0;
3545         }
3546         if (!st) {
3547             BIO_printf(bio_err,
3548                 "ECDSA sign setup failure.  No ECDSA sign will be done.\n");
3549             dofail();
3550             op_count = 1;
3551         } else {
3552             pkey_print_message("sign", "ecdsa",
3553                 ec_curves[testnum].bits, seconds.ecdsa);
3554             Time_F(START);
3555             count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3556             d = Time_F(STOP);
3557             BIO_printf(bio_err,
3558                 mr ? "+R7:%ld:%u:%.2f\n"
3559                    : "%ld %u bits ECDSA sign ops in %.2fs\n",
3560                 count, ec_curves[testnum].bits, d);
3561             ecdsa_results[testnum][0] = (double)count / d;
3562             op_count = count;
3563         }
3564 
3565         for (i = 0; st && i < loopargs_len; i++) {
3566             loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3567                 NULL);
3568             if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3569                 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3570                 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3571                        loopargs[i].buf2,
3572                        loopargs[i].sigsize,
3573                        loopargs[i].buf, 20)
3574                     <= 0)
3575                 st = 0;
3576         }
3577         if (!st) {
3578             BIO_printf(bio_err,
3579                 "ECDSA verify setup failure.  No ECDSA verify will be done.\n");
3580             dofail();
3581             ecdsa_doit[testnum] = 0;
3582         } else {
3583             pkey_print_message("verify", "ecdsa",
3584                 ec_curves[testnum].bits, seconds.ecdsa);
3585             Time_F(START);
3586             count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3587             d = Time_F(STOP);
3588             BIO_printf(bio_err,
3589                 mr ? "+R8:%ld:%u:%.2f\n"
3590                    : "%ld %u bits ECDSA verify ops in %.2fs\n",
3591                 count, ec_curves[testnum].bits, d);
3592             ecdsa_results[testnum][1] = (double)count / d;
3593         }
3594 
3595         if (op_count <= 1) {
3596             /* if longer than 10s, don't do any more */
3597             stop_it(ecdsa_doit, testnum);
3598         }
3599         EVP_PKEY_free(ecdsa_key);
3600     }
3601 
3602     for (testnum = 0; testnum < EC_NUM; testnum++) {
3603         int ecdh_checks = 1;
3604 
3605         if (!ecdh_doit[testnum])
3606             continue;
3607 
3608         for (i = 0; i < loopargs_len; i++) {
3609             EVP_PKEY_CTX *test_ctx = NULL;
3610             EVP_PKEY_CTX *ctx = NULL;
3611             EVP_PKEY *key_A = NULL;
3612             EVP_PKEY *key_B = NULL;
3613             size_t outlen;
3614             size_t test_outlen;
3615 
3616             if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3617                 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3618                 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3619                 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3620                 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3621                 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3622                 || outlen == 0 /* ensure outlen is a valid size */
3623                 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3624                 ecdh_checks = 0;
3625                 BIO_printf(bio_err, "ECDH key generation failure.\n");
3626                 dofail();
3627                 op_count = 1;
3628                 break;
3629             }
3630 
3631             /*
3632              * Here we perform a test run, comparing the output of a*B and b*A;
3633              * we try this here and assume that further EVP_PKEY_derive calls
3634              * never fail, so we can skip checks in the actually benchmarked
3635              * code, for maximum performance.
3636              */
3637             if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3638                 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3639                 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3640                 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3641                 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3642                 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3643                 || test_outlen != outlen /* compare output length */) {
3644                 ecdh_checks = 0;
3645                 BIO_printf(bio_err, "ECDH computation failure.\n");
3646                 dofail();
3647                 op_count = 1;
3648                 break;
3649             }
3650 
3651             /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3652             if (CRYPTO_memcmp(loopargs[i].secret_a,
3653                     loopargs[i].secret_b, outlen)) {
3654                 ecdh_checks = 0;
3655                 BIO_printf(bio_err, "ECDH computations don't match.\n");
3656                 dofail();
3657                 op_count = 1;
3658                 break;
3659             }
3660 
3661             loopargs[i].ecdh_ctx[testnum] = ctx;
3662             loopargs[i].outlen[testnum] = outlen;
3663 
3664             EVP_PKEY_free(key_A);
3665             EVP_PKEY_free(key_B);
3666             EVP_PKEY_CTX_free(test_ctx);
3667             test_ctx = NULL;
3668         }
3669         if (ecdh_checks != 0) {
3670             pkey_print_message("", "ecdh",
3671                 ec_curves[testnum].bits, seconds.ecdh);
3672             Time_F(START);
3673             count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3674             d = Time_F(STOP);
3675             BIO_printf(bio_err,
3676                 mr ? "+R9:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count,
3677                 ec_curves[testnum].bits, d);
3678             ecdh_results[testnum][0] = (double)count / d;
3679             op_count = count;
3680         }
3681 
3682         if (op_count <= 1) {
3683             /* if longer than 10s, don't do any more */
3684             stop_it(ecdh_doit, testnum);
3685         }
3686     }
3687 
3688 #ifndef OPENSSL_NO_ECX
3689     for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3690         int st = 1;
3691         EVP_PKEY *ed_pkey = NULL;
3692         EVP_PKEY_CTX *ed_pctx = NULL;
3693 
3694         if (!eddsa_doit[testnum])
3695             continue; /* Ignore Curve */
3696         for (i = 0; i < loopargs_len; i++) {
3697             loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3698             if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3699                 st = 0;
3700                 break;
3701             }
3702             loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3703             if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3704                 st = 0;
3705                 break;
3706             }
3707 
3708             if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3709                      NULL))
3710                     == NULL
3711                 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3712                 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3713                 st = 0;
3714                 EVP_PKEY_CTX_free(ed_pctx);
3715                 break;
3716             }
3717             EVP_PKEY_CTX_free(ed_pctx);
3718 
3719             if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3720                     NULL, ed_pkey)) {
3721                 st = 0;
3722                 EVP_PKEY_free(ed_pkey);
3723                 break;
3724             }
3725             if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3726                     NULL, NULL, ed_pkey)) {
3727                 st = 0;
3728                 EVP_PKEY_free(ed_pkey);
3729                 break;
3730             }
3731 
3732             EVP_PKEY_free(ed_pkey);
3733             ed_pkey = NULL;
3734         }
3735         if (st == 0) {
3736             BIO_printf(bio_err, "EdDSA failure.\n");
3737             dofail();
3738             op_count = 1;
3739         } else {
3740             for (i = 0; i < loopargs_len; i++) {
3741                 /* Perform EdDSA signature test */
3742                 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3743                 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3744                     loopargs[i].buf2, &loopargs[i].sigsize,
3745                     loopargs[i].buf, 20);
3746                 if (st == 0)
3747                     break;
3748             }
3749             if (st == 0) {
3750                 BIO_printf(bio_err,
3751                     "EdDSA sign failure.  No EdDSA sign will be done.\n");
3752                 dofail();
3753                 op_count = 1;
3754             } else {
3755                 pkey_print_message("sign", ed_curves[testnum].name,
3756                     ed_curves[testnum].bits, seconds.eddsa);
3757                 Time_F(START);
3758                 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3759                 d = Time_F(STOP);
3760 
3761                 BIO_printf(bio_err,
3762                     mr ? "+R10:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3763                     count, ed_curves[testnum].bits,
3764                     ed_curves[testnum].name, d);
3765                 eddsa_results[testnum][0] = (double)count / d;
3766                 op_count = count;
3767             }
3768             /* Perform EdDSA verification test */
3769             for (i = 0; i < loopargs_len; i++) {
3770                 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3771                     loopargs[i].buf2, loopargs[i].sigsize,
3772                     loopargs[i].buf, 20);
3773                 if (st != 1)
3774                     break;
3775             }
3776             if (st != 1) {
3777                 BIO_printf(bio_err,
3778                     "EdDSA verify failure.  No EdDSA verify will be done.\n");
3779                 dofail();
3780                 eddsa_doit[testnum] = 0;
3781             } else {
3782                 pkey_print_message("verify", ed_curves[testnum].name,
3783                     ed_curves[testnum].bits, seconds.eddsa);
3784                 Time_F(START);
3785                 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3786                 d = Time_F(STOP);
3787                 BIO_printf(bio_err,
3788                     mr ? "+R11:%ld:%u:%s:%.2f\n"
3789                        : "%ld %u bits %s verify ops in %.2fs\n",
3790                     count, ed_curves[testnum].bits,
3791                     ed_curves[testnum].name, d);
3792                 eddsa_results[testnum][1] = (double)count / d;
3793             }
3794 
3795             if (op_count <= 1) {
3796                 /* if longer than 10s, don't do any more */
3797                 stop_it(eddsa_doit, testnum);
3798             }
3799         }
3800     }
3801 #endif /* OPENSSL_NO_ECX */
3802 
3803 #ifndef OPENSSL_NO_SM2
3804     for (testnum = 0; testnum < SM2_NUM; testnum++) {
3805         int st = 1;
3806         EVP_PKEY *sm2_pkey = NULL;
3807 
3808         if (!sm2_doit[testnum])
3809             continue; /* Ignore Curve */
3810         /* Init signing and verification */
3811         for (i = 0; i < loopargs_len; i++) {
3812             EVP_PKEY_CTX *sm2_pctx = NULL;
3813             EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3814             EVP_PKEY_CTX *pctx = NULL;
3815             st = 0;
3816 
3817             loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3818             loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3819             if (loopargs[i].sm2_ctx[testnum] == NULL
3820                 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3821                 break;
3822 
3823             sm2_pkey = NULL;
3824 
3825             st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3826                 || EVP_PKEY_keygen_init(pctx) <= 0
3827                 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3828                        sm2_curves[testnum].nid)
3829                     <= 0
3830                 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3831             EVP_PKEY_CTX_free(pctx);
3832             if (st == 0)
3833                 break;
3834 
3835             st = 0; /* set back to zero */
3836             /* attach it sooner to rely on main final cleanup */
3837             loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3838             loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3839 
3840             sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3841             sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3842             if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3843                 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3844                 break;
3845             }
3846 
3847             /* attach them directly to respective ctx */
3848             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3849             EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3850 
3851             /*
3852              * No need to allow user to set an explicit ID here, just use
3853              * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3854              */
3855             if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3856                 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3857                 break;
3858 
3859             if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3860                     EVP_sm3(), NULL, sm2_pkey))
3861                 break;
3862             if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3863                     EVP_sm3(), NULL, sm2_pkey))
3864                 break;
3865             st = 1; /* mark loop as succeeded */
3866         }
3867         if (st == 0) {
3868             BIO_printf(bio_err, "SM2 init failure.\n");
3869             dofail();
3870             op_count = 1;
3871         } else {
3872             for (i = 0; i < loopargs_len; i++) {
3873                 /* Perform SM2 signature test */
3874                 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3875                     loopargs[i].buf2, &loopargs[i].sigsize,
3876                     loopargs[i].buf, 20);
3877                 if (st == 0)
3878                     break;
3879             }
3880             if (st == 0) {
3881                 BIO_printf(bio_err,
3882                     "SM2 sign failure.  No SM2 sign will be done.\n");
3883                 dofail();
3884                 op_count = 1;
3885             } else {
3886                 pkey_print_message("sign", sm2_curves[testnum].name,
3887                     sm2_curves[testnum].bits, seconds.sm2);
3888                 Time_F(START);
3889                 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3890                 d = Time_F(STOP);
3891 
3892                 BIO_printf(bio_err,
3893                     mr ? "+R12:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3894                     count, sm2_curves[testnum].bits,
3895                     sm2_curves[testnum].name, d);
3896                 sm2_results[testnum][0] = (double)count / d;
3897                 op_count = count;
3898             }
3899 
3900             /* Perform SM2 verification test */
3901             for (i = 0; i < loopargs_len; i++) {
3902                 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3903                     loopargs[i].buf2, loopargs[i].sigsize,
3904                     loopargs[i].buf, 20);
3905                 if (st != 1)
3906                     break;
3907             }
3908             if (st != 1) {
3909                 BIO_printf(bio_err,
3910                     "SM2 verify failure.  No SM2 verify will be done.\n");
3911                 dofail();
3912                 sm2_doit[testnum] = 0;
3913             } else {
3914                 pkey_print_message("verify", sm2_curves[testnum].name,
3915                     sm2_curves[testnum].bits, seconds.sm2);
3916                 Time_F(START);
3917                 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3918                 d = Time_F(STOP);
3919                 BIO_printf(bio_err,
3920                     mr ? "+R13:%ld:%u:%s:%.2f\n"
3921                        : "%ld %u bits %s verify ops in %.2fs\n",
3922                     count, sm2_curves[testnum].bits,
3923                     sm2_curves[testnum].name, d);
3924                 sm2_results[testnum][1] = (double)count / d;
3925             }
3926 
3927             if (op_count <= 1) {
3928                 /* if longer than 10s, don't do any more */
3929                 for (testnum++; testnum < SM2_NUM; testnum++)
3930                     sm2_doit[testnum] = 0;
3931             }
3932         }
3933     }
3934 #endif /* OPENSSL_NO_SM2 */
3935 
3936 #ifndef OPENSSL_NO_DH
3937     for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3938         int ffdh_checks = 1;
3939 
3940         if (!ffdh_doit[testnum])
3941             continue;
3942 
3943         for (i = 0; i < loopargs_len; i++) {
3944             EVP_PKEY *pkey_A = NULL;
3945             EVP_PKEY *pkey_B = NULL;
3946             EVP_PKEY_CTX *ffdh_ctx = NULL;
3947             EVP_PKEY_CTX *test_ctx = NULL;
3948             size_t secret_size;
3949             size_t test_out;
3950 
3951             /* Ensure that the error queue is empty */
3952             if (ERR_peek_error()) {
3953                 BIO_printf(bio_err,
3954                     "WARNING: the error queue contains previous unhandled errors.\n");
3955                 dofail();
3956             }
3957 
3958             pkey_A = EVP_PKEY_new();
3959             if (!pkey_A) {
3960                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3961                 dofail();
3962                 op_count = 1;
3963                 ffdh_checks = 0;
3964                 break;
3965             }
3966             pkey_B = EVP_PKEY_new();
3967             if (!pkey_B) {
3968                 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3969                 dofail();
3970                 op_count = 1;
3971                 ffdh_checks = 0;
3972                 break;
3973             }
3974 
3975             ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3976             if (!ffdh_ctx) {
3977                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3978                 dofail();
3979                 op_count = 1;
3980                 ffdh_checks = 0;
3981                 break;
3982             }
3983 
3984             if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3985                 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3986                 dofail();
3987                 op_count = 1;
3988                 ffdh_checks = 0;
3989                 break;
3990             }
3991             if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3992                 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3993                 dofail();
3994                 op_count = 1;
3995                 ffdh_checks = 0;
3996                 break;
3997             }
3998 
3999             if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
4000                 BIO_printf(bio_err, "FFDH key generation failure.\n");
4001                 dofail();
4002                 op_count = 1;
4003                 ffdh_checks = 0;
4004                 break;
4005             }
4006 
4007             EVP_PKEY_CTX_free(ffdh_ctx);
4008 
4009             /*
4010              * check if the derivation works correctly both ways so that
4011              * we know if future derive calls will fail, and we can skip
4012              * error checking in benchmarked code
4013              */
4014             ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
4015             if (ffdh_ctx == NULL) {
4016                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4017                 dofail();
4018                 op_count = 1;
4019                 ffdh_checks = 0;
4020                 break;
4021             }
4022             if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
4023                 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
4024                 dofail();
4025                 op_count = 1;
4026                 ffdh_checks = 0;
4027                 break;
4028             }
4029             if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
4030                 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
4031                 dofail();
4032                 op_count = 1;
4033                 ffdh_checks = 0;
4034                 break;
4035             }
4036             if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
4037                 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
4038                 dofail();
4039                 op_count = 1;
4040                 ffdh_checks = 0;
4041                 break;
4042             }
4043             if (secret_size > MAX_FFDH_SIZE) {
4044                 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
4045                 op_count = 1;
4046                 ffdh_checks = 0;
4047                 break;
4048             }
4049             if (EVP_PKEY_derive(ffdh_ctx,
4050                     loopargs[i].secret_ff_a,
4051                     &secret_size)
4052                 <= 0) {
4053                 BIO_printf(bio_err, "Shared secret derive failure.\n");
4054                 dofail();
4055                 op_count = 1;
4056                 ffdh_checks = 0;
4057                 break;
4058             }
4059             /* Now check from side B */
4060             test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
4061             if (!test_ctx) {
4062                 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4063                 dofail();
4064                 op_count = 1;
4065                 ffdh_checks = 0;
4066                 break;
4067             }
4068             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) {
4069                 BIO_printf(bio_err, "FFDH computation failure.\n");
4070                 op_count = 1;
4071                 ffdh_checks = 0;
4072                 break;
4073             }
4074 
4075             /* compare the computed secrets */
4076             if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
4077                     loopargs[i].secret_ff_b, secret_size)) {
4078                 BIO_printf(bio_err, "FFDH computations don't match.\n");
4079                 dofail();
4080                 op_count = 1;
4081                 ffdh_checks = 0;
4082                 break;
4083             }
4084 
4085             loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
4086 
4087             EVP_PKEY_free(pkey_A);
4088             pkey_A = NULL;
4089             EVP_PKEY_free(pkey_B);
4090             pkey_B = NULL;
4091             EVP_PKEY_CTX_free(test_ctx);
4092             test_ctx = NULL;
4093         }
4094         if (ffdh_checks != 0) {
4095             pkey_print_message("", "ffdh",
4096                 ffdh_params[testnum].bits, seconds.ffdh);
4097             Time_F(START);
4098             count = run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
4099             d = Time_F(STOP);
4100             BIO_printf(bio_err,
4101                 mr ? "+R14:%ld:%d:%.2f\n" : "%ld %u-bits FFDH ops in %.2fs\n", count,
4102                 ffdh_params[testnum].bits, d);
4103             ffdh_results[testnum][0] = (double)count / d;
4104             op_count = count;
4105         }
4106         if (op_count <= 1) {
4107             /* if longer than 10s, don't do any more */
4108             stop_it(ffdh_doit, testnum);
4109         }
4110     }
4111 #endif /* OPENSSL_NO_DH */
4112 
4113     for (testnum = 0; testnum < kems_algs_len; testnum++) {
4114         int kem_checks = 1;
4115         const char *kem_name = kems_algname[testnum];
4116 
4117         if (!kems_doit[testnum] || !do_kems)
4118             continue;
4119 
4120         for (i = 0; i < loopargs_len; i++) {
4121             EVP_PKEY *pkey = NULL;
4122             EVP_PKEY_CTX *kem_gen_ctx = NULL;
4123             EVP_PKEY_CTX *kem_encaps_ctx = NULL;
4124             EVP_PKEY_CTX *kem_decaps_ctx = NULL;
4125             size_t send_secret_len, out_len;
4126             size_t rcv_secret_len;
4127             unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
4128             unsigned int bits;
4129             char *name;
4130             char sfx[MAX_ALGNAME_SUFFIX];
4131             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4132             int use_params = 0;
4133             enum kem_type_t { KEM_RSA = 1,
4134                 KEM_EC,
4135                 KEM_X25519,
4136                 KEM_X448 } kem_type;
4137 
4138             /* no string after rsa<bitcnt> permitted: */
4139             if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4140                 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
4141                 kem_type = KEM_RSA;
4142             else if (strncmp(kem_name, "EC", 2) == 0)
4143                 kem_type = KEM_EC;
4144             else if (strcmp(kem_name, "X25519") == 0)
4145                 kem_type = KEM_X25519;
4146             else if (strcmp(kem_name, "X448") == 0)
4147                 kem_type = KEM_X448;
4148             else
4149                 kem_type = 0;
4150 
4151             if (ERR_peek_error()) {
4152                 BIO_printf(bio_err,
4153                     "WARNING: the error queue contains previous unhandled errors.\n");
4154                 dofail();
4155             }
4156 
4157             if (kem_type == KEM_RSA) {
4158                 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4159                     &bits);
4160                 use_params = 1;
4161             } else if (kem_type == KEM_EC) {
4162                 name = (char *)(kem_name + 2);
4163                 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
4164                     name, 0);
4165                 use_params = 1;
4166             }
4167 
4168             kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4169                 (kem_type == KEM_RSA) ? "RSA" : (kem_type == KEM_EC) ? "EC"
4170                                                                      : kem_name,
4171                 app_get0_propq());
4172 
4173             if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
4174                 || (use_params
4175                     && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
4176                 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4177                     kem_name);
4178                 goto kem_err_break;
4179             }
4180             if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
4181                 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
4182                 goto kem_err_break;
4183             }
4184             /* Now prepare encaps data structs */
4185             kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4186                 pkey,
4187                 app_get0_propq());
4188             if (kem_encaps_ctx == NULL
4189                 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
4190                 || (kem_type == KEM_RSA
4191                     && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
4192                 || ((kem_type == KEM_EC
4193                         || kem_type == KEM_X25519
4194                         || kem_type == KEM_X448)
4195                     && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
4196                 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
4197                        NULL, &send_secret_len)
4198                     <= 0) {
4199                 BIO_printf(bio_err,
4200                     "Error while initializing encaps data structs for %s.\n",
4201                     kem_name);
4202                 goto kem_err_break;
4203             }
4204             out = app_malloc(out_len, "encaps result");
4205             send_secret = app_malloc(send_secret_len, "encaps secret");
4206             if (out == NULL || send_secret == NULL) {
4207                 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
4208                 goto kem_err_break;
4209             }
4210             if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
4211                     send_secret, &send_secret_len)
4212                 <= 0) {
4213                 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
4214                 goto kem_err_break;
4215             }
4216             /* Now prepare decaps data structs */
4217             kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4218                 pkey,
4219                 app_get0_propq());
4220             if (kem_decaps_ctx == NULL
4221                 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
4222                 || (kem_type == KEM_RSA
4223                     && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
4224                 || ((kem_type == KEM_EC
4225                         || kem_type == KEM_X25519
4226                         || kem_type == KEM_X448)
4227                     && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
4228                 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
4229                        out, out_len)
4230                     <= 0) {
4231                 BIO_printf(bio_err,
4232                     "Error while initializing decaps data structs for %s.\n",
4233                     kem_name);
4234                 goto kem_err_break;
4235             }
4236             rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
4237             if (rcv_secret == NULL) {
4238                 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
4239                     kem_name);
4240                 goto kem_err_break;
4241             }
4242             if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
4243                     &rcv_secret_len, out, out_len)
4244                     <= 0
4245                 || rcv_secret_len != send_secret_len
4246                 || memcmp(send_secret, rcv_secret, send_secret_len)) {
4247                 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
4248                 goto kem_err_break;
4249             }
4250             loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
4251             loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
4252             loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
4253             loopargs[i].kem_out_len[testnum] = out_len;
4254             loopargs[i].kem_secret_len[testnum] = send_secret_len;
4255             loopargs[i].kem_out[testnum] = out;
4256             loopargs[i].kem_send_secret[testnum] = send_secret;
4257             loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
4258             EVP_PKEY_free(pkey);
4259             pkey = NULL;
4260             continue;
4261 
4262         kem_err_break:
4263             dofail();
4264             EVP_PKEY_free(pkey);
4265             op_count = 1;
4266             kem_checks = 0;
4267             break;
4268         }
4269         if (kem_checks != 0) {
4270             kskey_print_message(kem_name, "keygen", seconds.kem);
4271             Time_F(START);
4272             count = run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
4273             d = Time_F(STOP);
4274             BIO_printf(bio_err,
4275                 mr ? "+R15:%ld:%s:%.2f\n" : "%ld %s KEM keygen ops in %.2fs\n", count,
4276                 kem_name, d);
4277             kems_results[testnum][0] = (double)count / d;
4278             op_count = count;
4279             kskey_print_message(kem_name, "encaps", seconds.kem);
4280             Time_F(START);
4281             count = run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
4282             d = Time_F(STOP);
4283             BIO_printf(bio_err,
4284                 mr ? "+R16:%ld:%s:%.2f\n" : "%ld %s KEM encaps ops in %.2fs\n", count,
4285                 kem_name, d);
4286             kems_results[testnum][1] = (double)count / d;
4287             op_count = count;
4288             kskey_print_message(kem_name, "decaps", seconds.kem);
4289             Time_F(START);
4290             count = run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
4291             d = Time_F(STOP);
4292             BIO_printf(bio_err,
4293                 mr ? "+R17:%ld:%s:%.2f\n" : "%ld %s KEM decaps ops in %.2fs\n", count,
4294                 kem_name, d);
4295             kems_results[testnum][2] = (double)count / d;
4296             op_count = count;
4297         }
4298         if (op_count <= 1) {
4299             /* if longer than 10s, don't do any more */
4300             stop_it(kems_doit, testnum);
4301         }
4302     }
4303 
4304     for (testnum = 0; testnum < sigs_algs_len; testnum++) {
4305         int sig_checks = 1;
4306         const char *sig_name = sigs_algname[testnum];
4307 
4308         if (!sigs_doit[testnum] || !do_sigs)
4309             continue;
4310 
4311         for (i = 0; i < loopargs_len; i++) {
4312             EVP_PKEY *pkey = NULL;
4313             EVP_PKEY_CTX *ctx_params = NULL;
4314             EVP_PKEY *pkey_params = NULL;
4315             EVP_PKEY_CTX *sig_gen_ctx = NULL;
4316             EVP_PKEY_CTX *sig_sign_ctx = NULL;
4317             EVP_PKEY_CTX *sig_verify_ctx = NULL;
4318             EVP_SIGNATURE *alg = NULL;
4319             unsigned char md[SHA256_DIGEST_LENGTH];
4320             unsigned char *sig;
4321             char sfx[MAX_ALGNAME_SUFFIX];
4322             size_t md_len = SHA256_DIGEST_LENGTH;
4323             size_t max_sig_len, sig_len;
4324             unsigned int bits;
4325             OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4326             int use_params = 0;
4327 
4328             /* only sign little data to avoid measuring digest performance */
4329             memset(md, 0, SHA256_DIGEST_LENGTH);
4330 
4331             if (ERR_peek_error()) {
4332                 BIO_printf(bio_err,
4333                     "WARNING: the error queue contains previous unhandled errors.\n");
4334                 dofail();
4335             }
4336 
4337             /* no string after rsa<bitcnt> permitted: */
4338             if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4339                 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
4340                 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4341                     &bits);
4342                 use_params = 1;
4343             }
4344 
4345             if (strncmp(sig_name, "dsa", 3) == 0) {
4346                 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
4347                 if (ctx_params == NULL
4348                     || EVP_PKEY_paramgen_init(ctx_params) <= 0
4349                     || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
4350                            atoi(sig_name + 3))
4351                         <= 0
4352                     || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
4353                     || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
4354                     || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
4355                     BIO_printf(bio_err,
4356                         "Error initializing classic keygen ctx for %s.\n",
4357                         sig_name);
4358                     goto sig_err_break;
4359                 }
4360             }
4361 
4362             if (sig_gen_ctx == NULL)
4363                 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4364                     use_params == 1 ? "RSA" : sig_name,
4365                     app_get0_propq());
4366 
4367             if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
4368                 || (use_params && EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
4369                 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4370                     sig_name);
4371                 goto sig_err_break;
4372             }
4373             if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
4374                 BIO_printf(bio_err,
4375                     "Error while generating signature EVP_PKEY for %s.\n",
4376                     sig_name);
4377                 goto sig_err_break;
4378             }
4379 
4380             /*
4381              * Try explicitly fetching the signature algorithm implementation to
4382              * use in case the algorithm does not support EVP_PKEY_sign_init
4383              */
4384             ERR_set_mark();
4385             alg = EVP_SIGNATURE_fetch(app_get0_libctx(), sig_name, app_get0_propq());
4386             ERR_pop_to_mark();
4387 
4388             /* Now prepare signature data structs */
4389             sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4390                 pkey,
4391                 app_get0_propq());
4392             if (sig_sign_ctx == NULL) {
4393                 BIO_printf(bio_err,
4394                     "Error while initializing signing ctx for %s.\n",
4395                     sig_name);
4396                 goto sig_err_break;
4397             }
4398             ERR_set_mark();
4399             if (EVP_PKEY_sign_init(sig_sign_ctx) <= 0
4400                 && (alg == NULL
4401                     || EVP_PKEY_sign_message_init(sig_sign_ctx, alg, NULL) <= 0)) {
4402                 ERR_clear_last_mark();
4403                 BIO_printf(bio_err,
4404                     "Error while initializing signing data structs for %s.\n",
4405                     sig_name);
4406                 goto sig_err_break;
4407             }
4408             ERR_pop_to_mark();
4409             if (use_params == 1 && EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx, RSA_PKCS1_PADDING) <= 0) {
4410                 BIO_printf(bio_err,
4411                     "Error while initializing padding for %s.\n",
4412                     sig_name);
4413                 goto sig_err_break;
4414             }
4415             if (EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len, md, md_len) <= 0) {
4416                 BIO_printf(bio_err,
4417                     "Error while obtaining signature buffer length for %s.\n",
4418                     sig_name);
4419                 goto sig_err_break;
4420             }
4421             sig = app_malloc(sig_len = max_sig_len, "signature buffer");
4422             if (sig == NULL) {
4423                 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
4424                 goto sig_err_break;
4425             }
4426             if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
4427                 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
4428                 goto sig_err_break;
4429             }
4430             /* Now prepare verify data structs */
4431             memset(md, 0, SHA256_DIGEST_LENGTH);
4432             sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4433                 pkey,
4434                 app_get0_propq());
4435             if (sig_verify_ctx == NULL) {
4436                 BIO_printf(bio_err,
4437                     "Error while initializing verify ctx for %s.\n",
4438                     sig_name);
4439                 goto sig_err_break;
4440             }
4441             ERR_set_mark();
4442             if (EVP_PKEY_verify_init(sig_verify_ctx) <= 0
4443                 && (alg == NULL
4444                     || EVP_PKEY_verify_message_init(sig_verify_ctx, alg, NULL) <= 0)) {
4445                 ERR_clear_last_mark();
4446                 BIO_printf(bio_err,
4447                     "Error while initializing verify data structs for %s.\n",
4448                     sig_name);
4449                 goto sig_err_break;
4450             }
4451             ERR_pop_to_mark();
4452             if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4453                 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
4454                 goto sig_err_break;
4455             }
4456             if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4457                 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4458                 goto sig_err_break;
4459             }
4460             loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4461             loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4462             loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4463             loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4464             loopargs[i].sig_act_sig_len[testnum] = sig_len;
4465             loopargs[i].sig_sig[testnum] = sig;
4466             EVP_PKEY_free(pkey);
4467             EVP_SIGNATURE_free(alg);
4468             pkey = NULL;
4469             continue;
4470 
4471         sig_err_break:
4472             dofail();
4473             EVP_PKEY_free(pkey);
4474             EVP_SIGNATURE_free(alg);
4475             op_count = 1;
4476             sig_checks = 0;
4477             break;
4478         }
4479 
4480         if (sig_checks != 0) {
4481             kskey_print_message(sig_name, "keygen", seconds.sig);
4482             Time_F(START);
4483             count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4484             d = Time_F(STOP);
4485             BIO_printf(bio_err,
4486                 mr ? "+R18:%ld:%s:%.2f\n" : "%ld %s signature keygen ops in %.2fs\n", count,
4487                 sig_name, d);
4488             sigs_results[testnum][0] = (double)count / d;
4489             op_count = count;
4490             kskey_print_message(sig_name, "signs", seconds.sig);
4491             Time_F(START);
4492             count = run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4493             d = Time_F(STOP);
4494             BIO_printf(bio_err,
4495                 mr ? "+R19:%ld:%s:%.2f\n" : "%ld %s signature sign ops in %.2fs\n", count,
4496                 sig_name, d);
4497             sigs_results[testnum][1] = (double)count / d;
4498             op_count = count;
4499 
4500             kskey_print_message(sig_name, "verify", seconds.sig);
4501             Time_F(START);
4502             count = run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4503             d = Time_F(STOP);
4504             BIO_printf(bio_err,
4505                 mr ? "+R20:%ld:%s:%.2f\n" : "%ld %s signature verify ops in %.2fs\n", count,
4506                 sig_name, d);
4507             sigs_results[testnum][2] = (double)count / d;
4508             op_count = count;
4509         }
4510         if (op_count <= 1)
4511             stop_it(sigs_doit, testnum);
4512     }
4513 
4514 #ifndef NO_FORK
4515 show_res:
4516 #endif
4517     if (!mr) {
4518         printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4519         printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4520         printf("options: %s\n", BN_options());
4521         printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4522         printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4523     }
4524 
4525     if (pr_header) {
4526         if (mr) {
4527             printf("+H");
4528         } else {
4529             printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4530             printf("type        ");
4531         }
4532         for (testnum = 0; testnum < size_num; testnum++)
4533             printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4534         printf("\n");
4535     }
4536 
4537     for (k = 0; k < ALGOR_NUM; k++) {
4538         const char *alg_name = names[k];
4539 
4540         if (!doit[k])
4541             continue;
4542 
4543         if (k == D_EVP) {
4544             if (evp_cipher == NULL)
4545                 alg_name = evp_md_name;
4546             else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4547                 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4548         }
4549 
4550         if (mr)
4551             printf("+F:%u:%s", k, alg_name);
4552         else
4553             printf("%-13s", alg_name);
4554         for (testnum = 0; testnum < size_num; testnum++) {
4555             if (results[k][testnum] > 10000 && !mr)
4556                 printf(" %11.2fk", results[k][testnum] / 1e3);
4557             else
4558                 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4559         }
4560         printf("\n");
4561     }
4562     testnum = 1;
4563     for (k = 0; k < RSA_NUM; k++) {
4564         if (!rsa_doit[k])
4565             continue;
4566         if (testnum && !mr) {
4567             printf("%19ssign    verify    encrypt   decrypt   sign/s verify/s  encr./s  decr./s\n", " ");
4568             testnum = 0;
4569         }
4570         if (mr)
4571             printf("+F2:%u:%u:%f:%f:%f:%f\n",
4572                 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4573                 rsa_results[k][2], rsa_results[k][3]);
4574         else
4575             printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4576                 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4577                 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4578                 1.0 / rsa_results[k][3],
4579                 rsa_results[k][0], rsa_results[k][1],
4580                 rsa_results[k][2], rsa_results[k][3]);
4581     }
4582     testnum = 1;
4583 #ifndef OPENSSL_NO_DSA
4584     for (k = 0; k < DSA_NUM; k++) {
4585         if (!dsa_doit[k])
4586             continue;
4587         if (testnum && !mr) {
4588             printf("%18ssign    verify    sign/s verify/s\n", " ");
4589             testnum = 0;
4590         }
4591         if (mr)
4592             printf("+F3:%u:%u:%f:%f\n",
4593                 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4594         else
4595             printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4596                 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4597                 dsa_results[k][0], dsa_results[k][1]);
4598     }
4599 #endif /* OPENSSL_NO_DSA */
4600     testnum = 1;
4601     for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4602         if (!ecdsa_doit[k])
4603             continue;
4604         if (testnum && !mr) {
4605             printf("%30ssign    verify    sign/s verify/s\n", " ");
4606             testnum = 0;
4607         }
4608 
4609         if (mr)
4610             printf("+F4:%u:%u:%f:%f\n",
4611                 k, ec_curves[k].bits,
4612                 ecdsa_results[k][0], ecdsa_results[k][1]);
4613         else
4614             printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4615                 ec_curves[k].bits, ec_curves[k].name,
4616                 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4617                 ecdsa_results[k][0], ecdsa_results[k][1]);
4618     }
4619 
4620     testnum = 1;
4621     for (k = 0; k < EC_NUM; k++) {
4622         if (!ecdh_doit[k])
4623             continue;
4624         if (testnum && !mr) {
4625             printf("%30sop      op/s\n", " ");
4626             testnum = 0;
4627         }
4628         if (mr)
4629             printf("+F5:%u:%u:%f:%f\n",
4630                 k, ec_curves[k].bits,
4631                 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4632 
4633         else
4634             printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4635                 ec_curves[k].bits, ec_curves[k].name,
4636                 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4637     }
4638 
4639 #ifndef OPENSSL_NO_ECX
4640     testnum = 1;
4641     for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4642         if (!eddsa_doit[k])
4643             continue;
4644         if (testnum && !mr) {
4645             printf("%30ssign    verify    sign/s verify/s\n", " ");
4646             testnum = 0;
4647         }
4648 
4649         if (mr)
4650             printf("+F6:%u:%u:%s:%f:%f\n",
4651                 k, ed_curves[k].bits, ed_curves[k].name,
4652                 eddsa_results[k][0], eddsa_results[k][1]);
4653         else
4654             printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4655                 ed_curves[k].bits, ed_curves[k].name,
4656                 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4657                 eddsa_results[k][0], eddsa_results[k][1]);
4658     }
4659 #endif /* OPENSSL_NO_ECX */
4660 
4661 #ifndef OPENSSL_NO_SM2
4662     testnum = 1;
4663     for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4664         if (!sm2_doit[k])
4665             continue;
4666         if (testnum && !mr) {
4667             printf("%30ssign    verify    sign/s verify/s\n", " ");
4668             testnum = 0;
4669         }
4670 
4671         if (mr)
4672             printf("+F7:%u:%u:%s:%f:%f\n",
4673                 k, sm2_curves[k].bits, sm2_curves[k].name,
4674                 sm2_results[k][0], sm2_results[k][1]);
4675         else
4676             printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4677                 sm2_curves[k].bits, sm2_curves[k].name,
4678                 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4679                 sm2_results[k][0], sm2_results[k][1]);
4680     }
4681 #endif
4682 #ifndef OPENSSL_NO_DH
4683     testnum = 1;
4684     for (k = 0; k < FFDH_NUM; k++) {
4685         if (!ffdh_doit[k])
4686             continue;
4687         if (testnum && !mr) {
4688             printf("%23sop     op/s\n", " ");
4689             testnum = 0;
4690         }
4691         if (mr)
4692             printf("+F8:%u:%u:%f:%f\n",
4693                 k, ffdh_params[k].bits,
4694                 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4695 
4696         else
4697             printf("%4u bits ffdh %8.4fs %8.1f\n",
4698                 ffdh_params[k].bits,
4699                 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4700     }
4701 #endif /* OPENSSL_NO_DH */
4702 
4703     testnum = 1;
4704     for (k = 0; k < kems_algs_len; k++) {
4705         const char *kem_name = kems_algname[k];
4706 
4707         if (!kems_doit[k] || !do_kems)
4708             continue;
4709         if (testnum && !mr) {
4710             printf("%31skeygen    encaps    decaps keygens/s  encaps/s  decaps/s\n", " ");
4711             testnum = 0;
4712         }
4713         if (mr)
4714             printf("+F9:%u:%f:%f:%f\n",
4715                 k, kems_results[k][0], kems_results[k][1],
4716                 kems_results[k][2]);
4717         else
4718             printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4719                 1.0 / kems_results[k][0],
4720                 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4721                 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4722     }
4723     ret = 0;
4724 
4725     testnum = 1;
4726     for (k = 0; k < sigs_algs_len; k++) {
4727         const char *sig_name = sigs_algname[k];
4728 
4729         if (!sigs_doit[k] || !do_sigs)
4730             continue;
4731         if (testnum && !mr) {
4732             printf("%31skeygen     signs    verify keygens/s    sign/s  verify/s\n", " ");
4733             testnum = 0;
4734         }
4735         if (mr)
4736             printf("+F10:%u:%f:%f:%f\n",
4737                 k, sigs_results[k][0], sigs_results[k][1],
4738                 sigs_results[k][2]);
4739         else
4740             printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4741                 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4742                 1.0 / sigs_results[k][2], sigs_results[k][0],
4743                 sigs_results[k][1], sigs_results[k][2]);
4744     }
4745     ret = 0;
4746 
4747 end:
4748     if (ret == 0 && testmode)
4749         ret = testmoderesult;
4750     ERR_print_errors(bio_err);
4751     for (i = 0; i < loopargs_len; i++) {
4752         OPENSSL_free(loopargs[i].buf_malloc);
4753         OPENSSL_free(loopargs[i].buf2_malloc);
4754 
4755         BN_free(bn);
4756         EVP_PKEY_CTX_free(genctx);
4757         for (k = 0; k < RSA_NUM; k++) {
4758             EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4759             EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4760             EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]);
4761             EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]);
4762         }
4763 #ifndef OPENSSL_NO_DH
4764         OPENSSL_free(loopargs[i].secret_ff_a);
4765         OPENSSL_free(loopargs[i].secret_ff_b);
4766         for (k = 0; k < FFDH_NUM; k++)
4767             EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4768 #endif
4769 #ifndef OPENSSL_NO_DSA
4770         for (k = 0; k < DSA_NUM; k++) {
4771             EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4772             EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4773         }
4774 #endif
4775         for (k = 0; k < ECDSA_NUM; k++) {
4776             EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4777             EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4778         }
4779         for (k = 0; k < EC_NUM; k++)
4780             EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4781 #ifndef OPENSSL_NO_ECX
4782         for (k = 0; k < EdDSA_NUM; k++) {
4783             EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4784             EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4785         }
4786 #endif /* OPENSSL_NO_ECX */
4787 #ifndef OPENSSL_NO_SM2
4788         for (k = 0; k < SM2_NUM; k++) {
4789             EVP_PKEY_CTX *pctx = NULL;
4790 
4791             /* free signing ctx */
4792             if (loopargs[i].sm2_ctx[k] != NULL
4793                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4794                 EVP_PKEY_CTX_free(pctx);
4795             EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4796             /* free verification ctx */
4797             if (loopargs[i].sm2_vfy_ctx[k] != NULL
4798                 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4799                 EVP_PKEY_CTX_free(pctx);
4800             EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4801             /* free pkey */
4802             EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4803         }
4804 #endif
4805         for (k = 0; k < kems_algs_len; k++) {
4806             EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4807             EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4808             EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4809             OPENSSL_free(loopargs[i].kem_out[k]);
4810             OPENSSL_free(loopargs[i].kem_send_secret[k]);
4811             OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4812         }
4813         for (k = 0; k < sigs_algs_len; k++) {
4814             EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4815             EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4816             EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4817             OPENSSL_free(loopargs[i].sig_sig[k]);
4818         }
4819         OPENSSL_free(loopargs[i].secret_a);
4820         OPENSSL_free(loopargs[i].secret_b);
4821     }
4822     OPENSSL_free(evp_hmac_name);
4823     OPENSSL_free(evp_cmac_name);
4824     for (k = 0; k < kems_algs_len; k++)
4825         OPENSSL_free(kems_algname[k]);
4826     if (kem_stack != NULL)
4827         sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4828     for (k = 0; k < sigs_algs_len; k++)
4829         OPENSSL_free(sigs_algname[k]);
4830     if (sig_stack != NULL)
4831         sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4832 
4833     if (async_jobs > 0) {
4834         for (i = 0; i < loopargs_len; i++)
4835             ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4836     }
4837 
4838     if (async_init) {
4839         ASYNC_cleanup_thread();
4840     }
4841     OPENSSL_free(loopargs);
4842     release_engine(e);
4843     EVP_CIPHER_free(evp_cipher);
4844     EVP_MAC_free(mac);
4845     NCONF_free(conf);
4846     return ret;
4847 }
4848 
print_message(const char * s,int length,int tm)4849 static void print_message(const char *s, int length, int tm)
4850 {
4851     BIO_printf(bio_err,
4852         mr ? "+DT:%s:%d:%d\n"
4853            : "Doing %s ops for %ds on %d size blocks: ",
4854         s, tm, length);
4855     (void)BIO_flush(bio_err);
4856     run = 1;
4857     alarm(tm);
4858 }
4859 
pkey_print_message(const char * str,const char * str2,unsigned int bits,int tm)4860 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4861     int tm)
4862 {
4863     BIO_printf(bio_err,
4864         mr ? "+DTP:%d:%s:%s:%d\n"
4865            : "Doing %u bits %s %s ops for %ds: ",
4866         bits, str, str2, tm);
4867     (void)BIO_flush(bio_err);
4868     run = 1;
4869     alarm(tm);
4870 }
4871 
kskey_print_message(const char * str,const char * str2,int tm)4872 static void kskey_print_message(const char *str, const char *str2, int tm)
4873 {
4874     BIO_printf(bio_err,
4875         mr ? "+DTP:%s:%s:%d\n"
4876            : "Doing %s %s ops for %ds: ",
4877         str, str2, tm);
4878     (void)BIO_flush(bio_err);
4879     run = 1;
4880     alarm(tm);
4881 }
4882 
print_result(int alg,int run_no,int count,double time_used)4883 static void print_result(int alg, int run_no, int count, double time_used)
4884 {
4885     if (count == -1) {
4886         BIO_printf(bio_err, "%s error!\n", names[alg]);
4887         dofail();
4888         return;
4889     }
4890     BIO_printf(bio_err,
4891         mr ? "+R:%d:%s:%f\n"
4892            : "%d %s ops in %.2fs\n",
4893         count, names[alg], time_used);
4894     results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4895 }
4896 
4897 #ifndef NO_FORK
sstrsep(char ** string,const char * delim)4898 static char *sstrsep(char **string, const char *delim)
4899 {
4900     char isdelim[256];
4901     char *token = *string;
4902 
4903     memset(isdelim, 0, sizeof(isdelim));
4904     isdelim[0] = 1;
4905 
4906     while (*delim) {
4907         isdelim[(unsigned char)(*delim)] = 1;
4908         delim++;
4909     }
4910 
4911     while (!isdelim[(unsigned char)(**string)])
4912         (*string)++;
4913 
4914     if (**string) {
4915         **string = 0;
4916         (*string)++;
4917     }
4918 
4919     return token;
4920 }
4921 
strtoint(const char * str,const int min_val,const int upper_val,int * res)4922 static int strtoint(const char *str, const int min_val, const int upper_val,
4923     int *res)
4924 {
4925     char *end = NULL;
4926     long int val = 0;
4927 
4928     errno = 0;
4929     val = strtol(str, &end, 10);
4930     if (errno == 0 && end != str && *end == 0
4931         && min_val <= val && val < upper_val) {
4932         *res = (int)val;
4933         return 1;
4934     } else {
4935         return 0;
4936     }
4937 }
4938 
do_multi(int multi,int size_num)4939 static int do_multi(int multi, int size_num)
4940 {
4941     int n;
4942     int fd[2];
4943     int *fds;
4944     int status;
4945     static char sep[] = ":";
4946 
4947     fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4948     for (n = 0; n < multi; ++n) {
4949         if (pipe(fd) == -1) {
4950             BIO_printf(bio_err, "pipe failure\n");
4951             exit(1);
4952         }
4953         fflush(stdout);
4954         (void)BIO_flush(bio_err);
4955         if (fork()) {
4956             close(fd[1]);
4957             fds[n] = fd[0];
4958         } else {
4959             close(fd[0]);
4960             close(1);
4961             if (dup(fd[1]) == -1) {
4962                 BIO_printf(bio_err, "dup failed\n");
4963                 exit(1);
4964             }
4965             close(fd[1]);
4966             mr = 1;
4967             usertime = 0;
4968             OPENSSL_free(fds);
4969             return 0;
4970         }
4971         printf("Forked child %d\n", n);
4972     }
4973 
4974     /* for now, assume the pipe is long enough to take all the output */
4975     for (n = 0; n < multi; ++n) {
4976         FILE *f;
4977         char buf[1024];
4978         char *p;
4979         char *tk;
4980         int k;
4981         double d;
4982 
4983         if ((f = fdopen(fds[n], "r")) == NULL) {
4984             BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4985                 errno);
4986             OPENSSL_free(fds);
4987             return 1;
4988         }
4989         while (fgets(buf, sizeof(buf), f)) {
4990             p = strchr(buf, '\n');
4991             if (p)
4992                 *p = '\0';
4993             if (buf[0] != '+') {
4994                 BIO_printf(bio_err,
4995                     "Don't understand line '%s' from child %d\n", buf,
4996                     n);
4997                 continue;
4998             }
4999             printf("Got: %s from %d\n", buf, n);
5000             p = buf;
5001             if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
5002                 int alg;
5003                 int j;
5004 
5005                 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
5006                     sstrsep(&p, sep);
5007                     for (j = 0; j < size_num; ++j)
5008                         results[alg][j] += atof(sstrsep(&p, sep));
5009                 }
5010             } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
5011                 tk = sstrsep(&p, sep);
5012                 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
5013                     sstrsep(&p, sep);
5014 
5015                     d = atof(sstrsep(&p, sep));
5016                     rsa_results[k][0] += d;
5017 
5018                     d = atof(sstrsep(&p, sep));
5019                     rsa_results[k][1] += d;
5020 
5021                     d = atof(sstrsep(&p, sep));
5022                     rsa_results[k][2] += d;
5023 
5024                     d = atof(sstrsep(&p, sep));
5025                     rsa_results[k][3] += d;
5026                 }
5027 #ifndef OPENSSL_NO_DSA
5028             } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
5029                 tk = sstrsep(&p, sep);
5030                 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
5031                     sstrsep(&p, sep);
5032 
5033                     d = atof(sstrsep(&p, sep));
5034                     dsa_results[k][0] += d;
5035 
5036                     d = atof(sstrsep(&p, sep));
5037                     dsa_results[k][1] += d;
5038                 }
5039 #endif /* OPENSSL_NO_DSA */
5040             } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
5041                 tk = sstrsep(&p, sep);
5042                 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
5043                     sstrsep(&p, sep);
5044 
5045                     d = atof(sstrsep(&p, sep));
5046                     ecdsa_results[k][0] += d;
5047 
5048                     d = atof(sstrsep(&p, sep));
5049                     ecdsa_results[k][1] += d;
5050                 }
5051             } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
5052                 tk = sstrsep(&p, sep);
5053                 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
5054                     sstrsep(&p, sep);
5055 
5056                     d = atof(sstrsep(&p, sep));
5057                     ecdh_results[k][0] += d;
5058                 }
5059 #ifndef OPENSSL_NO_ECX
5060             } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
5061                 tk = sstrsep(&p, sep);
5062                 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
5063                     sstrsep(&p, sep);
5064                     sstrsep(&p, sep);
5065 
5066                     d = atof(sstrsep(&p, sep));
5067                     eddsa_results[k][0] += d;
5068 
5069                     d = atof(sstrsep(&p, sep));
5070                     eddsa_results[k][1] += d;
5071                 }
5072 #endif /* OPENSSL_NO_ECX */
5073 #ifndef OPENSSL_NO_SM2
5074             } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
5075                 tk = sstrsep(&p, sep);
5076                 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
5077                     sstrsep(&p, sep);
5078                     sstrsep(&p, sep);
5079 
5080                     d = atof(sstrsep(&p, sep));
5081                     sm2_results[k][0] += d;
5082 
5083                     d = atof(sstrsep(&p, sep));
5084                     sm2_results[k][1] += d;
5085                 }
5086 #endif /* OPENSSL_NO_SM2 */
5087 #ifndef OPENSSL_NO_DH
5088             } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
5089                 tk = sstrsep(&p, sep);
5090                 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
5091                     sstrsep(&p, sep);
5092 
5093                     d = atof(sstrsep(&p, sep));
5094                     ffdh_results[k][0] += d;
5095                 }
5096 #endif /* OPENSSL_NO_DH */
5097             } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
5098                 tk = sstrsep(&p, sep);
5099                 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
5100                     d = atof(sstrsep(&p, sep));
5101                     kems_results[k][0] += d;
5102 
5103                     d = atof(sstrsep(&p, sep));
5104                     kems_results[k][1] += d;
5105 
5106                     d = atof(sstrsep(&p, sep));
5107                     kems_results[k][2] += d;
5108                 }
5109             } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
5110                 tk = sstrsep(&p, sep);
5111                 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
5112                     d = atof(sstrsep(&p, sep));
5113                     sigs_results[k][0] += d;
5114 
5115                     d = atof(sstrsep(&p, sep));
5116                     sigs_results[k][1] += d;
5117 
5118                     d = atof(sstrsep(&p, sep));
5119                     sigs_results[k][2] += d;
5120                 }
5121             } else if (!HAS_PREFIX(buf, "+H:")) {
5122                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
5123                     n);
5124             }
5125         }
5126 
5127         fclose(f);
5128     }
5129     OPENSSL_free(fds);
5130     for (n = 0; n < multi; ++n) {
5131         while (wait(&status) == -1)
5132             if (errno != EINTR) {
5133                 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
5134                     errno);
5135                 return 1;
5136             }
5137         if (WIFEXITED(status) && WEXITSTATUS(status)) {
5138             BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
5139         } else if (WIFSIGNALED(status)) {
5140             BIO_printf(bio_err, "Child terminated by signal %d\n",
5141                 WTERMSIG(status));
5142         }
5143     }
5144     return 1;
5145 }
5146 #endif
5147 
multiblock_speed(const EVP_CIPHER * evp_cipher,int lengths_single,const openssl_speed_sec_t * seconds)5148 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
5149     const openssl_speed_sec_t *seconds)
5150 {
5151     static const int mblengths_list[] = {
5152         8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024
5153     };
5154     const int *mblengths = mblengths_list;
5155     int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
5156     const char *alg_name;
5157     unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
5158     EVP_CIPHER_CTX *ctx = NULL;
5159     double d = 0.0;
5160 
5161     if (lengths_single) {
5162         mblengths = &lengths_single;
5163         num = 1;
5164     }
5165 
5166     inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
5167     out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
5168     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
5169         app_bail_out("failed to allocate cipher context\n");
5170     if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
5171         app_bail_out("failed to initialise cipher context\n");
5172 
5173     if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
5174         BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
5175         goto err;
5176     }
5177     key = app_malloc(keylen, "evp_cipher key");
5178     if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
5179         app_bail_out("failed to generate random cipher key\n");
5180     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
5181         app_bail_out("failed to set cipher key\n");
5182     OPENSSL_clear_free(key, keylen);
5183 
5184     if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
5185             sizeof(no_key), no_key)
5186         <= 0)
5187         app_bail_out("failed to set AEAD key\n");
5188     if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
5189         app_bail_out("failed to get cipher name\n");
5190 
5191     for (j = 0; j < num; j++) {
5192         print_message(alg_name, mblengths[j], seconds->sym);
5193         Time_F(START);
5194         for (count = 0; run && COND(count); count++) {
5195             EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
5196             size_t len = mblengths[j];
5197             int packlen;
5198 
5199             memset(aad, 0, 8); /* avoid uninitialized values */
5200             aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
5201             aad[9] = 3; /* version */
5202             aad[10] = 2;
5203             aad[11] = 0; /* length */
5204             aad[12] = 0;
5205             mb_param.out = NULL;
5206             mb_param.inp = aad;
5207             mb_param.len = len;
5208             mb_param.interleave = 8;
5209 
5210             packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
5211                 sizeof(mb_param), &mb_param);
5212 
5213             if (packlen > 0) {
5214                 mb_param.out = out;
5215                 mb_param.inp = inp;
5216                 mb_param.len = len;
5217                 (void)EVP_CIPHER_CTX_ctrl(ctx,
5218                     EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
5219                     sizeof(mb_param), &mb_param);
5220             } else {
5221                 int pad;
5222 
5223                 if (RAND_bytes(inp, 16) <= 0)
5224                     app_bail_out("error setting random bytes\n");
5225                 len += 16;
5226                 aad[11] = (unsigned char)(len >> 8);
5227                 aad[12] = (unsigned char)(len);
5228                 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
5229                     EVP_AEAD_TLS1_AAD_LEN, aad);
5230                 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
5231             }
5232         }
5233         d = Time_F(STOP);
5234         BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" : "%d %s ops in %.2fs\n", count, "evp", d);
5235         if ((ciph_success <= 0) && (mr == 0))
5236             BIO_printf(bio_err, "Error performing cipher op\n");
5237         results[D_EVP][j] = ((double)count) / d * mblengths[j];
5238     }
5239 
5240     if (mr) {
5241         fprintf(stdout, "+H");
5242         for (j = 0; j < num; j++)
5243             fprintf(stdout, ":%d", mblengths[j]);
5244         fprintf(stdout, "\n");
5245         fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
5246         for (j = 0; j < num; j++)
5247             fprintf(stdout, ":%.2f", results[D_EVP][j]);
5248         fprintf(stdout, "\n");
5249     } else {
5250         fprintf(stdout,
5251             "The 'numbers' are in 1000s of bytes per second processed.\n");
5252         fprintf(stdout, "type                    ");
5253         for (j = 0; j < num; j++)
5254             fprintf(stdout, "%7d bytes", mblengths[j]);
5255         fprintf(stdout, "\n");
5256         fprintf(stdout, "%-24s", alg_name);
5257 
5258         for (j = 0; j < num; j++) {
5259             if (results[D_EVP][j] > 10000)
5260                 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
5261             else
5262                 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
5263         }
5264         fprintf(stdout, "\n");
5265     }
5266 
5267 err:
5268     OPENSSL_free(inp);
5269     OPENSSL_free(out);
5270     EVP_CIPHER_CTX_free(ctx);
5271 }
5272