]> git.ipfire.org Git - thirdparty/openssl.git/blob - apps/speed.c
"foo * bar" should be "foo *bar"
[thirdparty/openssl.git] / apps / speed.c
1 /*
2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
9 */
10
11 #undef SECONDS
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
22 #define KEM_SECONDS PKEY_SECONDS
23 #define SIG_SECONDS PKEY_SECONDS
24
25 #define MAX_ALGNAME_SUFFIX 100
26
27 /* We need to use some deprecated APIs */
28 #define OPENSSL_SUPPRESS_DEPRECATED
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 #include "apps.h"
35 #include "progs.h"
36 #include "internal/nelem.h"
37 #include "internal/numbers.h"
38 #include <openssl/crypto.h>
39 #include <openssl/rand.h>
40 #include <openssl/err.h>
41 #include <openssl/evp.h>
42 #include <openssl/objects.h>
43 #include <openssl/core_names.h>
44 #include <openssl/async.h>
45 #include <openssl/provider.h>
46 #if !defined(OPENSSL_SYS_MSDOS)
47 # include <unistd.h>
48 #endif
49
50 #if defined(__TANDEM)
51 # if defined(OPENSSL_TANDEM_FLOSS)
52 # include <floss.h(floss_fork)>
53 # endif
54 #endif
55
56 #if defined(_WIN32)
57 # include <windows.h>
58 /*
59 * While VirtualLock is available under the app partition (e.g. UWP),
60 * the headers do not define the API. Define it ourselves instead.
61 */
62 WINBASEAPI
63 BOOL
64 WINAPI
65 VirtualLock(
66 _In_ LPVOID lpAddress,
67 _In_ SIZE_T dwSize
68 );
69 #endif
70
71 #if defined(OPENSSL_SYS_LINUX)
72 # include <sys/mman.h>
73 #endif
74
75 #include <openssl/bn.h>
76 #include <openssl/rsa.h>
77 #include "./testrsa.h"
78 #ifndef OPENSSL_NO_DH
79 # include <openssl/dh.h>
80 #endif
81 #include <openssl/x509.h>
82 #include <openssl/dsa.h>
83 #include "./testdsa.h"
84 #include <openssl/modes.h>
85
86 #ifndef HAVE_FORK
87 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
88 # define HAVE_FORK 0
89 # else
90 # define HAVE_FORK 1
91 # include <sys/wait.h>
92 # endif
93 #endif
94
95 #if HAVE_FORK
96 # undef NO_FORK
97 #else
98 # define NO_FORK
99 #endif
100
101 #define MAX_MISALIGNMENT 63
102 #define MAX_ECDH_SIZE 256
103 #define MISALIGN 64
104 #define MAX_FFDH_SIZE 1024
105
106 #ifndef RSA_DEFAULT_PRIME_NUM
107 # define RSA_DEFAULT_PRIME_NUM 2
108 #endif
109
110 typedef struct openssl_speed_sec_st {
111 int sym;
112 int rsa;
113 int dsa;
114 int ecdsa;
115 int ecdh;
116 int eddsa;
117 int sm2;
118 int ffdh;
119 int kem;
120 int sig;
121 } openssl_speed_sec_t;
122
123 static volatile int run = 0;
124
125 static int mr = 0; /* machine-readeable output format to merge fork results */
126 static int usertime = 1;
127
128 static double Time_F(int s);
129 static void print_message(const char *s, int length, int tm);
130 static void pkey_print_message(const char *str, const char *str2,
131 unsigned int bits, int sec);
132 static void kskey_print_message(const char *str, const char *str2, int tm);
133 static void print_result(int alg, int run_no, int count, double time_used);
134 #ifndef NO_FORK
135 static int do_multi(int multi, int size_num);
136 #endif
137
138 static int domlock = 0;
139
140 static const int lengths_list[] = {
141 16, 64, 256, 1024, 8 * 1024, 16 * 1024
142 };
143 #define SIZE_NUM OSSL_NELEM(lengths_list)
144 static const int *lengths = lengths_list;
145
146 static const int aead_lengths_list[] = {
147 2, 31, 136, 1024, 8 * 1024, 16 * 1024
148 };
149
150 #define START 0
151 #define STOP 1
152
153 #ifdef SIGALRM
154
155 static void alarmed(ossl_unused int sig)
156 {
157 signal(SIGALRM, alarmed);
158 run = 0;
159 }
160
161 static double Time_F(int s)
162 {
163 double ret = app_tminterval(s, usertime);
164 if (s == STOP)
165 alarm(0);
166 return ret;
167 }
168
169 #elif defined(_WIN32)
170
171 # define SIGALRM -1
172
173 static unsigned int lapse;
174 static volatile unsigned int schlock;
175 static void alarm_win32(unsigned int secs)
176 {
177 lapse = secs * 1000;
178 }
179
180 # define alarm alarm_win32
181
182 static DWORD WINAPI sleepy(VOID * arg)
183 {
184 schlock = 1;
185 Sleep(lapse);
186 run = 0;
187 return 0;
188 }
189
190 static double Time_F(int s)
191 {
192 double ret;
193 static HANDLE thr;
194
195 if (s == START) {
196 schlock = 0;
197 thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
198 if (thr == NULL) {
199 DWORD err = GetLastError();
200 BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
201 ExitProcess(err);
202 }
203 while (!schlock)
204 Sleep(0); /* scheduler spinlock */
205 ret = app_tminterval(s, usertime);
206 } else {
207 ret = app_tminterval(s, usertime);
208 if (run)
209 TerminateThread(thr, 0);
210 CloseHandle(thr);
211 }
212
213 return ret;
214 }
215 #else
216 # error "SIGALRM not defined and the platform is not Windows"
217 #endif
218
219 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
220 const openssl_speed_sec_t *seconds);
221
222 static int opt_found(const char *name, unsigned int *result,
223 const OPT_PAIR pairs[], unsigned int nbelem)
224 {
225 unsigned int idx;
226
227 for (idx = 0; idx < nbelem; ++idx, pairs++)
228 if (strcmp(name, pairs->name) == 0) {
229 *result = pairs->retval;
230 return 1;
231 }
232 return 0;
233 }
234 #define opt_found(value, pairs, result)\
235 opt_found(value, result, pairs, OSSL_NELEM(pairs))
236
237 typedef enum OPTION_choice {
238 OPT_COMMON,
239 OPT_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
240 OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG,
241 OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD, OPT_CMAC, OPT_MLOCK, OPT_KEM, OPT_SIG
242 } OPTION_CHOICE;
243
244 const OPTIONS speed_options[] = {
245 {OPT_HELP_STR, 1, '-',
246 "Usage: %s [options] [algorithm...]\n"
247 "All +int options consider prefix '0' as base-8 input, "
248 "prefix '0x'/'0X' as base-16 input.\n"
249 },
250
251 OPT_SECTION("General"),
252 {"help", OPT_HELP, '-', "Display this summary"},
253 {"mb", OPT_MB, '-',
254 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
255 {"mr", OPT_MR, '-', "Produce machine readable output"},
256 #ifndef NO_FORK
257 {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
258 #endif
259 #ifndef OPENSSL_NO_ASYNC
260 {"async_jobs", OPT_ASYNCJOBS, 'p',
261 "Enable async mode and start specified number of jobs"},
262 #endif
263 #ifndef OPENSSL_NO_ENGINE
264 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
265 #endif
266 {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
267 {"mlock", OPT_MLOCK, '-', "Lock memory for better result determinism"},
268 OPT_CONFIG_OPTION,
269
270 OPT_SECTION("Selection"),
271 {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"},
272 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"},
273 {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"},
274 {"decrypt", OPT_DECRYPT, '-',
275 "Time decryption instead of encryption (only EVP)"},
276 {"aead", OPT_AEAD, '-',
277 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
278 {"kem-algorithms", OPT_KEM, '-',
279 "Benchmark KEM algorithms"},
280 {"signature-algorithms", OPT_SIG, '-',
281 "Benchmark signature algorithms"},
282
283 OPT_SECTION("Timing"),
284 {"elapsed", OPT_ELAPSED, '-',
285 "Use wall-clock time instead of CPU user time as divisor"},
286 {"seconds", OPT_SECONDS, 'p',
287 "Run benchmarks for specified amount of seconds"},
288 {"bytes", OPT_BYTES, 'p',
289 "Run [non-PKI] benchmarks on custom-sized buffer"},
290 {"misalign", OPT_MISALIGN, 'p',
291 "Use specified offset to mis-align buffers"},
292
293 OPT_R_OPTIONS,
294 OPT_PROV_OPTIONS,
295
296 OPT_PARAMETERS(),
297 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
298 {NULL}
299 };
300
301 enum {
302 D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160,
303 D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC,
304 D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED,
305 D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST,
306 D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES,
307 D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML,
308 D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM
309 };
310 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
311 static const char *names[ALGOR_NUM] = {
312 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
313 "sha256", "sha512", "whirlpool", "hmac(md5)",
314 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
315 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
316 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
317 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
318 "evp", "ghash", "rand", "cmac"
319 };
320
321 /* list of configured algorithm (remaining), with some few alias */
322 static const OPT_PAIR doit_choices[] = {
323 {"md2", D_MD2},
324 {"mdc2", D_MDC2},
325 {"md4", D_MD4},
326 {"md5", D_MD5},
327 {"hmac", D_HMAC},
328 {"sha1", D_SHA1},
329 {"sha256", D_SHA256},
330 {"sha512", D_SHA512},
331 {"whirlpool", D_WHIRLPOOL},
332 {"ripemd", D_RMD160},
333 {"rmd160", D_RMD160},
334 {"ripemd160", D_RMD160},
335 {"rc4", D_RC4},
336 {"des-cbc", D_CBC_DES},
337 {"des-ede3", D_EDE3_DES},
338 {"aes-128-cbc", D_CBC_128_AES},
339 {"aes-192-cbc", D_CBC_192_AES},
340 {"aes-256-cbc", D_CBC_256_AES},
341 {"camellia-128-cbc", D_CBC_128_CML},
342 {"camellia-192-cbc", D_CBC_192_CML},
343 {"camellia-256-cbc", D_CBC_256_CML},
344 {"rc2-cbc", D_CBC_RC2},
345 {"rc2", D_CBC_RC2},
346 {"rc5-cbc", D_CBC_RC5},
347 {"rc5", D_CBC_RC5},
348 {"idea-cbc", D_CBC_IDEA},
349 {"idea", D_CBC_IDEA},
350 {"seed-cbc", D_CBC_SEED},
351 {"seed", D_CBC_SEED},
352 {"bf-cbc", D_CBC_BF},
353 {"blowfish", D_CBC_BF},
354 {"bf", D_CBC_BF},
355 {"cast-cbc", D_CBC_CAST},
356 {"cast", D_CBC_CAST},
357 {"cast5", D_CBC_CAST},
358 {"ghash", D_GHASH},
359 {"rand", D_RAND}
360 };
361
362 static double results[ALGOR_NUM][SIZE_NUM];
363
364 enum { R_DSA_1024, R_DSA_2048, DSA_NUM };
365 static const OPT_PAIR dsa_choices[DSA_NUM] = {
366 {"dsa1024", R_DSA_1024},
367 {"dsa2048", R_DSA_2048}
368 };
369 static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */
370
371 enum {
372 R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680,
373 R_RSA_15360, RSA_NUM
374 };
375 static const OPT_PAIR rsa_choices[RSA_NUM] = {
376 {"rsa512", R_RSA_512},
377 {"rsa1024", R_RSA_1024},
378 {"rsa2048", R_RSA_2048},
379 {"rsa3072", R_RSA_3072},
380 {"rsa4096", R_RSA_4096},
381 {"rsa7680", R_RSA_7680},
382 {"rsa15360", R_RSA_15360}
383 };
384
385 static double rsa_results[RSA_NUM][4]; /* 4 ops: sign, verify, encrypt, decrypt */
386
387 #ifndef OPENSSL_NO_DH
388 enum ff_params_t {
389 R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM
390 };
391
392 static const OPT_PAIR ffdh_choices[FFDH_NUM] = {
393 {"ffdh2048", R_FFDH_2048},
394 {"ffdh3072", R_FFDH_3072},
395 {"ffdh4096", R_FFDH_4096},
396 {"ffdh6144", R_FFDH_6144},
397 {"ffdh8192", R_FFDH_8192},
398 };
399
400 static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */
401 #endif /* OPENSSL_NO_DH */
402
403 enum ec_curves_t {
404 R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521,
405 #ifndef OPENSSL_NO_EC2M
406 R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571,
407 R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571,
408 #endif
409 R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1,
410 R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM
411 };
412 /* list of ecdsa curves */
413 static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
414 {"ecdsap160", R_EC_P160},
415 {"ecdsap192", R_EC_P192},
416 {"ecdsap224", R_EC_P224},
417 {"ecdsap256", R_EC_P256},
418 {"ecdsap384", R_EC_P384},
419 {"ecdsap521", R_EC_P521},
420 #ifndef OPENSSL_NO_EC2M
421 {"ecdsak163", R_EC_K163},
422 {"ecdsak233", R_EC_K233},
423 {"ecdsak283", R_EC_K283},
424 {"ecdsak409", R_EC_K409},
425 {"ecdsak571", R_EC_K571},
426 {"ecdsab163", R_EC_B163},
427 {"ecdsab233", R_EC_B233},
428 {"ecdsab283", R_EC_B283},
429 {"ecdsab409", R_EC_B409},
430 {"ecdsab571", R_EC_B571},
431 #endif
432 {"ecdsabrp256r1", R_EC_BRP256R1},
433 {"ecdsabrp256t1", R_EC_BRP256T1},
434 {"ecdsabrp384r1", R_EC_BRP384R1},
435 {"ecdsabrp384t1", R_EC_BRP384T1},
436 {"ecdsabrp512r1", R_EC_BRP512R1},
437 {"ecdsabrp512t1", R_EC_BRP512T1}
438 };
439 enum {
440 #ifndef OPENSSL_NO_ECX
441 R_EC_X25519 = ECDSA_NUM, R_EC_X448, EC_NUM
442 #else
443 EC_NUM = ECDSA_NUM
444 #endif
445 };
446 /* list of ecdh curves, extension of |ecdsa_choices| list above */
447 static const OPT_PAIR ecdh_choices[EC_NUM] = {
448 {"ecdhp160", R_EC_P160},
449 {"ecdhp192", R_EC_P192},
450 {"ecdhp224", R_EC_P224},
451 {"ecdhp256", R_EC_P256},
452 {"ecdhp384", R_EC_P384},
453 {"ecdhp521", R_EC_P521},
454 #ifndef OPENSSL_NO_EC2M
455 {"ecdhk163", R_EC_K163},
456 {"ecdhk233", R_EC_K233},
457 {"ecdhk283", R_EC_K283},
458 {"ecdhk409", R_EC_K409},
459 {"ecdhk571", R_EC_K571},
460 {"ecdhb163", R_EC_B163},
461 {"ecdhb233", R_EC_B233},
462 {"ecdhb283", R_EC_B283},
463 {"ecdhb409", R_EC_B409},
464 {"ecdhb571", R_EC_B571},
465 #endif
466 {"ecdhbrp256r1", R_EC_BRP256R1},
467 {"ecdhbrp256t1", R_EC_BRP256T1},
468 {"ecdhbrp384r1", R_EC_BRP384R1},
469 {"ecdhbrp384t1", R_EC_BRP384T1},
470 {"ecdhbrp512r1", R_EC_BRP512R1},
471 {"ecdhbrp512t1", R_EC_BRP512T1},
472 #ifndef OPENSSL_NO_ECX
473 {"ecdhx25519", R_EC_X25519},
474 {"ecdhx448", R_EC_X448}
475 #endif
476 };
477
478 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
479 static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
480
481 #ifndef OPENSSL_NO_ECX
482 enum { R_EC_Ed25519, R_EC_Ed448, EdDSA_NUM };
483 static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
484 {"ed25519", R_EC_Ed25519},
485 {"ed448", R_EC_Ed448}
486
487 };
488 static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
489 #endif /* OPENSSL_NO_ECX */
490
491 #ifndef OPENSSL_NO_SM2
492 enum { R_EC_CURVESM2, SM2_NUM };
493 static const OPT_PAIR sm2_choices[SM2_NUM] = {
494 {"curveSM2", R_EC_CURVESM2}
495 };
496 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
497 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
498 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
499 #endif /* OPENSSL_NO_SM2 */
500
501 #define MAX_KEM_NUM 111
502 static size_t kems_algs_len = 0;
503 static char *kems_algname[MAX_KEM_NUM] = { NULL };
504 static double kems_results[MAX_KEM_NUM][3]; /* keygen, encaps, decaps */
505
506 #define MAX_SIG_NUM 111
507 static size_t sigs_algs_len = 0;
508 static char *sigs_algname[MAX_SIG_NUM] = { NULL };
509 static double sigs_results[MAX_SIG_NUM][3]; /* keygen, sign, verify */
510
511 #define COND(unused_cond) (run && count < INT_MAX)
512 #define COUNT(d) (count)
513
514 typedef struct loopargs_st {
515 ASYNC_JOB *inprogress_job;
516 ASYNC_WAIT_CTX *wait_ctx;
517 unsigned char *buf;
518 unsigned char *buf2;
519 unsigned char *buf_malloc;
520 unsigned char *buf2_malloc;
521 unsigned char *key;
522 size_t buflen;
523 size_t sigsize;
524 size_t encsize;
525 EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM];
526 EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM];
527 EVP_PKEY_CTX *rsa_encrypt_ctx[RSA_NUM];
528 EVP_PKEY_CTX *rsa_decrypt_ctx[RSA_NUM];
529 EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
530 EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
531 EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
532 EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
533 EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
534 #ifndef OPENSSL_NO_ECX
535 EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
536 EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
537 #endif /* OPENSSL_NO_ECX */
538 #ifndef OPENSSL_NO_SM2
539 EVP_MD_CTX *sm2_ctx[SM2_NUM];
540 EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
541 EVP_PKEY *sm2_pkey[SM2_NUM];
542 #endif
543 unsigned char *secret_a;
544 unsigned char *secret_b;
545 size_t outlen[EC_NUM];
546 #ifndef OPENSSL_NO_DH
547 EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM];
548 unsigned char *secret_ff_a;
549 unsigned char *secret_ff_b;
550 #endif
551 EVP_CIPHER_CTX *ctx;
552 EVP_MAC_CTX *mctx;
553 EVP_PKEY_CTX *kem_gen_ctx[MAX_KEM_NUM];
554 EVP_PKEY_CTX *kem_encaps_ctx[MAX_KEM_NUM];
555 EVP_PKEY_CTX *kem_decaps_ctx[MAX_KEM_NUM];
556 size_t kem_out_len[MAX_KEM_NUM];
557 size_t kem_secret_len[MAX_KEM_NUM];
558 unsigned char *kem_out[MAX_KEM_NUM];
559 unsigned char *kem_send_secret[MAX_KEM_NUM];
560 unsigned char *kem_rcv_secret[MAX_KEM_NUM];
561 EVP_PKEY_CTX *sig_gen_ctx[MAX_KEM_NUM];
562 EVP_PKEY_CTX *sig_sign_ctx[MAX_KEM_NUM];
563 EVP_PKEY_CTX *sig_verify_ctx[MAX_KEM_NUM];
564 size_t sig_max_sig_len[MAX_KEM_NUM];
565 size_t sig_act_sig_len[MAX_KEM_NUM];
566 unsigned char *sig_sig[MAX_KEM_NUM];
567 } loopargs_t;
568 static int run_benchmark(int async_jobs, int (*loop_function) (void *),
569 loopargs_t *loopargs);
570
571 static unsigned int testnum;
572
573 static char *evp_mac_mdname = "md5";
574 static char *evp_hmac_name = NULL;
575 static const char *evp_md_name = NULL;
576 static char *evp_mac_ciphername = "aes-128-cbc";
577 static char *evp_cmac_name = NULL;
578
579 static int have_md(const char *name)
580 {
581 int ret = 0;
582 EVP_MD *md = NULL;
583
584 if (opt_md_silent(name, &md)) {
585 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
586
587 if (ctx != NULL && EVP_DigestInit(ctx, md) > 0)
588 ret = 1;
589 EVP_MD_CTX_free(ctx);
590 EVP_MD_free(md);
591 }
592 return ret;
593 }
594
595 static int have_cipher(const char *name)
596 {
597 int ret = 0;
598 EVP_CIPHER *cipher = NULL;
599
600 if (opt_cipher_silent(name, &cipher)) {
601 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
602
603 if (ctx != NULL
604 && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0)
605 ret = 1;
606 EVP_CIPHER_CTX_free(ctx);
607 EVP_CIPHER_free(cipher);
608 }
609 return ret;
610 }
611
612 static int EVP_Digest_loop(const char *mdname, ossl_unused int algindex, void *args)
613 {
614 loopargs_t *tempargs = *(loopargs_t **) args;
615 unsigned char *buf = tempargs->buf;
616 unsigned char digest[EVP_MAX_MD_SIZE];
617 int count;
618 EVP_MD *md = NULL;
619
620 if (!opt_md_silent(mdname, &md))
621 return -1;
622 for (count = 0; COND(c[algindex][testnum]); count++) {
623 if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md,
624 NULL)) {
625 count = -1;
626 break;
627 }
628 }
629 EVP_MD_free(md);
630 return count;
631 }
632
633 static int EVP_Digest_md_loop(void *args)
634 {
635 return EVP_Digest_loop(evp_md_name, D_EVP, args);
636 }
637
638 static int EVP_Digest_MD2_loop(void *args)
639 {
640 return EVP_Digest_loop("md2", D_MD2, args);
641 }
642
643 static int EVP_Digest_MDC2_loop(void *args)
644 {
645 return EVP_Digest_loop("mdc2", D_MDC2, args);
646 }
647
648 static int EVP_Digest_MD4_loop(void *args)
649 {
650 return EVP_Digest_loop("md4", D_MD4, args);
651 }
652
653 static int MD5_loop(void *args)
654 {
655 return EVP_Digest_loop("md5", D_MD5, args);
656 }
657
658 static int EVP_MAC_loop(ossl_unused int algindex, void *args)
659 {
660 loopargs_t *tempargs = *(loopargs_t **) args;
661 unsigned char *buf = tempargs->buf;
662 EVP_MAC_CTX *mctx = tempargs->mctx;
663 unsigned char mac[EVP_MAX_MD_SIZE];
664 int count;
665
666 for (count = 0; COND(c[algindex][testnum]); count++) {
667 size_t outl;
668
669 if (!EVP_MAC_init(mctx, NULL, 0, NULL)
670 || !EVP_MAC_update(mctx, buf, lengths[testnum])
671 || !EVP_MAC_final(mctx, mac, &outl, sizeof(mac)))
672 return -1;
673 }
674 return count;
675 }
676
677 static int HMAC_loop(void *args)
678 {
679 return EVP_MAC_loop(D_HMAC, args);
680 }
681
682 static int CMAC_loop(void *args)
683 {
684 return EVP_MAC_loop(D_EVP_CMAC, args);
685 }
686
687 static int SHA1_loop(void *args)
688 {
689 return EVP_Digest_loop("sha1", D_SHA1, args);
690 }
691
692 static int SHA256_loop(void *args)
693 {
694 return EVP_Digest_loop("sha256", D_SHA256, args);
695 }
696
697 static int SHA512_loop(void *args)
698 {
699 return EVP_Digest_loop("sha512", D_SHA512, args);
700 }
701
702 static int WHIRLPOOL_loop(void *args)
703 {
704 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL, args);
705 }
706
707 static int EVP_Digest_RMD160_loop(void *args)
708 {
709 return EVP_Digest_loop("ripemd160", D_RMD160, args);
710 }
711
712 static int algindex;
713
714 static int EVP_Cipher_loop(void *args)
715 {
716 loopargs_t *tempargs = *(loopargs_t **) args;
717 unsigned char *buf = tempargs->buf;
718 int count;
719
720 if (tempargs->ctx == NULL)
721 return -1;
722 for (count = 0; COND(c[algindex][testnum]); count++)
723 if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0)
724 return -1;
725 return count;
726 }
727
728 static int GHASH_loop(void *args)
729 {
730 loopargs_t *tempargs = *(loopargs_t **) args;
731 unsigned char *buf = tempargs->buf;
732 EVP_MAC_CTX *mctx = tempargs->mctx;
733 int count;
734
735 /* just do the update in the loop to be comparable with 1.1.1 */
736 for (count = 0; COND(c[D_GHASH][testnum]); count++) {
737 if (!EVP_MAC_update(mctx, buf, lengths[testnum]))
738 return -1;
739 }
740 return count;
741 }
742
743 #define MAX_BLOCK_SIZE 128
744
745 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
746
747 static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername,
748 const unsigned char *key,
749 int keylen)
750 {
751 EVP_CIPHER_CTX *ctx = NULL;
752 EVP_CIPHER *cipher = NULL;
753
754 if (!opt_cipher_silent(ciphername, &cipher))
755 return NULL;
756
757 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
758 goto end;
759
760 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) {
761 EVP_CIPHER_CTX_free(ctx);
762 ctx = NULL;
763 goto end;
764 }
765
766 if (EVP_CIPHER_CTX_set_key_length(ctx, keylen) <= 0) {
767 EVP_CIPHER_CTX_free(ctx);
768 ctx = NULL;
769 goto end;
770 }
771
772 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) {
773 EVP_CIPHER_CTX_free(ctx);
774 ctx = NULL;
775 goto end;
776 }
777
778 end:
779 EVP_CIPHER_free(cipher);
780 return ctx;
781 }
782
783 static int RAND_bytes_loop(void *args)
784 {
785 loopargs_t *tempargs = *(loopargs_t **) args;
786 unsigned char *buf = tempargs->buf;
787 int count;
788
789 for (count = 0; COND(c[D_RAND][testnum]); count++)
790 RAND_bytes(buf, lengths[testnum]);
791 return count;
792 }
793
794 static int decrypt = 0;
795 static int EVP_Update_loop(void *args)
796 {
797 loopargs_t *tempargs = *(loopargs_t **) args;
798 unsigned char *buf = tempargs->buf;
799 EVP_CIPHER_CTX *ctx = tempargs->ctx;
800 int outl, count, rc;
801
802 if (decrypt) {
803 for (count = 0; COND(c[D_EVP][testnum]); count++) {
804 rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
805 if (rc != 1) {
806 /* reset iv in case of counter overflow */
807 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
808 }
809 }
810 } else {
811 for (count = 0; COND(c[D_EVP][testnum]); count++) {
812 rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
813 if (rc != 1) {
814 /* reset iv in case of counter overflow */
815 rc = EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
816 }
817 }
818 }
819 if (decrypt)
820 rc = EVP_DecryptFinal_ex(ctx, buf, &outl);
821 else
822 rc = EVP_EncryptFinal_ex(ctx, buf, &outl);
823
824 if (rc == 0)
825 BIO_printf(bio_err, "Error finalizing cipher loop\n");
826 return count;
827 }
828
829 /*
830 * CCM does not support streaming. For the purpose of performance measurement,
831 * each message is encrypted using the same (key,iv)-pair. Do not use this
832 * code in your application.
833 */
834 static int EVP_Update_loop_ccm(void *args)
835 {
836 loopargs_t *tempargs = *(loopargs_t **) args;
837 unsigned char *buf = tempargs->buf;
838 EVP_CIPHER_CTX *ctx = tempargs->ctx;
839 int outl, count, realcount = 0, final;
840 unsigned char tag[12];
841
842 if (decrypt) {
843 for (count = 0; COND(c[D_EVP][testnum]); count++) {
844 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag),
845 tag) > 0
846 /* reset iv */
847 && EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
848 /* counter is reset on every update */
849 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
850 realcount++;
851 }
852 } else {
853 for (count = 0; COND(c[D_EVP][testnum]); count++) {
854 /* restore iv length field */
855 if (EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]) > 0
856 /* counter is reset on every update */
857 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0)
858 realcount++;
859 }
860 }
861 if (decrypt)
862 final = EVP_DecryptFinal_ex(ctx, buf, &outl);
863 else
864 final = EVP_EncryptFinal_ex(ctx, buf, &outl);
865
866 if (final == 0)
867 BIO_printf(bio_err, "Error finalizing ccm loop\n");
868 return realcount;
869 }
870
871 /*
872 * To make AEAD benchmarking more relevant perform TLS-like operations,
873 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
874 * payload length is not actually limited by 16KB...
875 */
876 static int EVP_Update_loop_aead(void *args)
877 {
878 loopargs_t *tempargs = *(loopargs_t **) args;
879 unsigned char *buf = tempargs->buf;
880 EVP_CIPHER_CTX *ctx = tempargs->ctx;
881 int outl, count, realcount = 0;
882 unsigned char aad[13] = { 0xcc };
883 unsigned char faketag[16] = { 0xcc };
884
885 if (decrypt) {
886 for (count = 0; COND(c[D_EVP][testnum]); count++) {
887 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
888 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
889 sizeof(faketag), faketag) > 0
890 && EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
891 && EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
892 && EVP_DecryptFinal_ex(ctx, buf + outl, &outl) >0)
893 realcount++;
894 }
895 } else {
896 for (count = 0; COND(c[D_EVP][testnum]); count++) {
897 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) > 0
898 && EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)) > 0
899 && EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]) > 0
900 && EVP_EncryptFinal_ex(ctx, buf + outl, &outl) > 0)
901 realcount++;
902 }
903 }
904 return realcount;
905 }
906
907 static int RSA_sign_loop(void *args)
908 {
909 loopargs_t *tempargs = *(loopargs_t **) args;
910 unsigned char *buf = tempargs->buf;
911 unsigned char *buf2 = tempargs->buf2;
912 size_t *rsa_num = &tempargs->sigsize;
913 EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx;
914 int ret, count;
915
916 for (count = 0; COND(rsa_c[testnum][0]); count++) {
917 *rsa_num = tempargs->buflen;
918 ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36);
919 if (ret <= 0) {
920 BIO_printf(bio_err, "RSA sign failure\n");
921 ERR_print_errors(bio_err);
922 count = -1;
923 break;
924 }
925 }
926 return count;
927 }
928
929 static int RSA_verify_loop(void *args)
930 {
931 loopargs_t *tempargs = *(loopargs_t **) args;
932 unsigned char *buf = tempargs->buf;
933 unsigned char *buf2 = tempargs->buf2;
934 size_t rsa_num = tempargs->sigsize;
935 EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx;
936 int ret, count;
937
938 for (count = 0; COND(rsa_c[testnum][1]); count++) {
939 ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36);
940 if (ret <= 0) {
941 BIO_printf(bio_err, "RSA verify failure\n");
942 ERR_print_errors(bio_err);
943 count = -1;
944 break;
945 }
946 }
947 return count;
948 }
949
950 static int RSA_encrypt_loop(void *args)
951 {
952 loopargs_t *tempargs = *(loopargs_t **) args;
953 unsigned char *buf = tempargs->buf;
954 unsigned char *buf2 = tempargs->buf2;
955 size_t *rsa_num = &tempargs->encsize;
956 EVP_PKEY_CTX **rsa_encrypt_ctx = tempargs->rsa_encrypt_ctx;
957 int ret, count;
958
959 for (count = 0; COND(rsa_c[testnum][2]); count++) {
960 *rsa_num = tempargs->buflen;
961 ret = EVP_PKEY_encrypt(rsa_encrypt_ctx[testnum], buf2, rsa_num, buf, 36);
962 if (ret <= 0) {
963 BIO_printf(bio_err, "RSA encrypt failure\n");
964 ERR_print_errors(bio_err);
965 count = -1;
966 break;
967 }
968 }
969 return count;
970 }
971
972 static int RSA_decrypt_loop(void *args)
973 {
974 loopargs_t *tempargs = *(loopargs_t **) args;
975 unsigned char *buf = tempargs->buf;
976 unsigned char *buf2 = tempargs->buf2;
977 size_t rsa_num;
978 EVP_PKEY_CTX **rsa_decrypt_ctx = tempargs->rsa_decrypt_ctx;
979 int ret, count;
980
981 for (count = 0; COND(rsa_c[testnum][3]); count++) {
982 rsa_num = tempargs->buflen;
983 ret = EVP_PKEY_decrypt(rsa_decrypt_ctx[testnum], buf, &rsa_num, buf2, tempargs->encsize);
984 if (ret <= 0) {
985 BIO_printf(bio_err, "RSA decrypt failure\n");
986 ERR_print_errors(bio_err);
987 count = -1;
988 break;
989 }
990 }
991 return count;
992 }
993
994 #ifndef OPENSSL_NO_DH
995
996 static int FFDH_derive_key_loop(void *args)
997 {
998 loopargs_t *tempargs = *(loopargs_t **) args;
999 EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum];
1000 unsigned char *derived_secret = tempargs->secret_ff_a;
1001 int count;
1002
1003 for (count = 0; COND(ffdh_c[testnum][0]); count++) {
1004 /* outlen can be overwritten with a too small value (no padding used) */
1005 size_t outlen = MAX_FFDH_SIZE;
1006
1007 EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen);
1008 }
1009 return count;
1010 }
1011 #endif /* OPENSSL_NO_DH */
1012
1013 static int DSA_sign_loop(void *args)
1014 {
1015 loopargs_t *tempargs = *(loopargs_t **) args;
1016 unsigned char *buf = tempargs->buf;
1017 unsigned char *buf2 = tempargs->buf2;
1018 size_t *dsa_num = &tempargs->sigsize;
1019 EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx;
1020 int ret, count;
1021
1022 for (count = 0; COND(dsa_c[testnum][0]); count++) {
1023 *dsa_num = tempargs->buflen;
1024 ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20);
1025 if (ret <= 0) {
1026 BIO_printf(bio_err, "DSA sign failure\n");
1027 ERR_print_errors(bio_err);
1028 count = -1;
1029 break;
1030 }
1031 }
1032 return count;
1033 }
1034
1035 static int DSA_verify_loop(void *args)
1036 {
1037 loopargs_t *tempargs = *(loopargs_t **) args;
1038 unsigned char *buf = tempargs->buf;
1039 unsigned char *buf2 = tempargs->buf2;
1040 size_t dsa_num = tempargs->sigsize;
1041 EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx;
1042 int ret, count;
1043
1044 for (count = 0; COND(dsa_c[testnum][1]); count++) {
1045 ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20);
1046 if (ret <= 0) {
1047 BIO_printf(bio_err, "DSA verify failure\n");
1048 ERR_print_errors(bio_err);
1049 count = -1;
1050 break;
1051 }
1052 }
1053 return count;
1054 }
1055
1056 static int ECDSA_sign_loop(void *args)
1057 {
1058 loopargs_t *tempargs = *(loopargs_t **) args;
1059 unsigned char *buf = tempargs->buf;
1060 unsigned char *buf2 = tempargs->buf2;
1061 size_t *ecdsa_num = &tempargs->sigsize;
1062 EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
1063 int ret, count;
1064
1065 for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
1066 *ecdsa_num = tempargs->buflen;
1067 ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
1068 if (ret <= 0) {
1069 BIO_printf(bio_err, "ECDSA sign failure\n");
1070 ERR_print_errors(bio_err);
1071 count = -1;
1072 break;
1073 }
1074 }
1075 return count;
1076 }
1077
1078 static int ECDSA_verify_loop(void *args)
1079 {
1080 loopargs_t *tempargs = *(loopargs_t **) args;
1081 unsigned char *buf = tempargs->buf;
1082 unsigned char *buf2 = tempargs->buf2;
1083 size_t ecdsa_num = tempargs->sigsize;
1084 EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
1085 int ret, count;
1086
1087 for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
1088 ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
1089 buf, 20);
1090 if (ret <= 0) {
1091 BIO_printf(bio_err, "ECDSA verify failure\n");
1092 ERR_print_errors(bio_err);
1093 count = -1;
1094 break;
1095 }
1096 }
1097 return count;
1098 }
1099
1100 /* ******************************************************************** */
1101
1102 static int ECDH_EVP_derive_key_loop(void *args)
1103 {
1104 loopargs_t *tempargs = *(loopargs_t **) args;
1105 EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
1106 unsigned char *derived_secret = tempargs->secret_a;
1107 int count;
1108 size_t *outlen = &(tempargs->outlen[testnum]);
1109
1110 for (count = 0; COND(ecdh_c[testnum][0]); count++)
1111 EVP_PKEY_derive(ctx, derived_secret, outlen);
1112
1113 return count;
1114 }
1115
1116 #ifndef OPENSSL_NO_ECX
1117 static int EdDSA_sign_loop(void *args)
1118 {
1119 loopargs_t *tempargs = *(loopargs_t **) args;
1120 unsigned char *buf = tempargs->buf;
1121 EVP_MD_CTX **edctx = tempargs->eddsa_ctx;
1122 unsigned char *eddsasig = tempargs->buf2;
1123 size_t *eddsasigsize = &tempargs->sigsize;
1124 int ret, count;
1125
1126 for (count = 0; COND(eddsa_c[testnum][0]); count++) {
1127 ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
1128 if (ret == 0) {
1129 BIO_printf(bio_err, "EdDSA sign init failure\n");
1130 ERR_print_errors(bio_err);
1131 count = -1;
1132 break;
1133 }
1134 ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1135 if (ret == 0) {
1136 BIO_printf(bio_err, "EdDSA sign failure\n");
1137 ERR_print_errors(bio_err);
1138 count = -1;
1139 break;
1140 }
1141 }
1142 return count;
1143 }
1144
1145 static int EdDSA_verify_loop(void *args)
1146 {
1147 loopargs_t *tempargs = *(loopargs_t **) args;
1148 unsigned char *buf = tempargs->buf;
1149 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1150 unsigned char *eddsasig = tempargs->buf2;
1151 size_t eddsasigsize = tempargs->sigsize;
1152 int ret, count;
1153
1154 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1155 ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
1156 if (ret == 0) {
1157 BIO_printf(bio_err, "EdDSA verify init failure\n");
1158 ERR_print_errors(bio_err);
1159 count = -1;
1160 break;
1161 }
1162 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1163 if (ret != 1) {
1164 BIO_printf(bio_err, "EdDSA verify failure\n");
1165 ERR_print_errors(bio_err);
1166 count = -1;
1167 break;
1168 }
1169 }
1170 return count;
1171 }
1172 #endif /* OPENSSL_NO_ECX */
1173
1174 #ifndef OPENSSL_NO_SM2
1175 static int SM2_sign_loop(void *args)
1176 {
1177 loopargs_t *tempargs = *(loopargs_t **) args;
1178 unsigned char *buf = tempargs->buf;
1179 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1180 unsigned char *sm2sig = tempargs->buf2;
1181 size_t sm2sigsize;
1182 int ret, count;
1183 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1184 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1185
1186 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1187 sm2sigsize = max_size;
1188
1189 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1190 NULL, sm2_pkey[testnum])) {
1191 BIO_printf(bio_err, "SM2 init sign failure\n");
1192 ERR_print_errors(bio_err);
1193 count = -1;
1194 break;
1195 }
1196 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1197 buf, 20);
1198 if (ret == 0) {
1199 BIO_printf(bio_err, "SM2 sign failure\n");
1200 ERR_print_errors(bio_err);
1201 count = -1;
1202 break;
1203 }
1204 /* update the latest returned size and always use the fixed buffer size */
1205 tempargs->sigsize = sm2sigsize;
1206 }
1207
1208 return count;
1209 }
1210
1211 static int SM2_verify_loop(void *args)
1212 {
1213 loopargs_t *tempargs = *(loopargs_t **) args;
1214 unsigned char *buf = tempargs->buf;
1215 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1216 unsigned char *sm2sig = tempargs->buf2;
1217 size_t sm2sigsize = tempargs->sigsize;
1218 int ret, count;
1219 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1220
1221 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1222 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1223 NULL, sm2_pkey[testnum])) {
1224 BIO_printf(bio_err, "SM2 verify init failure\n");
1225 ERR_print_errors(bio_err);
1226 count = -1;
1227 break;
1228 }
1229 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1230 buf, 20);
1231 if (ret != 1) {
1232 BIO_printf(bio_err, "SM2 verify failure\n");
1233 ERR_print_errors(bio_err);
1234 count = -1;
1235 break;
1236 }
1237 }
1238 return count;
1239 }
1240 #endif /* OPENSSL_NO_SM2 */
1241
1242 static int KEM_keygen_loop(void *args)
1243 {
1244 loopargs_t *tempargs = *(loopargs_t **) args;
1245 EVP_PKEY_CTX *ctx = tempargs->kem_gen_ctx[testnum];
1246 EVP_PKEY *pkey = NULL;
1247 int count;
1248
1249 for (count = 0; COND(kems_c[testnum][0]); count++) {
1250 if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
1251 return -1;
1252 /*
1253 * runtime defined to quite some degree by randomness,
1254 * so performance overhead of _free doesn't impact
1255 * results significantly. In any case this test is
1256 * meant to permit relative algorithm performance
1257 * comparison.
1258 */
1259 EVP_PKEY_free(pkey);
1260 pkey = NULL;
1261 }
1262 return count;
1263 }
1264
1265 static int KEM_encaps_loop(void *args)
1266 {
1267 loopargs_t *tempargs = *(loopargs_t **) args;
1268 EVP_PKEY_CTX *ctx = tempargs->kem_encaps_ctx[testnum];
1269 size_t out_len = tempargs->kem_out_len[testnum];
1270 size_t secret_len = tempargs->kem_secret_len[testnum];
1271 unsigned char *out = tempargs->kem_out[testnum];
1272 unsigned char *secret = tempargs->kem_send_secret[testnum];
1273 int count;
1274
1275 for (count = 0; COND(kems_c[testnum][1]); count++) {
1276 if (EVP_PKEY_encapsulate(ctx, out, &out_len, secret, &secret_len) <= 0)
1277 return -1;
1278 }
1279 return count;
1280 }
1281
1282 static int KEM_decaps_loop(void *args)
1283 {
1284 loopargs_t *tempargs = *(loopargs_t **) args;
1285 EVP_PKEY_CTX *ctx = tempargs->kem_decaps_ctx[testnum];
1286 size_t out_len = tempargs->kem_out_len[testnum];
1287 size_t secret_len = tempargs->kem_secret_len[testnum];
1288 unsigned char *out = tempargs->kem_out[testnum];
1289 unsigned char *secret = tempargs->kem_send_secret[testnum];
1290 int count;
1291
1292 for (count = 0; COND(kems_c[testnum][2]); count++) {
1293 if (EVP_PKEY_decapsulate(ctx, secret, &secret_len, out, out_len) <= 0)
1294 return -1;
1295 }
1296 return count;
1297 }
1298
1299 static int SIG_keygen_loop(void *args)
1300 {
1301 loopargs_t *tempargs = *(loopargs_t **) args;
1302 EVP_PKEY_CTX *ctx = tempargs->sig_gen_ctx[testnum];
1303 EVP_PKEY *pkey = NULL;
1304 int count;
1305
1306 for (count = 0; COND(kems_c[testnum][0]); count++) {
1307 EVP_PKEY_keygen(ctx, &pkey);
1308 /* TBD: How much does free influence runtime? */
1309 EVP_PKEY_free(pkey);
1310 pkey = NULL;
1311 }
1312 return count;
1313 }
1314
1315 static int SIG_sign_loop(void *args)
1316 {
1317 loopargs_t *tempargs = *(loopargs_t **) args;
1318 EVP_PKEY_CTX *ctx = tempargs->sig_sign_ctx[testnum];
1319 /* be sure to not change stored sig: */
1320 unsigned char *sig = app_malloc(tempargs->sig_max_sig_len[testnum],
1321 "sig sign loop");
1322 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1323 size_t md_len = SHA256_DIGEST_LENGTH;
1324 int count;
1325
1326 for (count = 0; COND(kems_c[testnum][1]); count++) {
1327 size_t sig_len = tempargs->sig_max_sig_len[testnum];
1328 int ret = EVP_PKEY_sign(ctx, sig, &sig_len, md, md_len);
1329
1330 if (ret <= 0) {
1331 BIO_printf(bio_err, "SIG sign failure at count %d\n", count);
1332 ERR_print_errors(bio_err);
1333 count = -1;
1334 break;
1335 }
1336 }
1337 OPENSSL_free(sig);
1338 return count;
1339 }
1340
1341 static int SIG_verify_loop(void *args)
1342 {
1343 loopargs_t *tempargs = *(loopargs_t **) args;
1344 EVP_PKEY_CTX *ctx = tempargs->sig_verify_ctx[testnum];
1345 size_t sig_len = tempargs->sig_act_sig_len[testnum];
1346 unsigned char *sig = tempargs->sig_sig[testnum];
1347 unsigned char md[SHA256_DIGEST_LENGTH] = { 0 };
1348 size_t md_len = SHA256_DIGEST_LENGTH;
1349 int count;
1350
1351 for (count = 0; COND(kems_c[testnum][2]); count++) {
1352 int ret = EVP_PKEY_verify(ctx, sig, sig_len, md, md_len);
1353
1354 if (ret <= 0) {
1355 BIO_printf(bio_err, "SIG verify failure at count %d\n", count);
1356 ERR_print_errors(bio_err);
1357 count = -1;
1358 break;
1359 }
1360
1361 }
1362 return count;
1363 }
1364
1365 static int run_benchmark(int async_jobs,
1366 int (*loop_function) (void *), loopargs_t *loopargs)
1367 {
1368 int job_op_count = 0;
1369 int total_op_count = 0;
1370 int num_inprogress = 0;
1371 int error = 0, i = 0, ret = 0;
1372 OSSL_ASYNC_FD job_fd = 0;
1373 size_t num_job_fds = 0;
1374
1375 if (async_jobs == 0) {
1376 return loop_function((void *)&loopargs);
1377 }
1378
1379 for (i = 0; i < async_jobs && !error; i++) {
1380 loopargs_t *looparg_item = loopargs + i;
1381
1382 /* Copy pointer content (looparg_t item address) into async context */
1383 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1384 &job_op_count, loop_function,
1385 (void *)&looparg_item, sizeof(looparg_item));
1386 switch (ret) {
1387 case ASYNC_PAUSE:
1388 ++num_inprogress;
1389 break;
1390 case ASYNC_FINISH:
1391 if (job_op_count == -1) {
1392 error = 1;
1393 } else {
1394 total_op_count += job_op_count;
1395 }
1396 break;
1397 case ASYNC_NO_JOBS:
1398 case ASYNC_ERR:
1399 BIO_printf(bio_err, "Failure in the job\n");
1400 ERR_print_errors(bio_err);
1401 error = 1;
1402 break;
1403 }
1404 }
1405
1406 while (num_inprogress > 0) {
1407 #if defined(OPENSSL_SYS_WINDOWS)
1408 DWORD avail = 0;
1409 #elif defined(OPENSSL_SYS_UNIX)
1410 int select_result = 0;
1411 OSSL_ASYNC_FD max_fd = 0;
1412 fd_set waitfdset;
1413
1414 FD_ZERO(&waitfdset);
1415
1416 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1417 if (loopargs[i].inprogress_job == NULL)
1418 continue;
1419
1420 if (!ASYNC_WAIT_CTX_get_all_fds
1421 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1422 || num_job_fds > 1) {
1423 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1424 ERR_print_errors(bio_err);
1425 error = 1;
1426 break;
1427 }
1428 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1429 &num_job_fds);
1430 FD_SET(job_fd, &waitfdset);
1431 if (job_fd > max_fd)
1432 max_fd = job_fd;
1433 }
1434
1435 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1436 BIO_printf(bio_err,
1437 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1438 "Decrease the value of async_jobs\n",
1439 max_fd, FD_SETSIZE);
1440 ERR_print_errors(bio_err);
1441 error = 1;
1442 break;
1443 }
1444
1445 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1446 if (select_result == -1 && errno == EINTR)
1447 continue;
1448
1449 if (select_result == -1) {
1450 BIO_printf(bio_err, "Failure in the select\n");
1451 ERR_print_errors(bio_err);
1452 error = 1;
1453 break;
1454 }
1455
1456 if (select_result == 0)
1457 continue;
1458 #endif
1459
1460 for (i = 0; i < async_jobs; i++) {
1461 if (loopargs[i].inprogress_job == NULL)
1462 continue;
1463
1464 if (!ASYNC_WAIT_CTX_get_all_fds
1465 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1466 || num_job_fds > 1) {
1467 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1468 ERR_print_errors(bio_err);
1469 error = 1;
1470 break;
1471 }
1472 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1473 &num_job_fds);
1474
1475 #if defined(OPENSSL_SYS_UNIX)
1476 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1477 continue;
1478 #elif defined(OPENSSL_SYS_WINDOWS)
1479 if (num_job_fds == 1
1480 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1481 && avail > 0)
1482 continue;
1483 #endif
1484
1485 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1486 loopargs[i].wait_ctx, &job_op_count,
1487 loop_function, (void *)(loopargs + i),
1488 sizeof(loopargs_t));
1489 switch (ret) {
1490 case ASYNC_PAUSE:
1491 break;
1492 case ASYNC_FINISH:
1493 if (job_op_count == -1) {
1494 error = 1;
1495 } else {
1496 total_op_count += job_op_count;
1497 }
1498 --num_inprogress;
1499 loopargs[i].inprogress_job = NULL;
1500 break;
1501 case ASYNC_NO_JOBS:
1502 case ASYNC_ERR:
1503 --num_inprogress;
1504 loopargs[i].inprogress_job = NULL;
1505 BIO_printf(bio_err, "Failure in the job\n");
1506 ERR_print_errors(bio_err);
1507 error = 1;
1508 break;
1509 }
1510 }
1511 }
1512
1513 return error ? -1 : total_op_count;
1514 }
1515
1516 typedef struct ec_curve_st {
1517 const char *name;
1518 unsigned int nid;
1519 unsigned int bits;
1520 size_t sigsize; /* only used for EdDSA curves */
1521 } EC_CURVE;
1522
1523 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1524 {
1525 EVP_PKEY_CTX *kctx = NULL;
1526 EVP_PKEY *key = NULL;
1527
1528 /* Ensure that the error queue is empty */
1529 if (ERR_peek_error()) {
1530 BIO_printf(bio_err,
1531 "WARNING: the error queue contains previous unhandled errors.\n");
1532 ERR_print_errors(bio_err);
1533 }
1534
1535 /*
1536 * Let's try to create a ctx directly from the NID: this works for
1537 * curves like Curve25519 that are not implemented through the low
1538 * level EC interface.
1539 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1540 * then we set the curve by NID before deriving the actual keygen
1541 * ctx for that specific curve.
1542 */
1543 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1544 if (kctx == NULL) {
1545 EVP_PKEY_CTX *pctx = NULL;
1546 EVP_PKEY *params = NULL;
1547 /*
1548 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1549 * "int_ctx_new:unsupported algorithm" error was added to the
1550 * error queue.
1551 * We remove it from the error queue as we are handling it.
1552 */
1553 unsigned long error = ERR_peek_error();
1554
1555 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1556 /* check that the error origin matches */
1557 && ERR_GET_LIB(error) == ERR_LIB_EVP
1558 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1559 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1560 ERR_get_error(); /* pop error from queue */
1561 if (ERR_peek_error()) {
1562 BIO_printf(bio_err,
1563 "Unhandled error in the error queue during EC key setup.\n");
1564 ERR_print_errors(bio_err);
1565 return NULL;
1566 }
1567
1568 /* Create the context for parameter generation */
1569 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1570 || EVP_PKEY_paramgen_init(pctx) <= 0
1571 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1572 curve->nid) <= 0
1573 || EVP_PKEY_paramgen(pctx, &params) <= 0) {
1574 BIO_printf(bio_err, "EC params init failure.\n");
1575 ERR_print_errors(bio_err);
1576 EVP_PKEY_CTX_free(pctx);
1577 return NULL;
1578 }
1579 EVP_PKEY_CTX_free(pctx);
1580
1581 /* Create the context for the key generation */
1582 kctx = EVP_PKEY_CTX_new(params, NULL);
1583 EVP_PKEY_free(params);
1584 }
1585 if (kctx == NULL
1586 || EVP_PKEY_keygen_init(kctx) <= 0
1587 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1588 BIO_printf(bio_err, "EC key generation failure.\n");
1589 ERR_print_errors(bio_err);
1590 key = NULL;
1591 }
1592 EVP_PKEY_CTX_free(kctx);
1593 return key;
1594 }
1595
1596 #define stop_it(do_it, test_num)\
1597 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1598
1599 /* Checks to see if algorithms are fetchable */
1600 #define IS_FETCHABLE(type, TYPE) \
1601 static int is_ ## type ## _fetchable(const TYPE *alg) \
1602 { \
1603 TYPE *impl; \
1604 const char *propq = app_get0_propq(); \
1605 OSSL_LIB_CTX *libctx = app_get0_libctx(); \
1606 const char *name = TYPE ## _get0_name(alg); \
1607 \
1608 ERR_set_mark(); \
1609 impl = TYPE ## _fetch(libctx, name, propq); \
1610 ERR_pop_to_mark(); \
1611 if (impl == NULL) \
1612 return 0; \
1613 TYPE ## _free(impl); \
1614 return 1; \
1615 }
1616
1617 IS_FETCHABLE(signature, EVP_SIGNATURE)
1618 IS_FETCHABLE(kem, EVP_KEM)
1619
1620 DEFINE_STACK_OF(EVP_KEM)
1621
1622 static int kems_cmp(const EVP_KEM * const *a,
1623 const EVP_KEM * const *b)
1624 {
1625 return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
1626 OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
1627 }
1628
1629 static void collect_kem(EVP_KEM *kem, void *stack)
1630 {
1631 STACK_OF(EVP_KEM) *kem_stack = stack;
1632
1633 if (is_kem_fetchable(kem)
1634 && sk_EVP_KEM_push(kem_stack, kem) > 0) {
1635 EVP_KEM_up_ref(kem);
1636 }
1637 }
1638
1639 static int kem_locate(const char *algo, unsigned int *idx)
1640 {
1641 unsigned int i;
1642
1643 for (i = 0; i < kems_algs_len; i++) {
1644 if (strcmp(kems_algname[i], algo) == 0) {
1645 *idx = i;
1646 return 1;
1647 }
1648 }
1649 return 0;
1650 }
1651
1652 DEFINE_STACK_OF(EVP_SIGNATURE)
1653
1654 static int signatures_cmp(const EVP_SIGNATURE * const *a,
1655 const EVP_SIGNATURE * const *b)
1656 {
1657 return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
1658 OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
1659 }
1660
1661 static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
1662 {
1663 STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
1664
1665 if (is_signature_fetchable(sig)
1666 && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
1667 EVP_SIGNATURE_up_ref(sig);
1668 }
1669
1670 static int sig_locate(const char *algo, unsigned int *idx)
1671 {
1672 unsigned int i;
1673
1674 for (i = 0; i < sigs_algs_len; i++) {
1675 if (strcmp(sigs_algname[i], algo) == 0) {
1676 *idx = i;
1677 return 1;
1678 }
1679 }
1680 return 0;
1681 }
1682
1683 static int get_max(const uint8_t doit[], size_t algs_len) {
1684 size_t i = 0;
1685 int maxcnt = 0;
1686
1687 for (i = 0; i < algs_len; i++)
1688 if (maxcnt < doit[i]) maxcnt = doit[i];
1689 return maxcnt;
1690 }
1691
1692 int speed_main(int argc, char **argv)
1693 {
1694 CONF *conf = NULL;
1695 ENGINE *e = NULL;
1696 loopargs_t *loopargs = NULL;
1697 const char *prog;
1698 const char *engine_id = NULL;
1699 EVP_CIPHER *evp_cipher = NULL;
1700 EVP_MAC *mac = NULL;
1701 double d = 0.0;
1702 OPTION_CHOICE o;
1703 int async_init = 0, multiblock = 0, pr_header = 0;
1704 uint8_t doit[ALGOR_NUM] = { 0 };
1705 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1706 STACK_OF(EVP_KEM) *kem_stack = NULL;
1707 STACK_OF(EVP_SIGNATURE) *sig_stack = NULL;
1708 long count = 0;
1709 unsigned int size_num = SIZE_NUM;
1710 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1711 unsigned int idx;
1712 int keylen;
1713 int buflen;
1714 size_t declen;
1715 BIGNUM *bn = NULL;
1716 EVP_PKEY_CTX *genctx = NULL;
1717 #ifndef NO_FORK
1718 int multi = 0;
1719 #endif
1720 long op_count = 1;
1721 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1722 ECDSA_SECONDS, ECDH_SECONDS,
1723 EdDSA_SECONDS, SM2_SECONDS,
1724 FFDH_SECONDS, KEM_SECONDS,
1725 SIG_SECONDS };
1726
1727 static const unsigned char key32[32] = {
1728 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1729 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1730 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1731 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1732 };
1733 static const unsigned char deskey[] = {
1734 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1735 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1736 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1737 };
1738 static const struct {
1739 const unsigned char *data;
1740 unsigned int length;
1741 unsigned int bits;
1742 } rsa_keys[] = {
1743 { test512, sizeof(test512), 512 },
1744 { test1024, sizeof(test1024), 1024 },
1745 { test2048, sizeof(test2048), 2048 },
1746 { test3072, sizeof(test3072), 3072 },
1747 { test4096, sizeof(test4096), 4096 },
1748 { test7680, sizeof(test7680), 7680 },
1749 { test15360, sizeof(test15360), 15360 }
1750 };
1751 uint8_t rsa_doit[RSA_NUM] = { 0 };
1752 int primes = RSA_DEFAULT_PRIME_NUM;
1753 #ifndef OPENSSL_NO_DH
1754 typedef struct ffdh_params_st {
1755 const char *name;
1756 unsigned int nid;
1757 unsigned int bits;
1758 } FFDH_PARAMS;
1759
1760 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1761 {"ffdh2048", NID_ffdhe2048, 2048},
1762 {"ffdh3072", NID_ffdhe3072, 3072},
1763 {"ffdh4096", NID_ffdhe4096, 4096},
1764 {"ffdh6144", NID_ffdhe6144, 6144},
1765 {"ffdh8192", NID_ffdhe8192, 8192}
1766 };
1767 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1768
1769 #endif /* OPENSSL_NO_DH */
1770 static const unsigned int dsa_bits[DSA_NUM] = { 1024, 2048 };
1771 uint8_t dsa_doit[DSA_NUM] = { 0 };
1772 /*
1773 * We only test over the following curves as they are representative, To
1774 * add tests over more curves, simply add the curve NID and curve name to
1775 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1776 * lists accordingly.
1777 */
1778 static const EC_CURVE ec_curves[EC_NUM] = {
1779 /* Prime Curves */
1780 {"secp160r1", NID_secp160r1, 160},
1781 {"nistp192", NID_X9_62_prime192v1, 192},
1782 {"nistp224", NID_secp224r1, 224},
1783 {"nistp256", NID_X9_62_prime256v1, 256},
1784 {"nistp384", NID_secp384r1, 384},
1785 {"nistp521", NID_secp521r1, 521},
1786 #ifndef OPENSSL_NO_EC2M
1787 /* Binary Curves */
1788 {"nistk163", NID_sect163k1, 163},
1789 {"nistk233", NID_sect233k1, 233},
1790 {"nistk283", NID_sect283k1, 283},
1791 {"nistk409", NID_sect409k1, 409},
1792 {"nistk571", NID_sect571k1, 571},
1793 {"nistb163", NID_sect163r2, 163},
1794 {"nistb233", NID_sect233r1, 233},
1795 {"nistb283", NID_sect283r1, 283},
1796 {"nistb409", NID_sect409r1, 409},
1797 {"nistb571", NID_sect571r1, 571},
1798 #endif
1799 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1800 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1801 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1802 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1803 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1804 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1805 #ifndef OPENSSL_NO_ECX
1806 /* Other and ECDH only ones */
1807 {"X25519", NID_X25519, 253},
1808 {"X448", NID_X448, 448}
1809 #endif
1810 };
1811 #ifndef OPENSSL_NO_ECX
1812 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1813 /* EdDSA */
1814 {"Ed25519", NID_ED25519, 253, 64},
1815 {"Ed448", NID_ED448, 456, 114}
1816 };
1817 #endif /* OPENSSL_NO_ECX */
1818 #ifndef OPENSSL_NO_SM2
1819 static const EC_CURVE sm2_curves[SM2_NUM] = {
1820 /* SM2 */
1821 {"CurveSM2", NID_sm2, 256}
1822 };
1823 uint8_t sm2_doit[SM2_NUM] = { 0 };
1824 #endif
1825 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1826 uint8_t ecdh_doit[EC_NUM] = { 0 };
1827 #ifndef OPENSSL_NO_ECX
1828 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1829 #endif /* OPENSSL_NO_ECX */
1830
1831 uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
1832 uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
1833
1834 uint8_t do_kems = 0;
1835 uint8_t do_sigs = 0;
1836
1837 /* checks declared curves against choices list. */
1838 #ifndef OPENSSL_NO_ECX
1839 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1840 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1841
1842 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1843 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1844
1845 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1846 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1847 #endif /* OPENSSL_NO_ECX */
1848
1849 #ifndef OPENSSL_NO_SM2
1850 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1851 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1852 #endif
1853
1854 prog = opt_init(argc, argv, speed_options);
1855 while ((o = opt_next()) != OPT_EOF) {
1856 switch (o) {
1857 case OPT_EOF:
1858 case OPT_ERR:
1859 opterr:
1860 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1861 goto end;
1862 case OPT_HELP:
1863 opt_help(speed_options);
1864 ret = 0;
1865 goto end;
1866 case OPT_ELAPSED:
1867 usertime = 0;
1868 break;
1869 case OPT_EVP:
1870 if (doit[D_EVP]) {
1871 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1872 goto opterr;
1873 }
1874 ERR_set_mark();
1875 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1876 if (have_md(opt_arg()))
1877 evp_md_name = opt_arg();
1878 }
1879 if (evp_cipher == NULL && evp_md_name == NULL) {
1880 ERR_clear_last_mark();
1881 BIO_printf(bio_err,
1882 "%s: %s is an unknown cipher or digest\n",
1883 prog, opt_arg());
1884 goto end;
1885 }
1886 ERR_pop_to_mark();
1887 doit[D_EVP] = 1;
1888 break;
1889 case OPT_HMAC:
1890 if (!have_md(opt_arg())) {
1891 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1892 prog, opt_arg());
1893 goto end;
1894 }
1895 evp_mac_mdname = opt_arg();
1896 doit[D_HMAC] = 1;
1897 break;
1898 case OPT_CMAC:
1899 if (!have_cipher(opt_arg())) {
1900 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1901 prog, opt_arg());
1902 goto end;
1903 }
1904 evp_mac_ciphername = opt_arg();
1905 doit[D_EVP_CMAC] = 1;
1906 break;
1907 case OPT_DECRYPT:
1908 decrypt = 1;
1909 break;
1910 case OPT_ENGINE:
1911 /*
1912 * In a forked execution, an engine might need to be
1913 * initialised by each child process, not by the parent.
1914 * So store the name here and run setup_engine() later on.
1915 */
1916 engine_id = opt_arg();
1917 break;
1918 case OPT_MULTI:
1919 #ifndef NO_FORK
1920 multi = opt_int_arg();
1921 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1922 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1923 return 0;
1924 }
1925 #endif
1926 break;
1927 case OPT_ASYNCJOBS:
1928 #ifndef OPENSSL_NO_ASYNC
1929 async_jobs = opt_int_arg();
1930 if (!ASYNC_is_capable()) {
1931 BIO_printf(bio_err,
1932 "%s: async_jobs specified but async not supported\n",
1933 prog);
1934 goto opterr;
1935 }
1936 if (async_jobs > 99999) {
1937 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1938 goto opterr;
1939 }
1940 #endif
1941 break;
1942 case OPT_MISALIGN:
1943 misalign = opt_int_arg();
1944 if (misalign > MISALIGN) {
1945 BIO_printf(bio_err,
1946 "%s: Maximum offset is %d\n", prog, MISALIGN);
1947 goto opterr;
1948 }
1949 break;
1950 case OPT_MR:
1951 mr = 1;
1952 break;
1953 case OPT_MB:
1954 multiblock = 1;
1955 #ifdef OPENSSL_NO_MULTIBLOCK
1956 BIO_printf(bio_err,
1957 "%s: -mb specified but multi-block support is disabled\n",
1958 prog);
1959 goto end;
1960 #endif
1961 break;
1962 case OPT_R_CASES:
1963 if (!opt_rand(o))
1964 goto end;
1965 break;
1966 case OPT_PROV_CASES:
1967 if (!opt_provider(o))
1968 goto end;
1969 break;
1970 case OPT_CONFIG:
1971 conf = app_load_config_modules(opt_arg());
1972 if (conf == NULL)
1973 goto end;
1974 break;
1975 case OPT_PRIMES:
1976 primes = opt_int_arg();
1977 break;
1978 case OPT_SECONDS:
1979 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1980 = seconds.ecdh = seconds.eddsa
1981 = seconds.sm2 = seconds.ffdh
1982 = seconds.kem = seconds.sig = opt_int_arg();
1983 break;
1984 case OPT_BYTES:
1985 lengths_single = opt_int_arg();
1986 lengths = &lengths_single;
1987 size_num = 1;
1988 break;
1989 case OPT_AEAD:
1990 aead = 1;
1991 break;
1992 case OPT_KEM:
1993 do_kems = 1;
1994 break;
1995 case OPT_SIG:
1996 do_sigs = 1;
1997 break;
1998 case OPT_MLOCK:
1999 domlock = 1;
2000 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
2001 BIO_printf(bio_err,
2002 "%s: -mlock not supported on this platform\n",
2003 prog);
2004 goto end;
2005 #endif
2006 break;
2007 }
2008 }
2009
2010 /* find all KEMs currently available */
2011 kem_stack = sk_EVP_KEM_new(kems_cmp);
2012 EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
2013
2014 kems_algs_len = 0;
2015
2016 for (idx = 0; idx < (unsigned int)sk_EVP_KEM_num(kem_stack); idx++) {
2017 EVP_KEM *kem = sk_EVP_KEM_value(kem_stack, idx);
2018
2019 if (strcmp(EVP_KEM_get0_name(kem), "RSA") == 0) {
2020 if (kems_algs_len + OSSL_NELEM(rsa_choices) >= MAX_KEM_NUM) {
2021 BIO_printf(bio_err,
2022 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2023 goto end;
2024 }
2025 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2026 kems_doit[kems_algs_len] = 1;
2027 kems_algname[kems_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2028 }
2029 } else if (strcmp(EVP_KEM_get0_name(kem), "EC") == 0) {
2030 if (kems_algs_len + 3 >= MAX_KEM_NUM) {
2031 BIO_printf(bio_err,
2032 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2033 goto end;
2034 }
2035 kems_doit[kems_algs_len] = 1;
2036 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-256");
2037 kems_doit[kems_algs_len] = 1;
2038 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-384");
2039 kems_doit[kems_algs_len] = 1;
2040 kems_algname[kems_algs_len++] = OPENSSL_strdup("ECP-521");
2041 } else {
2042 if (kems_algs_len + 1 >= MAX_KEM_NUM) {
2043 BIO_printf(bio_err,
2044 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2045 goto end;
2046 }
2047 kems_doit[kems_algs_len] = 1;
2048 kems_algname[kems_algs_len++] = OPENSSL_strdup(EVP_KEM_get0_name(kem));
2049 }
2050 }
2051 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
2052 kem_stack = NULL;
2053
2054 /* find all SIGNATUREs currently available */
2055 sig_stack = sk_EVP_SIGNATURE_new(signatures_cmp);
2056 EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures, sig_stack);
2057
2058 sigs_algs_len = 0;
2059
2060 for (idx = 0; idx < (unsigned int)sk_EVP_SIGNATURE_num(sig_stack); idx++) {
2061 EVP_SIGNATURE *s = sk_EVP_SIGNATURE_value(sig_stack, idx);
2062 const char *sig_name = EVP_SIGNATURE_get0_name(s);
2063
2064 if (strcmp(sig_name, "RSA") == 0) {
2065 if (sigs_algs_len + OSSL_NELEM(rsa_choices) >= MAX_SIG_NUM) {
2066 BIO_printf(bio_err,
2067 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2068 goto end;
2069 }
2070 for (i = 0; i < OSSL_NELEM(rsa_choices); i++) {
2071 sigs_doit[sigs_algs_len] = 1;
2072 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(rsa_choices[i].name);
2073 }
2074 }
2075 else if (strcmp(sig_name, "DSA") == 0) {
2076 if (sigs_algs_len + DSA_NUM >= MAX_SIG_NUM) {
2077 BIO_printf(bio_err,
2078 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2079 goto end;
2080 }
2081 for (i = 0; i < DSA_NUM; i++) {
2082 sigs_doit[sigs_algs_len] = 1;
2083 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(dsa_choices[i].name);
2084 }
2085 }
2086 /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2087 else if (strcmp(sig_name, "ED25519") &&
2088 strcmp(sig_name, "ED448") &&
2089 strcmp(sig_name, "ECDSA") &&
2090 strcmp(sig_name, "HMAC") &&
2091 strcmp(sig_name, "SIPHASH") &&
2092 strcmp(sig_name, "POLY1305") &&
2093 strcmp(sig_name, "CMAC") &&
2094 strcmp(sig_name, "SM2")) { /* skip alg */
2095 if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
2096 BIO_printf(bio_err,
2097 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2098 goto end;
2099 }
2100 /* activate this provider algorithm */
2101 sigs_doit[sigs_algs_len] = 1;
2102 sigs_algname[sigs_algs_len++] = OPENSSL_strdup(sig_name);
2103 }
2104 }
2105 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
2106 sig_stack = NULL;
2107
2108 /* Remaining arguments are algorithms. */
2109 argc = opt_num_rest();
2110 argv = opt_rest();
2111
2112 if (!app_RAND_load())
2113 goto end;
2114
2115 for (; *argv; argv++) {
2116 const char *algo = *argv;
2117 int algo_found = 0;
2118
2119 if (opt_found(algo, doit_choices, &i)) {
2120 doit[i] = 1;
2121 algo_found = 1;
2122 }
2123 if (strcmp(algo, "des") == 0) {
2124 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
2125 algo_found = 1;
2126 }
2127 if (strcmp(algo, "sha") == 0) {
2128 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
2129 algo_found = 1;
2130 }
2131 #ifndef OPENSSL_NO_DEPRECATED_3_0
2132 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
2133 algo_found = 1;
2134 #endif
2135 if (HAS_PREFIX(algo, "rsa")) {
2136 if (algo[sizeof("rsa") - 1] == '\0') {
2137 memset(rsa_doit, 1, sizeof(rsa_doit));
2138 algo_found = 1;
2139 }
2140 if (opt_found(algo, rsa_choices, &i)) {
2141 rsa_doit[i] = 1;
2142 algo_found = 1;
2143 }
2144 }
2145 #ifndef OPENSSL_NO_DH
2146 if (HAS_PREFIX(algo, "ffdh")) {
2147 if (algo[sizeof("ffdh") - 1] == '\0') {
2148 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2149 algo_found = 1;
2150 }
2151 if (opt_found(algo, ffdh_choices, &i)) {
2152 ffdh_doit[i] = 2;
2153 algo_found = 1;
2154 }
2155 }
2156 #endif
2157 if (HAS_PREFIX(algo, "dsa")) {
2158 if (algo[sizeof("dsa") - 1] == '\0') {
2159 memset(dsa_doit, 1, sizeof(dsa_doit));
2160 algo_found = 1;
2161 }
2162 if (opt_found(algo, dsa_choices, &i)) {
2163 dsa_doit[i] = 2;
2164 algo_found = 1;
2165 }
2166 }
2167 if (strcmp(algo, "aes") == 0) {
2168 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
2169 algo_found = 1;
2170 }
2171 if (strcmp(algo, "camellia") == 0) {
2172 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
2173 algo_found = 1;
2174 }
2175 if (HAS_PREFIX(algo, "ecdsa")) {
2176 if (algo[sizeof("ecdsa") - 1] == '\0') {
2177 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2178 algo_found = 1;
2179 }
2180 if (opt_found(algo, ecdsa_choices, &i)) {
2181 ecdsa_doit[i] = 2;
2182 algo_found = 1;
2183 }
2184 }
2185 if (HAS_PREFIX(algo, "ecdh")) {
2186 if (algo[sizeof("ecdh") - 1] == '\0') {
2187 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2188 algo_found = 1;
2189 }
2190 if (opt_found(algo, ecdh_choices, &i)) {
2191 ecdh_doit[i] = 2;
2192 algo_found = 1;
2193 }
2194 }
2195 #ifndef OPENSSL_NO_ECX
2196 if (strcmp(algo, "eddsa") == 0) {
2197 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2198 algo_found = 1;
2199 }
2200 if (opt_found(algo, eddsa_choices, &i)) {
2201 eddsa_doit[i] = 2;
2202 algo_found = 1;
2203 }
2204 #endif /* OPENSSL_NO_ECX */
2205 #ifndef OPENSSL_NO_SM2
2206 if (strcmp(algo, "sm2") == 0) {
2207 memset(sm2_doit, 1, sizeof(sm2_doit));
2208 algo_found = 1;
2209 }
2210 if (opt_found(algo, sm2_choices, &i)) {
2211 sm2_doit[i] = 2;
2212 algo_found = 1;
2213 }
2214 #endif
2215 if (kem_locate(algo, &idx)) {
2216 kems_doit[idx]++;
2217 do_kems = 1;
2218 algo_found = 1;
2219 }
2220 if (sig_locate(algo, &idx)) {
2221 sigs_doit[idx]++;
2222 do_sigs = 1;
2223 algo_found = 1;
2224 }
2225
2226 if (!algo_found) {
2227 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
2228 goto end;
2229 }
2230 }
2231
2232 /* Sanity checks */
2233 if (aead) {
2234 if (evp_cipher == NULL) {
2235 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
2236 goto end;
2237 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2238 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2239 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
2240 EVP_CIPHER_get0_name(evp_cipher));
2241 goto end;
2242 }
2243 }
2244 if (kems_algs_len > 0) {
2245 int maxcnt = get_max(kems_doit, kems_algs_len);
2246
2247 if (maxcnt > 1) {
2248 /* some algs explicitly selected */
2249 for (i = 0; i < kems_algs_len; i++) {
2250 /* disable the rest */
2251 kems_doit[i]--;
2252 }
2253 }
2254 }
2255 if (sigs_algs_len > 0) {
2256 int maxcnt = get_max(sigs_doit, sigs_algs_len);
2257
2258 if (maxcnt > 1) {
2259 /* some algs explicitly selected */
2260 for (i = 0; i < sigs_algs_len; i++) {
2261 /* disable the rest */
2262 sigs_doit[i]--;
2263 }
2264 }
2265 }
2266 if (multiblock) {
2267 if (evp_cipher == NULL) {
2268 BIO_printf(bio_err, "-mb can be used only with a multi-block"
2269 " capable cipher\n");
2270 goto end;
2271 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
2272 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2273 BIO_printf(bio_err, "%s is not a multi-block capable\n",
2274 EVP_CIPHER_get0_name(evp_cipher));
2275 goto end;
2276 } else if (async_jobs > 0) {
2277 BIO_printf(bio_err, "Async mode is not supported with -mb");
2278 goto end;
2279 }
2280 }
2281
2282 /* Initialize the job pool if async mode is enabled */
2283 if (async_jobs > 0) {
2284 async_init = ASYNC_init_thread(async_jobs, async_jobs);
2285 if (!async_init) {
2286 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
2287 goto end;
2288 }
2289 }
2290
2291 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
2292 loopargs =
2293 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
2294 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
2295
2296 buflen = lengths[size_num - 1];
2297 if (buflen < 36) /* size of random vector in RSA benchmark */
2298 buflen = 36;
2299 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
2300 BIO_printf(bio_err, "Error: buffer size too large\n");
2301 goto end;
2302 }
2303 buflen += MAX_MISALIGNMENT + 1;
2304 for (i = 0; i < loopargs_len; i++) {
2305 if (async_jobs > 0) {
2306 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
2307 if (loopargs[i].wait_ctx == NULL) {
2308 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
2309 goto end;
2310 }
2311 }
2312
2313 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
2314 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
2315
2316 /* Align the start of buffers on a 64 byte boundary */
2317 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
2318 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
2319 loopargs[i].buflen = buflen - misalign;
2320 loopargs[i].sigsize = buflen - misalign;
2321 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
2322 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
2323 #ifndef OPENSSL_NO_DH
2324 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
2325 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
2326 #endif
2327 }
2328
2329 #ifndef NO_FORK
2330 if (multi && do_multi(multi, size_num))
2331 goto show_res;
2332 #endif
2333
2334 for (i = 0; i < loopargs_len; ++i) {
2335 if (domlock) {
2336 #if defined(_WIN32)
2337 (void)VirtualLock(loopargs[i].buf_malloc, buflen);
2338 (void)VirtualLock(loopargs[i].buf2_malloc, buflen);
2339 #elif defined(OPENSSL_SYS_LINUX)
2340 (void)mlock(loopargs[i].buf_malloc, buflen);
2341 (void)mlock(loopargs[i].buf_malloc, buflen);
2342 #endif
2343 }
2344 memset(loopargs[i].buf_malloc, 0, buflen);
2345 memset(loopargs[i].buf2_malloc, 0, buflen);
2346 }
2347
2348 /* Initialize the engine after the fork */
2349 e = setup_engine(engine_id, 0);
2350
2351 /* No parameters; turn on everything. */
2352 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC]
2353 && !doit[D_EVP_CMAC] && !do_kems && !do_sigs) {
2354 memset(doit, 1, sizeof(doit));
2355 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
2356 ERR_set_mark();
2357 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
2358 if (!have_md(names[i]))
2359 doit[i] = 0;
2360 }
2361 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
2362 if (!have_cipher(names[i]))
2363 doit[i] = 0;
2364 }
2365 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2366 app_get0_propq())) != NULL) {
2367 EVP_MAC_free(mac);
2368 mac = NULL;
2369 } else {
2370 doit[D_GHASH] = 0;
2371 }
2372 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2373 app_get0_propq())) != NULL) {
2374 EVP_MAC_free(mac);
2375 mac = NULL;
2376 } else {
2377 doit[D_HMAC] = 0;
2378 }
2379 ERR_pop_to_mark();
2380 memset(rsa_doit, 1, sizeof(rsa_doit));
2381 #ifndef OPENSSL_NO_DH
2382 memset(ffdh_doit, 1, sizeof(ffdh_doit));
2383 #endif
2384 memset(dsa_doit, 1, sizeof(dsa_doit));
2385 #ifndef OPENSSL_NO_ECX
2386 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
2387 memset(ecdh_doit, 1, sizeof(ecdh_doit));
2388 memset(eddsa_doit, 1, sizeof(eddsa_doit));
2389 #endif /* OPENSSL_NO_ECX */
2390 #ifndef OPENSSL_NO_SM2
2391 memset(sm2_doit, 1, sizeof(sm2_doit));
2392 #endif
2393 memset(kems_doit, 1, sizeof(kems_doit));
2394 do_kems = 1;
2395 memset(sigs_doit, 1, sizeof(sigs_doit));
2396 do_sigs = 1;
2397 }
2398 for (i = 0; i < ALGOR_NUM; i++)
2399 if (doit[i])
2400 pr_header++;
2401
2402 if (usertime == 0 && !mr)
2403 BIO_printf(bio_err,
2404 "You have chosen to measure elapsed time "
2405 "instead of user CPU time.\n");
2406
2407 #if SIGALRM > 0
2408 signal(SIGALRM, alarmed);
2409 #endif
2410
2411 if (doit[D_MD2]) {
2412 for (testnum = 0; testnum < size_num; testnum++) {
2413 print_message(names[D_MD2], lengths[testnum], seconds.sym);
2414 Time_F(START);
2415 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
2416 d = Time_F(STOP);
2417 print_result(D_MD2, testnum, count, d);
2418 if (count < 0)
2419 break;
2420 }
2421 }
2422
2423 if (doit[D_MDC2]) {
2424 for (testnum = 0; testnum < size_num; testnum++) {
2425 print_message(names[D_MDC2], lengths[testnum], seconds.sym);
2426 Time_F(START);
2427 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
2428 d = Time_F(STOP);
2429 print_result(D_MDC2, testnum, count, d);
2430 if (count < 0)
2431 break;
2432 }
2433 }
2434
2435 if (doit[D_MD4]) {
2436 for (testnum = 0; testnum < size_num; testnum++) {
2437 print_message(names[D_MD4], lengths[testnum], seconds.sym);
2438 Time_F(START);
2439 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
2440 d = Time_F(STOP);
2441 print_result(D_MD4, testnum, count, d);
2442 if (count < 0)
2443 break;
2444 }
2445 }
2446
2447 if (doit[D_MD5]) {
2448 for (testnum = 0; testnum < size_num; testnum++) {
2449 print_message(names[D_MD5], lengths[testnum], seconds.sym);
2450 Time_F(START);
2451 count = run_benchmark(async_jobs, MD5_loop, loopargs);
2452 d = Time_F(STOP);
2453 print_result(D_MD5, testnum, count, d);
2454 if (count < 0)
2455 break;
2456 }
2457 }
2458
2459 if (doit[D_SHA1]) {
2460 for (testnum = 0; testnum < size_num; testnum++) {
2461 print_message(names[D_SHA1], lengths[testnum], seconds.sym);
2462 Time_F(START);
2463 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
2464 d = Time_F(STOP);
2465 print_result(D_SHA1, testnum, count, d);
2466 if (count < 0)
2467 break;
2468 }
2469 }
2470
2471 if (doit[D_SHA256]) {
2472 for (testnum = 0; testnum < size_num; testnum++) {
2473 print_message(names[D_SHA256], lengths[testnum], seconds.sym);
2474 Time_F(START);
2475 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
2476 d = Time_F(STOP);
2477 print_result(D_SHA256, testnum, count, d);
2478 if (count < 0)
2479 break;
2480 }
2481 }
2482
2483 if (doit[D_SHA512]) {
2484 for (testnum = 0; testnum < size_num; testnum++) {
2485 print_message(names[D_SHA512], lengths[testnum], seconds.sym);
2486 Time_F(START);
2487 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
2488 d = Time_F(STOP);
2489 print_result(D_SHA512, testnum, count, d);
2490 if (count < 0)
2491 break;
2492 }
2493 }
2494
2495 if (doit[D_WHIRLPOOL]) {
2496 for (testnum = 0; testnum < size_num; testnum++) {
2497 print_message(names[D_WHIRLPOOL], lengths[testnum], seconds.sym);
2498 Time_F(START);
2499 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
2500 d = Time_F(STOP);
2501 print_result(D_WHIRLPOOL, testnum, count, d);
2502 if (count < 0)
2503 break;
2504 }
2505 }
2506
2507 if (doit[D_RMD160]) {
2508 for (testnum = 0; testnum < size_num; testnum++) {
2509 print_message(names[D_RMD160], lengths[testnum], seconds.sym);
2510 Time_F(START);
2511 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
2512 d = Time_F(STOP);
2513 print_result(D_RMD160, testnum, count, d);
2514 if (count < 0)
2515 break;
2516 }
2517 }
2518
2519 if (doit[D_HMAC]) {
2520 static const char hmac_key[] = "This is a key...";
2521 int len = strlen(hmac_key);
2522 OSSL_PARAM params[3];
2523
2524 mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
2525 if (mac == NULL || evp_mac_mdname == NULL)
2526 goto end;
2527
2528 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
2529 "HMAC name");
2530 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
2531 names[D_HMAC] = evp_hmac_name;
2532
2533 params[0] =
2534 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2535 evp_mac_mdname, 0);
2536 params[1] =
2537 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2538 (char *)hmac_key, len);
2539 params[2] = OSSL_PARAM_construct_end();
2540
2541 for (i = 0; i < loopargs_len; i++) {
2542 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2543 if (loopargs[i].mctx == NULL)
2544 goto end;
2545
2546 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2547 goto skip_hmac; /* Digest not found */
2548 }
2549 for (testnum = 0; testnum < size_num; testnum++) {
2550 print_message(names[D_HMAC], lengths[testnum], seconds.sym);
2551 Time_F(START);
2552 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2553 d = Time_F(STOP);
2554 print_result(D_HMAC, testnum, count, d);
2555 if (count < 0)
2556 break;
2557 }
2558 for (i = 0; i < loopargs_len; i++)
2559 EVP_MAC_CTX_free(loopargs[i].mctx);
2560 EVP_MAC_free(mac);
2561 mac = NULL;
2562 }
2563 skip_hmac:
2564 if (doit[D_CBC_DES]) {
2565 int st = 1;
2566
2567 for (i = 0; st && i < loopargs_len; i++) {
2568 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2569 sizeof(deskey) / 3);
2570 st = loopargs[i].ctx != NULL;
2571 }
2572 algindex = D_CBC_DES;
2573 for (testnum = 0; st && testnum < size_num; testnum++) {
2574 print_message(names[D_CBC_DES], lengths[testnum], seconds.sym);
2575 Time_F(START);
2576 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2577 d = Time_F(STOP);
2578 print_result(D_CBC_DES, testnum, count, d);
2579 }
2580 for (i = 0; i < loopargs_len; i++)
2581 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2582 }
2583
2584 if (doit[D_EDE3_DES]) {
2585 int st = 1;
2586
2587 for (i = 0; st && i < loopargs_len; i++) {
2588 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2589 sizeof(deskey));
2590 st = loopargs[i].ctx != NULL;
2591 }
2592 algindex = D_EDE3_DES;
2593 for (testnum = 0; st && testnum < size_num; testnum++) {
2594 print_message(names[D_EDE3_DES], lengths[testnum], seconds.sym);
2595 Time_F(START);
2596 count =
2597 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2598 d = Time_F(STOP);
2599 print_result(D_EDE3_DES, testnum, count, d);
2600 }
2601 for (i = 0; i < loopargs_len; i++)
2602 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2603 }
2604
2605 for (k = 0; k < 3; k++) {
2606 algindex = D_CBC_128_AES + k;
2607 if (doit[algindex]) {
2608 int st = 1;
2609
2610 keylen = 16 + k * 8;
2611 for (i = 0; st && i < loopargs_len; i++) {
2612 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2613 key32, keylen);
2614 st = loopargs[i].ctx != NULL;
2615 }
2616
2617 for (testnum = 0; st && testnum < size_num; testnum++) {
2618 print_message(names[algindex], lengths[testnum], seconds.sym);
2619 Time_F(START);
2620 count =
2621 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2622 d = Time_F(STOP);
2623 print_result(algindex, testnum, count, d);
2624 }
2625 for (i = 0; i < loopargs_len; i++)
2626 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2627 }
2628 }
2629
2630 for (k = 0; k < 3; k++) {
2631 algindex = D_CBC_128_CML + k;
2632 if (doit[algindex]) {
2633 int st = 1;
2634
2635 keylen = 16 + k * 8;
2636 for (i = 0; st && i < loopargs_len; i++) {
2637 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2638 key32, keylen);
2639 st = loopargs[i].ctx != NULL;
2640 }
2641
2642 for (testnum = 0; st && testnum < size_num; testnum++) {
2643 print_message(names[algindex], lengths[testnum], seconds.sym);
2644 Time_F(START);
2645 count =
2646 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2647 d = Time_F(STOP);
2648 print_result(algindex, testnum, count, d);
2649 }
2650 for (i = 0; i < loopargs_len; i++)
2651 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2652 }
2653 }
2654
2655 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2656 if (doit[algindex]) {
2657 int st = 1;
2658
2659 keylen = 16;
2660 for (i = 0; st && i < loopargs_len; i++) {
2661 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2662 key32, keylen);
2663 st = loopargs[i].ctx != NULL;
2664 }
2665
2666 for (testnum = 0; st && testnum < size_num; testnum++) {
2667 print_message(names[algindex], lengths[testnum], seconds.sym);
2668 Time_F(START);
2669 count =
2670 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2671 d = Time_F(STOP);
2672 print_result(algindex, testnum, count, d);
2673 }
2674 for (i = 0; i < loopargs_len; i++)
2675 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2676 }
2677 }
2678 if (doit[D_GHASH]) {
2679 static const char gmac_iv[] = "0123456789ab";
2680 OSSL_PARAM params[3];
2681
2682 mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2683 if (mac == NULL)
2684 goto end;
2685
2686 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2687 "aes-128-gcm", 0);
2688 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2689 (char *)gmac_iv,
2690 sizeof(gmac_iv) - 1);
2691 params[2] = OSSL_PARAM_construct_end();
2692
2693 for (i = 0; i < loopargs_len; i++) {
2694 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2695 if (loopargs[i].mctx == NULL)
2696 goto end;
2697
2698 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2699 goto end;
2700 }
2701 for (testnum = 0; testnum < size_num; testnum++) {
2702 print_message(names[D_GHASH], lengths[testnum], seconds.sym);
2703 Time_F(START);
2704 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2705 d = Time_F(STOP);
2706 print_result(D_GHASH, testnum, count, d);
2707 if (count < 0)
2708 break;
2709 }
2710 for (i = 0; i < loopargs_len; i++)
2711 EVP_MAC_CTX_free(loopargs[i].mctx);
2712 EVP_MAC_free(mac);
2713 mac = NULL;
2714 }
2715
2716 if (doit[D_RAND]) {
2717 for (testnum = 0; testnum < size_num; testnum++) {
2718 print_message(names[D_RAND], lengths[testnum], seconds.sym);
2719 Time_F(START);
2720 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2721 d = Time_F(STOP);
2722 print_result(D_RAND, testnum, count, d);
2723 }
2724 }
2725
2726 if (doit[D_EVP]) {
2727 if (evp_cipher != NULL) {
2728 int (*loopfunc) (void *) = EVP_Update_loop;
2729
2730 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2731 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2732 multiblock_speed(evp_cipher, lengths_single, &seconds);
2733 ret = 0;
2734 goto end;
2735 }
2736
2737 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2738
2739 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2740 loopfunc = EVP_Update_loop_ccm;
2741 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2742 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2743 loopfunc = EVP_Update_loop_aead;
2744 if (lengths == lengths_list) {
2745 lengths = aead_lengths_list;
2746 size_num = OSSL_NELEM(aead_lengths_list);
2747 }
2748 }
2749
2750 for (testnum = 0; testnum < size_num; testnum++) {
2751 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2752
2753 for (k = 0; k < loopargs_len; k++) {
2754 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2755 if (loopargs[k].ctx == NULL) {
2756 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2757 exit(1);
2758 }
2759 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2760 NULL, iv, decrypt ? 0 : 1)) {
2761 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2762 ERR_print_errors(bio_err);
2763 exit(1);
2764 }
2765
2766 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2767
2768 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2769 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2770 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2771 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2772 loopargs[k].key, NULL, -1)) {
2773 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2774 ERR_print_errors(bio_err);
2775 exit(1);
2776 }
2777 OPENSSL_clear_free(loopargs[k].key, keylen);
2778
2779 /* GCM-SIV/SIV mode only allows for a single Update operation */
2780 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE
2781 || EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_GCM_SIV_MODE)
2782 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2783 EVP_CTRL_SET_SPEED, 1, NULL);
2784 }
2785
2786 Time_F(START);
2787 count = run_benchmark(async_jobs, loopfunc, loopargs);
2788 d = Time_F(STOP);
2789 for (k = 0; k < loopargs_len; k++)
2790 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2791 print_result(D_EVP, testnum, count, d);
2792 }
2793 } else if (evp_md_name != NULL) {
2794 names[D_EVP] = evp_md_name;
2795
2796 for (testnum = 0; testnum < size_num; testnum++) {
2797 print_message(names[D_EVP], lengths[testnum], seconds.sym);
2798 Time_F(START);
2799 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2800 d = Time_F(STOP);
2801 print_result(D_EVP, testnum, count, d);
2802 if (count < 0)
2803 break;
2804 }
2805 }
2806 }
2807
2808 if (doit[D_EVP_CMAC]) {
2809 OSSL_PARAM params[3];
2810 EVP_CIPHER *cipher = NULL;
2811
2812 mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2813 if (mac == NULL || evp_mac_ciphername == NULL)
2814 goto end;
2815 if (!opt_cipher(evp_mac_ciphername, &cipher))
2816 goto end;
2817
2818 keylen = EVP_CIPHER_get_key_length(cipher);
2819 EVP_CIPHER_free(cipher);
2820 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2821 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2822 goto end;
2823 }
2824 evp_cmac_name = app_malloc(sizeof("cmac()")
2825 + strlen(evp_mac_ciphername), "CMAC name");
2826 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2827 names[D_EVP_CMAC] = evp_cmac_name;
2828
2829 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2830 evp_mac_ciphername, 0);
2831 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2832 (char *)key32, keylen);
2833 params[2] = OSSL_PARAM_construct_end();
2834
2835 for (i = 0; i < loopargs_len; i++) {
2836 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2837 if (loopargs[i].mctx == NULL)
2838 goto end;
2839
2840 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2841 goto end;
2842 }
2843
2844 for (testnum = 0; testnum < size_num; testnum++) {
2845 print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
2846 Time_F(START);
2847 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2848 d = Time_F(STOP);
2849 print_result(D_EVP_CMAC, testnum, count, d);
2850 if (count < 0)
2851 break;
2852 }
2853 for (i = 0; i < loopargs_len; i++)
2854 EVP_MAC_CTX_free(loopargs[i].mctx);
2855 EVP_MAC_free(mac);
2856 mac = NULL;
2857 }
2858
2859 for (i = 0; i < loopargs_len; i++)
2860 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2861 goto end;
2862
2863 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2864 EVP_PKEY *rsa_key = NULL;
2865 int st = 0;
2866
2867 if (!rsa_doit[testnum])
2868 continue;
2869
2870 if (primes > RSA_DEFAULT_PRIME_NUM) {
2871 /* we haven't set keys yet, generate multi-prime RSA keys */
2872 bn = BN_new();
2873 st = bn != NULL
2874 && BN_set_word(bn, RSA_F4)
2875 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2876 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2877 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2878 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2879 && EVP_PKEY_keygen(genctx, &rsa_key);
2880 BN_free(bn);
2881 bn = NULL;
2882 EVP_PKEY_CTX_free(genctx);
2883 genctx = NULL;
2884 } else {
2885 const unsigned char *p = rsa_keys[testnum].data;
2886
2887 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2888 rsa_keys[testnum].length)) != NULL;
2889 }
2890
2891 for (i = 0; st && i < loopargs_len; i++) {
2892 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2893 loopargs[i].sigsize = loopargs[i].buflen;
2894 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2895 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2896 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2897 loopargs[i].buf2,
2898 &loopargs[i].sigsize,
2899 loopargs[i].buf, 36) <= 0)
2900 st = 0;
2901 }
2902 if (!st) {
2903 BIO_printf(bio_err,
2904 "RSA sign setup failure. No RSA sign will be done.\n");
2905 ERR_print_errors(bio_err);
2906 op_count = 1;
2907 } else {
2908 pkey_print_message("private", "rsa sign",
2909 rsa_keys[testnum].bits, seconds.rsa);
2910 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2911 Time_F(START);
2912 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2913 d = Time_F(STOP);
2914 BIO_printf(bio_err,
2915 mr ? "+R1:%ld:%d:%.2f\n"
2916 : "%ld %u bits private RSA sign ops in %.2fs\n",
2917 count, rsa_keys[testnum].bits, d);
2918 rsa_results[testnum][0] = (double)count / d;
2919 op_count = count;
2920 }
2921
2922 for (i = 0; st && i < loopargs_len; i++) {
2923 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2924 NULL);
2925 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2926 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2927 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2928 loopargs[i].buf2,
2929 loopargs[i].sigsize,
2930 loopargs[i].buf, 36) <= 0)
2931 st = 0;
2932 }
2933 if (!st) {
2934 BIO_printf(bio_err,
2935 "RSA verify setup failure. No RSA verify will be done.\n");
2936 ERR_print_errors(bio_err);
2937 rsa_doit[testnum] = 0;
2938 } else {
2939 pkey_print_message("public", "rsa verify",
2940 rsa_keys[testnum].bits, seconds.rsa);
2941 Time_F(START);
2942 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2943 d = Time_F(STOP);
2944 BIO_printf(bio_err,
2945 mr ? "+R2:%ld:%d:%.2f\n"
2946 : "%ld %u bits public RSA verify ops in %.2fs\n",
2947 count, rsa_keys[testnum].bits, d);
2948 rsa_results[testnum][1] = (double)count / d;
2949 }
2950
2951 for (i = 0; st && i < loopargs_len; i++) {
2952 loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2953 loopargs[i].encsize = loopargs[i].buflen;
2954 if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
2955 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
2956 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
2957 loopargs[i].buf2,
2958 &loopargs[i].encsize,
2959 loopargs[i].buf, 36) <= 0)
2960 st = 0;
2961 }
2962 if (!st) {
2963 BIO_printf(bio_err,
2964 "RSA encrypt setup failure. No RSA encrypt will be done.\n");
2965 ERR_print_errors(bio_err);
2966 op_count = 1;
2967 } else {
2968 pkey_print_message("private", "rsa encrypt",
2969 rsa_keys[testnum].bits, seconds.rsa);
2970 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2971 Time_F(START);
2972 count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
2973 d = Time_F(STOP);
2974 BIO_printf(bio_err,
2975 mr ? "+R3:%ld:%d:%.2f\n"
2976 : "%ld %u bits public RSA encrypt ops in %.2fs\n",
2977 count, rsa_keys[testnum].bits, d);
2978 rsa_results[testnum][2] = (double)count / d;
2979 op_count = count;
2980 }
2981
2982 for (i = 0; st && i < loopargs_len; i++) {
2983 loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2984 declen = loopargs[i].buflen;
2985 if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
2986 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
2987 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
2988 loopargs[i].buf,
2989 &declen,
2990 loopargs[i].buf2,
2991 loopargs[i].encsize) <= 0)
2992 st = 0;
2993 }
2994 if (!st) {
2995 BIO_printf(bio_err,
2996 "RSA decrypt setup failure. No RSA decrypt will be done.\n");
2997 ERR_print_errors(bio_err);
2998 op_count = 1;
2999 } else {
3000 pkey_print_message("private", "rsa decrypt",
3001 rsa_keys[testnum].bits, seconds.rsa);
3002 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3003 Time_F(START);
3004 count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3005 d = Time_F(STOP);
3006 BIO_printf(bio_err,
3007 mr ? "+R4:%ld:%d:%.2f\n"
3008 : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3009 count, rsa_keys[testnum].bits, d);
3010 rsa_results[testnum][3] = (double)count / d;
3011 op_count = count;
3012 }
3013
3014 if (op_count <= 1) {
3015 /* if longer than 10s, don't do any more */
3016 stop_it(rsa_doit, testnum);
3017 }
3018 EVP_PKEY_free(rsa_key);
3019 }
3020
3021 for (testnum = 0; testnum < DSA_NUM; testnum++) {
3022 EVP_PKEY *dsa_key = NULL;
3023 int st;
3024
3025 if (!dsa_doit[testnum])
3026 continue;
3027
3028 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3029
3030 for (i = 0; st && i < loopargs_len; i++) {
3031 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3032 NULL);
3033 loopargs[i].sigsize = loopargs[i].buflen;
3034 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3035 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3036
3037 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3038 loopargs[i].buf2,
3039 &loopargs[i].sigsize,
3040 loopargs[i].buf, 20) <= 0)
3041 st = 0;
3042 }
3043 if (!st) {
3044 BIO_printf(bio_err,
3045 "DSA sign setup failure. No DSA sign will be done.\n");
3046 ERR_print_errors(bio_err);
3047 op_count = 1;
3048 } else {
3049 pkey_print_message("sign", "dsa",
3050 dsa_bits[testnum], seconds.dsa);
3051 Time_F(START);
3052 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3053 d = Time_F(STOP);
3054 BIO_printf(bio_err,
3055 mr ? "+R5:%ld:%u:%.2f\n"
3056 : "%ld %u bits DSA sign ops in %.2fs\n",
3057 count, dsa_bits[testnum], d);
3058 dsa_results[testnum][0] = (double)count / d;
3059 op_count = count;
3060 }
3061
3062 for (i = 0; st && i < loopargs_len; i++) {
3063 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3064 NULL);
3065 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3066 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3067 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3068 loopargs[i].buf2,
3069 loopargs[i].sigsize,
3070 loopargs[i].buf, 36) <= 0)
3071 st = 0;
3072 }
3073 if (!st) {
3074 BIO_printf(bio_err,
3075 "DSA verify setup failure. No DSA verify will be done.\n");
3076 ERR_print_errors(bio_err);
3077 dsa_doit[testnum] = 0;
3078 } else {
3079 pkey_print_message("verify", "dsa",
3080 dsa_bits[testnum], seconds.dsa);
3081 Time_F(START);
3082 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3083 d = Time_F(STOP);
3084 BIO_printf(bio_err,
3085 mr ? "+R6:%ld:%u:%.2f\n"
3086 : "%ld %u bits DSA verify ops in %.2fs\n",
3087 count, dsa_bits[testnum], d);
3088 dsa_results[testnum][1] = (double)count / d;
3089 }
3090
3091 if (op_count <= 1) {
3092 /* if longer than 10s, don't do any more */
3093 stop_it(dsa_doit, testnum);
3094 }
3095 EVP_PKEY_free(dsa_key);
3096 }
3097
3098 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3099 EVP_PKEY *ecdsa_key = NULL;
3100 int st;
3101
3102 if (!ecdsa_doit[testnum])
3103 continue;
3104
3105 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3106
3107 for (i = 0; st && i < loopargs_len; i++) {
3108 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3109 NULL);
3110 loopargs[i].sigsize = loopargs[i].buflen;
3111 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3112 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3113
3114 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3115 loopargs[i].buf2,
3116 &loopargs[i].sigsize,
3117 loopargs[i].buf, 20) <= 0)
3118 st = 0;
3119 }
3120 if (!st) {
3121 BIO_printf(bio_err,
3122 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
3123 ERR_print_errors(bio_err);
3124 op_count = 1;
3125 } else {
3126 pkey_print_message("sign", "ecdsa",
3127 ec_curves[testnum].bits, seconds.ecdsa);
3128 Time_F(START);
3129 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3130 d = Time_F(STOP);
3131 BIO_printf(bio_err,
3132 mr ? "+R7:%ld:%u:%.2f\n"
3133 : "%ld %u bits ECDSA sign ops in %.2fs\n",
3134 count, ec_curves[testnum].bits, d);
3135 ecdsa_results[testnum][0] = (double)count / d;
3136 op_count = count;
3137 }
3138
3139 for (i = 0; st && i < loopargs_len; i++) {
3140 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3141 NULL);
3142 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3143 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3144 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3145 loopargs[i].buf2,
3146 loopargs[i].sigsize,
3147 loopargs[i].buf, 20) <= 0)
3148 st = 0;
3149 }
3150 if (!st) {
3151 BIO_printf(bio_err,
3152 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3153 ERR_print_errors(bio_err);
3154 ecdsa_doit[testnum] = 0;
3155 } else {
3156 pkey_print_message("verify", "ecdsa",
3157 ec_curves[testnum].bits, seconds.ecdsa);
3158 Time_F(START);
3159 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3160 d = Time_F(STOP);
3161 BIO_printf(bio_err,
3162 mr ? "+R8:%ld:%u:%.2f\n"
3163 : "%ld %u bits ECDSA verify ops in %.2fs\n",
3164 count, ec_curves[testnum].bits, d);
3165 ecdsa_results[testnum][1] = (double)count / d;
3166 }
3167
3168 if (op_count <= 1) {
3169 /* if longer than 10s, don't do any more */
3170 stop_it(ecdsa_doit, testnum);
3171 }
3172 }
3173
3174 for (testnum = 0; testnum < EC_NUM; testnum++) {
3175 int ecdh_checks = 1;
3176
3177 if (!ecdh_doit[testnum])
3178 continue;
3179
3180 for (i = 0; i < loopargs_len; i++) {
3181 EVP_PKEY_CTX *test_ctx = NULL;
3182 EVP_PKEY_CTX *ctx = NULL;
3183 EVP_PKEY *key_A = NULL;
3184 EVP_PKEY *key_B = NULL;
3185 size_t outlen;
3186 size_t test_outlen;
3187
3188 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3189 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3190 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3191 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3192 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3193 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3194 || outlen == 0 /* ensure outlen is a valid size */
3195 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3196 ecdh_checks = 0;
3197 BIO_printf(bio_err, "ECDH key generation failure.\n");
3198 ERR_print_errors(bio_err);
3199 op_count = 1;
3200 break;
3201 }
3202
3203 /*
3204 * Here we perform a test run, comparing the output of a*B and b*A;
3205 * we try this here and assume that further EVP_PKEY_derive calls
3206 * never fail, so we can skip checks in the actually benchmarked
3207 * code, for maximum performance.
3208 */
3209 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3210 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3211 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3212 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3213 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3214 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3215 || test_outlen != outlen /* compare output length */) {
3216 ecdh_checks = 0;
3217 BIO_printf(bio_err, "ECDH computation failure.\n");
3218 ERR_print_errors(bio_err);
3219 op_count = 1;
3220 break;
3221 }
3222
3223 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3224 if (CRYPTO_memcmp(loopargs[i].secret_a,
3225 loopargs[i].secret_b, outlen)) {
3226 ecdh_checks = 0;
3227 BIO_printf(bio_err, "ECDH computations don't match.\n");
3228 ERR_print_errors(bio_err);
3229 op_count = 1;
3230 break;
3231 }
3232
3233 loopargs[i].ecdh_ctx[testnum] = ctx;
3234 loopargs[i].outlen[testnum] = outlen;
3235
3236 EVP_PKEY_free(key_A);
3237 EVP_PKEY_free(key_B);
3238 EVP_PKEY_CTX_free(test_ctx);
3239 test_ctx = NULL;
3240 }
3241 if (ecdh_checks != 0) {
3242 pkey_print_message("", "ecdh",
3243 ec_curves[testnum].bits, seconds.ecdh);
3244 Time_F(START);
3245 count =
3246 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3247 d = Time_F(STOP);
3248 BIO_printf(bio_err,
3249 mr ? "+R9:%ld:%d:%.2f\n" :
3250 "%ld %u-bits ECDH ops in %.2fs\n", count,
3251 ec_curves[testnum].bits, d);
3252 ecdh_results[testnum][0] = (double)count / d;
3253 op_count = count;
3254 }
3255
3256 if (op_count <= 1) {
3257 /* if longer than 10s, don't do any more */
3258 stop_it(ecdh_doit, testnum);
3259 }
3260 }
3261
3262 #ifndef OPENSSL_NO_ECX
3263 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3264 int st = 1;
3265 EVP_PKEY *ed_pkey = NULL;
3266 EVP_PKEY_CTX *ed_pctx = NULL;
3267
3268 if (!eddsa_doit[testnum])
3269 continue; /* Ignore Curve */
3270 for (i = 0; i < loopargs_len; i++) {
3271 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3272 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3273 st = 0;
3274 break;
3275 }
3276 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3277 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3278 st = 0;
3279 break;
3280 }
3281
3282 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3283 NULL)) == NULL
3284 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3285 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3286 st = 0;
3287 EVP_PKEY_CTX_free(ed_pctx);
3288 break;
3289 }
3290 EVP_PKEY_CTX_free(ed_pctx);
3291
3292 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3293 NULL, ed_pkey)) {
3294 st = 0;
3295 EVP_PKEY_free(ed_pkey);
3296 break;
3297 }
3298 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3299 NULL, NULL, ed_pkey)) {
3300 st = 0;
3301 EVP_PKEY_free(ed_pkey);
3302 break;
3303 }
3304
3305 EVP_PKEY_free(ed_pkey);
3306 ed_pkey = NULL;
3307 }
3308 if (st == 0) {
3309 BIO_printf(bio_err, "EdDSA failure.\n");
3310 ERR_print_errors(bio_err);
3311 op_count = 1;
3312 } else {
3313 for (i = 0; i < loopargs_len; i++) {
3314 /* Perform EdDSA signature test */
3315 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3316 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3317 loopargs[i].buf2, &loopargs[i].sigsize,
3318 loopargs[i].buf, 20);
3319 if (st == 0)
3320 break;
3321 }
3322 if (st == 0) {
3323 BIO_printf(bio_err,
3324 "EdDSA sign failure. No EdDSA sign will be done.\n");
3325 ERR_print_errors(bio_err);
3326 op_count = 1;
3327 } else {
3328 pkey_print_message("sign", ed_curves[testnum].name,
3329 ed_curves[testnum].bits, seconds.eddsa);
3330 Time_F(START);
3331 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3332 d = Time_F(STOP);
3333
3334 BIO_printf(bio_err,
3335 mr ? "+R10:%ld:%u:%s:%.2f\n" :
3336 "%ld %u bits %s sign ops in %.2fs \n",
3337 count, ed_curves[testnum].bits,
3338 ed_curves[testnum].name, d);
3339 eddsa_results[testnum][0] = (double)count / d;
3340 op_count = count;
3341 }
3342 /* Perform EdDSA verification test */
3343 for (i = 0; i < loopargs_len; i++) {
3344 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3345 loopargs[i].buf2, loopargs[i].sigsize,
3346 loopargs[i].buf, 20);
3347 if (st != 1)
3348 break;
3349 }
3350 if (st != 1) {
3351 BIO_printf(bio_err,
3352 "EdDSA verify failure. No EdDSA verify will be done.\n");
3353 ERR_print_errors(bio_err);
3354 eddsa_doit[testnum] = 0;
3355 } else {
3356 pkey_print_message("verify", ed_curves[testnum].name,
3357 ed_curves[testnum].bits, seconds.eddsa);
3358 Time_F(START);
3359 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3360 d = Time_F(STOP);
3361 BIO_printf(bio_err,
3362 mr ? "+R11:%ld:%u:%s:%.2f\n"
3363 : "%ld %u bits %s verify ops in %.2fs\n",
3364 count, ed_curves[testnum].bits,
3365 ed_curves[testnum].name, d);
3366 eddsa_results[testnum][1] = (double)count / d;
3367 }
3368
3369 if (op_count <= 1) {
3370 /* if longer than 10s, don't do any more */
3371 stop_it(eddsa_doit, testnum);
3372 }
3373 }
3374 }
3375 #endif /* OPENSSL_NO_ECX */
3376
3377 #ifndef OPENSSL_NO_SM2
3378 for (testnum = 0; testnum < SM2_NUM; testnum++) {
3379 int st = 1;
3380 EVP_PKEY *sm2_pkey = NULL;
3381
3382 if (!sm2_doit[testnum])
3383 continue; /* Ignore Curve */
3384 /* Init signing and verification */
3385 for (i = 0; i < loopargs_len; i++) {
3386 EVP_PKEY_CTX *sm2_pctx = NULL;
3387 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3388 EVP_PKEY_CTX *pctx = NULL;
3389 st = 0;
3390
3391 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3392 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3393 if (loopargs[i].sm2_ctx[testnum] == NULL
3394 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3395 break;
3396
3397 sm2_pkey = NULL;
3398
3399 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3400 || EVP_PKEY_keygen_init(pctx) <= 0
3401 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3402 sm2_curves[testnum].nid) <= 0
3403 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3404 EVP_PKEY_CTX_free(pctx);
3405 if (st == 0)
3406 break;
3407
3408 st = 0; /* set back to zero */
3409 /* attach it sooner to rely on main final cleanup */
3410 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3411 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3412
3413 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3414 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3415 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3416 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3417 break;
3418 }
3419
3420 /* attach them directly to respective ctx */
3421 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3422 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3423
3424 /*
3425 * No need to allow user to set an explicit ID here, just use
3426 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3427 */
3428 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3429 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3430 break;
3431
3432 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3433 EVP_sm3(), NULL, sm2_pkey))
3434 break;
3435 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3436 EVP_sm3(), NULL, sm2_pkey))
3437 break;
3438 st = 1; /* mark loop as succeeded */
3439 }
3440 if (st == 0) {
3441 BIO_printf(bio_err, "SM2 init failure.\n");
3442 ERR_print_errors(bio_err);
3443 op_count = 1;
3444 } else {
3445 for (i = 0; i < loopargs_len; i++) {
3446 /* Perform SM2 signature test */
3447 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3448 loopargs[i].buf2, &loopargs[i].sigsize,
3449 loopargs[i].buf, 20);
3450 if (st == 0)
3451 break;
3452 }
3453 if (st == 0) {
3454 BIO_printf(bio_err,
3455 "SM2 sign failure. No SM2 sign will be done.\n");
3456 ERR_print_errors(bio_err);
3457 op_count = 1;
3458 } else {
3459 pkey_print_message("sign", sm2_curves[testnum].name,
3460 sm2_curves[testnum].bits, seconds.sm2);
3461 Time_F(START);
3462 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3463 d = Time_F(STOP);
3464
3465 BIO_printf(bio_err,
3466 mr ? "+R12:%ld:%u:%s:%.2f\n" :
3467 "%ld %u bits %s sign ops in %.2fs \n",
3468 count, sm2_curves[testnum].bits,
3469 sm2_curves[testnum].name, d);
3470 sm2_results[testnum][0] = (double)count / d;
3471 op_count = count;
3472 }
3473
3474 /* Perform SM2 verification test */
3475 for (i = 0; i < loopargs_len; i++) {
3476 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3477 loopargs[i].buf2, loopargs[i].sigsize,
3478 loopargs[i].buf, 20);
3479 if (st != 1)
3480 break;
3481 }
3482 if (st != 1) {
3483 BIO_printf(bio_err,
3484 "SM2 verify failure. No SM2 verify will be done.\n");
3485 ERR_print_errors(bio_err);
3486 sm2_doit[testnum] = 0;
3487 } else {
3488 pkey_print_message("verify", sm2_curves[testnum].name,
3489 sm2_curves[testnum].bits, seconds.sm2);
3490 Time_F(START);
3491 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3492 d = Time_F(STOP);
3493 BIO_printf(bio_err,
3494 mr ? "+R13:%ld:%u:%s:%.2f\n"
3495 : "%ld %u bits %s verify ops in %.2fs\n",
3496 count, sm2_curves[testnum].bits,
3497 sm2_curves[testnum].name, d);
3498 sm2_results[testnum][1] = (double)count / d;
3499 }
3500
3501 if (op_count <= 1) {
3502 /* if longer than 10s, don't do any more */
3503 for (testnum++; testnum < SM2_NUM; testnum++)
3504 sm2_doit[testnum] = 0;
3505 }
3506 }
3507 }
3508 #endif /* OPENSSL_NO_SM2 */
3509
3510 #ifndef OPENSSL_NO_DH
3511 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3512 int ffdh_checks = 1;
3513
3514 if (!ffdh_doit[testnum])
3515 continue;
3516
3517 for (i = 0; i < loopargs_len; i++) {
3518 EVP_PKEY *pkey_A = NULL;
3519 EVP_PKEY *pkey_B = NULL;
3520 EVP_PKEY_CTX *ffdh_ctx = NULL;
3521 EVP_PKEY_CTX *test_ctx = NULL;
3522 size_t secret_size;
3523 size_t test_out;
3524
3525 /* Ensure that the error queue is empty */
3526 if (ERR_peek_error()) {
3527 BIO_printf(bio_err,
3528 "WARNING: the error queue contains previous unhandled errors.\n");
3529 ERR_print_errors(bio_err);
3530 }
3531
3532 pkey_A = EVP_PKEY_new();
3533 if (!pkey_A) {
3534 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3535 ERR_print_errors(bio_err);
3536 op_count = 1;
3537 ffdh_checks = 0;
3538 break;
3539 }
3540 pkey_B = EVP_PKEY_new();
3541 if (!pkey_B) {
3542 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3543 ERR_print_errors(bio_err);
3544 op_count = 1;
3545 ffdh_checks = 0;
3546 break;
3547 }
3548
3549 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3550 if (!ffdh_ctx) {
3551 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3552 ERR_print_errors(bio_err);
3553 op_count = 1;
3554 ffdh_checks = 0;
3555 break;
3556 }
3557
3558 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3559 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3560 ERR_print_errors(bio_err);
3561 op_count = 1;
3562 ffdh_checks = 0;
3563 break;
3564 }
3565 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3566 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3567 ERR_print_errors(bio_err);
3568 op_count = 1;
3569 ffdh_checks = 0;
3570 break;
3571 }
3572
3573 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
3574 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
3575 BIO_printf(bio_err, "FFDH key generation failure.\n");
3576 ERR_print_errors(bio_err);
3577 op_count = 1;
3578 ffdh_checks = 0;
3579 break;
3580 }
3581
3582 EVP_PKEY_CTX_free(ffdh_ctx);
3583
3584 /*
3585 * check if the derivation works correctly both ways so that
3586 * we know if future derive calls will fail, and we can skip
3587 * error checking in benchmarked code
3588 */
3589 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3590 if (ffdh_ctx == NULL) {
3591 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3592 ERR_print_errors(bio_err);
3593 op_count = 1;
3594 ffdh_checks = 0;
3595 break;
3596 }
3597 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3598 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3599 ERR_print_errors(bio_err);
3600 op_count = 1;
3601 ffdh_checks = 0;
3602 break;
3603 }
3604 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3605 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3606 ERR_print_errors(bio_err);
3607 op_count = 1;
3608 ffdh_checks = 0;
3609 break;
3610 }
3611 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3612 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3613 ERR_print_errors(bio_err);
3614 op_count = 1;
3615 ffdh_checks = 0;
3616 break;
3617 }
3618 if (secret_size > MAX_FFDH_SIZE) {
3619 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3620 op_count = 1;
3621 ffdh_checks = 0;
3622 break;
3623 }
3624 if (EVP_PKEY_derive(ffdh_ctx,
3625 loopargs[i].secret_ff_a,
3626 &secret_size) <= 0) {
3627 BIO_printf(bio_err, "Shared secret derive failure.\n");
3628 ERR_print_errors(bio_err);
3629 op_count = 1;
3630 ffdh_checks = 0;
3631 break;
3632 }
3633 /* Now check from side B */
3634 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3635 if (!test_ctx) {
3636 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3637 ERR_print_errors(bio_err);
3638 op_count = 1;
3639 ffdh_checks = 0;
3640 break;
3641 }
3642 if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3643 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3644 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3645 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3646 test_out != secret_size) {
3647 BIO_printf(bio_err, "FFDH computation failure.\n");
3648 op_count = 1;
3649 ffdh_checks = 0;
3650 break;
3651 }
3652
3653 /* compare the computed secrets */
3654 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3655 loopargs[i].secret_ff_b, secret_size)) {
3656 BIO_printf(bio_err, "FFDH computations don't match.\n");
3657 ERR_print_errors(bio_err);
3658 op_count = 1;
3659 ffdh_checks = 0;
3660 break;
3661 }
3662
3663 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3664
3665 EVP_PKEY_free(pkey_A);
3666 pkey_A = NULL;
3667 EVP_PKEY_free(pkey_B);
3668 pkey_B = NULL;
3669 EVP_PKEY_CTX_free(test_ctx);
3670 test_ctx = NULL;
3671 }
3672 if (ffdh_checks != 0) {
3673 pkey_print_message("", "ffdh",
3674 ffdh_params[testnum].bits, seconds.ffdh);
3675 Time_F(START);
3676 count =
3677 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3678 d = Time_F(STOP);
3679 BIO_printf(bio_err,
3680 mr ? "+R14:%ld:%d:%.2f\n" :
3681 "%ld %u-bits FFDH ops in %.2fs\n", count,
3682 ffdh_params[testnum].bits, d);
3683 ffdh_results[testnum][0] = (double)count / d;
3684 op_count = count;
3685 }
3686 if (op_count <= 1) {
3687 /* if longer than 10s, don't do any more */
3688 stop_it(ffdh_doit, testnum);
3689 }
3690 }
3691 #endif /* OPENSSL_NO_DH */
3692
3693 for (testnum = 0; testnum < kems_algs_len; testnum++) {
3694 int kem_checks = 1;
3695 const char *kem_name = kems_algname[testnum];
3696
3697 if (!kems_doit[testnum] || !do_kems)
3698 continue;
3699
3700 for (i = 0; i < loopargs_len; i++) {
3701 EVP_PKEY *pkey = NULL;
3702 EVP_PKEY_CTX *kem_gen_ctx = NULL;
3703 EVP_PKEY_CTX *kem_encaps_ctx = NULL;
3704 EVP_PKEY_CTX *kem_decaps_ctx = NULL;
3705 size_t send_secret_len, out_len;
3706 size_t rcv_secret_len;
3707 unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
3708 unsigned int bits;
3709 char *name;
3710 char sfx[MAX_ALGNAME_SUFFIX];
3711 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3712 int use_params = 0;
3713 enum kem_type_t { KEM_RSA = 1, KEM_EC, KEM_X25519, KEM_X448 } kem_type;
3714
3715 /* no string after rsa<bitcnt> permitted: */
3716 if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3717 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
3718 kem_type = KEM_RSA;
3719 else if (strncmp(kem_name, "EC", 2) == 0)
3720 kem_type = KEM_EC;
3721 else if (strcmp(kem_name, "X25519") == 0)
3722 kem_type = KEM_X25519;
3723 else if (strcmp(kem_name, "X448") == 0)
3724 kem_type = KEM_X448;
3725 else kem_type = 0;
3726
3727 if (ERR_peek_error()) {
3728 BIO_printf(bio_err,
3729 "WARNING: the error queue contains previous unhandled errors.\n");
3730 ERR_print_errors(bio_err);
3731 }
3732
3733 if (kem_type == KEM_RSA) {
3734 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3735 &bits);
3736 use_params = 1;
3737 } else if (kem_type == KEM_EC) {
3738 name = (char *)(kem_name + 2);
3739 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
3740 name, 0);
3741 use_params = 1;
3742 }
3743
3744 kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3745 (kem_type == KEM_RSA) ? "RSA":
3746 (kem_type == KEM_EC) ? "EC":
3747 kem_name,
3748 app_get0_propq());
3749
3750 if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
3751 || (use_params
3752 && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
3753 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
3754 kem_name);
3755 goto kem_err_break;
3756 }
3757 if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
3758 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
3759 goto kem_err_break;
3760 }
3761 /* Now prepare encaps data structs */
3762 kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3763 pkey,
3764 app_get0_propq());
3765 if (kem_encaps_ctx == NULL
3766 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
3767 || (kem_type == KEM_RSA
3768 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
3769 || ((kem_type == KEM_EC
3770 || kem_type == KEM_X25519
3771 || kem_type == KEM_X448)
3772 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
3773 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
3774 NULL, &send_secret_len) <= 0) {
3775 BIO_printf(bio_err,
3776 "Error while initializing encaps data structs for %s.\n",
3777 kem_name);
3778 goto kem_err_break;
3779 }
3780 out = app_malloc(out_len, "encaps result");
3781 send_secret = app_malloc(send_secret_len, "encaps secret");
3782 if (out == NULL || send_secret == NULL) {
3783 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
3784 goto kem_err_break;
3785 }
3786 if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
3787 send_secret, &send_secret_len) <= 0) {
3788 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
3789 goto kem_err_break;
3790 }
3791 /* Now prepare decaps data structs */
3792 kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3793 pkey,
3794 app_get0_propq());
3795 if (kem_decaps_ctx == NULL
3796 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
3797 || (kem_type == KEM_RSA
3798 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
3799 || ((kem_type == KEM_EC
3800 || kem_type == KEM_X25519
3801 || kem_type == KEM_X448)
3802 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
3803 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
3804 out, out_len) <= 0) {
3805 BIO_printf(bio_err,
3806 "Error while initializing decaps data structs for %s.\n",
3807 kem_name);
3808 goto kem_err_break;
3809 }
3810 rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
3811 if (rcv_secret == NULL) {
3812 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
3813 kem_name);
3814 goto kem_err_break;
3815 }
3816 if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
3817 &rcv_secret_len, out, out_len) <= 0
3818 || rcv_secret_len != send_secret_len
3819 || memcmp(send_secret, rcv_secret, send_secret_len)) {
3820 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
3821 goto kem_err_break;
3822 }
3823 loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
3824 loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
3825 loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
3826 loopargs[i].kem_out_len[testnum] = out_len;
3827 loopargs[i].kem_secret_len[testnum] = send_secret_len;
3828 loopargs[i].kem_out[testnum] = out;
3829 loopargs[i].kem_send_secret[testnum] = send_secret;
3830 loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
3831 break;
3832
3833 kem_err_break:
3834 ERR_print_errors(bio_err);
3835 op_count = 1;
3836 kem_checks = 0;
3837 break;
3838 }
3839 if (kem_checks != 0) {
3840 kskey_print_message(kem_name, "keygen", seconds.kem);
3841 Time_F(START);
3842 count =
3843 run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
3844 d = Time_F(STOP);
3845 BIO_printf(bio_err,
3846 mr ? "+R15:%ld:%s:%.2f\n" :
3847 "%ld %s KEM keygen ops in %.2fs\n", count,
3848 kem_name, d);
3849 kems_results[testnum][0] = (double)count / d;
3850 op_count = count;
3851 kskey_print_message(kem_name, "encaps", seconds.kem);
3852 Time_F(START);
3853 count =
3854 run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
3855 d = Time_F(STOP);
3856 BIO_printf(bio_err,
3857 mr ? "+R16:%ld:%s:%.2f\n" :
3858 "%ld %s KEM encaps ops in %.2fs\n", count,
3859 kem_name, d);
3860 kems_results[testnum][1] = (double)count / d;
3861 op_count = count;
3862 kskey_print_message(kem_name, "decaps", seconds.kem);
3863 Time_F(START);
3864 count =
3865 run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
3866 d = Time_F(STOP);
3867 BIO_printf(bio_err,
3868 mr ? "+R17:%ld:%s:%.2f\n" :
3869 "%ld %s KEM decaps ops in %.2fs\n", count,
3870 kem_name, d);
3871 kems_results[testnum][2] = (double)count / d;
3872 op_count = count;
3873 }
3874 if (op_count <= 1) {
3875 /* if longer than 10s, don't do any more */
3876 stop_it(kems_doit, testnum);
3877 }
3878 }
3879
3880 for (testnum = 0; testnum < sigs_algs_len; testnum++) {
3881 int sig_checks = 1;
3882 const char *sig_name = sigs_algname[testnum];
3883
3884 if (!sigs_doit[testnum] || !do_sigs)
3885 continue;
3886
3887 for (i = 0; i < loopargs_len; i++) {
3888 EVP_PKEY *pkey = NULL;
3889 EVP_PKEY_CTX *ctx_params = NULL;
3890 EVP_PKEY* pkey_params = NULL;
3891 EVP_PKEY_CTX *sig_gen_ctx = NULL;
3892 EVP_PKEY_CTX *sig_sign_ctx = NULL;
3893 EVP_PKEY_CTX *sig_verify_ctx = NULL;
3894 unsigned char md[SHA256_DIGEST_LENGTH];
3895 unsigned char *sig;
3896 char sfx[MAX_ALGNAME_SUFFIX];
3897 size_t md_len = SHA256_DIGEST_LENGTH;
3898 size_t max_sig_len, sig_len;
3899 unsigned int bits;
3900 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
3901 int use_params = 0;
3902
3903 /* only sign little data to avoid measuring digest performance */
3904 memset(md, 0, SHA256_DIGEST_LENGTH);
3905
3906 if (ERR_peek_error()) {
3907 BIO_printf(bio_err,
3908 "WARNING: the error queue contains previous unhandled errors.\n");
3909 ERR_print_errors(bio_err);
3910 }
3911
3912 /* no string after rsa<bitcnt> permitted: */
3913 if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
3914 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
3915 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
3916 &bits);
3917 use_params = 1;
3918 }
3919
3920 if (strncmp(sig_name, "dsa", 3) == 0) {
3921 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
3922 if (ctx_params == NULL
3923 || EVP_PKEY_paramgen_init(ctx_params) <= 0
3924 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
3925 atoi(sig_name + 3)) <= 0
3926 || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
3927 || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
3928 || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
3929 BIO_printf(bio_err,
3930 "Error initializing classic keygen ctx for %s.\n",
3931 sig_name);
3932 goto sig_err_break;
3933 }
3934 }
3935
3936 if (sig_gen_ctx == NULL)
3937 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3938 use_params == 1 ? "RSA" : sig_name,
3939 app_get0_propq());
3940
3941 if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
3942 || (use_params &&
3943 EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
3944 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
3945 sig_name);
3946 goto sig_err_break;
3947 }
3948 if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
3949 BIO_printf(bio_err,
3950 "Error while generating signature EVP_PKEY for %s.\n",
3951 sig_name);
3952 goto sig_err_break;
3953 }
3954 /* Now prepare signature data structs */
3955 sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3956 pkey,
3957 app_get0_propq());
3958 if (sig_sign_ctx == NULL
3959 || EVP_PKEY_sign_init(sig_sign_ctx) <= 0
3960 || (use_params == 1
3961 && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx,
3962 RSA_PKCS1_PADDING) <= 0))
3963 || EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len,
3964 md, md_len) <= 0) {
3965 BIO_printf(bio_err,
3966 "Error while initializing signing data structs for %s.\n",
3967 sig_name);
3968 goto sig_err_break;
3969 }
3970 sig = app_malloc(sig_len = max_sig_len, "signature buffer");
3971 if (sig == NULL) {
3972 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
3973 goto sig_err_break;
3974 }
3975 if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
3976 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
3977 goto sig_err_break;
3978 }
3979 /* Now prepare verify data structs */
3980 memset(md, 0, SHA256_DIGEST_LENGTH);
3981 sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3982 pkey,
3983 app_get0_propq());
3984 if (sig_verify_ctx == NULL
3985 || EVP_PKEY_verify_init(sig_verify_ctx) <= 0
3986 || (use_params == 1
3987 && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx,
3988 RSA_PKCS1_PADDING) <= 0))) {
3989 BIO_printf(bio_err,
3990 "Error while initializing verify data structs for %s.\n",
3991 sig_name);
3992 goto sig_err_break;
3993 }
3994 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
3995 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
3996 goto sig_err_break;
3997 }
3998 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
3999 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4000 goto sig_err_break;
4001 }
4002 loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4003 loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4004 loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4005 loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4006 loopargs[i].sig_act_sig_len[testnum] = sig_len;
4007 loopargs[i].sig_sig[testnum] = sig;
4008 break;
4009
4010 sig_err_break:
4011 ERR_print_errors(bio_err);
4012 op_count = 1;
4013 sig_checks = 0;
4014 break;
4015 }
4016
4017 if (sig_checks != 0) {
4018 kskey_print_message(sig_name, "keygen", seconds.sig);
4019 Time_F(START);
4020 count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4021 d = Time_F(STOP);
4022 BIO_printf(bio_err,
4023 mr ? "+R18:%ld:%s:%.2f\n" :
4024 "%ld %s signature keygen ops in %.2fs\n", count,
4025 sig_name, d);
4026 sigs_results[testnum][0] = (double)count / d;
4027 op_count = count;
4028 kskey_print_message(sig_name, "signs", seconds.sig);
4029 Time_F(START);
4030 count =
4031 run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4032 d = Time_F(STOP);
4033 BIO_printf(bio_err,
4034 mr ? "+R19:%ld:%s:%.2f\n" :
4035 "%ld %s signature sign ops in %.2fs\n", count,
4036 sig_name, d);
4037 sigs_results[testnum][1] = (double)count / d;
4038 op_count = count;
4039
4040 kskey_print_message(sig_name, "verify", seconds.sig);
4041 Time_F(START);
4042 count =
4043 run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4044 d = Time_F(STOP);
4045 BIO_printf(bio_err,
4046 mr ? "+R20:%ld:%s:%.2f\n" :
4047 "%ld %s signature verify ops in %.2fs\n", count,
4048 sig_name, d);
4049 sigs_results[testnum][2] = (double)count / d;
4050 op_count = count;
4051 }
4052 if (op_count <= 1)
4053 stop_it(sigs_doit, testnum);
4054 }
4055
4056 #ifndef NO_FORK
4057 show_res:
4058 #endif
4059 if (!mr) {
4060 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4061 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4062 printf("options: %s\n", BN_options());
4063 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4064 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4065 }
4066
4067 if (pr_header) {
4068 if (mr) {
4069 printf("+H");
4070 } else {
4071 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4072 printf("type ");
4073 }
4074 for (testnum = 0; testnum < size_num; testnum++)
4075 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4076 printf("\n");
4077 }
4078
4079 for (k = 0; k < ALGOR_NUM; k++) {
4080 const char *alg_name = names[k];
4081
4082 if (!doit[k])
4083 continue;
4084
4085 if (k == D_EVP) {
4086 if (evp_cipher == NULL)
4087 alg_name = evp_md_name;
4088 else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4089 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4090 }
4091
4092 if (mr)
4093 printf("+F:%u:%s", k, alg_name);
4094 else
4095 printf("%-13s", alg_name);
4096 for (testnum = 0; testnum < size_num; testnum++) {
4097 if (results[k][testnum] > 10000 && !mr)
4098 printf(" %11.2fk", results[k][testnum] / 1e3);
4099 else
4100 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4101 }
4102 printf("\n");
4103 }
4104 testnum = 1;
4105 for (k = 0; k < RSA_NUM; k++) {
4106 if (!rsa_doit[k])
4107 continue;
4108 if (testnum && !mr) {
4109 printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " ");
4110 testnum = 0;
4111 }
4112 if (mr)
4113 printf("+F2:%u:%u:%f:%f:%f:%f\n",
4114 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4115 rsa_results[k][2], rsa_results[k][3]);
4116 else
4117 printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4118 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4119 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4120 1.0 / rsa_results[k][3],
4121 rsa_results[k][0], rsa_results[k][1],
4122 rsa_results[k][2], rsa_results[k][3]);
4123 }
4124 testnum = 1;
4125 for (k = 0; k < DSA_NUM; k++) {
4126 if (!dsa_doit[k])
4127 continue;
4128 if (testnum && !mr) {
4129 printf("%18ssign verify sign/s verify/s\n", " ");
4130 testnum = 0;
4131 }
4132 if (mr)
4133 printf("+F3:%u:%u:%f:%f\n",
4134 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4135 else
4136 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4137 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4138 dsa_results[k][0], dsa_results[k][1]);
4139 }
4140 testnum = 1;
4141 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4142 if (!ecdsa_doit[k])
4143 continue;
4144 if (testnum && !mr) {
4145 printf("%30ssign verify sign/s verify/s\n", " ");
4146 testnum = 0;
4147 }
4148
4149 if (mr)
4150 printf("+F4:%u:%u:%f:%f\n",
4151 k, ec_curves[k].bits,
4152 ecdsa_results[k][0], ecdsa_results[k][1]);
4153 else
4154 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4155 ec_curves[k].bits, ec_curves[k].name,
4156 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4157 ecdsa_results[k][0], ecdsa_results[k][1]);
4158 }
4159
4160 testnum = 1;
4161 for (k = 0; k < EC_NUM; k++) {
4162 if (!ecdh_doit[k])
4163 continue;
4164 if (testnum && !mr) {
4165 printf("%30sop op/s\n", " ");
4166 testnum = 0;
4167 }
4168 if (mr)
4169 printf("+F5:%u:%u:%f:%f\n",
4170 k, ec_curves[k].bits,
4171 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4172
4173 else
4174 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4175 ec_curves[k].bits, ec_curves[k].name,
4176 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4177 }
4178
4179 #ifndef OPENSSL_NO_ECX
4180 testnum = 1;
4181 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4182 if (!eddsa_doit[k])
4183 continue;
4184 if (testnum && !mr) {
4185 printf("%30ssign verify sign/s verify/s\n", " ");
4186 testnum = 0;
4187 }
4188
4189 if (mr)
4190 printf("+F6:%u:%u:%s:%f:%f\n",
4191 k, ed_curves[k].bits, ed_curves[k].name,
4192 eddsa_results[k][0], eddsa_results[k][1]);
4193 else
4194 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4195 ed_curves[k].bits, ed_curves[k].name,
4196 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4197 eddsa_results[k][0], eddsa_results[k][1]);
4198 }
4199 #endif /* OPENSSL_NO_ECX */
4200
4201 #ifndef OPENSSL_NO_SM2
4202 testnum = 1;
4203 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4204 if (!sm2_doit[k])
4205 continue;
4206 if (testnum && !mr) {
4207 printf("%30ssign verify sign/s verify/s\n", " ");
4208 testnum = 0;
4209 }
4210
4211 if (mr)
4212 printf("+F7:%u:%u:%s:%f:%f\n",
4213 k, sm2_curves[k].bits, sm2_curves[k].name,
4214 sm2_results[k][0], sm2_results[k][1]);
4215 else
4216 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4217 sm2_curves[k].bits, sm2_curves[k].name,
4218 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4219 sm2_results[k][0], sm2_results[k][1]);
4220 }
4221 #endif
4222 #ifndef OPENSSL_NO_DH
4223 testnum = 1;
4224 for (k = 0; k < FFDH_NUM; k++) {
4225 if (!ffdh_doit[k])
4226 continue;
4227 if (testnum && !mr) {
4228 printf("%23sop op/s\n", " ");
4229 testnum = 0;
4230 }
4231 if (mr)
4232 printf("+F8:%u:%u:%f:%f\n",
4233 k, ffdh_params[k].bits,
4234 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4235
4236 else
4237 printf("%4u bits ffdh %8.4fs %8.1f\n",
4238 ffdh_params[k].bits,
4239 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4240 }
4241 #endif /* OPENSSL_NO_DH */
4242
4243 testnum = 1;
4244 for (k = 0; k < kems_algs_len; k++) {
4245 const char *kem_name = kems_algname[k];
4246
4247 if (!kems_doit[k] || !do_kems)
4248 continue;
4249 if (testnum && !mr) {
4250 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4251 testnum = 0;
4252 }
4253 if (mr)
4254 printf("+F9:%u:%f:%f:%f\n",
4255 k, kems_results[k][0], kems_results[k][1],
4256 kems_results[k][2]);
4257 else
4258 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4259 1.0 / kems_results[k][0],
4260 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4261 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4262 }
4263 ret = 0;
4264
4265 testnum = 1;
4266 for (k = 0; k < sigs_algs_len; k++) {
4267 const char *sig_name = sigs_algname[k];
4268
4269 if (!sigs_doit[k] || !do_sigs)
4270 continue;
4271 if (testnum && !mr) {
4272 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4273 testnum = 0;
4274 }
4275 if (mr)
4276 printf("+F10:%u:%f:%f:%f\n",
4277 k, sigs_results[k][0], sigs_results[k][1],
4278 sigs_results[k][2]);
4279 else
4280 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4281 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4282 1.0 / sigs_results[k][2], sigs_results[k][0],
4283 sigs_results[k][1], sigs_results[k][2]);
4284 }
4285 ret = 0;
4286
4287 end:
4288 ERR_print_errors(bio_err);
4289 for (i = 0; i < loopargs_len; i++) {
4290 OPENSSL_free(loopargs[i].buf_malloc);
4291 OPENSSL_free(loopargs[i].buf2_malloc);
4292
4293 BN_free(bn);
4294 EVP_PKEY_CTX_free(genctx);
4295 for (k = 0; k < RSA_NUM; k++) {
4296 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4297 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4298 }
4299 #ifndef OPENSSL_NO_DH
4300 OPENSSL_free(loopargs[i].secret_ff_a);
4301 OPENSSL_free(loopargs[i].secret_ff_b);
4302 for (k = 0; k < FFDH_NUM; k++)
4303 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4304 #endif
4305 for (k = 0; k < DSA_NUM; k++) {
4306 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4307 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4308 }
4309 for (k = 0; k < ECDSA_NUM; k++) {
4310 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4311 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4312 }
4313 for (k = 0; k < EC_NUM; k++)
4314 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4315 #ifndef OPENSSL_NO_ECX
4316 for (k = 0; k < EdDSA_NUM; k++) {
4317 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4318 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4319 }
4320 #endif /* OPENSSL_NO_ECX */
4321 #ifndef OPENSSL_NO_SM2
4322 for (k = 0; k < SM2_NUM; k++) {
4323 EVP_PKEY_CTX *pctx = NULL;
4324
4325 /* free signing ctx */
4326 if (loopargs[i].sm2_ctx[k] != NULL
4327 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4328 EVP_PKEY_CTX_free(pctx);
4329 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4330 /* free verification ctx */
4331 if (loopargs[i].sm2_vfy_ctx[k] != NULL
4332 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4333 EVP_PKEY_CTX_free(pctx);
4334 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4335 /* free pkey */
4336 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4337 }
4338 #endif
4339 for (k = 0; k < kems_algs_len; k++) {
4340 EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4341 EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4342 EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4343 OPENSSL_free(loopargs[i].kem_out[k]);
4344 OPENSSL_free(loopargs[i].kem_send_secret[k]);
4345 OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4346 }
4347 for (k = 0; k < sigs_algs_len; k++) {
4348 EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4349 EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4350 EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4351 OPENSSL_free(loopargs[i].sig_sig[k]);
4352 }
4353 OPENSSL_free(loopargs[i].secret_a);
4354 OPENSSL_free(loopargs[i].secret_b);
4355 }
4356 OPENSSL_free(evp_hmac_name);
4357 OPENSSL_free(evp_cmac_name);
4358 for (k = 0; k < kems_algs_len; k++)
4359 OPENSSL_free(kems_algname[k]);
4360 if (kem_stack != NULL)
4361 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4362 for (k = 0; k < sigs_algs_len; k++)
4363 OPENSSL_free(sigs_algname[k]);
4364 if (sig_stack != NULL)
4365 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4366
4367 if (async_jobs > 0) {
4368 for (i = 0; i < loopargs_len; i++)
4369 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4370 }
4371
4372 if (async_init) {
4373 ASYNC_cleanup_thread();
4374 }
4375 OPENSSL_free(loopargs);
4376 release_engine(e);
4377 EVP_CIPHER_free(evp_cipher);
4378 EVP_MAC_free(mac);
4379 NCONF_free(conf);
4380 return ret;
4381 }
4382
4383 static void print_message(const char *s, int length, int tm)
4384 {
4385 BIO_printf(bio_err,
4386 mr ? "+DT:%s:%d:%d\n"
4387 : "Doing %s ops for %ds on %d size blocks: ", s, tm, length);
4388 (void)BIO_flush(bio_err);
4389 run = 1;
4390 alarm(tm);
4391 }
4392
4393 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4394 int tm)
4395 {
4396 BIO_printf(bio_err,
4397 mr ? "+DTP:%d:%s:%s:%d\n"
4398 : "Doing %u bits %s %s ops for %ds: ", bits, str, str2, tm);
4399 (void)BIO_flush(bio_err);
4400 run = 1;
4401 alarm(tm);
4402 }
4403
4404 static void kskey_print_message(const char *str, const char *str2, int tm)
4405 {
4406 BIO_printf(bio_err,
4407 mr ? "+DTP:%s:%s:%d\n"
4408 : "Doing %s %s ops for %ds: ", str, str2, tm);
4409 (void)BIO_flush(bio_err);
4410 run = 1;
4411 alarm(tm);
4412 }
4413
4414 static void print_result(int alg, int run_no, int count, double time_used)
4415 {
4416 if (count == -1) {
4417 BIO_printf(bio_err, "%s error!\n", names[alg]);
4418 ERR_print_errors(bio_err);
4419 return;
4420 }
4421 BIO_printf(bio_err,
4422 mr ? "+R:%d:%s:%f\n"
4423 : "%d %s ops in %.2fs\n", count, names[alg], time_used);
4424 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4425 }
4426
4427 #ifndef NO_FORK
4428 static char *sstrsep(char **string, const char *delim)
4429 {
4430 char isdelim[256];
4431 char *token = *string;
4432
4433 memset(isdelim, 0, sizeof(isdelim));
4434 isdelim[0] = 1;
4435
4436 while (*delim) {
4437 isdelim[(unsigned char)(*delim)] = 1;
4438 delim++;
4439 }
4440
4441 while (!isdelim[(unsigned char)(**string)])
4442 (*string)++;
4443
4444 if (**string) {
4445 **string = 0;
4446 (*string)++;
4447 }
4448
4449 return token;
4450 }
4451
4452 static int strtoint(const char *str, const int min_val, const int upper_val,
4453 int *res)
4454 {
4455 char *end = NULL;
4456 long int val = 0;
4457
4458 errno = 0;
4459 val = strtol(str, &end, 10);
4460 if (errno == 0 && end != str && *end == 0
4461 && min_val <= val && val < upper_val) {
4462 *res = (int)val;
4463 return 1;
4464 } else {
4465 return 0;
4466 }
4467 }
4468
4469 static int do_multi(int multi, int size_num)
4470 {
4471 int n;
4472 int fd[2];
4473 int *fds;
4474 int status;
4475 static char sep[] = ":";
4476
4477 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4478 for (n = 0; n < multi; ++n) {
4479 if (pipe(fd) == -1) {
4480 BIO_printf(bio_err, "pipe failure\n");
4481 exit(1);
4482 }
4483 fflush(stdout);
4484 (void)BIO_flush(bio_err);
4485 if (fork()) {
4486 close(fd[1]);
4487 fds[n] = fd[0];
4488 } else {
4489 close(fd[0]);
4490 close(1);
4491 if (dup(fd[1]) == -1) {
4492 BIO_printf(bio_err, "dup failed\n");
4493 exit(1);
4494 }
4495 close(fd[1]);
4496 mr = 1;
4497 usertime = 0;
4498 OPENSSL_free(fds);
4499 return 0;
4500 }
4501 printf("Forked child %d\n", n);
4502 }
4503
4504 /* for now, assume the pipe is long enough to take all the output */
4505 for (n = 0; n < multi; ++n) {
4506 FILE *f;
4507 char buf[1024];
4508 char *p;
4509 char *tk;
4510 int k;
4511 double d;
4512
4513 if ((f = fdopen(fds[n], "r")) == NULL) {
4514 BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4515 errno);
4516 OPENSSL_free(fds);
4517 return 1;
4518 }
4519 while (fgets(buf, sizeof(buf), f)) {
4520 p = strchr(buf, '\n');
4521 if (p)
4522 *p = '\0';
4523 if (buf[0] != '+') {
4524 BIO_printf(bio_err,
4525 "Don't understand line '%s' from child %d\n", buf,
4526 n);
4527 continue;
4528 }
4529 printf("Got: %s from %d\n", buf, n);
4530 p = buf;
4531 if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
4532 int alg;
4533 int j;
4534
4535 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
4536 sstrsep(&p, sep);
4537 for (j = 0; j < size_num; ++j)
4538 results[alg][j] += atof(sstrsep(&p, sep));
4539 }
4540 } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
4541 tk = sstrsep(&p, sep);
4542 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
4543 sstrsep(&p, sep);
4544
4545 d = atof(sstrsep(&p, sep));
4546 rsa_results[k][0] += d;
4547
4548 d = atof(sstrsep(&p, sep));
4549 rsa_results[k][1] += d;
4550
4551 d = atof(sstrsep(&p, sep));
4552 rsa_results[k][2] += d;
4553
4554 d = atof(sstrsep(&p, sep));
4555 rsa_results[k][3] += d;
4556 }
4557 } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
4558 tk = sstrsep(&p, sep);
4559 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
4560 sstrsep(&p, sep);
4561
4562 d = atof(sstrsep(&p, sep));
4563 dsa_results[k][0] += d;
4564
4565 d = atof(sstrsep(&p, sep));
4566 dsa_results[k][1] += d;
4567 }
4568 } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
4569 tk = sstrsep(&p, sep);
4570 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
4571 sstrsep(&p, sep);
4572
4573 d = atof(sstrsep(&p, sep));
4574 ecdsa_results[k][0] += d;
4575
4576 d = atof(sstrsep(&p, sep));
4577 ecdsa_results[k][1] += d;
4578 }
4579 } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
4580 tk = sstrsep(&p, sep);
4581 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
4582 sstrsep(&p, sep);
4583
4584 d = atof(sstrsep(&p, sep));
4585 ecdh_results[k][0] += d;
4586 }
4587 # ifndef OPENSSL_NO_ECX
4588 } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
4589 tk = sstrsep(&p, sep);
4590 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
4591 sstrsep(&p, sep);
4592 sstrsep(&p, sep);
4593
4594 d = atof(sstrsep(&p, sep));
4595 eddsa_results[k][0] += d;
4596
4597 d = atof(sstrsep(&p, sep));
4598 eddsa_results[k][1] += d;
4599 }
4600 # endif /* OPENSSL_NO_ECX */
4601 # ifndef OPENSSL_NO_SM2
4602 } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
4603 tk = sstrsep(&p, sep);
4604 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
4605 sstrsep(&p, sep);
4606 sstrsep(&p, sep);
4607
4608 d = atof(sstrsep(&p, sep));
4609 sm2_results[k][0] += d;
4610
4611 d = atof(sstrsep(&p, sep));
4612 sm2_results[k][1] += d;
4613 }
4614 # endif /* OPENSSL_NO_SM2 */
4615 # ifndef OPENSSL_NO_DH
4616 } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
4617 tk = sstrsep(&p, sep);
4618 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
4619 sstrsep(&p, sep);
4620
4621 d = atof(sstrsep(&p, sep));
4622 ffdh_results[k][0] += d;
4623 }
4624 # endif /* OPENSSL_NO_DH */
4625 } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
4626 tk = sstrsep(&p, sep);
4627 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
4628 d = atof(sstrsep(&p, sep));
4629 kems_results[k][0] += d;
4630
4631 d = atof(sstrsep(&p, sep));
4632 kems_results[k][1] += d;
4633
4634 d = atof(sstrsep(&p, sep));
4635 kems_results[k][2] += d;
4636 }
4637 } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
4638 tk = sstrsep(&p, sep);
4639 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
4640 d = atof(sstrsep(&p, sep));
4641 sigs_results[k][0] += d;
4642
4643 d = atof(sstrsep(&p, sep));
4644 sigs_results[k][1] += d;
4645
4646 d = atof(sstrsep(&p, sep));
4647 sigs_results[k][2] += d;
4648 }
4649 } else if (!HAS_PREFIX(buf, "+H:")) {
4650 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
4651 n);
4652 }
4653 }
4654
4655 fclose(f);
4656 }
4657 OPENSSL_free(fds);
4658 for (n = 0; n < multi; ++n) {
4659 while (wait(&status) == -1)
4660 if (errno != EINTR) {
4661 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
4662 errno);
4663 return 1;
4664 }
4665 if (WIFEXITED(status) && WEXITSTATUS(status)) {
4666 BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
4667 } else if (WIFSIGNALED(status)) {
4668 BIO_printf(bio_err, "Child terminated by signal %d\n",
4669 WTERMSIG(status));
4670 }
4671 }
4672 return 1;
4673 }
4674 #endif
4675
4676 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
4677 const openssl_speed_sec_t *seconds)
4678 {
4679 static const int mblengths_list[] =
4680 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
4681 const int *mblengths = mblengths_list;
4682 int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
4683 const char *alg_name;
4684 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
4685 EVP_CIPHER_CTX *ctx = NULL;
4686 double d = 0.0;
4687
4688 if (lengths_single) {
4689 mblengths = &lengths_single;
4690 num = 1;
4691 }
4692
4693 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
4694 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
4695 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
4696 app_bail_out("failed to allocate cipher context\n");
4697 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
4698 app_bail_out("failed to initialise cipher context\n");
4699
4700 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
4701 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
4702 goto err;
4703 }
4704 key = app_malloc(keylen, "evp_cipher key");
4705 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
4706 app_bail_out("failed to generate random cipher key\n");
4707 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
4708 app_bail_out("failed to set cipher key\n");
4709 OPENSSL_clear_free(key, keylen);
4710
4711 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
4712 sizeof(no_key), no_key) <= 0)
4713 app_bail_out("failed to set AEAD key\n");
4714 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4715 app_bail_out("failed to get cipher name\n");
4716
4717 for (j = 0; j < num; j++) {
4718 print_message(alg_name, mblengths[j], seconds->sym);
4719 Time_F(START);
4720 for (count = 0; run && count < INT_MAX; count++) {
4721 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
4722 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
4723 size_t len = mblengths[j];
4724 int packlen;
4725
4726 memset(aad, 0, 8); /* avoid uninitialized values */
4727 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
4728 aad[9] = 3; /* version */
4729 aad[10] = 2;
4730 aad[11] = 0; /* length */
4731 aad[12] = 0;
4732 mb_param.out = NULL;
4733 mb_param.inp = aad;
4734 mb_param.len = len;
4735 mb_param.interleave = 8;
4736
4737 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
4738 sizeof(mb_param), &mb_param);
4739
4740 if (packlen > 0) {
4741 mb_param.out = out;
4742 mb_param.inp = inp;
4743 mb_param.len = len;
4744 (void)EVP_CIPHER_CTX_ctrl(ctx,
4745 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
4746 sizeof(mb_param), &mb_param);
4747 } else {
4748 int pad;
4749
4750 RAND_bytes(out, 16);
4751 len += 16;
4752 aad[11] = (unsigned char)(len >> 8);
4753 aad[12] = (unsigned char)(len);
4754 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
4755 EVP_AEAD_TLS1_AAD_LEN, aad);
4756 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
4757 }
4758 }
4759 d = Time_F(STOP);
4760 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
4761 : "%d %s ops in %.2fs\n", count, "evp", d);
4762 if ((ciph_success <= 0) && (mr == 0))
4763 BIO_printf(bio_err, "Error performing cipher op\n");
4764 results[D_EVP][j] = ((double)count) / d * mblengths[j];
4765 }
4766
4767 if (mr) {
4768 fprintf(stdout, "+H");
4769 for (j = 0; j < num; j++)
4770 fprintf(stdout, ":%d", mblengths[j]);
4771 fprintf(stdout, "\n");
4772 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
4773 for (j = 0; j < num; j++)
4774 fprintf(stdout, ":%.2f", results[D_EVP][j]);
4775 fprintf(stdout, "\n");
4776 } else {
4777 fprintf(stdout,
4778 "The 'numbers' are in 1000s of bytes per second processed.\n");
4779 fprintf(stdout, "type ");
4780 for (j = 0; j < num; j++)
4781 fprintf(stdout, "%7d bytes", mblengths[j]);
4782 fprintf(stdout, "\n");
4783 fprintf(stdout, "%-24s", alg_name);
4784
4785 for (j = 0; j < num; j++) {
4786 if (results[D_EVP][j] > 10000)
4787 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
4788 else
4789 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
4790 }
4791 fprintf(stdout, "\n");
4792 }
4793
4794 err:
4795 OPENSSL_free(inp);
4796 OPENSSL_free(out);
4797 EVP_CIPHER_CTX_free(ctx);
4798 }