X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fspeed.c;h=4bd42d4e423116c403f0f80cfb38df7ba735612d;hp=c063520df9f4f9bb708618849def3255309cdb39;hb=1154ffbfb38418ea68af9661e19daa0d6d984adb;hpb=031c9bd3f3e9a02fa126c7dbc47f3d934678a195 diff --git a/apps/speed.c b/apps/speed.c index c063520df9..4bd42d4e42 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -16,6 +16,7 @@ #define ECDH_SECONDS 10 #define EdDSA_SECONDS 10 #define SM2_SECONDS 10 +#define FFDH_SECONDS 10 /* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED @@ -98,6 +99,9 @@ # include # include "./testrsa.h" #endif +#ifndef OPENSSL_NO_DH +# include +#endif #include #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) # include @@ -125,6 +129,7 @@ #define MAX_MISALIGNMENT 63 #define MAX_ECDH_SIZE 256 #define MISALIGN 64 +#define MAX_FFDH_SIZE 1024 typedef struct openssl_speed_sec_st { int sym; @@ -134,6 +139,7 @@ typedef struct openssl_speed_sec_st { int ecdh; int eddsa; int sm2; + int ffdh; } openssl_speed_sec_t; static volatile int run = 0; @@ -435,6 +441,22 @@ static const OPT_PAIR rsa_choices[RSA_NUM] = { static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ #endif /* OPENSSL_NO_RSA */ +#ifndef OPENSSL_NO_DH +enum ff_params_t { + R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM +}; + +static const OPT_PAIR ffdh_choices[FFDH_NUM] = { + {"ffdh2048", R_FFDH_2048}, + {"ffdh3072", R_FFDH_3072}, + {"ffdh4096", R_FFDH_4096}, + {"ffdh6144", R_FFDH_6144}, + {"ffdh8192", R_FFDH_8192}, +}; + +static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */ +#endif /* OPENSSL_NO_DH */ + #ifndef OPENSSL_NO_EC enum ec_curves_t { R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521, @@ -553,6 +575,7 @@ typedef struct loopargs_st { EC_KEY *ecdsa[ECDSA_NUM]; EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; + EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM]; # ifndef OPENSSL_NO_SM2 EVP_MD_CTX *sm2_ctx[SM2_NUM]; EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM]; @@ -561,6 +584,11 @@ typedef struct loopargs_st { unsigned char *secret_a; unsigned char *secret_b; size_t outlen[EC_NUM]; +#endif +#ifndef OPENSSL_NO_DH + EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM]; + unsigned char *secret_ff_a; + unsigned char *secret_ff_b; #endif EVP_CIPHER_CTX *ctx; #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -1067,6 +1095,24 @@ static int RSA_verify_loop(void *args) } #endif +#ifndef OPENSSL_NO_DH +static long ffdh_c[FFDH_NUM][1]; + +static int FFDH_derive_key_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum]; + unsigned char *derived_secret = tempargs->secret_ff_a; + size_t outlen = MAX_FFDH_SIZE; + int count; + + for (count = 0; COND(ffdh_c[testnum][0]); count++) + EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen); + + return count; +} +#endif /* OPENSSL_NO_DH */ + #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) static long dsa_c[DSA_NUM][2]; static int DSA_sign_loop(void *args) @@ -1197,7 +1243,7 @@ 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; + EVP_MD_CTX **edctx = tempargs->eddsa_ctx2; unsigned char *eddsasig = tempargs->buf2; size_t eddsasigsize = tempargs->sigsize; int ret, count; @@ -1463,7 +1509,8 @@ int speed_main(int argc, char **argv) #endif openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, ECDH_SECONDS, - EdDSA_SECONDS, SM2_SECONDS }; + EdDSA_SECONDS, SM2_SECONDS, + FFDH_SECONDS }; /* What follows are the buffers and key material. */ #if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) @@ -1521,6 +1568,23 @@ int speed_main(int argc, char **argv) uint8_t rsa_doit[RSA_NUM] = { 0 }; int primes = RSA_DEFAULT_PRIME_NUM; #endif +#ifndef OPENSSL_NO_DH + typedef struct ffdh_params_st { + const char *name; + unsigned int nid; + unsigned int bits; + } FFDH_PARAMS; + + static const FFDH_PARAMS ffdh_params[FFDH_NUM] = { + {"ffdh2048", NID_ffdhe2048, 2048}, + {"ffdh3072", NID_ffdhe3072, 3072}, + {"ffdh4096", NID_ffdhe4096, 4096}, + {"ffdh6144", NID_ffdhe6144, 6144}, + {"ffdh8192", NID_ffdhe8192, 8192} + }; + uint8_t ffdh_doit[FFDH_NUM] = { 0 }; + +#endif /* OPENSSL_NO_DH */ #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; uint8_t dsa_doit[DSA_NUM] = { 0 }; @@ -1720,7 +1784,7 @@ int speed_main(int argc, char **argv) case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa = seconds.ecdh = seconds.eddsa - = seconds.sm2 = atoi(opt_arg()); + = seconds.sm2 = seconds.ffdh = atoi(opt_arg()); break; case OPT_BYTES: lengths_single = atoi(opt_arg()); @@ -1767,6 +1831,18 @@ int speed_main(int argc, char **argv) } } #endif +#ifndef OPENSSL_NO_DH + if (strncmp(algo, "ffdh", 4) == 0) { + if (algo[4] == '\0') { + memset(ffdh_doit, 1, sizeof(ffdh_doit)); + continue; + } + if (opt_found(algo, ffdh_choices, &i)) { + ffdh_doit[i] = 2; + continue; + } + } +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (strncmp(algo, "dsa", 3) == 0) { if (algo[3] == '\0') { @@ -1901,6 +1977,10 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_EC loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a"); loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b"); +#endif +#ifndef OPENSSL_NO_DH + loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a"); + loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b"); #endif } @@ -1916,9 +1996,21 @@ int speed_main(int argc, char **argv) if (argc == 0 && !doit[D_EVP] && !doit[D_EVP_HMAC] && !doit[D_EVP_CMAC]) { memset(doit, 1, sizeof(doit)); doit[D_EVP] = doit[D_EVP_HMAC] = doit[D_EVP_CMAC] = 0; +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_MDC2] = 0; +#endif +#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_MD4] = 0; +#endif +#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_RMD160] = 0; +#endif #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) memset(rsa_doit, 1, sizeof(rsa_doit)); #endif +#ifndef OPENSSL_NO_DH + memset(ffdh_doit, 1, sizeof(ffdh_doit)); +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) memset(dsa_doit, 1, sizeof(dsa_doit)); #endif @@ -2110,7 +2202,7 @@ int speed_main(int argc, char **argv) c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1; } -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) rsa_c[R_RSA_512][0] = count / 2000; rsa_c[R_RSA_512][1] = count / 400; for (i = 1; i < RSA_NUM; i++) { @@ -2260,6 +2352,19 @@ int speed_main(int argc, char **argv) # endif # endif /* OPENSSL_NO_EC */ +# ifndef OPENSSL_NO_DH + ffdh_c[R_FFDH_2048][0] = count / 1000; + for (i = R_FFDH_3072; i <= R_FFDH_8192; i++) { + ffdh_c[i][0] = ffdh_c[i - 1][0] / 2; + if (ffdh_doit[i] <= 1 && ffdh_c[i][0] == 0) { + ffdh_doit[i] = 0; + } else { + if (ffdh_c[i][0] == 0) + ffdh_c[i][0] = 1; + } + } +# endif /* OPENSSL_NO_DH */ + # else /* not worth fixing */ # error "You cannot disable DES on systems without SIGALRM." @@ -3049,7 +3154,6 @@ int speed_main(int argc, char **argv) rsa_count = 1; } else { for (i = 0; i < loopargs_len; i++) { - EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL); /* Perform ECDSA signature test */ EC_KEY_generate_key(loopargs[i].ecdsa[testnum]); st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2, @@ -3286,6 +3390,11 @@ int speed_main(int argc, char **argv) st = 0; break; } + loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new(); + if (loopargs[i].eddsa_ctx2[testnum] == NULL) { + st = 0; + break; + } if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid, NULL)) == NULL @@ -3303,6 +3412,13 @@ int speed_main(int argc, char **argv) EVP_PKEY_free(ed_pkey); break; } + if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL, + NULL, NULL, ed_pkey)) { + st = 0; + EVP_PKEY_free(ed_pkey); + break; + } + EVP_PKEY_free(ed_pkey); } if (st == 0) { @@ -3340,10 +3456,9 @@ int speed_main(int argc, char **argv) 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], + st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum], loopargs[i].buf2, loopargs[i].sigsize, loopargs[i].buf, 20); if (st != 1) @@ -3511,8 +3626,188 @@ int speed_main(int argc, char **argv) } } # endif /* OPENSSL_NO_SM2 */ - #endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_DH + for (testnum = 0; testnum < FFDH_NUM; testnum++) { + int ffdh_checks = 1; + + if (!ffdh_doit[testnum]) + continue; + + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY *pkey_A = NULL; + EVP_PKEY *pkey_B = NULL; + EVP_PKEY_CTX *ffdh_ctx = NULL; + EVP_PKEY_CTX *test_ctx = NULL; + size_t secret_size; + size_t test_out; + + /* Ensure that the error queue is empty */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + pkey_A = EVP_PKEY_new(); + if (!pkey_A) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + pkey_B = EVP_PKEY_new(); + if (!pkey_B) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); + if (!ffdh_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) { + BIO_printf(bio_err, "Error setting DH key size for keygen.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || + EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) { + BIO_printf(bio_err, "FFDH key generation failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + EVP_PKEY_CTX_free(ffdh_ctx); + + /* check if the derivation works correctly both ways so that + * we know if future derive calls will fail, and we can skip + * error checking in benchmarked code */ + ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL); + if (!ffdh_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "FFDH derivation context init failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) { + BIO_printf(bio_err, "Assigning peer key for derivation failed.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) { + BIO_printf(bio_err, "Checking size of shared secret failed.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (secret_size > MAX_FFDH_SIZE) { + BIO_printf(bio_err, "Assertion failure: shared secret too large.\n"); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, + loopargs[i].secret_ff_a, + &secret_size) <= 0) { + BIO_printf(bio_err, "Shared secret derive failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + /* Now check from side B */ + test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL); + if (!test_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (!EVP_PKEY_derive_init(test_ctx) || + !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) || + !EVP_PKEY_derive(test_ctx, NULL, &test_out) || + !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) || + test_out != secret_size) { + BIO_printf(bio_err, "FFDH computation failure.\n"); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + /* compare the computed secrets */ + if (CRYPTO_memcmp(loopargs[i].secret_ff_a, + loopargs[i].secret_ff_b, secret_size)) { + BIO_printf(bio_err, "FFDH computations don't match.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + loopargs[i].ffdh_ctx[testnum] = ffdh_ctx; + + EVP_PKEY_free(pkey_A); + pkey_A = NULL; + EVP_PKEY_free(pkey_B); + pkey_B = NULL; + EVP_PKEY_CTX_free(test_ctx); + test_ctx = NULL; + } + if (ffdh_checks != 0) { + pkey_print_message("", "ffdh", ffdh_c[testnum][0], + ffdh_params[testnum].bits, seconds.ffdh); + Time_F(START); + count = + run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R12:%ld:%d:%.2f\n" : + "%ld %u-bits FFDH ops in %.2fs\n", count, + ffdh_params[testnum].bits, d); + ffdh_results[testnum][0] = (double)count / d; + rsa_count = count; + }; + if (rsa_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(ffdh_doit, testnum); + } + } +#endif /* OPENSSL_NO_DH */ #ifndef NO_FORK show_res: #endif @@ -3689,6 +3984,26 @@ int speed_main(int argc, char **argv) } # endif #endif /* OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_DH + testnum = 1; + for (k = 0; k < FFDH_NUM; k++) { + if (!ffdh_doit[k]) + continue; + if (testnum && !mr) { + printf("%23sop op/s\n", " "); + testnum = 0; + } + if (mr) + printf("+F8:%u:%u:%f:%f\n", + k, ffdh_params[k].bits, + ffdh_results[k][0], 1.0 / ffdh_results[k][0]); + + else + printf("%4u bits ffdh %8.4fs %8.1f\n", + ffdh_params[k].bits, + 1.0 / ffdh_results[k][0], ffdh_results[k][0]); + } +#endif /* OPENSSL_NO_DH */ ret = 0; @@ -3702,6 +4017,13 @@ int speed_main(int argc, char **argv) for (k = 0; k < RSA_NUM; k++) RSA_free(loopargs[i].rsa_key[k]); #endif +#ifndef OPENSSL_NO_DH + OPENSSL_free(loopargs[i].secret_ff_a); + OPENSSL_free(loopargs[i].secret_ff_b); + for (k = 0; k < FFDH_NUM; k++) { + EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]); + } +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) for (k = 0; k < DSA_NUM; k++) DSA_free(loopargs[i].dsa_key[k]); @@ -3711,8 +4033,10 @@ 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++) + for (k = 0; k < EdDSA_NUM; k++) { EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]); + EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]); + } # ifndef OPENSSL_NO_SM2 for (k = 0; k < SM2_NUM; k++) { EVP_PKEY_CTX *pctx = NULL; @@ -3983,7 +4307,20 @@ static int do_multi(int multi, int size_num) sm2_results[k][1] += d; } # endif /* OPENSSL_NO_SM2 */ -# endif +# endif /* OPENSSL_NO_EC */ +# ifndef OPENSSL_NO_DH + else if (strncmp(buf, "+F8:", 4) == 0) { + int k; + double d; + + p = buf + 4; + k = atoi(sstrsep(&p, sep)); + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + ffdh_results[k][0] += d; + } +# endif /* OPENSSL_NO_DH */ else if (strncmp(buf, "+H:", 3) == 0) { ;