Commit 5cefb82fc7 for openssl.org

commit 5cefb82fc7fb5cad671e88d220084cffef0915b5
Author: Viktor Dukhovni <openssl-users@dukhovni.org>
Date:   Tue Feb 10 22:51:15 2026 +1100

    Refactor openssl-speed(1)

    - Adding support for "curveSM2" ECDH
    - Integrating EdDSA and SM2 signature support into existing ECDSA code.

    This removes ~500 lines of duplicated code.

    Reviewed-by: Tim Hudson <tjh@openssl.org>
    Reviewed-by: Matt Caswell <matt@openssl.org>
    Reviewed-by: Tomas Mraz <tomas@openssl.org>
    Reviewed-by: Paul Yang <paulyang.inf@gmail.com>
    MergeDate: Sat Feb 21 13:26:44 2026
    (Merged from https://github.com/openssl/openssl/pull/29953)

diff --git a/apps/speed.c b/apps/speed.c
index 807257ffbf..d5f0c53c2a 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -16,8 +16,6 @@
 #define DSA_SECONDS PKEY_SECONDS
 #define ECDSA_SECONDS PKEY_SECONDS
 #define ECDH_SECONDS PKEY_SECONDS
-#define EdDSA_SECONDS PKEY_SECONDS
-#define SM2_SECONDS PKEY_SECONDS
 #define FFDH_SECONDS PKEY_SECONDS
 #define KEM_SECONDS PKEY_SECONDS
 #define SIG_SECONDS PKEY_SECONDS
@@ -43,6 +41,7 @@
 #include <openssl/objects.h>
 #include <openssl/core_names.h>
 #include <openssl/async.h>
+#include <openssl/prov_ssl.h>
 #include <openssl/provider.h>
 #if !defined(OPENSSL_SYS_MSDOS)
 #include <unistd.h>
@@ -107,8 +106,6 @@ typedef struct openssl_speed_sec_st {
     int dsa;
     int ecdsa;
     int ecdh;
-    int eddsa;
-    int sm2;
     int ffdh;
     int kem;
     int sig;
@@ -220,6 +217,9 @@ static int opt_found(const char *name, unsigned int *result,
 {
     unsigned int idx;

+    if (*name == '\0')
+        return 0;
+
     for (idx = 0; idx < nbelem; ++idx, pairs++)
         if (strcmp(name, pairs->name) == 0) {
             *result = pairs->retval;
@@ -478,10 +478,26 @@ enum ec_curves_t {
     R_EC_BRP384T1,
     R_EC_BRP512R1,
     R_EC_BRP512T1,
-    ECDSA_NUM
+    ECBASE_NUM,
+#ifndef OPENSSL_NO_ECX
+    R_Ed25519 = ECBASE_NUM,
+    R_Ed448,
+    R_X25519,
+    R_X448,
+    ECX_NUM,
+#else
+    ECX_NUM = ECBASE_NUM,
+#endif
+#ifndef OPENSSL_NO_SM2
+    R_SM2 = ECX_NUM,
+    R_curveSM2,
+    EC_NUM,
+#else
+    EC_NUM = ECX_NUM,
+#endif
 };
 /* list of ecdsa curves */
-static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
+static const OPT_PAIR ecdsa_choices[EC_NUM] = {
     { "ecdsap160", R_EC_P160 },
     { "ecdsap192", R_EC_P192 },
     { "ecdsap224", R_EC_P224 },
@@ -505,15 +521,16 @@ static const OPT_PAIR ecdsa_choices[ECDSA_NUM] = {
     { "ecdsabrp384r1", R_EC_BRP384R1 },
     { "ecdsabrp384t1", R_EC_BRP384T1 },
     { "ecdsabrp512r1", R_EC_BRP512R1 },
-    { "ecdsabrp512t1", R_EC_BRP512T1 }
-};
-enum {
+    { "ecdsabrp512t1", R_EC_BRP512T1 },
 #ifndef OPENSSL_NO_ECX
-    R_EC_X25519 = ECDSA_NUM,
-    R_EC_X448,
-    EC_NUM
-#else
-    EC_NUM = ECDSA_NUM
+    { "ed25519", R_Ed25519 },
+    { "ed448", R_Ed448 },
+    { "", -1 },
+    { "", -1 },
+#endif
+#ifndef OPENSSL_NO_SM2
+    { "sm2", R_SM2 },
+    { "", -1 },
 #endif
 };
 /* list of ecdh curves, extension of |ecdsa_choices| list above */
@@ -543,36 +560,19 @@ static const OPT_PAIR ecdh_choices[EC_NUM] = {
     { "ecdhbrp512r1", R_EC_BRP512R1 },
     { "ecdhbrp512t1", R_EC_BRP512T1 },
 #ifndef OPENSSL_NO_ECX
-    { "ecdhx25519", R_EC_X25519 },
-    { "ecdhx448", R_EC_X448 }
+    { "", -1 },
+    { "", -1 },
+    { "ecdhx25519", R_X25519 },
+    { "ecdhx448", R_X448 },
+#endif
+#ifndef OPENSSL_NO_SM2
+    { "", -1 },
+    { "curveSM2", R_curveSM2 },
 #endif
 };

 static double ecdh_results[EC_NUM][1]; /* 1 op: derivation */
-static double ecdsa_results[ECDSA_NUM][2]; /* 2 ops: sign then verify */
-
-#ifndef OPENSSL_NO_ECX
-enum { R_EC_Ed25519,
-    R_EC_Ed448,
-    EdDSA_NUM };
-static const OPT_PAIR eddsa_choices[EdDSA_NUM] = {
-    { "ed25519", R_EC_Ed25519 },
-    { "ed448", R_EC_Ed448 }
-
-};
-static double eddsa_results[EdDSA_NUM][2]; /* 2 ops: sign then verify */
-#endif /* OPENSSL_NO_ECX */
-
-#ifndef OPENSSL_NO_SM2
-enum { R_EC_CURVESM2,
-    SM2_NUM };
-static const OPT_PAIR sm2_choices[SM2_NUM] = {
-    { "curveSM2", R_EC_CURVESM2 }
-};
-#define SM2_ID "TLSv1.3+GM+Cipher+Suite"
-#define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1
-static double sm2_results[SM2_NUM][2]; /* 2 ops: sign then verify */
-#endif /* OPENSSL_NO_SM2 */
+static double ecdsa_results[EC_NUM][2]; /* 2 ops: sign then verify */

 #define MAX_KEM_NUM 111
 static size_t kems_algs_len = 0;
@@ -615,18 +615,12 @@ typedef struct loopargs_st {
     EVP_PKEY_CTX *dsa_sign_ctx[DSA_NUM];
     EVP_PKEY_CTX *dsa_verify_ctx[DSA_NUM];
 #endif
-    EVP_PKEY_CTX *ecdsa_sign_ctx[ECDSA_NUM];
-    EVP_PKEY_CTX *ecdsa_verify_ctx[ECDSA_NUM];
+    const char *curve_name[EC_NUM];
     EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
-#ifndef OPENSSL_NO_ECX
-    EVP_MD_CTX *eddsa_ctx[EdDSA_NUM];
-    EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM];
-#endif /* OPENSSL_NO_ECX */
-#ifndef OPENSSL_NO_SM2
-    EVP_MD_CTX *sm2_ctx[SM2_NUM];
-    EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM];
-    EVP_PKEY *sm2_pkey[SM2_NUM];
-#endif
+    EVP_PKEY_CTX *pk_sign_ctx[EC_NUM];
+    EVP_PKEY_CTX *pk_verify_ctx[EC_NUM];
+    EVP_MD_CTX *md_sign_ctx[EC_NUM];
+    EVP_MD_CTX *md_verify_ctx[EC_NUM];
     unsigned char *secret_a;
     unsigned char *secret_b;
     size_t outlen[EC_NUM];
@@ -1298,15 +1292,21 @@ static int ECDSA_sign_loop(void *args)
     loopargs_t *tempargs = *(loopargs_t **)args;
     unsigned char *buf = tempargs->buf;
     unsigned char *buf2 = tempargs->buf2;
-    size_t *ecdsa_num = &tempargs->sigsize;
-    EVP_PKEY_CTX **ecdsa_sign_ctx = tempargs->ecdsa_sign_ctx;
+    size_t *sigsize = &tempargs->sigsize;
+    EVP_PKEY_CTX *pctx = tempargs->pk_sign_ctx[testnum];
+    EVP_MD_CTX *mctx = tempargs->md_sign_ctx[testnum];
+    const char *curve_name = tempargs->curve_name[testnum];
     int ret, count;

     for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
-        *ecdsa_num = tempargs->buflen;
-        ret = EVP_PKEY_sign(ecdsa_sign_ctx[testnum], buf2, ecdsa_num, buf, 20);
+        *sigsize = tempargs->buflen;
+        if (pctx != NULL)
+            ret = EVP_PKEY_sign(pctx, buf2, sigsize, buf, 20);
+        else
+            ret = EVP_DigestSignInit_ex(mctx, NULL, NULL, NULL, NULL, NULL, NULL)
+                && EVP_DigestSign(mctx, buf2, sigsize, buf, 20);
         if (ret <= 0) {
-            BIO_puts(bio_err, "ECDSA sign failure\n");
+            BIO_printf(bio_err, "%s sign failure\n", curve_name);
             dofail();
             count = -1;
             break;
@@ -1320,15 +1320,20 @@ static int ECDSA_verify_loop(void *args)
     loopargs_t *tempargs = *(loopargs_t **)args;
     unsigned char *buf = tempargs->buf;
     unsigned char *buf2 = tempargs->buf2;
-    size_t ecdsa_num = tempargs->sigsize;
-    EVP_PKEY_CTX **ecdsa_verify_ctx = tempargs->ecdsa_verify_ctx;
+    size_t sigsize = tempargs->sigsize;
+    EVP_PKEY_CTX *pctx = tempargs->pk_verify_ctx[testnum];
+    EVP_MD_CTX *mctx = tempargs->md_verify_ctx[testnum];
+    const char *curve_name = tempargs->curve_name[testnum];
     int ret, count;

     for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
-        ret = EVP_PKEY_verify(ecdsa_verify_ctx[testnum], buf2, ecdsa_num,
-            buf, 20);
+        if (pctx != NULL)
+            ret = EVP_PKEY_verify(pctx, buf2, sigsize, buf, 20);
+        else
+            ret = EVP_DigestVerifyInit_ex(mctx, NULL, NULL, NULL, NULL, NULL, NULL)
+                && EVP_DigestVerify(mctx, buf2, sigsize, buf, 20);
         if (ret <= 0) {
-            BIO_puts(bio_err, "ECDSA verify failure\n");
+            BIO_printf(bio_err, "%s verify failure\n", curve_name);
             dofail();
             count = -1;
             break;
@@ -1353,132 +1358,6 @@ static int ECDH_EVP_derive_key_loop(void *args)
     return count;
 }

-#ifndef OPENSSL_NO_ECX
-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_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
-        if (ret == 0) {
-            BIO_puts(bio_err, "EdDSA sign init failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-        ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
-        if (ret == 0) {
-            BIO_puts(bio_err, "EdDSA sign failure\n");
-            dofail();
-            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_ctx2;
-    unsigned char *eddsasig = tempargs->buf2;
-    size_t eddsasigsize = tempargs->sigsize;
-    int ret, count;
-
-    for (count = 0; COND(eddsa_c[testnum][1]); count++) {
-        ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
-        if (ret == 0) {
-            BIO_puts(bio_err, "EdDSA verify init failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-        ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
-        if (ret != 1) {
-            BIO_puts(bio_err, "EdDSA verify failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-    }
-    return count;
-}
-#endif /* OPENSSL_NO_ECX */
-
-#ifndef OPENSSL_NO_SM2
-static int SM2_sign_loop(void *args)
-{
-    loopargs_t *tempargs = *(loopargs_t **)args;
-    unsigned char *buf = tempargs->buf;
-    EVP_MD_CTX **sm2ctx = tempargs->sm2_ctx;
-    unsigned char *sm2sig = tempargs->buf2;
-    size_t sm2sigsize;
-    int ret, count;
-    EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
-    const size_t max_size = EVP_PKEY_get_size(sm2_pkey[testnum]);
-
-    for (count = 0; COND(sm2_c[testnum][0]); count++) {
-        sm2sigsize = max_size;
-
-        if (!EVP_DigestSignInit(sm2ctx[testnum], NULL, EVP_sm3(),
-                NULL, sm2_pkey[testnum])) {
-            BIO_puts(bio_err, "SM2 init sign failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-        ret = EVP_DigestSign(sm2ctx[testnum], sm2sig, &sm2sigsize,
-            buf, 20);
-        if (ret == 0) {
-            BIO_puts(bio_err, "SM2 sign failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-        /* update the latest returned size and always use the fixed buffer size */
-        tempargs->sigsize = sm2sigsize;
-    }
-
-    return count;
-}
-
-static int SM2_verify_loop(void *args)
-{
-    loopargs_t *tempargs = *(loopargs_t **)args;
-    unsigned char *buf = tempargs->buf;
-    EVP_MD_CTX **sm2ctx = tempargs->sm2_vfy_ctx;
-    unsigned char *sm2sig = tempargs->buf2;
-    size_t sm2sigsize = tempargs->sigsize;
-    int ret, count;
-    EVP_PKEY **sm2_pkey = tempargs->sm2_pkey;
-
-    for (count = 0; COND(sm2_c[testnum][1]); count++) {
-        if (!EVP_DigestVerifyInit(sm2ctx[testnum], NULL, EVP_sm3(),
-                NULL, sm2_pkey[testnum])) {
-            BIO_puts(bio_err, "SM2 verify init failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-        ret = EVP_DigestVerify(sm2ctx[testnum], sm2sig, sm2sigsize,
-            buf, 20);
-        if (ret != 1) {
-            BIO_puts(bio_err, "SM2 verify failure\n");
-            dofail();
-            count = -1;
-            break;
-        }
-    }
-    return count;
-}
-#endif /* OPENSSL_NO_SM2 */
-
 static int KEM_keygen_loop(void *args)
 {
     loopargs_t *tempargs = *(loopargs_t **)args;
@@ -1769,79 +1648,33 @@ static int run_benchmark(int async_jobs,
 }

 typedef struct ec_curve_st {
-    const char *name;
-    unsigned int nid;
+    const char *algor;
+    char *group_name;
+    size_t group_name_size;
+    int mdsig;
     unsigned int bits;
-    size_t sigsize; /* only used for EdDSA curves */
 } EC_CURVE;

+#define EC_CURVE_NAME(c) ((c).group_name ? (c).group_name : (c).algor)
+
 static EVP_PKEY *get_ecdsa(const EC_CURVE *curve)
 {
     EVP_PKEY_CTX *kctx = NULL;
     EVP_PKEY *key = NULL;
+    OSSL_PARAM param[] = {
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
+        OSSL_PARAM_END,
+    };

-    /* Ensure that the error queue is empty */
-    if (ERR_peek_error()) {
-        BIO_puts(bio_err,
-            "WARNING: the error queue contains previous unhandled errors.\n");
-        dofail();
-    }
-
-    /*
-     * Let's try to create a ctx directly from the NID: this works for
-     * curves like Curve25519 that are not implemented through the low
-     * level EC interface.
-     * 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(curve->nid, NULL);
-    if (kctx == NULL) {
-        EVP_PKEY_CTX *pctx = NULL;
-        EVP_PKEY *params = NULL;
-        /*
-         * If we reach this code EVP_PKEY_CTX_new_id() failed and a
-         * "int_ctx_new:unsupported algorithm" error was added to the
-         * error queue.
-         * We remove it from the error queue as we are handling it.
-         */
-        unsigned long error = ERR_peek_error();
-
-        if (error == ERR_peek_last_error() /* oldest and latest errors match */
-            /* check that the error origin matches */
-            && ERR_GET_LIB(error) == ERR_LIB_EVP
-            && (ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM
-                || ERR_GET_REASON(error) == ERR_R_UNSUPPORTED))
-            ERR_get_error(); /* pop error from queue */
-        if (ERR_peek_error()) {
-            BIO_puts(bio_err,
-                "Unhandled error in the error queue during EC key setup.\n");
-            dofail();
-            return NULL;
-        }
-
-        /* Create the context for parameter generation */
-        if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL
-            || EVP_PKEY_paramgen_init(pctx) <= 0
-            || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
-                   curve->nid)
-                <= 0
-            || EVP_PKEY_paramgen(pctx, &params) <= 0) {
-            BIO_puts(bio_err, "EC params init failure.\n");
-            dofail();
-            EVP_PKEY_CTX_free(pctx);
-            return NULL;
-        }
-        EVP_PKEY_CTX_free(pctx);
+    param[0].data = curve->group_name;
+    param[0].data_size = curve->group_name_size;

-        /* Create the context for the key generation */
-        kctx = EVP_PKEY_CTX_new(params, NULL);
-        EVP_PKEY_free(params);
-    }
-    if (kctx == NULL
+    /* Create the context for parameter generation */
+    if ((kctx = EVP_PKEY_CTX_new_from_name(NULL, curve->algor, NULL)) == NULL
         || EVP_PKEY_keygen_init(kctx) <= 0
+        || (param[0].data_size > 0 && !EVP_PKEY_CTX_set_params(kctx, param))
         || EVP_PKEY_keygen(kctx, &key) <= 0) {
-        BIO_puts(bio_err, "EC key generation failure.\n");
+        BIO_printf(bio_err, "%s key generation failure.\n", curve->group_name);
         dofail();
         key = NULL;
     }
@@ -1904,7 +1737,9 @@ static int kem_locate(const char *algo, unsigned int *idx)
             return 1;
         }
     }
+    ERR_set_mark();
     kem = EVP_KEM_fetch(app_get0_libctx(), algo, app_get0_propq());
+    ERR_pop_to_mark();
     if (kem != NULL) {
         canonical_name = EVP_KEM_get0_name(kem);
         for (i = 0; i < kems_algs_len; i++) {
@@ -1950,7 +1785,9 @@ static int sig_locate(const char *algo, unsigned int *idx)
             return 1;
         }
     }
+    ERR_set_mark();
     sig = EVP_SIGNATURE_fetch(app_get0_libctx(), algo, app_get0_propq());
+    ERR_pop_to_mark();
     if (sig != NULL) {
         canonical_name = EVP_SIGNATURE_get0_name(sig);
         for (i = 0; i < sigs_algs_len; i++) {
@@ -2003,11 +1840,16 @@ int speed_main(int argc, char **argv)
     int multi = 0;
 #endif
     long op_count = 1;
-    openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
-        ECDSA_SECONDS, ECDH_SECONDS,
-        EdDSA_SECONDS, SM2_SECONDS,
-        FFDH_SECONDS, KEM_SECONDS,
-        SIG_SECONDS };
+    openssl_speed_sec_t seconds = {
+        SECONDS,
+        RSA_SECONDS,
+        DSA_SECONDS,
+        ECDSA_SECONDS,
+        ECDH_SECONDS,
+        FFDH_SECONDS,
+        KEM_SECONDS,
+        SIG_SECONDS,
+    };

     static const unsigned char key32[32] = {
         0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
@@ -2062,58 +1904,47 @@ int speed_main(int argc, char **argv)
      * the following arrays and increase the |ecdh_choices| and |ecdsa_choices|
      * lists accordingly.
      */
+#define STRSZ(lit) (lit), (sizeof(lit))
     static const EC_CURVE ec_curves[EC_NUM] = {
         /* Prime Curves */
-        { "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 },
+        { "EC", STRSZ("secp160r1"), 0, 160 },
+        { "EC", STRSZ("prime192v1"), 0, 192 },
+        { "EC", STRSZ("secp224r1"), 0, 224 },
+        { "EC", STRSZ("prime256v1"), 0, 256 },
+        { "EC", STRSZ("secp384r1"), 0, 384 },
+        { "EC", STRSZ("secp521r1"), 0, 521 },
 #ifndef OPENSSL_NO_EC2M
         /* Binary Curves */
-        { "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 },
+        { "EC", STRSZ("sect163k1"), 0, 163 },
+        { "EC", STRSZ("sect233k1"), 0, 233 },
+        { "EC", STRSZ("sect283k1"), 0, 283 },
+        { "EC", STRSZ("sect409k1"), 0, 409 },
+        { "EC", STRSZ("sect571k1"), 0, 571 },
+        { "EC", STRSZ("sect163r2"), 0, 163 },
+        { "EC", STRSZ("sect233r1"), 0, 233 },
+        { "EC", STRSZ("sect283r1"), 0, 283 },
+        { "EC", STRSZ("sect409r1"), 0, 409 },
+        { "EC", STRSZ("sect571r1"), 0, 571 },
 #endif
-        { "brainpoolP256r1", NID_brainpoolP256r1, 256 },
-        { "brainpoolP256t1", NID_brainpoolP256t1, 256 },
-        { "brainpoolP384r1", NID_brainpoolP384r1, 384 },
-        { "brainpoolP384t1", NID_brainpoolP384t1, 384 },
-        { "brainpoolP512r1", NID_brainpoolP512r1, 512 },
-        { "brainpoolP512t1", NID_brainpoolP512t1, 512 },
+        { "EC", STRSZ("brainpoolP256r1"), 0, 256 },
+        { "EC", STRSZ("brainpoolP256t1"), 0, 256 },
+        { "EC", STRSZ("brainpoolP384r1"), 0, 384 },
+        { "EC", STRSZ("brainpoolP384t1"), 0, 384 },
+        { "EC", STRSZ("brainpoolP512r1"), 0, 512 },
+        { "EC", STRSZ("brainpoolP512t1"), 0, 512 },
 #ifndef OPENSSL_NO_ECX
-        /* Other and ECDH only ones */
-        { "X25519", NID_X25519, 253 },
-        { "X448", NID_X448, 448 }
+        { "Ed25519", NULL, 0, 1, 253 },
+        { "Ed448", NULL, 0, 1, 456 },
+        { "X25519", NULL, 0, -1, 253 },
+        { "X448", NULL, 0, -1, 448 },
 #endif
-    };
-#ifndef OPENSSL_NO_ECX
-    static const EC_CURVE ed_curves[EdDSA_NUM] = {
-        /* EdDSA */
-        { "Ed25519", NID_ED25519, 253, 64 },
-        { "Ed448", NID_ED448, 456, 114 }
-    };
-#endif /* OPENSSL_NO_ECX */
 #ifndef OPENSSL_NO_SM2
-    static const EC_CURVE sm2_curves[SM2_NUM] = {
-        /* SM2 */
-        { "CurveSM2", NID_sm2, 256 }
-    };
-    uint8_t sm2_doit[SM2_NUM] = { 0 };
+        { "SM2", STRSZ("SM2"), 1, 256 },
+        { "curveSM2", STRSZ("SM2"), -1, 256 },
 #endif
-    uint8_t ecdsa_doit[ECDSA_NUM] = { 0 };
+    };
+    uint8_t ecdsa_doit[EC_NUM] = { 0 };
     uint8_t ecdh_doit[EC_NUM] = { 0 };
-#ifndef OPENSSL_NO_ECX
-    uint8_t eddsa_doit[EdDSA_NUM] = { 0 };
-#endif /* OPENSSL_NO_ECX */

     uint8_t kems_doit[MAX_KEM_NUM] = { 0 };
     uint8_t sigs_doit[MAX_SIG_NUM] = { 0 };
@@ -2121,23 +1952,6 @@ int speed_main(int argc, char **argv)
     uint8_t do_kems = 0;
     uint8_t do_sigs = 0;

-    /* checks declared curves against choices list. */
-#ifndef OPENSSL_NO_ECX
-    OPENSSL_assert(ed_curves[EdDSA_NUM - 1].nid == NID_ED448);
-    OPENSSL_assert(strcmp(eddsa_choices[EdDSA_NUM - 1].name, "ed448") == 0);
-
-    OPENSSL_assert(ec_curves[EC_NUM - 1].nid == NID_X448);
-    OPENSSL_assert(strcmp(ecdh_choices[EC_NUM - 1].name, "ecdhx448") == 0);
-
-    OPENSSL_assert(ec_curves[ECDSA_NUM - 1].nid == NID_brainpoolP512t1);
-    OPENSSL_assert(strcmp(ecdsa_choices[ECDSA_NUM - 1].name, "ecdsabrp512t1") == 0);
-#endif /* OPENSSL_NO_ECX */
-
-#ifndef OPENSSL_NO_SM2
-    OPENSSL_assert(sm2_curves[SM2_NUM - 1].nid == NID_sm2);
-    OPENSSL_assert(strcmp(sm2_choices[SM2_NUM - 1].name, "curveSM2") == 0);
-#endif
-
     prog = opt_init(argc, argv, speed_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -2259,9 +2073,8 @@ int speed_main(int argc, char **argv)
             break;
         case OPT_SECONDS:
             seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
-                = seconds.ecdh = seconds.eddsa
-                = seconds.sm2 = seconds.ffdh
-                = seconds.kem = seconds.sig = opt_int_arg();
+                = seconds.ecdh = seconds.ffdh = seconds.kem
+                = seconds.sig = opt_int_arg();
             break;
         case OPT_BYTES:
             lengths_single = opt_int_arg();
@@ -2371,7 +2184,16 @@ int speed_main(int argc, char **argv)
         }
 #endif /* OPENSSL_NO_DSA */
         /* skipping these algs as tested elsewhere - and b/o setup is a pain */
-        else if (strncmp(sig_name, "RSA", 3) && strncmp(sig_name, "DSA", 3) && strncmp(sig_name, "ED25519", 7) && strncmp(sig_name, "ED448", 5) && strncmp(sig_name, "ECDSA", 5) && strcmp(sig_name, "HMAC") && strcmp(sig_name, "SIPHASH") && strcmp(sig_name, "POLY1305") && strcmp(sig_name, "CMAC") && strcmp(sig_name, "SM2")) { /* skip alg */
+        else if (strncmp(sig_name, "RSA", 3)
+            && strncmp(sig_name, "DSA", 3)
+            && strncmp(sig_name, "ED25519", 7)
+            && strncmp(sig_name, "ED448", 5)
+            && strncmp(sig_name, "ECDSA", 5)
+            && strcmp(sig_name, "HMAC")
+            && strcmp(sig_name, "SIPHASH")
+            && strcmp(sig_name, "POLY1305")
+            && strcmp(sig_name, "CMAC")
+            && strcmp(sig_name, "SM2")) { /* skip alg */
             if (sigs_algs_len + 1 >= MAX_SIG_NUM) {
                 BIO_puts(bio_err,
                     "Too many signatures registered. Change MAX_SIG_NUM.\n");
@@ -2454,46 +2276,37 @@ int speed_main(int argc, char **argv)
             doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
             algo_found = 1;
         }
-        if (HAS_PREFIX(algo, "ecdsa")) {
-            if (algo[sizeof("ecdsa") - 1] == '\0') {
-                memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
-                algo_found = 1;
-            }
-            if (opt_found(algo, ecdsa_choices, &i)) {
-                ecdsa_doit[i] = 2;
-                algo_found = 1;
-            }
-        }
-        if (HAS_PREFIX(algo, "ecdh")) {
-            if (algo[sizeof("ecdh") - 1] == '\0') {
-                memset(ecdh_doit, 1, sizeof(ecdh_doit));
-                algo_found = 1;
-            }
-            if (opt_found(algo, ecdh_choices, &i)) {
-                ecdh_doit[i] = 2;
-                algo_found = 1;
-            }
+        if (strcmp(algo, "ecdsa") == 0) {
+            memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
+            algo_found = 1;
         }
-#ifndef OPENSSL_NO_ECX
-        if (strcmp(algo, "eddsa") == 0) {
-            memset(eddsa_doit, 1, sizeof(eddsa_doit));
+        if (strcmp(algo, "ecdh") == 0) {
+            memset(ecdh_doit, 1, sizeof(ecdh_doit));
             algo_found = 1;
         }
-        if (opt_found(algo, eddsa_choices, &i)) {
-            eddsa_doit[i] = 2;
+        for (i = 0; i < EC_NUM; i++) {
+            /* Negative values are ECDH-only curves */
+            if (ec_curves[i].mdsig < 0)
+                ecdsa_doit[i] = 0;
+            /* Positive values are signature-only curves */
+            if (ec_curves[i].mdsig > 0)
+                ecdh_doit[i] = 0;
+        }
+        if (opt_found(algo, ecdsa_choices, &i)) {
+            ecdsa_doit[i] = 2;
             algo_found = 1;
         }
-#endif /* OPENSSL_NO_ECX */
-#ifndef OPENSSL_NO_SM2
-        if (strcmp(algo, "sm2") == 0) {
-            memset(sm2_doit, 1, sizeof(sm2_doit));
+#ifndef OPENSSL_NO_ECX
+        if (strcmp(algo, "eddsa") == 0) {
             algo_found = 1;
+            ecdsa_doit[R_Ed25519] = 2;
+            ecdsa_doit[R_Ed448] = 2;
         }
-        if (opt_found(algo, sm2_choices, &i)) {
-            sm2_doit[i] = 2;
+#endif /* OPENSSL_NO_ECX */
+        if (opt_found(algo, ecdh_choices, &i)) {
+            ecdh_doit[i] = 2;
             algo_found = 1;
         }
-#endif
         if (kem_locate(algo, &idx)) {
             kems_doit[idx]++;
             do_kems = 1;
@@ -2673,11 +2486,7 @@ int speed_main(int argc, char **argv)
 #ifndef OPENSSL_NO_ECX
         memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
         memset(ecdh_doit, 1, sizeof(ecdh_doit));
-        memset(eddsa_doit, 1, sizeof(eddsa_doit));
 #endif /* OPENSSL_NO_ECX */
-#ifndef OPENSSL_NO_SM2
-        memset(sm2_doit, 1, sizeof(sm2_doit));
-#endif
         memset(kems_doit, 1, sizeof(kems_doit));
         do_kems = 1;
         memset(sigs_doit, 1, sizeof(sigs_doit));
@@ -3343,8 +3152,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R1:%ld:%d:%.2f\n"
-                   : "%ld %u bits private RSA sign ops in %.2fs\n",
+                mr ? "+R1:%ld:%d:%.2f\n" : "%ld %u bits private RSA sign ops in %.2fs\n",
                 count, rsa_keys[testnum].bits, d);
             rsa_results[testnum][0] = (double)count / d;
             op_count = count;
@@ -3374,8 +3182,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R2:%ld:%d:%.2f\n"
-                   : "%ld %u bits public RSA verify ops in %.2fs\n",
+                mr ? "+R2:%ld:%d:%.2f\n" : "%ld %u bits public RSA verify ops in %.2fs\n",
                 count, rsa_keys[testnum].bits, d);
             rsa_results[testnum][1] = (double)count / d;
         }
@@ -3405,8 +3212,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, RSA_encrypt_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R3:%ld:%d:%.2f\n"
-                   : "%ld %u bits public RSA encrypt ops in %.2fs\n",
+                mr ? "+R3:%ld:%d:%.2f\n" : "%ld %u bits public RSA encrypt ops in %.2fs\n",
                 count, rsa_keys[testnum].bits, d);
             rsa_results[testnum][2] = (double)count / d;
             op_count = count;
@@ -3438,8 +3244,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, RSA_decrypt_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R4:%ld:%d:%.2f\n"
-                   : "%ld %u bits private RSA decrypt ops in %.2fs\n",
+                mr ? "+R4:%ld:%d:%.2f\n" : "%ld %u bits private RSA decrypt ops in %.2fs\n",
                 count, rsa_keys[testnum].bits, d);
             rsa_results[testnum][3] = (double)count / d;
             op_count = count;
@@ -3487,8 +3292,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R5:%ld:%u:%.2f\n"
-                   : "%ld %u bits DSA sign ops in %.2fs\n",
+                mr ? "+R5:%ld:%u:%.2f\n" : "%ld %u bits DSA sign ops in %.2fs\n",
                 count, dsa_bits[testnum], d);
             dsa_results[testnum][0] = (double)count / d;
             op_count = count;
@@ -3518,8 +3322,7 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R6:%ld:%u:%.2f\n"
-                   : "%ld %u bits DSA verify ops in %.2fs\n",
+                mr ? "+R6:%ld:%u:%.2f\n" : "%ld %u bits DSA verify ops in %.2fs\n",
                 count, dsa_bits[testnum], d);
             dsa_results[testnum][1] = (double)count / d;
         }
@@ -3532,74 +3335,110 @@ int speed_main(int argc, char **argv)
     }
 #endif /* OPENSSL_NO_DSA */

-    for (testnum = 0; testnum < ECDSA_NUM; testnum++) {
-        EVP_PKEY *ecdsa_key = NULL;
+    for (testnum = 0; testnum < EC_NUM; testnum++) {
+        EVP_PKEY *pkey = NULL;
         int st;
+        int mdsig = ec_curves[testnum].mdsig > 0;

         if (!ecdsa_doit[testnum])
             continue;

-        st = (ecdsa_key = get_ecdsa(&ec_curves[testnum])) != NULL;
+        st = (pkey = get_ecdsa(&ec_curves[testnum])) != NULL;

         for (i = 0; st && i < loopargs_len; i++) {
-            loopargs[i].ecdsa_sign_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
-                NULL);
             loopargs[i].sigsize = loopargs[i].buflen;
-            if (loopargs[i].ecdsa_sign_ctx[testnum] == NULL
-                || EVP_PKEY_sign_init(loopargs[i].ecdsa_sign_ctx[testnum]) <= 0
-                || EVP_PKEY_sign(loopargs[i].ecdsa_sign_ctx[testnum],
-                       loopargs[i].buf2,
-                       &loopargs[i].sigsize,
-                       loopargs[i].buf, 20)
-                    <= 0)
-                st = 0;
+            loopargs[i].curve_name[testnum] = EC_CURVE_NAME(ec_curves[testnum]);
+            if (!mdsig) {
+                EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
+
+                if ((loopargs[i].pk_sign_ctx[testnum] = pctx) == NULL
+                    || EVP_PKEY_sign_init(pctx) <= 0
+                    || EVP_PKEY_sign(pctx, loopargs[i].buf2,
+                           &loopargs[i].sigsize, loopargs[i].buf, 20)
+                        <= 0)
+                    st = 0;
+            } else {
+                OSSL_PARAM params[2] = {
+                    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_TLS_VERSION, NULL),
+                    OSSL_PARAM_END,
+                };
+                EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+                int v = TLS1_3_VERSION;
+
+                /*
+                 * Emulate TLS signature code, the TLS version is needed for
+                 * SM2 to infer the correct "distinguishing identifier".
+                 */
+                params[0].data = &v;
+                if ((loopargs[i].md_sign_ctx[testnum] = mctx) == NULL
+                    || !EVP_DigestSignInit_ex(mctx, NULL, NULL, NULL, NULL, pkey, params))
+                    st = 0;
+            }
         }
         if (!st) {
-            BIO_puts(bio_err,
-                "ECDSA sign setup failure.  No ECDSA sign will be done.\n");
+            BIO_printf(bio_err,
+                "%s sign setup failure.  No %s signing will be done.\n",
+                EC_CURVE_NAME(ec_curves[testnum]),
+                EC_CURVE_NAME(ec_curves[testnum]));
             dofail();
             op_count = 1;
         } else {
-            pkey_print_message("sign", "ecdsa",
+            pkey_print_message("sign", EC_CURVE_NAME(ec_curves[testnum]),
                 ec_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 ? "+R7:%ld:%u:%.2f\n"
-                   : "%ld %u bits ECDSA sign ops in %.2fs\n",
-                count, ec_curves[testnum].bits, d);
+                mr ? "+R7:%ld:%s:%.2f\n" : "%ld %s sign ops in %.2fs\n",
+                count, EC_CURVE_NAME(ec_curves[testnum]), d);
             ecdsa_results[testnum][0] = (double)count / d;
             op_count = count;
         }

         for (i = 0; st && i < loopargs_len; i++) {
-            loopargs[i].ecdsa_verify_ctx[testnum] = EVP_PKEY_CTX_new(ecdsa_key,
-                NULL);
-            if (loopargs[i].ecdsa_verify_ctx[testnum] == NULL
-                || EVP_PKEY_verify_init(loopargs[i].ecdsa_verify_ctx[testnum]) <= 0
-                || EVP_PKEY_verify(loopargs[i].ecdsa_verify_ctx[testnum],
-                       loopargs[i].buf2,
-                       loopargs[i].sigsize,
-                       loopargs[i].buf, 20)
-                    <= 0)
-                st = 0;
+            if (!mdsig) {
+                EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
+
+                if ((loopargs[i].pk_verify_ctx[testnum] = pctx) == NULL
+                    || EVP_PKEY_verify_init(pctx) <= 0
+                    || EVP_PKEY_verify(pctx, loopargs[i].buf2,
+                           loopargs[i].sigsize, loopargs[i].buf, 20)
+                        <= 0)
+                    st = 0;
+            } else {
+                OSSL_PARAM params[2] = {
+                    OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_TLS_VERSION, NULL),
+                    OSSL_PARAM_END,
+                };
+                EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+                int v = TLS1_3_VERSION;
+
+                /*
+                 * Emulate TLS signature code, the TLS version is needed for
+                 * SM2 to infer the correct "distinguishing identifier".
+                 */
+                params[0].data = &v;
+                if ((loopargs[i].md_verify_ctx[testnum] = mctx) == NULL
+                    || !EVP_DigestVerifyInit_ex(mctx, NULL, NULL, NULL, NULL, pkey, params))
+                    st = 0;
+            }
         }
         if (!st) {
-            BIO_puts(bio_err,
-                "ECDSA verify setup failure.  No ECDSA verify will be done.\n");
+            BIO_printf(bio_err,
+                "%s verify setup failure.  No %s verification will be done.\n",
+                EC_CURVE_NAME(ec_curves[testnum]),
+                EC_CURVE_NAME(ec_curves[testnum]));
             dofail();
             ecdsa_doit[testnum] = 0;
         } else {
-            pkey_print_message("verify", "ecdsa",
+            pkey_print_message("verify", EC_CURVE_NAME(ec_curves[testnum]),
                 ec_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 ? "+R8:%ld:%u:%.2f\n"
-                   : "%ld %u bits ECDSA verify ops in %.2fs\n",
-                count, ec_curves[testnum].bits, d);
+                mr ? "+R8:%ld:%s:%.2f\n" : "%ld %s verify ops in %.2fs\n",
+                count, EC_CURVE_NAME(ec_curves[testnum]), d);
             ecdsa_results[testnum][1] = (double)count / d;
         }

@@ -3607,7 +3446,7 @@ int speed_main(int argc, char **argv)
             /* if longer than 10s, don't do any more */
             stop_it(ecdsa_doit, testnum);
         }
-        EVP_PKEY_free(ecdsa_key);
+        EVP_PKEY_free(pkey);
     }

     for (testnum = 0; testnum < EC_NUM; testnum++) {
@@ -3678,14 +3517,14 @@ int speed_main(int argc, char **argv)
             test_ctx = NULL;
         }
         if (ecdh_checks != 0) {
-            pkey_print_message("", "ecdh",
+            pkey_print_message("", EC_CURVE_NAME(ec_curves[testnum]),
                 ec_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 ? "+R9:%ld:%d:%.2f\n" : "%ld %u-bits ECDH ops in %.2fs\n", count,
-                ec_curves[testnum].bits, d);
+                mr ? "+R9:%ld:%s:%.2f\n" : "%ld %s ops in %.2fs\n",
+                count, EC_CURVE_NAME(ec_curves[testnum]), d);
             ecdh_results[testnum][0] = (double)count / d;
             op_count = count;
         }
@@ -3696,254 +3535,6 @@ int speed_main(int argc, char **argv)
         }
     }

-#ifndef OPENSSL_NO_ECX
-    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;
-            }
-            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
-                || EVP_PKEY_keygen_init(ed_pctx) <= 0
-                || EVP_PKEY_keygen(ed_pctx, &ed_pkey) <= 0) {
-                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;
-            }
-            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);
-            ed_pkey = NULL;
-        }
-        if (st == 0) {
-            BIO_puts(bio_err, "EdDSA failure.\n");
-            dofail();
-            op_count = 1;
-        } else {
-            for (i = 0; i < loopargs_len; i++) {
-                /* Perform EdDSA signature test */
-                loopargs[i].sigsize = 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_puts(bio_err,
-                    "EdDSA sign failure.  No EdDSA sign will be done.\n");
-                dofail();
-                op_count = 1;
-            } else {
-                pkey_print_message("sign", ed_curves[testnum].name,
-                    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 ? "+R10:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
-                    count, ed_curves[testnum].bits,
-                    ed_curves[testnum].name, d);
-                eddsa_results[testnum][0] = (double)count / d;
-                op_count = count;
-            }
-            /* Perform EdDSA verification test */
-            for (i = 0; i < loopargs_len; i++) {
-                st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum],
-                    loopargs[i].buf2, loopargs[i].sigsize,
-                    loopargs[i].buf, 20);
-                if (st != 1)
-                    break;
-            }
-            if (st != 1) {
-                BIO_puts(bio_err,
-                    "EdDSA verify failure.  No EdDSA verify will be done.\n");
-                dofail();
-                eddsa_doit[testnum] = 0;
-            } else {
-                pkey_print_message("verify", ed_curves[testnum].name,
-                    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 ? "+R11:%ld:%u:%s:%.2f\n"
-                       : "%ld %u bits %s verify ops in %.2fs\n",
-                    count, ed_curves[testnum].bits,
-                    ed_curves[testnum].name, d);
-                eddsa_results[testnum][1] = (double)count / d;
-            }
-
-            if (op_count <= 1) {
-                /* if longer than 10s, don't do any more */
-                stop_it(eddsa_doit, testnum);
-            }
-        }
-    }
-#endif /* OPENSSL_NO_ECX */
-
-#ifndef OPENSSL_NO_SM2
-    for (testnum = 0; testnum < SM2_NUM; testnum++) {
-        int st = 1;
-        EVP_PKEY *sm2_pkey = NULL;
-
-        if (!sm2_doit[testnum])
-            continue; /* Ignore Curve */
-        /* Init signing and verification */
-        for (i = 0; i < loopargs_len; i++) {
-            EVP_PKEY_CTX *sm2_pctx = NULL;
-            EVP_PKEY_CTX *sm2_vfy_pctx = NULL;
-            EVP_PKEY_CTX *pctx = NULL;
-            st = 0;
-
-            loopargs[i].sm2_ctx[testnum] = EVP_MD_CTX_new();
-            loopargs[i].sm2_vfy_ctx[testnum] = EVP_MD_CTX_new();
-            if (loopargs[i].sm2_ctx[testnum] == NULL
-                || loopargs[i].sm2_vfy_ctx[testnum] == NULL)
-                break;
-
-            sm2_pkey = NULL;
-
-            st = !((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL
-                || EVP_PKEY_keygen_init(pctx) <= 0
-                || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
-                       sm2_curves[testnum].nid)
-                    <= 0
-                || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0);
-            EVP_PKEY_CTX_free(pctx);
-            if (st == 0)
-                break;
-
-            st = 0; /* set back to zero */
-            /* attach it sooner to rely on main final cleanup */
-            loopargs[i].sm2_pkey[testnum] = sm2_pkey;
-            loopargs[i].sigsize = EVP_PKEY_get_size(sm2_pkey);
-
-            sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
-            sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
-            if (sm2_pctx == NULL || sm2_vfy_pctx == NULL) {
-                EVP_PKEY_CTX_free(sm2_vfy_pctx);
-                break;
-            }
-
-            /* attach them directly to respective ctx */
-            EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_ctx[testnum], sm2_pctx);
-            EVP_MD_CTX_set_pkey_ctx(loopargs[i].sm2_vfy_ctx[testnum], sm2_vfy_pctx);
-
-            /*
-             * No need to allow user to set an explicit ID here, just use
-             * the one defined in the 'draft-yang-tls-tl13-sm-suites' I-D.
-             */
-            if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1
-                || EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1)
-                break;
-
-            if (!EVP_DigestSignInit(loopargs[i].sm2_ctx[testnum], NULL,
-                    EVP_sm3(), NULL, sm2_pkey))
-                break;
-            if (!EVP_DigestVerifyInit(loopargs[i].sm2_vfy_ctx[testnum], NULL,
-                    EVP_sm3(), NULL, sm2_pkey))
-                break;
-            st = 1; /* mark loop as succeeded */
-        }
-        if (st == 0) {
-            BIO_puts(bio_err, "SM2 init failure.\n");
-            dofail();
-            op_count = 1;
-        } else {
-            for (i = 0; i < loopargs_len; i++) {
-                /* Perform SM2 signature test */
-                st = EVP_DigestSign(loopargs[i].sm2_ctx[testnum],
-                    loopargs[i].buf2, &loopargs[i].sigsize,
-                    loopargs[i].buf, 20);
-                if (st == 0)
-                    break;
-            }
-            if (st == 0) {
-                BIO_puts(bio_err,
-                    "SM2 sign failure.  No SM2 sign will be done.\n");
-                dofail();
-                op_count = 1;
-            } else {
-                pkey_print_message("sign", sm2_curves[testnum].name,
-                    sm2_curves[testnum].bits, seconds.sm2);
-                Time_F(START);
-                count = run_benchmark(async_jobs, SM2_sign_loop, loopargs);
-                d = Time_F(STOP);
-
-                BIO_printf(bio_err,
-                    mr ? "+R12:%ld:%u:%s:%.2f\n" : "%ld %u bits %s sign ops in %.2fs \n",
-                    count, sm2_curves[testnum].bits,
-                    sm2_curves[testnum].name, d);
-                sm2_results[testnum][0] = (double)count / d;
-                op_count = count;
-            }
-
-            /* Perform SM2 verification test */
-            for (i = 0; i < loopargs_len; i++) {
-                st = EVP_DigestVerify(loopargs[i].sm2_vfy_ctx[testnum],
-                    loopargs[i].buf2, loopargs[i].sigsize,
-                    loopargs[i].buf, 20);
-                if (st != 1)
-                    break;
-            }
-            if (st != 1) {
-                BIO_puts(bio_err,
-                    "SM2 verify failure.  No SM2 verify will be done.\n");
-                dofail();
-                sm2_doit[testnum] = 0;
-            } else {
-                pkey_print_message("verify", sm2_curves[testnum].name,
-                    sm2_curves[testnum].bits, seconds.sm2);
-                Time_F(START);
-                count = run_benchmark(async_jobs, SM2_verify_loop, loopargs);
-                d = Time_F(STOP);
-                BIO_printf(bio_err,
-                    mr ? "+R13:%ld:%u:%s:%.2f\n"
-                       : "%ld %u bits %s verify ops in %.2fs\n",
-                    count, sm2_curves[testnum].bits,
-                    sm2_curves[testnum].name, d);
-                sm2_results[testnum][1] = (double)count / d;
-            }
-
-            if (op_count <= 1) {
-                /* if longer than 10s, don't do any more */
-                for (testnum++; testnum < SM2_NUM; testnum++)
-                    sm2_doit[testnum] = 0;
-            }
-        }
-    }
-#endif /* OPENSSL_NO_SM2 */
-
 #ifndef OPENSSL_NO_DH
     for (testnum = 0; testnum < FFDH_NUM; testnum++) {
         int ffdh_checks = 1;
@@ -4283,8 +3874,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, KEM_keygen_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R15:%ld:%s:%.2f\n" : "%ld %s KEM keygen ops in %.2fs\n", count,
-                kem_name, d);
+                mr ? "+R15:%ld:%s:%.2f\n" : "%ld %s KEM keygen ops in %.2fs\n",
+                count, kem_name, d);
             kems_results[testnum][0] = (double)count / d;
             op_count = count;
             kskey_print_message(kem_name, "encaps", seconds.kem);
@@ -4292,8 +3883,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, KEM_encaps_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R16:%ld:%s:%.2f\n" : "%ld %s KEM encaps ops in %.2fs\n", count,
-                kem_name, d);
+                mr ? "+R16:%ld:%s:%.2f\n" : "%ld %s KEM encaps ops in %.2fs\n",
+                count, kem_name, d);
             kems_results[testnum][1] = (double)count / d;
             op_count = count;
             kskey_print_message(kem_name, "decaps", seconds.kem);
