EVP_PKCS82PKEY: Create provided keys if possible
[openssl.git] / test / endecode_test.c
index 580b7e8f35b1388c08ebe41624e17f9fa19a2d7c..ab4b631a8f63ef330afbd2b6103a2a224b1cd9d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -8,6 +8,7 @@
  */
 
 #include <string.h>
+#include <openssl/core_dispatch.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/rsa.h>
 #include <openssl/encoder.h>
 #include <openssl/decoder.h>
 
-#include "internal/pem.h"        /* For PVK and "blob" PEM headers */
 #include "internal/cryptlib.h"   /* ossl_assert */
+#include "crypto/pem.h"          /* For PVK and "blob" PEM headers */
+#include "crypto/evp.h"          /* For evp_pkey_is_provided() */
 
+#include "helpers/predefined_dhparams.h"
 #include "testutil.h"
 
+/* Extended test macros to allow passing file & line number */
+#define TEST_FL_ptr(a)               test_ptr(file, line, #a, a)
+#define TEST_FL_mem_eq(a, m, b, n)   test_mem_eq(file, line, #a, #b, a, m, b, n)
+#define TEST_FL_strn_eq(a, b, n)     test_strn_eq(file, line, #a, #b, a, n, b, n)
+#define TEST_FL_strn2_eq(a, m, b, n) test_strn_eq(file, line, #a, #b, a, m, b, n)
+#define TEST_FL_int_eq(a, b)         test_int_eq(file, line, #a, #b, a, b)
+#define TEST_FL_int_ge(a, b)         test_int_ge(file, line, #a, #b, a, b)
+#define TEST_FL_int_gt(a, b)         test_int_gt(file, line, #a, #b, a, b)
+#define TEST_FL_long_gt(a, b)        test_long_gt(file, line, #a, #b, a, b)
+#define TEST_FL_true(a)              test_true(file, line, #a, (a) != 0)
+
+#if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_DSA) && defined(OPENSSL_NO_EC)
+# define OPENSSL_NO_KEYPARAMS
+#endif
+
 #ifndef OPENSSL_NO_EC
 static BN_CTX *bnctx = NULL;
 static OSSL_PARAM_BLD *bld_prime_nc = NULL;
@@ -38,16 +56,28 @@ static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL;
 # endif
 #endif
 
