X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fspeed.c;h=bb8836d81b9054eaf949dfdfd2c4cfbbc81d89bd;hp=462e3e7cfe790bb2c35d4896d401a14cceb5e26b;hb=80c455d5ae405e855391e298a2bf8a24629dd95d;hpb=c8bff7ad501c38f1ce9bfe9392fcb22a709e0f6f diff --git a/apps/speed.c b/apps/speed.c index 462e3e7cfe..bb8836d81b 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -1,39 +1,27 @@ /* - * Copyright 1995-2016 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 + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * The ECDH and ECDSA speed test software is originally written by - * Sumit Gupta of Sun Microsystems Laboratories. - * - */ - #undef SECONDS #define SECONDS 3 -#define PRIME_SECONDS 10 #define RSA_SECONDS 10 #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 @@ -125,51 +113,24 @@ # define NO_FORK #endif -#undef BUFSIZE -#define BUFSIZE (1024*16+1) #define MAX_MISALIGNMENT 63 - -#define ALGOR_NUM 30 -#define SIZE_NUM 6 -#define PRIME_NUM 3 -#define RSA_NUM 7 -#define DSA_NUM 3 - -#define EC_NUM 17 #define MAX_ECDH_SIZE 256 #define MISALIGN 64 +typedef struct openssl_speed_sec_st { + int sym; + int rsa; + int dsa; + int ecdsa; + int ecdh; + 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 @@ -207,7 +168,10 @@ static int AES_cbc_256_encrypt_loop(void *args); static int AES_ige_192_encrypt_loop(void *args); static int AES_ige_256_encrypt_loop(void *args); 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); @@ -220,75 +184,53 @@ 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); +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); +static int do_multi(int multi, int size_num); #endif -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" -}; - -static double results[ALGOR_NUM][SIZE_NUM]; - -static const int lengths[SIZE_NUM] = { +static const int lengths_list[] = { 16, 64, 256, 1024, 8 * 1024, 16 * 1024 }; +static const int *lengths = 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 +static const int aead_lengths_list[] = { + 2, 31, 136, 1024, 8 * 1024, 16 * 1024 +}; -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) -static const char rnd_seed[] = - "string to make the random number generator think it has entropy"; -#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) -# if !defined(SIGALRM) -# define SIGALRM -# endif -static unsigned int lapse, schlock; +# define SIGALRM -1 + +static unsigned int lapse; +static volatile unsigned int schlock; static void alarm_win32(unsigned int secs) { lapse = secs * 1000; @@ -330,21 +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); +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; @@ -354,34 +298,45 @@ static int found(const char *name, const OPT_PAIR *pairs, int *result) 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_ELAPSED, OPT_EVP, OPT_HMAC, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI, + OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM, + 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"}, + {"hmac", OPT_HMAC, 's', "HMAC using EVP-named 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 - {NULL}, + {"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 specified amount of seconds"}, + {"bytes", OPT_BYTES, 'p', + "Run [non-PKI] benchmarks on custom-sized buffer"}, + {"misalign", OPT_MISALIGN, 'p', + "Use specified offset to mis-align buffers"}, + {NULL} }; #define D_MD2 0 @@ -414,7 +369,24 @@ const OPTIONS speed_options[] = { #define D_IGE_192_AES 27 #define D_IGE_256_AES 28 #define D_GHASH 29 -static OPT_PAIR doit_choices[] = { +#define D_RAND 30 +#define D_EVP_HMAC 31 + +/* 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", "hmac" +}; +#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 @@ -479,20 +451,24 @@ static OPT_PAIR doit_choices[] = { {"cast5", D_CBC_CAST}, #endif {"ghash", D_GHASH}, - {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 @@ -501,16 +477,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 @@ -528,7 +508,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}, @@ -547,10 +534,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}, @@ -567,10 +562,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)) @@ -580,10 +594,41 @@ 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][SIZE_NUM]; +static long c[ALGOR_NUM][OSSL_NELEM(lengths_list)]; #ifndef OPENSSL_NO_MD2 static int EVP_Digest_MD2_loop(void *args) @@ -852,6 +897,17 @@ static int CRYPTO_gcm128_aad_loop(void *args) return count; } +static int RAND_bytes_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + int count; + + for (count = 0; COND(c[D_RAND][testnum]); count++) + RAND_bytes(buf, lengths[testnum]); + return count; +} + static long save_count = 0; static int decrypt = 0; static int EVP_Update_loop(void *args) @@ -859,16 +915,65 @@ 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++) { + 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) - for (count = 0; COND(nb_iter); count++) - EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + EVP_DecryptFinal_ex(ctx, buf, &outl); else - for (count = 0; COND(nb_iter); count++) + 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 + * code in your application. + */ +static int EVP_Update_loop_ccm(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + EVP_CIPHER_CTX *ctx = tempargs->ctx; + int outl, count; + unsigned char tag[12]; +#ifndef SIGALRM + int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; +#endif + if (decrypt) { + for (count = 0; COND(nb_iter); count++) { + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag); + /* reset iv */ + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv); + /* counter is reset on every update */ + EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]); + } + } else { + for (count = 0; COND(nb_iter); count++) { + /* 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 @@ -876,6 +981,42 @@ static int EVP_Update_loop(void *args) 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; +} + static const EVP_MD *evp_md = NULL; static int EVP_Digest_loop(void *args) { @@ -894,6 +1035,26 @@ static int EVP_Digest_loop(void *args) return count; } +static const EVP_MD *evp_hmac_md = NULL; +static char *evp_hmac_name = NULL; +static int EVP_HMAC_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + unsigned char *buf = tempargs->buf; + unsigned char no_key[32]; + int count; +#ifndef SIGALRM + int nb_iter = save_count * 4 * lengths[0] / lengths[testnum]; +#endif + + for (count = 0; COND(nb_iter); count++) { + if (HMAC(evp_hmac_md, no_key, sizeof(no_key), buf, lengths[testnum], + NULL, NULL) == NULL) + return -1; + } + return count; +} + #ifndef OPENSSL_NO_RSA static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */ @@ -983,7 +1144,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; @@ -1041,6 +1202,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, @@ -1200,25 +1403,29 @@ int speed_main(int argc, char **argv) { ENGINE *e = NULL; 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; + 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 - 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 @@ -1293,6 +1500,7 @@ int speed_main(int argc, char **argv) sizeof(test15360) }; int rsa_doit[RSA_NUM] = { 0 }; + int primes = RSA_DEFAULT_PRIME_NUM; #endif #ifndef OPENSSL_NO_DSA static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; @@ -1302,43 +1510,56 @@ 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 int test_curves_bits[EC_NUM] = { - 160, 192, 224, - 256, 384, 521, - 163, 233, 283, - 409, 571, 163, - 233, 283, 409, - 571, 253 /* 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} }; - - 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 */ prog = opt_init(argc, argv, speed_options); @@ -1357,6 +1578,7 @@ int speed_main(int argc, char **argv) usertime = 0; break; case OPT_EVP: + evp_md = NULL; evp_cipher = EVP_get_cipherbyname(opt_arg()); if (evp_cipher == NULL) evp_md = EVP_get_digestbyname(opt_arg()); @@ -1368,6 +1590,15 @@ int speed_main(int argc, char **argv) } doit[D_EVP] = 1; break; + case OPT_HMAC: + evp_hmac_md = EVP_get_digestbyname(opt_arg()); + if (evp_hmac_md == NULL) { + BIO_printf(bio_err, "%s: %s is an unknown digest\n", + prog, opt_arg()); + goto end; + } + doit[D_EVP_HMAC] = 1; + break; case OPT_DECRYPT: decrypt = 1; break; @@ -1393,6 +1624,10 @@ int speed_main(int argc, char **argv) prog); goto opterr; } + if (async_jobs > 99999) { + BIO_printf(bio_err, "%s: too many async_jobs\n", prog); + goto opterr; + } #endif break; case OPT_MISALIGN: @@ -1416,6 +1651,26 @@ int speed_main(int argc, char **argv) goto end; #endif break; + case OPT_R_CASES: + if (!opt_rand(o)) + goto end; + break; + case OPT_PRIMES: + if (!opt_int(opt_arg(), &primes)) + goto end; + break; + case OPT_SECONDS: + seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa + = 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(); @@ -1438,17 +1693,11 @@ int speed_main(int argc, char **argv) continue; } #ifndef OPENSSL_NO_RSA -# ifndef RSA_NULL - if (strcmp(*argv, "openssl") == 0) { - RSA_set_default_method(RSA_PKCS1_OpenSSL()); + if (strcmp(*argv, "openssl") == 0) continue; - } -# endif 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)) { @@ -1479,8 +1728,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)) { @@ -1488,19 +1737,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); @@ -1524,10 +1810,15 @@ int speed_main(int argc, char **argv) } } - loopargs[i].buf_malloc = - app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer"); - loopargs[i].buf2_malloc = - app_malloc((int)BUFSIZE + 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; @@ -1538,7 +1829,7 @@ int speed_main(int argc, char **argv) } #ifndef NO_FORK - if (multi && do_multi(multi)) + if (multi && do_multi(multi, size_num)) goto show_res; #endif @@ -1546,9 +1837,9 @@ int speed_main(int argc, char **argv) e = setup_engine(engine_id, 0); /* No parameters; turn on everything. */ - if ((argc == 0) && !doit[D_EVP]) { + if (argc == 0 && !doit[D_EVP] && !doit[D_EVP_HMAC]) { for (i = 0; i < ALGOR_NUM; i++) - if (i != D_EVP) + if (i != D_EVP && i != D_EVP_HMAC) doit[i] = 1; #ifndef OPENSSL_NO_RSA for (i = 0; i < RSA_NUM; i++) @@ -1559,10 +1850,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++) @@ -1576,6 +1869,10 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_RSA for (i = 0; i < loopargs_len; i++) { + if (primes > RSA_DEFAULT_PRIME_NUM) { + /* for multi-prime RSA, skip this */ + break; + } for (k = 0; k < RSA_NUM; k++) { const unsigned char *p; @@ -1592,9 +1889,9 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_DSA for (i = 0; i < loopargs_len; i++) { - loopargs[i].dsa_key[0] = get_dsa512(); - loopargs[i].dsa_key[1] = get_dsa1024(); - loopargs[i].dsa_key[2] = get_dsa2048(); + loopargs[i].dsa_key[0] = get_dsa(512); + loopargs[i].dsa_key[1] = get_dsa(1024); + loopargs[i].dsa_key[2] = get_dsa(2048); } #endif #ifndef OPENSSL_NO_DES @@ -1674,8 +1971,9 @@ int speed_main(int argc, char **argv) c[D_IGE_192_AES][0] = count; c[D_IGE_256_AES][0] = count; c[D_GHASH][0] = count; + c[D_RAND][0] = count; - for (i = 1; i < SIZE_NUM; i++) { + for (i = 1; i < size_num; i++) { long l0, l1; l0 = (long)lengths[0]; @@ -1692,6 +1990,7 @@ int speed_main(int argc, char **argv) c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1; c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1; c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1; + c[D_RAND][i] = c[D_RAND][0] * 4 * l0 / l1; l0 = (long)lengths[i - 1]; @@ -1826,22 +2125,50 @@ 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 if (doit[D_MD2]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs); d = Time_F(STOP); @@ -1851,8 +2178,9 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_MDC2 if (doit[D_MDC2]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs); d = Time_F(STOP); @@ -1863,8 +2191,9 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_MD4 if (doit[D_MD4]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs); d = Time_F(STOP); @@ -1875,8 +2204,9 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_MD5 if (doit[D_MD5]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, MD5_loop, loopargs); d = Time_F(STOP); @@ -1897,8 +2227,9 @@ int speed_main(int argc, char **argv) HMAC_Init_ex(loopargs[i].hctx, hmac_key, len, EVP_md5(), NULL); } - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, HMAC_loop, loopargs); d = Time_F(STOP); @@ -1910,8 +2241,9 @@ int speed_main(int argc, char **argv) } #endif if (doit[D_SHA1]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA1_loop, loopargs); d = Time_F(STOP); @@ -1919,9 +2251,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_SHA256]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_SHA256], c[D_SHA256][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA256_loop, loopargs); d = Time_F(STOP); @@ -1929,9 +2261,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_SHA512]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_SHA512], c[D_SHA512][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, SHA512_loop, loopargs); d = Time_F(STOP); @@ -1940,9 +2272,9 @@ int speed_main(int argc, char **argv) } #ifndef OPENSSL_NO_WHIRLPOOL if (doit[D_WHIRLPOOL]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs); d = Time_F(STOP); @@ -1953,9 +2285,9 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_RMD160 if (doit[D_RMD160]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_RMD160], c[D_RMD160][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs); d = Time_F(STOP); @@ -1965,8 +2297,9 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_RC4 if (doit[D_RC4]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { - print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum]); + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum], + seconds.sym); Time_F(START); count = run_benchmark(async_jobs, RC4_loop, loopargs); d = Time_F(STOP); @@ -1976,9 +2309,9 @@ int speed_main(int argc, char **argv) #endif #ifndef OPENSSL_NO_DES if (doit[D_CBC_DES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, DES_ncbc_encrypt_loop, loopargs); d = Time_F(STOP); @@ -1987,9 +2320,9 @@ int speed_main(int argc, char **argv) } if (doit[D_EDE3_DES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs); @@ -2000,9 +2333,9 @@ int speed_main(int argc, char **argv) #endif if (doit[D_CBC_128_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs); @@ -2011,9 +2344,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_CBC_192_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs); @@ -2022,9 +2355,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_CBC_256_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs); @@ -2034,9 +2367,9 @@ int speed_main(int argc, char **argv) } if (doit[D_IGE_128_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs); @@ -2045,9 +2378,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_IGE_192_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs); @@ -2056,9 +2389,9 @@ int speed_main(int argc, char **argv) } } if (doit[D_IGE_256_AES]) { - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs); @@ -2074,9 +2407,9 @@ int speed_main(int argc, char **argv) (unsigned char *)"0123456789ab", 12); } - for (testnum = 0; testnum < SIZE_NUM; testnum++) { + for (testnum = 0; testnum < size_num; testnum++) { print_message(names[D_GHASH], c[D_GHASH][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); count = run_benchmark(async_jobs, CRYPTO_gcm128_aad_loop, loopargs); d = Time_F(STOP); @@ -2092,9 +2425,9 @@ int speed_main(int argc, char **argv) names[D_CBC_128_CML]); doit[D_CBC_128_CML] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_128_CML][testnum]); count++) Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2110,9 +2443,9 @@ int speed_main(int argc, char **argv) names[D_CBC_192_CML]); doit[D_CBC_192_CML] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported, exiting..."); exit(1); @@ -2132,9 +2465,9 @@ int speed_main(int argc, char **argv) names[D_CBC_256_CML]); doit[D_CBC_256_CML] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_256_CML][testnum]); count++) Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2152,9 +2485,9 @@ int speed_main(int argc, char **argv) names[D_CBC_IDEA]); doit[D_CBC_IDEA] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_IDEA][testnum]); count++) IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2172,9 +2505,9 @@ int speed_main(int argc, char **argv) names[D_CBC_SEED]); doit[D_CBC_SEED] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_SEED][testnum]); count++) SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2191,9 +2524,9 @@ int speed_main(int argc, char **argv) names[D_CBC_RC2]); doit[D_CBC_RC2] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported, exiting..."); exit(1); @@ -2215,9 +2548,9 @@ int speed_main(int argc, char **argv) names[D_CBC_RC5]); doit[D_CBC_RC5] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); if (async_jobs > 0) { BIO_printf(bio_err, "Async mode is not supported, exiting..."); exit(1); @@ -2239,9 +2572,9 @@ int speed_main(int argc, char **argv) names[D_CBC_BF]); doit[D_CBC_BF] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_BF][testnum]); count++) BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2259,9 +2592,9 @@ int speed_main(int argc, char **argv) names[D_CBC_CAST]); doit[D_CBC_CAST] = 0; } - for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) { + for (testnum = 0; testnum < size_num && async_init == 0; testnum++) { print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], - lengths[testnum]); + lengths[testnum], seconds.sym); Time_F(START); for (count = 0, run = 1; COND(c[D_CBC_CAST][testnum]); count++) CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf, @@ -2272,65 +2605,108 @@ int speed_main(int argc, char **argv) } } #endif + if (doit[D_RAND]) { + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum], + seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs); + d = Time_F(STOP); + print_result(D_RAND, testnum, count, d); + } + } 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); - 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 - */ - print_message(names[D_EVP], save_count, lengths[testnum]); + 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); + + 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); + + /* SIV mode only allows for a single Update operation */ + if (EVP_CIPHER_mode(evp_cipher) == EVP_CIPH_SIV_MODE) + EVP_CIPHER_CTX_ctrl(loopargs[k].ctx, EVP_CTRL_SET_SPEED, 1, NULL); } Time_F(START); - count = run_benchmark(async_jobs, EVP_Update_loop, loopargs); + count = run_benchmark(async_jobs, loopfunc, loopargs); d = Time_F(STOP); 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)); - print_message(names[D_EVP], save_count, lengths[testnum]); + } 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); + } + } + } + + if (doit[D_EVP_HMAC]) { + if (evp_hmac_md != NULL) { + const char *md_name = OBJ_nid2ln(EVP_MD_type(evp_hmac_md)); + evp_hmac_name = app_malloc(sizeof("HMAC()") + strlen(md_name), + "HMAC name"); + sprintf(evp_hmac_name, "HMAC(%s)", md_name); + names[D_EVP_HMAC] = evp_hmac_name; + + for (testnum = 0; testnum < size_num; testnum++) { + print_message(names[D_EVP_HMAC], save_count, lengths[testnum], + seconds.sym); + Time_F(START); + count = run_benchmark(async_jobs, EVP_HMAC_loop, loopargs); + d = Time_F(STOP); + print_result(D_EVP_HMAC, 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++) { @@ -2338,6 +2714,34 @@ int speed_main(int argc, char **argv) if (!rsa_doit[testnum]) continue; for (i = 0; i < loopargs_len; i++) { + if (primes > 2) { + /* we haven't set keys yet, generate multi-prime RSA keys */ + BIGNUM *bn = BN_new(); + + if (bn == NULL) + goto end; + if (!BN_set_word(bn, RSA_F4)) { + BN_free(bn); + goto end; + } + + BIO_printf(bio_err, "Generate multi-prime RSA key for %s\n", + rsa_choices[testnum].name); + + loopargs[i].rsa_key[testnum] = RSA_new(); + if (loopargs[i].rsa_key[testnum] == NULL) { + BN_free(bn); + goto end; + } + + if (!RSA_generate_multi_prime_key(loopargs[i].rsa_key[testnum], + rsa_bits[testnum], + primes, bn, NULL)) { + BN_free(bn); + goto end; + } + BN_free(bn); + } st = RSA_sign(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2, &loopargs[i].siglen, loopargs[i].rsa_key[testnum]); if (st == 0) @@ -2351,14 +2755,14 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("private", "rsa", rsa_c[testnum][0], rsa_bits[testnum], - RSA_SECONDS); + seconds.rsa); /* RSA_blinding_on(rsa_key[testnum],NULL); */ Time_F(START); count = run_benchmark(async_jobs, RSA_sign_loop, loopargs); 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; @@ -2378,13 +2782,13 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("public", "rsa", rsa_c[testnum][1], rsa_bits[testnum], - RSA_SECONDS); + seconds.rsa); Time_F(START); count = run_benchmark(async_jobs, RSA_verify_loop, loopargs); 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; } @@ -2398,12 +2802,10 @@ 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 - if (RAND_status() != 1) { - RAND_seed(rnd_seed, sizeof rnd_seed); - } for (testnum = 0; testnum < DSA_NUM; testnum++) { int st = 0; if (!dsa_doit[testnum]) @@ -2425,13 +2827,13 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("sign", "dsa", dsa_c[testnum][0], dsa_bits[testnum], - DSA_SECONDS); + seconds.dsa); Time_F(START); 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; @@ -2451,13 +2853,13 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("verify", "dsa", dsa_c[testnum][1], dsa_bits[testnum], - DSA_SECONDS); + seconds.dsa); Time_F(START); 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; } @@ -2471,17 +2873,14 @@ int speed_main(int argc, char **argv) #endif /* OPENSSL_NO_DSA */ #ifndef OPENSSL_NO_EC - if (RAND_status() != 1) { - RAND_seed(rnd_seed, sizeof rnd_seed); - } - 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; @@ -2510,15 +2909,15 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("sign", "ecdsa", ecdsa_c[testnum][0], - test_curves_bits[testnum], ECDSA_SECONDS); + 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; } @@ -2539,28 +2938,25 @@ int speed_main(int argc, char **argv) } else { pkey_print_message("verify", "ecdsa", ecdsa_c[testnum][1], - test_curves_bits[testnum], ECDSA_SECONDS); + 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; } if (rsa_count <= 1) { /* if longer than 10s, don't do any more */ - for (testnum++; testnum < EC_NUM; testnum++) + for (testnum++; testnum < ECDSA_NUM; testnum++) ecdsa_doit[testnum] = 0; } } } - if (RAND_status() != 1) { - RAND_seed(rnd_seed, sizeof rnd_seed); - } for (testnum = 0; testnum < EC_NUM; testnum++) { int ecdh_checks = 1; @@ -2589,7 +2985,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; @@ -2620,7 +3016,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; @@ -2637,7 +3033,7 @@ int speed_main(int argc, char **argv) EVP_PKEY_CTX_free(pctx); pctx = NULL; } - if (!kctx || /* keygen ctx is not null */ + if (kctx == NULL || /* keygen ctx is not null */ !EVP_PKEY_keygen_init(kctx) /* init keygen ctx */ ) { ecdh_checks = 0; BIO_printf(bio_err, "ECDH keygen failure.\n"); @@ -2692,6 +3088,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); @@ -2700,32 +3098,137 @@ int speed_main(int argc, char **argv) if (ecdh_checks != 0) { pkey_print_message("", "ecdh", ecdh_c[testnum][0], - test_curves_bits[testnum], ECDH_SECONDS); + 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); - ecdh_results[testnum][0] = d / (double)count; + "%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: #endif if (!mr) { - printf("%s\n", OpenSSL_version(OPENSSL_VERSION)); - printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON)); + printf("version: %s\n", OpenSSL_version(OPENSSL_FULL_VERSION_STRING)); + printf("built on: %s\n", OpenSSL_version(OPENSSL_BUILT_ON)); printf("options:"); printf("%s ", BN_options()); #ifndef OPENSSL_NO_MD2 @@ -2755,7 +3258,7 @@ int speed_main(int argc, char **argv) ("The 'numbers' are in 1000s of bytes per second processed.\n"); printf("type "); } - for (testnum = 0; testnum < SIZE_NUM; testnum++) + for (testnum = 0; testnum < size_num; testnum++) printf(mr ? ":%d" : "%7d bytes", lengths[testnum]); printf("\n"); } @@ -2764,10 +3267,10 @@ 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++) { + for (testnum = 0; testnum < size_num; testnum++) { if (results[k][testnum] > 10000 && !mr) printf(" %11.2fk", results[k][testnum] / 1e3); else @@ -2813,7 +3316,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) { @@ -2823,12 +3326,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]); } @@ -2843,14 +3345,33 @@ 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], - ecdh_results[k][0], 1.0 / ecdh_results[k][0]); + 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 @@ -2871,14 +3392,17 @@ 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 } + OPENSSL_free(evp_hmac_name); if (async_jobs > 0) { for (i = 0; i < loopargs_len; i++) @@ -2890,17 +3414,17 @@ int speed_main(int argc, char **argv) } OPENSSL_free(loopargs); release_engine(e); - return (ret); + return ret; } -static void print_message(const char *s, long num, int length) +static void print_message(const char *s, long num, int length, int tm) { #ifdef SIGALRM BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n" - : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length); + : "Doing %s for %ds on %d size blocks: ", s, tm, length); (void)BIO_flush(bio_err); - alarm(SECONDS); + alarm(tm); #else BIO_printf(bio_err, mr ? "+DN:%s:%ld:%d\n" @@ -2910,18 +3434,18 @@ static void print_message(const char *s, long num, int length) } 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 } @@ -2947,7 +3471,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) { @@ -2967,14 +3491,14 @@ static char *sstrsep(char **string, const char *delim) return token; } -static int do_multi(int multi) +static int do_multi(int multi, int size_num) { int n; int fd[2]; 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"); @@ -3008,7 +3532,7 @@ static int do_multi(int multi) 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'; @@ -3026,7 +3550,7 @@ static int do_multi(int multi) p = buf + 3; alg = atoi(sstrsep(&p, sep)); sstrsep(&p, sep); - for (j = 0; j < SIZE_NUM; ++j) + for (j = 0; j < size_num; ++j) results[alg][j] += atof(sstrsep(&p, sep)); } else if (strncmp(buf, "+F2:", 4) == 0) { int k; @@ -3081,11 +3605,20 @@ static int do_multi(int multi) sstrsep(&p, sep); d = atof(sstrsep(&p, sep)); - if (n) - ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d); - else - ecdh_results[k][0] = d; + 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 @@ -3103,25 +3636,39 @@ static int do_multi(int multi) } #endif -static void multiblock_speed(const EVP_CIPHER *evp_cipher) +static void multiblock_speed(const EVP_CIPHER *evp_cipher, int lengths_single, + const openssl_speed_sec_t *seconds) { - static int mblengths[] = + static const int mblengths_list[] = { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 }; - int j, count, num = OSSL_NELEM(mblengths); + const int *mblengths = 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; + if (lengths_single) { + mblengths = &lengths_single; + num = 1; + } + 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)); for (j = 0; j < num; j++) { - print_message(alg_name, 0, mblengths[j]); + print_message(alg_name, 0, mblengths[j], seconds->sym); Time_F(START); for (count = 0, run = 1; run && count < 0x7fffffff; count++) { unsigned char aad[EVP_AEAD_TLS1_AAD_LEN]; @@ -3154,8 +3701,8 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher) RAND_bytes(out, 16); len += 16; - aad[11] = len >> 8; - aad[12] = len; + aad[11] = (unsigned char)(len >> 8); + aad[12] = (unsigned char)(len); pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, EVP_AEAD_TLS1_AAD_LEN, aad); EVP_Cipher(ctx, out, inp, len + pad);