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