+#ifndef OPENSSL_NO_KEYPARAMS
 static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
 {
     EVP_PKEY *pkey = NULL;
-    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
+    EVP_PKEY_CTX *ctx = NULL;
+
+# ifndef OPENSSL_NO_DH
+    /*
+     * Use 512-bit DH(X) keys with predetermined parameters for efficiency,
+     * for testing only. Use a minimum key size of 2048 for security purposes.
+     */
+    if (strcmp(type, "DH") == 0)
+        return get_dh512(NULL);
+    if (strcmp(type, "X9.42 DH") == 0)
+        return get_dhx512(NULL);
+# endif
 
     /*
      * No real need to check the errors other than for the cascade
      * effect.  |pkey| will simply remain NULL if something goes wrong.
      */
-    (void)(ctx != NULL
+    (void)((ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL)) != NULL
            && EVP_PKEY_paramgen_init(ctx) > 0
            && (genparams == NULL
                || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
@@ -56,6 +86,7 @@ static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
 
     return pkey;
 }
+#endif
 
 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
                           OSSL_PARAM *genparams)
@@ -81,29 +112,32 @@ static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
 
 /* Main test driver */
 
-/*
- * TODO(3.0) For better error output, changed the callbacks to take __FILE__
- * and __LINE__ as first two arguments, and have them use the lower case
- * functions, such as test_strn_eq(), rather than the uppercase macros
- * (TEST_strn2_eq(), for example).
- */
-
-typedef int (encoder)(void **encoded, long *encoded_len,
-                      void *object, const char *pass, const char *pcipher,
-                      const char *encoder_propq);
-typedef int (decoder)(void **object,
-                      void *encoded, long encoded_len,
-                      const char *pass);
-typedef int (tester)(const void *data1, size_t data1_len,
+typedef int (encoder)(const char *file, const int line,
+                      void **encoded, long *encoded_len,
+                      void *object, int selection,
+                      const char *output_type, const char *output_structure,
+                      const char *pass, const char *pcipher);
+typedef int (decoder)(const char *file, const int line,
+                      void **object, void *encoded, long encoded_len,
+                      const char *input_type, const char *structure_type,
+                      const char *keytype, int selection, const char *pass);
+typedef int (tester)(const char *file, const int line,
+                     const void *data1, size_t data1_len,
                      const void *data2, size_t data2_len);
-typedef int (checker)(const char *type, const void *data, size_t data_len);
+typedef int (checker)(const char *file, const int line,
+                      const char *type, const void *data, size_t data_len);
 typedef void (dumper)(const char *label, const void *data, size_t data_len);
 
-static int test_encode_decode(const char *type, EVP_PKEY *pkey,
+#define FLAG_DECODE_WITH_TYPE   0x0001
+
+static int test_encode_decode(const char *file, const int line,
+                              const char *type, EVP_PKEY *pkey,
+                              int selection, const char *output_type,
+                              const char *output_structure,
                               const char *pass, const char *pcipher,
                               encoder *encode_cb, decoder *decode_cb,
                               tester *test_cb, checker *check_cb,
-                              dumper *dump_cb, const char *encoder_propq)
+                              dumper *dump_cb, int flags)
 {
     void *encoded = NULL;
     long encoded_len = 0;
@@ -112,33 +146,46 @@ static int test_encode_decode(const char *type, EVP_PKEY *pkey,
     long encoded2_len = 0;
     int ok = 0;
 
-    if (!encode_cb(&encoded, &encoded_len, pkey,
-                      pass, pcipher, encoder_propq)
-        || !check_cb(type, encoded, encoded_len)
-        || !decode_cb((void **)&pkey2, encoded, encoded_len,
-                           pass)
-        || !TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
+    /*
+     * Encode |pkey|, decode the result into |pkey2|, and finish off by
+     * encoding |pkey2| as well.  That last encoding is for checking and
+     * dumping purposes.
+     */
+    if (!TEST_true(encode_cb(file, line, &encoded, &encoded_len, pkey, selection,
+                             output_type, output_structure, pass, pcipher))
+        || !TEST_true(check_cb(file, line, type, encoded, encoded_len))
+        || !TEST_true(decode_cb(file, line, (void **)&pkey2, encoded, encoded_len,
+                                output_type, output_structure,
+                                (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
+                                selection, pass))
+        || !TEST_true(encode_cb(file, line, &encoded2, &encoded2_len, pkey2, selection,
+                                output_type, output_structure, pass, pcipher)))
         goto end;
 
+    if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
+        if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1))
+            goto end;
+    } else {
+        if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
+            goto end;
+    }
+
     /*
      * Double check the encoding, but only for unprotected keys,
      * as protected keys have a random component, which makes the output
      * differ.
      */
     if ((pass == NULL && pcipher == NULL)
-        && (!encode_cb(&encoded2, &encoded2_len, pkey2,
-                          pass, pcipher, encoder_propq)
-            || !test_cb(encoded, encoded_len,
-                        encoded2, encoded2_len)))
+        && !test_cb(file, line, encoded, encoded_len, encoded2, encoded2_len))
         goto end;
 
     ok = 1;
  end:
     if (!ok) {
         if (encoded != NULL && encoded_len != 0)
-            dump_cb("encoded result", encoded, encoded_len);
+            dump_cb("|pkey| encoded", encoded, encoded_len);
         if (encoded2 != NULL && encoded2_len != 0)
-            dump_cb("re-encoded result", encoded2, encoded2_len);
+            dump_cb("|pkey2| encoded", encoded2, encoded2_len);
     }
 
     OPENSSL_free(encoded);
@@ -147,12 +194,14 @@ static int test_encode_decode(const char *type, EVP_PKEY *pkey,
     return ok;
 }
 
-/* Encoding and desencoding methods */
+/* Encoding and decoding methods */
 
-static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
-                                void *object,
-                                const char *pass, const char *pcipher,
-                                const char *encoder_propq)
+static int encode_EVP_PKEY_prov(const char *file, const int line,
+                                void **encoded, long *encoded_len,
+                                void *object, int selection,
+                                const char *output_type,
+                                const char *output_structure,
+                                const char *pass, const char *pcipher)
 {
     EVP_PKEY *pkey = object;
     OSSL_ENCODER_CTX *ectx = NULL;
@@ -161,17 +210,21 @@ static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
     const unsigned char *upass = (const unsigned char *)pass;
     int ok = 0;
 
-    if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, encoder_propq))
+    if (!TEST_FL_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
+                                                       output_type,
+                                                       output_structure,
+                                                       NULL))
+        || !TEST_FL_int_gt(OSSL_ENCODER_CTX_get_num_encoders(ectx), 0)
         || (pass != NULL
-            && !TEST_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
-                                                             strlen(pass))))
+            && !TEST_FL_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
+                                                          strlen(pass))))
         || (pcipher != NULL
-            && !TEST_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
-        || !TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
-        || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*encoded = mem_buf->data)
-        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
+            && !TEST_FL_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
+        || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
+        || !TEST_FL_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
+        || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
+        || !TEST_FL_ptr(*encoded = mem_buf->data)
+        || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
     /* Detach the encoded output */
@@ -184,37 +237,87 @@ static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
     return ok;
 }
 
