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