2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
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
13 #define PKEY_SECONDS 10
15 #define RSA_SECONDS PKEY_SECONDS
16 #define DSA_SECONDS PKEY_SECONDS
17 #define ECDSA_SECONDS PKEY_SECONDS
18 #define ECDH_SECONDS PKEY_SECONDS
19 #define EdDSA_SECONDS PKEY_SECONDS
20 #define SM2_SECONDS PKEY_SECONDS
21 #define FFDH_SECONDS PKEY_SECONDS
22 #define KEM_SECONDS PKEY_SECONDS
23 #define SIG_SECONDS PKEY_SECONDS
25 #define MAX_ALGNAME_SUFFIX 100
27 /* We need to use some deprecated APIs */
28 #define OPENSSL_SUPPRESS_DEPRECATED
36 #include "internal/nelem.h"
37 #include "internal/numbers.h"
38 #include <openssl/crypto.h>
39 #include <openssl/rand.h>
40 #include <openssl/err.h>
41 #include <openssl/evp.h>
42 #include <openssl/objects.h>
43 #include <openssl/core_names.h>
44 #include <openssl/async.h>
45 #include <openssl/provider.h>
46 #if !defined(OPENSSL_SYS_MSDOS)
51 # if defined(OPENSSL_TANDEM_FLOSS)
52 # include <floss.h(floss_fork)>
59 * While VirtualLock is available under the app partition (e.g. UWP),
60 * the headers do not define the API. Define it ourselves instead.
66 _In_ LPVOID lpAddress
,
71 #if defined(OPENSSL_SYS_LINUX)
72 # include <sys/mman.h>
75 #include <openssl/bn.h>
76 #include <openssl/rsa.h>
77 #include "./testrsa.h"
79 # include <openssl/dh.h>
81 #include <openssl/x509.h>
82 #include <openssl/dsa.h>
83 #include "./testdsa.h"
84 #include <openssl/modes.h>
87 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
91 # include <sys/wait.h>
101 #define MAX_MISALIGNMENT 63
102 #define MAX_ECDH_SIZE 256
104 #define MAX_FFDH_SIZE 1024
106 #ifndef RSA_DEFAULT_PRIME_NUM
107 # define RSA_DEFAULT_PRIME_NUM 2
110 typedef struct openssl_speed_sec_st
{
121 } openssl_speed_sec_t
;
123 static volatile int run
= 0;
125 static int mr
= 0; /* machine-readeable output format to merge fork results */
126 static int usertime
= 1;
128 static double Time_F(int s
);
129 static void print_message(const char *s
, int length
, int tm
);
130 static void pkey_print_message(const char *str
, const char *str2
,
131 unsigned int bits
, int sec
);
132 static void kskey_print_message(const char *str
, const char *str2
, int tm
);
133 static void print_result(int alg
, int run_no
, int count
, double time_used
);
135 static int do_multi(int multi
, int size_num
);
138 static int domlock
= 0;
140 static const int lengths_list
[] = {
141 16, 64, 256, 1024, 8 * 1024, 16 * 1024
143 #define SIZE_NUM OSSL_NELEM(lengths_list)
144 static const int *lengths
= lengths_list
;
146 static const int aead_lengths_list
[] = {
147 2, 31, 136, 1024, 8 * 1024, 16 * 1024
155 static void alarmed(ossl_unused
int sig
)
157 signal(SIGALRM
, alarmed
);
161 static double Time_F(int s
)
163 double ret
= app_tminterval(s
, usertime
);
169 #elif defined(_WIN32)
173 static unsigned int lapse
;
174 static volatile unsigned int schlock
;
175 static void alarm_win32(unsigned int secs
)
180 # define alarm alarm_win32
182 static DWORD WINAPI
sleepy(VOID
* arg
)
190 static double Time_F(int s
)
197 thr
= CreateThread(NULL
, 4096, sleepy
, NULL
, 0, NULL
);
199 DWORD err
= GetLastError();
200 BIO_printf(bio_err
, "unable to CreateThread (%lu)", err
);
204 Sleep(0); /* scheduler spinlock */
205 ret
= app_tminterval(s
, usertime
);
207 ret
= app_tminterval(s
, usertime
);
209 TerminateThread(thr
, 0);
216 # error "SIGALRM not defined and the platform is not Windows"
219 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
220 const openssl_speed_sec_t
*seconds
);
222 static int opt_found(const char *name
, unsigned int *result
,
223 const OPT_PAIR pairs
[], unsigned int nbelem
)
227 for (idx
= 0; idx
< nbelem
; ++idx
, pairs
++)
228 if (strcmp(name
, pairs
->name
) == 0) {
229 *result
= pairs
->retval
;
234 #define opt_found(value, pairs, result)\
235 opt_found(value, result, pairs, OSSL_NELEM(pairs))
237 typedef enum OPTION_choice
{
239 OPT_ELAPSED
, OPT_EVP
, OPT_HMAC
, OPT_DECRYPT
, OPT_ENGINE
, OPT_MULTI
,
240 OPT_MR
, OPT_MB
, OPT_MISALIGN
, OPT_ASYNCJOBS
, OPT_R_ENUM
, OPT_PROV_ENUM
, OPT_CONFIG
,
241 OPT_PRIMES
, OPT_SECONDS
, OPT_BYTES
, OPT_AEAD
, OPT_CMAC
, OPT_MLOCK
, OPT_KEM
, OPT_SIG
244 const OPTIONS speed_options
[] = {
245 {OPT_HELP_STR
, 1, '-',
246 "Usage: %s [options] [algorithm...]\n"
247 "All +int options consider prefix '0' as base-8 input, "
248 "prefix '0x'/'0X' as base-16 input.\n"
251 OPT_SECTION("General"),
252 {"help", OPT_HELP
, '-', "Display this summary"},
254 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
255 {"mr", OPT_MR
, '-', "Produce machine readable output"},
257 {"multi", OPT_MULTI
, 'p', "Run benchmarks in parallel"},
259 #ifndef OPENSSL_NO_ASYNC
260 {"async_jobs", OPT_ASYNCJOBS
, 'p',
261 "Enable async mode and start specified number of jobs"},
263 #ifndef OPENSSL_NO_ENGINE
264 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
266 {"primes", OPT_PRIMES
, 'p', "Specify number of primes (for RSA only)"},
267 {"mlock", OPT_MLOCK
, '-', "Lock memory for better result determinism"},
270 OPT_SECTION("Selection"),
271 {"evp", OPT_EVP
, 's', "Use EVP-named cipher or digest"},
272 {"hmac", OPT_HMAC
, 's', "HMAC using EVP-named digest"},
273 {"cmac", OPT_CMAC
, 's', "CMAC using EVP-named cipher"},
274 {"decrypt", OPT_DECRYPT
, '-',
275 "Time decryption instead of encryption (only EVP)"},
276 {"aead", OPT_AEAD
, '-',
277 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
278 {"kem-algorithms", OPT_KEM
, '-',
279 "Benchmark KEM algorithms"},
280 {"signature-algorithms", OPT_SIG
, '-',
281 "Benchmark signature algorithms"},
283 OPT_SECTION("Timing"),
284 {"elapsed", OPT_ELAPSED
, '-',
285 "Use wall-clock time instead of CPU user time as divisor"},
286 {"seconds", OPT_SECONDS
, 'p',
287 "Run benchmarks for specified amount of seconds"},
288 {"bytes", OPT_BYTES
, 'p',
289 "Run [non-PKI] benchmarks on custom-sized buffer"},
290 {"misalign", OPT_MISALIGN
, 'p',
291 "Use specified offset to mis-align buffers"},
297 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
302 D_MD2
, D_MDC2
, D_MD4
, D_MD5
, D_SHA1
, D_RMD160
,
303 D_SHA256
, D_SHA512
, D_WHIRLPOOL
, D_HMAC
,
304 D_CBC_DES
, D_EDE3_DES
, D_RC4
, D_CBC_IDEA
, D_CBC_SEED
,
305 D_CBC_RC2
, D_CBC_RC5
, D_CBC_BF
, D_CBC_CAST
,
306 D_CBC_128_AES
, D_CBC_192_AES
, D_CBC_256_AES
,
307 D_CBC_128_CML
, D_CBC_192_CML
, D_CBC_256_CML
,
308 D_EVP
, D_GHASH
, D_RAND
, D_EVP_CMAC
, ALGOR_NUM
310 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
311 static const char *names
[ALGOR_NUM
] = {
312 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
313 "sha256", "sha512", "whirlpool", "hmac(md5)",
314 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
315 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
316 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
317 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
318 "evp", "ghash", "rand", "cmac"
321 /* list of configured algorithm (remaining), with some few alias */
322 static const OPT_PAIR doit_choices
[] = {
329 {"sha256", D_SHA256
},
330 {"sha512", D_SHA512
},
331 {"whirlpool", D_WHIRLPOOL
},
332 {"ripemd", D_RMD160
},
333 {"rmd160", D_RMD160
},
334 {"ripemd160", D_RMD160
},
336 {"des-cbc", D_CBC_DES
},
337 {"des-ede3", D_EDE3_DES
},
338 {"aes-128-cbc", D_CBC_128_AES
},
339 {"aes-192-cbc", D_CBC_192_AES
},
340 {"aes-256-cbc", D_CBC_256_AES
},
341 {"camellia-128-cbc", D_CBC_128_CML
},
342 {"camellia-192-cbc", D_CBC_192_CML
},
343 {"camellia-256-cbc", D_CBC_256_CML
},
344 {"rc2-cbc", D_CBC_RC2
},
346 {"rc5-cbc", D_CBC_RC5
},
348 {"idea-cbc", D_CBC_IDEA
},
349 {"idea", D_CBC_IDEA
},
350 {"seed-cbc", D_CBC_SEED
},
351 {"seed", D_CBC_SEED
},
352 {"bf-cbc", D_CBC_BF
},
353 {"blowfish", D_CBC_BF
},
355 {"cast-cbc", D_CBC_CAST
},
356 {"cast", D_CBC_CAST
},
357 {"cast5", D_CBC_CAST
},
362 static double results
[ALGOR_NUM
][SIZE_NUM
];
364 enum { R_DSA_1024
, R_DSA_2048
, DSA_NUM
};
365 static const OPT_PAIR dsa_choices
[DSA_NUM
] = {
366 {"dsa1024", R_DSA_1024
},
367 {"dsa2048", R_DSA_2048
}
369 static double dsa_results
[DSA_NUM
][2]; /* 2 ops: sign then verify */
372 R_RSA_512
, R_RSA_1024
, R_RSA_2048
, R_RSA_3072
, R_RSA_4096
, R_RSA_7680
,
375 static const OPT_PAIR rsa_choices
[RSA_NUM
] = {
376 {"rsa512", R_RSA_512
},
377 {"rsa1024", R_RSA_1024
},
378 {"rsa2048", R_RSA_2048
},
379 {"rsa3072", R_RSA_3072
},
380 {"rsa4096", R_RSA_4096
},
381 {"rsa7680", R_RSA_7680
},
382 {"rsa15360", R_RSA_15360
}
385 static double rsa_results
[RSA_NUM
][2]; /* 2 ops: sign then verify */
387 #ifndef OPENSSL_NO_DH
389 R_FFDH_2048
, R_FFDH_3072
, R_FFDH_4096
, R_FFDH_6144
, R_FFDH_8192
, FFDH_NUM
392 static const OPT_PAIR ffdh_choices
[FFDH_NUM
] = {
393 {"ffdh2048", R_FFDH_2048
},
394 {"ffdh3072", R_FFDH_3072
},
395 {"ffdh4096", R_FFDH_4096
},
396 {"ffdh6144", R_FFDH_6144
},
397 {"ffdh8192", R_FFDH_8192
},
400 static double ffdh_results
[FFDH_NUM
][1]; /* 1 op: derivation */
401 #endif /* OPENSSL_NO_DH */
404 R_EC_P160
, R_EC_P192
, R_EC_P224
, R_EC_P256
, R_EC_P384
, R_EC_P521
,
405 #ifndef OPENSSL_NO_EC2M
406 R_EC_K163
, R_EC_K233
, R_EC_K283
, R_EC_K409
, R_EC_K571
,
407 R_EC_B163
, R_EC_B233
, R_EC_B283
, R_EC_B409
, R_EC_B571
,
409 R_EC_BRP256R1
, R_EC_BRP256T1
, R_EC_BRP384R1
, R_EC_BRP384T1
,
410 R_EC_BRP512R1
, R_EC_BRP512T1
, ECDSA_NUM
412 /* list of ecdsa curves */
413 static const OPT_PAIR ecdsa_choices
[ECDSA_NUM
] = {
414 {"ecdsap160", R_EC_P160
},
415 {"ecdsap192", R_EC_P192
},
416 {"ecdsap224", R_EC_P224
},
417 {"ecdsap256", R_EC_P256
},
418 {"ecdsap384", R_EC_P384
},
419 {"ecdsap521", R_EC_P521
},
420 #ifndef OPENSSL_NO_EC2M
421 {"ecdsak163", R_EC_K163
},
422 {"ecdsak233", R_EC_K233
},
423 {"ecdsak283", R_EC_K283
},
424 {"ecdsak409", R_EC_K409
},
425 {"ecdsak571", R_EC_K571
},
426 {"ecdsab163", R_EC_B163
},
427 {"ecdsab233", R_EC_B233
},
428 {"ecdsab283", R_EC_B283
},
429 {"ecdsab409", R_EC_B409
},
430 {"ecdsab571", R_EC_B571
},
432 {"ecdsabrp256r1", R_EC_BRP256R1
},
433 {"ecdsabrp256t1", R_EC_BRP256T1
},
434 {"ecdsabrp384r1", R_EC_BRP384R1
},
435 {"ecdsabrp384t1", R_EC_BRP384T1
},
436 {"ecdsabrp512r1", R_EC_BRP512R1
},
437 {"ecdsabrp512t1", R_EC_BRP512T1
}
440 #ifndef OPENSSL_NO_ECX
441 R_EC_X25519
= ECDSA_NUM
, R_EC_X448
, EC_NUM
446 /* list of ecdh curves, extension of |ecdsa_choices| list above */
447 static const OPT_PAIR ecdh_choices
[EC_NUM
] = {
448 {"ecdhp160", R_EC_P160
},
449 {"ecdhp192", R_EC_P192
},
450 {"ecdhp224", R_EC_P224
},
451 {"ecdhp256", R_EC_P256
},
452 {"ecdhp384", R_EC_P384
},
453 {"ecdhp521", R_EC_P521
},
454 #ifndef OPENSSL_NO_EC2M
455 {"ecdhk163", R_EC_K163
},
456 {"ecdhk233", R_EC_K233
},
457 {"ecdhk283", R_EC_K283
},
458 {"ecdhk409", R_EC_K409
},
459 {"ecdhk571", R_EC_K571
},
460 {"ecdhb163", R_EC_B163
},
461 {"ecdhb233", R_EC_B233
},
462 {"ecdhb283", R_EC_B283
},
463 {"ecdhb409", R_EC_B409
},
464 {"ecdhb571", R_EC_B571
},
466 {"ecdhbrp256r1", R_EC_BRP256R1
},
467 {"ecdhbrp256t1", R_EC_BRP256T1
},
468 {"ecdhbrp384r1", R_EC_BRP384R1
},
469 {"ecdhbrp384t1", R_EC_BRP384T1
},
470 {"ecdhbrp512r1", R_EC_BRP512R1
},
471 {"ecdhbrp512t1", R_EC_BRP512T1
},
472 #ifndef OPENSSL_NO_ECX
473 {"ecdhx25519", R_EC_X25519
},
474 {"ecdhx448", R_EC_X448
}
478 static double ecdh_results
[EC_NUM
][1]; /* 1 op: derivation */
479 static double ecdsa_results
[ECDSA_NUM
][2]; /* 2 ops: sign then verify */
481 #ifndef OPENSSL_NO_ECX
482 enum { R_EC_Ed25519
, R_EC_Ed448
, EdDSA_NUM
};
483 static const OPT_PAIR eddsa_choices
[EdDSA_NUM
] = {
484 {"ed25519", R_EC_Ed25519
},
485 {"ed448", R_EC_Ed448
}
488 static double eddsa_results
[EdDSA_NUM
][2]; /* 2 ops: sign then verify */
489 #endif /* OPENSSL_NO_ECX */
491 #ifndef OPENSSL_NO_SM2
492 enum { R_EC_CURVESM2
, SM2_NUM
};
493 static const OPT_PAIR sm2_choices
[SM2_NUM
] = {
494 {"curveSM2", R_EC_CURVESM2
}
496 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
497 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
498 static double sm2_results
[SM2_NUM
][2]; /* 2 ops: sign then verify */
499 #endif /* OPENSSL_NO_SM2 */
501 #define MAX_KEM_NUM 111
502 static size_t kems_algs_len
= 0;
503 static char *kems_algname
[MAX_KEM_NUM
] = { NULL
};
504 static double kems_results
[MAX_KEM_NUM
][3]; /* keygen, encaps, decaps */
506 #define MAX_SIG_NUM 111
507 static size_t sigs_algs_len
= 0;
508 static char *sigs_algname
[MAX_SIG_NUM
] = { NULL
};
509 static double sigs_results
[MAX_SIG_NUM
][3]; /* keygen, sign, verify */
511 #define COND(unused_cond) (run && count < INT_MAX)
512 #define COUNT(d) (count)
514 typedef struct loopargs_st
{
515 ASYNC_JOB
*inprogress_job
;
516 ASYNC_WAIT_CTX
*wait_ctx
;
519 unsigned char *buf_malloc
;
520 unsigned char *buf2_malloc
;
524 EVP_PKEY_CTX
*rsa_sign_ctx
[RSA_NUM
];
525 EVP_PKEY_CTX
*rsa_verify_ctx
[RSA_NUM
];
526 EVP_PKEY_CTX
*dsa_sign_ctx
[DSA_NUM
];
527 EVP_PKEY_CTX
*dsa_verify_ctx
[DSA_NUM
];
528 EVP_PKEY_CTX
*ecdsa_sign_ctx
[ECDSA_NUM
];
529 EVP_PKEY_CTX
*ecdsa_verify_ctx
[ECDSA_NUM
];
530 EVP_PKEY_CTX
*ecdh_ctx
[EC_NUM
];
531 #ifndef OPENSSL_NO_ECX
532 EVP_MD_CTX
*eddsa_ctx
[EdDSA_NUM
];
533 EVP_MD_CTX
*eddsa_ctx2
[EdDSA_NUM
];
534 #endif /* OPENSSL_NO_ECX */
535 #ifndef OPENSSL_NO_SM2
536 EVP_MD_CTX
*sm2_ctx
[SM2_NUM
];
537 EVP_MD_CTX
*sm2_vfy_ctx
[SM2_NUM
];
538 EVP_PKEY
*sm2_pkey
[SM2_NUM
];
540 unsigned char *secret_a
;
541 unsigned char *secret_b
;
542 size_t outlen
[EC_NUM
];
543 #ifndef OPENSSL_NO_DH
544 EVP_PKEY_CTX
*ffdh_ctx
[FFDH_NUM
];
545 unsigned char *secret_ff_a
;
546 unsigned char *secret_ff_b
;
550 EVP_PKEY_CTX
*kem_gen_ctx
[MAX_KEM_NUM
];
551 EVP_PKEY_CTX
*kem_encaps_ctx
[MAX_KEM_NUM
];
552 EVP_PKEY_CTX
*kem_decaps_ctx
[MAX_KEM_NUM
];
553 size_t kem_out_len
[MAX_KEM_NUM
];
554 size_t kem_secret_len
[MAX_KEM_NUM
];
555 unsigned char *kem_out
[MAX_KEM_NUM
];
556 unsigned char *kem_send_secret
[MAX_KEM_NUM
];
557 unsigned char *kem_rcv_secret
[MAX_KEM_NUM
];
558 EVP_PKEY_CTX
*sig_gen_ctx
[MAX_KEM_NUM
];
559 EVP_PKEY_CTX
*sig_sign_ctx
[MAX_KEM_NUM
];
560 EVP_PKEY_CTX
*sig_verify_ctx
[MAX_KEM_NUM
];
561 size_t sig_max_sig_len
[MAX_KEM_NUM
];
562 size_t sig_act_sig_len
[MAX_KEM_NUM
];
563 unsigned char *sig_sig
[MAX_KEM_NUM
];
565 static int run_benchmark(int async_jobs
, int (*loop_function
) (void *),
566 loopargs_t
* loopargs
);
568 static unsigned int testnum
;
570 static char *evp_mac_mdname
= "md5";
571 static char *evp_hmac_name
= NULL
;
572 static const char *evp_md_name
= NULL
;
573 static char *evp_mac_ciphername
= "aes-128-cbc";
574 static char *evp_cmac_name
= NULL
;
576 static int have_md(const char *name
)
581 if (opt_md_silent(name
, &md
)) {
582 EVP_MD_CTX
*ctx
= EVP_MD_CTX_new();
584 if (ctx
!= NULL
&& EVP_DigestInit(ctx
, md
) > 0)
586 EVP_MD_CTX_free(ctx
);
592 static int have_cipher(const char *name
)
595 EVP_CIPHER
*cipher
= NULL
;
597 if (opt_cipher_silent(name
, &cipher
)) {
598 EVP_CIPHER_CTX
*ctx
= EVP_CIPHER_CTX_new();
601 && EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1) > 0)
603 EVP_CIPHER_CTX_free(ctx
);
604 EVP_CIPHER_free(cipher
);
609 static int EVP_Digest_loop(const char *mdname
, ossl_unused
int algindex
, void *args
)
611 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
612 unsigned char *buf
= tempargs
->buf
;
613 unsigned char digest
[EVP_MAX_MD_SIZE
];
617 if (!opt_md_silent(mdname
, &md
))
619 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
620 if (!EVP_Digest(buf
, (size_t)lengths
[testnum
], digest
, NULL
, md
,
630 static int EVP_Digest_md_loop(void *args
)
632 return EVP_Digest_loop(evp_md_name
, D_EVP
, args
);
635 static int EVP_Digest_MD2_loop(void *args
)
637 return EVP_Digest_loop("md2", D_MD2
, args
);
640 static int EVP_Digest_MDC2_loop(void *args
)
642 return EVP_Digest_loop("mdc2", D_MDC2
, args
);
645 static int EVP_Digest_MD4_loop(void *args
)
647 return EVP_Digest_loop("md4", D_MD4
, args
);
650 static int MD5_loop(void *args
)
652 return EVP_Digest_loop("md5", D_MD5
, args
);
655 static int EVP_MAC_loop(ossl_unused
int algindex
, void *args
)
657 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
658 unsigned char *buf
= tempargs
->buf
;
659 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
660 unsigned char mac
[EVP_MAX_MD_SIZE
];
663 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
666 if (!EVP_MAC_init(mctx
, NULL
, 0, NULL
)
667 || !EVP_MAC_update(mctx
, buf
, lengths
[testnum
])
668 || !EVP_MAC_final(mctx
, mac
, &outl
, sizeof(mac
)))
674 static int HMAC_loop(void *args
)
676 return EVP_MAC_loop(D_HMAC
, args
);
679 static int CMAC_loop(void *args
)
681 return EVP_MAC_loop(D_EVP_CMAC
, args
);
684 static int SHA1_loop(void *args
)
686 return EVP_Digest_loop("sha1", D_SHA1
, args
);
689 static int SHA256_loop(void *args
)
691 return EVP_Digest_loop("sha256", D_SHA256
, args
);
694 static int SHA512_loop(void *args
)
696 return EVP_Digest_loop("sha512", D_SHA512
, args
);
699 static int WHIRLPOOL_loop(void *args
)
701 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL
, args
);
704 static int EVP_Digest_RMD160_loop(void *args
)
706 return EVP_Digest_loop("ripemd160", D_RMD160
, args
);
711 static int EVP_Cipher_loop(void *args
)
713 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
714 unsigned char *buf
= tempargs
->buf
;
717 if (tempargs
->ctx
== NULL
)
719 for (count
= 0; COND(c
[algindex
][testnum
]); count
++)
720 if (EVP_Cipher(tempargs
->ctx
, buf
, buf
, (size_t)lengths
[testnum
]) <= 0)
725 static int GHASH_loop(void *args
)
727 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
728 unsigned char *buf
= tempargs
->buf
;
729 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
732 /* just do the update in the loop to be comparable with 1.1.1 */
733 for (count
= 0; COND(c
[D_GHASH
][testnum
]); count
++) {
734 if (!EVP_MAC_update(mctx
, buf
, lengths
[testnum
]))
740 #define MAX_BLOCK_SIZE 128
742 static unsigned char iv
[2 * MAX_BLOCK_SIZE
/ 8];
744 static EVP_CIPHER_CTX
*init_evp_cipher_ctx(const char *ciphername
,
745 const unsigned char *key
,
748 EVP_CIPHER_CTX
*ctx
= NULL
;
749 EVP_CIPHER
*cipher
= NULL
;
751 if (!opt_cipher_silent(ciphername
, &cipher
))
754 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
757 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1)) {
758 EVP_CIPHER_CTX_free(ctx
);
763 if (EVP_CIPHER_CTX_set_key_length(ctx
, keylen
) <= 0) {
764 EVP_CIPHER_CTX_free(ctx
);
769 if (!EVP_CipherInit_ex(ctx
, NULL
, NULL
, key
, iv
, 1)) {
770 EVP_CIPHER_CTX_free(ctx
);
776 EVP_CIPHER_free(cipher
);
780 static int RAND_bytes_loop(void *args
)
782 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
783 unsigned char *buf
= tempargs
->buf
;
786 for (count
= 0; COND(c
[D_RAND
][testnum
]); count
++)
787 RAND_bytes(buf
, lengths
[testnum
]);
791 static int decrypt
= 0;
792 static int EVP_Update_loop(void *args
)
794 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
795 unsigned char *buf
= tempargs
->buf
;
796 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
800 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
801 rc
= EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
803 /* reset iv in case of counter overflow */
804 rc
= EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
808 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
809 rc
= EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
811 /* reset iv in case of counter overflow */
812 rc
= EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
817 rc
= EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
819 rc
= EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
822 BIO_printf(bio_err
, "Error finalizing cipher loop\n");
827 * CCM does not support streaming. For the purpose of performance measurement,
828 * each message is encrypted using the same (key,iv)-pair. Do not use this
829 * code in your application.
831 static int EVP_Update_loop_ccm(void *args
)
833 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
834 unsigned char *buf
= tempargs
->buf
;
835 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
836 int outl
, count
, realcount
= 0, final
;
837 unsigned char tag
[12];
840 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
841 if (EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
, sizeof(tag
),
844 && EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
845 /* counter is reset on every update */
846 && EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0)
850 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
851 /* restore iv length field */
852 if (EVP_EncryptUpdate(ctx
, NULL
, &outl
, NULL
, lengths
[testnum
]) > 0
853 /* counter is reset on every update */
854 && EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0)
859 final
= EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
861 final
= EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
864 BIO_printf(bio_err
, "Error finalizing ccm loop\n");
869 * To make AEAD benchmarking more relevant perform TLS-like operations,
870 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
871 * payload length is not actually limited by 16KB...
873 static int EVP_Update_loop_aead(void *args
)
875 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
876 unsigned char *buf
= tempargs
->buf
;
877 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
878 int outl
, count
, realcount
= 0;
879 unsigned char aad
[13] = { 0xcc };
880 unsigned char faketag
[16] = { 0xcc };
883 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
884 if (EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
885 && EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
,
886 sizeof(faketag
), faketag
) > 0
887 && EVP_DecryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
)) > 0
888 && EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0
889 && EVP_DecryptFinal_ex(ctx
, buf
+ outl
, &outl
) >0)
893 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
894 if (EVP_EncryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
895 && EVP_EncryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
)) > 0
896 && EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0
897 && EVP_EncryptFinal_ex(ctx
, buf
+ outl
, &outl
) > 0)
904 static int RSA_sign_loop(void *args
)
906 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
907 unsigned char *buf
= tempargs
->buf
;
908 unsigned char *buf2
= tempargs
->buf2
;
909 size_t *rsa_num
= &tempargs
->sigsize
;
910 EVP_PKEY_CTX
**rsa_sign_ctx
= tempargs
->rsa_sign_ctx
;
913 for (count
= 0; COND(rsa_c
[testnum
][0]); count
++) {
914 *rsa_num
= tempargs
->buflen
;
915 ret
= EVP_PKEY_sign(rsa_sign_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
917 BIO_printf(bio_err
, "RSA sign failure\n");
918 ERR_print_errors(bio_err
);
926 static int RSA_verify_loop(void *args
)
928 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
929 unsigned char *buf
= tempargs
->buf
;
930 unsigned char *buf2
= tempargs
->buf2
;
931 size_t rsa_num
= tempargs
->sigsize
;
932 EVP_PKEY_CTX
**rsa_verify_ctx
= tempargs
->rsa_verify_ctx
;
935 for (count
= 0; COND(rsa_c
[testnum
][1]); count
++) {
936 ret
= EVP_PKEY_verify(rsa_verify_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
938 BIO_printf(bio_err
, "RSA verify failure\n");
939 ERR_print_errors(bio_err
);
947 #ifndef OPENSSL_NO_DH
949 static int FFDH_derive_key_loop(void *args
)
951 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
952 EVP_PKEY_CTX
*ffdh_ctx
= tempargs
->ffdh_ctx
[testnum
];
953 unsigned char *derived_secret
= tempargs
->secret_ff_a
;
956 for (count
= 0; COND(ffdh_c
[testnum
][0]); count
++) {
957 /* outlen can be overwritten with a too small value (no padding used) */
958 size_t outlen
= MAX_FFDH_SIZE
;
960 EVP_PKEY_derive(ffdh_ctx
, derived_secret
, &outlen
);
964 #endif /* OPENSSL_NO_DH */
966 static int DSA_sign_loop(void *args
)
968 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
969 unsigned char *buf
= tempargs
->buf
;
970 unsigned char *buf2
= tempargs
->buf2
;
971 size_t *dsa_num
= &tempargs
->sigsize
;
972 EVP_PKEY_CTX
**dsa_sign_ctx
= tempargs
->dsa_sign_ctx
;
975 for (count
= 0; COND(dsa_c
[testnum
][0]); count
++) {
976 *dsa_num
= tempargs
->buflen
;
977 ret
= EVP_PKEY_sign(dsa_sign_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
979 BIO_printf(bio_err
, "DSA sign failure\n");
980 ERR_print_errors(bio_err
);
988 static int DSA_verify_loop(void *args
)
990 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
991 unsigned char *buf
= tempargs
->buf
;
992 unsigned char *buf2
= tempargs
->buf2
;
993 size_t dsa_num
= tempargs
->sigsize
;
994 EVP_PKEY_CTX
**dsa_verify_ctx
= tempargs
->dsa_verify_ctx
;
997 for (count
= 0; COND(dsa_c
[testnum
][1]); count
++) {
998 ret
= EVP_PKEY_verify(dsa_verify_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
1000 BIO_printf(bio_err
, "DSA verify failure\n");
1001 ERR_print_errors(bio_err
);
1009 static int ECDSA_sign_loop(void *args
)
1011 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1012 unsigned char *buf
= tempargs
->buf
;
1013 unsigned char *buf2
= tempargs
->buf2
;
1014 size_t *ecdsa_num
= &tempargs
->sigsize
;
1015 EVP_PKEY_CTX
**ecdsa_sign_ctx
= tempargs
->ecdsa_sign_ctx
;
1018 for (count
= 0; COND(ecdsa_c
[testnum
][0]); count
++) {
1019 *ecdsa_num
= tempargs
->buflen
;
1020 ret
= EVP_PKEY_sign(ecdsa_sign_ctx
[testnum
], buf2
, ecdsa_num
, buf
, 20);
1022 BIO_printf(bio_err
, "ECDSA sign failure\n");
1023 ERR_print_errors(bio_err
);
1031 static int ECDSA_verify_loop(void *args
)
1033 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1034 unsigned char *buf
= tempargs
->buf
;
1035 unsigned char *buf2
= tempargs
->buf2
;
1036 size_t ecdsa_num
= tempargs
->sigsize
;
1037 EVP_PKEY_CTX
**ecdsa_verify_ctx
= tempargs
->ecdsa_verify_ctx
;
1040 for (count
= 0; COND(ecdsa_c
[testnum
][1]); count
++) {
1041 ret
= EVP_PKEY_verify(ecdsa_verify_ctx
[testnum
], buf2
, ecdsa_num
,
1044 BIO_printf(bio_err
, "ECDSA verify failure\n");
1045 ERR_print_errors(bio_err
);
1053 /* ******************************************************************** */
1055 static int ECDH_EVP_derive_key_loop(void *args
)
1057 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1058 EVP_PKEY_CTX
*ctx
= tempargs
->ecdh_ctx
[testnum
];
1059 unsigned char *derived_secret
= tempargs
->secret_a
;
1061 size_t *outlen
= &(tempargs
->outlen
[testnum
]);
1063 for (count
= 0; COND(ecdh_c
[testnum
][0]); count
++)
1064 EVP_PKEY_derive(ctx
, derived_secret
, outlen
);
1069 #ifndef OPENSSL_NO_ECX
1070 static int EdDSA_sign_loop(void *args
)
1072 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1073 unsigned char *buf
= tempargs
->buf
;
1074 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx
;
1075 unsigned char *eddsasig
= tempargs
->buf2
;
1076 size_t *eddsasigsize
= &tempargs
->sigsize
;
1079 for (count
= 0; COND(eddsa_c
[testnum
][0]); count
++) {
1080 ret
= EVP_DigestSign(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1082 BIO_printf(bio_err
, "EdDSA sign failure\n");
1083 ERR_print_errors(bio_err
);
1091 static int EdDSA_verify_loop(void *args
)
1093 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1094 unsigned char *buf
= tempargs
->buf
;
1095 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx2
;
1096 unsigned char *eddsasig
= tempargs
->buf2
;
1097 size_t eddsasigsize
= tempargs
->sigsize
;
1100 for (count
= 0; COND(eddsa_c
[testnum
][1]); count
++) {
1101 ret
= EVP_DigestVerify(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1103 BIO_printf(bio_err
, "EdDSA verify failure\n");
1104 ERR_print_errors(bio_err
);
1111 #endif /* OPENSSL_NO_ECX */
1113 #ifndef OPENSSL_NO_SM2
1114 static int SM2_sign_loop(void *args
)
1116 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1117 unsigned char *buf
= tempargs
->buf
;
1118 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_ctx
;
1119 unsigned char *sm2sig
= tempargs
->buf2
;
1122 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1123 const size_t max_size
= EVP_PKEY_get_size(sm2_pkey
[testnum
]);
1125 for (count
= 0; COND(sm2_c
[testnum
][0]); count
++) {
1126 sm2sigsize
= max_size
;
1128 if (!EVP_DigestSignInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1129 NULL
, sm2_pkey
[testnum
])) {
1130 BIO_printf(bio_err
, "SM2 init sign failure\n");
1131 ERR_print_errors(bio_err
);
1135 ret
= EVP_DigestSign(sm2ctx
[testnum
], sm2sig
, &sm2sigsize
,
1138 BIO_printf(bio_err
, "SM2 sign failure\n");
1139 ERR_print_errors(bio_err
);
1143 /* update the latest returned size and always use the fixed buffer size */
1144 tempargs
->sigsize
= sm2sigsize
;
1150 static int SM2_verify_loop(void *args
)
1152 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1153 unsigned char *buf
= tempargs
->buf
;
1154 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_vfy_ctx
;
1155 unsigned char *sm2sig
= tempargs
->buf2
;
1156 size_t sm2sigsize
= tempargs
->sigsize
;
1158 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1160 for (count
= 0; COND(sm2_c
[testnum
][1]); count
++) {
1161 if (!EVP_DigestVerifyInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1162 NULL
, sm2_pkey
[testnum
])) {
1163 BIO_printf(bio_err
, "SM2 verify init failure\n");
1164 ERR_print_errors(bio_err
);
1168 ret
= EVP_DigestVerify(sm2ctx
[testnum
], sm2sig
, sm2sigsize
,
1171 BIO_printf(bio_err
, "SM2 verify failure\n");
1172 ERR_print_errors(bio_err
);
1179 #endif /* OPENSSL_NO_SM2 */
1181 static int KEM_keygen_loop(void *args
)
1183 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1184 EVP_PKEY_CTX
*ctx
= tempargs
->kem_gen_ctx
[testnum
];
1185 EVP_PKEY
*pkey
= NULL
;
1188 for (count
= 0; COND(kems_c
[testnum
][0]); count
++) {
1189 if (EVP_PKEY_keygen(ctx
, &pkey
) <= 0)
1192 * runtime defined to quite some degree by randomness,
1193 * so performance overhead of _free doesn't impact
1194 * results significantly. In any case this test is
1195 * meant to permit relative algorithm performance
1198 EVP_PKEY_free(pkey
);
1204 static int KEM_encaps_loop(void *args
)
1206 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1207 EVP_PKEY_CTX
*ctx
= tempargs
->kem_encaps_ctx
[testnum
];
1208 size_t out_len
= tempargs
->kem_out_len
[testnum
];
1209 size_t secret_len
= tempargs
->kem_secret_len
[testnum
];
1210 unsigned char *out
= tempargs
->kem_out
[testnum
];
1211 unsigned char *secret
= tempargs
->kem_send_secret
[testnum
];
1214 for (count
= 0; COND(kems_c
[testnum
][1]); count
++) {
1215 if (EVP_PKEY_encapsulate(ctx
, out
, &out_len
, secret
, &secret_len
) <= 0)
1221 static int KEM_decaps_loop(void *args
)
1223 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1224 EVP_PKEY_CTX
*ctx
= tempargs
->kem_decaps_ctx
[testnum
];
1225 size_t out_len
= tempargs
->kem_out_len
[testnum
];
1226 size_t secret_len
= tempargs
->kem_secret_len
[testnum
];
1227 unsigned char *out
= tempargs
->kem_out
[testnum
];
1228 unsigned char *secret
= tempargs
->kem_send_secret
[testnum
];
1231 for (count
= 0; COND(kems_c
[testnum
][2]); count
++) {
1232 if (EVP_PKEY_decapsulate(ctx
, secret
, &secret_len
, out
, out_len
) <= 0)
1238 static int SIG_keygen_loop(void *args
)
1240 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1241 EVP_PKEY_CTX
*ctx
= tempargs
->sig_gen_ctx
[testnum
];
1242 EVP_PKEY
*pkey
= NULL
;
1245 for (count
= 0; COND(kems_c
[testnum
][0]); count
++) {
1246 EVP_PKEY_keygen(ctx
, &pkey
);
1247 /* TBD: How much does free influence runtime? */
1248 EVP_PKEY_free(pkey
);
1254 static int SIG_sign_loop(void *args
)
1256 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1257 EVP_PKEY_CTX
*ctx
= tempargs
->sig_sign_ctx
[testnum
];
1258 /* be sure to not change stored sig: */
1259 unsigned char *sig
= app_malloc(tempargs
->sig_max_sig_len
[testnum
],
1261 unsigned char md
[SHA256_DIGEST_LENGTH
] = { 0 };
1262 size_t md_len
= SHA256_DIGEST_LENGTH
;
1265 for (count
= 0; COND(kems_c
[testnum
][1]); count
++) {
1266 size_t sig_len
= tempargs
->sig_max_sig_len
[testnum
];
1267 int ret
= EVP_PKEY_sign(ctx
, sig
, &sig_len
, md
, md_len
);
1270 BIO_printf(bio_err
, "SIG sign failure at count %d\n", count
);
1271 ERR_print_errors(bio_err
);
1280 static int SIG_verify_loop(void *args
)
1282 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1283 EVP_PKEY_CTX
*ctx
= tempargs
->sig_verify_ctx
[testnum
];
1284 size_t sig_len
= tempargs
->sig_act_sig_len
[testnum
];
1285 unsigned char *sig
= tempargs
->sig_sig
[testnum
];
1286 unsigned char md
[SHA256_DIGEST_LENGTH
] = { 0 };
1287 size_t md_len
= SHA256_DIGEST_LENGTH
;
1290 for (count
= 0; COND(kems_c
[testnum
][2]); count
++) {
1291 int ret
= EVP_PKEY_verify(ctx
, sig
, sig_len
, md
, md_len
);
1294 BIO_printf(bio_err
, "SIG verify failure at count %d\n", count
);
1295 ERR_print_errors(bio_err
);
1304 static int run_benchmark(int async_jobs
,
1305 int (*loop_function
) (void *), loopargs_t
* loopargs
)
1307 int job_op_count
= 0;
1308 int total_op_count
= 0;
1309 int num_inprogress
= 0;
1310 int error
= 0, i
= 0, ret
= 0;
1311 OSSL_ASYNC_FD job_fd
= 0;
1312 size_t num_job_fds
= 0;
1314 if (async_jobs
== 0) {
1315 return loop_function((void *)&loopargs
);
1318 for (i
= 0; i
< async_jobs
&& !error
; i
++) {
1319 loopargs_t
*looparg_item
= loopargs
+ i
;
1321 /* Copy pointer content (looparg_t item address) into async context */
1322 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
, loopargs
[i
].wait_ctx
,
1323 &job_op_count
, loop_function
,
1324 (void *)&looparg_item
, sizeof(looparg_item
));
1330 if (job_op_count
== -1) {
1333 total_op_count
+= job_op_count
;
1338 BIO_printf(bio_err
, "Failure in the job\n");
1339 ERR_print_errors(bio_err
);
1345 while (num_inprogress
> 0) {
1346 #if defined(OPENSSL_SYS_WINDOWS)
1348 #elif defined(OPENSSL_SYS_UNIX)
1349 int select_result
= 0;
1350 OSSL_ASYNC_FD max_fd
= 0;
1353 FD_ZERO(&waitfdset
);
1355 for (i
= 0; i
< async_jobs
&& num_inprogress
> 0; i
++) {
1356 if (loopargs
[i
].inprogress_job
== NULL
)
1359 if (!ASYNC_WAIT_CTX_get_all_fds
1360 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1361 || num_job_fds
> 1) {
1362 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1363 ERR_print_errors(bio_err
);
1367 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1369 FD_SET(job_fd
, &waitfdset
);
1370 if (job_fd
> max_fd
)
1374 if (max_fd
>= (OSSL_ASYNC_FD
)FD_SETSIZE
) {
1376 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1377 "Decrease the value of async_jobs\n",
1378 max_fd
, FD_SETSIZE
);
1379 ERR_print_errors(bio_err
);
1384 select_result
= select(max_fd
+ 1, &waitfdset
, NULL
, NULL
, NULL
);
1385 if (select_result
== -1 && errno
== EINTR
)
1388 if (select_result
== -1) {
1389 BIO_printf(bio_err
, "Failure in the select\n");
1390 ERR_print_errors(bio_err
);
1395 if (select_result
== 0)
1399 for (i
= 0; i
< async_jobs
; i
++) {
1400 if (loopargs
[i
].inprogress_job
== NULL
)
1403 if (!ASYNC_WAIT_CTX_get_all_fds
1404 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1405 || num_job_fds
> 1) {
1406 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1407 ERR_print_errors(bio_err
);
1411 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1414 #if defined(OPENSSL_SYS_UNIX)
1415 if (num_job_fds
== 1 && !FD_ISSET(job_fd
, &waitfdset
))
1417 #elif defined(OPENSSL_SYS_WINDOWS)
1418 if (num_job_fds
== 1
1419 && !PeekNamedPipe(job_fd
, NULL
, 0, NULL
, &avail
, NULL
)
1424 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
,
1425 loopargs
[i
].wait_ctx
, &job_op_count
,
1426 loop_function
, (void *)(loopargs
+ i
),
1427 sizeof(loopargs_t
));
1432 if (job_op_count
== -1) {
1435 total_op_count
+= job_op_count
;
1438 loopargs
[i
].inprogress_job
= NULL
;
1443 loopargs
[i
].inprogress_job
= NULL
;
1444 BIO_printf(bio_err
, "Failure in the job\n");
1445 ERR_print_errors(bio_err
);
1452 return error
? -1 : total_op_count
;
1455 typedef struct ec_curve_st
{
1459 size_t sigsize
; /* only used for EdDSA curves */
1462 static EVP_PKEY
*get_ecdsa(const EC_CURVE
*curve
)
1464 EVP_PKEY_CTX
*kctx
= NULL
;
1465 EVP_PKEY
*key
= NULL
;
1467 /* Ensure that the error queue is empty */
1468 if (ERR_peek_error()) {
1470 "WARNING: the error queue contains previous unhandled errors.\n");
1471 ERR_print_errors(bio_err
);
1475 * Let's try to create a ctx directly from the NID: this works for
1476 * curves like Curve25519 that are not implemented through the low
1477 * level EC interface.
1478 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1479 * then we set the curve by NID before deriving the actual keygen
1480 * ctx for that specific curve.
1482 kctx
= EVP_PKEY_CTX_new_id(curve
->nid
, NULL
);
1484 EVP_PKEY_CTX
*pctx
= NULL
;
1485 EVP_PKEY
*params
= NULL
;
1487 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1488 * "int_ctx_new:unsupported algorithm" error was added to the
1490 * We remove it from the error queue as we are handling it.
1492 unsigned long error
= ERR_peek_error();
1494 if (error
== ERR_peek_last_error() /* oldest and latest errors match */
1495 /* check that the error origin matches */
1496 && ERR_GET_LIB(error
) == ERR_LIB_EVP
1497 && (ERR_GET_REASON(error
) == EVP_R_UNSUPPORTED_ALGORITHM
1498 || ERR_GET_REASON(error
) == ERR_R_UNSUPPORTED
))
1499 ERR_get_error(); /* pop error from queue */
1500 if (ERR_peek_error()) {
1502 "Unhandled error in the error queue during EC key setup.\n");
1503 ERR_print_errors(bio_err
);
1507 /* Create the context for parameter generation */
1508 if ((pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
)) == NULL
1509 || EVP_PKEY_paramgen_init(pctx
) <= 0
1510 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
1512 || EVP_PKEY_paramgen(pctx
, ¶ms
) <= 0) {
1513 BIO_printf(bio_err
, "EC params init failure.\n");
1514 ERR_print_errors(bio_err
);
1515 EVP_PKEY_CTX_free(pctx
);
1518 EVP_PKEY_CTX_free(pctx
);
1520 /* Create the context for the key generation */
1521 kctx
= EVP_PKEY_CTX_new(params
, NULL
);
1522 EVP_PKEY_free(params
);
1525 || EVP_PKEY_keygen_init(kctx
) <= 0
1526 || EVP_PKEY_keygen(kctx
, &key
) <= 0) {
1527 BIO_printf(bio_err
, "EC key generation failure.\n");
1528 ERR_print_errors(bio_err
);
1531 EVP_PKEY_CTX_free(kctx
);
1535 #define stop_it(do_it, test_num)\
1536 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1538 /* Checks to see if algorithms are fetchable */
1539 #define IS_FETCHABLE(type, TYPE) \
1540 static int is_ ## type ## _fetchable(const TYPE *alg) \
1543 const char *propq = app_get0_propq(); \
1544 OSSL_LIB_CTX *libctx = app_get0_libctx(); \
1545 const char *name = TYPE ## _get0_name(alg); \
1548 impl = TYPE ## _fetch(libctx, name, propq); \
1549 ERR_pop_to_mark(); \
1552 TYPE ## _free(impl); \
1556 IS_FETCHABLE(signature
, EVP_SIGNATURE
)
1557 IS_FETCHABLE(kem
, EVP_KEM
)
1559 DEFINE_STACK_OF(EVP_KEM
)
1561 static int kems_cmp(const EVP_KEM
* const *a
,
1562 const EVP_KEM
* const *b
)
1564 return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a
)),
1565 OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b
)));
1568 static void collect_kem(EVP_KEM
*kem
, void *stack
)
1570 STACK_OF(EVP_KEM
) *kem_stack
= stack
;
1572 if (is_kem_fetchable(kem
)
1573 && sk_EVP_KEM_push(kem_stack
, kem
) > 0) {
1574 EVP_KEM_up_ref(kem
);
1578 static int kem_locate(const char *algo
, unsigned int *idx
)
1582 for (i
= 0; i
< kems_algs_len
; i
++) {
1583 if (strcmp(kems_algname
[i
], algo
) == 0) {
1591 DEFINE_STACK_OF(EVP_SIGNATURE
)
1593 static int signatures_cmp(const EVP_SIGNATURE
* const *a
,
1594 const EVP_SIGNATURE
* const *b
)
1596 return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a
)),
1597 OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b
)));
1600 static void collect_signatures(EVP_SIGNATURE
*sig
, void *stack
)
1602 STACK_OF(EVP_SIGNATURE
) *sig_stack
= stack
;
1604 if (is_signature_fetchable(sig
)
1605 && sk_EVP_SIGNATURE_push(sig_stack
, sig
) > 0)
1606 EVP_SIGNATURE_up_ref(sig
);
1609 static int sig_locate(const char *algo
, unsigned int *idx
)
1613 for (i
= 0; i
< sigs_algs_len
; i
++) {
1614 if (strcmp(sigs_algname
[i
], algo
) == 0) {
1622 static int get_max(const uint8_t doit
[], size_t algs_len
) {
1626 for (i
= 0; i
< algs_len
; i
++)
1627 if (maxcnt
< doit
[i
]) maxcnt
= doit
[i
];
1631 int speed_main(int argc
, char **argv
)
1635 loopargs_t
*loopargs
= NULL
;
1637 const char *engine_id
= NULL
;
1638 EVP_CIPHER
*evp_cipher
= NULL
;
1639 EVP_MAC
*mac
= NULL
;
1642 int async_init
= 0, multiblock
= 0, pr_header
= 0;
1643 uint8_t doit
[ALGOR_NUM
] = { 0 };
1644 int ret
= 1, misalign
= 0, lengths_single
= 0, aead
= 0;
1645 STACK_OF(EVP_KEM
) *kem_stack
= NULL
;
1646 STACK_OF(EVP_SIGNATURE
) *sig_stack
= NULL
;
1648 unsigned int size_num
= SIZE_NUM
;
1649 unsigned int i
, k
, loopargs_len
= 0, async_jobs
= 0;
1654 EVP_PKEY_CTX
*genctx
= NULL
;
1659 openssl_speed_sec_t seconds
= { SECONDS
, RSA_SECONDS
, DSA_SECONDS
,
1660 ECDSA_SECONDS
, ECDH_SECONDS
,
1661 EdDSA_SECONDS
, SM2_SECONDS
,
1662 FFDH_SECONDS
, KEM_SECONDS
,
1665 static const unsigned char key32
[32] = {
1666 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1667 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1668 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1669 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1671 static const unsigned char deskey
[] = {
1672 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1673 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1674 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1676 static const struct {
1677 const unsigned char *data
;
1678 unsigned int length
;
1681 { test512
, sizeof(test512
), 512 },
1682 { test1024
, sizeof(test1024
), 1024 },
1683 { test2048
, sizeof(test2048
), 2048 },
1684 { test3072
, sizeof(test3072
), 3072 },
1685 { test4096
, sizeof(test4096
), 4096 },
1686 { test7680
, sizeof(test7680
), 7680 },
1687 { test15360
, sizeof(test15360
), 15360 }
1689 uint8_t rsa_doit
[RSA_NUM
] = { 0 };
1690 int primes
= RSA_DEFAULT_PRIME_NUM
;
1691 #ifndef OPENSSL_NO_DH
1692 typedef struct ffdh_params_st
{
1698 static const FFDH_PARAMS ffdh_params
[FFDH_NUM
] = {
1699 {"ffdh2048", NID_ffdhe2048
, 2048},
1700 {"ffdh3072", NID_ffdhe3072
, 3072},
1701 {"ffdh4096", NID_ffdhe4096
, 4096},
1702 {"ffdh6144", NID_ffdhe6144
, 6144},
1703 {"ffdh8192", NID_ffdhe8192
, 8192}
1705 uint8_t ffdh_doit
[FFDH_NUM
] = { 0 };
1707 #endif /* OPENSSL_NO_DH */
1708 static const unsigned int dsa_bits
[DSA_NUM
] = { 1024, 2048 };
1709 uint8_t dsa_doit
[DSA_NUM
] = { 0 };
1711 * We only test over the following curves as they are representative, To
1712 * add tests over more curves, simply add the curve NID and curve name to
1713 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1714 * lists accordingly.
1716 static const EC_CURVE ec_curves
[EC_NUM
] = {
1718 {"secp160r1", NID_secp160r1
, 160},
1719 {"nistp192", NID_X9_62_prime192v1
, 192},
1720 {"nistp224", NID_secp224r1
, 224},
1721 {"nistp256", NID_X9_62_prime256v1
, 256},
1722 {"nistp384", NID_secp384r1
, 384},
1723 {"nistp521", NID_secp521r1
, 521},
1724 #ifndef OPENSSL_NO_EC2M
1726 {"nistk163", NID_sect163k1
, 163},
1727 {"nistk233", NID_sect233k1
, 233},
1728 {"nistk283", NID_sect283k1
, 283},
1729 {"nistk409", NID_sect409k1
, 409},
1730 {"nistk571", NID_sect571k1
, 571},
1731 {"nistb163", NID_sect163r2
, 163},
1732 {"nistb233", NID_sect233r1
, 233},
1733 {"nistb283", NID_sect283r1
, 283},
1734 {"nistb409", NID_sect409r1
, 409},
1735 {"nistb571", NID_sect571r1
, 571},
1737 {"brainpoolP256r1", NID_brainpoolP256r1
, 256},
1738 {"brainpoolP256t1", NID_brainpoolP256t1
, 256},
1739 {"brainpoolP384r1", NID_brainpoolP384r1
, 384},
1740 {"brainpoolP384t1", NID_brainpoolP384t1
, 384},
1741 {"brainpoolP512r1", NID_brainpoolP512r1
, 512},
1742 {"brainpoolP512t1", NID_brainpoolP512t1
, 512},
1743 #ifndef OPENSSL_NO_ECX
1744 /* Other and ECDH only ones */
1745 {"X25519", NID_X25519
, 253},
1746 {"X448", NID_X448
, 448}
1749 #ifndef OPENSSL_NO_ECX
1750 static const EC_CURVE ed_curves
[EdDSA_NUM
] = {
1752 {"Ed25519", NID_ED25519
, 253, 64},
1753 {"Ed448", NID_ED448
, 456, 114}
1755 #endif /* OPENSSL_NO_ECX */
1756 #ifndef OPENSSL_NO_SM2
1757 static const EC_CURVE sm2_curves
[SM2_NUM
] = {
1759 {"CurveSM2", NID_sm2
, 256}
1761 uint8_t sm2_doit
[SM2_NUM
] = { 0 };
1763 uint8_t ecdsa_doit
[ECDSA_NUM
] = { 0 };
1764 uint8_t ecdh_doit
[EC_NUM
] = { 0 };
1765 #ifndef OPENSSL_NO_ECX
1766 uint8_t eddsa_doit
[EdDSA_NUM
] = { 0 };
1767 #endif /* OPENSSL_NO_ECX */
1769 uint8_t kems_doit
[MAX_KEM_NUM
] = { 0 };
1770 uint8_t sigs_doit
[MAX_SIG_NUM
] = { 0 };
1772 uint8_t do_kems
= 0;
1773 uint8_t do_sigs
= 0;
1775 /* checks declared curves against choices list. */
1776 #ifndef OPENSSL_NO_ECX
1777 OPENSSL_assert(ed_curves
[EdDSA_NUM
- 1].nid
== NID_ED448
);
1778 OPENSSL_assert(strcmp(eddsa_choices
[EdDSA_NUM
- 1].name
, "ed448") == 0);
1780 OPENSSL_assert(ec_curves
[EC_NUM
- 1].nid
== NID_X448
);
1781 OPENSSL_assert(strcmp(ecdh_choices
[EC_NUM
- 1].name
, "ecdhx448") == 0);
1783 OPENSSL_assert(ec_curves
[ECDSA_NUM
- 1].nid
== NID_brainpoolP512t1
);
1784 OPENSSL_assert(strcmp(ecdsa_choices
[ECDSA_NUM
- 1].name
, "ecdsabrp512t1") == 0);
1785 #endif /* OPENSSL_NO_ECX */
1787 #ifndef OPENSSL_NO_SM2
1788 OPENSSL_assert(sm2_curves
[SM2_NUM
- 1].nid
== NID_sm2
);
1789 OPENSSL_assert(strcmp(sm2_choices
[SM2_NUM
- 1].name
, "curveSM2") == 0);
1792 prog
= opt_init(argc
, argv
, speed_options
);
1793 while ((o
= opt_next()) != OPT_EOF
) {
1798 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
1801 opt_help(speed_options
);
1809 BIO_printf(bio_err
, "%s: -evp option cannot be used more than once\n", prog
);
1813 if (!opt_cipher_silent(opt_arg(), &evp_cipher
)) {
1814 if (have_md(opt_arg()))
1815 evp_md_name
= opt_arg();
1817 if (evp_cipher
== NULL
&& evp_md_name
== NULL
) {
1818 ERR_clear_last_mark();
1820 "%s: %s is an unknown cipher or digest\n",
1828 if (!have_md(opt_arg())) {
1829 BIO_printf(bio_err
, "%s: %s is an unknown digest\n",
1833 evp_mac_mdname
= opt_arg();
1837 if (!have_cipher(opt_arg())) {
1838 BIO_printf(bio_err
, "%s: %s is an unknown cipher\n",
1842 evp_mac_ciphername
= opt_arg();
1843 doit
[D_EVP_CMAC
] = 1;
1850 * In a forked execution, an engine might need to be
1851 * initialised by each child process, not by the parent.
1852 * So store the name here and run setup_engine() later on.
1854 engine_id
= opt_arg();
1858 multi
= opt_int_arg();
1859 if ((size_t)multi
>= SIZE_MAX
/ sizeof(int)) {
1860 BIO_printf(bio_err
, "%s: multi argument too large\n", prog
);
1866 #ifndef OPENSSL_NO_ASYNC
1867 async_jobs
= opt_int_arg();
1868 if (!ASYNC_is_capable()) {
1870 "%s: async_jobs specified but async not supported\n",
1874 if (async_jobs
> 99999) {
1875 BIO_printf(bio_err
, "%s: too many async_jobs\n", prog
);
1881 misalign
= opt_int_arg();
1882 if (misalign
> MISALIGN
) {
1884 "%s: Maximum offset is %d\n", prog
, MISALIGN
);
1893 #ifdef OPENSSL_NO_MULTIBLOCK
1895 "%s: -mb specified but multi-block support is disabled\n",
1904 case OPT_PROV_CASES
:
1905 if (!opt_provider(o
))
1909 conf
= app_load_config_modules(opt_arg());
1914 primes
= opt_int_arg();
1917 seconds
.sym
= seconds
.rsa
= seconds
.dsa
= seconds
.ecdsa
1918 = seconds
.ecdh
= seconds
.eddsa
1919 = seconds
.sm2
= seconds
.ffdh
1920 = seconds
.kem
= seconds
.sig
= opt_int_arg();
1923 lengths_single
= opt_int_arg();
1924 lengths
= &lengths_single
;
1938 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
1940 "%s: -mlock not supported on this platform\n",
1948 /* find all KEMs currently available */
1949 kem_stack
= sk_EVP_KEM_new(kems_cmp
);
1950 EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem
, kem_stack
);
1954 for (idx
= 0; idx
< (unsigned int)sk_EVP_KEM_num(kem_stack
); idx
++) {
1955 EVP_KEM
*kem
= sk_EVP_KEM_value(kem_stack
, idx
);
1957 if (strcmp(EVP_KEM_get0_name(kem
), "RSA") == 0) {
1958 if (kems_algs_len
+ OSSL_NELEM(rsa_choices
) >= MAX_KEM_NUM
) {
1960 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
1963 for (i
= 0; i
< OSSL_NELEM(rsa_choices
); i
++) {
1964 kems_doit
[kems_algs_len
] = 1;
1965 kems_algname
[kems_algs_len
++] = OPENSSL_strdup(rsa_choices
[i
].name
);
1967 } else if (strcmp(EVP_KEM_get0_name(kem
), "EC") == 0) {
1968 if (kems_algs_len
+ 3 >= MAX_KEM_NUM
) {
1970 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
1973 kems_doit
[kems_algs_len
] = 1;
1974 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-256");
1975 kems_doit
[kems_algs_len
] = 1;
1976 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-384");
1977 kems_doit
[kems_algs_len
] = 1;
1978 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-521");
1980 if (kems_algs_len
+ 1 >= MAX_KEM_NUM
) {
1982 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
1985 kems_doit
[kems_algs_len
] = 1;
1986 kems_algname
[kems_algs_len
++] = OPENSSL_strdup(EVP_KEM_get0_name(kem
));
1989 sk_EVP_KEM_pop_free(kem_stack
, EVP_KEM_free
);
1992 /* find all SIGNATUREs currently available */
1993 sig_stack
= sk_EVP_SIGNATURE_new(signatures_cmp
);
1994 EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures
, sig_stack
);
1998 for (idx
= 0; idx
< (unsigned int)sk_EVP_SIGNATURE_num(sig_stack
); idx
++) {
1999 EVP_SIGNATURE
*s
= sk_EVP_SIGNATURE_value(sig_stack
, idx
);
2000 const char *sig_name
= EVP_SIGNATURE_get0_name(s
);
2002 if (strcmp(sig_name
, "RSA") == 0) {
2003 if (sigs_algs_len
+ OSSL_NELEM(rsa_choices
) >= MAX_SIG_NUM
) {
2005 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2008 for (i
= 0; i
< OSSL_NELEM(rsa_choices
); i
++) {
2009 sigs_doit
[sigs_algs_len
] = 1;
2010 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(rsa_choices
[i
].name
);
2013 else if (strcmp(sig_name
, "DSA") == 0) {
2014 if (sigs_algs_len
+ DSA_NUM
>= MAX_SIG_NUM
) {
2016 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2019 for (i
= 0; i
< DSA_NUM
; i
++) {
2020 sigs_doit
[sigs_algs_len
] = 1;
2021 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(dsa_choices
[i
].name
);
2024 /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2025 else if (strcmp(sig_name
, "ED25519") &&
2026 strcmp(sig_name
, "ED448") &&
2027 strcmp(sig_name
, "ECDSA") &&
2028 strcmp(sig_name
, "HMAC") &&
2029 strcmp(sig_name
, "SIPHASH") &&
2030 strcmp(sig_name
, "POLY1305") &&
2031 strcmp(sig_name
, "CMAC") &&
2032 strcmp(sig_name
, "SM2")) { /* skip alg */
2033 if (sigs_algs_len
+ 1 >= MAX_SIG_NUM
) {
2035 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2038 /* activate this provider algorithm */
2039 sigs_doit
[sigs_algs_len
] = 1;
2040 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(sig_name
);
2044 /* Remaining arguments are algorithms. */
2045 argc
= opt_num_rest();
2048 if (!app_RAND_load())
2051 for (; *argv
; argv
++) {
2052 const char *algo
= *argv
;
2055 if (opt_found(algo
, doit_choices
, &i
)) {
2059 if (strcmp(algo
, "des") == 0) {
2060 doit
[D_CBC_DES
] = doit
[D_EDE3_DES
] = 1;
2063 if (strcmp(algo
, "sha") == 0) {
2064 doit
[D_SHA1
] = doit
[D_SHA256
] = doit
[D_SHA512
] = 1;
2067 #ifndef OPENSSL_NO_DEPRECATED_3_0
2068 if (strcmp(algo
, "openssl") == 0) /* just for compatibility */
2071 if (HAS_PREFIX(algo
, "rsa")) {
2072 if (algo
[sizeof("rsa") - 1] == '\0') {
2073 memset(rsa_doit
, 1, sizeof(rsa_doit
));
2076 if (opt_found(algo
, rsa_choices
, &i
)) {
2081 #ifndef OPENSSL_NO_DH
2082 if (HAS_PREFIX(algo
, "ffdh")) {
2083 if (algo
[sizeof("ffdh") - 1] == '\0') {
2084 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
2087 if (opt_found(algo
, ffdh_choices
, &i
)) {
2093 if (HAS_PREFIX(algo
, "dsa")) {
2094 if (algo
[sizeof("dsa") - 1] == '\0') {
2095 memset(dsa_doit
, 1, sizeof(dsa_doit
));
2098 if (opt_found(algo
, dsa_choices
, &i
)) {
2103 if (strcmp(algo
, "aes") == 0) {
2104 doit
[D_CBC_128_AES
] = doit
[D_CBC_192_AES
] = doit
[D_CBC_256_AES
] = 1;
2107 if (strcmp(algo
, "camellia") == 0) {
2108 doit
[D_CBC_128_CML
] = doit
[D_CBC_192_CML
] = doit
[D_CBC_256_CML
] = 1;
2111 if (HAS_PREFIX(algo
, "ecdsa")) {
2112 if (algo
[sizeof("ecdsa") - 1] == '\0') {
2113 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
2116 if (opt_found(algo
, ecdsa_choices
, &i
)) {
2121 if (HAS_PREFIX(algo
, "ecdh")) {
2122 if (algo
[sizeof("ecdh") - 1] == '\0') {
2123 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
2126 if (opt_found(algo
, ecdh_choices
, &i
)) {
2131 #ifndef OPENSSL_NO_ECX
2132 if (strcmp(algo
, "eddsa") == 0) {
2133 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
2136 if (opt_found(algo
, eddsa_choices
, &i
)) {
2140 #endif /* OPENSSL_NO_ECX */
2141 #ifndef OPENSSL_NO_SM2
2142 if (strcmp(algo
, "sm2") == 0) {
2143 memset(sm2_doit
, 1, sizeof(sm2_doit
));
2146 if (opt_found(algo
, sm2_choices
, &i
)) {
2151 if (kem_locate(algo
, &idx
)) {
2156 if (sig_locate(algo
, &idx
)) {
2163 BIO_printf(bio_err
, "%s: Unknown algorithm %s\n", prog
, algo
);
2170 if (evp_cipher
== NULL
) {
2171 BIO_printf(bio_err
, "-aead can be used only with an AEAD cipher\n");
2173 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
2174 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2175 BIO_printf(bio_err
, "%s is not an AEAD cipher\n",
2176 EVP_CIPHER_get0_name(evp_cipher
));
2180 if (kems_algs_len
> 0) {
2181 int maxcnt
= get_max(kems_doit
, kems_algs_len
);
2184 /* some algs explicitly selected */
2185 for (i
= 0; i
< kems_algs_len
; i
++) {
2186 /* disable the rest */
2191 if (sigs_algs_len
> 0) {
2192 int maxcnt
= get_max(sigs_doit
, sigs_algs_len
);
2195 /* some algs explicitly selected */
2196 for (i
= 0; i
< sigs_algs_len
; i
++) {
2197 /* disable the rest */
2203 if (evp_cipher
== NULL
) {
2204 BIO_printf(bio_err
, "-mb can be used only with a multi-block"
2205 " capable cipher\n");
2207 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
2208 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2209 BIO_printf(bio_err
, "%s is not a multi-block capable\n",
2210 EVP_CIPHER_get0_name(evp_cipher
));
2212 } else if (async_jobs
> 0) {
2213 BIO_printf(bio_err
, "Async mode is not supported with -mb");
2218 /* Initialize the job pool if async mode is enabled */
2219 if (async_jobs
> 0) {
2220 async_init
= ASYNC_init_thread(async_jobs
, async_jobs
);
2222 BIO_printf(bio_err
, "Error creating the ASYNC job pool\n");
2227 loopargs_len
= (async_jobs
== 0 ? 1 : async_jobs
);
2229 app_malloc(loopargs_len
* sizeof(loopargs_t
), "array of loopargs");
2230 memset(loopargs
, 0, loopargs_len
* sizeof(loopargs_t
));
2232 buflen
= lengths
[size_num
- 1];
2233 if (buflen
< 36) /* size of random vector in RSA benchmark */
2235 if (INT_MAX
- (MAX_MISALIGNMENT
+ 1) < buflen
) {
2236 BIO_printf(bio_err
, "Error: buffer size too large\n");
2239 buflen
+= MAX_MISALIGNMENT
+ 1;
2240 for (i
= 0; i
< loopargs_len
; i
++) {
2241 if (async_jobs
> 0) {
2242 loopargs
[i
].wait_ctx
= ASYNC_WAIT_CTX_new();
2243 if (loopargs
[i
].wait_ctx
== NULL
) {
2244 BIO_printf(bio_err
, "Error creating the ASYNC_WAIT_CTX\n");
2249 loopargs
[i
].buf_malloc
= app_malloc(buflen
, "input buffer");
2250 loopargs
[i
].buf2_malloc
= app_malloc(buflen
, "input buffer");
2252 /* Align the start of buffers on a 64 byte boundary */
2253 loopargs
[i
].buf
= loopargs
[i
].buf_malloc
+ misalign
;
2254 loopargs
[i
].buf2
= loopargs
[i
].buf2_malloc
+ misalign
;
2255 loopargs
[i
].buflen
= buflen
- misalign
;
2256 loopargs
[i
].sigsize
= buflen
- misalign
;
2257 loopargs
[i
].secret_a
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret a");
2258 loopargs
[i
].secret_b
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret b");
2259 #ifndef OPENSSL_NO_DH
2260 loopargs
[i
].secret_ff_a
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret a");
2261 loopargs
[i
].secret_ff_b
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret b");
2266 if (multi
&& do_multi(multi
, size_num
))
2270 for (i
= 0; i
< loopargs_len
; ++i
) {
2273 (void)VirtualLock(loopargs
[i
].buf_malloc
, buflen
);
2274 (void)VirtualLock(loopargs
[i
].buf2_malloc
, buflen
);
2275 #elif defined(OPENSSL_SYS_LINUX)
2276 (void)mlock(loopargs
[i
].buf_malloc
, buflen
);
2277 (void)mlock(loopargs
[i
].buf_malloc
, buflen
);
2280 memset(loopargs
[i
].buf_malloc
, 0, buflen
);
2281 memset(loopargs
[i
].buf2_malloc
, 0, buflen
);
2284 /* Initialize the engine after the fork */
2285 e
= setup_engine(engine_id
, 0);
2287 /* No parameters; turn on everything. */
2288 if (argc
== 0 && !doit
[D_EVP
] && !doit
[D_HMAC
]
2289 && !doit
[D_EVP_CMAC
] && !do_kems
&& !do_sigs
) {
2290 memset(doit
, 1, sizeof(doit
));
2291 doit
[D_EVP
] = doit
[D_EVP_CMAC
] = 0;
2293 for (i
= D_MD2
; i
<= D_WHIRLPOOL
; i
++) {
2294 if (!have_md(names
[i
]))
2297 for (i
= D_CBC_DES
; i
<= D_CBC_256_CML
; i
++) {
2298 if (!have_cipher(names
[i
]))
2301 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2302 app_get0_propq())) != NULL
) {
2308 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2309 app_get0_propq())) != NULL
) {
2316 memset(rsa_doit
, 1, sizeof(rsa_doit
));
2317 #ifndef OPENSSL_NO_DH
2318 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
2320 memset(dsa_doit
, 1, sizeof(dsa_doit
));
2321 #ifndef OPENSSL_NO_ECX
2322 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
2323 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
2324 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
2325 #endif /* OPENSSL_NO_ECX */
2326 #ifndef OPENSSL_NO_SM2
2327 memset(sm2_doit
, 1, sizeof(sm2_doit
));
2329 memset(kems_doit
, 1, sizeof(kems_doit
));
2331 memset(sigs_doit
, 1, sizeof(sigs_doit
));
2334 for (i
= 0; i
< ALGOR_NUM
; i
++)
2338 if (usertime
== 0 && !mr
)
2340 "You have chosen to measure elapsed time "
2341 "instead of user CPU time.\n");
2344 signal(SIGALRM
, alarmed
);
2348 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2349 print_message(names
[D_MD2
], lengths
[testnum
], seconds
.sym
);
2351 count
= run_benchmark(async_jobs
, EVP_Digest_MD2_loop
, loopargs
);
2353 print_result(D_MD2
, testnum
, count
, d
);
2360 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2361 print_message(names
[D_MDC2
], lengths
[testnum
], seconds
.sym
);
2363 count
= run_benchmark(async_jobs
, EVP_Digest_MDC2_loop
, loopargs
);
2365 print_result(D_MDC2
, testnum
, count
, d
);
2372 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2373 print_message(names
[D_MD4
], lengths
[testnum
], seconds
.sym
);
2375 count
= run_benchmark(async_jobs
, EVP_Digest_MD4_loop
, loopargs
);
2377 print_result(D_MD4
, testnum
, count
, d
);
2384 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2385 print_message(names
[D_MD5
], lengths
[testnum
], seconds
.sym
);
2387 count
= run_benchmark(async_jobs
, MD5_loop
, loopargs
);
2389 print_result(D_MD5
, testnum
, count
, d
);
2396 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2397 print_message(names
[D_SHA1
], lengths
[testnum
], seconds
.sym
);
2399 count
= run_benchmark(async_jobs
, SHA1_loop
, loopargs
);
2401 print_result(D_SHA1
, testnum
, count
, d
);
2407 if (doit
[D_SHA256
]) {
2408 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2409 print_message(names
[D_SHA256
], lengths
[testnum
], seconds
.sym
);
2411 count
= run_benchmark(async_jobs
, SHA256_loop
, loopargs
);
2413 print_result(D_SHA256
, testnum
, count
, d
);
2419 if (doit
[D_SHA512
]) {
2420 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2421 print_message(names
[D_SHA512
], lengths
[testnum
], seconds
.sym
);
2423 count
= run_benchmark(async_jobs
, SHA512_loop
, loopargs
);
2425 print_result(D_SHA512
, testnum
, count
, d
);
2431 if (doit
[D_WHIRLPOOL
]) {
2432 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2433 print_message(names
[D_WHIRLPOOL
], lengths
[testnum
], seconds
.sym
);
2435 count
= run_benchmark(async_jobs
, WHIRLPOOL_loop
, loopargs
);
2437 print_result(D_WHIRLPOOL
, testnum
, count
, d
);
2443 if (doit
[D_RMD160
]) {
2444 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2445 print_message(names
[D_RMD160
], lengths
[testnum
], seconds
.sym
);
2447 count
= run_benchmark(async_jobs
, EVP_Digest_RMD160_loop
, loopargs
);
2449 print_result(D_RMD160
, testnum
, count
, d
);
2456 static const char hmac_key
[] = "This is a key...";
2457 int len
= strlen(hmac_key
);
2458 OSSL_PARAM params
[3];
2460 mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
2461 if (mac
== NULL
|| evp_mac_mdname
== NULL
)
2464 evp_hmac_name
= app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname
),
2466 sprintf(evp_hmac_name
, "hmac(%s)", evp_mac_mdname
);
2467 names
[D_HMAC
] = evp_hmac_name
;
2470 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
2473 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2474 (char *)hmac_key
, len
);
2475 params
[2] = OSSL_PARAM_construct_end();
2477 for (i
= 0; i
< loopargs_len
; i
++) {
2478 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2479 if (loopargs
[i
].mctx
== NULL
)
2482 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2483 goto skip_hmac
; /* Digest not found */
2485 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2486 print_message(names
[D_HMAC
], lengths
[testnum
], seconds
.sym
);
2488 count
= run_benchmark(async_jobs
, HMAC_loop
, loopargs
);
2490 print_result(D_HMAC
, testnum
, count
, d
);
2494 for (i
= 0; i
< loopargs_len
; i
++)
2495 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2500 if (doit
[D_CBC_DES
]) {
2503 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2504 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-cbc", deskey
,
2505 sizeof(deskey
) / 3);
2506 st
= loopargs
[i
].ctx
!= NULL
;
2508 algindex
= D_CBC_DES
;
2509 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2510 print_message(names
[D_CBC_DES
], lengths
[testnum
], seconds
.sym
);
2512 count
= run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2514 print_result(D_CBC_DES
, testnum
, count
, d
);
2516 for (i
= 0; i
< loopargs_len
; i
++)
2517 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2520 if (doit
[D_EDE3_DES
]) {
2523 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2524 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-ede3-cbc", deskey
,
2526 st
= loopargs
[i
].ctx
!= NULL
;
2528 algindex
= D_EDE3_DES
;
2529 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2530 print_message(names
[D_EDE3_DES
], lengths
[testnum
], seconds
.sym
);
2533 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2535 print_result(D_EDE3_DES
, testnum
, count
, d
);
2537 for (i
= 0; i
< loopargs_len
; i
++)
2538 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2541 for (k
= 0; k
< 3; k
++) {
2542 algindex
= D_CBC_128_AES
+ k
;
2543 if (doit
[algindex
]) {
2546 keylen
= 16 + k
* 8;
2547 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2548 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2550 st
= loopargs
[i
].ctx
!= NULL
;
2553 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2554 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2557 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2559 print_result(algindex
, testnum
, count
, d
);
2561 for (i
= 0; i
< loopargs_len
; i
++)
2562 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2566 for (k
= 0; k
< 3; k
++) {
2567 algindex
= D_CBC_128_CML
+ k
;
2568 if (doit
[algindex
]) {
2571 keylen
= 16 + k
* 8;
2572 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2573 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2575 st
= loopargs
[i
].ctx
!= NULL
;
2578 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2579 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2582 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2584 print_result(algindex
, testnum
, count
, d
);
2586 for (i
= 0; i
< loopargs_len
; i
++)
2587 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2591 for (algindex
= D_RC4
; algindex
<= D_CBC_CAST
; algindex
++) {
2592 if (doit
[algindex
]) {
2596 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2597 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2599 st
= loopargs
[i
].ctx
!= NULL
;
2602 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2603 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2606 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2608 print_result(algindex
, testnum
, count
, d
);
2610 for (i
= 0; i
< loopargs_len
; i
++)
2611 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2614 if (doit
[D_GHASH
]) {
2615 static const char gmac_iv
[] = "0123456789ab";
2616 OSSL_PARAM params
[3];
2618 mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2622 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2624 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV
,
2626 sizeof(gmac_iv
) - 1);
2627 params
[2] = OSSL_PARAM_construct_end();
2629 for (i
= 0; i
< loopargs_len
; i
++) {
2630 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2631 if (loopargs
[i
].mctx
== NULL
)
2634 if (!EVP_MAC_init(loopargs
[i
].mctx
, key32
, 16, params
))
2637 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2638 print_message(names
[D_GHASH
], lengths
[testnum
], seconds
.sym
);
2640 count
= run_benchmark(async_jobs
, GHASH_loop
, loopargs
);
2642 print_result(D_GHASH
, testnum
, count
, d
);
2646 for (i
= 0; i
< loopargs_len
; i
++)
2647 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2653 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2654 print_message(names
[D_RAND
], lengths
[testnum
], seconds
.sym
);
2656 count
= run_benchmark(async_jobs
, RAND_bytes_loop
, loopargs
);
2658 print_result(D_RAND
, testnum
, count
, d
);
2663 if (evp_cipher
!= NULL
) {
2664 int (*loopfunc
) (void *) = EVP_Update_loop
;
2666 if (multiblock
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2667 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2668 multiblock_speed(evp_cipher
, lengths_single
, &seconds
);
2673 names
[D_EVP
] = EVP_CIPHER_get0_name(evp_cipher
);
2675 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_CCM_MODE
) {
2676 loopfunc
= EVP_Update_loop_ccm
;
2677 } else if (aead
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2678 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2679 loopfunc
= EVP_Update_loop_aead
;
2680 if (lengths
== lengths_list
) {
2681 lengths
= aead_lengths_list
;
2682 size_num
= OSSL_NELEM(aead_lengths_list
);
2686 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2687 print_message(names
[D_EVP
], lengths
[testnum
], seconds
.sym
);
2689 for (k
= 0; k
< loopargs_len
; k
++) {
2690 loopargs
[k
].ctx
= EVP_CIPHER_CTX_new();
2691 if (loopargs
[k
].ctx
== NULL
) {
2692 BIO_printf(bio_err
, "\nEVP_CIPHER_CTX_new failure\n");
2695 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, evp_cipher
, NULL
,
2696 NULL
, iv
, decrypt
? 0 : 1)) {
2697 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2698 ERR_print_errors(bio_err
);
2702 EVP_CIPHER_CTX_set_padding(loopargs
[k
].ctx
, 0);
2704 keylen
= EVP_CIPHER_CTX_get_key_length(loopargs
[k
].ctx
);
2705 loopargs
[k
].key
= app_malloc(keylen
, "evp_cipher key");
2706 EVP_CIPHER_CTX_rand_key(loopargs
[k
].ctx
, loopargs
[k
].key
);
2707 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, NULL
, NULL
,
2708 loopargs
[k
].key
, NULL
, -1)) {
2709 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2710 ERR_print_errors(bio_err
);
2713 OPENSSL_clear_free(loopargs
[k
].key
, keylen
);
2715 /* GCM-SIV/SIV mode only allows for a single Update operation */
2716 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_SIV_MODE
2717 || EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_GCM_SIV_MODE
)
2718 (void)EVP_CIPHER_CTX_ctrl(loopargs
[k
].ctx
,
2719 EVP_CTRL_SET_SPEED
, 1, NULL
);
2723 count
= run_benchmark(async_jobs
, loopfunc
, loopargs
);
2725 for (k
= 0; k
< loopargs_len
; k
++)
2726 EVP_CIPHER_CTX_free(loopargs
[k
].ctx
);
2727 print_result(D_EVP
, testnum
, count
, d
);
2729 } else if (evp_md_name
!= NULL
) {
2730 names
[D_EVP
] = evp_md_name
;
2732 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2733 print_message(names
[D_EVP
], lengths
[testnum
], seconds
.sym
);
2735 count
= run_benchmark(async_jobs
, EVP_Digest_md_loop
, loopargs
);
2737 print_result(D_EVP
, testnum
, count
, d
);
2744 if (doit
[D_EVP_CMAC
]) {
2745 OSSL_PARAM params
[3];
2746 EVP_CIPHER
*cipher
= NULL
;
2748 mac
= EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2749 if (mac
== NULL
|| evp_mac_ciphername
== NULL
)
2751 if (!opt_cipher(evp_mac_ciphername
, &cipher
))
2754 keylen
= EVP_CIPHER_get_key_length(cipher
);
2755 EVP_CIPHER_free(cipher
);
2756 if (keylen
<= 0 || keylen
> (int)sizeof(key32
)) {
2757 BIO_printf(bio_err
, "\nRequested CMAC cipher with unsupported key length.\n");
2760 evp_cmac_name
= app_malloc(sizeof("cmac()")
2761 + strlen(evp_mac_ciphername
), "CMAC name");
2762 sprintf(evp_cmac_name
, "cmac(%s)", evp_mac_ciphername
);
2763 names
[D_EVP_CMAC
] = evp_cmac_name
;
2765 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2766 evp_mac_ciphername
, 0);
2767 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2768 (char *)key32
, keylen
);
2769 params
[2] = OSSL_PARAM_construct_end();
2771 for (i
= 0; i
< loopargs_len
; i
++) {
2772 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2773 if (loopargs
[i
].mctx
== NULL
)
2776 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2780 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2781 print_message(names
[D_EVP_CMAC
], lengths
[testnum
], seconds
.sym
);
2783 count
= run_benchmark(async_jobs
, CMAC_loop
, loopargs
);
2785 print_result(D_EVP_CMAC
, testnum
, count
, d
);
2789 for (i
= 0; i
< loopargs_len
; i
++)
2790 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2795 for (i
= 0; i
< loopargs_len
; i
++)
2796 if (RAND_bytes(loopargs
[i
].buf
, 36) <= 0)
2799 for (testnum
= 0; testnum
< RSA_NUM
; testnum
++) {
2800 EVP_PKEY
*rsa_key
= NULL
;
2803 if (!rsa_doit
[testnum
])
2806 if (primes
> RSA_DEFAULT_PRIME_NUM
) {
2807 /* we haven't set keys yet, generate multi-prime RSA keys */
2810 && BN_set_word(bn
, RSA_F4
)
2811 && init_gen_str(&genctx
, "RSA", NULL
, 0, NULL
, NULL
)
2812 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx
, rsa_keys
[testnum
].bits
) > 0
2813 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx
, bn
) > 0
2814 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx
, primes
) > 0
2815 && EVP_PKEY_keygen(genctx
, &rsa_key
);
2818 EVP_PKEY_CTX_free(genctx
);
2821 const unsigned char *p
= rsa_keys
[testnum
].data
;
2823 st
= (rsa_key
= d2i_PrivateKey(EVP_PKEY_RSA
, NULL
, &p
,
2824 rsa_keys
[testnum
].length
)) != NULL
;
2827 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2828 loopargs
[i
].rsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2829 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2830 if (loopargs
[i
].rsa_sign_ctx
[testnum
] == NULL
2831 || EVP_PKEY_sign_init(loopargs
[i
].rsa_sign_ctx
[testnum
]) <= 0
2832 || EVP_PKEY_sign(loopargs
[i
].rsa_sign_ctx
[testnum
],
2834 &loopargs
[i
].sigsize
,
2835 loopargs
[i
].buf
, 36) <= 0)
2840 "RSA sign setup failure. No RSA sign will be done.\n");
2841 ERR_print_errors(bio_err
);
2844 pkey_print_message("private", "rsa",
2845 rsa_keys
[testnum
].bits
, seconds
.rsa
);
2846 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2848 count
= run_benchmark(async_jobs
, RSA_sign_loop
, loopargs
);
2851 mr
? "+R1:%ld:%d:%.2f\n"
2852 : "%ld %u bits private RSA's in %.2fs\n",
2853 count
, rsa_keys
[testnum
].bits
, d
);
2854 rsa_results
[testnum
][0] = (double)count
/ d
;
2858 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2859 loopargs
[i
].rsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
,
2861 if (loopargs
[i
].rsa_verify_ctx
[testnum
] == NULL
2862 || EVP_PKEY_verify_init(loopargs
[i
].rsa_verify_ctx
[testnum
]) <= 0
2863 || EVP_PKEY_verify(loopargs
[i
].rsa_verify_ctx
[testnum
],
2865 loopargs
[i
].sigsize
,
2866 loopargs
[i
].buf
, 36) <= 0)
2871 "RSA verify setup failure. No RSA verify will be done.\n");
2872 ERR_print_errors(bio_err
);
2873 rsa_doit
[testnum
] = 0;
2875 pkey_print_message("public", "rsa",
2876 rsa_keys
[testnum
].bits
, seconds
.rsa
);
2878 count
= run_benchmark(async_jobs
, RSA_verify_loop
, loopargs
);
2881 mr
? "+R2:%ld:%d:%.2f\n"
2882 : "%ld %u bits public RSA's in %.2fs\n",
2883 count
, rsa_keys
[testnum
].bits
, d
);
2884 rsa_results
[testnum
][1] = (double)count
/ d
;
2887 if (op_count
<= 1) {
2888 /* if longer than 10s, don't do any more */
2889 stop_it(rsa_doit
, testnum
);
2891 EVP_PKEY_free(rsa_key
);
2894 for (testnum
= 0; testnum
< DSA_NUM
; testnum
++) {
2895 EVP_PKEY
*dsa_key
= NULL
;
2898 if (!dsa_doit
[testnum
])
2901 st
= (dsa_key
= get_dsa(dsa_bits
[testnum
])) != NULL
;
2903 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2904 loopargs
[i
].dsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2906 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2907 if (loopargs
[i
].dsa_sign_ctx
[testnum
] == NULL
2908 || EVP_PKEY_sign_init(loopargs
[i
].dsa_sign_ctx
[testnum
]) <= 0
2910 || EVP_PKEY_sign(loopargs
[i
].dsa_sign_ctx
[testnum
],
2912 &loopargs
[i
].sigsize
,
2913 loopargs
[i
].buf
, 20) <= 0)
2918 "DSA sign setup failure. No DSA sign will be done.\n");
2919 ERR_print_errors(bio_err
);
2922 pkey_print_message("sign", "dsa",
2923 dsa_bits
[testnum
], seconds
.dsa
);
2925 count
= run_benchmark(async_jobs
, DSA_sign_loop
, loopargs
);
2928 mr
? "+R3:%ld:%u:%.2f\n"
2929 : "%ld %u bits DSA signs in %.2fs\n",
2930 count
, dsa_bits
[testnum
], d
);
2931 dsa_results
[testnum
][0] = (double)count
/ d
;
2935 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2936 loopargs
[i
].dsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2938 if (loopargs
[i
].dsa_verify_ctx
[testnum
] == NULL
2939 || EVP_PKEY_verify_init(loopargs
[i
].dsa_verify_ctx
[testnum
]) <= 0
2940 || EVP_PKEY_verify(loopargs
[i
].dsa_verify_ctx
[testnum
],
2942 loopargs
[i
].sigsize
,
2943 loopargs
[i
].buf
, 36) <= 0)
2948 "DSA verify setup failure. No DSA verify will be done.\n");
2949 ERR_print_errors(bio_err
);
2950 dsa_doit
[testnum
] = 0;
2952 pkey_print_message("verify", "dsa",
2953 dsa_bits
[testnum
], seconds
.dsa
);
2955 count
= run_benchmark(async_jobs
, DSA_verify_loop
, loopargs
);
2958 mr
? "+R4:%ld:%u:%.2f\n"
2959 : "%ld %u bits DSA verify in %.2fs\n",
2960 count
, dsa_bits
[testnum
], d
);
2961 dsa_results
[testnum
][1] = (double)count
/ d
;
2964 if (op_count
<= 1) {
2965 /* if longer than 10s, don't do any more */
2966 stop_it(dsa_doit
, testnum
);
2968 EVP_PKEY_free(dsa_key
);
2971 for (testnum
= 0; testnum
< ECDSA_NUM
; testnum
++) {
2972 EVP_PKEY
*ecdsa_key
= NULL
;
2975 if (!ecdsa_doit
[testnum
])
2978 st
= (ecdsa_key
= get_ecdsa(&ec_curves
[testnum
])) != NULL
;
2980 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2981 loopargs
[i
].ecdsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2983 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2984 if (loopargs
[i
].ecdsa_sign_ctx
[testnum
] == NULL
2985 || EVP_PKEY_sign_init(loopargs
[i
].ecdsa_sign_ctx
[testnum
]) <= 0
2987 || EVP_PKEY_sign(loopargs
[i
].ecdsa_sign_ctx
[testnum
],
2989 &loopargs
[i
].sigsize
,
2990 loopargs
[i
].buf
, 20) <= 0)
2995 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2996 ERR_print_errors(bio_err
);
2999 pkey_print_message("sign", "ecdsa",
3000 ec_curves
[testnum
].bits
, seconds
.ecdsa
);
3002 count
= run_benchmark(async_jobs
, ECDSA_sign_loop
, loopargs
);
3005 mr
? "+R5:%ld:%u:%.2f\n"
3006 : "%ld %u bits ECDSA signs in %.2fs\n",
3007 count
, ec_curves
[testnum
].bits
, d
);
3008 ecdsa_results
[testnum
][0] = (double)count
/ d
;
3012 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
3013 loopargs
[i
].ecdsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
3015 if (loopargs
[i
].ecdsa_verify_ctx
[testnum
] == NULL
3016 || EVP_PKEY_verify_init(loopargs
[i
].ecdsa_verify_ctx
[testnum
]) <= 0
3017 || EVP_PKEY_verify(loopargs
[i
].ecdsa_verify_ctx
[testnum
],
3019 loopargs
[i
].sigsize
,
3020 loopargs
[i
].buf
, 20) <= 0)
3025 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3026 ERR_print_errors(bio_err
);
3027 ecdsa_doit
[testnum
] = 0;
3029 pkey_print_message("verify", "ecdsa",
3030 ec_curves
[testnum
].bits
, seconds
.ecdsa
);
3032 count
= run_benchmark(async_jobs
, ECDSA_verify_loop
, loopargs
);
3035 mr
? "+R6:%ld:%u:%.2f\n"
3036 : "%ld %u bits ECDSA verify in %.2fs\n",
3037 count
, ec_curves
[testnum
].bits
, d
);
3038 ecdsa_results
[testnum
][1] = (double)count
/ d
;
3041 if (op_count
<= 1) {
3042 /* if longer than 10s, don't do any more */
3043 stop_it(ecdsa_doit
, testnum
);
3047 for (testnum
= 0; testnum
< EC_NUM
; testnum
++) {
3048 int ecdh_checks
= 1;
3050 if (!ecdh_doit
[testnum
])
3053 for (i
= 0; i
< loopargs_len
; i
++) {
3054 EVP_PKEY_CTX
*test_ctx
= NULL
;
3055 EVP_PKEY_CTX
*ctx
= NULL
;
3056 EVP_PKEY
*key_A
= NULL
;
3057 EVP_PKEY
*key_B
= NULL
;
3061 if ((key_A
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key A */
3062 || (key_B
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key B */
3063 || (ctx
= EVP_PKEY_CTX_new(key_A
, NULL
)) == NULL
/* derivation ctx from skeyA */
3064 || EVP_PKEY_derive_init(ctx
) <= 0 /* init derivation ctx */
3065 || EVP_PKEY_derive_set_peer(ctx
, key_B
) <= 0 /* set peer pubkey in ctx */
3066 || EVP_PKEY_derive(ctx
, NULL
, &outlen
) <= 0 /* determine max length */
3067 || outlen
== 0 /* ensure outlen is a valid size */
3068 || outlen
> MAX_ECDH_SIZE
/* avoid buffer overflow */) {
3070 BIO_printf(bio_err
, "ECDH key generation failure.\n");
3071 ERR_print_errors(bio_err
);
3077 * Here we perform a test run, comparing the output of a*B and b*A;
3078 * we try this here and assume that further EVP_PKEY_derive calls
3079 * never fail, so we can skip checks in the actually benchmarked
3080 * code, for maximum performance.
3082 if ((test_ctx
= EVP_PKEY_CTX_new(key_B
, NULL
)) == NULL
/* test ctx from skeyB */
3083 || EVP_PKEY_derive_init(test_ctx
) <= 0 /* init derivation test_ctx */
3084 || EVP_PKEY_derive_set_peer(test_ctx
, key_A
) <= 0 /* set peer pubkey in test_ctx */
3085 || EVP_PKEY_derive(test_ctx
, NULL
, &test_outlen
) <= 0 /* determine max length */
3086 || EVP_PKEY_derive(ctx
, loopargs
[i
].secret_a
, &outlen
) <= 0 /* compute a*B */
3087 || EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_b
, &test_outlen
) <= 0 /* compute b*A */
3088 || test_outlen
!= outlen
/* compare output length */) {
3090 BIO_printf(bio_err
, "ECDH computation failure.\n");
3091 ERR_print_errors(bio_err
);
3096 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3097 if (CRYPTO_memcmp(loopargs
[i
].secret_a
,
3098 loopargs
[i
].secret_b
, outlen
)) {
3100 BIO_printf(bio_err
, "ECDH computations don't match.\n");
3101 ERR_print_errors(bio_err
);
3106 loopargs
[i
].ecdh_ctx
[testnum
] = ctx
;
3107 loopargs
[i
].outlen
[testnum
] = outlen
;
3109 EVP_PKEY_free(key_A
);
3110 EVP_PKEY_free(key_B
);
3111 EVP_PKEY_CTX_free(test_ctx
);
3114 if (ecdh_checks
!= 0) {
3115 pkey_print_message("", "ecdh",
3116 ec_curves
[testnum
].bits
, seconds
.ecdh
);
3119 run_benchmark(async_jobs
, ECDH_EVP_derive_key_loop
, loopargs
);
3122 mr
? "+R7:%ld:%d:%.2f\n" :
3123 "%ld %u-bits ECDH ops in %.2fs\n", count
,
3124 ec_curves
[testnum
].bits
, d
);
3125 ecdh_results
[testnum
][0] = (double)count
/ d
;
3129 if (op_count
<= 1) {
3130 /* if longer than 10s, don't do any more */
3131 stop_it(ecdh_doit
, testnum
);
3135 #ifndef OPENSSL_NO_ECX
3136 for (testnum
= 0; testnum
< EdDSA_NUM
; testnum
++) {
3138 EVP_PKEY
*ed_pkey
= NULL
;
3139 EVP_PKEY_CTX
*ed_pctx
= NULL
;
3141 if (!eddsa_doit
[testnum
])
3142 continue; /* Ignore Curve */
3143 for (i
= 0; i
< loopargs_len
; i
++) {
3144 loopargs
[i
].eddsa_ctx
[testnum
] = EVP_MD_CTX_new();
3145 if (loopargs
[i
].eddsa_ctx
[testnum
] == NULL
) {
3149 loopargs
[i
].eddsa_ctx2
[testnum
] = EVP_MD_CTX_new();
3150 if (loopargs
[i
].eddsa_ctx2
[testnum
] == NULL
) {
3155 if ((ed_pctx
= EVP_PKEY_CTX_new_id(ed_curves
[testnum
].nid
,
3157 || EVP_PKEY_keygen_init(ed_pctx
) <= 0
3158 || EVP_PKEY_keygen(ed_pctx
, &ed_pkey
) <= 0) {
3160 EVP_PKEY_CTX_free(ed_pctx
);
3163 EVP_PKEY_CTX_free(ed_pctx
);
3165 if (!EVP_DigestSignInit(loopargs
[i
].eddsa_ctx
[testnum
], NULL
, NULL
,
3168 EVP_PKEY_free(ed_pkey
);
3171 if (!EVP_DigestVerifyInit(loopargs
[i
].eddsa_ctx2
[testnum
], NULL
,
3172 NULL
, NULL
, ed_pkey
)) {
3174 EVP_PKEY_free(ed_pkey
);
3178 EVP_PKEY_free(ed_pkey
);
3182 BIO_printf(bio_err
, "EdDSA failure.\n");
3183 ERR_print_errors(bio_err
);
3186 for (i
= 0; i
< loopargs_len
; i
++) {
3187 /* Perform EdDSA signature test */
3188 loopargs
[i
].sigsize
= ed_curves
[testnum
].sigsize
;
3189 st
= EVP_DigestSign(loopargs
[i
].eddsa_ctx
[testnum
],
3190 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
3191 loopargs
[i
].buf
, 20);
3197 "EdDSA sign failure. No EdDSA sign will be done.\n");
3198 ERR_print_errors(bio_err
);
3201 pkey_print_message("sign", ed_curves
[testnum
].name
,
3202 ed_curves
[testnum
].bits
, seconds
.eddsa
);
3204 count
= run_benchmark(async_jobs
, EdDSA_sign_loop
, loopargs
);
3208 mr
? "+R8:%ld:%u:%s:%.2f\n" :
3209 "%ld %u bits %s signs in %.2fs \n",
3210 count
, ed_curves
[testnum
].bits
,
3211 ed_curves
[testnum
].name
, d
);
3212 eddsa_results
[testnum
][0] = (double)count
/ d
;
3215 /* Perform EdDSA verification test */
3216 for (i
= 0; i
< loopargs_len
; i
++) {
3217 st
= EVP_DigestVerify(loopargs
[i
].eddsa_ctx2
[testnum
],
3218 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
3219 loopargs
[i
].buf
, 20);
3225 "EdDSA verify failure. No EdDSA verify will be done.\n");
3226 ERR_print_errors(bio_err
);
3227 eddsa_doit
[testnum
] = 0;
3229 pkey_print_message("verify", ed_curves
[testnum
].name
,
3230 ed_curves
[testnum
].bits
, seconds
.eddsa
);
3232 count
= run_benchmark(async_jobs
, EdDSA_verify_loop
, loopargs
);
3235 mr
? "+R9:%ld:%u:%s:%.2f\n"
3236 : "%ld %u bits %s verify in %.2fs\n",
3237 count
, ed_curves
[testnum
].bits
,
3238 ed_curves
[testnum
].name
, d
);
3239 eddsa_results
[testnum
][1] = (double)count
/ d
;
3242 if (op_count
<= 1) {
3243 /* if longer than 10s, don't do any more */
3244 stop_it(eddsa_doit
, testnum
);
3248 #endif /* OPENSSL_NO_ECX */
3250 #ifndef OPENSSL_NO_SM2
3251 for (testnum
= 0; testnum
< SM2_NUM
; testnum
++) {
3253 EVP_PKEY
*sm2_pkey
= NULL
;
3255 if (!sm2_doit
[testnum
])
3256 continue; /* Ignore Curve */
3257 /* Init signing and verification */
3258 for (i
= 0; i
< loopargs_len
; i
++) {
3259 EVP_PKEY_CTX
*sm2_pctx
= NULL
;
3260 EVP_PKEY_CTX
*sm2_vfy_pctx
= NULL
;
3261 EVP_PKEY_CTX
*pctx
= NULL
;
3264 loopargs
[i
].sm2_ctx
[testnum
] = EVP_MD_CTX_new();
3265 loopargs
[i
].sm2_vfy_ctx
[testnum
] = EVP_MD_CTX_new();
3266 if (loopargs
[i
].sm2_ctx
[testnum
] == NULL
3267 || loopargs
[i
].sm2_vfy_ctx
[testnum
] == NULL
)
3272 st
= !((pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_SM2
, NULL
)) == NULL
3273 || EVP_PKEY_keygen_init(pctx
) <= 0
3274 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
3275 sm2_curves
[testnum
].nid
) <= 0
3276 || EVP_PKEY_keygen(pctx
, &sm2_pkey
) <= 0);
3277 EVP_PKEY_CTX_free(pctx
);
3281 st
= 0; /* set back to zero */
3282 /* attach it sooner to rely on main final cleanup */
3283 loopargs
[i
].sm2_pkey
[testnum
] = sm2_pkey
;
3284 loopargs
[i
].sigsize
= EVP_PKEY_get_size(sm2_pkey
);
3286 sm2_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
3287 sm2_vfy_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
3288 if (sm2_pctx
== NULL
|| sm2_vfy_pctx
== NULL
) {
3289 EVP_PKEY_CTX_free(sm2_vfy_pctx
);
3293 /* attach them directly to respective ctx */
3294 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_ctx
[testnum
], sm2_pctx
);
3295 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[testnum
], sm2_vfy_pctx
);
3298 * No need to allow user to set an explicit ID here, just use
3299 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3301 if (EVP_PKEY_CTX_set1_id(sm2_pctx
, SM2_ID
, SM2_ID_LEN
) != 1
3302 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx
, SM2_ID
, SM2_ID_LEN
) != 1)
3305 if (!EVP_DigestSignInit(loopargs
[i
].sm2_ctx
[testnum
], NULL
,
3306 EVP_sm3(), NULL
, sm2_pkey
))
3308 if (!EVP_DigestVerifyInit(loopargs
[i
].sm2_vfy_ctx
[testnum
], NULL
,
3309 EVP_sm3(), NULL
, sm2_pkey
))
3311 st
= 1; /* mark loop as succeeded */
3314 BIO_printf(bio_err
, "SM2 init failure.\n");
3315 ERR_print_errors(bio_err
);
3318 for (i
= 0; i
< loopargs_len
; i
++) {
3319 /* Perform SM2 signature test */
3320 st
= EVP_DigestSign(loopargs
[i
].sm2_ctx
[testnum
],
3321 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
3322 loopargs
[i
].buf
, 20);
3328 "SM2 sign failure. No SM2 sign will be done.\n");
3329 ERR_print_errors(bio_err
);
3332 pkey_print_message("sign", sm2_curves
[testnum
].name
,
3333 sm2_curves
[testnum
].bits
, seconds
.sm2
);
3335 count
= run_benchmark(async_jobs
, SM2_sign_loop
, loopargs
);
3339 mr
? "+R10:%ld:%u:%s:%.2f\n" :
3340 "%ld %u bits %s signs in %.2fs \n",
3341 count
, sm2_curves
[testnum
].bits
,
3342 sm2_curves
[testnum
].name
, d
);
3343 sm2_results
[testnum
][0] = (double)count
/ d
;
3347 /* Perform SM2 verification test */
3348 for (i
= 0; i
< loopargs_len
; i
++) {
3349 st
= EVP_DigestVerify(loopargs
[i
].sm2_vfy_ctx
[testnum
],
3350 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
3351 loopargs
[i
].buf
, 20);
3357 "SM2 verify failure. No SM2 verify will be done.\n");
3358 ERR_print_errors(bio_err
);
3359 sm2_doit
[testnum
] = 0;
3361 pkey_print_message("verify", sm2_curves
[testnum
].name
,
3362 sm2_curves
[testnum
].bits
, seconds
.sm2
);
3364 count
= run_benchmark(async_jobs
, SM2_verify_loop
, loopargs
);
3367 mr
? "+R11:%ld:%u:%s:%.2f\n"
3368 : "%ld %u bits %s verify in %.2fs\n",
3369 count
, sm2_curves
[testnum
].bits
,
3370 sm2_curves
[testnum
].name
, d
);
3371 sm2_results
[testnum
][1] = (double)count
/ d
;
3374 if (op_count
<= 1) {
3375 /* if longer than 10s, don't do any more */
3376 for (testnum
++; testnum
< SM2_NUM
; testnum
++)
3377 sm2_doit
[testnum
] = 0;
3381 #endif /* OPENSSL_NO_SM2 */
3383 #ifndef OPENSSL_NO_DH
3384 for (testnum
= 0; testnum
< FFDH_NUM
; testnum
++) {
3385 int ffdh_checks
= 1;
3387 if (!ffdh_doit
[testnum
])
3390 for (i
= 0; i
< loopargs_len
; i
++) {
3391 EVP_PKEY
*pkey_A
= NULL
;
3392 EVP_PKEY
*pkey_B
= NULL
;
3393 EVP_PKEY_CTX
*ffdh_ctx
= NULL
;
3394 EVP_PKEY_CTX
*test_ctx
= NULL
;
3398 /* Ensure that the error queue is empty */
3399 if (ERR_peek_error()) {
3401 "WARNING: the error queue contains previous unhandled errors.\n");
3402 ERR_print_errors(bio_err
);
3405 pkey_A
= EVP_PKEY_new();
3407 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
3408 ERR_print_errors(bio_err
);
3413 pkey_B
= EVP_PKEY_new();
3415 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
3416 ERR_print_errors(bio_err
);
3422 ffdh_ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_DH
, NULL
);
3424 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3425 ERR_print_errors(bio_err
);
3431 if (EVP_PKEY_keygen_init(ffdh_ctx
) <= 0) {
3432 BIO_printf(bio_err
, "Error while initialising EVP_PKEY_CTX.\n");
3433 ERR_print_errors(bio_err
);
3438 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx
, ffdh_params
[testnum
].nid
) <= 0) {
3439 BIO_printf(bio_err
, "Error setting DH key size for keygen.\n");
3440 ERR_print_errors(bio_err
);
3446 if (EVP_PKEY_keygen(ffdh_ctx
, &pkey_A
) <= 0 ||
3447 EVP_PKEY_keygen(ffdh_ctx
, &pkey_B
) <= 0) {
3448 BIO_printf(bio_err
, "FFDH key generation failure.\n");
3449 ERR_print_errors(bio_err
);
3455 EVP_PKEY_CTX_free(ffdh_ctx
);
3458 * check if the derivation works correctly both ways so that
3459 * we know if future derive calls will fail, and we can skip
3460 * error checking in benchmarked code
3462 ffdh_ctx
= EVP_PKEY_CTX_new(pkey_A
, NULL
);
3463 if (ffdh_ctx
== NULL
) {
3464 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3465 ERR_print_errors(bio_err
);
3470 if (EVP_PKEY_derive_init(ffdh_ctx
) <= 0) {
3471 BIO_printf(bio_err
, "FFDH derivation context init failure.\n");
3472 ERR_print_errors(bio_err
);
3477 if (EVP_PKEY_derive_set_peer(ffdh_ctx
, pkey_B
) <= 0) {
3478 BIO_printf(bio_err
, "Assigning peer key for derivation failed.\n");
3479 ERR_print_errors(bio_err
);
3484 if (EVP_PKEY_derive(ffdh_ctx
, NULL
, &secret_size
) <= 0) {
3485 BIO_printf(bio_err
, "Checking size of shared secret failed.\n");
3486 ERR_print_errors(bio_err
);
3491 if (secret_size
> MAX_FFDH_SIZE
) {
3492 BIO_printf(bio_err
, "Assertion failure: shared secret too large.\n");
3497 if (EVP_PKEY_derive(ffdh_ctx
,
3498 loopargs
[i
].secret_ff_a
,
3499 &secret_size
) <= 0) {
3500 BIO_printf(bio_err
, "Shared secret derive failure.\n");
3501 ERR_print_errors(bio_err
);
3506 /* Now check from side B */
3507 test_ctx
= EVP_PKEY_CTX_new(pkey_B
, NULL
);
3509 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3510 ERR_print_errors(bio_err
);
3515 if (EVP_PKEY_derive_init(test_ctx
) <= 0 ||
3516 EVP_PKEY_derive_set_peer(test_ctx
, pkey_A
) <= 0 ||
3517 EVP_PKEY_derive(test_ctx
, NULL
, &test_out
) <= 0 ||
3518 EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_ff_b
, &test_out
) <= 0 ||
3519 test_out
!= secret_size
) {
3520 BIO_printf(bio_err
, "FFDH computation failure.\n");
3526 /* compare the computed secrets */
3527 if (CRYPTO_memcmp(loopargs
[i
].secret_ff_a
,
3528 loopargs
[i
].secret_ff_b
, secret_size
)) {
3529 BIO_printf(bio_err
, "FFDH computations don't match.\n");
3530 ERR_print_errors(bio_err
);
3536 loopargs
[i
].ffdh_ctx
[testnum
] = ffdh_ctx
;
3538 EVP_PKEY_free(pkey_A
);
3540 EVP_PKEY_free(pkey_B
);
3542 EVP_PKEY_CTX_free(test_ctx
);
3545 if (ffdh_checks
!= 0) {
3546 pkey_print_message("", "ffdh",
3547 ffdh_params
[testnum
].bits
, seconds
.ffdh
);
3550 run_benchmark(async_jobs
, FFDH_derive_key_loop
, loopargs
);
3553 mr
? "+R12:%ld:%d:%.2f\n" :
3554 "%ld %u-bits FFDH ops in %.2fs\n", count
,
3555 ffdh_params
[testnum
].bits
, d
);
3556 ffdh_results
[testnum
][0] = (double)count
/ d
;
3559 if (op_count
<= 1) {
3560 /* if longer than 10s, don't do any more */
3561 stop_it(ffdh_doit
, testnum
);
3564 #endif /* OPENSSL_NO_DH */
3566 for (testnum
= 0; testnum
< kems_algs_len
; testnum
++) {
3568 const char *kem_name
= kems_algname
[testnum
];
3570 if (!kems_doit
[testnum
] || !do_kems
)
3573 for (i
= 0; i
< loopargs_len
; i
++) {
3574 EVP_PKEY
*pkey
= NULL
;
3575 EVP_PKEY_CTX
*kem_gen_ctx
= NULL
;
3576 EVP_PKEY_CTX
*kem_encaps_ctx
= NULL
;
3577 EVP_PKEY_CTX
*kem_decaps_ctx
= NULL
;
3578 size_t send_secret_len
, out_len
;
3579 size_t rcv_secret_len
;
3580 unsigned char *out
= NULL
, *send_secret
= NULL
, *rcv_secret
;
3583 char sfx
[MAX_ALGNAME_SUFFIX
];
3584 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
3586 enum kem_type_t
{ KEM_RSA
= 1, KEM_EC
, KEM_X25519
, KEM_X448
} kem_type
;
3588 /* no string after rsa<bitcnt> permitted: */
3589 if (strlen(kem_name
) < MAX_ALGNAME_SUFFIX
+ 4 /* rsa+digit */
3590 && sscanf(kem_name
, "rsa%u%s", &bits
, sfx
) == 1)
3592 else if (strncmp(kem_name
, "EC", 2) == 0)
3594 else if (strcmp(kem_name
, "X25519") == 0)
3595 kem_type
= KEM_X25519
;
3596 else if (strcmp(kem_name
, "X448") == 0)
3597 kem_type
= KEM_X448
;
3600 if (ERR_peek_error()) {
3602 "WARNING: the error queue contains previous unhandled errors.\n");
3603 ERR_print_errors(bio_err
);
3606 if (kem_type
== KEM_RSA
) {
3607 params
[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS
,
3610 } else if (kem_type
== KEM_EC
) {
3611 name
= (char *)(kem_name
+ 2);
3612 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
,
3617 kem_gen_ctx
= EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3618 (kem_type
== KEM_RSA
) ? "RSA":
3619 (kem_type
== KEM_EC
) ? "EC":
3623 if ((!kem_gen_ctx
|| EVP_PKEY_keygen_init(kem_gen_ctx
) <= 0)
3625 && EVP_PKEY_CTX_set_params(kem_gen_ctx
, params
) <= 0)) {
3626 BIO_printf(bio_err
, "Error initializing keygen ctx for %s.\n",
3630 if (EVP_PKEY_keygen(kem_gen_ctx
, &pkey
) <= 0) {
3631 BIO_printf(bio_err
, "Error while generating KEM EVP_PKEY.\n");
3634 /* Now prepare encaps data structs */
3635 kem_encaps_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3638 if (kem_encaps_ctx
== NULL
3639 || EVP_PKEY_encapsulate_init(kem_encaps_ctx
, NULL
) <= 0
3640 || (kem_type
== KEM_RSA
3641 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx
, "RSASVE") <= 0)
3642 || ((kem_type
== KEM_EC
3643 || kem_type
== KEM_X25519
3644 || kem_type
== KEM_X448
)
3645 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx
, "DHKEM") <= 0)
3646 || EVP_PKEY_encapsulate(kem_encaps_ctx
, NULL
, &out_len
,
3647 NULL
, &send_secret_len
) <= 0) {
3649 "Error while initializing encaps data structs for %s.\n",
3653 out
= app_malloc(out_len
, "encaps result");
3654 send_secret
= app_malloc(send_secret_len
, "encaps secret");
3655 if (out
== NULL
|| send_secret
== NULL
) {
3656 BIO_printf(bio_err
, "MemAlloc error in encaps for %s.\n", kem_name
);
3659 if (EVP_PKEY_encapsulate(kem_encaps_ctx
, out
, &out_len
,
3660 send_secret
, &send_secret_len
) <= 0) {
3661 BIO_printf(bio_err
, "Encaps error for %s.\n", kem_name
);
3664 /* Now prepare decaps data structs */
3665 kem_decaps_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3668 if (kem_decaps_ctx
== NULL
3669 || EVP_PKEY_decapsulate_init(kem_decaps_ctx
, NULL
) <= 0
3670 || (kem_type
== KEM_RSA
3671 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx
, "RSASVE") <= 0)
3672 || ((kem_type
== KEM_EC
3673 || kem_type
== KEM_X25519
3674 || kem_type
== KEM_X448
)
3675 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx
, "DHKEM") <= 0)
3676 || EVP_PKEY_decapsulate(kem_decaps_ctx
, NULL
, &rcv_secret_len
,
3677 out
, out_len
) <= 0) {
3679 "Error while initializing decaps data structs for %s.\n",
3683 rcv_secret
= app_malloc(rcv_secret_len
, "KEM decaps secret");
3684 if (rcv_secret
== NULL
) {
3685 BIO_printf(bio_err
, "MemAlloc failure in decaps for %s.\n",
3689 if (EVP_PKEY_decapsulate(kem_decaps_ctx
, rcv_secret
,
3690 &rcv_secret_len
, out
, out_len
) <= 0
3691 || rcv_secret_len
!= send_secret_len
3692 || memcmp(send_secret
, rcv_secret
, send_secret_len
)) {
3693 BIO_printf(bio_err
, "Decaps error for %s.\n", kem_name
);
3696 loopargs
[i
].kem_gen_ctx
[testnum
] = kem_gen_ctx
;
3697 loopargs
[i
].kem_encaps_ctx
[testnum
] = kem_encaps_ctx
;
3698 loopargs
[i
].kem_decaps_ctx
[testnum
] = kem_decaps_ctx
;
3699 loopargs
[i
].kem_out_len
[testnum
] = out_len
;
3700 loopargs
[i
].kem_secret_len
[testnum
] = send_secret_len
;
3701 loopargs
[i
].kem_out
[testnum
] = out
;
3702 loopargs
[i
].kem_send_secret
[testnum
] = send_secret
;
3703 loopargs
[i
].kem_rcv_secret
[testnum
] = rcv_secret
;
3707 ERR_print_errors(bio_err
);
3712 if (kem_checks
!= 0) {
3713 kskey_print_message(kem_name
, "keygen", seconds
.kem
);
3716 run_benchmark(async_jobs
, KEM_keygen_loop
, loopargs
);
3719 mr
? "+R13:%ld:%s:%.2f\n" :
3720 "%ld %s KEM keygens in %.2fs\n", count
,
3722 kems_results
[testnum
][0] = (double)count
/ d
;
3724 kskey_print_message(kem_name
, "encaps", seconds
.kem
);
3727 run_benchmark(async_jobs
, KEM_encaps_loop
, loopargs
);
3730 mr
? "+R14:%ld:%s:%.2f\n" :
3731 "%ld %s KEM encaps in %.2fs\n", count
,
3733 kems_results
[testnum
][1] = (double)count
/ d
;
3735 kskey_print_message(kem_name
, "decaps", seconds
.kem
);
3738 run_benchmark(async_jobs
, KEM_decaps_loop
, loopargs
);
3741 mr
? "+R15:%ld:%s:%.2f\n" :
3742 "%ld %s KEM decaps in %.2fs\n", count
,
3744 kems_results
[testnum
][2] = (double)count
/ d
;
3747 if (op_count
<= 1) {
3748 /* if longer than 10s, don't do any more */
3749 stop_it(kems_doit
, testnum
);
3753 for (testnum
= 0; testnum
< sigs_algs_len
; testnum
++) {
3755 const char *sig_name
= sigs_algname
[testnum
];
3757 if (!sigs_doit
[testnum
] || !do_sigs
)
3760 for (i
= 0; i
< loopargs_len
; i
++) {
3761 EVP_PKEY
*pkey
= NULL
;
3762 EVP_PKEY_CTX
*ctx_params
= NULL
;
3763 EVP_PKEY
* pkey_params
= NULL
;
3764 EVP_PKEY_CTX
*sig_gen_ctx
= NULL
;
3765 EVP_PKEY_CTX
*sig_sign_ctx
= NULL
;
3766 EVP_PKEY_CTX
*sig_verify_ctx
= NULL
;
3767 unsigned char md
[SHA256_DIGEST_LENGTH
];
3769 char sfx
[MAX_ALGNAME_SUFFIX
];
3770 size_t md_len
= SHA256_DIGEST_LENGTH
;
3771 size_t max_sig_len
, sig_len
;
3773 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
3776 /* only sign little data to avoid measuring digest performance */
3777 memset(md
, 0, SHA256_DIGEST_LENGTH
);
3779 if (ERR_peek_error()) {
3781 "WARNING: the error queue contains previous unhandled errors.\n");
3782 ERR_print_errors(bio_err
);
3785 /* no string after rsa<bitcnt> permitted: */
3786 if (strlen(sig_name
) < MAX_ALGNAME_SUFFIX
+ 4 /* rsa+digit */
3787 && sscanf(sig_name
, "rsa%u%s", &bits
, sfx
) == 1) {
3788 params
[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS
,
3793 if (strncmp(sig_name
, "dsa", 3) == 0) {
3794 ctx_params
= EVP_PKEY_CTX_new_id(EVP_PKEY_DSA
, NULL
);
3795 if (ctx_params
== NULL
3796 || EVP_PKEY_paramgen_init(ctx_params
) <= 0
3797 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params
,
3798 atoi(sig_name
+ 3)) <= 0
3799 || EVP_PKEY_paramgen(ctx_params
, &pkey_params
) <= 0
3800 || (sig_gen_ctx
= EVP_PKEY_CTX_new(pkey_params
, NULL
)) == NULL
3801 || EVP_PKEY_keygen_init(sig_gen_ctx
) <= 0) {
3803 "Error initializing classic keygen ctx for %s.\n",
3809 if (sig_gen_ctx
== NULL
)
3810 sig_gen_ctx
= EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3811 use_params
== 1 ? "RSA" : sig_name
,
3814 if (!sig_gen_ctx
|| EVP_PKEY_keygen_init(sig_gen_ctx
) <= 0
3816 EVP_PKEY_CTX_set_params(sig_gen_ctx
, params
) <= 0)) {
3817 BIO_printf(bio_err
, "Error initializing keygen ctx for %s.\n",
3821 if (EVP_PKEY_keygen(sig_gen_ctx
, &pkey
) <= 0) {
3823 "Error while generating signature EVP_PKEY for %s.\n",
3827 /* Now prepare signature data structs */
3828 sig_sign_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3831 if (sig_sign_ctx
== NULL
3832 || EVP_PKEY_sign_init(sig_sign_ctx
) <= 0
3834 && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx
,
3835 RSA_PKCS1_PADDING
) <= 0))
3836 || EVP_PKEY_sign(sig_sign_ctx
, NULL
, &max_sig_len
,
3839 "Error while initializing signing data structs for %s.\n",
3843 sig
= app_malloc(sig_len
= max_sig_len
, "signature buffer");
3845 BIO_printf(bio_err
, "MemAlloc error in sign for %s.\n", sig_name
);
3848 if (EVP_PKEY_sign(sig_sign_ctx
, sig
, &sig_len
, md
, md_len
) <= 0) {
3849 BIO_printf(bio_err
, "Signing error for %s.\n", sig_name
);
3852 /* Now prepare verify data structs */
3853 memset(md
, 0, SHA256_DIGEST_LENGTH
);
3854 sig_verify_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3857 if (sig_verify_ctx
== NULL
3858 || EVP_PKEY_verify_init(sig_verify_ctx
) <= 0
3860 && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx
,
3861 RSA_PKCS1_PADDING
) <= 0))) {
3863 "Error while initializing verify data structs for %s.\n",
3867 if (EVP_PKEY_verify(sig_verify_ctx
, sig
, sig_len
, md
, md_len
) <= 0) {
3868 BIO_printf(bio_err
, "Verify error for %s.\n", sig_name
);
3871 if (EVP_PKEY_verify(sig_verify_ctx
, sig
, sig_len
, md
, md_len
) <= 0) {
3872 BIO_printf(bio_err
, "Verify 2 error for %s.\n", sig_name
);
3875 loopargs
[i
].sig_gen_ctx
[testnum
] = sig_gen_ctx
;
3876 loopargs
[i
].sig_sign_ctx
[testnum
] = sig_sign_ctx
;
3877 loopargs
[i
].sig_verify_ctx
[testnum
] = sig_verify_ctx
;
3878 loopargs
[i
].sig_max_sig_len
[testnum
] = max_sig_len
;
3879 loopargs
[i
].sig_act_sig_len
[testnum
] = sig_len
;
3880 loopargs
[i
].sig_sig
[testnum
] = sig
;
3884 ERR_print_errors(bio_err
);
3890 if (sig_checks
!= 0) {
3891 kskey_print_message(sig_name
, "keygen", seconds
.sig
);
3893 count
= run_benchmark(async_jobs
, SIG_keygen_loop
, loopargs
);
3896 mr
? "+R16:%ld:%s:%.2f\n" :
3897 "%ld %s signature keygens in %.2fs\n", count
,
3899 sigs_results
[testnum
][0] = (double)count
/ d
;
3901 kskey_print_message(sig_name
, "signs", seconds
.sig
);
3904 run_benchmark(async_jobs
, SIG_sign_loop
, loopargs
);
3907 mr
? "+R17:%ld:%s:%.2f\n" :
3908 "%ld %s signature signs in %.2fs\n", count
,
3910 sigs_results
[testnum
][1] = (double)count
/ d
;
3913 kskey_print_message(sig_name
, "verify", seconds
.sig
);
3916 run_benchmark(async_jobs
, SIG_verify_loop
, loopargs
);
3919 mr
? "+R18:%ld:%s:%.2f\n" :
3920 "%ld %s signature verifys in %.2fs\n", count
,
3922 sigs_results
[testnum
][2] = (double)count
/ d
;
3926 stop_it(sigs_doit
, testnum
);
3933 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING
));
3934 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON
));
3935 printf("options: %s\n", BN_options());
3936 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS
));
3937 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO
));
3944 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3947 for (testnum
= 0; testnum
< size_num
; testnum
++)
3948 printf(mr
? ":%d" : "%7d bytes", lengths
[testnum
]);
3952 for (k
= 0; k
< ALGOR_NUM
; k
++) {
3953 const char *alg_name
= names
[k
];
3959 if (evp_cipher
== NULL
)
3960 alg_name
= evp_md_name
;
3961 else if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
3962 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher
);
3966 printf("+F:%u:%s", k
, alg_name
);
3968 printf("%-13s", alg_name
);
3969 for (testnum
= 0; testnum
< size_num
; testnum
++) {
3970 if (results
[k
][testnum
] > 10000 && !mr
)
3971 printf(" %11.2fk", results
[k
][testnum
] / 1e3
);
3973 printf(mr
? ":%.2f" : " %11.2f ", results
[k
][testnum
]);
3978 for (k
= 0; k
< RSA_NUM
; k
++) {
3981 if (testnum
&& !mr
) {
3982 printf("%18ssign verify sign/s verify/s\n", " ");
3986 printf("+F2:%u:%u:%f:%f\n",
3987 k
, rsa_keys
[k
].bits
, rsa_results
[k
][0], rsa_results
[k
][1]);
3989 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3990 rsa_keys
[k
].bits
, 1.0 / rsa_results
[k
][0],
3991 1.0 / rsa_results
[k
][1],
3992 rsa_results
[k
][0], rsa_results
[k
][1]);
3995 for (k
= 0; k
< DSA_NUM
; k
++) {
3998 if (testnum
&& !mr
) {
3999 printf("%18ssign verify sign/s verify/s\n", " ");
4003 printf("+F3:%u:%u:%f:%f\n",
4004 k
, dsa_bits
[k
], dsa_results
[k
][0], dsa_results
[k
][1]);
4006 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4007 dsa_bits
[k
], 1.0 / dsa_results
[k
][0], 1.0 / dsa_results
[k
][1],
4008 dsa_results
[k
][0], dsa_results
[k
][1]);
4011 for (k
= 0; k
< OSSL_NELEM(ecdsa_doit
); k
++) {
4014 if (testnum
&& !mr
) {
4015 printf("%30ssign verify sign/s verify/s\n", " ");
4020 printf("+F4:%u:%u:%f:%f\n",
4021 k
, ec_curves
[k
].bits
,
4022 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
4024 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4025 ec_curves
[k
].bits
, ec_curves
[k
].name
,
4026 1.0 / ecdsa_results
[k
][0], 1.0 / ecdsa_results
[k
][1],
4027 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
4031 for (k
= 0; k
< EC_NUM
; k
++) {
4034 if (testnum
&& !mr
) {
4035 printf("%30sop op/s\n", " ");
4039 printf("+F5:%u:%u:%f:%f\n",
4040 k
, ec_curves
[k
].bits
,
4041 ecdh_results
[k
][0], 1.0 / ecdh_results
[k
][0]);
4044 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4045 ec_curves
[k
].bits
, ec_curves
[k
].name
,
4046 1.0 / ecdh_results
[k
][0], ecdh_results
[k
][0]);
4049 #ifndef OPENSSL_NO_ECX
4051 for (k
= 0; k
< OSSL_NELEM(eddsa_doit
); k
++) {
4054 if (testnum
&& !mr
) {
4055 printf("%30ssign verify sign/s verify/s\n", " ");
4060 printf("+F6:%u:%u:%s:%f:%f\n",
4061 k
, ed_curves
[k
].bits
, ed_curves
[k
].name
,
4062 eddsa_results
[k
][0], eddsa_results
[k
][1]);
4064 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4065 ed_curves
[k
].bits
, ed_curves
[k
].name
,
4066 1.0 / eddsa_results
[k
][0], 1.0 / eddsa_results
[k
][1],
4067 eddsa_results
[k
][0], eddsa_results
[k
][1]);
4069 #endif /* OPENSSL_NO_ECX */
4071 #ifndef OPENSSL_NO_SM2
4073 for (k
= 0; k
< OSSL_NELEM(sm2_doit
); k
++) {
4076 if (testnum
&& !mr
) {
4077 printf("%30ssign verify sign/s verify/s\n", " ");
4082 printf("+F7:%u:%u:%s:%f:%f\n",
4083 k
, sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
4084 sm2_results
[k
][0], sm2_results
[k
][1]);
4086 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4087 sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
4088 1.0 / sm2_results
[k
][0], 1.0 / sm2_results
[k
][1],
4089 sm2_results
[k
][0], sm2_results
[k
][1]);
4092 #ifndef OPENSSL_NO_DH
4094 for (k
= 0; k
< FFDH_NUM
; k
++) {
4097 if (testnum
&& !mr
) {
4098 printf("%23sop op/s\n", " ");
4102 printf("+F8:%u:%u:%f:%f\n",
4103 k
, ffdh_params
[k
].bits
,
4104 ffdh_results
[k
][0], 1.0 / ffdh_results
[k
][0]);
4107 printf("%4u bits ffdh %8.4fs %8.1f\n",
4108 ffdh_params
[k
].bits
,
4109 1.0 / ffdh_results
[k
][0], ffdh_results
[k
][0]);
4111 #endif /* OPENSSL_NO_DH */
4114 for (k
= 0; k
< kems_algs_len
; k
++) {
4115 const char *kem_name
= kems_algname
[k
];
4117 if (!kems_doit
[k
] || !do_kems
)
4119 if (testnum
&& !mr
) {
4120 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4124 printf("+F9:%u:%f:%f:%f\n",
4125 k
, kems_results
[k
][0], kems_results
[k
][1],
4126 kems_results
[k
][2]);
4128 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name
,
4129 1.0 / kems_results
[k
][0],
4130 1.0 / kems_results
[k
][1], 1.0 / kems_results
[k
][2],
4131 kems_results
[k
][0], kems_results
[k
][1], kems_results
[k
][2]);
4136 for (k
= 0; k
< sigs_algs_len
; k
++) {
4137 const char *sig_name
= sigs_algname
[k
];
4139 if (!sigs_doit
[k
] || !do_sigs
)
4141 if (testnum
&& !mr
) {
4142 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4146 printf("+F10:%u:%f:%f:%f\n",
4147 k
, sigs_results
[k
][0], sigs_results
[k
][1],
4148 sigs_results
[k
][2]);
4150 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name
,
4151 1.0 / sigs_results
[k
][0], 1.0 / sigs_results
[k
][1],
4152 1.0 / sigs_results
[k
][2], sigs_results
[k
][0],
4153 sigs_results
[k
][1], sigs_results
[k
][2]);
4158 ERR_print_errors(bio_err
);
4159 for (i
= 0; i
< loopargs_len
; i
++) {
4160 OPENSSL_free(loopargs
[i
].buf_malloc
);
4161 OPENSSL_free(loopargs
[i
].buf2_malloc
);
4164 EVP_PKEY_CTX_free(genctx
);
4165 for (k
= 0; k
< RSA_NUM
; k
++) {
4166 EVP_PKEY_CTX_free(loopargs
[i
].rsa_sign_ctx
[k
]);
4167 EVP_PKEY_CTX_free(loopargs
[i
].rsa_verify_ctx
[k
]);
4169 #ifndef OPENSSL_NO_DH
4170 OPENSSL_free(loopargs
[i
].secret_ff_a
);
4171 OPENSSL_free(loopargs
[i
].secret_ff_b
);
4172 for (k
= 0; k
< FFDH_NUM
; k
++)
4173 EVP_PKEY_CTX_free(loopargs
[i
].ffdh_ctx
[k
]);
4175 for (k
= 0; k
< DSA_NUM
; k
++) {
4176 EVP_PKEY_CTX_free(loopargs
[i
].dsa_sign_ctx
[k
]);
4177 EVP_PKEY_CTX_free(loopargs
[i
].dsa_verify_ctx
[k
]);
4179 for (k
= 0; k
< ECDSA_NUM
; k
++) {
4180 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_sign_ctx
[k
]);
4181 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_verify_ctx
[k
]);
4183 for (k
= 0; k
< EC_NUM
; k
++)
4184 EVP_PKEY_CTX_free(loopargs
[i
].ecdh_ctx
[k
]);
4185 #ifndef OPENSSL_NO_ECX
4186 for (k
= 0; k
< EdDSA_NUM
; k
++) {
4187 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx
[k
]);
4188 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx2
[k
]);
4190 #endif /* OPENSSL_NO_ECX */
4191 #ifndef OPENSSL_NO_SM2
4192 for (k
= 0; k
< SM2_NUM
; k
++) {
4193 EVP_PKEY_CTX
*pctx
= NULL
;
4195 /* free signing ctx */
4196 if (loopargs
[i
].sm2_ctx
[k
] != NULL
4197 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_ctx
[k
])) != NULL
)
4198 EVP_PKEY_CTX_free(pctx
);
4199 EVP_MD_CTX_free(loopargs
[i
].sm2_ctx
[k
]);
4200 /* free verification ctx */
4201 if (loopargs
[i
].sm2_vfy_ctx
[k
] != NULL
4202 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[k
])) != NULL
)
4203 EVP_PKEY_CTX_free(pctx
);
4204 EVP_MD_CTX_free(loopargs
[i
].sm2_vfy_ctx
[k
]);
4206 EVP_PKEY_free(loopargs
[i
].sm2_pkey
[k
]);
4209 for (k
= 0; k
< kems_algs_len
; k
++) {
4210 EVP_PKEY_CTX_free(loopargs
[i
].kem_gen_ctx
[k
]);
4211 EVP_PKEY_CTX_free(loopargs
[i
].kem_encaps_ctx
[k
]);
4212 EVP_PKEY_CTX_free(loopargs
[i
].kem_decaps_ctx
[k
]);
4213 OPENSSL_free(loopargs
[i
].kem_out
[k
]);
4214 OPENSSL_free(loopargs
[i
].kem_send_secret
[k
]);
4215 OPENSSL_free(loopargs
[i
].kem_rcv_secret
[k
]);
4217 for (k
= 0; k
< sigs_algs_len
; k
++) {
4218 EVP_PKEY_CTX_free(loopargs
[i
].sig_gen_ctx
[k
]);
4219 EVP_PKEY_CTX_free(loopargs
[i
].sig_sign_ctx
[k
]);
4220 EVP_PKEY_CTX_free(loopargs
[i
].sig_verify_ctx
[k
]);
4221 OPENSSL_free(loopargs
[i
].sig_sig
[k
]);
4223 OPENSSL_free(loopargs
[i
].secret_a
);
4224 OPENSSL_free(loopargs
[i
].secret_b
);
4226 OPENSSL_free(evp_hmac_name
);
4227 OPENSSL_free(evp_cmac_name
);
4228 for (k
= 0; k
< kems_algs_len
; k
++)
4229 OPENSSL_free(kems_algname
[k
]);
4230 for (k
= 0; k
< sigs_algs_len
; k
++)
4231 OPENSSL_free(sigs_algname
[k
]);
4233 if (async_jobs
> 0) {
4234 for (i
= 0; i
< loopargs_len
; i
++)
4235 ASYNC_WAIT_CTX_free(loopargs
[i
].wait_ctx
);
4239 ASYNC_cleanup_thread();
4241 OPENSSL_free(loopargs
);
4243 EVP_CIPHER_free(evp_cipher
);
4249 static void print_message(const char *s
, int length
, int tm
)
4252 mr
? "+DT:%s:%d:%d\n"
4253 : "Doing %s for %ds on %d size blocks: ", s
, tm
, length
);
4254 (void)BIO_flush(bio_err
);
4259 static void pkey_print_message(const char *str
, const char *str2
, unsigned int bits
,
4263 mr
? "+DTP:%d:%s:%s:%d\n"
4264 : "Doing %u bits %s %s's for %ds: ", bits
, str
, str2
, tm
);
4265 (void)BIO_flush(bio_err
);
4270 static void kskey_print_message(const char *str
, const char *str2
, int tm
)
4273 mr
? "+DTP:%s:%s:%d\n"
4274 : "Doing %s %s's for %ds: ", str
, str2
, tm
);
4275 (void)BIO_flush(bio_err
);
4280 static void print_result(int alg
, int run_no
, int count
, double time_used
)
4283 BIO_printf(bio_err
, "%s error!\n", names
[alg
]);
4284 ERR_print_errors(bio_err
);
4288 mr
? "+R:%d:%s:%f\n"
4289 : "%d %s's in %.2fs\n", count
, names
[alg
], time_used
);
4290 results
[alg
][run_no
] = ((double)count
) / time_used
* lengths
[run_no
];
4294 static char *sstrsep(char **string
, const char *delim
)
4297 char *token
= *string
;
4299 memset(isdelim
, 0, sizeof(isdelim
));
4303 isdelim
[(unsigned char)(*delim
)] = 1;
4307 while (!isdelim
[(unsigned char)(**string
)])
4318 static int strtoint(const char *str
, const int min_val
, const int upper_val
,
4325 val
= strtol(str
, &end
, 10);
4326 if (errno
== 0 && end
!= str
&& *end
== 0
4327 && min_val
<= val
&& val
< upper_val
) {
4335 static int do_multi(int multi
, int size_num
)
4341 static char sep
[] = ":";
4343 fds
= app_malloc(sizeof(*fds
) * multi
, "fd buffer for do_multi");
4344 for (n
= 0; n
< multi
; ++n
) {
4345 if (pipe(fd
) == -1) {
4346 BIO_printf(bio_err
, "pipe failure\n");
4350 (void)BIO_flush(bio_err
);
4357 if (dup(fd
[1]) == -1) {
4358 BIO_printf(bio_err
, "dup failed\n");
4367 printf("Forked child %d\n", n
);
4370 /* for now, assume the pipe is long enough to take all the output */
4371 for (n
= 0; n
< multi
; ++n
) {
4379 if ((f
= fdopen(fds
[n
], "r")) == NULL
) {
4380 BIO_printf(bio_err
, "fdopen failure with 0x%x\n",
4385 while (fgets(buf
, sizeof(buf
), f
)) {
4386 p
= strchr(buf
, '\n');
4389 if (buf
[0] != '+') {
4391 "Don't understand line '%s' from child %d\n", buf
,
4395 printf("Got: %s from %d\n", buf
, n
);
4397 if (CHECK_AND_SKIP_PREFIX(p
, "+F:")) {
4401 if (strtoint(sstrsep(&p
, sep
), 0, ALGOR_NUM
, &alg
)) {
4403 for (j
= 0; j
< size_num
; ++j
)
4404 results
[alg
][j
] += atof(sstrsep(&p
, sep
));
4406 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F2:")) {
4407 tk
= sstrsep(&p
, sep
);
4408 if (strtoint(tk
, 0, OSSL_NELEM(rsa_results
), &k
)) {
4411 d
= atof(sstrsep(&p
, sep
));
4412 rsa_results
[k
][0] += d
;
4414 d
= atof(sstrsep(&p
, sep
));
4415 rsa_results
[k
][1] += d
;
4417 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F3:")) {
4418 tk
= sstrsep(&p
, sep
);
4419 if (strtoint(tk
, 0, OSSL_NELEM(dsa_results
), &k
)) {
4422 d
= atof(sstrsep(&p
, sep
));
4423 dsa_results
[k
][0] += d
;
4425 d
= atof(sstrsep(&p
, sep
));
4426 dsa_results
[k
][1] += d
;
4428 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F4:")) {
4429 tk
= sstrsep(&p
, sep
);
4430 if (strtoint(tk
, 0, OSSL_NELEM(ecdsa_results
), &k
)) {
4433 d
= atof(sstrsep(&p
, sep
));
4434 ecdsa_results
[k
][0] += d
;
4436 d
= atof(sstrsep(&p
, sep
));
4437 ecdsa_results
[k
][1] += d
;
4439 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F5:")) {
4440 tk
= sstrsep(&p
, sep
);
4441 if (strtoint(tk
, 0, OSSL_NELEM(ecdh_results
), &k
)) {
4444 d
= atof(sstrsep(&p
, sep
));
4445 ecdh_results
[k
][0] += d
;
4447 # ifndef OPENSSL_NO_ECX
4448 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F6:")) {
4449 tk
= sstrsep(&p
, sep
);
4450 if (strtoint(tk
, 0, OSSL_NELEM(eddsa_results
), &k
)) {
4454 d
= atof(sstrsep(&p
, sep
));
4455 eddsa_results
[k
][0] += d
;
4457 d
= atof(sstrsep(&p
, sep
));
4458 eddsa_results
[k
][1] += d
;
4460 # endif /* OPENSSL_NO_ECX */
4461 # ifndef OPENSSL_NO_SM2
4462 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F7:")) {
4463 tk
= sstrsep(&p
, sep
);
4464 if (strtoint(tk
, 0, OSSL_NELEM(sm2_results
), &k
)) {
4468 d
= atof(sstrsep(&p
, sep
));
4469 sm2_results
[k
][0] += d
;
4471 d
= atof(sstrsep(&p
, sep
));
4472 sm2_results
[k
][1] += d
;
4474 # endif /* OPENSSL_NO_SM2 */
4475 # ifndef OPENSSL_NO_DH
4476 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F8:")) {
4477 tk
= sstrsep(&p
, sep
);
4478 if (strtoint(tk
, 0, OSSL_NELEM(ffdh_results
), &k
)) {
4481 d
= atof(sstrsep(&p
, sep
));
4482 ffdh_results
[k
][0] += d
;
4484 # endif /* OPENSSL_NO_DH */
4485 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F9:")) {
4486 tk
= sstrsep(&p
, sep
);
4487 if (strtoint(tk
, 0, OSSL_NELEM(kems_results
), &k
)) {
4488 d
= atof(sstrsep(&p
, sep
));
4489 kems_results
[k
][0] += d
;
4491 d
= atof(sstrsep(&p
, sep
));
4492 kems_results
[k
][1] += d
;
4494 d
= atof(sstrsep(&p
, sep
));
4495 kems_results
[k
][2] += d
;
4497 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F10:")) {
4498 tk
= sstrsep(&p
, sep
);
4499 if (strtoint(tk
, 0, OSSL_NELEM(sigs_results
), &k
)) {
4500 d
= atof(sstrsep(&p
, sep
));
4501 sigs_results
[k
][0] += d
;
4503 d
= atof(sstrsep(&p
, sep
));
4504 sigs_results
[k
][1] += d
;
4506 d
= atof(sstrsep(&p
, sep
));
4507 sigs_results
[k
][2] += d
;
4509 } else if (!HAS_PREFIX(buf
, "+H:")) {
4510 BIO_printf(bio_err
, "Unknown type '%s' from child %d\n", buf
,
4518 for (n
= 0; n
< multi
; ++n
) {
4519 while (wait(&status
) == -1)
4520 if (errno
!= EINTR
) {
4521 BIO_printf(bio_err
, "Waitng for child failed with 0x%x\n",
4525 if (WIFEXITED(status
) && WEXITSTATUS(status
)) {
4526 BIO_printf(bio_err
, "Child exited with %d\n", WEXITSTATUS(status
));
4527 } else if (WIFSIGNALED(status
)) {
4528 BIO_printf(bio_err
, "Child terminated by signal %d\n",
4536 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
4537 const openssl_speed_sec_t
*seconds
)
4539 static const int mblengths_list
[] =
4540 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
4541 const int *mblengths
= mblengths_list
;
4542 int j
, count
, keylen
, num
= OSSL_NELEM(mblengths_list
), ciph_success
= 1;
4543 const char *alg_name
;
4544 unsigned char *inp
= NULL
, *out
= NULL
, *key
, no_key
[32], no_iv
[16];
4545 EVP_CIPHER_CTX
*ctx
= NULL
;
4548 if (lengths_single
) {
4549 mblengths
= &lengths_single
;
4553 inp
= app_malloc(mblengths
[num
- 1], "multiblock input buffer");
4554 out
= app_malloc(mblengths
[num
- 1] + 1024, "multiblock output buffer");
4555 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
4556 app_bail_out("failed to allocate cipher context\n");
4557 if (!EVP_EncryptInit_ex(ctx
, evp_cipher
, NULL
, NULL
, no_iv
))
4558 app_bail_out("failed to initialise cipher context\n");
4560 if ((keylen
= EVP_CIPHER_CTX_get_key_length(ctx
)) < 0) {
4561 BIO_printf(bio_err
, "Impossible negative key length: %d\n", keylen
);
4564 key
= app_malloc(keylen
, "evp_cipher key");
4565 if (EVP_CIPHER_CTX_rand_key(ctx
, key
) <= 0)
4566 app_bail_out("failed to generate random cipher key\n");
4567 if (!EVP_EncryptInit_ex(ctx
, NULL
, NULL
, key
, NULL
))
4568 app_bail_out("failed to set cipher key\n");
4569 OPENSSL_clear_free(key
, keylen
);
4571 if (EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_MAC_KEY
,
4572 sizeof(no_key
), no_key
) <= 0)
4573 app_bail_out("failed to set AEAD key\n");
4574 if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
4575 app_bail_out("failed to get cipher name\n");
4577 for (j
= 0; j
< num
; j
++) {
4578 print_message(alg_name
, mblengths
[j
], seconds
->sym
);
4580 for (count
= 0; run
&& count
< INT_MAX
; count
++) {
4581 unsigned char aad
[EVP_AEAD_TLS1_AAD_LEN
];
4582 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param
;
4583 size_t len
= mblengths
[j
];
4586 memset(aad
, 0, 8); /* avoid uninitialized values */
4587 aad
[8] = 23; /* SSL3_RT_APPLICATION_DATA */
4588 aad
[9] = 3; /* version */
4590 aad
[11] = 0; /* length */
4592 mb_param
.out
= NULL
;
4595 mb_param
.interleave
= 8;
4597 packlen
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD
,
4598 sizeof(mb_param
), &mb_param
);
4604 (void)EVP_CIPHER_CTX_ctrl(ctx
,
4605 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT
,
4606 sizeof(mb_param
), &mb_param
);
4610 RAND_bytes(out
, 16);
4612 aad
[11] = (unsigned char)(len
>> 8);
4613 aad
[12] = (unsigned char)(len
);
4614 pad
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_TLS1_AAD
,
4615 EVP_AEAD_TLS1_AAD_LEN
, aad
);
4616 ciph_success
= EVP_Cipher(ctx
, out
, inp
, len
+ pad
);
4620 BIO_printf(bio_err
, mr
? "+R:%d:%s:%f\n"
4621 : "%d %s's in %.2fs\n", count
, "evp", d
);
4622 if ((ciph_success
<= 0) && (mr
== 0))
4623 BIO_printf(bio_err
, "Error performing cipher op\n");
4624 results
[D_EVP
][j
] = ((double)count
) / d
* mblengths
[j
];
4628 fprintf(stdout
, "+H");
4629 for (j
= 0; j
< num
; j
++)
4630 fprintf(stdout
, ":%d", mblengths
[j
]);
4631 fprintf(stdout
, "\n");
4632 fprintf(stdout
, "+F:%d:%s", D_EVP
, alg_name
);
4633 for (j
= 0; j
< num
; j
++)
4634 fprintf(stdout
, ":%.2f", results
[D_EVP
][j
]);
4635 fprintf(stdout
, "\n");
4638 "The 'numbers' are in 1000s of bytes per second processed.\n");
4639 fprintf(stdout
, "type ");
4640 for (j
= 0; j
< num
; j
++)
4641 fprintf(stdout
, "%7d bytes", mblengths
[j
]);
4642 fprintf(stdout
, "\n");
4643 fprintf(stdout
, "%-24s", alg_name
);
4645 for (j
= 0; j
< num
; j
++) {
4646 if (results
[D_EVP
][j
] > 10000)
4647 fprintf(stdout
, " %11.2fk", results
[D_EVP
][j
] / 1e3
);
4649 fprintf(stdout
, " %11.2f ", results
[D_EVP
][j
]);
4651 fprintf(stdout
, "\n");
4657 EVP_CIPHER_CTX_free(ctx
);