-static int decode_EVP_PKEY_prov(void **object,
-                                void *encoded, long encoded_len,
+static int decode_EVP_PKEY_prov(const char *file, const int line,
+                                void **object, void *encoded, long encoded_len,
+                                const char *input_type,
+                                const char *structure_type,
+                                const char *keytype, int selection,
                                 const char *pass)
 {
-    EVP_PKEY *pkey = NULL;
+    EVP_PKEY *pkey = NULL, *testpkey = NULL;
     OSSL_DECODER_CTX *dctx = NULL;
-    BIO *mem_deser = NULL;
+    BIO *encoded_bio = NULL;
     const unsigned char *upass = (const unsigned char *)pass;
     int ok = 0;
+    int i;
+    const char *badtype;
 
-    if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL,
-                                                               NULL, NULL))
-        || (pass != NULL
-            && !OSSL_DECODER_CTX_set_passphrase(dctx, upass,
-                                                     strlen(pass)))
-        || !TEST_ptr(mem_deser = BIO_new_mem_buf(encoded, encoded_len))
-        || !TEST_true(OSSL_DECODER_from_bio(dctx, mem_deser)))
+    if (strcmp(input_type, "DER") == 0)
+        badtype = "PEM";
+    else
+        badtype = "DER";
+
+    if (!TEST_FL_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
         goto end;
+
+    /*
+     * We attempt the decode 3 times. The first time we provide the expected
+     * starting input type. The second time we provide NULL for the starting
+     * type. The third time we provide a bad starting input type.
+     * The bad starting input type should fail. The other two should succeed
+     * and produce the same result.
+     */
+    for (i = 0; i < 3; i++) {
+        const char *testtype = (i == 0) ? input_type
+                                        : ((i == 1) ? NULL : badtype);
+
+        if (!TEST_FL_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&testpkey,
+                                                           testtype,
+                                                           structure_type,
+                                                           keytype,
+                                                           selection,
+                                                           NULL, NULL))
+            || (pass != NULL
+                && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
+            || !TEST_FL_int_gt(BIO_reset(encoded_bio), 0)
+               /* We expect to fail when using a bad input type */
+            || !TEST_FL_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
+                            (i == 2) ? 0 : 1))
+            goto end;
+        OSSL_DECODER_CTX_free(dctx);
+        dctx = NULL;
+
+        if (i == 0) {
+            pkey = testpkey;
+            testpkey = NULL;
+        } else if (i == 1) {
+            if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
+                if (!TEST_FL_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
+                    goto end;
+            } else {
+                if (!TEST_FL_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
+                    goto end;
+            }
+        }
+    }
     ok = 1;
     *object = pkey;
+    pkey = NULL;
+
  end:
-    BIO_free(mem_deser);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_free(testpkey);
+    BIO_free(encoded_bio);
     OSSL_DECODER_CTX_free(dctx);
     return ok;
 }
 
-static int encode_EVP_PKEY_legacy_PEM(void **encoded,
-                                      long *encoded_len,
-                                      void *object,
-                                      const char *pass, const char *pcipher,
-                                      ossl_unused const char *encoder_propq)
+static int encode_EVP_PKEY_legacy_PEM(const char *file, const int line,
+                                      void **encoded, long *encoded_len,
+                                      void *object, ossl_unused int selection,
+                                      ossl_unused const char *output_type,
+                                      ossl_unused const char *output_structure,
+                                      const char *pass, const char *pcipher)
 {
     EVP_PKEY *pkey = object;
     EVP_CIPHER *cipher = NULL;
@@ -226,17 +329,17 @@ static int encode_EVP_PKEY_legacy_PEM(void **encoded,
 
     if (pcipher != NULL && pass != NULL) {
         passlen = strlen(pass);
-        if (!TEST_ptr(cipher = EVP_CIPHER_fetch(NULL, pcipher, NULL)))
+        if (!TEST_FL_ptr(cipher = EVP_CIPHER_fetch(NULL, pcipher, NULL)))
             goto end;
     }
-    if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
+    if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
+        || !TEST_FL_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
                                                            cipher,
                                                            upass, passlen,
                                                            NULL, NULL))
-        || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*encoded = mem_buf->data)
-        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
+        || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
+        || !TEST_FL_ptr(*encoded = mem_buf->data)
+        || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
     /* Detach the encoded output */
@@ -249,50 +352,33 @@ static int encode_EVP_PKEY_legacy_PEM(void **encoded,
     return ok;
 }
 
-#ifndef OPENSSL_NO_DSA
-static int encode_EVP_PKEY_MSBLOB(void **encoded, long *encoded_len,
-                                  void *object,
+static int encode_EVP_PKEY_MSBLOB(const char *file, const int line,
+                                  void **encoded, long *encoded_len,
+                                  void *object, int selection,
+                                  ossl_unused const char *output_type,
+                                  ossl_unused const char *output_structure,
                                   ossl_unused const char *pass,
-                                  ossl_unused const char *pcipher,
-                                  ossl_unused const char *encoder_propq)
+                                  ossl_unused const char *pcipher)
 {
     EVP_PKEY *pkey = object;
     BIO *mem_ser = NULL;
     BUF_MEM *mem_buf = NULL;
     int ok = 0;
 
-    if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0)
-        || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*encoded = mem_buf->data)
-        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
+    if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem())))
         goto end;
 
