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