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