-    /* Detach the encoded output */
-    mem_buf->data = NULL;
-    mem_buf->length = 0;
-    ok = 1;
- end:
-    BIO_free(mem_ser);
-    return ok;
-}
-
-static int encode_public_EVP_PKEY_MSBLOB(void **encoded, long *encoded_len,
-                                         void *object,
-                                         ossl_unused const char *pass,
-                                         ossl_unused const char *pcipher,
-                                         ossl_unused const char *encoder_propq)
-{
-    EVP_PKEY *pkey = object;
-    BIO *mem_ser = NULL;
-    BUF_MEM *mem_buf = NULL;
-    int ok = 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if (!TEST_FL_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0))
+            goto end;
+    } else {
+        if (!TEST_FL_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0))
+            goto end;
+    }
 
-    if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0)
-        || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*encoded = mem_buf->data)
-        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
+    if (!TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
+        || !TEST_FL_ptr(*encoded = mem_buf->data)
+        || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
     /* Detach the encoded output */
@@ -304,7 +390,6 @@ static int encode_public_EVP_PKEY_MSBLOB(void **encoded, long *encoded_len,
     return ok;
 }
 
-# ifndef OPENSSL_NO_RC4
 static pem_password_cb pass_pw;
 static int pass_pw(char *buf, int size, int rwflag, void *userdata)
 {
@@ -312,11 +397,13 @@ static int pass_pw(char *buf, int size, int rwflag, void *userdata)
     return strlen(userdata);
 }
 
-static int encode_EVP_PKEY_PVK(void **encoded, long *encoded_len,
-                               void *object,
+static int encode_EVP_PKEY_PVK(const char *file, const int line,
+                               void **encoded, long *encoded_len,
+                               void *object, int selection,
+                               ossl_unused const char *output_type,
+                               ossl_unused const char *output_structure,
                                const char *pass,
-                               ossl_unused const char *pcipher,
-                               ossl_unused const char *encoder_propq)
+                               ossl_unused const char *pcipher)
 {
     EVP_PKEY *pkey = object;
     BIO *mem_ser = NULL;
@@ -324,12 +411,14 @@ static int encode_EVP_PKEY_PVK(void **encoded, long *encoded_len,
     int enc = (pass != NULL);
     int ok = 0;
 
-    if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_int_ge(i2b_PVK_bio(mem_ser, pkey, enc,
+    if (!TEST_FL_true(ossl_assert((selection
+                                & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0))
+        || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
+        || !TEST_FL_int_ge(i2b_PVK_bio(mem_ser, pkey, enc,
                                     pass_pw, (void *)pass), 0)
-        || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*encoded = mem_buf->data)
-        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
+        || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
+        || !TEST_FL_ptr(*encoded = mem_buf->data)
+        || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
     /* Detach the encoded output */
@@ -340,23 +429,46 @@ static int encode_EVP_PKEY_PVK(void **encoded, long *encoded_len,
     BIO_free(mem_ser);
     return ok;
 }
-# endif
-#endif
 
-static int test_text(const void *data1, size_t data1_len,
+static int test_text(const char *file, const int line,
+                     const void *data1, size_t data1_len,
                      const void *data2, size_t data2_len)
 {
-    return TEST_strn2_eq(data1, data1_len, data2, data2_len);
+    return TEST_FL_strn2_eq(data1, data1_len, data2, data2_len);
 }
 
-static int test_mem(const void *data1, size_t data1_len,
+static int test_mem(const char *file, const int line,
+                    const void *data1, size_t data1_len,
                     const void *data2, size_t data2_len)
 {
-    return TEST_mem_eq(data1, data1_len, data2, data2_len);
+    return TEST_FL_mem_eq(data1, data1_len, data2, data2_len);
 }
 
 /* Test cases and their dumpers / checkers */
 
+static void collect_name(const char *name, void *arg)
+{
+    char **namelist = arg;
+    char *new_namelist;
+    size_t space;
+
+    space = strlen(name);
+    if (*namelist != NULL)
+        space += strlen(*namelist) + 2 /* for comma and space */;
+    space++; /* for terminating null byte */
+
+    new_namelist = OPENSSL_realloc(*namelist, space);
+    if (new_namelist == NULL)
+        return;
+    if (*namelist != NULL) {
+        strcat(new_namelist, ", ");
+        strcat(new_namelist, name);
+    } else {
+        strcpy(new_namelist, name);
+    }
+    *namelist = new_namelist;
+}
+
 static void dump_der(const char *label, const void *data, size_t data_len)
 {
     test_output_memory(label, data, data_len);
@@ -367,7 +479,8 @@ static void dump_pem(const char *label, const void *data, size_t data_len)
     test_output_string(label, data, data_len - 1);
 }
 
-static int check_unprotected_PKCS8_DER(const char *type,
+static int check_unprotected_PKCS8_DER(const char *file, const int line,
+                                       const char *type,
                                        const void *data, size_t data_len)
 {
     const unsigned char *datap = data;
@@ -375,11 +488,20 @@ static int check_unprotected_PKCS8_DER(const char *type,
         d2i_PKCS8_PRIV_KEY_INFO(NULL, &datap, data_len);
     int ok = 0;
 
-    if (TEST_ptr(p8inf)) {
+    if (TEST_FL_ptr(p8inf)) {
         EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
-
-        ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, type)));
-        EVP_PKEY_free(pkey);
+        char *namelist = NULL;
+
+        if (TEST_FL_ptr(pkey)) {
+            if (!(ok = TEST_FL_true(EVP_PKEY_is_a(pkey, type)))) {
+                EVP_PKEY_typenames_do_all(pkey, collect_name, &namelist);
+                if (namelist != NULL)
+                    TEST_note("%s isn't any of %s", type, namelist);
+                OPENSSL_free(namelist);
+            }
+            ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
+            EVP_PKEY_free(pkey);
+        }
     }
     PKCS8_PRIV_KEY_INFO_free(p8inf);
     return ok;
@@ -387,53 +509,125 @@ static int check_unprotected_PKCS8_DER(const char *type,
 
 static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "DER", "pkcs8", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_mem, check_unprotected_PKCS8_DER, dump_der,
-                              OSSL_ENCODER_PrivateKey_TO_DER_PQ);
+                              test_mem, check_unprotected_PKCS8_DER,
+                              dump_der, 0);
 }
 
-static int check_unprotected_PKCS8_PEM(const char *type,
+static int check_unprotected_PKCS8_PEM(const char *file, const int line,
+                                       const char *type,
                                        const void *data, size_t data_len)
 {
-    static const char pem_header[] = "-----BEGIN " PEM_STRING_PKCS8INF "-----";
+    static const char expected_pem_header[] =
+        "-----BEGIN " PEM_STRING_PKCS8INF "-----";
 
-    return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
+    return TEST_FL_strn_eq(data, expected_pem_header,
+                        sizeof(expected_pem_header) - 1);
 }
 
 static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "pkcs8", NULL, NULL,
+                              encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                              test_text, check_unprotected_PKCS8_PEM,
+                              dump_pem, 0);
+}
+
+#ifndef OPENSSL_NO_KEYPARAMS
+static int check_params_DER(const char *file, const int line,
+                            const char *type, const void *data, size_t data_len)
+{
+    const unsigned char *datap = data;
+    int ok = 0;
+    int itype = NID_undef;
+    EVP_PKEY *pkey = NULL;
+
+    if (strcmp(type, "DH") == 0)
+        itype = EVP_PKEY_DH;
+    else if (strcmp(type, "X9.42 DH") == 0)
+        itype = EVP_PKEY_DHX;
+    else if (strcmp(type, "DSA") ==  0)
+        itype = EVP_PKEY_DSA;
+    else if (strcmp(type, "EC") ==  0)
+        itype = EVP_PKEY_EC;
+
+    if (itype != NID_undef) {
+        pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
+        ok = (pkey != NULL);
+        EVP_PKEY_free(pkey);
+    }
+
+    return ok;
+}
+
+static int check_params_PEM(const char *file, const int line,
+                            const char *type,
+                            const void *data, size_t data_len)
+{
+    static char expected_pem_header[80];
+
+    return
+        TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
+                                 sizeof(expected_pem_header),
+                                 "-----BEGIN %s PARAMETERS-----", type), 0)
+        && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
+}
+
+static int test_params_via_DER(const char *type, EVP_PKEY *key)
+{
+    return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "DER", "type-specific", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_text, check_unprotected_PKCS8_PEM, dump_pem,
-                              OSSL_ENCODER_PrivateKey_TO_PEM_PQ);
+                              test_mem, check_params_DER,
+                              dump_der, FLAG_DECODE_WITH_TYPE);
 }
 
-static int check_unprotected_legacy_PEM(const char *type,
+static int test_params_via_PEM(const char *type, EVP_PKEY *key)
+{
+    return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "type-specific", NULL, NULL,
+                              encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                              test_text, check_params_PEM,
+                              dump_pem, 0);
+}
+#endif /* !OPENSSL_NO_KEYPARAMS */
+
+static int check_unprotected_legacy_PEM(const char *file, const int line,
+                                        const char *type,
                                         const void *data, size_t data_len)
 {
-    static char pem_header[80];
+    static char expected_pem_header[80];
 
     return
-        TEST_int_gt(BIO_snprintf(pem_header, sizeof(pem_header),
+        TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
+                                 sizeof(expected_pem_header),
                                  "-----BEGIN %s PRIVATE KEY-----", type), 0)
-        && TEST_strn_eq(data, pem_header, strlen(pem_header));
+        && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
 }
 
 static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "type-specific", NULL, NULL,
                               encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
-                              test_text, check_unprotected_legacy_PEM, dump_pem,
-                              NULL);
+                              test_text, check_unprotected_legacy_PEM,
+                              dump_pem, 0);
 }
 