@@ -4301,8 +3892,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, KEM_decaps_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R17:%ld:%s:%.2f\n" : "%ld %s KEM decaps ops in %.2fs\n", count,
-                kem_name, d);
+                mr ? "+R17:%ld:%s:%.2f\n" : "%ld %s KEM decaps ops in %.2fs\n",
+                count, kem_name, d);
             kems_results[testnum][2] = (double)count / d;
             op_count = count;
         }
@@ -4494,8 +4085,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, SIG_keygen_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R18:%ld:%s:%.2f\n" : "%ld %s signature keygen ops in %.2fs\n", count,
-                sig_name, d);
+                mr ? "+R18:%ld:%s:%.2f\n" : "%ld %s signature keygen ops in %.2fs\n",
+                count, sig_name, d);
             sigs_results[testnum][0] = (double)count / d;
             op_count = count;
             kskey_print_message(sig_name, "signs", seconds.sig);
@@ -4503,8 +4094,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, SIG_sign_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R19:%ld:%s:%.2f\n" : "%ld %s signature sign ops in %.2fs\n", count,
-                sig_name, d);
+                mr ? "+R19:%ld:%s:%.2f\n" : "%ld %s signature sign ops in %.2fs\n",
+                count, sig_name, d);
             sigs_results[testnum][1] = (double)count / d;
             op_count = count;

