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