X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fspeed.c;h=a4879179e4142844bdd86d35111590dd7fb3b336;hp=c0a34ee9948b2f7e9ccfcf45295daa9db936e3a5;hb=52307f94f8f3e5a1cd392f0a48802a24ccf73ba2;hpb=1c534560dc905b6d399dbde242422f0cf5543286 diff --git a/apps/speed.c b/apps/speed.c index c0a34ee994..a4879179e4 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -14,6 +14,7 @@ #define DSA_SECONDS 10 #define ECDSA_SECONDS 10 #define ECDH_SECONDS 10 +#define EdDSA_SECONDS 10 #include #include @@ -122,6 +123,7 @@ typedef struct openssl_speed_sec_st { int dsa; int ecdsa; int ecdh; + int eddsa; } openssl_speed_sec_t; static volatile int run = 0; @@ -169,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); @@ -181,6 +184,8 @@ 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 double Time_F(int s); @@ -197,29 +202,33 @@ static const int lengths_list[] = { }; static const int *lengths = lengths_list; +static const int aead_lengths_list[] = { + 2, 31, 136, 1024, 8 * 1024, 16 * 1024 +}; + +#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) @@ -263,13 +272,9 @@ 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 @@ -295,38 +300,41 @@ 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"}, + "Run [non-PKI] benchmarks on custom-sized buffer"}, + {"misalign", OPT_MISALIGN, 'p', + "Use specified offset to mis-align buffers"}, {NULL} }; @@ -563,6 +571,16 @@ static const OPT_PAIR ecdh_choices[] = { # 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 @@ -582,6 +600,7 @@ typedef struct loopargs_st { unsigned char *buf2_malloc; unsigned char *key; unsigned int siglen; + size_t sigsize; #ifndef OPENSSL_NO_RSA RSA *rsa_key[RSA_NUM]; #endif @@ -591,6 +610,7 @@ typedef struct loopargs_st { #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]; @@ -899,14 +919,18 @@ static int EVP_Update_loop(void *args) if (decrypt) { for (count = 0; COND(nb_iter); count++) { rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); - if (rc != 1) + 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) + if (rc != 1) { + /* reset iv in case of counter overflow */ EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1); + } } } if (decrypt) @@ -915,6 +939,7 @@ static int EVP_Update_loop(void *args) 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 @@ -932,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]); - EVP_EncryptFinal_ex(ctx, buf, &outl); + } + } + 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, &outl); } } return count; @@ -1114,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, @@ -1272,7 +1379,6 @@ 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; const char *prog; const char *engine_id = NULL; @@ -1281,7 +1387,7 @@ int speed_main(int argc, char **argv) OPTION_CHOICE o; int async_init = 0, multiblock = 0, pr_header = 0; int doit[ALGOR_NUM] = { 0 }; - int ret = 1, misalign = 0, lengths_single = 0; + int ret = 1, misalign = 0, lengths_single = 0, aead = 0; long count = 0; unsigned int size_num = OSSL_NELEM(lengths_list); unsigned int i, k, loop, loopargs_len = 0, async_jobs = 0; @@ -1295,7 +1401,8 @@ int speed_main(int argc, char **argv) long rsa_count = 1; #endif openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, - ECDSA_SECONDS, ECDH_SECONDS }; + ECDSA_SECONDS, ECDH_SECONDS, + EdDSA_SECONDS }; /* What follows are the buffers and key material. */ #ifndef OPENSSL_NO_RC5 @@ -1415,9 +1522,21 @@ int speed_main(int argc, char **argv) {"X25519", NID_X25519, 253}, {"X448", NID_X448, 448} }; + 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} + }; 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 */ prog = opt_init(argc, argv, speed_options); @@ -1510,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(); @@ -1591,11 +1713,48 @@ int speed_main(int argc, char **argv) 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); @@ -1619,7 +1778,10 @@ int speed_main(int argc, char **argv) } } - buflen = lengths[size_num - 1] + MAX_MISALIGNMENT + 1; + 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); @@ -1660,6 +1822,8 @@ int speed_main(int argc, char **argv) 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++) @@ -1955,16 +2119,17 @@ int speed_main(int argc, char **argv) /* 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 @@ -2420,30 +2585,30 @@ 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, lengths_single, &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); @@ -2461,13 +2626,6 @@ int speed_main(int argc, char **argv) loopargs[k].key, NULL, -1); OPENSSL_clear_free(loopargs[k].key, keylen); } - switch (EVP_CIPHER_mode(evp_cipher)) { - case EVP_CIPH_CCM_MODE: - loopfunc = EVP_Update_loop_ccm; - break; - default: - loopfunc = EVP_Update_loop; - } Time_F(START); count = run_benchmark(async_jobs, loopfunc, loopargs); @@ -2475,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++) { @@ -2585,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++) { @@ -2899,6 +3062,111 @@ int speed_main(int argc, char **argv) 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: @@ -3030,6 +3298,26 @@ int speed_main(int argc, char **argv) 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; @@ -3053,6 +3341,8 @@ int speed_main(int argc, char **argv) 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 @@ -3152,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"); @@ -3260,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