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