-#ifndef OPENSSL_NO_DSA
-static int check_MSBLOB(const char *type, const void *data, size_t data_len)
+static int check_MSBLOB(const char *file, const int line,
+                        const char *type, const void *data, size_t data_len)
 {
     const unsigned char *datap = data;
     EVP_PKEY *pkey = b2i_PrivateKey(&datap, data_len);
-    int ok = TEST_ptr(pkey);
+    int ok = TEST_FL_ptr(pkey);
 
     EVP_PKEY_free(pkey);
     return ok;
@@ -441,14 +635,17 @@ static int check_MSBLOB(const char *type, const void *data, size_t data_len)
 
 static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "MSBLOB", NULL, NULL, NULL,
                               encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
-                              test_mem, check_MSBLOB, dump_der,
-                              NULL);
+                              test_mem, check_MSBLOB,
+                              dump_der, 0);
 }
 
-# ifndef OPENSSL_NO_RC4
-static int check_PVK(const char *type, const void *data, size_t data_len)
+static int check_PVK(const char *file, const int line,
+                     const char *type, const void *data, size_t data_len)
 {
     const unsigned char *in = data;
     unsigned int saltlen = 0, keylen = 0;
@@ -459,23 +656,25 @@ static int check_PVK(const char *type, const void *data, size_t data_len)
 
 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PVK", NULL, NULL, NULL,
                               encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
-                              test_mem, check_PVK, dump_der,
-                              NULL);
+                              test_mem, check_PVK,
+                              dump_der, 0);
 }
