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