VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/apps/speed.c

Last change on this file was 108206, checked in by vboxsync, 3 months ago

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette