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