diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-02-18 10:48:18 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-02-24 16:53:18 +0100 |
commit | f3ccfc76fe3b73190e3de60fb8c8c39d88203db1 (patch) | |
tree | a65fb90f5869c82fd9b89bb972ed399522e4bd89 /apps | |
parent | a89cd8d87c48b1d3561ce74af79e1d4fbaa034b7 (diff) |
speed: Use EVP for ciphers, cmac, ghash, rsa, dsa, and ecdsa
Fixes #13909
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14228)
Diffstat (limited to 'apps')
-rw-r--r-- | apps/speed.c | 1632 | ||||
-rw-r--r-- | apps/testdsa.h | 47 |
2 files changed, 656 insertions, 1023 deletions
diff --git a/apps/speed.c b/apps/speed.c index db83a5c6a1..b015b239c5 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -9,14 +9,16 @@ */ #undef SECONDS -#define SECONDS 3 -#define RSA_SECONDS 10 -#define DSA_SECONDS 10 -#define ECDSA_SECONDS 10 -#define ECDH_SECONDS 10 -#define EdDSA_SECONDS 10 -#define SM2_SECONDS 10 -#define FFDH_SECONDS 10 +#define SECONDS 3 +#define PKEY_SECONDS 10 + +#define RSA_SECONDS PKEY_SECONDS +#define DSA_SECONDS PKEY_SECONDS +#define ECDSA_SECONDS PKEY_SECONDS +#define ECDH_SECONDS PKEY_SECONDS +#define EdDSA_SECONDS PKEY_SECONDS +#define SM2_SECONDS PKEY_SECONDS +#define FFDH_SECONDS PKEY_SECONDS /* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED @@ -32,6 +34,7 @@ #include <openssl/err.h> #include <openssl/evp.h> #include <openssl/objects.h> +#include <openssl/core_names.h> #include <openssl/async.h> #if !defined(OPENSSL_SYS_MSDOS) # include <unistd.h> @@ -54,51 +57,26 @@ #ifndef OPENSSL_NO_DEPRECATED_3_0 #include <openssl/aes.h> #endif -#ifndef OPENSSL_NO_CAMELLIA -# include <openssl/camellia.h> -#endif #ifndef OPENSSL_NO_MD2 # include <openssl/md2.h> #endif -#ifndef OPENSSL_NO_CMAC -#include <openssl/cmac.h> -#endif #ifndef OPENSSL_NO_RC4 # include <openssl/rc4.h> #endif -#ifndef OPENSSL_NO_RC5 -# include <openssl/rc5.h> -#endif -#ifndef OPENSSL_NO_RC2 -# include <openssl/rc2.h> -#endif #ifndef OPENSSL_NO_IDEA # include <openssl/idea.h> #endif -#ifndef OPENSSL_NO_SEED -# include <openssl/seed.h> -#endif #ifndef OPENSSL_NO_BF # include <openssl/blowfish.h> #endif -#ifndef OPENSSL_NO_CAST -# include <openssl/cast.h> -#endif -#ifndef OPENSSL_NO_DEPRECATED_3_0 -# include <openssl/rsa.h> -# include "./testrsa.h" -#endif +#include <openssl/rsa.h> +#include "./testrsa.h" #ifndef OPENSSL_NO_DH # include <openssl/dh.h> #endif #include <openssl/x509.h> -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) -# include <openssl/dsa.h> -# include "./testdsa.h" -#endif -#ifndef OPENSSL_NO_EC -# include <openssl/ec.h> -#endif +#include <openssl/dsa.h> +#include "./testdsa.h" #include <openssl/modes.h> #ifndef HAVE_FORK @@ -120,6 +98,10 @@ #define MISALIGN 64 #define MAX_FFDH_SIZE 1024 +#ifndef RSA_DEFAULT_PRIME_NUM +# define RSA_DEFAULT_PRIME_NUM 2 +#endif + typedef struct openssl_speed_sec_st { int sym; int rsa; @@ -138,13 +120,8 @@ static int usertime = 1; static double Time_F(int s); static void print_message(const char *s, long num, int length, int tm); -#if !defined(OPENSSL_NO_DEPRECATED_3_0) \ - || !defined(OPENSSL_NO_DSA) \ - || !defined(OPENSSL_NO_DH) \ - || !defined(OPENSSL_NO_EC) static void pkey_print_message(const char *str, const char *str2, long num, unsigned int bits, int sec); -#endif static void print_result(int alg, int run_no, int count, double time_used); #ifndef NO_FORK static int do_multi(int multi, int size_num); @@ -276,12 +253,8 @@ const OPTIONS speed_options[] = { OPT_SECTION("Selection"), {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, -#ifndef OPENSSL_NO_DEPRECATED_3_0 {"hmac", OPT_HMAC, 's', "HMAC using EVP-named digest"}, -#endif -#if !defined(OPENSSL_NO_CMAC) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"cmac", OPT_CMAC, 's', "CMAC using EVP-named cipher"}, -#endif {"decrypt", OPT_DECRYPT, '-', "Time decryption instead of encryption (only EVP)"}, {"aead", OPT_AEAD, '-', @@ -308,23 +281,21 @@ const OPTIONS speed_options[] = { enum { D_MD2, D_MDC2, D_MD4, D_MD5, D_SHA1, D_RMD160, D_SHA256, D_SHA512, D_WHIRLPOOL, D_HMAC, - D_RC4, D_CBC_DES, D_EDE3_DES, D_CBC_IDEA, D_CBC_SEED, + D_CBC_DES, D_EDE3_DES, D_RC4, D_CBC_IDEA, D_CBC_SEED, D_CBC_RC2, D_CBC_RC5, D_CBC_BF, D_CBC_CAST, D_CBC_128_AES, D_CBC_192_AES, D_CBC_256_AES, D_CBC_128_CML, D_CBC_192_CML, D_CBC_256_CML, - D_EVP, D_IGE_128_AES, D_IGE_192_AES, D_IGE_256_AES, - D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM + D_EVP, D_GHASH, D_RAND, D_EVP_CMAC, ALGOR_NUM }; /* name of algorithms to test. MUST BE KEEP IN SYNC with above enum ! */ static const char *names[ALGOR_NUM] = { "md2", "mdc2", "md4", "md5", "sha1", "rmd160", "sha256", "sha512", "whirlpool", "hmac(md5)", - "rc4", "des cbc", "des ede3", "idea cbc", "seed cbc", - "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc", - "aes-128 cbc", "aes-192 cbc", "aes-256 cbc", - "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc", - "evp", "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash", - "rand", "cmac" + "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc", + "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc", + "aes-128-cbc", "aes-192-cbc", "aes-256-cbc", + "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc", + "evp", "ghash", "rand", "cmac" }; /* list of configured algorithm (remaining), with some few alias */ @@ -341,54 +312,35 @@ static const OPT_PAIR doit_choices[] = { {"ripemd", D_RMD160}, {"rmd160", D_RMD160}, {"ripemd160", D_RMD160}, -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"rc4", D_RC4}, -#endif -#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"des-cbc", D_CBC_DES}, {"des-ede3", D_EDE3_DES}, -#endif -#ifndef OPENSSL_NO_DEPRECATED_3_0 {"aes-128-cbc", D_CBC_128_AES}, {"aes-192-cbc", D_CBC_192_AES}, {"aes-256-cbc", D_CBC_256_AES}, - {"aes-128-ige", D_IGE_128_AES}, - {"aes-192-ige", D_IGE_192_AES}, - {"aes-256-ige", D_IGE_256_AES}, -#endif -#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) + {"camellia-128-cbc", D_CBC_128_CML}, + {"camellia-192-cbc", D_CBC_192_CML}, + {"camellia-256-cbc", D_CBC_256_CML}, {"rc2-cbc", D_CBC_RC2}, {"rc2", D_CBC_RC2}, -#endif -#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"rc5-cbc", D_CBC_RC5}, {"rc5", D_CBC_RC5}, -#endif -#if !defined(OPENSSL_NO_IDEA) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"idea-cbc", D_CBC_IDEA}, {"idea", D_CBC_IDEA}, -#endif -#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"seed-cbc", D_CBC_SEED}, {"seed", D_CBC_SEED}, -#endif -#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"bf-cbc", D_CBC_BF}, {"blowfish", D_CBC_BF}, {"bf", D_CBC_BF}, -#endif -#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) {"cast-cbc", D_CBC_CAST}, {"cast", D_CBC_CAST}, {"cast5", D_CBC_CAST}, -#endif {"ghash", D_GHASH}, {"rand", D_RAND} }; static double results[ALGOR_NUM][SIZE_NUM]; -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) enum { R_DSA_512, R_DSA_1024, R_DSA_2048, DSA_NUM }; static const OPT_PAIR dsa_choices[DSA_NUM] = { {"dsa512", R_DSA_512}, @@ -396,9 +348,7 @@ static const OPT_PAIR dsa_choices[DSA_NUM] = { {"dsa2048", R_DSA_2048} }; static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */ -#endif /* OPENSSL_NO_DSA */ -#ifndef OPENSSL_NO_DEPRECATED_3_0 enum { R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_7680, R_RSA_15360, RSA_NUM @@ -414,7 +364,6 @@ static const OPT_PAIR rsa_choices[RSA_NUM] = { }; static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ -#endif /* OPENSSL_NO_DEPRECATED_3_0 */ #ifndef OPENSSL_NO_DH enum ff_params_t { @@ -432,13 +381,12 @@ static const OPT_PAIR ffdh_choices[FFDH_NUM] = { static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */ #endif /* OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_EC enum ec_curves_t { R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M R_EC_K163, R_EC_K233, R_EC_K283, R_EC_K409, R_EC_K571, R_EC_B163, R_EC_B233, R_EC_B283, R_EC_B409, R_EC_B571, -# endif +#endif R_EC_BRP256R1, R_EC_BRP256T1, R_EC_BRP384R1, R_EC_BRP384T1, R_EC_BRP512R1, R_EC_BRP512T1, ECDSA_NUM }; @@ -450,7 +398,7 @@ static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = { {"ecdsap256", R_EC_P256}, {"ecdsap384", R_EC_P384}, {"ecdsap521", R_EC_P521}, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M {"ecdsak163", R_EC_K163}, {"ecdsak233", R_EC_K233}, {"ecdsak283", R_EC_K283}, @@ -461,7 +409,7 @@ static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = { {"ecdsab283", R_EC_B283}, {"ecdsab409", R_EC_B409}, {"ecdsab571", R_EC_B571}, -# endif +#endif {"ecdsabrp256r1", R_EC_BRP256R1}, {"ecdsabrp256t1", R_EC_BRP256T1}, {"ecdsabrp384r1", R_EC_BRP384R1}, @@ -478,7 +426,7 @@ static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhp256", R_EC_P256}, {"ecdhp384", R_EC_P384}, {"ecdhp521", R_EC_P521}, -# ifndef OPENSSL_NO_EC2M +#ifndef OPENSSL_NO_EC2M {"ecdhk163", R_EC_K163}, {"ecdhk233", R_EC_K233}, {"ecdhk283", R_EC_K283}, @@ -489,7 +437,7 @@ static const OPT_PAIR ecdh_choices[EC_NUM] = { {"ecdhb283", R_EC_B283}, {"ecdhb409", R_EC_B409}, {"ecdhb571", R_EC_B571}, -# endif +#endif {"ecdhbrp256r1", R_EC_BRP256R1}, {"ecdhbrp256t1", R_EC_BRP256T1}, {"ecdhbrp384r1", R_EC_BRP384R1}, @@ -511,16 +459,15 @@ static const OPT_PAIR eddsa_choices[EdDSA_NUM] = { }; static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */ -# ifndef OPENSSL_NO_SM2 +#ifndef OPENSSL_NO_SM2 enum { R_EC_CURVESM2, SM2_NUM }; static const OPT_PAIR sm2_choices[SM2_NUM] = { {"curveSM2", R_EC_CURVESM2} }; -# define SM2_ID "TLSv1.3+GM+Cipher+Suite" -# define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1 +# define SM2_ID "TLSv1.3+GM+Cipher+Suite" +# define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1 static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */ -# endif /* OPENSSL_NO_SM2 */ -#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_SM2 */ #define COND(unused_cond) (run && count<0x7fffffff) #define COUNT(d) (count) @@ -533,30 +480,24 @@ typedef struct loopargs_st { unsigned char *buf_malloc; unsigned char *buf2_malloc; unsigned char *key; - unsigned int siglen; size_t sigsize; -#ifndef OPENSSL_NO_DEPRECATED_3_0 - RSA *rsa_key[RSA_NUM]; -#endif -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - DSA *dsa_key[DSA_NUM]; -#endif -#ifndef OPENSSL_NO_EC -# ifndef OPENSSL_NO_DEPRECATED_3_0 - EC_KEY *ecdsa[ECDSA_NUM]; -# endif + EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM]; + EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM]; + EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM]; + EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM]; + EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM]; + EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM]; EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM]; -# ifndef OPENSSL_NO_SM2 +#ifndef OPENSSL_NO_SM2 EVP_MD_CTX *sm2_ctx[SM2_NUM]; EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM]; EVP_PKEY *sm2_pkey[SM2_NUM]; -# endif +#endif unsigned char *secret_a; unsigned char *secret_b; size_t outlen[EC_NUM]; -#endif #ifndef OPENSSL_NO_DH EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM]; unsigned char *secret_ff_a; @@ -564,10 +505,6 @@ typedef struct loopargs_st { #endif EVP_CIPHER_CTX *ctx; EVP_MAC_CTX *mctx; -#if !defined(OPENSSL_NO_CMAC) && !defined(OPENSSL_NO_DEPRECATED_3_0) - CMAC_CTX *cmac_ctx; -#endif - GCM128_CONTEXT *gcm_ctx; } loopargs_t; static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs); @@ -580,6 +517,8 @@ static long c[ALGOR_NUM][SIZE_NUM]; static char *evp_mac_mdname = "md5"; static char *evp_hmac_name = NULL; static const char *evp_md_name = NULL; +static char *evp_mac_ciphername = "aes-128-cbc"; +static char *evp_cmac_name = NULL; static EVP_MD *obtain_md(const char *name, int *fetched) { @@ -601,14 +540,55 @@ static EVP_MD *obtain_md(const char *name, int *fetched) static int have_md(const char *name) { int fetched = 0; + int ret = 0; EVP_MD *md = obtain_md(name, &fetched); if (md != NULL) { + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + + if (ctx != NULL && EVP_DigestInit(ctx, md) > 0) + ret = 1; + EVP_MD_CTX_free(ctx); if (fetched) EVP_MD_free(md); - return 1; } - return 0; + return ret; +} + +static EVP_CIPHER *obtain_cipher(const char *name, int *fetched) +{ + EVP_CIPHER *cipher = NULL; + + *fetched = 0; + /* Look through providers' digests */ + ERR_set_mark(); + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + ERR_pop_to_mark(); + if (cipher != NULL) { + *fetched = 1; + return cipher; + } + + return (EVP_CIPHER *)EVP_get_cipherbyname(name); +} + +static int have_cipher(const char *name) +{ + int fetched = 0; + int ret = 0; + EVP_CIPHER *cipher = obtain_cipher(name, &fetched); + + if (cipher != NULL) { + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + if (ctx != NULL + && EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) > 0) + ret = 1; + EVP_CIPHER_CTX_free(ctx); + if (fetched) + EVP_CIPHER_free(cipher); + } + return ret; } static int EVP_Digest_loop(const char *mdname, int algindex, void *args) @@ -617,20 +597,10 @@ static int EVP_Digest_loop(const char *mdname, int algindex, void *args) unsigned char *buf = tempargs->buf; unsigned char digest[EVP_MAX_MD_SIZE]; int count, fetched = 0; - EVP_MD *md = NULL; - - /* Look through providers' digests */ - ERR_set_mark(); - md = EVP_MD_fetch(NULL, mdname, NULL); - ERR_pop_to_mark(); - if (md != NULL) - fetched = 1; - else - md = (EVP_MD *)EVP_get_digestbyname(mdname); + EVP_MD *md = obtain_md(mdname, &fetched); if (md == NULL) return -1; - for (count = 0; COND(c[algindex][testnum]); count++) { if (!EVP_Digest(buf, (size_t)lengths[testnum], digest, NULL, md, NULL)) { @@ -668,7 +638,7 @@ static int MD5_loop(void *args) return EVP_Digest_loop("md5", D_MD5, args); } -static int HMAC_loop(void *args) +static int EVP_MAC_loop(int algindex, void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; @@ -676,7 +646,7 @@ static int HMAC_loop(void *args) unsigned char mac[EVP_MAX_MD_SIZE]; int count; - for (count = 0; COND(c[D_HMAC][testnum]); count++) { + for (count = 0; COND(c[algindex][testnum]); count++) { size_t outl; if (!EVP_MAC_init(mctx) || !EVP_MAC_update(mctx, buf, lengths[testnum]) @@ -686,6 +656,16 @@ static int HMAC_loop(void *args) return count; } +static int HMAC_loop(void *args) +{ + return EVP_MAC_loop(D_HMAC, args); +} + +static int CMAC_loop(void *args) +{ + return EVP_MAC_loop(D_EVP_CMAC, args); +} + static int SHA1_loop(void *args) { return EVP_Digest_loop("sha1", D_SHA1, args); @@ -711,131 +691,75 @@ static int EVP_Digest_RMD160_loop(void *args) return EVP_Digest_loop("ripemd160", D_RMD160, args); } -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_DEPRECATED_3_0) -static RC4_KEY rc4_ks; -static int RC4_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_RC4][testnum]); count++) - RC4(&rc4_ks, (size_t)lengths[testnum], buf, buf); - return count; -} -#endif +static int algindex; -#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) -static unsigned char DES_iv[8]; -static DES_key_schedule sch[3]; -static int DES_ncbc_encrypt_loop(void *args) +static int EVP_Cipher_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; int count; - for (count = 0; COND(c[D_CBC_DES][testnum]); count++) - DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch[0], - &DES_iv, DES_ENCRYPT); + + if (tempargs->ctx == NULL) + return -1; + for (count = 0; COND(c[algindex][testnum]); count++) + if (EVP_Cipher(tempargs->ctx, buf, buf, (size_t)lengths[testnum]) <= 0) + return -1; return count; } -static int DES_ede3_cbc_encrypt_loop(void *args) +static int GHASH_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; + EVP_MAC_CTX *mctx = tempargs->mctx; int count; - for (count = 0; COND(c[D_EDE3_DES][testnum]); count++) - DES_ede3_cbc_encrypt(buf, buf, lengths[testnum], - &sch[0], &sch[1], &sch[2], &DES_iv, DES_ENCRYPT); + + /* just do the update in the loop to be comparable with 1.1.1 */ + for (count = 0; COND(c[D_GHASH][testnum]); count++) { + if (!EVP_MAC_update(mctx, buf, lengths[testnum])) + return -1; + } return count; } -#endif + #define MAX_BLOCK_SIZE 128 static unsigned char iv[2 * MAX_BLOCK_SIZE / 8]; -#ifndef OPENSSL_NO_DEPRECATED_3_0 -static AES_KEY aes_ks1, aes_ks2, aes_ks3; -static int AES_cbc_128_encrypt_loop(void *args) +static EVP_CIPHER_CTX *init_evp_cipher_ctx(const char *ciphername, + const unsigned char *key, + int keylen) { - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_128_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT); - return count; -} + EVP_CIPHER_CTX *ctx = NULL; + int fetched = 0; + EVP_CIPHER *cipher = obtain_cipher(ciphername, &fetched); -static int AES_cbc_192_encrypt_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_192_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT); - return count; -} + if (cipher == NULL) + return NULL; -static int AES_cbc_256_encrypt_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - int count; - for (count = 0; COND(c[D_CBC_256_AES][testnum]); count++) - AES_cbc_encrypt(buf, buf, - (size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT); - return count; -} + if ((ctx = EVP_CIPHER_CTX_new()) == NULL) + goto end; -static int AES_ige_128_encrypt_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; - int count; - for (count = 0; COND(c[D_IGE_128_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT); - return count; -} + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1)) { + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + goto end; + } -static int AES_ige_192_encrypt_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; - int count; - for (count = 0; COND(c[D_IGE_192_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT); - return count; -} + EVP_CIPHER_CTX_set_key_length(ctx, keylen); -static int AES_ige_256_encrypt_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - unsigned char *buf2 = tempargs->buf2; - int count; - for (count = 0; COND(c[D_IGE_256_AES][testnum]); count++) - AES_ige_encrypt(buf, buf2, - (size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT); - return count; -} + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1)) { + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + goto end; + } -static int CRYPTO_gcm128_aad_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - GCM128_CONTEXT *gcm_ctx = tempargs->gcm_ctx; - int count; - for (count = 0; COND(c[D_GHASH][testnum]); count++) - CRYPTO_gcm128_aad(gcm_ctx, buf, lengths[testnum]); - return count; +end: + if (fetched) + EVP_CIPHER_free(cipher); + return ctx; } -#endif static int RAND_bytes_loop(void *args) { @@ -950,31 +874,6 @@ static int EVP_Update_loop_aead(void *args) return count; } -#if !defined(OPENSSL_NO_CMAC) && !defined(OPENSSL_NO_DEPRECATED_3_0) -static const EVP_CIPHER *evp_cmac_cipher = NULL; -static char *evp_cmac_name = NULL; - -static int EVP_CMAC_loop(void *args) -{ - loopargs_t *tempargs = *(loopargs_t **) args; - unsigned char *buf = tempargs->buf; - CMAC_CTX *cmac_ctx = tempargs->cmac_ctx; - static const char key[16] = "This is a key..."; - unsigned char mac[16]; - size_t len = sizeof(mac); - int count; - - for (count = 0; COND(c[D_EVP_CMAC][testnum]); count++) { - if (!CMAC_Init(cmac_ctx, key, sizeof(key), evp_cmac_cipher, NULL) - || !CMAC_Update(cmac_ctx, buf, lengths[testnum]) - || !CMAC_Final(cmac_ctx, mac, &len)) - return -1; - } - return count; -} -#endif - -#ifndef OPENSSL_NO_DEPRECATED_3_0 static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */ static int RSA_sign_loop(void *args) @@ -982,12 +881,12 @@ static int RSA_sign_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - unsigned int *rsa_num = &tempargs->siglen; - RSA **rsa_key = tempargs->rsa_key; + size_t *rsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **rsa_sign_ctx = tempargs->rsa_sign_ctx; int ret, count; for (count = 0; COND(rsa_c[testnum][0]); count++) { - ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]); - if (ret == 0) { + ret = EVP_PKEY_sign(rsa_sign_ctx[testnum], buf2, rsa_num, buf, 36); + if (ret <= 0) { BIO_printf(bio_err, "RSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1002,12 +901,11 @@ static int RSA_verify_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - unsigned int rsa_num = tempargs->siglen; - RSA **rsa_key = tempargs->rsa_key; + size_t rsa_num = tempargs->sigsize; + EVP_PKEY_CTX **rsa_verify_ctx = tempargs->rsa_verify_ctx; int ret, count; for (count = 0; COND(rsa_c[testnum][1]); count++) { - ret = - RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]); + ret = EVP_PKEY_verify(rsa_verify_ctx[testnum], buf2, rsa_num, buf, 36); if (ret <= 0) { BIO_printf(bio_err, "RSA verify failure\n"); ERR_print_errors(bio_err); @@ -1017,7 +915,6 @@ static int RSA_verify_loop(void *args) } return count; } -#endif #ifndef OPENSSL_NO_DH static long ffdh_c[FFDH_NUM][1]; @@ -1037,19 +934,18 @@ static int FFDH_derive_key_loop(void *args) } #endif /* OPENSSL_NO_DH */ -#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) static long dsa_c[DSA_NUM][2]; static int DSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - DSA **dsa_key = tempargs->dsa_key; - unsigned int *siglen = &tempargs->siglen; + size_t *dsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **dsa_sign_ctx = tempargs->dsa_sign_ctx; int ret, count; for (count = 0; COND(dsa_c[testnum][0]); count++) { - ret = DSA_sign(0, buf, 20, buf2, siglen, dsa_key[testnum]); - if (ret == 0) { + ret = EVP_PKEY_sign(dsa_sign_ctx[testnum], buf2, dsa_num, buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "DSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1064,11 +960,11 @@ static int DSA_verify_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; unsigned char *buf2 = tempargs->buf2; - DSA **dsa_key = tempargs->dsa_key; - unsigned int siglen = tempargs->siglen; + size_t dsa_num = tempargs->sigsize; + EVP_PKEY_CTX **dsa_verify_ctx = tempargs->dsa_verify_ctx; int ret, count; for (count = 0; COND(dsa_c[testnum][1]); count++) { - ret = DSA_verify(0, buf, 20, buf2, siglen, dsa_key[testnum]); + ret = EVP_PKEY_verify(dsa_verify_ctx[testnum], buf2, dsa_num, buf, 20); if (ret <= 0) { BIO_printf(bio_err, "DSA verify failure\n"); ERR_print_errors(bio_err); @@ -1078,22 +974,19 @@ static int DSA_verify_loop(void *args) } return count; } -#endif -#ifndef OPENSSL_NO_EC -# ifndef OPENSSL_NO_DEPRECATED_3_0 static long ecdsa_c[ECDSA_NUM][2]; static int ECDSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EC_KEY **ecdsa = tempargs->ecdsa; - unsigned char *ecdsasig = tempargs->buf2; - unsigned int *ecdsasiglen = &tempargs->siglen; + unsigned char *buf2 = tempargs->buf2; + size_t *ecdsa_num = &tempargs->sigsize; + EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx; int ret, count; for (count = 0; COND(ecdsa_c[testnum][0]); count++) { - ret = ECDSA_sign(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]); - if (ret == 0) { + ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "ECDSA sign failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1107,13 +1000,13 @@ static int ECDSA_verify_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EC_KEY **ecdsa = tempargs->ecdsa; - unsigned char *ecdsasig = tempargs->buf2; - unsigned int ecdsasiglen = tempargs->siglen; + unsigned char *buf2 = tempargs->buf2; + size_t ecdsa_num = tempargs->sigsize; + EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx; int ret, count; for (count = 0; COND(ecdsa_c[testnum][1]); count++) { - ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]); - if (ret != 1) { + ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num, buf, 20); + if (ret <= 0) { BIO_printf(bio_err, "ECDSA verify failure\n"); ERR_print_errors(bio_err); count = -1; @@ -1122,7 +1015,6 @@ static int ECDSA_verify_loop(void *args) } return count; } -# endif /* ******************************************************************** */ static long ecdh_c[EC_NUM][1]; @@ -1184,7 +1076,7 @@ static int EdDSA_verify_loop(void *args) return count; } -# ifndef OPENSSL_NO_SM2 +#ifndef OPENSSL_NO_SM2 static long sm2_c[SM2_NUM][2]; static int SM2_sign_loop(void *args) { @@ -1251,8 +1143,7 @@ static int SM2_verify_loop(void *args) } return count; } -# endif /* OPENSSL_NO_SM2 */ -#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_SM2 */ static int run_benchmark(int async_jobs, int (*loop_function) (void *), loopargs_t * loopargs) @@ -1405,22 +1296,84 @@ static int run_benchmark(int async_jobs, return error ? -1 : total_op_count; } -static int fetched_alg = 0; +typedef struct ec_curve_st { + const char *name; + unsigned int nid; + unsigned int bits; + size_t sigsize; /* only used for EdDSA curves */ +} EC_CURVE; -static EVP_CIPHER *obtain_cipher(const char *name) +static EVP_PKEY *get_ecdsa(const EC_CURVE *curve) { - EVP_CIPHER *cipher = NULL; + EVP_PKEY_CTX *kctx = NULL; + EVP_PKEY *key = NULL; - /* Look through providers' ciphers */ - ERR_set_mark(); - cipher = EVP_CIPHER_fetch(NULL, name, NULL); - ERR_pop_to_mark(); - if (cipher != NULL) { - fetched_alg = 1; - return cipher; + /* Ensure that the error queue is empty */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); } - return (EVP_CIPHER *)EVP_get_cipherbyname(name); + /* + * Let's try to create a ctx directly from the NID: this works for + * curves like Curve25519 that are not implemented through the low + * level EC interface. + * If this fails we try creating a EVP_PKEY_EC generic param ctx, + * then we set the curve by NID before deriving the actual keygen + * ctx for that specific curve. + */ + kctx = EVP_PKEY_CTX_new_id(curve->nid, NULL); + if (kctx == NULL) { + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *params = NULL; + /* + * If we reach this code EVP_PKEY_CTX_new_id() failed and a + * "int_ctx_new:unsupported algorithm" error was added to the + * error queue. + * We remove it from the error queue as we are handling it. + */ + unsigned long error = ERR_peek_error(); + + if (error == ERR_peek_last_error() /* oldest and latest errors match */ + /* check that the error origin matches */ + && ERR_GET_LIB(error) == ERR_LIB_EVP + && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM + || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED)) + ERR_get_error(); /* pop error from queue */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "Unhandled error in the error queue during EC key setup.\n"); + ERR_print_errors(bio_err); + return NULL; + } + + /* Create the context for parameter generation */ + if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL + || EVP_PKEY_paramgen_init(pctx) <= 0 + || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, + curve->nid) <= 0 + || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { + BIO_printf(bio_err, "EC params init failure.\n"); + ERR_print_errors(bio_err); + EVP_PKEY_CTX_free(pctx); + return NULL; + } + EVP_PKEY_CTX_free(pctx); + + /* Create the context for the key generation */ + kctx = EVP_PKEY_CTX_new(params, NULL); + EVP_PKEY_free(params); + } + if (kctx == NULL + || EVP_PKEY_keygen_init(kctx) <= 0 + || EVP_PKEY_keygen(kctx, &key) <= 0) { + BIO_printf(bio_err, "EC key generation failure.\n"); + ERR_print_errors(bio_err); + key = NULL; + } + EVP_PKEY_CTX_free(kctx); + return key; } #define stop_it(do_it, test_num)\ @@ -1443,60 +1396,29 @@ int speed_main(int argc, char **argv) unsigned int i, k, loopargs_len = 0, async_jobs = 0; int keylen; int buflen; + int fetched_cipher = 0; + BIGNUM *bn = NULL; + EVP_PKEY_CTX *genctx = NULL; #ifndef NO_FORK int multi = 0; #endif -#if !defined(OPENSSL_NO_DEPRECATED_3_0) \ - || !defined(OPENSSL_NO_DSA) \ - || !defined(OPENSSL_NO_DH) \ - || !defined(OPENSSL_NO_EC) - long op_count = 1; -#endif + long op_count = 1; openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, ECDH_SECONDS, EdDSA_SECONDS, SM2_SECONDS, FFDH_SECONDS }; - /* What follows are the buffers and key material. */ -#if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) - RC5_32_KEY rc5_ks; -#endif -#if !defined(OPENSSL_NO_RC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) - RC2_KEY rc2_ks; -#endif -#if !defined(OPENSSL_NO_IDEA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - IDEA_KEY_SCHEDULE idea_ks; -#endif -#if !defined(OPENSSL_NO_SEED) && !defined(OPENSSL_NO_DEPRECATED_3_0) - SEED_KEY_SCHEDULE seed_ks; -#endif -#if !defined(OPENSSL_NO_BF) && !defined(OPENSSL_NO_DEPRECATED_3_0) - BF_KEY bf_ks; -#endif -#if !defined(OPENSSL_NO_CAST) && !defined(OPENSSL_NO_DEPRECATED_3_0) - CAST_KEY cast_ks; -#endif -#ifndef OPENSSL_NO_DEPRECATED_3_0 - static const unsigned char key16[16] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 - }; - static const unsigned char key24[24] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 - }; static const unsigned char key32[32] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56 }; -#endif -#if !defined(OPENSSL_NO_CAMELLIA) && !defined(OPENSSL_NO_DEPRECATED_3_0) - CAMELLIA_KEY camellia_ks[3]; -#endif -#ifndef OPENSSL_NO_DEPRECATED_3_0 + static const unsigned char deskey[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, /* key1 */ + 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, /* key2 */ + 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 /* key3 */ + }; static const struct { const unsigned char |