]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/speed.c
Update copyright year
[thirdparty/openssl.git] / apps / speed.c
CommitLineData
846e33c7 1/*
fecb3aae 2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
aa8f3d76 3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
d02b48c6 4 *
dffa7520 5 * Licensed under the Apache License 2.0 (the "License"). You may not use
846e33c7
RS
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
d02b48c6 9 */
846e33c7 10
a00ae6c4 11#undef SECONDS
f3ccfc76
TM
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
a00ae6c4 22
7573fe1a
MC
23/* We need to use some deprecated APIs */
24#define OPENSSL_SUPPRESS_DEPRECATED
25
a00ae6c4
RS
26#include <stdio.h>
27#include <stdlib.h>
a00ae6c4
RS
28#include <string.h>
29#include <math.h>
30#include "apps.h"
dab2cd68 31#include "progs.h"
25a0a44d 32#include "internal/numbers.h"
a00ae6c4
RS
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>
f3ccfc76 38#include <openssl/core_names.h>
8b0b80d9 39#include <openssl/async.h>
a00ae6c4 40#if !defined(OPENSSL_SYS_MSDOS)
6b10d29c 41# include <unistd.h>
a00ae6c4 42#endif
d02b48c6 43
08073700
RB
44#if defined(__TANDEM)
45# if defined(OPENSSL_TANDEM_FLOSS)
46# include <floss.h(floss_fork)>
47# endif
48#endif
49
8d35ceb9 50#if defined(_WIN32)
a00ae6c4 51# include <windows.h>
a00ae6c4 52#endif
d02b48c6 53
a00ae6c4 54#include <openssl/bn.h>
f3ccfc76
TM
55#include <openssl/rsa.h>
56#include "./testrsa.h"
60d3b5b9
HK
57#ifndef OPENSSL_NO_DH
58# include <openssl/dh.h>
59#endif
a00ae6c4 60#include <openssl/x509.h>
f3ccfc76
TM
61#include <openssl/dsa.h>
62#include "./testdsa.h"
a00ae6c4 63#include <openssl/modes.h>
b5419b81 64
a00ae6c4 65#ifndef HAVE_FORK
5c8b7b4c 66# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
a00ae6c4 67# define HAVE_FORK 0
0f113f3e 68# else
a00ae6c4 69# define HAVE_FORK 1
0f113f3e 70# endif
a00ae6c4 71#endif
66d3e748 72
a00ae6c4
RS
73#if HAVE_FORK
74# undef NO_FORK
75#else
76# define NO_FORK
77#endif
78
a00ae6c4 79#define MAX_MISALIGNMENT 63
0ff43435
AG
80#define MAX_ECDH_SIZE 256
81#define MISALIGN 64
60d3b5b9 82#define MAX_FFDH_SIZE 1024
0ff43435 83
f3ccfc76
TM
84#ifndef RSA_DEFAULT_PRIME_NUM
85# define RSA_DEFAULT_PRIME_NUM 2
86#endif
87
8f26f9d5 88typedef struct openssl_speed_sec_st {
64daf14d
PS
89 int sym;
90 int rsa;
91 int dsa;
92 int ecdsa;
93 int ecdh;
d3a9fb10 94 int eddsa;
a56f68ad 95 int sm2;
60d3b5b9 96 int ffdh;
8f26f9d5 97} openssl_speed_sec_t;
64daf14d 98
0f113f3e 99static volatile int run = 0;
d02b48c6 100
1352e0ff 101static int mr = 0; /* machine-readeable output format to merge fork results */
0f113f3e 102static int usertime = 1;
7876e448 103
0e211563 104static double Time_F(int s);
64daf14d 105static void print_message(const char *s, long num, int length, int tm);
689c6f25 106static void pkey_print_message(const char *str, const char *str2,
48bc0d99 107 long num, unsigned int bits, int sec);
0f113f3e 108static void print_result(int alg, int run_no, int count, double time_used);
a00ae6c4 109#ifndef NO_FORK
64daf14d 110static int do_multi(int multi, int size_num);
a00ae6c4 111#endif
0f113f3e 112
64daf14d
PS
113static const int lengths_list[] = {
114 16, 64, 256, 1024, 8 * 1024, 16 * 1024
115};
1352e0ff 116#define SIZE_NUM OSSL_NELEM(lengths_list)
64daf14d
PS
117static const int *lengths = lengths_list;
118
44ca7565
AP
119static const int aead_lengths_list[] = {
120 2, 31, 136, 1024, 8 * 1024, 16 * 1024
121};
122
ffcca684
AP
123#define START 0
124#define STOP 1
125
a00ae6c4 126#ifdef SIGALRM
b83eddc5 127
ffcca684 128static void alarmed(int sig)
0f113f3e 129{
ffcca684 130 signal(SIGALRM, alarmed);
0f113f3e
MC
131 run = 0;
132}
d02b48c6 133
ffcca684
AP
134static double Time_F(int s)
135{
136 double ret = app_tminterval(s, usertime);
137 if (s == STOP)
138 alarm(0);
139 return ret;
140}
d02b48c6 141
ffcca684
AP
142#elif defined(_WIN32)
143
144# define SIGALRM -1
4d8743f4 145
e0de4dd5
XL
146static unsigned int lapse;
147static volatile unsigned int schlock;
0f113f3e
MC
148static void alarm_win32(unsigned int secs)
149{
150 lapse = secs * 1000;
151}
4d8743f4 152
a00ae6c4 153# define alarm alarm_win32
0f113f3e
MC
154
155static DWORD WINAPI sleepy(VOID * arg)
156{
157 schlock = 1;
158 Sleep(lapse);
159 run = 0;
160 return 0;
161}
4e74239c 162
0a39d8f2 163static double Time_F(int s)
0f113f3e
MC
164{
165 double ret;
166 static HANDLE thr;
167
168 if (s == START) {
169 schlock = 0;
170 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
171 if (thr == NULL) {
db40a14e
AP
172 DWORD err = GetLastError();
173 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
f219a1b0 174 ExitProcess(err);
0f113f3e
MC
175 }
176 while (!schlock)
177 Sleep(0); /* scheduler spinlock */
178 ret = app_tminterval(s, usertime);
179 } else {
180 ret = app_tminterval(s, usertime);
181 if (run)
182 TerminateThread(thr, 0);
183 CloseHandle(thr);
184 }
185
186 return ret;
187}
a00ae6c4 188#else
ee1d7f1d 189# error "SIGALRM not defined and the platform is not Windows"
a00ae6c4 190#endif
176f31dd 191
5c6a69f5 192static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
8f26f9d5 193 const openssl_speed_sec_t *seconds);
176f31dd 194
5c6a69f5
F
195static int opt_found(const char *name, unsigned int *result,
196 const OPT_PAIR pairs[], unsigned int nbelem)
7e1b7485 197{
5c6a69f5
F
198 unsigned int idx;
199
200 for (idx = 0; idx < nbelem; ++idx, pairs++)
7e1b7485
RS
201 if (strcmp(name, pairs->name) == 0) {
202 *result = pairs->retval;
203 return 1;
204 }
205 return 0;
206}
1352e0ff
F
207#define opt_found(value, pairs, result)\
208 opt_found(value, result, pairs, OSSL_NELEM(pairs))
7e1b7485
RS
209
210typedef enum OPTION_choice {
b0f96018 211 OPT_COMMON,
f88b9b79 212 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
6bd4e3f2 213 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM,
9bba2c4c 214 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC
7e1b7485
RS
215} OPTION_CHOICE;
216
44c83ebd 217const OPTIONS speed_options[] = {
78212c64
KB
218 {OPT_HELP_STR, 1, '-',
219 "Usage: %s [options] [algorithm...]\n"
220 "All +int options consider prefix '0' as base-8 input, "
221 "prefix '0x'/'0X' as base-16 input.\n"
222 },
5388f986
RS
223
224 OPT_SECTION("General"),
7e1b7485 225 {"help", OPT_HELP, '-', "Display this summary"},
700b8145 226 {"mb", OPT_MB, '-',
44ca7565
AP
227 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
228 {"mr", OPT_MR, '-', "Produce machine readable output"},
7e1b7485
RS
229#ifndef NO_FORK
230 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
231#endif
667867cc 232#ifndef OPENSSL_NO_ASYNC
d6073e27 233 {"async_jobs", OPT_ASYNCJOBS, 'p',
44ca7565 234 "Enable async mode and start specified number of jobs"},
8b0b80d9 235#endif
7e1b7485
RS
236#ifndef OPENSSL_NO_ENGINE
237 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
238#endif
5388f986
RS
239 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
240
241 OPT_SECTION("Selection"),
242 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
243 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
5388f986 244 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
5388f986
RS
245 {"decrypt", OPT_DECRYPT, '-',
246 "Time decryption instead of encryption (only EVP)"},
247 {"aead", OPT_AEAD, '-',
248 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
249
250 OPT_SECTION("Timing"),
44ca7565
AP
251 {"elapsed", OPT_ELAPSED, '-',
252 "Use wall-clock time instead of CPU user time as divisor"},
64daf14d 253 {"seconds", OPT_SECONDS, 'p',
44ca7565 254 "Run benchmarks for specified amount of seconds"},
64daf14d 255 {"bytes", OPT_BYTES, 'p',
44ca7565
AP
256 "Run [non-PKI] benchmarks on custom-sized buffer"},
257 {"misalign", OPT_MISALIGN, 'p',
258 "Use specified offset to mis-align buffers"},
5388f986
RS
259
260 OPT_R_OPTIONS,
6bd4e3f2 261 OPT_PROV_OPTIONS,
92de469f
RS
262
263 OPT_PARAMETERS(),
264 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
5c6a69f5 265 {NULL}
7e1b7485
RS
266};
267
1352e0ff 268enum {
a89cd8d8
TM
269 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
270 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
f3ccfc76 271 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
1352e0ff
F
272 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
273 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
274 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
861f265a 275 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
1352e0ff
F
276};
277/* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
278static const char *names[ALGOR_NUM] = {
a89cd8d8
TM
279 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
280 "sha256", "sha512", "whirlpool", "hmac(md5)",
f3ccfc76
TM
281 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
282 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
283 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
284 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
285 "evp", "ghash", "rand", "cmac"
5c6a69f5 286};
5c6a69f5 287
1352e0ff 288/* list of configured algorithm (remaining), with some few alias */
5c6a69f5 289static const OPT_PAIR doit_choices[] = {
7e1b7485 290 {"md2", D_MD2},
7e1b7485 291 {"mdc2", D_MDC2},
7e1b7485 292 {"md4", D_MD4},
7e1b7485 293 {"md5", D_MD5},
7e1b7485 294 {"hmac", D_HMAC},
7e1b7485
RS
295 {"sha1", D_SHA1},
296 {"sha256", D_SHA256},
297 {"sha512", D_SHA512},
7e1b7485 298 {"whirlpool", D_WHIRLPOOL},
7e1b7485
RS
299 {"ripemd", D_RMD160},
300 {"rmd160", D_RMD160},
301 {"ripemd160", D_RMD160},
7e1b7485 302 {"rc4", D_RC4},
7e1b7485
RS
303 {"des-cbc", D_CBC_DES},
304 {"des-ede3", D_EDE3_DES},
7e1b7485
RS
305 {"aes-128-cbc", D_CBC_128_AES},
306 {"aes-192-cbc", D_CBC_192_AES},
307 {"aes-256-cbc", D_CBC_256_AES},
f3ccfc76
TM
308 {"camellia-128-cbc", D_CBC_128_CML},
309 {"camellia-192-cbc", D_CBC_192_CML},
310 {"camellia-256-cbc", D_CBC_256_CML},
7e1b7485
RS
311 {"rc2-cbc", D_CBC_RC2},
312 {"rc2", D_CBC_RC2},
7e1b7485
RS
313 {"rc5-cbc", D_CBC_RC5},
314 {"rc5", D_CBC_RC5},
7e1b7485
RS
315 {"idea-cbc", D_CBC_IDEA},
316 {"idea", D_CBC_IDEA},
7e1b7485
RS
317 {"seed-cbc", D_CBC_SEED},
318 {"seed", D_CBC_SEED},
7e1b7485
RS
319 {"bf-cbc", D_CBC_BF},
320 {"blowfish", D_CBC_BF},
321 {"bf", D_CBC_BF},
7e1b7485
RS
322 {"cast-cbc", D_CBC_CAST},
323 {"cast", D_CBC_CAST},
324 {"cast5", D_CBC_CAST},
7e1b7485 325 {"ghash", D_GHASH},
5c6a69f5 326 {"rand", D_RAND}
7e1b7485
RS
327};
328
1352e0ff 329static double results[ALGOR_NUM][SIZE_NUM];
5c6a69f5 330
1352e0ff
F
331enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM };
332static const OPT_PAIR dsa_choices[DSA_NUM] = {
7e1b7485
RS
333 {"dsa512", R_DSA_512},
334 {"dsa1024", R_DSA_1024},
5c6a69f5 335 {"dsa2048", R_DSA_2048}
7e1b7485 336};
5c6a69f5 337static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
667ac4ec 338
1352e0ff
F
339enum {
340 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
341 R_RSA_15360, RSA_NUM
342};
343static const OPT_PAIR rsa_choices[RSA_NUM] = {
7e1b7485
RS
344 {"rsa512", R_RSA_512},
345 {"rsa1024", R_RSA_1024},
346 {"rsa2048", R_RSA_2048},
347 {"rsa3072", R_RSA_3072},
348 {"rsa4096", R_RSA_4096},
349 {"rsa7680", R_RSA_7680},
5c6a69f5 350 {"rsa15360", R_RSA_15360}
7e1b7485 351};
5c6a69f5
F
352
353static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */
7e1b7485 354
60d3b5b9
HK
355#ifndef OPENSSL_NO_DH
356enum ff_params_t {
357 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
358};
359
360static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
361 {"ffdh2048", R_FFDH_2048},
362 {"ffdh3072", R_FFDH_3072},
363 {"ffdh4096", R_FFDH_4096},
364 {"ffdh6144", R_FFDH_6144},
365 {"ffdh8192", R_FFDH_8192},
366};
367
368static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
369#endif /* OPENSSL_NO_DH */
370
1352e0ff
F
371enum ec_curves_t {
372 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
f3ccfc76 373#ifndef OPENSSL_NO_EC2M
1352e0ff
F
374 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
375 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
f3ccfc76 376#endif
1352e0ff
F
377 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
378 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
379};
380/* list of ecdsa curves */
381static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
7e1b7485
RS
382 {"ecdsap160", R_EC_P160},
383 {"ecdsap192", R_EC_P192},
384 {"ecdsap224", R_EC_P224},
385 {"ecdsap256", R_EC_P256},
386 {"ecdsap384", R_EC_P384},
387 {"ecdsap521", R_EC_P521},
f3ccfc76 388#ifndef OPENSSL_NO_EC2M
7e1b7485
RS
389 {"ecdsak163", R_EC_K163},
390 {"ecdsak233", R_EC_K233},
391 {"ecdsak283", R_EC_K283},
392 {"ecdsak409", R_EC_K409},
393 {"ecdsak571", R_EC_K571},
394 {"ecdsab163", R_EC_B163},
395 {"ecdsab233", R_EC_B233},
396 {"ecdsab283", R_EC_B283},
397 {"ecdsab409", R_EC_B409},
1c534560 398 {"ecdsab571", R_EC_B571},
f3ccfc76 399#endif
1c534560
F
400 {"ecdsabrp256r1", R_EC_BRP256R1},
401 {"ecdsabrp256t1", R_EC_BRP256T1},
402 {"ecdsabrp384r1", R_EC_BRP384R1},
403 {"ecdsabrp384t1", R_EC_BRP384T1},
404 {"ecdsabrp512r1", R_EC_BRP512R1},
405 {"ecdsabrp512t1", R_EC_BRP512T1}
7e1b7485 406};
1352e0ff
F
407enum { R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM };
408/* list of ecdh curves, extension of |ecdsa_choices| list above */
409static const OPT_PAIR ecdh_choices[EC_NUM] = {
7e1b7485
RS
410 {"ecdhp160", R_EC_P160},
411 {"ecdhp192", R_EC_P192},
412 {"ecdhp224", R_EC_P224},
413 {"ecdhp256", R_EC_P256},
414 {"ecdhp384", R_EC_P384},
415 {"ecdhp521", R_EC_P521},
f3ccfc76 416#ifndef OPENSSL_NO_EC2M
7e1b7485
RS
417 {"ecdhk163", R_EC_K163},
418 {"ecdhk233", R_EC_K233},
419 {"ecdhk283", R_EC_K283},
420 {"ecdhk409", R_EC_K409},
421 {"ecdhk571", R_EC_K571},
422 {"ecdhb163", R_EC_B163},
423 {"ecdhb233", R_EC_B233},
424 {"ecdhb283", R_EC_B283},
425 {"ecdhb409", R_EC_B409},
426 {"ecdhb571", R_EC_B571},
f3ccfc76 427#endif
1c534560
F
428 {"ecdhbrp256r1", R_EC_BRP256R1},
429 {"ecdhbrp256t1", R_EC_BRP256T1},
430 {"ecdhbrp384r1", R_EC_BRP384R1},
431 {"ecdhbrp384t1", R_EC_BRP384T1},
432 {"ecdhbrp512r1", R_EC_BRP512R1},
433 {"ecdhbrp512t1", R_EC_BRP512T1},
db50c1da 434 {"ecdhx25519", R_EC_X25519},
5c6a69f5 435 {"ecdhx448", R_EC_X448}
7e1b7485 436};
5c6a69f5 437
1352e0ff
F
438static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
439static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
d3a9fb10 440
1352e0ff
F
441enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
442static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
d3a9fb10
PY
443 {"ed25519", R_EC_Ed25519},
444 {"ed448", R_EC_Ed448}
d3a9fb10 445
1352e0ff 446};
d3a9fb10 447static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
a56f68ad 448
f3ccfc76 449#ifndef OPENSSL_NO_SM2
1352e0ff
F
450enum { R_EC_CURVESM2, SM2_NUM };
451static const OPT_PAIR sm2_choices[SM2_NUM] = {
a56f68ad
PY
452 {"curveSM2", R_EC_CURVESM2}
453};
f3ccfc76
TM
454# define SM2_ID "TLSv1.3+GM+Cipher+Suite"
455# define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
a56f68ad 456static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
f3ccfc76 457#endif /* OPENSSL_NO_SM2 */
7e1b7485 458
378c50f6 459#define COND(unused_cond) (run && count < INT_MAX)
ee1d7f1d 460#define COUNT(d) (count)
8b0b80d9 461
5c6a69f5
F
462typedef struct loopargs_st {
463 ASYNC_JOB *inprogress_job;
464 ASYNC_WAIT_CTX *wait_ctx;
465 unsigned char *buf;
466 unsigned char *buf2;
467 unsigned char *buf_malloc;
468 unsigned char *buf2_malloc;
469 unsigned char *key;
e7414634 470 size_t buflen;
52307f94 471 size_t sigsize;
f3ccfc76
TM
472 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
473 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
474 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
475 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
476 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
477 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
5c6a69f5 478 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
d3a9fb10 479 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
1154ffbf 480 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
f3ccfc76 481#ifndef OPENSSL_NO_SM2
a56f68ad
PY
482 EVP_MD_CTX *sm2_ctx[SM2_NUM];
483 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
484 EVP_PKEY *sm2_pkey[SM2_NUM];
f3ccfc76 485#endif
5c6a69f5
F
486 unsigned char *secret_a;
487 unsigned char *secret_b;
488 size_t outlen[EC_NUM];
60d3b5b9
HK
489#ifndef OPENSSL_NO_DH
490 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
491 unsigned char *secret_ff_a;
492 unsigned char *secret_ff_b;
5c6a69f5
F
493#endif
494 EVP_CIPHER_CTX *ctx;
a89cd8d8 495 EVP_MAC_CTX *mctx;
5c6a69f5
F
496} loopargs_t;
497static int run_benchmark(int async_jobs, int (*loop_function) (void *),
498 loopargs_t * loopargs);
499
500static unsigned int testnum;
8b0b80d9 501
70c4e156 502/* Nb of iterations to do per algorithm and key-size */
1352e0ff 503static long c[ALGOR_NUM][SIZE_NUM];
8b0b80d9 504
a89cd8d8
TM
505static char *evp_mac_mdname = "md5";
506static char *evp_hmac_name = NULL;
507static const char *evp_md_name = NULL;
f3ccfc76
TM
508static char *evp_mac_ciphername = "aes-128-cbc";
509static char *evp_cmac_name = NULL;
a89cd8d8 510
a89cd8d8 511static int have_md(const char *name)
8b0b80d9 512{
f3ccfc76 513 int ret = 0;
eaf8a40d 514 EVP_MD *md = NULL;
8829ce30 515
eaf8a40d 516 if (opt_md_silent(name, &md)) {
f3ccfc76
TM
517 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
518
519 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
520 ret = 1;
521 EVP_MD_CTX_free(ctx);
eaf8a40d 522 EVP_MD_free(md);
d166ed8c 523 }
f3ccfc76
TM
524 return ret;
525}
526
f3ccfc76
TM
527static int have_cipher(const char *name)
528{
f3ccfc76 529 int ret = 0;
eaf8a40d 530 EVP_CIPHER *cipher = NULL;
f3ccfc76 531
eaf8a40d 532 if (opt_cipher_silent(name, &cipher)) {
f3ccfc76
TM
533 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
534
535 if (ctx != NULL
536 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
537 ret = 1;
538 EVP_CIPHER_CTX_free(ctx);
eaf8a40d 539 EVP_CIPHER_free(cipher);
f3ccfc76
TM
540 }
541 return ret;
8b0b80d9 542}
8b0b80d9 543
a89cd8d8 544static int EVP_Digest_loop(const char *mdname, int algindex, void *args)
8b0b80d9 545{
29dd15b1 546 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9 547 unsigned char *buf = tempargs->buf;
a89cd8d8 548 unsigned char digest[EVP_MAX_MD_SIZE];
eaf8a40d
TM
549 int count;
550 EVP_MD *md = NULL;
a89cd8d8 551
eaf8a40d 552 if (!opt_md_silent(mdname, &md))
a89cd8d8 553 return -1;
a89cd8d8
TM
554 for (count = 0; COND(c[algindex][testnum]); count++) {
555 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
556 NULL)) {
557 count = -1;
558 break;
559 }
d166ed8c 560 }
eaf8a40d 561 EVP_MD_free(md);
8b0b80d9
AG
562 return count;
563}
8b0b80d9 564
a89cd8d8
TM
565static int EVP_Digest_md_loop(void *args)
566{
567 return EVP_Digest_loop(evp_md_name, D_EVP, args);
568}
569
570static int EVP_Digest_MD2_loop(void *args)
571{
572 return EVP_Digest_loop("md2", D_MD2, args);
573}
574
575static int EVP_Digest_MDC2_loop(void *args)
576{
577 return EVP_Digest_loop("mdc2", D_MDC2, args);
578}
579
580static int EVP_Digest_MD4_loop(void *args)
581{
582 return EVP_Digest_loop("md4", D_MD4, args);
583}
584
8b0b80d9
AG
585static int MD5_loop(void *args)
586{
a89cd8d8 587 return EVP_Digest_loop("md5", D_MD5, args);
8b0b80d9
AG
588}
589
f3ccfc76 590static int EVP_MAC_loop(int algindex, void *args)
8b0b80d9 591{
29dd15b1 592 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9 593 unsigned char *buf = tempargs->buf;
a89cd8d8
TM
594 EVP_MAC_CTX *mctx = tempargs->mctx;
595 unsigned char mac[EVP_MAX_MD_SIZE];
8b0b80d9 596 int count;
8829ce30 597
f3ccfc76 598 for (count = 0; COND(c[algindex][testnum]); count++) {
a89cd8d8 599 size_t outl;
861f265a 600
7f7640c4 601 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
a89cd8d8
TM
602 || !EVP_MAC_update(mctx, buf, lengths[testnum])
603 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
604 return -1;
8b0b80d9
AG
605 }
606 return count;
607}
8b0b80d9 608
f3ccfc76
TM
609static int HMAC_loop(void *args)
610{
611 return EVP_MAC_loop(D_HMAC, args);
612}
613
614static int CMAC_loop(void *args)
615{
616 return EVP_MAC_loop(D_EVP_CMAC, args);
617}
618
8b0b80d9
AG
619static int SHA1_loop(void *args)
620{
a89cd8d8 621 return EVP_Digest_loop("sha1", D_SHA1, args);
8b0b80d9
AG
622}
623
624static int SHA256_loop(void *args)
625{
a89cd8d8 626 return EVP_Digest_loop("sha256", D_SHA256, args);
8b0b80d9
AG
627}
628
629static int SHA512_loop(void *args)
630{
a89cd8d8 631 return EVP_Digest_loop("sha512", D_SHA512, args);
8b0b80d9
AG
632}
633
8b0b80d9
AG
634static int WHIRLPOOL_loop(void *args)
635{
a89cd8d8 636 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
8b0b80d9 637}
8b0b80d9 638
8b0b80d9
AG
639static int EVP_Digest_RMD160_loop(void *args)
640{
a89cd8d8 641 return EVP_Digest_loop("ripemd160", D_RMD160, args);
8b0b80d9 642}
8b0b80d9 643
f3ccfc76 644static int algindex;
8b0b80d9 645
f3ccfc76 646static int EVP_Cipher_loop(void *args)
8b0b80d9 647{
29dd15b1 648 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
649 unsigned char *buf = tempargs->buf;
650 int count;
f3ccfc76
TM
651
652 if (tempargs->ctx == NULL)
653 return -1;
654 for (count = 0; COND(c[algindex][testnum]); count++)
655 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
656 return -1;
8b0b80d9
AG
657 return count;
658}
659
f3ccfc76 660static int GHASH_loop(void *args)
8b0b80d9 661{
29dd15b1 662 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9 663 unsigned char *buf = tempargs->buf;
f3ccfc76 664 EVP_MAC_CTX *mctx = tempargs->mctx;
8b0b80d9 665 int count;
f3ccfc76
TM
666
667 /* just do the update in the loop to be comparable with 1.1.1 */
668 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
669 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
670 return -1;
671 }
8b0b80d9
AG
672 return count;
673}
f3ccfc76 674
5158c763 675#define MAX_BLOCK_SIZE 128
8b0b80d9
AG
676
677static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
c72fa255 678
f3ccfc76
TM
679static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
680 const unsigned char *key,
681 int keylen)
8b0b80d9 682{
f3ccfc76 683 EVP_CIPHER_CTX *ctx = NULL;
eaf8a40d 684 EVP_CIPHER *cipher = NULL;
8b0b80d9 685
eaf8a40d 686 if (!opt_cipher_silent(ciphername, &cipher))
f3ccfc76 687 return NULL;
8b0b80d9 688
f3ccfc76
TM
689 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
690 goto end;
8b0b80d9 691
f3ccfc76
TM
692 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
693 EVP_CIPHER_CTX_free(ctx);
694 ctx = NULL;
695 goto end;
696 }
8b0b80d9 697
a02d70dd
P
698 if (!EVP_CIPHER_CTX_set_key_length(ctx, keylen)) {
699 EVP_CIPHER_CTX_free(ctx);
700 ctx = NULL;
701 goto end;
702 }
8b0b80d9 703
f3ccfc76
TM
704 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
705 EVP_CIPHER_CTX_free(ctx);
706 ctx = NULL;
707 goto end;
708 }
8b0b80d9 709
f3ccfc76 710end:
eaf8a40d 711 EVP_CIPHER_free(cipher);
f3ccfc76 712 return ctx;
8b0b80d9
AG
713}
714
65e6b9a4
PS
715static int RAND_bytes_loop(void *args)
716{
717 loopargs_t *tempargs = *(loopargs_t **) args;
718 unsigned char *buf = tempargs->buf;
719 int count;
720
721 for (count = 0; COND(c[D_RAND][testnum]); count++)
722 RAND_bytes(buf, lengths[testnum]);
723 return count;
724}
725
8b0b80d9
AG
726static int decrypt = 0;
727static int EVP_Update_loop(void *args)
728{
29dd15b1 729 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
730 unsigned char *buf = tempargs->buf;
731 EVP_CIPHER_CTX *ctx = tempargs->ctx;
723a7c5a 732 int outl, count, rc;
d02b7e09 733
723a7c5a 734 if (decrypt) {
d02b7e09 735 for (count = 0; COND(c[D_EVP][testnum]); count++) {
723a7c5a 736 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
7da84e0f
PS
737 if (rc != 1) {
738 /* reset iv in case of counter overflow */
723a7c5a 739 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
7da84e0f 740 }
723a7c5a
PS
741 }
742 } else {
d02b7e09 743 for (count = 0; COND(c[D_EVP][testnum]); count++) {
723a7c5a 744 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
7da84e0f
PS
745 if (rc != 1) {
746 /* reset iv in case of counter overflow */
723a7c5a 747 EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
7da84e0f 748 }
723a7c5a
PS
749 }
750 }
8b0b80d9
AG
751 if (decrypt)
752 EVP_DecryptFinal_ex(ctx, buf, &outl);
753 else
754 EVP_EncryptFinal_ex(ctx, buf, &outl);
755 return count;
756}
44ca7565 757
fe4f66d2
PS
758/*
759 * CCM does not support streaming. For the purpose of performance measurement,
760 * each message is encrypted using the same (key,iv)-pair. Do not use this
761 * code in your application.
762 */
763static int EVP_Update_loop_ccm(void *args)
764{
765 loopargs_t *tempargs = *(loopargs_t **) args;
766 unsigned char *buf = tempargs->buf;
767 EVP_CIPHER_CTX *ctx = tempargs->ctx;
768 int outl, count;
769 unsigned char tag[12];
d02b7e09 770
fe4f66d2 771 if (decrypt) {
d02b7e09 772 for (count = 0; COND(c[D_EVP][testnum]); count++) {
5c8c2e6b
P
773 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
774 tag);
7da84e0f 775 /* reset iv */
5c8c2e6b 776 (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
7da84e0f 777 /* counter is reset on every update */
5c8c2e6b 778 (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
fe4f66d2
PS
779 }
780 } else {
d02b7e09 781 for (count = 0; COND(c[D_EVP][testnum]); count++) {
7da84e0f 782 /* restore iv length field */
5c8c2e6b 783 (void)EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
7da84e0f 784 /* counter is reset on every update */
5c8c2e6b 785 (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
fe4f66d2
PS
786 }
787 }
7da84e0f 788 if (decrypt)
5c8c2e6b 789 (void)EVP_DecryptFinal_ex(ctx, buf, &outl);
7da84e0f 790 else
5c8c2e6b 791 (void)EVP_EncryptFinal_ex(ctx, buf, &outl);
fe4f66d2
PS
792 return count;
793}
8b0b80d9 794
44ca7565
AP
795/*
796 * To make AEAD benchmarking more relevant perform TLS-like operations,
797 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
798 * payload length is not actually limited by 16KB...
799 */
800static int EVP_Update_loop_aead(void *args)
801{
802 loopargs_t *tempargs = *(loopargs_t **) args;
803 unsigned char *buf = tempargs->buf;
804 EVP_CIPHER_CTX *ctx = tempargs->ctx;
805 int outl, count;
806 unsigned char aad[13] = { 0xcc };
807 unsigned char faketag[16] = { 0xcc };
d02b7e09 808
44ca7565 809 if (decrypt) {
d02b7e09 810 for (count = 0; COND(c[D_EVP][testnum]); count++) {
a02d70dd
P
811 (void)EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
812 (void)EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
813 sizeof(faketag), faketag);
814 (void)EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
815 (void)EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
816 (void)EVP_DecryptFinal_ex(ctx, buf + outl, &outl);
44ca7565
AP
817 }
818 } else {
d02b7e09 819 for (count = 0; COND(c[D_EVP][testnum]); count++) {
a02d70dd
P
820 (void)EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv);
821 (void)EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad));
822 (void)EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
823 (void)EVP_EncryptFinal_ex(ctx, buf + outl, &outl);
44ca7565
AP
824 }
825 }
826 return count;
827}
828
70c4e156 829static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */
8b0b80d9
AG
830
831static int RSA_sign_loop(void *args)
832{
29dd15b1 833 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
834 unsigned char *buf = tempargs->buf;
835 unsigned char *buf2 = tempargs->buf2;
f3ccfc76
TM
836 size_t *rsa_num = &tempargs->sigsize;
837 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
8b0b80d9 838 int ret, count;
861f265a 839
8b0b80d9 840 for (count = 0; COND(rsa_c[testnum][0]); count++) {
e7414634 841 *rsa_num = tempargs->buflen;
f3ccfc76
TM
842 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
843 if (ret <= 0) {
8b0b80d9
AG
844 BIO_printf(bio_err, "RSA sign failure\n");
845 ERR_print_errors(bio_err);
846 count = -1;
847 break;
848 }
849 }
850 return count;
851}
852
853static int RSA_verify_loop(void *args)
854{
29dd15b1 855 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
856 unsigned char *buf = tempargs->buf;
857 unsigned char *buf2 = tempargs->buf2;
f3ccfc76
TM
858 size_t rsa_num = tempargs->sigsize;
859 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
8b0b80d9 860 int ret, count;
861f265a 861
8b0b80d9 862 for (count = 0; COND(rsa_c[testnum][1]); count++) {
f3ccfc76 863 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
8b0b80d9
AG
864 if (ret <= 0) {
865 BIO_printf(bio_err, "RSA verify failure\n");
866 ERR_print_errors(bio_err);
867 count = -1;
868 break;
869 }
870 }
871 return count;
872}
8b0b80d9 873
60d3b5b9
HK
874#ifndef OPENSSL_NO_DH
875static long ffdh_c[FFDH_NUM][1];
876
877static int FFDH_derive_key_loop(void *args)
878{
861f265a
TM
879 loopargs_t *tempargs = *(loopargs_t **) args;
880 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
881 unsigned char *derived_secret = tempargs->secret_ff_a;
882 size_t outlen = MAX_FFDH_SIZE;
883 int count;
60d3b5b9 884
861f265a
TM
885 for (count = 0; COND(ffdh_c[testnum][0]); count++)
886 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
887 return count;
60d3b5b9
HK
888}
889#endif /* OPENSSL_NO_DH */
890
8b0b80d9
AG
891static long dsa_c[DSA_NUM][2];
892static int DSA_sign_loop(void *args)
893{
29dd15b1 894 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
895 unsigned char *buf = tempargs->buf;
896 unsigned char *buf2 = tempargs->buf2;
f3ccfc76
TM
897 size_t *dsa_num = &tempargs->sigsize;
898 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
8b0b80d9 899 int ret, count;
861f265a 900
8b0b80d9 901 for (count = 0; COND(dsa_c[testnum][0]); count++) {
e7414634 902 *dsa_num = tempargs->buflen;
f3ccfc76
TM
903 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
904 if (ret <= 0) {
8b0b80d9
AG
905 BIO_printf(bio_err, "DSA sign failure\n");
906 ERR_print_errors(bio_err);
0ff43435 907 count = -1;
8b0b80d9
AG
908 break;
909 }
910 }
911 return count;
912}
913
914static int DSA_verify_loop(void *args)
915{
29dd15b1 916 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9
AG
917 unsigned char *buf = tempargs->buf;
918 unsigned char *buf2 = tempargs->buf2;
f3ccfc76
TM
919 size_t dsa_num = tempargs->sigsize;
920 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
8b0b80d9 921 int ret, count;
861f265a 922
8b0b80d9 923 for (count = 0; COND(dsa_c[testnum][1]); count++) {
f3ccfc76 924 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
8b0b80d9
AG
925 if (ret <= 0) {
926 BIO_printf(bio_err, "DSA verify failure\n");
927 ERR_print_errors(bio_err);
0ff43435 928 count = -1;
8b0b80d9
AG
929 break;
930 }
931 }
932 return count;
933}
8b0b80d9 934
5c6a69f5 935static long ecdsa_c[ECDSA_NUM][2];
8b0b80d9
AG
936static int ECDSA_sign_loop(void *args)
937{
29dd15b1 938 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9 939 unsigned char *buf = tempargs->buf;
f3ccfc76
TM
940 unsigned char *buf2 = tempargs->buf2;
941 size_t *ecdsa_num = &tempargs->sigsize;
942 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
8b0b80d9 943 int ret, count;
861f265a 944
8b0b80d9 945 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
e7414634 946 *ecdsa_num = tempargs->buflen;
f3ccfc76
TM
947 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
948 if (ret <= 0) {
8b0b80d9
AG
949 BIO_printf(bio_err, "ECDSA sign failure\n");
950 ERR_print_errors(bio_err);
0ff43435 951 count = -1;
8b0b80d9
AG
952 break;
953 }
954 }
955 return count;
956}
957
958static int ECDSA_verify_loop(void *args)
959{
29dd15b1 960 loopargs_t *tempargs = *(loopargs_t **) args;
8b0b80d9 961 unsigned char *buf = tempargs->buf;
f3ccfc76
TM
962 unsigned char *buf2 = tempargs->buf2;
963 size_t ecdsa_num = tempargs->sigsize;
964 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
8b0b80d9 965 int ret, count;
861f265a 966
8b0b80d9 967 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
861f265a
TM
968 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
969 buf, 20);
f3ccfc76 970 if (ret <= 0) {
8b0b80d9
AG
971 BIO_printf(bio_err, "ECDSA verify failure\n");
972 ERR_print_errors(bio_err);
0ff43435 973 count = -1;
8b0b80d9
AG
974 break;
975 }
976 }
977 return count;
978}
979
19075d58 980/* ******************************************************************** */
c5baa266
F
981static long ecdh_c[EC_NUM][1];
982
ed7377db
NT
983static int ECDH_EVP_derive_key_loop(void *args)
984{
985 loopargs_t *tempargs = *(loopargs_t **) args;
ed7377db
NT
986 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
987 unsigned char *derived_secret = tempargs->secret_a;
358558eb 988 int count;
cc98e639 989 size_t *outlen = &(tempargs->outlen[testnum]);
3331e43b 990
db1dd936 991 for (count = 0; COND(ecdh_c[testnum][0]); count++)
f7d984dd
NT
992 EVP_PKEY_derive(ctx, derived_secret, outlen);
993
8b0b80d9
AG
994 return count;
995}
5f986ed3 996
d3a9fb10
PY
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;
52307f94 1004 size_t *eddsasigsize = &tempargs->sigsize;
d3a9fb10
PY
1005 int ret, count;
1006
1007 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
52307f94 1008 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
d3a9fb10
PY
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;
1154ffbf 1023 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
d3a9fb10 1024 unsigned char *eddsasig = tempargs->buf2;
52307f94 1025 size_t eddsasigsize = tempargs->sigsize;
d3a9fb10
PY
1026 int ret, count;
1027
1028 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
52307f94 1029 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
d3a9fb10
PY
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}
a56f68ad 1039
f3ccfc76 1040#ifndef OPENSSL_NO_SM2
a56f68ad
PY
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;
c2279499 1048 size_t sm2sigsize;
a56f68ad
PY
1049 int ret, count;
1050 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
ed576acd 1051 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
a56f68ad
PY
1052
1053 for (count = 0; COND(sm2_c[testnum][0]); count++) {
c2279499
CZ
1054 sm2sigsize = max_size;
1055
a56f68ad
PY
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;
a56f68ad
PY
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}
f3ccfc76 1107#endif /* OPENSSL_NO_SM2 */
8b0b80d9 1108
700b8145 1109static int run_benchmark(int async_jobs,
29dd15b1 1110 int (*loop_function) (void *), loopargs_t * loopargs)
8b0b80d9
AG
1111{
1112 int job_op_count = 0;
1113 int total_op_count = 0;
1114 int num_inprogress = 0;
700b8145 1115 int error = 0, i = 0, ret = 0;
1e613922
AG
1116 OSSL_ASYNC_FD job_fd = 0;
1117 size_t num_job_fds = 0;
8b0b80d9 1118
0ff43435 1119 if (async_jobs == 0) {
fb2141c7 1120 return loop_function((void *)&loopargs);
8b0b80d9
AG
1121 }
1122
1123 for (i = 0; i < async_jobs && !error; i++) {
fb2141c7
F
1124 loopargs_t *looparg_item = loopargs + i;
1125
1126 /* Copy pointer content (looparg_t item address) into async context */
700b8145
F
1127 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1128 &job_op_count, loop_function,
fb2141c7 1129 (void *)&looparg_item, sizeof(looparg_item));
700b8145 1130 switch (ret) {
fd4b0c08
F
1131 case ASYNC_PAUSE:
1132 ++num_inprogress;
1133 break;
1134 case ASYNC_FINISH:
1135 if (job_op_count == -1) {
8b0b80d9 1136 error = 1;
fd4b0c08
F
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;
8b0b80d9
AG
1147 }
1148 }
1149
1150 while (num_inprogress > 0) {
2ea92604 1151#if defined(OPENSSL_SYS_WINDOWS)
564e1029 1152 DWORD avail = 0;
2ea92604 1153#elif defined(OPENSSL_SYS_UNIX)
8b0b80d9 1154 int select_result = 0;
564e1029
AG
1155 OSSL_ASYNC_FD max_fd = 0;
1156 fd_set waitfdset;
363a1fc6 1157
564e1029 1158 FD_ZERO(&waitfdset);
1e613922 1159
564e1029
AG
1160 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1161 if (loopargs[i].inprogress_job == NULL)
1162 continue;
1e613922 1163
29dd15b1
NT
1164 if (!ASYNC_WAIT_CTX_get_all_fds
1165 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1166 || num_job_fds > 1) {
564e1029
AG
1167 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1168 ERR_print_errors(bio_err);
1169 error = 1;
1170 break;
8b0b80d9 1171 }
29dd15b1
NT
1172 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1173 &num_job_fds);
564e1029
AG
1174 FD_SET(job_fd, &waitfdset);
1175 if (job_fd > max_fd)
1176 max_fd = job_fd;
8b0b80d9 1177 }
8b0b80d9 1178
402ec2f5 1179 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
570c0716 1180 BIO_printf(bio_err,
29dd15b1
NT
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);
570c0716
AG
1184 ERR_print_errors(bio_err);
1185 error = 1;
1186 break;
1187 }
1188
564e1029 1189 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
8b0b80d9
AG
1190 if (select_result == -1 && errno == EINTR)
1191 continue;
1192
1193 if (select_result == -1) {
564e1029
AG
1194 BIO_printf(bio_err, "Failure in the select\n");
1195 ERR_print_errors(bio_err);
1196 error = 1;
1197 break;
8b0b80d9
AG
1198 }
1199
1200 if (select_result == 0)
1201 continue;
8b0b80d9
AG
1202#endif
1203
1204 for (i = 0; i < async_jobs; i++) {
1205 if (loopargs[i].inprogress_job == NULL)
1206 continue;
1207
29dd15b1
NT
1208 if (!ASYNC_WAIT_CTX_get_all_fds
1209 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1210 || num_job_fds > 1) {
1e613922
AG
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 }
29dd15b1
NT
1216 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1217 &num_job_fds);
8b0b80d9 1218
667867cc 1219#if defined(OPENSSL_SYS_UNIX)
1e613922 1220 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
8b0b80d9 1221 continue;
667867cc 1222#elif defined(OPENSSL_SYS_WINDOWS)
fd4b0c08 1223 if (num_job_fds == 1
700b8145 1224 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
fd4b0c08 1225 && avail > 0)
8b0b80d9
AG
1226 continue;
1227#endif
1228
609b0852 1229 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
29dd15b1
NT
1230 loopargs[i].wait_ctx, &job_op_count,
1231 loop_function, (void *)(loopargs + i),
1232 sizeof(loopargs_t));
700b8145 1233 switch (ret) {
fd4b0c08
F
1234 case ASYNC_PAUSE:
1235 break;
1236 case ASYNC_FINISH:
1237 if (job_op_count == -1) {
8b0b80d9 1238 error = 1;
fd4b0c08
F
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;
8b0b80d9
AG
1253 }
1254 }
1255 }
1256
1257 return error ? -1 : total_op_count;
1258}
1259
f3ccfc76
TM
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;
128d25ba 1266
f3ccfc76 1267static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
128d25ba 1268{
f3ccfc76
TM
1269 EVP_PKEY_CTX *kctx = NULL;
1270 EVP_PKEY *key = NULL;
128d25ba 1271
f3ccfc76
TM
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);
128d25ba
DB
1277 }
1278
f3ccfc76
TM
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;
128d25ba
DB
1338}
1339
f607f6ea
F
1340#define stop_it(do_it, test_num)\
1341 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1342
8b0b80d9
AG
1343int speed_main(int argc, char **argv)
1344{
dd1abd44 1345 ENGINE *e = NULL;
8b0b80d9 1346 loopargs_t *loopargs = NULL;
5c6a69f5 1347 const char *prog;
19075d58 1348 const char *engine_id = NULL;
128d25ba 1349 EVP_CIPHER *evp_cipher = NULL;
c696f4bf 1350 EVP_MAC *mac = NULL;
8b0b80d9
AG
1351 double d = 0.0;
1352 OPTION_CHOICE o;
5c6a69f5 1353 int async_init = 0, multiblock = 0, pr_header = 0;
f607f6ea 1354 uint8_t doit[ALGOR_NUM] = { 0 };
44ca7565 1355 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
19075d58 1356 long count = 0;
1352e0ff 1357 unsigned int size_num = SIZE_NUM;
f607f6ea 1358 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
6b1fe3d0 1359 int keylen;
397e23f8 1360 int buflen;
f3ccfc76
TM
1361 BIGNUM *bn = NULL;
1362 EVP_PKEY_CTX *genctx = NULL;
8b0b80d9
AG
1363#ifndef NO_FORK
1364 int multi = 0;
1365#endif
f3ccfc76 1366 long op_count = 1;
5c6a69f5 1367 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
d3a9fb10 1368 ECDSA_SECONDS, ECDH_SECONDS,
60d3b5b9
HK
1369 EdDSA_SECONDS, SM2_SECONDS,
1370 FFDH_SECONDS };
5f986ed3 1371
0f113f3e
MC
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 };
f3ccfc76
TM
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 };
d63d89ea
F
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 },
f3ccfc76 1392 { test4096, sizeof(test4096), 4096 },
d63d89ea
F
1393 { test7680, sizeof(test7680), 7680 },
1394 { test15360, sizeof(test15360), 15360 }
0f113f3e 1395 };
f607f6ea 1396 uint8_t rsa_doit[RSA_NUM] = { 0 };
665d899f 1397 int primes = RSA_DEFAULT_PRIME_NUM;
60d3b5b9
HK
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 */
4d82c58b 1415 static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
f607f6ea 1416 uint8_t dsa_doit[DSA_NUM] = { 0 };
0f113f3e
MC
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
1352e0ff
F
1420 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1421 * lists accordingly.
0f113f3e 1422 */
d63d89ea 1423 static const EC_CURVE ec_curves[EC_NUM] = {
0f113f3e 1424 /* Prime Curves */
48bc0d99
F
1425 {"secp160r1", NID_secp160r1, 160},
1426 {"nistp192", NID_X9_62_prime192v1, 192},
1427 {"nistp224", NID_secp224r1, 224},
1428 {"nistp256", NID_X9_62_prime256v1, 256},
5c8b7b4c 1429 {"nistp384", NID_secp384r1, 384},
48bc0d99 1430 {"nistp521", NID_secp521r1, 521},
f3ccfc76 1431#ifndef OPENSSL_NO_EC2M
0f113f3e 1432 /* Binary Curves */
48bc0d99 1433 {"nistk163", NID_sect163k1, 163},
5c8b7b4c 1434 {"nistk233", NID_sect233k1, 233},
48bc0d99
F
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},
f3ccfc76 1443#endif
1c534560
F
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},
5c6a69f5 1450 /* Other and ECDH only ones */
48bc0d99
F
1451 {"X25519", NID_X25519, 253},
1452 {"X448", NID_X448, 448}
0f113f3e 1453 };
d63d89ea 1454 static const EC_CURVE ed_curves[EdDSA_NUM] = {
d3a9fb10
PY
1455 /* EdDSA */
1456 {"Ed25519", NID_ED25519, 253, 64},
1457 {"Ed448", NID_ED448, 456, 114}
1458 };
f3ccfc76 1459#ifndef OPENSSL_NO_SM2
d63d89ea 1460 static const EC_CURVE sm2_curves[SM2_NUM] = {
a56f68ad
PY
1461 /* SM2 */
1462 {"CurveSM2", NID_sm2, 256}
1463 };
f607f6ea 1464 uint8_t sm2_doit[SM2_NUM] = { 0 };
f3ccfc76 1465#endif
f607f6ea
F
1466 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1467 uint8_t ecdh_doit[EC_NUM] = { 0 };
1468 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1352e0ff 1469
07c5465e 1470 /* checks declared curves against choices list. */
1352e0ff
F
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
f3ccfc76 1480#ifndef OPENSSL_NO_SM2
1352e0ff
F
1481 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1482 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
f3ccfc76 1483#endif
7e1b7485
RS
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:
0f113f3e 1498 usertime = 0;
7e1b7485
RS
1499 break;
1500 case OPT_EVP:
128d25ba
DB
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 }
eaf8a40d
TM
1505 ERR_set_mark();
1506 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
a89cd8d8
TM
1507 if (have_md(opt_arg()))
1508 evp_md_name = opt_arg();
1509 }
1510 if (evp_cipher == NULL && evp_md_name == NULL) {
eaf8a40d 1511 ERR_clear_last_mark();
7e1b7485 1512 BIO_printf(bio_err,
55b09fe6 1513 "%s: %s is an unknown cipher or digest\n",
7e1b7485 1514 prog, opt_arg());
0f113f3e
MC
1515 goto end;
1516 }
eaf8a40d 1517 ERR_pop_to_mark();
0f113f3e 1518 doit[D_EVP] = 1;
7e1b7485 1519 break;
f88b9b79 1520 case OPT_HMAC:
a89cd8d8 1521 if (!have_md(opt_arg())) {
f88b9b79
P
1522 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1523 prog, opt_arg());
1524 goto end;
1525 }
a89cd8d8
TM
1526 evp_mac_mdname = opt_arg();
1527 doit[D_HMAC] = 1;
f88b9b79 1528 break;
9bba2c4c 1529 case OPT_CMAC:
f3ccfc76 1530 if (!have_cipher(opt_arg())) {
9bba2c4c
BE
1531 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1532 prog, opt_arg());
1533 goto end;
1534 }
f3ccfc76 1535 evp_mac_ciphername = opt_arg();
9bba2c4c 1536 doit[D_EVP_CMAC] = 1;
9bba2c4c 1537 break;
7e1b7485 1538 case OPT_DECRYPT:
0f113f3e 1539 decrypt = 1;
7e1b7485 1540 break;
7e1b7485 1541 case OPT_ENGINE:
8b0b80d9
AG
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();
7e1b7485 1548 break;
7e1b7485 1549 case OPT_MULTI:
9c3bcfa0 1550#ifndef NO_FORK
78212c64 1551 multi = opt_int_arg();
7220085f
P
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 }
8b0b80d9
AG
1556#endif
1557 break;
1558 case OPT_ASYNCJOBS:
667867cc 1559#ifndef OPENSSL_NO_ASYNC
78212c64 1560 async_jobs = opt_int_arg();
667867cc
MC
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 }
f8aa1572 1567 if (async_jobs > 99999) {
5c6a69f5 1568 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
f8aa1572
BE
1569 goto opterr;
1570 }
a00ae6c4 1571#endif
9c3bcfa0 1572 break;
7e1b7485 1573 case OPT_MISALIGN:
d830526c 1574 misalign = opt_int_arg();
7e1b7485 1575 if (misalign > MISALIGN) {
0f113f3e 1576 BIO_printf(bio_err,
7e1b7485
RS
1577 "%s: Maximum offset is %d\n", prog, MISALIGN);
1578 goto opterr;
0f113f3e 1579 }
7e1b7485
RS
1580 break;
1581 case OPT_MR:
1582 mr = 1;
1583 break;
1584 case OPT_MB:
1585 multiblock = 1;
cfd451d4
F
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
7e1b7485 1592 break;
3ee1eac2
RS
1593 case OPT_R_CASES:
1594 if (!opt_rand(o))
1595 goto end;
1596 break;
6bd4e3f2
P
1597 case OPT_PROV_CASES:
1598 if (!opt_provider(o))
1599 goto end;
1600 break;
665d899f 1601 case OPT_PRIMES:
d830526c 1602 primes = opt_int_arg();
665d899f 1603 break;
64daf14d
PS
1604 case OPT_SECONDS:
1605 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
a56f68ad 1606 = seconds.ecdh = seconds.eddsa
78212c64 1607 = seconds.sm2 = seconds.ffdh = opt_int_arg();
64daf14d
PS
1608 break;
1609 case OPT_BYTES:
78212c64 1610 lengths_single = opt_int_arg();
64daf14d
PS
1611 lengths = &lengths_single;
1612 size_num = 1;
1613 break;
44ca7565
AP
1614 case OPT_AEAD:
1615 aead = 1;
1616 break;
7e1b7485
RS
1617 }
1618 }
021410ea
RS
1619
1620 /* Remaining arguments are algorithms. */
7e1b7485
RS
1621 argc = opt_num_rest();
1622 argv = opt_rest();
1623
3ad60309
DDO
1624 if (!app_RAND_load())
1625 goto end;
1626
29dd15b1 1627 for (; *argv; argv++) {
f607f6ea
F
1628 const char *algo = *argv;
1629
1352e0ff 1630 if (opt_found(algo, doit_choices, &i)) {
7e1b7485
RS
1631 doit[i] = 1;
1632 continue;
1633 }
f607f6ea 1634 if (strcmp(algo, "des") == 0) {
7e1b7485
RS
1635 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1636 continue;
1637 }
f607f6ea 1638 if (strcmp(algo, "sha") == 0) {
7e1b7485
RS
1639 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1640 continue;
1641 }
3a1ee3c1 1642#ifndef OPENSSL_NO_DEPRECATED_3_0
f607f6ea 1643 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
7e1b7485 1644 continue;
f3ccfc76 1645#endif
2ff286c2
DDO
1646 if (HAS_PREFIX(algo, "rsa")) {
1647 if (algo[sizeof("rsa") - 1] == '\0') {
f607f6ea
F
1648 memset(rsa_doit, 1, sizeof(rsa_doit));
1649 continue;
1650 }
1352e0ff 1651 if (opt_found(algo, rsa_choices, &i)) {
f607f6ea
F
1652 rsa_doit[i] = 1;
1653 continue;
1654 }
7e1b7485 1655 }
60d3b5b9 1656#ifndef OPENSSL_NO_DH
2ff286c2
DDO
1657 if (HAS_PREFIX(algo, "ffdh")) {
1658 if (algo[sizeof("ffdh") - 1] == '\0') {
60d3b5b9
HK
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
2ff286c2
DDO
1668 if (HAS_PREFIX(algo, "dsa")) {
1669 if (algo[sizeof("dsa") - 1] == '\0') {
f607f6ea
F
1670 memset(dsa_doit, 1, sizeof(dsa_doit));
1671 continue;
1672 }
1352e0ff 1673 if (opt_found(algo, dsa_choices, &i)) {
f607f6ea
F
1674 dsa_doit[i] = 2;
1675 continue;
1676 }
7e1b7485 1677 }
f607f6ea 1678 if (strcmp(algo, "aes") == 0) {
29dd15b1 1679 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
7e1b7485
RS
1680 continue;
1681 }
f607f6ea 1682 if (strcmp(algo, "camellia") == 0) {
29dd15b1 1683 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
7e1b7485
RS
1684 continue;
1685 }
2ff286c2
DDO
1686 if (HAS_PREFIX(algo, "ecdsa")) {
1687 if (algo[sizeof("ecdsa") - 1] == '\0') {
f607f6ea
F
1688 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1689 continue;
1690 }
1352e0ff 1691 if (opt_found(algo, ecdsa_choices, &i)) {
f607f6ea
F
1692 ecdsa_doit[i] = 2;
1693 continue;
1694 }
0f113f3e 1695 }
2ff286c2
DDO
1696 if (HAS_PREFIX(algo, "ecdh")) {
1697 if (algo[sizeof("ecdh") - 1] == '\0') {
f607f6ea
F
1698 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1699 continue;
1700 }
1352e0ff 1701 if (opt_found(algo, ecdh_choices, &i)) {
f607f6ea
F
1702 ecdh_doit[i] = 2;
1703 continue;
1704 }
d3a9fb10 1705 }
1352e0ff
F
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;
d3a9fb10 1713 }
f3ccfc76 1714#ifndef OPENSSL_NO_SM2
f607f6ea
F
1715 if (strcmp(algo, "sm2") == 0) {
1716 memset(sm2_doit, 1, sizeof(sm2_doit));
a56f68ad
PY
1717 continue;
1718 }
1352e0ff 1719 if (opt_found(algo, sm2_choices, &i)) {
a56f68ad
PY
1720 sm2_doit[i] = 2;
1721 continue;
1722 }
f3ccfc76 1723#endif
f607f6ea 1724 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
7e1b7485 1725 goto end;
0f113f3e 1726 }
d02b48c6 1727
44ca7565
AP
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;
ed576acd 1733 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
44ca7565
AP
1734 EVP_CIPH_FLAG_AEAD_CIPHER)) {
1735 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
ed576acd 1736 EVP_CIPHER_get0_name(evp_cipher));
44ca7565
AP
1737 goto end;
1738 }
1739 }
1740 if (multiblock) {
1741 if (evp_cipher == NULL) {
861f265a
TM
1742 BIO_printf(bio_err, "-mb can be used only with a multi-block"
1743 " capable cipher\n");
44ca7565 1744 goto end;
ed576acd 1745 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
44ca7565
AP
1746 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1747 BIO_printf(bio_err, "%s is not a multi-block capable\n",
ed576acd 1748 EVP_CIPHER_get0_name(evp_cipher));
44ca7565
AP
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
8b0b80d9
AG
1756 /* Initialize the job pool if async mode is enabled */
1757 if (async_jobs > 0) {
dab1f5fe
CS
1758 async_init = ASYNC_init_thread(async_jobs, async_jobs);
1759 if (!async_init) {
8b0b80d9
AG
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);
29dd15b1
NT
1766 loopargs =
1767 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
8b0b80d9
AG
1768 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1769
0ff43435 1770 for (i = 0; i < loopargs_len; i++) {
1e613922
AG
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
2fc45cb8 1779 buflen = lengths[size_num - 1];
c2969ff6 1780 if (buflen < 36) /* size of random vector in RSA benchmark */
2fc45cb8 1781 buflen = 36;
378c50f6
KB
1782 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1783 BIO_printf(bio_err, "Error: buffer size too large\n");
1784 goto end;
1785 }
2fc45cb8 1786 buflen += MAX_MISALIGNMENT + 1;
397e23f8
PS
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
8b0b80d9
AG
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;
e7414634
XB
1795 loopargs[i].buflen = buflen - misalign;
1796 loopargs[i].sigsize = buflen - misalign;
0ff43435
AG
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");
60d3b5b9
HK
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");
0ff43435 1802#endif
8b0b80d9
AG
1803 }
1804
a00ae6c4 1805#ifndef NO_FORK
64daf14d 1806 if (multi && do_multi(multi, size_num))
0f113f3e 1807 goto show_res;
a00ae6c4 1808#endif
d02b48c6 1809
8b0b80d9 1810 /* Initialize the engine after the fork */
dd1abd44 1811 e = setup_engine(engine_id, 0);
8b0b80d9 1812
7e1b7485 1813 /* No parameters; turn on everything. */
a89cd8d8 1814 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
f607f6ea 1815 memset(doit, 1, sizeof(doit));
a89cd8d8 1816 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
f3ccfc76 1817 ERR_set_mark();
a89cd8d8
TM
1818 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1819 if (!have_md(names[i]))
1820 doit[i] = 0;
1821 }
f3ccfc76
TM
1822 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1823 if (!have_cipher(names[i]))
1824 doit[i] = 0;
1825 }
4d574312 1826 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
c696f4bf 1827 app_get0_propq())) != NULL) {
f3ccfc76 1828 EVP_MAC_free(mac);
c696f4bf
P
1829 mac = NULL;
1830 } else {
f3ccfc76 1831 doit[D_GHASH] = 0;
c696f4bf 1832 }
4d574312 1833 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
c696f4bf 1834 app_get0_propq())) != NULL) {
f3ccfc76 1835 EVP_MAC_free(mac);
c696f4bf
P
1836 mac = NULL;
1837 } else {
f3ccfc76 1838 doit[D_HMAC] = 0;
c696f4bf 1839 }
f3ccfc76 1840 ERR_pop_to_mark();
f607f6ea 1841 memset(rsa_doit, 1, sizeof(rsa_doit));
60d3b5b9
HK
1842#ifndef OPENSSL_NO_DH
1843 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1844#endif
f607f6ea 1845 memset(dsa_doit, 1, sizeof(dsa_doit));
f607f6ea
F
1846 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1847 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1848 memset(eddsa_doit, 1, sizeof(eddsa_doit));
f3ccfc76 1849#ifndef OPENSSL_NO_SM2
f607f6ea 1850 memset(sm2_doit, 1, sizeof(sm2_doit));
a00ae6c4 1851#endif
0f113f3e
MC
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
ee1d7f1d 1862#if SIGALRM > 0
ffcca684 1863 signal(SIGALRM, alarmed);
ee1d7f1d 1864#endif
0f113f3e 1865
0f113f3e 1866 if (doit[D_MD2]) {
64daf14d
PS
1867 for (testnum = 0; testnum < size_num; testnum++) {
1868 print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1869 seconds.sym);
0f113f3e 1870 Time_F(START);
8b0b80d9 1871 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
0f113f3e 1872 d = Time_F(STOP);
8b0b80d9 1873 print_result(D_MD2, testnum, count, d);
a89cd8d8
TM
1874 if (count < 0)
1875 break;
0f113f3e
MC
1876 }
1877 }
a89cd8d8 1878
0f113f3e 1879 if (doit[D_MDC2]) {
64daf14d
PS
1880 for (testnum = 0; testnum < size_num; testnum++) {
1881 print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1882 seconds.sym);
0f113f3e 1883 Time_F(START);
8b0b80d9 1884 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
0f113f3e 1885 d = Time_F(STOP);
8b0b80d9 1886 print_result(D_MDC2, testnum, count, d);
af0857f0
F
1887 if (count < 0)
1888 break;
0f113f3e
MC
1889 }
1890 }
d02b48c6 1891
0f113f3e 1892 if (doit[D_MD4]) {
64daf14d
PS
1893 for (testnum = 0; testnum < size_num; testnum++) {
1894 print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1895 seconds.sym);
0f113f3e 1896 Time_F(START);
8b0b80d9 1897 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
0f113f3e 1898 d = Time_F(STOP);
8b0b80d9 1899 print_result(D_MD4, testnum, count, d);
af0857f0
F
1900 if (count < 0)
1901 break;
0f113f3e
MC
1902 }
1903 }
3009458e 1904
0f113f3e 1905 if (doit[D_MD5]) {
64daf14d
PS
1906 for (testnum = 0; testnum < size_num; testnum++) {
1907 print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1908 seconds.sym);
0f113f3e 1909 Time_F(START);
8b0b80d9 1910 count = run_benchmark(async_jobs, MD5_loop, loopargs);
0f113f3e 1911 d = Time_F(STOP);
8b0b80d9 1912 print_result(D_MD5, testnum, count, d);
a89cd8d8
TM
1913 if (count < 0)
1914 break;
0f113f3e
MC
1915 }
1916 }
d02b48c6 1917
0f113f3e 1918 if (doit[D_SHA1]) {
64daf14d
PS
1919 for (testnum = 0; testnum < size_num; testnum++) {
1920 print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1921 seconds.sym);
0f113f3e 1922 Time_F(START);
8b0b80d9 1923 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
0f113f3e 1924 d = Time_F(STOP);
8b0b80d9 1925 print_result(D_SHA1, testnum, count, d);
a89cd8d8
TM
1926 if (count < 0)
1927 break;
0f113f3e
MC
1928 }
1929 }
a89cd8d8 1930
0f113f3e 1931 if (doit[D_SHA256]) {
64daf14d 1932 for (testnum = 0; testnum < size_num; testnum++) {
29dd15b1 1933 print_message(names[D_SHA256], c[D_SHA256][testnum],
64daf14d 1934 lengths[testnum], seconds.sym);
0f113f3e 1935 Time_F(START);
8b0b80d9 1936 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
0f113f3e 1937 d = Time_F(STOP);
8b0b80d9 1938 print_result(D_SHA256, testnum, count, d);
a89cd8d8
TM
1939 if (count < 0)
1940 break;
0f113f3e
MC
1941 }
1942 }
a89cd8d8 1943
0f113f3e 1944 if (doit[D_SHA512]) {
64daf14d 1945 for (testnum = 0; testnum < size_num; testnum++) {
29dd15b1 1946 print_message(names[D_SHA512], c[D_SHA512][testnum],
64daf14d 1947 lengths[testnum], seconds.sym);
0f113f3e 1948 Time_F(START);
8b0b80d9 1949 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
0f113f3e 1950 d = Time_F(STOP);
8b0b80d9 1951 print_result(D_SHA512, testnum, count, d);
a89cd8d8
TM
1952 if (count < 0)
1953 break;
0f113f3e
MC
1954 }
1955 }
a89cd8d8 1956
0f113f3e 1957 if (doit[D_WHIRLPOOL]) {
64daf14d 1958 for (testnum = 0; testnum < size_num; testnum++) {
29dd15b1 1959 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
64daf14d 1960 lengths[testnum], seconds.sym);
0f113f3e 1961 Time_F(START);
8b0b80d9 1962 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
0f113f3e 1963 d = Time_F(STOP);
8b0b80d9 1964 print_result(D_WHIRLPOOL, testnum, count, d);
a89cd8d8
TM
1965 if (count < 0)
1966 break;
0f113f3e
MC
1967 }
1968 }
c88f8f76 1969
0f113f3e 1970 if (doit[D_RMD160]) {
64daf14d 1971 for (testnum = 0; testnum < size_num; testnum++) {
29dd15b1 1972 print_message(names[D_RMD160], c[D_RMD160][testnum],
64daf14d 1973 lengths[testnum], seconds.sym);
0f113f3e 1974 Time_F(START);
8b0b80d9 1975 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
0f113f3e 1976 d = Time_F(STOP);
8b0b80d9 1977 print_result(D_RMD160, testnum, count, d);
af0857f0
F
1978 if (count < 0)
1979 break;
0f113f3e
MC
1980 }
1981 }
a89cd8d8
TM
1982
1983 if (doit[D_HMAC]) {
1984 static const char hmac_key[] = "This is a key...";
1985 int len = strlen(hmac_key);
a89cd8d8
TM
1986 OSSL_PARAM params[3];
1987
c696f4bf 1988 mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
a89cd8d8
TM
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] =
861f265a
TM
1998 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
1999 evp_mac_mdname, 0);
a89cd8d8 2000 params[1] =
861f265a
TM
2001 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2002 (char *)hmac_key, len);
a89cd8d8
TM
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))
f3ccfc76 2011 goto end;
a89cd8d8
TM
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);
c696f4bf 2026 mac = NULL;
a89cd8d8
TM
2027 }
2028
0f113f3e 2029 if (doit[D_CBC_DES]) {
f3ccfc76
TM
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,
861f265a 2034 sizeof(deskey) / 3);
f3ccfc76
TM
2035 st = loopargs[i].ctx != NULL;
2036 }
2037 algindex = D_CBC_DES;
2038 for (testnum = 0; st && testnum < size_num; testnum++) {
29dd15b1 2039 print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
64daf14d 2040 lengths[testnum], seconds.sym);
0f113f3e 2041 Time_F(START);
f3ccfc76 2042 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
0f113f3e 2043 d = Time_F(STOP);
8b0b80d9 2044 print_result(D_CBC_DES, testnum, count, d);
0f113f3e 2045 }
861f265a 2046 for (i = 0; i < loopargs_len; i++)
f3ccfc76 2047 EVP_CIPHER_CTX_free(loopargs[i].ctx);
0f113f3e 2048 }
ae93dc13 2049
0f113f3e 2050 if (doit[D_EDE3_DES]) {
f3ccfc76 2051 int st = 1;
5158c763 2052
f3ccfc76
TM
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;
0f113f3e 2057 }
f3ccfc76
TM
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],
64daf14d 2061 lengths[testnum], seconds.sym);
0f113f3e 2062 Time_F(START);
29dd15b1 2063 count =
f3ccfc76 2064 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
0f113f3e 2065 d = Time_F(STOP);
f3ccfc76 2066 print_result(D_EDE3_DES, testnum, count, d);
0f113f3e 2067 }
861f265a 2068 for (i = 0; i < loopargs_len; i++)
f3ccfc76 2069 EVP_CIPHER_CTX_free(loopargs[i].ctx);
0f113f3e 2070 }
5f09d0ec 2071
f3ccfc76
TM
2072 for (k = 0; k < 3; k++) {
2073 algindex = D_CBC_128_AES + k;
2074 if (doit[algindex]) {
2075 int st = 1;
c72fa255 2076
9695f6de 2077 keylen = 16 + k * 8;
f3ccfc76
TM
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 }
861f265a 2093 for (i = 0; i < loopargs_len; i++)
f3ccfc76 2094 EVP_CIPHER_CTX_free(loopargs[i].ctx);
0f113f3e
MC
2095 }
2096 }
f3ccfc76
TM
2097
2098 for (k = 0; k < 3; k++) {
2099 algindex = D_CBC_128_CML + k;
2100 if (doit[algindex]) {
2101 int st = 1;
2102
987a66a6 2103 keylen = 16 + k * 8;
f3ccfc76
TM
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 }
861f265a 2119 for (i = 0; i < loopargs_len; i++)
f3ccfc76 2120 EVP_CIPHER_CTX_free(loopargs[i].ctx);
0f113f3e
MC
2121 }
2122 }
f3ccfc76
TM
2123
2124 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2125 if (doit[algindex]) {
2126 int st = 1;
861f265a 2127
f3ccfc76
TM
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 }
861f265a 2144 for (i = 0; i < loopargs_len; i++)
f3ccfc76 2145 EVP_CIPHER_CTX_free(loopargs[i].ctx);
0f113f3e
MC
2146 }
2147 }
2148 if (doit[D_GHASH]) {
f3ccfc76 2149 static const char gmac_iv[] = "0123456789ab";
7f7640c4 2150 OSSL_PARAM params[3];
f3ccfc76 2151
c696f4bf 2152 mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
f3ccfc76
TM
2153 if (mac == NULL)
2154 goto end;
2155
861f265a
TM
2156 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2157 "aes-128-gcm", 0);
7f7640c4 2158 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
861f265a
TM
2159 (char *)gmac_iv,
2160 sizeof(gmac_iv) - 1);
7f7640c4 2161 params[2] = OSSL_PARAM_construct_end();
f3ccfc76 2162
0ff43435 2163 for (i = 0; i < loopargs_len; i++) {
f3ccfc76
TM
2164 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2165 if (loopargs[i].mctx == NULL)
2166 goto end;
0f113f3e 2167
7f7640c4 2168 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
f3ccfc76
TM
2169 goto end;
2170 }
64daf14d 2171 for (testnum = 0; testnum < size_num; testnum++) {
f3ccfc76
TM
2172 print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2173 seconds.sym);
0f113f3e 2174 Time_F(START);
f3ccfc76 2175 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
0f113f3e 2176 d = Time_F(STOP);
8b0b80d9 2177 print_result(D_GHASH, testnum, count, d);
f3ccfc76
TM
2178 if (count < 0)
2179 break;
0f113f3e 2180 }
0ff43435 2181 for (i = 0; i < loopargs_len; i++)
f3ccfc76
TM
2182 EVP_MAC_CTX_free(loopargs[i].mctx);
2183 EVP_MAC_free(mac);
c696f4bf 2184 mac = NULL;
0f113f3e 2185 }
f3ccfc76 2186
65e6b9a4 2187 if (doit[D_RAND]) {
64daf14d
PS
2188 for (testnum = 0; testnum < size_num; testnum++) {
2189 print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2190 seconds.sym);
65e6b9a4
PS
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 }
f3dea9a5 2197
0f113f3e 2198 if (doit[D_EVP]) {
44ca7565 2199 if (evp_cipher != NULL) {
d02b7e09 2200 int (*loopfunc) (void *) = EVP_Update_loop;
44ca7565 2201
ed576acd 2202 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
44ca7565
AP
2203 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2204 multiblock_speed(evp_cipher, lengths_single, &seconds);
2205 ret = 0;
0f113f3e
MC
2206 goto end;
2207 }
44ca7565 2208
ed576acd 2209 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
44ca7565 2210
ed576acd 2211 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
44ca7565 2212 loopfunc = EVP_Update_loop_ccm;
ed576acd 2213 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
44ca7565
AP
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 }
8b0b80d9 2220 }
0f113f3e 2221
44ca7565 2222 for (testnum = 0; testnum < size_num; testnum++) {
d02b7e09 2223 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
64daf14d 2224 seconds.sym);
8b0b80d9
AG
2225
2226 for (k = 0; k < loopargs_len; k++) {
2227 loopargs[k].ctx = EVP_CIPHER_CTX_new();
5d238a10
BE
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 }
6b1fe3d0 2238
8b0b80d9 2239 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
6b1fe3d0 2240
ed576acd 2241 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
6b1fe3d0
PS
2242 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2243 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
5d238a10
BE
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 }
6b1fe3d0 2250 OPENSSL_clear_free(loopargs[k].key, keylen);
b1ceb439
TS
2251
2252 /* SIV mode only allows for a single Update operation */
ed576acd 2253 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
5c8c2e6b
P
2254 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2255 EVP_CTRL_SET_SPEED, 1, NULL);
8b0b80d9 2256 }
0f113f3e
MC
2257
2258 Time_F(START);
fe4f66d2 2259 count = run_benchmark(async_jobs, loopfunc, loopargs);
0f113f3e 2260 d = Time_F(STOP);
861f265a 2261 for (k = 0; k < loopargs_len; k++)
8b0b80d9 2262 EVP_CIPHER_CTX_free(loopargs[k].ctx);
44ca7565 2263 print_result(D_EVP, testnum, count, d);
0f113f3e 2264 }
a89cd8d8
TM
2265 } else if (evp_md_name != NULL) {
2266 names[D_EVP] = evp_md_name;
44ca7565
AP
2267
2268 for (testnum = 0; testnum < size_num; testnum++) {
d02b7e09 2269 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
64daf14d 2270 seconds.sym);
0f113f3e 2271 Time_F(START);
a89cd8d8 2272 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
0f113f3e 2273 d = Time_F(STOP);
44ca7565 2274 print_result(D_EVP, testnum, count, d);
a89cd8d8
TM
2275 if (count < 0)
2276 break;
0f113f3e 2277 }
0f113f3e
MC
2278 }
2279 }
7e1b7485 2280
f3ccfc76 2281 if (doit[D_EVP_CMAC]) {
f3ccfc76 2282 OSSL_PARAM params[3];
eaf8a40d 2283 EVP_CIPHER *cipher = NULL;
d02b7e09 2284
c696f4bf 2285 mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
f3ccfc76
TM
2286 if (mac == NULL || evp_mac_ciphername == NULL)
2287 goto end;
eaf8a40d 2288 if (!opt_cipher(evp_mac_ciphername, &cipher))
f3ccfc76
TM
2289 goto end;
2290
ed576acd 2291 keylen = EVP_CIPHER_get_key_length(cipher);
eaf8a40d 2292 EVP_CIPHER_free(cipher);
f3ccfc76
TM
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 }
861f265a
TM
2297 evp_cmac_name = app_malloc(sizeof("cmac()")
2298 + strlen(evp_mac_ciphername), "CMAC name");
f3ccfc76 2299 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
d02b7e09
F
2300 names[D_EVP_CMAC] = evp_cmac_name;
2301
861f265a
TM
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);
f3ccfc76
TM
2306 params[2] = OSSL_PARAM_construct_end();
2307
d02b7e09 2308 for (i = 0; i < loopargs_len; i++) {
f3ccfc76
TM
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;
9bba2c4c 2315 }
861f265a 2316
d02b7e09 2317 for (testnum = 0; testnum < size_num; testnum++) {
861f265a
TM
2318 print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2319 lengths[testnum], seconds.sym);
d02b7e09 2320 Time_F(START);
f3ccfc76 2321 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
d02b7e09
F
2322 d = Time_F(STOP);
2323 print_result(D_EVP_CMAC, testnum, count, d);
f3ccfc76
TM
2324 if (count < 0)
2325 break;
d02b7e09
F
2326 }
2327 for (i = 0; i < loopargs_len; i++)
f3ccfc76
TM
2328 EVP_MAC_CTX_free(loopargs[i].mctx);
2329 EVP_MAC_free(mac);
c696f4bf 2330 mac = NULL;
9bba2c4c 2331 }
9bba2c4c 2332
0ff43435 2333 for (i = 0; i < loopargs_len; i++)
3445872e 2334 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2335 goto end;
8b0b80d9 2336
8b0b80d9 2337 for (testnum = 0; testnum < RSA_NUM; testnum++) {
f3ccfc76 2338 EVP_PKEY *rsa_key = NULL;
8b0b80d9 2339 int st = 0;
f3ccfc76 2340
8b0b80d9 2341 if (!rsa_doit[testnum])
0f113f3e 2342 continue;
665d899f 2343
f3ccfc76
TM
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;
665d899f 2360
f3ccfc76
TM
2361 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2362 rsa_keys[testnum].length)) != NULL;
2363 }
665d899f 2364
f3ccfc76 2365 for (i = 0; st && i < loopargs_len; i++) {
861f265a 2366 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
e7414634 2367 loopargs[i].sigsize = loopargs[i].buflen;
f3ccfc76
TM
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;
8b0b80d9 2375 }
f3ccfc76 2376 if (!st) {
0f113f3e 2377 BIO_printf(bio_err,
f3ccfc76 2378 "RSA sign setup failure. No RSA sign will be done.\n");
0f113f3e 2379 ERR_print_errors(bio_err);
9d0854f4 2380 op_count = 1;
0f113f3e
MC
2381 } else {
2382 pkey_print_message("private", "rsa",
d63d89ea 2383 rsa_c[testnum][0], rsa_keys[testnum].bits,
64daf14d 2384 seconds.rsa);
8b0b80d9 2385 /* RSA_blinding_on(rsa_key[testnum],NULL); */
0f113f3e 2386 Time_F(START);
8b0b80d9 2387 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
0f113f3e
MC
2388 d = Time_F(STOP);
2389 BIO_printf(bio_err,
2390 mr ? "+R1:%ld:%d:%.2f\n"
48bc0d99 2391 : "%ld %u bits private RSA's in %.2fs\n",
d63d89ea 2392 count, rsa_keys[testnum].bits, d);
8ac2d1ab 2393 rsa_results[testnum][0] = (double)count / d;
9d0854f4 2394 op_count = count;
0f113f3e 2395 }
d02b48c6 2396
f3ccfc76
TM
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;
8b0b80d9 2407 }
f3ccfc76 2408 if (!st) {
0f113f3e 2409 BIO_printf(bio_err,
f3ccfc76 2410 "RSA verify setup failure. No RSA verify will be done.\n");
0f113f3e 2411 ERR_print_errors(bio_err);
8b0b80d9 2412 rsa_doit[testnum] = 0;
0f113f3e
MC
2413 } else {
2414 pkey_print_message("public", "rsa",
d63d89ea 2415 rsa_c[testnum][1], rsa_keys[testnum].bits,
64daf14d 2416 seconds.rsa);
0f113f3e 2417 Time_F(START);
8b0b80d9 2418 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
0f113f3e
MC
2419 d = Time_F(STOP);
2420 BIO_printf(bio_err,
2421 mr ? "+R2:%ld:%d:%.2f\n"
48bc0d99 2422 : "%ld %u bits public RSA's in %.2fs\n",
d63d89ea 2423 count, rsa_keys[testnum].bits, d);
8ac2d1ab 2424 rsa_results[testnum][1] = (double)count / d;
0f113f3e 2425 }
d02b48c6 2426
9d0854f4 2427 if (op_count <= 1) {
0f113f3e 2428 /* if longer than 10s, don't do any more */
f607f6ea 2429 stop_it(rsa_doit, testnum);
0f113f3e 2430 }
f3ccfc76 2431 EVP_PKEY_free(rsa_key);
0f113f3e 2432 }
8b0b80d9 2433
8b0b80d9 2434 for (testnum = 0; testnum < DSA_NUM; testnum++) {
f3ccfc76
TM
2435 EVP_PKEY *dsa_key = NULL;
2436 int st;
2437
8b0b80d9 2438 if (!dsa_doit[testnum])
0f113f3e
MC
2439 continue;
2440
f3ccfc76
TM
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);
e7414634 2446 loopargs[i].sigsize = loopargs[i].buflen;
f3ccfc76
TM
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;
8b0b80d9 2455 }
f3ccfc76 2456 if (!st) {
0f113f3e 2457 BIO_printf(bio_err,
f3ccfc76 2458 "DSA sign setup failure. No DSA sign will be done.\n");
0f113f3e 2459 ERR_print_errors(bio_err);
9d0854f4 2460 op_count = 1;
0f113f3e
MC
2461 } else {
2462 pkey_print_message("sign", "dsa",
29dd15b1 2463 dsa_c[testnum][0], dsa_bits[testnum],
64daf14d 2464 seconds.dsa);
0f113f3e 2465 Time_F(START);
8b0b80d9 2466 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
0f113f3e
MC
2467 d = Time_F(STOP);
2468 BIO_printf(bio_err,
48bc0d99
F
2469 mr ? "+R3:%ld:%u:%.2f\n"
2470 : "%ld %u bits DSA signs in %.2fs\n",
8b0b80d9 2471 count, dsa_bits[testnum], d);
0d4de756 2472 dsa_results[testnum][0] = (double)count / d;
9d0854f4 2473 op_count = count;
0f113f3e 2474 }
e172d60d 2475
f3ccfc76
TM
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;
8b0b80d9 2486 }
f3ccfc76 2487 if (!st) {
0f113f3e 2488 BIO_printf(bio_err,
f3ccfc76 2489 "DSA verify setup failure. No DSA verify will be done.\n");
0f113f3e 2490 ERR_print_errors(bio_err);
8b0b80d9 2491 dsa_doit[testnum] = 0;
0f113f3e
MC
2492 } else {
2493 pkey_print_message("verify", "dsa",
29dd15b1 2494 dsa_c[testnum][1], dsa_bits[testnum],
64daf14d 2495 seconds.dsa);
0f113f3e 2496 Time_F(START);
8b0b80d9 2497 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
0f113f3e
MC
2498 d = Time_F(STOP);
2499 BIO_printf(bio_err,
48bc0d99
F
2500 mr ? "+R4:%ld:%u:%.2f\n"
2501 : "%ld %u bits DSA verify in %.2fs\n",
8b0b80d9 2502 count, dsa_bits[testnum], d);
0d4de756 2503 dsa_results[testnum][1] = (double)count / d;
0f113f3e 2504 }
e172d60d 2505
9d0854f4 2506 if (op_count <= 1) {
0f113f3e 2507 /* if longer than 10s, don't do any more */
f607f6ea 2508 stop_it(dsa_doit, testnum);
0f113f3e 2509 }
f3ccfc76 2510 EVP_PKEY_free(dsa_key);
0f113f3e 2511 }
e172d60d 2512
5c6a69f5 2513 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
f3ccfc76
TM
2514 EVP_PKEY *ecdsa_key = NULL;
2515 int st;
0f113f3e 2516
8b0b80d9 2517 if (!ecdsa_doit[testnum])
f3ccfc76
TM
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);
e7414634 2525 loopargs[i].sigsize = loopargs[i].buflen;
f3ccfc76
TM
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)
0ff43435 2533 st = 0;
0ff43435 2534 }
f3ccfc76
TM
2535 if (!st) {
2536 BIO_printf(bio_err,
2537 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
0f113f3e 2538 ERR_print_errors(bio_err);
9d0854f4 2539 op_count = 1;
0f113f3e 2540 } else {
f3ccfc76
TM
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 }
0f113f3e 2554
f3ccfc76
TM
2555 for (i = 0; st && i < loopargs_len; i++) {
2556 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
861f265a 2557 NULL);
f3ccfc76
TM
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 }
0f113f3e 2584
f3ccfc76
TM
2585 if (op_count <= 1) {
2586 /* if longer than 10s, don't do any more */
2587 stop_it(ecdsa_doit, testnum);
0f113f3e
MC
2588 }
2589 }
7e1b7485 2590
8b0b80d9 2591 for (testnum = 0; testnum < EC_NUM; testnum++) {
4d82c58b
F
2592 int ecdh_checks = 1;
2593
8b0b80d9 2594 if (!ecdh_doit[testnum])
0f113f3e 2595 continue;
ed7377db 2596
0ff43435 2597 for (i = 0; i < loopargs_len; i++) {
f7d984dd 2598 EVP_PKEY_CTX *test_ctx = NULL;
2e4c3b5c
NT
2599 EVP_PKEY_CTX *ctx = NULL;
2600 EVP_PKEY *key_A = NULL;
2601 EVP_PKEY *key_B = NULL;
cc98e639 2602 size_t outlen;
f7d984dd 2603 size_t test_outlen;
ed7377db 2604
861f265a
TM
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 */) {
ed7377db
NT
2613 ecdh_checks = 0;
2614 BIO_printf(bio_err, "ECDH key generation failure.\n");
2615 ERR_print_errors(bio_err);
9d0854f4 2616 op_count = 1;
ed7377db
NT
2617 break;
2618 }
2619
861f265a
TM
2620 /*
2621 * Here we perform a test run, comparing the output of a*B and b*A;
f7d984dd
NT
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
861f265a
TM
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) /* init derivation test_ctx */
2628 || !EVP_PKEY_derive_set_peer(test_ctx, key_A) /* set peer pubkey in test_ctx */
2629 || !EVP_PKEY_derive(test_ctx, NULL, &test_outlen) /* determine max length */
2630 || !EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) /* compute a*B */
2631 || !EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) /* compute b*A */
2632 || test_outlen != outlen /* compare output length */) {
f7d984dd
NT
2633 ecdh_checks = 0;
2634 BIO_printf(bio_err, "ECDH computation failure.\n");
2635 ERR_print_errors(bio_err);
9d0854f4 2636 op_count = 1;
f7d984dd
NT
2637 break;
2638 }
9bffdebc
NT
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;
f7d984dd
NT
2644 BIO_printf(bio_err, "ECDH computations don't match.\n");
2645 ERR_print_errors(bio_err);
9d0854f4 2646 op_count = 1;
f7d984dd
NT
2647 break;
2648 }
2649
ed7377db 2650 loopargs[i].ecdh_ctx[testnum] = ctx;
cc98e639 2651 loopargs[i].outlen[testnum] = outlen;
ed7377db 2652
a00cceb2
PS
2653 EVP_PKEY_free(key_A);
2654 EVP_PKEY_free(key_B);
f7d984dd
NT
2655 EVP_PKEY_CTX_free(test_ctx);
2656 test_ctx = NULL;
ed7377db
NT
2657 }
2658 if (ecdh_checks != 0) {
2659 pkey_print_message("", "ecdh",
29dd15b1 2660 ecdh_c[testnum][0],
d63d89ea 2661 ec_curves[testnum].bits, seconds.ecdh);
ed7377db 2662 Time_F(START);
29dd15b1
NT
2663 count =
2664 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
ed7377db
NT
2665 d = Time_F(STOP);
2666 BIO_printf(bio_err,
29dd15b1 2667 mr ? "+R7:%ld:%d:%.2f\n" :
48bc0d99 2668 "%ld %u-bits ECDH ops in %.2fs\n", count,
d63d89ea 2669 ec_curves[testnum].bits, d);
222c3da3 2670 ecdh_results[testnum][0] = (double)count / d;
9d0854f4 2671 op_count = count;
0f113f3e 2672 }
e172d60d 2673
9d0854f4 2674 if (op_count <= 1) {
0f113f3e 2675 /* if longer than 10s, don't do any more */
f607f6ea 2676 stop_it(ecdh_doit, testnum);
0f113f3e
MC
2677 }
2678 }
d3a9fb10
PY
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 }
1154ffbf
SAS
2693 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2694 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2695 st = 0;
2696 break;
2697 }
d3a9fb10 2698
861f265a
TM
2699 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2700 NULL)) == NULL
94bd168a
PY
2701 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2702 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
d3a9fb10
PY
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 }
861f265a
TM
2715 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2716 NULL, NULL, ed_pkey)) {
1154ffbf
SAS
2717 st = 0;
2718 EVP_PKEY_free(ed_pkey);
2719 break;
2720 }
2721
d3a9fb10 2722 EVP_PKEY_free(ed_pkey);
4f5b222b 2723 ed_pkey = NULL;
d3a9fb10
PY
2724 }
2725 if (st == 0) {
2726 BIO_printf(bio_err, "EdDSA failure.\n");
2727 ERR_print_errors(bio_err);
9d0854f4 2728 op_count = 1;
d3a9fb10
PY
2729 } else {
2730 for (i = 0; i < loopargs_len; i++) {
2731 /* Perform EdDSA signature test */
d63d89ea 2732 loopargs[i].sigsize = ed_curves[testnum].sigsize;
d3a9fb10 2733 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
52307f94 2734 loopargs[i].buf2, &loopargs[i].sigsize,
d3a9fb10
PY
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);
9d0854f4 2743 op_count = 1;
d3a9fb10 2744 } else {
d63d89ea 2745 pkey_print_message("sign", ed_curves[testnum].name,
d3a9fb10 2746 eddsa_c[testnum][0],
d63d89ea 2747 ed_curves[testnum].bits, seconds.eddsa);
d3a9fb10
PY
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",
d63d89ea
F
2755 count, ed_curves[testnum].bits,
2756 ed_curves[testnum].name, d);
d3a9fb10 2757 eddsa_results[testnum][0] = (double)count / d;
9d0854f4 2758 op_count = count;
d3a9fb10 2759 }
d3a9fb10
PY
2760 /* Perform EdDSA verification test */
2761 for (i = 0; i < loopargs_len; i++) {
1154ffbf 2762 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
52307f94 2763 loopargs[i].buf2, loopargs[i].sigsize,
d3a9fb10
PY
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 {
d63d89ea 2774 pkey_print_message("verify", ed_curves[testnum].name,
d3a9fb10 2775 eddsa_c[testnum][1],
d63d89ea 2776 ed_curves[testnum].bits, seconds.eddsa);
d3a9fb10
PY
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",
d63d89ea
F
2783 count, ed_curves[testnum].bits,
2784 ed_curves[testnum].name, d);
d3a9fb10
PY
2785 eddsa_results[testnum][1] = (double)count / d;
2786 }
2787
9d0854f4 2788 if (op_count <= 1) {
d3a9fb10 2789 /* if longer than 10s, don't do any more */
f607f6ea 2790 stop_it(eddsa_doit, testnum);
d3a9fb10
PY
2791 }
2792 }
2793 }
2794
f3ccfc76 2795#ifndef OPENSSL_NO_SM2
a56f68ad
PY
2796 for (testnum = 0; testnum < SM2_NUM; testnum++) {
2797 int st = 1;
2798 EVP_PKEY *sm2_pkey = NULL;
a56f68ad
PY
2799
2800 if (!sm2_doit[testnum])
2801 continue; /* Ignore Curve */
2802 /* Init signing and verification */
2803 for (i = 0; i < loopargs_len; i++) {
001d5e2c
F
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
a56f68ad 2809 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
a56f68ad 2810 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
001d5e2c
F
2811 if (loopargs[i].sm2_ctx[testnum] == NULL
2812 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
a56f68ad 2813 break;
a56f68ad 2814
c2279499
CZ
2815 sm2_pkey = NULL;
2816
2817 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
a56f68ad
PY
2818 || EVP_PKEY_keygen_init(pctx) <= 0
2819 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
d63d89ea 2820 sm2_curves[testnum].nid) <= 0
001d5e2c 2821 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
a56f68ad 2822 EVP_PKEY_CTX_free(pctx);
001d5e2c
F
2823 if (st == 0)
2824 break;
a56f68ad 2825
001d5e2c
F
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;
ed576acd 2829 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
a56f68ad
PY
2830
2831 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
a56f68ad 2832 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
001d5e2c
F
2833 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2834 EVP_PKEY_CTX_free(sm2_vfy_pctx);
a56f68ad
PY
2835 break;
2836 }
579422c8 2837
001d5e2c
F
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
a56f68ad
PY
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 */
001d5e2c
F
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)
a56f68ad 2848 break;
a56f68ad
PY
2849
2850 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
001d5e2c 2851 EVP_sm3(), NULL, sm2_pkey))
a56f68ad 2852 break;
a56f68ad 2853 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
001d5e2c 2854 EVP_sm3(), NULL, sm2_pkey))
a56f68ad 2855 break;
001d5e2c 2856 st = 1; /* mark loop as succeeded */
a56f68ad
PY
2857 }
2858 if (st == 0) {
001d5e2c 2859 BIO_printf(bio_err, "SM2 init failure.\n");
a56f68ad 2860 ERR_print_errors(bio_err);
9d0854f4 2861 op_count = 1;
a56f68ad
PY
2862 } else {
2863 for (i = 0; i < loopargs_len; i++) {
a56f68ad
PY
2864 /* Perform SM2 signature test */
2865 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
c2279499 2866 loopargs[i].buf2, &loopargs[i].sigsize,
a56f68ad
PY
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);
9d0854f4 2875 op_count = 1;
a56f68ad 2876 } else {
d63d89ea 2877 pkey_print_message("sign", sm2_curves[testnum].name,
a56f68ad 2878 sm2_c[testnum][0],
d63d89ea 2879 sm2_curves[testnum].bits, seconds.sm2);
a56f68ad
PY
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,
031c9bd3 2885 mr ? "+R10:%ld:%u:%s:%.2f\n" :
a56f68ad 2886 "%ld %u bits %s signs in %.2fs \n",
d63d89ea
F
2887 count, sm2_curves[testnum].bits,
2888 sm2_curves[testnum].name, d);
a56f68ad 2889 sm2_results[testnum][0] = (double)count / d;
9d0854f4 2890 op_count = count;
a56f68ad
PY
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 {
d63d89ea 2907 pkey_print_message("verify", sm2_curves[testnum].name,
a56f68ad 2908 sm2_c[testnum][1],
d63d89ea 2909 sm2_curves[testnum].bits, seconds.sm2);
a56f68ad
PY
2910 Time_F(START);
2911 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2912 d = Time_F(STOP);
2913 BIO_printf(bio_err,
031c9bd3 2914 mr ? "+R11:%ld:%u:%s:%.2f\n"
a56f68ad 2915 : "%ld %u bits %s verify in %.2fs\n",
d63d89ea
F
2916 count, sm2_curves[testnum].bits,
2917 sm2_curves[testnum].name, d);
a56f68ad
PY
2918 sm2_results[testnum][1] = (double)count / d;
2919 }
2920
9d0854f4 2921 if (op_count <= 1) {
a56f68ad
PY
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 }
f3ccfc76 2928#endif /* OPENSSL_NO_SM2 */
60d3b5b9
HK
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);
9d0854f4 2956 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 2964 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 2973 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 2981 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 2988 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 2997 op_count = 1;
60d3b5b9
HK
2998 ffdh_checks = 0;
2999 break;
3000 }
3001
3002 EVP_PKEY_CTX_free(ffdh_ctx);
3003
861f265a
TM
3004 /*
3005 * check if the derivation works correctly both ways so that
60d3b5b9 3006 * we know if future derive calls will fail, and we can skip
861f265a
TM
3007 * error checking in benchmarked code
3008 */
60d3b5b9 3009 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
f3ccfc76 3010 if (ffdh_ctx == NULL) {
60d3b5b9
HK
3011 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3012 ERR_print_errors(bio_err);
9d0854f4 3013 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3020 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3027 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3034 op_count = 1;
60d3b5b9
HK
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");
9d0854f4 3040 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3049 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3058 op_count = 1;
60d3b5b9
HK
3059 ffdh_checks = 0;
3060 break;
3061 }
3062 if (!EVP_PKEY_derive_init(test_ctx) ||
3063 !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) ||
3064 !EVP_PKEY_derive(test_ctx, NULL, &test_out) ||
3065 !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) ||
3066 test_out != secret_size) {
3067 BIO_printf(bio_err, "FFDH computation failure.\n");
9d0854f4 3068 op_count = 1;
60d3b5b9
HK
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);
9d0854f4 3078 op_count = 1;
60d3b5b9
HK
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;
9d0854f4 3104 op_count = count;
861f265a 3105 }
9d0854f4 3106 if (op_count <= 1) {
60d3b5b9
HK
3107 /* if longer than 10s, don't do any more */
3108 stop_it(ffdh_doit, testnum);
3109 }
3110 }
3111#endif /* OPENSSL_NO_DH */
a00ae6c4 3112#ifndef NO_FORK
0f113f3e 3113 show_res:
a00ae6c4 3114#endif
0f113f3e 3115 if (!mr) {
3a63dbef 3116 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
9e1b6f3c
RL
3117 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3118 printf("options: %s\n", BN_options());
3119 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
363e941e 3120 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
0f113f3e 3121 }
e172d60d 3122
0f113f3e 3123 if (pr_header) {
861f265a 3124 if (mr) {
7e1b7485 3125 printf("+H");
861f265a
TM
3126 } else {
3127 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
7e1b7485 3128 printf("type ");
0f113f3e 3129 }
64daf14d 3130 for (testnum = 0; testnum < size_num; testnum++)
8b0b80d9 3131 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
7e1b7485 3132 printf("\n");
0f113f3e 3133 }
e172d60d 3134
0f113f3e
MC
3135 for (k = 0; k < ALGOR_NUM; k++) {
3136 if (!doit[k])
3137 continue;
3138 if (mr)
5c6a69f5 3139 printf("+F:%u:%s", k, names[k]);
0f113f3e 3140 else
7e1b7485 3141 printf("%-13s", names[k]);
64daf14d 3142 for (testnum = 0; testnum < size_num; testnum++) {
8b0b80d9
AG
3143 if (results[k][testnum] > 10000 && !mr)
3144 printf(" %11.2fk", results[k][testnum] / 1e3);
0f113f3e 3145 else
8b0b80d9 3146 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
0f113f3e 3147 }
7e1b7485 3148 printf("\n");
0f113f3e 3149 }
8b0b80d9 3150 testnum = 1;
0f113f3e
MC
3151 for (k = 0; k < RSA_NUM; k++) {
3152 if (!rsa_doit[k])
3153 continue;
8b0b80d9 3154 if (testnum && !mr) {
0f113f3e 3155 printf("%18ssign verify sign/s verify/s\n", " ");
8b0b80d9 3156 testnum = 0;
0f113f3e
MC
3157 }
3158 if (mr)
7e1b7485 3159 printf("+F2:%u:%u:%f:%f\n",
d63d89ea 3160 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
0f113f3e 3161 else
7e1b7485 3162 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
d63d89ea 3163 rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
8ac2d1ab 3164 rsa_results[k][0], rsa_results[k][1]);
0f113f3e 3165 }
8b0b80d9 3166 testnum = 1;
0f113f3e
MC
3167 for (k = 0; k < DSA_NUM; k++) {
3168 if (!dsa_doit[k])
3169 continue;
8b0b80d9 3170 if (testnum && !mr) {
0f113f3e 3171 printf("%18ssign verify sign/s verify/s\n", " ");
8b0b80d9 3172 testnum = 0;
0f113f3e
MC
3173 }
3174 if (mr)
7e1b7485
RS
3175 printf("+F3:%u:%u:%f:%f\n",
3176 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
0f113f3e 3177 else
7e1b7485 3178 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
0d4de756
CS
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]);
0f113f3e 3181 }
8b0b80d9 3182 testnum = 1;
5c6a69f5 3183 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
0f113f3e
MC
3184 if (!ecdsa_doit[k])
3185 continue;
8b0b80d9 3186 if (testnum && !mr) {
0f113f3e 3187 printf("%30ssign verify sign/s verify/s\n", " ");
8b0b80d9 3188 testnum = 0;
0f113f3e
MC
3189 }
3190
3191 if (mr)
7e1b7485 3192 printf("+F4:%u:%u:%f:%f\n",
d63d89ea 3193 k, ec_curves[k].bits,
7e1b7485 3194 ecdsa_results[k][0], ecdsa_results[k][1]);
0f113f3e 3195 else
48bc0d99 3196 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
d63d89ea 3197 ec_curves[k].bits, ec_curves[k].name,
c8bff7ad
CS
3198 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3199 ecdsa_results[k][0], ecdsa_results[k][1]);
0f113f3e 3200 }
7e1b7485 3201
8b0b80d9 3202 testnum = 1;
0f113f3e
MC
3203 for (k = 0; k < EC_NUM; k++) {
3204 if (!ecdh_doit[k])
3205 continue;
8b0b80d9 3206 if (testnum && !mr) {
0f113f3e 3207 printf("%30sop op/s\n", " ");
8b0b80d9 3208 testnum = 0;
0f113f3e
MC
3209 }
3210 if (mr)
7e1b7485 3211 printf("+F5:%u:%u:%f:%f\n",
d63d89ea 3212 k, ec_curves[k].bits,
7e1b7485 3213 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
0f113f3e
MC
3214
3215 else
48bc0d99 3216 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
d63d89ea 3217 ec_curves[k].bits, ec_curves[k].name,
222c3da3 3218 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
0f113f3e 3219 }
d3a9fb10
PY
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",
d63d89ea 3232 k, ed_curves[k].bits, ed_curves[k].name,
d3a9fb10
PY
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",
d63d89ea 3236 ed_curves[k].bits, ed_curves[k].name,
d3a9fb10
PY
3237 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3238 eddsa_results[k][0], eddsa_results[k][1]);
3239 }
a56f68ad 3240
f3ccfc76 3241#ifndef OPENSSL_NO_SM2
a56f68ad
PY
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)
031c9bd3 3252 printf("+F7:%u:%u:%s:%f:%f\n",
d63d89ea 3253 k, sm2_curves[k].bits, sm2_curves[k].name,
a56f68ad
PY
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",
d63d89ea 3257 sm2_curves[k].bits, sm2_curves[k].name,
a56f68ad
PY
3258 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3259 sm2_results[k][0], sm2_results[k][1]);
3260 }
f3ccfc76 3261#endif
60d3b5b9
HK
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 */
0f113f3e 3282
7e1b7485 3283 ret = 0;
0f113f3e
MC
3284
3285 end:
3286 ERR_print_errors(bio_err);
0ff43435 3287 for (i = 0; i < loopargs_len; i++) {
b2839683
AG
3288 OPENSSL_free(loopargs[i].buf_malloc);
3289 OPENSSL_free(loopargs[i].buf2_malloc);
5f986ed3 3290
f3ccfc76
TM
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 }
60d3b5b9
HK
3297#ifndef OPENSSL_NO_DH
3298 OPENSSL_free(loopargs[i].secret_ff_a);
3299 OPENSSL_free(loopargs[i].secret_ff_b);
861f265a 3300 for (k = 0; k < FFDH_NUM; k++)
60d3b5b9 3301 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
60d3b5b9 3302#endif
f3ccfc76
TM
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 }
5c6a69f5 3311 for (k = 0; k < EC_NUM; k++)
ed7377db 3312 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
1154ffbf 3313 for (k = 0; k < EdDSA_NUM; k++) {
d3a9fb10 3314 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
1154ffbf 3315 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
861f265a 3316 }
f3ccfc76 3317#ifndef OPENSSL_NO_SM2
a56f68ad
PY
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
ed576acd 3323 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
a56f68ad
PY
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
ed576acd 3328 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
a56f68ad
PY
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 }
f3ccfc76 3334#endif
b2839683
AG
3335 OPENSSL_free(loopargs[i].secret_a);
3336 OPENSSL_free(loopargs[i].secret_b);
5f986ed3 3337 }
f88b9b79 3338 OPENSSL_free(evp_hmac_name);
9bba2c4c 3339 OPENSSL_free(evp_cmac_name);
5f986ed3 3340
1e613922
AG
3341 if (async_jobs > 0) {
3342 for (i = 0; i < loopargs_len; i++)
3343 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
dab1f5fe 3344 }
1e613922 3345
dab1f5fe 3346 if (async_init) {
8b0b80d9 3347 ASYNC_cleanup_thread();
1e613922
AG
3348 }
3349 OPENSSL_free(loopargs);
dd1abd44 3350 release_engine(e);
eaf8a40d 3351 EVP_CIPHER_free(evp_cipher);
c696f4bf 3352 EVP_MAC_free(mac);
26a7d938 3353 return ret;
0f113f3e 3354}
d02b48c6 3355
64daf14d 3356static void print_message(const char *s, long num, int length, int tm)
0f113f3e 3357{
0f113f3e
MC
3358 BIO_printf(bio_err,
3359 mr ? "+DT:%s:%d:%d\n"
64daf14d 3360 : "Doing %s for %ds on %d size blocks: ", s, tm, length);
0f113f3e 3361 (void)BIO_flush(bio_err);
f3fdfbf7 3362 run = 1;
64daf14d 3363 alarm(tm);
0f113f3e 3364}
d02b48c6 3365
689c6f25 3366static void pkey_print_message(const char *str, const char *str2, long num,
48bc0d99 3367 unsigned int bits, int tm)
0f113f3e 3368{
0f113f3e
MC
3369 BIO_printf(bio_err,
3370 mr ? "+DTP:%d:%s:%s:%d\n"
48bc0d99 3371 : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
0f113f3e 3372 (void)BIO_flush(bio_err);
6e49b514 3373 run = 1;
0f113f3e 3374 alarm(tm);
0f113f3e 3375}
58964a49 3376
0f113f3e
MC
3377static void print_result(int alg, int run_no, int count, double time_used)
3378{
d166ed8c 3379 if (count == -1) {
af0857f0
F
3380 BIO_printf(bio_err, "%s error!\n", names[alg]);
3381 ERR_print_errors(bio_err);
af0857f0 3382 return;
d166ed8c 3383 }
0f113f3e
MC
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}
0e211563 3389
a00ae6c4 3390#ifndef NO_FORK
0e211563 3391static char *sstrsep(char **string, const char *delim)
0f113f3e 3392{
0e211563
BL
3393 char isdelim[256];
3394 char *token = *string;
3395
3396 if (**string == 0)
3397 return NULL;
3398
cbe29648 3399 memset(isdelim, 0, sizeof(isdelim));
0e211563
BL
3400 isdelim[0] = 1;
3401
0f113f3e 3402 while (*delim) {
0e211563
BL
3403 isdelim[(unsigned char)(*delim)] = 1;
3404 delim++;
0f113f3e 3405 }
0e211563 3406
861f265a 3407 while (!isdelim[(unsigned char)(**string)])
0e211563 3408 (*string)++;
0e211563 3409
0f113f3e 3410 if (**string) {
0e211563
BL
3411 **string = 0;
3412 (*string)++;
0f113f3e 3413 }
0e211563
BL
3414
3415 return token;
0f113f3e 3416}
0e211563 3417
64daf14d 3418static int do_multi(int multi, int size_num)
0f113f3e
MC
3419{
3420 int n;
3421 int fd[2];
3422 int *fds;
3423 static char sep[] = ":";
3424
8e51a340 3425 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
0f113f3e
MC
3426 for (n = 0; n < multi; ++n) {
3427 if (pipe(fd) == -1) {
7768e116 3428 BIO_printf(bio_err, "pipe failure\n");
0f113f3e
MC
3429 exit(1);
3430 }
3431 fflush(stdout);
7768e116 3432 (void)BIO_flush(bio_err);
0f113f3e
MC
3433 if (fork()) {
3434 close(fd[1]);
3435 fds[n] = fd[0];
3436 } else {
3437 close(fd[0]);
3438 close(1);
3439 if (dup(fd[1]) == -1) {
7768e116 3440 BIO_printf(bio_err, "dup failed\n");
0f113f3e
MC
3441 exit(1);
3442 }
3443 close(fd[1]);
3444 mr = 1;
3445 usertime = 0;
b481fbe6 3446 OPENSSL_free(fds);
0f113f3e
MC
3447 return 0;
3448 }
3449 printf("Forked child %d\n", n);
3450 }
e172d60d 3451
0f113f3e
MC
3452 /* for now, assume the pipe is long enough to take all the output */
3453 for (n = 0; n < multi; ++n) {
3454 FILE *f;
3455 char buf[1024];
3456 char *p;
3457
3458 f = fdopen(fds[n], "r");
cbe29648 3459 while (fgets(buf, sizeof(buf), f)) {
0f113f3e
MC
3460 p = strchr(buf, '\n');
3461 if (p)
3462 *p = '\0';
3463 if (buf[0] != '+') {
29dd15b1
NT
3464 BIO_printf(bio_err,
3465 "Don't understand line '%s' from child %d\n", buf,
3466 n);
0f113f3e
MC
3467 continue;
3468 }
3469 printf("Got: %s from %d\n", buf, n);
2ff286c2
DDO
3470 p = buf;
3471 if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
0f113f3e
MC
3472 int alg;
3473 int j;
3474
0f113f3e
MC
3475 alg = atoi(sstrsep(&p, sep));
3476 sstrsep(&p, sep);
64daf14d 3477 for (j = 0; j < size_num; ++j)
0f113f3e 3478 results[alg][j] += atof(sstrsep(&p, sep));
2ff286c2 3479 } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
0f113f3e
MC
3480 int k;
3481 double d;
3482
0f113f3e
MC
3483 k = atoi(sstrsep(&p, sep));
3484 sstrsep(&p, sep);
3485
0f113f3e 3486 d = atof(sstrsep(&p, sep));
8ac2d1ab 3487 rsa_results[k][0] += d;
0f113f3e
MC
3488
3489 d = atof(sstrsep(&p, sep));
8ac2d1ab 3490 rsa_results[k][1] += d;
2ff286c2 3491 } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
0f113f3e
MC
3492 int k;
3493 double d;
3494
0f113f3e
MC
3495 k = atoi(sstrsep(&p, sep));
3496 sstrsep(&p, sep);
3497
3498 d = atof(sstrsep(&p, sep));
0d4de756 3499 dsa_results[k][0] += d;
0f113f3e
MC
3500
3501 d = atof(sstrsep(&p, sep));
0d4de756 3502 dsa_results[k][1] += d;
2ff286c2 3503 } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
0f113f3e
MC
3504 int k;
3505 double d;
3506
0f113f3e
MC
3507 k = atoi(sstrsep(&p, sep));
3508 sstrsep(&p, sep);
3509
3510 d = atof(sstrsep(&p, sep));
c8bff7ad 3511 ecdsa_results[k][0] += d;
0f113f3e
MC
3512
3513 d = atof(sstrsep(&p, sep));
c8bff7ad 3514 ecdsa_results[k][1] += d;
2ff286c2 3515 } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
0f113f3e
MC
3516 int k;
3517 double d;
3518
0f113f3e
MC
3519 k = atoi(sstrsep(&p, sep));
3520 sstrsep(&p, sep);
3521
3522 d = atof(sstrsep(&p, sep));
222c3da3 3523 ecdh_results[k][0] += d;
2ff286c2 3524 } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
d3a9fb10
PY
3525 int k;
3526 double d;
3527
d3a9fb10
PY
3528 k = atoi(sstrsep(&p, sep));
3529 sstrsep(&p, sep);
1ac7e153 3530 sstrsep(&p, sep);
d3a9fb10
PY
3531
3532 d = atof(sstrsep(&p, sep));
3533 eddsa_results[k][0] += d;
3534
3535 d = atof(sstrsep(&p, sep));
3536 eddsa_results[k][1] += d;
f3ccfc76 3537# ifndef OPENSSL_NO_SM2
2ff286c2 3538 } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
a56f68ad
PY
3539 int k;
3540 double d;
3541
a56f68ad
PY
3542 k = atoi(sstrsep(&p, sep));
3543 sstrsep(&p, sep);
031c9bd3 3544 sstrsep(&p, sep);
a56f68ad
PY
3545
3546 d = atof(sstrsep(&p, sep));
3547 sm2_results[k][0] += d;
3548
3549 d = atof(sstrsep(&p, sep));
3550 sm2_results[k][1] += d;
f3ccfc76 3551# endif /* OPENSSL_NO_SM2 */
60d3b5b9 3552# ifndef OPENSSL_NO_DH
2ff286c2 3553 } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
60d3b5b9
HK
3554 int k;
3555 double d;
3556
60d3b5b9
HK
3557 k = atoi(sstrsep(&p, sep));
3558 sstrsep(&p, sep);
3559
3560 d = atof(sstrsep(&p, sep));
3561 ffdh_results[k][0] += d;
60d3b5b9 3562# endif /* OPENSSL_NO_DH */
a09a342f 3563 } else if (!HAS_PREFIX(buf, "+H:")) {
29dd15b1
NT
3564 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3565 n);
861f265a 3566 }
0f113f3e
MC
3567 }
3568
3569 fclose(f);
3570 }
b481fbe6 3571 OPENSSL_free(fds);
0f113f3e
MC
3572 return 1;
3573}
a00ae6c4 3574#endif
375a64e3 3575
5c6a69f5 3576static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
8f26f9d5 3577 const openssl_speed_sec_t *seconds)
0f113f3e 3578{
64daf14d 3579 static const int mblengths_list[] =
0f113f3e 3580 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
64daf14d 3581 const int *mblengths = mblengths_list;
6b1fe3d0 3582 int j, count, keylen, num = OSSL_NELEM(mblengths_list);
0f113f3e 3583 const char *alg_name;
d1a57d87
P
3584 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3585 EVP_CIPHER_CTX *ctx = NULL;
0f113f3e
MC
3586 double d = 0.0;
3587
64daf14d
PS
3588 if (lengths_single) {
3589 mblengths = &lengths_single;
3590 num = 1;
3591 }
3592
68dc6824
RS
3593 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3594 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
a02d70dd
P
3595 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3596 app_bail_out("failed to allocate cipher context\n");
3597 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3598 app_bail_out("failed to initialise cipher context\n");
6b1fe3d0 3599
ed576acd 3600 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
9ca269af 3601 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
d1a57d87 3602 goto err;
9ca269af 3603 }
6b1fe3d0 3604 key = app_malloc(keylen, "evp_cipher key");
a02d70dd
P
3605 if (!EVP_CIPHER_CTX_rand_key(ctx, key))
3606 app_bail_out("failed to generate random cipher key\n");
3607 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3608 app_bail_out("failed to set cipher key\n");
6b1fe3d0
PS
3609 OPENSSL_clear_free(key, keylen);
3610
a02d70dd
P
3611 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3612 sizeof(no_key), no_key))
3613 app_bail_out("failed to set AEAD key\n");
ed576acd 3614 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
a02d70dd 3615 app_bail_out("failed to get cipher name\n");
0f113f3e
MC
3616
3617 for (j = 0; j < num; j++) {
64daf14d 3618 print_message(alg_name, 0, mblengths[j], seconds->sym);
0f113f3e 3619 Time_F(START);
378c50f6 3620 for (count = 0; run && count < INT_MAX; count++) {
c8269881 3621 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
0f113f3e
MC
3622 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3623 size_t len = mblengths[j];
3624 int packlen;
3625
3626 memset(aad, 0, 8); /* avoid uninitialized values */
3627 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3628 aad[9] = 3; /* version */
3629 aad[10] = 2;
3630 aad[11] = 0; /* length */
3631 aad[12] = 0;
3632 mb_param.out = NULL;
3633 mb_param.inp = aad;
3634 mb_param.len = len;
3635 mb_param.interleave = 8;
3636
846ec07d 3637 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
0f113f3e
MC
3638 sizeof(mb_param), &mb_param);
3639
3640 if (packlen > 0) {
3641 mb_param.out = out;
3642 mb_param.inp = inp;
3643 mb_param.len = len;
5c8c2e6b
P
3644 (void)EVP_CIPHER_CTX_ctrl(ctx,
3645 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3646 sizeof(mb_param), &mb_param);
0f113f3e
MC
3647 } else {
3648 int pad;
3649
3650 RAND_bytes(out, 16);
3651 len += 16;
3a63c0ed
AP
3652 aad[11] = (unsigned char)(len >> 8);
3653 aad[12] = (unsigned char)(len);
846ec07d 3654 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
c8269881 3655 EVP_AEAD_TLS1_AAD_LEN, aad);
846ec07d 3656 EVP_Cipher(ctx, out, inp, len + pad);
0f113f3e
MC
3657 }
3658 }
3659 d = Time_F(STOP);
7e1b7485 3660 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
0f113f3e
MC
3661 : "%d %s's in %.2fs\n", count, "evp", d);
3662 results[D_EVP][j] = ((double)count) / d * mblengths[j];
3663 }
3664
3665 if (mr) {
3666 fprintf(stdout, "+H");
3667 for (j = 0; j < num; j++)
3668 fprintf(stdout, ":%d", mblengths[j]);
3669 fprintf(stdout, "\n");
3670 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3671 for (j = 0; j < num; j++)
3672 fprintf(stdout, ":%.2f", results[D_EVP][j]);
3673 fprintf(stdout, "\n");
3674 } else {
3675 fprintf(stdout,
3676 "The 'numbers' are in 1000s of bytes per second processed.\n");
3677 fprintf(stdout, "type ");
3678 for (j = 0; j < num; j++)
3679 fprintf(stdout, "%7d bytes", mblengths[j]);
3680 fprintf(stdout, "\n");
3681 fprintf(stdout, "%-24s", alg_name);
3682
3683 for (j = 0; j < num; j++) {
3684 if (results[D_EVP][j] > 10000)
3685 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3686 else
3687 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3688 }
3689 fprintf(stdout, "\n");
3690 }
3691
d1a57d87 3692 err:
b548a1f1
RS
3693 OPENSSL_free(inp);
3694 OPENSSL_free(out);
846ec07d 3695 EVP_CIPHER_CTX_free(ctx);
0f113f3e 3696}