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