@@ -4513,8 +4104,8 @@ int speed_main(int argc, char **argv)
             count = run_benchmark(async_jobs, SIG_verify_loop, loopargs);
             d = Time_F(STOP);
             BIO_printf(bio_err,
-                mr ? "+R20:%ld:%s:%.2f\n" : "%ld %s signature verify ops in %.2fs\n", count,
-                sig_name, d);
+                mr ? "+R20:%ld:%s:%.2f\n" : "%ld %s signature verify ops in %.2fs\n",
+                count, sig_name, d);
             sigs_results[testnum][2] = (double)count / d;
             op_count = count;
         }
@@ -4622,8 +4213,8 @@ show_res:
                 k, ec_curves[k].bits,
                 ecdsa_results[k][0], ecdsa_results[k][1]);
         else
-            printf("%4u bits ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
-                ec_curves[k].bits, ec_curves[k].name,
+            printf("%4u bits EC (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
+                ec_curves[k].bits, EC_CURVE_NAME(ec_curves[k]),
                 1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
                 ecdsa_results[k][0], ecdsa_results[k][1]);
     }
@@ -4643,53 +4234,10 @@ show_res:

         else
             printf("%4u bits ecdh (%s) %8.4fs %8.1f\n",
-                ec_curves[k].bits, ec_curves[k].name,
+                ec_curves[k].bits, EC_CURVE_NAME(ec_curves[k]),
                 1.0 / ecdh_results[k][0], ecdh_results[k][0]);
     }

-#ifndef OPENSSL_NO_ECX
-    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, ed_curves[k].bits, 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",
-                ed_curves[k].bits, 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 /* OPENSSL_NO_ECX */
-
-#ifndef OPENSSL_NO_SM2
-    testnum = 1;
-    for (k = 0; k < OSSL_NELEM(sm2_doit); k++) {
-        if (!sm2_doit[k])
-            continue;
-        if (testnum && !mr) {
-            printf("%30ssign    verify    sign/s verify/s\n", " ");
-            testnum = 0;
-        }
-
-        if (mr)
-            printf("+F7:%u:%u:%s:%f:%f\n",
-                k, sm2_curves[k].bits, sm2_curves[k].name,
-                sm2_results[k][0], sm2_results[k][1]);
-        else
-            printf("%4u bits SM2 (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
-                sm2_curves[k].bits, sm2_curves[k].name,
-                1.0 / sm2_results[k][0], 1.0 / sm2_results[k][1],
-                sm2_results[k][0], sm2_results[k][1]);
-    }
-#endif
 #ifndef OPENSSL_NO_DH
     testnum = 1;
     for (k = 0; k < FFDH_NUM; k++) {
@@ -4700,7 +4248,7 @@ show_res:
             testnum = 0;
         }
         if (mr)