-# endif
-#endif
 
 static const char *pass_cipher = "AES-256-CBC";
 static const char *pass = "the holy handgrenade of antioch";
 
-static int check_protected_PKCS8_DER(const char *type,
+static int check_protected_PKCS8_DER(const char *file, const int line,
+                                     const char *type,
                                      const void *data, size_t data_len)
 {
     const unsigned char *datap = data;
     X509_SIG *p8 = d2i_X509_SIG(NULL, &datap, data_len);
-    int ok = TEST_ptr(p8);
+    int ok = TEST_FL_ptr(p8);
 
     X509_SIG_free(p8);
     return ok;
@@ -483,63 +682,80 @@ static int check_protected_PKCS8_DER(const char *type,
 
 static int test_protected_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, pass, pass_cipher,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "DER", "pkcs8", pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_mem, check_protected_PKCS8_DER, dump_der,
-                              OSSL_ENCODER_PrivateKey_TO_DER_PQ);
+                              test_mem, check_protected_PKCS8_DER,
+                              dump_der, 0);
 }
 
-static int check_protected_PKCS8_PEM(const char *type,
+static int check_protected_PKCS8_PEM(const char *file, const int line,
+                                     const char *type,
                                      const void *data, size_t data_len)
 {
-    static const char pem_header[] = "-----BEGIN " PEM_STRING_PKCS8 "-----";
+    static const char expected_pem_header[] =
+        "-----BEGIN " PEM_STRING_PKCS8 "-----";
 
-    return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
+    return TEST_FL_strn_eq(data, expected_pem_header,
+                        sizeof(expected_pem_header) - 1);
 }
 
 static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, pass, pass_cipher,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "pkcs8", pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_text, check_protected_PKCS8_PEM, dump_pem,
-                              OSSL_ENCODER_PrivateKey_TO_PEM_PQ);
+                              test_text, check_protected_PKCS8_PEM,
+                              dump_pem, 0);
 }
 
-static int check_protected_legacy_PEM(const char *type,
+static int check_protected_legacy_PEM(const char *file, const int line,
+                                      const char *type,
                                       const void *data, size_t data_len)
 {
-    static char pem_header[80];
+    static char expected_pem_header[80];
 
     return
-        TEST_int_gt(BIO_snprintf(pem_header, sizeof(pem_header),
+        TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
+                                 sizeof(expected_pem_header),
                                  "-----BEGIN %s PRIVATE KEY-----", type), 0)
-        && TEST_strn_eq(data, pem_header, strlen(pem_header))
-        && TEST_ptr(strstr(data, "\nDEK-Info: "));
+        && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header))
+        && TEST_FL_ptr(strstr(data, "\nDEK-Info: "));
 }
 
 static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, pass, pass_cipher,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "type-specific", pass, pass_cipher,
                               encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
-                              test_text, check_protected_legacy_PEM, dump_pem,
-                              NULL);
+                              test_text, check_protected_legacy_PEM,
+                              dump_pem, 0);
 }
 
-#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+#ifndef OPENSSL_NO_RC4
 static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, pass, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_KEYPAIR
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PVK", NULL, pass, NULL,
                               encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
-                              test_mem, check_PVK, dump_der,
-                              NULL);
+                              test_mem, check_PVK, dump_der, 0);
 }
 #endif
 
-static int check_public_DER(const char *type, const void *data, size_t data_len)
+static int check_public_DER(const char *file, const int line,
+                            const char *type, const void *data, size_t data_len)
 {
     const unsigned char *datap = data;
     EVP_PKEY *pkey = d2i_PUBKEY(NULL, &datap, data_len);
-    int ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, type)));
+    int ok = (TEST_FL_ptr(pkey) && TEST_FL_true(EVP_PKEY_is_a(pkey, type)));
 
     EVP_PKEY_free(pkey);
     return ok;
@@ -547,35 +763,42 @@ static int check_public_DER(const char *type, const void *data, size_t data_len)
 
 static int test_public_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "DER", "SubjectPublicKeyInfo", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_mem, check_public_DER, dump_der,
-                              OSSL_ENCODER_PUBKEY_TO_DER_PQ);
+                              test_mem, check_public_DER, dump_der, 0);
 }
 
-static int check_public_PEM(const char *type, const void *data, size_t data_len)
+static int check_public_PEM(const char *file, const int line,
+                            const char *type, const void *data, size_t data_len)
 {
-    static const char pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----";
+    static const char expected_pem_header[] =
+        "-----BEGIN " PEM_STRING_PUBLIC "-----";
 
     return
-        TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1);
+        TEST_FL_strn_eq(data, expected_pem_header,
+                     sizeof(expected_pem_header) - 1);
 }
 
 static int test_public_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
+    return test_encode_decode(__FILE__, __LINE__, type, key,
+                              OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "PEM", "SubjectPublicKeyInfo", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
-                              test_text, check_public_PEM, dump_pem,
-                              OSSL_ENCODER_PUBKEY_TO_PEM_PQ);
+                              test_text, check_public_PEM, dump_pem, 0);
 }
 
-#ifndef OPENSSL_NO_DSA
-static int check_public_MSBLOB(const char *type,
+static int check_public_MSBLOB(const char *file, const int line,
+                               const char *type,
                                const void *data, size_t data_len)
 {
     const unsigned char *datap = data;
     EVP_PKEY *pkey = b2i_PublicKey(&datap, data_len);
-    int ok = TEST_ptr(pkey);
+    int ok = TEST_FL_ptr(pkey);
 
     EVP_PKEY_free(pkey);
     return ok;
@@ -583,13 +806,12 @@ static int check_public_MSBLOB(const char *type,
 
 static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
 {
-    return test_encode_decode(type, key, NULL, NULL,
-                              encode_public_EVP_PKEY_MSBLOB,
-                              decode_EVP_PKEY_prov,
-                              test_mem, check_public_MSBLOB, dump_der,
-                              NULL);
+    return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                              | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                              "MSBLOB", NULL, NULL, NULL,
+                              encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
+                              test_mem, check_public_MSBLOB, dump_der, 0);
 }
-#endif
 
 #define KEYS(KEYTYPE)                           \
     static EVP_PKEY *key_##KEYTYPE = NULL
@@ -646,6 +868,20 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
     ADD_TEST(test_public_##KEYTYPE##_via_DER);                  \
     ADD_TEST(test_public_##KEYTYPE##_via_PEM)
 
+#define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr)           \
+    static int test_params_##KEYTYPE##_via_DER(void)               \
+    {                                                              \
+        return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE);     \
+    }                                                              \
+    static int test_params_##KEYTYPE##_via_PEM(void)               \
+    {                                                              \
+        return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE);     \
+    }
+
+#define ADD_TEST_SUITE_PARAMS(KEYTYPE)                          \
+    ADD_TEST(test_params_##KEYTYPE##_via_DER);                  \
+    ADD_TEST(test_params_##KEYTYPE##_via_PEM)
+
 #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr)                \
     static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void)        \
     {                                                                   \
@@ -658,12 +894,11 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
             test_protected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE);   \
     }
 
-#define ADD_TEST_SUITE_LEGACY(KEYTYPE)                                 \
-    ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM);             \
+#define ADD_TEST_SUITE_LEGACY(KEYTYPE)                                  \
+    ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM);              \
     ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM)
 
-#ifndef OPENSSL_NO_DSA
-# define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr)               \
+#define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr)                \
     static int test_unprotected_##KEYTYPE##_via_MSBLOB(void)            \
     {                                                                   \
         return test_unprotected_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE);  \
@@ -673,32 +908,34 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
         return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE);       \
     }
 
-# define ADD_TEST_SUITE_MSBLOB(KEYTYPE)                         \
-    ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB);          \
+#define ADD_TEST_SUITE_MSBLOB(KEYTYPE)                                  \
+    ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB);                  \
     ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB)
 
-# ifndef OPENSSL_NO_RC4
-#  define IMPLEMENT_TEST_SUITE_PVK(KEYTYPE, KEYTYPEstr)                 \
+#define IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE, KEYTYPEstr)       \
     static int test_unprotected_##KEYTYPE##_via_PVK(void)               \
     {                                                                   \
         return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE);     \
-    }                                                                   \
+    }
+# define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE)                        \
+    ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK)
+#ifndef OPENSSL_NO_RC4
+# define IMPLEMENT_TEST_SUITE_PROTECTED_PVK(KEYTYPE, KEYTYPEstr)        \
     static int test_protected_##KEYTYPE##_via_PVK(void)                 \
     {                                                                   \
         return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE);       \
     }
