VirtualBox

source: vbox/trunk/src/libs/openssl-3.0.3/apps/speed.c@ 96441

Last change on this file since 96441 was 94404, checked in by vboxsync, 3 years ago

libs/openssl: Update to 3.0.2 and switch to it, bugref:10128

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