X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fspeed.c;h=a4879179e4142844bdd86d35111590dd7fb3b336;hp=79e4f5c3af0a52f2befbeec4dc24318a1649f6f9;hb=52307f94f8f3e5a1cd392f0a48802a24ccf73ba2;hpb=64daf14d9cc54a61f0392fdd6e1b71e475fb7a96 diff --git a/apps/speed.c b/apps/speed.c index 79e4f5c3af..a4879179e4 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the OpenSSL license (the "License"). You may not use @@ -14,12 +14,14 @@ #define DSA_SECONDS 10 #define ECDSA_SECONDS 10 #define ECDH_SECONDS 10 +#define EdDSA_SECONDS 10 #include #include #include #include #include "apps.h" +#include "progs.h" #include #include #include @@ -112,54 +114,23 @@ #endif #define MAX_MISALIGNMENT 63 - -#define ALGOR_NUM 31 -#define RSA_NUM 7 -#define DSA_NUM 3 - -#define EC_NUM 17 #define MAX_ECDH_SIZE 256 #define MISALIGN 64 -typedef struct sec_st { +typedef struct openssl_speed_sec_st { int sym; int rsa; int dsa; int ecdsa; int ecdh; -} SEC; + int eddsa; +} openssl_speed_sec_t; static volatile int run = 0; static int mr = 0; static int usertime = 1; -typedef struct loopargs_st { - ASYNC_JOB *inprogress_job; - ASYNC_WAIT_CTX *wait_ctx; - unsigned char *buf; - unsigned char *buf2; - unsigned char *buf_malloc; - unsigned char *buf2_malloc; - unsigned int siglen; -#ifndef OPENSSL_NO_RSA - RSA *rsa_key[RSA_NUM]; -#endif -#ifndef OPENSSL_NO_DSA - DSA *dsa_key[DSA_NUM]; -#endif -#ifndef OPENSSL_NO_EC - EC_KEY *ecdsa[EC_NUM]; - EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; - unsigned char *secret_a; - unsigned char *secret_b; - size_t outlen[EC_NUM]; -#endif - EVP_CIPHER_CTX *ctx; - HMAC_CTX *hctx; - GCM128_CONTEXT *gcm_ctx; -} loopargs_t; - #ifndef OPENSSL_NO_MD2 static int EVP_Digest_MD2_loop(void *args); #endif @@ -200,6 +171,7 @@ static int CRYPTO_gcm128_aad_loop(void *args); static int RAND_bytes_loop(void *args); static int EVP_Update_loop(void *args); static int EVP_Update_loop_ccm(void *args); +static int EVP_Update_loop_aead(void *args); static int EVP_Digest_loop(void *args); #ifndef OPENSSL_NO_RSA static int RSA_sign_loop(void *args); @@ -212,14 +184,14 @@ static int DSA_verify_loop(void *args); #ifndef OPENSSL_NO_EC static int ECDSA_sign_loop(void *args); static int ECDSA_verify_loop(void *args); +static int EdDSA_sign_loop(void *args); +static int EdDSA_verify_loop(void *args); #endif -static int run_benchmark(int async_jobs, int (*loop_function) (void *), - loopargs_t * loopargs); static double Time_F(int s); static void print_message(const char *s, long num, int length, int tm); static void pkey_print_message(const char *str, const char *str2, - long num, int bits, int sec); + long num, unsigned int bits, int sec); 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); @@ -228,57 +200,35 @@ static int do_multi(int multi, int size_num); static const int lengths_list[] = { 16, 64, 256, 1024, 8 * 1024, 16 * 1024 }; -static int lengths_single = 0; - static const int *lengths = lengths_list; -static const char *names[ALGOR_NUM] = { - "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "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", "sha256", "sha512", "whirlpool", - "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash", - "rand" +static const int aead_lengths_list[] = { + 2, 31, 136, 1024, 8 * 1024, 16 * 1024 }; -static double results[ALGOR_NUM][OSSL_NELEM(lengths_list)]; - -#ifndef OPENSSL_NO_RSA -static double rsa_results[RSA_NUM][2]; -#endif -#ifndef OPENSSL_NO_DSA -static double dsa_results[DSA_NUM][2]; -#endif -#ifndef OPENSSL_NO_EC -static double ecdsa_results[EC_NUM][2]; -static double ecdh_results[EC_NUM][1]; -#endif +#define START 0 +#define STOP 1 #ifdef SIGALRM -# if defined(__STDC__) || defined(sgi) || defined(_AIX) -# define SIGRETTYPE void -# else -# define SIGRETTYPE int -# endif -static SIGRETTYPE sig_done(int sig); -static SIGRETTYPE sig_done(int sig) +static void alarmed(int sig) { - signal(SIGALRM, sig_done); + signal(SIGALRM, alarmed); run = 0; } -#endif -#define START 0 -#define STOP 1 +static double Time_F(int s) +{ + double ret = app_tminterval(s, usertime); + if (s == STOP) + alarm(0); + return ret; +} -#if defined(_WIN32) +#elif defined(_WIN32) + +# define SIGALRM -1 -# if !defined(SIGALRM) -# define SIGALRM -# endif static unsigned int lapse; static volatile unsigned int schlock; static void alarm_win32(unsigned int secs) @@ -322,22 +272,23 @@ static double Time_F(int s) return ret; } #else - static double Time_F(int s) { - double ret = app_tminterval(s, usertime); - if (s == STOP) - alarm(0); - return ret; + return app_tminterval(s, usertime); } #endif -static void multiblock_speed(const EVP_CIPHER *evp_cipher, - const SEC *seconds); +static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, + const openssl_speed_sec_t *seconds); -static int found(const char *name, const OPT_PAIR *pairs, int *result) +#define found(value, pairs, result)\ + opt_found(value, result, pairs, OSSL_NELEM(pairs)) +static int opt_found(const char *name, unsigned int *result, + const OPT_PAIR pairs[], unsigned int nbelem) { - for (; pairs->name; pairs++) + unsigned int idx; + + for (idx = 0; idx < nbelem; ++idx, pairs++) if (strcmp(name, pairs->name) == 0) { *result = pairs->retval; return 1; @@ -349,39 +300,42 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, - OPT_PRIMES, OPT_SECONDS, OPT_BYTES + OPT_PRIMES, OPT_SECONDS, OPT_BYTES, OPT_AEAD } OPTION_CHOICE; const OPTIONS speed_options[] = { {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"}, {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, {"help", OPT_HELP, '-', "Display this summary"}, - {"evp", OPT_EVP, 's', "Use specified EVP cipher"}, + {"evp", OPT_EVP, 's', "Use EVP-named cipher or digest"}, {"decrypt", OPT_DECRYPT, '-', "Time decryption instead of encryption (only EVP)"}, - {"mr", OPT_MR, '-', "Produce machine readable output"}, + {"aead", OPT_AEAD, '-', + "Benchmark EVP-named AEAD cipher in TLS-like sequence"}, {"mb", OPT_MB, '-', - "Enable (tls1.1) multi-block mode on evp_cipher requested with -evp"}, - {"misalign", OPT_MISALIGN, 'n', "Amount to mis-align buffers"}, - {"elapsed", OPT_ELAPSED, '-', - "Measure time in real time instead of CPU user time"}, + "Enable (tls1>=1) multi-block mode on EVP-named cipher"}, + {"mr", OPT_MR, '-', "Produce machine readable output"}, #ifndef NO_FORK {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"}, #endif #ifndef OPENSSL_NO_ASYNC {"async_jobs", OPT_ASYNCJOBS, 'p', - "Enable async mode and start pnum jobs"}, + "Enable async mode and start specified number of jobs"}, #endif OPT_R_OPTIONS, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"elapsed", OPT_ELAPSED, '-', + "Use wall-clock time instead of CPU user time as divisor"}, {"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"}, {"seconds", OPT_SECONDS, 'p', - "Run benchmarks for pnum seconds"}, + "Run benchmarks for specified amount of seconds"}, {"bytes", OPT_BYTES, 'p', - "Run cipher, digest and rand benchmarks on pnum bytes"}, - {NULL}, + "Run [non-PKI] benchmarks on custom-sized buffer"}, + {"misalign", OPT_MISALIGN, 'p', + "Use specified offset to mis-align buffers"}, + {NULL} }; #define D_MD2 0 @@ -415,7 +369,21 @@ const OPTIONS speed_options[] = { #define D_IGE_256_AES 28 #define D_GHASH 29 #define D_RAND 30 -static OPT_PAIR doit_choices[] = { +/* name of algorithms to test */ +static const char *names[] = { + "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "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", "sha256", "sha512", "whirlpool", + "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash", + "rand" +}; +#define ALGOR_NUM OSSL_NELEM(names) + +/* list of configured algorithm (remaining) */ +static const OPT_PAIR doit_choices[] = { #ifndef OPENSSL_NO_MD2 {"md2", D_MD2}, #endif @@ -480,21 +448,24 @@ static OPT_PAIR doit_choices[] = { {"cast5", D_CBC_CAST}, #endif {"ghash", D_GHASH}, - {"rand", D_RAND}, - {NULL} + {"rand", D_RAND} }; +static double results[ALGOR_NUM][OSSL_NELEM(lengths_list)]; + #ifndef OPENSSL_NO_DSA # define R_DSA_512 0 # define R_DSA_1024 1 # define R_DSA_2048 2 -static OPT_PAIR dsa_choices[] = { +static const OPT_PAIR dsa_choices[] = { {"dsa512", R_DSA_512}, {"dsa1024", R_DSA_1024}, - {"dsa2048", R_DSA_2048}, - {NULL}, + {"dsa2048", R_DSA_2048} }; -#endif +# define DSA_NUM OSSL_NELEM(dsa_choices) + +static double dsa_results[DSA_NUM][2]; /* 2 ops: sign then verify */ +#endif /* OPENSSL_NO_DSA */ #define R_RSA_512 0 #define R_RSA_1024 1 @@ -503,16 +474,20 @@ static OPT_PAIR dsa_choices[] = { #define R_RSA_4096 4 #define R_RSA_7680 5 #define R_RSA_15360 6 -static OPT_PAIR rsa_choices[] = { +#ifndef OPENSSL_NO_RSA +static const OPT_PAIR rsa_choices[] = { {"rsa512", R_RSA_512}, {"rsa1024", R_RSA_1024}, {"rsa2048", R_RSA_2048}, {"rsa3072", R_RSA_3072}, {"rsa4096", R_RSA_4096}, {"rsa7680", R_RSA_7680}, - {"rsa15360", R_RSA_15360}, - {NULL} + {"rsa15360", R_RSA_15360} }; +# define RSA_NUM OSSL_NELEM(rsa_choices) + +static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ +#endif /* OPENSSL_NO_RSA */ #define R_EC_P160 0 #define R_EC_P192 1 @@ -530,7 +505,14 @@ static OPT_PAIR rsa_choices[] = { #define R_EC_B283 13 #define R_EC_B409 14 #define R_EC_B571 15 -#define R_EC_X25519 16 +#define R_EC_BRP256R1 16 +#define R_EC_BRP256T1 17 +#define R_EC_BRP384R1 18 +#define R_EC_BRP384T1 19 +#define R_EC_BRP512R1 20 +#define R_EC_BRP512T1 21 +#define R_EC_X25519 22 +#define R_EC_X448 23 #ifndef OPENSSL_NO_EC static OPT_PAIR ecdsa_choices[] = { {"ecdsap160", R_EC_P160}, @@ -549,10 +531,18 @@ static OPT_PAIR ecdsa_choices[] = { {"ecdsab283", R_EC_B283}, {"ecdsab409", R_EC_B409}, {"ecdsab571", R_EC_B571}, - {NULL} + {"ecdsabrp256r1", R_EC_BRP256R1}, + {"ecdsabrp256t1", R_EC_BRP256T1}, + {"ecdsabrp384r1", R_EC_BRP384R1}, + {"ecdsabrp384t1", R_EC_BRP384T1}, + {"ecdsabrp512r1", R_EC_BRP512R1}, + {"ecdsabrp512t1", R_EC_BRP512T1} }; +# define ECDSA_NUM OSSL_NELEM(ecdsa_choices) + +static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */ -static OPT_PAIR ecdh_choices[] = { +static const OPT_PAIR ecdh_choices[] = { {"ecdhp160", R_EC_P160}, {"ecdhp192", R_EC_P192}, {"ecdhp224", R_EC_P224}, @@ -569,10 +559,29 @@ static OPT_PAIR ecdh_choices[] = { {"ecdhb283", R_EC_B283}, {"ecdhb409", R_EC_B409}, {"ecdhb571", R_EC_B571}, + {"ecdhbrp256r1", R_EC_BRP256R1}, + {"ecdhbrp256t1", R_EC_BRP256T1}, + {"ecdhbrp384r1", R_EC_BRP384R1}, + {"ecdhbrp384t1", R_EC_BRP384T1}, + {"ecdhbrp512r1", R_EC_BRP512R1}, + {"ecdhbrp512t1", R_EC_BRP512T1}, {"ecdhx25519", R_EC_X25519}, - {NULL} + {"ecdhx448", R_EC_X448} }; -#endif +# define EC_NUM OSSL_NELEM(ecdh_choices) + +static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */ + +#define R_EC_Ed25519 0 +#define R_EC_Ed448 1 +static OPT_PAIR eddsa_choices[] = { + {"ed25519", R_EC_Ed25519}, + {"ed448", R_EC_Ed448} +}; +# define EdDSA_NUM OSSL_NELEM(eddsa_choices) + +static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */ +#endif /* OPENSSL_NO_EC */ #ifndef SIGALRM # define COND(d) (count < (d)) @@ -582,7 +591,38 @@ static OPT_PAIR ecdh_choices[] = { # define COUNT(d) (count) #endif /* SIGALRM */ -static int testnum; +typedef struct loopargs_st { + ASYNC_JOB *inprogress_job; + ASYNC_WAIT_CTX *wait_ctx; + unsigned char *buf; + unsigned char *buf2; + unsigned char *buf_malloc; + unsigned char *buf2_malloc; + unsigned char *key; + unsigned int siglen; + size_t sigsize; +#ifndef OPENSSL_NO_RSA + RSA *rsa_key[RSA_NUM]; +#endif +#ifndef OPENSSL_NO_DSA + DSA *dsa_key[DSA_NUM]; +#endif +#ifndef OPENSSL_NO_EC + EC_KEY *ecdsa[ECDSA_NUM]; + EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; + EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; + unsigned char *secret_a; + unsigned char *secret_b; + size_t outlen[EC_NUM]; +#endif + EVP_CIPHER_CTX *ctx; + HMAC_CTX *hctx; + GCM128_CONTEXT *gcm_ctx; +} loopargs_t; +static int run_benchmark(int async_jobs, int (*loop_function) (void *), + loopargs_t * loopargs); + +static unsigned int testnum; /* Nb of iterations to do per algorithm and key-size */ static long c[ALGOR_NUM][OSSL_NELEM(lengths_list)]; @@ -872,22 +912,34 @@ static int EVP_Update_loop(void *args) loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; EVP_CIPHER_CTX *ctx = tempargs->ctx; - int outl, count; + int outl, count, rc; #ifndef SIGALRM int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; #endif - if (decrypt) - for (count = 0; COND(nb_iter); count++) - EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - else - for (count = 0; COND(nb_iter); count++) - EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + if (decrypt) { + for (count = 0; COND(nb_iter); count++) { + rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + if (rc != 1) { + /* reset iv in case of counter overflow */ + EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); + } + } + } else { + for (count = 0; COND(nb_iter); count++) { + rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + if (rc != 1) { + /* reset iv in case of counter overflow */ + EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); + } + } + } if (decrypt) EVP_DecryptFinal_ex(ctx, buf, &outl); else EVP_EncryptFinal_ex(ctx, buf, &outl); return count; } + /* * CCM does not support streaming. For the purpose of performance measurement, * each message is encrypted using the same (key,iv)-pair. Do not use this @@ -905,18 +957,58 @@ static int EVP_Update_loop_ccm(void *args) #endif if (decrypt) { for (count = 0; COND(nb_iter); count++) { - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag); - EVP_DecryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); + /* reset iv */ + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); + /* counter is reset on every update */ EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - EVP_DecryptFinal_ex(ctx, buf, &outl); } } else { for (count = 0; COND(nb_iter); count++) { - EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); + /* restore iv length field */ EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]); + /* counter is reset on every update */ + EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + } + } + if (decrypt) + EVP_DecryptFinal_ex(ctx, buf, &outl); + else + EVP_EncryptFinal_ex(ctx, buf, &outl); + return count; +} + +/* + * To make AEAD benchmarking more relevant perform TLS-like operations, + * 13-byte AAD followed by payload. But don't use TLS-formatted AAD, as + * payload length is not actually limited by 16KB... + */ +static int EVP_Update_loop_aead(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_CIPHER_CTX *ctx = tempargs->ctx; + int outl, count; + unsigned char aad[13] = { 0xcc }; + unsigned char faketag[16] = { 0xcc }; +#ifndef SIGALRM + int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; +#endif + if (decrypt) { + for (count = 0; COND(nb_iter); count++) { + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + sizeof(faketag), faketag); + EVP_DecryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); + EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + EVP_DecryptFinal_ex(ctx, buf + outl, &outl); + } + } else { + for (count = 0; COND(nb_iter); count++) { + EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); + EVP_EncryptUpdate(ctx, NULL, &outl, aad, sizeof(aad)); EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - EVP_EncryptFinal_ex(ctx, buf, &outl); + EVP_EncryptFinal_ex(ctx, buf + outl, &outl); } } return count; @@ -1029,7 +1121,7 @@ static int DSA_verify_loop(void *args) #endif #ifndef OPENSSL_NO_EC -static long ecdsa_c[EC_NUM][2]; +static long ecdsa_c[ECDSA_NUM][2]; static int ECDSA_sign_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; @@ -1087,6 +1179,48 @@ static int ECDH_EVP_derive_key_loop(void *args) return count; } +static long eddsa_c[EdDSA_NUM][2]; +static int EdDSA_sign_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_MD_CTX **edctx = tempargs->eddsa_ctx; + unsigned char *eddsasig = tempargs->buf2; + size_t *eddsasigsize = &tempargs->sigsize; + int ret, count; + + for (count = 0; COND(eddsa_c[testnum][0]); count++) { + ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20); + if (ret == 0) { + BIO_printf(bio_err, "EdDSA sign failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + return count; +} + +static int EdDSA_verify_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_MD_CTX **edctx = tempargs->eddsa_ctx; + unsigned char *eddsasig = tempargs->buf2; + size_t eddsasigsize = tempargs->sigsize; + int ret, count; + + for (count = 0; COND(eddsa_c[testnum][1]); count++) { + ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20); + if (ret != 1) { + BIO_printf(bio_err, "EdDSA verify failure\n"); + ERR_print_errors(bio_err); + count = -1; + break; + } + } + return count; +} #endif /* OPENSSL_NO_EC */ static int run_benchmark(int async_jobs, @@ -1245,28 +1379,30 @@ static int run_benchmark(int async_jobs, int speed_main(int argc, char **argv) { ENGINE *e = NULL; - int (*loopfunc)(void *args); loopargs_t *loopargs = NULL; - int async_init = 0; - int loopargs_len = 0; - char *prog; + const char *prog; const char *engine_id = NULL; const EVP_CIPHER *evp_cipher = NULL; double d = 0.0; OPTION_CHOICE o; - int multiblock = 0, pr_header = 0; + int async_init = 0, multiblock = 0, pr_header = 0; int doit[ALGOR_NUM] = { 0 }; - int ret = 1, i, k, misalign = 0; + int ret = 1, misalign = 0, lengths_single = 0, aead = 0; long count = 0; - int size_num = OSSL_NELEM(lengths_list); + unsigned int size_num = OSSL_NELEM(lengths_list); + unsigned int i, k, loop, loopargs_len = 0, async_jobs = 0; + int keylen; + int buflen; #ifndef NO_FORK int multi = 0; #endif - unsigned int async_jobs = 0; #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) \ || !defined(OPENSSL_NO_EC) long rsa_count = 1; #endif + openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, + ECDSA_SECONDS, ECDH_SECONDS, + EdDSA_SECONDS }; /* What follows are the buffers and key material. */ #ifndef OPENSSL_NO_RC5 @@ -1351,48 +1487,58 @@ int speed_main(int argc, char **argv) /* * We only test over the following curves as they are representative, To * add tests over more curves, simply add the curve NID and curve name to - * the following arrays and increase the EC_NUM value accordingly. + * the following arrays and increase the |ecdh_choices| list accordingly. */ - static const unsigned int test_curves[EC_NUM] = { + static const struct { + const char *name; + unsigned int nid; + unsigned int bits; + } test_curves[] = { /* Prime Curves */ - NID_secp160r1, NID_X9_62_prime192v1, NID_secp224r1, - NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, + {"secp160r1", NID_secp160r1, 160}, + {"nistp192", NID_X9_62_prime192v1, 192}, + {"nistp224", NID_secp224r1, 224}, + {"nistp256", NID_X9_62_prime256v1, 256}, + {"nistp384", NID_secp384r1, 384}, + {"nistp521", NID_secp521r1, 521}, /* Binary Curves */ - NID_sect163k1, NID_sect233k1, NID_sect283k1, - NID_sect409k1, NID_sect571k1, NID_sect163r2, - NID_sect233r1, NID_sect283r1, NID_sect409r1, - NID_sect571r1, - /* Other */ - NID_X25519 + {"nistk163", NID_sect163k1, 163}, + {"nistk233", NID_sect233k1, 233}, + {"nistk283", NID_sect283k1, 283}, + {"nistk409", NID_sect409k1, 409}, + {"nistk571", NID_sect571k1, 571}, + {"nistb163", NID_sect163r2, 163}, + {"nistb233", NID_sect233r1, 233}, + {"nistb283", NID_sect283r1, 283}, + {"nistb409", NID_sect409r1, 409}, + {"nistb571", NID_sect571r1, 571}, + {"brainpoolP256r1", NID_brainpoolP256r1, 256}, + {"brainpoolP256t1", NID_brainpoolP256t1, 256}, + {"brainpoolP384r1", NID_brainpoolP384r1, 384}, + {"brainpoolP384t1", NID_brainpoolP384t1, 384}, + {"brainpoolP512r1", NID_brainpoolP512r1, 512}, + {"brainpoolP512t1", NID_brainpoolP512t1, 512}, + /* Other and ECDH only ones */ + {"X25519", NID_X25519, 253}, + {"X448", NID_X448, 448} }; - static const char *test_curves_names[EC_NUM] = { - /* Prime Curves */ - "secp160r1", "nistp192", "nistp224", - "nistp256", "nistp384", "nistp521", - /* Binary Curves */ - "nistk163", "nistk233", "nistk283", - "nistk409", "nistk571", "nistb163", - "nistb233", "nistb283", "nistb409", - "nistb571", - /* Other */ - "X25519" + static const struct { + const char *name; + unsigned int nid; + unsigned int bits; + size_t sigsize; + } test_ed_curves[] = { + /* EdDSA */ + {"Ed25519", NID_ED25519, 253, 64}, + {"Ed448", NID_ED448, 456, 114} }; - static const int test_curves_bits[EC_NUM] = { - 160, 192, 224, - 256, 384, 521, - 163, 233, 283, - 409, 571, 163, - 233, 283, 409, - 571, 253 /* X25519 */ - }; - - int ecdsa_doit[EC_NUM] = { 0 }; + int ecdsa_doit[ECDSA_NUM] = { 0 }; int ecdh_doit[EC_NUM] = { 0 }; + int eddsa_doit[EdDSA_NUM] = { 0 }; + OPENSSL_assert(OSSL_NELEM(test_curves) >= EC_NUM); + OPENSSL_assert(OSSL_NELEM(test_ed_curves) >= EdDSA_NUM); #endif /* ndef OPENSSL_NO_EC */ - SEC seconds = {SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, - ECDH_SECONDS}; - prog = opt_init(argc, argv, speed_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -1447,9 +1593,7 @@ int speed_main(int argc, char **argv) goto opterr; } if (async_jobs > 99999) { - BIO_printf(bio_err, - "%s: too many async_jobs\n", - prog); + BIO_printf(bio_err, "%s: too many async_jobs\n", prog); goto opterr; } #endif @@ -1485,13 +1629,16 @@ int speed_main(int argc, char **argv) break; case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa - = seconds.ecdh = atoi(opt_arg()); + = seconds.ecdh = seconds.eddsa = atoi(opt_arg()); break; case OPT_BYTES: lengths_single = atoi(opt_arg()); lengths = &lengths_single; size_num = 1; break; + case OPT_AEAD: + aead = 1; + break; } } argc = opt_num_rest(); @@ -1517,10 +1664,8 @@ int speed_main(int argc, char **argv) if (strcmp(*argv, "openssl") == 0) continue; if (strcmp(*argv, "rsa") == 0) { - rsa_doit[R_RSA_512] = rsa_doit[R_RSA_1024] = - rsa_doit[R_RSA_2048] = rsa_doit[R_RSA_3072] = - rsa_doit[R_RSA_4096] = rsa_doit[R_RSA_7680] = - rsa_doit[R_RSA_15360] = 1; + for (loop = 0; loop < OSSL_NELEM(rsa_doit); loop++) + rsa_doit[loop] = 1; continue; } if (found(*argv, rsa_choices, &i)) { @@ -1551,8 +1696,8 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_EC if (strcmp(*argv, "ecdsa") == 0) { - for (i = 0; i < EC_NUM; i++) - ecdsa_doit[i] = 1; + for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) + ecdsa_doit[loop] = 1; continue; } if (found(*argv, ecdsa_choices, &i)) { @@ -1560,19 +1705,56 @@ int speed_main(int argc, char **argv) continue; } if (strcmp(*argv, "ecdh") == 0) { - for (i = 0; i < EC_NUM; i++) - ecdh_doit[i] = 1; + for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) + ecdh_doit[loop] = 1; continue; } if (found(*argv, ecdh_choices, &i)) { ecdh_doit[i] = 2; continue; } + if (strcmp(*argv, "eddsa") == 0) { + for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) + eddsa_doit[loop] = 1; + continue; + } + if (found(*argv, eddsa_choices, &i)) { + eddsa_doit[i] = 2; + continue; + } #endif BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv); goto end; } + /* Sanity checks */ + if (aead) { + if (evp_cipher == NULL) { + BIO_printf(bio_err, "-aead can be used only with an AEAD cipher\n"); + goto end; + } else if (!(EVP_CIPHER_flags(evp_cipher) & + EVP_CIPH_FLAG_AEAD_CIPHER)) { + BIO_printf(bio_err, "%s is not an AEAD cipher\n", + OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher))); + goto end; + } + } + if (multiblock) { + if (evp_cipher == NULL) { + BIO_printf(bio_err,"-mb can be used only with a multi-block" + " capable cipher\n"); + goto end; + } else if (!(EVP_CIPHER_flags(evp_cipher) & + EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { + BIO_printf(bio_err, "%s is not a multi-block capable\n", + OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher))); + goto end; + } else if (async_jobs > 0) { + BIO_printf(bio_err, "Async mode is not supported with -mb"); + goto end; + } + } + /* Initialize the job pool if async mode is enabled */ if (async_jobs > 0) { async_init = ASYNC_init_thread(async_jobs, async_jobs); @@ -1596,12 +1778,15 @@ int speed_main(int argc, char **argv) } } - loopargs[i].buf_malloc = - app_malloc(lengths[size_num - 1] + MAX_MISALIGNMENT + 1, - "input buffer"); - loopargs[i].buf2_malloc = - app_malloc(lengths[size_num - 1] + MAX_MISALIGNMENT + 1, - "input buffer"); + buflen = lengths[size_num - 1]; + if (buflen < 36) /* size of random vector in RSA bencmark */ + buflen = 36; + buflen += MAX_MISALIGNMENT + 1; + loopargs[i].buf_malloc = app_malloc(buflen, "input buffer"); + loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer"); + memset(loopargs[i].buf_malloc, 0, buflen); + memset(loopargs[i].buf2_malloc, 0, buflen); + /* Align the start of buffers on a 64 byte boundary */ loopargs[i].buf = loopargs[i].buf_malloc + misalign; loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign; @@ -1633,10 +1818,12 @@ int speed_main(int argc, char **argv) dsa_doit[i] = 1; #endif #ifndef OPENSSL_NO_EC - for (i = 0; i < EC_NUM; i++) - ecdsa_doit[i] = 1; - for (i = 0; i < EC_NUM; i++) - ecdh_doit[i] = 1; + for (loop = 0; loop < OSSL_NELEM(ecdsa_doit); loop++) + ecdsa_doit[loop] = 1; + for (loop = 0; loop < OSSL_NELEM(ecdh_doit); loop++) + ecdh_doit[loop] = 1; + for (loop = 0; loop < OSSL_NELEM(eddsa_doit); loop++) + eddsa_doit[loop] = 1; #endif } for (i = 0; i < ALGOR_NUM; i++) @@ -1906,16 +2093,43 @@ int speed_main(int argc, char **argv) } } } + /* repeated code good to factorize */ + ecdh_c[R_EC_BRP256R1][0] = count / 1000; + for (i = R_EC_BRP384R1; i <= R_EC_BRP512R1; i += 2) { + ecdh_c[i][0] = ecdh_c[i - 2][0] / 2; + if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) + ecdh_doit[i] = 0; + else { + if (ecdh_c[i][0] == 0) { + ecdh_c[i][0] = 1; + } + } + } + ecdh_c[R_EC_BRP256T1][0] = count / 1000; + for (i = R_EC_BRP384T1; i <= R_EC_BRP512T1; i += 2) { + ecdh_c[i][0] = ecdh_c[i - 2][0] / 2; + if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0) + ecdh_doit[i] = 0; + else { + if (ecdh_c[i][0] == 0) { + ecdh_c[i][0] = 1; + } + } + } + /* default iteration count for the last two EC Curves */ + ecdh_c[R_EC_X25519][0] = count / 1800; + ecdh_c[R_EC_X448][0] = count / 7200; + + eddsa_c[R_EC_Ed25519][0] = count / 1800; + eddsa_c[R_EC_Ed448][0] = count / 7200; # endif # else /* not worth fixing */ # error "You cannot disable DES on systems without SIGALRM." # endif /* OPENSSL_NO_DES */ -#else -# ifndef _WIN32 - signal(SIGALRM, sig_done); -# endif +#elif SIGALRM > 0 + signal(SIGALRM, alarmed); #endif /* SIGALRM */ #ifndef OPENSSL_NO_MD2 @@ -2371,49 +2585,46 @@ int speed_main(int argc, char **argv) } if (doit[D_EVP]) { - if (multiblock && evp_cipher) { - if (! - (EVP_CIPHER_flags(evp_cipher) & - EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { - BIO_printf(bio_err, "%s is not multi-block capable\n", - OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher))); + if (evp_cipher != NULL) { + int (*loopfunc)(void *args) = EVP_Update_loop; + + if (multiblock && (EVP_CIPHER_flags(evp_cipher) & + EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) { + multiblock_speed(evp_cipher, lengths_single, &seconds); + ret = 0; goto end; } - if (async_jobs > 0) { - BIO_printf(bio_err, "Async mode is not supported, exiting..."); - exit(1); + + names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)); + + if (EVP_CIPHER_mode(evp_cipher) == EVP_CIPH_CCM_MODE) { + loopfunc = EVP_Update_loop_ccm; + } else if (aead && (EVP_CIPHER_flags(evp_cipher) & + EVP_CIPH_FLAG_AEAD_CIPHER)) { + loopfunc = EVP_Update_loop_aead; + if (lengths == lengths_list) { + lengths = aead_lengths_list; + size_num = OSSL_NELEM(aead_lengths_list); + } } - multiblock_speed(evp_cipher, &seconds); - ret = 0; - goto end; - } - for (testnum = 0; testnum < size_num; testnum++) { - if (evp_cipher) { - names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)); - /* - * -O3 -fschedule-insns messes up an optimization here! - * names[D_EVP] somehow becomes NULL - */ + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_EVP], save_count, lengths[testnum], seconds.sym); for (k = 0; k < loopargs_len; k++) { loopargs[k].ctx = EVP_CIPHER_CTX_new(); - if (decrypt) - EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, - key16, iv); - else - EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, - key16, iv); + EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL, NULL, + iv, decrypt ? 0 : 1); + EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0); - } - switch (EVP_CIPHER_mode(evp_cipher)) { - case EVP_CIPH_CCM_MODE: - loopfunc = EVP_Update_loop_ccm; - break; - default: - loopfunc = EVP_Update_loop; + + keylen = EVP_CIPHER_CTX_key_length(loopargs[k].ctx); + loopargs[k].key = app_malloc(keylen, "evp_cipher key"); + EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key); + EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL, + loopargs[k].key, NULL, -1); + OPENSSL_clear_free(loopargs[k].key, keylen); } Time_F(START); @@ -2422,21 +2633,25 @@ int speed_main(int argc, char **argv) for (k = 0; k < loopargs_len; k++) { EVP_CIPHER_CTX_free(loopargs[k].ctx); } + print_result(D_EVP, testnum, count, d); } - if (evp_md) { - names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md)); + } else if (evp_md != NULL) { + names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md)); + + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_EVP], save_count, lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs); d = Time_F(STOP); + print_result(D_EVP, testnum, count, d); } - print_result(D_EVP, testnum, count, d); } } for (i = 0; i < loopargs_len; i++) - RAND_bytes(loopargs[i].buf, 36); + if (RAND_bytes(loopargs[i].buf, 36) <= 0) + goto end; #ifndef OPENSSL_NO_RSA for (testnum = 0; testnum < RSA_NUM; testnum++) { @@ -2492,7 +2707,7 @@ int speed_main(int argc, char **argv) d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n" - : "%ld %d bit private RSA's in %.2fs\n", + : "%ld %u bits private RSA's in %.2fs\n", count, rsa_bits[testnum], d); rsa_results[testnum][0] = (double)count / d; rsa_count = count; @@ -2518,7 +2733,7 @@ int speed_main(int argc, char **argv) d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n" - : "%ld %d bit public RSA's in %.2fs\n", + : "%ld %u bits public RSA's in %.2fs\n", count, rsa_bits[testnum], d); rsa_results[testnum][1] = (double)count / d; } @@ -2532,7 +2747,8 @@ int speed_main(int argc, char **argv) #endif /* OPENSSL_NO_RSA */ for (i = 0; i < loopargs_len; i++) - RAND_bytes(loopargs[i].buf, 36); + if (RAND_bytes(loopargs[i].buf, 36) <= 0) + goto end; #ifndef OPENSSL_NO_DSA for (testnum = 0; testnum < DSA_NUM; testnum++) { @@ -2561,8 +2777,8 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, DSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R3:%ld:%d:%.2f\n" - : "%ld %d bit DSA signs in %.2fs\n", + mr ? "+R3:%ld:%u:%.2f\n" + : "%ld %u bits DSA signs in %.2fs\n", count, dsa_bits[testnum], d); dsa_results[testnum][0] = (double)count / d; rsa_count = count; @@ -2587,8 +2803,8 @@ int speed_main(int argc, char **argv) count = run_benchmark(async_jobs, DSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R4:%ld:%d:%.2f\n" - : "%ld %d bit DSA verify in %.2fs\n", + mr ? "+R4:%ld:%u:%.2f\n" + : "%ld %u bits DSA verify in %.2fs\n", count, dsa_bits[testnum], d); dsa_results[testnum][1] = (double)count / d; } @@ -2602,14 +2818,14 @@ int speed_main(int argc, char **argv) #endif /* OPENSSL_NO_DSA */ #ifndef OPENSSL_NO_EC - for (testnum = 0; testnum < EC_NUM; testnum++) { + for (testnum = 0; testnum < ECDSA_NUM; testnum++) { int st = 1; if (!ecdsa_doit[testnum]) continue; /* Ignore Curve */ for (i = 0; i < loopargs_len; i++) { loopargs[i].ecdsa[testnum] = - EC_KEY_new_by_curve_name(test_curves[testnum]); + EC_KEY_new_by_curve_name(test_curves[testnum].nid); if (loopargs[i].ecdsa[testnum] == NULL) { st = 0; break; @@ -2638,16 +2854,15 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("sign", "ecdsa", ecdsa_c[testnum][0], - test_curves_bits[testnum], - seconds.ecdsa); + test_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R5:%ld:%d:%.2f\n" : - "%ld %d bit ECDSA signs in %.2fs \n", - count, test_curves_bits[testnum], d); + mr ? "+R5:%ld:%u:%.2f\n" : + "%ld %u bits ECDSA signs in %.2fs \n", + count, test_curves[testnum].bits, d); ecdsa_results[testnum][0] = (double)count / d; rsa_count = count; } @@ -2668,15 +2883,14 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("verify", "ecdsa", ecdsa_c[testnum][1], - test_curves_bits[testnum], - seconds.ecdsa); + test_curves[testnum].bits, seconds.ecdsa); Time_F(START); count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, - mr ? "+R6:%ld:%d:%.2f\n" - : "%ld %d bit ECDSA verify in %.2fs\n", - count, test_curves_bits[testnum], d); + mr ? "+R6:%ld:%u:%.2f\n" + : "%ld %u bits ECDSA verify in %.2fs\n", + count, test_curves[testnum].bits, d); ecdsa_results[testnum][1] = (double)count / d; } @@ -2716,7 +2930,7 @@ int speed_main(int argc, char **argv) * 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(test_curves[testnum], NULL); /* keygen ctx from NID */ + kctx = EVP_PKEY_CTX_new_id(test_curves[testnum].nid, NULL); /* keygen ctx from NID */ if (!kctx) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *params = NULL; @@ -2747,7 +2961,7 @@ int speed_main(int argc, char **argv) /* Set the curve by NID */ !EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, test_curves - [testnum]) || + [testnum].nid) || /* Create the parameter object params */ !EVP_PKEY_paramgen(pctx, ¶ms)) { ecdh_checks = 0; @@ -2819,6 +3033,8 @@ int speed_main(int argc, char **argv) loopargs[i].ecdh_ctx[testnum] = ctx; loopargs[i].outlen[testnum] = outlen; + EVP_PKEY_free(key_A); + EVP_PKEY_free(key_B); EVP_PKEY_CTX_free(kctx); kctx = NULL; EVP_PKEY_CTX_free(test_ctx); @@ -2827,26 +3043,130 @@ int speed_main(int argc, char **argv) if (ecdh_checks != 0) { pkey_print_message("", "ecdh", ecdh_c[testnum][0], - test_curves_bits[testnum], - seconds.ecdh); + test_curves[testnum].bits, seconds.ecdh); Time_F(START); count = run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs); d = Time_F(STOP); BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" : - "%ld %d-bit ECDH ops in %.2fs\n", count, - test_curves_bits[testnum], d); + "%ld %u-bits ECDH ops in %.2fs\n", count, + test_curves[testnum].bits, d); ecdh_results[testnum][0] = (double)count / d; rsa_count = count; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < EC_NUM; testnum++) + for (testnum++; testnum < OSSL_NELEM(ecdh_doit); testnum++) ecdh_doit[testnum] = 0; } } + + for (testnum = 0; testnum < EdDSA_NUM; testnum++) { + int st = 1; + EVP_PKEY *ed_pkey = NULL; + EVP_PKEY_CTX *ed_pctx = NULL; + + if (!eddsa_doit[testnum]) + continue; /* Ignore Curve */ + for (i = 0; i < loopargs_len; i++) { + loopargs[i].eddsa_ctx[testnum] = EVP_MD_CTX_new(); + if (loopargs[i].eddsa_ctx[testnum] == NULL) { + st = 0; + break; + } + + if ((ed_pctx = EVP_PKEY_CTX_new_id(test_ed_curves[testnum].nid, NULL)) + == NULL + || !EVP_PKEY_keygen_init(ed_pctx) + || !EVP_PKEY_keygen(ed_pctx, &ed_pkey)) { + st = 0; + EVP_PKEY_CTX_free(ed_pctx); + break; + } + EVP_PKEY_CTX_free(ed_pctx); + + if (!EVP_DigestSignInit(loopargs[i].eddsa_ctx[testnum], NULL, NULL, + NULL, ed_pkey)) { + st = 0; + EVP_PKEY_free(ed_pkey); + break; + } + EVP_PKEY_free(ed_pkey); + } + if (st == 0) { + BIO_printf(bio_err, "EdDSA failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + } else { + for (i = 0; i < loopargs_len; i++) { + /* Perform EdDSA signature test */ + loopargs[i].sigsize = test_ed_curves[testnum].sigsize; + st = EVP_DigestSign(loopargs[i].eddsa_ctx[testnum], + loopargs[i].buf2, &loopargs[i].sigsize, + loopargs[i].buf, 20); + if (st == 0) + break; + } + if (st == 0) { + BIO_printf(bio_err, + "EdDSA sign failure. No EdDSA sign will be done.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + } else { + pkey_print_message("sign", test_ed_curves[testnum].name, + eddsa_c[testnum][0], + test_ed_curves[testnum].bits, seconds.eddsa); + Time_F(START); + count = run_benchmark(async_jobs, EdDSA_sign_loop, loopargs); + d = Time_F(STOP); + + BIO_printf(bio_err, + mr ? "+R8:%ld:%u:%s:%.2f\n" : + "%ld %u bits %s signs in %.2fs \n", + count, test_ed_curves[testnum].bits, + test_ed_curves[testnum].name, d); + eddsa_results[testnum][0] = (double)count / d; + rsa_count = count; + } + + /* Perform EdDSA verification test */ + for (i = 0; i < loopargs_len; i++) { + st = EVP_DigestVerify(loopargs[i].eddsa_ctx[testnum], + loopargs[i].buf2, loopargs[i].sigsize, + loopargs[i].buf, 20); + if (st != 1) + break; + } + if (st != 1) { + BIO_printf(bio_err, + "EdDSA verify failure. No EdDSA verify will be done.\n"); + ERR_print_errors(bio_err); + eddsa_doit[testnum] = 0; + } else { + pkey_print_message("verify", test_ed_curves[testnum].name, + eddsa_c[testnum][1], + test_ed_curves[testnum].bits, seconds.eddsa); + Time_F(START); + count = run_benchmark(async_jobs, EdDSA_verify_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R9:%ld:%u:%s:%.2f\n" + : "%ld %u bits %s verify in %.2fs\n", + count, test_ed_curves[testnum].bits, + test_ed_curves[testnum].name, d); + eddsa_results[testnum][1] = (double)count / d; + } + + if (rsa_count <= 1) { + /* if longer than 10s, don't do any more */ + for (testnum++; testnum < EdDSA_NUM; testnum++) + eddsa_doit[testnum] = 0; + } + } + } + #endif /* OPENSSL_NO_EC */ #ifndef NO_FORK show_res: @@ -2892,7 +3212,7 @@ int speed_main(int argc, char **argv) if (!doit[k]) continue; if (mr) - printf("+F:%d:%s", k, names[k]); + printf("+F:%u:%s", k, names[k]); else printf("%-13s", names[k]); for (testnum = 0; testnum < size_num; testnum++) { @@ -2941,7 +3261,7 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_EC testnum = 1; - for (k = 0; k < EC_NUM; k++) { + for (k = 0; k < OSSL_NELEM(ecdsa_doit); k++) { if (!ecdsa_doit[k]) continue; if (testnum && !mr) { @@ -2951,12 +3271,11 @@ int speed_main(int argc, char **argv) if (mr) printf("+F4:%u:%u:%f:%f\n", - k, test_curves_bits[k], + k, test_curves[k].bits, ecdsa_results[k][0], ecdsa_results[k][1]); else - printf("%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", - test_curves_bits[k], - test_curves_names[k], + printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", + test_curves[k].bits, test_curves[k].name, 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1], ecdsa_results[k][0], ecdsa_results[k][1]); } @@ -2971,15 +3290,34 @@ int speed_main(int argc, char **argv) } if (mr) printf("+F5:%u:%u:%f:%f\n", - k, test_curves_bits[k], + k, test_curves[k].bits, ecdh_results[k][0], 1.0 / ecdh_results[k][0]); else - printf("%4u bit ecdh (%s) %8.4fs %8.1f\n", - test_curves_bits[k], - test_curves_names[k], + printf("%4u bits ecdh (%s) %8.4fs %8.1f\n", + test_curves[k].bits, test_curves[k].name, 1.0 / ecdh_results[k][0], ecdh_results[k][0]); } + + testnum = 1; + for (k = 0; k < OSSL_NELEM(eddsa_doit); k++) { + if (!eddsa_doit[k]) + continue; + if (testnum && !mr) { + printf("%30ssign verify sign/s verify/s\n", " "); + testnum = 0; + } + + if (mr) + printf("+F6:%u:%u:%s:%f:%f\n", + k, test_ed_curves[k].bits, test_ed_curves[k].name, + eddsa_results[k][0], eddsa_results[k][1]); + else + printf("%4u bits EdDSA (%s) %8.4fs %8.4fs %8.1f %8.1f\n", + test_ed_curves[k].bits, test_ed_curves[k].name, + 1.0 / eddsa_results[k][0], 1.0 / eddsa_results[k][1], + eddsa_results[k][0], eddsa_results[k][1]); + } #endif ret = 0; @@ -2999,10 +3337,12 @@ int speed_main(int argc, char **argv) DSA_free(loopargs[i].dsa_key[k]); #endif #ifndef OPENSSL_NO_EC - for (k = 0; k < EC_NUM; k++) { + for (k = 0; k < ECDSA_NUM; k++) EC_KEY_free(loopargs[i].ecdsa[k]); + for (k = 0; k < EC_NUM; k++) EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]); - } + for (k = 0; k < EdDSA_NUM; k++) + EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]); OPENSSL_free(loopargs[i].secret_a); OPENSSL_free(loopargs[i].secret_b); #endif @@ -3038,18 +3378,18 @@ static void print_message(const char *s, long num, int length, int tm) } static void pkey_print_message(const char *str, const char *str2, long num, - int bits, int tm) + unsigned int bits, int tm) { #ifdef SIGALRM BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n" - : "Doing %d bit %s %s's for %ds: ", bits, str, str2, tm); + : "Doing %u bits %s %s's for %ds: ", bits, str, str2, tm); (void)BIO_flush(bio_err); alarm(tm); #else BIO_printf(bio_err, mr ? "+DNP:%ld:%d:%s:%s\n" - : "Doing %ld %d bit %s %s's: ", num, bits, str, str2); + : "Doing %ld %u bits %s %s's: ", num, bits, str, str2); (void)BIO_flush(bio_err); #endif } @@ -3075,7 +3415,7 @@ static char *sstrsep(char **string, const char *delim) if (**string == 0) return NULL; - memset(isdelim, 0, sizeof isdelim); + memset(isdelim, 0, sizeof(isdelim)); isdelim[0] = 1; while (*delim) { @@ -3102,7 +3442,7 @@ static int do_multi(int multi, int size_num) int *fds; static char sep[] = ":"; - fds = malloc(sizeof(*fds) * multi); + fds = app_malloc(sizeof(*fds) * multi, "fd buffer for do_multi"); for (n = 0; n < multi; ++n) { if (pipe(fd) == -1) { BIO_printf(bio_err, "pipe failure\n"); @@ -3136,7 +3476,7 @@ static int do_multi(int multi, int size_num) char *p; f = fdopen(fds[n], "r"); - while (fgets(buf, sizeof buf, f)) { + while (fgets(buf, sizeof(buf), f)) { p = strchr(buf, '\n'); if (p) *p = '\0'; @@ -3210,6 +3550,19 @@ static int do_multi(int multi, int size_num) d = atof(sstrsep(&p, sep)); ecdh_results[k][0] += d; + } else if (strncmp(buf, "+F6:", 4) == 0) { + int k; + double d; + + p = buf + 4; + k = atoi(sstrsep(&p, sep)); + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + eddsa_results[k][0] += d; + + d = atof(sstrsep(&p, sep)); + eddsa_results[k][1] += d; } # endif @@ -3227,14 +3580,15 @@ static int do_multi(int multi, int size_num) } #endif -static void multiblock_speed(const EVP_CIPHER *evp_cipher, const SEC *seconds) +static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, + const openssl_speed_sec_t *seconds) { static const int mblengths_list[] = { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 }; const int *mblengths = mblengths_list; - int j, count, num = OSSL_NELEM(mblengths_list); + int j, count, keylen, num = OSSL_NELEM(mblengths_list); const char *alg_name; - unsigned char *inp, *out, no_key[32], no_iv[16]; + unsigned char *inp, *out, *key, no_key[32], no_iv[16]; EVP_CIPHER_CTX *ctx; double d = 0.0; @@ -3246,7 +3600,14 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher, const SEC *seconds) inp = app_malloc(mblengths[num - 1], "multiblock input buffer"); out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer"); ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, evp_cipher, NULL, no_key, no_iv); + EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv); + + keylen = EVP_CIPHER_CTX_key_length(ctx); + key = app_malloc(keylen, "evp_cipher key"); + EVP_CIPHER_CTX_rand_key(ctx, key); + EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); + OPENSSL_clear_free(key, keylen); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key), no_key); alg_name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));