2 * Copyright 1995-2021 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 <openssl/crypto.h>
33 #include <openssl/rand.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/objects.h>
37 #include <openssl/core_names.h>
38 #include <openssl/async.h>
39 #if !defined(OPENSSL_SYS_MSDOS)
44 # if defined(OPENSSL_TANDEM_FLOSS)
45 # include <floss.h(floss_fork)>
53 #include <openssl/bn.h>
54 #include <openssl/rsa.h>
55 #include "./testrsa.h"
57 # include <openssl/dh.h>
59 #include <openssl/x509.h>
60 #include <openssl/dsa.h>
61 #include "./testdsa.h"
62 #include <openssl/modes.h>
65 # if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
78 #define MAX_MISALIGNMENT 63
79 #define MAX_ECDH_SIZE 256
81 #define MAX_FFDH_SIZE 1024
83 #ifndef RSA_DEFAULT_PRIME_NUM
84 # define RSA_DEFAULT_PRIME_NUM 2
87 typedef struct openssl_speed_sec_st
{
96 } openssl_speed_sec_t
;
98 static volatile int run
= 0;
100 static int mr
= 0; /* machine-readeable output format to merge fork results */
101 static int usertime
= 1;
103 static double Time_F(int s
);
104 static void print_message(const char *s
, long num
, int length
, int tm
);
105 static void pkey_print_message(const char *str
, const char *str2
,
106 long num
, unsigned int bits
, int sec
);
107 static void print_result(int alg
, int run_no
, int count
, double time_used
);
109 static int do_multi(int multi
, int size_num
);
112 static const int lengths_list
[] = {
113 16, 64, 256, 1024, 8 * 1024, 16 * 1024
115 #define SIZE_NUM OSSL_NELEM(lengths_list)
116 static const int *lengths
= lengths_list
;
118 static const int aead_lengths_list
[] = {
119 2, 31, 136, 1024, 8 * 1024, 16 * 1024
127 static void alarmed(int sig
)
129 signal(SIGALRM
, alarmed
);
133 static double Time_F(int s
)
135 double ret
= app_tminterval(s
, usertime
);
141 #elif defined(_WIN32)
145 static unsigned int lapse
;
146 static volatile unsigned int schlock
;
147 static void alarm_win32(unsigned int secs
)
152 # define alarm alarm_win32
154 static DWORD WINAPI
sleepy(VOID
* arg
)
162 static double Time_F(int s
)
169 thr
= CreateThread(NULL
, 4096, sleepy
, NULL
, 0, NULL
);
171 DWORD err
= GetLastError();
172 BIO_printf(bio_err
, "unable to CreateThread (%lu)", err
);
176 Sleep(0); /* scheduler spinlock */
177 ret
= app_tminterval(s
, usertime
);
179 ret
= app_tminterval(s
, usertime
);
181 TerminateThread(thr
, 0);
188 # error "SIGALRM not defined and the platform is not Windows"
191 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
192 const openssl_speed_sec_t
*seconds
);
194 static int opt_found(const char *name
, unsigned int *result
,
195 const OPT_PAIR pairs
[], unsigned int nbelem
)
199 for (idx
= 0; idx
< nbelem
; ++idx
, pairs
++)
200 if (strcmp(name
, pairs
->name
) == 0) {
201 *result
= pairs
->retval
;
206 #define opt_found(value, pairs, result)\
207 opt_found(value, result, pairs, OSSL_NELEM(pairs))
209 typedef enum OPTION_choice
{
211 OPT_ELAPSED
, OPT_EVP
, OPT_HMAC
, OPT_DECRYPT
, OPT_ENGINE
, OPT_MULTI
,
212 OPT_MR
, OPT_MB
, OPT_MISALIGN
, OPT_ASYNCJOBS
, OPT_R_ENUM
, OPT_PROV_ENUM
,
213 OPT_PRIMES
, OPT_SECONDS
, OPT_BYTES
, OPT_AEAD
, OPT_CMAC
216 const OPTIONS speed_options
[] = {
217 {OPT_HELP_STR
, 1, '-',
218 "Usage: %s [options] [algorithm...]\n"
219 "All +int options consider prefix '0' as base-8 input, "
220 "prefix '0x'/'0X' as base-16 input.\n"
223 OPT_SECTION("General"),
224 {"help", OPT_HELP
, '-', "Display this summary"},
226 "Enable (tls1>=1) multi-block mode on EVP-named cipher"},
227 {"mr", OPT_MR
, '-', "Produce machine readable output"},
229 {"multi", OPT_MULTI
, 'p', "Run benchmarks in parallel"},
231 #ifndef OPENSSL_NO_ASYNC
232 {"async_jobs", OPT_ASYNCJOBS
, 'p',
233 "Enable async mode and start specified number of jobs"},
235 #ifndef OPENSSL_NO_ENGINE
236 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
238 {"primes", OPT_PRIMES
, 'p', "Specify number of primes (for RSA only)"},
240 OPT_SECTION("Selection"),
241 {"evp", OPT_EVP
, 's', "Use EVP-named cipher or digest"},
242 {"hmac", OPT_HMAC
, 's', "HMAC using EVP-named digest"},
243 {"cmac", OPT_CMAC
, 's', "CMAC using EVP-named cipher"},
244 {"decrypt", OPT_DECRYPT
, '-',
245 "Time decryption instead of encryption (only EVP)"},
246 {"aead", OPT_AEAD
, '-',
247 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
249 OPT_SECTION("Timing"),
250 {"elapsed", OPT_ELAPSED
, '-',
251 "Use wall-clock time instead of CPU user time as divisor"},
252 {"seconds", OPT_SECONDS
, 'p',
253 "Run benchmarks for specified amount of seconds"},
254 {"bytes", OPT_BYTES
, 'p',
255 "Run [non-PKI] benchmarks on custom-sized buffer"},
256 {"misalign", OPT_MISALIGN
, 'p',
257 "Use specified offset to mis-align buffers"},
263 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
268 D_MD2
, D_MDC2
, D_MD4
, D_MD5
, D_SHA1
, D_RMD160
,
269 D_SHA256
, D_SHA512
, D_WHIRLPOOL
, D_HMAC
,
270 D_CBC_DES
, D_EDE3_DES
, D_RC4
, D_CBC_IDEA
, D_CBC_SEED
,
271 D_CBC_RC2
, D_CBC_RC5
, D_CBC_BF
, D_CBC_CAST
,
272 D_CBC_128_AES
, D_CBC_192_AES
, D_CBC_256_AES
,
273 D_CBC_128_CML
, D_CBC_192_CML
, D_CBC_256_CML
,
274 D_EVP
, D_GHASH
, D_RAND
, D_EVP_CMAC
, ALGOR_NUM
276 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
277 static const char *names
[ALGOR_NUM
] = {
278 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
279 "sha256", "sha512", "whirlpool", "hmac(md5)",
280 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
281 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
282 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
283 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
284 "evp", "ghash", "rand", "cmac"
287 /* list of configured algorithm (remaining), with some few alias */
288 static const OPT_PAIR doit_choices
[] = {
295 {"sha256", D_SHA256
},
296 {"sha512", D_SHA512
},
297 {"whirlpool", D_WHIRLPOOL
},
298 {"ripemd", D_RMD160
},
299 {"rmd160", D_RMD160
},
300 {"ripemd160", D_RMD160
},
302 {"des-cbc", D_CBC_DES
},
303 {"des-ede3", D_EDE3_DES
},
304 {"aes-128-cbc", D_CBC_128_AES
},
305 {"aes-192-cbc", D_CBC_192_AES
},
306 {"aes-256-cbc", D_CBC_256_AES
},
307 {"camellia-128-cbc", D_CBC_128_CML
},
308 {"camellia-192-cbc", D_CBC_192_CML
},
309 {"camellia-256-cbc", D_CBC_256_CML
},
310 {"rc2-cbc", D_CBC_RC2
},
312 {"rc5-cbc", D_CBC_RC5
},
314 {"idea-cbc", D_CBC_IDEA
},
315 {"idea", D_CBC_IDEA
},
316 {"seed-cbc", D_CBC_SEED
},
317 {"seed", D_CBC_SEED
},
318 {"bf-cbc", D_CBC_BF
},
319 {"blowfish", D_CBC_BF
},
321 {"cast-cbc", D_CBC_CAST
},
322 {"cast", D_CBC_CAST
},
323 {"cast5", D_CBC_CAST
},
328 static double results
[ALGOR_NUM
][SIZE_NUM
];
330 enum { R_DSA_512
, R_DSA_1024
, R_DSA_2048
, DSA_NUM
};
331 static const OPT_PAIR dsa_choices
[DSA_NUM
] = {
332 {"dsa512", R_DSA_512
},
333 {"dsa1024", R_DSA_1024
},
334 {"dsa2048", R_DSA_2048
}
336 static double dsa_results
[DSA_NUM
][2]; /* 2 ops: sign then verify */
339 R_RSA_512
, R_RSA_1024
, R_RSA_2048
, R_RSA_3072
, R_RSA_4096
, R_RSA_7680
,
342 static const OPT_PAIR rsa_choices
[RSA_NUM
] = {
343 {"rsa512", R_RSA_512
},
344 {"rsa1024", R_RSA_1024
},
345 {"rsa2048", R_RSA_2048
},
346 {"rsa3072", R_RSA_3072
},
347 {"rsa4096", R_RSA_4096
},
348 {"rsa7680", R_RSA_7680
},
349 {"rsa15360", R_RSA_15360
}
352 static double rsa_results
[RSA_NUM
][2]; /* 2 ops: sign then verify */
354 #ifndef OPENSSL_NO_DH
356 R_FFDH_2048
, R_FFDH_3072
, R_FFDH_4096
, R_FFDH_6144
, R_FFDH_8192
, FFDH_NUM
359 static const OPT_PAIR ffdh_choices
[FFDH_NUM
] = {
360 {"ffdh2048", R_FFDH_2048
},
361 {"ffdh3072", R_FFDH_3072
},
362 {"ffdh4096", R_FFDH_4096
},
363 {"ffdh6144", R_FFDH_6144
},
364 {"ffdh8192", R_FFDH_8192
},
367 static double ffdh_results
[FFDH_NUM
][1]; /* 1 op: derivation */
368 #endif /* OPENSSL_NO_DH */
371 R_EC_P160
, R_EC_P192
, R_EC_P224
, R_EC_P256
, R_EC_P384
, R_EC_P521
,
372 #ifndef OPENSSL_NO_EC2M
373 R_EC_K163
, R_EC_K233
, R_EC_K283
, R_EC_K409
, R_EC_K571
,
374 R_EC_B163
, R_EC_B233
, R_EC_B283
, R_EC_B409
, R_EC_B571
,
376 R_EC_BRP256R1
, R_EC_BRP256T1
, R_EC_BRP384R1
, R_EC_BRP384T1
,
377 R_EC_BRP512R1
, R_EC_BRP512T1
, ECDSA_NUM
379 /* list of ecdsa curves */
380 static const OPT_PAIR ecdsa_choices
[ECDSA_NUM
] = {
381 {"ecdsap160", R_EC_P160
},
382 {"ecdsap192", R_EC_P192
},
383 {"ecdsap224", R_EC_P224
},
384 {"ecdsap256", R_EC_P256
},
385 {"ecdsap384", R_EC_P384
},
386 {"ecdsap521", R_EC_P521
},
387 #ifndef OPENSSL_NO_EC2M
388 {"ecdsak163", R_EC_K163
},
389 {"ecdsak233", R_EC_K233
},
390 {"ecdsak283", R_EC_K283
},
391 {"ecdsak409", R_EC_K409
},
392 {"ecdsak571", R_EC_K571
},
393 {"ecdsab163", R_EC_B163
},
394 {"ecdsab233", R_EC_B233
},
395 {"ecdsab283", R_EC_B283
},
396 {"ecdsab409", R_EC_B409
},
397 {"ecdsab571", R_EC_B571
},
399 {"ecdsabrp256r1", R_EC_BRP256R1
},
400 {"ecdsabrp256t1", R_EC_BRP256T1
},
401 {"ecdsabrp384r1", R_EC_BRP384R1
},
402 {"ecdsabrp384t1", R_EC_BRP384T1
},
403 {"ecdsabrp512r1", R_EC_BRP512R1
},
404 {"ecdsabrp512t1", R_EC_BRP512T1
}
406 enum { R_EC_X25519
= ECDSA_NUM
, R_EC_X448
, EC_NUM
};
407 /* list of ecdh curves, extension of |ecdsa_choices| list above */
408 static const OPT_PAIR ecdh_choices
[EC_NUM
] = {
409 {"ecdhp160", R_EC_P160
},
410 {"ecdhp192", R_EC_P192
},
411 {"ecdhp224", R_EC_P224
},
412 {"ecdhp256", R_EC_P256
},
413 {"ecdhp384", R_EC_P384
},
414 {"ecdhp521", R_EC_P521
},
415 #ifndef OPENSSL_NO_EC2M
416 {"ecdhk163", R_EC_K163
},
417 {"ecdhk233", R_EC_K233
},
418 {"ecdhk283", R_EC_K283
},
419 {"ecdhk409", R_EC_K409
},
420 {"ecdhk571", R_EC_K571
},
421 {"ecdhb163", R_EC_B163
},
422 {"ecdhb233", R_EC_B233
},
423 {"ecdhb283", R_EC_B283
},
424 {"ecdhb409", R_EC_B409
},
425 {"ecdhb571", R_EC_B571
},
427 {"ecdhbrp256r1", R_EC_BRP256R1
},
428 {"ecdhbrp256t1", R_EC_BRP256T1
},
429 {"ecdhbrp384r1", R_EC_BRP384R1
},
430 {"ecdhbrp384t1", R_EC_BRP384T1
},
431 {"ecdhbrp512r1", R_EC_BRP512R1
},
432 {"ecdhbrp512t1", R_EC_BRP512T1
},
433 {"ecdhx25519", R_EC_X25519
},
434 {"ecdhx448", R_EC_X448
}
437 static double ecdh_results
[EC_NUM
][1]; /* 1 op: derivation */
438 static double ecdsa_results
[ECDSA_NUM
][2]; /* 2 ops: sign then verify */
440 enum { R_EC_Ed25519
, R_EC_Ed448
, EdDSA_NUM
};
441 static const OPT_PAIR eddsa_choices
[EdDSA_NUM
] = {
442 {"ed25519", R_EC_Ed25519
},
443 {"ed448", R_EC_Ed448
}
446 static double eddsa_results
[EdDSA_NUM
][2]; /* 2 ops: sign then verify */
448 #ifndef OPENSSL_NO_SM2
449 enum { R_EC_CURVESM2
, SM2_NUM
};
450 static const OPT_PAIR sm2_choices
[SM2_NUM
] = {
451 {"curveSM2", R_EC_CURVESM2
}
453 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
454 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
455 static double sm2_results
[SM2_NUM
][2]; /* 2 ops: sign then verify */
456 #endif /* OPENSSL_NO_SM2 */
458 #define COND(unused_cond) (run && count < 0x7fffffff)
459 #define COUNT(d) (count)
461 typedef struct loopargs_st
{
462 ASYNC_JOB
*inprogress_job
;
463 ASYNC_WAIT_CTX
*wait_ctx
;
466 unsigned char *buf_malloc
;
467 unsigned char *buf2_malloc
;
471 EVP_PKEY_CTX
*rsa_sign_ctx
[RSA_NUM
];
472 EVP_PKEY_CTX
*rsa_verify_ctx
[RSA_NUM
];
473 EVP_PKEY_CTX
*dsa_sign_ctx
[DSA_NUM
];
474 EVP_PKEY_CTX
*dsa_verify_ctx
[DSA_NUM
];
475 EVP_PKEY_CTX
*ecdsa_sign_ctx
[ECDSA_NUM
];
476 EVP_PKEY_CTX
*ecdsa_verify_ctx
[ECDSA_NUM
];
477 EVP_PKEY_CTX
*ecdh_ctx
[EC_NUM
];
478 EVP_MD_CTX
*eddsa_ctx
[EdDSA_NUM
];
479 EVP_MD_CTX
*eddsa_ctx2
[EdDSA_NUM
];
480 #ifndef OPENSSL_NO_SM2
481 EVP_MD_CTX
*sm2_ctx
[SM2_NUM
];
482 EVP_MD_CTX
*sm2_vfy_ctx
[SM2_NUM
];
483 EVP_PKEY
*sm2_pkey
[SM2_NUM
];
485 unsigned char *secret_a
;
486 unsigned char *secret_b
;
487 size_t outlen
[EC_NUM
];
488 #ifndef OPENSSL_NO_DH
489 EVP_PKEY_CTX
*ffdh_ctx
[FFDH_NUM
];
490 unsigned char *secret_ff_a
;
491 unsigned char *secret_ff_b
;
496 static int run_benchmark(int async_jobs
, int (*loop_function
) (void *),
497 loopargs_t
* loopargs
);
499 static unsigned int testnum
;
501 /* Nb of iterations to do per algorithm and key-size */
502 static long c
[ALGOR_NUM
][SIZE_NUM
];
504 static char *evp_mac_mdname
= "md5";
505 static char *evp_hmac_name
= NULL
;
506 static const char *evp_md_name
= NULL
;
507 static char *evp_mac_ciphername
= "aes-128-cbc";
508 static char *evp_cmac_name
= NULL
;
510 static int have_md(const char *name
)
515 if (opt_md_silent(name
, &md
)) {
516 EVP_MD_CTX
*ctx
= EVP_MD_CTX_new();
518 if (ctx
!= NULL
&& EVP_DigestInit(ctx
, md
) > 0)
520 EVP_MD_CTX_free(ctx
);
526 static int have_cipher(const char *name
)
529 EVP_CIPHER
*cipher
= NULL
;
531 if (opt_cipher_silent(name
, &cipher
)) {
532 EVP_CIPHER_CTX
*ctx
= EVP_CIPHER_CTX_new();
535 && EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1) > 0)
537 EVP_CIPHER_CTX_free(ctx
);
538 EVP_CIPHER_free(cipher
);
543 static int EVP_Digest_loop(const char *mdname
, int algindex
, void *args
)
545 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
546 unsigned char *buf
= tempargs
->buf
;
547 unsigned char digest
[EVP_MAX_MD_SIZE
];
551 if (!opt_md_silent(mdname
, &md
))
553 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
554 if (!EVP_Digest(buf
, (size_t)lengths
[testnum
], digest
, NULL
, md
,
564 static int EVP_Digest_md_loop(void *args
)
566 return EVP_Digest_loop(evp_md_name
, D_EVP
, args
);
569 static int EVP_Digest_MD2_loop(void *args
)
571 return EVP_Digest_loop("md2", D_MD2
, args
);
574 static int EVP_Digest_MDC2_loop(void *args
)
576 return EVP_Digest_loop("mdc2", D_MDC2
, args
);
579 static int EVP_Digest_MD4_loop(void *args
)
581 return EVP_Digest_loop("md4", D_MD4
, args
);
584 static int MD5_loop(void *args
)
586 return EVP_Digest_loop("md5", D_MD5
, args
);
589 static int EVP_MAC_loop(int algindex
, void *args
)
591 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
592 unsigned char *buf
= tempargs
->buf
;
593 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
594 unsigned char mac
[EVP_MAX_MD_SIZE
];
597 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
600 if (!EVP_MAC_init(mctx
, NULL
, 0, NULL
)
601 || !EVP_MAC_update(mctx
, buf
, lengths
[testnum
])
602 || !EVP_MAC_final(mctx
, mac
, &outl
, sizeof(mac
)))
608 static int HMAC_loop(void *args
)
610 return EVP_MAC_loop(D_HMAC
, args
);
613 static int CMAC_loop(void *args
)
615 return EVP_MAC_loop(D_EVP_CMAC
, args
);
618 static int SHA1_loop(void *args
)
620 return EVP_Digest_loop("sha1", D_SHA1
, args
);
623 static int SHA256_loop(void *args
)
625 return EVP_Digest_loop("sha256", D_SHA256
, args
);
628 static int SHA512_loop(void *args
)
630 return EVP_Digest_loop("sha512", D_SHA512
, args
);
633 static int WHIRLPOOL_loop(void *args
)
635 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL
, args
);
638 static int EVP_Digest_RMD160_loop(void *args
)
640 return EVP_Digest_loop("ripemd160", D_RMD160
, args
);
645 static int EVP_Cipher_loop(void *args
)
647 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
648 unsigned char *buf
= tempargs
->buf
;
651 if (tempargs
->ctx
== NULL
)
653 for (count
= 0; COND(c
[algindex
][testnum
]); count
++)
654 if (EVP_Cipher(tempargs
->ctx
, buf
, buf
, (size_t)lengths
[testnum
]) <= 0)
659 static int GHASH_loop(void *args
)
661 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
662 unsigned char *buf
= tempargs
->buf
;
663 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
666 /* just do the update in the loop to be comparable with 1.1.1 */
667 for (count
= 0; COND(c
[D_GHASH
][testnum
]); count
++) {
668 if (!EVP_MAC_update(mctx
, buf
, lengths
[testnum
]))
674 #define MAX_BLOCK_SIZE 128
676 static unsigned char iv
[2 * MAX_BLOCK_SIZE
/ 8];
678 static EVP_CIPHER_CTX
*init_evp_cipher_ctx(const char *ciphername
,
679 const unsigned char *key
,
682 EVP_CIPHER_CTX
*ctx
= NULL
;
683 EVP_CIPHER
*cipher
= NULL
;
685 if (!opt_cipher_silent(ciphername
, &cipher
))
688 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
691 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1)) {
692 EVP_CIPHER_CTX_free(ctx
);
697 if (!EVP_CIPHER_CTX_set_key_length(ctx
, keylen
)) {
698 EVP_CIPHER_CTX_free(ctx
);
703 if (!EVP_CipherInit_ex(ctx
, NULL
, NULL
, key
, iv
, 1)) {
704 EVP_CIPHER_CTX_free(ctx
);
710 EVP_CIPHER_free(cipher
);
714 static int RAND_bytes_loop(void *args
)
716 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
717 unsigned char *buf
= tempargs
->buf
;
720 for (count
= 0; COND(c
[D_RAND
][testnum
]); count
++)
721 RAND_bytes(buf
, lengths
[testnum
]);
725 static int decrypt
= 0;
726 static int EVP_Update_loop(void *args
)
728 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
729 unsigned char *buf
= tempargs
->buf
;
730 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
734 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
735 rc
= EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
737 /* reset iv in case of counter overflow */
738 EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
742 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
743 rc
= EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
745 /* reset iv in case of counter overflow */
746 EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
751 EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
753 EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
758 * CCM does not support streaming. For the purpose of performance measurement,
759 * each message is encrypted using the same (key,iv)-pair. Do not use this
760 * code in your application.
762 static int EVP_Update_loop_ccm(void *args
)
764 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
765 unsigned char *buf
= tempargs
->buf
;
766 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
768 unsigned char tag
[12];
771 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
772 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
, sizeof(tag
),
775 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
776 /* counter is reset on every update */
777 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
780 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
781 /* restore iv length field */
782 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, NULL
, lengths
[testnum
]);
783 /* counter is reset on every update */
784 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
788 (void)EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
790 (void)EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
795 * To make AEAD benchmarking more relevant perform TLS-like operations,
796 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
797 * payload length is not actually limited by 16KB...
799 static int EVP_Update_loop_aead(void *args
)
801 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
802 unsigned char *buf
= tempargs
->buf
;
803 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
805 unsigned char aad
[13] = { 0xcc };
806 unsigned char faketag
[16] = { 0xcc };
809 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
810 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
811 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
,
812 sizeof(faketag
), faketag
);
813 (void)EVP_DecryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
814 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
815 (void)EVP_DecryptFinal_ex(ctx
, buf
+ outl
, &outl
);
818 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
819 (void)EVP_EncryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
820 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
821 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
822 (void)EVP_EncryptFinal_ex(ctx
, buf
+ outl
, &outl
);
828 static long rsa_c
[RSA_NUM
][2]; /* # RSA iteration test */
830 static int RSA_sign_loop(void *args
)
832 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
833 unsigned char *buf
= tempargs
->buf
;
834 unsigned char *buf2
= tempargs
->buf2
;
835 size_t *rsa_num
= &tempargs
->sigsize
;
836 EVP_PKEY_CTX
**rsa_sign_ctx
= tempargs
->rsa_sign_ctx
;
839 for (count
= 0; COND(rsa_c
[testnum
][0]); count
++) {
840 *rsa_num
= tempargs
->buflen
;
841 ret
= EVP_PKEY_sign(rsa_sign_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
843 BIO_printf(bio_err
, "RSA sign failure\n");
844 ERR_print_errors(bio_err
);
852 static int RSA_verify_loop(void *args
)
854 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
855 unsigned char *buf
= tempargs
->buf
;
856 unsigned char *buf2
= tempargs
->buf2
;
857 size_t rsa_num
= tempargs
->sigsize
;
858 EVP_PKEY_CTX
**rsa_verify_ctx
= tempargs
->rsa_verify_ctx
;
861 for (count
= 0; COND(rsa_c
[testnum
][1]); count
++) {
862 ret
= EVP_PKEY_verify(rsa_verify_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
864 BIO_printf(bio_err
, "RSA verify failure\n");
865 ERR_print_errors(bio_err
);
873 #ifndef OPENSSL_NO_DH
874 static long ffdh_c
[FFDH_NUM
][1];
876 static int FFDH_derive_key_loop(void *args
)
878 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
879 EVP_PKEY_CTX
*ffdh_ctx
= tempargs
->ffdh_ctx
[testnum
];
880 unsigned char *derived_secret
= tempargs
->secret_ff_a
;
881 size_t outlen
= MAX_FFDH_SIZE
;
884 for (count
= 0; COND(ffdh_c
[testnum
][0]); count
++)
885 EVP_PKEY_derive(ffdh_ctx
, derived_secret
, &outlen
);
888 #endif /* OPENSSL_NO_DH */
890 static long dsa_c
[DSA_NUM
][2];
891 static int DSA_sign_loop(void *args
)
893 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
894 unsigned char *buf
= tempargs
->buf
;
895 unsigned char *buf2
= tempargs
->buf2
;
896 size_t *dsa_num
= &tempargs
->sigsize
;
897 EVP_PKEY_CTX
**dsa_sign_ctx
= tempargs
->dsa_sign_ctx
;
900 for (count
= 0; COND(dsa_c
[testnum
][0]); count
++) {
901 *dsa_num
= tempargs
->buflen
;
902 ret
= EVP_PKEY_sign(dsa_sign_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
904 BIO_printf(bio_err
, "DSA sign failure\n");
905 ERR_print_errors(bio_err
);
913 static int DSA_verify_loop(void *args
)
915 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
916 unsigned char *buf
= tempargs
->buf
;
917 unsigned char *buf2
= tempargs
->buf2
;
918 size_t dsa_num
= tempargs
->sigsize
;
919 EVP_PKEY_CTX
**dsa_verify_ctx
= tempargs
->dsa_verify_ctx
;
922 for (count
= 0; COND(dsa_c
[testnum
][1]); count
++) {
923 ret
= EVP_PKEY_verify(dsa_verify_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
925 BIO_printf(bio_err
, "DSA verify failure\n");
926 ERR_print_errors(bio_err
);
934 static long ecdsa_c
[ECDSA_NUM
][2];
935 static int ECDSA_sign_loop(void *args
)
937 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
938 unsigned char *buf
= tempargs
->buf
;
939 unsigned char *buf2
= tempargs
->buf2
;
940 size_t *ecdsa_num
= &tempargs
->sigsize
;
941 EVP_PKEY_CTX
**ecdsa_sign_ctx
= tempargs
->ecdsa_sign_ctx
;
944 for (count
= 0; COND(ecdsa_c
[testnum
][0]); count
++) {
945 *ecdsa_num
= tempargs
->buflen
;
946 ret
= EVP_PKEY_sign(ecdsa_sign_ctx
[testnum
], buf2
, ecdsa_num
, buf
, 20);
948 BIO_printf(bio_err
, "ECDSA sign failure\n");
949 ERR_print_errors(bio_err
);
957 static int ECDSA_verify_loop(void *args
)
959 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
960 unsigned char *buf
= tempargs
->buf
;
961 unsigned char *buf2
= tempargs
->buf2
;
962 size_t ecdsa_num
= tempargs
->sigsize
;
963 EVP_PKEY_CTX
**ecdsa_verify_ctx
= tempargs
->ecdsa_verify_ctx
;
966 for (count
= 0; COND(ecdsa_c
[testnum
][1]); count
++) {
967 ret
= EVP_PKEY_verify(ecdsa_verify_ctx
[testnum
], buf2
, ecdsa_num
,
970 BIO_printf(bio_err
, "ECDSA verify failure\n");
971 ERR_print_errors(bio_err
);
979 /* ******************************************************************** */
980 static long ecdh_c
[EC_NUM
][1];
982 static int ECDH_EVP_derive_key_loop(void *args
)
984 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
985 EVP_PKEY_CTX
*ctx
= tempargs
->ecdh_ctx
[testnum
];
986 unsigned char *derived_secret
= tempargs
->secret_a
;
988 size_t *outlen
= &(tempargs
->outlen
[testnum
]);
990 for (count
= 0; COND(ecdh_c
[testnum
][0]); count
++)
991 EVP_PKEY_derive(ctx
, derived_secret
, outlen
);
996 static long eddsa_c
[EdDSA_NUM
][2];
997 static int EdDSA_sign_loop(void *args
)
999 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1000 unsigned char *buf
= tempargs
->buf
;
1001 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx
;
1002 unsigned char *eddsasig
= tempargs
->buf2
;
1003 size_t *eddsasigsize
= &tempargs
->sigsize
;
1006 for (count
= 0; COND(eddsa_c
[testnum
][0]); count
++) {
1007 ret
= EVP_DigestSign(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1009 BIO_printf(bio_err
, "EdDSA sign failure\n");
1010 ERR_print_errors(bio_err
);
1018 static int EdDSA_verify_loop(void *args
)
1020 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1021 unsigned char *buf
= tempargs
->buf
;
1022 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx2
;
1023 unsigned char *eddsasig
= tempargs
->buf2
;
1024 size_t eddsasigsize
= tempargs
->sigsize
;
1027 for (count
= 0; COND(eddsa_c
[testnum
][1]); count
++) {
1028 ret
= EVP_DigestVerify(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1030 BIO_printf(bio_err
, "EdDSA verify failure\n");
1031 ERR_print_errors(bio_err
);
1039 #ifndef OPENSSL_NO_SM2
1040 static long sm2_c
[SM2_NUM
][2];
1041 static int SM2_sign_loop(void *args
)
1043 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1044 unsigned char *buf
= tempargs
->buf
;
1045 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_ctx
;
1046 unsigned char *sm2sig
= tempargs
->buf2
;
1049 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1050 const size_t max_size
= EVP_PKEY_get_size(sm2_pkey
[testnum
]);
1052 for (count
= 0; COND(sm2_c
[testnum
][0]); count
++) {
1053 sm2sigsize
= max_size
;
1055 if (!EVP_DigestSignInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1056 NULL
, sm2_pkey
[testnum
])) {
1057 BIO_printf(bio_err
, "SM2 init sign failure\n");
1058 ERR_print_errors(bio_err
);
1062 ret
= EVP_DigestSign(sm2ctx
[testnum
], sm2sig
, &sm2sigsize
,
1065 BIO_printf(bio_err
, "SM2 sign failure\n");
1066 ERR_print_errors(bio_err
);
1070 /* update the latest returned size and always use the fixed buffer size */
1071 tempargs
->sigsize
= sm2sigsize
;
1077 static int SM2_verify_loop(void *args
)
1079 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1080 unsigned char *buf
= tempargs
->buf
;
1081 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_vfy_ctx
;
1082 unsigned char *sm2sig
= tempargs
->buf2
;
1083 size_t sm2sigsize
= tempargs
->sigsize
;
1085 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1087 for (count
= 0; COND(sm2_c
[testnum
][1]); count
++) {
1088 if (!EVP_DigestVerifyInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1089 NULL
, sm2_pkey
[testnum
])) {
1090 BIO_printf(bio_err
, "SM2 verify init failure\n");
1091 ERR_print_errors(bio_err
);
1095 ret
= EVP_DigestVerify(sm2ctx
[testnum
], sm2sig
, sm2sigsize
,
1098 BIO_printf(bio_err
, "SM2 verify failure\n");
1099 ERR_print_errors(bio_err
);
1106 #endif /* OPENSSL_NO_SM2 */
1108 static int run_benchmark(int async_jobs
,
1109 int (*loop_function
) (void *), loopargs_t
* loopargs
)
1111 int job_op_count
= 0;
1112 int total_op_count
= 0;
1113 int num_inprogress
= 0;
1114 int error
= 0, i
= 0, ret
= 0;
1115 OSSL_ASYNC_FD job_fd
= 0;
1116 size_t num_job_fds
= 0;
1118 if (async_jobs
== 0) {
1119 return loop_function((void *)&loopargs
);
1122 for (i
= 0; i
< async_jobs
&& !error
; i
++) {
1123 loopargs_t
*looparg_item
= loopargs
+ i
;
1125 /* Copy pointer content (looparg_t item address) into async context */
1126 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
, loopargs
[i
].wait_ctx
,
1127 &job_op_count
, loop_function
,
1128 (void *)&looparg_item
, sizeof(looparg_item
));
1134 if (job_op_count
== -1) {
1137 total_op_count
+= job_op_count
;
1142 BIO_printf(bio_err
, "Failure in the job\n");
1143 ERR_print_errors(bio_err
);
1149 while (num_inprogress
> 0) {
1150 #if defined(OPENSSL_SYS_WINDOWS)
1152 #elif defined(OPENSSL_SYS_UNIX)
1153 int select_result
= 0;
1154 OSSL_ASYNC_FD max_fd
= 0;
1157 FD_ZERO(&waitfdset
);
1159 for (i
= 0; i
< async_jobs
&& num_inprogress
> 0; i
++) {
1160 if (loopargs
[i
].inprogress_job
== NULL
)
1163 if (!ASYNC_WAIT_CTX_get_all_fds
1164 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1165 || num_job_fds
> 1) {
1166 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1167 ERR_print_errors(bio_err
);
1171 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1173 FD_SET(job_fd
, &waitfdset
);
1174 if (job_fd
> max_fd
)
1178 if (max_fd
>= (OSSL_ASYNC_FD
)FD_SETSIZE
) {
1180 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1181 "Decrease the value of async_jobs\n",
1182 max_fd
, FD_SETSIZE
);
1183 ERR_print_errors(bio_err
);
1188 select_result
= select(max_fd
+ 1, &waitfdset
, NULL
, NULL
, NULL
);
1189 if (select_result
== -1 && errno
== EINTR
)
1192 if (select_result
== -1) {
1193 BIO_printf(bio_err
, "Failure in the select\n");
1194 ERR_print_errors(bio_err
);
1199 if (select_result
== 0)
1203 for (i
= 0; i
< async_jobs
; i
++) {
1204 if (loopargs
[i
].inprogress_job
== NULL
)
1207 if (!ASYNC_WAIT_CTX_get_all_fds
1208 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1209 || num_job_fds
> 1) {
1210 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1211 ERR_print_errors(bio_err
);
1215 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1218 #if defined(OPENSSL_SYS_UNIX)
1219 if (num_job_fds
== 1 && !FD_ISSET(job_fd
, &waitfdset
))
1221 #elif defined(OPENSSL_SYS_WINDOWS)
1222 if (num_job_fds
== 1
1223 && !PeekNamedPipe(job_fd
, NULL
, 0, NULL
, &avail
, NULL
)
1228 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
,
1229 loopargs
[i
].wait_ctx
, &job_op_count
,
1230 loop_function
, (void *)(loopargs
+ i
),
1231 sizeof(loopargs_t
));
1236 if (job_op_count
== -1) {
1239 total_op_count
+= job_op_count
;
1242 loopargs
[i
].inprogress_job
= NULL
;
1247 loopargs
[i
].inprogress_job
= NULL
;
1248 BIO_printf(bio_err
, "Failure in the job\n");
1249 ERR_print_errors(bio_err
);
1256 return error
? -1 : total_op_count
;
1259 typedef struct ec_curve_st
{
1263 size_t sigsize
; /* only used for EdDSA curves */
1266 static EVP_PKEY
*get_ecdsa(const EC_CURVE
*curve
)
1268 EVP_PKEY_CTX
*kctx
= NULL
;
1269 EVP_PKEY
*key
= NULL
;
1271 /* Ensure that the error queue is empty */
1272 if (ERR_peek_error()) {
1274 "WARNING: the error queue contains previous unhandled errors.\n");
1275 ERR_print_errors(bio_err
);
1279 * Let's try to create a ctx directly from the NID: this works for
1280 * curves like Curve25519 that are not implemented through the low
1281 * level EC interface.
1282 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1283 * then we set the curve by NID before deriving the actual keygen
1284 * ctx for that specific curve.
1286 kctx
= EVP_PKEY_CTX_new_id(curve
->nid
, NULL
);
1288 EVP_PKEY_CTX
*pctx
= NULL
;
1289 EVP_PKEY
*params
= NULL
;
1291 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1292 * "int_ctx_new:unsupported algorithm" error was added to the
1294 * We remove it from the error queue as we are handling it.
1296 unsigned long error
= ERR_peek_error();
1298 if (error
== ERR_peek_last_error() /* oldest and latest errors match */
1299 /* check that the error origin matches */
1300 && ERR_GET_LIB(error
) == ERR_LIB_EVP
1301 && (ERR_GET_REASON(error
) == EVP_R_UNSUPPORTED_ALGORITHM
1302 || ERR_GET_REASON(error
) == ERR_R_UNSUPPORTED
))
1303 ERR_get_error(); /* pop error from queue */
1304 if (ERR_peek_error()) {
1306 "Unhandled error in the error queue during EC key setup.\n");
1307 ERR_print_errors(bio_err
);
1311 /* Create the context for parameter generation */
1312 if ((pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
)) == NULL
1313 || EVP_PKEY_paramgen_init(pctx
) <= 0
1314 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
1316 || EVP_PKEY_paramgen(pctx
, ¶ms
) <= 0) {
1317 BIO_printf(bio_err
, "EC params init failure.\n");
1318 ERR_print_errors(bio_err
);
1319 EVP_PKEY_CTX_free(pctx
);
1322 EVP_PKEY_CTX_free(pctx
);
1324 /* Create the context for the key generation */
1325 kctx
= EVP_PKEY_CTX_new(params
, NULL
);
1326 EVP_PKEY_free(params
);
1329 || EVP_PKEY_keygen_init(kctx
) <= 0
1330 || EVP_PKEY_keygen(kctx
, &key
) <= 0) {
1331 BIO_printf(bio_err
, "EC key generation failure.\n");
1332 ERR_print_errors(bio_err
);
1335 EVP_PKEY_CTX_free(kctx
);
1339 #define stop_it(do_it, test_num)\
1340 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1342 int speed_main(int argc
, char **argv
)
1345 loopargs_t
*loopargs
= NULL
;
1347 const char *engine_id
= NULL
;
1348 EVP_CIPHER
*evp_cipher
= NULL
;
1349 EVP_MAC
*mac
= NULL
;
1352 int async_init
= 0, multiblock
= 0, pr_header
= 0;
1353 uint8_t doit
[ALGOR_NUM
] = { 0 };
1354 int ret
= 1, misalign
= 0, lengths_single
= 0, aead
= 0;
1356 unsigned int size_num
= SIZE_NUM
;
1357 unsigned int i
, k
, loopargs_len
= 0, async_jobs
= 0;
1361 EVP_PKEY_CTX
*genctx
= NULL
;
1366 openssl_speed_sec_t seconds
= { SECONDS
, RSA_SECONDS
, DSA_SECONDS
,
1367 ECDSA_SECONDS
, ECDH_SECONDS
,
1368 EdDSA_SECONDS
, SM2_SECONDS
,
1371 static const unsigned char key32
[32] = {
1372 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1373 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1374 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1375 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1377 static const unsigned char deskey
[] = {
1378 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1379 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1380 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1382 static const struct {
1383 const unsigned char *data
;
1384 unsigned int length
;
1387 { test512
, sizeof(test512
), 512 },
1388 { test1024
, sizeof(test1024
), 1024 },
1389 { test2048
, sizeof(test2048
), 2048 },
1390 { test3072
, sizeof(test3072
), 3072 },
1391 { test4096
, sizeof(test4096
), 4096 },
1392 { test7680
, sizeof(test7680
), 7680 },
1393 { test15360
, sizeof(test15360
), 15360 }
1395 uint8_t rsa_doit
[RSA_NUM
] = { 0 };
1396 int primes
= RSA_DEFAULT_PRIME_NUM
;
1397 #ifndef OPENSSL_NO_DH
1398 typedef struct ffdh_params_st
{
1404 static const FFDH_PARAMS ffdh_params
[FFDH_NUM
] = {
1405 {"ffdh2048", NID_ffdhe2048
, 2048},
1406 {"ffdh3072", NID_ffdhe3072
, 3072},
1407 {"ffdh4096", NID_ffdhe4096
, 4096},
1408 {"ffdh6144", NID_ffdhe6144
, 6144},
1409 {"ffdh8192", NID_ffdhe8192
, 8192}
1411 uint8_t ffdh_doit
[FFDH_NUM
] = { 0 };
1413 #endif /* OPENSSL_NO_DH */
1414 static const unsigned int dsa_bits
[DSA_NUM
] = { 512, 1024, 2048 };
1415 uint8_t dsa_doit
[DSA_NUM
] = { 0 };
1417 * We only test over the following curves as they are representative, To
1418 * add tests over more curves, simply add the curve NID and curve name to
1419 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1420 * lists accordingly.
1422 static const EC_CURVE ec_curves
[EC_NUM
] = {
1424 {"secp160r1", NID_secp160r1
, 160},
1425 {"nistp192", NID_X9_62_prime192v1
, 192},
1426 {"nistp224", NID_secp224r1
, 224},
1427 {"nistp256", NID_X9_62_prime256v1
, 256},
1428 {"nistp384", NID_secp384r1
, 384},
1429 {"nistp521", NID_secp521r1
, 521},
1430 #ifndef OPENSSL_NO_EC2M
1432 {"nistk163", NID_sect163k1
, 163},
1433 {"nistk233", NID_sect233k1
, 233},
1434 {"nistk283", NID_sect283k1
, 283},
1435 {"nistk409", NID_sect409k1
, 409},
1436 {"nistk571", NID_sect571k1
, 571},
1437 {"nistb163", NID_sect163r2
, 163},
1438 {"nistb233", NID_sect233r1
, 233},
1439 {"nistb283", NID_sect283r1
, 283},
1440 {"nistb409", NID_sect409r1
, 409},
1441 {"nistb571", NID_sect571r1
, 571},
1443 {"brainpoolP256r1", NID_brainpoolP256r1
, 256},
1444 {"brainpoolP256t1", NID_brainpoolP256t1
, 256},
1445 {"brainpoolP384r1", NID_brainpoolP384r1
, 384},
1446 {"brainpoolP384t1", NID_brainpoolP384t1
, 384},
1447 {"brainpoolP512r1", NID_brainpoolP512r1
, 512},
1448 {"brainpoolP512t1", NID_brainpoolP512t1
, 512},
1449 /* Other and ECDH only ones */
1450 {"X25519", NID_X25519
, 253},
1451 {"X448", NID_X448
, 448}
1453 static const EC_CURVE ed_curves
[EdDSA_NUM
] = {
1455 {"Ed25519", NID_ED25519
, 253, 64},
1456 {"Ed448", NID_ED448
, 456, 114}
1458 #ifndef OPENSSL_NO_SM2
1459 static const EC_CURVE sm2_curves
[SM2_NUM
] = {
1461 {"CurveSM2", NID_sm2
, 256}
1463 uint8_t sm2_doit
[SM2_NUM
] = { 0 };
1465 uint8_t ecdsa_doit
[ECDSA_NUM
] = { 0 };
1466 uint8_t ecdh_doit
[EC_NUM
] = { 0 };
1467 uint8_t eddsa_doit
[EdDSA_NUM
] = { 0 };
1469 /* checks declarated curves against choices list. */
1470 OPENSSL_assert(ed_curves
[EdDSA_NUM
- 1].nid
== NID_ED448
);
1471 OPENSSL_assert(strcmp(eddsa_choices
[EdDSA_NUM
- 1].name
, "ed448") == 0);
1473 OPENSSL_assert(ec_curves
[EC_NUM
- 1].nid
== NID_X448
);
1474 OPENSSL_assert(strcmp(ecdh_choices
[EC_NUM
- 1].name
, "ecdhx448") == 0);
1476 OPENSSL_assert(ec_curves
[ECDSA_NUM
- 1].nid
== NID_brainpoolP512t1
);
1477 OPENSSL_assert(strcmp(ecdsa_choices
[ECDSA_NUM
- 1].name
, "ecdsabrp512t1") == 0);
1479 #ifndef OPENSSL_NO_SM2
1480 OPENSSL_assert(sm2_curves
[SM2_NUM
- 1].nid
== NID_sm2
);
1481 OPENSSL_assert(strcmp(sm2_choices
[SM2_NUM
- 1].name
, "curveSM2") == 0);
1484 prog
= opt_init(argc
, argv
, speed_options
);
1485 while ((o
= opt_next()) != OPT_EOF
) {
1490 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
1493 opt_help(speed_options
);
1501 BIO_printf(bio_err
, "%s: -evp option cannot be used more than once\n", prog
);
1505 if (!opt_cipher_silent(opt_arg(), &evp_cipher
)) {
1506 if (have_md(opt_arg()))
1507 evp_md_name
= opt_arg();
1509 if (evp_cipher
== NULL
&& evp_md_name
== NULL
) {
1510 ERR_clear_last_mark();
1512 "%s: %s is an unknown cipher or digest\n",
1520 if (!have_md(opt_arg())) {
1521 BIO_printf(bio_err
, "%s: %s is an unknown digest\n",
1525 evp_mac_mdname
= opt_arg();
1529 if (!have_cipher(opt_arg())) {
1530 BIO_printf(bio_err
, "%s: %s is an unknown cipher\n",
1534 evp_mac_ciphername
= opt_arg();
1535 doit
[D_EVP_CMAC
] = 1;
1542 * In a forked execution, an engine might need to be
1543 * initialised by each child process, not by the parent.
1544 * So store the name here and run setup_engine() later on.
1546 engine_id
= opt_arg();
1550 multi
= opt_int_arg();
1551 if ((size_t)multi
>= SIZE_MAX
/ sizeof(int)) {
1552 BIO_printf(bio_err
, "%s: multi argument too large\n", prog
);
1558 #ifndef OPENSSL_NO_ASYNC
1559 async_jobs
= opt_int_arg();
1560 if (!ASYNC_is_capable()) {
1562 "%s: async_jobs specified but async not supported\n",
1566 if (async_jobs
> 99999) {
1567 BIO_printf(bio_err
, "%s: too many async_jobs\n", prog
);
1573 misalign
= opt_int_arg();
1574 if (misalign
> MISALIGN
) {
1576 "%s: Maximum offset is %d\n", prog
, MISALIGN
);
1585 #ifdef OPENSSL_NO_MULTIBLOCK
1587 "%s: -mb specified but multi-block support is disabled\n",
1596 case OPT_PROV_CASES
:
1597 if (!opt_provider(o
))
1601 primes
= opt_int_arg();
1604 seconds
.sym
= seconds
.rsa
= seconds
.dsa
= seconds
.ecdsa
1605 = seconds
.ecdh
= seconds
.eddsa
1606 = seconds
.sm2
= seconds
.ffdh
= opt_int_arg();
1609 lengths_single
= opt_int_arg();
1610 lengths
= &lengths_single
;
1619 /* Remaining arguments are algorithms. */
1620 argc
= opt_num_rest();
1623 if (!app_RAND_load())
1626 for (; *argv
; argv
++) {
1627 const char *algo
= *argv
;
1629 if (opt_found(algo
, doit_choices
, &i
)) {
1633 if (strcmp(algo
, "des") == 0) {
1634 doit
[D_CBC_DES
] = doit
[D_EDE3_DES
] = 1;
1637 if (strcmp(algo
, "sha") == 0) {
1638 doit
[D_SHA1
] = doit
[D_SHA256
] = doit
[D_SHA512
] = 1;
1641 #ifndef OPENSSL_NO_DEPRECATED_3_0
1642 if (strcmp(algo
, "openssl") == 0) /* just for compatibility */
1645 if (HAS_PREFIX(algo
, "rsa")) {
1646 if (algo
[sizeof("rsa") - 1] == '\0') {
1647 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1650 if (opt_found(algo
, rsa_choices
, &i
)) {
1655 #ifndef OPENSSL_NO_DH
1656 if (HAS_PREFIX(algo
, "ffdh")) {
1657 if (algo
[sizeof("ffdh") - 1] == '\0') {
1658 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1661 if (opt_found(algo
, ffdh_choices
, &i
)) {
1667 if (HAS_PREFIX(algo
, "dsa")) {
1668 if (algo
[sizeof("dsa") - 1] == '\0') {
1669 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1672 if (opt_found(algo
, dsa_choices
, &i
)) {
1677 if (strcmp(algo
, "aes") == 0) {
1678 doit
[D_CBC_128_AES
] = doit
[D_CBC_192_AES
] = doit
[D_CBC_256_AES
] = 1;
1681 if (strcmp(algo
, "camellia") == 0) {
1682 doit
[D_CBC_128_CML
] = doit
[D_CBC_192_CML
] = doit
[D_CBC_256_CML
] = 1;
1685 if (HAS_PREFIX(algo
, "ecdsa")) {
1686 if (algo
[sizeof("ecdsa") - 1] == '\0') {
1687 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1690 if (opt_found(algo
, ecdsa_choices
, &i
)) {
1695 if (HAS_PREFIX(algo
, "ecdh")) {
1696 if (algo
[sizeof("ecdh") - 1] == '\0') {
1697 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1700 if (opt_found(algo
, ecdh_choices
, &i
)) {
1705 if (strcmp(algo
, "eddsa") == 0) {
1706 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1709 if (opt_found(algo
, eddsa_choices
, &i
)) {
1713 #ifndef OPENSSL_NO_SM2
1714 if (strcmp(algo
, "sm2") == 0) {
1715 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1718 if (opt_found(algo
, sm2_choices
, &i
)) {
1723 BIO_printf(bio_err
, "%s: Unknown algorithm %s\n", prog
, algo
);
1729 if (evp_cipher
== NULL
) {
1730 BIO_printf(bio_err
, "-aead can be used only with an AEAD cipher\n");
1732 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1733 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
1734 BIO_printf(bio_err
, "%s is not an AEAD cipher\n",
1735 EVP_CIPHER_get0_name(evp_cipher
));
1740 if (evp_cipher
== NULL
) {
1741 BIO_printf(bio_err
, "-mb can be used only with a multi-block"
1742 " capable cipher\n");
1744 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1745 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
1746 BIO_printf(bio_err
, "%s is not a multi-block capable\n",
1747 EVP_CIPHER_get0_name(evp_cipher
));
1749 } else if (async_jobs
> 0) {
1750 BIO_printf(bio_err
, "Async mode is not supported with -mb");
1755 /* Initialize the job pool if async mode is enabled */
1756 if (async_jobs
> 0) {
1757 async_init
= ASYNC_init_thread(async_jobs
, async_jobs
);
1759 BIO_printf(bio_err
, "Error creating the ASYNC job pool\n");
1764 loopargs_len
= (async_jobs
== 0 ? 1 : async_jobs
);
1766 app_malloc(loopargs_len
* sizeof(loopargs_t
), "array of loopargs");
1767 memset(loopargs
, 0, loopargs_len
* sizeof(loopargs_t
));
1769 for (i
= 0; i
< loopargs_len
; i
++) {
1770 if (async_jobs
> 0) {
1771 loopargs
[i
].wait_ctx
= ASYNC_WAIT_CTX_new();
1772 if (loopargs
[i
].wait_ctx
== NULL
) {
1773 BIO_printf(bio_err
, "Error creating the ASYNC_WAIT_CTX\n");
1778 buflen
= lengths
[size_num
- 1];
1779 if (buflen
< 36) /* size of random vector in RSA benchmark */
1781 buflen
+= MAX_MISALIGNMENT
+ 1;
1782 loopargs
[i
].buf_malloc
= app_malloc(buflen
, "input buffer");
1783 loopargs
[i
].buf2_malloc
= app_malloc(buflen
, "input buffer");
1784 memset(loopargs
[i
].buf_malloc
, 0, buflen
);
1785 memset(loopargs
[i
].buf2_malloc
, 0, buflen
);
1787 /* Align the start of buffers on a 64 byte boundary */
1788 loopargs
[i
].buf
= loopargs
[i
].buf_malloc
+ misalign
;
1789 loopargs
[i
].buf2
= loopargs
[i
].buf2_malloc
+ misalign
;
1790 loopargs
[i
].buflen
= buflen
- misalign
;
1791 loopargs
[i
].sigsize
= buflen
- misalign
;
1792 loopargs
[i
].secret_a
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret a");
1793 loopargs
[i
].secret_b
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret b");
1794 #ifndef OPENSSL_NO_DH
1795 loopargs
[i
].secret_ff_a
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret a");
1796 loopargs
[i
].secret_ff_b
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret b");
1801 if (multi
&& do_multi(multi
, size_num
))
1805 /* Initialize the engine after the fork */
1806 e
= setup_engine(engine_id
, 0);
1808 /* No parameters; turn on everything. */
1809 if (argc
== 0 && !doit
[D_EVP
] && !doit
[D_HMAC
] && !doit
[D_EVP_CMAC
]) {
1810 memset(doit
, 1, sizeof(doit
));
1811 doit
[D_EVP
] = doit
[D_EVP_CMAC
] = 0;
1813 for (i
= D_MD2
; i
<= D_WHIRLPOOL
; i
++) {
1814 if (!have_md(names
[i
]))
1817 for (i
= D_CBC_DES
; i
<= D_CBC_256_CML
; i
++) {
1818 if (!have_cipher(names
[i
]))
1821 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1822 app_get0_propq())) != NULL
) {
1828 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1829 app_get0_propq())) != NULL
) {
1836 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1837 #ifndef OPENSSL_NO_DH
1838 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1840 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1841 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1842 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1843 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1844 #ifndef OPENSSL_NO_SM2
1845 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1848 for (i
= 0; i
< ALGOR_NUM
; i
++)
1852 if (usertime
== 0 && !mr
)
1854 "You have chosen to measure elapsed time "
1855 "instead of user CPU time.\n");
1858 signal(SIGALRM
, alarmed
);
1862 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1863 print_message(names
[D_MD2
], c
[D_MD2
][testnum
], lengths
[testnum
],
1866 count
= run_benchmark(async_jobs
, EVP_Digest_MD2_loop
, loopargs
);
1868 print_result(D_MD2
, testnum
, count
, d
);
1875 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1876 print_message(names
[D_MDC2
], c
[D_MDC2
][testnum
], lengths
[testnum
],
1879 count
= run_benchmark(async_jobs
, EVP_Digest_MDC2_loop
, loopargs
);
1881 print_result(D_MDC2
, testnum
, count
, d
);
1888 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1889 print_message(names
[D_MD4
], c
[D_MD4
][testnum
], lengths
[testnum
],
1892 count
= run_benchmark(async_jobs
, EVP_Digest_MD4_loop
, loopargs
);
1894 print_result(D_MD4
, testnum
, count
, d
);
1901 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1902 print_message(names
[D_MD5
], c
[D_MD5
][testnum
], lengths
[testnum
],
1905 count
= run_benchmark(async_jobs
, MD5_loop
, loopargs
);
1907 print_result(D_MD5
, testnum
, count
, d
);
1914 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1915 print_message(names
[D_SHA1
], c
[D_SHA1
][testnum
], lengths
[testnum
],
1918 count
= run_benchmark(async_jobs
, SHA1_loop
, loopargs
);
1920 print_result(D_SHA1
, testnum
, count
, d
);
1926 if (doit
[D_SHA256
]) {
1927 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1928 print_message(names
[D_SHA256
], c
[D_SHA256
][testnum
],
1929 lengths
[testnum
], seconds
.sym
);
1931 count
= run_benchmark(async_jobs
, SHA256_loop
, loopargs
);
1933 print_result(D_SHA256
, testnum
, count
, d
);
1939 if (doit
[D_SHA512
]) {
1940 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1941 print_message(names
[D_SHA512
], c
[D_SHA512
][testnum
],
1942 lengths
[testnum
], seconds
.sym
);
1944 count
= run_benchmark(async_jobs
, SHA512_loop
, loopargs
);
1946 print_result(D_SHA512
, testnum
, count
, d
);
1952 if (doit
[D_WHIRLPOOL
]) {
1953 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1954 print_message(names
[D_WHIRLPOOL
], c
[D_WHIRLPOOL
][testnum
],
1955 lengths
[testnum
], seconds
.sym
);
1957 count
= run_benchmark(async_jobs
, WHIRLPOOL_loop
, loopargs
);
1959 print_result(D_WHIRLPOOL
, testnum
, count
, d
);
1965 if (doit
[D_RMD160
]) {
1966 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1967 print_message(names
[D_RMD160
], c
[D_RMD160
][testnum
],
1968 lengths
[testnum
], seconds
.sym
);
1970 count
= run_benchmark(async_jobs
, EVP_Digest_RMD160_loop
, loopargs
);
1972 print_result(D_RMD160
, testnum
, count
, d
);
1979 static const char hmac_key
[] = "This is a key...";
1980 int len
= strlen(hmac_key
);
1981 OSSL_PARAM params
[3];
1983 mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1984 if (mac
== NULL
|| evp_mac_mdname
== NULL
)
1987 evp_hmac_name
= app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname
),
1989 sprintf(evp_hmac_name
, "hmac(%s)", evp_mac_mdname
);
1990 names
[D_HMAC
] = evp_hmac_name
;
1993 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
1996 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
1997 (char *)hmac_key
, len
);
1998 params
[2] = OSSL_PARAM_construct_end();
2000 for (i
= 0; i
< loopargs_len
; i
++) {
2001 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2002 if (loopargs
[i
].mctx
== NULL
)
2005 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2008 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2009 print_message(names
[D_HMAC
], c
[D_HMAC
][testnum
], lengths
[testnum
],
2012 count
= run_benchmark(async_jobs
, HMAC_loop
, loopargs
);
2014 print_result(D_HMAC
, testnum
, count
, d
);
2018 for (i
= 0; i
< loopargs_len
; i
++)
2019 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2024 if (doit
[D_CBC_DES
]) {
2027 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2028 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-cbc", deskey
,
2029 sizeof(deskey
) / 3);
2030 st
= loopargs
[i
].ctx
!= NULL
;
2032 algindex
= D_CBC_DES
;
2033 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2034 print_message(names
[D_CBC_DES
], c
[D_CBC_DES
][testnum
],
2035 lengths
[testnum
], seconds
.sym
);
2037 count
= run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2039 print_result(D_CBC_DES
, testnum
, count
, d
);
2041 for (i
= 0; i
< loopargs_len
; i
++)
2042 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2045 if (doit
[D_EDE3_DES
]) {
2048 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2049 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-ede3-cbc", deskey
,
2051 st
= loopargs
[i
].ctx
!= NULL
;
2053 algindex
= D_EDE3_DES
;
2054 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2055 print_message(names
[D_EDE3_DES
], c
[D_EDE3_DES
][testnum
],
2056 lengths
[testnum
], seconds
.sym
);
2059 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2061 print_result(D_EDE3_DES
, testnum
, count
, d
);
2063 for (i
= 0; i
< loopargs_len
; i
++)
2064 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2067 for (k
= 0; k
< 3; k
++) {
2068 algindex
= D_CBC_128_AES
+ k
;
2069 if (doit
[algindex
]) {
2072 keylen
= 16 + k
* 8;
2073 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2074 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2076 st
= loopargs
[i
].ctx
!= NULL
;
2079 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2080 print_message(names
[algindex
], c
[algindex
][testnum
],
2081 lengths
[testnum
], seconds
.sym
);
2084 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2086 print_result(algindex
, testnum
, count
, d
);
2088 for (i
= 0; i
< loopargs_len
; i
++)
2089 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2093 for (k
= 0; k
< 3; k
++) {
2094 algindex
= D_CBC_128_CML
+ k
;
2095 if (doit
[algindex
]) {
2098 keylen
= 16 + k
* 8;
2099 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2100 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2102 st
= loopargs
[i
].ctx
!= NULL
;
2105 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2106 print_message(names
[algindex
], c
[algindex
][testnum
],
2107 lengths
[testnum
], seconds
.sym
);
2110 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2112 print_result(algindex
, testnum
, count
, d
);
2114 for (i
= 0; i
< loopargs_len
; i
++)
2115 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2119 for (algindex
= D_RC4
; algindex
<= D_CBC_CAST
; algindex
++) {
2120 if (doit
[algindex
]) {
2124 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2125 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2127 st
= loopargs
[i
].ctx
!= NULL
;
2130 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2131 print_message(names
[algindex
], c
[algindex
][testnum
],
2132 lengths
[testnum
], seconds
.sym
);
2135 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2137 print_result(algindex
, testnum
, count
, d
);
2139 for (i
= 0; i
< loopargs_len
; i
++)
2140 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2143 if (doit
[D_GHASH
]) {
2144 static const char gmac_iv
[] = "0123456789ab";
2145 OSSL_PARAM params
[3];
2147 mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2151 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2153 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV
,
2155 sizeof(gmac_iv
) - 1);
2156 params
[2] = OSSL_PARAM_construct_end();
2158 for (i
= 0; i
< loopargs_len
; i
++) {
2159 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2160 if (loopargs
[i
].mctx
== NULL
)
2163 if (!EVP_MAC_init(loopargs
[i
].mctx
, key32
, 16, params
))
2166 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2167 print_message(names
[D_GHASH
], c
[D_GHASH
][testnum
], lengths
[testnum
],
2170 count
= run_benchmark(async_jobs
, GHASH_loop
, loopargs
);
2172 print_result(D_GHASH
, testnum
, count
, d
);
2176 for (i
= 0; i
< loopargs_len
; i
++)
2177 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2183 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2184 print_message(names
[D_RAND
], c
[D_RAND
][testnum
], lengths
[testnum
],
2187 count
= run_benchmark(async_jobs
, RAND_bytes_loop
, loopargs
);
2189 print_result(D_RAND
, testnum
, count
, d
);
2194 if (evp_cipher
!= NULL
) {
2195 int (*loopfunc
) (void *) = EVP_Update_loop
;
2197 if (multiblock
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2198 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2199 multiblock_speed(evp_cipher
, lengths_single
, &seconds
);
2204 names
[D_EVP
] = EVP_CIPHER_get0_name(evp_cipher
);
2206 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_CCM_MODE
) {
2207 loopfunc
= EVP_Update_loop_ccm
;
2208 } else if (aead
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2209 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2210 loopfunc
= EVP_Update_loop_aead
;
2211 if (lengths
== lengths_list
) {
2212 lengths
= aead_lengths_list
;
2213 size_num
= OSSL_NELEM(aead_lengths_list
);
2217 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2218 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2221 for (k
= 0; k
< loopargs_len
; k
++) {
2222 loopargs
[k
].ctx
= EVP_CIPHER_CTX_new();
2223 if (loopargs
[k
].ctx
== NULL
) {
2224 BIO_printf(bio_err
, "\nEVP_CIPHER_CTX_new failure\n");
2227 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, evp_cipher
, NULL
,
2228 NULL
, iv
, decrypt
? 0 : 1)) {
2229 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2230 ERR_print_errors(bio_err
);
2234 EVP_CIPHER_CTX_set_padding(loopargs
[k
].ctx
, 0);
2236 keylen
= EVP_CIPHER_CTX_get_key_length(loopargs
[k
].ctx
);
2237 loopargs
[k
].key
= app_malloc(keylen
, "evp_cipher key");
2238 EVP_CIPHER_CTX_rand_key(loopargs
[k
].ctx
, loopargs
[k
].key
);
2239 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, NULL
, NULL
,
2240 loopargs
[k
].key
, NULL
, -1)) {
2241 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2242 ERR_print_errors(bio_err
);
2245 OPENSSL_clear_free(loopargs
[k
].key
, keylen
);
2247 /* SIV mode only allows for a single Update operation */
2248 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_SIV_MODE
)
2249 (void)EVP_CIPHER_CTX_ctrl(loopargs
[k
].ctx
,
2250 EVP_CTRL_SET_SPEED
, 1, NULL
);
2254 count
= run_benchmark(async_jobs
, loopfunc
, loopargs
);
2256 for (k
= 0; k
< loopargs_len
; k
++)
2257 EVP_CIPHER_CTX_free(loopargs
[k
].ctx
);
2258 print_result(D_EVP
, testnum
, count
, d
);
2260 } else if (evp_md_name
!= NULL
) {
2261 names
[D_EVP
] = evp_md_name
;
2263 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2264 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2267 count
= run_benchmark(async_jobs
, EVP_Digest_md_loop
, loopargs
);
2269 print_result(D_EVP
, testnum
, count
, d
);
2276 if (doit
[D_EVP_CMAC
]) {
2277 OSSL_PARAM params
[3];
2278 EVP_CIPHER
*cipher
= NULL
;
2280 mac
= EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2281 if (mac
== NULL
|| evp_mac_ciphername
== NULL
)
2283 if (!opt_cipher(evp_mac_ciphername
, &cipher
))
2286 keylen
= EVP_CIPHER_get_key_length(cipher
);
2287 EVP_CIPHER_free(cipher
);
2288 if (keylen
<= 0 || keylen
> (int)sizeof(key32
)) {
2289 BIO_printf(bio_err
, "\nRequested CMAC cipher with unsupported key length.\n");
2292 evp_cmac_name
= app_malloc(sizeof("cmac()")
2293 + strlen(evp_mac_ciphername
), "CMAC name");
2294 sprintf(evp_cmac_name
, "cmac(%s)", evp_mac_ciphername
);
2295 names
[D_EVP_CMAC
] = evp_cmac_name
;
2297 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2298 evp_mac_ciphername
, 0);
2299 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2300 (char *)key32
, keylen
);
2301 params
[2] = OSSL_PARAM_construct_end();
2303 for (i
= 0; i
< loopargs_len
; i
++) {
2304 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2305 if (loopargs
[i
].mctx
== NULL
)
2308 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2312 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2313 print_message(names
[D_EVP_CMAC
], c
[D_EVP_CMAC
][testnum
],
2314 lengths
[testnum
], seconds
.sym
);
2316 count
= run_benchmark(async_jobs
, CMAC_loop
, loopargs
);
2318 print_result(D_EVP_CMAC
, testnum
, count
, d
);
2322 for (i
= 0; i
< loopargs_len
; i
++)
2323 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2328 for (i
= 0; i
< loopargs_len
; i
++)
2329 if (RAND_bytes(loopargs
[i
].buf
, 36) <= 0)
2332 for (testnum
= 0; testnum
< RSA_NUM
; testnum
++) {
2333 EVP_PKEY
*rsa_key
= NULL
;
2336 if (!rsa_doit
[testnum
])
2339 if (primes
> RSA_DEFAULT_PRIME_NUM
) {
2340 /* we haven't set keys yet, generate multi-prime RSA keys */
2343 && BN_set_word(bn
, RSA_F4
)
2344 && init_gen_str(&genctx
, "RSA", NULL
, 0, NULL
, NULL
)
2345 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx
, rsa_keys
[testnum
].bits
) > 0
2346 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx
, bn
) > 0
2347 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx
, primes
) > 0
2348 && EVP_PKEY_keygen(genctx
, &rsa_key
);
2351 EVP_PKEY_CTX_free(genctx
);
2354 const unsigned char *p
= rsa_keys
[testnum
].data
;
2356 st
= (rsa_key
= d2i_PrivateKey(EVP_PKEY_RSA
, NULL
, &p
,
2357 rsa_keys
[testnum
].length
)) != NULL
;
2360 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2361 loopargs
[i
].rsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2362 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2363 if (loopargs
[i
].rsa_sign_ctx
[testnum
] == NULL
2364 || EVP_PKEY_sign_init(loopargs
[i
].rsa_sign_ctx
[testnum
]) <= 0
2365 || EVP_PKEY_sign(loopargs
[i
].rsa_sign_ctx
[testnum
],
2367 &loopargs
[i
].sigsize
,
2368 loopargs
[i
].buf
, 36) <= 0)
2373 "RSA sign setup failure. No RSA sign will be done.\n");
2374 ERR_print_errors(bio_err
);
2377 pkey_print_message("private", "rsa",
2378 rsa_c
[testnum
][0], rsa_keys
[testnum
].bits
,
2380 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2382 count
= run_benchmark(async_jobs
, RSA_sign_loop
, loopargs
);
2385 mr
? "+R1:%ld:%d:%.2f\n"
2386 : "%ld %u bits private RSA's in %.2fs\n",
2387 count
, rsa_keys
[testnum
].bits
, d
);
2388 rsa_results
[testnum
][0] = (double)count
/ d
;
2392 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2393 loopargs
[i
].rsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
,
2395 if (loopargs
[i
].rsa_verify_ctx
[testnum
] == NULL
2396 || EVP_PKEY_verify_init(loopargs
[i
].rsa_verify_ctx
[testnum
]) <= 0
2397 || EVP_PKEY_verify(loopargs
[i
].rsa_verify_ctx
[testnum
],
2399 loopargs
[i
].sigsize
,
2400 loopargs
[i
].buf
, 36) <= 0)
2405 "RSA verify setup failure. No RSA verify will be done.\n");
2406 ERR_print_errors(bio_err
);
2407 rsa_doit
[testnum
] = 0;
2409 pkey_print_message("public", "rsa",
2410 rsa_c
[testnum
][1], rsa_keys
[testnum
].bits
,
2413 count
= run_benchmark(async_jobs
, RSA_verify_loop
, loopargs
);
2416 mr
? "+R2:%ld:%d:%.2f\n"
2417 : "%ld %u bits public RSA's in %.2fs\n",
2418 count
, rsa_keys
[testnum
].bits
, d
);
2419 rsa_results
[testnum
][1] = (double)count
/ d
;
2422 if (op_count
<= 1) {
2423 /* if longer than 10s, don't do any more */
2424 stop_it(rsa_doit
, testnum
);
2426 EVP_PKEY_free(rsa_key
);
2429 for (testnum
= 0; testnum
< DSA_NUM
; testnum
++) {
2430 EVP_PKEY
*dsa_key
= NULL
;
2433 if (!dsa_doit
[testnum
])
2436 st
= (dsa_key
= get_dsa(dsa_bits
[testnum
])) != NULL
;
2438 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2439 loopargs
[i
].dsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2441 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2442 if (loopargs
[i
].dsa_sign_ctx
[testnum
] == NULL
2443 || EVP_PKEY_sign_init(loopargs
[i
].dsa_sign_ctx
[testnum
]) <= 0
2445 || EVP_PKEY_sign(loopargs
[i
].dsa_sign_ctx
[testnum
],
2447 &loopargs
[i
].sigsize
,
2448 loopargs
[i
].buf
, 20) <= 0)
2453 "DSA sign setup failure. No DSA sign will be done.\n");
2454 ERR_print_errors(bio_err
);
2457 pkey_print_message("sign", "dsa",
2458 dsa_c
[testnum
][0], dsa_bits
[testnum
],
2461 count
= run_benchmark(async_jobs
, DSA_sign_loop
, loopargs
);
2464 mr
? "+R3:%ld:%u:%.2f\n"
2465 : "%ld %u bits DSA signs in %.2fs\n",
2466 count
, dsa_bits
[testnum
], d
);
2467 dsa_results
[testnum
][0] = (double)count
/ d
;
2471 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2472 loopargs
[i
].dsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2474 if (loopargs
[i
].dsa_verify_ctx
[testnum
] == NULL
2475 || EVP_PKEY_verify_init(loopargs
[i
].dsa_verify_ctx
[testnum
]) <= 0
2476 || EVP_PKEY_verify(loopargs
[i
].dsa_verify_ctx
[testnum
],
2478 loopargs
[i
].sigsize
,
2479 loopargs
[i
].buf
, 36) <= 0)
2484 "DSA verify setup failure. No DSA verify will be done.\n");
2485 ERR_print_errors(bio_err
);
2486 dsa_doit
[testnum
] = 0;
2488 pkey_print_message("verify", "dsa",
2489 dsa_c
[testnum
][1], dsa_bits
[testnum
],
2492 count
= run_benchmark(async_jobs
, DSA_verify_loop
, loopargs
);
2495 mr
? "+R4:%ld:%u:%.2f\n"
2496 : "%ld %u bits DSA verify in %.2fs\n",
2497 count
, dsa_bits
[testnum
], d
);
2498 dsa_results
[testnum
][1] = (double)count
/ d
;
2501 if (op_count
<= 1) {
2502 /* if longer than 10s, don't do any more */
2503 stop_it(dsa_doit
, testnum
);
2505 EVP_PKEY_free(dsa_key
);
2508 for (testnum
= 0; testnum
< ECDSA_NUM
; testnum
++) {
2509 EVP_PKEY
*ecdsa_key
= NULL
;
2512 if (!ecdsa_doit
[testnum
])
2515 st
= (ecdsa_key
= get_ecdsa(&ec_curves
[testnum
])) != NULL
;
2517 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2518 loopargs
[i
].ecdsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2520 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2521 if (loopargs
[i
].ecdsa_sign_ctx
[testnum
] == NULL
2522 || EVP_PKEY_sign_init(loopargs
[i
].ecdsa_sign_ctx
[testnum
]) <= 0
2524 || EVP_PKEY_sign(loopargs
[i
].ecdsa_sign_ctx
[testnum
],
2526 &loopargs
[i
].sigsize
,
2527 loopargs
[i
].buf
, 20) <= 0)
2532 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2533 ERR_print_errors(bio_err
);
2536 pkey_print_message("sign", "ecdsa",
2537 ecdsa_c
[testnum
][0], ec_curves
[testnum
].bits
,
2540 count
= run_benchmark(async_jobs
, ECDSA_sign_loop
, loopargs
);
2543 mr
? "+R5:%ld:%u:%.2f\n"
2544 : "%ld %u bits ECDSA signs in %.2fs\n",
2545 count
, ec_curves
[testnum
].bits
, d
);
2546 ecdsa_results
[testnum
][0] = (double)count
/ d
;
2550 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2551 loopargs
[i
].ecdsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2553 if (loopargs
[i
].ecdsa_verify_ctx
[testnum
] == NULL
2554 || EVP_PKEY_verify_init(loopargs
[i
].ecdsa_verify_ctx
[testnum
]) <= 0
2555 || EVP_PKEY_verify(loopargs
[i
].ecdsa_verify_ctx
[testnum
],
2557 loopargs
[i
].sigsize
,
2558 loopargs
[i
].buf
, 20) <= 0)
2563 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2564 ERR_print_errors(bio_err
);
2565 ecdsa_doit
[testnum
] = 0;
2567 pkey_print_message("verify", "ecdsa",
2568 ecdsa_c
[testnum
][1], ec_curves
[testnum
].bits
,
2571 count
= run_benchmark(async_jobs
, ECDSA_verify_loop
, loopargs
);
2574 mr
? "+R6:%ld:%u:%.2f\n"
2575 : "%ld %u bits ECDSA verify in %.2fs\n",
2576 count
, ec_curves
[testnum
].bits
, d
);
2577 ecdsa_results
[testnum
][1] = (double)count
/ d
;
2580 if (op_count
<= 1) {
2581 /* if longer than 10s, don't do any more */
2582 stop_it(ecdsa_doit
, testnum
);
2586 for (testnum
= 0; testnum
< EC_NUM
; testnum
++) {
2587 int ecdh_checks
= 1;
2589 if (!ecdh_doit
[testnum
])
2592 for (i
= 0; i
< loopargs_len
; i
++) {
2593 EVP_PKEY_CTX
*test_ctx
= NULL
;
2594 EVP_PKEY_CTX
*ctx
= NULL
;
2595 EVP_PKEY
*key_A
= NULL
;
2596 EVP_PKEY
*key_B
= NULL
;
2600 if ((key_A
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key A */
2601 || (key_B
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key B */
2602 || (ctx
= EVP_PKEY_CTX_new(key_A
, NULL
)) == NULL
/* derivation ctx from skeyA */
2603 || EVP_PKEY_derive_init(ctx
) <= 0 /* init derivation ctx */
2604 || EVP_PKEY_derive_set_peer(ctx
, key_B
) <= 0 /* set peer pubkey in ctx */
2605 || EVP_PKEY_derive(ctx
, NULL
, &outlen
) <= 0 /* determine max length */
2606 || outlen
== 0 /* ensure outlen is a valid size */
2607 || outlen
> MAX_ECDH_SIZE
/* avoid buffer overflow */) {
2609 BIO_printf(bio_err
, "ECDH key generation failure.\n");
2610 ERR_print_errors(bio_err
);
2616 * Here we perform a test run, comparing the output of a*B and b*A;
2617 * we try this here and assume that further EVP_PKEY_derive calls
2618 * never fail, so we can skip checks in the actually benchmarked
2619 * code, for maximum performance.
2621 if ((test_ctx
= EVP_PKEY_CTX_new(key_B
, NULL
)) == NULL
/* test ctx from skeyB */
2622 || !EVP_PKEY_derive_init(test_ctx
) /* init derivation test_ctx */
2623 || !EVP_PKEY_derive_set_peer(test_ctx
, key_A
) /* set peer pubkey in test_ctx */
2624 || !EVP_PKEY_derive(test_ctx
, NULL
, &test_outlen
) /* determine max length */
2625 || !EVP_PKEY_derive(ctx
, loopargs
[i
].secret_a
, &outlen
) /* compute a*B */
2626 || !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_b
, &test_outlen
) /* compute b*A */
2627 || test_outlen
!= outlen
/* compare output length */) {
2629 BIO_printf(bio_err
, "ECDH computation failure.\n");
2630 ERR_print_errors(bio_err
);
2635 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2636 if (CRYPTO_memcmp(loopargs
[i
].secret_a
,
2637 loopargs
[i
].secret_b
, outlen
)) {
2639 BIO_printf(bio_err
, "ECDH computations don't match.\n");
2640 ERR_print_errors(bio_err
);
2645 loopargs
[i
].ecdh_ctx
[testnum
] = ctx
;
2646 loopargs
[i
].outlen
[testnum
] = outlen
;
2648 EVP_PKEY_free(key_A
);
2649 EVP_PKEY_free(key_B
);
2650 EVP_PKEY_CTX_free(test_ctx
);
2653 if (ecdh_checks
!= 0) {
2654 pkey_print_message("", "ecdh",
2656 ec_curves
[testnum
].bits
, seconds
.ecdh
);
2659 run_benchmark(async_jobs
, ECDH_EVP_derive_key_loop
, loopargs
);
2662 mr
? "+R7:%ld:%d:%.2f\n" :
2663 "%ld %u-bits ECDH ops in %.2fs\n", count
,
2664 ec_curves
[testnum
].bits
, d
);
2665 ecdh_results
[testnum
][0] = (double)count
/ d
;
2669 if (op_count
<= 1) {
2670 /* if longer than 10s, don't do any more */
2671 stop_it(ecdh_doit
, testnum
);
2675 for (testnum
= 0; testnum
< EdDSA_NUM
; testnum
++) {
2677 EVP_PKEY
*ed_pkey
= NULL
;
2678 EVP_PKEY_CTX
*ed_pctx
= NULL
;
2680 if (!eddsa_doit
[testnum
])
2681 continue; /* Ignore Curve */
2682 for (i
= 0; i
< loopargs_len
; i
++) {
2683 loopargs
[i
].eddsa_ctx
[testnum
] = EVP_MD_CTX_new();
2684 if (loopargs
[i
].eddsa_ctx
[testnum
] == NULL
) {
2688 loopargs
[i
].eddsa_ctx2
[testnum
] = EVP_MD_CTX_new();
2689 if (loopargs
[i
].eddsa_ctx2
[testnum
] == NULL
) {
2694 if ((ed_pctx
= EVP_PKEY_CTX_new_id(ed_curves
[testnum
].nid
,
2696 || EVP_PKEY_keygen_init(ed_pctx
) <= 0
2697 || EVP_PKEY_keygen(ed_pctx
, &ed_pkey
) <= 0) {
2699 EVP_PKEY_CTX_free(ed_pctx
);
2702 EVP_PKEY_CTX_free(ed_pctx
);
2704 if (!EVP_DigestSignInit(loopargs
[i
].eddsa_ctx
[testnum
], NULL
, NULL
,
2707 EVP_PKEY_free(ed_pkey
);
2710 if (!EVP_DigestVerifyInit(loopargs
[i
].eddsa_ctx2
[testnum
], NULL
,
2711 NULL
, NULL
, ed_pkey
)) {
2713 EVP_PKEY_free(ed_pkey
);
2717 EVP_PKEY_free(ed_pkey
);
2721 BIO_printf(bio_err
, "EdDSA failure.\n");
2722 ERR_print_errors(bio_err
);
2725 for (i
= 0; i
< loopargs_len
; i
++) {
2726 /* Perform EdDSA signature test */
2727 loopargs
[i
].sigsize
= ed_curves
[testnum
].sigsize
;
2728 st
= EVP_DigestSign(loopargs
[i
].eddsa_ctx
[testnum
],
2729 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2730 loopargs
[i
].buf
, 20);
2736 "EdDSA sign failure. No EdDSA sign will be done.\n");
2737 ERR_print_errors(bio_err
);
2740 pkey_print_message("sign", ed_curves
[testnum
].name
,
2741 eddsa_c
[testnum
][0],
2742 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2744 count
= run_benchmark(async_jobs
, EdDSA_sign_loop
, loopargs
);
2748 mr
? "+R8:%ld:%u:%s:%.2f\n" :
2749 "%ld %u bits %s signs in %.2fs \n",
2750 count
, ed_curves
[testnum
].bits
,
2751 ed_curves
[testnum
].name
, d
);
2752 eddsa_results
[testnum
][0] = (double)count
/ d
;
2755 /* Perform EdDSA verification test */
2756 for (i
= 0; i
< loopargs_len
; i
++) {
2757 st
= EVP_DigestVerify(loopargs
[i
].eddsa_ctx2
[testnum
],
2758 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2759 loopargs
[i
].buf
, 20);
2765 "EdDSA verify failure. No EdDSA verify will be done.\n");
2766 ERR_print_errors(bio_err
);
2767 eddsa_doit
[testnum
] = 0;
2769 pkey_print_message("verify", ed_curves
[testnum
].name
,
2770 eddsa_c
[testnum
][1],
2771 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2773 count
= run_benchmark(async_jobs
, EdDSA_verify_loop
, loopargs
);
2776 mr
? "+R9:%ld:%u:%s:%.2f\n"
2777 : "%ld %u bits %s verify in %.2fs\n",
2778 count
, ed_curves
[testnum
].bits
,
2779 ed_curves
[testnum
].name
, d
);
2780 eddsa_results
[testnum
][1] = (double)count
/ d
;
2783 if (op_count
<= 1) {
2784 /* if longer than 10s, don't do any more */
2785 stop_it(eddsa_doit
, testnum
);
2790 #ifndef OPENSSL_NO_SM2
2791 for (testnum
= 0; testnum
< SM2_NUM
; testnum
++) {
2793 EVP_PKEY
*sm2_pkey
= NULL
;
2795 if (!sm2_doit
[testnum
])
2796 continue; /* Ignore Curve */
2797 /* Init signing and verification */
2798 for (i
= 0; i
< loopargs_len
; i
++) {
2799 EVP_PKEY_CTX
*sm2_pctx
= NULL
;
2800 EVP_PKEY_CTX
*sm2_vfy_pctx
= NULL
;
2801 EVP_PKEY_CTX
*pctx
= NULL
;
2804 loopargs
[i
].sm2_ctx
[testnum
] = EVP_MD_CTX_new();
2805 loopargs
[i
].sm2_vfy_ctx
[testnum
] = EVP_MD_CTX_new();
2806 if (loopargs
[i
].sm2_ctx
[testnum
] == NULL
2807 || loopargs
[i
].sm2_vfy_ctx
[testnum
] == NULL
)
2812 st
= !((pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_SM2
, NULL
)) == NULL
2813 || EVP_PKEY_keygen_init(pctx
) <= 0
2814 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
2815 sm2_curves
[testnum
].nid
) <= 0
2816 || EVP_PKEY_keygen(pctx
, &sm2_pkey
) <= 0);
2817 EVP_PKEY_CTX_free(pctx
);
2821 st
= 0; /* set back to zero */
2822 /* attach it sooner to rely on main final cleanup */
2823 loopargs
[i
].sm2_pkey
[testnum
] = sm2_pkey
;
2824 loopargs
[i
].sigsize
= EVP_PKEY_get_size(sm2_pkey
);
2826 sm2_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2827 sm2_vfy_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2828 if (sm2_pctx
== NULL
|| sm2_vfy_pctx
== NULL
) {
2829 EVP_PKEY_CTX_free(sm2_vfy_pctx
);
2833 /* attach them directly to respective ctx */
2834 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_ctx
[testnum
], sm2_pctx
);
2835 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[testnum
], sm2_vfy_pctx
);
2838 * No need to allow user to set an explicit ID here, just use
2839 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2841 if (EVP_PKEY_CTX_set1_id(sm2_pctx
, SM2_ID
, SM2_ID_LEN
) != 1
2842 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx
, SM2_ID
, SM2_ID_LEN
) != 1)
2845 if (!EVP_DigestSignInit(loopargs
[i
].sm2_ctx
[testnum
], NULL
,
2846 EVP_sm3(), NULL
, sm2_pkey
))
2848 if (!EVP_DigestVerifyInit(loopargs
[i
].sm2_vfy_ctx
[testnum
], NULL
,
2849 EVP_sm3(), NULL
, sm2_pkey
))
2851 st
= 1; /* mark loop as succeeded */
2854 BIO_printf(bio_err
, "SM2 init failure.\n");
2855 ERR_print_errors(bio_err
);
2858 for (i
= 0; i
< loopargs_len
; i
++) {
2859 /* Perform SM2 signature test */
2860 st
= EVP_DigestSign(loopargs
[i
].sm2_ctx
[testnum
],
2861 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2862 loopargs
[i
].buf
, 20);
2868 "SM2 sign failure. No SM2 sign will be done.\n");
2869 ERR_print_errors(bio_err
);
2872 pkey_print_message("sign", sm2_curves
[testnum
].name
,
2874 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2876 count
= run_benchmark(async_jobs
, SM2_sign_loop
, loopargs
);
2880 mr
? "+R10:%ld:%u:%s:%.2f\n" :
2881 "%ld %u bits %s signs in %.2fs \n",
2882 count
, sm2_curves
[testnum
].bits
,
2883 sm2_curves
[testnum
].name
, d
);
2884 sm2_results
[testnum
][0] = (double)count
/ d
;
2888 /* Perform SM2 verification test */
2889 for (i
= 0; i
< loopargs_len
; i
++) {
2890 st
= EVP_DigestVerify(loopargs
[i
].sm2_vfy_ctx
[testnum
],
2891 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2892 loopargs
[i
].buf
, 20);
2898 "SM2 verify failure. No SM2 verify will be done.\n");
2899 ERR_print_errors(bio_err
);
2900 sm2_doit
[testnum
] = 0;
2902 pkey_print_message("verify", sm2_curves
[testnum
].name
,
2904 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2906 count
= run_benchmark(async_jobs
, SM2_verify_loop
, loopargs
);
2909 mr
? "+R11:%ld:%u:%s:%.2f\n"
2910 : "%ld %u bits %s verify in %.2fs\n",
2911 count
, sm2_curves
[testnum
].bits
,
2912 sm2_curves
[testnum
].name
, d
);
2913 sm2_results
[testnum
][1] = (double)count
/ d
;
2916 if (op_count
<= 1) {
2917 /* if longer than 10s, don't do any more */
2918 for (testnum
++; testnum
< SM2_NUM
; testnum
++)
2919 sm2_doit
[testnum
] = 0;
2923 #endif /* OPENSSL_NO_SM2 */
2925 #ifndef OPENSSL_NO_DH
2926 for (testnum
= 0; testnum
< FFDH_NUM
; testnum
++) {
2927 int ffdh_checks
= 1;
2929 if (!ffdh_doit
[testnum
])
2932 for (i
= 0; i
< loopargs_len
; i
++) {
2933 EVP_PKEY
*pkey_A
= NULL
;
2934 EVP_PKEY
*pkey_B
= NULL
;
2935 EVP_PKEY_CTX
*ffdh_ctx
= NULL
;
2936 EVP_PKEY_CTX
*test_ctx
= NULL
;
2940 /* Ensure that the error queue is empty */
2941 if (ERR_peek_error()) {
2943 "WARNING: the error queue contains previous unhandled errors.\n");
2944 ERR_print_errors(bio_err
);
2947 pkey_A
= EVP_PKEY_new();
2949 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2950 ERR_print_errors(bio_err
);
2955 pkey_B
= EVP_PKEY_new();
2957 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2958 ERR_print_errors(bio_err
);
2964 ffdh_ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_DH
, NULL
);
2966 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
2967 ERR_print_errors(bio_err
);
2973 if (EVP_PKEY_keygen_init(ffdh_ctx
) <= 0) {
2974 BIO_printf(bio_err
, "Error while initialising EVP_PKEY_CTX.\n");
2975 ERR_print_errors(bio_err
);
2980 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx
, ffdh_params
[testnum
].nid
) <= 0) {
2981 BIO_printf(bio_err
, "Error setting DH key size for keygen.\n");
2982 ERR_print_errors(bio_err
);
2988 if (EVP_PKEY_keygen(ffdh_ctx
, &pkey_A
) <= 0 ||
2989 EVP_PKEY_keygen(ffdh_ctx
, &pkey_B
) <= 0) {
2990 BIO_printf(bio_err
, "FFDH key generation failure.\n");
2991 ERR_print_errors(bio_err
);
2997 EVP_PKEY_CTX_free(ffdh_ctx
);
3000 * check if the derivation works correctly both ways so that
3001 * we know if future derive calls will fail, and we can skip
3002 * error checking in benchmarked code
3004 ffdh_ctx
= EVP_PKEY_CTX_new(pkey_A
, NULL
);
3005 if (ffdh_ctx
== NULL
) {
3006 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3007 ERR_print_errors(bio_err
);
3012 if (EVP_PKEY_derive_init(ffdh_ctx
) <= 0) {
3013 BIO_printf(bio_err
, "FFDH derivation context init failure.\n");
3014 ERR_print_errors(bio_err
);
3019 if (EVP_PKEY_derive_set_peer(ffdh_ctx
, pkey_B
) <= 0) {
3020 BIO_printf(bio_err
, "Assigning peer key for derivation failed.\n");
3021 ERR_print_errors(bio_err
);
3026 if (EVP_PKEY_derive(ffdh_ctx
, NULL
, &secret_size
) <= 0) {
3027 BIO_printf(bio_err
, "Checking size of shared secret failed.\n");
3028 ERR_print_errors(bio_err
);
3033 if (secret_size
> MAX_FFDH_SIZE
) {
3034 BIO_printf(bio_err
, "Assertion failure: shared secret too large.\n");
3039 if (EVP_PKEY_derive(ffdh_ctx
,
3040 loopargs
[i
].secret_ff_a
,
3041 &secret_size
) <= 0) {
3042 BIO_printf(bio_err
, "Shared secret derive failure.\n");
3043 ERR_print_errors(bio_err
);
3048 /* Now check from side B */
3049 test_ctx
= EVP_PKEY_CTX_new(pkey_B
, NULL
);
3051 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3052 ERR_print_errors(bio_err
);
3057 if (!EVP_PKEY_derive_init(test_ctx
) ||
3058 !EVP_PKEY_derive_set_peer(test_ctx
, pkey_A
) ||
3059 !EVP_PKEY_derive(test_ctx
, NULL
, &test_out
) ||
3060 !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_ff_b
, &test_out
) ||
3061 test_out
!= secret_size
) {
3062 BIO_printf(bio_err
, "FFDH computation failure.\n");
3068 /* compare the computed secrets */
3069 if (CRYPTO_memcmp(loopargs
[i
].secret_ff_a
,
3070 loopargs
[i
].secret_ff_b
, secret_size
)) {
3071 BIO_printf(bio_err
, "FFDH computations don't match.\n");
3072 ERR_print_errors(bio_err
);
3078 loopargs
[i
].ffdh_ctx
[testnum
] = ffdh_ctx
;
3080 EVP_PKEY_free(pkey_A
);
3082 EVP_PKEY_free(pkey_B
);
3084 EVP_PKEY_CTX_free(test_ctx
);
3087 if (ffdh_checks
!= 0) {
3088 pkey_print_message("", "ffdh", ffdh_c
[testnum
][0],
3089 ffdh_params
[testnum
].bits
, seconds
.ffdh
);
3092 run_benchmark(async_jobs
, FFDH_derive_key_loop
, loopargs
);
3095 mr
? "+R12:%ld:%d:%.2f\n" :
3096 "%ld %u-bits FFDH ops in %.2fs\n", count
,
3097 ffdh_params
[testnum
].bits
, d
);
3098 ffdh_results
[testnum
][0] = (double)count
/ d
;
3101 if (op_count
<= 1) {
3102 /* if longer than 10s, don't do any more */
3103 stop_it(ffdh_doit
, testnum
);
3106 #endif /* OPENSSL_NO_DH */
3111 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING
));
3112 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON
));
3113 printf("options: %s\n", BN_options());
3114 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS
));
3115 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO
));
3122 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3125 for (testnum
= 0; testnum
< size_num
; testnum
++)
3126 printf(mr
? ":%d" : "%7d bytes", lengths
[testnum
]);
3130 for (k
= 0; k
< ALGOR_NUM
; k
++) {
3134 printf("+F:%u:%s", k
, names
[k
]);
3136 printf("%-13s", names
[k
]);
3137 for (testnum
= 0; testnum
< size_num
; testnum
++) {
3138 if (results
[k
][testnum
] > 10000 && !mr
)
3139 printf(" %11.2fk", results
[k
][testnum
] / 1e3
);
3141 printf(mr
? ":%.2f" : " %11.2f ", results
[k
][testnum
]);
3146 for (k
= 0; k
< RSA_NUM
; k
++) {
3149 if (testnum
&& !mr
) {
3150 printf("%18ssign verify sign/s verify/s\n", " ");
3154 printf("+F2:%u:%u:%f:%f\n",
3155 k
, rsa_keys
[k
].bits
, rsa_results
[k
][0], rsa_results
[k
][1]);
3157 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3158 rsa_keys
[k
].bits
, 1.0 / rsa_results
[k
][0], 1.0 / rsa_results
[k
][1],
3159 rsa_results
[k
][0], rsa_results
[k
][1]);
3162 for (k
= 0; k
< DSA_NUM
; k
++) {
3165 if (testnum
&& !mr
) {
3166 printf("%18ssign verify sign/s verify/s\n", " ");
3170 printf("+F3:%u:%u:%f:%f\n",
3171 k
, dsa_bits
[k
], dsa_results
[k
][0], dsa_results
[k
][1]);
3173 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3174 dsa_bits
[k
], 1.0 / dsa_results
[k
][0], 1.0 / dsa_results
[k
][1],
3175 dsa_results
[k
][0], dsa_results
[k
][1]);
3178 for (k
= 0; k
< OSSL_NELEM(ecdsa_doit
); k
++) {
3181 if (testnum
&& !mr
) {
3182 printf("%30ssign verify sign/s verify/s\n", " ");
3187 printf("+F4:%u:%u:%f:%f\n",
3188 k
, ec_curves
[k
].bits
,
3189 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3191 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3192 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3193 1.0 / ecdsa_results
[k
][0], 1.0 / ecdsa_results
[k
][1],
3194 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3198 for (k
= 0; k
< EC_NUM
; k
++) {
3201 if (testnum
&& !mr
) {
3202 printf("%30sop op/s\n", " ");
3206 printf("+F5:%u:%u:%f:%f\n",
3207 k
, ec_curves
[k
].bits
,
3208 ecdh_results
[k
][0], 1.0 / ecdh_results
[k
][0]);
3211 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3212 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3213 1.0 / ecdh_results
[k
][0], ecdh_results
[k
][0]);
3217 for (k
= 0; k
< OSSL_NELEM(eddsa_doit
); k
++) {
3220 if (testnum
&& !mr
) {
3221 printf("%30ssign verify sign/s verify/s\n", " ");
3226 printf("+F6:%u:%u:%s:%f:%f\n",
3227 k
, ed_curves
[k
].bits
, ed_curves
[k
].name
,
3228 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3230 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3231 ed_curves
[k
].bits
, ed_curves
[k
].name
,
3232 1.0 / eddsa_results
[k
][0], 1.0 / eddsa_results
[k
][1],
3233 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3236 #ifndef OPENSSL_NO_SM2
3238 for (k
= 0; k
< OSSL_NELEM(sm2_doit
); k
++) {
3241 if (testnum
&& !mr
) {
3242 printf("%30ssign verify sign/s verify/s\n", " ");
3247 printf("+F7:%u:%u:%s:%f:%f\n",
3248 k
, sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3249 sm2_results
[k
][0], sm2_results
[k
][1]);
3251 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3252 sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3253 1.0 / sm2_results
[k
][0], 1.0 / sm2_results
[k
][1],
3254 sm2_results
[k
][0], sm2_results
[k
][1]);
3257 #ifndef OPENSSL_NO_DH
3259 for (k
= 0; k
< FFDH_NUM
; k
++) {
3262 if (testnum
&& !mr
) {
3263 printf("%23sop op/s\n", " ");
3267 printf("+F8:%u:%u:%f:%f\n",
3268 k
, ffdh_params
[k
].bits
,
3269 ffdh_results
[k
][0], 1.0 / ffdh_results
[k
][0]);
3272 printf("%4u bits ffdh %8.4fs %8.1f\n",
3273 ffdh_params
[k
].bits
,
3274 1.0 / ffdh_results
[k
][0], ffdh_results
[k
][0]);
3276 #endif /* OPENSSL_NO_DH */
3281 ERR_print_errors(bio_err
);
3282 for (i
= 0; i
< loopargs_len
; i
++) {
3283 OPENSSL_free(loopargs
[i
].buf_malloc
);
3284 OPENSSL_free(loopargs
[i
].buf2_malloc
);
3287 EVP_PKEY_CTX_free(genctx
);
3288 for (k
= 0; k
< RSA_NUM
; k
++) {
3289 EVP_PKEY_CTX_free(loopargs
[i
].rsa_sign_ctx
[k
]);
3290 EVP_PKEY_CTX_free(loopargs
[i
].rsa_verify_ctx
[k
]);
3292 #ifndef OPENSSL_NO_DH
3293 OPENSSL_free(loopargs
[i
].secret_ff_a
);
3294 OPENSSL_free(loopargs
[i
].secret_ff_b
);
3295 for (k
= 0; k
< FFDH_NUM
; k
++)
3296 EVP_PKEY_CTX_free(loopargs
[i
].ffdh_ctx
[k
]);
3298 for (k
= 0; k
< DSA_NUM
; k
++) {
3299 EVP_PKEY_CTX_free(loopargs
[i
].dsa_sign_ctx
[k
]);
3300 EVP_PKEY_CTX_free(loopargs
[i
].dsa_verify_ctx
[k
]);
3302 for (k
= 0; k
< ECDSA_NUM
; k
++) {
3303 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_sign_ctx
[k
]);
3304 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_verify_ctx
[k
]);
3306 for (k
= 0; k
< EC_NUM
; k
++)
3307 EVP_PKEY_CTX_free(loopargs
[i
].ecdh_ctx
[k
]);
3308 for (k
= 0; k
< EdDSA_NUM
; k
++) {
3309 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx
[k
]);
3310 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx2
[k
]);
3312 #ifndef OPENSSL_NO_SM2
3313 for (k
= 0; k
< SM2_NUM
; k
++) {
3314 EVP_PKEY_CTX
*pctx
= NULL
;
3316 /* free signing ctx */
3317 if (loopargs
[i
].sm2_ctx
[k
] != NULL
3318 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_ctx
[k
])) != NULL
)
3319 EVP_PKEY_CTX_free(pctx
);
3320 EVP_MD_CTX_free(loopargs
[i
].sm2_ctx
[k
]);
3321 /* free verification ctx */
3322 if (loopargs
[i
].sm2_vfy_ctx
[k
] != NULL
3323 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[k
])) != NULL
)
3324 EVP_PKEY_CTX_free(pctx
);
3325 EVP_MD_CTX_free(loopargs
[i
].sm2_vfy_ctx
[k
]);
3327 EVP_PKEY_free(loopargs
[i
].sm2_pkey
[k
]);
3330 OPENSSL_free(loopargs
[i
].secret_a
);
3331 OPENSSL_free(loopargs
[i
].secret_b
);
3333 OPENSSL_free(evp_hmac_name
);
3334 OPENSSL_free(evp_cmac_name
);
3336 if (async_jobs
> 0) {
3337 for (i
= 0; i
< loopargs_len
; i
++)
3338 ASYNC_WAIT_CTX_free(loopargs
[i
].wait_ctx
);
3342 ASYNC_cleanup_thread();
3344 OPENSSL_free(loopargs
);
3346 EVP_CIPHER_free(evp_cipher
);
3351 static void print_message(const char *s
, long num
, int length
, int tm
)
3354 mr
? "+DT:%s:%d:%d\n"
3355 : "Doing %s for %ds on %d size blocks: ", s
, tm
, length
);
3356 (void)BIO_flush(bio_err
);
3361 static void pkey_print_message(const char *str
, const char *str2
, long num
,
3362 unsigned int bits
, int tm
)
3365 mr
? "+DTP:%d:%s:%s:%d\n"
3366 : "Doing %u bits %s %s's for %ds: ", bits
, str
, str2
, tm
);
3367 (void)BIO_flush(bio_err
);
3372 static void print_result(int alg
, int run_no
, int count
, double time_used
)
3375 BIO_printf(bio_err
, "%s error!\n", names
[alg
]);
3376 ERR_print_errors(bio_err
);
3380 mr
? "+R:%d:%s:%f\n"
3381 : "%d %s's in %.2fs\n", count
, names
[alg
], time_used
);
3382 results
[alg
][run_no
] = ((double)count
) / time_used
* lengths
[run_no
];
3386 static char *sstrsep(char **string
, const char *delim
)
3389 char *token
= *string
;
3394 memset(isdelim
, 0, sizeof(isdelim
));
3398 isdelim
[(unsigned char)(*delim
)] = 1;
3402 while (!isdelim
[(unsigned char)(**string
)])
3413 static int do_multi(int multi
, int size_num
)
3418 static char sep
[] = ":";
3420 fds
= app_malloc(sizeof(*fds
) * multi
, "fd buffer for do_multi");
3421 for (n
= 0; n
< multi
; ++n
) {
3422 if (pipe(fd
) == -1) {
3423 BIO_printf(bio_err
, "pipe failure\n");
3427 (void)BIO_flush(bio_err
);
3434 if (dup(fd
[1]) == -1) {
3435 BIO_printf(bio_err
, "dup failed\n");
3444 printf("Forked child %d\n", n
);
3447 /* for now, assume the pipe is long enough to take all the output */
3448 for (n
= 0; n
< multi
; ++n
) {
3453 f
= fdopen(fds
[n
], "r");
3454 while (fgets(buf
, sizeof(buf
), f
)) {
3455 p
= strchr(buf
, '\n');
3458 if (buf
[0] != '+') {
3460 "Don't understand line '%s' from child %d\n", buf
,
3464 printf("Got: %s from %d\n", buf
, n
);
3466 if (CHECK_AND_SKIP_PREFIX(p
, "+F:")) {
3470 alg
= atoi(sstrsep(&p
, sep
));
3472 for (j
= 0; j
< size_num
; ++j
)
3473 results
[alg
][j
] += atof(sstrsep(&p
, sep
));
3474 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F2:")) {
3478 k
= atoi(sstrsep(&p
, sep
));
3481 d
= atof(sstrsep(&p
, sep
));
3482 rsa_results
[k
][0] += d
;
3484 d
= atof(sstrsep(&p
, sep
));
3485 rsa_results
[k
][1] += d
;
3486 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F3:")) {
3490 k
= atoi(sstrsep(&p
, sep
));
3493 d
= atof(sstrsep(&p
, sep
));
3494 dsa_results
[k
][0] += d
;
3496 d
= atof(sstrsep(&p
, sep
));
3497 dsa_results
[k
][1] += d
;
3498 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F4:")) {
3502 k
= atoi(sstrsep(&p
, sep
));
3505 d
= atof(sstrsep(&p
, sep
));
3506 ecdsa_results
[k
][0] += d
;
3508 d
= atof(sstrsep(&p
, sep
));
3509 ecdsa_results
[k
][1] += d
;
3510 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F5:")) {
3514 k
= atoi(sstrsep(&p
, sep
));
3517 d
= atof(sstrsep(&p
, sep
));
3518 ecdh_results
[k
][0] += d
;
3519 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F6:")) {
3523 k
= atoi(sstrsep(&p
, sep
));
3527 d
= atof(sstrsep(&p
, sep
));
3528 eddsa_results
[k
][0] += d
;
3530 d
= atof(sstrsep(&p
, sep
));
3531 eddsa_results
[k
][1] += d
;
3532 # ifndef OPENSSL_NO_SM2
3533 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F7:")) {
3537 k
= atoi(sstrsep(&p
, sep
));
3541 d
= atof(sstrsep(&p
, sep
));
3542 sm2_results
[k
][0] += d
;
3544 d
= atof(sstrsep(&p
, sep
));
3545 sm2_results
[k
][1] += d
;
3546 # endif /* OPENSSL_NO_SM2 */
3547 # ifndef OPENSSL_NO_DH
3548 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F8:")) {
3552 k
= atoi(sstrsep(&p
, sep
));
3555 d
= atof(sstrsep(&p
, sep
));
3556 ffdh_results
[k
][0] += d
;
3557 # endif /* OPENSSL_NO_DH */
3558 } else if (!HAS_PREFIX(buf
, "+H:")) {
3559 BIO_printf(bio_err
, "Unknown type '%s' from child %d\n", buf
,
3571 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
3572 const openssl_speed_sec_t
*seconds
)
3574 static const int mblengths_list
[] =
3575 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3576 const int *mblengths
= mblengths_list
;
3577 int j
, count
, keylen
, num
= OSSL_NELEM(mblengths_list
);
3578 const char *alg_name
;
3579 unsigned char *inp
= NULL
, *out
= NULL
, *key
, no_key
[32], no_iv
[16];
3580 EVP_CIPHER_CTX
*ctx
= NULL
;
3583 if (lengths_single
) {
3584 mblengths
= &lengths_single
;
3588 inp
= app_malloc(mblengths
[num
- 1], "multiblock input buffer");
3589 out
= app_malloc(mblengths
[num
- 1] + 1024, "multiblock output buffer");
3590 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
3591 app_bail_out("failed to allocate cipher context\n");
3592 if (!EVP_EncryptInit_ex(ctx
, evp_cipher
, NULL
, NULL
, no_iv
))
3593 app_bail_out("failed to initialise cipher context\n");
3595 if ((keylen
= EVP_CIPHER_CTX_get_key_length(ctx
)) < 0) {
3596 BIO_printf(bio_err
, "Impossible negative key length: %d\n", keylen
);
3599 key
= app_malloc(keylen
, "evp_cipher key");
3600 if (!EVP_CIPHER_CTX_rand_key(ctx
, key
))
3601 app_bail_out("failed to generate random cipher key\n");
3602 if (!EVP_EncryptInit_ex(ctx
, NULL
, NULL
, key
, NULL
))
3603 app_bail_out("failed to set cipher key\n");
3604 OPENSSL_clear_free(key
, keylen
);
3606 if (!EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_MAC_KEY
,
3607 sizeof(no_key
), no_key
))
3608 app_bail_out("failed to set AEAD key\n");
3609 if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
3610 app_bail_out("failed to get cipher name\n");
3612 for (j
= 0; j
< num
; j
++) {
3613 print_message(alg_name
, 0, mblengths
[j
], seconds
->sym
);
3615 for (count
= 0; run
&& count
< 0x7fffffff; count
++) {
3616 unsigned char aad
[EVP_AEAD_TLS1_AAD_LEN
];
3617 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param
;
3618 size_t len
= mblengths
[j
];
3621 memset(aad
, 0, 8); /* avoid uninitialized values */
3622 aad
[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3623 aad
[9] = 3; /* version */
3625 aad
[11] = 0; /* length */
3627 mb_param
.out
= NULL
;
3630 mb_param
.interleave
= 8;
3632 packlen
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD
,
3633 sizeof(mb_param
), &mb_param
);
3639 (void)EVP_CIPHER_CTX_ctrl(ctx
,
3640 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT
,
3641 sizeof(mb_param
), &mb_param
);
3645 RAND_bytes(out
, 16);
3647 aad
[11] = (unsigned char)(len
>> 8);
3648 aad
[12] = (unsigned char)(len
);
3649 pad
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_TLS1_AAD
,
3650 EVP_AEAD_TLS1_AAD_LEN
, aad
);
3651 EVP_Cipher(ctx
, out
, inp
, len
+ pad
);
3655 BIO_printf(bio_err
, mr
? "+R:%d:%s:%f\n"
3656 : "%d %s's in %.2fs\n", count
, "evp", d
);
3657 results
[D_EVP
][j
] = ((double)count
) / d
* mblengths
[j
];
3661 fprintf(stdout
, "+H");
3662 for (j
= 0; j
< num
; j
++)
3663 fprintf(stdout
, ":%d", mblengths
[j
]);
3664 fprintf(stdout
, "\n");
3665 fprintf(stdout
, "+F:%d:%s", D_EVP
, alg_name
);
3666 for (j
= 0; j
< num
; j
++)
3667 fprintf(stdout
, ":%.2f", results
[D_EVP
][j
]);
3668 fprintf(stdout
, "\n");
3671 "The 'numbers' are in 1000s of bytes per second processed.\n");
3672 fprintf(stdout
, "type ");
3673 for (j
= 0; j
< num
; j
++)
3674 fprintf(stdout
, "%7d bytes", mblengths
[j
]);
3675 fprintf(stdout
, "\n");
3676 fprintf(stdout
, "%-24s", alg_name
);
3678 for (j
= 0; j
< num
; j
++) {
3679 if (results
[D_EVP
][j
] > 10000)
3680 fprintf(stdout
, " %11.2fk", results
[D_EVP
][j
] / 1e3
);
3682 fprintf(stdout
, " %11.2f ", results
[D_EVP
][j
]);
3684 fprintf(stdout
, "\n");
3690 EVP_CIPHER_CTX_free(ctx
);