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