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