[openssl] master update

tmraz at fedoraproject.org tmraz at fedoraproject.org
Mon Jun 1 07:01:56 UTC 2020


The branch master has been updated
       via  60d3b5b9ffb8c1273af0cc0338ec1c98f464f4b1 (commit)
      from  082c041b4233b17b80129d4ac6b33a28014442b0 (commit)


- Log -----------------------------------------------------------------
commit 60d3b5b9ffb8c1273af0cc0338ec1c98f464f4b1
Author: Hubert Kario <hubert at kario.pl>
Date:   Sat Jan 18 19:13:02 2020 +0100

    add FFDH to speed command
    
    the openssl speed command could not benchmark FFDH speed, but it could
    benchmark ECDH, making comparisons between the two hard
    
    this commit adds this feature
    
    fixes #9475
    
    Signed-off-by: Hubert Kario <hubert at kario.pl>
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Tomas Mraz <tmraz at fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/10887)

-----------------------------------------------------------------------

Summary of changes:
 apps/speed.c | 325 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 320 insertions(+), 5 deletions(-)

diff --git a/apps/speed.c b/apps/speed.c
index bd05631f30..f481b6b8fd 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -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 <openssl/rsa.h>
 # include "./testrsa.h"
 #endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
 #include <openssl/x509.h>
 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0)
 # include <openssl/dsa.h>
@@ -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,
@@ -561,6 +583,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 +1094,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)
@@ -1463,7 +1508,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 +1567,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 +1783,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 +1830,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 +1976,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
     }
 
@@ -1919,6 +1998,9 @@ int speed_main(int argc, char **argv)
 #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 +2192,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 +2342,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."
@@ -3510,8 +3605,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
@@ -3688,6 +3963,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;
 
@@ -3701,6 +3996,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]);
@@ -3982,7 +4284,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) {
                 ;


More information about the openssl-commits mailing list