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