VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.3/apps/speed.c@ 101814

Last change on this file since 101814 was 101211, checked in by vboxsync, 17 months ago

openssl-3.1.3: Applied and adjusted our OpenSSL changes to 3.1.2. bugref:10527

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

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