2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
13 #define PKEY_SECONDS 10
15 #define RSA_SECONDS PKEY_SECONDS
16 #define DSA_SECONDS PKEY_SECONDS
17 #define ECDSA_SECONDS PKEY_SECONDS
18 #define ECDH_SECONDS PKEY_SECONDS
19 #define EdDSA_SECONDS PKEY_SECONDS
20 #define SM2_SECONDS PKEY_SECONDS
21 #define FFDH_SECONDS PKEY_SECONDS
23 /* We need to use some deprecated APIs */
24 #define OPENSSL_SUPPRESS_DEPRECATED
32 #include "internal/numbers.h"
33 #include <openssl/crypto.h>
34 #include <openssl/rand.h>
35 #include <openssl/err.h>
36 #include <openssl/evp.h>
37 #include <openssl/objects.h>
38 #include <openssl/core_names.h>
39 #include <openssl/async.h>
40 #if !defined(OPENSSL_SYS_MSDOS)
45 # if defined(OPENSSL_TANDEM_FLOSS)
46 # include <floss.h(floss_fork)>
54 #include <openssl/bn.h>
55 #include <openssl/rsa.h>
56 #include "./testrsa.h"
58 # include <openssl/dh.h>
60 #include <openssl/x509.h>
61 #include <openssl/dsa.h>
62 #include "./testdsa.h"
63 #include <openssl/modes.h>
66 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
79 #define MAX_MISALIGNMENT 63
80 #define MAX_ECDH_SIZE 256
82 #define MAX_FFDH_SIZE 1024
84 #ifndef RSA_DEFAULT_PRIME_NUM
85 # define RSA_DEFAULT_PRIME_NUM 2
88 typedef struct openssl_speed_sec_st
{
97 } openssl_speed_sec_t
;
99 static volatile int run
= 0;
101 static int mr
= 0; /* machine-readeable output format to merge fork results */
102 static int usertime
= 1;
104 static double Time_F(int s
);
105 static void print_message(const char *s
, long num
, int length
, int tm
);
106 static void pkey_print_message(const char *str
, const char *str2
,
107 long num
, unsigned int bits
, int sec
);
108 static void print_result(int alg
, int run_no
, int count
, double time_used
);
110 static int do_multi(int multi
, int size_num
);
113 static const int lengths_list
[] = {
114 16, 64, 256, 1024, 8 * 1024, 16 * 1024
116 #define SIZE_NUM OSSL_NELEM(lengths_list)
117 static const int *lengths
= lengths_list
;
119 static const int aead_lengths_list
[] = {
120 2, 31, 136, 1024, 8 * 1024, 16 * 1024
128 static void alarmed(int sig
)
130 signal(SIGALRM
, alarmed
);
134 static double Time_F(int s
)
136 double ret
= app_tminterval(s
, usertime
);
142 #elif defined(_WIN32)
146 static unsigned int lapse
;
147 static volatile unsigned int schlock
;
148 static void alarm_win32(unsigned int secs
)
153 # define alarm alarm_win32
155 static DWORD WINAPI
sleepy(VOID
* arg
)
163 static double Time_F(int s
)
170 thr
= CreateThread(NULL
, 4096, sleepy
, NULL
, 0, NULL
);
172 DWORD err
= GetLastError();
173 BIO_printf(bio_err
, "unable to CreateThread (%lu)", err
);
177 Sleep(0); /* scheduler spinlock */
178 ret
= app_tminterval(s
, usertime
);
180 ret
= app_tminterval(s
, usertime
);
182 TerminateThread(thr
, 0);
189 # error "SIGALRM not defined and the platform is not Windows"
192 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
193 const openssl_speed_sec_t
*seconds
);
195 static int opt_found(const char *name
, unsigned int *result
,
196 const OPT_PAIR pairs
[], unsigned int nbelem
)
200 for (idx
= 0; idx
< nbelem
; ++idx
, pairs
++)
201 if (strcmp(name
, pairs
->name
) == 0) {
202 *result
= pairs
->retval
;
207 #define opt_found(value, pairs, result)\
208 opt_found(value, result, pairs, OSSL_NELEM(pairs))
210 typedef enum OPTION_choice
{
212 OPT_ELAPSED
, OPT_EVP
, OPT_HMAC
, OPT_DECRYPT
, OPT_ENGINE
, OPT_MULTI
,
213 OPT_MR
, OPT_MB
, OPT_MISALIGN
, OPT_ASYNCJOBS
, OPT_R_ENUM
, OPT_PROV_ENUM
,
214 OPT_PRIMES
, OPT_SECONDS
, OPT_BYTES
, OPT_AEAD
, OPT_CMAC
217 const OPTIONS speed_options
[] = {
218 {OPT_HELP_STR
, 1, '-',
219 "Usage: %s [options] [algorithm...]\n"
220 "All +int options consider prefix '0' as base-8 input, "
221 "prefix '0x'/'0X' as base-16 input.\n"
224 OPT_SECTION("General"),
225 {"help", OPT_HELP
, '-', "Display this summary"},
227 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
228 {"mr", OPT_MR
, '-', "Produce machine readable output"},
230 {"multi", OPT_MULTI
, 'p', "Run benchmarks in parallel"},
232 #ifndef OPENSSL_NO_ASYNC
233 {"async_jobs", OPT_ASYNCJOBS
, 'p',
234 "Enable async mode and start specified number of jobs"},
236 #ifndef OPENSSL_NO_ENGINE
237 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
239 {"primes", OPT_PRIMES
, 'p', "Specify number of primes (for RSA only)"},
241 OPT_SECTION("Selection"),
242 {"evp", OPT_EVP
, 's', "Use EVP-named cipher or digest"},
243 {"hmac", OPT_HMAC
, 's', "HMAC using EVP-named digest"},
244 {"cmac", OPT_CMAC
, 's', "CMAC using EVP-named cipher"},
245 {"decrypt", OPT_DECRYPT
, '-',
246 "Time decryption instead of encryption (only EVP)"},
247 {"aead", OPT_AEAD
, '-',
248 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
250 OPT_SECTION("Timing"),
251 {"elapsed", OPT_ELAPSED
, '-',
252 "Use wall-clock time instead of CPU user time as divisor"},
253 {"seconds", OPT_SECONDS
, 'p',
254 "Run benchmarks for specified amount of seconds"},
255 {"bytes", OPT_BYTES
, 'p',
256 "Run [non-PKI] benchmarks on custom-sized buffer"},
257 {"misalign", OPT_MISALIGN
, 'p',
258 "Use specified offset to mis-align buffers"},
264 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
269 D_MD2
, D_MDC2
, D_MD4
, D_MD5
, D_SHA1
, D_RMD160
,
270 D_SHA256
, D_SHA512
, D_WHIRLPOOL
, D_HMAC
,
271 D_CBC_DES
, D_EDE3_DES
, D_RC4
, D_CBC_IDEA
, D_CBC_SEED
,
272 D_CBC_RC2
, D_CBC_RC5
, D_CBC_BF
, D_CBC_CAST
,
273 D_CBC_128_AES
, D_CBC_192_AES
, D_CBC_256_AES
,
274 D_CBC_128_CML
, D_CBC_192_CML
, D_CBC_256_CML
,
275 D_EVP
, D_GHASH
, D_RAND
, D_EVP_CMAC
, ALGOR_NUM
277 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
278 static const char *names
[ALGOR_NUM
] = {
279 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
280 "sha256", "sha512", "whirlpool", "hmac(md5)",
281 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
282 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
283 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
284 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
285 "evp", "ghash", "rand", "cmac"
288 /* list of configured algorithm (remaining), with some few alias */
289 static const OPT_PAIR doit_choices
[] = {
296 {"sha256", D_SHA256
},
297 {"sha512", D_SHA512
},
298 {"whirlpool", D_WHIRLPOOL
},
299 {"ripemd", D_RMD160
},
300 {"rmd160", D_RMD160
},
301 {"ripemd160", D_RMD160
},
303 {"des-cbc", D_CBC_DES
},
304 {"des-ede3", D_EDE3_DES
},
305 {"aes-128-cbc", D_CBC_128_AES
},
306 {"aes-192-cbc", D_CBC_192_AES
},
307 {"aes-256-cbc", D_CBC_256_AES
},
308 {"camellia-128-cbc", D_CBC_128_CML
},
309 {"camellia-192-cbc", D_CBC_192_CML
},
310 {"camellia-256-cbc", D_CBC_256_CML
},
311 {"rc2-cbc", D_CBC_RC2
},
313 {"rc5-cbc", D_CBC_RC5
},
315 {"idea-cbc", D_CBC_IDEA
},
316 {"idea", D_CBC_IDEA
},
317 {"seed-cbc", D_CBC_SEED
},
318 {"seed", D_CBC_SEED
},
319 {"bf-cbc", D_CBC_BF
},
320 {"blowfish", D_CBC_BF
},
322 {"cast-cbc", D_CBC_CAST
},
323 {"cast", D_CBC_CAST
},
324 {"cast5", D_CBC_CAST
},
329 static double results
[ALGOR_NUM
][SIZE_NUM
];
331 enum { R_DSA_512
, R_DSA_1024
, R_DSA_2048
, DSA_NUM
};
332 static const OPT_PAIR dsa_choices
[DSA_NUM
] = {
333 {"dsa512", R_DSA_512
},
334 {"dsa1024", R_DSA_1024
},
335 {"dsa2048", R_DSA_2048
}
337 static double dsa_results
[DSA_NUM
][2]; /* 2 ops: sign then verify */
340 R_RSA_512
, R_RSA_1024
, R_RSA_2048
, R_RSA_3072
, R_RSA_4096
, R_RSA_7680
,
343 static const OPT_PAIR rsa_choices
[RSA_NUM
] = {
344 {"rsa512", R_RSA_512
},
345 {"rsa1024", R_RSA_1024
},
346 {"rsa2048", R_RSA_2048
},
347 {"rsa3072", R_RSA_3072
},
348 {"rsa4096", R_RSA_4096
},
349 {"rsa7680", R_RSA_7680
},
350 {"rsa15360", R_RSA_15360
}
353 static double rsa_results
[RSA_NUM
][2]; /* 2 ops: sign then verify */
355 #ifndef OPENSSL_NO_DH
357 R_FFDH_2048
, R_FFDH_3072
, R_FFDH_4096
, R_FFDH_6144
, R_FFDH_8192
, FFDH_NUM
360 static const OPT_PAIR ffdh_choices
[FFDH_NUM
] = {
361 {"ffdh2048", R_FFDH_2048
},
362 {"ffdh3072", R_FFDH_3072
},
363 {"ffdh4096", R_FFDH_4096
},
364 {"ffdh6144", R_FFDH_6144
},
365 {"ffdh8192", R_FFDH_8192
},
368 static double ffdh_results
[FFDH_NUM
][1]; /* 1 op: derivation */
369 #endif /* OPENSSL_NO_DH */
372 R_EC_P160
, R_EC_P192
, R_EC_P224
, R_EC_P256
, R_EC_P384
, R_EC_P521
,
373 #ifndef OPENSSL_NO_EC2M
374 R_EC_K163
, R_EC_K233
, R_EC_K283
, R_EC_K409
, R_EC_K571
,
375 R_EC_B163
, R_EC_B233
, R_EC_B283
, R_EC_B409
, R_EC_B571
,
377 R_EC_BRP256R1
, R_EC_BRP256T1
, R_EC_BRP384R1
, R_EC_BRP384T1
,
378 R_EC_BRP512R1
, R_EC_BRP512T1
, ECDSA_NUM
380 /* list of ecdsa curves */
381 static const OPT_PAIR ecdsa_choices
[ECDSA_NUM
] = {
382 {"ecdsap160", R_EC_P160
},
383 {"ecdsap192", R_EC_P192
},
384 {"ecdsap224", R_EC_P224
},
385 {"ecdsap256", R_EC_P256
},
386 {"ecdsap384", R_EC_P384
},
387 {"ecdsap521", R_EC_P521
},
388 #ifndef OPENSSL_NO_EC2M
389 {"ecdsak163", R_EC_K163
},
390 {"ecdsak233", R_EC_K233
},
391 {"ecdsak283", R_EC_K283
},
392 {"ecdsak409", R_EC_K409
},
393 {"ecdsak571", R_EC_K571
},
394 {"ecdsab163", R_EC_B163
},
395 {"ecdsab233", R_EC_B233
},
396 {"ecdsab283", R_EC_B283
},
397 {"ecdsab409", R_EC_B409
},
398 {"ecdsab571", R_EC_B571
},
400 {"ecdsabrp256r1", R_EC_BRP256R1
},
401 {"ecdsabrp256t1", R_EC_BRP256T1
},
402 {"ecdsabrp384r1", R_EC_BRP384R1
},
403 {"ecdsabrp384t1", R_EC_BRP384T1
},
404 {"ecdsabrp512r1", R_EC_BRP512R1
},
405 {"ecdsabrp512t1", R_EC_BRP512T1
}
407 enum { R_EC_X25519
= ECDSA_NUM
, R_EC_X448
, EC_NUM
};
408 /* list of ecdh curves, extension of |ecdsa_choices| list above */
409 static const OPT_PAIR ecdh_choices
[EC_NUM
] = {
410 {"ecdhp160", R_EC_P160
},
411 {"ecdhp192", R_EC_P192
},
412 {"ecdhp224", R_EC_P224
},
413 {"ecdhp256", R_EC_P256
},
414 {"ecdhp384", R_EC_P384
},
415 {"ecdhp521", R_EC_P521
},
416 #ifndef OPENSSL_NO_EC2M
417 {"ecdhk163", R_EC_K163
},
418 {"ecdhk233", R_EC_K233
},
419 {"ecdhk283", R_EC_K283
},
420 {"ecdhk409", R_EC_K409
},
421 {"ecdhk571", R_EC_K571
},
422 {"ecdhb163", R_EC_B163
},
423 {"ecdhb233", R_EC_B233
},
424 {"ecdhb283", R_EC_B283
},
425 {"ecdhb409", R_EC_B409
},
426 {"ecdhb571", R_EC_B571
},
428 {"ecdhbrp256r1", R_EC_BRP256R1
},
429 {"ecdhbrp256t1", R_EC_BRP256T1
},
430 {"ecdhbrp384r1", R_EC_BRP384R1
},
431 {"ecdhbrp384t1", R_EC_BRP384T1
},
432 {"ecdhbrp512r1", R_EC_BRP512R1
},
433 {"ecdhbrp512t1", R_EC_BRP512T1
},
434 {"ecdhx25519", R_EC_X25519
},
435 {"ecdhx448", R_EC_X448
}
438 static double ecdh_results
[EC_NUM
][1]; /* 1 op: derivation */
439 static double ecdsa_results
[ECDSA_NUM
][2]; /* 2 ops: sign then verify */
441 enum { R_EC_Ed25519
, R_EC_Ed448
, EdDSA_NUM
};
442 static const OPT_PAIR eddsa_choices
[EdDSA_NUM
] = {
443 {"ed25519", R_EC_Ed25519
},
444 {"ed448", R_EC_Ed448
}
447 static double eddsa_results
[EdDSA_NUM
][2]; /* 2 ops: sign then verify */
449 #ifndef OPENSSL_NO_SM2
450 enum { R_EC_CURVESM2
, SM2_NUM
};
451 static const OPT_PAIR sm2_choices
[SM2_NUM
] = {
452 {"curveSM2", R_EC_CURVESM2
}
454 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
455 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
456 static double sm2_results
[SM2_NUM
][2]; /* 2 ops: sign then verify */
457 #endif /* OPENSSL_NO_SM2 */
459 #define COND(unused_cond) (run && count < INT_MAX)
460 #define COUNT(d) (count)
462 typedef struct loopargs_st
{
463 ASYNC_JOB
*inprogress_job
;
464 ASYNC_WAIT_CTX
*wait_ctx
;
467 unsigned char *buf_malloc
;
468 unsigned char *buf2_malloc
;
472 EVP_PKEY_CTX
*rsa_sign_ctx
[RSA_NUM
];
473 EVP_PKEY_CTX
*rsa_verify_ctx
[RSA_NUM
];
474 EVP_PKEY_CTX
*dsa_sign_ctx
[DSA_NUM
];
475 EVP_PKEY_CTX
*dsa_verify_ctx
[DSA_NUM
];
476 EVP_PKEY_CTX
*ecdsa_sign_ctx
[ECDSA_NUM
];
477 EVP_PKEY_CTX
*ecdsa_verify_ctx
[ECDSA_NUM
];
478 EVP_PKEY_CTX
*ecdh_ctx
[EC_NUM
];
479 EVP_MD_CTX
*eddsa_ctx
[EdDSA_NUM
];
480 EVP_MD_CTX
*eddsa_ctx2
[EdDSA_NUM
];
481 #ifndef OPENSSL_NO_SM2
482 EVP_MD_CTX
*sm2_ctx
[SM2_NUM
];
483 EVP_MD_CTX
*sm2_vfy_ctx
[SM2_NUM
];
484 EVP_PKEY
*sm2_pkey
[SM2_NUM
];
486 unsigned char *secret_a
;
487 unsigned char *secret_b
;
488 size_t outlen
[EC_NUM
];
489 #ifndef OPENSSL_NO_DH
490 EVP_PKEY_CTX
*ffdh_ctx
[FFDH_NUM
];
491 unsigned char *secret_ff_a
;
492 unsigned char *secret_ff_b
;
497 static int run_benchmark(int async_jobs
, int (*loop_function
) (void *),
498 loopargs_t
* loopargs
);
500 static unsigned int testnum
;
502 /* Nb of iterations to do per algorithm and key-size */
503 static long c
[ALGOR_NUM
][SIZE_NUM
];
505 static char *evp_mac_mdname
= "md5";
506 static char *evp_hmac_name
= NULL
;
507 static const char *evp_md_name
= NULL
;
508 static char *evp_mac_ciphername
= "aes-128-cbc";
509 static char *evp_cmac_name
= NULL
;
511 static int have_md(const char *name
)
516 if (opt_md_silent(name
, &md
)) {
517 EVP_MD_CTX
*ctx
= EVP_MD_CTX_new();
519 if (ctx
!= NULL
&& EVP_DigestInit(ctx
, md
) > 0)
521 EVP_MD_CTX_free(ctx
);
527 static int have_cipher(const char *name
)
530 EVP_CIPHER
*cipher
= NULL
;
532 if (opt_cipher_silent(name
, &cipher
)) {
533 EVP_CIPHER_CTX
*ctx
= EVP_CIPHER_CTX_new();
536 && EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1) > 0)
538 EVP_CIPHER_CTX_free(ctx
);
539 EVP_CIPHER_free(cipher
);
544 static int EVP_Digest_loop(const char *mdname
, int algindex
, void *args
)
546 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
547 unsigned char *buf
= tempargs
->buf
;
548 unsigned char digest
[EVP_MAX_MD_SIZE
];
552 if (!opt_md_silent(mdname
, &md
))
554 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
555 if (!EVP_Digest(buf
, (size_t)lengths
[testnum
], digest
, NULL
, md
,
565 static int EVP_Digest_md_loop(void *args
)
567 return EVP_Digest_loop(evp_md_name
, D_EVP
, args
);
570 static int EVP_Digest_MD2_loop(void *args
)
572 return EVP_Digest_loop("md2", D_MD2
, args
);
575 static int EVP_Digest_MDC2_loop(void *args
)
577 return EVP_Digest_loop("mdc2", D_MDC2
, args
);
580 static int EVP_Digest_MD4_loop(void *args
)
582 return EVP_Digest_loop("md4", D_MD4
, args
);
585 static int MD5_loop(void *args
)
587 return EVP_Digest_loop("md5", D_MD5
, args
);
590 static int EVP_MAC_loop(int algindex
, void *args
)
592 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
593 unsigned char *buf
= tempargs
->buf
;
594 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
595 unsigned char mac
[EVP_MAX_MD_SIZE
];
598 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
601 if (!EVP_MAC_init(mctx
, NULL
, 0, NULL
)
602 || !EVP_MAC_update(mctx
, buf
, lengths
[testnum
])
603 || !EVP_MAC_final(mctx
, mac
, &outl
, sizeof(mac
)))
609 static int HMAC_loop(void *args
)
611 return EVP_MAC_loop(D_HMAC
, args
);
614 static int CMAC_loop(void *args
)
616 return EVP_MAC_loop(D_EVP_CMAC
, args
);
619 static int SHA1_loop(void *args
)
621 return EVP_Digest_loop("sha1", D_SHA1
, args
);
624 static int SHA256_loop(void *args
)
626 return EVP_Digest_loop("sha256", D_SHA256
, args
);
629 static int SHA512_loop(void *args
)
631 return EVP_Digest_loop("sha512", D_SHA512
, args
);
634 static int WHIRLPOOL_loop(void *args
)
636 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL
, args
);
639 static int EVP_Digest_RMD160_loop(void *args
)
641 return EVP_Digest_loop("ripemd160", D_RMD160
, args
);
646 static int EVP_Cipher_loop(void *args
)
648 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
649 unsigned char *buf
= tempargs
->buf
;
652 if (tempargs
->ctx
== NULL
)
654 for (count
= 0; COND(c
[algindex
][testnum
]); count
++)
655 if (EVP_Cipher(tempargs
->ctx
, buf
, buf
, (size_t)lengths
[testnum
]) <= 0)
660 static int GHASH_loop(void *args
)
662 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
663 unsigned char *buf
= tempargs
->buf
;
664 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
667 /* just do the update in the loop to be comparable with 1.1.1 */
668 for (count
= 0; COND(c
[D_GHASH
][testnum
]); count
++) {
669 if (!EVP_MAC_update(mctx
, buf
, lengths
[testnum
]))
675 #define MAX_BLOCK_SIZE 128
677 static unsigned char iv
[2 * MAX_BLOCK_SIZE
/ 8];
679 static EVP_CIPHER_CTX
*init_evp_cipher_ctx(const char *ciphername
,
680 const unsigned char *key
,
683 EVP_CIPHER_CTX
*ctx
= NULL
;
684 EVP_CIPHER
*cipher
= NULL
;
686 if (!opt_cipher_silent(ciphername
, &cipher
))
689 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
692 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1)) {
693 EVP_CIPHER_CTX_free(ctx
);
698 if (!EVP_CIPHER_CTX_set_key_length(ctx
, keylen
)) {
699 EVP_CIPHER_CTX_free(ctx
);
704 if (!EVP_CipherInit_ex(ctx
, NULL
, NULL
, key
, iv
, 1)) {
705 EVP_CIPHER_CTX_free(ctx
);
711 EVP_CIPHER_free(cipher
);
715 static int RAND_bytes_loop(void *args
)
717 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
718 unsigned char *buf
= tempargs
->buf
;
721 for (count
= 0; COND(c
[D_RAND
][testnum
]); count
++)
722 RAND_bytes(buf
, lengths
[testnum
]);
726 static int decrypt
= 0;
727 static int EVP_Update_loop(void *args
)
729 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
730 unsigned char *buf
= tempargs
->buf
;
731 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
735 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
736 rc
= EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
738 /* reset iv in case of counter overflow */
739 (void)EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
743 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
744 rc
= EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
746 /* reset iv in case of counter overflow */
747 (void)EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
752 EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
754 EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
759 * CCM does not support streaming. For the purpose of performance measurement,
760 * each message is encrypted using the same (key,iv)-pair. Do not use this
761 * code in your application.
763 static int EVP_Update_loop_ccm(void *args
)
765 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
766 unsigned char *buf
= tempargs
->buf
;
767 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
769 unsigned char tag
[12];
772 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
773 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
, sizeof(tag
),
776 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
777 /* counter is reset on every update */
778 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
781 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
782 /* restore iv length field */
783 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, NULL
, lengths
[testnum
]);
784 /* counter is reset on every update */
785 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
789 (void)EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
791 (void)EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
796 * To make AEAD benchmarking more relevant perform TLS-like operations,
797 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
798 * payload length is not actually limited by 16KB...
800 static int EVP_Update_loop_aead(void *args
)
802 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
803 unsigned char *buf
= tempargs
->buf
;
804 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
806 unsigned char aad
[13] = { 0xcc };
807 unsigned char faketag
[16] = { 0xcc };
810 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
811 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
812 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
,
813 sizeof(faketag
), faketag
);
814 (void)EVP_DecryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
815 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
816 (void)EVP_DecryptFinal_ex(ctx
, buf
+ outl
, &outl
);
819 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
820 (void)EVP_EncryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
821 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
822 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
823 (void)EVP_EncryptFinal_ex(ctx
, buf
+ outl
, &outl
);
829 static long rsa_c
[RSA_NUM
][2]; /* # RSA iteration test */
831 static int RSA_sign_loop(void *args
)
833 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
834 unsigned char *buf
= tempargs
->buf
;
835 unsigned char *buf2
= tempargs
->buf2
;
836 size_t *rsa_num
= &tempargs
->sigsize
;
837 EVP_PKEY_CTX
**rsa_sign_ctx
= tempargs
->rsa_sign_ctx
;
840 for (count
= 0; COND(rsa_c
[testnum
][0]); count
++) {
841 *rsa_num
= tempargs
->buflen
;
842 ret
= EVP_PKEY_sign(rsa_sign_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
844 BIO_printf(bio_err
, "RSA sign failure\n");
845 ERR_print_errors(bio_err
);
853 static int RSA_verify_loop(void *args
)
855 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
856 unsigned char *buf
= tempargs
->buf
;
857 unsigned char *buf2
= tempargs
->buf2
;
858 size_t rsa_num
= tempargs
->sigsize
;
859 EVP_PKEY_CTX
**rsa_verify_ctx
= tempargs
->rsa_verify_ctx
;
862 for (count
= 0; COND(rsa_c
[testnum
][1]); count
++) {
863 ret
= EVP_PKEY_verify(rsa_verify_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
865 BIO_printf(bio_err
, "RSA verify failure\n");
866 ERR_print_errors(bio_err
);
874 #ifndef OPENSSL_NO_DH
875 static long ffdh_c
[FFDH_NUM
][1];
877 static int FFDH_derive_key_loop(void *args
)
879 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
880 EVP_PKEY_CTX
*ffdh_ctx
= tempargs
->ffdh_ctx
[testnum
];
881 unsigned char *derived_secret
= tempargs
->secret_ff_a
;
882 size_t outlen
= MAX_FFDH_SIZE
;
885 for (count
= 0; COND(ffdh_c
[testnum
][0]); count
++)
886 EVP_PKEY_derive(ffdh_ctx
, derived_secret
, &outlen
);
889 #endif /* OPENSSL_NO_DH */
891 static long dsa_c
[DSA_NUM
][2];
892 static int DSA_sign_loop(void *args
)
894 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
895 unsigned char *buf
= tempargs
->buf
;
896 unsigned char *buf2
= tempargs
->buf2
;
897 size_t *dsa_num
= &tempargs
->sigsize
;
898 EVP_PKEY_CTX
**dsa_sign_ctx
= tempargs
->dsa_sign_ctx
;
901 for (count
= 0; COND(dsa_c
[testnum
][0]); count
++) {
902 *dsa_num
= tempargs
->buflen
;
903 ret
= EVP_PKEY_sign(dsa_sign_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
905 BIO_printf(bio_err
, "DSA sign failure\n");
906 ERR_print_errors(bio_err
);
914 static int DSA_verify_loop(void *args
)
916 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
917 unsigned char *buf
= tempargs
->buf
;
918 unsigned char *buf2
= tempargs
->buf2
;
919 size_t dsa_num
= tempargs
->sigsize
;
920 EVP_PKEY_CTX
**dsa_verify_ctx
= tempargs
->dsa_verify_ctx
;
923 for (count
= 0; COND(dsa_c
[testnum
][1]); count
++) {
924 ret
= EVP_PKEY_verify(dsa_verify_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
926 BIO_printf(bio_err
, "DSA verify failure\n");
927 ERR_print_errors(bio_err
);
935 static long ecdsa_c
[ECDSA_NUM
][2];
936 static int ECDSA_sign_loop(void *args
)
938 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
939 unsigned char *buf
= tempargs
->buf
;
940 unsigned char *buf2
= tempargs
->buf2
;
941 size_t *ecdsa_num
= &tempargs
->sigsize
;
942 EVP_PKEY_CTX
**ecdsa_sign_ctx
= tempargs
->ecdsa_sign_ctx
;
945 for (count
= 0; COND(ecdsa_c
[testnum
][0]); count
++) {
946 *ecdsa_num
= tempargs
->buflen
;
947 ret
= EVP_PKEY_sign(ecdsa_sign_ctx
[testnum
], buf2
, ecdsa_num
, buf
, 20);
949 BIO_printf(bio_err
, "ECDSA sign failure\n");
950 ERR_print_errors(bio_err
);
958 static int ECDSA_verify_loop(void *args
)
960 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
961 unsigned char *buf
= tempargs
->buf
;
962 unsigned char *buf2
= tempargs
->buf2
;
963 size_t ecdsa_num
= tempargs
->sigsize
;
964 EVP_PKEY_CTX
**ecdsa_verify_ctx
= tempargs
->ecdsa_verify_ctx
;
967 for (count
= 0; COND(ecdsa_c
[testnum
][1]); count
++) {
968 ret
= EVP_PKEY_verify(ecdsa_verify_ctx
[testnum
], buf2
, ecdsa_num
,
971 BIO_printf(bio_err
, "ECDSA verify failure\n");
972 ERR_print_errors(bio_err
);
980 /* ******************************************************************** */
981 static long ecdh_c
[EC_NUM
][1];
983 static int ECDH_EVP_derive_key_loop(void *args
)
985 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
986 EVP_PKEY_CTX
*ctx
= tempargs
->ecdh_ctx
[testnum
];
987 unsigned char *derived_secret
= tempargs
->secret_a
;
989 size_t *outlen
= &(tempargs
->outlen
[testnum
]);
991 for (count
= 0; COND(ecdh_c
[testnum
][0]); count
++)
992 EVP_PKEY_derive(ctx
, derived_secret
, outlen
);
997 static long eddsa_c
[EdDSA_NUM
][2];
998 static int EdDSA_sign_loop(void *args
)
1000 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1001 unsigned char *buf
= tempargs
->buf
;
1002 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx
;
1003 unsigned char *eddsasig
= tempargs
->buf2
;
1004 size_t *eddsasigsize
= &tempargs
->sigsize
;
1007 for (count
= 0; COND(eddsa_c
[testnum
][0]); count
++) {
1008 ret
= EVP_DigestSign(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1010 BIO_printf(bio_err
, "EdDSA sign failure\n");
1011 ERR_print_errors(bio_err
);
1019 static int EdDSA_verify_loop(void *args
)
1021 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1022 unsigned char *buf
= tempargs
->buf
;
1023 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx2
;
1024 unsigned char *eddsasig
= tempargs
->buf2
;
1025 size_t eddsasigsize
= tempargs
->sigsize
;
1028 for (count
= 0; COND(eddsa_c
[testnum
][1]); count
++) {
1029 ret
= EVP_DigestVerify(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1031 BIO_printf(bio_err
, "EdDSA verify failure\n");
1032 ERR_print_errors(bio_err
);
1040 #ifndef OPENSSL_NO_SM2
1041 static long sm2_c
[SM2_NUM
][2];
1042 static int SM2_sign_loop(void *args
)
1044 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1045 unsigned char *buf
= tempargs
->buf
;
1046 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_ctx
;
1047 unsigned char *sm2sig
= tempargs
->buf2
;
1050 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1051 const size_t max_size
= EVP_PKEY_get_size(sm2_pkey
[testnum
]);
1053 for (count
= 0; COND(sm2_c
[testnum
][0]); count
++) {
1054 sm2sigsize
= max_size
;
1056 if (!EVP_DigestSignInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1057 NULL
, sm2_pkey
[testnum
])) {
1058 BIO_printf(bio_err
, "SM2 init sign failure\n");
1059 ERR_print_errors(bio_err
);
1063 ret
= EVP_DigestSign(sm2ctx
[testnum
], sm2sig
, &sm2sigsize
,
1066 BIO_printf(bio_err
, "SM2 sign failure\n");
1067 ERR_print_errors(bio_err
);
1071 /* update the latest returned size and always use the fixed buffer size */
1072 tempargs
->sigsize
= sm2sigsize
;
1078 static int SM2_verify_loop(void *args
)
1080 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1081 unsigned char *buf
= tempargs
->buf
;
1082 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_vfy_ctx
;
1083 unsigned char *sm2sig
= tempargs
->buf2
;
1084 size_t sm2sigsize
= tempargs
->sigsize
;
1086 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1088 for (count
= 0; COND(sm2_c
[testnum
][1]); count
++) {
1089 if (!EVP_DigestVerifyInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1090 NULL
, sm2_pkey
[testnum
])) {
1091 BIO_printf(bio_err
, "SM2 verify init failure\n");
1092 ERR_print_errors(bio_err
);
1096 ret
= EVP_DigestVerify(sm2ctx
[testnum
], sm2sig
, sm2sigsize
,
1099 BIO_printf(bio_err
, "SM2 verify failure\n");
1100 ERR_print_errors(bio_err
);
1107 #endif /* OPENSSL_NO_SM2 */
1109 static int run_benchmark(int async_jobs
,
1110 int (*loop_function
) (void *), loopargs_t
* loopargs
)
1112 int job_op_count
= 0;
1113 int total_op_count
= 0;
1114 int num_inprogress
= 0;
1115 int error
= 0, i
= 0, ret
= 0;
1116 OSSL_ASYNC_FD job_fd
= 0;
1117 size_t num_job_fds
= 0;
1119 if (async_jobs
== 0) {
1120 return loop_function((void *)&loopargs
);
1123 for (i
= 0; i
< async_jobs
&& !error
; i
++) {
1124 loopargs_t
*looparg_item
= loopargs
+ i
;
1126 /* Copy pointer content (looparg_t item address) into async context */
1127 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
, loopargs
[i
].wait_ctx
,
1128 &job_op_count
, loop_function
,
1129 (void *)&looparg_item
, sizeof(looparg_item
));
1135 if (job_op_count
== -1) {
1138 total_op_count
+= job_op_count
;
1143 BIO_printf(bio_err
, "Failure in the job\n");
1144 ERR_print_errors(bio_err
);
1150 while (num_inprogress
> 0) {
1151 #if defined(OPENSSL_SYS_WINDOWS)
1153 #elif defined(OPENSSL_SYS_UNIX)
1154 int select_result
= 0;
1155 OSSL_ASYNC_FD max_fd
= 0;
1158 FD_ZERO(&waitfdset
);
1160 for (i
= 0; i
< async_jobs
&& num_inprogress
> 0; i
++) {
1161 if (loopargs
[i
].inprogress_job
== NULL
)
1164 if (!ASYNC_WAIT_CTX_get_all_fds
1165 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1166 || num_job_fds
> 1) {
1167 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1168 ERR_print_errors(bio_err
);
1172 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1174 FD_SET(job_fd
, &waitfdset
);
1175 if (job_fd
> max_fd
)
1179 if (max_fd
>= (OSSL_ASYNC_FD
)FD_SETSIZE
) {
1181 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1182 "Decrease the value of async_jobs\n",
1183 max_fd
, FD_SETSIZE
);
1184 ERR_print_errors(bio_err
);
1189 select_result
= select(max_fd
+ 1, &waitfdset
, NULL
, NULL
, NULL
);
1190 if (select_result
== -1 && errno
== EINTR
)
1193 if (select_result
== -1) {
1194 BIO_printf(bio_err
, "Failure in the select\n");
1195 ERR_print_errors(bio_err
);
1200 if (select_result
== 0)
1204 for (i
= 0; i
< async_jobs
; i
++) {
1205 if (loopargs
[i
].inprogress_job
== NULL
)
1208 if (!ASYNC_WAIT_CTX_get_all_fds
1209 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1210 || num_job_fds
> 1) {
1211 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1212 ERR_print_errors(bio_err
);
1216 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1219 #if defined(OPENSSL_SYS_UNIX)
1220 if (num_job_fds
== 1 && !FD_ISSET(job_fd
, &waitfdset
))
1222 #elif defined(OPENSSL_SYS_WINDOWS)
1223 if (num_job_fds
== 1
1224 && !PeekNamedPipe(job_fd
, NULL
, 0, NULL
, &avail
, NULL
)
1229 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
,
1230 loopargs
[i
].wait_ctx
, &job_op_count
,
1231 loop_function
, (void *)(loopargs
+ i
),
1232 sizeof(loopargs_t
));
1237 if (job_op_count
== -1) {
1240 total_op_count
+= job_op_count
;
1243 loopargs
[i
].inprogress_job
= NULL
;
1248 loopargs
[i
].inprogress_job
= NULL
;
1249 BIO_printf(bio_err
, "Failure in the job\n");
1250 ERR_print_errors(bio_err
);
1257 return error
? -1 : total_op_count
;
1260 typedef struct ec_curve_st
{
1264 size_t sigsize
; /* only used for EdDSA curves */
1267 static EVP_PKEY
*get_ecdsa(const EC_CURVE
*curve
)
1269 EVP_PKEY_CTX
*kctx
= NULL
;
1270 EVP_PKEY
*key
= NULL
;
1272 /* Ensure that the error queue is empty */
1273 if (ERR_peek_error()) {
1275 "WARNING: the error queue contains previous unhandled errors.\n");
1276 ERR_print_errors(bio_err
);
1280 * Let's try to create a ctx directly from the NID: this works for
1281 * curves like Curve25519 that are not implemented through the low
1282 * level EC interface.
1283 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1284 * then we set the curve by NID before deriving the actual keygen
1285 * ctx for that specific curve.
1287 kctx
= EVP_PKEY_CTX_new_id(curve
->nid
, NULL
);
1289 EVP_PKEY_CTX
*pctx
= NULL
;
1290 EVP_PKEY
*params
= NULL
;
1292 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1293 * "int_ctx_new:unsupported algorithm" error was added to the
1295 * We remove it from the error queue as we are handling it.
1297 unsigned long error
= ERR_peek_error();
1299 if (error
== ERR_peek_last_error() /* oldest and latest errors match */
1300 /* check that the error origin matches */
1301 && ERR_GET_LIB(error
) == ERR_LIB_EVP
1302 && (ERR_GET_REASON(error
) == EVP_R_UNSUPPORTED_ALGORITHM
1303 || ERR_GET_REASON(error
) == ERR_R_UNSUPPORTED
))
1304 ERR_get_error(); /* pop error from queue */
1305 if (ERR_peek_error()) {
1307 "Unhandled error in the error queue during EC key setup.\n");
1308 ERR_print_errors(bio_err
);
1312 /* Create the context for parameter generation */
1313 if ((pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
)) == NULL
1314 || EVP_PKEY_paramgen_init(pctx
) <= 0
1315 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
1317 || EVP_PKEY_paramgen(pctx
, ¶ms
) <= 0) {
1318 BIO_printf(bio_err
, "EC params init failure.\n");
1319 ERR_print_errors(bio_err
);
1320 EVP_PKEY_CTX_free(pctx
);
1323 EVP_PKEY_CTX_free(pctx
);
1325 /* Create the context for the key generation */
1326 kctx
= EVP_PKEY_CTX_new(params
, NULL
);
1327 EVP_PKEY_free(params
);
1330 || EVP_PKEY_keygen_init(kctx
) <= 0
1331 || EVP_PKEY_keygen(kctx
, &key
) <= 0) {
1332 BIO_printf(bio_err
, "EC key generation failure.\n");
1333 ERR_print_errors(bio_err
);
1336 EVP_PKEY_CTX_free(kctx
);
1340 #define stop_it(do_it, test_num)\
1341 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1343 int speed_main(int argc
, char **argv
)
1346 loopargs_t
*loopargs
= NULL
;
1348 const char *engine_id
= NULL
;
1349 EVP_CIPHER
*evp_cipher
= NULL
;
1350 EVP_MAC
*mac
= NULL
;
1353 int async_init
= 0, multiblock
= 0, pr_header
= 0;
1354 uint8_t doit
[ALGOR_NUM
] = { 0 };
1355 int ret
= 1, misalign
= 0, lengths_single
= 0, aead
= 0;
1357 unsigned int size_num
= SIZE_NUM
;
1358 unsigned int i
, k
, loopargs_len
= 0, async_jobs
= 0;
1362 EVP_PKEY_CTX
*genctx
= NULL
;
1367 openssl_speed_sec_t seconds
= { SECONDS
, RSA_SECONDS
, DSA_SECONDS
,
1368 ECDSA_SECONDS
, ECDH_SECONDS
,
1369 EdDSA_SECONDS
, SM2_SECONDS
,
1372 static const unsigned char key32
[32] = {
1373 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1374 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1375 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1376 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1378 static const unsigned char deskey
[] = {
1379 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1380 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1381 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1383 static const struct {
1384 const unsigned char *data
;
1385 unsigned int length
;
1388 { test512
, sizeof(test512
), 512 },
1389 { test1024
, sizeof(test1024
), 1024 },
1390 { test2048
, sizeof(test2048
), 2048 },
1391 { test3072
, sizeof(test3072
), 3072 },
1392 { test4096
, sizeof(test4096
), 4096 },
1393 { test7680
, sizeof(test7680
), 7680 },
1394 { test15360
, sizeof(test15360
), 15360 }
1396 uint8_t rsa_doit
[RSA_NUM
] = { 0 };
1397 int primes
= RSA_DEFAULT_PRIME_NUM
;
1398 #ifndef OPENSSL_NO_DH
1399 typedef struct ffdh_params_st
{
1405 static const FFDH_PARAMS ffdh_params
[FFDH_NUM
] = {
1406 {"ffdh2048", NID_ffdhe2048
, 2048},
1407 {"ffdh3072", NID_ffdhe3072
, 3072},
1408 {"ffdh4096", NID_ffdhe4096
, 4096},
1409 {"ffdh6144", NID_ffdhe6144
, 6144},
1410 {"ffdh8192", NID_ffdhe8192
, 8192}
1412 uint8_t ffdh_doit
[FFDH_NUM
] = { 0 };
1414 #endif /* OPENSSL_NO_DH */
1415 static const unsigned int dsa_bits
[DSA_NUM
] = { 512, 1024, 2048 };
1416 uint8_t dsa_doit
[DSA_NUM
] = { 0 };
1418 * We only test over the following curves as they are representative, To
1419 * add tests over more curves, simply add the curve NID and curve name to
1420 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1421 * lists accordingly.
1423 static const EC_CURVE ec_curves
[EC_NUM
] = {
1425 {"secp160r1", NID_secp160r1
, 160},
1426 {"nistp192", NID_X9_62_prime192v1
, 192},
1427 {"nistp224", NID_secp224r1
, 224},
1428 {"nistp256", NID_X9_62_prime256v1
, 256},
1429 {"nistp384", NID_secp384r1
, 384},
1430 {"nistp521", NID_secp521r1
, 521},
1431 #ifndef OPENSSL_NO_EC2M
1433 {"nistk163", NID_sect163k1
, 163},
1434 {"nistk233", NID_sect233k1
, 233},
1435 {"nistk283", NID_sect283k1
, 283},
1436 {"nistk409", NID_sect409k1
, 409},
1437 {"nistk571", NID_sect571k1
, 571},
1438 {"nistb163", NID_sect163r2
, 163},
1439 {"nistb233", NID_sect233r1
, 233},
1440 {"nistb283", NID_sect283r1
, 283},
1441 {"nistb409", NID_sect409r1
, 409},
1442 {"nistb571", NID_sect571r1
, 571},
1444 {"brainpoolP256r1", NID_brainpoolP256r1
, 256},
1445 {"brainpoolP256t1", NID_brainpoolP256t1
, 256},
1446 {"brainpoolP384r1", NID_brainpoolP384r1
, 384},
1447 {"brainpoolP384t1", NID_brainpoolP384t1
, 384},
1448 {"brainpoolP512r1", NID_brainpoolP512r1
, 512},
1449 {"brainpoolP512t1", NID_brainpoolP512t1
, 512},
1450 /* Other and ECDH only ones */
1451 {"X25519", NID_X25519
, 253},
1452 {"X448", NID_X448
, 448}
1454 static const EC_CURVE ed_curves
[EdDSA_NUM
] = {
1456 {"Ed25519", NID_ED25519
, 253, 64},
1457 {"Ed448", NID_ED448
, 456, 114}
1459 #ifndef OPENSSL_NO_SM2
1460 static const EC_CURVE sm2_curves
[SM2_NUM
] = {
1462 {"CurveSM2", NID_sm2
, 256}
1464 uint8_t sm2_doit
[SM2_NUM
] = { 0 };
1466 uint8_t ecdsa_doit
[ECDSA_NUM
] = { 0 };
1467 uint8_t ecdh_doit
[EC_NUM
] = { 0 };
1468 uint8_t eddsa_doit
[EdDSA_NUM
] = { 0 };
1470 /* checks declared curves against choices list. */
1471 OPENSSL_assert(ed_curves
[EdDSA_NUM
- 1].nid
== NID_ED448
);
1472 OPENSSL_assert(strcmp(eddsa_choices
[EdDSA_NUM
- 1].name
, "ed448") == 0);
1474 OPENSSL_assert(ec_curves
[EC_NUM
- 1].nid
== NID_X448
);
1475 OPENSSL_assert(strcmp(ecdh_choices
[EC_NUM
- 1].name
, "ecdhx448") == 0);
1477 OPENSSL_assert(ec_curves
[ECDSA_NUM
- 1].nid
== NID_brainpoolP512t1
);
1478 OPENSSL_assert(strcmp(ecdsa_choices
[ECDSA_NUM
- 1].name
, "ecdsabrp512t1") == 0);
1480 #ifndef OPENSSL_NO_SM2
1481 OPENSSL_assert(sm2_curves
[SM2_NUM
- 1].nid
== NID_sm2
);
1482 OPENSSL_assert(strcmp(sm2_choices
[SM2_NUM
- 1].name
, "curveSM2") == 0);
1485 prog
= opt_init(argc
, argv
, speed_options
);
1486 while ((o
= opt_next()) != OPT_EOF
) {
1491 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
1494 opt_help(speed_options
);
1502 BIO_printf(bio_err
, "%s: -evp option cannot be used more than once\n", prog
);
1506 if (!opt_cipher_silent(opt_arg(), &evp_cipher
)) {
1507 if (have_md(opt_arg()))
1508 evp_md_name
= opt_arg();
1510 if (evp_cipher
== NULL
&& evp_md_name
== NULL
) {
1511 ERR_clear_last_mark();
1513 "%s: %s is an unknown cipher or digest\n",
1521 if (!have_md(opt_arg())) {
1522 BIO_printf(bio_err
, "%s: %s is an unknown digest\n",
1526 evp_mac_mdname
= opt_arg();
1530 if (!have_cipher(opt_arg())) {
1531 BIO_printf(bio_err
, "%s: %s is an unknown cipher\n",
1535 evp_mac_ciphername
= opt_arg();
1536 doit
[D_EVP_CMAC
] = 1;
1543 * In a forked execution, an engine might need to be
1544 * initialised by each child process, not by the parent.
1545 * So store the name here and run setup_engine() later on.
1547 engine_id
= opt_arg();
1551 multi
= opt_int_arg();
1552 if ((size_t)multi
>= SIZE_MAX
/ sizeof(int)) {
1553 BIO_printf(bio_err
, "%s: multi argument too large\n", prog
);
1559 #ifndef OPENSSL_NO_ASYNC
1560 async_jobs
= opt_int_arg();
1561 if (!ASYNC_is_capable()) {
1563 "%s: async_jobs specified but async not supported\n",
1567 if (async_jobs
> 99999) {
1568 BIO_printf(bio_err
, "%s: too many async_jobs\n", prog
);
1574 misalign
= opt_int_arg();
1575 if (misalign
> MISALIGN
) {
1577 "%s: Maximum offset is %d\n", prog
, MISALIGN
);
1586 #ifdef OPENSSL_NO_MULTIBLOCK
1588 "%s: -mb specified but multi-block support is disabled\n",
1597 case OPT_PROV_CASES
:
1598 if (!opt_provider(o
))
1602 primes
= opt_int_arg();
1605 seconds
.sym
= seconds
.rsa
= seconds
.dsa
= seconds
.ecdsa
1606 = seconds
.ecdh
= seconds
.eddsa
1607 = seconds
.sm2
= seconds
.ffdh
= opt_int_arg();
1610 lengths_single
= opt_int_arg();
1611 lengths
= &lengths_single
;
1620 /* Remaining arguments are algorithms. */
1621 argc
= opt_num_rest();
1624 if (!app_RAND_load())
1627 for (; *argv
; argv
++) {
1628 const char *algo
= *argv
;
1630 if (opt_found(algo
, doit_choices
, &i
)) {
1634 if (strcmp(algo
, "des") == 0) {
1635 doit
[D_CBC_DES
] = doit
[D_EDE3_DES
] = 1;
1638 if (strcmp(algo
, "sha") == 0) {
1639 doit
[D_SHA1
] = doit
[D_SHA256
] = doit
[D_SHA512
] = 1;
1642 #ifndef OPENSSL_NO_DEPRECATED_3_0
1643 if (strcmp(algo
, "openssl") == 0) /* just for compatibility */
1646 if (HAS_PREFIX(algo
, "rsa")) {
1647 if (algo
[sizeof("rsa") - 1] == '\0') {
1648 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1651 if (opt_found(algo
, rsa_choices
, &i
)) {
1656 #ifndef OPENSSL_NO_DH
1657 if (HAS_PREFIX(algo
, "ffdh")) {
1658 if (algo
[sizeof("ffdh") - 1] == '\0') {
1659 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1662 if (opt_found(algo
, ffdh_choices
, &i
)) {
1668 if (HAS_PREFIX(algo
, "dsa")) {
1669 if (algo
[sizeof("dsa") - 1] == '\0') {
1670 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1673 if (opt_found(algo
, dsa_choices
, &i
)) {
1678 if (strcmp(algo
, "aes") == 0) {
1679 doit
[D_CBC_128_AES
] = doit
[D_CBC_192_AES
] = doit
[D_CBC_256_AES
] = 1;
1682 if (strcmp(algo
, "camellia") == 0) {
1683 doit
[D_CBC_128_CML
] = doit
[D_CBC_192_CML
] = doit
[D_CBC_256_CML
] = 1;
1686 if (HAS_PREFIX(algo
, "ecdsa")) {
1687 if (algo
[sizeof("ecdsa") - 1] == '\0') {
1688 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1691 if (opt_found(algo
, ecdsa_choices
, &i
)) {
1696 if (HAS_PREFIX(algo
, "ecdh")) {
1697 if (algo
[sizeof("ecdh") - 1] == '\0') {
1698 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1701 if (opt_found(algo
, ecdh_choices
, &i
)) {
1706 if (strcmp(algo
, "eddsa") == 0) {
1707 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1710 if (opt_found(algo
, eddsa_choices
, &i
)) {
1714 #ifndef OPENSSL_NO_SM2
1715 if (strcmp(algo
, "sm2") == 0) {
1716 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1719 if (opt_found(algo
, sm2_choices
, &i
)) {
1724 BIO_printf(bio_err
, "%s: Unknown algorithm %s\n", prog
, algo
);
1730 if (evp_cipher
== NULL
) {
1731 BIO_printf(bio_err
, "-aead can be used only with an AEAD cipher\n");
1733 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1734 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
1735 BIO_printf(bio_err
, "%s is not an AEAD cipher\n",
1736 EVP_CIPHER_get0_name(evp_cipher
));
1741 if (evp_cipher
== NULL
) {
1742 BIO_printf(bio_err
, "-mb can be used only with a multi-block"
1743 " capable cipher\n");
1745 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1746 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
1747 BIO_printf(bio_err
, "%s is not a multi-block capable\n",
1748 EVP_CIPHER_get0_name(evp_cipher
));
1750 } else if (async_jobs
> 0) {
1751 BIO_printf(bio_err
, "Async mode is not supported with -mb");
1756 /* Initialize the job pool if async mode is enabled */
1757 if (async_jobs
> 0) {
1758 async_init
= ASYNC_init_thread(async_jobs
, async_jobs
);
1760 BIO_printf(bio_err
, "Error creating the ASYNC job pool\n");
1765 loopargs_len
= (async_jobs
== 0 ? 1 : async_jobs
);
1767 app_malloc(loopargs_len
* sizeof(loopargs_t
), "array of loopargs");
1768 memset(loopargs
, 0, loopargs_len
* sizeof(loopargs_t
));
1770 for (i
= 0; i
< loopargs_len
; i
++) {
1771 if (async_jobs
> 0) {
1772 loopargs
[i
].wait_ctx
= ASYNC_WAIT_CTX_new();
1773 if (loopargs
[i
].wait_ctx
== NULL
) {
1774 BIO_printf(bio_err
, "Error creating the ASYNC_WAIT_CTX\n");
1779 buflen
= lengths
[size_num
- 1];
1780 if (buflen
< 36) /* size of random vector in RSA benchmark */
1782 if (INT_MAX
- (MAX_MISALIGNMENT
+ 1) < buflen
) {
1783 BIO_printf(bio_err
, "Error: buffer size too large\n");
1786 buflen
+= MAX_MISALIGNMENT
+ 1;
1787 loopargs
[i
].buf_malloc
= app_malloc(buflen
, "input buffer");
1788 loopargs
[i
].buf2_malloc
= app_malloc(buflen
, "input buffer");
1789 memset(loopargs
[i
].buf_malloc
, 0, buflen
);
1790 memset(loopargs
[i
].buf2_malloc
, 0, buflen
);
1792 /* Align the start of buffers on a 64 byte boundary */
1793 loopargs
[i
].buf
= loopargs
[i
].buf_malloc
+ misalign
;
1794 loopargs
[i
].buf2
= loopargs
[i
].buf2_malloc
+ misalign
;
1795 loopargs
[i
].buflen
= buflen
- misalign
;
1796 loopargs
[i
].sigsize
= buflen
- misalign
;
1797 loopargs
[i
].secret_a
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret a");
1798 loopargs
[i
].secret_b
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret b");
1799 #ifndef OPENSSL_NO_DH
1800 loopargs
[i
].secret_ff_a
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret a");
1801 loopargs
[i
].secret_ff_b
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret b");
1806 if (multi
&& do_multi(multi
, size_num
))
1810 /* Initialize the engine after the fork */
1811 e
= setup_engine(engine_id
, 0);
1813 /* No parameters; turn on everything. */
1814 if (argc
== 0 && !doit
[D_EVP
] && !doit
[D_HMAC
] && !doit
[D_EVP_CMAC
]) {
1815 memset(doit
, 1, sizeof(doit
));
1816 doit
[D_EVP
] = doit
[D_EVP_CMAC
] = 0;
1818 for (i
= D_MD2
; i
<= D_WHIRLPOOL
; i
++) {
1819 if (!have_md(names
[i
]))
1822 for (i
= D_CBC_DES
; i
<= D_CBC_256_CML
; i
++) {
1823 if (!have_cipher(names
[i
]))
1826 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1827 app_get0_propq())) != NULL
) {
1833 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1834 app_get0_propq())) != NULL
) {
1841 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1842 #ifndef OPENSSL_NO_DH
1843 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1845 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1846 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1847 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1848 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1849 #ifndef OPENSSL_NO_SM2
1850 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1853 for (i
= 0; i
< ALGOR_NUM
; i
++)
1857 if (usertime
== 0 && !mr
)
1859 "You have chosen to measure elapsed time "
1860 "instead of user CPU time.\n");
1863 signal(SIGALRM
, alarmed
);
1867 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1868 print_message(names
[D_MD2
], c
[D_MD2
][testnum
], lengths
[testnum
],
1871 count
= run_benchmark(async_jobs
, EVP_Digest_MD2_loop
, loopargs
);
1873 print_result(D_MD2
, testnum
, count
, d
);
1880 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1881 print_message(names
[D_MDC2
], c
[D_MDC2
][testnum
], lengths
[testnum
],
1884 count
= run_benchmark(async_jobs
, EVP_Digest_MDC2_loop
, loopargs
);
1886 print_result(D_MDC2
, testnum
, count
, d
);
1893 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1894 print_message(names
[D_MD4
], c
[D_MD4
][testnum
], lengths
[testnum
],
1897 count
= run_benchmark(async_jobs
, EVP_Digest_MD4_loop
, loopargs
);
1899 print_result(D_MD4
, testnum
, count
, d
);
1906 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1907 print_message(names
[D_MD5
], c
[D_MD5
][testnum
], lengths
[testnum
],
1910 count
= run_benchmark(async_jobs
, MD5_loop
, loopargs
);
1912 print_result(D_MD5
, testnum
, count
, d
);
1919 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1920 print_message(names
[D_SHA1
], c
[D_SHA1
][testnum
], lengths
[testnum
],
1923 count
= run_benchmark(async_jobs
, SHA1_loop
, loopargs
);
1925 print_result(D_SHA1
, testnum
, count
, d
);
1931 if (doit
[D_SHA256
]) {
1932 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1933 print_message(names
[D_SHA256
], c
[D_SHA256
][testnum
],
1934 lengths
[testnum
], seconds
.sym
);
1936 count
= run_benchmark(async_jobs
, SHA256_loop
, loopargs
);
1938 print_result(D_SHA256
, testnum
, count
, d
);
1944 if (doit
[D_SHA512
]) {
1945 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1946 print_message(names
[D_SHA512
], c
[D_SHA512
][testnum
],
1947 lengths
[testnum
], seconds
.sym
);
1949 count
= run_benchmark(async_jobs
, SHA512_loop
, loopargs
);
1951 print_result(D_SHA512
, testnum
, count
, d
);
1957 if (doit
[D_WHIRLPOOL
]) {
1958 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1959 print_message(names
[D_WHIRLPOOL
], c
[D_WHIRLPOOL
][testnum
],
1960 lengths
[testnum
], seconds
.sym
);
1962 count
= run_benchmark(async_jobs
, WHIRLPOOL_loop
, loopargs
);
1964 print_result(D_WHIRLPOOL
, testnum
, count
, d
);
1970 if (doit
[D_RMD160
]) {
1971 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1972 print_message(names
[D_RMD160
], c
[D_RMD160
][testnum
],
1973 lengths
[testnum
], seconds
.sym
);
1975 count
= run_benchmark(async_jobs
, EVP_Digest_RMD160_loop
, loopargs
);
1977 print_result(D_RMD160
, testnum
, count
, d
);
1984 static const char hmac_key
[] = "This is a key...";
1985 int len
= strlen(hmac_key
);
1986 OSSL_PARAM params
[3];
1988 mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1989 if (mac
== NULL
|| evp_mac_mdname
== NULL
)
1992 evp_hmac_name
= app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname
),
1994 sprintf(evp_hmac_name
, "hmac(%s)", evp_mac_mdname
);
1995 names
[D_HMAC
] = evp_hmac_name
;
1998 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
2001 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2002 (char *)hmac_key
, len
);
2003 params
[2] = OSSL_PARAM_construct_end();
2005 for (i
= 0; i
< loopargs_len
; i
++) {
2006 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2007 if (loopargs
[i
].mctx
== NULL
)
2010 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2013 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2014 print_message(names
[D_HMAC
], c
[D_HMAC
][testnum
], lengths
[testnum
],
2017 count
= run_benchmark(async_jobs
, HMAC_loop
, loopargs
);
2019 print_result(D_HMAC
, testnum
, count
, d
);
2023 for (i
= 0; i
< loopargs_len
; i
++)
2024 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2029 if (doit
[D_CBC_DES
]) {
2032 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2033 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-cbc", deskey
,
2034 sizeof(deskey
) / 3);
2035 st
= loopargs
[i
].ctx
!= NULL
;
2037 algindex
= D_CBC_DES
;
2038 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2039 print_message(names
[D_CBC_DES
], c
[D_CBC_DES
][testnum
],
2040 lengths
[testnum
], seconds
.sym
);
2042 count
= run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2044 print_result(D_CBC_DES
, testnum
, count
, d
);
2046 for (i
= 0; i
< loopargs_len
; i
++)
2047 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2050 if (doit
[D_EDE3_DES
]) {
2053 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2054 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-ede3-cbc", deskey
,
2056 st
= loopargs
[i
].ctx
!= NULL
;
2058 algindex
= D_EDE3_DES
;
2059 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2060 print_message(names
[D_EDE3_DES
], c
[D_EDE3_DES
][testnum
],
2061 lengths
[testnum
], seconds
.sym
);
2064 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2066 print_result(D_EDE3_DES
, testnum
, count
, d
);
2068 for (i
= 0; i
< loopargs_len
; i
++)
2069 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2072 for (k
= 0; k
< 3; k
++) {
2073 algindex
= D_CBC_128_AES
+ k
;
2074 if (doit
[algindex
]) {
2077 keylen
= 16 + k
* 8;
2078 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2079 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2081 st
= loopargs
[i
].ctx
!= NULL
;
2084 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2085 print_message(names
[algindex
], c
[algindex
][testnum
],
2086 lengths
[testnum
], seconds
.sym
);
2089 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2091 print_result(algindex
, testnum
, count
, d
);
2093 for (i
= 0; i
< loopargs_len
; i
++)
2094 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2098 for (k
= 0; k
< 3; k
++) {
2099 algindex
= D_CBC_128_CML
+ k
;
2100 if (doit
[algindex
]) {
2103 keylen
= 16 + k
* 8;
2104 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2105 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2107 st
= loopargs
[i
].ctx
!= NULL
;
2110 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2111 print_message(names
[algindex
], c
[algindex
][testnum
],
2112 lengths
[testnum
], seconds
.sym
);
2115 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2117 print_result(algindex
, testnum
, count
, d
);
2119 for (i
= 0; i
< loopargs_len
; i
++)
2120 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2124 for (algindex
= D_RC4
; algindex
<= D_CBC_CAST
; algindex
++) {
2125 if (doit
[algindex
]) {
2129 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2130 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2132 st
= loopargs
[i
].ctx
!= NULL
;
2135 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2136 print_message(names
[algindex
], c
[algindex
][testnum
],
2137 lengths
[testnum
], seconds
.sym
);
2140 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2142 print_result(algindex
, testnum
, count
, d
);
2144 for (i
= 0; i
< loopargs_len
; i
++)
2145 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2148 if (doit
[D_GHASH
]) {
2149 static const char gmac_iv
[] = "0123456789ab";
2150 OSSL_PARAM params
[3];
2152 mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2156 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2158 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV
,
2160 sizeof(gmac_iv
) - 1);
2161 params
[2] = OSSL_PARAM_construct_end();
2163 for (i
= 0; i
< loopargs_len
; i
++) {
2164 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2165 if (loopargs
[i
].mctx
== NULL
)
2168 if (!EVP_MAC_init(loopargs
[i
].mctx
, key32
, 16, params
))
2171 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2172 print_message(names
[D_GHASH
], c
[D_GHASH
][testnum
], lengths
[testnum
],
2175 count
= run_benchmark(async_jobs
, GHASH_loop
, loopargs
);
2177 print_result(D_GHASH
, testnum
, count
, d
);
2181 for (i
= 0; i
< loopargs_len
; i
++)
2182 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2188 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2189 print_message(names
[D_RAND
], c
[D_RAND
][testnum
], lengths
[testnum
],
2192 count
= run_benchmark(async_jobs
, RAND_bytes_loop
, loopargs
);
2194 print_result(D_RAND
, testnum
, count
, d
);
2199 if (evp_cipher
!= NULL
) {
2200 int (*loopfunc
) (void *) = EVP_Update_loop
;
2202 if (multiblock
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2203 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2204 multiblock_speed(evp_cipher
, lengths_single
, &seconds
);
2209 names
[D_EVP
] = EVP_CIPHER_get0_name(evp_cipher
);
2211 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_CCM_MODE
) {
2212 loopfunc
= EVP_Update_loop_ccm
;
2213 } else if (aead
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2214 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2215 loopfunc
= EVP_Update_loop_aead
;
2216 if (lengths
== lengths_list
) {
2217 lengths
= aead_lengths_list
;
2218 size_num
= OSSL_NELEM(aead_lengths_list
);
2222 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2223 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2226 for (k
= 0; k
< loopargs_len
; k
++) {
2227 loopargs
[k
].ctx
= EVP_CIPHER_CTX_new();
2228 if (loopargs
[k
].ctx
== NULL
) {
2229 BIO_printf(bio_err
, "\nEVP_CIPHER_CTX_new failure\n");
2232 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, evp_cipher
, NULL
,
2233 NULL
, iv
, decrypt
? 0 : 1)) {
2234 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2235 ERR_print_errors(bio_err
);
2239 EVP_CIPHER_CTX_set_padding(loopargs
[k
].ctx
, 0);
2241 keylen
= EVP_CIPHER_CTX_get_key_length(loopargs
[k
].ctx
);
2242 loopargs
[k
].key
= app_malloc(keylen
, "evp_cipher key");
2243 EVP_CIPHER_CTX_rand_key(loopargs
[k
].ctx
, loopargs
[k
].key
);
2244 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, NULL
, NULL
,
2245 loopargs
[k
].key
, NULL
, -1)) {
2246 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2247 ERR_print_errors(bio_err
);
2250 OPENSSL_clear_free(loopargs
[k
].key
, keylen
);
2252 /* SIV mode only allows for a single Update operation */
2253 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_SIV_MODE
)
2254 (void)EVP_CIPHER_CTX_ctrl(loopargs
[k
].ctx
,
2255 EVP_CTRL_SET_SPEED
, 1, NULL
);
2259 count
= run_benchmark(async_jobs
, loopfunc
, loopargs
);
2261 for (k
= 0; k
< loopargs_len
; k
++)
2262 EVP_CIPHER_CTX_free(loopargs
[k
].ctx
);
2263 print_result(D_EVP
, testnum
, count
, d
);
2265 } else if (evp_md_name
!= NULL
) {
2266 names
[D_EVP
] = evp_md_name
;
2268 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2269 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2272 count
= run_benchmark(async_jobs
, EVP_Digest_md_loop
, loopargs
);
2274 print_result(D_EVP
, testnum
, count
, d
);
2281 if (doit
[D_EVP_CMAC
]) {
2282 OSSL_PARAM params
[3];
2283 EVP_CIPHER
*cipher
= NULL
;
2285 mac
= EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2286 if (mac
== NULL
|| evp_mac_ciphername
== NULL
)
2288 if (!opt_cipher(evp_mac_ciphername
, &cipher
))
2291 keylen
= EVP_CIPHER_get_key_length(cipher
);
2292 EVP_CIPHER_free(cipher
);
2293 if (keylen
<= 0 || keylen
> (int)sizeof(key32
)) {
2294 BIO_printf(bio_err
, "\nRequested CMAC cipher with unsupported key length.\n");
2297 evp_cmac_name
= app_malloc(sizeof("cmac()")
2298 + strlen(evp_mac_ciphername
), "CMAC name");
2299 sprintf(evp_cmac_name
, "cmac(%s)", evp_mac_ciphername
);
2300 names
[D_EVP_CMAC
] = evp_cmac_name
;
2302 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2303 evp_mac_ciphername
, 0);
2304 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2305 (char *)key32
, keylen
);
2306 params
[2] = OSSL_PARAM_construct_end();
2308 for (i
= 0; i
< loopargs_len
; i
++) {
2309 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2310 if (loopargs
[i
].mctx
== NULL
)
2313 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2317 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2318 print_message(names
[D_EVP_CMAC
], c
[D_EVP_CMAC
][testnum
],
2319 lengths
[testnum
], seconds
.sym
);
2321 count
= run_benchmark(async_jobs
, CMAC_loop
, loopargs
);
2323 print_result(D_EVP_CMAC
, testnum
, count
, d
);
2327 for (i
= 0; i
< loopargs_len
; i
++)
2328 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2333 for (i
= 0; i
< loopargs_len
; i
++)
2334 if (RAND_bytes(loopargs
[i
].buf
, 36) <= 0)
2337 for (testnum
= 0; testnum
< RSA_NUM
; testnum
++) {
2338 EVP_PKEY
*rsa_key
= NULL
;
2341 if (!rsa_doit
[testnum
])
2344 if (primes
> RSA_DEFAULT_PRIME_NUM
) {
2345 /* we haven't set keys yet, generate multi-prime RSA keys */
2348 && BN_set_word(bn
, RSA_F4
)
2349 && init_gen_str(&genctx
, "RSA", NULL
, 0, NULL
, NULL
)
2350 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx
, rsa_keys
[testnum
].bits
) > 0
2351 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx
, bn
) > 0
2352 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx
, primes
) > 0
2353 && EVP_PKEY_keygen(genctx
, &rsa_key
);
2356 EVP_PKEY_CTX_free(genctx
);
2359 const unsigned char *p
= rsa_keys
[testnum
].data
;
2361 st
= (rsa_key
= d2i_PrivateKey(EVP_PKEY_RSA
, NULL
, &p
,
2362 rsa_keys
[testnum
].length
)) != NULL
;
2365 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2366 loopargs
[i
].rsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2367 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2368 if (loopargs
[i
].rsa_sign_ctx
[testnum
] == NULL
2369 || EVP_PKEY_sign_init(loopargs
[i
].rsa_sign_ctx
[testnum
]) <= 0
2370 || EVP_PKEY_sign(loopargs
[i
].rsa_sign_ctx
[testnum
],
2372 &loopargs
[i
].sigsize
,
2373 loopargs
[i
].buf
, 36) <= 0)
2378 "RSA sign setup failure. No RSA sign will be done.\n");
2379 ERR_print_errors(bio_err
);
2382 pkey_print_message("private", "rsa",
2383 rsa_c
[testnum
][0], rsa_keys
[testnum
].bits
,
2385 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2387 count
= run_benchmark(async_jobs
, RSA_sign_loop
, loopargs
);
2390 mr
? "+R1:%ld:%d:%.2f\n"
2391 : "%ld %u bits private RSA's in %.2fs\n",
2392 count
, rsa_keys
[testnum
].bits
, d
);
2393 rsa_results
[testnum
][0] = (double)count
/ d
;
2397 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2398 loopargs
[i
].rsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
,
2400 if (loopargs
[i
].rsa_verify_ctx
[testnum
] == NULL
2401 || EVP_PKEY_verify_init(loopargs
[i
].rsa_verify_ctx
[testnum
]) <= 0
2402 || EVP_PKEY_verify(loopargs
[i
].rsa_verify_ctx
[testnum
],
2404 loopargs
[i
].sigsize
,
2405 loopargs
[i
].buf
, 36) <= 0)
2410 "RSA verify setup failure. No RSA verify will be done.\n");
2411 ERR_print_errors(bio_err
);
2412 rsa_doit
[testnum
] = 0;
2414 pkey_print_message("public", "rsa",
2415 rsa_c
[testnum
][1], rsa_keys
[testnum
].bits
,
2418 count
= run_benchmark(async_jobs
, RSA_verify_loop
, loopargs
);
2421 mr
? "+R2:%ld:%d:%.2f\n"
2422 : "%ld %u bits public RSA's in %.2fs\n",
2423 count
, rsa_keys
[testnum
].bits
, d
);
2424 rsa_results
[testnum
][1] = (double)count
/ d
;
2427 if (op_count
<= 1) {
2428 /* if longer than 10s, don't do any more */
2429 stop_it(rsa_doit
, testnum
);
2431 EVP_PKEY_free(rsa_key
);
2434 for (testnum
= 0; testnum
< DSA_NUM
; testnum
++) {
2435 EVP_PKEY
*dsa_key
= NULL
;
2438 if (!dsa_doit
[testnum
])
2441 st
= (dsa_key
= get_dsa(dsa_bits
[testnum
])) != NULL
;
2443 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2444 loopargs
[i
].dsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2446 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2447 if (loopargs
[i
].dsa_sign_ctx
[testnum
] == NULL
2448 || EVP_PKEY_sign_init(loopargs
[i
].dsa_sign_ctx
[testnum
]) <= 0
2450 || EVP_PKEY_sign(loopargs
[i
].dsa_sign_ctx
[testnum
],
2452 &loopargs
[i
].sigsize
,
2453 loopargs
[i
].buf
, 20) <= 0)
2458 "DSA sign setup failure. No DSA sign will be done.\n");
2459 ERR_print_errors(bio_err
);
2462 pkey_print_message("sign", "dsa",
2463 dsa_c
[testnum
][0], dsa_bits
[testnum
],
2466 count
= run_benchmark(async_jobs
, DSA_sign_loop
, loopargs
);
2469 mr
? "+R3:%ld:%u:%.2f\n"
2470 : "%ld %u bits DSA signs in %.2fs\n",
2471 count
, dsa_bits
[testnum
], d
);
2472 dsa_results
[testnum
][0] = (double)count
/ d
;
2476 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2477 loopargs
[i
].dsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2479 if (loopargs
[i
].dsa_verify_ctx
[testnum
] == NULL
2480 || EVP_PKEY_verify_init(loopargs
[i
].dsa_verify_ctx
[testnum
]) <= 0
2481 || EVP_PKEY_verify(loopargs
[i
].dsa_verify_ctx
[testnum
],
2483 loopargs
[i
].sigsize
,
2484 loopargs
[i
].buf
, 36) <= 0)
2489 "DSA verify setup failure. No DSA verify will be done.\n");
2490 ERR_print_errors(bio_err
);
2491 dsa_doit
[testnum
] = 0;
2493 pkey_print_message("verify", "dsa",
2494 dsa_c
[testnum
][1], dsa_bits
[testnum
],
2497 count
= run_benchmark(async_jobs
, DSA_verify_loop
, loopargs
);
2500 mr
? "+R4:%ld:%u:%.2f\n"
2501 : "%ld %u bits DSA verify in %.2fs\n",
2502 count
, dsa_bits
[testnum
], d
);
2503 dsa_results
[testnum
][1] = (double)count
/ d
;
2506 if (op_count
<= 1) {
2507 /* if longer than 10s, don't do any more */
2508 stop_it(dsa_doit
, testnum
);
2510 EVP_PKEY_free(dsa_key
);
2513 for (testnum
= 0; testnum
< ECDSA_NUM
; testnum
++) {
2514 EVP_PKEY
*ecdsa_key
= NULL
;
2517 if (!ecdsa_doit
[testnum
])
2520 st
= (ecdsa_key
= get_ecdsa(&ec_curves
[testnum
])) != NULL
;
2522 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2523 loopargs
[i
].ecdsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2525 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2526 if (loopargs
[i
].ecdsa_sign_ctx
[testnum
] == NULL
2527 || EVP_PKEY_sign_init(loopargs
[i
].ecdsa_sign_ctx
[testnum
]) <= 0
2529 || EVP_PKEY_sign(loopargs
[i
].ecdsa_sign_ctx
[testnum
],
2531 &loopargs
[i
].sigsize
,
2532 loopargs
[i
].buf
, 20) <= 0)
2537 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2538 ERR_print_errors(bio_err
);
2541 pkey_print_message("sign", "ecdsa",
2542 ecdsa_c
[testnum
][0], ec_curves
[testnum
].bits
,
2545 count
= run_benchmark(async_jobs
, ECDSA_sign_loop
, loopargs
);
2548 mr
? "+R5:%ld:%u:%.2f\n"
2549 : "%ld %u bits ECDSA signs in %.2fs\n",
2550 count
, ec_curves
[testnum
].bits
, d
);
2551 ecdsa_results
[testnum
][0] = (double)count
/ d
;
2555 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2556 loopargs
[i
].ecdsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2558 if (loopargs
[i
].ecdsa_verify_ctx
[testnum
] == NULL
2559 || EVP_PKEY_verify_init(loopargs
[i
].ecdsa_verify_ctx
[testnum
]) <= 0
2560 || EVP_PKEY_verify(loopargs
[i
].ecdsa_verify_ctx
[testnum
],
2562 loopargs
[i
].sigsize
,
2563 loopargs
[i
].buf
, 20) <= 0)
2568 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2569 ERR_print_errors(bio_err
);
2570 ecdsa_doit
[testnum
] = 0;
2572 pkey_print_message("verify", "ecdsa",
2573 ecdsa_c
[testnum
][1], ec_curves
[testnum
].bits
,
2576 count
= run_benchmark(async_jobs
, ECDSA_verify_loop
, loopargs
);
2579 mr
? "+R6:%ld:%u:%.2f\n"
2580 : "%ld %u bits ECDSA verify in %.2fs\n",
2581 count
, ec_curves
[testnum
].bits
, d
);
2582 ecdsa_results
[testnum
][1] = (double)count
/ d
;
2585 if (op_count
<= 1) {
2586 /* if longer than 10s, don't do any more */
2587 stop_it(ecdsa_doit
, testnum
);
2591 for (testnum
= 0; testnum
< EC_NUM
; testnum
++) {
2592 int ecdh_checks
= 1;
2594 if (!ecdh_doit
[testnum
])
2597 for (i
= 0; i
< loopargs_len
; i
++) {
2598 EVP_PKEY_CTX
*test_ctx
= NULL
;
2599 EVP_PKEY_CTX
*ctx
= NULL
;
2600 EVP_PKEY
*key_A
= NULL
;
2601 EVP_PKEY
*key_B
= NULL
;
2605 if ((key_A
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key A */
2606 || (key_B
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key B */
2607 || (ctx
= EVP_PKEY_CTX_new(key_A
, NULL
)) == NULL
/* derivation ctx from skeyA */
2608 || EVP_PKEY_derive_init(ctx
) <= 0 /* init derivation ctx */
2609 || EVP_PKEY_derive_set_peer(ctx
, key_B
) <= 0 /* set peer pubkey in ctx */
2610 || EVP_PKEY_derive(ctx
, NULL
, &outlen
) <= 0 /* determine max length */
2611 || outlen
== 0 /* ensure outlen is a valid size */
2612 || outlen
> MAX_ECDH_SIZE
/* avoid buffer overflow */) {
2614 BIO_printf(bio_err
, "ECDH key generation failure.\n");
2615 ERR_print_errors(bio_err
);
2621 * Here we perform a test run, comparing the output of a*B and b*A;
2622 * we try this here and assume that further EVP_PKEY_derive calls
2623 * never fail, so we can skip checks in the actually benchmarked
2624 * code, for maximum performance.
2626 if ((test_ctx
= EVP_PKEY_CTX_new(key_B
, NULL
)) == NULL
/* test ctx from skeyB */
2627 || !EVP_PKEY_derive_init(test_ctx
) /* init derivation test_ctx */
2628 || !EVP_PKEY_derive_set_peer(test_ctx
, key_A
) /* set peer pubkey in test_ctx */
2629 || !EVP_PKEY_derive(test_ctx
, NULL
, &test_outlen
) /* determine max length */
2630 || !EVP_PKEY_derive(ctx
, loopargs
[i
].secret_a
, &outlen
) /* compute a*B */
2631 || !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_b
, &test_outlen
) /* compute b*A */
2632 || test_outlen
!= outlen
/* compare output length */) {
2634 BIO_printf(bio_err
, "ECDH computation failure.\n");
2635 ERR_print_errors(bio_err
);
2640 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2641 if (CRYPTO_memcmp(loopargs
[i
].secret_a
,
2642 loopargs
[i
].secret_b
, outlen
)) {
2644 BIO_printf(bio_err
, "ECDH computations don't match.\n");
2645 ERR_print_errors(bio_err
);
2650 loopargs
[i
].ecdh_ctx
[testnum
] = ctx
;
2651 loopargs
[i
].outlen
[testnum
] = outlen
;
2653 EVP_PKEY_free(key_A
);
2654 EVP_PKEY_free(key_B
);
2655 EVP_PKEY_CTX_free(test_ctx
);
2658 if (ecdh_checks
!= 0) {
2659 pkey_print_message("", "ecdh",
2661 ec_curves
[testnum
].bits
, seconds
.ecdh
);
2664 run_benchmark(async_jobs
, ECDH_EVP_derive_key_loop
, loopargs
);
2667 mr
? "+R7:%ld:%d:%.2f\n" :
2668 "%ld %u-bits ECDH ops in %.2fs\n", count
,
2669 ec_curves
[testnum
].bits
, d
);
2670 ecdh_results
[testnum
][0] = (double)count
/ d
;
2674 if (op_count
<= 1) {
2675 /* if longer than 10s, don't do any more */
2676 stop_it(ecdh_doit
, testnum
);
2680 for (testnum
= 0; testnum
< EdDSA_NUM
; testnum
++) {
2682 EVP_PKEY
*ed_pkey
= NULL
;
2683 EVP_PKEY_CTX
*ed_pctx
= NULL
;
2685 if (!eddsa_doit
[testnum
])
2686 continue; /* Ignore Curve */
2687 for (i
= 0; i
< loopargs_len
; i
++) {
2688 loopargs
[i
].eddsa_ctx
[testnum
] = EVP_MD_CTX_new();
2689 if (loopargs
[i
].eddsa_ctx
[testnum
] == NULL
) {
2693 loopargs
[i
].eddsa_ctx2
[testnum
] = EVP_MD_CTX_new();
2694 if (loopargs
[i
].eddsa_ctx2
[testnum
] == NULL
) {
2699 if ((ed_pctx
= EVP_PKEY_CTX_new_id(ed_curves
[testnum
].nid
,
2701 || EVP_PKEY_keygen_init(ed_pctx
) <= 0
2702 || EVP_PKEY_keygen(ed_pctx
, &ed_pkey
) <= 0) {
2704 EVP_PKEY_CTX_free(ed_pctx
);
2707 EVP_PKEY_CTX_free(ed_pctx
);
2709 if (!EVP_DigestSignInit(loopargs
[i
].eddsa_ctx
[testnum
], NULL
, NULL
,
2712 EVP_PKEY_free(ed_pkey
);
2715 if (!EVP_DigestVerifyInit(loopargs
[i
].eddsa_ctx2
[testnum
], NULL
,
2716 NULL
, NULL
, ed_pkey
)) {
2718 EVP_PKEY_free(ed_pkey
);
2722 EVP_PKEY_free(ed_pkey
);
2726 BIO_printf(bio_err
, "EdDSA failure.\n");
2727 ERR_print_errors(bio_err
);
2730 for (i
= 0; i
< loopargs_len
; i
++) {
2731 /* Perform EdDSA signature test */
2732 loopargs
[i
].sigsize
= ed_curves
[testnum
].sigsize
;
2733 st
= EVP_DigestSign(loopargs
[i
].eddsa_ctx
[testnum
],
2734 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2735 loopargs
[i
].buf
, 20);
2741 "EdDSA sign failure. No EdDSA sign will be done.\n");
2742 ERR_print_errors(bio_err
);
2745 pkey_print_message("sign", ed_curves
[testnum
].name
,
2746 eddsa_c
[testnum
][0],
2747 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2749 count
= run_benchmark(async_jobs
, EdDSA_sign_loop
, loopargs
);
2753 mr
? "+R8:%ld:%u:%s:%.2f\n" :
2754 "%ld %u bits %s signs in %.2fs \n",
2755 count
, ed_curves
[testnum
].bits
,
2756 ed_curves
[testnum
].name
, d
);
2757 eddsa_results
[testnum
][0] = (double)count
/ d
;
2760 /* Perform EdDSA verification test */
2761 for (i
= 0; i
< loopargs_len
; i
++) {
2762 st
= EVP_DigestVerify(loopargs
[i
].eddsa_ctx2
[testnum
],
2763 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2764 loopargs
[i
].buf
, 20);
2770 "EdDSA verify failure. No EdDSA verify will be done.\n");
2771 ERR_print_errors(bio_err
);
2772 eddsa_doit
[testnum
] = 0;
2774 pkey_print_message("verify", ed_curves
[testnum
].name
,
2775 eddsa_c
[testnum
][1],
2776 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2778 count
= run_benchmark(async_jobs
, EdDSA_verify_loop
, loopargs
);
2781 mr
? "+R9:%ld:%u:%s:%.2f\n"
2782 : "%ld %u bits %s verify in %.2fs\n",
2783 count
, ed_curves
[testnum
].bits
,
2784 ed_curves
[testnum
].name
, d
);
2785 eddsa_results
[testnum
][1] = (double)count
/ d
;
2788 if (op_count
<= 1) {
2789 /* if longer than 10s, don't do any more */
2790 stop_it(eddsa_doit
, testnum
);
2795 #ifndef OPENSSL_NO_SM2
2796 for (testnum
= 0; testnum
< SM2_NUM
; testnum
++) {
2798 EVP_PKEY
*sm2_pkey
= NULL
;
2800 if (!sm2_doit
[testnum
])
2801 continue; /* Ignore Curve */
2802 /* Init signing and verification */
2803 for (i
= 0; i
< loopargs_len
; i
++) {
2804 EVP_PKEY_CTX
*sm2_pctx
= NULL
;
2805 EVP_PKEY_CTX
*sm2_vfy_pctx
= NULL
;
2806 EVP_PKEY_CTX
*pctx
= NULL
;
2809 loopargs
[i
].sm2_ctx
[testnum
] = EVP_MD_CTX_new();
2810 loopargs
[i
].sm2_vfy_ctx
[testnum
] = EVP_MD_CTX_new();
2811 if (loopargs
[i
].sm2_ctx
[testnum
] == NULL
2812 || loopargs
[i
].sm2_vfy_ctx
[testnum
] == NULL
)
2817 st
= !((pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_SM2
, NULL
)) == NULL
2818 || EVP_PKEY_keygen_init(pctx
) <= 0
2819 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
2820 sm2_curves
[testnum
].nid
) <= 0
2821 || EVP_PKEY_keygen(pctx
, &sm2_pkey
) <= 0);
2822 EVP_PKEY_CTX_free(pctx
);
2826 st
= 0; /* set back to zero */
2827 /* attach it sooner to rely on main final cleanup */
2828 loopargs
[i
].sm2_pkey
[testnum
] = sm2_pkey
;
2829 loopargs
[i
].sigsize
= EVP_PKEY_get_size(sm2_pkey
);
2831 sm2_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2832 sm2_vfy_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2833 if (sm2_pctx
== NULL
|| sm2_vfy_pctx
== NULL
) {
2834 EVP_PKEY_CTX_free(sm2_vfy_pctx
);
2838 /* attach them directly to respective ctx */
2839 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_ctx
[testnum
], sm2_pctx
);
2840 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[testnum
], sm2_vfy_pctx
);
2843 * No need to allow user to set an explicit ID here, just use
2844 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2846 if (EVP_PKEY_CTX_set1_id(sm2_pctx
, SM2_ID
, SM2_ID_LEN
) != 1
2847 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx
, SM2_ID
, SM2_ID_LEN
) != 1)
2850 if (!EVP_DigestSignInit(loopargs
[i
].sm2_ctx
[testnum
], NULL
,
2851 EVP_sm3(), NULL
, sm2_pkey
))
2853 if (!EVP_DigestVerifyInit(loopargs
[i
].sm2_vfy_ctx
[testnum
], NULL
,
2854 EVP_sm3(), NULL
, sm2_pkey
))
2856 st
= 1; /* mark loop as succeeded */
2859 BIO_printf(bio_err
, "SM2 init failure.\n");
2860 ERR_print_errors(bio_err
);
2863 for (i
= 0; i
< loopargs_len
; i
++) {
2864 /* Perform SM2 signature test */
2865 st
= EVP_DigestSign(loopargs
[i
].sm2_ctx
[testnum
],
2866 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2867 loopargs
[i
].buf
, 20);
2873 "SM2 sign failure. No SM2 sign will be done.\n");
2874 ERR_print_errors(bio_err
);
2877 pkey_print_message("sign", sm2_curves
[testnum
].name
,
2879 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2881 count
= run_benchmark(async_jobs
, SM2_sign_loop
, loopargs
);
2885 mr
? "+R10:%ld:%u:%s:%.2f\n" :
2886 "%ld %u bits %s signs in %.2fs \n",
2887 count
, sm2_curves
[testnum
].bits
,
2888 sm2_curves
[testnum
].name
, d
);
2889 sm2_results
[testnum
][0] = (double)count
/ d
;
2893 /* Perform SM2 verification test */
2894 for (i
= 0; i
< loopargs_len
; i
++) {
2895 st
= EVP_DigestVerify(loopargs
[i
].sm2_vfy_ctx
[testnum
],
2896 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2897 loopargs
[i
].buf
, 20);
2903 "SM2 verify failure. No SM2 verify will be done.\n");
2904 ERR_print_errors(bio_err
);
2905 sm2_doit
[testnum
] = 0;
2907 pkey_print_message("verify", sm2_curves
[testnum
].name
,
2909 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2911 count
= run_benchmark(async_jobs
, SM2_verify_loop
, loopargs
);
2914 mr
? "+R11:%ld:%u:%s:%.2f\n"
2915 : "%ld %u bits %s verify in %.2fs\n",
2916 count
, sm2_curves
[testnum
].bits
,
2917 sm2_curves
[testnum
].name
, d
);
2918 sm2_results
[testnum
][1] = (double)count
/ d
;
2921 if (op_count
<= 1) {
2922 /* if longer than 10s, don't do any more */
2923 for (testnum
++; testnum
< SM2_NUM
; testnum
++)
2924 sm2_doit
[testnum
] = 0;
2928 #endif /* OPENSSL_NO_SM2 */
2930 #ifndef OPENSSL_NO_DH
2931 for (testnum
= 0; testnum
< FFDH_NUM
; testnum
++) {
2932 int ffdh_checks
= 1;
2934 if (!ffdh_doit
[testnum
])
2937 for (i
= 0; i
< loopargs_len
; i
++) {
2938 EVP_PKEY
*pkey_A
= NULL
;
2939 EVP_PKEY
*pkey_B
= NULL
;
2940 EVP_PKEY_CTX
*ffdh_ctx
= NULL
;
2941 EVP_PKEY_CTX
*test_ctx
= NULL
;
2945 /* Ensure that the error queue is empty */
2946 if (ERR_peek_error()) {
2948 "WARNING: the error queue contains previous unhandled errors.\n");
2949 ERR_print_errors(bio_err
);
2952 pkey_A
= EVP_PKEY_new();
2954 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2955 ERR_print_errors(bio_err
);
2960 pkey_B
= EVP_PKEY_new();
2962 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2963 ERR_print_errors(bio_err
);
2969 ffdh_ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_DH
, NULL
);
2971 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
2972 ERR_print_errors(bio_err
);
2978 if (EVP_PKEY_keygen_init(ffdh_ctx
) <= 0) {
2979 BIO_printf(bio_err
, "Error while initialising EVP_PKEY_CTX.\n");
2980 ERR_print_errors(bio_err
);
2985 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx
, ffdh_params
[testnum
].nid
) <= 0) {
2986 BIO_printf(bio_err
, "Error setting DH key size for keygen.\n");
2987 ERR_print_errors(bio_err
);
2993 if (EVP_PKEY_keygen(ffdh_ctx
, &pkey_A
) <= 0 ||
2994 EVP_PKEY_keygen(ffdh_ctx
, &pkey_B
) <= 0) {
2995 BIO_printf(bio_err
, "FFDH key generation failure.\n");
2996 ERR_print_errors(bio_err
);
3002 EVP_PKEY_CTX_free(ffdh_ctx
);
3005 * check if the derivation works correctly both ways so that
3006 * we know if future derive calls will fail, and we can skip
3007 * error checking in benchmarked code
3009 ffdh_ctx
= EVP_PKEY_CTX_new(pkey_A
, NULL
);
3010 if (ffdh_ctx
== NULL
) {
3011 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3012 ERR_print_errors(bio_err
);
3017 if (EVP_PKEY_derive_init(ffdh_ctx
) <= 0) {
3018 BIO_printf(bio_err
, "FFDH derivation context init failure.\n");
3019 ERR_print_errors(bio_err
);
3024 if (EVP_PKEY_derive_set_peer(ffdh_ctx
, pkey_B
) <= 0) {
3025 BIO_printf(bio_err
, "Assigning peer key for derivation failed.\n");
3026 ERR_print_errors(bio_err
);
3031 if (EVP_PKEY_derive(ffdh_ctx
, NULL
, &secret_size
) <= 0) {
3032 BIO_printf(bio_err
, "Checking size of shared secret failed.\n");
3033 ERR_print_errors(bio_err
);
3038 if (secret_size
> MAX_FFDH_SIZE
) {
3039 BIO_printf(bio_err
, "Assertion failure: shared secret too large.\n");
3044 if (EVP_PKEY_derive(ffdh_ctx
,
3045 loopargs
[i
].secret_ff_a
,
3046 &secret_size
) <= 0) {
3047 BIO_printf(bio_err
, "Shared secret derive failure.\n");
3048 ERR_print_errors(bio_err
);
3053 /* Now check from side B */
3054 test_ctx
= EVP_PKEY_CTX_new(pkey_B
, NULL
);
3056 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3057 ERR_print_errors(bio_err
);
3062 if (!EVP_PKEY_derive_init(test_ctx
) ||
3063 !EVP_PKEY_derive_set_peer(test_ctx
, pkey_A
) ||
3064 !EVP_PKEY_derive(test_ctx
, NULL
, &test_out
) ||
3065 !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_ff_b
, &test_out
) ||
3066 test_out
!= secret_size
) {
3067 BIO_printf(bio_err
, "FFDH computation failure.\n");
3073 /* compare the computed secrets */
3074 if (CRYPTO_memcmp(loopargs
[i
].secret_ff_a
,
3075 loopargs
[i
].secret_ff_b
, secret_size
)) {
3076 BIO_printf(bio_err
, "FFDH computations don't match.\n");
3077 ERR_print_errors(bio_err
);
3083 loopargs
[i
].ffdh_ctx
[testnum
] = ffdh_ctx
;
3085 EVP_PKEY_free(pkey_A
);
3087 EVP_PKEY_free(pkey_B
);
3089 EVP_PKEY_CTX_free(test_ctx
);
3092 if (ffdh_checks
!= 0) {
3093 pkey_print_message("", "ffdh", ffdh_c
[testnum
][0],
3094 ffdh_params
[testnum
].bits
, seconds
.ffdh
);
3097 run_benchmark(async_jobs
, FFDH_derive_key_loop
, loopargs
);
3100 mr
? "+R12:%ld:%d:%.2f\n" :
3101 "%ld %u-bits FFDH ops in %.2fs\n", count
,
3102 ffdh_params
[testnum
].bits
, d
);
3103 ffdh_results
[testnum
][0] = (double)count
/ d
;
3106 if (op_count
<= 1) {
3107 /* if longer than 10s, don't do any more */
3108 stop_it(ffdh_doit
, testnum
);
3111 #endif /* OPENSSL_NO_DH */
3116 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING
));
3117 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON
));
3118 printf("options: %s\n", BN_options());
3119 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS
));
3120 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO
));
3127 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3130 for (testnum
= 0; testnum
< size_num
; testnum
++)
3131 printf(mr
? ":%d" : "%7d bytes", lengths
[testnum
]);
3135 for (k
= 0; k
< ALGOR_NUM
; k
++) {
3139 printf("+F:%u:%s", k
, names
[k
]);
3141 printf("%-13s", names
[k
]);
3142 for (testnum
= 0; testnum
< size_num
; testnum
++) {
3143 if (results
[k
][testnum
] > 10000 && !mr
)
3144 printf(" %11.2fk", results
[k
][testnum
] / 1e3
);
3146 printf(mr
? ":%.2f" : " %11.2f ", results
[k
][testnum
]);
3151 for (k
= 0; k
< RSA_NUM
; k
++) {
3154 if (testnum
&& !mr
) {
3155 printf("%18ssign verify sign/s verify/s\n", " ");
3159 printf("+F2:%u:%u:%f:%f\n",
3160 k
, rsa_keys
[k
].bits
, rsa_results
[k
][0], rsa_results
[k
][1]);
3162 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3163 rsa_keys
[k
].bits
, 1.0 / rsa_results
[k
][0], 1.0 / rsa_results
[k
][1],
3164 rsa_results
[k
][0], rsa_results
[k
][1]);
3167 for (k
= 0; k
< DSA_NUM
; k
++) {
3170 if (testnum
&& !mr
) {
3171 printf("%18ssign verify sign/s verify/s\n", " ");
3175 printf("+F3:%u:%u:%f:%f\n",
3176 k
, dsa_bits
[k
], dsa_results
[k
][0], dsa_results
[k
][1]);
3178 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3179 dsa_bits
[k
], 1.0 / dsa_results
[k
][0], 1.0 / dsa_results
[k
][1],
3180 dsa_results
[k
][0], dsa_results
[k
][1]);
3183 for (k
= 0; k
< OSSL_NELEM(ecdsa_doit
); k
++) {
3186 if (testnum
&& !mr
) {
3187 printf("%30ssign verify sign/s verify/s\n", " ");
3192 printf("+F4:%u:%u:%f:%f\n",
3193 k
, ec_curves
[k
].bits
,
3194 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3196 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3197 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3198 1.0 / ecdsa_results
[k
][0], 1.0 / ecdsa_results
[k
][1],
3199 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3203 for (k
= 0; k
< EC_NUM
; k
++) {
3206 if (testnum
&& !mr
) {
3207 printf("%30sop op/s\n", " ");
3211 printf("+F5:%u:%u:%f:%f\n",
3212 k
, ec_curves
[k
].bits
,
3213 ecdh_results
[k
][0], 1.0 / ecdh_results
[k
][0]);
3216 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3217 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3218 1.0 / ecdh_results
[k
][0], ecdh_results
[k
][0]);
3222 for (k
= 0; k
< OSSL_NELEM(eddsa_doit
); k
++) {
3225 if (testnum
&& !mr
) {
3226 printf("%30ssign verify sign/s verify/s\n", " ");
3231 printf("+F6:%u:%u:%s:%f:%f\n",
3232 k
, ed_curves
[k
].bits
, ed_curves
[k
].name
,
3233 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3235 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3236 ed_curves
[k
].bits
, ed_curves
[k
].name
,
3237 1.0 / eddsa_results
[k
][0], 1.0 / eddsa_results
[k
][1],
3238 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3241 #ifndef OPENSSL_NO_SM2
3243 for (k
= 0; k
< OSSL_NELEM(sm2_doit
); k
++) {
3246 if (testnum
&& !mr
) {
3247 printf("%30ssign verify sign/s verify/s\n", " ");
3252 printf("+F7:%u:%u:%s:%f:%f\n",
3253 k
, sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3254 sm2_results
[k
][0], sm2_results
[k
][1]);
3256 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3257 sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3258 1.0 / sm2_results
[k
][0], 1.0 / sm2_results
[k
][1],
3259 sm2_results
[k
][0], sm2_results
[k
][1]);
3262 #ifndef OPENSSL_NO_DH
3264 for (k
= 0; k
< FFDH_NUM
; k
++) {
3267 if (testnum
&& !mr
) {
3268 printf("%23sop op/s\n", " ");
3272 printf("+F8:%u:%u:%f:%f\n",
3273 k
, ffdh_params
[k
].bits
,
3274 ffdh_results
[k
][0], 1.0 / ffdh_results
[k
][0]);
3277 printf("%4u bits ffdh %8.4fs %8.1f\n",
3278 ffdh_params
[k
].bits
,
3279 1.0 / ffdh_results
[k
][0], ffdh_results
[k
][0]);
3281 #endif /* OPENSSL_NO_DH */
3286 ERR_print_errors(bio_err
);
3287 for (i
= 0; i
< loopargs_len
; i
++) {
3288 OPENSSL_free(loopargs
[i
].buf_malloc
);
3289 OPENSSL_free(loopargs
[i
].buf2_malloc
);
3292 EVP_PKEY_CTX_free(genctx
);
3293 for (k
= 0; k
< RSA_NUM
; k
++) {
3294 EVP_PKEY_CTX_free(loopargs
[i
].rsa_sign_ctx
[k
]);
3295 EVP_PKEY_CTX_free(loopargs
[i
].rsa_verify_ctx
[k
]);
3297 #ifndef OPENSSL_NO_DH
3298 OPENSSL_free(loopargs
[i
].secret_ff_a
);
3299 OPENSSL_free(loopargs
[i
].secret_ff_b
);
3300 for (k
= 0; k
< FFDH_NUM
; k
++)
3301 EVP_PKEY_CTX_free(loopargs
[i
].ffdh_ctx
[k
]);
3303 for (k
= 0; k
< DSA_NUM
; k
++) {
3304 EVP_PKEY_CTX_free(loopargs
[i
].dsa_sign_ctx
[k
]);
3305 EVP_PKEY_CTX_free(loopargs
[i
].dsa_verify_ctx
[k
]);
3307 for (k
= 0; k
< ECDSA_NUM
; k
++) {
3308 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_sign_ctx
[k
]);
3309 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_verify_ctx
[k
]);
3311 for (k
= 0; k
< EC_NUM
; k
++)
3312 EVP_PKEY_CTX_free(loopargs
[i
].ecdh_ctx
[k
]);
3313 for (k
= 0; k
< EdDSA_NUM
; k
++) {
3314 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx
[k
]);
3315 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx2
[k
]);
3317 #ifndef OPENSSL_NO_SM2
3318 for (k
= 0; k
< SM2_NUM
; k
++) {
3319 EVP_PKEY_CTX
*pctx
= NULL
;
3321 /* free signing ctx */
3322 if (loopargs
[i
].sm2_ctx
[k
] != NULL
3323 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_ctx
[k
])) != NULL
)
3324 EVP_PKEY_CTX_free(pctx
);
3325 EVP_MD_CTX_free(loopargs
[i
].sm2_ctx
[k
]);
3326 /* free verification ctx */
3327 if (loopargs
[i
].sm2_vfy_ctx
[k
] != NULL
3328 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[k
])) != NULL
)
3329 EVP_PKEY_CTX_free(pctx
);
3330 EVP_MD_CTX_free(loopargs
[i
].sm2_vfy_ctx
[k
]);
3332 EVP_PKEY_free(loopargs
[i
].sm2_pkey
[k
]);
3335 OPENSSL_free(loopargs
[i
].secret_a
);
3336 OPENSSL_free(loopargs
[i
].secret_b
);
3338 OPENSSL_free(evp_hmac_name
);
3339 OPENSSL_free(evp_cmac_name
);
3341 if (async_jobs
> 0) {
3342 for (i
= 0; i
< loopargs_len
; i
++)
3343 ASYNC_WAIT_CTX_free(loopargs
[i
].wait_ctx
);
3347 ASYNC_cleanup_thread();
3349 OPENSSL_free(loopargs
);
3351 EVP_CIPHER_free(evp_cipher
);
3356 static void print_message(const char *s
, long num
, int length
, int tm
)
3359 mr
? "+DT:%s:%d:%d\n"
3360 : "Doing %s for %ds on %d size blocks: ", s
, tm
, length
);
3361 (void)BIO_flush(bio_err
);
3366 static void pkey_print_message(const char *str
, const char *str2
, long num
,
3367 unsigned int bits
, int tm
)
3370 mr
? "+DTP:%d:%s:%s:%d\n"
3371 : "Doing %u bits %s %s's for %ds: ", bits
, str
, str2
, tm
);
3372 (void)BIO_flush(bio_err
);
3377 static void print_result(int alg
, int run_no
, int count
, double time_used
)
3380 BIO_printf(bio_err
, "%s error!\n", names
[alg
]);
3381 ERR_print_errors(bio_err
);
3385 mr
? "+R:%d:%s:%f\n"
3386 : "%d %s's in %.2fs\n", count
, names
[alg
], time_used
);
3387 results
[alg
][run_no
] = ((double)count
) / time_used
* lengths
[run_no
];
3391 static char *sstrsep(char **string
, const char *delim
)
3394 char *token
= *string
;
3399 memset(isdelim
, 0, sizeof(isdelim
));
3403 isdelim
[(unsigned char)(*delim
)] = 1;
3407 while (!isdelim
[(unsigned char)(**string
)])
3418 static int do_multi(int multi
, int size_num
)
3423 static char sep
[] = ":";
3425 fds
= app_malloc(sizeof(*fds
) * multi
, "fd buffer for do_multi");
3426 for (n
= 0; n
< multi
; ++n
) {
3427 if (pipe(fd
) == -1) {
3428 BIO_printf(bio_err
, "pipe failure\n");
3432 (void)BIO_flush(bio_err
);
3439 if (dup(fd
[1]) == -1) {
3440 BIO_printf(bio_err
, "dup failed\n");
3449 printf("Forked child %d\n", n
);
3452 /* for now, assume the pipe is long enough to take all the output */
3453 for (n
= 0; n
< multi
; ++n
) {
3458 f
= fdopen(fds
[n
], "r");
3459 while (fgets(buf
, sizeof(buf
), f
)) {
3460 p
= strchr(buf
, '\n');
3463 if (buf
[0] != '+') {
3465 "Don't understand line '%s' from child %d\n", buf
,
3469 printf("Got: %s from %d\n", buf
, n
);
3471 if (CHECK_AND_SKIP_PREFIX(p
, "+F:")) {
3475 alg
= atoi(sstrsep(&p
, sep
));
3477 for (j
= 0; j
< size_num
; ++j
)
3478 results
[alg
][j
] += atof(sstrsep(&p
, sep
));
3479 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F2:")) {
3483 k
= atoi(sstrsep(&p
, sep
));
3486 d
= atof(sstrsep(&p
, sep
));
3487 rsa_results
[k
][0] += d
;
3489 d
= atof(sstrsep(&p
, sep
));
3490 rsa_results
[k
][1] += d
;
3491 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F3:")) {
3495 k
= atoi(sstrsep(&p
, sep
));
3498 d
= atof(sstrsep(&p
, sep
));
3499 dsa_results
[k
][0] += d
;
3501 d
= atof(sstrsep(&p
, sep
));
3502 dsa_results
[k
][1] += d
;
3503 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F4:")) {
3507 k
= atoi(sstrsep(&p
, sep
));
3510 d
= atof(sstrsep(&p
, sep
));
3511 ecdsa_results
[k
][0] += d
;
3513 d
= atof(sstrsep(&p
, sep
));
3514 ecdsa_results
[k
][1] += d
;
3515 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F5:")) {
3519 k
= atoi(sstrsep(&p
, sep
));
3522 d
= atof(sstrsep(&p
, sep
));
3523 ecdh_results
[k
][0] += d
;
3524 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F6:")) {
3528 k
= atoi(sstrsep(&p
, sep
));
3532 d
= atof(sstrsep(&p
, sep
));
3533 eddsa_results
[k
][0] += d
;
3535 d
= atof(sstrsep(&p
, sep
));
3536 eddsa_results
[k
][1] += d
;
3537 # ifndef OPENSSL_NO_SM2
3538 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F7:")) {
3542 k
= atoi(sstrsep(&p
, sep
));
3546 d
= atof(sstrsep(&p
, sep
));
3547 sm2_results
[k
][0] += d
;
3549 d
= atof(sstrsep(&p
, sep
));
3550 sm2_results
[k
][1] += d
;
3551 # endif /* OPENSSL_NO_SM2 */
3552 # ifndef OPENSSL_NO_DH
3553 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F8:")) {
3557 k
= atoi(sstrsep(&p
, sep
));
3560 d
= atof(sstrsep(&p
, sep
));
3561 ffdh_results
[k
][0] += d
;
3562 # endif /* OPENSSL_NO_DH */
3563 } else if (!HAS_PREFIX(buf
, "+H:")) {
3564 BIO_printf(bio_err
, "Unknown type '%s' from child %d\n", buf
,
3576 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
3577 const openssl_speed_sec_t
*seconds
)
3579 static const int mblengths_list
[] =
3580 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3581 const int *mblengths
= mblengths_list
;
3582 int j
, count
, keylen
, num
= OSSL_NELEM(mblengths_list
);
3583 const char *alg_name
;
3584 unsigned char *inp
= NULL
, *out
= NULL
, *key
, no_key
[32], no_iv
[16];
3585 EVP_CIPHER_CTX
*ctx
= NULL
;
3588 if (lengths_single
) {
3589 mblengths
= &lengths_single
;
3593 inp
= app_malloc(mblengths
[num
- 1], "multiblock input buffer");
3594 out
= app_malloc(mblengths
[num
- 1] + 1024, "multiblock output buffer");
3595 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
3596 app_bail_out("failed to allocate cipher context\n");
3597 if (!EVP_EncryptInit_ex(ctx
, evp_cipher
, NULL
, NULL
, no_iv
))
3598 app_bail_out("failed to initialise cipher context\n");
3600 if ((keylen
= EVP_CIPHER_CTX_get_key_length(ctx
)) < 0) {
3601 BIO_printf(bio_err
, "Impossible negative key length: %d\n", keylen
);
3604 key
= app_malloc(keylen
, "evp_cipher key");
3605 if (!EVP_CIPHER_CTX_rand_key(ctx
, key
))
3606 app_bail_out("failed to generate random cipher key\n");
3607 if (!EVP_EncryptInit_ex(ctx
, NULL
, NULL
, key
, NULL
))
3608 app_bail_out("failed to set cipher key\n");
3609 OPENSSL_clear_free(key
, keylen
);
3611 if (!EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_MAC_KEY
,
3612 sizeof(no_key
), no_key
))
3613 app_bail_out("failed to set AEAD key\n");
3614 if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
3615 app_bail_out("failed to get cipher name\n");
3617 for (j
= 0; j
< num
; j
++) {
3618 print_message(alg_name
, 0, mblengths
[j
], seconds
->sym
);
3620 for (count
= 0; run
&& count
< INT_MAX
; count
++) {
3621 unsigned char aad
[EVP_AEAD_TLS1_AAD_LEN
];
3622 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param
;
3623 size_t len
= mblengths
[j
];
3626 memset(aad
, 0, 8); /* avoid uninitialized values */
3627 aad
[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3628 aad
[9] = 3; /* version */
3630 aad
[11] = 0; /* length */
3632 mb_param
.out
= NULL
;
3635 mb_param
.interleave
= 8;
3637 packlen
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD
,
3638 sizeof(mb_param
), &mb_param
);
3644 (void)EVP_CIPHER_CTX_ctrl(ctx
,
3645 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT
,
3646 sizeof(mb_param
), &mb_param
);
3650 RAND_bytes(out
, 16);
3652 aad
[11] = (unsigned char)(len
>> 8);
3653 aad
[12] = (unsigned char)(len
);
3654 pad
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_TLS1_AAD
,
3655 EVP_AEAD_TLS1_AAD_LEN
, aad
);
3656 EVP_Cipher(ctx
, out
, inp
, len
+ pad
);
3660 BIO_printf(bio_err
, mr
? "+R:%d:%s:%f\n"
3661 : "%d %s's in %.2fs\n", count
, "evp", d
);
3662 results
[D_EVP
][j
] = ((double)count
) / d
* mblengths
[j
];
3666 fprintf(stdout
, "+H");
3667 for (j
= 0; j
< num
; j
++)
3668 fprintf(stdout
, ":%d", mblengths
[j
]);
3669 fprintf(stdout
, "\n");
3670 fprintf(stdout
, "+F:%d:%s", D_EVP
, alg_name
);
3671 for (j
= 0; j
< num
; j
++)
3672 fprintf(stdout
, ":%.2f", results
[D_EVP
][j
]);
3673 fprintf(stdout
, "\n");
3676 "The 'numbers' are in 1000s of bytes per second processed.\n");
3677 fprintf(stdout
, "type ");
3678 for (j
= 0; j
< num
; j
++)
3679 fprintf(stdout
, "%7d bytes", mblengths
[j
]);
3680 fprintf(stdout
, "\n");
3681 fprintf(stdout
, "%-24s", alg_name
);
3683 for (j
= 0; j
< num
; j
++) {
3684 if (results
[D_EVP
][j
] > 10000)
3685 fprintf(stdout
, " %11.2fk", results
[D_EVP
][j
] / 1e3
);
3687 fprintf(stdout
, " %11.2f ", results
[D_EVP
][j
]);
3689 fprintf(stdout
, "\n");
3695 EVP_CIPHER_CTX_free(ctx
);