1 /*
2 * Copyright 1995-2025 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 BIO_printf(bio_err, "\nFailed to get the tag\n");
3144 dofail();
3145 exit(1);
3146 }
3147
3148 EVP_CIPHER_CTX_free(loopargs[k].ctx);
3149 loopargs[k].ctx = EVP_CIPHER_CTX_new();
3150 if (loopargs[k].ctx == NULL) {
3151 BIO_printf(bio_err,
3152 "\nEVP_CIPHER_CTX_new failure\n");
3153 exit(1);
3154 }
3155 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher,
3156 NULL, NULL, NULL, 0)) {
3157 BIO_printf(bio_err,
3158 "\nFailed initializing the context\n");
3159 dofail();
3160 exit(1);
3161 }
3162
3163 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
3164
3165 /* GCM-SIV/SIV only allows for a single Update operation */
3166 if (mode_op == EVP_CIPH_SIV_MODE
3167 || mode_op == EVP_CIPH_GCM_SIV_MODE)
3168 EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
3169 EVP_CTRL_SET_SPEED, 1, NULL);
3170 }
3171 }
3172
3173 Time_F(START);
3174 count = run_benchmark(async_jobs, loopfunc, loopargs);
3175 d = Time_F(STOP);
3176 for (k = 0; k < loopargs_len; k++) {
3177 OPENSSL_clear_free(loopargs[k].key, keylen);
3178 EVP_CIPHER_CTX_free(loopargs[k].ctx);
3179 }
3180 print_result(D_EVP, testnum, count, d);
3181 }
3182 } else if (evp_md_name != NULL) {
3183 names[D_EVP] = evp_md_name;
3184
3185 for (testnum = 0; testnum < size_num; testnum++) {
3186 print_message(names[D_EVP], lengths[testnum], seconds.sym);
3187 Time_F(START);
3188 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
3189 d = Time_F(STOP);
3190 print_result(D_EVP, testnum, count, d);
3191 if (count < 0)
3192 break;
3193 }
3194 }
3195 }
3196
3197 if (doit[D_EVP_CMAC]) {
3198 size_t len = sizeof("cmac()") + strlen(evp_mac_ciphername);
3199 OSSL_PARAM params[3];
3200 EVP_CIPHER *cipher = NULL;
3201
3202 if (!opt_cipher(evp_mac_ciphername, &cipher))
3203 goto end;
3204
3205 keylen = EVP_CIPHER_get_key_length(cipher);
3206 EVP_CIPHER_free(cipher);
3207 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
3208 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
3209 goto end;
3210 }
3211 evp_cmac_name = app_malloc(len, "CMAC name");
3212 BIO_snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername);
3213 names[D_EVP_CMAC] = evp_cmac_name;
3214
3215 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
3216 evp_mac_ciphername, 0);
3217 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3218 (char *)key32, keylen);
3219 params[2] = OSSL_PARAM_construct_end();
3220
3221 if (mac_setup("CMAC", &mac, params, loopargs, loopargs_len) < 1)
3222 goto end;
3223 for (testnum = 0; testnum < size_num; testnum++) {
3224 print_message(names[D_EVP_CMAC], lengths[testnum], seconds.sym);
3225 Time_F(START);
3226 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
3227 d = Time_F(STOP);
3228 print_result(D_EVP_CMAC, testnum, count, d);
3229 if (count < 0)
3230 break;
3231 }
3232 mac_teardown(&mac, loopargs, loopargs_len);
3233 }
3234
3235 if (doit[D_KMAC128]) {
3236 OSSL_PARAM params[2];
3237
3238 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3239 (void *)key32, 16);
3240 params[1] = OSSL_PARAM_construct_end();
3241
3242 if (mac_setup("KMAC-128", &mac, params, loopargs, loopargs_len) < 1)
3243 goto end;
3244 for (testnum = 0; testnum < size_num; testnum++) {
3245 print_message(names[D_KMAC128], lengths[testnum], seconds.sym);
3246 Time_F(START);
3247 count = run_benchmark(async_jobs, KMAC128_loop, loopargs);
3248 d = Time_F(STOP);
3249 print_result(D_KMAC128, testnum, count, d);
3250 if (count < 0)
3251 break;
3252 }
3253 mac_teardown(&mac, loopargs, loopargs_len);
3254 }
3255
3256 if (doit[D_KMAC256]) {
3257 OSSL_PARAM params[2];
3258
3259 params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
3260 (void *)key32, 32);
3261 params[1] = OSSL_PARAM_construct_end();
3262
3263 if (mac_setup("KMAC-256", &mac, params, loopargs, loopargs_len) < 1)
3264 goto end;
3265 for (testnum = 0; testnum < size_num; testnum++) {
3266 print_message(names[D_KMAC256], lengths[testnum], seconds.sym);
3267 Time_F(START);
3268 count = run_benchmark(async_jobs, KMAC256_loop, loopargs);
3269 d = Time_F(STOP);
3270 print_result(D_KMAC256, testnum, count, d);
3271 if (count < 0)
3272 break;
3273 }
3274 mac_teardown(&mac, loopargs, loopargs_len);
3275 }
3276
3277 for (i = 0; i < loopargs_len; i++)
3278 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
3279 goto end;
3280
3281 for (testnum = 0; testnum < RSA_NUM; testnum++) {
3282 EVP_PKEY *rsa_key = NULL;
3283 int st = 0;
3284
3285 if (!rsa_doit[testnum])
3286 continue;
3287
3288 if (primes > RSA_DEFAULT_PRIME_NUM) {
3289 /* we haven't set keys yet, generate multi-prime RSA keys */
3290 bn = BN_new();
3291 st = bn != NULL
3292 && BN_set_word(bn, RSA_F4)
3293 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
3294 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
3295 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
3296 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
3297 && EVP_PKEY_keygen(genctx, &rsa_key) > 0;
3298 BN_free(bn);
3299 bn = NULL;
3300 EVP_PKEY_CTX_free(genctx);
3301 genctx = NULL;
3302 } else {
3303 const unsigned char *p = rsa_keys[testnum].data;
3304
3305 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
3306 rsa_keys[testnum].length))
3307 != NULL;
3308 }
3309
3310 for (i = 0; st && i < loopargs_len; i++) {
3311 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3312 loopargs[i].sigsize = loopargs[i].buflen;
3313 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
3314 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
3315 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
3316 loopargs[i].buf2,
3317 &loopargs[i].sigsize,
3318 loopargs[i].buf, 36)
3319 <= 0)
3320 st = 0;
3321 }
3322 if (!st) {
3323 BIO_printf(bio_err,
3324 "RSA sign setup failure. No RSA sign will be done.\n");
3325 dofail();
3326 op_count = 1;
3327 } else {
3328 pkey_print_message("private", "rsa sign",
3329 rsa_keys[testnum].bits, seconds.rsa);
3330 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3331 Time_F(START);
3332 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
3333 d = Time_F(STOP);
3334 BIO_printf(bio_err,
3335 mr ? "+R1:%ld:%d:%.2f\n"
3336 : "%ld %u bits private RSA sign ops in %.2fs\n",
3337 count, rsa_keys[testnum].bits, d);
3338 rsa_results[testnum][0] = (double)count / d;
3339 op_count = count;
3340 }
3341
3342 for (i = 0; st && i < loopargs_len; i++) {
3343 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
3344 NULL);
3345 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
3346 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
3347 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
3348 loopargs[i].buf2,
3349 loopargs[i].sigsize,
3350 loopargs[i].buf, 36)
3351 <= 0)
3352 st = 0;
3353 }
3354 if (!st) {
3355 BIO_printf(bio_err,
3356 "RSA verify setup failure. No RSA verify will be done.\n");
3357 dofail();
3358 rsa_doit[testnum] = 0;
3359 } else {
3360 pkey_print_message("public", "rsa verify",
3361 rsa_keys[testnum].bits, seconds.rsa);
3362 Time_F(START);
3363 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
3364 d = Time_F(STOP);
3365 BIO_printf(bio_err,
3366 mr ? "+R2:%ld:%d:%.2f\n"
3367 : "%ld %u bits public RSA verify ops in %.2fs\n",
3368 count, rsa_keys[testnum].bits, d);
3369 rsa_results[testnum][1] = (double)count / d;
3370 }
3371
3372 for (i = 0; st && i < loopargs_len; i++) {
3373 loopargs[i].rsa_encrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3374 loopargs[i].encsize = loopargs[i].buflen;
3375 if (loopargs[i].rsa_encrypt_ctx[testnum] == NULL
3376 || EVP_PKEY_encrypt_init(loopargs[i].rsa_encrypt_ctx[testnum]) <= 0
3377 || EVP_PKEY_encrypt(loopargs[i].rsa_encrypt_ctx[testnum],
3378 loopargs[i].buf2,
3379 &loopargs[i].encsize,
3380 loopargs[i].buf, 36)
3381 <= 0)
3382 st = 0;
3383 }
3384 if (!st) {
3385 BIO_printf(bio_err,
3386 "RSA encrypt setup failure. No RSA encrypt will be done.\n");
3387 dofail();
3388 op_count = 1;
3389 } else {
3390 pkey_print_message("public", "rsa encrypt",
3391 rsa_keys[testnum].bits, seconds.rsa);
3392 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3393 Time_F(START);
3394 count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
3395 d = Time_F(STOP);
3396 BIO_printf(bio_err,
3397 mr ? "+R3:%ld:%d:%.2f\n"
3398 : "%ld %u bits public RSA encrypt ops in %.2fs\n",
3399 count, rsa_keys[testnum].bits, d);
3400 rsa_results[testnum][2] = (double)count / d;
3401 op_count = count;
3402 }
3403
3404 for (i = 0; st && i < loopargs_len; i++) {
3405 loopargs[i].rsa_decrypt_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
3406 declen = loopargs[i].buflen;
3407 if (loopargs[i].rsa_decrypt_ctx[testnum] == NULL
3408 || EVP_PKEY_decrypt_init(loopargs[i].rsa_decrypt_ctx[testnum]) <= 0
3409 || EVP_PKEY_decrypt(loopargs[i].rsa_decrypt_ctx[testnum],
3410 loopargs[i].buf,
3411 &declen,
3412 loopargs[i].buf2,
3413 loopargs[i].encsize)
3414 <= 0)
3415 st = 0;
3416 }
3417 if (!st) {
3418 BIO_printf(bio_err,
3419 "RSA decrypt setup failure. No RSA decrypt will be done.\n");
3420 dofail();
3421 op_count = 1;
3422 } else {
3423 pkey_print_message("private", "rsa decrypt",
3424 rsa_keys[testnum].bits, seconds.rsa);
3425 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3426 Time_F(START);
3427 count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
3428 d = Time_F(STOP);
3429 BIO_printf(bio_err,
3430 mr ? "+R4:%ld:%d:%.2f\n"
3431 : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3432 count, rsa_keys[testnum].bits, d);
3433 rsa_results[testnum][3] = (double)count / d;
3434 op_count = count;
3435 }
3436
3437 if (op_count <= 1) {
3438 /* if longer than 10s, don't do any more */
3439 stop_it(rsa_doit, testnum);
3440 }
3441 EVP_PKEY_free(rsa_key);
3442 }
3443
3444 #ifndef OPENSSL_NO_DSA
3445 for (testnum = 0; testnum < DSA_NUM; testnum++) {
3446 EVP_PKEY *dsa_key = NULL;
3447 int st;
3448
3449 if (!dsa_doit[testnum])
3450 continue;
3451
3452 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
3453
3454 for (i = 0; st && i < loopargs_len; i++) {
3455 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3456 NULL);
3457 loopargs[i].sigsize = loopargs[i].buflen;
3458 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
3459 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
3460 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
3461 loopargs[i].buf2,
3462 &loopargs[i].sigsize,
3463 loopargs[i].buf, 20)
3464 <= 0)
3465 st = 0;
3466 }
3467 if (!st) {
3468 BIO_printf(bio_err,
3469 "DSA sign setup failure. No DSA sign will be done.\n");
3470 dofail();
3471 op_count = 1;
3472 } else {
3473 pkey_print_message("sign", "dsa",
3474 dsa_bits[testnum], seconds.dsa);
3475 Time_F(START);
3476 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
3477 d = Time_F(STOP);
3478 BIO_printf(bio_err,
3479 mr ? "+R5:%ld:%u:%.2f\n"
3480 : "%ld %u bits DSA sign ops in %.2fs\n",
3481 count, dsa_bits[testnum], d);
3482 dsa_results[testnum][0] = (double)count / d;
3483 op_count = count;
3484 }
3485
3486 for (i = 0; st && i < loopargs_len; i++) {
3487 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
3488 NULL);
3489 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
3490 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
3491 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
3492 loopargs[i].buf2,
3493 loopargs[i].sigsize,
3494 loopargs[i].buf, 36)
3495 <= 0)
3496 st = 0;
3497 }
3498 if (!st) {
3499 BIO_printf(bio_err,
3500 "DSA verify setup failure. No DSA verify will be done.\n");
3501 dofail();
3502 dsa_doit[testnum] = 0;
3503 } else {
3504 pkey_print_message("verify", "dsa",
3505 dsa_bits[testnum], seconds.dsa);
3506 Time_F(START);
3507 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
3508 d = Time_F(STOP);
3509 BIO_printf(bio_err,
3510 mr ? "+R6:%ld:%u:%.2f\n"
3511 : "%ld %u bits DSA verify ops in %.2fs\n",
3512 count, dsa_bits[testnum], d);
3513 dsa_results[testnum][1] = (double)count / d;
3514 }
3515
3516 if (op_count <= 1) {
3517 /* if longer than 10s, don't do any more */
3518 stop_it(dsa_doit, testnum);
3519 }
3520 EVP_PKEY_free(dsa_key);
3521 }
3522 #endif /* OPENSSL_NO_DSA */
3523
3524 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
3525 EVP_PKEY *ecdsa_key = NULL;
3526 int st;
3527
3528 if (!ecdsa_doit[testnum])
3529 continue;
3530
3531 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
3532
3533 for (i = 0; st && i < loopargs_len; i++) {
3534 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3535 NULL);
3536 loopargs[i].sigsize = loopargs[i].buflen;
3537 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
3538 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
3539 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
3540 loopargs[i].buf2,
3541 &loopargs[i].sigsize,
3542 loopargs[i].buf, 20)
3543 <= 0)
3544 st = 0;
3545 }
3546 if (!st) {
3547 BIO_printf(bio_err,
3548 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
3549 dofail();
3550 op_count = 1;
3551 } else {
3552 pkey_print_message("sign", "ecdsa",
3553 ec_curves[testnum].bits, seconds.ecdsa);
3554 Time_F(START);
3555 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
3556 d = Time_F(STOP);
3557 BIO_printf(bio_err,
3558 mr ? "+R7:%ld:%u:%.2f\n"
3559 : "%ld %u bits ECDSA sign ops in %.2fs\n",
3560 count, ec_curves[testnum].bits, d);
3561 ecdsa_results[testnum][0] = (double)count / d;
3562 op_count = count;
3563 }
3564
3565 for (i = 0; st && i < loopargs_len; i++) {
3566 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
3567 NULL);
3568 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
3569 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
3570 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
3571 loopargs[i].buf2,
3572 loopargs[i].sigsize,
3573 loopargs[i].buf, 20)
3574 <= 0)
3575 st = 0;
3576 }
3577 if (!st) {
3578 BIO_printf(bio_err,
3579 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3580 dofail();
3581 ecdsa_doit[testnum] = 0;
3582 } else {
3583 pkey_print_message("verify", "ecdsa",
3584 ec_curves[testnum].bits, seconds.ecdsa);
3585 Time_F(START);
3586 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
3587 d = Time_F(STOP);
3588 BIO_printf(bio_err,
3589 mr ? "+R8:%ld:%u:%.2f\n"
3590 : "%ld %u bits ECDSA verify ops in %.2fs\n",
3591 count, ec_curves[testnum].bits, d);
3592 ecdsa_results[testnum][1] = (double)count / d;
3593 }
3594
3595 if (op_count <= 1) {
3596 /* if longer than 10s, don't do any more */
3597 stop_it(ecdsa_doit, testnum);
3598 }
3599 EVP_PKEY_free(ecdsa_key);
3600 }
3601
3602 for (testnum = 0; testnum < EC_NUM; testnum++) {
3603 int ecdh_checks = 1;
3604
3605 if (!ecdh_doit[testnum])
3606 continue;
3607
3608 for (i = 0; i < loopargs_len; i++) {
3609 EVP_PKEY_CTX *test_ctx = NULL;
3610 EVP_PKEY_CTX *ctx = NULL;
3611 EVP_PKEY *key_A = NULL;
3612 EVP_PKEY *key_B = NULL;
3613 size_t outlen;
3614 size_t test_outlen;
3615
3616 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
3617 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
3618 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
3619 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
3620 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
3621 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
3622 || outlen == 0 /* ensure outlen is a valid size */
3623 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
3624 ecdh_checks = 0;
3625 BIO_printf(bio_err, "ECDH key generation failure.\n");
3626 dofail();
3627 op_count = 1;
3628 break;
3629 }
3630
3631 /*
3632 * Here we perform a test run, comparing the output of a*B and b*A;
3633 * we try this here and assume that further EVP_PKEY_derive calls
3634 * never fail, so we can skip checks in the actually benchmarked
3635 * code, for maximum performance.
3636 */
3637 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
3638 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
3639 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
3640 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
3641 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
3642 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
3643 || test_outlen != outlen /* compare output length */) {
3644 ecdh_checks = 0;
3645 BIO_printf(bio_err, "ECDH computation failure.\n");
3646 dofail();
3647 op_count = 1;
3648 break;
3649 }
3650
3651 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3652 if (CRYPTO_memcmp(loopargs[i].secret_a,
3653 loopargs[i].secret_b, outlen)) {
3654 ecdh_checks = 0;
3655 BIO_printf(bio_err, "ECDH computations don't match.\n");
3656 dofail();
3657 op_count = 1;
3658 break;
3659 }
3660
3661 loopargs[i].ecdh_ctx[testnum] = ctx;
3662 loopargs[i].outlen[testnum] = outlen;
3663
3664 EVP_PKEY_free(key_A);
3665 EVP_PKEY_free(key_B);
3666 EVP_PKEY_CTX_free(test_ctx);
3667 test_ctx = NULL;
3668 }
3669 if (ecdh_checks != 0) {
3670 pkey_print_message("", "ecdh",
3671 ec_curves[testnum].bits, seconds.ecdh);
3672 Time_F(START);
3673 count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
3674 d = Time_F(STOP);
3675 BIO_printf(bio_err,
3676 mr ? "+R9:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count,
3677 ec_curves[testnum].bits, d);
3678 ecdh_results[testnum][0] = (double)count / d;
3679 op_count = count;
3680 }
3681
3682 if (op_count <= 1) {
3683 /* if longer than 10s, don't do any more */
3684 stop_it(ecdh_doit, testnum);
3685 }
3686 }
3687
3688 #ifndef OPENSSL_NO_ECX
3689 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
3690 int st = 1;
3691 EVP_PKEY *ed_pkey = NULL;
3692 EVP_PKEY_CTX *ed_pctx = NULL;
3693
3694 if (!eddsa_doit[testnum])
3695 continue; /* Ignore Curve */
3696 for (i = 0; i < loopargs_len; i++) {
3697 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
3698 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
3699 st = 0;
3700 break;
3701 }
3702 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
3703 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
3704 st = 0;
3705 break;
3706 }
3707
3708 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
3709 NULL))
3710 == NULL
3711 || EVP_PKEY_keygen_init(ed_pctx) <= 0
3712 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
3713 st = 0;
3714 EVP_PKEY_CTX_free(ed_pctx);
3715 break;
3716 }
3717 EVP_PKEY_CTX_free(ed_pctx);
3718
3719 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
3720 NULL, ed_pkey)) {
3721 st = 0;
3722 EVP_PKEY_free(ed_pkey);
3723 break;
3724 }
3725 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
3726 NULL, NULL, ed_pkey)) {
3727 st = 0;
3728 EVP_PKEY_free(ed_pkey);
3729 break;
3730 }
3731
3732 EVP_PKEY_free(ed_pkey);
3733 ed_pkey = NULL;
3734 }
3735 if (st == 0) {
3736 BIO_printf(bio_err, "EdDSA failure.\n");
3737 dofail();
3738 op_count = 1;
3739 } else {
3740 for (i = 0; i < loopargs_len; i++) {
3741 /* Perform EdDSA signature test */
3742 loopargs[i].sigsize = ed_curves[testnum].sigsize;
3743 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
3744 loopargs[i].buf2, &loopargs[i].sigsize,
3745 loopargs[i].buf, 20);
3746 if (st == 0)
3747 break;
3748 }
3749 if (st == 0) {
3750 BIO_printf(bio_err,
3751 "EdDSA sign failure. No EdDSA sign will be done.\n");
3752 dofail();
3753 op_count = 1;
3754 } else {
3755 pkey_print_message("sign", ed_curves[testnum].name,
3756 ed_curves[testnum].bits, seconds.eddsa);
3757 Time_F(START);
3758 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
3759 d = Time_F(STOP);
3760
3761 BIO_printf(bio_err,
3762 mr ? "+R10:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3763 count, ed_curves[testnum].bits,
3764 ed_curves[testnum].name, d);
3765 eddsa_results[testnum][0] = (double)count / d;
3766 op_count = count;
3767 }
3768 /* Perform EdDSA verification test */
3769 for (i = 0; i < loopargs_len; i++) {
3770 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
3771 loopargs[i].buf2, loopargs[i].sigsize,
3772 loopargs[i].buf, 20);
3773 if (st != 1)
3774 break;
3775 }
3776 if (st != 1) {
3777 BIO_printf(bio_err,
3778 "EdDSA verify failure. No EdDSA verify will be done.\n");
3779 dofail();
3780 eddsa_doit[testnum] = 0;
3781 } else {
3782 pkey_print_message("verify", ed_curves[testnum].name,
3783 ed_curves[testnum].bits, seconds.eddsa);
3784 Time_F(START);
3785 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
3786 d = Time_F(STOP);
3787 BIO_printf(bio_err,
3788 mr ? "+R11:%ld:%u:%s:%.2f\n"
3789 : "%ld %u bits %s verify ops in %.2fs\n",
3790 count, ed_curves[testnum].bits,
3791 ed_curves[testnum].name, d);
3792 eddsa_results[testnum][1] = (double)count / d;
3793 }
3794
3795 if (op_count <= 1) {
3796 /* if longer than 10s, don't do any more */
3797 stop_it(eddsa_doit, testnum);
3798 }
3799 }
3800 }
3801 #endif /* OPENSSL_NO_ECX */
3802
3803 #ifndef OPENSSL_NO_SM2
3804 for (testnum = 0; testnum < SM2_NUM; testnum++) {
3805 int st = 1;
3806 EVP_PKEY *sm2_pkey = NULL;
3807
3808 if (!sm2_doit[testnum])
3809 continue; /* Ignore Curve */
3810 /* Init signing and verification */
3811 for (i = 0; i < loopargs_len; i++) {
3812 EVP_PKEY_CTX *sm2_pctx = NULL;
3813 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
3814 EVP_PKEY_CTX *pctx = NULL;
3815 st = 0;
3816
3817 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
3818 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
3819 if (loopargs[i].sm2_ctx[testnum] == NULL
3820 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
3821 break;
3822
3823 sm2_pkey = NULL;
3824
3825 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
3826 || EVP_PKEY_keygen_init(pctx) <= 0
3827 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
3828 sm2_curves[testnum].nid)
3829 <= 0
3830 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
3831 EVP_PKEY_CTX_free(pctx);
3832 if (st == 0)
3833 break;
3834
3835 st = 0; /* set back to zero */
3836 /* attach it sooner to rely on main final cleanup */
3837 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
3838 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
3839
3840 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3841 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
3842 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
3843 EVP_PKEY_CTX_free(sm2_vfy_pctx);
3844 break;
3845 }
3846
3847 /* attach them directly to respective ctx */
3848 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
3849 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
3850
3851 /*
3852 * No need to allow user to set an explicit ID here, just use
3853 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3854 */
3855 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
3856 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
3857 break;
3858
3859 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
3860 EVP_sm3(), NULL, sm2_pkey))
3861 break;
3862 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
3863 EVP_sm3(), NULL, sm2_pkey))
3864 break;
3865 st = 1; /* mark loop as succeeded */
3866 }
3867 if (st == 0) {
3868 BIO_printf(bio_err, "SM2 init failure.\n");
3869 dofail();
3870 op_count = 1;
3871 } else {
3872 for (i = 0; i < loopargs_len; i++) {
3873 /* Perform SM2 signature test */
3874 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
3875 loopargs[i].buf2, &loopargs[i].sigsize,
3876 loopargs[i].buf, 20);
3877 if (st == 0)
3878 break;
3879 }
3880 if (st == 0) {
3881 BIO_printf(bio_err,
3882 "SM2 sign failure. No SM2 sign will be done.\n");
3883 dofail();
3884 op_count = 1;
3885 } else {
3886 pkey_print_message("sign", sm2_curves[testnum].name,
3887 sm2_curves[testnum].bits, seconds.sm2);
3888 Time_F(START);
3889 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
3890 d = Time_F(STOP);
3891
3892 BIO_printf(bio_err,
3893 mr ? "+R12:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
3894 count, sm2_curves[testnum].bits,
3895 sm2_curves[testnum].name, d);
3896 sm2_results[testnum][0] = (double)count / d;
3897 op_count = count;
3898 }
3899
3900 /* Perform SM2 verification test */
3901 for (i = 0; i < loopargs_len; i++) {
3902 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
3903 loopargs[i].buf2, loopargs[i].sigsize,
3904 loopargs[i].buf, 20);
3905 if (st != 1)
3906 break;
3907 }
3908 if (st != 1) {
3909 BIO_printf(bio_err,
3910 "SM2 verify failure. No SM2 verify will be done.\n");
3911 dofail();
3912 sm2_doit[testnum] = 0;
3913 } else {
3914 pkey_print_message("verify", sm2_curves[testnum].name,
3915 sm2_curves[testnum].bits, seconds.sm2);
3916 Time_F(START);
3917 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
3918 d = Time_F(STOP);
3919 BIO_printf(bio_err,
3920 mr ? "+R13:%ld:%u:%s:%.2f\n"
3921 : "%ld %u bits %s verify ops in %.2fs\n",
3922 count, sm2_curves[testnum].bits,
3923 sm2_curves[testnum].name, d);
3924 sm2_results[testnum][1] = (double)count / d;
3925 }
3926
3927 if (op_count <= 1) {
3928 /* if longer than 10s, don't do any more */
3929 for (testnum++; testnum < SM2_NUM; testnum++)
3930 sm2_doit[testnum] = 0;
3931 }
3932 }
3933 }
3934 #endif /* OPENSSL_NO_SM2 */
3935
3936 #ifndef OPENSSL_NO_DH
3937 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
3938 int ffdh_checks = 1;
3939
3940 if (!ffdh_doit[testnum])
3941 continue;
3942
3943 for (i = 0; i < loopargs_len; i++) {
3944 EVP_PKEY *pkey_A = NULL;
3945 EVP_PKEY *pkey_B = NULL;
3946 EVP_PKEY_CTX *ffdh_ctx = NULL;
3947 EVP_PKEY_CTX *test_ctx = NULL;
3948 size_t secret_size;
3949 size_t test_out;
3950
3951 /* Ensure that the error queue is empty */
3952 if (ERR_peek_error()) {
3953 BIO_printf(bio_err,
3954 "WARNING: the error queue contains previous unhandled errors.\n");
3955 dofail();
3956 }
3957
3958 pkey_A = EVP_PKEY_new();
3959 if (!pkey_A) {
3960 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3961 dofail();
3962 op_count = 1;
3963 ffdh_checks = 0;
3964 break;
3965 }
3966 pkey_B = EVP_PKEY_new();
3967 if (!pkey_B) {
3968 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3969 dofail();
3970 op_count = 1;
3971 ffdh_checks = 0;
3972 break;
3973 }
3974
3975 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3976 if (!ffdh_ctx) {
3977 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3978 dofail();
3979 op_count = 1;
3980 ffdh_checks = 0;
3981 break;
3982 }
3983
3984 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3985 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3986 dofail();
3987 op_count = 1;
3988 ffdh_checks = 0;
3989 break;
3990 }
3991 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3992 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3993 dofail();
3994 op_count = 1;
3995 ffdh_checks = 0;
3996 break;
3997 }
3998
3999 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
4000 BIO_printf(bio_err, "FFDH key generation failure.\n");
4001 dofail();
4002 op_count = 1;
4003 ffdh_checks = 0;
4004 break;
4005 }
4006
4007 EVP_PKEY_CTX_free(ffdh_ctx);
4008
4009 /*
4010 * check if the derivation works correctly both ways so that
4011 * we know if future derive calls will fail, and we can skip
4012 * error checking in benchmarked code
4013 */
4014 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
4015 if (ffdh_ctx == NULL) {
4016 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4017 dofail();
4018 op_count = 1;
4019 ffdh_checks = 0;
4020 break;
4021 }
4022 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
4023 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
4024 dofail();
4025 op_count = 1;
4026 ffdh_checks = 0;
4027 break;
4028 }
4029 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
4030 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
4031 dofail();
4032 op_count = 1;
4033 ffdh_checks = 0;
4034 break;
4035 }
4036 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
4037 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
4038 dofail();
4039 op_count = 1;
4040 ffdh_checks = 0;
4041 break;
4042 }
4043 if (secret_size > MAX_FFDH_SIZE) {
4044 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
4045 op_count = 1;
4046 ffdh_checks = 0;
4047 break;
4048 }
4049 if (EVP_PKEY_derive(ffdh_ctx,
4050 loopargs[i].secret_ff_a,
4051 &secret_size)
4052 <= 0) {
4053 BIO_printf(bio_err, "Shared secret derive failure.\n");
4054 dofail();
4055 op_count = 1;
4056 ffdh_checks = 0;
4057 break;
4058 }
4059 /* Now check from side B */
4060 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
4061 if (!test_ctx) {
4062 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
4063 dofail();
4064 op_count = 1;
4065 ffdh_checks = 0;
4066 break;
4067 }
4068 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) {
4069 BIO_printf(bio_err, "FFDH computation failure.\n");
4070 op_count = 1;
4071 ffdh_checks = 0;
4072 break;
4073 }
4074
4075 /* compare the computed secrets */
4076 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
4077 loopargs[i].secret_ff_b, secret_size)) {
4078 BIO_printf(bio_err, "FFDH computations don't match.\n");
4079 dofail();
4080 op_count = 1;
4081 ffdh_checks = 0;
4082 break;
4083 }
4084
4085 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
4086
4087 EVP_PKEY_free(pkey_A);
4088 pkey_A = NULL;
4089 EVP_PKEY_free(pkey_B);
4090 pkey_B = NULL;
4091 EVP_PKEY_CTX_free(test_ctx);
4092 test_ctx = NULL;
4093 }
4094 if (ffdh_checks != 0) {
4095 pkey_print_message("", "ffdh",
4096 ffdh_params[testnum].bits, seconds.ffdh);
4097 Time_F(START);
4098 count = run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
4099 d = Time_F(STOP);
4100 BIO_printf(bio_err,
4101 mr ? "+R14:%ld:%d:%.2f\n" : "%ld %u-bits FFDH ops in %.2fs\n", count,
4102 ffdh_params[testnum].bits, d);
4103 ffdh_results[testnum][0] = (double)count / d;
4104 op_count = count;
4105 }
4106 if (op_count <= 1) {
4107 /* if longer than 10s, don't do any more */
4108 stop_it(ffdh_doit, testnum);
4109 }
4110 }
4111 #endif /* OPENSSL_NO_DH */
4112
4113 for (testnum = 0; testnum < kems_algs_len; testnum++) {
4114 int kem_checks = 1;
4115 const char *kem_name = kems_algname[testnum];
4116
4117 if (!kems_doit[testnum] || !do_kems)
4118 continue;
4119
4120 for (i = 0; i < loopargs_len; i++) {
4121 EVP_PKEY *pkey = NULL;
4122 EVP_PKEY_CTX *kem_gen_ctx = NULL;
4123 EVP_PKEY_CTX *kem_encaps_ctx = NULL;
4124 EVP_PKEY_CTX *kem_decaps_ctx = NULL;
4125 size_t send_secret_len, out_len;
4126 size_t rcv_secret_len;
4127 unsigned char *out = NULL, *send_secret = NULL, *rcv_secret;
4128 unsigned int bits;
4129 char *name;
4130 char sfx[MAX_ALGNAME_SUFFIX];
4131 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4132 int use_params = 0;
4133 enum kem_type_t { KEM_RSA = 1,
4134 KEM_EC,
4135 KEM_X25519,
4136 KEM_X448 } kem_type;
4137
4138 /* no string after rsa<bitcnt> permitted: */
4139 if (strlen(kem_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4140 && sscanf(kem_name, "rsa%u%s", &bits, sfx) == 1)
4141 kem_type = KEM_RSA;
4142 else if (strncmp(kem_name, "EC", 2) == 0)
4143 kem_type = KEM_EC;
4144 else if (strcmp(kem_name, "X25519") == 0)
4145 kem_type = KEM_X25519;
4146 else if (strcmp(kem_name, "X448") == 0)
4147 kem_type = KEM_X448;
4148 else
4149 kem_type = 0;
4150
4151 if (ERR_peek_error()) {
4152 BIO_printf(bio_err,
4153 "WARNING: the error queue contains previous unhandled errors.\n");
4154 dofail();
4155 }
4156
4157 if (kem_type == KEM_RSA) {
4158 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4159 &bits);
4160 use_params = 1;
4161 } else if (kem_type == KEM_EC) {
4162 name = (char *)(kem_name + 2);
4163 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
4164 name, 0);
4165 use_params = 1;
4166 }
4167
4168 kem_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4169 (kem_type == KEM_RSA) ? "RSA" : (kem_type == KEM_EC) ? "EC"
4170 : kem_name,
4171 app_get0_propq());
4172
4173 if ((!kem_gen_ctx || EVP_PKEY_keygen_init(kem_gen_ctx) <= 0)
4174 || (use_params
4175 && EVP_PKEY_CTX_set_params(kem_gen_ctx, params) <= 0)) {
4176 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4177 kem_name);
4178 goto kem_err_break;
4179 }
4180 if (EVP_PKEY_keygen(kem_gen_ctx, &pkey) <= 0) {
4181 BIO_printf(bio_err, "Error while generating KEM EVP_PKEY.\n");
4182 goto kem_err_break;
4183 }
4184 /* Now prepare encaps data structs */
4185 kem_encaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4186 pkey,
4187 app_get0_propq());
4188 if (kem_encaps_ctx == NULL
4189 || EVP_PKEY_encapsulate_init(kem_encaps_ctx, NULL) <= 0
4190 || (kem_type == KEM_RSA
4191 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "RSASVE") <= 0)
4192 || ((kem_type == KEM_EC
4193 || kem_type == KEM_X25519
4194 || kem_type == KEM_X448)
4195 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx, "DHKEM") <= 0)
4196 || EVP_PKEY_encapsulate(kem_encaps_ctx, NULL, &out_len,
4197 NULL, &send_secret_len)
4198 <= 0) {
4199 BIO_printf(bio_err,
4200 "Error while initializing encaps data structs for %s.\n",
4201 kem_name);
4202 goto kem_err_break;
4203 }
4204 out = app_malloc(out_len, "encaps result");
4205 send_secret = app_malloc(send_secret_len, "encaps secret");
4206 if (out == NULL || send_secret == NULL) {
4207 BIO_printf(bio_err, "MemAlloc error in encaps for %s.\n", kem_name);
4208 goto kem_err_break;
4209 }
4210 if (EVP_PKEY_encapsulate(kem_encaps_ctx, out, &out_len,
4211 send_secret, &send_secret_len)
4212 <= 0) {
4213 BIO_printf(bio_err, "Encaps error for %s.\n", kem_name);
4214 goto kem_err_break;
4215 }
4216 /* Now prepare decaps data structs */
4217 kem_decaps_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4218 pkey,
4219 app_get0_propq());
4220 if (kem_decaps_ctx == NULL
4221 || EVP_PKEY_decapsulate_init(kem_decaps_ctx, NULL) <= 0
4222 || (kem_type == KEM_RSA
4223 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "RSASVE") <= 0)
4224 || ((kem_type == KEM_EC
4225 || kem_type == KEM_X25519
4226 || kem_type == KEM_X448)
4227 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx, "DHKEM") <= 0)
4228 || EVP_PKEY_decapsulate(kem_decaps_ctx, NULL, &rcv_secret_len,
4229 out, out_len)
4230 <= 0) {
4231 BIO_printf(bio_err,
4232 "Error while initializing decaps data structs for %s.\n",
4233 kem_name);
4234 goto kem_err_break;
4235 }
4236 rcv_secret = app_malloc(rcv_secret_len, "KEM decaps secret");
4237 if (rcv_secret == NULL) {
4238 BIO_printf(bio_err, "MemAlloc failure in decaps for %s.\n",
4239 kem_name);
4240 goto kem_err_break;
4241 }
4242 if (EVP_PKEY_decapsulate(kem_decaps_ctx, rcv_secret,
4243 &rcv_secret_len, out, out_len)
4244 <= 0
4245 || rcv_secret_len != send_secret_len
4246 || memcmp(send_secret, rcv_secret, send_secret_len)) {
4247 BIO_printf(bio_err, "Decaps error for %s.\n", kem_name);
4248 goto kem_err_break;
4249 }
4250 loopargs[i].kem_gen_ctx[testnum] = kem_gen_ctx;
4251 loopargs[i].kem_encaps_ctx[testnum] = kem_encaps_ctx;
4252 loopargs[i].kem_decaps_ctx[testnum] = kem_decaps_ctx;
4253 loopargs[i].kem_out_len[testnum] = out_len;
4254 loopargs[i].kem_secret_len[testnum] = send_secret_len;
4255 loopargs[i].kem_out[testnum] = out;
4256 loopargs[i].kem_send_secret[testnum] = send_secret;
4257 loopargs[i].kem_rcv_secret[testnum] = rcv_secret;
4258 EVP_PKEY_free(pkey);
4259 pkey = NULL;
4260 continue;
4261
4262 kem_err_break:
4263 dofail();
4264 EVP_PKEY_free(pkey);
4265 op_count = 1;
4266 kem_checks = 0;
4267 break;
4268 }
4269 if (kem_checks != 0) {
4270 kskey_print_message(kem_name, "keygen", seconds.kem);
4271 Time_F(START);
4272 count = run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
4273 d = Time_F(STOP);
4274 BIO_printf(bio_err,
4275 mr ? "+R15:%ld:%s:%.2f\n" : "%ld %s KEM keygen ops in %.2fs\n", count,
4276 kem_name, d);
4277 kems_results[testnum][0] = (double)count / d;
4278 op_count = count;
4279 kskey_print_message(kem_name, "encaps", seconds.kem);
4280 Time_F(START);
4281 count = run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
4282 d = Time_F(STOP);
4283 BIO_printf(bio_err,
4284 mr ? "+R16:%ld:%s:%.2f\n" : "%ld %s KEM encaps ops in %.2fs\n", count,
4285 kem_name, d);
4286 kems_results[testnum][1] = (double)count / d;
4287 op_count = count;
4288 kskey_print_message(kem_name, "decaps", seconds.kem);
4289 Time_F(START);
4290 count = run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
4291 d = Time_F(STOP);
4292 BIO_printf(bio_err,
4293 mr ? "+R17:%ld:%s:%.2f\n" : "%ld %s KEM decaps ops in %.2fs\n", count,
4294 kem_name, d);
4295 kems_results[testnum][2] = (double)count / d;
4296 op_count = count;
4297 }
4298 if (op_count <= 1) {
4299 /* if longer than 10s, don't do any more */
4300 stop_it(kems_doit, testnum);
4301 }
4302 }
4303
4304 for (testnum = 0; testnum < sigs_algs_len; testnum++) {
4305 int sig_checks = 1;
4306 const char *sig_name = sigs_algname[testnum];
4307
4308 if (!sigs_doit[testnum] || !do_sigs)
4309 continue;
4310
4311 for (i = 0; i < loopargs_len; i++) {
4312 EVP_PKEY *pkey = NULL;
4313 EVP_PKEY_CTX *ctx_params = NULL;
4314 EVP_PKEY *pkey_params = NULL;
4315 EVP_PKEY_CTX *sig_gen_ctx = NULL;
4316 EVP_PKEY_CTX *sig_sign_ctx = NULL;
4317 EVP_PKEY_CTX *sig_verify_ctx = NULL;
4318 EVP_SIGNATURE *alg = NULL;
4319 unsigned char md[SHA256_DIGEST_LENGTH];
4320 unsigned char *sig;
4321 char sfx[MAX_ALGNAME_SUFFIX];
4322 size_t md_len = SHA256_DIGEST_LENGTH;
4323 size_t max_sig_len, sig_len;
4324 unsigned int bits;
4325 OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
4326 int use_params = 0;
4327
4328 /* only sign little data to avoid measuring digest performance */
4329 memset(md, 0, SHA256_DIGEST_LENGTH);
4330
4331 if (ERR_peek_error()) {
4332 BIO_printf(bio_err,
4333 "WARNING: the error queue contains previous unhandled errors.\n");
4334 dofail();
4335 }
4336
4337 /* no string after rsa<bitcnt> permitted: */
4338 if (strlen(sig_name) < MAX_ALGNAME_SUFFIX + 4 /* rsa+digit */
4339 && sscanf(sig_name, "rsa%u%s", &bits, sfx) == 1) {
4340 params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS,
4341 &bits);
4342 use_params = 1;
4343 }
4344
4345 if (strncmp(sig_name, "dsa", 3) == 0) {
4346 ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
4347 if (ctx_params == NULL
4348 || EVP_PKEY_paramgen_init(ctx_params) <= 0
4349 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params,
4350 atoi(sig_name + 3))
4351 <= 0
4352 || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0
4353 || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL
4354 || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0) {
4355 BIO_printf(bio_err,
4356 "Error initializing classic keygen ctx for %s.\n",
4357 sig_name);
4358 goto sig_err_break;
4359 }
4360 }
4361
4362 if (sig_gen_ctx == NULL)
4363 sig_gen_ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
4364 use_params == 1 ? "RSA" : sig_name,
4365 app_get0_propq());
4366
4367 if (!sig_gen_ctx || EVP_PKEY_keygen_init(sig_gen_ctx) <= 0
4368 || (use_params && EVP_PKEY_CTX_set_params(sig_gen_ctx, params) <= 0)) {
4369 BIO_printf(bio_err, "Error initializing keygen ctx for %s.\n",
4370 sig_name);
4371 goto sig_err_break;
4372 }
4373 if (EVP_PKEY_keygen(sig_gen_ctx, &pkey) <= 0) {
4374 BIO_printf(bio_err,
4375 "Error while generating signature EVP_PKEY for %s.\n",
4376 sig_name);
4377 goto sig_err_break;
4378 }
4379
4380 /*
4381 * Try explicitly fetching the signature algorithm implementation to
4382 * use in case the algorithm does not support EVP_PKEY_sign_init
4383 */
4384 ERR_set_mark();
4385 alg = EVP_SIGNATURE_fetch(app_get0_libctx(), sig_name, app_get0_propq());
4386 ERR_pop_to_mark();
4387
4388 /* Now prepare signature data structs */
4389 sig_sign_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4390 pkey,
4391 app_get0_propq());
4392 if (sig_sign_ctx == NULL) {
4393 BIO_printf(bio_err,
4394 "Error while initializing signing ctx for %s.\n",
4395 sig_name);
4396 goto sig_err_break;
4397 }
4398 ERR_set_mark();
4399 if (EVP_PKEY_sign_init(sig_sign_ctx) <= 0
4400 && (alg == NULL
4401 || EVP_PKEY_sign_message_init(sig_sign_ctx, alg, NULL) <= 0)) {
4402 ERR_clear_last_mark();
4403 BIO_printf(bio_err,
4404 "Error while initializing signing data structs for %s.\n",
4405 sig_name);
4406 goto sig_err_break;
4407 }
4408 ERR_pop_to_mark();
4409 if (use_params == 1 && EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx, RSA_PKCS1_PADDING) <= 0) {
4410 BIO_printf(bio_err,
4411 "Error while initializing padding for %s.\n",
4412 sig_name);
4413 goto sig_err_break;
4414 }
4415 if (EVP_PKEY_sign(sig_sign_ctx, NULL, &max_sig_len, md, md_len) <= 0) {
4416 BIO_printf(bio_err,
4417 "Error while obtaining signature buffer length for %s.\n",
4418 sig_name);
4419 goto sig_err_break;
4420 }
4421 sig = app_malloc(sig_len = max_sig_len, "signature buffer");
4422 if (sig == NULL) {
4423 BIO_printf(bio_err, "MemAlloc error in sign for %s.\n", sig_name);
4424 goto sig_err_break;
4425 }
4426 if (EVP_PKEY_sign(sig_sign_ctx, sig, &sig_len, md, md_len) <= 0) {
4427 BIO_printf(bio_err, "Signing error for %s.\n", sig_name);
4428 goto sig_err_break;
4429 }
4430 /* Now prepare verify data structs */
4431 memset(md, 0, SHA256_DIGEST_LENGTH);
4432 sig_verify_ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
4433 pkey,
4434 app_get0_propq());
4435 if (sig_verify_ctx == NULL) {
4436 BIO_printf(bio_err,
4437 "Error while initializing verify ctx for %s.\n",
4438 sig_name);
4439 goto sig_err_break;
4440 }
4441 ERR_set_mark();
4442 if (EVP_PKEY_verify_init(sig_verify_ctx) <= 0
4443 && (alg == NULL
4444 || EVP_PKEY_verify_message_init(sig_verify_ctx, alg, NULL) <= 0)) {
4445 ERR_clear_last_mark();
4446 BIO_printf(bio_err,
4447 "Error while initializing verify data structs for %s.\n",
4448 sig_name);
4449 goto sig_err_break;
4450 }
4451 ERR_pop_to_mark();
4452 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4453 BIO_printf(bio_err, "Verify error for %s.\n", sig_name);
4454 goto sig_err_break;
4455 }
4456 if (EVP_PKEY_verify(sig_verify_ctx, sig, sig_len, md, md_len) <= 0) {
4457 BIO_printf(bio_err, "Verify 2 error for %s.\n", sig_name);
4458 goto sig_err_break;
4459 }
4460 loopargs[i].sig_gen_ctx[testnum] = sig_gen_ctx;
4461 loopargs[i].sig_sign_ctx[testnum] = sig_sign_ctx;
4462 loopargs[i].sig_verify_ctx[testnum] = sig_verify_ctx;
4463 loopargs[i].sig_max_sig_len[testnum] = max_sig_len;
4464 loopargs[i].sig_act_sig_len[testnum] = sig_len;
4465 loopargs[i].sig_sig[testnum] = sig;
4466 EVP_PKEY_free(pkey);
4467 EVP_SIGNATURE_free(alg);
4468 pkey = NULL;
4469 continue;
4470
4471 sig_err_break:
4472 dofail();
4473 EVP_PKEY_free(pkey);
4474 EVP_SIGNATURE_free(alg);
4475 op_count = 1;
4476 sig_checks = 0;
4477 break;
4478 }
4479
4480 if (sig_checks != 0) {
4481 kskey_print_message(sig_name, "keygen", seconds.sig);
4482 Time_F(START);
4483 count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
4484 d = Time_F(STOP);
4485 BIO_printf(bio_err,
4486 mr ? "+R18:%ld:%s:%.2f\n" : "%ld %s signature keygen ops in %.2fs\n", count,
4487 sig_name, d);
4488 sigs_results[testnum][0] = (double)count / d;
4489 op_count = count;
4490 kskey_print_message(sig_name, "signs", seconds.sig);
4491 Time_F(START);
4492 count = run_benchmark(async_jobs, SIG_sign_loop, loopargs);
4493 d = Time_F(STOP);
4494 BIO_printf(bio_err,
4495 mr ? "+R19:%ld:%s:%.2f\n" : "%ld %s signature sign ops in %.2fs\n", count,
4496 sig_name, d);
4497 sigs_results[testnum][1] = (double)count / d;
4498 op_count = count;
4499
4500 kskey_print_message(sig_name, "verify", seconds.sig);
4501 Time_F(START);
4502 count = run_benchmark(async_jobs, SIG_verify_loop, loopargs);
4503 d = Time_F(STOP);
4504 BIO_printf(bio_err,
4505 mr ? "+R20:%ld:%s:%.2f\n" : "%ld %s signature verify ops in %.2fs\n", count,
4506 sig_name, d);
4507 sigs_results[testnum][2] = (double)count / d;
4508 op_count = count;
4509 }
4510 if (op_count <= 1)
4511 stop_it(sigs_doit, testnum);
4512 }
4513
4514 #ifndef NO_FORK
4515 show_res:
4516 #endif
4517 if (!mr) {
4518 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
4519 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
4520 printf("options: %s\n", BN_options());
4521 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
4522 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
4523 }
4524
4525 if (pr_header) {
4526 if (mr) {
4527 printf("+H");
4528 } else {
4529 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4530 printf("type ");
4531 }
4532 for (testnum = 0; testnum < size_num; testnum++)
4533 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
4534 printf("\n");
4535 }
4536
4537 for (k = 0; k < ALGOR_NUM; k++) {
4538 const char *alg_name = names[k];
4539
4540 if (!doit[k])
4541 continue;
4542
4543 if (k == D_EVP) {
4544 if (evp_cipher == NULL)
4545 alg_name = evp_md_name;
4546 else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
4547 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
4548 }
4549
4550 if (mr)
4551 printf("+F:%u:%s", k, alg_name);
4552 else
4553 printf("%-13s", alg_name);
4554 for (testnum = 0; testnum < size_num; testnum++) {
4555 if (results[k][testnum] > 10000 && !mr)
4556 printf(" %11.2fk", results[k][testnum] / 1e3);
4557 else
4558 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
4559 }
4560 printf("\n");
4561 }
4562 testnum = 1;
4563 for (k = 0; k < RSA_NUM; k++) {
4564 if (!rsa_doit[k])
4565 continue;
4566 if (testnum && !mr) {
4567 printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " ");
4568 testnum = 0;
4569 }
4570 if (mr)
4571 printf("+F2:%u:%u:%f:%f:%f:%f\n",
4572 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1],
4573 rsa_results[k][2], rsa_results[k][3]);
4574 else
4575 printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4576 rsa_keys[k].bits, 1.0 / rsa_results[k][0],
4577 1.0 / rsa_results[k][1], 1.0 / rsa_results[k][2],
4578 1.0 / rsa_results[k][3],
4579 rsa_results[k][0], rsa_results[k][1],
4580 rsa_results[k][2], rsa_results[k][3]);
4581 }
4582 testnum = 1;
4583 #ifndef OPENSSL_NO_DSA
4584 for (k = 0; k < DSA_NUM; k++) {
4585 if (!dsa_doit[k])
4586 continue;
4587 if (testnum && !mr) {
4588 printf("%18ssign verify sign/s verify/s\n", " ");
4589 testnum = 0;
4590 }
4591 if (mr)
4592 printf("+F3:%u:%u:%f:%f\n",
4593 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
4594 else
4595 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4596 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
4597 dsa_results[k][0], dsa_results[k][1]);
4598 }
4599 #endif /* OPENSSL_NO_DSA */
4600 testnum = 1;
4601 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
4602 if (!ecdsa_doit[k])
4603 continue;
4604 if (testnum && !mr) {
4605 printf("%30ssign verify sign/s verify/s\n", " ");
4606 testnum = 0;
4607 }
4608
4609 if (mr)
4610 printf("+F4:%u:%u:%f:%f\n",
4611 k, ec_curves[k].bits,
4612 ecdsa_results[k][0], ecdsa_results[k][1]);
4613 else
4614 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4615 ec_curves[k].bits, ec_curves[k].name,
4616 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
4617 ecdsa_results[k][0], ecdsa_results[k][1]);
4618 }
4619
4620 testnum = 1;
4621 for (k = 0; k < EC_NUM; k++) {
4622 if (!ecdh_doit[k])
4623 continue;
4624 if (testnum && !mr) {
4625 printf("%30sop op/s\n", " ");
4626 testnum = 0;
4627 }
4628 if (mr)
4629 printf("+F5:%u:%u:%f:%f\n",
4630 k, ec_curves[k].bits,
4631 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
4632
4633 else
4634 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4635 ec_curves[k].bits, ec_curves[k].name,
4636 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
4637 }
4638
4639 #ifndef OPENSSL_NO_ECX
4640 testnum = 1;
4641 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
4642 if (!eddsa_doit[k])
4643 continue;
4644 if (testnum && !mr) {
4645 printf("%30ssign verify sign/s verify/s\n", " ");
4646 testnum = 0;
4647 }
4648
4649 if (mr)
4650 printf("+F6:%u:%u:%s:%f:%f\n",
4651 k, ed_curves[k].bits, ed_curves[k].name,
4652 eddsa_results[k][0], eddsa_results[k][1]);
4653 else
4654 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4655 ed_curves[k].bits, ed_curves[k].name,
4656 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
4657 eddsa_results[k][0], eddsa_results[k][1]);
4658 }
4659 #endif /* OPENSSL_NO_ECX */
4660
4661 #ifndef OPENSSL_NO_SM2
4662 testnum = 1;
4663 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
4664 if (!sm2_doit[k])
4665 continue;
4666 if (testnum && !mr) {
4667 printf("%30ssign verify sign/s verify/s\n", " ");
4668 testnum = 0;
4669 }
4670
4671 if (mr)
4672 printf("+F7:%u:%u:%s:%f:%f\n",
4673 k, sm2_curves[k].bits, sm2_curves[k].name,
4674 sm2_results[k][0], sm2_results[k][1]);
4675 else
4676 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4677 sm2_curves[k].bits, sm2_curves[k].name,
4678 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
4679 sm2_results[k][0], sm2_results[k][1]);
4680 }
4681 #endif
4682 #ifndef OPENSSL_NO_DH
4683 testnum = 1;
4684 for (k = 0; k < FFDH_NUM; k++) {
4685 if (!ffdh_doit[k])
4686 continue;
4687 if (testnum && !mr) {
4688 printf("%23sop op/s\n", " ");
4689 testnum = 0;
4690 }
4691 if (mr)
4692 printf("+F8:%u:%u:%f:%f\n",
4693 k, ffdh_params[k].bits,
4694 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
4695
4696 else
4697 printf("%4u bits ffdh %8.4fs %8.1f\n",
4698 ffdh_params[k].bits,
4699 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
4700 }
4701 #endif /* OPENSSL_NO_DH */
4702
4703 testnum = 1;
4704 for (k = 0; k < kems_algs_len; k++) {
4705 const char *kem_name = kems_algname[k];
4706
4707 if (!kems_doit[k] || !do_kems)
4708 continue;
4709 if (testnum && !mr) {
4710 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4711 testnum = 0;
4712 }
4713 if (mr)
4714 printf("+F9:%u:%f:%f:%f\n",
4715 k, kems_results[k][0], kems_results[k][1],
4716 kems_results[k][2]);
4717 else
4718 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name,
4719 1.0 / kems_results[k][0],
4720 1.0 / kems_results[k][1], 1.0 / kems_results[k][2],
4721 kems_results[k][0], kems_results[k][1], kems_results[k][2]);
4722 }
4723 ret = 0;
4724
4725 testnum = 1;
4726 for (k = 0; k < sigs_algs_len; k++) {
4727 const char *sig_name = sigs_algname[k];
4728
4729 if (!sigs_doit[k] || !do_sigs)
4730 continue;
4731 if (testnum && !mr) {
4732 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4733 testnum = 0;
4734 }
4735 if (mr)
4736 printf("+F10:%u:%f:%f:%f\n",
4737 k, sigs_results[k][0], sigs_results[k][1],
4738 sigs_results[k][2]);
4739 else
4740 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name,
4741 1.0 / sigs_results[k][0], 1.0 / sigs_results[k][1],
4742 1.0 / sigs_results[k][2], sigs_results[k][0],
4743 sigs_results[k][1], sigs_results[k][2]);
4744 }
4745 ret = 0;
4746
4747 end:
4748 if (ret == 0 && testmode)
4749 ret = testmoderesult;
4750 ERR_print_errors(bio_err);
4751 for (i = 0; i < loopargs_len; i++) {
4752 OPENSSL_free(loopargs[i].buf_malloc);
4753 OPENSSL_free(loopargs[i].buf2_malloc);
4754
4755 BN_free(bn);
4756 EVP_PKEY_CTX_free(genctx);
4757 for (k = 0; k < RSA_NUM; k++) {
4758 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
4759 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
4760 EVP_PKEY_CTX_free(loopargs[i].rsa_encrypt_ctx[k]);
4761 EVP_PKEY_CTX_free(loopargs[i].rsa_decrypt_ctx[k]);
4762 }
4763 #ifndef OPENSSL_NO_DH
4764 OPENSSL_free(loopargs[i].secret_ff_a);
4765 OPENSSL_free(loopargs[i].secret_ff_b);
4766 for (k = 0; k < FFDH_NUM; k++)
4767 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
4768 #endif
4769 #ifndef OPENSSL_NO_DSA
4770 for (k = 0; k < DSA_NUM; k++) {
4771 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
4772 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
4773 }
4774 #endif
4775 for (k = 0; k < ECDSA_NUM; k++) {
4776 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
4777 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
4778 }
4779 for (k = 0; k < EC_NUM; k++)
4780 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
4781 #ifndef OPENSSL_NO_ECX
4782 for (k = 0; k < EdDSA_NUM; k++) {
4783 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
4784 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
4785 }
4786 #endif /* OPENSSL_NO_ECX */
4787 #ifndef OPENSSL_NO_SM2
4788 for (k = 0; k < SM2_NUM; k++) {
4789 EVP_PKEY_CTX *pctx = NULL;
4790
4791 /* free signing ctx */
4792 if (loopargs[i].sm2_ctx[k] != NULL
4793 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
4794 EVP_PKEY_CTX_free(pctx);
4795 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
4796 /* free verification ctx */
4797 if (loopargs[i].sm2_vfy_ctx[k] != NULL
4798 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
4799 EVP_PKEY_CTX_free(pctx);
4800 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
4801 /* free pkey */
4802 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
4803 }
4804 #endif
4805 for (k = 0; k < kems_algs_len; k++) {
4806 EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
4807 EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
4808 EVP_PKEY_CTX_free(loopargs[i].kem_decaps_ctx[k]);
4809 OPENSSL_free(loopargs[i].kem_out[k]);
4810 OPENSSL_free(loopargs[i].kem_send_secret[k]);
4811 OPENSSL_free(loopargs[i].kem_rcv_secret[k]);
4812 }
4813 for (k = 0; k < sigs_algs_len; k++) {
4814 EVP_PKEY_CTX_free(loopargs[i].sig_gen_ctx[k]);
4815 EVP_PKEY_CTX_free(loopargs[i].sig_sign_ctx[k]);
4816 EVP_PKEY_CTX_free(loopargs[i].sig_verify_ctx[k]);
4817 OPENSSL_free(loopargs[i].sig_sig[k]);
4818 }
4819 OPENSSL_free(loopargs[i].secret_a);
4820 OPENSSL_free(loopargs[i].secret_b);
4821 }
4822 OPENSSL_free(evp_hmac_name);
4823 OPENSSL_free(evp_cmac_name);
4824 for (k = 0; k < kems_algs_len; k++)
4825 OPENSSL_free(kems_algname[k]);
4826 if (kem_stack != NULL)
4827 sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
4828 for (k = 0; k < sigs_algs_len; k++)
4829 OPENSSL_free(sigs_algname[k]);
4830 if (sig_stack != NULL)
4831 sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
4832
4833 if (async_jobs > 0) {
4834 for (i = 0; i < loopargs_len; i++)
4835 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
4836 }
4837
4838 if (async_init) {
4839 ASYNC_cleanup_thread();
4840 }
4841 OPENSSL_free(loopargs);
4842 release_engine(e);
4843 EVP_CIPHER_free(evp_cipher);
4844 EVP_MAC_free(mac);
4845 NCONF_free(conf);
4846 return ret;
4847 }
4848
print_message(const char * s,int length,int tm)4849 static void print_message(const char *s, int length, int tm)
4850 {
4851 BIO_printf(bio_err,
4852 mr ? "+DT:%s:%d:%d\n"
4853 : "Doing %s ops for %ds on %d size blocks: ",
4854 s, tm, length);
4855 (void)BIO_flush(bio_err);
4856 run = 1;
4857 alarm(tm);
4858 }
4859
pkey_print_message(const char * str,const char * str2,unsigned int bits,int tm)4860 static void pkey_print_message(const char *str, const char *str2, unsigned int bits,
4861 int tm)
4862 {
4863 BIO_printf(bio_err,
4864 mr ? "+DTP:%d:%s:%s:%d\n"
4865 : "Doing %u bits %s %s ops for %ds: ",
4866 bits, str, str2, tm);
4867 (void)BIO_flush(bio_err);
4868 run = 1;
4869 alarm(tm);
4870 }
4871
kskey_print_message(const char * str,const char * str2,int tm)4872 static void kskey_print_message(const char *str, const char *str2, int tm)
4873 {
4874 BIO_printf(bio_err,
4875 mr ? "+DTP:%s:%s:%d\n"
4876 : "Doing %s %s ops for %ds: ",
4877 str, str2, tm);
4878 (void)BIO_flush(bio_err);
4879 run = 1;
4880 alarm(tm);
4881 }
4882
print_result(int alg,int run_no,int count,double time_used)4883 static void print_result(int alg, int run_no, int count, double time_used)
4884 {
4885 if (count == -1) {
4886 BIO_printf(bio_err, "%s error!\n", names[alg]);
4887 dofail();
4888 return;
4889 }
4890 BIO_printf(bio_err,
4891 mr ? "+R:%d:%s:%f\n"
4892 : "%d %s ops in %.2fs\n",
4893 count, names[alg], time_used);
4894 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
4895 }
4896
4897 #ifndef NO_FORK
sstrsep(char ** string,const char * delim)4898 static char *sstrsep(char **string, const char *delim)
4899 {
4900 char isdelim[256];
4901 char *token = *string;
4902
4903 memset(isdelim, 0, sizeof(isdelim));
4904 isdelim[0] = 1;
4905
4906 while (*delim) {
4907 isdelim[(unsigned char)(*delim)] = 1;
4908 delim++;
4909 }
4910
4911 while (!isdelim[(unsigned char)(**string)])
4912 (*string)++;
4913
4914 if (**string) {
4915 **string = 0;
4916 (*string)++;
4917 }
4918
4919 return token;
4920 }
4921
strtoint(const char * str,const int min_val,const int upper_val,int * res)4922 static int strtoint(const char *str, const int min_val, const int upper_val,
4923 int *res)
4924 {
4925 char *end = NULL;
4926 long int val = 0;
4927
4928 errno = 0;
4929 val = strtol(str, &end, 10);
4930 if (errno == 0 && end != str && *end == 0
4931 && min_val <= val && val < upper_val) {
4932 *res = (int)val;
4933 return 1;
4934 } else {
4935 return 0;
4936 }
4937 }
4938
do_multi(int multi,int size_num)4939 static int do_multi(int multi, int size_num)
4940 {
4941 int n;
4942 int fd[2];
4943 int *fds;
4944 int status;
4945 static char sep[] = ":";
4946
4947 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
4948 for (n = 0; n < multi; ++n) {
4949 if (pipe(fd) == -1) {
4950 BIO_printf(bio_err, "pipe failure\n");
4951 exit(1);
4952 }
4953 fflush(stdout);
4954 (void)BIO_flush(bio_err);
4955 if (fork()) {
4956 close(fd[1]);
4957 fds[n] = fd[0];
4958 } else {
4959 close(fd[0]);
4960 close(1);
4961 if (dup(fd[1]) == -1) {
4962 BIO_printf(bio_err, "dup failed\n");
4963 exit(1);
4964 }
4965 close(fd[1]);
4966 mr = 1;
4967 usertime = 0;
4968 OPENSSL_free(fds);
4969 return 0;
4970 }
4971 printf("Forked child %d\n", n);
4972 }
4973
4974 /* for now, assume the pipe is long enough to take all the output */
4975 for (n = 0; n < multi; ++n) {
4976 FILE *f;
4977 char buf[1024];
4978 char *p;
4979 char *tk;
4980 int k;
4981 double d;
4982
4983 if ((f = fdopen(fds[n], "r")) == NULL) {
4984 BIO_printf(bio_err, "fdopen failure with 0x%x\n",
4985 errno);
4986 OPENSSL_free(fds);
4987 return 1;
4988 }
4989 while (fgets(buf, sizeof(buf), f)) {
4990 p = strchr(buf, '\n');
4991 if (p)
4992 *p = '\0';
4993 if (buf[0] != '+') {
4994 BIO_printf(bio_err,
4995 "Don't understand line '%s' from child %d\n", buf,
4996 n);
4997 continue;
4998 }
4999 printf("Got: %s from %d\n", buf, n);
5000 p = buf;
5001 if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
5002 int alg;
5003 int j;
5004
5005 if (strtoint(sstrsep(&p, sep), 0, ALGOR_NUM, &alg)) {
5006 sstrsep(&p, sep);
5007 for (j = 0; j < size_num; ++j)
5008 results[alg][j] += atof(sstrsep(&p, sep));
5009 }
5010 } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
5011 tk = sstrsep(&p, sep);
5012 if (strtoint(tk, 0, OSSL_NELEM(rsa_results), &k)) {
5013 sstrsep(&p, sep);
5014
5015 d = atof(sstrsep(&p, sep));
5016 rsa_results[k][0] += d;
5017
5018 d = atof(sstrsep(&p, sep));
5019 rsa_results[k][1] += d;
5020
5021 d = atof(sstrsep(&p, sep));
5022 rsa_results[k][2] += d;
5023
5024 d = atof(sstrsep(&p, sep));
5025 rsa_results[k][3] += d;
5026 }
5027 #ifndef OPENSSL_NO_DSA
5028 } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
5029 tk = sstrsep(&p, sep);
5030 if (strtoint(tk, 0, OSSL_NELEM(dsa_results), &k)) {
5031 sstrsep(&p, sep);
5032
5033 d = atof(sstrsep(&p, sep));
5034 dsa_results[k][0] += d;
5035
5036 d = atof(sstrsep(&p, sep));
5037 dsa_results[k][1] += d;
5038 }
5039 #endif /* OPENSSL_NO_DSA */
5040 } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
5041 tk = sstrsep(&p, sep);
5042 if (strtoint(tk, 0, OSSL_NELEM(ecdsa_results), &k)) {
5043 sstrsep(&p, sep);
5044
5045 d = atof(sstrsep(&p, sep));
5046 ecdsa_results[k][0] += d;
5047
5048 d = atof(sstrsep(&p, sep));
5049 ecdsa_results[k][1] += d;
5050 }
5051 } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
5052 tk = sstrsep(&p, sep);
5053 if (strtoint(tk, 0, OSSL_NELEM(ecdh_results), &k)) {
5054 sstrsep(&p, sep);
5055
5056 d = atof(sstrsep(&p, sep));
5057 ecdh_results[k][0] += d;
5058 }
5059 #ifndef OPENSSL_NO_ECX
5060 } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
5061 tk = sstrsep(&p, sep);
5062 if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
5063 sstrsep(&p, sep);
5064 sstrsep(&p, sep);
5065
5066 d = atof(sstrsep(&p, sep));
5067 eddsa_results[k][0] += d;
5068
5069 d = atof(sstrsep(&p, sep));
5070 eddsa_results[k][1] += d;
5071 }
5072 #endif /* OPENSSL_NO_ECX */
5073 #ifndef OPENSSL_NO_SM2
5074 } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
5075 tk = sstrsep(&p, sep);
5076 if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
5077 sstrsep(&p, sep);
5078 sstrsep(&p, sep);
5079
5080 d = atof(sstrsep(&p, sep));
5081 sm2_results[k][0] += d;
5082
5083 d = atof(sstrsep(&p, sep));
5084 sm2_results[k][1] += d;
5085 }
5086 #endif /* OPENSSL_NO_SM2 */
5087 #ifndef OPENSSL_NO_DH
5088 } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
5089 tk = sstrsep(&p, sep);
5090 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
5091 sstrsep(&p, sep);
5092
5093 d = atof(sstrsep(&p, sep));
5094 ffdh_results[k][0] += d;
5095 }
5096 #endif /* OPENSSL_NO_DH */
5097 } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
5098 tk = sstrsep(&p, sep);
5099 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
5100 d = atof(sstrsep(&p, sep));
5101 kems_results[k][0] += d;
5102
5103 d = atof(sstrsep(&p, sep));
5104 kems_results[k][1] += d;
5105
5106 d = atof(sstrsep(&p, sep));
5107 kems_results[k][2] += d;
5108 }
5109 } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
5110 tk = sstrsep(&p, sep);
5111 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
5112 d = atof(sstrsep(&p, sep));
5113 sigs_results[k][0] += d;
5114
5115 d = atof(sstrsep(&p, sep));
5116 sigs_results[k][1] += d;
5117
5118 d = atof(sstrsep(&p, sep));
5119 sigs_results[k][2] += d;
5120 }
5121 } else if (!HAS_PREFIX(buf, "+H:")) {
5122 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
5123 n);
5124 }
5125 }
5126
5127 fclose(f);
5128 }
5129 OPENSSL_free(fds);
5130 for (n = 0; n < multi; ++n) {
5131 while (wait(&status) == -1)
5132 if (errno != EINTR) {
5133 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
5134 errno);
5135 return 1;
5136 }
5137 if (WIFEXITED(status) && WEXITSTATUS(status)) {
5138 BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
5139 } else if (WIFSIGNALED(status)) {
5140 BIO_printf(bio_err, "Child terminated by signal %d\n",
5141 WTERMSIG(status));
5142 }
5143 }
5144 return 1;
5145 }
5146 #endif
5147
multiblock_speed(const EVP_CIPHER * evp_cipher,int lengths_single,const openssl_speed_sec_t * seconds)5148 static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
5149 const openssl_speed_sec_t *seconds)
5150 {
5151 static const int mblengths_list[] = {
5152 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024
5153 };
5154 const int *mblengths = mblengths_list;
5155 int j, count, keylen, num = OSSL_NELEM(mblengths_list), ciph_success = 1;
5156 const char *alg_name;
5157 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
5158 EVP_CIPHER_CTX *ctx = NULL;
5159 double d = 0.0;
5160
5161 if (lengths_single) {
5162 mblengths = &lengths_single;
5163 num = 1;
5164 }
5165
5166 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
5167 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
5168 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
5169 app_bail_out("failed to allocate cipher context\n");
5170 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
5171 app_bail_out("failed to initialise cipher context\n");
5172
5173 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
5174 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
5175 goto err;
5176 }
5177 key = app_malloc(keylen, "evp_cipher key");
5178 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
5179 app_bail_out("failed to generate random cipher key\n");
5180 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
5181 app_bail_out("failed to set cipher key\n");
5182 OPENSSL_clear_free(key, keylen);
5183
5184 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
5185 sizeof(no_key), no_key)
5186 <= 0)
5187 app_bail_out("failed to set AEAD key\n");
5188 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
5189 app_bail_out("failed to get cipher name\n");
5190
5191 for (j = 0; j < num; j++) {
5192 print_message(alg_name, mblengths[j], seconds->sym);
5193 Time_F(START);
5194 for (count = 0; run && COND(count); count++) {
5195 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
5196 size_t len = mblengths[j];
5197 int packlen;
5198
5199 memset(aad, 0, 8); /* avoid uninitialized values */
5200 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
5201 aad[9] = 3; /* version */
5202 aad[10] = 2;
5203 aad[11] = 0; /* length */
5204 aad[12] = 0;
5205 mb_param.out = NULL;
5206 mb_param.inp = aad;
5207 mb_param.len = len;
5208 mb_param.interleave = 8;
5209
5210 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
5211 sizeof(mb_param), &mb_param);
5212
5213 if (packlen > 0) {
5214 mb_param.out = out;
5215 mb_param.inp = inp;
5216 mb_param.len = len;
5217 (void)EVP_CIPHER_CTX_ctrl(ctx,
5218 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
5219 sizeof(mb_param), &mb_param);
5220 } else {
5221 int pad;
5222
5223 if (RAND_bytes(inp, 16) <= 0)
5224 app_bail_out("error setting random bytes\n");
5225 len += 16;
5226 aad[11] = (unsigned char)(len >> 8);
5227 aad[12] = (unsigned char)(len);
5228 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
5229 EVP_AEAD_TLS1_AAD_LEN, aad);
5230 ciph_success = EVP_Cipher(ctx, out, inp, len + pad);
5231 }
5232 }
5233 d = Time_F(STOP);
5234 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n" : "%d %s ops in %.2fs\n", count, "evp", d);
5235 if ((ciph_success <= 0) && (mr == 0))
5236 BIO_printf(bio_err, "Error performing cipher op\n");
5237 results[D_EVP][j] = ((double)count) / d * mblengths[j];
5238 }
5239
5240 if (mr) {
5241 fprintf(stdout, "+H");
5242 for (j = 0; j < num; j++)
5243 fprintf(stdout, ":%d", mblengths[j]);
5244 fprintf(stdout, "\n");
5245 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
5246 for (j = 0; j < num; j++)
5247 fprintf(stdout, ":%.2f", results[D_EVP][j]);
5248 fprintf(stdout, "\n");
5249 } else {
5250 fprintf(stdout,
5251 "The 'numbers' are in 1000s of bytes per second processed.\n");
5252 fprintf(stdout, "type ");
5253 for (j = 0; j < num; j++)
5254 fprintf(stdout, "%7d bytes", mblengths[j]);
5255 fprintf(stdout, "\n");
5256 fprintf(stdout, "%-24s", alg_name);
5257
5258 for (j = 0; j < num; j++) {
5259 if (results[D_EVP][j] > 10000)
5260 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
5261 else
5262 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
5263 }
5264 fprintf(stdout, "\n");
5265 }
5266
5267 err:
5268 OPENSSL_free(inp);
5269 OPENSSL_free(out);
5270 EVP_CIPHER_CTX_free(ctx);
5271 }
5272