-
-#  define ADD_TEST_SUITE_PVK(KEYTYPE)                           \
-    ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK);             \
+# define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE)                          \
     ADD_TEST(test_protected_##KEYTYPE##_via_PVK)
-# endif
 #endif
 
 #ifndef OPENSSL_NO_DH
 DOMAIN_KEYS(DH);
 IMPLEMENT_TEST_SUITE(DH, "DH")
+IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
 DOMAIN_KEYS(DHX);
 IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
+IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
 /*
  * DH has no support for PEM_write_bio_PrivateKey_traditional(),
  * so no legacy tests.
@@ -707,15 +944,18 @@ IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
 #ifndef OPENSSL_NO_DSA
 DOMAIN_KEYS(DSA);
 IMPLEMENT_TEST_SUITE(DSA, "DSA")
+IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
 IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
 IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
+IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(DSA, "DSA")
 # ifndef OPENSSL_NO_RC4
-IMPLEMENT_TEST_SUITE_PVK(DSA, "DSA")
+IMPLEMENT_TEST_SUITE_PROTECTED_PVK(DSA, "DSA")
 # endif
 #endif
 #ifndef OPENSSL_NO_EC
 DOMAIN_KEYS(EC);
 IMPLEMENT_TEST_SUITE(EC, "EC")
+IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
 IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
 DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
 IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
@@ -753,11 +993,10 @@ IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS")
  * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
  * so no legacy tests.
  */
-#ifndef OPENSSL_NO_DSA
 IMPLEMENT_TEST_SUITE_MSBLOB(RSA, "RSA")
-# ifndef OPENSSL_NO_RC4
-IMPLEMENT_TEST_SUITE_PVK(RSA, "RSA")
-# endif
+IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(RSA, "RSA")
+#ifndef OPENSSL_NO_RC4
+IMPLEMENT_TEST_SUITE_PROTECTED_PVK(RSA, "RSA")
 #endif
 
 #ifndef OPENSSL_NO_EC
@@ -945,6 +1184,9 @@ static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
 
 int setup_tests(void)
 {
+# ifndef OPENSSL_NO_RC4
+    int use_legacy = OSSL_PROVIDER_available(NULL, "legacy");
+#endif
     int ok = 1;
 
 #ifndef OPENSSL_NO_DSA
@@ -997,9 +1239,11 @@ int setup_tests(void)
 #ifndef OPENSSL_NO_DH
     MAKE_DOMAIN_KEYS(DH, "DH", NULL);
     MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
+    TEST_info("Generating keys...DH done");
 #endif
 #ifndef OPENSSL_NO_DSA
     MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
+    TEST_info("Generating keys...DSA done");
 #endif
 #ifndef OPENSSL_NO_EC
     MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
@@ -1013,15 +1257,19 @@ int setup_tests(void)
     MAKE_KEYS(ED448, "ED448", NULL);
     MAKE_KEYS(X25519, "X25519", NULL);
     MAKE_KEYS(X448, "X448", NULL);
+    TEST_info("Generating keys...EC done");
 #endif
     MAKE_KEYS(RSA, "RSA", NULL);
+    TEST_info("Generating keys...RSA done");
     MAKE_KEYS(RSA_PSS, "RSA-PSS", RSA_PSS_params);
-    TEST_info("Generating key... done");
+    TEST_info("Generating keys...RSA_PSS done");
 
     if (ok) {
 #ifndef OPENSSL_NO_DH
         ADD_TEST_SUITE(DH);
+        ADD_TEST_SUITE_PARAMS(DH);
         ADD_TEST_SUITE(DHX);
+        ADD_TEST_SUITE_PARAMS(DHX);
         /*
          * DH has no support for PEM_write_bio_PrivateKey_traditional(),
          * so no legacy tests.
@@ -1029,14 +1277,19 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_DSA
         ADD_TEST_SUITE(DSA);
+        ADD_TEST_SUITE_PARAMS(DSA);
         ADD_TEST_SUITE_LEGACY(DSA);
         ADD_TEST_SUITE_MSBLOB(DSA);
+        ADD_TEST_SUITE_UNPROTECTED_PVK(DSA);
 # ifndef OPENSSL_NO_RC4
-        ADD_TEST_SUITE_PVK(DSA);
+        if (use_legacy) {
+            ADD_TEST_SUITE_PROTECTED_PVK(DSA);
+        }
 # endif
 #endif
 #ifndef OPENSSL_NO_EC
         ADD_TEST_SUITE(EC);
+        ADD_TEST_SUITE_PARAMS(EC);
         ADD_TEST_SUITE_LEGACY(EC);
         ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
         ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
@@ -1064,12 +1317,13 @@ int setup_tests(void)
          * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
          * so no legacy tests.
          */
-#ifndef OPENSSL_NO_DSA
         ADD_TEST_SUITE_MSBLOB(RSA);
+        ADD_TEST_SUITE_UNPROTECTED_PVK(RSA);
 # ifndef OPENSSL_NO_RC4
-        ADD_TEST_SUITE_PVK(RSA);
+        if (use_legacy) {
+            ADD_TEST_SUITE_PROTECTED_PVK(RSA);
+        }
 # endif
-#endif
     }
 
     return 1;