2 * Copyright 1995-2023 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
][4]; /* 4 ops: sign, verify, encrypt, decrypt */
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
;
525 EVP_PKEY_CTX
*rsa_sign_ctx
[RSA_NUM
];
526 EVP_PKEY_CTX
*rsa_verify_ctx
[RSA_NUM
];
527 EVP_PKEY_CTX
*rsa_encrypt_ctx
[RSA_NUM
];
528 EVP_PKEY_CTX
*rsa_decrypt_ctx
[RSA_NUM
];
529 EVP_PKEY_CTX
*dsa_sign_ctx
[DSA_NUM
];
530 EVP_PKEY_CTX
*dsa_verify_ctx
[DSA_NUM
];
531 EVP_PKEY_CTX
*ecdsa_sign_ctx
[ECDSA_NUM
];
532 EVP_PKEY_CTX
*ecdsa_verify_ctx
[ECDSA_NUM
];
533 EVP_PKEY_CTX
*ecdh_ctx
[EC_NUM
];
534 #ifndef OPENSSL_NO_ECX
535 EVP_MD_CTX
*eddsa_ctx
[EdDSA_NUM
];
536 EVP_MD_CTX
*eddsa_ctx2
[EdDSA_NUM
];
537 #endif /* OPENSSL_NO_ECX */
538 #ifndef OPENSSL_NO_SM2
539 EVP_MD_CTX
*sm2_ctx
[SM2_NUM
];
540 EVP_MD_CTX
*sm2_vfy_ctx
[SM2_NUM
];
541 EVP_PKEY
*sm2_pkey
[SM2_NUM
];
543 unsigned char *secret_a
;
544 unsigned char *secret_b
;
545 size_t outlen
[EC_NUM
];
546 #ifndef OPENSSL_NO_DH
547 EVP_PKEY_CTX
*ffdh_ctx
[FFDH_NUM
];
548 unsigned char *secret_ff_a
;
549 unsigned char *secret_ff_b
;
553 EVP_PKEY_CTX
*kem_gen_ctx
[MAX_KEM_NUM
];
554 EVP_PKEY_CTX
*kem_encaps_ctx
[MAX_KEM_NUM
];
555 EVP_PKEY_CTX
*kem_decaps_ctx
[MAX_KEM_NUM
];
556 size_t kem_out_len
[MAX_KEM_NUM
];
557 size_t kem_secret_len
[MAX_KEM_NUM
];
558 unsigned char *kem_out
[MAX_KEM_NUM
];
559 unsigned char *kem_send_secret
[MAX_KEM_NUM
];
560 unsigned char *kem_rcv_secret
[MAX_KEM_NUM
];
561 EVP_PKEY_CTX
*sig_gen_ctx
[MAX_KEM_NUM
];
562 EVP_PKEY_CTX
*sig_sign_ctx
[MAX_KEM_NUM
];
563 EVP_PKEY_CTX
*sig_verify_ctx
[MAX_KEM_NUM
];
564 size_t sig_max_sig_len
[MAX_KEM_NUM
];
565 size_t sig_act_sig_len
[MAX_KEM_NUM
];
566 unsigned char *sig_sig
[MAX_KEM_NUM
];
568 static int run_benchmark(int async_jobs
, int (*loop_function
) (void *),
569 loopargs_t
*loopargs
);
571 static unsigned int testnum
;
573 static char *evp_mac_mdname
= "md5";
574 static char *evp_hmac_name
= NULL
;
575 static const char *evp_md_name
= NULL
;
576 static char *evp_mac_ciphername
= "aes-128-cbc";
577 static char *evp_cmac_name
= NULL
;
579 static int have_md(const char *name
)
584 if (opt_md_silent(name
, &md
)) {
585 EVP_MD_CTX
*ctx
= EVP_MD_CTX_new();
587 if (ctx
!= NULL
&& EVP_DigestInit(ctx
, md
) > 0)
589 EVP_MD_CTX_free(ctx
);
595 static int have_cipher(const char *name
)
598 EVP_CIPHER
*cipher
= NULL
;
600 if (opt_cipher_silent(name
, &cipher
)) {
601 EVP_CIPHER_CTX
*ctx
= EVP_CIPHER_CTX_new();
604 && EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1) > 0)
606 EVP_CIPHER_CTX_free(ctx
);
607 EVP_CIPHER_free(cipher
);
612 static int EVP_Digest_loop(const char *mdname
, ossl_unused
int algindex
, void *args
)
614 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
615 unsigned char *buf
= tempargs
->buf
;
616 unsigned char digest
[EVP_MAX_MD_SIZE
];
620 if (!opt_md_silent(mdname
, &md
))
622 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
623 if (!EVP_Digest(buf
, (size_t)lengths
[testnum
], digest
, NULL
, md
,
633 static int EVP_Digest_md_loop(void *args
)
635 return EVP_Digest_loop(evp_md_name
, D_EVP
, args
);
638 static int EVP_Digest_MD2_loop(void *args
)
640 return EVP_Digest_loop("md2", D_MD2
, args
);
643 static int EVP_Digest_MDC2_loop(void *args
)
645 return EVP_Digest_loop("mdc2", D_MDC2
, args
);
648 static int EVP_Digest_MD4_loop(void *args
)
650 return EVP_Digest_loop("md4", D_MD4
, args
);
653 static int MD5_loop(void *args
)
655 return EVP_Digest_loop("md5", D_MD5
, args
);
658 static int EVP_MAC_loop(ossl_unused
int algindex
, void *args
)
660 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
661 unsigned char *buf
= tempargs
->buf
;
662 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
663 unsigned char mac
[EVP_MAX_MD_SIZE
];
666 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
669 if (!EVP_MAC_init(mctx
, NULL
, 0, NULL
)
670 || !EVP_MAC_update(mctx
, buf
, lengths
[testnum
])
671 || !EVP_MAC_final(mctx
, mac
, &outl
, sizeof(mac
)))
677 static int HMAC_loop(void *args
)
679 return EVP_MAC_loop(D_HMAC
, args
);
682 static int CMAC_loop(void *args
)
684 return EVP_MAC_loop(D_EVP_CMAC
, args
);
687 static int SHA1_loop(void *args
)
689 return EVP_Digest_loop("sha1", D_SHA1
, args
);
692 static int SHA256_loop(void *args
)
694 return EVP_Digest_loop("sha256", D_SHA256
, args
);
697 static int SHA512_loop(void *args
)
699 return EVP_Digest_loop("sha512", D_SHA512
, args
);
702 static int WHIRLPOOL_loop(void *args
)
704 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL
, args
);
707 static int EVP_Digest_RMD160_loop(void *args
)
709 return EVP_Digest_loop("ripemd160", D_RMD160
, args
);
714 static int EVP_Cipher_loop(void *args
)
716 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
717 unsigned char *buf
= tempargs
->buf
;
720 if (tempargs
->ctx
== NULL
)
722 for (count
= 0; COND(c
[algindex
][testnum
]); count
++)
723 if (EVP_Cipher(tempargs
->ctx
, buf
, buf
, (size_t)lengths
[testnum
]) <= 0)
728 static int GHASH_loop(void *args
)
730 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
731 unsigned char *buf
= tempargs
->buf
;
732 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
735 /* just do the update in the loop to be comparable with 1.1.1 */
736 for (count
= 0; COND(c
[D_GHASH
][testnum
]); count
++) {
737 if (!EVP_MAC_update(mctx
, buf
, lengths
[testnum
]))
743 #define MAX_BLOCK_SIZE 128
745 static unsigned char iv
[2 * MAX_BLOCK_SIZE
/ 8];
747 static EVP_CIPHER_CTX
*init_evp_cipher_ctx(const char *ciphername
,
748 const unsigned char *key
,
751 EVP_CIPHER_CTX
*ctx
= NULL
;
752 EVP_CIPHER
*cipher
= NULL
;
754 if (!opt_cipher_silent(ciphername
, &cipher
))
757 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
760 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1)) {
761 EVP_CIPHER_CTX_free(ctx
);
766 if (EVP_CIPHER_CTX_set_key_length(ctx
, keylen
) <= 0) {
767 EVP_CIPHER_CTX_free(ctx
);
772 if (!EVP_CipherInit_ex(ctx
, NULL
, NULL
, key
, iv
, 1)) {
773 EVP_CIPHER_CTX_free(ctx
);
779 EVP_CIPHER_free(cipher
);
783 static int RAND_bytes_loop(void *args
)
785 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
786 unsigned char *buf
= tempargs
->buf
;
789 for (count
= 0; COND(c
[D_RAND
][testnum
]); count
++)
790 RAND_bytes(buf
, lengths
[testnum
]);
794 static int decrypt
= 0;
795 static int EVP_Update_loop(void *args
)
797 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
798 unsigned char *buf
= tempargs
->buf
;
799 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
803 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
804 rc
= EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
806 /* reset iv in case of counter overflow */
807 rc
= EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
811 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
812 rc
= EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
814 /* reset iv in case of counter overflow */
815 rc
= EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
820 rc
= EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
822 rc
= EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
825 BIO_printf(bio_err
, "Error finalizing cipher loop\n");
830 * CCM does not support streaming. For the purpose of performance measurement,
831 * each message is encrypted using the same (key,iv)-pair. Do not use this
832 * code in your application.
834 static int EVP_Update_loop_ccm(void *args
)
836 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
837 unsigned char *buf
= tempargs
->buf
;
838 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
839 int outl
, count
, realcount
= 0, final
;
840 unsigned char tag
[12];
843 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
844 if (EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
, sizeof(tag
),
847 && EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
848 /* counter is reset on every update */
849 && EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0)
853 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
854 /* restore iv length field */
855 if (EVP_EncryptUpdate(ctx
, NULL
, &outl
, NULL
, lengths
[testnum
]) > 0
856 /* counter is reset on every update */
857 && EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0)
862 final
= EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
864 final
= EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
867 BIO_printf(bio_err
, "Error finalizing ccm loop\n");
872 * To make AEAD benchmarking more relevant perform TLS-like operations,
873 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
874 * payload length is not actually limited by 16KB...
876 static int EVP_Update_loop_aead(void *args
)
878 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
879 unsigned char *buf
= tempargs
->buf
;
880 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
881 int outl
, count
, realcount
= 0;
882 unsigned char aad
[13] = { 0xcc };
883 unsigned char faketag
[16] = { 0xcc };
886 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
887 if (EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
888 && EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
,
889 sizeof(faketag
), faketag
) > 0
890 && EVP_DecryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
)) > 0
891 && EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0
892 && EVP_DecryptFinal_ex(ctx
, buf
+ outl
, &outl
) >0)
896 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
897 if (EVP_EncryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
) > 0
898 && EVP_EncryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
)) > 0
899 && EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]) > 0
900 && EVP_EncryptFinal_ex(ctx
, buf
+ outl
, &outl
) > 0)
907 static int RSA_sign_loop(void *args
)
909 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
910 unsigned char *buf
= tempargs
->buf
;
911 unsigned char *buf2
= tempargs
->buf2
;
912 size_t *rsa_num
= &tempargs
->sigsize
;
913 EVP_PKEY_CTX
**rsa_sign_ctx
= tempargs
->rsa_sign_ctx
;
916 for (count
= 0; COND(rsa_c
[testnum
][0]); count
++) {
917 *rsa_num
= tempargs
->buflen
;
918 ret
= EVP_PKEY_sign(rsa_sign_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
920 BIO_printf(bio_err
, "RSA sign failure\n");
921 ERR_print_errors(bio_err
);
929 static int RSA_verify_loop(void *args
)
931 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
932 unsigned char *buf
= tempargs
->buf
;
933 unsigned char *buf2
= tempargs
->buf2
;
934 size_t rsa_num
= tempargs
->sigsize
;
935 EVP_PKEY_CTX
**rsa_verify_ctx
= tempargs
->rsa_verify_ctx
;
938 for (count
= 0; COND(rsa_c
[testnum
][1]); count
++) {
939 ret
= EVP_PKEY_verify(rsa_verify_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
941 BIO_printf(bio_err
, "RSA verify failure\n");
942 ERR_print_errors(bio_err
);
950 static int RSA_encrypt_loop(void *args
)
952 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
953 unsigned char *buf
= tempargs
->buf
;
954 unsigned char *buf2
= tempargs
->buf2
;
955 size_t *rsa_num
= &tempargs
->encsize
;
956 EVP_PKEY_CTX
**rsa_encrypt_ctx
= tempargs
->rsa_encrypt_ctx
;
959 for (count
= 0; COND(rsa_c
[testnum
][2]); count
++) {
960 *rsa_num
= tempargs
->buflen
;
961 ret
= EVP_PKEY_encrypt(rsa_encrypt_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
963 BIO_printf(bio_err
, "RSA encrypt failure\n");
964 ERR_print_errors(bio_err
);
972 static int RSA_decrypt_loop(void *args
)
974 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
975 unsigned char *buf
= tempargs
->buf
;
976 unsigned char *buf2
= tempargs
->buf2
;
978 EVP_PKEY_CTX
**rsa_decrypt_ctx
= tempargs
->rsa_decrypt_ctx
;
981 for (count
= 0; COND(rsa_c
[testnum
][3]); count
++) {
982 rsa_num
= tempargs
->buflen
;
983 ret
= EVP_PKEY_decrypt(rsa_decrypt_ctx
[testnum
], buf
, &rsa_num
, buf2
, tempargs
->encsize
);
985 BIO_printf(bio_err
, "RSA decrypt failure\n");
986 ERR_print_errors(bio_err
);
994 #ifndef OPENSSL_NO_DH
996 static int FFDH_derive_key_loop(void *args
)
998 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
999 EVP_PKEY_CTX
*ffdh_ctx
= tempargs
->ffdh_ctx
[testnum
];
1000 unsigned char *derived_secret
= tempargs
->secret_ff_a
;
1003 for (count
= 0; COND(ffdh_c
[testnum
][0]); count
++) {
1004 /* outlen can be overwritten with a too small value (no padding used) */
1005 size_t outlen
= MAX_FFDH_SIZE
;
1007 EVP_PKEY_derive(ffdh_ctx
, derived_secret
, &outlen
);
1011 #endif /* OPENSSL_NO_DH */
1013 static int DSA_sign_loop(void *args
)
1015 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1016 unsigned char *buf
= tempargs
->buf
;
1017 unsigned char *buf2
= tempargs
->buf2
;
1018 size_t *dsa_num
= &tempargs
->sigsize
;
1019 EVP_PKEY_CTX
**dsa_sign_ctx
= tempargs
->dsa_sign_ctx
;
1022 for (count
= 0; COND(dsa_c
[testnum
][0]); count
++) {
1023 *dsa_num
= tempargs
->buflen
;
1024 ret
= EVP_PKEY_sign(dsa_sign_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
1026 BIO_printf(bio_err
, "DSA sign failure\n");
1027 ERR_print_errors(bio_err
);
1035 static int DSA_verify_loop(void *args
)
1037 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1038 unsigned char *buf
= tempargs
->buf
;
1039 unsigned char *buf2
= tempargs
->buf2
;
1040 size_t dsa_num
= tempargs
->sigsize
;
1041 EVP_PKEY_CTX
**dsa_verify_ctx
= tempargs
->dsa_verify_ctx
;
1044 for (count
= 0; COND(dsa_c
[testnum
][1]); count
++) {
1045 ret
= EVP_PKEY_verify(dsa_verify_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
1047 BIO_printf(bio_err
, "DSA verify failure\n");
1048 ERR_print_errors(bio_err
);
1056 static int ECDSA_sign_loop(void *args
)
1058 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1059 unsigned char *buf
= tempargs
->buf
;
1060 unsigned char *buf2
= tempargs
->buf2
;
1061 size_t *ecdsa_num
= &tempargs
->sigsize
;
1062 EVP_PKEY_CTX
**ecdsa_sign_ctx
= tempargs
->ecdsa_sign_ctx
;
1065 for (count
= 0; COND(ecdsa_c
[testnum
][0]); count
++) {
1066 *ecdsa_num
= tempargs
->buflen
;
1067 ret
= EVP_PKEY_sign(ecdsa_sign_ctx
[testnum
], buf2
, ecdsa_num
, buf
, 20);
1069 BIO_printf(bio_err
, "ECDSA sign failure\n");
1070 ERR_print_errors(bio_err
);
1078 static int ECDSA_verify_loop(void *args
)
1080 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1081 unsigned char *buf
= tempargs
->buf
;
1082 unsigned char *buf2
= tempargs
->buf2
;
1083 size_t ecdsa_num
= tempargs
->sigsize
;
1084 EVP_PKEY_CTX
**ecdsa_verify_ctx
= tempargs
->ecdsa_verify_ctx
;
1087 for (count
= 0; COND(ecdsa_c
[testnum
][1]); count
++) {
1088 ret
= EVP_PKEY_verify(ecdsa_verify_ctx
[testnum
], buf2
, ecdsa_num
,
1091 BIO_printf(bio_err
, "ECDSA verify failure\n");
1092 ERR_print_errors(bio_err
);
1100 /* ******************************************************************** */
1102 static int ECDH_EVP_derive_key_loop(void *args
)
1104 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1105 EVP_PKEY_CTX
*ctx
= tempargs
->ecdh_ctx
[testnum
];
1106 unsigned char *derived_secret
= tempargs
->secret_a
;
1108 size_t *outlen
= &(tempargs
->outlen
[testnum
]);
1110 for (count
= 0; COND(ecdh_c
[testnum
][0]); count
++)
1111 EVP_PKEY_derive(ctx
, derived_secret
, outlen
);
1116 #ifndef OPENSSL_NO_ECX
1117 static int EdDSA_sign_loop(void *args
)
1119 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1120 unsigned char *buf
= tempargs
->buf
;
1121 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx
;
1122 unsigned char *eddsasig
= tempargs
->buf2
;
1123 size_t *eddsasigsize
= &tempargs
->sigsize
;
1126 for (count
= 0; COND(eddsa_c
[testnum
][0]); count
++) {
1127 ret
= EVP_DigestSignInit(edctx
[testnum
], NULL
, NULL
, NULL
, NULL
);
1129 BIO_printf(bio_err
, "EdDSA sign init failure\n");
1130 ERR_print_errors(bio_err
);
1134 ret
= EVP_DigestSign(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1136 BIO_printf(bio_err
, "EdDSA sign failure\n");
1137 ERR_print_errors(bio_err
);
1145 static int EdDSA_verify_loop(void *args
)
1147 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1148 unsigned char *buf
= tempargs
->buf
;
1149 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx2
;
1150 unsigned char *eddsasig
= tempargs
->buf2
;
1151 size_t eddsasigsize
= tempargs
->sigsize
;
1154 for (count
= 0; COND(eddsa_c
[testnum
][1]); count
++) {
1155 ret
= EVP_DigestVerifyInit(edctx
[testnum
], NULL
, NULL
, NULL
, NULL
);
1157 BIO_printf(bio_err
, "EdDSA verify init failure\n");
1158 ERR_print_errors(bio_err
);
1162 ret
= EVP_DigestVerify(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1164 BIO_printf(bio_err
, "EdDSA verify failure\n");
1165 ERR_print_errors(bio_err
);
1172 #endif /* OPENSSL_NO_ECX */
1174 #ifndef OPENSSL_NO_SM2
1175 static int SM2_sign_loop(void *args
)
1177 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1178 unsigned char *buf
= tempargs
->buf
;
1179 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_ctx
;
1180 unsigned char *sm2sig
= tempargs
->buf2
;
1183 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1184 const size_t max_size
= EVP_PKEY_get_size(sm2_pkey
[testnum
]);
1186 for (count
= 0; COND(sm2_c
[testnum
][0]); count
++) {
1187 sm2sigsize
= max_size
;
1189 if (!EVP_DigestSignInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1190 NULL
, sm2_pkey
[testnum
])) {
1191 BIO_printf(bio_err
, "SM2 init sign failure\n");
1192 ERR_print_errors(bio_err
);
1196 ret
= EVP_DigestSign(sm2ctx
[testnum
], sm2sig
, &sm2sigsize
,
1199 BIO_printf(bio_err
, "SM2 sign failure\n");
1200 ERR_print_errors(bio_err
);
1204 /* update the latest returned size and always use the fixed buffer size */
1205 tempargs
->sigsize
= sm2sigsize
;
1211 static int SM2_verify_loop(void *args
)
1213 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1214 unsigned char *buf
= tempargs
->buf
;
1215 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_vfy_ctx
;
1216 unsigned char *sm2sig
= tempargs
->buf2
;
1217 size_t sm2sigsize
= tempargs
->sigsize
;
1219 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1221 for (count
= 0; COND(sm2_c
[testnum
][1]); count
++) {
1222 if (!EVP_DigestVerifyInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1223 NULL
, sm2_pkey
[testnum
])) {
1224 BIO_printf(bio_err
, "SM2 verify init failure\n");
1225 ERR_print_errors(bio_err
);
1229 ret
= EVP_DigestVerify(sm2ctx
[testnum
], sm2sig
, sm2sigsize
,
1232 BIO_printf(bio_err
, "SM2 verify failure\n");
1233 ERR_print_errors(bio_err
);
1240 #endif /* OPENSSL_NO_SM2 */
1242 static int KEM_keygen_loop(void *args
)
1244 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1245 EVP_PKEY_CTX
*ctx
= tempargs
->kem_gen_ctx
[testnum
];
1246 EVP_PKEY
*pkey
= NULL
;
1249 for (count
= 0; COND(kems_c
[testnum
][0]); count
++) {
1250 if (EVP_PKEY_keygen(ctx
, &pkey
) <= 0)
1253 * runtime defined to quite some degree by randomness,
1254 * so performance overhead of _free doesn't impact
1255 * results significantly. In any case this test is
1256 * meant to permit relative algorithm performance
1259 EVP_PKEY_free(pkey
);
1265 static int KEM_encaps_loop(void *args
)
1267 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1268 EVP_PKEY_CTX
*ctx
= tempargs
->kem_encaps_ctx
[testnum
];
1269 size_t out_len
= tempargs
->kem_out_len
[testnum
];
1270 size_t secret_len
= tempargs
->kem_secret_len
[testnum
];
1271 unsigned char *out
= tempargs
->kem_out
[testnum
];
1272 unsigned char *secret
= tempargs
->kem_send_secret
[testnum
];
1275 for (count
= 0; COND(kems_c
[testnum
][1]); count
++) {
1276 if (EVP_PKEY_encapsulate(ctx
, out
, &out_len
, secret
, &secret_len
) <= 0)
1282 static int KEM_decaps_loop(void *args
)
1284 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1285 EVP_PKEY_CTX
*ctx
= tempargs
->kem_decaps_ctx
[testnum
];
1286 size_t out_len
= tempargs
->kem_out_len
[testnum
];
1287 size_t secret_len
= tempargs
->kem_secret_len
[testnum
];
1288 unsigned char *out
= tempargs
->kem_out
[testnum
];
1289 unsigned char *secret
= tempargs
->kem_send_secret
[testnum
];
1292 for (count
= 0; COND(kems_c
[testnum
][2]); count
++) {
1293 if (EVP_PKEY_decapsulate(ctx
, secret
, &secret_len
, out
, out_len
) <= 0)
1299 static int SIG_keygen_loop(void *args
)
1301 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1302 EVP_PKEY_CTX
*ctx
= tempargs
->sig_gen_ctx
[testnum
];
1303 EVP_PKEY
*pkey
= NULL
;
1306 for (count
= 0; COND(kems_c
[testnum
][0]); count
++) {
1307 EVP_PKEY_keygen(ctx
, &pkey
);
1308 /* TBD: How much does free influence runtime? */
1309 EVP_PKEY_free(pkey
);
1315 static int SIG_sign_loop(void *args
)
1317 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1318 EVP_PKEY_CTX
*ctx
= tempargs
->sig_sign_ctx
[testnum
];
1319 /* be sure to not change stored sig: */
1320 unsigned char *sig
= app_malloc(tempargs
->sig_max_sig_len
[testnum
],
1322 unsigned char md
[SHA256_DIGEST_LENGTH
] = { 0 };
1323 size_t md_len
= SHA256_DIGEST_LENGTH
;
1326 for (count
= 0; COND(kems_c
[testnum
][1]); count
++) {
1327 size_t sig_len
= tempargs
->sig_max_sig_len
[testnum
];
1328 int ret
= EVP_PKEY_sign(ctx
, sig
, &sig_len
, md
, md_len
);
1331 BIO_printf(bio_err
, "SIG sign failure at count %d\n", count
);
1332 ERR_print_errors(bio_err
);
1341 static int SIG_verify_loop(void *args
)
1343 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1344 EVP_PKEY_CTX
*ctx
= tempargs
->sig_verify_ctx
[testnum
];
1345 size_t sig_len
= tempargs
->sig_act_sig_len
[testnum
];
1346 unsigned char *sig
= tempargs
->sig_sig
[testnum
];
1347 unsigned char md
[SHA256_DIGEST_LENGTH
] = { 0 };
1348 size_t md_len
= SHA256_DIGEST_LENGTH
;
1351 for (count
= 0; COND(kems_c
[testnum
][2]); count
++) {
1352 int ret
= EVP_PKEY_verify(ctx
, sig
, sig_len
, md
, md_len
);
1355 BIO_printf(bio_err
, "SIG verify failure at count %d\n", count
);
1356 ERR_print_errors(bio_err
);
1365 static int run_benchmark(int async_jobs
,
1366 int (*loop_function
) (void *), loopargs_t
*loopargs
)
1368 int job_op_count
= 0;
1369 int total_op_count
= 0;
1370 int num_inprogress
= 0;
1371 int error
= 0, i
= 0, ret
= 0;
1372 OSSL_ASYNC_FD job_fd
= 0;
1373 size_t num_job_fds
= 0;
1375 if (async_jobs
== 0) {
1376 return loop_function((void *)&loopargs
);
1379 for (i
= 0; i
< async_jobs
&& !error
; i
++) {
1380 loopargs_t
*looparg_item
= loopargs
+ i
;
1382 /* Copy pointer content (looparg_t item address) into async context */
1383 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
, loopargs
[i
].wait_ctx
,
1384 &job_op_count
, loop_function
,
1385 (void *)&looparg_item
, sizeof(looparg_item
));
1391 if (job_op_count
== -1) {
1394 total_op_count
+= job_op_count
;
1399 BIO_printf(bio_err
, "Failure in the job\n");
1400 ERR_print_errors(bio_err
);
1406 while (num_inprogress
> 0) {
1407 #if defined(OPENSSL_SYS_WINDOWS)
1409 #elif defined(OPENSSL_SYS_UNIX)
1410 int select_result
= 0;
1411 OSSL_ASYNC_FD max_fd
= 0;
1414 FD_ZERO(&waitfdset
);
1416 for (i
= 0; i
< async_jobs
&& num_inprogress
> 0; i
++) {
1417 if (loopargs
[i
].inprogress_job
== NULL
)
1420 if (!ASYNC_WAIT_CTX_get_all_fds
1421 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1422 || num_job_fds
> 1) {
1423 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1424 ERR_print_errors(bio_err
);
1428 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1430 FD_SET(job_fd
, &waitfdset
);
1431 if (job_fd
> max_fd
)
1435 if (max_fd
>= (OSSL_ASYNC_FD
)FD_SETSIZE
) {
1437 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1438 "Decrease the value of async_jobs\n",
1439 max_fd
, FD_SETSIZE
);
1440 ERR_print_errors(bio_err
);
1445 select_result
= select(max_fd
+ 1, &waitfdset
, NULL
, NULL
, NULL
);
1446 if (select_result
== -1 && errno
== EINTR
)
1449 if (select_result
== -1) {
1450 BIO_printf(bio_err
, "Failure in the select\n");
1451 ERR_print_errors(bio_err
);
1456 if (select_result
== 0)
1460 for (i
= 0; i
< async_jobs
; i
++) {
1461 if (loopargs
[i
].inprogress_job
== NULL
)
1464 if (!ASYNC_WAIT_CTX_get_all_fds
1465 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1466 || num_job_fds
> 1) {
1467 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1468 ERR_print_errors(bio_err
);
1472 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1475 #if defined(OPENSSL_SYS_UNIX)
1476 if (num_job_fds
== 1 && !FD_ISSET(job_fd
, &waitfdset
))
1478 #elif defined(OPENSSL_SYS_WINDOWS)
1479 if (num_job_fds
== 1
1480 && !PeekNamedPipe(job_fd
, NULL
, 0, NULL
, &avail
, NULL
)
1485 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
,
1486 loopargs
[i
].wait_ctx
, &job_op_count
,
1487 loop_function
, (void *)(loopargs
+ i
),
1488 sizeof(loopargs_t
));
1493 if (job_op_count
== -1) {
1496 total_op_count
+= job_op_count
;
1499 loopargs
[i
].inprogress_job
= NULL
;
1504 loopargs
[i
].inprogress_job
= NULL
;
1505 BIO_printf(bio_err
, "Failure in the job\n");
1506 ERR_print_errors(bio_err
);
1513 return error
? -1 : total_op_count
;
1516 typedef struct ec_curve_st
{
1520 size_t sigsize
; /* only used for EdDSA curves */
1523 static EVP_PKEY
*get_ecdsa(const EC_CURVE
*curve
)
1525 EVP_PKEY_CTX
*kctx
= NULL
;
1526 EVP_PKEY
*key
= NULL
;
1528 /* Ensure that the error queue is empty */
1529 if (ERR_peek_error()) {
1531 "WARNING: the error queue contains previous unhandled errors.\n");
1532 ERR_print_errors(bio_err
);
1536 * Let's try to create a ctx directly from the NID: this works for
1537 * curves like Curve25519 that are not implemented through the low
1538 * level EC interface.
1539 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1540 * then we set the curve by NID before deriving the actual keygen
1541 * ctx for that specific curve.
1543 kctx
= EVP_PKEY_CTX_new_id(curve
->nid
, NULL
);
1545 EVP_PKEY_CTX
*pctx
= NULL
;
1546 EVP_PKEY
*params
= NULL
;
1548 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1549 * "int_ctx_new:unsupported algorithm" error was added to the
1551 * We remove it from the error queue as we are handling it.
1553 unsigned long error
= ERR_peek_error();
1555 if (error
== ERR_peek_last_error() /* oldest and latest errors match */
1556 /* check that the error origin matches */
1557 && ERR_GET_LIB(error
) == ERR_LIB_EVP
1558 && (ERR_GET_REASON(error
) == EVP_R_UNSUPPORTED_ALGORITHM
1559 || ERR_GET_REASON(error
) == ERR_R_UNSUPPORTED
))
1560 ERR_get_error(); /* pop error from queue */
1561 if (ERR_peek_error()) {
1563 "Unhandled error in the error queue during EC key setup.\n");
1564 ERR_print_errors(bio_err
);
1568 /* Create the context for parameter generation */
1569 if ((pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
)) == NULL
1570 || EVP_PKEY_paramgen_init(pctx
) <= 0
1571 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
1573 || EVP_PKEY_paramgen(pctx
, ¶ms
) <= 0) {
1574 BIO_printf(bio_err
, "EC params init failure.\n");
1575 ERR_print_errors(bio_err
);
1576 EVP_PKEY_CTX_free(pctx
);
1579 EVP_PKEY_CTX_free(pctx
);
1581 /* Create the context for the key generation */
1582 kctx
= EVP_PKEY_CTX_new(params
, NULL
);
1583 EVP_PKEY_free(params
);
1586 || EVP_PKEY_keygen_init(kctx
) <= 0
1587 || EVP_PKEY_keygen(kctx
, &key
) <= 0) {
1588 BIO_printf(bio_err
, "EC key generation failure.\n");
1589 ERR_print_errors(bio_err
);
1592 EVP_PKEY_CTX_free(kctx
);
1596 #define stop_it(do_it, test_num)\
1597 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1599 /* Checks to see if algorithms are fetchable */
1600 #define IS_FETCHABLE(type, TYPE) \
1601 static int is_ ## type ## _fetchable(const TYPE *alg) \
1604 const char *propq = app_get0_propq(); \
1605 OSSL_LIB_CTX *libctx = app_get0_libctx(); \
1606 const char *name = TYPE ## _get0_name(alg); \
1609 impl = TYPE ## _fetch(libctx, name, propq); \
1610 ERR_pop_to_mark(); \
1613 TYPE ## _free(impl); \
1617 IS_FETCHABLE(signature
, EVP_SIGNATURE
)
1618 IS_FETCHABLE(kem
, EVP_KEM
)
1620 DEFINE_STACK_OF(EVP_KEM
)
1622 static int kems_cmp(const EVP_KEM
* const *a
,
1623 const EVP_KEM
* const *b
)
1625 return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a
)),
1626 OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b
)));
1629 static void collect_kem(EVP_KEM
*kem
, void *stack
)
1631 STACK_OF(EVP_KEM
) *kem_stack
= stack
;
1633 if (is_kem_fetchable(kem
)
1634 && sk_EVP_KEM_push(kem_stack
, kem
) > 0) {
1635 EVP_KEM_up_ref(kem
);
1639 static int kem_locate(const char *algo
, unsigned int *idx
)
1643 for (i
= 0; i
< kems_algs_len
; i
++) {
1644 if (strcmp(kems_algname
[i
], algo
) == 0) {
1652 DEFINE_STACK_OF(EVP_SIGNATURE
)
1654 static int signatures_cmp(const EVP_SIGNATURE
* const *a
,
1655 const EVP_SIGNATURE
* const *b
)
1657 return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a
)),
1658 OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b
)));
1661 static void collect_signatures(EVP_SIGNATURE
*sig
, void *stack
)
1663 STACK_OF(EVP_SIGNATURE
) *sig_stack
= stack
;
1665 if (is_signature_fetchable(sig
)
1666 && sk_EVP_SIGNATURE_push(sig_stack
, sig
) > 0)
1667 EVP_SIGNATURE_up_ref(sig
);
1670 static int sig_locate(const char *algo
, unsigned int *idx
)
1674 for (i
= 0; i
< sigs_algs_len
; i
++) {
1675 if (strcmp(sigs_algname
[i
], algo
) == 0) {
1683 static int get_max(const uint8_t doit
[], size_t algs_len
) {
1687 for (i
= 0; i
< algs_len
; i
++)
1688 if (maxcnt
< doit
[i
]) maxcnt
= doit
[i
];
1692 int speed_main(int argc
, char **argv
)
1696 loopargs_t
*loopargs
= NULL
;
1698 const char *engine_id
= NULL
;
1699 EVP_CIPHER
*evp_cipher
= NULL
;
1700 EVP_MAC
*mac
= NULL
;
1703 int async_init
= 0, multiblock
= 0, pr_header
= 0;
1704 uint8_t doit
[ALGOR_NUM
] = { 0 };
1705 int ret
= 1, misalign
= 0, lengths_single
= 0, aead
= 0;
1706 STACK_OF(EVP_KEM
) *kem_stack
= NULL
;
1707 STACK_OF(EVP_SIGNATURE
) *sig_stack
= NULL
;
1709 unsigned int size_num
= SIZE_NUM
;
1710 unsigned int i
, k
, loopargs_len
= 0, async_jobs
= 0;
1716 EVP_PKEY_CTX
*genctx
= NULL
;
1721 openssl_speed_sec_t seconds
= { SECONDS
, RSA_SECONDS
, DSA_SECONDS
,
1722 ECDSA_SECONDS
, ECDH_SECONDS
,
1723 EdDSA_SECONDS
, SM2_SECONDS
,
1724 FFDH_SECONDS
, KEM_SECONDS
,
1727 static const unsigned char key32
[32] = {
1728 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1729 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1730 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1731 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1733 static const unsigned char deskey
[] = {
1734 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1735 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1736 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1738 static const struct {
1739 const unsigned char *data
;
1740 unsigned int length
;
1743 { test512
, sizeof(test512
), 512 },
1744 { test1024
, sizeof(test1024
), 1024 },
1745 { test2048
, sizeof(test2048
), 2048 },
1746 { test3072
, sizeof(test3072
), 3072 },
1747 { test4096
, sizeof(test4096
), 4096 },
1748 { test7680
, sizeof(test7680
), 7680 },
1749 { test15360
, sizeof(test15360
), 15360 }
1751 uint8_t rsa_doit
[RSA_NUM
] = { 0 };
1752 int primes
= RSA_DEFAULT_PRIME_NUM
;
1753 #ifndef OPENSSL_NO_DH
1754 typedef struct ffdh_params_st
{
1760 static const FFDH_PARAMS ffdh_params
[FFDH_NUM
] = {
1761 {"ffdh2048", NID_ffdhe2048
, 2048},
1762 {"ffdh3072", NID_ffdhe3072
, 3072},
1763 {"ffdh4096", NID_ffdhe4096
, 4096},
1764 {"ffdh6144", NID_ffdhe6144
, 6144},
1765 {"ffdh8192", NID_ffdhe8192
, 8192}
1767 uint8_t ffdh_doit
[FFDH_NUM
] = { 0 };
1769 #endif /* OPENSSL_NO_DH */
1770 static const unsigned int dsa_bits
[DSA_NUM
] = { 1024, 2048 };
1771 uint8_t dsa_doit
[DSA_NUM
] = { 0 };
1773 * We only test over the following curves as they are representative, To
1774 * add tests over more curves, simply add the curve NID and curve name to
1775 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1776 * lists accordingly.
1778 static const EC_CURVE ec_curves
[EC_NUM
] = {
1780 {"secp160r1", NID_secp160r1
, 160},
1781 {"nistp192", NID_X9_62_prime192v1
, 192},
1782 {"nistp224", NID_secp224r1
, 224},
1783 {"nistp256", NID_X9_62_prime256v1
, 256},
1784 {"nistp384", NID_secp384r1
, 384},
1785 {"nistp521", NID_secp521r1
, 521},
1786 #ifndef OPENSSL_NO_EC2M
1788 {"nistk163", NID_sect163k1
, 163},
1789 {"nistk233", NID_sect233k1
, 233},
1790 {"nistk283", NID_sect283k1
, 283},
1791 {"nistk409", NID_sect409k1
, 409},
1792 {"nistk571", NID_sect571k1
, 571},
1793 {"nistb163", NID_sect163r2
, 163},
1794 {"nistb233", NID_sect233r1
, 233},
1795 {"nistb283", NID_sect283r1
, 283},
1796 {"nistb409", NID_sect409r1
, 409},
1797 {"nistb571", NID_sect571r1
, 571},
1799 {"brainpoolP256r1", NID_brainpoolP256r1
, 256},
1800 {"brainpoolP256t1", NID_brainpoolP256t1
, 256},
1801 {"brainpoolP384r1", NID_brainpoolP384r1
, 384},
1802 {"brainpoolP384t1", NID_brainpoolP384t1
, 384},
1803 {"brainpoolP512r1", NID_brainpoolP512r1
, 512},
1804 {"brainpoolP512t1", NID_brainpoolP512t1
, 512},
1805 #ifndef OPENSSL_NO_ECX
1806 /* Other and ECDH only ones */
1807 {"X25519", NID_X25519
, 253},
1808 {"X448", NID_X448
, 448}
1811 #ifndef OPENSSL_NO_ECX
1812 static const EC_CURVE ed_curves
[EdDSA_NUM
] = {
1814 {"Ed25519", NID_ED25519
, 253, 64},
1815 {"Ed448", NID_ED448
, 456, 114}
1817 #endif /* OPENSSL_NO_ECX */
1818 #ifndef OPENSSL_NO_SM2
1819 static const EC_CURVE sm2_curves
[SM2_NUM
] = {
1821 {"CurveSM2", NID_sm2
, 256}
1823 uint8_t sm2_doit
[SM2_NUM
] = { 0 };
1825 uint8_t ecdsa_doit
[ECDSA_NUM
] = { 0 };
1826 uint8_t ecdh_doit
[EC_NUM
] = { 0 };
1827 #ifndef OPENSSL_NO_ECX
1828 uint8_t eddsa_doit
[EdDSA_NUM
] = { 0 };
1829 #endif /* OPENSSL_NO_ECX */
1831 uint8_t kems_doit
[MAX_KEM_NUM
] = { 0 };
1832 uint8_t sigs_doit
[MAX_SIG_NUM
] = { 0 };
1834 uint8_t do_kems
= 0;
1835 uint8_t do_sigs
= 0;
1837 /* checks declared curves against choices list. */
1838 #ifndef OPENSSL_NO_ECX
1839 OPENSSL_assert(ed_curves
[EdDSA_NUM
- 1].nid
== NID_ED448
);
1840 OPENSSL_assert(strcmp(eddsa_choices
[EdDSA_NUM
- 1].name
, "ed448") == 0);
1842 OPENSSL_assert(ec_curves
[EC_NUM
- 1].nid
== NID_X448
);
1843 OPENSSL_assert(strcmp(ecdh_choices
[EC_NUM
- 1].name
, "ecdhx448") == 0);
1845 OPENSSL_assert(ec_curves
[ECDSA_NUM
- 1].nid
== NID_brainpoolP512t1
);
1846 OPENSSL_assert(strcmp(ecdsa_choices
[ECDSA_NUM
- 1].name
, "ecdsabrp512t1") == 0);
1847 #endif /* OPENSSL_NO_ECX */
1849 #ifndef OPENSSL_NO_SM2
1850 OPENSSL_assert(sm2_curves
[SM2_NUM
- 1].nid
== NID_sm2
);
1851 OPENSSL_assert(strcmp(sm2_choices
[SM2_NUM
- 1].name
, "curveSM2") == 0);
1854 prog
= opt_init(argc
, argv
, speed_options
);
1855 while ((o
= opt_next()) != OPT_EOF
) {
1860 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
1863 opt_help(speed_options
);
1871 BIO_printf(bio_err
, "%s: -evp option cannot be used more than once\n", prog
);
1875 if (!opt_cipher_silent(opt_arg(), &evp_cipher
)) {
1876 if (have_md(opt_arg()))
1877 evp_md_name
= opt_arg();
1879 if (evp_cipher
== NULL
&& evp_md_name
== NULL
) {
1880 ERR_clear_last_mark();
1882 "%s: %s is an unknown cipher or digest\n",
1890 if (!have_md(opt_arg())) {
1891 BIO_printf(bio_err
, "%s: %s is an unknown digest\n",
1895 evp_mac_mdname
= opt_arg();
1899 if (!have_cipher(opt_arg())) {
1900 BIO_printf(bio_err
, "%s: %s is an unknown cipher\n",
1904 evp_mac_ciphername
= opt_arg();
1905 doit
[D_EVP_CMAC
] = 1;
1912 * In a forked execution, an engine might need to be
1913 * initialised by each child process, not by the parent.
1914 * So store the name here and run setup_engine() later on.
1916 engine_id
= opt_arg();
1920 multi
= opt_int_arg();
1921 if ((size_t)multi
>= SIZE_MAX
/ sizeof(int)) {
1922 BIO_printf(bio_err
, "%s: multi argument too large\n", prog
);
1928 #ifndef OPENSSL_NO_ASYNC
1929 async_jobs
= opt_int_arg();
1930 if (!ASYNC_is_capable()) {
1932 "%s: async_jobs specified but async not supported\n",
1936 if (async_jobs
> 99999) {
1937 BIO_printf(bio_err
, "%s: too many async_jobs\n", prog
);
1943 misalign
= opt_int_arg();
1944 if (misalign
> MISALIGN
) {
1946 "%s: Maximum offset is %d\n", prog
, MISALIGN
);
1955 #ifdef OPENSSL_NO_MULTIBLOCK
1957 "%s: -mb specified but multi-block support is disabled\n",
1966 case OPT_PROV_CASES
:
1967 if (!opt_provider(o
))
1971 conf
= app_load_config_modules(opt_arg());
1976 primes
= opt_int_arg();
1979 seconds
.sym
= seconds
.rsa
= seconds
.dsa
= seconds
.ecdsa
1980 = seconds
.ecdh
= seconds
.eddsa
1981 = seconds
.sm2
= seconds
.ffdh
1982 = seconds
.kem
= seconds
.sig
= opt_int_arg();
1985 lengths_single
= opt_int_arg();
1986 lengths
= &lengths_single
;
2000 #if !defined(_WIN32) && !defined(OPENSSL_SYS_LINUX)
2002 "%s: -mlock not supported on this platform\n",
2010 /* find all KEMs currently available */
2011 kem_stack
= sk_EVP_KEM_new(kems_cmp
);
2012 EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem
, kem_stack
);
2016 for (idx
= 0; idx
< (unsigned int)sk_EVP_KEM_num(kem_stack
); idx
++) {
2017 EVP_KEM
*kem
= sk_EVP_KEM_value(kem_stack
, idx
);
2019 if (strcmp(EVP_KEM_get0_name(kem
), "RSA") == 0) {
2020 if (kems_algs_len
+ OSSL_NELEM(rsa_choices
) >= MAX_KEM_NUM
) {
2022 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2025 for (i
= 0; i
< OSSL_NELEM(rsa_choices
); i
++) {
2026 kems_doit
[kems_algs_len
] = 1;
2027 kems_algname
[kems_algs_len
++] = OPENSSL_strdup(rsa_choices
[i
].name
);
2029 } else if (strcmp(EVP_KEM_get0_name(kem
), "EC") == 0) {
2030 if (kems_algs_len
+ 3 >= MAX_KEM_NUM
) {
2032 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2035 kems_doit
[kems_algs_len
] = 1;
2036 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-256");
2037 kems_doit
[kems_algs_len
] = 1;
2038 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-384");
2039 kems_doit
[kems_algs_len
] = 1;
2040 kems_algname
[kems_algs_len
++] = OPENSSL_strdup("ECP-521");
2042 if (kems_algs_len
+ 1 >= MAX_KEM_NUM
) {
2044 "Too many KEMs registered. Change MAX_KEM_NUM.\n");
2047 kems_doit
[kems_algs_len
] = 1;
2048 kems_algname
[kems_algs_len
++] = OPENSSL_strdup(EVP_KEM_get0_name(kem
));
2051 sk_EVP_KEM_pop_free(kem_stack
, EVP_KEM_free
);
2054 /* find all SIGNATUREs currently available */
2055 sig_stack
= sk_EVP_SIGNATURE_new(signatures_cmp
);
2056 EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures
, sig_stack
);
2060 for (idx
= 0; idx
< (unsigned int)sk_EVP_SIGNATURE_num(sig_stack
); idx
++) {
2061 EVP_SIGNATURE
*s
= sk_EVP_SIGNATURE_value(sig_stack
, idx
);
2062 const char *sig_name
= EVP_SIGNATURE_get0_name(s
);
2064 if (strcmp(sig_name
, "RSA") == 0) {
2065 if (sigs_algs_len
+ OSSL_NELEM(rsa_choices
) >= MAX_SIG_NUM
) {
2067 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2070 for (i
= 0; i
< OSSL_NELEM(rsa_choices
); i
++) {
2071 sigs_doit
[sigs_algs_len
] = 1;
2072 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(rsa_choices
[i
].name
);
2075 else if (strcmp(sig_name
, "DSA") == 0) {
2076 if (sigs_algs_len
+ DSA_NUM
>= MAX_SIG_NUM
) {
2078 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2081 for (i
= 0; i
< DSA_NUM
; i
++) {
2082 sigs_doit
[sigs_algs_len
] = 1;
2083 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(dsa_choices
[i
].name
);
2086 /* skipping these algs as tested elsewhere - and b/o setup is a pain */
2087 else if (strcmp(sig_name
, "ED25519") &&
2088 strcmp(sig_name
, "ED448") &&
2089 strcmp(sig_name
, "ECDSA") &&
2090 strcmp(sig_name
, "HMAC") &&
2091 strcmp(sig_name
, "SIPHASH") &&
2092 strcmp(sig_name
, "POLY1305") &&
2093 strcmp(sig_name
, "CMAC") &&
2094 strcmp(sig_name
, "SM2")) { /* skip alg */
2095 if (sigs_algs_len
+ 1 >= MAX_SIG_NUM
) {
2097 "Too many signatures registered. Change MAX_SIG_NUM.\n");
2100 /* activate this provider algorithm */
2101 sigs_doit
[sigs_algs_len
] = 1;
2102 sigs_algname
[sigs_algs_len
++] = OPENSSL_strdup(sig_name
);
2105 sk_EVP_SIGNATURE_pop_free(sig_stack
, EVP_SIGNATURE_free
);
2108 /* Remaining arguments are algorithms. */
2109 argc
= opt_num_rest();
2112 if (!app_RAND_load())
2115 for (; *argv
; argv
++) {
2116 const char *algo
= *argv
;
2119 if (opt_found(algo
, doit_choices
, &i
)) {
2123 if (strcmp(algo
, "des") == 0) {
2124 doit
[D_CBC_DES
] = doit
[D_EDE3_DES
] = 1;
2127 if (strcmp(algo
, "sha") == 0) {
2128 doit
[D_SHA1
] = doit
[D_SHA256
] = doit
[D_SHA512
] = 1;
2131 #ifndef OPENSSL_NO_DEPRECATED_3_0
2132 if (strcmp(algo
, "openssl") == 0) /* just for compatibility */
2135 if (HAS_PREFIX(algo
, "rsa")) {
2136 if (algo
[sizeof("rsa") - 1] == '\0') {
2137 memset(rsa_doit
, 1, sizeof(rsa_doit
));
2140 if (opt_found(algo
, rsa_choices
, &i
)) {
2145 #ifndef OPENSSL_NO_DH
2146 if (HAS_PREFIX(algo
, "ffdh")) {
2147 if (algo
[sizeof("ffdh") - 1] == '\0') {
2148 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
2151 if (opt_found(algo
, ffdh_choices
, &i
)) {
2157 if (HAS_PREFIX(algo
, "dsa")) {
2158 if (algo
[sizeof("dsa") - 1] == '\0') {
2159 memset(dsa_doit
, 1, sizeof(dsa_doit
));
2162 if (opt_found(algo
, dsa_choices
, &i
)) {
2167 if (strcmp(algo
, "aes") == 0) {
2168 doit
[D_CBC_128_AES
] = doit
[D_CBC_192_AES
] = doit
[D_CBC_256_AES
] = 1;
2171 if (strcmp(algo
, "camellia") == 0) {
2172 doit
[D_CBC_128_CML
] = doit
[D_CBC_192_CML
] = doit
[D_CBC_256_CML
] = 1;
2175 if (HAS_PREFIX(algo
, "ecdsa")) {
2176 if (algo
[sizeof("ecdsa") - 1] == '\0') {
2177 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
2180 if (opt_found(algo
, ecdsa_choices
, &i
)) {
2185 if (HAS_PREFIX(algo
, "ecdh")) {
2186 if (algo
[sizeof("ecdh") - 1] == '\0') {
2187 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
2190 if (opt_found(algo
, ecdh_choices
, &i
)) {
2195 #ifndef OPENSSL_NO_ECX
2196 if (strcmp(algo
, "eddsa") == 0) {
2197 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
2200 if (opt_found(algo
, eddsa_choices
, &i
)) {
2204 #endif /* OPENSSL_NO_ECX */
2205 #ifndef OPENSSL_NO_SM2
2206 if (strcmp(algo
, "sm2") == 0) {
2207 memset(sm2_doit
, 1, sizeof(sm2_doit
));
2210 if (opt_found(algo
, sm2_choices
, &i
)) {
2215 if (kem_locate(algo
, &idx
)) {
2220 if (sig_locate(algo
, &idx
)) {
2227 BIO_printf(bio_err
, "%s: Unknown algorithm %s\n", prog
, algo
);
2234 if (evp_cipher
== NULL
) {
2235 BIO_printf(bio_err
, "-aead can be used only with an AEAD cipher\n");
2237 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
2238 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2239 BIO_printf(bio_err
, "%s is not an AEAD cipher\n",
2240 EVP_CIPHER_get0_name(evp_cipher
));
2244 if (kems_algs_len
> 0) {
2245 int maxcnt
= get_max(kems_doit
, kems_algs_len
);
2248 /* some algs explicitly selected */
2249 for (i
= 0; i
< kems_algs_len
; i
++) {
2250 /* disable the rest */
2255 if (sigs_algs_len
> 0) {
2256 int maxcnt
= get_max(sigs_doit
, sigs_algs_len
);
2259 /* some algs explicitly selected */
2260 for (i
= 0; i
< sigs_algs_len
; i
++) {
2261 /* disable the rest */
2267 if (evp_cipher
== NULL
) {
2268 BIO_printf(bio_err
, "-mb can be used only with a multi-block"
2269 " capable cipher\n");
2271 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
2272 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2273 BIO_printf(bio_err
, "%s is not a multi-block capable\n",
2274 EVP_CIPHER_get0_name(evp_cipher
));
2276 } else if (async_jobs
> 0) {
2277 BIO_printf(bio_err
, "Async mode is not supported with -mb");
2282 /* Initialize the job pool if async mode is enabled */
2283 if (async_jobs
> 0) {
2284 async_init
= ASYNC_init_thread(async_jobs
, async_jobs
);
2286 BIO_printf(bio_err
, "Error creating the ASYNC job pool\n");
2291 loopargs_len
= (async_jobs
== 0 ? 1 : async_jobs
);
2293 app_malloc(loopargs_len
* sizeof(loopargs_t
), "array of loopargs");
2294 memset(loopargs
, 0, loopargs_len
* sizeof(loopargs_t
));
2296 buflen
= lengths
[size_num
- 1];
2297 if (buflen
< 36) /* size of random vector in RSA benchmark */
2299 if (INT_MAX
- (MAX_MISALIGNMENT
+ 1) < buflen
) {
2300 BIO_printf(bio_err
, "Error: buffer size too large\n");
2303 buflen
+= MAX_MISALIGNMENT
+ 1;
2304 for (i
= 0; i
< loopargs_len
; i
++) {
2305 if (async_jobs
> 0) {
2306 loopargs
[i
].wait_ctx
= ASYNC_WAIT_CTX_new();
2307 if (loopargs
[i
].wait_ctx
== NULL
) {
2308 BIO_printf(bio_err
, "Error creating the ASYNC_WAIT_CTX\n");
2313 loopargs
[i
].buf_malloc
= app_malloc(buflen
, "input buffer");
2314 loopargs
[i
].buf2_malloc
= app_malloc(buflen
, "input buffer");
2316 /* Align the start of buffers on a 64 byte boundary */
2317 loopargs
[i
].buf
= loopargs
[i
].buf_malloc
+ misalign
;
2318 loopargs
[i
].buf2
= loopargs
[i
].buf2_malloc
+ misalign
;
2319 loopargs
[i
].buflen
= buflen
- misalign
;
2320 loopargs
[i
].sigsize
= buflen
- misalign
;
2321 loopargs
[i
].secret_a
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret a");
2322 loopargs
[i
].secret_b
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret b");
2323 #ifndef OPENSSL_NO_DH
2324 loopargs
[i
].secret_ff_a
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret a");
2325 loopargs
[i
].secret_ff_b
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret b");
2330 if (multi
&& do_multi(multi
, size_num
))
2334 for (i
= 0; i
< loopargs_len
; ++i
) {
2337 (void)VirtualLock(loopargs
[i
].buf_malloc
, buflen
);
2338 (void)VirtualLock(loopargs
[i
].buf2_malloc
, buflen
);
2339 #elif defined(OPENSSL_SYS_LINUX)
2340 (void)mlock(loopargs
[i
].buf_malloc
, buflen
);
2341 (void)mlock(loopargs
[i
].buf_malloc
, buflen
);
2344 memset(loopargs
[i
].buf_malloc
, 0, buflen
);
2345 memset(loopargs
[i
].buf2_malloc
, 0, buflen
);
2348 /* Initialize the engine after the fork */
2349 e
= setup_engine(engine_id
, 0);
2351 /* No parameters; turn on everything. */
2352 if (argc
== 0 && !doit
[D_EVP
] && !doit
[D_HMAC
]
2353 && !doit
[D_EVP_CMAC
] && !do_kems
&& !do_sigs
) {
2354 memset(doit
, 1, sizeof(doit
));
2355 doit
[D_EVP
] = doit
[D_EVP_CMAC
] = 0;
2357 for (i
= D_MD2
; i
<= D_WHIRLPOOL
; i
++) {
2358 if (!have_md(names
[i
]))
2361 for (i
= D_CBC_DES
; i
<= D_CBC_256_CML
; i
++) {
2362 if (!have_cipher(names
[i
]))
2365 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC",
2366 app_get0_propq())) != NULL
) {
2372 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC",
2373 app_get0_propq())) != NULL
) {
2380 memset(rsa_doit
, 1, sizeof(rsa_doit
));
2381 #ifndef OPENSSL_NO_DH
2382 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
2384 memset(dsa_doit
, 1, sizeof(dsa_doit
));
2385 #ifndef OPENSSL_NO_ECX
2386 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
2387 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
2388 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
2389 #endif /* OPENSSL_NO_ECX */
2390 #ifndef OPENSSL_NO_SM2
2391 memset(sm2_doit
, 1, sizeof(sm2_doit
));
2393 memset(kems_doit
, 1, sizeof(kems_doit
));
2395 memset(sigs_doit
, 1, sizeof(sigs_doit
));
2398 for (i
= 0; i
< ALGOR_NUM
; i
++)
2402 if (usertime
== 0 && !mr
)
2404 "You have chosen to measure elapsed time "
2405 "instead of user CPU time.\n");
2408 signal(SIGALRM
, alarmed
);
2412 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2413 print_message(names
[D_MD2
], lengths
[testnum
], seconds
.sym
);
2415 count
= run_benchmark(async_jobs
, EVP_Digest_MD2_loop
, loopargs
);
2417 print_result(D_MD2
, testnum
, count
, d
);
2424 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2425 print_message(names
[D_MDC2
], lengths
[testnum
], seconds
.sym
);
2427 count
= run_benchmark(async_jobs
, EVP_Digest_MDC2_loop
, loopargs
);
2429 print_result(D_MDC2
, testnum
, count
, d
);
2436 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2437 print_message(names
[D_MD4
], lengths
[testnum
], seconds
.sym
);
2439 count
= run_benchmark(async_jobs
, EVP_Digest_MD4_loop
, loopargs
);
2441 print_result(D_MD4
, testnum
, count
, d
);
2448 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2449 print_message(names
[D_MD5
], lengths
[testnum
], seconds
.sym
);
2451 count
= run_benchmark(async_jobs
, MD5_loop
, loopargs
);
2453 print_result(D_MD5
, testnum
, count
, d
);
2460 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2461 print_message(names
[D_SHA1
], lengths
[testnum
], seconds
.sym
);
2463 count
= run_benchmark(async_jobs
, SHA1_loop
, loopargs
);
2465 print_result(D_SHA1
, testnum
, count
, d
);
2471 if (doit
[D_SHA256
]) {
2472 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2473 print_message(names
[D_SHA256
], lengths
[testnum
], seconds
.sym
);
2475 count
= run_benchmark(async_jobs
, SHA256_loop
, loopargs
);
2477 print_result(D_SHA256
, testnum
, count
, d
);
2483 if (doit
[D_SHA512
]) {
2484 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2485 print_message(names
[D_SHA512
], lengths
[testnum
], seconds
.sym
);
2487 count
= run_benchmark(async_jobs
, SHA512_loop
, loopargs
);
2489 print_result(D_SHA512
, testnum
, count
, d
);
2495 if (doit
[D_WHIRLPOOL
]) {
2496 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2497 print_message(names
[D_WHIRLPOOL
], lengths
[testnum
], seconds
.sym
);
2499 count
= run_benchmark(async_jobs
, WHIRLPOOL_loop
, loopargs
);
2501 print_result(D_WHIRLPOOL
, testnum
, count
, d
);
2507 if (doit
[D_RMD160
]) {
2508 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2509 print_message(names
[D_RMD160
], lengths
[testnum
], seconds
.sym
);
2511 count
= run_benchmark(async_jobs
, EVP_Digest_RMD160_loop
, loopargs
);
2513 print_result(D_RMD160
, testnum
, count
, d
);
2520 static const char hmac_key
[] = "This is a key...";
2521 int len
= strlen(hmac_key
);
2522 OSSL_PARAM params
[3];
2524 mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
2525 if (mac
== NULL
|| evp_mac_mdname
== NULL
)
2528 evp_hmac_name
= app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname
),
2530 sprintf(evp_hmac_name
, "hmac(%s)", evp_mac_mdname
);
2531 names
[D_HMAC
] = evp_hmac_name
;
2534 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
2537 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2538 (char *)hmac_key
, len
);
2539 params
[2] = OSSL_PARAM_construct_end();
2541 for (i
= 0; i
< loopargs_len
; i
++) {
2542 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2543 if (loopargs
[i
].mctx
== NULL
)
2546 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2547 goto skip_hmac
; /* Digest not found */
2549 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2550 print_message(names
[D_HMAC
], lengths
[testnum
], seconds
.sym
);
2552 count
= run_benchmark(async_jobs
, HMAC_loop
, loopargs
);
2554 print_result(D_HMAC
, testnum
, count
, d
);
2558 for (i
= 0; i
< loopargs_len
; i
++)
2559 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2564 if (doit
[D_CBC_DES
]) {
2567 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2568 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-cbc", deskey
,
2569 sizeof(deskey
) / 3);
2570 st
= loopargs
[i
].ctx
!= NULL
;
2572 algindex
= D_CBC_DES
;
2573 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2574 print_message(names
[D_CBC_DES
], lengths
[testnum
], seconds
.sym
);
2576 count
= run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2578 print_result(D_CBC_DES
, testnum
, count
, d
);
2580 for (i
= 0; i
< loopargs_len
; i
++)
2581 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2584 if (doit
[D_EDE3_DES
]) {
2587 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2588 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-ede3-cbc", deskey
,
2590 st
= loopargs
[i
].ctx
!= NULL
;
2592 algindex
= D_EDE3_DES
;
2593 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2594 print_message(names
[D_EDE3_DES
], lengths
[testnum
], seconds
.sym
);
2597 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2599 print_result(D_EDE3_DES
, testnum
, count
, d
);
2601 for (i
= 0; i
< loopargs_len
; i
++)
2602 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2605 for (k
= 0; k
< 3; k
++) {
2606 algindex
= D_CBC_128_AES
+ k
;
2607 if (doit
[algindex
]) {
2610 keylen
= 16 + k
* 8;
2611 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2612 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2614 st
= loopargs
[i
].ctx
!= NULL
;
2617 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2618 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2621 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2623 print_result(algindex
, testnum
, count
, d
);
2625 for (i
= 0; i
< loopargs_len
; i
++)
2626 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2630 for (k
= 0; k
< 3; k
++) {
2631 algindex
= D_CBC_128_CML
+ k
;
2632 if (doit
[algindex
]) {
2635 keylen
= 16 + k
* 8;
2636 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2637 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2639 st
= loopargs
[i
].ctx
!= NULL
;
2642 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2643 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2646 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2648 print_result(algindex
, testnum
, count
, d
);
2650 for (i
= 0; i
< loopargs_len
; i
++)
2651 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2655 for (algindex
= D_RC4
; algindex
<= D_CBC_CAST
; algindex
++) {
2656 if (doit
[algindex
]) {
2660 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2661 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2663 st
= loopargs
[i
].ctx
!= NULL
;
2666 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2667 print_message(names
[algindex
], lengths
[testnum
], seconds
.sym
);
2670 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2672 print_result(algindex
, testnum
, count
, d
);
2674 for (i
= 0; i
< loopargs_len
; i
++)
2675 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2678 if (doit
[D_GHASH
]) {
2679 static const char gmac_iv
[] = "0123456789ab";
2680 OSSL_PARAM params
[3];
2682 mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2686 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2688 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV
,
2690 sizeof(gmac_iv
) - 1);
2691 params
[2] = OSSL_PARAM_construct_end();
2693 for (i
= 0; i
< loopargs_len
; i
++) {
2694 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2695 if (loopargs
[i
].mctx
== NULL
)
2698 if (!EVP_MAC_init(loopargs
[i
].mctx
, key32
, 16, params
))
2701 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2702 print_message(names
[D_GHASH
], lengths
[testnum
], seconds
.sym
);
2704 count
= run_benchmark(async_jobs
, GHASH_loop
, loopargs
);
2706 print_result(D_GHASH
, testnum
, count
, d
);
2710 for (i
= 0; i
< loopargs_len
; i
++)
2711 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2717 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2718 print_message(names
[D_RAND
], lengths
[testnum
], seconds
.sym
);
2720 count
= run_benchmark(async_jobs
, RAND_bytes_loop
, loopargs
);
2722 print_result(D_RAND
, testnum
, count
, d
);
2727 if (evp_cipher
!= NULL
) {
2728 int (*loopfunc
) (void *) = EVP_Update_loop
;
2730 if (multiblock
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2731 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2732 multiblock_speed(evp_cipher
, lengths_single
, &seconds
);
2737 names
[D_EVP
] = EVP_CIPHER_get0_name(evp_cipher
);
2739 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_CCM_MODE
) {
2740 loopfunc
= EVP_Update_loop_ccm
;
2741 } else if (aead
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2742 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2743 loopfunc
= EVP_Update_loop_aead
;
2744 if (lengths
== lengths_list
) {
2745 lengths
= aead_lengths_list
;
2746 size_num
= OSSL_NELEM(aead_lengths_list
);
2750 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2751 print_message(names
[D_EVP
], lengths
[testnum
], seconds
.sym
);
2753 for (k
= 0; k
< loopargs_len
; k
++) {
2754 loopargs
[k
].ctx
= EVP_CIPHER_CTX_new();
2755 if (loopargs
[k
].ctx
== NULL
) {
2756 BIO_printf(bio_err
, "\nEVP_CIPHER_CTX_new failure\n");
2759 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, evp_cipher
, NULL
,
2760 NULL
, iv
, decrypt
? 0 : 1)) {
2761 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2762 ERR_print_errors(bio_err
);
2766 EVP_CIPHER_CTX_set_padding(loopargs
[k
].ctx
, 0);
2768 keylen
= EVP_CIPHER_CTX_get_key_length(loopargs
[k
].ctx
);
2769 loopargs
[k
].key
= app_malloc(keylen
, "evp_cipher key");
2770 EVP_CIPHER_CTX_rand_key(loopargs
[k
].ctx
, loopargs
[k
].key
);
2771 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, NULL
, NULL
,
2772 loopargs
[k
].key
, NULL
, -1)) {
2773 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2774 ERR_print_errors(bio_err
);
2777 OPENSSL_clear_free(loopargs
[k
].key
, keylen
);
2779 /* GCM-SIV/SIV mode only allows for a single Update operation */
2780 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_SIV_MODE
2781 || EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_GCM_SIV_MODE
)
2782 (void)EVP_CIPHER_CTX_ctrl(loopargs
[k
].ctx
,
2783 EVP_CTRL_SET_SPEED
, 1, NULL
);
2787 count
= run_benchmark(async_jobs
, loopfunc
, loopargs
);
2789 for (k
= 0; k
< loopargs_len
; k
++)
2790 EVP_CIPHER_CTX_free(loopargs
[k
].ctx
);
2791 print_result(D_EVP
, testnum
, count
, d
);
2793 } else if (evp_md_name
!= NULL
) {
2794 names
[D_EVP
] = evp_md_name
;
2796 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2797 print_message(names
[D_EVP
], lengths
[testnum
], seconds
.sym
);
2799 count
= run_benchmark(async_jobs
, EVP_Digest_md_loop
, loopargs
);
2801 print_result(D_EVP
, testnum
, count
, d
);
2808 if (doit
[D_EVP_CMAC
]) {
2809 OSSL_PARAM params
[3];
2810 EVP_CIPHER
*cipher
= NULL
;
2812 mac
= EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2813 if (mac
== NULL
|| evp_mac_ciphername
== NULL
)
2815 if (!opt_cipher(evp_mac_ciphername
, &cipher
))
2818 keylen
= EVP_CIPHER_get_key_length(cipher
);
2819 EVP_CIPHER_free(cipher
);
2820 if (keylen
<= 0 || keylen
> (int)sizeof(key32
)) {
2821 BIO_printf(bio_err
, "\nRequested CMAC cipher with unsupported key length.\n");
2824 evp_cmac_name
= app_malloc(sizeof("cmac()")
2825 + strlen(evp_mac_ciphername
), "CMAC name");
2826 sprintf(evp_cmac_name
, "cmac(%s)", evp_mac_ciphername
);
2827 names
[D_EVP_CMAC
] = evp_cmac_name
;
2829 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2830 evp_mac_ciphername
, 0);
2831 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2832 (char *)key32
, keylen
);
2833 params
[2] = OSSL_PARAM_construct_end();
2835 for (i
= 0; i
< loopargs_len
; i
++) {
2836 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2837 if (loopargs
[i
].mctx
== NULL
)
2840 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2844 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2845 print_message(names
[D_EVP_CMAC
], lengths
[testnum
], seconds
.sym
);
2847 count
= run_benchmark(async_jobs
, CMAC_loop
, loopargs
);
2849 print_result(D_EVP_CMAC
, testnum
, count
, d
);
2853 for (i
= 0; i
< loopargs_len
; i
++)
2854 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2859 for (i
= 0; i
< loopargs_len
; i
++)
2860 if (RAND_bytes(loopargs
[i
].buf
, 36) <= 0)
2863 for (testnum
= 0; testnum
< RSA_NUM
; testnum
++) {
2864 EVP_PKEY
*rsa_key
= NULL
;
2867 if (!rsa_doit
[testnum
])
2870 if (primes
> RSA_DEFAULT_PRIME_NUM
) {
2871 /* we haven't set keys yet, generate multi-prime RSA keys */
2874 && BN_set_word(bn
, RSA_F4
)
2875 && init_gen_str(&genctx
, "RSA", NULL
, 0, NULL
, NULL
)
2876 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx
, rsa_keys
[testnum
].bits
) > 0
2877 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx
, bn
) > 0
2878 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx
, primes
) > 0
2879 && EVP_PKEY_keygen(genctx
, &rsa_key
);
2882 EVP_PKEY_CTX_free(genctx
);
2885 const unsigned char *p
= rsa_keys
[testnum
].data
;
2887 st
= (rsa_key
= d2i_PrivateKey(EVP_PKEY_RSA
, NULL
, &p
,
2888 rsa_keys
[testnum
].length
)) != NULL
;
2891 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2892 loopargs
[i
].rsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2893 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2894 if (loopargs
[i
].rsa_sign_ctx
[testnum
] == NULL
2895 || EVP_PKEY_sign_init(loopargs
[i
].rsa_sign_ctx
[testnum
]) <= 0
2896 || EVP_PKEY_sign(loopargs
[i
].rsa_sign_ctx
[testnum
],
2898 &loopargs
[i
].sigsize
,
2899 loopargs
[i
].buf
, 36) <= 0)
2904 "RSA sign setup failure. No RSA sign will be done.\n");
2905 ERR_print_errors(bio_err
);
2908 pkey_print_message("private", "rsa sign",
2909 rsa_keys
[testnum
].bits
, seconds
.rsa
);
2910 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2912 count
= run_benchmark(async_jobs
, RSA_sign_loop
, loopargs
);
2915 mr
? "+R1:%ld:%d:%.2f\n"
2916 : "%ld %u bits private RSA sign ops in %.2fs\n",
2917 count
, rsa_keys
[testnum
].bits
, d
);
2918 rsa_results
[testnum
][0] = (double)count
/ d
;
2922 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2923 loopargs
[i
].rsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
,
2925 if (loopargs
[i
].rsa_verify_ctx
[testnum
] == NULL
2926 || EVP_PKEY_verify_init(loopargs
[i
].rsa_verify_ctx
[testnum
]) <= 0
2927 || EVP_PKEY_verify(loopargs
[i
].rsa_verify_ctx
[testnum
],
2929 loopargs
[i
].sigsize
,
2930 loopargs
[i
].buf
, 36) <= 0)
2935 "RSA verify setup failure. No RSA verify will be done.\n");
2936 ERR_print_errors(bio_err
);
2937 rsa_doit
[testnum
] = 0;
2939 pkey_print_message("public", "rsa verify",
2940 rsa_keys
[testnum
].bits
, seconds
.rsa
);
2942 count
= run_benchmark(async_jobs
, RSA_verify_loop
, loopargs
);
2945 mr
? "+R2:%ld:%d:%.2f\n"
2946 : "%ld %u bits public RSA verify ops in %.2fs\n",
2947 count
, rsa_keys
[testnum
].bits
, d
);
2948 rsa_results
[testnum
][1] = (double)count
/ d
;
2951 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2952 loopargs
[i
].rsa_encrypt_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2953 loopargs
[i
].encsize
= loopargs
[i
].buflen
;
2954 if (loopargs
[i
].rsa_encrypt_ctx
[testnum
] == NULL
2955 || EVP_PKEY_encrypt_init(loopargs
[i
].rsa_encrypt_ctx
[testnum
]) <= 0
2956 || EVP_PKEY_encrypt(loopargs
[i
].rsa_encrypt_ctx
[testnum
],
2958 &loopargs
[i
].encsize
,
2959 loopargs
[i
].buf
, 36) <= 0)
2964 "RSA encrypt setup failure. No RSA encrypt will be done.\n");
2965 ERR_print_errors(bio_err
);
2968 pkey_print_message("private", "rsa encrypt",
2969 rsa_keys
[testnum
].bits
, seconds
.rsa
);
2970 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2972 count
= run_benchmark(async_jobs
, RSA_encrypt_loop
, loopargs
);
2975 mr
? "+R3:%ld:%d:%.2f\n"
2976 : "%ld %u bits public RSA encrypt ops in %.2fs\n",
2977 count
, rsa_keys
[testnum
].bits
, d
);
2978 rsa_results
[testnum
][2] = (double)count
/ d
;
2982 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2983 loopargs
[i
].rsa_decrypt_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2984 declen
= loopargs
[i
].buflen
;
2985 if (loopargs
[i
].rsa_decrypt_ctx
[testnum
] == NULL
2986 || EVP_PKEY_decrypt_init(loopargs
[i
].rsa_decrypt_ctx
[testnum
]) <= 0
2987 || EVP_PKEY_decrypt(loopargs
[i
].rsa_decrypt_ctx
[testnum
],
2991 loopargs
[i
].encsize
) <= 0)
2996 "RSA decrypt setup failure. No RSA decrypt will be done.\n");
2997 ERR_print_errors(bio_err
);
3000 pkey_print_message("private", "rsa decrypt",
3001 rsa_keys
[testnum
].bits
, seconds
.rsa
);
3002 /* RSA_blinding_on(rsa_key[testnum],NULL); */
3004 count
= run_benchmark(async_jobs
, RSA_decrypt_loop
, loopargs
);
3007 mr
? "+R4:%ld:%d:%.2f\n"
3008 : "%ld %u bits private RSA decrypt ops in %.2fs\n",
3009 count
, rsa_keys
[testnum
].bits
, d
);
3010 rsa_results
[testnum
][3] = (double)count
/ d
;
3014 if (op_count
<= 1) {
3015 /* if longer than 10s, don't do any more */
3016 stop_it(rsa_doit
, testnum
);
3018 EVP_PKEY_free(rsa_key
);
3021 for (testnum
= 0; testnum
< DSA_NUM
; testnum
++) {
3022 EVP_PKEY
*dsa_key
= NULL
;
3025 if (!dsa_doit
[testnum
])
3028 st
= (dsa_key
= get_dsa(dsa_bits
[testnum
])) != NULL
;
3030 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
3031 loopargs
[i
].dsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
3033 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
3034 if (loopargs
[i
].dsa_sign_ctx
[testnum
] == NULL
3035 || EVP_PKEY_sign_init(loopargs
[i
].dsa_sign_ctx
[testnum
]) <= 0
3037 || EVP_PKEY_sign(loopargs
[i
].dsa_sign_ctx
[testnum
],
3039 &loopargs
[i
].sigsize
,
3040 loopargs
[i
].buf
, 20) <= 0)
3045 "DSA sign setup failure. No DSA sign will be done.\n");
3046 ERR_print_errors(bio_err
);
3049 pkey_print_message("sign", "dsa",
3050 dsa_bits
[testnum
], seconds
.dsa
);
3052 count
= run_benchmark(async_jobs
, DSA_sign_loop
, loopargs
);
3055 mr
? "+R5:%ld:%u:%.2f\n"
3056 : "%ld %u bits DSA sign ops in %.2fs\n",
3057 count
, dsa_bits
[testnum
], d
);
3058 dsa_results
[testnum
][0] = (double)count
/ d
;
3062 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
3063 loopargs
[i
].dsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
3065 if (loopargs
[i
].dsa_verify_ctx
[testnum
] == NULL
3066 || EVP_PKEY_verify_init(loopargs
[i
].dsa_verify_ctx
[testnum
]) <= 0
3067 || EVP_PKEY_verify(loopargs
[i
].dsa_verify_ctx
[testnum
],
3069 loopargs
[i
].sigsize
,
3070 loopargs
[i
].buf
, 36) <= 0)
3075 "DSA verify setup failure. No DSA verify will be done.\n");
3076 ERR_print_errors(bio_err
);
3077 dsa_doit
[testnum
] = 0;
3079 pkey_print_message("verify", "dsa",
3080 dsa_bits
[testnum
], seconds
.dsa
);
3082 count
= run_benchmark(async_jobs
, DSA_verify_loop
, loopargs
);
3085 mr
? "+R6:%ld:%u:%.2f\n"
3086 : "%ld %u bits DSA verify ops in %.2fs\n",
3087 count
, dsa_bits
[testnum
], d
);
3088 dsa_results
[testnum
][1] = (double)count
/ d
;
3091 if (op_count
<= 1) {
3092 /* if longer than 10s, don't do any more */
3093 stop_it(dsa_doit
, testnum
);
3095 EVP_PKEY_free(dsa_key
);
3098 for (testnum
= 0; testnum
< ECDSA_NUM
; testnum
++) {
3099 EVP_PKEY
*ecdsa_key
= NULL
;
3102 if (!ecdsa_doit
[testnum
])
3105 st
= (ecdsa_key
= get_ecdsa(&ec_curves
[testnum
])) != NULL
;
3107 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
3108 loopargs
[i
].ecdsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
3110 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
3111 if (loopargs
[i
].ecdsa_sign_ctx
[testnum
] == NULL
3112 || EVP_PKEY_sign_init(loopargs
[i
].ecdsa_sign_ctx
[testnum
]) <= 0
3114 || EVP_PKEY_sign(loopargs
[i
].ecdsa_sign_ctx
[testnum
],
3116 &loopargs
[i
].sigsize
,
3117 loopargs
[i
].buf
, 20) <= 0)
3122 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
3123 ERR_print_errors(bio_err
);
3126 pkey_print_message("sign", "ecdsa",
3127 ec_curves
[testnum
].bits
, seconds
.ecdsa
);
3129 count
= run_benchmark(async_jobs
, ECDSA_sign_loop
, loopargs
);
3132 mr
? "+R7:%ld:%u:%.2f\n"
3133 : "%ld %u bits ECDSA sign ops in %.2fs\n",
3134 count
, ec_curves
[testnum
].bits
, d
);
3135 ecdsa_results
[testnum
][0] = (double)count
/ d
;
3139 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
3140 loopargs
[i
].ecdsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
3142 if (loopargs
[i
].ecdsa_verify_ctx
[testnum
] == NULL
3143 || EVP_PKEY_verify_init(loopargs
[i
].ecdsa_verify_ctx
[testnum
]) <= 0
3144 || EVP_PKEY_verify(loopargs
[i
].ecdsa_verify_ctx
[testnum
],
3146 loopargs
[i
].sigsize
,
3147 loopargs
[i
].buf
, 20) <= 0)
3152 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
3153 ERR_print_errors(bio_err
);
3154 ecdsa_doit
[testnum
] = 0;
3156 pkey_print_message("verify", "ecdsa",
3157 ec_curves
[testnum
].bits
, seconds
.ecdsa
);
3159 count
= run_benchmark(async_jobs
, ECDSA_verify_loop
, loopargs
);
3162 mr
? "+R8:%ld:%u:%.2f\n"
3163 : "%ld %u bits ECDSA verify ops in %.2fs\n",
3164 count
, ec_curves
[testnum
].bits
, d
);
3165 ecdsa_results
[testnum
][1] = (double)count
/ d
;
3168 if (op_count
<= 1) {
3169 /* if longer than 10s, don't do any more */
3170 stop_it(ecdsa_doit
, testnum
);
3174 for (testnum
= 0; testnum
< EC_NUM
; testnum
++) {
3175 int ecdh_checks
= 1;
3177 if (!ecdh_doit
[testnum
])
3180 for (i
= 0; i
< loopargs_len
; i
++) {
3181 EVP_PKEY_CTX
*test_ctx
= NULL
;
3182 EVP_PKEY_CTX
*ctx
= NULL
;
3183 EVP_PKEY
*key_A
= NULL
;
3184 EVP_PKEY
*key_B
= NULL
;
3188 if ((key_A
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key A */
3189 || (key_B
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key B */
3190 || (ctx
= EVP_PKEY_CTX_new(key_A
, NULL
)) == NULL
/* derivation ctx from skeyA */
3191 || EVP_PKEY_derive_init(ctx
) <= 0 /* init derivation ctx */
3192 || EVP_PKEY_derive_set_peer(ctx
, key_B
) <= 0 /* set peer pubkey in ctx */
3193 || EVP_PKEY_derive(ctx
, NULL
, &outlen
) <= 0 /* determine max length */
3194 || outlen
== 0 /* ensure outlen is a valid size */
3195 || outlen
> MAX_ECDH_SIZE
/* avoid buffer overflow */) {
3197 BIO_printf(bio_err
, "ECDH key generation failure.\n");
3198 ERR_print_errors(bio_err
);
3204 * Here we perform a test run, comparing the output of a*B and b*A;
3205 * we try this here and assume that further EVP_PKEY_derive calls
3206 * never fail, so we can skip checks in the actually benchmarked
3207 * code, for maximum performance.
3209 if ((test_ctx
= EVP_PKEY_CTX_new(key_B
, NULL
)) == NULL
/* test ctx from skeyB */
3210 || EVP_PKEY_derive_init(test_ctx
) <= 0 /* init derivation test_ctx */
3211 || EVP_PKEY_derive_set_peer(test_ctx
, key_A
) <= 0 /* set peer pubkey in test_ctx */
3212 || EVP_PKEY_derive(test_ctx
, NULL
, &test_outlen
) <= 0 /* determine max length */
3213 || EVP_PKEY_derive(ctx
, loopargs
[i
].secret_a
, &outlen
) <= 0 /* compute a*B */
3214 || EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_b
, &test_outlen
) <= 0 /* compute b*A */
3215 || test_outlen
!= outlen
/* compare output length */) {
3217 BIO_printf(bio_err
, "ECDH computation failure.\n");
3218 ERR_print_errors(bio_err
);
3223 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
3224 if (CRYPTO_memcmp(loopargs
[i
].secret_a
,
3225 loopargs
[i
].secret_b
, outlen
)) {
3227 BIO_printf(bio_err
, "ECDH computations don't match.\n");
3228 ERR_print_errors(bio_err
);
3233 loopargs
[i
].ecdh_ctx
[testnum
] = ctx
;
3234 loopargs
[i
].outlen
[testnum
] = outlen
;
3236 EVP_PKEY_free(key_A
);
3237 EVP_PKEY_free(key_B
);
3238 EVP_PKEY_CTX_free(test_ctx
);
3241 if (ecdh_checks
!= 0) {
3242 pkey_print_message("", "ecdh",
3243 ec_curves
[testnum
].bits
, seconds
.ecdh
);
3246 run_benchmark(async_jobs
, ECDH_EVP_derive_key_loop
, loopargs
);
3249 mr
? "+R9:%ld:%d:%.2f\n" :
3250 "%ld %u-bits ECDH ops in %.2fs\n", count
,
3251 ec_curves
[testnum
].bits
, d
);
3252 ecdh_results
[testnum
][0] = (double)count
/ d
;
3256 if (op_count
<= 1) {
3257 /* if longer than 10s, don't do any more */
3258 stop_it(ecdh_doit
, testnum
);
3262 #ifndef OPENSSL_NO_ECX
3263 for (testnum
= 0; testnum
< EdDSA_NUM
; testnum
++) {
3265 EVP_PKEY
*ed_pkey
= NULL
;
3266 EVP_PKEY_CTX
*ed_pctx
= NULL
;
3268 if (!eddsa_doit
[testnum
])
3269 continue; /* Ignore Curve */
3270 for (i
= 0; i
< loopargs_len
; i
++) {
3271 loopargs
[i
].eddsa_ctx
[testnum
] = EVP_MD_CTX_new();
3272 if (loopargs
[i
].eddsa_ctx
[testnum
] == NULL
) {
3276 loopargs
[i
].eddsa_ctx2
[testnum
] = EVP_MD_CTX_new();
3277 if (loopargs
[i
].eddsa_ctx2
[testnum
] == NULL
) {
3282 if ((ed_pctx
= EVP_PKEY_CTX_new_id(ed_curves
[testnum
].nid
,
3284 || EVP_PKEY_keygen_init(ed_pctx
) <= 0
3285 || EVP_PKEY_keygen(ed_pctx
, &ed_pkey
) <= 0) {
3287 EVP_PKEY_CTX_free(ed_pctx
);
3290 EVP_PKEY_CTX_free(ed_pctx
);
3292 if (!EVP_DigestSignInit(loopargs
[i
].eddsa_ctx
[testnum
], NULL
, NULL
,
3295 EVP_PKEY_free(ed_pkey
);
3298 if (!EVP_DigestVerifyInit(loopargs
[i
].eddsa_ctx2
[testnum
], NULL
,
3299 NULL
, NULL
, ed_pkey
)) {
3301 EVP_PKEY_free(ed_pkey
);
3305 EVP_PKEY_free(ed_pkey
);
3309 BIO_printf(bio_err
, "EdDSA failure.\n");
3310 ERR_print_errors(bio_err
);
3313 for (i
= 0; i
< loopargs_len
; i
++) {
3314 /* Perform EdDSA signature test */
3315 loopargs
[i
].sigsize
= ed_curves
[testnum
].sigsize
;
3316 st
= EVP_DigestSign(loopargs
[i
].eddsa_ctx
[testnum
],
3317 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
3318 loopargs
[i
].buf
, 20);
3324 "EdDSA sign failure. No EdDSA sign will be done.\n");
3325 ERR_print_errors(bio_err
);
3328 pkey_print_message("sign", ed_curves
[testnum
].name
,
3329 ed_curves
[testnum
].bits
, seconds
.eddsa
);
3331 count
= run_benchmark(async_jobs
, EdDSA_sign_loop
, loopargs
);
3335 mr
? "+R10:%ld:%u:%s:%.2f\n" :
3336 "%ld %u bits %s sign ops in %.2fs \n",
3337 count
, ed_curves
[testnum
].bits
,
3338 ed_curves
[testnum
].name
, d
);
3339 eddsa_results
[testnum
][0] = (double)count
/ d
;
3342 /* Perform EdDSA verification test */
3343 for (i
= 0; i
< loopargs_len
; i
++) {
3344 st
= EVP_DigestVerify(loopargs
[i
].eddsa_ctx2
[testnum
],
3345 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
3346 loopargs
[i
].buf
, 20);
3352 "EdDSA verify failure. No EdDSA verify will be done.\n");
3353 ERR_print_errors(bio_err
);
3354 eddsa_doit
[testnum
] = 0;
3356 pkey_print_message("verify", ed_curves
[testnum
].name
,
3357 ed_curves
[testnum
].bits
, seconds
.eddsa
);
3359 count
= run_benchmark(async_jobs
, EdDSA_verify_loop
, loopargs
);
3362 mr
? "+R11:%ld:%u:%s:%.2f\n"
3363 : "%ld %u bits %s verify ops in %.2fs\n",
3364 count
, ed_curves
[testnum
].bits
,
3365 ed_curves
[testnum
].name
, d
);
3366 eddsa_results
[testnum
][1] = (double)count
/ d
;
3369 if (op_count
<= 1) {
3370 /* if longer than 10s, don't do any more */
3371 stop_it(eddsa_doit
, testnum
);
3375 #endif /* OPENSSL_NO_ECX */
3377 #ifndef OPENSSL_NO_SM2
3378 for (testnum
= 0; testnum
< SM2_NUM
; testnum
++) {
3380 EVP_PKEY
*sm2_pkey
= NULL
;
3382 if (!sm2_doit
[testnum
])
3383 continue; /* Ignore Curve */
3384 /* Init signing and verification */
3385 for (i
= 0; i
< loopargs_len
; i
++) {
3386 EVP_PKEY_CTX
*sm2_pctx
= NULL
;
3387 EVP_PKEY_CTX
*sm2_vfy_pctx
= NULL
;
3388 EVP_PKEY_CTX
*pctx
= NULL
;
3391 loopargs
[i
].sm2_ctx
[testnum
] = EVP_MD_CTX_new();
3392 loopargs
[i
].sm2_vfy_ctx
[testnum
] = EVP_MD_CTX_new();
3393 if (loopargs
[i
].sm2_ctx
[testnum
] == NULL
3394 || loopargs
[i
].sm2_vfy_ctx
[testnum
] == NULL
)
3399 st
= !((pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_SM2
, NULL
)) == NULL
3400 || EVP_PKEY_keygen_init(pctx
) <= 0
3401 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
3402 sm2_curves
[testnum
].nid
) <= 0
3403 || EVP_PKEY_keygen(pctx
, &sm2_pkey
) <= 0);
3404 EVP_PKEY_CTX_free(pctx
);
3408 st
= 0; /* set back to zero */
3409 /* attach it sooner to rely on main final cleanup */
3410 loopargs
[i
].sm2_pkey
[testnum
] = sm2_pkey
;
3411 loopargs
[i
].sigsize
= EVP_PKEY_get_size(sm2_pkey
);
3413 sm2_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
3414 sm2_vfy_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
3415 if (sm2_pctx
== NULL
|| sm2_vfy_pctx
== NULL
) {
3416 EVP_PKEY_CTX_free(sm2_vfy_pctx
);
3420 /* attach them directly to respective ctx */
3421 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_ctx
[testnum
], sm2_pctx
);
3422 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[testnum
], sm2_vfy_pctx
);
3425 * No need to allow user to set an explicit ID here, just use
3426 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
3428 if (EVP_PKEY_CTX_set1_id(sm2_pctx
, SM2_ID
, SM2_ID_LEN
) != 1
3429 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx
, SM2_ID
, SM2_ID_LEN
) != 1)
3432 if (!EVP_DigestSignInit(loopargs
[i
].sm2_ctx
[testnum
], NULL
,
3433 EVP_sm3(), NULL
, sm2_pkey
))
3435 if (!EVP_DigestVerifyInit(loopargs
[i
].sm2_vfy_ctx
[testnum
], NULL
,
3436 EVP_sm3(), NULL
, sm2_pkey
))
3438 st
= 1; /* mark loop as succeeded */
3441 BIO_printf(bio_err
, "SM2 init failure.\n");
3442 ERR_print_errors(bio_err
);
3445 for (i
= 0; i
< loopargs_len
; i
++) {
3446 /* Perform SM2 signature test */
3447 st
= EVP_DigestSign(loopargs
[i
].sm2_ctx
[testnum
],
3448 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
3449 loopargs
[i
].buf
, 20);
3455 "SM2 sign failure. No SM2 sign will be done.\n");
3456 ERR_print_errors(bio_err
);
3459 pkey_print_message("sign", sm2_curves
[testnum
].name
,
3460 sm2_curves
[testnum
].bits
, seconds
.sm2
);
3462 count
= run_benchmark(async_jobs
, SM2_sign_loop
, loopargs
);
3466 mr
? "+R12:%ld:%u:%s:%.2f\n" :
3467 "%ld %u bits %s sign ops in %.2fs \n",
3468 count
, sm2_curves
[testnum
].bits
,
3469 sm2_curves
[testnum
].name
, d
);
3470 sm2_results
[testnum
][0] = (double)count
/ d
;
3474 /* Perform SM2 verification test */
3475 for (i
= 0; i
< loopargs_len
; i
++) {
3476 st
= EVP_DigestVerify(loopargs
[i
].sm2_vfy_ctx
[testnum
],
3477 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
3478 loopargs
[i
].buf
, 20);
3484 "SM2 verify failure. No SM2 verify will be done.\n");
3485 ERR_print_errors(bio_err
);
3486 sm2_doit
[testnum
] = 0;
3488 pkey_print_message("verify", sm2_curves
[testnum
].name
,
3489 sm2_curves
[testnum
].bits
, seconds
.sm2
);
3491 count
= run_benchmark(async_jobs
, SM2_verify_loop
, loopargs
);
3494 mr
? "+R13:%ld:%u:%s:%.2f\n"
3495 : "%ld %u bits %s verify ops in %.2fs\n",
3496 count
, sm2_curves
[testnum
].bits
,
3497 sm2_curves
[testnum
].name
, d
);
3498 sm2_results
[testnum
][1] = (double)count
/ d
;
3501 if (op_count
<= 1) {
3502 /* if longer than 10s, don't do any more */
3503 for (testnum
++; testnum
< SM2_NUM
; testnum
++)
3504 sm2_doit
[testnum
] = 0;
3508 #endif /* OPENSSL_NO_SM2 */
3510 #ifndef OPENSSL_NO_DH
3511 for (testnum
= 0; testnum
< FFDH_NUM
; testnum
++) {
3512 int ffdh_checks
= 1;
3514 if (!ffdh_doit
[testnum
])
3517 for (i
= 0; i
< loopargs_len
; i
++) {
3518 EVP_PKEY
*pkey_A
= NULL
;
3519 EVP_PKEY
*pkey_B
= NULL
;
3520 EVP_PKEY_CTX
*ffdh_ctx
= NULL
;
3521 EVP_PKEY_CTX
*test_ctx
= NULL
;
3525 /* Ensure that the error queue is empty */
3526 if (ERR_peek_error()) {
3528 "WARNING: the error queue contains previous unhandled errors.\n");
3529 ERR_print_errors(bio_err
);
3532 pkey_A
= EVP_PKEY_new();
3534 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
3535 ERR_print_errors(bio_err
);
3540 pkey_B
= EVP_PKEY_new();
3542 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
3543 ERR_print_errors(bio_err
);
3549 ffdh_ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_DH
, NULL
);
3551 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3552 ERR_print_errors(bio_err
);
3558 if (EVP_PKEY_keygen_init(ffdh_ctx
) <= 0) {
3559 BIO_printf(bio_err
, "Error while initialising EVP_PKEY_CTX.\n");
3560 ERR_print_errors(bio_err
);
3565 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx
, ffdh_params
[testnum
].nid
) <= 0) {
3566 BIO_printf(bio_err
, "Error setting DH key size for keygen.\n");
3567 ERR_print_errors(bio_err
);
3573 if (EVP_PKEY_keygen(ffdh_ctx
, &pkey_A
) <= 0 ||
3574 EVP_PKEY_keygen(ffdh_ctx
, &pkey_B
) <= 0) {
3575 BIO_printf(bio_err
, "FFDH key generation failure.\n");
3576 ERR_print_errors(bio_err
);
3582 EVP_PKEY_CTX_free(ffdh_ctx
);
3585 * check if the derivation works correctly both ways so that
3586 * we know if future derive calls will fail, and we can skip
3587 * error checking in benchmarked code
3589 ffdh_ctx
= EVP_PKEY_CTX_new(pkey_A
, NULL
);
3590 if (ffdh_ctx
== NULL
) {
3591 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3592 ERR_print_errors(bio_err
);
3597 if (EVP_PKEY_derive_init(ffdh_ctx
) <= 0) {
3598 BIO_printf(bio_err
, "FFDH derivation context init failure.\n");
3599 ERR_print_errors(bio_err
);
3604 if (EVP_PKEY_derive_set_peer(ffdh_ctx
, pkey_B
) <= 0) {
3605 BIO_printf(bio_err
, "Assigning peer key for derivation failed.\n");
3606 ERR_print_errors(bio_err
);
3611 if (EVP_PKEY_derive(ffdh_ctx
, NULL
, &secret_size
) <= 0) {
3612 BIO_printf(bio_err
, "Checking size of shared secret failed.\n");
3613 ERR_print_errors(bio_err
);
3618 if (secret_size
> MAX_FFDH_SIZE
) {
3619 BIO_printf(bio_err
, "Assertion failure: shared secret too large.\n");
3624 if (EVP_PKEY_derive(ffdh_ctx
,
3625 loopargs
[i
].secret_ff_a
,
3626 &secret_size
) <= 0) {
3627 BIO_printf(bio_err
, "Shared secret derive failure.\n");
3628 ERR_print_errors(bio_err
);
3633 /* Now check from side B */
3634 test_ctx
= EVP_PKEY_CTX_new(pkey_B
, NULL
);
3636 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3637 ERR_print_errors(bio_err
);
3642 if (EVP_PKEY_derive_init(test_ctx
) <= 0 ||
3643 EVP_PKEY_derive_set_peer(test_ctx
, pkey_A
) <= 0 ||
3644 EVP_PKEY_derive(test_ctx
, NULL
, &test_out
) <= 0 ||
3645 EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_ff_b
, &test_out
) <= 0 ||
3646 test_out
!= secret_size
) {
3647 BIO_printf(bio_err
, "FFDH computation failure.\n");
3653 /* compare the computed secrets */
3654 if (CRYPTO_memcmp(loopargs
[i
].secret_ff_a
,
3655 loopargs
[i
].secret_ff_b
, secret_size
)) {
3656 BIO_printf(bio_err
, "FFDH computations don't match.\n");
3657 ERR_print_errors(bio_err
);
3663 loopargs
[i
].ffdh_ctx
[testnum
] = ffdh_ctx
;
3665 EVP_PKEY_free(pkey_A
);
3667 EVP_PKEY_free(pkey_B
);
3669 EVP_PKEY_CTX_free(test_ctx
);
3672 if (ffdh_checks
!= 0) {
3673 pkey_print_message("", "ffdh",
3674 ffdh_params
[testnum
].bits
, seconds
.ffdh
);
3677 run_benchmark(async_jobs
, FFDH_derive_key_loop
, loopargs
);
3680 mr
? "+R14:%ld:%d:%.2f\n" :
3681 "%ld %u-bits FFDH ops in %.2fs\n", count
,
3682 ffdh_params
[testnum
].bits
, d
);
3683 ffdh_results
[testnum
][0] = (double)count
/ d
;
3686 if (op_count
<= 1) {
3687 /* if longer than 10s, don't do any more */
3688 stop_it(ffdh_doit
, testnum
);
3691 #endif /* OPENSSL_NO_DH */
3693 for (testnum
= 0; testnum
< kems_algs_len
; testnum
++) {
3695 const char *kem_name
= kems_algname
[testnum
];
3697 if (!kems_doit
[testnum
] || !do_kems
)
3700 for (i
= 0; i
< loopargs_len
; i
++) {
3701 EVP_PKEY
*pkey
= NULL
;
3702 EVP_PKEY_CTX
*kem_gen_ctx
= NULL
;
3703 EVP_PKEY_CTX
*kem_encaps_ctx
= NULL
;
3704 EVP_PKEY_CTX
*kem_decaps_ctx
= NULL
;
3705 size_t send_secret_len
, out_len
;
3706 size_t rcv_secret_len
;
3707 unsigned char *out
= NULL
, *send_secret
= NULL
, *rcv_secret
;
3710 char sfx
[MAX_ALGNAME_SUFFIX
];
3711 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
3713 enum kem_type_t
{ KEM_RSA
= 1, KEM_EC
, KEM_X25519
, KEM_X448
} kem_type
;
3715 /* no string after rsa<bitcnt> permitted: */
3716 if (strlen(kem_name
) < MAX_ALGNAME_SUFFIX
+ 4 /* rsa+digit */
3717 && sscanf(kem_name
, "rsa%u%s", &bits
, sfx
) == 1)
3719 else if (strncmp(kem_name
, "EC", 2) == 0)
3721 else if (strcmp(kem_name
, "X25519") == 0)
3722 kem_type
= KEM_X25519
;
3723 else if (strcmp(kem_name
, "X448") == 0)
3724 kem_type
= KEM_X448
;
3727 if (ERR_peek_error()) {
3729 "WARNING: the error queue contains previous unhandled errors.\n");
3730 ERR_print_errors(bio_err
);
3733 if (kem_type
== KEM_RSA
) {
3734 params
[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS
,
3737 } else if (kem_type
== KEM_EC
) {
3738 name
= (char *)(kem_name
+ 2);
3739 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
,
3744 kem_gen_ctx
= EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3745 (kem_type
== KEM_RSA
) ? "RSA":
3746 (kem_type
== KEM_EC
) ? "EC":
3750 if ((!kem_gen_ctx
|| EVP_PKEY_keygen_init(kem_gen_ctx
) <= 0)
3752 && EVP_PKEY_CTX_set_params(kem_gen_ctx
, params
) <= 0)) {
3753 BIO_printf(bio_err
, "Error initializing keygen ctx for %s.\n",
3757 if (EVP_PKEY_keygen(kem_gen_ctx
, &pkey
) <= 0) {
3758 BIO_printf(bio_err
, "Error while generating KEM EVP_PKEY.\n");
3761 /* Now prepare encaps data structs */
3762 kem_encaps_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3765 if (kem_encaps_ctx
== NULL
3766 || EVP_PKEY_encapsulate_init(kem_encaps_ctx
, NULL
) <= 0
3767 || (kem_type
== KEM_RSA
3768 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx
, "RSASVE") <= 0)
3769 || ((kem_type
== KEM_EC
3770 || kem_type
== KEM_X25519
3771 || kem_type
== KEM_X448
)
3772 && EVP_PKEY_CTX_set_kem_op(kem_encaps_ctx
, "DHKEM") <= 0)
3773 || EVP_PKEY_encapsulate(kem_encaps_ctx
, NULL
, &out_len
,
3774 NULL
, &send_secret_len
) <= 0) {
3776 "Error while initializing encaps data structs for %s.\n",
3780 out
= app_malloc(out_len
, "encaps result");
3781 send_secret
= app_malloc(send_secret_len
, "encaps secret");
3782 if (out
== NULL
|| send_secret
== NULL
) {
3783 BIO_printf(bio_err
, "MemAlloc error in encaps for %s.\n", kem_name
);
3786 if (EVP_PKEY_encapsulate(kem_encaps_ctx
, out
, &out_len
,
3787 send_secret
, &send_secret_len
) <= 0) {
3788 BIO_printf(bio_err
, "Encaps error for %s.\n", kem_name
);
3791 /* Now prepare decaps data structs */
3792 kem_decaps_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3795 if (kem_decaps_ctx
== NULL
3796 || EVP_PKEY_decapsulate_init(kem_decaps_ctx
, NULL
) <= 0
3797 || (kem_type
== KEM_RSA
3798 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx
, "RSASVE") <= 0)
3799 || ((kem_type
== KEM_EC
3800 || kem_type
== KEM_X25519
3801 || kem_type
== KEM_X448
)
3802 && EVP_PKEY_CTX_set_kem_op(kem_decaps_ctx
, "DHKEM") <= 0)
3803 || EVP_PKEY_decapsulate(kem_decaps_ctx
, NULL
, &rcv_secret_len
,
3804 out
, out_len
) <= 0) {
3806 "Error while initializing decaps data structs for %s.\n",
3810 rcv_secret
= app_malloc(rcv_secret_len
, "KEM decaps secret");
3811 if (rcv_secret
== NULL
) {
3812 BIO_printf(bio_err
, "MemAlloc failure in decaps for %s.\n",
3816 if (EVP_PKEY_decapsulate(kem_decaps_ctx
, rcv_secret
,
3817 &rcv_secret_len
, out
, out_len
) <= 0
3818 || rcv_secret_len
!= send_secret_len
3819 || memcmp(send_secret
, rcv_secret
, send_secret_len
)) {
3820 BIO_printf(bio_err
, "Decaps error for %s.\n", kem_name
);
3823 loopargs
[i
].kem_gen_ctx
[testnum
] = kem_gen_ctx
;
3824 loopargs
[i
].kem_encaps_ctx
[testnum
] = kem_encaps_ctx
;
3825 loopargs
[i
].kem_decaps_ctx
[testnum
] = kem_decaps_ctx
;
3826 loopargs
[i
].kem_out_len
[testnum
] = out_len
;
3827 loopargs
[i
].kem_secret_len
[testnum
] = send_secret_len
;
3828 loopargs
[i
].kem_out
[testnum
] = out
;
3829 loopargs
[i
].kem_send_secret
[testnum
] = send_secret
;
3830 loopargs
[i
].kem_rcv_secret
[testnum
] = rcv_secret
;
3834 ERR_print_errors(bio_err
);
3839 if (kem_checks
!= 0) {
3840 kskey_print_message(kem_name
, "keygen", seconds
.kem
);
3843 run_benchmark(async_jobs
, KEM_keygen_loop
, loopargs
);
3846 mr
? "+R15:%ld:%s:%.2f\n" :
3847 "%ld %s KEM keygen ops in %.2fs\n", count
,
3849 kems_results
[testnum
][0] = (double)count
/ d
;
3851 kskey_print_message(kem_name
, "encaps", seconds
.kem
);
3854 run_benchmark(async_jobs
, KEM_encaps_loop
, loopargs
);
3857 mr
? "+R16:%ld:%s:%.2f\n" :
3858 "%ld %s KEM encaps ops in %.2fs\n", count
,
3860 kems_results
[testnum
][1] = (double)count
/ d
;
3862 kskey_print_message(kem_name
, "decaps", seconds
.kem
);
3865 run_benchmark(async_jobs
, KEM_decaps_loop
, loopargs
);
3868 mr
? "+R17:%ld:%s:%.2f\n" :
3869 "%ld %s KEM decaps ops in %.2fs\n", count
,
3871 kems_results
[testnum
][2] = (double)count
/ d
;
3874 if (op_count
<= 1) {
3875 /* if longer than 10s, don't do any more */
3876 stop_it(kems_doit
, testnum
);
3880 for (testnum
= 0; testnum
< sigs_algs_len
; testnum
++) {
3882 const char *sig_name
= sigs_algname
[testnum
];
3884 if (!sigs_doit
[testnum
] || !do_sigs
)
3887 for (i
= 0; i
< loopargs_len
; i
++) {
3888 EVP_PKEY
*pkey
= NULL
;
3889 EVP_PKEY_CTX
*ctx_params
= NULL
;
3890 EVP_PKEY
* pkey_params
= NULL
;
3891 EVP_PKEY_CTX
*sig_gen_ctx
= NULL
;
3892 EVP_PKEY_CTX
*sig_sign_ctx
= NULL
;
3893 EVP_PKEY_CTX
*sig_verify_ctx
= NULL
;
3894 unsigned char md
[SHA256_DIGEST_LENGTH
];
3896 char sfx
[MAX_ALGNAME_SUFFIX
];
3897 size_t md_len
= SHA256_DIGEST_LENGTH
;
3898 size_t max_sig_len
, sig_len
;
3900 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
3903 /* only sign little data to avoid measuring digest performance */
3904 memset(md
, 0, SHA256_DIGEST_LENGTH
);
3906 if (ERR_peek_error()) {
3908 "WARNING: the error queue contains previous unhandled errors.\n");
3909 ERR_print_errors(bio_err
);
3912 /* no string after rsa<bitcnt> permitted: */
3913 if (strlen(sig_name
) < MAX_ALGNAME_SUFFIX
+ 4 /* rsa+digit */
3914 && sscanf(sig_name
, "rsa%u%s", &bits
, sfx
) == 1) {
3915 params
[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS
,
3920 if (strncmp(sig_name
, "dsa", 3) == 0) {
3921 ctx_params
= EVP_PKEY_CTX_new_id(EVP_PKEY_DSA
, NULL
);
3922 if (ctx_params
== NULL
3923 || EVP_PKEY_paramgen_init(ctx_params
) <= 0
3924 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params
,
3925 atoi(sig_name
+ 3)) <= 0
3926 || EVP_PKEY_paramgen(ctx_params
, &pkey_params
) <= 0
3927 || (sig_gen_ctx
= EVP_PKEY_CTX_new(pkey_params
, NULL
)) == NULL
3928 || EVP_PKEY_keygen_init(sig_gen_ctx
) <= 0) {
3930 "Error initializing classic keygen ctx for %s.\n",
3936 if (sig_gen_ctx
== NULL
)
3937 sig_gen_ctx
= EVP_PKEY_CTX_new_from_name(app_get0_libctx(),
3938 use_params
== 1 ? "RSA" : sig_name
,
3941 if (!sig_gen_ctx
|| EVP_PKEY_keygen_init(sig_gen_ctx
) <= 0
3943 EVP_PKEY_CTX_set_params(sig_gen_ctx
, params
) <= 0)) {
3944 BIO_printf(bio_err
, "Error initializing keygen ctx for %s.\n",
3948 if (EVP_PKEY_keygen(sig_gen_ctx
, &pkey
) <= 0) {
3950 "Error while generating signature EVP_PKEY for %s.\n",
3954 /* Now prepare signature data structs */
3955 sig_sign_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3958 if (sig_sign_ctx
== NULL
3959 || EVP_PKEY_sign_init(sig_sign_ctx
) <= 0
3961 && (EVP_PKEY_CTX_set_rsa_padding(sig_sign_ctx
,
3962 RSA_PKCS1_PADDING
) <= 0))
3963 || EVP_PKEY_sign(sig_sign_ctx
, NULL
, &max_sig_len
,
3966 "Error while initializing signing data structs for %s.\n",
3970 sig
= app_malloc(sig_len
= max_sig_len
, "signature buffer");
3972 BIO_printf(bio_err
, "MemAlloc error in sign for %s.\n", sig_name
);
3975 if (EVP_PKEY_sign(sig_sign_ctx
, sig
, &sig_len
, md
, md_len
) <= 0) {
3976 BIO_printf(bio_err
, "Signing error for %s.\n", sig_name
);
3979 /* Now prepare verify data structs */
3980 memset(md
, 0, SHA256_DIGEST_LENGTH
);
3981 sig_verify_ctx
= EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(),
3984 if (sig_verify_ctx
== NULL
3985 || EVP_PKEY_verify_init(sig_verify_ctx
) <= 0
3987 && (EVP_PKEY_CTX_set_rsa_padding(sig_verify_ctx
,
3988 RSA_PKCS1_PADDING
) <= 0))) {
3990 "Error while initializing verify data structs for %s.\n",
3994 if (EVP_PKEY_verify(sig_verify_ctx
, sig
, sig_len
, md
, md_len
) <= 0) {
3995 BIO_printf(bio_err
, "Verify error for %s.\n", sig_name
);
3998 if (EVP_PKEY_verify(sig_verify_ctx
, sig
, sig_len
, md
, md_len
) <= 0) {
3999 BIO_printf(bio_err
, "Verify 2 error for %s.\n", sig_name
);
4002 loopargs
[i
].sig_gen_ctx
[testnum
] = sig_gen_ctx
;
4003 loopargs
[i
].sig_sign_ctx
[testnum
] = sig_sign_ctx
;
4004 loopargs
[i
].sig_verify_ctx
[testnum
] = sig_verify_ctx
;
4005 loopargs
[i
].sig_max_sig_len
[testnum
] = max_sig_len
;
4006 loopargs
[i
].sig_act_sig_len
[testnum
] = sig_len
;
4007 loopargs
[i
].sig_sig
[testnum
] = sig
;
4011 ERR_print_errors(bio_err
);
4017 if (sig_checks
!= 0) {
4018 kskey_print_message(sig_name
, "keygen", seconds
.sig
);
4020 count
= run_benchmark(async_jobs
, SIG_keygen_loop
, loopargs
);
4023 mr
? "+R18:%ld:%s:%.2f\n" :
4024 "%ld %s signature keygen ops in %.2fs\n", count
,
4026 sigs_results
[testnum
][0] = (double)count
/ d
;
4028 kskey_print_message(sig_name
, "signs", seconds
.sig
);
4031 run_benchmark(async_jobs
, SIG_sign_loop
, loopargs
);
4034 mr
? "+R19:%ld:%s:%.2f\n" :
4035 "%ld %s signature sign ops in %.2fs\n", count
,
4037 sigs_results
[testnum
][1] = (double)count
/ d
;
4040 kskey_print_message(sig_name
, "verify", seconds
.sig
);
4043 run_benchmark(async_jobs
, SIG_verify_loop
, loopargs
);
4046 mr
? "+R20:%ld:%s:%.2f\n" :
4047 "%ld %s signature verify ops in %.2fs\n", count
,
4049 sigs_results
[testnum
][2] = (double)count
/ d
;
4053 stop_it(sigs_doit
, testnum
);
4060 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING
));
4061 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON
));
4062 printf("options: %s\n", BN_options());
4063 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS
));
4064 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO
));
4071 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
4074 for (testnum
= 0; testnum
< size_num
; testnum
++)
4075 printf(mr
? ":%d" : "%7d bytes", lengths
[testnum
]);
4079 for (k
= 0; k
< ALGOR_NUM
; k
++) {
4080 const char *alg_name
= names
[k
];
4086 if (evp_cipher
== NULL
)
4087 alg_name
= evp_md_name
;
4088 else if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
4089 app_bail_out("failed to get name of cipher '%s'\n", evp_cipher
);
4093 printf("+F:%u:%s", k
, alg_name
);
4095 printf("%-13s", alg_name
);
4096 for (testnum
= 0; testnum
< size_num
; testnum
++) {
4097 if (results
[k
][testnum
] > 10000 && !mr
)
4098 printf(" %11.2fk", results
[k
][testnum
] / 1e3
);
4100 printf(mr
? ":%.2f" : " %11.2f ", results
[k
][testnum
]);
4105 for (k
= 0; k
< RSA_NUM
; k
++) {
4108 if (testnum
&& !mr
) {
4109 printf("%19ssign verify encrypt decrypt sign/s verify/s encr./s decr./s\n", " ");
4113 printf("+F2:%u:%u:%f:%f:%f:%f\n",
4114 k
, rsa_keys
[k
].bits
, rsa_results
[k
][0], rsa_results
[k
][1],
4115 rsa_results
[k
][2], rsa_results
[k
][3]);
4117 printf("rsa %5u bits %8.6fs %8.6fs %8.6fs %8.6fs %8.1f %8.1f %8.1f %8.1f\n",
4118 rsa_keys
[k
].bits
, 1.0 / rsa_results
[k
][0],
4119 1.0 / rsa_results
[k
][1], 1.0 / rsa_results
[k
][2],
4120 1.0 / rsa_results
[k
][3],
4121 rsa_results
[k
][0], rsa_results
[k
][1],
4122 rsa_results
[k
][2], rsa_results
[k
][3]);
4125 for (k
= 0; k
< DSA_NUM
; k
++) {
4128 if (testnum
&& !mr
) {
4129 printf("%18ssign verify sign/s verify/s\n", " ");
4133 printf("+F3:%u:%u:%f:%f\n",
4134 k
, dsa_bits
[k
], dsa_results
[k
][0], dsa_results
[k
][1]);
4136 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
4137 dsa_bits
[k
], 1.0 / dsa_results
[k
][0], 1.0 / dsa_results
[k
][1],
4138 dsa_results
[k
][0], dsa_results
[k
][1]);
4141 for (k
= 0; k
< OSSL_NELEM(ecdsa_doit
); k
++) {
4144 if (testnum
&& !mr
) {
4145 printf("%30ssign verify sign/s verify/s\n", " ");
4150 printf("+F4:%u:%u:%f:%f\n",
4151 k
, ec_curves
[k
].bits
,
4152 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
4154 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4155 ec_curves
[k
].bits
, ec_curves
[k
].name
,
4156 1.0 / ecdsa_results
[k
][0], 1.0 / ecdsa_results
[k
][1],
4157 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
4161 for (k
= 0; k
< EC_NUM
; k
++) {
4164 if (testnum
&& !mr
) {
4165 printf("%30sop op/s\n", " ");
4169 printf("+F5:%u:%u:%f:%f\n",
4170 k
, ec_curves
[k
].bits
,
4171 ecdh_results
[k
][0], 1.0 / ecdh_results
[k
][0]);
4174 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
4175 ec_curves
[k
].bits
, ec_curves
[k
].name
,
4176 1.0 / ecdh_results
[k
][0], ecdh_results
[k
][0]);
4179 #ifndef OPENSSL_NO_ECX
4181 for (k
= 0; k
< OSSL_NELEM(eddsa_doit
); k
++) {
4184 if (testnum
&& !mr
) {
4185 printf("%30ssign verify sign/s verify/s\n", " ");
4190 printf("+F6:%u:%u:%s:%f:%f\n",
4191 k
, ed_curves
[k
].bits
, ed_curves
[k
].name
,
4192 eddsa_results
[k
][0], eddsa_results
[k
][1]);
4194 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4195 ed_curves
[k
].bits
, ed_curves
[k
].name
,
4196 1.0 / eddsa_results
[k
][0], 1.0 / eddsa_results
[k
][1],
4197 eddsa_results
[k
][0], eddsa_results
[k
][1]);
4199 #endif /* OPENSSL_NO_ECX */
4201 #ifndef OPENSSL_NO_SM2
4203 for (k
= 0; k
< OSSL_NELEM(sm2_doit
); k
++) {
4206 if (testnum
&& !mr
) {
4207 printf("%30ssign verify sign/s verify/s\n", " ");
4212 printf("+F7:%u:%u:%s:%f:%f\n",
4213 k
, sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
4214 sm2_results
[k
][0], sm2_results
[k
][1]);
4216 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
4217 sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
4218 1.0 / sm2_results
[k
][0], 1.0 / sm2_results
[k
][1],
4219 sm2_results
[k
][0], sm2_results
[k
][1]);
4222 #ifndef OPENSSL_NO_DH
4224 for (k
= 0; k
< FFDH_NUM
; k
++) {
4227 if (testnum
&& !mr
) {
4228 printf("%23sop op/s\n", " ");
4232 printf("+F8:%u:%u:%f:%f\n",
4233 k
, ffdh_params
[k
].bits
,
4234 ffdh_results
[k
][0], 1.0 / ffdh_results
[k
][0]);
4237 printf("%4u bits ffdh %8.4fs %8.1f\n",
4238 ffdh_params
[k
].bits
,
4239 1.0 / ffdh_results
[k
][0], ffdh_results
[k
][0]);
4241 #endif /* OPENSSL_NO_DH */
4244 for (k
= 0; k
< kems_algs_len
; k
++) {
4245 const char *kem_name
= kems_algname
[k
];
4247 if (!kems_doit
[k
] || !do_kems
)
4249 if (testnum
&& !mr
) {
4250 printf("%31skeygen encaps decaps keygens/s encaps/s decaps/s\n", " ");
4254 printf("+F9:%u:%f:%f:%f\n",
4255 k
, kems_results
[k
][0], kems_results
[k
][1],
4256 kems_results
[k
][2]);
4258 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", kem_name
,
4259 1.0 / kems_results
[k
][0],
4260 1.0 / kems_results
[k
][1], 1.0 / kems_results
[k
][2],
4261 kems_results
[k
][0], kems_results
[k
][1], kems_results
[k
][2]);
4266 for (k
= 0; k
< sigs_algs_len
; k
++) {
4267 const char *sig_name
= sigs_algname
[k
];
4269 if (!sigs_doit
[k
] || !do_sigs
)
4271 if (testnum
&& !mr
) {
4272 printf("%31skeygen signs verify keygens/s sign/s verify/s\n", " ");
4276 printf("+F10:%u:%f:%f:%f\n",
4277 k
, sigs_results
[k
][0], sigs_results
[k
][1],
4278 sigs_results
[k
][2]);
4280 printf("%27s %8.6fs %8.6fs %8.6fs %9.1f %9.1f %9.1f\n", sig_name
,
4281 1.0 / sigs_results
[k
][0], 1.0 / sigs_results
[k
][1],
4282 1.0 / sigs_results
[k
][2], sigs_results
[k
][0],
4283 sigs_results
[k
][1], sigs_results
[k
][2]);
4288 ERR_print_errors(bio_err
);
4289 for (i
= 0; i
< loopargs_len
; i
++) {
4290 OPENSSL_free(loopargs
[i
].buf_malloc
);
4291 OPENSSL_free(loopargs
[i
].buf2_malloc
);
4294 EVP_PKEY_CTX_free(genctx
);
4295 for (k
= 0; k
< RSA_NUM
; k
++) {
4296 EVP_PKEY_CTX_free(loopargs
[i
].rsa_sign_ctx
[k
]);
4297 EVP_PKEY_CTX_free(loopargs
[i
].rsa_verify_ctx
[k
]);
4299 #ifndef OPENSSL_NO_DH
4300 OPENSSL_free(loopargs
[i
].secret_ff_a
);
4301 OPENSSL_free(loopargs
[i
].secret_ff_b
);
4302 for (k
= 0; k
< FFDH_NUM
; k
++)
4303 EVP_PKEY_CTX_free(loopargs
[i
].ffdh_ctx
[k
]);
4305 for (k
= 0; k
< DSA_NUM
; k
++) {
4306 EVP_PKEY_CTX_free(loopargs
[i
].dsa_sign_ctx
[k
]);
4307 EVP_PKEY_CTX_free(loopargs
[i
].dsa_verify_ctx
[k
]);
4309 for (k
= 0; k
< ECDSA_NUM
; k
++) {
4310 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_sign_ctx
[k
]);
4311 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_verify_ctx
[k
]);
4313 for (k
= 0; k
< EC_NUM
; k
++)
4314 EVP_PKEY_CTX_free(loopargs
[i
].ecdh_ctx
[k
]);
4315 #ifndef OPENSSL_NO_ECX
4316 for (k
= 0; k
< EdDSA_NUM
; k
++) {
4317 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx
[k
]);
4318 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx2
[k
]);
4320 #endif /* OPENSSL_NO_ECX */
4321 #ifndef OPENSSL_NO_SM2
4322 for (k
= 0; k
< SM2_NUM
; k
++) {
4323 EVP_PKEY_CTX
*pctx
= NULL
;
4325 /* free signing ctx */
4326 if (loopargs
[i
].sm2_ctx
[k
] != NULL
4327 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_ctx
[k
])) != NULL
)
4328 EVP_PKEY_CTX_free(pctx
);
4329 EVP_MD_CTX_free(loopargs
[i
].sm2_ctx
[k
]);
4330 /* free verification ctx */
4331 if (loopargs
[i
].sm2_vfy_ctx
[k
] != NULL
4332 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[k
])) != NULL
)
4333 EVP_PKEY_CTX_free(pctx
);
4334 EVP_MD_CTX_free(loopargs
[i
].sm2_vfy_ctx
[k
]);
4336 EVP_PKEY_free(loopargs
[i
].sm2_pkey
[k
]);
4339 for (k
= 0; k
< kems_algs_len
; k
++) {
4340 EVP_PKEY_CTX_free(loopargs
[i
].kem_gen_ctx
[k
]);
4341 EVP_PKEY_CTX_free(loopargs
[i
].kem_encaps_ctx
[k
]);
4342 EVP_PKEY_CTX_free(loopargs
[i
].kem_decaps_ctx
[k
]);
4343 OPENSSL_free(loopargs
[i
].kem_out
[k
]);
4344 OPENSSL_free(loopargs
[i
].kem_send_secret
[k
]);
4345 OPENSSL_free(loopargs
[i
].kem_rcv_secret
[k
]);
4347 for (k
= 0; k
< sigs_algs_len
; k
++) {
4348 EVP_PKEY_CTX_free(loopargs
[i
].sig_gen_ctx
[k
]);
4349 EVP_PKEY_CTX_free(loopargs
[i
].sig_sign_ctx
[k
]);
4350 EVP_PKEY_CTX_free(loopargs
[i
].sig_verify_ctx
[k
]);
4351 OPENSSL_free(loopargs
[i
].sig_sig
[k
]);
4353 OPENSSL_free(loopargs
[i
].secret_a
);
4354 OPENSSL_free(loopargs
[i
].secret_b
);
4356 OPENSSL_free(evp_hmac_name
);
4357 OPENSSL_free(evp_cmac_name
);
4358 for (k
= 0; k
< kems_algs_len
; k
++)
4359 OPENSSL_free(kems_algname
[k
]);
4360 if (kem_stack
!= NULL
)
4361 sk_EVP_KEM_pop_free(kem_stack
, EVP_KEM_free
);
4362 for (k
= 0; k
< sigs_algs_len
; k
++)
4363 OPENSSL_free(sigs_algname
[k
]);
4364 if (sig_stack
!= NULL
)
4365 sk_EVP_SIGNATURE_pop_free(sig_stack
, EVP_SIGNATURE_free
);
4367 if (async_jobs
> 0) {
4368 for (i
= 0; i
< loopargs_len
; i
++)
4369 ASYNC_WAIT_CTX_free(loopargs
[i
].wait_ctx
);
4373 ASYNC_cleanup_thread();
4375 OPENSSL_free(loopargs
);
4377 EVP_CIPHER_free(evp_cipher
);
4383 static void print_message(const char *s
, int length
, int tm
)
4386 mr
? "+DT:%s:%d:%d\n"
4387 : "Doing %s ops for %ds on %d size blocks: ", s
, tm
, length
);
4388 (void)BIO_flush(bio_err
);
4393 static void pkey_print_message(const char *str
, const char *str2
, unsigned int bits
,
4397 mr
? "+DTP:%d:%s:%s:%d\n"
4398 : "Doing %u bits %s %s ops for %ds: ", bits
, str
, str2
, tm
);
4399 (void)BIO_flush(bio_err
);
4404 static void kskey_print_message(const char *str
, const char *str2
, int tm
)
4407 mr
? "+DTP:%s:%s:%d\n"
4408 : "Doing %s %s ops for %ds: ", str
, str2
, tm
);
4409 (void)BIO_flush(bio_err
);
4414 static void print_result(int alg
, int run_no
, int count
, double time_used
)
4417 BIO_printf(bio_err
, "%s error!\n", names
[alg
]);
4418 ERR_print_errors(bio_err
);
4422 mr
? "+R:%d:%s:%f\n"
4423 : "%d %s ops in %.2fs\n", count
, names
[alg
], time_used
);
4424 results
[alg
][run_no
] = ((double)count
) / time_used
* lengths
[run_no
];
4428 static char *sstrsep(char **string
, const char *delim
)
4431 char *token
= *string
;
4433 memset(isdelim
, 0, sizeof(isdelim
));
4437 isdelim
[(unsigned char)(*delim
)] = 1;
4441 while (!isdelim
[(unsigned char)(**string
)])
4452 static int strtoint(const char *str
, const int min_val
, const int upper_val
,
4459 val
= strtol(str
, &end
, 10);
4460 if (errno
== 0 && end
!= str
&& *end
== 0
4461 && min_val
<= val
&& val
< upper_val
) {
4469 static int do_multi(int multi
, int size_num
)
4475 static char sep
[] = ":";
4477 fds
= app_malloc(sizeof(*fds
) * multi
, "fd buffer for do_multi");
4478 for (n
= 0; n
< multi
; ++n
) {
4479 if (pipe(fd
) == -1) {
4480 BIO_printf(bio_err
, "pipe failure\n");
4484 (void)BIO_flush(bio_err
);
4491 if (dup(fd
[1]) == -1) {
4492 BIO_printf(bio_err
, "dup failed\n");
4501 printf("Forked child %d\n", n
);
4504 /* for now, assume the pipe is long enough to take all the output */
4505 for (n
= 0; n
< multi
; ++n
) {
4513 if ((f
= fdopen(fds
[n
], "r")) == NULL
) {
4514 BIO_printf(bio_err
, "fdopen failure with 0x%x\n",
4519 while (fgets(buf
, sizeof(buf
), f
)) {
4520 p
= strchr(buf
, '\n');
4523 if (buf
[0] != '+') {
4525 "Don't understand line '%s' from child %d\n", buf
,
4529 printf("Got: %s from %d\n", buf
, n
);
4531 if (CHECK_AND_SKIP_PREFIX(p
, "+F:")) {
4535 if (strtoint(sstrsep(&p
, sep
), 0, ALGOR_NUM
, &alg
)) {
4537 for (j
= 0; j
< size_num
; ++j
)
4538 results
[alg
][j
] += atof(sstrsep(&p
, sep
));
4540 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F2:")) {
4541 tk
= sstrsep(&p
, sep
);
4542 if (strtoint(tk
, 0, OSSL_NELEM(rsa_results
), &k
)) {
4545 d
= atof(sstrsep(&p
, sep
));
4546 rsa_results
[k
][0] += d
;
4548 d
= atof(sstrsep(&p
, sep
));
4549 rsa_results
[k
][1] += d
;
4551 d
= atof(sstrsep(&p
, sep
));
4552 rsa_results
[k
][2] += d
;
4554 d
= atof(sstrsep(&p
, sep
));
4555 rsa_results
[k
][3] += d
;
4557 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F3:")) {
4558 tk
= sstrsep(&p
, sep
);
4559 if (strtoint(tk
, 0, OSSL_NELEM(dsa_results
), &k
)) {
4562 d
= atof(sstrsep(&p
, sep
));
4563 dsa_results
[k
][0] += d
;
4565 d
= atof(sstrsep(&p
, sep
));
4566 dsa_results
[k
][1] += d
;
4568 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F4:")) {
4569 tk
= sstrsep(&p
, sep
);
4570 if (strtoint(tk
, 0, OSSL_NELEM(ecdsa_results
), &k
)) {
4573 d
= atof(sstrsep(&p
, sep
));
4574 ecdsa_results
[k
][0] += d
;
4576 d
= atof(sstrsep(&p
, sep
));
4577 ecdsa_results
[k
][1] += d
;
4579 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F5:")) {
4580 tk
= sstrsep(&p
, sep
);
4581 if (strtoint(tk
, 0, OSSL_NELEM(ecdh_results
), &k
)) {
4584 d
= atof(sstrsep(&p
, sep
));
4585 ecdh_results
[k
][0] += d
;
4587 # ifndef OPENSSL_NO_ECX
4588 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F6:")) {
4589 tk
= sstrsep(&p
, sep
);
4590 if (strtoint(tk
, 0, OSSL_NELEM(eddsa_results
), &k
)) {
4594 d
= atof(sstrsep(&p
, sep
));
4595 eddsa_results
[k
][0] += d
;
4597 d
= atof(sstrsep(&p
, sep
));
4598 eddsa_results
[k
][1] += d
;
4600 # endif /* OPENSSL_NO_ECX */
4601 # ifndef OPENSSL_NO_SM2
4602 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F7:")) {
4603 tk
= sstrsep(&p
, sep
);
4604 if (strtoint(tk
, 0, OSSL_NELEM(sm2_results
), &k
)) {
4608 d
= atof(sstrsep(&p
, sep
));
4609 sm2_results
[k
][0] += d
;
4611 d
= atof(sstrsep(&p
, sep
));
4612 sm2_results
[k
][1] += d
;
4614 # endif /* OPENSSL_NO_SM2 */
4615 # ifndef OPENSSL_NO_DH
4616 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F8:")) {
4617 tk
= sstrsep(&p
, sep
);
4618 if (strtoint(tk
, 0, OSSL_NELEM(ffdh_results
), &k
)) {
4621 d
= atof(sstrsep(&p
, sep
));
4622 ffdh_results
[k
][0] += d
;
4624 # endif /* OPENSSL_NO_DH */
4625 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F9:")) {
4626 tk
= sstrsep(&p
, sep
);
4627 if (strtoint(tk
, 0, OSSL_NELEM(kems_results
), &k
)) {
4628 d
= atof(sstrsep(&p
, sep
));
4629 kems_results
[k
][0] += d
;
4631 d
= atof(sstrsep(&p
, sep
));
4632 kems_results
[k
][1] += d
;
4634 d
= atof(sstrsep(&p
, sep
));
4635 kems_results
[k
][2] += d
;
4637 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F10:")) {
4638 tk
= sstrsep(&p
, sep
);
4639 if (strtoint(tk
, 0, OSSL_NELEM(sigs_results
), &k
)) {
4640 d
= atof(sstrsep(&p
, sep
));
4641 sigs_results
[k
][0] += d
;
4643 d
= atof(sstrsep(&p
, sep
));
4644 sigs_results
[k
][1] += d
;
4646 d
= atof(sstrsep(&p
, sep
));
4647 sigs_results
[k
][2] += d
;
4649 } else if (!HAS_PREFIX(buf
, "+H:")) {
4650 BIO_printf(bio_err
, "Unknown type '%s' from child %d\n", buf
,
4658 for (n
= 0; n
< multi
; ++n
) {
4659 while (wait(&status
) == -1)
4660 if (errno
!= EINTR
) {
4661 BIO_printf(bio_err
, "Waitng for child failed with 0x%x\n",
4665 if (WIFEXITED(status
) && WEXITSTATUS(status
)) {
4666 BIO_printf(bio_err
, "Child exited with %d\n", WEXITSTATUS(status
));
4667 } else if (WIFSIGNALED(status
)) {
4668 BIO_printf(bio_err
, "Child terminated by signal %d\n",
4676 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
4677 const openssl_speed_sec_t
*seconds
)
4679 static const int mblengths_list
[] =
4680 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
4681 const int *mblengths
= mblengths_list
;
4682 int j
, count
, keylen
, num
= OSSL_NELEM(mblengths_list
), ciph_success
= 1;
4683 const char *alg_name
;
4684 unsigned char *inp
= NULL
, *out
= NULL
, *key
, no_key
[32], no_iv
[16];
4685 EVP_CIPHER_CTX
*ctx
= NULL
;
4688 if (lengths_single
) {
4689 mblengths
= &lengths_single
;
4693 inp
= app_malloc(mblengths
[num
- 1], "multiblock input buffer");
4694 out
= app_malloc(mblengths
[num
- 1] + 1024, "multiblock output buffer");
4695 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
4696 app_bail_out("failed to allocate cipher context\n");
4697 if (!EVP_EncryptInit_ex(ctx
, evp_cipher
, NULL
, NULL
, no_iv
))
4698 app_bail_out("failed to initialise cipher context\n");
4700 if ((keylen
= EVP_CIPHER_CTX_get_key_length(ctx
)) < 0) {
4701 BIO_printf(bio_err
, "Impossible negative key length: %d\n", keylen
);
4704 key
= app_malloc(keylen
, "evp_cipher key");
4705 if (EVP_CIPHER_CTX_rand_key(ctx
, key
) <= 0)
4706 app_bail_out("failed to generate random cipher key\n");
4707 if (!EVP_EncryptInit_ex(ctx
, NULL
, NULL
, key
, NULL
))
4708 app_bail_out("failed to set cipher key\n");
4709 OPENSSL_clear_free(key
, keylen
);
4711 if (EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_MAC_KEY
,
4712 sizeof(no_key
), no_key
) <= 0)
4713 app_bail_out("failed to set AEAD key\n");
4714 if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
4715 app_bail_out("failed to get cipher name\n");
4717 for (j
= 0; j
< num
; j
++) {
4718 print_message(alg_name
, mblengths
[j
], seconds
->sym
);
4720 for (count
= 0; run
&& count
< INT_MAX
; count
++) {
4721 unsigned char aad
[EVP_AEAD_TLS1_AAD_LEN
];
4722 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param
;
4723 size_t len
= mblengths
[j
];
4726 memset(aad
, 0, 8); /* avoid uninitialized values */
4727 aad
[8] = 23; /* SSL3_RT_APPLICATION_DATA */
4728 aad
[9] = 3; /* version */
4730 aad
[11] = 0; /* length */
4732 mb_param
.out
= NULL
;
4735 mb_param
.interleave
= 8;
4737 packlen
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD
,
4738 sizeof(mb_param
), &mb_param
);
4744 (void)EVP_CIPHER_CTX_ctrl(ctx
,
4745 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT
,
4746 sizeof(mb_param
), &mb_param
);
4750 RAND_bytes(out
, 16);
4752 aad
[11] = (unsigned char)(len
>> 8);
4753 aad
[12] = (unsigned char)(len
);
4754 pad
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_TLS1_AAD
,
4755 EVP_AEAD_TLS1_AAD_LEN
, aad
);
4756 ciph_success
= EVP_Cipher(ctx
, out
, inp
, len
+ pad
);
4760 BIO_printf(bio_err
, mr
? "+R:%d:%s:%f\n"
4761 : "%d %s ops in %.2fs\n", count
, "evp", d
);
4762 if ((ciph_success
<= 0) && (mr
== 0))
4763 BIO_printf(bio_err
, "Error performing cipher op\n");
4764 results
[D_EVP
][j
] = ((double)count
) / d
* mblengths
[j
];
4768 fprintf(stdout
, "+H");
4769 for (j
= 0; j
< num
; j
++)
4770 fprintf(stdout
, ":%d", mblengths
[j
]);
4771 fprintf(stdout
, "\n");
4772 fprintf(stdout
, "+F:%d:%s", D_EVP
, alg_name
);
4773 for (j
= 0; j
< num
; j
++)
4774 fprintf(stdout
, ":%.2f", results
[D_EVP
][j
]);
4775 fprintf(stdout
, "\n");
4778 "The 'numbers' are in 1000s of bytes per second processed.\n");
4779 fprintf(stdout
, "type ");
4780 for (j
= 0; j
< num
; j
++)
4781 fprintf(stdout
, "%7d bytes", mblengths
[j
]);
4782 fprintf(stdout
, "\n");
4783 fprintf(stdout
, "%-24s", alg_name
);
4785 for (j
= 0; j
< num
; j
++) {
4786 if (results
[D_EVP
][j
] > 10000)
4787 fprintf(stdout
, " %11.2fk", results
[D_EVP
][j
] / 1e3
);
4789 fprintf(stdout
, " %11.2f ", results
[D_EVP
][j
]);
4791 fprintf(stdout
, "\n");
4797 EVP_CIPHER_CTX_free(ctx
);