-            printf("+F8:%u:%u:%f:%f\n",
+            printf("+F7:%u:%u:%f:%f\n",
                 k, ffdh_params[k].bits,
                 ffdh_results[k][0], 1.0 / ffdh_results[k][0]);

@@ -4722,7 +4270,7 @@ show_res:
             testnum = 0;
         }
         if (mr)
-            printf("+F9:%u:%f:%f:%f\n",
+            printf("+F8:%u:%f:%f:%f\n",
                 k, kems_results[k][0], kems_results[k][1],
                 kems_results[k][2]);
         else
@@ -4744,7 +4292,7 @@ show_res:
             testnum = 0;
         }
         if (mr)
-            printf("+F10:%u:%f:%f:%f\n",
+            printf("+F9:%u:%f:%f:%f\n",
                 k, sigs_results[k][0], sigs_results[k][1],
                 sigs_results[k][2]);
         else
@@ -4783,36 +4331,12 @@ end:
             EVP_PKEY_CTX_free(loopargs[i].dsa_verify_ctx[k]);
         }
 #endif
-        for (k = 0; k < ECDSA_NUM; k++) {
-            EVP_PKEY_CTX_free(loopargs[i].ecdsa_sign_ctx[k]);
-            EVP_PKEY_CTX_free(loopargs[i].ecdsa_verify_ctx[k]);
+        for (k = 0; k < EC_NUM; k++) {
+            EVP_PKEY_CTX_free(loopargs[i].pk_sign_ctx[k]);
+            EVP_PKEY_CTX_free(loopargs[i].pk_verify_ctx[k]);
         }
         for (k = 0; k < EC_NUM; k++)
             EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
-#ifndef OPENSSL_NO_ECX
-        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]);
-        }
-#endif /* OPENSSL_NO_ECX */
-#ifndef OPENSSL_NO_SM2
-        for (k = 0; k < SM2_NUM; k++) {
-            EVP_PKEY_CTX *pctx = NULL;
-
-            /* free signing ctx */
-            if (loopargs[i].sm2_ctx[k] != NULL
-                && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_ctx[k])) != NULL)
-                EVP_PKEY_CTX_free(pctx);
-            EVP_MD_CTX_free(loopargs[i].sm2_ctx[k]);
-            /* free verification ctx */
-            if (loopargs[i].sm2_vfy_ctx[k] != NULL
-                && (pctx = EVP_MD_CTX_get_pkey_ctx(loopargs[i].sm2_vfy_ctx[k])) != NULL)
-                EVP_PKEY_CTX_free(pctx);
-            EVP_MD_CTX_free(loopargs[i].sm2_vfy_ctx[k]);
-            /* free pkey */
-            EVP_PKEY_free(loopargs[i].sm2_pkey[k]);
-        }
-#endif
         for (k = 0; k < kems_algs_len; k++) {
             EVP_PKEY_CTX_free(loopargs[i].kem_gen_ctx[k]);
             EVP_PKEY_CTX_free(loopargs[i].kem_encaps_ctx[k]);
@@ -4859,8 +4383,7 @@ end:
 static void print_message(const char *s, int length, int tm)
 {
     BIO_printf(bio_err,
-        mr ? "+DT:%s:%d:%d\n"
-           : "Doing %s ops for %ds on %d size blocks: ",
+        mr ? "+DT:%s:%d:%d\n" : "Doing %s ops for %ds on %d size blocks: ",
         s, tm, length);
     (void)BIO_flush(bio_err);
     run = 1;
@@ -4871,8 +4394,7 @@ static void pkey_print_message(const char *str, const char *str2, unsigned int b
     int tm)
 {
     BIO_printf(bio_err,
-        mr ? "+DTP:%d:%s:%s:%d\n"
-           : "Doing %u bits %s %s ops for %ds: ",
+        mr ? "+DTP:%d:%s:%s:%d\n" : "Doing %u bits %s %s ops for %ds: ",
         bits, str, str2, tm);
     (void)BIO_flush(bio_err);
     run = 1;
@@ -4882,8 +4404,7 @@ static void pkey_print_message(const char *str, const char *str2, unsigned int b
 static void kskey_print_message(const char *str, const char *str2, int tm)
 {
     BIO_printf(bio_err,
-        mr ? "+DTP:%s:%s:%d\n"
-           : "Doing %s %s ops for %ds: ",
+        mr ? "+DTP:%s:%s:%d\n" : "Doing %s %s ops for %ds: ",
         str, str2, tm);
     (void)BIO_flush(bio_err);
     run = 1;
@@ -4898,8 +4419,7 @@ static void print_result(int alg, int run_no, int count, double time_used)
         return;
     }
     BIO_printf(bio_err,
-        mr ? "+R:%d:%s:%f\n"
-           : "%d %s ops in %.2fs\n",
+        mr ? "+R:%d:%s:%f\n" : "%d %s ops in %.2fs\n",
         count, names[alg], time_used);
     results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
 }
@@ -5066,36 +4586,8 @@ static int do_multi(int multi, int size_num)
                     d = atof(sstrsep(&p, sep));
                     ecdh_results[k][0] += d;
                 }
-#ifndef OPENSSL_NO_ECX
-            } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
-                tk = sstrsep(&p, sep);
-                if (strtoint(tk, 0, OSSL_NELEM(eddsa_results), &k)) {
-                    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 /* OPENSSL_NO_ECX */
-#ifndef OPENSSL_NO_SM2
-            } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
-                tk = sstrsep(&p, sep);
-                if (strtoint(tk, 0, OSSL_NELEM(sm2_results), &k)) {
-                    sstrsep(&p, sep);
-                    sstrsep(&p, sep);
-
-                    d = atof(sstrsep(&p, sep));
-                    sm2_results[k][0] += d;
-
-                    d = atof(sstrsep(&p, sep));
-                    sm2_results[k][1] += d;
-                }
-#endif /* OPENSSL_NO_SM2 */
 #ifndef OPENSSL_NO_DH
-            } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
                 tk = sstrsep(&p, sep);
                 if (strtoint(tk, 0, OSSL_NELEM(ffdh_results), &k)) {
                     sstrsep(&p, sep);
@@ -5104,7 +4596,7 @@ static int do_multi(int multi, int size_num)
                     ffdh_results[k][0] += d;
                 }
 #endif /* OPENSSL_NO_DH */
-            } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
                 tk = sstrsep(&p, sep);
                 if (strtoint(tk, 0, OSSL_NELEM(kems_results), &k)) {
                     d = atof(sstrsep(&p, sep));
@@ -5116,7 +4608,7 @@ static int do_multi(int multi, int size_num)
                     d = atof(sstrsep(&p, sep));
                     kems_results[k][2] += d;
                 }
-            } else if (CHECK_AND_SKIP_PREFIX(p, "+F10:")) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F9:")) {
                 tk = sstrsep(&p, sep);
                 if (strtoint(tk, 0, OSSL_NELEM(sigs_results), &k)) {
                     d = atof(sstrsep(&p, sep));