VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.0/apps/speed.c@ 100111

Last change on this file since 100111 was 99366, checked in by vboxsync, 21 months ago

openssl-3.1.0: Applied and adjusted our OpenSSL changes to 3.0.7. bugref:10418

File size: 125.4 KB
Line 
1/*
2 * Copyright 1995-2022 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_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1028 if (ret == 0) {
1029 BIO_printf(bio_err, "EdDSA sign failure\n");
1030 ERR_print_errors(bio_err);
1031 count = -1;
1032 break;
1033 }
1034 }
1035 return count;
1036}
1037
1038static int EdDSA_verify_loop(void *args)
1039{
1040 loopargs_t *tempargs = *(loopargs_t **) args;
1041 unsigned char *buf = tempargs->buf;
1042 EVP_MD_CTX **edctx = tempargs->eddsa_ctx2;
1043 unsigned char *eddsasig = tempargs->buf2;
1044 size_t eddsasigsize = tempargs->sigsize;
1045 int ret, count;
1046
1047 for (count = 0; COND(eddsa_c[testnum][1]); count++) {
1048 ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
1049 if (ret != 1) {
1050 BIO_printf(bio_err, "EdDSA verify failure\n");
1051 ERR_print_errors(bio_err);
1052 count = -1;
1053 break;
1054 }
1055 }
1056 return count;
1057}
1058
1059#ifndef OPENSSL_NO_SM2
1060static long sm2_c[SM2_NUM][2];
1061static int SM2_sign_loop(void *args)
1062{
1063 loopargs_t *tempargs = *(loopargs_t **) args;
1064 unsigned char *buf = tempargs->buf;
1065 EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
1066 unsigned char *sm2sig = tempargs->buf2;
1067 size_t sm2sigsize;
1068 int ret, count;
1069 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1070 const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
1071
1072 for (count = 0; COND(sm2_c[testnum][0]); count++) {
1073 sm2sigsize = max_size;
1074
1075 if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
1076 NULL, sm2_pkey[testnum])) {
1077 BIO_printf(bio_err, "SM2 init sign failure\n");
1078 ERR_print_errors(bio_err);
1079 count = -1;
1080 break;
1081 }
1082 ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
1083 buf, 20);
1084 if (ret == 0) {
1085 BIO_printf(bio_err, "SM2 sign failure\n");
1086 ERR_print_errors(bio_err);
1087 count = -1;
1088 break;
1089 }
1090 /* update the latest returned size and always use the fixed buffer size */
1091 tempargs->sigsize = sm2sigsize;
1092 }
1093
1094 return count;
1095}
1096
1097static int SM2_verify_loop(void *args)
1098{
1099 loopargs_t *tempargs = *(loopargs_t **) args;
1100 unsigned char *buf = tempargs->buf;
1101 EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
1102 unsigned char *sm2sig = tempargs->buf2;
1103 size_t sm2sigsize = tempargs->sigsize;
1104 int ret, count;
1105 EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
1106
1107 for (count = 0; COND(sm2_c[testnum][1]); count++) {
1108 if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
1109 NULL, sm2_pkey[testnum])) {
1110 BIO_printf(bio_err, "SM2 verify init failure\n");
1111 ERR_print_errors(bio_err);
1112 count = -1;
1113 break;
1114 }
1115 ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
1116 buf, 20);
1117 if (ret != 1) {
1118 BIO_printf(bio_err, "SM2 verify failure\n");
1119 ERR_print_errors(bio_err);
1120 count = -1;
1121 break;
1122 }
1123 }
1124 return count;
1125}
1126#endif /* OPENSSL_NO_SM2 */
1127
1128static int run_benchmark(int async_jobs,
1129 int (*loop_function) (void *), loopargs_t * loopargs)
1130{
1131 int job_op_count = 0;
1132 int total_op_count = 0;
1133 int num_inprogress = 0;
1134 int error = 0, i = 0, ret = 0;
1135 OSSL_ASYNC_FD job_fd = 0;
1136 size_t num_job_fds = 0;
1137
1138 if (async_jobs == 0) {
1139 return loop_function((void *)&loopargs);
1140 }
1141
1142 for (i = 0; i < async_jobs && !error; i++) {
1143 loopargs_t *looparg_item = loopargs + i;
1144
1145 /* Copy pointer content (looparg_t item address) into async context */
1146 ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
1147 &job_op_count, loop_function,
1148 (void *)&looparg_item, sizeof(looparg_item));
1149 switch (ret) {
1150 case ASYNC_PAUSE:
1151 ++num_inprogress;
1152 break;
1153 case ASYNC_FINISH:
1154 if (job_op_count == -1) {
1155 error = 1;
1156 } else {
1157 total_op_count += job_op_count;
1158 }
1159 break;
1160 case ASYNC_NO_JOBS:
1161 case ASYNC_ERR:
1162 BIO_printf(bio_err, "Failure in the job\n");
1163 ERR_print_errors(bio_err);
1164 error = 1;
1165 break;
1166 }
1167 }
1168
1169 while (num_inprogress > 0) {
1170#if defined(OPENSSL_SYS_WINDOWS)
1171 DWORD avail = 0;
1172#elif defined(OPENSSL_SYS_UNIX)
1173 int select_result = 0;
1174 OSSL_ASYNC_FD max_fd = 0;
1175 fd_set waitfdset;
1176
1177 FD_ZERO(&waitfdset);
1178
1179 for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
1180 if (loopargs[i].inprogress_job == NULL)
1181 continue;
1182
1183 if (!ASYNC_WAIT_CTX_get_all_fds
1184 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1185 || num_job_fds > 1) {
1186 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1187 ERR_print_errors(bio_err);
1188 error = 1;
1189 break;
1190 }
1191 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1192 &num_job_fds);
1193 FD_SET(job_fd, &waitfdset);
1194 if (job_fd > max_fd)
1195 max_fd = job_fd;
1196 }
1197
1198 if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
1199 BIO_printf(bio_err,
1200 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1201 "Decrease the value of async_jobs\n",
1202 max_fd, FD_SETSIZE);
1203 ERR_print_errors(bio_err);
1204 error = 1;
1205 break;
1206 }
1207
1208 select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
1209 if (select_result == -1 && errno == EINTR)
1210 continue;
1211
1212 if (select_result == -1) {
1213 BIO_printf(bio_err, "Failure in the select\n");
1214 ERR_print_errors(bio_err);
1215 error = 1;
1216 break;
1217 }
1218
1219 if (select_result == 0)
1220 continue;
1221#endif
1222
1223 for (i = 0; i < async_jobs; i++) {
1224 if (loopargs[i].inprogress_job == NULL)
1225 continue;
1226
1227 if (!ASYNC_WAIT_CTX_get_all_fds
1228 (loopargs[i].wait_ctx, NULL, &num_job_fds)
1229 || num_job_fds > 1) {
1230 BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
1231 ERR_print_errors(bio_err);
1232 error = 1;
1233 break;
1234 }
1235 ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
1236 &num_job_fds);
1237
1238#if defined(OPENSSL_SYS_UNIX)
1239 if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
1240 continue;
1241#elif defined(OPENSSL_SYS_WINDOWS)
1242 if (num_job_fds == 1
1243 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
1244 && avail > 0)
1245 continue;
1246#endif
1247
1248 ret = ASYNC_start_job(&loopargs[i].inprogress_job,
1249 loopargs[i].wait_ctx, &job_op_count,
1250 loop_function, (void *)(loopargs + i),
1251 sizeof(loopargs_t));
1252 switch (ret) {
1253 case ASYNC_PAUSE:
1254 break;
1255 case ASYNC_FINISH:
1256 if (job_op_count == -1) {
1257 error = 1;
1258 } else {
1259 total_op_count += job_op_count;
1260 }
1261 --num_inprogress;
1262 loopargs[i].inprogress_job = NULL;
1263 break;
1264 case ASYNC_NO_JOBS:
1265 case ASYNC_ERR:
1266 --num_inprogress;
1267 loopargs[i].inprogress_job = NULL;
1268 BIO_printf(bio_err, "Failure in the job\n");
1269 ERR_print_errors(bio_err);
1270 error = 1;
1271 break;
1272 }
1273 }
1274 }
1275
1276 return error ? -1 : total_op_count;
1277}
1278
1279typedef struct ec_curve_st {
1280 const char *name;
1281 unsigned int nid;
1282 unsigned int bits;
1283 size_t sigsize; /* only used for EdDSA curves */
1284} EC_CURVE;
1285
1286static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
1287{
1288 EVP_PKEY_CTX *kctx = NULL;
1289 EVP_PKEY *key = NULL;
1290
1291 /* Ensure that the error queue is empty */
1292 if (ERR_peek_error()) {
1293 BIO_printf(bio_err,
1294 "WARNING: the error queue contains previous unhandled errors.\n");
1295 ERR_print_errors(bio_err);
1296 }
1297
1298 /*
1299 * Let's try to create a ctx directly from the NID: this works for
1300 * curves like Curve25519 that are not implemented through the low
1301 * level EC interface.
1302 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1303 * then we set the curve by NID before deriving the actual keygen
1304 * ctx for that specific curve.
1305 */
1306 kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL);
1307 if (kctx == NULL) {
1308 EVP_PKEY_CTX *pctx = NULL;
1309 EVP_PKEY *params = NULL;
1310 /*
1311 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1312 * "int_ctx_new:unsupported algorithm" error was added to the
1313 * error queue.
1314 * We remove it from the error queue as we are handling it.
1315 */
1316 unsigned long error = ERR_peek_error();
1317
1318 if (error == ERR_peek_last_error() /* oldest and latest errors match */
1319 /* check that the error origin matches */
1320 && ERR_GET_LIB(error) == ERR_LIB_EVP
1321 && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
1322 || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
1323 ERR_get_error(); /* pop error from queue */
1324 if (ERR_peek_error()) {
1325 BIO_printf(bio_err,
1326 "Unhandled error in the error queue during EC key setup.\n");
1327 ERR_print_errors(bio_err);
1328 return NULL;
1329 }
1330
1331 /* Create the context for parameter generation */
1332 if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
1333 || EVP_PKEY_paramgen_init(pctx) <= 0
1334 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1335 curve->nid) <= 0
1336 || EVP_PKEY_paramgen(pctx, &params) <= 0) {
1337 BIO_printf(bio_err, "EC params init failure.\n");
1338 ERR_print_errors(bio_err);
1339 EVP_PKEY_CTX_free(pctx);
1340 return NULL;
1341 }
1342 EVP_PKEY_CTX_free(pctx);
1343
1344 /* Create the context for the key generation */
1345 kctx = EVP_PKEY_CTX_new(params, NULL);
1346 EVP_PKEY_free(params);
1347 }
1348 if (kctx == NULL
1349 || EVP_PKEY_keygen_init(kctx) <= 0
1350 || EVP_PKEY_keygen(kctx, &key) <= 0) {
1351 BIO_printf(bio_err, "EC key generation failure.\n");
1352 ERR_print_errors(bio_err);
1353 key = NULL;
1354 }
1355 EVP_PKEY_CTX_free(kctx);
1356 return key;
1357}
1358
1359#define stop_it(do_it, test_num)\
1360 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1361
1362int speed_main(int argc, char **argv)
1363{
1364 CONF *conf = NULL;
1365 ENGINE *e = NULL;
1366 loopargs_t *loopargs = NULL;
1367 const char *prog;
1368 const char *engine_id = NULL;
1369 EVP_CIPHER *evp_cipher = NULL;
1370 EVP_MAC *mac = NULL;
1371 double d = 0.0;
1372 OPTION_CHOICE o;
1373 int async_init = 0, multiblock = 0, pr_header = 0;
1374 uint8_t doit[ALGOR_NUM] = { 0 };
1375 int ret = 1, misalign = 0, lengths_single = 0, aead = 0;
1376 long count = 0;
1377 unsigned int size_num = SIZE_NUM;
1378 unsigned int i, k, loopargs_len = 0, async_jobs = 0;
1379 int keylen;
1380 int buflen;
1381 BIGNUM *bn = NULL;
1382 EVP_PKEY_CTX *genctx = NULL;
1383#ifndef NO_FORK
1384 int multi = 0;
1385#endif
1386 long op_count = 1;
1387 openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
1388 ECDSA_SECONDS, ECDH_SECONDS,
1389 EdDSA_SECONDS, SM2_SECONDS,
1390 FFDH_SECONDS };
1391
1392 static const unsigned char key32[32] = {
1393 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1394 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1395 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1396 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1397 };
1398 static const unsigned char deskey[] = {
1399 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1400 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1401 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1402 };
1403 static const struct {
1404 const unsigned char *data;
1405 unsigned int length;
1406 unsigned int bits;
1407 } rsa_keys[] = {
1408 { test512, sizeof(test512), 512 },
1409 { test1024, sizeof(test1024), 1024 },
1410 { test2048, sizeof(test2048), 2048 },
1411 { test3072, sizeof(test3072), 3072 },
1412 { test4096, sizeof(test4096), 4096 },
1413 { test7680, sizeof(test7680), 7680 },
1414 { test15360, sizeof(test15360), 15360 }
1415 };
1416 uint8_t rsa_doit[RSA_NUM] = { 0 };
1417 int primes = RSA_DEFAULT_PRIME_NUM;
1418#ifndef OPENSSL_NO_DH
1419 typedef struct ffdh_params_st {
1420 const char *name;
1421 unsigned int nid;
1422 unsigned int bits;
1423 } FFDH_PARAMS;
1424
1425 static const FFDH_PARAMS ffdh_params[FFDH_NUM] = {
1426 {"ffdh2048", NID_ffdhe2048, 2048},
1427 {"ffdh3072", NID_ffdhe3072, 3072},
1428 {"ffdh4096", NID_ffdhe4096, 4096},
1429 {"ffdh6144", NID_ffdhe6144, 6144},
1430 {"ffdh8192", NID_ffdhe8192, 8192}
1431 };
1432 uint8_t ffdh_doit[FFDH_NUM] = { 0 };
1433
1434#endif /* OPENSSL_NO_DH */
1435 static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
1436 uint8_t dsa_doit[DSA_NUM] = { 0 };
1437 /*
1438 * We only test over the following curves as they are representative, To
1439 * add tests over more curves, simply add the curve NID and curve name to
1440 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1441 * lists accordingly.
1442 */
1443 static const EC_CURVE ec_curves[EC_NUM] = {
1444 /* Prime Curves */
1445 {"secp160r1", NID_secp160r1, 160},
1446 {"nistp192", NID_X9_62_prime192v1, 192},
1447 {"nistp224", NID_secp224r1, 224},
1448 {"nistp256", NID_X9_62_prime256v1, 256},
1449 {"nistp384", NID_secp384r1, 384},
1450 {"nistp521", NID_secp521r1, 521},
1451#ifndef OPENSSL_NO_EC2M
1452 /* Binary Curves */
1453 {"nistk163", NID_sect163k1, 163},
1454 {"nistk233", NID_sect233k1, 233},
1455 {"nistk283", NID_sect283k1, 283},
1456 {"nistk409", NID_sect409k1, 409},
1457 {"nistk571", NID_sect571k1, 571},
1458 {"nistb163", NID_sect163r2, 163},
1459 {"nistb233", NID_sect233r1, 233},
1460 {"nistb283", NID_sect283r1, 283},
1461 {"nistb409", NID_sect409r1, 409},
1462 {"nistb571", NID_sect571r1, 571},
1463#endif
1464 {"brainpoolP256r1", NID_brainpoolP256r1, 256},
1465 {"brainpoolP256t1", NID_brainpoolP256t1, 256},
1466 {"brainpoolP384r1", NID_brainpoolP384r1, 384},
1467 {"brainpoolP384t1", NID_brainpoolP384t1, 384},
1468 {"brainpoolP512r1", NID_brainpoolP512r1, 512},
1469 {"brainpoolP512t1", NID_brainpoolP512t1, 512},
1470 /* Other and ECDH only ones */
1471 {"X25519", NID_X25519, 253},
1472 {"X448", NID_X448, 448}
1473 };
1474 static const EC_CURVE ed_curves[EdDSA_NUM] = {
1475 /* EdDSA */
1476 {"Ed25519", NID_ED25519, 253, 64},
1477 {"Ed448", NID_ED448, 456, 114}
1478 };
1479#ifndef OPENSSL_NO_SM2
1480 static const EC_CURVE sm2_curves[SM2_NUM] = {
1481 /* SM2 */
1482 {"CurveSM2", NID_sm2, 256}
1483 };
1484 uint8_t sm2_doit[SM2_NUM] = { 0 };
1485#endif
1486 uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
1487 uint8_t ecdh_doit[EC_NUM] = { 0 };
1488 uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
1489
1490 /* checks declared curves against choices list. */
1491 OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
1492 OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
1493
1494 OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
1495 OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
1496
1497 OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
1498 OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
1499
1500#ifndef OPENSSL_NO_SM2
1501 OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
1502 OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
1503#endif
1504
1505 prog = opt_init(argc, argv, speed_options);
1506 while ((o = opt_next()) != OPT_EOF) {
1507 switch (o) {
1508 case OPT_EOF:
1509 case OPT_ERR:
1510 opterr:
1511 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1512 goto end;
1513 case OPT_HELP:
1514 opt_help(speed_options);
1515 ret = 0;
1516 goto end;
1517 case OPT_ELAPSED:
1518 usertime = 0;
1519 break;
1520 case OPT_EVP:
1521 if (doit[D_EVP]) {
1522 BIO_printf(bio_err, "%s: -evp option cannot be used more than once\n", prog);
1523 goto opterr;
1524 }
1525 ERR_set_mark();
1526 if (!opt_cipher_silent(opt_arg(), &evp_cipher)) {
1527 if (have_md(opt_arg()))
1528 evp_md_name = opt_arg();
1529 }
1530 if (evp_cipher == NULL && evp_md_name == NULL) {
1531 ERR_clear_last_mark();
1532 BIO_printf(bio_err,
1533 "%s: %s is an unknown cipher or digest\n",
1534 prog, opt_arg());
1535 goto end;
1536 }
1537 ERR_pop_to_mark();
1538 doit[D_EVP] = 1;
1539 break;
1540 case OPT_HMAC:
1541 if (!have_md(opt_arg())) {
1542 BIO_printf(bio_err, "%s: %s is an unknown digest\n",
1543 prog, opt_arg());
1544 goto end;
1545 }
1546 evp_mac_mdname = opt_arg();
1547 doit[D_HMAC] = 1;
1548 break;
1549 case OPT_CMAC:
1550 if (!have_cipher(opt_arg())) {
1551 BIO_printf(bio_err, "%s: %s is an unknown cipher\n",
1552 prog, opt_arg());
1553 goto end;
1554 }
1555 evp_mac_ciphername = opt_arg();
1556 doit[D_EVP_CMAC] = 1;
1557 break;
1558 case OPT_DECRYPT:
1559 decrypt = 1;
1560 break;
1561 case OPT_ENGINE:
1562 /*
1563 * In a forked execution, an engine might need to be
1564 * initialised by each child process, not by the parent.
1565 * So store the name here and run setup_engine() later on.
1566 */
1567 engine_id = opt_arg();
1568 break;
1569 case OPT_MULTI:
1570#ifndef NO_FORK
1571 multi = atoi(opt_arg());
1572 if ((size_t)multi >= SIZE_MAX / sizeof(int)) {
1573 BIO_printf(bio_err, "%s: multi argument too large\n", prog);
1574 return 0;
1575 }
1576#endif
1577 break;
1578 case OPT_ASYNCJOBS:
1579#ifndef OPENSSL_NO_ASYNC
1580 async_jobs = atoi(opt_arg());
1581 if (!ASYNC_is_capable()) {
1582 BIO_printf(bio_err,
1583 "%s: async_jobs specified but async not supported\n",
1584 prog);
1585 goto opterr;
1586 }
1587 if (async_jobs > 99999) {
1588 BIO_printf(bio_err, "%s: too many async_jobs\n", prog);
1589 goto opterr;
1590 }
1591#endif
1592 break;
1593 case OPT_MISALIGN:
1594 misalign = opt_int_arg();
1595 if (misalign > MISALIGN) {
1596 BIO_printf(bio_err,
1597 "%s: Maximum offset is %d\n", prog, MISALIGN);
1598 goto opterr;
1599 }
1600 break;
1601 case OPT_MR:
1602 mr = 1;
1603 break;
1604 case OPT_MB:
1605 multiblock = 1;
1606#ifdef OPENSSL_NO_MULTIBLOCK
1607 BIO_printf(bio_err,
1608 "%s: -mb specified but multi-block support is disabled\n",
1609 prog);
1610 goto end;
1611#endif
1612 break;
1613 case OPT_R_CASES:
1614 if (!opt_rand(o))
1615 goto end;
1616 break;
1617 case OPT_PROV_CASES:
1618 if (!opt_provider(o))
1619 goto end;
1620 break;
1621 case OPT_CONFIG:
1622 conf = app_load_config_modules(opt_arg());
1623 if (conf == NULL)
1624 goto end;
1625 break;
1626 case OPT_PRIMES:
1627 primes = opt_int_arg();
1628 break;
1629 case OPT_SECONDS:
1630 seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
1631 = seconds.ecdh = seconds.eddsa
1632 = seconds.sm2 = seconds.ffdh = atoi(opt_arg());
1633 break;
1634 case OPT_BYTES:
1635 lengths_single = atoi(opt_arg());
1636 lengths = &lengths_single;
1637 size_num = 1;
1638 break;
1639 case OPT_AEAD:
1640 aead = 1;
1641 break;
1642 case OPT_MLOCK:
1643 domlock = 1;
1644#if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
1645 BIO_printf(bio_err,
1646 "%s: -mlock not supported on this platform\n",
1647 prog);
1648 goto end;
1649#endif
1650 break;
1651 }
1652 }
1653
1654 /* Remaining arguments are algorithms. */
1655 argc = opt_num_rest();
1656 argv = opt_rest();
1657
1658 if (!app_RAND_load())
1659 goto end;
1660
1661 for (; *argv; argv++) {
1662 const char *algo = *argv;
1663
1664 if (opt_found(algo, doit_choices, &i)) {
1665 doit[i] = 1;
1666 continue;
1667 }
1668 if (strcmp(algo, "des") == 0) {
1669 doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
1670 continue;
1671 }
1672 if (strcmp(algo, "sha") == 0) {
1673 doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
1674 continue;
1675 }
1676#ifndef OPENSSL_NO_DEPRECATED_3_0
1677 if (strcmp(algo, "openssl") == 0) /* just for compatibility */
1678 continue;
1679#endif
1680 if (strncmp(algo, "rsa", 3) == 0) {
1681 if (algo[3] == '\0') {
1682 memset(rsa_doit, 1, sizeof(rsa_doit));
1683 continue;
1684 }
1685 if (opt_found(algo, rsa_choices, &i)) {
1686 rsa_doit[i] = 1;
1687 continue;
1688 }
1689 }
1690#ifndef OPENSSL_NO_DH
1691 if (strncmp(algo, "ffdh", 4) == 0) {
1692 if (algo[4] == '\0') {
1693 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1694 continue;
1695 }
1696 if (opt_found(algo, ffdh_choices, &i)) {
1697 ffdh_doit[i] = 2;
1698 continue;
1699 }
1700 }
1701#endif
1702 if (strncmp(algo, "dsa", 3) == 0) {
1703 if (algo[3] == '\0') {
1704 memset(dsa_doit, 1, sizeof(dsa_doit));
1705 continue;
1706 }
1707 if (opt_found(algo, dsa_choices, &i)) {
1708 dsa_doit[i] = 2;
1709 continue;
1710 }
1711 }
1712 if (strcmp(algo, "aes") == 0) {
1713 doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
1714 continue;
1715 }
1716 if (strcmp(algo, "camellia") == 0) {
1717 doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
1718 continue;
1719 }
1720 if (strncmp(algo, "ecdsa", 5) == 0) {
1721 if (algo[5] == '\0') {
1722 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1723 continue;
1724 }
1725 if (opt_found(algo, ecdsa_choices, &i)) {
1726 ecdsa_doit[i] = 2;
1727 continue;
1728 }
1729 }
1730 if (strncmp(algo, "ecdh", 4) == 0) {
1731 if (algo[4] == '\0') {
1732 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1733 continue;
1734 }
1735 if (opt_found(algo, ecdh_choices, &i)) {
1736 ecdh_doit[i] = 2;
1737 continue;
1738 }
1739 }
1740 if (strcmp(algo, "eddsa") == 0) {
1741 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1742 continue;
1743 }
1744 if (opt_found(algo, eddsa_choices, &i)) {
1745 eddsa_doit[i] = 2;
1746 continue;
1747 }
1748#ifndef OPENSSL_NO_SM2
1749 if (strcmp(algo, "sm2") == 0) {
1750 memset(sm2_doit, 1, sizeof(sm2_doit));
1751 continue;
1752 }
1753 if (opt_found(algo, sm2_choices, &i)) {
1754 sm2_doit[i] = 2;
1755 continue;
1756 }
1757#endif
1758 BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, algo);
1759 goto end;
1760 }
1761
1762 /* Sanity checks */
1763 if (aead) {
1764 if (evp_cipher == NULL) {
1765 BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n");
1766 goto end;
1767 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1768 EVP_CIPH_FLAG_AEAD_CIPHER)) {
1769 BIO_printf(bio_err, "%s is not an AEAD cipher\n",
1770 EVP_CIPHER_get0_name(evp_cipher));
1771 goto end;
1772 }
1773 }
1774 if (multiblock) {
1775 if (evp_cipher == NULL) {
1776 BIO_printf(bio_err, "-mb can be used only with a multi-block"
1777 " capable cipher\n");
1778 goto end;
1779 } else if (!(EVP_CIPHER_get_flags(evp_cipher) &
1780 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
1781 BIO_printf(bio_err, "%s is not a multi-block capable\n",
1782 EVP_CIPHER_get0_name(evp_cipher));
1783 goto end;
1784 } else if (async_jobs > 0) {
1785 BIO_printf(bio_err, "Async mode is not supported with -mb");
1786 goto end;
1787 }
1788 }
1789
1790 /* Initialize the job pool if async mode is enabled */
1791 if (async_jobs > 0) {
1792 async_init = ASYNC_init_thread(async_jobs, async_jobs);
1793 if (!async_init) {
1794 BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
1795 goto end;
1796 }
1797 }
1798
1799 loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
1800 loopargs =
1801 app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
1802 memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
1803
1804 buflen = lengths[size_num - 1];
1805 if (buflen < 36) /* size of random vector in RSA benchmark */
1806 buflen = 36;
1807 if (INT_MAX - (MAX_MISALIGNMENT + 1) < buflen) {
1808 BIO_printf(bio_err, "Error: buffer size too large\n");
1809 goto end;
1810 }
1811 buflen += MAX_MISALIGNMENT + 1;
1812 for (i = 0; i < loopargs_len; i++) {
1813 if (async_jobs > 0) {
1814 loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
1815 if (loopargs[i].wait_ctx == NULL) {
1816 BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
1817 goto end;
1818 }
1819 }
1820
1821 loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
1822 loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
1823
1824 /* Align the start of buffers on a 64 byte boundary */
1825 loopargs[i].buf = loopargs[i].buf_malloc + misalign;
1826 loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
1827 loopargs[i].buflen = buflen - misalign;
1828 loopargs[i].sigsize = buflen - misalign;
1829 loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
1830 loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
1831#ifndef OPENSSL_NO_DH
1832 loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a");
1833 loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b");
1834#endif
1835 }
1836
1837#ifndef NO_FORK
1838 if (multi && do_multi(multi, size_num))
1839 goto show_res;
1840#endif
1841
1842 for (i = 0; i < loopargs_len; ++i) {
1843 if (domlock) {
1844#if defined(_WIN32)
1845 (void)VirtualLock(loopargs[i].buf_malloc, buflen);
1846 (void)VirtualLock(loopargs[i].buf2_malloc, buflen);
1847#elif defined(OPENSSL_SYS_LINUX)
1848 (void)mlock(loopargs[i].buf_malloc, buflen);
1849 (void)mlock(loopargs[i].buf_malloc, buflen);
1850#endif
1851 }
1852 memset(loopargs[i].buf_malloc, 0, buflen);
1853 memset(loopargs[i].buf2_malloc, 0, buflen);
1854 }
1855
1856 /* Initialize the engine after the fork */
1857 e = setup_engine(engine_id, 0);
1858
1859 /* No parameters; turn on everything. */
1860 if (argc == 0 && !doit[D_EVP] && !doit[D_HMAC] && !doit[D_EVP_CMAC]) {
1861 memset(doit, 1, sizeof(doit));
1862 doit[D_EVP] = doit[D_EVP_CMAC] = 0;
1863 ERR_set_mark();
1864 for (i = D_MD2; i <= D_WHIRLPOOL; i++) {
1865 if (!have_md(names[i]))
1866 doit[i] = 0;
1867 }
1868 for (i = D_CBC_DES; i <= D_CBC_256_CML; i++) {
1869 if (!have_cipher(names[i]))
1870 doit[i] = 0;
1871 }
1872 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1873 app_get0_propq())) != NULL) {
1874 EVP_MAC_free(mac);
1875 mac = NULL;
1876 } else {
1877 doit[D_GHASH] = 0;
1878 }
1879 if ((mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1880 app_get0_propq())) != NULL) {
1881 EVP_MAC_free(mac);
1882 mac = NULL;
1883 } else {
1884 doit[D_HMAC] = 0;
1885 }
1886 ERR_pop_to_mark();
1887 memset(rsa_doit, 1, sizeof(rsa_doit));
1888#ifndef OPENSSL_NO_DH
1889 memset(ffdh_doit, 1, sizeof(ffdh_doit));
1890#endif
1891 memset(dsa_doit, 1, sizeof(dsa_doit));
1892 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
1893 memset(ecdh_doit, 1, sizeof(ecdh_doit));
1894 memset(eddsa_doit, 1, sizeof(eddsa_doit));
1895#ifndef OPENSSL_NO_SM2
1896 memset(sm2_doit, 1, sizeof(sm2_doit));
1897#endif
1898 }
1899 for (i = 0; i < ALGOR_NUM; i++)
1900 if (doit[i])
1901 pr_header++;
1902
1903 if (usertime == 0 && !mr)
1904 BIO_printf(bio_err,
1905 "You have chosen to measure elapsed time "
1906 "instead of user CPU time.\n");
1907
1908#if SIGALRM > 0
1909 signal(SIGALRM, alarmed);
1910#endif
1911
1912 if (doit[D_MD2]) {
1913 for (testnum = 0; testnum < size_num; testnum++) {
1914 print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
1915 seconds.sym);
1916 Time_F(START);
1917 count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
1918 d = Time_F(STOP);
1919 print_result(D_MD2, testnum, count, d);
1920 if (count < 0)
1921 break;
1922 }
1923 }
1924
1925 if (doit[D_MDC2]) {
1926 for (testnum = 0; testnum < size_num; testnum++) {
1927 print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
1928 seconds.sym);
1929 Time_F(START);
1930 count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
1931 d = Time_F(STOP);
1932 print_result(D_MDC2, testnum, count, d);
1933 if (count < 0)
1934 break;
1935 }
1936 }
1937
1938 if (doit[D_MD4]) {
1939 for (testnum = 0; testnum < size_num; testnum++) {
1940 print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
1941 seconds.sym);
1942 Time_F(START);
1943 count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
1944 d = Time_F(STOP);
1945 print_result(D_MD4, testnum, count, d);
1946 if (count < 0)
1947 break;
1948 }
1949 }
1950
1951 if (doit[D_MD5]) {
1952 for (testnum = 0; testnum < size_num; testnum++) {
1953 print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
1954 seconds.sym);
1955 Time_F(START);
1956 count = run_benchmark(async_jobs, MD5_loop, loopargs);
1957 d = Time_F(STOP);
1958 print_result(D_MD5, testnum, count, d);
1959 if (count < 0)
1960 break;
1961 }
1962 }
1963
1964 if (doit[D_SHA1]) {
1965 for (testnum = 0; testnum < size_num; testnum++) {
1966 print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
1967 seconds.sym);
1968 Time_F(START);
1969 count = run_benchmark(async_jobs, SHA1_loop, loopargs);
1970 d = Time_F(STOP);
1971 print_result(D_SHA1, testnum, count, d);
1972 if (count < 0)
1973 break;
1974 }
1975 }
1976
1977 if (doit[D_SHA256]) {
1978 for (testnum = 0; testnum < size_num; testnum++) {
1979 print_message(names[D_SHA256], c[D_SHA256][testnum],
1980 lengths[testnum], seconds.sym);
1981 Time_F(START);
1982 count = run_benchmark(async_jobs, SHA256_loop, loopargs);
1983 d = Time_F(STOP);
1984 print_result(D_SHA256, testnum, count, d);
1985 if (count < 0)
1986 break;
1987 }
1988 }
1989
1990 if (doit[D_SHA512]) {
1991 for (testnum = 0; testnum < size_num; testnum++) {
1992 print_message(names[D_SHA512], c[D_SHA512][testnum],
1993 lengths[testnum], seconds.sym);
1994 Time_F(START);
1995 count = run_benchmark(async_jobs, SHA512_loop, loopargs);
1996 d = Time_F(STOP);
1997 print_result(D_SHA512, testnum, count, d);
1998 if (count < 0)
1999 break;
2000 }
2001 }
2002
2003 if (doit[D_WHIRLPOOL]) {
2004 for (testnum = 0; testnum < size_num; testnum++) {
2005 print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
2006 lengths[testnum], seconds.sym);
2007 Time_F(START);
2008 count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
2009 d = Time_F(STOP);
2010 print_result(D_WHIRLPOOL, testnum, count, d);
2011 if (count < 0)
2012 break;
2013 }
2014 }
2015
2016 if (doit[D_RMD160]) {
2017 for (testnum = 0; testnum < size_num; testnum++) {
2018 print_message(names[D_RMD160], c[D_RMD160][testnum],
2019 lengths[testnum], seconds.sym);
2020 Time_F(START);
2021 count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
2022 d = Time_F(STOP);
2023 print_result(D_RMD160, testnum, count, d);
2024 if (count < 0)
2025 break;
2026 }
2027 }
2028
2029 if (doit[D_HMAC]) {
2030 static const char hmac_key[] = "This is a key...";
2031 int len = strlen(hmac_key);
2032 OSSL_PARAM params[3];
2033
2034 mac = EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
2035 if (mac == NULL || evp_mac_mdname == NULL)
2036 goto end;
2037
2038 evp_hmac_name = app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname),
2039 "HMAC name");
2040 sprintf(evp_hmac_name, "hmac(%s)", evp_mac_mdname);
2041 names[D_HMAC] = evp_hmac_name;
2042
2043 params[0] =
2044 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
2045 evp_mac_mdname, 0);
2046 params[1] =
2047 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2048 (char *)hmac_key, len);
2049 params[2] = OSSL_PARAM_construct_end();
2050
2051 for (i = 0; i < loopargs_len; i++) {
2052 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2053 if (loopargs[i].mctx == NULL)
2054 goto end;
2055
2056 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2057 goto skip_hmac; /* Digest not found */
2058 }
2059 for (testnum = 0; testnum < size_num; testnum++) {
2060 print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
2061 seconds.sym);
2062 Time_F(START);
2063 count = run_benchmark(async_jobs, HMAC_loop, loopargs);
2064 d = Time_F(STOP);
2065 print_result(D_HMAC, testnum, count, d);
2066 if (count < 0)
2067 break;
2068 }
2069 for (i = 0; i < loopargs_len; i++)
2070 EVP_MAC_CTX_free(loopargs[i].mctx);
2071 EVP_MAC_free(mac);
2072 mac = NULL;
2073 }
2074skip_hmac:
2075 if (doit[D_CBC_DES]) {
2076 int st = 1;
2077
2078 for (i = 0; st && i < loopargs_len; i++) {
2079 loopargs[i].ctx = init_evp_cipher_ctx("des-cbc", deskey,
2080 sizeof(deskey) / 3);
2081 st = loopargs[i].ctx != NULL;
2082 }
2083 algindex = D_CBC_DES;
2084 for (testnum = 0; st && testnum < size_num; testnum++) {
2085 print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
2086 lengths[testnum], seconds.sym);
2087 Time_F(START);
2088 count = run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2089 d = Time_F(STOP);
2090 print_result(D_CBC_DES, testnum, count, d);
2091 }
2092 for (i = 0; i < loopargs_len; i++)
2093 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2094 }
2095
2096 if (doit[D_EDE3_DES]) {
2097 int st = 1;
2098
2099 for (i = 0; st && i < loopargs_len; i++) {
2100 loopargs[i].ctx = init_evp_cipher_ctx("des-ede3-cbc", deskey,
2101 sizeof(deskey));
2102 st = loopargs[i].ctx != NULL;
2103 }
2104 algindex = D_EDE3_DES;
2105 for (testnum = 0; st && testnum < size_num; testnum++) {
2106 print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
2107 lengths[testnum], seconds.sym);
2108 Time_F(START);
2109 count =
2110 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2111 d = Time_F(STOP);
2112 print_result(D_EDE3_DES, testnum, count, d);
2113 }
2114 for (i = 0; i < loopargs_len; i++)
2115 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2116 }
2117
2118 for (k = 0; k < 3; k++) {
2119 algindex = D_CBC_128_AES + k;
2120 if (doit[algindex]) {
2121 int st = 1;
2122
2123 keylen = 16 + k * 8;
2124 for (i = 0; st && i < loopargs_len; i++) {
2125 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2126 key32, keylen);
2127 st = loopargs[i].ctx != NULL;
2128 }
2129
2130 for (testnum = 0; st && testnum < size_num; testnum++) {
2131 print_message(names[algindex], c[algindex][testnum],
2132 lengths[testnum], seconds.sym);
2133 Time_F(START);
2134 count =
2135 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2136 d = Time_F(STOP);
2137 print_result(algindex, testnum, count, d);
2138 }
2139 for (i = 0; i < loopargs_len; i++)
2140 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2141 }
2142 }
2143
2144 for (k = 0; k < 3; k++) {
2145 algindex = D_CBC_128_CML + k;
2146 if (doit[algindex]) {
2147 int st = 1;
2148
2149 keylen = 16 + k * 8;
2150 for (i = 0; st && i < loopargs_len; i++) {
2151 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2152 key32, keylen);
2153 st = loopargs[i].ctx != NULL;
2154 }
2155
2156 for (testnum = 0; st && testnum < size_num; testnum++) {
2157 print_message(names[algindex], c[algindex][testnum],
2158 lengths[testnum], seconds.sym);
2159 Time_F(START);
2160 count =
2161 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2162 d = Time_F(STOP);
2163 print_result(algindex, testnum, count, d);
2164 }
2165 for (i = 0; i < loopargs_len; i++)
2166 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2167 }
2168 }
2169
2170 for (algindex = D_RC4; algindex <= D_CBC_CAST; algindex++) {
2171 if (doit[algindex]) {
2172 int st = 1;
2173
2174 keylen = 16;
2175 for (i = 0; st && i < loopargs_len; i++) {
2176 loopargs[i].ctx = init_evp_cipher_ctx(names[algindex],
2177 key32, keylen);
2178 st = loopargs[i].ctx != NULL;
2179 }
2180
2181 for (testnum = 0; st && testnum < size_num; testnum++) {
2182 print_message(names[algindex], c[algindex][testnum],
2183 lengths[testnum], seconds.sym);
2184 Time_F(START);
2185 count =
2186 run_benchmark(async_jobs, EVP_Cipher_loop, loopargs);
2187 d = Time_F(STOP);
2188 print_result(algindex, testnum, count, d);
2189 }
2190 for (i = 0; i < loopargs_len; i++)
2191 EVP_CIPHER_CTX_free(loopargs[i].ctx);
2192 }
2193 }
2194 if (doit[D_GHASH]) {
2195 static const char gmac_iv[] = "0123456789ab";
2196 OSSL_PARAM params[3];
2197
2198 mac = EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2199 if (mac == NULL)
2200 goto end;
2201
2202 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2203 "aes-128-gcm", 0);
2204 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV,
2205 (char *)gmac_iv,
2206 sizeof(gmac_iv) - 1);
2207 params[2] = OSSL_PARAM_construct_end();
2208
2209 for (i = 0; i < loopargs_len; i++) {
2210 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2211 if (loopargs[i].mctx == NULL)
2212 goto end;
2213
2214 if (!EVP_MAC_init(loopargs[i].mctx, key32, 16, params))
2215 goto end;
2216 }
2217 for (testnum = 0; testnum < size_num; testnum++) {
2218 print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum],
2219 seconds.sym);
2220 Time_F(START);
2221 count = run_benchmark(async_jobs, GHASH_loop, loopargs);
2222 d = Time_F(STOP);
2223 print_result(D_GHASH, testnum, count, d);
2224 if (count < 0)
2225 break;
2226 }
2227 for (i = 0; i < loopargs_len; i++)
2228 EVP_MAC_CTX_free(loopargs[i].mctx);
2229 EVP_MAC_free(mac);
2230 mac = NULL;
2231 }
2232
2233 if (doit[D_RAND]) {
2234 for (testnum = 0; testnum < size_num; testnum++) {
2235 print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
2236 seconds.sym);
2237 Time_F(START);
2238 count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
2239 d = Time_F(STOP);
2240 print_result(D_RAND, testnum, count, d);
2241 }
2242 }
2243
2244 if (doit[D_EVP]) {
2245 if (evp_cipher != NULL) {
2246 int (*loopfunc) (void *) = EVP_Update_loop;
2247
2248 if (multiblock && (EVP_CIPHER_get_flags(evp_cipher) &
2249 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
2250 multiblock_speed(evp_cipher, lengths_single, &seconds);
2251 ret = 0;
2252 goto end;
2253 }
2254
2255 names[D_EVP] = EVP_CIPHER_get0_name(evp_cipher);
2256
2257 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_CCM_MODE) {
2258 loopfunc = EVP_Update_loop_ccm;
2259 } else if (aead && (EVP_CIPHER_get_flags(evp_cipher) &
2260 EVP_CIPH_FLAG_AEAD_CIPHER)) {
2261 loopfunc = EVP_Update_loop_aead;
2262 if (lengths == lengths_list) {
2263 lengths = aead_lengths_list;
2264 size_num = OSSL_NELEM(aead_lengths_list);
2265 }
2266 }
2267
2268 for (testnum = 0; testnum < size_num; testnum++) {
2269 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2270 seconds.sym);
2271
2272 for (k = 0; k < loopargs_len; k++) {
2273 loopargs[k].ctx = EVP_CIPHER_CTX_new();
2274 if (loopargs[k].ctx == NULL) {
2275 BIO_printf(bio_err, "\nEVP_CIPHER_CTX_new failure\n");
2276 exit(1);
2277 }
2278 if (!EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL,
2279 NULL, iv, decrypt ? 0 : 1)) {
2280 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2281 ERR_print_errors(bio_err);
2282 exit(1);
2283 }
2284
2285 EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
2286
2287 keylen = EVP_CIPHER_CTX_get_key_length(loopargs[k].ctx);
2288 loopargs[k].key = app_malloc(keylen, "evp_cipher key");
2289 EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
2290 if (!EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
2291 loopargs[k].key, NULL, -1)) {
2292 BIO_printf(bio_err, "\nEVP_CipherInit_ex failure\n");
2293 ERR_print_errors(bio_err);
2294 exit(1);
2295 }
2296 OPENSSL_clear_free(loopargs[k].key, keylen);
2297
2298 /* SIV mode only allows for a single Update operation */
2299 if (EVP_CIPHER_get_mode(evp_cipher) == EVP_CIPH_SIV_MODE)
2300 (void)EVP_CIPHER_CTX_ctrl(loopargs[k].ctx,
2301 EVP_CTRL_SET_SPEED, 1, NULL);
2302 }
2303
2304 Time_F(START);
2305 count = run_benchmark(async_jobs, loopfunc, loopargs);
2306 d = Time_F(STOP);
2307 for (k = 0; k < loopargs_len; k++)
2308 EVP_CIPHER_CTX_free(loopargs[k].ctx);
2309 print_result(D_EVP, testnum, count, d);
2310 }
2311 } else if (evp_md_name != NULL) {
2312 names[D_EVP] = evp_md_name;
2313
2314 for (testnum = 0; testnum < size_num; testnum++) {
2315 print_message(names[D_EVP], c[D_EVP][testnum], lengths[testnum],
2316 seconds.sym);
2317 Time_F(START);
2318 count = run_benchmark(async_jobs, EVP_Digest_md_loop, loopargs);
2319 d = Time_F(STOP);
2320 print_result(D_EVP, testnum, count, d);
2321 if (count < 0)
2322 break;
2323 }
2324 }
2325 }
2326
2327 if (doit[D_EVP_CMAC]) {
2328 OSSL_PARAM params[3];
2329 EVP_CIPHER *cipher = NULL;
2330
2331 mac = EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2332 if (mac == NULL || evp_mac_ciphername == NULL)
2333 goto end;
2334 if (!opt_cipher(evp_mac_ciphername, &cipher))
2335 goto end;
2336
2337 keylen = EVP_CIPHER_get_key_length(cipher);
2338 EVP_CIPHER_free(cipher);
2339 if (keylen <= 0 || keylen > (int)sizeof(key32)) {
2340 BIO_printf(bio_err, "\nRequested CMAC cipher with unsupported key length.\n");
2341 goto end;
2342 }
2343 evp_cmac_name = app_malloc(sizeof("cmac()")
2344 + strlen(evp_mac_ciphername), "CMAC name");
2345 sprintf(evp_cmac_name, "cmac(%s)", evp_mac_ciphername);
2346 names[D_EVP_CMAC] = evp_cmac_name;
2347
2348 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER,
2349 evp_mac_ciphername, 0);
2350 params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
2351 (char *)key32, keylen);
2352 params[2] = OSSL_PARAM_construct_end();
2353
2354 for (i = 0; i < loopargs_len; i++) {
2355 loopargs[i].mctx = EVP_MAC_CTX_new(mac);
2356 if (loopargs[i].mctx == NULL)
2357 goto end;
2358
2359 if (!EVP_MAC_CTX_set_params(loopargs[i].mctx, params))
2360 goto end;
2361 }
2362
2363 for (testnum = 0; testnum < size_num; testnum++) {
2364 print_message(names[D_EVP_CMAC], c[D_EVP_CMAC][testnum],
2365 lengths[testnum], seconds.sym);
2366 Time_F(START);
2367 count = run_benchmark(async_jobs, CMAC_loop, loopargs);
2368 d = Time_F(STOP);
2369 print_result(D_EVP_CMAC, testnum, count, d);
2370 if (count < 0)
2371 break;
2372 }
2373 for (i = 0; i < loopargs_len; i++)
2374 EVP_MAC_CTX_free(loopargs[i].mctx);
2375 EVP_MAC_free(mac);
2376 mac = NULL;
2377 }
2378
2379 for (i = 0; i < loopargs_len; i++)
2380 if (RAND_bytes(loopargs[i].buf, 36) <= 0)
2381 goto end;
2382
2383 for (testnum = 0; testnum < RSA_NUM; testnum++) {
2384 EVP_PKEY *rsa_key = NULL;
2385 int st = 0;
2386
2387 if (!rsa_doit[testnum])
2388 continue;
2389
2390 if (primes > RSA_DEFAULT_PRIME_NUM) {
2391 /* we haven't set keys yet, generate multi-prime RSA keys */
2392 bn = BN_new();
2393 st = bn != NULL
2394 && BN_set_word(bn, RSA_F4)
2395 && init_gen_str(&genctx, "RSA", NULL, 0, NULL, NULL)
2396 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx, rsa_keys[testnum].bits) > 0
2397 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx, bn) > 0
2398 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx, primes) > 0
2399 && EVP_PKEY_keygen(genctx, &rsa_key);
2400 BN_free(bn);
2401 bn = NULL;
2402 EVP_PKEY_CTX_free(genctx);
2403 genctx = NULL;
2404 } else {
2405 const unsigned char *p = rsa_keys[testnum].data;
2406
2407 st = (rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
2408 rsa_keys[testnum].length)) != NULL;
2409 }
2410
2411 for (i = 0; st && i < loopargs_len; i++) {
2412 loopargs[i].rsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key, NULL);
2413 loopargs[i].sigsize = loopargs[i].buflen;
2414 if (loopargs[i].rsa_sign_ctx[testnum] == NULL
2415 || EVP_PKEY_sign_init(loopargs[i].rsa_sign_ctx[testnum]) <= 0
2416 || EVP_PKEY_sign(loopargs[i].rsa_sign_ctx[testnum],
2417 loopargs[i].buf2,
2418 &loopargs[i].sigsize,
2419 loopargs[i].buf, 36) <= 0)
2420 st = 0;
2421 }
2422 if (!st) {
2423 BIO_printf(bio_err,
2424 "RSA sign setup failure. No RSA sign will be done.\n");
2425 ERR_print_errors(bio_err);
2426 op_count = 1;
2427 } else {
2428 pkey_print_message("private", "rsa",
2429 rsa_c[testnum][0], rsa_keys[testnum].bits,
2430 seconds.rsa);
2431 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2432 Time_F(START);
2433 count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
2434 d = Time_F(STOP);
2435 BIO_printf(bio_err,
2436 mr ? "+R1:%ld:%d:%.2f\n"
2437 : "%ld %u bits private RSA's in %.2fs\n",
2438 count, rsa_keys[testnum].bits, d);
2439 rsa_results[testnum][0] = (double)count / d;
2440 op_count = count;
2441 }
2442
2443 for (i = 0; st && i < loopargs_len; i++) {
2444 loopargs[i].rsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(rsa_key,
2445 NULL);
2446 if (loopargs[i].rsa_verify_ctx[testnum] == NULL
2447 || EVP_PKEY_verify_init(loopargs[i].rsa_verify_ctx[testnum]) <= 0
2448 || EVP_PKEY_verify(loopargs[i].rsa_verify_ctx[testnum],
2449 loopargs[i].buf2,
2450 loopargs[i].sigsize,
2451 loopargs[i].buf, 36) <= 0)
2452 st = 0;
2453 }
2454 if (!st) {
2455 BIO_printf(bio_err,
2456 "RSA verify setup failure. No RSA verify will be done.\n");
2457 ERR_print_errors(bio_err);
2458 rsa_doit[testnum] = 0;
2459 } else {
2460 pkey_print_message("public", "rsa",
2461 rsa_c[testnum][1], rsa_keys[testnum].bits,
2462 seconds.rsa);
2463 Time_F(START);
2464 count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
2465 d = Time_F(STOP);
2466 BIO_printf(bio_err,
2467 mr ? "+R2:%ld:%d:%.2f\n"
2468 : "%ld %u bits public RSA's in %.2fs\n",
2469 count, rsa_keys[testnum].bits, d);
2470 rsa_results[testnum][1] = (double)count / d;
2471 }
2472
2473 if (op_count <= 1) {
2474 /* if longer than 10s, don't do any more */
2475 stop_it(rsa_doit, testnum);
2476 }
2477 EVP_PKEY_free(rsa_key);
2478 }
2479
2480 for (testnum = 0; testnum < DSA_NUM; testnum++) {
2481 EVP_PKEY *dsa_key = NULL;
2482 int st;
2483
2484 if (!dsa_doit[testnum])
2485 continue;
2486
2487 st = (dsa_key = get_dsa(dsa_bits[testnum])) != NULL;
2488
2489 for (i = 0; st && i < loopargs_len; i++) {
2490 loopargs[i].dsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2491 NULL);
2492 loopargs[i].sigsize = loopargs[i].buflen;
2493 if (loopargs[i].dsa_sign_ctx[testnum] == NULL
2494 || EVP_PKEY_sign_init(loopargs[i].dsa_sign_ctx[testnum]) <= 0
2495
2496 || EVP_PKEY_sign(loopargs[i].dsa_sign_ctx[testnum],
2497 loopargs[i].buf2,
2498 &loopargs[i].sigsize,
2499 loopargs[i].buf, 20) <= 0)
2500 st = 0;
2501 }
2502 if (!st) {
2503 BIO_printf(bio_err,
2504 "DSA sign setup failure. No DSA sign will be done.\n");
2505 ERR_print_errors(bio_err);
2506 op_count = 1;
2507 } else {
2508 pkey_print_message("sign", "dsa",
2509 dsa_c[testnum][0], dsa_bits[testnum],
2510 seconds.dsa);
2511 Time_F(START);
2512 count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
2513 d = Time_F(STOP);
2514 BIO_printf(bio_err,
2515 mr ? "+R3:%ld:%u:%.2f\n"
2516 : "%ld %u bits DSA signs in %.2fs\n",
2517 count, dsa_bits[testnum], d);
2518 dsa_results[testnum][0] = (double)count / d;
2519 op_count = count;
2520 }
2521
2522 for (i = 0; st && i < loopargs_len; i++) {
2523 loopargs[i].dsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(dsa_key,
2524 NULL);
2525 if (loopargs[i].dsa_verify_ctx[testnum] == NULL
2526 || EVP_PKEY_verify_init(loopargs[i].dsa_verify_ctx[testnum]) <= 0
2527 || EVP_PKEY_verify(loopargs[i].dsa_verify_ctx[testnum],
2528 loopargs[i].buf2,
2529 loopargs[i].sigsize,
2530 loopargs[i].buf, 36) <= 0)
2531 st = 0;
2532 }
2533 if (!st) {
2534 BIO_printf(bio_err,
2535 "DSA verify setup failure. No DSA verify will be done.\n");
2536 ERR_print_errors(bio_err);
2537 dsa_doit[testnum] = 0;
2538 } else {
2539 pkey_print_message("verify", "dsa",
2540 dsa_c[testnum][1], dsa_bits[testnum],
2541 seconds.dsa);
2542 Time_F(START);
2543 count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
2544 d = Time_F(STOP);
2545 BIO_printf(bio_err,
2546 mr ? "+R4:%ld:%u:%.2f\n"
2547 : "%ld %u bits DSA verify in %.2fs\n",
2548 count, dsa_bits[testnum], d);
2549 dsa_results[testnum][1] = (double)count / d;
2550 }
2551
2552 if (op_count <= 1) {
2553 /* if longer than 10s, don't do any more */
2554 stop_it(dsa_doit, testnum);
2555 }
2556 EVP_PKEY_free(dsa_key);
2557 }
2558
2559 for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
2560 EVP_PKEY *ecdsa_key = NULL;
2561 int st;
2562
2563 if (!ecdsa_doit[testnum])
2564 continue;
2565
2566 st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
2567
2568 for (i = 0; st && i < loopargs_len; i++) {
2569 loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2570 NULL);
2571 loopargs[i].sigsize = loopargs[i].buflen;
2572 if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
2573 || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
2574
2575 || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
2576 loopargs[i].buf2,
2577 &loopargs[i].sigsize,
2578 loopargs[i].buf, 20) <= 0)
2579 st = 0;
2580 }
2581 if (!st) {
2582 BIO_printf(bio_err,
2583 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2584 ERR_print_errors(bio_err);
2585 op_count = 1;
2586 } else {
2587 pkey_print_message("sign", "ecdsa",
2588 ecdsa_c[testnum][0], ec_curves[testnum].bits,
2589 seconds.ecdsa);
2590 Time_F(START);
2591 count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
2592 d = Time_F(STOP);
2593 BIO_printf(bio_err,
2594 mr ? "+R5:%ld:%u:%.2f\n"
2595 : "%ld %u bits ECDSA signs in %.2fs\n",
2596 count, ec_curves[testnum].bits, d);
2597 ecdsa_results[testnum][0] = (double)count / d;
2598 op_count = count;
2599 }
2600
2601 for (i = 0; st && i < loopargs_len; i++) {
2602 loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
2603 NULL);
2604 if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
2605 || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
2606 || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
2607 loopargs[i].buf2,
2608 loopargs[i].sigsize,
2609 loopargs[i].buf, 20) <= 0)
2610 st = 0;
2611 }
2612 if (!st) {
2613 BIO_printf(bio_err,
2614 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2615 ERR_print_errors(bio_err);
2616 ecdsa_doit[testnum] = 0;
2617 } else {
2618 pkey_print_message("verify", "ecdsa",
2619 ecdsa_c[testnum][1], ec_curves[testnum].bits,
2620 seconds.ecdsa);
2621 Time_F(START);
2622 count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
2623 d = Time_F(STOP);
2624 BIO_printf(bio_err,
2625 mr ? "+R6:%ld:%u:%.2f\n"
2626 : "%ld %u bits ECDSA verify in %.2fs\n",
2627 count, ec_curves[testnum].bits, d);
2628 ecdsa_results[testnum][1] = (double)count / d;
2629 }
2630
2631 if (op_count <= 1) {
2632 /* if longer than 10s, don't do any more */
2633 stop_it(ecdsa_doit, testnum);
2634 }
2635 }
2636
2637 for (testnum = 0; testnum < EC_NUM; testnum++) {
2638 int ecdh_checks = 1;
2639
2640 if (!ecdh_doit[testnum])
2641 continue;
2642
2643 for (i = 0; i < loopargs_len; i++) {
2644 EVP_PKEY_CTX *test_ctx = NULL;
2645 EVP_PKEY_CTX *ctx = NULL;
2646 EVP_PKEY *key_A = NULL;
2647 EVP_PKEY *key_B = NULL;
2648 size_t outlen;
2649 size_t test_outlen;
2650
2651 if ((key_A = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key A */
2652 || (key_B = get_ecdsa(&ec_curves[testnum])) == NULL /* generate secret key B */
2653 || (ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL /* derivation ctx from skeyA */
2654 || EVP_PKEY_derive_init(ctx) <= 0 /* init derivation ctx */
2655 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 /* set peer pubkey in ctx */
2656 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 /* determine max length */
2657 || outlen == 0 /* ensure outlen is a valid size */
2658 || outlen > MAX_ECDH_SIZE /* avoid buffer overflow */) {
2659 ecdh_checks = 0;
2660 BIO_printf(bio_err, "ECDH key generation failure.\n");
2661 ERR_print_errors(bio_err);
2662 op_count = 1;
2663 break;
2664 }
2665
2666 /*
2667 * Here we perform a test run, comparing the output of a*B and b*A;
2668 * we try this here and assume that further EVP_PKEY_derive calls
2669 * never fail, so we can skip checks in the actually benchmarked
2670 * code, for maximum performance.
2671 */
2672 if ((test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL /* test ctx from skeyB */
2673 || EVP_PKEY_derive_init(test_ctx) <= 0 /* init derivation test_ctx */
2674 || EVP_PKEY_derive_set_peer(test_ctx, key_A) <= 0 /* set peer pubkey in test_ctx */
2675 || EVP_PKEY_derive(test_ctx, NULL, &test_outlen) <= 0 /* determine max length */
2676 || EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) <= 0 /* compute a*B */
2677 || EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) <= 0 /* compute b*A */
2678 || test_outlen != outlen /* compare output length */) {
2679 ecdh_checks = 0;
2680 BIO_printf(bio_err, "ECDH computation failure.\n");
2681 ERR_print_errors(bio_err);
2682 op_count = 1;
2683 break;
2684 }
2685
2686 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2687 if (CRYPTO_memcmp(loopargs[i].secret_a,
2688 loopargs[i].secret_b, outlen)) {
2689 ecdh_checks = 0;
2690 BIO_printf(bio_err, "ECDH computations don't match.\n");
2691 ERR_print_errors(bio_err);
2692 op_count = 1;
2693 break;
2694 }
2695
2696 loopargs[i].ecdh_ctx[testnum] = ctx;
2697 loopargs[i].outlen[testnum] = outlen;
2698
2699 EVP_PKEY_free(key_A);
2700 EVP_PKEY_free(key_B);
2701 EVP_PKEY_CTX_free(test_ctx);
2702 test_ctx = NULL;
2703 }
2704 if (ecdh_checks != 0) {
2705 pkey_print_message("", "ecdh",
2706 ecdh_c[testnum][0],
2707 ec_curves[testnum].bits, seconds.ecdh);
2708 Time_F(START);
2709 count =
2710 run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
2711 d = Time_F(STOP);
2712 BIO_printf(bio_err,
2713 mr ? "+R7:%ld:%d:%.2f\n" :
2714 "%ld %u-bits ECDH ops in %.2fs\n", count,
2715 ec_curves[testnum].bits, d);
2716 ecdh_results[testnum][0] = (double)count / d;
2717 op_count = count;
2718 }
2719
2720 if (op_count <= 1) {
2721 /* if longer than 10s, don't do any more */
2722 stop_it(ecdh_doit, testnum);
2723 }
2724 }
2725
2726 for (testnum = 0; testnum < EdDSA_NUM; testnum++) {
2727 int st = 1;
2728 EVP_PKEY *ed_pkey = NULL;
2729 EVP_PKEY_CTX *ed_pctx = NULL;
2730
2731 if (!eddsa_doit[testnum])
2732 continue; /* Ignore Curve */
2733 for (i = 0; i < loopargs_len; i++) {
2734 loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new();
2735 if (loopargs[i].eddsa_ctx[testnum] == NULL) {
2736 st = 0;
2737 break;
2738 }
2739 loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new();
2740 if (loopargs[i].eddsa_ctx2[testnum] == NULL) {
2741 st = 0;
2742 break;
2743 }
2744
2745 if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid,
2746 NULL)) == NULL
2747 || EVP_PKEY_keygen_init(ed_pctx) <= 0
2748 || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
2749 st = 0;
2750 EVP_PKEY_CTX_free(ed_pctx);
2751 break;
2752 }
2753 EVP_PKEY_CTX_free(ed_pctx);
2754
2755 if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL,
2756 NULL, ed_pkey)) {
2757 st = 0;
2758 EVP_PKEY_free(ed_pkey);
2759 break;
2760 }
2761 if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL,
2762 NULL, NULL, ed_pkey)) {
2763 st = 0;
2764 EVP_PKEY_free(ed_pkey);
2765 break;
2766 }
2767
2768 EVP_PKEY_free(ed_pkey);
2769 ed_pkey = NULL;
2770 }
2771 if (st == 0) {
2772 BIO_printf(bio_err, "EdDSA failure.\n");
2773 ERR_print_errors(bio_err);
2774 op_count = 1;
2775 } else {
2776 for (i = 0; i < loopargs_len; i++) {
2777 /* Perform EdDSA signature test */
2778 loopargs[i].sigsize = ed_curves[testnum].sigsize;
2779 st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum],
2780 loopargs[i].buf2, &loopargs[i].sigsize,
2781 loopargs[i].buf, 20);
2782 if (st == 0)
2783 break;
2784 }
2785 if (st == 0) {
2786 BIO_printf(bio_err,
2787 "EdDSA sign failure. No EdDSA sign will be done.\n");
2788 ERR_print_errors(bio_err);
2789 op_count = 1;
2790 } else {
2791 pkey_print_message("sign", ed_curves[testnum].name,
2792 eddsa_c[testnum][0],
2793 ed_curves[testnum].bits, seconds.eddsa);
2794 Time_F(START);
2795 count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs);
2796 d = Time_F(STOP);
2797
2798 BIO_printf(bio_err,
2799 mr ? "+R8:%ld:%u:%s:%.2f\n" :
2800 "%ld %u bits %s signs in %.2fs \n",
2801 count, ed_curves[testnum].bits,
2802 ed_curves[testnum].name, d);
2803 eddsa_results[testnum][0] = (double)count / d;
2804 op_count = count;
2805 }
2806 /* Perform EdDSA verification test */
2807 for (i = 0; i < loopargs_len; i++) {
2808 st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
2809 loopargs[i].buf2, loopargs[i].sigsize,
2810 loopargs[i].buf, 20);
2811 if (st != 1)
2812 break;
2813 }
2814 if (st != 1) {
2815 BIO_printf(bio_err,
2816 "EdDSA verify failure. No EdDSA verify will be done.\n");
2817 ERR_print_errors(bio_err);
2818 eddsa_doit[testnum] = 0;
2819 } else {
2820 pkey_print_message("verify", ed_curves[testnum].name,
2821 eddsa_c[testnum][1],
2822 ed_curves[testnum].bits, seconds.eddsa);
2823 Time_F(START);
2824 count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs);
2825 d = Time_F(STOP);
2826 BIO_printf(bio_err,
2827 mr ? "+R9:%ld:%u:%s:%.2f\n"
2828 : "%ld %u bits %s verify in %.2fs\n",
2829 count, ed_curves[testnum].bits,
2830 ed_curves[testnum].name, d);
2831 eddsa_results[testnum][1] = (double)count / d;
2832 }
2833
2834 if (op_count <= 1) {
2835 /* if longer than 10s, don't do any more */
2836 stop_it(eddsa_doit, testnum);
2837 }
2838 }
2839 }
2840
2841#ifndef OPENSSL_NO_SM2
2842 for (testnum = 0; testnum < SM2_NUM; testnum++) {
2843 int st = 1;
2844 EVP_PKEY *sm2_pkey = NULL;
2845
2846 if (!sm2_doit[testnum])
2847 continue; /* Ignore Curve */
2848 /* Init signing and verification */
2849 for (i = 0; i < loopargs_len; i++) {
2850 EVP_PKEY_CTX *sm2_pctx = NULL;
2851 EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
2852 EVP_PKEY_CTX *pctx = NULL;
2853 st = 0;
2854
2855 loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
2856 loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
2857 if (loopargs[i].sm2_ctx[testnum] == NULL
2858 || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
2859 break;
2860
2861 sm2_pkey = NULL;
2862
2863 st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
2864 || EVP_PKEY_keygen_init(pctx) <= 0
2865 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
2866 sm2_curves[testnum].nid) <= 0
2867 || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
2868 EVP_PKEY_CTX_free(pctx);
2869 if (st == 0)
2870 break;
2871
2872 st = 0; /* set back to zero */
2873 /* attach it sooner to rely on main final cleanup */
2874 loopargs[i].sm2_pkey[testnum] = sm2_pkey;
2875 loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
2876
2877 sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2878 sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
2879 if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
2880 EVP_PKEY_CTX_free(sm2_vfy_pctx);
2881 break;
2882 }
2883
2884 /* attach them directly to respective ctx */
2885 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
2886 EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
2887
2888 /*
2889 * No need to allow user to set an explicit ID here, just use
2890 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2891 */
2892 if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
2893 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
2894 break;
2895
2896 if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
2897 EVP_sm3(), NULL, sm2_pkey))
2898 break;
2899 if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
2900 EVP_sm3(), NULL, sm2_pkey))
2901 break;
2902 st = 1; /* mark loop as succeeded */
2903 }
2904 if (st == 0) {
2905 BIO_printf(bio_err, "SM2 init failure.\n");
2906 ERR_print_errors(bio_err);
2907 op_count = 1;
2908 } else {
2909 for (i = 0; i < loopargs_len; i++) {
2910 /* Perform SM2 signature test */
2911 st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
2912 loopargs[i].buf2, &loopargs[i].sigsize,
2913 loopargs[i].buf, 20);
2914 if (st == 0)
2915 break;
2916 }
2917 if (st == 0) {
2918 BIO_printf(bio_err,
2919 "SM2 sign failure. No SM2 sign will be done.\n");
2920 ERR_print_errors(bio_err);
2921 op_count = 1;
2922 } else {
2923 pkey_print_message("sign", sm2_curves[testnum].name,
2924 sm2_c[testnum][0],
2925 sm2_curves[testnum].bits, seconds.sm2);
2926 Time_F(START);
2927 count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
2928 d = Time_F(STOP);
2929
2930 BIO_printf(bio_err,
2931 mr ? "+R10:%ld:%u:%s:%.2f\n" :
2932 "%ld %u bits %s signs in %.2fs \n",
2933 count, sm2_curves[testnum].bits,
2934 sm2_curves[testnum].name, d);
2935 sm2_results[testnum][0] = (double)count / d;
2936 op_count = count;
2937 }
2938
2939 /* Perform SM2 verification test */
2940 for (i = 0; i < loopargs_len; i++) {
2941 st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
2942 loopargs[i].buf2, loopargs[i].sigsize,
2943 loopargs[i].buf, 20);
2944 if (st != 1)
2945 break;
2946 }
2947 if (st != 1) {
2948 BIO_printf(bio_err,
2949 "SM2 verify failure. No SM2 verify will be done.\n");
2950 ERR_print_errors(bio_err);
2951 sm2_doit[testnum] = 0;
2952 } else {
2953 pkey_print_message("verify", sm2_curves[testnum].name,
2954 sm2_c[testnum][1],
2955 sm2_curves[testnum].bits, seconds.sm2);
2956 Time_F(START);
2957 count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
2958 d = Time_F(STOP);
2959 BIO_printf(bio_err,
2960 mr ? "+R11:%ld:%u:%s:%.2f\n"
2961 : "%ld %u bits %s verify in %.2fs\n",
2962 count, sm2_curves[testnum].bits,
2963 sm2_curves[testnum].name, d);
2964 sm2_results[testnum][1] = (double)count / d;
2965 }
2966
2967 if (op_count <= 1) {
2968 /* if longer than 10s, don't do any more */
2969 for (testnum++; testnum < SM2_NUM; testnum++)
2970 sm2_doit[testnum] = 0;
2971 }
2972 }
2973 }
2974#endif /* OPENSSL_NO_SM2 */
2975
2976#ifndef OPENSSL_NO_DH
2977 for (testnum = 0; testnum < FFDH_NUM; testnum++) {
2978 int ffdh_checks = 1;
2979
2980 if (!ffdh_doit[testnum])
2981 continue;
2982
2983 for (i = 0; i < loopargs_len; i++) {
2984 EVP_PKEY *pkey_A = NULL;
2985 EVP_PKEY *pkey_B = NULL;
2986 EVP_PKEY_CTX *ffdh_ctx = NULL;
2987 EVP_PKEY_CTX *test_ctx = NULL;
2988 size_t secret_size;
2989 size_t test_out;
2990
2991 /* Ensure that the error queue is empty */
2992 if (ERR_peek_error()) {
2993 BIO_printf(bio_err,
2994 "WARNING: the error queue contains previous unhandled errors.\n");
2995 ERR_print_errors(bio_err);
2996 }
2997
2998 pkey_A = EVP_PKEY_new();
2999 if (!pkey_A) {
3000 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3001 ERR_print_errors(bio_err);
3002 op_count = 1;
3003 ffdh_checks = 0;
3004 break;
3005 }
3006 pkey_B = EVP_PKEY_new();
3007 if (!pkey_B) {
3008 BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n");
3009 ERR_print_errors(bio_err);
3010 op_count = 1;
3011 ffdh_checks = 0;
3012 break;
3013 }
3014
3015 ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL);
3016 if (!ffdh_ctx) {
3017 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3018 ERR_print_errors(bio_err);
3019 op_count = 1;
3020 ffdh_checks = 0;
3021 break;
3022 }
3023
3024 if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) {
3025 BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n");
3026 ERR_print_errors(bio_err);
3027 op_count = 1;
3028 ffdh_checks = 0;
3029 break;
3030 }
3031 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) {
3032 BIO_printf(bio_err, "Error setting DH key size for keygen.\n");
3033 ERR_print_errors(bio_err);
3034 op_count = 1;
3035 ffdh_checks = 0;
3036 break;
3037 }
3038
3039 if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 ||
3040 EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) {
3041 BIO_printf(bio_err, "FFDH key generation failure.\n");
3042 ERR_print_errors(bio_err);
3043 op_count = 1;
3044 ffdh_checks = 0;
3045 break;
3046 }
3047
3048 EVP_PKEY_CTX_free(ffdh_ctx);
3049
3050 /*
3051 * check if the derivation works correctly both ways so that
3052 * we know if future derive calls will fail, and we can skip
3053 * error checking in benchmarked code
3054 */
3055 ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL);
3056 if (ffdh_ctx == NULL) {
3057 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3058 ERR_print_errors(bio_err);
3059 op_count = 1;
3060 ffdh_checks = 0;
3061 break;
3062 }
3063 if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) {
3064 BIO_printf(bio_err, "FFDH derivation context init failure.\n");
3065 ERR_print_errors(bio_err);
3066 op_count = 1;
3067 ffdh_checks = 0;
3068 break;
3069 }
3070 if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) {
3071 BIO_printf(bio_err, "Assigning peer key for derivation failed.\n");
3072 ERR_print_errors(bio_err);
3073 op_count = 1;
3074 ffdh_checks = 0;
3075 break;
3076 }
3077 if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) {
3078 BIO_printf(bio_err, "Checking size of shared secret failed.\n");
3079 ERR_print_errors(bio_err);
3080 op_count = 1;
3081 ffdh_checks = 0;
3082 break;
3083 }
3084 if (secret_size > MAX_FFDH_SIZE) {
3085 BIO_printf(bio_err, "Assertion failure: shared secret too large.\n");
3086 op_count = 1;
3087 ffdh_checks = 0;
3088 break;
3089 }
3090 if (EVP_PKEY_derive(ffdh_ctx,
3091 loopargs[i].secret_ff_a,
3092 &secret_size) <= 0) {
3093 BIO_printf(bio_err, "Shared secret derive failure.\n");
3094 ERR_print_errors(bio_err);
3095 op_count = 1;
3096 ffdh_checks = 0;
3097 break;
3098 }
3099 /* Now check from side B */
3100 test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL);
3101 if (!test_ctx) {
3102 BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n");
3103 ERR_print_errors(bio_err);
3104 op_count = 1;
3105 ffdh_checks = 0;
3106 break;
3107 }
3108 if (EVP_PKEY_derive_init(test_ctx) <= 0 ||
3109 EVP_PKEY_derive_set_peer(test_ctx, pkey_A) <= 0 ||
3110 EVP_PKEY_derive(test_ctx, NULL, &test_out) <= 0 ||
3111 EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) <= 0 ||
3112 test_out != secret_size) {
3113 BIO_printf(bio_err, "FFDH computation failure.\n");
3114 op_count = 1;
3115 ffdh_checks = 0;
3116 break;
3117 }
3118
3119 /* compare the computed secrets */
3120 if (CRYPTO_memcmp(loopargs[i].secret_ff_a,
3121 loopargs[i].secret_ff_b, secret_size)) {
3122 BIO_printf(bio_err, "FFDH computations don't match.\n");
3123 ERR_print_errors(bio_err);
3124 op_count = 1;
3125 ffdh_checks = 0;
3126 break;
3127 }
3128
3129 loopargs[i].ffdh_ctx[testnum] = ffdh_ctx;
3130
3131 EVP_PKEY_free(pkey_A);
3132 pkey_A = NULL;
3133 EVP_PKEY_free(pkey_B);
3134 pkey_B = NULL;
3135 EVP_PKEY_CTX_free(test_ctx);
3136 test_ctx = NULL;
3137 }
3138 if (ffdh_checks != 0) {
3139 pkey_print_message("", "ffdh", ffdh_c[testnum][0],
3140 ffdh_params[testnum].bits, seconds.ffdh);
3141 Time_F(START);
3142 count =
3143 run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs);
3144 d = Time_F(STOP);
3145 BIO_printf(bio_err,
3146 mr ? "+R12:%ld:%d:%.2f\n" :
3147 "%ld %u-bits FFDH ops in %.2fs\n", count,
3148 ffdh_params[testnum].bits, d);
3149 ffdh_results[testnum][0] = (double)count / d;
3150 op_count = count;
3151 }
3152 if (op_count <= 1) {
3153 /* if longer than 10s, don't do any more */
3154 stop_it(ffdh_doit, testnum);
3155 }
3156 }
3157#endif /* OPENSSL_NO_DH */
3158#ifndef NO_FORK
3159 show_res:
3160#endif
3161 if (!mr) {
3162 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING));
3163 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
3164 printf("options: %s\n", BN_options());
3165 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
3166 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO));
3167 }
3168
3169 if (pr_header) {
3170 if (mr) {
3171 printf("+H");
3172 } else {
3173 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3174 printf("type ");
3175 }
3176 for (testnum = 0; testnum < size_num; testnum++)
3177 printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
3178 printf("\n");
3179 }
3180
3181 for (k = 0; k < ALGOR_NUM; k++) {
3182 if (!doit[k])
3183 continue;
3184 if (mr)
3185 printf("+F:%u:%s", k, names[k]);
3186 else
3187 printf("%-13s", names[k]);
3188 for (testnum = 0; testnum < size_num; testnum++) {
3189 if (results[k][testnum] > 10000 && !mr)
3190 printf(" %11.2fk", results[k][testnum] / 1e3);
3191 else
3192 printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
3193 }
3194 printf("\n");
3195 }
3196 testnum = 1;
3197 for (k = 0; k < RSA_NUM; k++) {
3198 if (!rsa_doit[k])
3199 continue;
3200 if (testnum && !mr) {
3201 printf("%18ssign verify sign/s verify/s\n", " ");
3202 testnum = 0;
3203 }
3204 if (mr)
3205 printf("+F2:%u:%u:%f:%f\n",
3206 k, rsa_keys[k].bits, rsa_results[k][0], rsa_results[k][1]);
3207 else
3208 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3209 rsa_keys[k].bits, 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
3210 rsa_results[k][0], rsa_results[k][1]);
3211 }
3212 testnum = 1;
3213 for (k = 0; k < DSA_NUM; k++) {
3214 if (!dsa_doit[k])
3215 continue;
3216 if (testnum && !mr) {
3217 printf("%18ssign verify sign/s verify/s\n", " ");
3218 testnum = 0;
3219 }
3220 if (mr)
3221 printf("+F3:%u:%u:%f:%f\n",
3222 k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
3223 else
3224 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3225 dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
3226 dsa_results[k][0], dsa_results[k][1]);
3227 }
3228 testnum = 1;
3229 for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) {
3230 if (!ecdsa_doit[k])
3231 continue;
3232 if (testnum && !mr) {
3233 printf("%30ssign verify sign/s verify/s\n", " ");
3234 testnum = 0;
3235 }
3236
3237 if (mr)
3238 printf("+F4:%u:%u:%f:%f\n",
3239 k, ec_curves[k].bits,
3240 ecdsa_results[k][0], ecdsa_results[k][1]);
3241 else
3242 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3243 ec_curves[k].bits, ec_curves[k].name,
3244 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
3245 ecdsa_results[k][0], ecdsa_results[k][1]);
3246 }
3247
3248 testnum = 1;
3249 for (k = 0; k < EC_NUM; k++) {
3250 if (!ecdh_doit[k])
3251 continue;
3252 if (testnum && !mr) {
3253 printf("%30sop op/s\n", " ");
3254 testnum = 0;
3255 }
3256 if (mr)
3257 printf("+F5:%u:%u:%f:%f\n",
3258 k, ec_curves[k].bits,
3259 ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
3260
3261 else
3262 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3263 ec_curves[k].bits, ec_curves[k].name,
3264 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
3265 }
3266
3267 testnum = 1;
3268 for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) {
3269 if (!eddsa_doit[k])
3270 continue;
3271 if (testnum && !mr) {
3272 printf("%30ssign verify sign/s verify/s\n", " ");
3273 testnum = 0;
3274 }
3275
3276 if (mr)
3277 printf("+F6:%u:%u:%s:%f:%f\n",
3278 k, ed_curves[k].bits, ed_curves[k].name,
3279 eddsa_results[k][0], eddsa_results[k][1]);
3280 else
3281 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3282 ed_curves[k].bits, ed_curves[k].name,
3283 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1],
3284 eddsa_results[k][0], eddsa_results[k][1]);
3285 }
3286
3287#ifndef OPENSSL_NO_SM2
3288 testnum = 1;
3289 for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
3290 if (!sm2_doit[k])
3291 continue;
3292 if (testnum && !mr) {
3293 printf("%30ssign verify sign/s verify/s\n", " ");
3294 testnum = 0;
3295 }
3296
3297 if (mr)
3298 printf("+F7:%u:%u:%s:%f:%f\n",
3299 k, sm2_curves[k].bits, sm2_curves[k].name,
3300 sm2_results[k][0], sm2_results[k][1]);
3301 else
3302 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3303 sm2_curves[k].bits, sm2_curves[k].name,
3304 1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
3305 sm2_results[k][0], sm2_results[k][1]);
3306 }
3307#endif
3308#ifndef OPENSSL_NO_DH
3309 testnum = 1;
3310 for (k = 0; k < FFDH_NUM; k++) {
3311 if (!ffdh_doit[k])
3312 continue;
3313 if (testnum && !mr) {
3314 printf("%23sop op/s\n", " ");
3315 testnum = 0;
3316 }
3317 if (mr)
3318 printf("+F8:%u:%u:%f:%f\n",
3319 k, ffdh_params[k].bits,
3320 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);
3321
3322 else
3323 printf("%4u bits ffdh %8.4fs %8.1f\n",
3324 ffdh_params[k].bits,
3325 1.0 / ffdh_results[k][0], ffdh_results[k][0]);
3326 }
3327#endif /* OPENSSL_NO_DH */
3328
3329 ret = 0;
3330
3331 end:
3332 ERR_print_errors(bio_err);
3333 for (i = 0; i < loopargs_len; i++) {
3334 OPENSSL_free(loopargs[i].buf_malloc);
3335 OPENSSL_free(loopargs[i].buf2_malloc);
3336
3337 BN_free(bn);
3338 EVP_PKEY_CTX_free(genctx);
3339 for (k = 0; k < RSA_NUM; k++) {
3340 EVP_PKEY_CTX_free(loopargs[i].rsa_sign_ctx[k]);
3341 EVP_PKEY_CTX_free(loopargs[i].rsa_verify_ctx[k]);
3342 }
3343#ifndef OPENSSL_NO_DH
3344 OPENSSL_free(loopargs[i].secret_ff_a);
3345 OPENSSL_free(loopargs[i].secret_ff_b);
3346 for (k = 0; k < FFDH_NUM; k++)
3347 EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]);
3348#endif
3349 for (k = 0; k < DSA_NUM; k++) {
3350 EVP_PKEY_CTX_free(loopargs[i].dsa_sign_ctx[k]);
3351 EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
3352 }
3353 for (k = 0; k < ECDSA_NUM; k++) {
3354 EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
3355 EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
3356 }
3357 for (k = 0; k < EC_NUM; k++)
3358 EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
3359 for (k = 0; k < EdDSA_NUM; k++) {
3360 EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]);
3361 EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]);
3362 }
3363#ifndef OPENSSL_NO_SM2
3364 for (k = 0; k < SM2_NUM; k++) {
3365 EVP_PKEY_CTX *pctx = NULL;
3366
3367 /* free signing ctx */
3368 if (loopargs[i].sm2_ctx[k] != NULL
3369 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
3370 EVP_PKEY_CTX_free(pctx);
3371 EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
3372 /* free verification ctx */
3373 if (loopargs[i].sm2_vfy_ctx[k] != NULL
3374 && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
3375 EVP_PKEY_CTX_free(pctx);
3376 EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
3377 /* free pkey */
3378 EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
3379 }
3380#endif
3381 OPENSSL_free(loopargs[i].secret_a);
3382 OPENSSL_free(loopargs[i].secret_b);
3383 }
3384 OPENSSL_free(evp_hmac_name);
3385 OPENSSL_free(evp_cmac_name);
3386
3387 if (async_jobs > 0) {
3388 for (i = 0; i < loopargs_len; i++)
3389 ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
3390 }
3391
3392 if (async_init) {
3393 ASYNC_cleanup_thread();
3394 }
3395 OPENSSL_free(loopargs);
3396 release_engine(e);
3397 EVP_CIPHER_free(evp_cipher);
3398 EVP_MAC_free(mac);
3399 NCONF_free(conf);
3400 return ret;
3401}
3402
3403static void print_message(const char *s, long num, int length, int tm)
3404{
3405 BIO_printf(bio_err,
3406 mr ? "+DT:%s:%d:%d\n"
3407 : "Doing %s for %ds on %d size blocks: ", s, tm, length);
3408 (void)BIO_flush(bio_err);
3409 run = 1;
3410 alarm(tm);
3411}
3412
3413static void pkey_print_message(const char *str, const char *str2, long num,
3414 unsigned int bits, int tm)
3415{
3416 BIO_printf(bio_err,
3417 mr ? "+DTP:%d:%s:%s:%d\n"
3418 : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm);
3419 (void)BIO_flush(bio_err);
3420 run = 1;
3421 alarm(tm);
3422}
3423
3424static void print_result(int alg, int run_no, int count, double time_used)
3425{
3426 if (count == -1) {
3427 BIO_printf(bio_err, "%s error!\n", names[alg]);
3428 ERR_print_errors(bio_err);
3429 return;
3430 }
3431 BIO_printf(bio_err,
3432 mr ? "+R:%d:%s:%f\n"
3433 : "%d %s's in %.2fs\n", count, names[alg], time_used);
3434 results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
3435}
3436
3437#ifndef NO_FORK
3438static char *sstrsep(char **string, const char *delim)
3439{
3440 char isdelim[256];
3441 char *token = *string;
3442
3443 if (**string == 0)
3444 return NULL;
3445
3446 memset(isdelim, 0, sizeof(isdelim));
3447 isdelim[0] = 1;
3448
3449 while (*delim) {
3450 isdelim[(unsigned char)(*delim)] = 1;
3451 delim++;
3452 }
3453
3454 while (!isdelim[(unsigned char)(**string)])
3455 (*string)++;
3456
3457 if (**string) {
3458 **string = 0;
3459 (*string)++;
3460 }
3461
3462 return token;
3463}
3464
3465static int do_multi(int multi, int size_num)
3466{
3467 int n;
3468 int fd[2];
3469 int *fds;
3470 int status;
3471 static char sep[] = ":";
3472
3473 fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi");
3474 for (n = 0; n < multi; ++n) {
3475 if (pipe(fd) == -1) {
3476 BIO_printf(bio_err, "pipe failure\n");
3477 exit(1);
3478 }
3479 fflush(stdout);
3480 (void)BIO_flush(bio_err);
3481 if (fork()) {
3482 close(fd[1]);
3483 fds[n] = fd[0];
3484 } else {
3485 close(fd[0]);
3486 close(1);
3487 if (dup(fd[1]) == -1) {
3488 BIO_printf(bio_err, "dup failed\n");
3489 exit(1);
3490 }
3491 close(fd[1]);
3492 mr = 1;
3493 usertime = 0;
3494 OPENSSL_free(fds);
3495 return 0;
3496 }
3497 printf("Forked child %d\n", n);
3498 }
3499
3500 /* for now, assume the pipe is long enough to take all the output */
3501 for (n = 0; n < multi; ++n) {
3502 FILE *f;
3503 char buf[1024];
3504 char *p;
3505
3506 if ((f = fdopen(fds[n], "r")) == NULL) {
3507 BIO_printf(bio_err, "fdopen failure with 0x%x\n",
3508 errno);
3509 OPENSSL_free(fds);
3510 return 1;
3511 }
3512 while (fgets(buf, sizeof(buf), f)) {
3513 p = strchr(buf, '\n');
3514 if (p)
3515 *p = '\0';
3516 if (buf[0] != '+') {
3517 BIO_printf(bio_err,
3518 "Don't understand line '%s' from child %d\n", buf,
3519 n);
3520 continue;
3521 }
3522 printf("Got: %s from %d\n", buf, n);
3523 if (strncmp(buf, "+F:", 3) == 0) {
3524 int alg;
3525 int j;
3526
3527 p = buf + 3;
3528 alg = atoi(sstrsep(&p, sep));
3529 sstrsep(&p, sep);
3530 for (j = 0; j < size_num; ++j)
3531 results[alg][j] += atof(sstrsep(&p, sep));
3532 } else if (strncmp(buf, "+F2:", 4) == 0) {
3533 int k;
3534 double d;
3535
3536 p = buf + 4;
3537 k = atoi(sstrsep(&p, sep));
3538 sstrsep(&p, sep);
3539
3540 d = atof(sstrsep(&p, sep));
3541 rsa_results[k][0] += d;
3542
3543 d = atof(sstrsep(&p, sep));
3544 rsa_results[k][1] += d;
3545 } else if (strncmp(buf, "+F3:", 4) == 0) {
3546 int k;
3547 double d;
3548
3549 p = buf + 4;
3550 k = atoi(sstrsep(&p, sep));
3551 sstrsep(&p, sep);
3552
3553 d = atof(sstrsep(&p, sep));
3554 dsa_results[k][0] += d;
3555
3556 d = atof(sstrsep(&p, sep));
3557 dsa_results[k][1] += d;
3558 } else if (strncmp(buf, "+F4:", 4) == 0) {
3559 int k;
3560 double d;
3561
3562 p = buf + 4;
3563 k = atoi(sstrsep(&p, sep));
3564 sstrsep(&p, sep);
3565
3566 d = atof(sstrsep(&p, sep));
3567 ecdsa_results[k][0] += d;
3568
3569 d = atof(sstrsep(&p, sep));
3570 ecdsa_results[k][1] += d;
3571 } else if (strncmp(buf, "+F5:", 4) == 0) {
3572 int k;
3573 double d;
3574
3575 p = buf + 4;
3576 k = atoi(sstrsep(&p, sep));
3577 sstrsep(&p, sep);
3578
3579 d = atof(sstrsep(&p, sep));
3580 ecdh_results[k][0] += d;
3581 } else if (strncmp(buf, "+F6:", 4) == 0) {
3582 int k;
3583 double d;
3584
3585 p = buf + 4;
3586 k = atoi(sstrsep(&p, sep));
3587 sstrsep(&p, sep);
3588 sstrsep(&p, sep);
3589
3590 d = atof(sstrsep(&p, sep));
3591 eddsa_results[k][0] += d;
3592
3593 d = atof(sstrsep(&p, sep));
3594 eddsa_results[k][1] += d;
3595# ifndef OPENSSL_NO_SM2
3596 } else if (strncmp(buf, "+F7:", 4) == 0) {
3597 int k;
3598 double d;
3599
3600 p = buf + 4;
3601 k = atoi(sstrsep(&p, sep));
3602 sstrsep(&p, sep);
3603 sstrsep(&p, sep);
3604
3605 d = atof(sstrsep(&p, sep));
3606 sm2_results[k][0] += d;
3607
3608 d = atof(sstrsep(&p, sep));
3609 sm2_results[k][1] += d;
3610# endif /* OPENSSL_NO_SM2 */
3611# ifndef OPENSSL_NO_DH
3612 } else if (strncmp(buf, "+F8:", 4) == 0) {
3613 int k;
3614 double d;
3615
3616 p = buf + 4;
3617 k = atoi(sstrsep(&p, sep));
3618 sstrsep(&p, sep);
3619
3620 d = atof(sstrsep(&p, sep));
3621 ffdh_results[k][0] += d;
3622# endif /* OPENSSL_NO_DH */
3623 } else if (strncmp(buf, "+H:", 3) == 0) {
3624 ;
3625 } else {
3626 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
3627 n);
3628 }
3629 }
3630
3631 fclose(f);
3632 }
3633 OPENSSL_free(fds);
3634 for (n = 0; n < multi; ++n) {
3635 while (wait(&status) == -1)
3636 if (errno != EINTR) {
3637 BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
3638 errno);
3639 return 1;
3640 }
3641 if (WIFEXITED(status) && WEXITSTATUS(status)) {
3642 BIO_printf(bio_err, "Child exited with %d\n", WEXITSTATUS(status));
3643 } else if (WIFSIGNALED(status)) {
3644 BIO_printf(bio_err, "Child terminated by signal %d\n",
3645 WTERMSIG(status));
3646 }
3647 }
3648 return 1;
3649}
3650#endif
3651
3652static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single,
3653 const openssl_speed_sec_t *seconds)
3654{
3655 static const int mblengths_list[] =
3656 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3657 const int *mblengths = mblengths_list;
3658 int j, count, keylen, num = OSSL_NELEM(mblengths_list);
3659 const char *alg_name;
3660 unsigned char *inp = NULL, *out = NULL, *key, no_key[32], no_iv[16];
3661 EVP_CIPHER_CTX *ctx = NULL;
3662 double d = 0.0;
3663
3664 if (lengths_single) {
3665 mblengths = &lengths_single;
3666 num = 1;
3667 }
3668
3669 inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
3670 out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
3671 if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
3672 app_bail_out("failed to allocate cipher context\n");
3673 if (!EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv))
3674 app_bail_out("failed to initialise cipher context\n");
3675
3676 if ((keylen = EVP_CIPHER_CTX_get_key_length(ctx)) < 0) {
3677 BIO_printf(bio_err, "Impossible negative key length: %d\n", keylen);
3678 goto err;
3679 }
3680 key = app_malloc(keylen, "evp_cipher key");
3681 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
3682 app_bail_out("failed to generate random cipher key\n");
3683 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL))
3684 app_bail_out("failed to set cipher key\n");
3685 OPENSSL_clear_free(key, keylen);
3686
3687 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
3688 sizeof(no_key), no_key) <= 0)
3689 app_bail_out("failed to set AEAD key\n");
3690 if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
3691 app_bail_out("failed to get cipher name\n");
3692
3693 for (j = 0; j < num; j++) {
3694 print_message(alg_name, 0, mblengths[j], seconds->sym);
3695 Time_F(START);
3696 for (count = 0; run && count < INT_MAX; count++) {
3697 unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
3698 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
3699 size_t len = mblengths[j];
3700 int packlen;
3701
3702 memset(aad, 0, 8); /* avoid uninitialized values */
3703 aad[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3704 aad[9] = 3; /* version */
3705 aad[10] = 2;
3706 aad[11] = 0; /* length */
3707 aad[12] = 0;
3708 mb_param.out = NULL;
3709 mb_param.inp = aad;
3710 mb_param.len = len;
3711 mb_param.interleave = 8;
3712
3713 packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
3714 sizeof(mb_param), &mb_param);
3715
3716 if (packlen > 0) {
3717 mb_param.out = out;
3718 mb_param.inp = inp;
3719 mb_param.len = len;
3720 (void)EVP_CIPHER_CTX_ctrl(ctx,
3721 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
3722 sizeof(mb_param), &mb_param);
3723 } else {
3724 int pad;
3725
3726 RAND_bytes(out, 16);
3727 len += 16;
3728 aad[11] = (unsigned char)(len >> 8);
3729 aad[12] = (unsigned char)(len);
3730 pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
3731 EVP_AEAD_TLS1_AAD_LEN, aad);
3732 EVP_Cipher(ctx, out, inp, len + pad);
3733 }
3734 }
3735 d = Time_F(STOP);
3736 BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
3737 : "%d %s's in %.2fs\n", count, "evp", d);
3738 results[D_EVP][j] = ((double)count) / d * mblengths[j];
3739 }
3740
3741 if (mr) {
3742 fprintf(stdout, "+H");
3743 for (j = 0; j < num; j++)
3744 fprintf(stdout, ":%d", mblengths[j]);
3745 fprintf(stdout, "\n");
3746 fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
3747 for (j = 0; j < num; j++)
3748 fprintf(stdout, ":%.2f", results[D_EVP][j]);
3749 fprintf(stdout, "\n");
3750 } else {
3751 fprintf(stdout,
3752 "The 'numbers' are in 1000s of bytes per second processed.\n");
3753 fprintf(stdout, "type ");
3754 for (j = 0; j < num; j++)
3755 fprintf(stdout, "%7d bytes", mblengths[j]);
3756 fprintf(stdout, "\n");
3757 fprintf(stdout, "%-24s", alg_name);
3758
3759 for (j = 0; j < num; j++) {
3760 if (results[D_EVP][j] > 10000)
3761 fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
3762 else
3763 fprintf(stdout, " %11.2f ", results[D_EVP][j]);
3764 }
3765 fprintf(stdout, "\n");
3766 }
3767
3768 err:
3769 OPENSSL_free(inp);
3770 OPENSSL_free(out);
3771 EVP_CIPHER_CTX_free(ctx);
3772}
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