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