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
, OPT_CONFIG
,
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)"},
242 OPT_SECTION("Selection"),
243 {"evp", OPT_EVP
, 's', "Use EVP-named cipher or digest"},
244 {"hmac", OPT_HMAC
, 's', "HMAC using EVP-named digest"},
245 {"cmac", OPT_CMAC
, 's', "CMAC using EVP-named cipher"},
246 {"decrypt", OPT_DECRYPT
, '-',
247 "Time decryption instead of encryption (only EVP)"},
248 {"aead", OPT_AEAD
, '-',
249 "Benchmark EVP-named AEAD cipher in TLS-like sequence"},
251 OPT_SECTION("Timing"),
252 {"elapsed", OPT_ELAPSED
, '-',
253 "Use wall-clock time instead of CPU user time as divisor"},
254 {"seconds", OPT_SECONDS
, 'p',
255 "Run benchmarks for specified amount of seconds"},
256 {"bytes", OPT_BYTES
, 'p',
257 "Run [non-PKI] benchmarks on custom-sized buffer"},
258 {"misalign", OPT_MISALIGN
, 'p',
259 "Use specified offset to mis-align buffers"},
265 {"algorithm", 0, 0, "Algorithm(s) to test (optional; otherwise tests all)"},
270 D_MD2
, D_MDC2
, D_MD4
, D_MD5
, D_SHA1
, D_RMD160
,
271 D_SHA256
, D_SHA512
, D_WHIRLPOOL
, D_HMAC
,
272 D_CBC_DES
, D_EDE3_DES
, D_RC4
, D_CBC_IDEA
, D_CBC_SEED
,
273 D_CBC_RC2
, D_CBC_RC5
, D_CBC_BF
, D_CBC_CAST
,
274 D_CBC_128_AES
, D_CBC_192_AES
, D_CBC_256_AES
,
275 D_CBC_128_CML
, D_CBC_192_CML
, D_CBC_256_CML
,
276 D_EVP
, D_GHASH
, D_RAND
, D_EVP_CMAC
, ALGOR_NUM
278 /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */
279 static const char *names
[ALGOR_NUM
] = {
280 "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
281 "sha256", "sha512", "whirlpool", "hmac(md5)",
282 "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
283 "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
284 "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
285 "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
286 "evp", "ghash", "rand", "cmac"
289 /* list of configured algorithm (remaining), with some few alias */
290 static const OPT_PAIR doit_choices
[] = {
297 {"sha256", D_SHA256
},
298 {"sha512", D_SHA512
},
299 {"whirlpool", D_WHIRLPOOL
},
300 {"ripemd", D_RMD160
},
301 {"rmd160", D_RMD160
},
302 {"ripemd160", D_RMD160
},
304 {"des-cbc", D_CBC_DES
},
305 {"des-ede3", D_EDE3_DES
},
306 {"aes-128-cbc", D_CBC_128_AES
},
307 {"aes-192-cbc", D_CBC_192_AES
},
308 {"aes-256-cbc", D_CBC_256_AES
},
309 {"camellia-128-cbc", D_CBC_128_CML
},
310 {"camellia-192-cbc", D_CBC_192_CML
},
311 {"camellia-256-cbc", D_CBC_256_CML
},
312 {"rc2-cbc", D_CBC_RC2
},
314 {"rc5-cbc", D_CBC_RC5
},
316 {"idea-cbc", D_CBC_IDEA
},
317 {"idea", D_CBC_IDEA
},
318 {"seed-cbc", D_CBC_SEED
},
319 {"seed", D_CBC_SEED
},
320 {"bf-cbc", D_CBC_BF
},
321 {"blowfish", D_CBC_BF
},
323 {"cast-cbc", D_CBC_CAST
},
324 {"cast", D_CBC_CAST
},
325 {"cast5", D_CBC_CAST
},
330 static double results
[ALGOR_NUM
][SIZE_NUM
];
332 enum { R_DSA_512
, R_DSA_1024
, R_DSA_2048
, DSA_NUM
};
333 static const OPT_PAIR dsa_choices
[DSA_NUM
] = {
334 {"dsa512", R_DSA_512
},
335 {"dsa1024", R_DSA_1024
},
336 {"dsa2048", R_DSA_2048
}
338 static double dsa_results
[DSA_NUM
][2]; /* 2 ops: sign then verify */
341 R_RSA_512
, R_RSA_1024
, R_RSA_2048
, R_RSA_3072
, R_RSA_4096
, R_RSA_7680
,
344 static const OPT_PAIR rsa_choices
[RSA_NUM
] = {
345 {"rsa512", R_RSA_512
},
346 {"rsa1024", R_RSA_1024
},
347 {"rsa2048", R_RSA_2048
},
348 {"rsa3072", R_RSA_3072
},
349 {"rsa4096", R_RSA_4096
},
350 {"rsa7680", R_RSA_7680
},
351 {"rsa15360", R_RSA_15360
}
354 static double rsa_results
[RSA_NUM
][2]; /* 2 ops: sign then verify */
356 #ifndef OPENSSL_NO_DH
358 R_FFDH_2048
, R_FFDH_3072
, R_FFDH_4096
, R_FFDH_6144
, R_FFDH_8192
, FFDH_NUM
361 static const OPT_PAIR ffdh_choices
[FFDH_NUM
] = {
362 {"ffdh2048", R_FFDH_2048
},
363 {"ffdh3072", R_FFDH_3072
},
364 {"ffdh4096", R_FFDH_4096
},
365 {"ffdh6144", R_FFDH_6144
},
366 {"ffdh8192", R_FFDH_8192
},
369 static double ffdh_results
[FFDH_NUM
][1]; /* 1 op: derivation */
370 #endif /* OPENSSL_NO_DH */
373 R_EC_P160
, R_EC_P192
, R_EC_P224
, R_EC_P256
, R_EC_P384
, R_EC_P521
,
374 #ifndef OPENSSL_NO_EC2M
375 R_EC_K163
, R_EC_K233
, R_EC_K283
, R_EC_K409
, R_EC_K571
,
376 R_EC_B163
, R_EC_B233
, R_EC_B283
, R_EC_B409
, R_EC_B571
,
378 R_EC_BRP256R1
, R_EC_BRP256T1
, R_EC_BRP384R1
, R_EC_BRP384T1
,
379 R_EC_BRP512R1
, R_EC_BRP512T1
, ECDSA_NUM
381 /* list of ecdsa curves */
382 static const OPT_PAIR ecdsa_choices
[ECDSA_NUM
] = {
383 {"ecdsap160", R_EC_P160
},
384 {"ecdsap192", R_EC_P192
},
385 {"ecdsap224", R_EC_P224
},
386 {"ecdsap256", R_EC_P256
},
387 {"ecdsap384", R_EC_P384
},
388 {"ecdsap521", R_EC_P521
},
389 #ifndef OPENSSL_NO_EC2M
390 {"ecdsak163", R_EC_K163
},
391 {"ecdsak233", R_EC_K233
},
392 {"ecdsak283", R_EC_K283
},
393 {"ecdsak409", R_EC_K409
},
394 {"ecdsak571", R_EC_K571
},
395 {"ecdsab163", R_EC_B163
},
396 {"ecdsab233", R_EC_B233
},
397 {"ecdsab283", R_EC_B283
},
398 {"ecdsab409", R_EC_B409
},
399 {"ecdsab571", R_EC_B571
},
401 {"ecdsabrp256r1", R_EC_BRP256R1
},
402 {"ecdsabrp256t1", R_EC_BRP256T1
},
403 {"ecdsabrp384r1", R_EC_BRP384R1
},
404 {"ecdsabrp384t1", R_EC_BRP384T1
},
405 {"ecdsabrp512r1", R_EC_BRP512R1
},
406 {"ecdsabrp512t1", R_EC_BRP512T1
}
408 enum { R_EC_X25519
= ECDSA_NUM
, R_EC_X448
, EC_NUM
};
409 /* list of ecdh curves, extension of |ecdsa_choices| list above */
410 static const OPT_PAIR ecdh_choices
[EC_NUM
] = {
411 {"ecdhp160", R_EC_P160
},
412 {"ecdhp192", R_EC_P192
},
413 {"ecdhp224", R_EC_P224
},
414 {"ecdhp256", R_EC_P256
},
415 {"ecdhp384", R_EC_P384
},
416 {"ecdhp521", R_EC_P521
},
417 #ifndef OPENSSL_NO_EC2M
418 {"ecdhk163", R_EC_K163
},
419 {"ecdhk233", R_EC_K233
},
420 {"ecdhk283", R_EC_K283
},
421 {"ecdhk409", R_EC_K409
},
422 {"ecdhk571", R_EC_K571
},
423 {"ecdhb163", R_EC_B163
},
424 {"ecdhb233", R_EC_B233
},
425 {"ecdhb283", R_EC_B283
},
426 {"ecdhb409", R_EC_B409
},
427 {"ecdhb571", R_EC_B571
},
429 {"ecdhbrp256r1", R_EC_BRP256R1
},
430 {"ecdhbrp256t1", R_EC_BRP256T1
},
431 {"ecdhbrp384r1", R_EC_BRP384R1
},
432 {"ecdhbrp384t1", R_EC_BRP384T1
},
433 {"ecdhbrp512r1", R_EC_BRP512R1
},
434 {"ecdhbrp512t1", R_EC_BRP512T1
},
435 {"ecdhx25519", R_EC_X25519
},
436 {"ecdhx448", R_EC_X448
}
439 static double ecdh_results
[EC_NUM
][1]; /* 1 op: derivation */
440 static double ecdsa_results
[ECDSA_NUM
][2]; /* 2 ops: sign then verify */
442 enum { R_EC_Ed25519
, R_EC_Ed448
, EdDSA_NUM
};
443 static const OPT_PAIR eddsa_choices
[EdDSA_NUM
] = {
444 {"ed25519", R_EC_Ed25519
},
445 {"ed448", R_EC_Ed448
}
448 static double eddsa_results
[EdDSA_NUM
][2]; /* 2 ops: sign then verify */
450 #ifndef OPENSSL_NO_SM2
451 enum { R_EC_CURVESM2
, SM2_NUM
};
452 static const OPT_PAIR sm2_choices
[SM2_NUM
] = {
453 {"curveSM2", R_EC_CURVESM2
}
455 # define SM2_ID "TLSv1.3+GM+Cipher+Suite"
456 # define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
457 static double sm2_results
[SM2_NUM
][2]; /* 2 ops: sign then verify */
458 #endif /* OPENSSL_NO_SM2 */
460 #define COND(unused_cond) (run && count < INT_MAX)
461 #define COUNT(d) (count)
463 typedef struct loopargs_st
{
464 ASYNC_JOB
*inprogress_job
;
465 ASYNC_WAIT_CTX
*wait_ctx
;
468 unsigned char *buf_malloc
;
469 unsigned char *buf2_malloc
;
473 EVP_PKEY_CTX
*rsa_sign_ctx
[RSA_NUM
];
474 EVP_PKEY_CTX
*rsa_verify_ctx
[RSA_NUM
];
475 EVP_PKEY_CTX
*dsa_sign_ctx
[DSA_NUM
];
476 EVP_PKEY_CTX
*dsa_verify_ctx
[DSA_NUM
];
477 EVP_PKEY_CTX
*ecdsa_sign_ctx
[ECDSA_NUM
];
478 EVP_PKEY_CTX
*ecdsa_verify_ctx
[ECDSA_NUM
];
479 EVP_PKEY_CTX
*ecdh_ctx
[EC_NUM
];
480 EVP_MD_CTX
*eddsa_ctx
[EdDSA_NUM
];
481 EVP_MD_CTX
*eddsa_ctx2
[EdDSA_NUM
];
482 #ifndef OPENSSL_NO_SM2
483 EVP_MD_CTX
*sm2_ctx
[SM2_NUM
];
484 EVP_MD_CTX
*sm2_vfy_ctx
[SM2_NUM
];
485 EVP_PKEY
*sm2_pkey
[SM2_NUM
];
487 unsigned char *secret_a
;
488 unsigned char *secret_b
;
489 size_t outlen
[EC_NUM
];
490 #ifndef OPENSSL_NO_DH
491 EVP_PKEY_CTX
*ffdh_ctx
[FFDH_NUM
];
492 unsigned char *secret_ff_a
;
493 unsigned char *secret_ff_b
;
498 static int run_benchmark(int async_jobs
, int (*loop_function
) (void *),
499 loopargs_t
* loopargs
);
501 static unsigned int testnum
;
503 /* Nb of iterations to do per algorithm and key-size */
504 static long c
[ALGOR_NUM
][SIZE_NUM
];
506 static char *evp_mac_mdname
= "md5";
507 static char *evp_hmac_name
= NULL
;
508 static const char *evp_md_name
= NULL
;
509 static char *evp_mac_ciphername
= "aes-128-cbc";
510 static char *evp_cmac_name
= NULL
;
512 static int have_md(const char *name
)
517 if (opt_md_silent(name
, &md
)) {
518 EVP_MD_CTX
*ctx
= EVP_MD_CTX_new();
520 if (ctx
!= NULL
&& EVP_DigestInit(ctx
, md
) > 0)
522 EVP_MD_CTX_free(ctx
);
528 static int have_cipher(const char *name
)
531 EVP_CIPHER
*cipher
= NULL
;
533 if (opt_cipher_silent(name
, &cipher
)) {
534 EVP_CIPHER_CTX
*ctx
= EVP_CIPHER_CTX_new();
537 && EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1) > 0)
539 EVP_CIPHER_CTX_free(ctx
);
540 EVP_CIPHER_free(cipher
);
545 static int EVP_Digest_loop(const char *mdname
, int algindex
, void *args
)
547 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
548 unsigned char *buf
= tempargs
->buf
;
549 unsigned char digest
[EVP_MAX_MD_SIZE
];
553 if (!opt_md_silent(mdname
, &md
))
555 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
556 if (!EVP_Digest(buf
, (size_t)lengths
[testnum
], digest
, NULL
, md
,
566 static int EVP_Digest_md_loop(void *args
)
568 return EVP_Digest_loop(evp_md_name
, D_EVP
, args
);
571 static int EVP_Digest_MD2_loop(void *args
)
573 return EVP_Digest_loop("md2", D_MD2
, args
);
576 static int EVP_Digest_MDC2_loop(void *args
)
578 return EVP_Digest_loop("mdc2", D_MDC2
, args
);
581 static int EVP_Digest_MD4_loop(void *args
)
583 return EVP_Digest_loop("md4", D_MD4
, args
);
586 static int MD5_loop(void *args
)
588 return EVP_Digest_loop("md5", D_MD5
, args
);
591 static int EVP_MAC_loop(int algindex
, void *args
)
593 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
594 unsigned char *buf
= tempargs
->buf
;
595 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
596 unsigned char mac
[EVP_MAX_MD_SIZE
];
599 for (count
= 0; COND(c
[algindex
][testnum
]); count
++) {
602 if (!EVP_MAC_init(mctx
, NULL
, 0, NULL
)
603 || !EVP_MAC_update(mctx
, buf
, lengths
[testnum
])
604 || !EVP_MAC_final(mctx
, mac
, &outl
, sizeof(mac
)))
610 static int HMAC_loop(void *args
)
612 return EVP_MAC_loop(D_HMAC
, args
);
615 static int CMAC_loop(void *args
)
617 return EVP_MAC_loop(D_EVP_CMAC
, args
);
620 static int SHA1_loop(void *args
)
622 return EVP_Digest_loop("sha1", D_SHA1
, args
);
625 static int SHA256_loop(void *args
)
627 return EVP_Digest_loop("sha256", D_SHA256
, args
);
630 static int SHA512_loop(void *args
)
632 return EVP_Digest_loop("sha512", D_SHA512
, args
);
635 static int WHIRLPOOL_loop(void *args
)
637 return EVP_Digest_loop("whirlpool", D_WHIRLPOOL
, args
);
640 static int EVP_Digest_RMD160_loop(void *args
)
642 return EVP_Digest_loop("ripemd160", D_RMD160
, args
);
647 static int EVP_Cipher_loop(void *args
)
649 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
650 unsigned char *buf
= tempargs
->buf
;
653 if (tempargs
->ctx
== NULL
)
655 for (count
= 0; COND(c
[algindex
][testnum
]); count
++)
656 if (EVP_Cipher(tempargs
->ctx
, buf
, buf
, (size_t)lengths
[testnum
]) <= 0)
661 static int GHASH_loop(void *args
)
663 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
664 unsigned char *buf
= tempargs
->buf
;
665 EVP_MAC_CTX
*mctx
= tempargs
->mctx
;
668 /* just do the update in the loop to be comparable with 1.1.1 */
669 for (count
= 0; COND(c
[D_GHASH
][testnum
]); count
++) {
670 if (!EVP_MAC_update(mctx
, buf
, lengths
[testnum
]))
676 #define MAX_BLOCK_SIZE 128
678 static unsigned char iv
[2 * MAX_BLOCK_SIZE
/ 8];
680 static EVP_CIPHER_CTX
*init_evp_cipher_ctx(const char *ciphername
,
681 const unsigned char *key
,
684 EVP_CIPHER_CTX
*ctx
= NULL
;
685 EVP_CIPHER
*cipher
= NULL
;
687 if (!opt_cipher_silent(ciphername
, &cipher
))
690 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
693 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, NULL
, 1)) {
694 EVP_CIPHER_CTX_free(ctx
);
699 if (EVP_CIPHER_CTX_set_key_length(ctx
, keylen
) <= 0) {
700 EVP_CIPHER_CTX_free(ctx
);
705 if (!EVP_CipherInit_ex(ctx
, NULL
, NULL
, key
, iv
, 1)) {
706 EVP_CIPHER_CTX_free(ctx
);
712 EVP_CIPHER_free(cipher
);
716 static int RAND_bytes_loop(void *args
)
718 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
719 unsigned char *buf
= tempargs
->buf
;
722 for (count
= 0; COND(c
[D_RAND
][testnum
]); count
++)
723 RAND_bytes(buf
, lengths
[testnum
]);
727 static int decrypt
= 0;
728 static int EVP_Update_loop(void *args
)
730 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
731 unsigned char *buf
= tempargs
->buf
;
732 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
736 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
737 rc
= EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
739 /* reset iv in case of counter overflow */
740 (void)EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
744 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
745 rc
= EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
747 /* reset iv in case of counter overflow */
748 (void)EVP_CipherInit_ex(ctx
, NULL
, NULL
, NULL
, iv
, -1);
753 EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
755 EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
760 * CCM does not support streaming. For the purpose of performance measurement,
761 * each message is encrypted using the same (key,iv)-pair. Do not use this
762 * code in your application.
764 static int EVP_Update_loop_ccm(void *args
)
766 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
767 unsigned char *buf
= tempargs
->buf
;
768 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
770 unsigned char tag
[12];
773 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
774 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
, sizeof(tag
),
777 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
778 /* counter is reset on every update */
779 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
782 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
783 /* restore iv length field */
784 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, NULL
, lengths
[testnum
]);
785 /* counter is reset on every update */
786 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
790 (void)EVP_DecryptFinal_ex(ctx
, buf
, &outl
);
792 (void)EVP_EncryptFinal_ex(ctx
, buf
, &outl
);
797 * To make AEAD benchmarking more relevant perform TLS-like operations,
798 * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as
799 * payload length is not actually limited by 16KB...
801 static int EVP_Update_loop_aead(void *args
)
803 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
804 unsigned char *buf
= tempargs
->buf
;
805 EVP_CIPHER_CTX
*ctx
= tempargs
->ctx
;
807 unsigned char aad
[13] = { 0xcc };
808 unsigned char faketag
[16] = { 0xcc };
811 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
812 (void)EVP_DecryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
813 (void)EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_TAG
,
814 sizeof(faketag
), faketag
);
815 (void)EVP_DecryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
816 (void)EVP_DecryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
817 (void)EVP_DecryptFinal_ex(ctx
, buf
+ outl
, &outl
);
820 for (count
= 0; COND(c
[D_EVP
][testnum
]); count
++) {
821 (void)EVP_EncryptInit_ex(ctx
, NULL
, NULL
, NULL
, iv
);
822 (void)EVP_EncryptUpdate(ctx
, NULL
, &outl
, aad
, sizeof(aad
));
823 (void)EVP_EncryptUpdate(ctx
, buf
, &outl
, buf
, lengths
[testnum
]);
824 (void)EVP_EncryptFinal_ex(ctx
, buf
+ outl
, &outl
);
830 static long rsa_c
[RSA_NUM
][2]; /* # RSA iteration test */
832 static int RSA_sign_loop(void *args
)
834 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
835 unsigned char *buf
= tempargs
->buf
;
836 unsigned char *buf2
= tempargs
->buf2
;
837 size_t *rsa_num
= &tempargs
->sigsize
;
838 EVP_PKEY_CTX
**rsa_sign_ctx
= tempargs
->rsa_sign_ctx
;
841 for (count
= 0; COND(rsa_c
[testnum
][0]); count
++) {
842 *rsa_num
= tempargs
->buflen
;
843 ret
= EVP_PKEY_sign(rsa_sign_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
845 BIO_printf(bio_err
, "RSA sign failure\n");
846 ERR_print_errors(bio_err
);
854 static int RSA_verify_loop(void *args
)
856 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
857 unsigned char *buf
= tempargs
->buf
;
858 unsigned char *buf2
= tempargs
->buf2
;
859 size_t rsa_num
= tempargs
->sigsize
;
860 EVP_PKEY_CTX
**rsa_verify_ctx
= tempargs
->rsa_verify_ctx
;
863 for (count
= 0; COND(rsa_c
[testnum
][1]); count
++) {
864 ret
= EVP_PKEY_verify(rsa_verify_ctx
[testnum
], buf2
, rsa_num
, buf
, 36);
866 BIO_printf(bio_err
, "RSA verify failure\n");
867 ERR_print_errors(bio_err
);
875 #ifndef OPENSSL_NO_DH
876 static long ffdh_c
[FFDH_NUM
][1];
878 static int FFDH_derive_key_loop(void *args
)
880 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
881 EVP_PKEY_CTX
*ffdh_ctx
= tempargs
->ffdh_ctx
[testnum
];
882 unsigned char *derived_secret
= tempargs
->secret_ff_a
;
883 size_t outlen
= MAX_FFDH_SIZE
;
886 for (count
= 0; COND(ffdh_c
[testnum
][0]); count
++)
887 EVP_PKEY_derive(ffdh_ctx
, derived_secret
, &outlen
);
890 #endif /* OPENSSL_NO_DH */
892 static long dsa_c
[DSA_NUM
][2];
893 static int DSA_sign_loop(void *args
)
895 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
896 unsigned char *buf
= tempargs
->buf
;
897 unsigned char *buf2
= tempargs
->buf2
;
898 size_t *dsa_num
= &tempargs
->sigsize
;
899 EVP_PKEY_CTX
**dsa_sign_ctx
= tempargs
->dsa_sign_ctx
;
902 for (count
= 0; COND(dsa_c
[testnum
][0]); count
++) {
903 *dsa_num
= tempargs
->buflen
;
904 ret
= EVP_PKEY_sign(dsa_sign_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
906 BIO_printf(bio_err
, "DSA sign failure\n");
907 ERR_print_errors(bio_err
);
915 static int DSA_verify_loop(void *args
)
917 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
918 unsigned char *buf
= tempargs
->buf
;
919 unsigned char *buf2
= tempargs
->buf2
;
920 size_t dsa_num
= tempargs
->sigsize
;
921 EVP_PKEY_CTX
**dsa_verify_ctx
= tempargs
->dsa_verify_ctx
;
924 for (count
= 0; COND(dsa_c
[testnum
][1]); count
++) {
925 ret
= EVP_PKEY_verify(dsa_verify_ctx
[testnum
], buf2
, dsa_num
, buf
, 20);
927 BIO_printf(bio_err
, "DSA verify failure\n");
928 ERR_print_errors(bio_err
);
936 static long ecdsa_c
[ECDSA_NUM
][2];
937 static int ECDSA_sign_loop(void *args
)
939 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
940 unsigned char *buf
= tempargs
->buf
;
941 unsigned char *buf2
= tempargs
->buf2
;
942 size_t *ecdsa_num
= &tempargs
->sigsize
;
943 EVP_PKEY_CTX
**ecdsa_sign_ctx
= tempargs
->ecdsa_sign_ctx
;
946 for (count
= 0; COND(ecdsa_c
[testnum
][0]); count
++) {
947 *ecdsa_num
= tempargs
->buflen
;
948 ret
= EVP_PKEY_sign(ecdsa_sign_ctx
[testnum
], buf2
, ecdsa_num
, buf
, 20);
950 BIO_printf(bio_err
, "ECDSA sign failure\n");
951 ERR_print_errors(bio_err
);
959 static int ECDSA_verify_loop(void *args
)
961 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
962 unsigned char *buf
= tempargs
->buf
;
963 unsigned char *buf2
= tempargs
->buf2
;
964 size_t ecdsa_num
= tempargs
->sigsize
;
965 EVP_PKEY_CTX
**ecdsa_verify_ctx
= tempargs
->ecdsa_verify_ctx
;
968 for (count
= 0; COND(ecdsa_c
[testnum
][1]); count
++) {
969 ret
= EVP_PKEY_verify(ecdsa_verify_ctx
[testnum
], buf2
, ecdsa_num
,
972 BIO_printf(bio_err
, "ECDSA verify failure\n");
973 ERR_print_errors(bio_err
);
981 /* ******************************************************************** */
982 static long ecdh_c
[EC_NUM
][1];
984 static int ECDH_EVP_derive_key_loop(void *args
)
986 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
987 EVP_PKEY_CTX
*ctx
= tempargs
->ecdh_ctx
[testnum
];
988 unsigned char *derived_secret
= tempargs
->secret_a
;
990 size_t *outlen
= &(tempargs
->outlen
[testnum
]);
992 for (count
= 0; COND(ecdh_c
[testnum
][0]); count
++)
993 EVP_PKEY_derive(ctx
, derived_secret
, outlen
);
998 static long eddsa_c
[EdDSA_NUM
][2];
999 static int EdDSA_sign_loop(void *args
)
1001 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1002 unsigned char *buf
= tempargs
->buf
;
1003 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx
;
1004 unsigned char *eddsasig
= tempargs
->buf2
;
1005 size_t *eddsasigsize
= &tempargs
->sigsize
;
1008 for (count
= 0; COND(eddsa_c
[testnum
][0]); count
++) {
1009 ret
= EVP_DigestSign(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1011 BIO_printf(bio_err
, "EdDSA sign failure\n");
1012 ERR_print_errors(bio_err
);
1020 static int EdDSA_verify_loop(void *args
)
1022 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1023 unsigned char *buf
= tempargs
->buf
;
1024 EVP_MD_CTX
**edctx
= tempargs
->eddsa_ctx2
;
1025 unsigned char *eddsasig
= tempargs
->buf2
;
1026 size_t eddsasigsize
= tempargs
->sigsize
;
1029 for (count
= 0; COND(eddsa_c
[testnum
][1]); count
++) {
1030 ret
= EVP_DigestVerify(edctx
[testnum
], eddsasig
, eddsasigsize
, buf
, 20);
1032 BIO_printf(bio_err
, "EdDSA verify failure\n");
1033 ERR_print_errors(bio_err
);
1041 #ifndef OPENSSL_NO_SM2
1042 static long sm2_c
[SM2_NUM
][2];
1043 static int SM2_sign_loop(void *args
)
1045 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1046 unsigned char *buf
= tempargs
->buf
;
1047 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_ctx
;
1048 unsigned char *sm2sig
= tempargs
->buf2
;
1051 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1052 const size_t max_size
= EVP_PKEY_get_size(sm2_pkey
[testnum
]);
1054 for (count
= 0; COND(sm2_c
[testnum
][0]); count
++) {
1055 sm2sigsize
= max_size
;
1057 if (!EVP_DigestSignInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1058 NULL
, sm2_pkey
[testnum
])) {
1059 BIO_printf(bio_err
, "SM2 init sign failure\n");
1060 ERR_print_errors(bio_err
);
1064 ret
= EVP_DigestSign(sm2ctx
[testnum
], sm2sig
, &sm2sigsize
,
1067 BIO_printf(bio_err
, "SM2 sign failure\n");
1068 ERR_print_errors(bio_err
);
1072 /* update the latest returned size and always use the fixed buffer size */
1073 tempargs
->sigsize
= sm2sigsize
;
1079 static int SM2_verify_loop(void *args
)
1081 loopargs_t
*tempargs
= *(loopargs_t
**) args
;
1082 unsigned char *buf
= tempargs
->buf
;
1083 EVP_MD_CTX
**sm2ctx
= tempargs
->sm2_vfy_ctx
;
1084 unsigned char *sm2sig
= tempargs
->buf2
;
1085 size_t sm2sigsize
= tempargs
->sigsize
;
1087 EVP_PKEY
**sm2_pkey
= tempargs
->sm2_pkey
;
1089 for (count
= 0; COND(sm2_c
[testnum
][1]); count
++) {
1090 if (!EVP_DigestVerifyInit(sm2ctx
[testnum
], NULL
, EVP_sm3(),
1091 NULL
, sm2_pkey
[testnum
])) {
1092 BIO_printf(bio_err
, "SM2 verify init failure\n");
1093 ERR_print_errors(bio_err
);
1097 ret
= EVP_DigestVerify(sm2ctx
[testnum
], sm2sig
, sm2sigsize
,
1100 BIO_printf(bio_err
, "SM2 verify failure\n");
1101 ERR_print_errors(bio_err
);
1108 #endif /* OPENSSL_NO_SM2 */
1110 static int run_benchmark(int async_jobs
,
1111 int (*loop_function
) (void *), loopargs_t
* loopargs
)
1113 int job_op_count
= 0;
1114 int total_op_count
= 0;
1115 int num_inprogress
= 0;
1116 int error
= 0, i
= 0, ret
= 0;
1117 OSSL_ASYNC_FD job_fd
= 0;
1118 size_t num_job_fds
= 0;
1120 if (async_jobs
== 0) {
1121 return loop_function((void *)&loopargs
);
1124 for (i
= 0; i
< async_jobs
&& !error
; i
++) {
1125 loopargs_t
*looparg_item
= loopargs
+ i
;
1127 /* Copy pointer content (looparg_t item address) into async context */
1128 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
, loopargs
[i
].wait_ctx
,
1129 &job_op_count
, loop_function
,
1130 (void *)&looparg_item
, sizeof(looparg_item
));
1136 if (job_op_count
== -1) {
1139 total_op_count
+= job_op_count
;
1144 BIO_printf(bio_err
, "Failure in the job\n");
1145 ERR_print_errors(bio_err
);
1151 while (num_inprogress
> 0) {
1152 #if defined(OPENSSL_SYS_WINDOWS)
1154 #elif defined(OPENSSL_SYS_UNIX)
1155 int select_result
= 0;
1156 OSSL_ASYNC_FD max_fd
= 0;
1159 FD_ZERO(&waitfdset
);
1161 for (i
= 0; i
< async_jobs
&& num_inprogress
> 0; i
++) {
1162 if (loopargs
[i
].inprogress_job
== NULL
)
1165 if (!ASYNC_WAIT_CTX_get_all_fds
1166 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1167 || num_job_fds
> 1) {
1168 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1169 ERR_print_errors(bio_err
);
1173 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1175 FD_SET(job_fd
, &waitfdset
);
1176 if (job_fd
> max_fd
)
1180 if (max_fd
>= (OSSL_ASYNC_FD
)FD_SETSIZE
) {
1182 "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
1183 "Decrease the value of async_jobs\n",
1184 max_fd
, FD_SETSIZE
);
1185 ERR_print_errors(bio_err
);
1190 select_result
= select(max_fd
+ 1, &waitfdset
, NULL
, NULL
, NULL
);
1191 if (select_result
== -1 && errno
== EINTR
)
1194 if (select_result
== -1) {
1195 BIO_printf(bio_err
, "Failure in the select\n");
1196 ERR_print_errors(bio_err
);
1201 if (select_result
== 0)
1205 for (i
= 0; i
< async_jobs
; i
++) {
1206 if (loopargs
[i
].inprogress_job
== NULL
)
1209 if (!ASYNC_WAIT_CTX_get_all_fds
1210 (loopargs
[i
].wait_ctx
, NULL
, &num_job_fds
)
1211 || num_job_fds
> 1) {
1212 BIO_printf(bio_err
, "Too many fds in ASYNC_WAIT_CTX\n");
1213 ERR_print_errors(bio_err
);
1217 ASYNC_WAIT_CTX_get_all_fds(loopargs
[i
].wait_ctx
, &job_fd
,
1220 #if defined(OPENSSL_SYS_UNIX)
1221 if (num_job_fds
== 1 && !FD_ISSET(job_fd
, &waitfdset
))
1223 #elif defined(OPENSSL_SYS_WINDOWS)
1224 if (num_job_fds
== 1
1225 && !PeekNamedPipe(job_fd
, NULL
, 0, NULL
, &avail
, NULL
)
1230 ret
= ASYNC_start_job(&loopargs
[i
].inprogress_job
,
1231 loopargs
[i
].wait_ctx
, &job_op_count
,
1232 loop_function
, (void *)(loopargs
+ i
),
1233 sizeof(loopargs_t
));
1238 if (job_op_count
== -1) {
1241 total_op_count
+= job_op_count
;
1244 loopargs
[i
].inprogress_job
= NULL
;
1249 loopargs
[i
].inprogress_job
= NULL
;
1250 BIO_printf(bio_err
, "Failure in the job\n");
1251 ERR_print_errors(bio_err
);
1258 return error
? -1 : total_op_count
;
1261 typedef struct ec_curve_st
{
1265 size_t sigsize
; /* only used for EdDSA curves */
1268 static EVP_PKEY
*get_ecdsa(const EC_CURVE
*curve
)
1270 EVP_PKEY_CTX
*kctx
= NULL
;
1271 EVP_PKEY
*key
= NULL
;
1273 /* Ensure that the error queue is empty */
1274 if (ERR_peek_error()) {
1276 "WARNING: the error queue contains previous unhandled errors.\n");
1277 ERR_print_errors(bio_err
);
1281 * Let's try to create a ctx directly from the NID: this works for
1282 * curves like Curve25519 that are not implemented through the low
1283 * level EC interface.
1284 * If this fails we try creating a EVP_PKEY_EC generic param ctx,
1285 * then we set the curve by NID before deriving the actual keygen
1286 * ctx for that specific curve.
1288 kctx
= EVP_PKEY_CTX_new_id(curve
->nid
, NULL
);
1290 EVP_PKEY_CTX
*pctx
= NULL
;
1291 EVP_PKEY
*params
= NULL
;
1293 * If we reach this code EVP_PKEY_CTX_new_id() failed and a
1294 * "int_ctx_new:unsupported algorithm" error was added to the
1296 * We remove it from the error queue as we are handling it.
1298 unsigned long error
= ERR_peek_error();
1300 if (error
== ERR_peek_last_error() /* oldest and latest errors match */
1301 /* check that the error origin matches */
1302 && ERR_GET_LIB(error
) == ERR_LIB_EVP
1303 && (ERR_GET_REASON(error
) == EVP_R_UNSUPPORTED_ALGORITHM
1304 || ERR_GET_REASON(error
) == ERR_R_UNSUPPORTED
))
1305 ERR_get_error(); /* pop error from queue */
1306 if (ERR_peek_error()) {
1308 "Unhandled error in the error queue during EC key setup.\n");
1309 ERR_print_errors(bio_err
);
1313 /* Create the context for parameter generation */
1314 if ((pctx
= EVP_PKEY_CTX_new_from_name(NULL
, "EC", NULL
)) == NULL
1315 || EVP_PKEY_paramgen_init(pctx
) <= 0
1316 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
1318 || EVP_PKEY_paramgen(pctx
, ¶ms
) <= 0) {
1319 BIO_printf(bio_err
, "EC params init failure.\n");
1320 ERR_print_errors(bio_err
);
1321 EVP_PKEY_CTX_free(pctx
);
1324 EVP_PKEY_CTX_free(pctx
);
1326 /* Create the context for the key generation */
1327 kctx
= EVP_PKEY_CTX_new(params
, NULL
);
1328 EVP_PKEY_free(params
);
1331 || EVP_PKEY_keygen_init(kctx
) <= 0
1332 || EVP_PKEY_keygen(kctx
, &key
) <= 0) {
1333 BIO_printf(bio_err
, "EC key generation failure.\n");
1334 ERR_print_errors(bio_err
);
1337 EVP_PKEY_CTX_free(kctx
);
1341 #define stop_it(do_it, test_num)\
1342 memset(do_it + test_num, 0, OSSL_NELEM(do_it) - test_num);
1344 int speed_main(int argc
, char **argv
)
1348 loopargs_t
*loopargs
= NULL
;
1350 const char *engine_id
= NULL
;
1351 EVP_CIPHER
*evp_cipher
= NULL
;
1352 EVP_MAC
*mac
= NULL
;
1355 int async_init
= 0, multiblock
= 0, pr_header
= 0;
1356 uint8_t doit
[ALGOR_NUM
] = { 0 };
1357 int ret
= 1, misalign
= 0, lengths_single
= 0, aead
= 0;
1359 unsigned int size_num
= SIZE_NUM
;
1360 unsigned int i
, k
, loopargs_len
= 0, async_jobs
= 0;
1364 EVP_PKEY_CTX
*genctx
= NULL
;
1369 openssl_speed_sec_t seconds
= { SECONDS
, RSA_SECONDS
, DSA_SECONDS
,
1370 ECDSA_SECONDS
, ECDH_SECONDS
,
1371 EdDSA_SECONDS
, SM2_SECONDS
,
1374 static const unsigned char key32
[32] = {
1375 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
1376 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
1377 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
1378 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
1380 static const unsigned char deskey
[] = {
1381 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */
1382 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */
1383 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */
1385 static const struct {
1386 const unsigned char *data
;
1387 unsigned int length
;
1390 { test512
, sizeof(test512
), 512 },
1391 { test1024
, sizeof(test1024
), 1024 },
1392 { test2048
, sizeof(test2048
), 2048 },
1393 { test3072
, sizeof(test3072
), 3072 },
1394 { test4096
, sizeof(test4096
), 4096 },
1395 { test7680
, sizeof(test7680
), 7680 },
1396 { test15360
, sizeof(test15360
), 15360 }
1398 uint8_t rsa_doit
[RSA_NUM
] = { 0 };
1399 int primes
= RSA_DEFAULT_PRIME_NUM
;
1400 #ifndef OPENSSL_NO_DH
1401 typedef struct ffdh_params_st
{
1407 static const FFDH_PARAMS ffdh_params
[FFDH_NUM
] = {
1408 {"ffdh2048", NID_ffdhe2048
, 2048},
1409 {"ffdh3072", NID_ffdhe3072
, 3072},
1410 {"ffdh4096", NID_ffdhe4096
, 4096},
1411 {"ffdh6144", NID_ffdhe6144
, 6144},
1412 {"ffdh8192", NID_ffdhe8192
, 8192}
1414 uint8_t ffdh_doit
[FFDH_NUM
] = { 0 };
1416 #endif /* OPENSSL_NO_DH */
1417 static const unsigned int dsa_bits
[DSA_NUM
] = { 512, 1024, 2048 };
1418 uint8_t dsa_doit
[DSA_NUM
] = { 0 };
1420 * We only test over the following curves as they are representative, To
1421 * add tests over more curves, simply add the curve NID and curve name to
1422 * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
1423 * lists accordingly.
1425 static const EC_CURVE ec_curves
[EC_NUM
] = {
1427 {"secp160r1", NID_secp160r1
, 160},
1428 {"nistp192", NID_X9_62_prime192v1
, 192},
1429 {"nistp224", NID_secp224r1
, 224},
1430 {"nistp256", NID_X9_62_prime256v1
, 256},
1431 {"nistp384", NID_secp384r1
, 384},
1432 {"nistp521", NID_secp521r1
, 521},
1433 #ifndef OPENSSL_NO_EC2M
1435 {"nistk163", NID_sect163k1
, 163},
1436 {"nistk233", NID_sect233k1
, 233},
1437 {"nistk283", NID_sect283k1
, 283},
1438 {"nistk409", NID_sect409k1
, 409},
1439 {"nistk571", NID_sect571k1
, 571},
1440 {"nistb163", NID_sect163r2
, 163},
1441 {"nistb233", NID_sect233r1
, 233},
1442 {"nistb283", NID_sect283r1
, 283},
1443 {"nistb409", NID_sect409r1
, 409},
1444 {"nistb571", NID_sect571r1
, 571},
1446 {"brainpoolP256r1", NID_brainpoolP256r1
, 256},
1447 {"brainpoolP256t1", NID_brainpoolP256t1
, 256},
1448 {"brainpoolP384r1", NID_brainpoolP384r1
, 384},
1449 {"brainpoolP384t1", NID_brainpoolP384t1
, 384},
1450 {"brainpoolP512r1", NID_brainpoolP512r1
, 512},
1451 {"brainpoolP512t1", NID_brainpoolP512t1
, 512},
1452 /* Other and ECDH only ones */
1453 {"X25519", NID_X25519
, 253},
1454 {"X448", NID_X448
, 448}
1456 static const EC_CURVE ed_curves
[EdDSA_NUM
] = {
1458 {"Ed25519", NID_ED25519
, 253, 64},
1459 {"Ed448", NID_ED448
, 456, 114}
1461 #ifndef OPENSSL_NO_SM2
1462 static const EC_CURVE sm2_curves
[SM2_NUM
] = {
1464 {"CurveSM2", NID_sm2
, 256}
1466 uint8_t sm2_doit
[SM2_NUM
] = { 0 };
1468 uint8_t ecdsa_doit
[ECDSA_NUM
] = { 0 };
1469 uint8_t ecdh_doit
[EC_NUM
] = { 0 };
1470 uint8_t eddsa_doit
[EdDSA_NUM
] = { 0 };
1472 /* checks declared curves against choices list. */
1473 OPENSSL_assert(ed_curves
[EdDSA_NUM
- 1].nid
== NID_ED448
);
1474 OPENSSL_assert(strcmp(eddsa_choices
[EdDSA_NUM
- 1].name
, "ed448") == 0);
1476 OPENSSL_assert(ec_curves
[EC_NUM
- 1].nid
== NID_X448
);
1477 OPENSSL_assert(strcmp(ecdh_choices
[EC_NUM
- 1].name
, "ecdhx448") == 0);
1479 OPENSSL_assert(ec_curves
[ECDSA_NUM
- 1].nid
== NID_brainpoolP512t1
);
1480 OPENSSL_assert(strcmp(ecdsa_choices
[ECDSA_NUM
- 1].name
, "ecdsabrp512t1") == 0);
1482 #ifndef OPENSSL_NO_SM2
1483 OPENSSL_assert(sm2_curves
[SM2_NUM
- 1].nid
== NID_sm2
);
1484 OPENSSL_assert(strcmp(sm2_choices
[SM2_NUM
- 1].name
, "curveSM2") == 0);
1487 prog
= opt_init(argc
, argv
, speed_options
);
1488 while ((o
= opt_next()) != OPT_EOF
) {
1493 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
1496 opt_help(speed_options
);
1504 BIO_printf(bio_err
, "%s: -evp option cannot be used more than once\n", prog
);
1508 if (!opt_cipher_silent(opt_arg(), &evp_cipher
)) {
1509 if (have_md(opt_arg()))
1510 evp_md_name
= opt_arg();
1512 if (evp_cipher
== NULL
&& evp_md_name
== NULL
) {
1513 ERR_clear_last_mark();
1515 "%s: %s is an unknown cipher or digest\n",
1523 if (!have_md(opt_arg())) {
1524 BIO_printf(bio_err
, "%s: %s is an unknown digest\n",
1528 evp_mac_mdname
= opt_arg();
1532 if (!have_cipher(opt_arg())) {
1533 BIO_printf(bio_err
, "%s: %s is an unknown cipher\n",
1537 evp_mac_ciphername
= opt_arg();
1538 doit
[D_EVP_CMAC
] = 1;
1545 * In a forked execution, an engine might need to be
1546 * initialised by each child process, not by the parent.
1547 * So store the name here and run setup_engine() later on.
1549 engine_id
= opt_arg();
1553 multi
= opt_int_arg();
1554 if ((size_t)multi
>= SIZE_MAX
/ sizeof(int)) {
1555 BIO_printf(bio_err
, "%s: multi argument too large\n", prog
);
1561 #ifndef OPENSSL_NO_ASYNC
1562 async_jobs
= opt_int_arg();
1563 if (!ASYNC_is_capable()) {
1565 "%s: async_jobs specified but async not supported\n",
1569 if (async_jobs
> 99999) {
1570 BIO_printf(bio_err
, "%s: too many async_jobs\n", prog
);
1576 misalign
= opt_int_arg();
1577 if (misalign
> MISALIGN
) {
1579 "%s: Maximum offset is %d\n", prog
, MISALIGN
);
1588 #ifdef OPENSSL_NO_MULTIBLOCK
1590 "%s: -mb specified but multi-block support is disabled\n",
1599 case OPT_PROV_CASES
:
1600 if (!opt_provider(o
))
1604 conf
= app_load_config_modules(opt_arg());
1609 primes
= opt_int_arg();
1612 seconds
.sym
= seconds
.rsa
= seconds
.dsa
= seconds
.ecdsa
1613 = seconds
.ecdh
= seconds
.eddsa
1614 = seconds
.sm2
= seconds
.ffdh
= opt_int_arg();
1617 lengths_single
= opt_int_arg();
1618 lengths
= &lengths_single
;
1627 /* Remaining arguments are algorithms. */
1628 argc
= opt_num_rest();
1631 if (!app_RAND_load())
1634 for (; *argv
; argv
++) {
1635 const char *algo
= *argv
;
1637 if (opt_found(algo
, doit_choices
, &i
)) {
1641 if (strcmp(algo
, "des") == 0) {
1642 doit
[D_CBC_DES
] = doit
[D_EDE3_DES
] = 1;
1645 if (strcmp(algo
, "sha") == 0) {
1646 doit
[D_SHA1
] = doit
[D_SHA256
] = doit
[D_SHA512
] = 1;
1649 #ifndef OPENSSL_NO_DEPRECATED_3_0
1650 if (strcmp(algo
, "openssl") == 0) /* just for compatibility */
1653 if (HAS_PREFIX(algo
, "rsa")) {
1654 if (algo
[sizeof("rsa") - 1] == '\0') {
1655 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1658 if (opt_found(algo
, rsa_choices
, &i
)) {
1663 #ifndef OPENSSL_NO_DH
1664 if (HAS_PREFIX(algo
, "ffdh")) {
1665 if (algo
[sizeof("ffdh") - 1] == '\0') {
1666 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1669 if (opt_found(algo
, ffdh_choices
, &i
)) {
1675 if (HAS_PREFIX(algo
, "dsa")) {
1676 if (algo
[sizeof("dsa") - 1] == '\0') {
1677 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1680 if (opt_found(algo
, dsa_choices
, &i
)) {
1685 if (strcmp(algo
, "aes") == 0) {
1686 doit
[D_CBC_128_AES
] = doit
[D_CBC_192_AES
] = doit
[D_CBC_256_AES
] = 1;
1689 if (strcmp(algo
, "camellia") == 0) {
1690 doit
[D_CBC_128_CML
] = doit
[D_CBC_192_CML
] = doit
[D_CBC_256_CML
] = 1;
1693 if (HAS_PREFIX(algo
, "ecdsa")) {
1694 if (algo
[sizeof("ecdsa") - 1] == '\0') {
1695 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1698 if (opt_found(algo
, ecdsa_choices
, &i
)) {
1703 if (HAS_PREFIX(algo
, "ecdh")) {
1704 if (algo
[sizeof("ecdh") - 1] == '\0') {
1705 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1708 if (opt_found(algo
, ecdh_choices
, &i
)) {
1713 if (strcmp(algo
, "eddsa") == 0) {
1714 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1717 if (opt_found(algo
, eddsa_choices
, &i
)) {
1721 #ifndef OPENSSL_NO_SM2
1722 if (strcmp(algo
, "sm2") == 0) {
1723 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1726 if (opt_found(algo
, sm2_choices
, &i
)) {
1731 BIO_printf(bio_err
, "%s: Unknown algorithm %s\n", prog
, algo
);
1737 if (evp_cipher
== NULL
) {
1738 BIO_printf(bio_err
, "-aead can be used only with an AEAD cipher\n");
1740 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1741 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
1742 BIO_printf(bio_err
, "%s is not an AEAD cipher\n",
1743 EVP_CIPHER_get0_name(evp_cipher
));
1748 if (evp_cipher
== NULL
) {
1749 BIO_printf(bio_err
, "-mb can be used only with a multi-block"
1750 " capable cipher\n");
1752 } else if (!(EVP_CIPHER_get_flags(evp_cipher
) &
1753 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
1754 BIO_printf(bio_err
, "%s is not a multi-block capable\n",
1755 EVP_CIPHER_get0_name(evp_cipher
));
1757 } else if (async_jobs
> 0) {
1758 BIO_printf(bio_err
, "Async mode is not supported with -mb");
1763 /* Initialize the job pool if async mode is enabled */
1764 if (async_jobs
> 0) {
1765 async_init
= ASYNC_init_thread(async_jobs
, async_jobs
);
1767 BIO_printf(bio_err
, "Error creating the ASYNC job pool\n");
1772 loopargs_len
= (async_jobs
== 0 ? 1 : async_jobs
);
1774 app_malloc(loopargs_len
* sizeof(loopargs_t
), "array of loopargs");
1775 memset(loopargs
, 0, loopargs_len
* sizeof(loopargs_t
));
1777 for (i
= 0; i
< loopargs_len
; i
++) {
1778 if (async_jobs
> 0) {
1779 loopargs
[i
].wait_ctx
= ASYNC_WAIT_CTX_new();
1780 if (loopargs
[i
].wait_ctx
== NULL
) {
1781 BIO_printf(bio_err
, "Error creating the ASYNC_WAIT_CTX\n");
1786 buflen
= lengths
[size_num
- 1];
1787 if (buflen
< 36) /* size of random vector in RSA benchmark */
1789 if (INT_MAX
- (MAX_MISALIGNMENT
+ 1) < buflen
) {
1790 BIO_printf(bio_err
, "Error: buffer size too large\n");
1793 buflen
+= MAX_MISALIGNMENT
+ 1;
1794 loopargs
[i
].buf_malloc
= app_malloc(buflen
, "input buffer");
1795 loopargs
[i
].buf2_malloc
= app_malloc(buflen
, "input buffer");
1796 memset(loopargs
[i
].buf_malloc
, 0, buflen
);
1797 memset(loopargs
[i
].buf2_malloc
, 0, buflen
);
1799 /* Align the start of buffers on a 64 byte boundary */
1800 loopargs
[i
].buf
= loopargs
[i
].buf_malloc
+ misalign
;
1801 loopargs
[i
].buf2
= loopargs
[i
].buf2_malloc
+ misalign
;
1802 loopargs
[i
].buflen
= buflen
- misalign
;
1803 loopargs
[i
].sigsize
= buflen
- misalign
;
1804 loopargs
[i
].secret_a
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret a");
1805 loopargs
[i
].secret_b
= app_malloc(MAX_ECDH_SIZE
, "ECDH secret b");
1806 #ifndef OPENSSL_NO_DH
1807 loopargs
[i
].secret_ff_a
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret a");
1808 loopargs
[i
].secret_ff_b
= app_malloc(MAX_FFDH_SIZE
, "FFDH secret b");
1813 if (multi
&& do_multi(multi
, size_num
))
1817 /* Initialize the engine after the fork */
1818 e
= setup_engine(engine_id
, 0);
1820 /* No parameters; turn on everything. */
1821 if (argc
== 0 && !doit
[D_EVP
] && !doit
[D_HMAC
] && !doit
[D_EVP_CMAC
]) {
1822 memset(doit
, 1, sizeof(doit
));
1823 doit
[D_EVP
] = doit
[D_EVP_CMAC
] = 0;
1825 for (i
= D_MD2
; i
<= D_WHIRLPOOL
; i
++) {
1826 if (!have_md(names
[i
]))
1829 for (i
= D_CBC_DES
; i
<= D_CBC_256_CML
; i
++) {
1830 if (!have_cipher(names
[i
]))
1833 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC",
1834 app_get0_propq())) != NULL
) {
1840 if ((mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC",
1841 app_get0_propq())) != NULL
) {
1848 memset(rsa_doit
, 1, sizeof(rsa_doit
));
1849 #ifndef OPENSSL_NO_DH
1850 memset(ffdh_doit
, 1, sizeof(ffdh_doit
));
1852 memset(dsa_doit
, 1, sizeof(dsa_doit
));
1853 memset(ecdsa_doit
, 1, sizeof(ecdsa_doit
));
1854 memset(ecdh_doit
, 1, sizeof(ecdh_doit
));
1855 memset(eddsa_doit
, 1, sizeof(eddsa_doit
));
1856 #ifndef OPENSSL_NO_SM2
1857 memset(sm2_doit
, 1, sizeof(sm2_doit
));
1860 for (i
= 0; i
< ALGOR_NUM
; i
++)
1864 if (usertime
== 0 && !mr
)
1866 "You have chosen to measure elapsed time "
1867 "instead of user CPU time.\n");
1870 signal(SIGALRM
, alarmed
);
1874 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1875 print_message(names
[D_MD2
], c
[D_MD2
][testnum
], lengths
[testnum
],
1878 count
= run_benchmark(async_jobs
, EVP_Digest_MD2_loop
, loopargs
);
1880 print_result(D_MD2
, testnum
, count
, d
);
1887 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1888 print_message(names
[D_MDC2
], c
[D_MDC2
][testnum
], lengths
[testnum
],
1891 count
= run_benchmark(async_jobs
, EVP_Digest_MDC2_loop
, loopargs
);
1893 print_result(D_MDC2
, testnum
, count
, d
);
1900 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1901 print_message(names
[D_MD4
], c
[D_MD4
][testnum
], lengths
[testnum
],
1904 count
= run_benchmark(async_jobs
, EVP_Digest_MD4_loop
, loopargs
);
1906 print_result(D_MD4
, testnum
, count
, d
);
1913 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1914 print_message(names
[D_MD5
], c
[D_MD5
][testnum
], lengths
[testnum
],
1917 count
= run_benchmark(async_jobs
, MD5_loop
, loopargs
);
1919 print_result(D_MD5
, testnum
, count
, d
);
1926 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1927 print_message(names
[D_SHA1
], c
[D_SHA1
][testnum
], lengths
[testnum
],
1930 count
= run_benchmark(async_jobs
, SHA1_loop
, loopargs
);
1932 print_result(D_SHA1
, testnum
, count
, d
);
1938 if (doit
[D_SHA256
]) {
1939 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1940 print_message(names
[D_SHA256
], c
[D_SHA256
][testnum
],
1941 lengths
[testnum
], seconds
.sym
);
1943 count
= run_benchmark(async_jobs
, SHA256_loop
, loopargs
);
1945 print_result(D_SHA256
, testnum
, count
, d
);
1951 if (doit
[D_SHA512
]) {
1952 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1953 print_message(names
[D_SHA512
], c
[D_SHA512
][testnum
],
1954 lengths
[testnum
], seconds
.sym
);
1956 count
= run_benchmark(async_jobs
, SHA512_loop
, loopargs
);
1958 print_result(D_SHA512
, testnum
, count
, d
);
1964 if (doit
[D_WHIRLPOOL
]) {
1965 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1966 print_message(names
[D_WHIRLPOOL
], c
[D_WHIRLPOOL
][testnum
],
1967 lengths
[testnum
], seconds
.sym
);
1969 count
= run_benchmark(async_jobs
, WHIRLPOOL_loop
, loopargs
);
1971 print_result(D_WHIRLPOOL
, testnum
, count
, d
);
1977 if (doit
[D_RMD160
]) {
1978 for (testnum
= 0; testnum
< size_num
; testnum
++) {
1979 print_message(names
[D_RMD160
], c
[D_RMD160
][testnum
],
1980 lengths
[testnum
], seconds
.sym
);
1982 count
= run_benchmark(async_jobs
, EVP_Digest_RMD160_loop
, loopargs
);
1984 print_result(D_RMD160
, testnum
, count
, d
);
1991 static const char hmac_key
[] = "This is a key...";
1992 int len
= strlen(hmac_key
);
1993 OSSL_PARAM params
[3];
1995 mac
= EVP_MAC_fetch(app_get0_libctx(), "HMAC", app_get0_propq());
1996 if (mac
== NULL
|| evp_mac_mdname
== NULL
)
1999 evp_hmac_name
= app_malloc(sizeof("hmac()") + strlen(evp_mac_mdname
),
2001 sprintf(evp_hmac_name
, "hmac(%s)", evp_mac_mdname
);
2002 names
[D_HMAC
] = evp_hmac_name
;
2005 OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST
,
2008 OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2009 (char *)hmac_key
, len
);
2010 params
[2] = OSSL_PARAM_construct_end();
2012 for (i
= 0; i
< loopargs_len
; i
++) {
2013 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2014 if (loopargs
[i
].mctx
== NULL
)
2017 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2020 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2021 print_message(names
[D_HMAC
], c
[D_HMAC
][testnum
], lengths
[testnum
],
2024 count
= run_benchmark(async_jobs
, HMAC_loop
, loopargs
);
2026 print_result(D_HMAC
, testnum
, count
, d
);
2030 for (i
= 0; i
< loopargs_len
; i
++)
2031 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2036 if (doit
[D_CBC_DES
]) {
2039 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2040 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-cbc", deskey
,
2041 sizeof(deskey
) / 3);
2042 st
= loopargs
[i
].ctx
!= NULL
;
2044 algindex
= D_CBC_DES
;
2045 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2046 print_message(names
[D_CBC_DES
], c
[D_CBC_DES
][testnum
],
2047 lengths
[testnum
], seconds
.sym
);
2049 count
= run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2051 print_result(D_CBC_DES
, testnum
, count
, d
);
2053 for (i
= 0; i
< loopargs_len
; i
++)
2054 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2057 if (doit
[D_EDE3_DES
]) {
2060 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2061 loopargs
[i
].ctx
= init_evp_cipher_ctx("des-ede3-cbc", deskey
,
2063 st
= loopargs
[i
].ctx
!= NULL
;
2065 algindex
= D_EDE3_DES
;
2066 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2067 print_message(names
[D_EDE3_DES
], c
[D_EDE3_DES
][testnum
],
2068 lengths
[testnum
], seconds
.sym
);
2071 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2073 print_result(D_EDE3_DES
, testnum
, count
, d
);
2075 for (i
= 0; i
< loopargs_len
; i
++)
2076 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2079 for (k
= 0; k
< 3; k
++) {
2080 algindex
= D_CBC_128_AES
+ k
;
2081 if (doit
[algindex
]) {
2084 keylen
= 16 + k
* 8;
2085 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2086 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2088 st
= loopargs
[i
].ctx
!= NULL
;
2091 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2092 print_message(names
[algindex
], c
[algindex
][testnum
],
2093 lengths
[testnum
], seconds
.sym
);
2096 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2098 print_result(algindex
, testnum
, count
, d
);
2100 for (i
= 0; i
< loopargs_len
; i
++)
2101 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2105 for (k
= 0; k
< 3; k
++) {
2106 algindex
= D_CBC_128_CML
+ k
;
2107 if (doit
[algindex
]) {
2110 keylen
= 16 + k
* 8;
2111 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2112 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2114 st
= loopargs
[i
].ctx
!= NULL
;
2117 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2118 print_message(names
[algindex
], c
[algindex
][testnum
],
2119 lengths
[testnum
], seconds
.sym
);
2122 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2124 print_result(algindex
, testnum
, count
, d
);
2126 for (i
= 0; i
< loopargs_len
; i
++)
2127 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2131 for (algindex
= D_RC4
; algindex
<= D_CBC_CAST
; algindex
++) {
2132 if (doit
[algindex
]) {
2136 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2137 loopargs
[i
].ctx
= init_evp_cipher_ctx(names
[algindex
],
2139 st
= loopargs
[i
].ctx
!= NULL
;
2142 for (testnum
= 0; st
&& testnum
< size_num
; testnum
++) {
2143 print_message(names
[algindex
], c
[algindex
][testnum
],
2144 lengths
[testnum
], seconds
.sym
);
2147 run_benchmark(async_jobs
, EVP_Cipher_loop
, loopargs
);
2149 print_result(algindex
, testnum
, count
, d
);
2151 for (i
= 0; i
< loopargs_len
; i
++)
2152 EVP_CIPHER_CTX_free(loopargs
[i
].ctx
);
2155 if (doit
[D_GHASH
]) {
2156 static const char gmac_iv
[] = "0123456789ab";
2157 OSSL_PARAM params
[3];
2159 mac
= EVP_MAC_fetch(app_get0_libctx(), "GMAC", app_get0_propq());
2163 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2165 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_IV
,
2167 sizeof(gmac_iv
) - 1);
2168 params
[2] = OSSL_PARAM_construct_end();
2170 for (i
= 0; i
< loopargs_len
; i
++) {
2171 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2172 if (loopargs
[i
].mctx
== NULL
)
2175 if (!EVP_MAC_init(loopargs
[i
].mctx
, key32
, 16, params
))
2178 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2179 print_message(names
[D_GHASH
], c
[D_GHASH
][testnum
], lengths
[testnum
],
2182 count
= run_benchmark(async_jobs
, GHASH_loop
, loopargs
);
2184 print_result(D_GHASH
, testnum
, count
, d
);
2188 for (i
= 0; i
< loopargs_len
; i
++)
2189 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2195 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2196 print_message(names
[D_RAND
], c
[D_RAND
][testnum
], lengths
[testnum
],
2199 count
= run_benchmark(async_jobs
, RAND_bytes_loop
, loopargs
);
2201 print_result(D_RAND
, testnum
, count
, d
);
2206 if (evp_cipher
!= NULL
) {
2207 int (*loopfunc
) (void *) = EVP_Update_loop
;
2209 if (multiblock
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2210 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
)) {
2211 multiblock_speed(evp_cipher
, lengths_single
, &seconds
);
2216 names
[D_EVP
] = EVP_CIPHER_get0_name(evp_cipher
);
2218 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_CCM_MODE
) {
2219 loopfunc
= EVP_Update_loop_ccm
;
2220 } else if (aead
&& (EVP_CIPHER_get_flags(evp_cipher
) &
2221 EVP_CIPH_FLAG_AEAD_CIPHER
)) {
2222 loopfunc
= EVP_Update_loop_aead
;
2223 if (lengths
== lengths_list
) {
2224 lengths
= aead_lengths_list
;
2225 size_num
= OSSL_NELEM(aead_lengths_list
);
2229 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2230 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2233 for (k
= 0; k
< loopargs_len
; k
++) {
2234 loopargs
[k
].ctx
= EVP_CIPHER_CTX_new();
2235 if (loopargs
[k
].ctx
== NULL
) {
2236 BIO_printf(bio_err
, "\nEVP_CIPHER_CTX_new failure\n");
2239 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, evp_cipher
, NULL
,
2240 NULL
, iv
, decrypt
? 0 : 1)) {
2241 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2242 ERR_print_errors(bio_err
);
2246 EVP_CIPHER_CTX_set_padding(loopargs
[k
].ctx
, 0);
2248 keylen
= EVP_CIPHER_CTX_get_key_length(loopargs
[k
].ctx
);
2249 loopargs
[k
].key
= app_malloc(keylen
, "evp_cipher key");
2250 EVP_CIPHER_CTX_rand_key(loopargs
[k
].ctx
, loopargs
[k
].key
);
2251 if (!EVP_CipherInit_ex(loopargs
[k
].ctx
, NULL
, NULL
,
2252 loopargs
[k
].key
, NULL
, -1)) {
2253 BIO_printf(bio_err
, "\nEVP_CipherInit_ex failure\n");
2254 ERR_print_errors(bio_err
);
2257 OPENSSL_clear_free(loopargs
[k
].key
, keylen
);
2259 /* SIV mode only allows for a single Update operation */
2260 if (EVP_CIPHER_get_mode(evp_cipher
) == EVP_CIPH_SIV_MODE
)
2261 (void)EVP_CIPHER_CTX_ctrl(loopargs
[k
].ctx
,
2262 EVP_CTRL_SET_SPEED
, 1, NULL
);
2266 count
= run_benchmark(async_jobs
, loopfunc
, loopargs
);
2268 for (k
= 0; k
< loopargs_len
; k
++)
2269 EVP_CIPHER_CTX_free(loopargs
[k
].ctx
);
2270 print_result(D_EVP
, testnum
, count
, d
);
2272 } else if (evp_md_name
!= NULL
) {
2273 names
[D_EVP
] = evp_md_name
;
2275 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2276 print_message(names
[D_EVP
], c
[D_EVP
][testnum
], lengths
[testnum
],
2279 count
= run_benchmark(async_jobs
, EVP_Digest_md_loop
, loopargs
);
2281 print_result(D_EVP
, testnum
, count
, d
);
2288 if (doit
[D_EVP_CMAC
]) {
2289 OSSL_PARAM params
[3];
2290 EVP_CIPHER
*cipher
= NULL
;
2292 mac
= EVP_MAC_fetch(app_get0_libctx(), "CMAC", app_get0_propq());
2293 if (mac
== NULL
|| evp_mac_ciphername
== NULL
)
2295 if (!opt_cipher(evp_mac_ciphername
, &cipher
))
2298 keylen
= EVP_CIPHER_get_key_length(cipher
);
2299 EVP_CIPHER_free(cipher
);
2300 if (keylen
<= 0 || keylen
> (int)sizeof(key32
)) {
2301 BIO_printf(bio_err
, "\nRequested CMAC cipher with unsupported key length.\n");
2304 evp_cmac_name
= app_malloc(sizeof("cmac()")
2305 + strlen(evp_mac_ciphername
), "CMAC name");
2306 sprintf(evp_cmac_name
, "cmac(%s)", evp_mac_ciphername
);
2307 names
[D_EVP_CMAC
] = evp_cmac_name
;
2309 params
[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER
,
2310 evp_mac_ciphername
, 0);
2311 params
[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
2312 (char *)key32
, keylen
);
2313 params
[2] = OSSL_PARAM_construct_end();
2315 for (i
= 0; i
< loopargs_len
; i
++) {
2316 loopargs
[i
].mctx
= EVP_MAC_CTX_new(mac
);
2317 if (loopargs
[i
].mctx
== NULL
)
2320 if (!EVP_MAC_CTX_set_params(loopargs
[i
].mctx
, params
))
2324 for (testnum
= 0; testnum
< size_num
; testnum
++) {
2325 print_message(names
[D_EVP_CMAC
], c
[D_EVP_CMAC
][testnum
],
2326 lengths
[testnum
], seconds
.sym
);
2328 count
= run_benchmark(async_jobs
, CMAC_loop
, loopargs
);
2330 print_result(D_EVP_CMAC
, testnum
, count
, d
);
2334 for (i
= 0; i
< loopargs_len
; i
++)
2335 EVP_MAC_CTX_free(loopargs
[i
].mctx
);
2340 for (i
= 0; i
< loopargs_len
; i
++)
2341 if (RAND_bytes(loopargs
[i
].buf
, 36) <= 0)
2344 for (testnum
= 0; testnum
< RSA_NUM
; testnum
++) {
2345 EVP_PKEY
*rsa_key
= NULL
;
2348 if (!rsa_doit
[testnum
])
2351 if (primes
> RSA_DEFAULT_PRIME_NUM
) {
2352 /* we haven't set keys yet, generate multi-prime RSA keys */
2355 && BN_set_word(bn
, RSA_F4
)
2356 && init_gen_str(&genctx
, "RSA", NULL
, 0, NULL
, NULL
)
2357 && EVP_PKEY_CTX_set_rsa_keygen_bits(genctx
, rsa_keys
[testnum
].bits
) > 0
2358 && EVP_PKEY_CTX_set1_rsa_keygen_pubexp(genctx
, bn
) > 0
2359 && EVP_PKEY_CTX_set_rsa_keygen_primes(genctx
, primes
) > 0
2360 && EVP_PKEY_keygen(genctx
, &rsa_key
);
2363 EVP_PKEY_CTX_free(genctx
);
2366 const unsigned char *p
= rsa_keys
[testnum
].data
;
2368 st
= (rsa_key
= d2i_PrivateKey(EVP_PKEY_RSA
, NULL
, &p
,
2369 rsa_keys
[testnum
].length
)) != NULL
;
2372 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2373 loopargs
[i
].rsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
, NULL
);
2374 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2375 if (loopargs
[i
].rsa_sign_ctx
[testnum
] == NULL
2376 || EVP_PKEY_sign_init(loopargs
[i
].rsa_sign_ctx
[testnum
]) <= 0
2377 || EVP_PKEY_sign(loopargs
[i
].rsa_sign_ctx
[testnum
],
2379 &loopargs
[i
].sigsize
,
2380 loopargs
[i
].buf
, 36) <= 0)
2385 "RSA sign setup failure. No RSA sign will be done.\n");
2386 ERR_print_errors(bio_err
);
2389 pkey_print_message("private", "rsa",
2390 rsa_c
[testnum
][0], rsa_keys
[testnum
].bits
,
2392 /* RSA_blinding_on(rsa_key[testnum],NULL); */
2394 count
= run_benchmark(async_jobs
, RSA_sign_loop
, loopargs
);
2397 mr
? "+R1:%ld:%d:%.2f\n"
2398 : "%ld %u bits private RSA's in %.2fs\n",
2399 count
, rsa_keys
[testnum
].bits
, d
);
2400 rsa_results
[testnum
][0] = (double)count
/ d
;
2404 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2405 loopargs
[i
].rsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(rsa_key
,
2407 if (loopargs
[i
].rsa_verify_ctx
[testnum
] == NULL
2408 || EVP_PKEY_verify_init(loopargs
[i
].rsa_verify_ctx
[testnum
]) <= 0
2409 || EVP_PKEY_verify(loopargs
[i
].rsa_verify_ctx
[testnum
],
2411 loopargs
[i
].sigsize
,
2412 loopargs
[i
].buf
, 36) <= 0)
2417 "RSA verify setup failure. No RSA verify will be done.\n");
2418 ERR_print_errors(bio_err
);
2419 rsa_doit
[testnum
] = 0;
2421 pkey_print_message("public", "rsa",
2422 rsa_c
[testnum
][1], rsa_keys
[testnum
].bits
,
2425 count
= run_benchmark(async_jobs
, RSA_verify_loop
, loopargs
);
2428 mr
? "+R2:%ld:%d:%.2f\n"
2429 : "%ld %u bits public RSA's in %.2fs\n",
2430 count
, rsa_keys
[testnum
].bits
, d
);
2431 rsa_results
[testnum
][1] = (double)count
/ d
;
2434 if (op_count
<= 1) {
2435 /* if longer than 10s, don't do any more */
2436 stop_it(rsa_doit
, testnum
);
2438 EVP_PKEY_free(rsa_key
);
2441 for (testnum
= 0; testnum
< DSA_NUM
; testnum
++) {
2442 EVP_PKEY
*dsa_key
= NULL
;
2445 if (!dsa_doit
[testnum
])
2448 st
= (dsa_key
= get_dsa(dsa_bits
[testnum
])) != NULL
;
2450 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2451 loopargs
[i
].dsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2453 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2454 if (loopargs
[i
].dsa_sign_ctx
[testnum
] == NULL
2455 || EVP_PKEY_sign_init(loopargs
[i
].dsa_sign_ctx
[testnum
]) <= 0
2457 || EVP_PKEY_sign(loopargs
[i
].dsa_sign_ctx
[testnum
],
2459 &loopargs
[i
].sigsize
,
2460 loopargs
[i
].buf
, 20) <= 0)
2465 "DSA sign setup failure. No DSA sign will be done.\n");
2466 ERR_print_errors(bio_err
);
2469 pkey_print_message("sign", "dsa",
2470 dsa_c
[testnum
][0], dsa_bits
[testnum
],
2473 count
= run_benchmark(async_jobs
, DSA_sign_loop
, loopargs
);
2476 mr
? "+R3:%ld:%u:%.2f\n"
2477 : "%ld %u bits DSA signs in %.2fs\n",
2478 count
, dsa_bits
[testnum
], d
);
2479 dsa_results
[testnum
][0] = (double)count
/ d
;
2483 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2484 loopargs
[i
].dsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(dsa_key
,
2486 if (loopargs
[i
].dsa_verify_ctx
[testnum
] == NULL
2487 || EVP_PKEY_verify_init(loopargs
[i
].dsa_verify_ctx
[testnum
]) <= 0
2488 || EVP_PKEY_verify(loopargs
[i
].dsa_verify_ctx
[testnum
],
2490 loopargs
[i
].sigsize
,
2491 loopargs
[i
].buf
, 36) <= 0)
2496 "DSA verify setup failure. No DSA verify will be done.\n");
2497 ERR_print_errors(bio_err
);
2498 dsa_doit
[testnum
] = 0;
2500 pkey_print_message("verify", "dsa",
2501 dsa_c
[testnum
][1], dsa_bits
[testnum
],
2504 count
= run_benchmark(async_jobs
, DSA_verify_loop
, loopargs
);
2507 mr
? "+R4:%ld:%u:%.2f\n"
2508 : "%ld %u bits DSA verify in %.2fs\n",
2509 count
, dsa_bits
[testnum
], d
);
2510 dsa_results
[testnum
][1] = (double)count
/ d
;
2513 if (op_count
<= 1) {
2514 /* if longer than 10s, don't do any more */
2515 stop_it(dsa_doit
, testnum
);
2517 EVP_PKEY_free(dsa_key
);
2520 for (testnum
= 0; testnum
< ECDSA_NUM
; testnum
++) {
2521 EVP_PKEY
*ecdsa_key
= NULL
;
2524 if (!ecdsa_doit
[testnum
])
2527 st
= (ecdsa_key
= get_ecdsa(&ec_curves
[testnum
])) != NULL
;
2529 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2530 loopargs
[i
].ecdsa_sign_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2532 loopargs
[i
].sigsize
= loopargs
[i
].buflen
;
2533 if (loopargs
[i
].ecdsa_sign_ctx
[testnum
] == NULL
2534 || EVP_PKEY_sign_init(loopargs
[i
].ecdsa_sign_ctx
[testnum
]) <= 0
2536 || EVP_PKEY_sign(loopargs
[i
].ecdsa_sign_ctx
[testnum
],
2538 &loopargs
[i
].sigsize
,
2539 loopargs
[i
].buf
, 20) <= 0)
2544 "ECDSA sign setup failure. No ECDSA sign will be done.\n");
2545 ERR_print_errors(bio_err
);
2548 pkey_print_message("sign", "ecdsa",
2549 ecdsa_c
[testnum
][0], ec_curves
[testnum
].bits
,
2552 count
= run_benchmark(async_jobs
, ECDSA_sign_loop
, loopargs
);
2555 mr
? "+R5:%ld:%u:%.2f\n"
2556 : "%ld %u bits ECDSA signs in %.2fs\n",
2557 count
, ec_curves
[testnum
].bits
, d
);
2558 ecdsa_results
[testnum
][0] = (double)count
/ d
;
2562 for (i
= 0; st
&& i
< loopargs_len
; i
++) {
2563 loopargs
[i
].ecdsa_verify_ctx
[testnum
] = EVP_PKEY_CTX_new(ecdsa_key
,
2565 if (loopargs
[i
].ecdsa_verify_ctx
[testnum
] == NULL
2566 || EVP_PKEY_verify_init(loopargs
[i
].ecdsa_verify_ctx
[testnum
]) <= 0
2567 || EVP_PKEY_verify(loopargs
[i
].ecdsa_verify_ctx
[testnum
],
2569 loopargs
[i
].sigsize
,
2570 loopargs
[i
].buf
, 20) <= 0)
2575 "ECDSA verify setup failure. No ECDSA verify will be done.\n");
2576 ERR_print_errors(bio_err
);
2577 ecdsa_doit
[testnum
] = 0;
2579 pkey_print_message("verify", "ecdsa",
2580 ecdsa_c
[testnum
][1], ec_curves
[testnum
].bits
,
2583 count
= run_benchmark(async_jobs
, ECDSA_verify_loop
, loopargs
);
2586 mr
? "+R6:%ld:%u:%.2f\n"
2587 : "%ld %u bits ECDSA verify in %.2fs\n",
2588 count
, ec_curves
[testnum
].bits
, d
);
2589 ecdsa_results
[testnum
][1] = (double)count
/ d
;
2592 if (op_count
<= 1) {
2593 /* if longer than 10s, don't do any more */
2594 stop_it(ecdsa_doit
, testnum
);
2598 for (testnum
= 0; testnum
< EC_NUM
; testnum
++) {
2599 int ecdh_checks
= 1;
2601 if (!ecdh_doit
[testnum
])
2604 for (i
= 0; i
< loopargs_len
; i
++) {
2605 EVP_PKEY_CTX
*test_ctx
= NULL
;
2606 EVP_PKEY_CTX
*ctx
= NULL
;
2607 EVP_PKEY
*key_A
= NULL
;
2608 EVP_PKEY
*key_B
= NULL
;
2612 if ((key_A
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key A */
2613 || (key_B
= get_ecdsa(&ec_curves
[testnum
])) == NULL
/* generate secret key B */
2614 || (ctx
= EVP_PKEY_CTX_new(key_A
, NULL
)) == NULL
/* derivation ctx from skeyA */
2615 || EVP_PKEY_derive_init(ctx
) <= 0 /* init derivation ctx */
2616 || EVP_PKEY_derive_set_peer(ctx
, key_B
) <= 0 /* set peer pubkey in ctx */
2617 || EVP_PKEY_derive(ctx
, NULL
, &outlen
) <= 0 /* determine max length */
2618 || outlen
== 0 /* ensure outlen is a valid size */
2619 || outlen
> MAX_ECDH_SIZE
/* avoid buffer overflow */) {
2621 BIO_printf(bio_err
, "ECDH key generation failure.\n");
2622 ERR_print_errors(bio_err
);
2628 * Here we perform a test run, comparing the output of a*B and b*A;
2629 * we try this here and assume that further EVP_PKEY_derive calls
2630 * never fail, so we can skip checks in the actually benchmarked
2631 * code, for maximum performance.
2633 if ((test_ctx
= EVP_PKEY_CTX_new(key_B
, NULL
)) == NULL
/* test ctx from skeyB */
2634 || !EVP_PKEY_derive_init(test_ctx
) /* init derivation test_ctx */
2635 || !EVP_PKEY_derive_set_peer(test_ctx
, key_A
) /* set peer pubkey in test_ctx */
2636 || !EVP_PKEY_derive(test_ctx
, NULL
, &test_outlen
) /* determine max length */
2637 || !EVP_PKEY_derive(ctx
, loopargs
[i
].secret_a
, &outlen
) /* compute a*B */
2638 || !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_b
, &test_outlen
) /* compute b*A */
2639 || test_outlen
!= outlen
/* compare output length */) {
2641 BIO_printf(bio_err
, "ECDH computation failure.\n");
2642 ERR_print_errors(bio_err
);
2647 /* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
2648 if (CRYPTO_memcmp(loopargs
[i
].secret_a
,
2649 loopargs
[i
].secret_b
, outlen
)) {
2651 BIO_printf(bio_err
, "ECDH computations don't match.\n");
2652 ERR_print_errors(bio_err
);
2657 loopargs
[i
].ecdh_ctx
[testnum
] = ctx
;
2658 loopargs
[i
].outlen
[testnum
] = outlen
;
2660 EVP_PKEY_free(key_A
);
2661 EVP_PKEY_free(key_B
);
2662 EVP_PKEY_CTX_free(test_ctx
);
2665 if (ecdh_checks
!= 0) {
2666 pkey_print_message("", "ecdh",
2668 ec_curves
[testnum
].bits
, seconds
.ecdh
);
2671 run_benchmark(async_jobs
, ECDH_EVP_derive_key_loop
, loopargs
);
2674 mr
? "+R7:%ld:%d:%.2f\n" :
2675 "%ld %u-bits ECDH ops in %.2fs\n", count
,
2676 ec_curves
[testnum
].bits
, d
);
2677 ecdh_results
[testnum
][0] = (double)count
/ d
;
2681 if (op_count
<= 1) {
2682 /* if longer than 10s, don't do any more */
2683 stop_it(ecdh_doit
, testnum
);
2687 for (testnum
= 0; testnum
< EdDSA_NUM
; testnum
++) {
2689 EVP_PKEY
*ed_pkey
= NULL
;
2690 EVP_PKEY_CTX
*ed_pctx
= NULL
;
2692 if (!eddsa_doit
[testnum
])
2693 continue; /* Ignore Curve */
2694 for (i
= 0; i
< loopargs_len
; i
++) {
2695 loopargs
[i
].eddsa_ctx
[testnum
] = EVP_MD_CTX_new();
2696 if (loopargs
[i
].eddsa_ctx
[testnum
] == NULL
) {
2700 loopargs
[i
].eddsa_ctx2
[testnum
] = EVP_MD_CTX_new();
2701 if (loopargs
[i
].eddsa_ctx2
[testnum
] == NULL
) {
2706 if ((ed_pctx
= EVP_PKEY_CTX_new_id(ed_curves
[testnum
].nid
,
2708 || EVP_PKEY_keygen_init(ed_pctx
) <= 0
2709 || EVP_PKEY_keygen(ed_pctx
, &ed_pkey
) <= 0) {
2711 EVP_PKEY_CTX_free(ed_pctx
);
2714 EVP_PKEY_CTX_free(ed_pctx
);
2716 if (!EVP_DigestSignInit(loopargs
[i
].eddsa_ctx
[testnum
], NULL
, NULL
,
2719 EVP_PKEY_free(ed_pkey
);
2722 if (!EVP_DigestVerifyInit(loopargs
[i
].eddsa_ctx2
[testnum
], NULL
,
2723 NULL
, NULL
, ed_pkey
)) {
2725 EVP_PKEY_free(ed_pkey
);
2729 EVP_PKEY_free(ed_pkey
);
2733 BIO_printf(bio_err
, "EdDSA failure.\n");
2734 ERR_print_errors(bio_err
);
2737 for (i
= 0; i
< loopargs_len
; i
++) {
2738 /* Perform EdDSA signature test */
2739 loopargs
[i
].sigsize
= ed_curves
[testnum
].sigsize
;
2740 st
= EVP_DigestSign(loopargs
[i
].eddsa_ctx
[testnum
],
2741 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2742 loopargs
[i
].buf
, 20);
2748 "EdDSA sign failure. No EdDSA sign will be done.\n");
2749 ERR_print_errors(bio_err
);
2752 pkey_print_message("sign", ed_curves
[testnum
].name
,
2753 eddsa_c
[testnum
][0],
2754 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2756 count
= run_benchmark(async_jobs
, EdDSA_sign_loop
, loopargs
);
2760 mr
? "+R8:%ld:%u:%s:%.2f\n" :
2761 "%ld %u bits %s signs in %.2fs \n",
2762 count
, ed_curves
[testnum
].bits
,
2763 ed_curves
[testnum
].name
, d
);
2764 eddsa_results
[testnum
][0] = (double)count
/ d
;
2767 /* Perform EdDSA verification test */
2768 for (i
= 0; i
< loopargs_len
; i
++) {
2769 st
= EVP_DigestVerify(loopargs
[i
].eddsa_ctx2
[testnum
],
2770 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2771 loopargs
[i
].buf
, 20);
2777 "EdDSA verify failure. No EdDSA verify will be done.\n");
2778 ERR_print_errors(bio_err
);
2779 eddsa_doit
[testnum
] = 0;
2781 pkey_print_message("verify", ed_curves
[testnum
].name
,
2782 eddsa_c
[testnum
][1],
2783 ed_curves
[testnum
].bits
, seconds
.eddsa
);
2785 count
= run_benchmark(async_jobs
, EdDSA_verify_loop
, loopargs
);
2788 mr
? "+R9:%ld:%u:%s:%.2f\n"
2789 : "%ld %u bits %s verify in %.2fs\n",
2790 count
, ed_curves
[testnum
].bits
,
2791 ed_curves
[testnum
].name
, d
);
2792 eddsa_results
[testnum
][1] = (double)count
/ d
;
2795 if (op_count
<= 1) {
2796 /* if longer than 10s, don't do any more */
2797 stop_it(eddsa_doit
, testnum
);
2802 #ifndef OPENSSL_NO_SM2
2803 for (testnum
= 0; testnum
< SM2_NUM
; testnum
++) {
2805 EVP_PKEY
*sm2_pkey
= NULL
;
2807 if (!sm2_doit
[testnum
])
2808 continue; /* Ignore Curve */
2809 /* Init signing and verification */
2810 for (i
= 0; i
< loopargs_len
; i
++) {
2811 EVP_PKEY_CTX
*sm2_pctx
= NULL
;
2812 EVP_PKEY_CTX
*sm2_vfy_pctx
= NULL
;
2813 EVP_PKEY_CTX
*pctx
= NULL
;
2816 loopargs
[i
].sm2_ctx
[testnum
] = EVP_MD_CTX_new();
2817 loopargs
[i
].sm2_vfy_ctx
[testnum
] = EVP_MD_CTX_new();
2818 if (loopargs
[i
].sm2_ctx
[testnum
] == NULL
2819 || loopargs
[i
].sm2_vfy_ctx
[testnum
] == NULL
)
2824 st
= !((pctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_SM2
, NULL
)) == NULL
2825 || EVP_PKEY_keygen_init(pctx
) <= 0
2826 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx
,
2827 sm2_curves
[testnum
].nid
) <= 0
2828 || EVP_PKEY_keygen(pctx
, &sm2_pkey
) <= 0);
2829 EVP_PKEY_CTX_free(pctx
);
2833 st
= 0; /* set back to zero */
2834 /* attach it sooner to rely on main final cleanup */
2835 loopargs
[i
].sm2_pkey
[testnum
] = sm2_pkey
;
2836 loopargs
[i
].sigsize
= EVP_PKEY_get_size(sm2_pkey
);
2838 sm2_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2839 sm2_vfy_pctx
= EVP_PKEY_CTX_new(sm2_pkey
, NULL
);
2840 if (sm2_pctx
== NULL
|| sm2_vfy_pctx
== NULL
) {
2841 EVP_PKEY_CTX_free(sm2_vfy_pctx
);
2845 /* attach them directly to respective ctx */
2846 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_ctx
[testnum
], sm2_pctx
);
2847 EVP_MD_CTX_set_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[testnum
], sm2_vfy_pctx
);
2850 * No need to allow user to set an explicit ID here, just use
2851 * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
2853 if (EVP_PKEY_CTX_set1_id(sm2_pctx
, SM2_ID
, SM2_ID_LEN
) != 1
2854 || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx
, SM2_ID
, SM2_ID_LEN
) != 1)
2857 if (!EVP_DigestSignInit(loopargs
[i
].sm2_ctx
[testnum
], NULL
,
2858 EVP_sm3(), NULL
, sm2_pkey
))
2860 if (!EVP_DigestVerifyInit(loopargs
[i
].sm2_vfy_ctx
[testnum
], NULL
,
2861 EVP_sm3(), NULL
, sm2_pkey
))
2863 st
= 1; /* mark loop as succeeded */
2866 BIO_printf(bio_err
, "SM2 init failure.\n");
2867 ERR_print_errors(bio_err
);
2870 for (i
= 0; i
< loopargs_len
; i
++) {
2871 /* Perform SM2 signature test */
2872 st
= EVP_DigestSign(loopargs
[i
].sm2_ctx
[testnum
],
2873 loopargs
[i
].buf2
, &loopargs
[i
].sigsize
,
2874 loopargs
[i
].buf
, 20);
2880 "SM2 sign failure. No SM2 sign will be done.\n");
2881 ERR_print_errors(bio_err
);
2884 pkey_print_message("sign", sm2_curves
[testnum
].name
,
2886 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2888 count
= run_benchmark(async_jobs
, SM2_sign_loop
, loopargs
);
2892 mr
? "+R10:%ld:%u:%s:%.2f\n" :
2893 "%ld %u bits %s signs in %.2fs \n",
2894 count
, sm2_curves
[testnum
].bits
,
2895 sm2_curves
[testnum
].name
, d
);
2896 sm2_results
[testnum
][0] = (double)count
/ d
;
2900 /* Perform SM2 verification test */
2901 for (i
= 0; i
< loopargs_len
; i
++) {
2902 st
= EVP_DigestVerify(loopargs
[i
].sm2_vfy_ctx
[testnum
],
2903 loopargs
[i
].buf2
, loopargs
[i
].sigsize
,
2904 loopargs
[i
].buf
, 20);
2910 "SM2 verify failure. No SM2 verify will be done.\n");
2911 ERR_print_errors(bio_err
);
2912 sm2_doit
[testnum
] = 0;
2914 pkey_print_message("verify", sm2_curves
[testnum
].name
,
2916 sm2_curves
[testnum
].bits
, seconds
.sm2
);
2918 count
= run_benchmark(async_jobs
, SM2_verify_loop
, loopargs
);
2921 mr
? "+R11:%ld:%u:%s:%.2f\n"
2922 : "%ld %u bits %s verify in %.2fs\n",
2923 count
, sm2_curves
[testnum
].bits
,
2924 sm2_curves
[testnum
].name
, d
);
2925 sm2_results
[testnum
][1] = (double)count
/ d
;
2928 if (op_count
<= 1) {
2929 /* if longer than 10s, don't do any more */
2930 for (testnum
++; testnum
< SM2_NUM
; testnum
++)
2931 sm2_doit
[testnum
] = 0;
2935 #endif /* OPENSSL_NO_SM2 */
2937 #ifndef OPENSSL_NO_DH
2938 for (testnum
= 0; testnum
< FFDH_NUM
; testnum
++) {
2939 int ffdh_checks
= 1;
2941 if (!ffdh_doit
[testnum
])
2944 for (i
= 0; i
< loopargs_len
; i
++) {
2945 EVP_PKEY
*pkey_A
= NULL
;
2946 EVP_PKEY
*pkey_B
= NULL
;
2947 EVP_PKEY_CTX
*ffdh_ctx
= NULL
;
2948 EVP_PKEY_CTX
*test_ctx
= NULL
;
2952 /* Ensure that the error queue is empty */
2953 if (ERR_peek_error()) {
2955 "WARNING: the error queue contains previous unhandled errors.\n");
2956 ERR_print_errors(bio_err
);
2959 pkey_A
= EVP_PKEY_new();
2961 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2962 ERR_print_errors(bio_err
);
2967 pkey_B
= EVP_PKEY_new();
2969 BIO_printf(bio_err
, "Error while initialising EVP_PKEY (out of memory?).\n");
2970 ERR_print_errors(bio_err
);
2976 ffdh_ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_DH
, NULL
);
2978 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
2979 ERR_print_errors(bio_err
);
2985 if (EVP_PKEY_keygen_init(ffdh_ctx
) <= 0) {
2986 BIO_printf(bio_err
, "Error while initialising EVP_PKEY_CTX.\n");
2987 ERR_print_errors(bio_err
);
2992 if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx
, ffdh_params
[testnum
].nid
) <= 0) {
2993 BIO_printf(bio_err
, "Error setting DH key size for keygen.\n");
2994 ERR_print_errors(bio_err
);
3000 if (EVP_PKEY_keygen(ffdh_ctx
, &pkey_A
) <= 0 ||
3001 EVP_PKEY_keygen(ffdh_ctx
, &pkey_B
) <= 0) {
3002 BIO_printf(bio_err
, "FFDH key generation failure.\n");
3003 ERR_print_errors(bio_err
);
3009 EVP_PKEY_CTX_free(ffdh_ctx
);
3012 * check if the derivation works correctly both ways so that
3013 * we know if future derive calls will fail, and we can skip
3014 * error checking in benchmarked code
3016 ffdh_ctx
= EVP_PKEY_CTX_new(pkey_A
, NULL
);
3017 if (ffdh_ctx
== NULL
) {
3018 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3019 ERR_print_errors(bio_err
);
3024 if (EVP_PKEY_derive_init(ffdh_ctx
) <= 0) {
3025 BIO_printf(bio_err
, "FFDH derivation context init failure.\n");
3026 ERR_print_errors(bio_err
);
3031 if (EVP_PKEY_derive_set_peer(ffdh_ctx
, pkey_B
) <= 0) {
3032 BIO_printf(bio_err
, "Assigning peer key for derivation failed.\n");
3033 ERR_print_errors(bio_err
);
3038 if (EVP_PKEY_derive(ffdh_ctx
, NULL
, &secret_size
) <= 0) {
3039 BIO_printf(bio_err
, "Checking size of shared secret failed.\n");
3040 ERR_print_errors(bio_err
);
3045 if (secret_size
> MAX_FFDH_SIZE
) {
3046 BIO_printf(bio_err
, "Assertion failure: shared secret too large.\n");
3051 if (EVP_PKEY_derive(ffdh_ctx
,
3052 loopargs
[i
].secret_ff_a
,
3053 &secret_size
) <= 0) {
3054 BIO_printf(bio_err
, "Shared secret derive failure.\n");
3055 ERR_print_errors(bio_err
);
3060 /* Now check from side B */
3061 test_ctx
= EVP_PKEY_CTX_new(pkey_B
, NULL
);
3063 BIO_printf(bio_err
, "Error while allocating EVP_PKEY_CTX.\n");
3064 ERR_print_errors(bio_err
);
3069 if (!EVP_PKEY_derive_init(test_ctx
) ||
3070 !EVP_PKEY_derive_set_peer(test_ctx
, pkey_A
) ||
3071 !EVP_PKEY_derive(test_ctx
, NULL
, &test_out
) ||
3072 !EVP_PKEY_derive(test_ctx
, loopargs
[i
].secret_ff_b
, &test_out
) ||
3073 test_out
!= secret_size
) {
3074 BIO_printf(bio_err
, "FFDH computation failure.\n");
3080 /* compare the computed secrets */
3081 if (CRYPTO_memcmp(loopargs
[i
].secret_ff_a
,
3082 loopargs
[i
].secret_ff_b
, secret_size
)) {
3083 BIO_printf(bio_err
, "FFDH computations don't match.\n");
3084 ERR_print_errors(bio_err
);
3090 loopargs
[i
].ffdh_ctx
[testnum
] = ffdh_ctx
;
3092 EVP_PKEY_free(pkey_A
);
3094 EVP_PKEY_free(pkey_B
);
3096 EVP_PKEY_CTX_free(test_ctx
);
3099 if (ffdh_checks
!= 0) {
3100 pkey_print_message("", "ffdh", ffdh_c
[testnum
][0],
3101 ffdh_params
[testnum
].bits
, seconds
.ffdh
);
3104 run_benchmark(async_jobs
, FFDH_derive_key_loop
, loopargs
);
3107 mr
? "+R12:%ld:%d:%.2f\n" :
3108 "%ld %u-bits FFDH ops in %.2fs\n", count
,
3109 ffdh_params
[testnum
].bits
, d
);
3110 ffdh_results
[testnum
][0] = (double)count
/ d
;
3113 if (op_count
<= 1) {
3114 /* if longer than 10s, don't do any more */
3115 stop_it(ffdh_doit
, testnum
);
3118 #endif /* OPENSSL_NO_DH */
3123 printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING
));
3124 printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON
));
3125 printf("options: %s\n", BN_options());
3126 printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS
));
3127 printf("%s\n", OpenSSL_version(OPENSSL_CPU_INFO
));
3134 printf("The 'numbers' are in 1000s of bytes per second processed.\n");
3137 for (testnum
= 0; testnum
< size_num
; testnum
++)
3138 printf(mr
? ":%d" : "%7d bytes", lengths
[testnum
]);
3142 for (k
= 0; k
< ALGOR_NUM
; k
++) {
3146 printf("+F:%u:%s", k
, names
[k
]);
3148 printf("%-13s", names
[k
]);
3149 for (testnum
= 0; testnum
< size_num
; testnum
++) {
3150 if (results
[k
][testnum
] > 10000 && !mr
)
3151 printf(" %11.2fk", results
[k
][testnum
] / 1e3
);
3153 printf(mr
? ":%.2f" : " %11.2f ", results
[k
][testnum
]);
3158 for (k
= 0; k
< RSA_NUM
; k
++) {
3161 if (testnum
&& !mr
) {
3162 printf("%18ssign verify sign/s verify/s\n", " ");
3166 printf("+F2:%u:%u:%f:%f\n",
3167 k
, rsa_keys
[k
].bits
, rsa_results
[k
][0], rsa_results
[k
][1]);
3169 printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3170 rsa_keys
[k
].bits
, 1.0 / rsa_results
[k
][0], 1.0 / rsa_results
[k
][1],
3171 rsa_results
[k
][0], rsa_results
[k
][1]);
3174 for (k
= 0; k
< DSA_NUM
; k
++) {
3177 if (testnum
&& !mr
) {
3178 printf("%18ssign verify sign/s verify/s\n", " ");
3182 printf("+F3:%u:%u:%f:%f\n",
3183 k
, dsa_bits
[k
], dsa_results
[k
][0], dsa_results
[k
][1]);
3185 printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
3186 dsa_bits
[k
], 1.0 / dsa_results
[k
][0], 1.0 / dsa_results
[k
][1],
3187 dsa_results
[k
][0], dsa_results
[k
][1]);
3190 for (k
= 0; k
< OSSL_NELEM(ecdsa_doit
); k
++) {
3193 if (testnum
&& !mr
) {
3194 printf("%30ssign verify sign/s verify/s\n", " ");
3199 printf("+F4:%u:%u:%f:%f\n",
3200 k
, ec_curves
[k
].bits
,
3201 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3203 printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3204 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3205 1.0 / ecdsa_results
[k
][0], 1.0 / ecdsa_results
[k
][1],
3206 ecdsa_results
[k
][0], ecdsa_results
[k
][1]);
3210 for (k
= 0; k
< EC_NUM
; k
++) {
3213 if (testnum
&& !mr
) {
3214 printf("%30sop op/s\n", " ");
3218 printf("+F5:%u:%u:%f:%f\n",
3219 k
, ec_curves
[k
].bits
,
3220 ecdh_results
[k
][0], 1.0 / ecdh_results
[k
][0]);
3223 printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
3224 ec_curves
[k
].bits
, ec_curves
[k
].name
,
3225 1.0 / ecdh_results
[k
][0], ecdh_results
[k
][0]);
3229 for (k
= 0; k
< OSSL_NELEM(eddsa_doit
); k
++) {
3232 if (testnum
&& !mr
) {
3233 printf("%30ssign verify sign/s verify/s\n", " ");
3238 printf("+F6:%u:%u:%s:%f:%f\n",
3239 k
, ed_curves
[k
].bits
, ed_curves
[k
].name
,
3240 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3242 printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3243 ed_curves
[k
].bits
, ed_curves
[k
].name
,
3244 1.0 / eddsa_results
[k
][0], 1.0 / eddsa_results
[k
][1],
3245 eddsa_results
[k
][0], eddsa_results
[k
][1]);
3248 #ifndef OPENSSL_NO_SM2
3250 for (k
= 0; k
< OSSL_NELEM(sm2_doit
); k
++) {
3253 if (testnum
&& !mr
) {
3254 printf("%30ssign verify sign/s verify/s\n", " ");
3259 printf("+F7:%u:%u:%s:%f:%f\n",
3260 k
, sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3261 sm2_results
[k
][0], sm2_results
[k
][1]);
3263 printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
3264 sm2_curves
[k
].bits
, sm2_curves
[k
].name
,
3265 1.0 / sm2_results
[k
][0], 1.0 / sm2_results
[k
][1],
3266 sm2_results
[k
][0], sm2_results
[k
][1]);
3269 #ifndef OPENSSL_NO_DH
3271 for (k
= 0; k
< FFDH_NUM
; k
++) {
3274 if (testnum
&& !mr
) {
3275 printf("%23sop op/s\n", " ");
3279 printf("+F8:%u:%u:%f:%f\n",
3280 k
, ffdh_params
[k
].bits
,
3281 ffdh_results
[k
][0], 1.0 / ffdh_results
[k
][0]);
3284 printf("%4u bits ffdh %8.4fs %8.1f\n",
3285 ffdh_params
[k
].bits
,
3286 1.0 / ffdh_results
[k
][0], ffdh_results
[k
][0]);
3288 #endif /* OPENSSL_NO_DH */
3293 ERR_print_errors(bio_err
);
3294 for (i
= 0; i
< loopargs_len
; i
++) {
3295 OPENSSL_free(loopargs
[i
].buf_malloc
);
3296 OPENSSL_free(loopargs
[i
].buf2_malloc
);
3299 EVP_PKEY_CTX_free(genctx
);
3300 for (k
= 0; k
< RSA_NUM
; k
++) {
3301 EVP_PKEY_CTX_free(loopargs
[i
].rsa_sign_ctx
[k
]);
3302 EVP_PKEY_CTX_free(loopargs
[i
].rsa_verify_ctx
[k
]);
3304 #ifndef OPENSSL_NO_DH
3305 OPENSSL_free(loopargs
[i
].secret_ff_a
);
3306 OPENSSL_free(loopargs
[i
].secret_ff_b
);
3307 for (k
= 0; k
< FFDH_NUM
; k
++)
3308 EVP_PKEY_CTX_free(loopargs
[i
].ffdh_ctx
[k
]);
3310 for (k
= 0; k
< DSA_NUM
; k
++) {
3311 EVP_PKEY_CTX_free(loopargs
[i
].dsa_sign_ctx
[k
]);
3312 EVP_PKEY_CTX_free(loopargs
[i
].dsa_verify_ctx
[k
]);
3314 for (k
= 0; k
< ECDSA_NUM
; k
++) {
3315 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_sign_ctx
[k
]);
3316 EVP_PKEY_CTX_free(loopargs
[i
].ecdsa_verify_ctx
[k
]);
3318 for (k
= 0; k
< EC_NUM
; k
++)
3319 EVP_PKEY_CTX_free(loopargs
[i
].ecdh_ctx
[k
]);
3320 for (k
= 0; k
< EdDSA_NUM
; k
++) {
3321 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx
[k
]);
3322 EVP_MD_CTX_free(loopargs
[i
].eddsa_ctx2
[k
]);
3324 #ifndef OPENSSL_NO_SM2
3325 for (k
= 0; k
< SM2_NUM
; k
++) {
3326 EVP_PKEY_CTX
*pctx
= NULL
;
3328 /* free signing ctx */
3329 if (loopargs
[i
].sm2_ctx
[k
] != NULL
3330 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_ctx
[k
])) != NULL
)
3331 EVP_PKEY_CTX_free(pctx
);
3332 EVP_MD_CTX_free(loopargs
[i
].sm2_ctx
[k
]);
3333 /* free verification ctx */
3334 if (loopargs
[i
].sm2_vfy_ctx
[k
] != NULL
3335 && (pctx
= EVP_MD_CTX_get_pkey_ctx(loopargs
[i
].sm2_vfy_ctx
[k
])) != NULL
)
3336 EVP_PKEY_CTX_free(pctx
);
3337 EVP_MD_CTX_free(loopargs
[i
].sm2_vfy_ctx
[k
]);
3339 EVP_PKEY_free(loopargs
[i
].sm2_pkey
[k
]);
3342 OPENSSL_free(loopargs
[i
].secret_a
);
3343 OPENSSL_free(loopargs
[i
].secret_b
);
3345 OPENSSL_free(evp_hmac_name
);
3346 OPENSSL_free(evp_cmac_name
);
3348 if (async_jobs
> 0) {
3349 for (i
= 0; i
< loopargs_len
; i
++)
3350 ASYNC_WAIT_CTX_free(loopargs
[i
].wait_ctx
);
3354 ASYNC_cleanup_thread();
3356 OPENSSL_free(loopargs
);
3358 EVP_CIPHER_free(evp_cipher
);
3364 static void print_message(const char *s
, long num
, int length
, int tm
)
3367 mr
? "+DT:%s:%d:%d\n"
3368 : "Doing %s for %ds on %d size blocks: ", s
, tm
, length
);
3369 (void)BIO_flush(bio_err
);
3374 static void pkey_print_message(const char *str
, const char *str2
, long num
,
3375 unsigned int bits
, int tm
)
3378 mr
? "+DTP:%d:%s:%s:%d\n"
3379 : "Doing %u bits %s %s's for %ds: ", bits
, str
, str2
, tm
);
3380 (void)BIO_flush(bio_err
);
3385 static void print_result(int alg
, int run_no
, int count
, double time_used
)
3388 BIO_printf(bio_err
, "%s error!\n", names
[alg
]);
3389 ERR_print_errors(bio_err
);
3393 mr
? "+R:%d:%s:%f\n"
3394 : "%d %s's in %.2fs\n", count
, names
[alg
], time_used
);
3395 results
[alg
][run_no
] = ((double)count
) / time_used
* lengths
[run_no
];
3399 static char *sstrsep(char **string
, const char *delim
)
3402 char *token
= *string
;
3407 memset(isdelim
, 0, sizeof(isdelim
));
3411 isdelim
[(unsigned char)(*delim
)] = 1;
3415 while (!isdelim
[(unsigned char)(**string
)])
3426 static int do_multi(int multi
, int size_num
)
3431 static char sep
[] = ":";
3433 fds
= app_malloc(sizeof(*fds
) * multi
, "fd buffer for do_multi");
3434 for (n
= 0; n
< multi
; ++n
) {
3435 if (pipe(fd
) == -1) {
3436 BIO_printf(bio_err
, "pipe failure\n");
3440 (void)BIO_flush(bio_err
);
3447 if (dup(fd
[1]) == -1) {
3448 BIO_printf(bio_err
, "dup failed\n");
3457 printf("Forked child %d\n", n
);
3460 /* for now, assume the pipe is long enough to take all the output */
3461 for (n
= 0; n
< multi
; ++n
) {
3466 f
= fdopen(fds
[n
], "r");
3467 while (fgets(buf
, sizeof(buf
), f
)) {
3468 p
= strchr(buf
, '\n');
3471 if (buf
[0] != '+') {
3473 "Don't understand line '%s' from child %d\n", buf
,
3477 printf("Got: %s from %d\n", buf
, n
);
3479 if (CHECK_AND_SKIP_PREFIX(p
, "+F:")) {
3483 alg
= atoi(sstrsep(&p
, sep
));
3485 for (j
= 0; j
< size_num
; ++j
)
3486 results
[alg
][j
] += atof(sstrsep(&p
, sep
));
3487 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F2:")) {
3491 k
= atoi(sstrsep(&p
, sep
));
3494 d
= atof(sstrsep(&p
, sep
));
3495 rsa_results
[k
][0] += d
;
3497 d
= atof(sstrsep(&p
, sep
));
3498 rsa_results
[k
][1] += d
;
3499 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F3:")) {
3503 k
= atoi(sstrsep(&p
, sep
));
3506 d
= atof(sstrsep(&p
, sep
));
3507 dsa_results
[k
][0] += d
;
3509 d
= atof(sstrsep(&p
, sep
));
3510 dsa_results
[k
][1] += d
;
3511 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F4:")) {
3515 k
= atoi(sstrsep(&p
, sep
));
3518 d
= atof(sstrsep(&p
, sep
));
3519 ecdsa_results
[k
][0] += d
;
3521 d
= atof(sstrsep(&p
, sep
));
3522 ecdsa_results
[k
][1] += d
;
3523 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F5:")) {
3527 k
= atoi(sstrsep(&p
, sep
));
3530 d
= atof(sstrsep(&p
, sep
));
3531 ecdh_results
[k
][0] += d
;
3532 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F6:")) {
3536 k
= atoi(sstrsep(&p
, sep
));
3540 d
= atof(sstrsep(&p
, sep
));
3541 eddsa_results
[k
][0] += d
;
3543 d
= atof(sstrsep(&p
, sep
));
3544 eddsa_results
[k
][1] += d
;
3545 # ifndef OPENSSL_NO_SM2
3546 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F7:")) {
3550 k
= atoi(sstrsep(&p
, sep
));
3554 d
= atof(sstrsep(&p
, sep
));
3555 sm2_results
[k
][0] += d
;
3557 d
= atof(sstrsep(&p
, sep
));
3558 sm2_results
[k
][1] += d
;
3559 # endif /* OPENSSL_NO_SM2 */
3560 # ifndef OPENSSL_NO_DH
3561 } else if (CHECK_AND_SKIP_PREFIX(p
, "+F8:")) {
3565 k
= atoi(sstrsep(&p
, sep
));
3568 d
= atof(sstrsep(&p
, sep
));
3569 ffdh_results
[k
][0] += d
;
3570 # endif /* OPENSSL_NO_DH */
3571 } else if (!HAS_PREFIX(buf
, "+H:")) {
3572 BIO_printf(bio_err
, "Unknown type '%s' from child %d\n", buf
,
3584 static void multiblock_speed(const EVP_CIPHER
*evp_cipher
, int lengths_single
,
3585 const openssl_speed_sec_t
*seconds
)
3587 static const int mblengths_list
[] =
3588 { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
3589 const int *mblengths
= mblengths_list
;
3590 int j
, count
, keylen
, num
= OSSL_NELEM(mblengths_list
);
3591 const char *alg_name
;
3592 unsigned char *inp
= NULL
, *out
= NULL
, *key
, no_key
[32], no_iv
[16];
3593 EVP_CIPHER_CTX
*ctx
= NULL
;
3596 if (lengths_single
) {
3597 mblengths
= &lengths_single
;
3601 inp
= app_malloc(mblengths
[num
- 1], "multiblock input buffer");
3602 out
= app_malloc(mblengths
[num
- 1] + 1024, "multiblock output buffer");
3603 if ((ctx
= EVP_CIPHER_CTX_new()) == NULL
)
3604 app_bail_out("failed to allocate cipher context\n");
3605 if (!EVP_EncryptInit_ex(ctx
, evp_cipher
, NULL
, NULL
, no_iv
))
3606 app_bail_out("failed to initialise cipher context\n");
3608 if ((keylen
= EVP_CIPHER_CTX_get_key_length(ctx
)) < 0) {
3609 BIO_printf(bio_err
, "Impossible negative key length: %d\n", keylen
);
3612 key
= app_malloc(keylen
, "evp_cipher key");
3613 if (EVP_CIPHER_CTX_rand_key(ctx
, key
) <= 0)
3614 app_bail_out("failed to generate random cipher key\n");
3615 if (!EVP_EncryptInit_ex(ctx
, NULL
, NULL
, key
, NULL
))
3616 app_bail_out("failed to set cipher key\n");
3617 OPENSSL_clear_free(key
, keylen
);
3619 if (EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_SET_MAC_KEY
,
3620 sizeof(no_key
), no_key
) <= 0)
3621 app_bail_out("failed to set AEAD key\n");
3622 if ((alg_name
= EVP_CIPHER_get0_name(evp_cipher
)) == NULL
)
3623 app_bail_out("failed to get cipher name\n");
3625 for (j
= 0; j
< num
; j
++) {
3626 print_message(alg_name
, 0, mblengths
[j
], seconds
->sym
);
3628 for (count
= 0; run
&& count
< INT_MAX
; count
++) {
3629 unsigned char aad
[EVP_AEAD_TLS1_AAD_LEN
];
3630 EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param
;
3631 size_t len
= mblengths
[j
];
3634 memset(aad
, 0, 8); /* avoid uninitialized values */
3635 aad
[8] = 23; /* SSL3_RT_APPLICATION_DATA */
3636 aad
[9] = 3; /* version */
3638 aad
[11] = 0; /* length */
3640 mb_param
.out
= NULL
;
3643 mb_param
.interleave
= 8;
3645 packlen
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD
,
3646 sizeof(mb_param
), &mb_param
);
3652 (void)EVP_CIPHER_CTX_ctrl(ctx
,
3653 EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT
,
3654 sizeof(mb_param
), &mb_param
);
3658 RAND_bytes(out
, 16);
3660 aad
[11] = (unsigned char)(len
>> 8);
3661 aad
[12] = (unsigned char)(len
);
3662 pad
= EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_AEAD_TLS1_AAD
,
3663 EVP_AEAD_TLS1_AAD_LEN
, aad
);
3664 EVP_Cipher(ctx
, out
, inp
, len
+ pad
);
3668 BIO_printf(bio_err
, mr
? "+R:%d:%s:%f\n"
3669 : "%d %s's in %.2fs\n", count
, "evp", d
);
3670 results
[D_EVP
][j
] = ((double)count
) / d
* mblengths
[j
];
3674 fprintf(stdout
, "+H");
3675 for (j
= 0; j
< num
; j
++)
3676 fprintf(stdout
, ":%d", mblengths
[j
]);
3677 fprintf(stdout
, "\n");
3678 fprintf(stdout
, "+F:%d:%s", D_EVP
, alg_name
);
3679 for (j
= 0; j
< num
; j
++)
3680 fprintf(stdout
, ":%.2f", results
[D_EVP
][j
]);
3681 fprintf(stdout
, "\n");
3684 "The 'numbers' are in 1000s of bytes per second processed.\n");
3685 fprintf(stdout
, "type ");
3686 for (j
= 0; j
< num
; j
++)
3687 fprintf(stdout
, "%7d bytes", mblengths
[j
]);
3688 fprintf(stdout
, "\n");
3689 fprintf(stdout
, "%-24s", alg_name
);
3691 for (j
= 0; j
< num
; j
++) {
3692 if (results
[D_EVP
][j
] > 10000)
3693 fprintf(stdout
, " %11.2fk", results
[D_EVP
][j
] / 1e3
);
3695 fprintf(stdout
, " %11.2f ", results
[D_EVP
][j
]);
3697 fprintf(stdout
, "\n");
3703 EVP_CIPHER_CTX_free(ctx
);