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