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