[openssl] master update

Richard Levitte levitte at openssl.org
Wed Sep 9 14:36:36 UTC 2020


The branch master has been updated
       via  8ae40cf57d2138af92a3479e23f35037ae8c5c30 (commit)
      from  ce43db7a3fcd18866385a4552f5e4a83adfc0979 (commit)


- Log -----------------------------------------------------------------
commit 8ae40cf57d2138af92a3479e23f35037ae8c5c30
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Sep 7 12:25:17 2020 +0200

    ENCODER: Refactor provider implementations, and some cleanup
    
    The encoder implementations were implemented by unnecessarily copying
    code into numerous topical source files, making them hard to maintain.
    This changes merges all those into two source files, one that encodes
    into DER and PEM, the other to text.
    
    Diverse small cleanups are included.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12803)

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

Summary of changes:
 crypto/encode_decode/encoder_pkey.c                |   7 +-
 crypto/err/openssl.txt                             |   1 +
 include/openssl/core_dispatch.h                    |   2 +-
 providers/common/include/prov/providercommonerr.h  |   1 +
 providers/common/provider_err.c                    |   1 +
 providers/encoders.inc                             | 205 +++--
 providers/implementations/encode_decode/build.info |  20 +-
 .../implementations/encode_decode/decode_common.c  | 116 ---
 .../implementations/encode_decode/decode_der2key.c |  68 +-
 .../implementations/encode_decode/decode_ms2key.c  |  43 +-
 .../implementations/encode_decode/decode_pem2der.c |  17 +-
 .../implementations/encode_decode/encode_key2any.c | 924 +++++++++++++++++++++
 .../encode_decode/encode_key2text.c                | 891 ++++++++++++++++++++
 .../implementations/encode_decode/encoder_common.c | 397 ---------
 .../implementations/encode_decode/encoder_dh.c     | 166 ----
 .../encode_decode/encoder_dh_param.c               | 186 -----
 .../encode_decode/encoder_dh_priv.c                | 295 -------
 .../implementations/encode_decode/encoder_dh_pub.c | 196 -----
 .../implementations/encode_decode/encoder_dsa.c    | 173 ----
 .../encode_decode/encoder_dsa_param.c              | 187 -----
 .../encode_decode/encoder_dsa_priv.c               | 293 -------
 .../encode_decode/encoder_dsa_pub.c                | 205 -----
 .../implementations/encode_decode/encoder_ec.c     | 293 -------
 .../encode_decode/encoder_ec_param.c               | 184 ----
 .../encode_decode/encoder_ec_priv.c                | 290 -------
 .../implementations/encode_decode/encoder_ec_pub.c | 192 -----
 .../implementations/encode_decode/encoder_ecx.c    | 145 ----
 .../encode_decode/encoder_ecx_priv.c               | 307 -------
 .../encode_decode/encoder_ecx_pub.c                | 226 -----
 .../encode_decode/encoder_ffc_params.c             |  63 --
 .../implementations/encode_decode/encoder_local.h  | 183 ----
 .../implementations/encode_decode/encoder_rsa.c    | 277 ------
 .../encode_decode/encoder_rsa_priv.c               | 297 -------
 .../encode_decode/encoder_rsa_pub.c                | 196 -----
 .../encode_decode/endecoder_common.c               |  84 ++
 .../encode_decode/endecoder_local.h                |  26 +
 .../implementations/include/prov/implementations.h | 115 +--
 37 files changed, 2239 insertions(+), 5033 deletions(-)
 delete mode 100644 providers/implementations/encode_decode/decode_common.c
 create mode 100644 providers/implementations/encode_decode/encode_key2any.c
 create mode 100644 providers/implementations/encode_decode/encode_key2text.c
 delete mode 100644 providers/implementations/encode_decode/encoder_common.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dh.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dh_param.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dh_priv.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dh_pub.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dsa.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dsa_param.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dsa_priv.c
 delete mode 100644 providers/implementations/encode_decode/encoder_dsa_pub.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ec.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ec_param.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ec_priv.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ec_pub.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ecx.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ecx_priv.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ecx_pub.c
 delete mode 100644 providers/implementations/encode_decode/encoder_ffc_params.c
 delete mode 100644 providers/implementations/encode_decode/encoder_local.h
 delete mode 100644 providers/implementations/encode_decode/encoder_rsa.c
 delete mode 100644 providers/implementations/encode_decode/encoder_rsa_priv.c
 delete mode 100644 providers/implementations/encode_decode/encoder_rsa_pub.c
 create mode 100644 providers/implementations/encode_decode/endecoder_common.c
 create mode 100644 providers/implementations/encode_decode/endecoder_local.h

diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c
index 176f4fab95..76b8386e0c 100644
--- a/crypto/encode_decode/encoder_pkey.c
+++ b/crypto/encode_decode/encoder_pkey.c
@@ -40,12 +40,7 @@ int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
                                     const unsigned char *kstr,
                                     size_t klen)
 {
-    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
-
-    params[0] = OSSL_PARAM_construct_octet_string(OSSL_ENCODER_PARAM_PASS,
-                                                  (void *)kstr, klen);
-
-    return OSSL_ENCODER_CTX_set_params(ctx, params);
+    return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen);
 }
 
 int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 44e36805f6..df8a7af26c 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2934,6 +2934,7 @@ PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure
 PROV_R_NOT_A_PRIVATE_KEY:221:not a private key
 PROV_R_NOT_A_PUBLIC_KEY:220:not a public key
 PROV_R_NOT_INSTANTIATED:193:not instantiated
+PROV_R_NOT_PARAMETERS:224:not parameters
 PROV_R_NOT_SUPPORTED:136:not supported
 PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
 PROV_R_NO_KEY_SET:114:no key set
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index ac83f88cc4..ad1df714ea 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -735,7 +735,7 @@ OSSL_CORE_MAKE_FUNC(int, encoder_encode_data,
                     (void *ctx, const OSSL_PARAM[], OSSL_CORE_BIO *out,
                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
 OSSL_CORE_MAKE_FUNC(int, encoder_encode_object,
-                    (void *ctx, void *obj, OSSL_CORE_BIO *out,
+                    (void *ctx, const void *obj, OSSL_CORE_BIO *out,
                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
 
 # define OSSL_FUNC_DECODER_NEWCTX                      1
diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h
index 82eea21049..68bcfb4828 100644
--- a/providers/common/include/prov/providercommonerr.h
+++ b/providers/common/include/prov/providercommonerr.h
@@ -131,6 +131,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_NOT_A_PRIVATE_KEY                         221
 # define PROV_R_NOT_A_PUBLIC_KEY                          220
 # define PROV_R_NOT_INSTANTIATED                          193
+# define PROV_R_NOT_PARAMETERS                            224
 # define PROV_R_NOT_SUPPORTED                             136
 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH                 113
 # define PROV_R_NO_KEY_SET                                114
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 6d6a254dd6..75f24f88d7 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -136,6 +136,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH),
     "not xof or invalid length"},
diff --git a/providers/encoders.inc b/providers/encoders.inc
index 4d894a73e5..284703c6e8 100644
--- a/providers/encoders.inc
+++ b/providers/encoders.inc
@@ -11,102 +11,161 @@
 # error Macro ENCODER undefined
 #endif
 
-    ENCODER("RSA", "yes", "text", "private", rsa_priv_text_encoder_functions),
-    ENCODER("RSA", "yes", "text", "public", rsa_pub_text_encoder_functions),
-    ENCODER("RSA", "yes", "der", "private", rsa_priv_der_encoder_functions),
-    ENCODER("RSA", "yes", "der", "public", rsa_pub_der_encoder_functions),
-    ENCODER("RSA", "yes", "pem", "private", rsa_priv_pem_encoder_functions),
-    ENCODER("RSA", "yes", "pem", "public", rsa_pub_pem_encoder_functions),
+    ENCODER("RSA", "yes", "text", "private",
+            rsa_priv_to_text_encoder_functions),
+    ENCODER("RSA", "yes", "text", "public",
+            rsa_pub_to_text_encoder_functions),
+    ENCODER("RSA", "yes", "der", "private",
+            rsa_priv_to_der_encoder_functions),
+    ENCODER("RSA", "yes", "der", "public",
+            rsa_pub_to_der_encoder_functions),
+    ENCODER("RSA", "yes", "pem", "private",
+            rsa_priv_to_pem_encoder_functions),
+    ENCODER("RSA", "yes", "pem", "public",
+            rsa_pub_to_pem_encoder_functions),
     ENCODER("RSA-PSS", "yes", "text", "private",
-        rsa_priv_text_encoder_functions),
-    ENCODER("RSA-PSS", "yes", "text", "public", rsa_pub_text_encoder_functions),
-    ENCODER("RSA-PSS", "yes", "der", "private", rsa_priv_der_encoder_functions),
-    ENCODER("RSA-PSS", "yes", "der", "public", rsa_pub_der_encoder_functions),
-    ENCODER("RSA-PSS", "yes", "pem", "private", rsa_priv_pem_encoder_functions),
-    ENCODER("RSA-PSS", "yes", "pem", "public", rsa_pub_pem_encoder_functions),
+            rsa_priv_to_text_encoder_functions),
+    ENCODER("RSA-PSS", "yes", "text", "public",
+            rsa_pub_to_text_encoder_functions),
+    ENCODER("RSA-PSS", "yes", "der", "private",
+            rsa_priv_to_der_encoder_functions),
+    ENCODER("RSA-PSS", "yes", "der", "public",
+            rsa_pub_to_der_encoder_functions),
+    ENCODER("RSA-PSS", "yes", "pem", "private",
+            rsa_priv_to_pem_encoder_functions),
+    ENCODER("RSA-PSS", "yes", "pem", "public",
+            rsa_pub_to_pem_encoder_functions),
 
 #ifndef OPENSSL_NO_DH
-    ENCODER("DH", "yes", "text", "private", dh_priv_text_encoder_functions),
-    ENCODER("DH", "yes", "text", "public", dh_pub_text_encoder_functions),
-    ENCODER("DH", "yes", "text", "parameters", dh_param_text_encoder_functions),
-    ENCODER("DH", "yes", "der", "private", dh_priv_der_encoder_functions),
-    ENCODER("DH", "yes", "der", "public", dh_pub_der_encoder_functions),
-    ENCODER("DH", "yes", "der", "parameters", dh_param_der_encoder_functions),
-    ENCODER("DH", "yes", "pem", "private", dh_priv_pem_encoder_functions),
-    ENCODER("DH", "yes", "pem", "public", dh_pub_pem_encoder_functions),
-    ENCODER("DH", "yes", "pem", "parameters", dh_param_pem_encoder_functions),
+    ENCODER("DH", "yes", "text", "private",
+            dh_priv_to_text_encoder_functions),
+    ENCODER("DH", "yes", "text", "public",
+            dh_pub_to_text_encoder_functions),
+    ENCODER("DH", "yes", "text", "parameters",
+            dh_param_to_text_encoder_functions),
+    ENCODER("DH", "yes", "der", "private",
+            dh_priv_to_der_encoder_functions),
+    ENCODER("DH", "yes", "der", "public",
+            dh_pub_to_der_encoder_functions),
+    ENCODER("DH", "yes", "der", "parameters",
+            dh_param_to_der_encoder_functions),
+    ENCODER("DH", "yes", "pem", "private",
+            dh_priv_to_pem_encoder_functions),
+    ENCODER("DH", "yes", "pem", "public",
+            dh_pub_to_pem_encoder_functions),
+    ENCODER("DH", "yes", "pem", "parameters",
+            dh_param_to_pem_encoder_functions),
 
-    ENCODER("DHX", "yes", "text", "private", dh_priv_text_encoder_functions),
-    ENCODER("DHX", "yes", "text", "public", dh_pub_text_encoder_functions),
-    ENCODER("DHX", "yes", "text", "parameters", dh_param_text_encoder_functions),
-    ENCODER("DHX", "yes", "der", "private", dh_priv_der_encoder_functions),
-    ENCODER("DHX", "yes", "der", "public", dh_pub_der_encoder_functions),
-    ENCODER("DHX", "yes", "der", "parameters", dh_param_der_encoder_functions),
-    ENCODER("DHX", "yes", "pem", "private", dh_priv_pem_encoder_functions),
-    ENCODER("DHX", "yes", "pem", "public", dh_pub_pem_encoder_functions),
-    ENCODER("DHX", "yes", "pem", "parameters", dh_param_pem_encoder_functions),
+    ENCODER("DHX", "yes", "text", "private",
+            dh_priv_to_text_encoder_functions),
+    ENCODER("DHX", "yes", "text", "public",
+            dh_pub_to_text_encoder_functions),
+    ENCODER("DHX", "yes", "text", "parameters",
+            dh_param_to_text_encoder_functions),
+    ENCODER("DHX", "yes", "der", "private",
+            dh_priv_to_der_encoder_functions),
+    ENCODER("DHX", "yes", "der", "public",
+            dh_pub_to_der_encoder_functions),
+    ENCODER("DHX", "yes", "der", "parameters",
+            dh_param_to_der_encoder_functions),
+    ENCODER("DHX", "yes", "pem", "private",
+            dh_priv_to_pem_encoder_functions),
+    ENCODER("DHX", "yes", "pem", "public",
+            dh_pub_to_pem_encoder_functions),
+    ENCODER("DHX", "yes", "pem", "parameters",
+            dh_param_to_pem_encoder_functions),
 #endif
 
 #ifndef OPENSSL_NO_DSA
-    ENCODER("DSA", "yes", "text", "private", dsa_priv_text_encoder_functions),
-    ENCODER("DSA", "yes", "text", "public", dsa_pub_text_encoder_functions),
+    ENCODER("DSA", "yes", "text", "private",
+            dsa_priv_to_text_encoder_functions),
+    ENCODER("DSA", "yes", "text", "public",
+            dsa_pub_to_text_encoder_functions),
     ENCODER("DSA", "yes", "text", "parameters",
-        dsa_param_text_encoder_functions),
-    ENCODER("DSA", "yes", "der", "private", dsa_priv_der_encoder_functions),
-    ENCODER("DSA", "yes", "der", "public", dsa_pub_der_encoder_functions),
-    ENCODER("DSA", "yes", "der", "parameters", dsa_param_der_encoder_functions),
-    ENCODER("DSA", "yes", "pem", "private", dsa_priv_pem_encoder_functions),
-    ENCODER("DSA", "yes", "pem", "public", dsa_pub_pem_encoder_functions),
-    ENCODER("DSA", "yes", "pem", "parameters", dsa_param_pem_encoder_functions),
+            dsa_param_to_text_encoder_functions),
+    ENCODER("DSA", "yes", "der", "private",
+            dsa_priv_to_der_encoder_functions),
+    ENCODER("DSA", "yes", "der", "public",
+            dsa_pub_to_der_encoder_functions),
+    ENCODER("DSA", "yes", "der", "parameters",
+            dsa_param_to_der_encoder_functions),
+    ENCODER("DSA", "yes", "pem", "private",
+            dsa_priv_to_pem_encoder_functions),
+    ENCODER("DSA", "yes", "pem", "public",
+            dsa_pub_to_pem_encoder_functions),
+    ENCODER("DSA", "yes", "pem", "parameters",
+            dsa_param_to_pem_encoder_functions),
 #endif
 
 #ifndef OPENSSL_NO_EC
     ENCODER("X25519", "yes", "text", "private",
-        x25519_priv_print_encoder_functions),
+            x25519_priv_to_text_encoder_functions),
     ENCODER("X25519", "yes", "text", "public",
-        x25519_pub_print_encoder_functions),
+            x25519_pub_to_text_encoder_functions),
     ENCODER("X25519", "yes", "der", "private",
-        x25519_priv_der_encoder_functions),
-    ENCODER("X25519", "yes", "der", "public", x25519_pub_der_encoder_functions),
+            x25519_priv_to_der_encoder_functions),
+    ENCODER("X25519", "yes", "der", "public",
+            x25519_pub_to_der_encoder_functions),
     ENCODER("X25519", "yes", "pem", "private",
-        x25519_priv_pem_encoder_functions),
-    ENCODER("X25519", "yes", "pem", "public", x25519_pub_pem_encoder_functions),
+            x25519_priv_to_pem_encoder_functions),
+    ENCODER("X25519", "yes", "pem", "public",
+            x25519_pub_to_pem_encoder_functions),
 
-    ENCODER("X448", "no", "text", "private", x448_priv_print_encoder_functions),
-    ENCODER("X448", "no", "text", "public", x448_pub_print_encoder_functions),
-    ENCODER("X448", "no", "der", "private", x448_priv_der_encoder_functions),
-    ENCODER("X448", "no", "der", "public", x448_pub_der_encoder_functions),
-    ENCODER("X448", "no", "pem", "private", x448_priv_pem_encoder_functions),
-    ENCODER("X448", "no", "pem", "public", x448_pub_pem_encoder_functions),
+    ENCODER("X448", "yes", "text", "private",
+            x448_priv_to_text_encoder_functions),
+    ENCODER("X448", "yes", "text", "public",
+            x448_pub_to_text_encoder_functions),
+    ENCODER("X448", "yes", "der", "private",
+            x448_priv_to_der_encoder_functions),
+    ENCODER("X448", "yes", "der", "public",
+            x448_pub_to_der_encoder_functions),
+    ENCODER("X448", "yes", "pem", "private",
+            x448_priv_to_pem_encoder_functions),
+    ENCODER("X448", "yes", "pem", "public",
+            x448_pub_to_pem_encoder_functions),
 
     ENCODER("ED25519", "yes", "text", "private",
-        ed25519_priv_print_encoder_functions),
+            ed25519_priv_to_text_encoder_functions),
     ENCODER("ED25519", "yes", "text", "public",
-        ed25519_pub_print_encoder_functions),
+            ed25519_pub_to_text_encoder_functions),
     ENCODER("ED25519", "yes", "der", "private",
-        ed25519_priv_der_encoder_functions),
+            ed25519_priv_to_der_encoder_functions),
     ENCODER("ED25519", "yes", "der", "public",
-        ed25519_pub_der_encoder_functions),
+            ed25519_pub_to_der_encoder_functions),
     ENCODER("ED25519", "yes", "pem", "private",
-        ed25519_priv_pem_encoder_functions),
+            ed25519_priv_to_pem_encoder_functions),
     ENCODER("ED25519", "yes", "pem", "public",
-        ed25519_pub_pem_encoder_functions),
+            ed25519_pub_to_pem_encoder_functions),
 
-    ENCODER("ED448", "no", "text", "private",
-        ed448_priv_print_encoder_functions),
-    ENCODER("ED448", "no", "text", "public", ed448_pub_print_encoder_functions),
-    ENCODER("ED448", "no", "der", "private", ed448_priv_der_encoder_functions),
-    ENCODER("ED448", "no", "der", "public", ed448_pub_der_encoder_functions),
-    ENCODER("ED448", "no", "pem", "private", ed448_priv_pem_encoder_functions),
-    ENCODER("ED448", "no", "pem", "public", ed448_pub_pem_encoder_functions),
+    ENCODER("ED448", "yes", "text", "private",
+            ed448_priv_to_text_encoder_functions),
+    ENCODER("ED448", "yes", "text", "public",
+            ed448_pub_to_text_encoder_functions),
+    ENCODER("ED448", "yes", "der", "private",
+            ed448_priv_to_der_encoder_functions),
+    ENCODER("ED448", "yes", "der", "public",
+            ed448_pub_to_der_encoder_functions),
+    ENCODER("ED448", "yes", "pem", "private",
+            ed448_priv_to_pem_encoder_functions),
+    ENCODER("ED448", "yes", "pem", "public",
+            ed448_pub_to_pem_encoder_functions),
 
-    ENCODER("EC", "yes", "text", "private", ec_priv_text_encoder_functions),
-    ENCODER("EC", "yes", "text", "public", ec_pub_text_encoder_functions),
-    ENCODER("EC", "yes", "text", "parameters", ec_param_text_encoder_functions),
-    ENCODER("EC", "yes", "der", "private", ec_priv_der_encoder_functions),
-    ENCODER("EC", "yes", "der", "public", ec_pub_der_encoder_functions),
-    ENCODER("EC", "yes", "der", "parameters", ec_param_der_encoder_functions),
-    ENCODER("EC", "yes", "pem", "private", ec_priv_pem_encoder_functions),
-    ENCODER("EC", "yes", "pem", "public", ec_pub_pem_encoder_functions),
-    ENCODER("EC", "yes", "pem", "parameters", ec_param_pem_encoder_functions),
+    ENCODER("EC", "yes", "text", "private",
+            ec_priv_to_text_encoder_functions),
+    ENCODER("EC", "yes", "text", "public",
+            ec_pub_to_text_encoder_functions),
+    ENCODER("EC", "yes", "text", "parameters",
+            ec_param_to_text_encoder_functions),
+    ENCODER("EC", "yes", "der", "private",
+            ec_priv_to_der_encoder_functions),
+    ENCODER("EC", "yes", "der", "public",
+            ec_pub_to_der_encoder_functions),
+    ENCODER("EC", "yes", "der", "parameters",
+            ec_param_to_der_encoder_functions),
+    ENCODER("EC", "yes", "pem", "private",
+            ec_priv_to_pem_encoder_functions),
+    ENCODER("EC", "yes", "pem", "public",
+            ec_pub_to_pem_encoder_functions),
+    ENCODER("EC", "yes", "pem", "parameters",
+            ec_param_to_pem_encoder_functions),
 #endif
diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info
index 3e78849dfc..97e2264418 100644
--- a/providers/implementations/encode_decode/build.info
+++ b/providers/implementations/encode_decode/build.info
@@ -10,26 +10,12 @@ $DSA_GOAL=../../libimplementations.a
 $ECX_GOAL=../../libimplementations.a
 $EC_GOAL=../../libimplementations.a
 
-SOURCE[$ENCODER_GOAL]=encoder_common.c decode_common.c
+SOURCE[$ENCODER_GOAL]=endecoder_common.c
 
 SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c
 IF[{- !$disabled{dsa} -}]
   SOURCE[$DECODER_GOAL]=decode_ms2key.c
 ENDIF
 
-SOURCE[$RSA_GOAL]=encoder_rsa.c encoder_rsa_priv.c encoder_rsa_pub.c
-DEPEND[encoder_rsa.o]=../../common/include/prov/der_rsa.h
-
-IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}]
-  SOURCE[$FFC_GOAL]=encoder_ffc_params.c
-ENDIF
-IF[{- !$disabled{dh} -}]
-  SOURCE[$DH_GOAL]=encoder_dh.c encoder_dh_priv.c encoder_dh_pub.c encoder_dh_param.c
-ENDIF
-IF[{- !$disabled{dsa} -}]
-  SOURCE[$DSA_GOAL]=encoder_dsa.c encoder_dsa_priv.c encoder_dsa_pub.c encoder_dsa_param.c
-ENDIF
-IF[{- !$disabled{ec} -}]
-  SOURCE[$ECX_GOAL]=encoder_ecx.c encoder_ecx_priv.c encoder_ecx_pub.c
-  SOURCE[$EC_GOAL]=encoder_ec.c encoder_ec_priv.c encoder_ec_pub.c encoder_ec_param.c
-ENDIF
+SOURCE[$DECODER_GOAL]=encode_key2any.c encode_key2text.c
+DEPEND[encode_key2any.o]=../../common/include/prov/der_rsa.h
diff --git a/providers/implementations/encode_decode/decode_common.c b/providers/implementations/encode_decode/decode_common.c
deleted file mode 100644
index 798d8f10b2..0000000000
--- a/providers/implementations/encode_decode/decode_common.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_names.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/buffer.h>
-#include <openssl/pem.h>         /* For public PEM and PVK functions */
-#include <openssl/pkcs12.h>
-#include "internal/pem.h"        /* For internal PVK and "blob" functions */
-#include "internal/cryptlib.h"
-#include "internal/asn1.h"
-#include "internal/passphrase.h"
-#include "prov/bio.h"               /* ossl_prov_bio_printf() */
-#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
-#include "encoder_local.h"
-
-int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                       unsigned char **data, long *len)
-{
-    BUF_MEM *mem = NULL;
-    BIO *in = bio_new_from_core_bio(provctx, cin);
-    int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
-
-    if (ok) {
-        *data = (unsigned char *)mem->data;
-        *len = (long)mem->length;
-        OPENSSL_free(mem);
-    }
-    BIO_free(in);
-    return ok;
-}
-
-int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                       char **pem_name, char **pem_header,
-                       unsigned char **data, long *len)
-{
-    BIO *in = bio_new_from_core_bio(provctx, cin);
-    int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0);
-
-    BIO_free(in);
-    return ok;
-}
-
-#ifndef OPENSSL_NO_DSA
-EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                                int *ispub)
-{
-    BIO *in = bio_new_from_core_bio(provctx, cin);
-    EVP_PKEY *pkey = ossl_b2i_bio(in, ispub);
-
-    BIO_free(in);
-    return pkey;
-}
-
-# ifndef OPENSSL_NO_RC4
-EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                             OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
-{
-    BIO *in = NULL;
-    EVP_PKEY *pkey = NULL;
-    struct ossl_passphrase_data_st pwdata;
-
-    memset(&pwdata, 0, sizeof(pwdata));
-    if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg))
-        return NULL;
-
-    in = bio_new_from_core_bio(provctx, cin);
-    pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata);
-    BIO_free(in);
-
-    return pkey;
-}
-# endif
-#endif
-
-int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
-                          unsigned char *input_der, long input_der_len,
-                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
-{
-    const unsigned char *derp;
-    X509_SIG *p8 = NULL;
-    int ok = 0;
-
-    if (!ossl_assert(new_der != NULL && *new_der == NULL)
-        || !ossl_assert(new_der_len != NULL))
-        return 0;
-
-    derp = input_der;
-    if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
-        char pbuf[PEM_BUFSIZE];
-        size_t plen = 0;
-
-        if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
-        } else {
-            const X509_ALGOR *alg = NULL;
-            const ASN1_OCTET_STRING *oct = NULL;
-            int len = 0;
-
-            X509_SIG_get0(p8, &alg, &oct);
-            if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
-                                 new_der, &len, 0) != NULL)
-                ok = 1;
-            *new_der_len = len;
-        }
-    }
-    X509_SIG_free(p8);
-    return ok;
-}
diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c
index b8b268217d..011f05803d 100644
--- a/providers/implementations/encode_decode/decode_der2key.c
+++ b/providers/implementations/encode_decode/decode_der2key.c
@@ -17,13 +17,71 @@
 #include <openssl/core_names.h>
 #include <openssl/core_object.h>
 #include <openssl/crypto.h>
+#include <openssl/err.h>
 #include <openssl/params.h>
+#include <openssl/pem.h>         /* PEM_BUFSIZE and public PEM functions */
+#include <openssl/pkcs12.h>
 #include <openssl/x509.h>
+#include "internal/cryptlib.h"   /* ossl_assert() */
+#include "internal/asn1.h"
+#include "crypto/ecx.h"
 #include "prov/bio.h"
 #include "prov/implementations.h"
-#include "encoder_local.h"
+#include "prov/providercommonerr.h"
+#include "endecoder_local.h"
 
-static OSSL_FUNC_decoder_newctx_fn der2rsa_newctx;
+static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
+                    unsigned char **data, long *len)
+{
+    BUF_MEM *mem = NULL;
+    BIO *in = bio_new_from_core_bio(provctx, cin);
+    int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+
+    if (ok) {
+        *data = (unsigned char *)mem->data;
+        *len = (long)mem->length;
+        OPENSSL_free(mem);
+    }
+    BIO_free(in);
+    return ok;
+}
+
+static int der_from_p8(unsigned char **new_der, long *new_der_len,
+                       unsigned char *input_der, long input_der_len,
+                       OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+    const unsigned char *derp;
+    X509_SIG *p8 = NULL;
+    int ok = 0;
+
+    if (!ossl_assert(new_der != NULL && *new_der == NULL)
+        || !ossl_assert(new_der_len != NULL))
+        return 0;
+
+    derp = input_der;
+    if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
+        char pbuf[PEM_BUFSIZE];
+        size_t plen = 0;
+
+        if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
+        } else {
+            const X509_ALGOR *alg = NULL;
+            const ASN1_OCTET_STRING *oct = NULL;
+            int len = 0;
+
+            X509_SIG_get0(p8, &alg, &oct);
+            if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
+                                 new_der, &len, 0) != NULL)
+                ok = 1;
+            *new_der_len = len;
+        }
+    }
+    X509_SIG_free(p8);
+    return ok;
+}
+
+/* ---------------------------------------------------------------------- */
 
 static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
 static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params;
@@ -109,15 +167,14 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin,
     void *key = NULL;
     int ok = 0;
 
-    if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len))
+    if (!read_der(ctx->provctx, cin, &der, &der_len))
         return 0;
 
     /*
      * Opportunistic attempt to decrypt.  If it doesn't work, we try to
      * decode our input unencrypted.
      */
-    if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len,
-                              pw_cb, pw_cbarg)) {
+    if (der_from_p8(&new_der, &new_der_len, der, der_len, pw_cb, pw_cbarg)) {
         OPENSSL_free(der);
         der = new_der;
         der_len = new_der_len;
@@ -203,6 +260,7 @@ static int der2key_export_object(void *vctx,
         { EVP_PKEY_##KEYTYPE, KEYTYPEstr, keytype##_keymgmt_functions,  \
           (extract_key_fn *)extract,                                    \
           (free_key_fn *)free };                                        \
+    static OSSL_FUNC_decoder_newctx_fn der2##keytype##_newctx;          \
     static void *der2##keytype##_newctx(void *provctx)                  \
     {                                                                   \
         return der2key_newctx(provctx, &keytype##_desc);                \
diff --git a/providers/implementations/encode_decode/decode_ms2key.c b/providers/implementations/encode_decode/decode_ms2key.c
index d8aa813ced..707e6bc08f 100644
--- a/providers/implementations/encode_decode/decode_ms2key.c
+++ b/providers/implementations/encode_decode/decode_ms2key.c
@@ -13,16 +13,51 @@
  */
 #include "internal/deprecated.h"
 
+#include <string.h>
+
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
 #include <openssl/core_object.h>
 #include <openssl/crypto.h>
 #include <openssl/params.h>
+#include <openssl/pem.h>         /* For public PVK functions */
 #include <openssl/x509.h>
-#include "internal/pem.h"        /* For PVK and "blob" PEM headers */
+#include "internal/pem.h"        /* For internal PVK and "blob" headers */
+#include "internal/passphrase.h"
 #include "prov/bio.h"
 #include "prov/implementations.h"
-#include "encoder_local.h"
+#include "endecoder_local.h"
+
+#ifndef OPENSSL_NO_DSA
+static EVP_PKEY *read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin, int *ispub)
+{
+    BIO *in = bio_new_from_core_bio(provctx, cin);
+    EVP_PKEY *pkey = ossl_b2i_bio(in, ispub);
+
+    BIO_free(in);
+    return pkey;
+}
+
+# ifndef OPENSSL_NO_RC4
+static EVP_PKEY *read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+    BIO *in = NULL;
+    EVP_PKEY *pkey = NULL;
+    struct ossl_passphrase_data_st pwdata;
+
+    memset(&pwdata, 0, sizeof(pwdata));
+    if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg))
+        return NULL;
+
+    in = bio_new_from_core_bio(provctx, cin);
+    pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata);
+    BIO_free(in);
+
+    return pkey;
+}
+# endif
+#endif
 
 static OSSL_FUNC_decoder_freectx_fn ms2key_freectx;
 static OSSL_FUNC_decoder_gettable_params_fn ms2key_gettable_params;
@@ -159,7 +194,7 @@ static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin,
 {
     struct ms2key_ctx_st *ctx = vctx;
     int ispub = -1;
-    EVP_PKEY *pkey = ossl_prov_read_msblob(ctx->provctx, cin, &ispub);
+    EVP_PKEY *pkey = read_msblob(ctx->provctx, cin, &ispub);
     int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg);
 
     EVP_PKEY_free(pkey);
@@ -172,7 +207,7 @@ static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin,
                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     struct ms2key_ctx_st *ctx = vctx;
-    EVP_PKEY *pkey = ossl_prov_read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg);
+    EVP_PKEY *pkey = read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg);
     int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg);
 
     EVP_PKEY_free(pkey);
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
index cbee397982..6e669884de 100644
--- a/providers/implementations/encode_decode/decode_pem2der.c
+++ b/providers/implementations/encode_decode/decode_pem2der.c
@@ -24,7 +24,18 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
-#include "encoder_local.h"
+#include "endecoder_local.h"
+
+static int read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
+                    char **pem_name, char **pem_header,
+                    unsigned char **data, long *len)
+{
+    BIO *in = bio_new_from_core_bio(provctx, cin);
+    int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0);
+
+    BIO_free(in);
+    return ok;
+}
 
 static OSSL_FUNC_decoder_newctx_fn pem2der_newctx;
 static OSSL_FUNC_decoder_freectx_fn pem2der_freectx;
@@ -104,8 +115,8 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin,
     long der_len = 0;
     int ok = 0;
 
-    if (ossl_prov_read_pem(ctx->provctx, cin, &pem_name, &pem_header,
-                           &der, &der_len) <= 0)
+    if (read_pem(ctx->provctx, cin, &pem_name, &pem_header,
+                 &der, &der_len) <= 0)
         return 0;
 
     /*
diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c
new file mode 100644
index 0000000000..ba240aa094
--- /dev/null
+++ b/providers/implementations/encode_decode/encode_key2any.c
@@ -0,0 +1,924 @@
+/*
+ * Copyright 2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Low level APIs are deprecated for public use, but still ok for internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/crypto.h>
+#include <openssl/params.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>      /* PKCS8_encrypt() */
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+#include "internal/passphrase.h"
+#include "internal/cryptlib.h"
+#include "crypto/ecx.h"
+#include "crypto/rsa.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
+#include "prov/bio.h"
+#include "prov/provider_ctx.h"
+#include "prov/der_rsa.h"
+#include "endecoder_local.h"
+
+struct key2any_ctx_st {
+    PROV_CTX *provctx;
+
+    /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
+    int cipher_intent;
+
+    EVP_CIPHER *cipher;
+
+    struct ossl_passphrase_data_st pwdata;
+};
+
+typedef int key_to_paramstring_fn(const void *key, int nid,
+                                  void **str, int *strtype);
+typedef int key_to_der_fn(BIO *out, const void *key, int key_nid,
+                          key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+                          struct key2any_ctx_st *ctx);
+typedef int write_bio_of_void_fn(BIO *bp, const void *x);
+
+static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid,
+                                          void *params, int params_type,
+                                          i2d_of_void *k2d)
+{
+    /* der, derlen store the key DER output and its length */
+    unsigned char *der = NULL;
+    int derlen;
+    /* The final PKCS#8 info */
+    PKCS8_PRIV_KEY_INFO *p8info = NULL;
+
+
+    if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL
+        || (derlen = k2d(key, &der)) <= 0
+        || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0,
+                            params_type, params, der, derlen)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        PKCS8_PRIV_KEY_INFO_free(p8info);
+        OPENSSL_free(der);
+        p8info = NULL;
+    }
+
+    return p8info;
+}
+
+static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info,
+                                 struct key2any_ctx_st *ctx)
+{
+    X509_SIG *p8 = NULL;
+    char kstr[PEM_BUFSIZE];
+    size_t klen = 0;
+
+    if (ctx->cipher == NULL)
+        return NULL;
+
+    if (!ossl_pw_get_passphrase(kstr, sizeof(kstr), &klen, NULL, 1,
+                                &ctx->pwdata)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
+        return NULL;
+    }
+    /* First argument == -1 means "standard" */
+    p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info);
+    OPENSSL_cleanse(kstr, klen);
+    return p8;
+}
+
+static X509_SIG *key_to_encp8(const void *key, int key_nid,
+                              void *params, int params_type,
+                              i2d_of_void *k2d, struct key2any_ctx_st *ctx)
+{
+    PKCS8_PRIV_KEY_INFO *p8info =
+        key_to_p8info(key, key_nid, params, params_type, k2d);
+    X509_SIG *p8 = p8info_to_encp8(p8info, ctx);
+
+    PKCS8_PRIV_KEY_INFO_free(p8info);
+    return p8;
+}
+
+static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid,
+                                  void *params, int params_type,
+                                  i2d_of_void k2d)
+{
+    /* der, derlen store the key DER output and its length */
+    unsigned char *der = NULL;
+    int derlen;
+    /* The final X509_PUBKEY */
+    X509_PUBKEY *xpk = NULL;
+
+
+    if ((xpk = X509_PUBKEY_new()) == NULL
+        || (derlen = k2d(key, &der)) <= 0
+        || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid),
+                                   params_type, params, der, derlen)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        X509_PUBKEY_free(xpk);
+        OPENSSL_free(der);
+        xpk = NULL;
+    }
+
+    return xpk;
+}
+
+static int key_to_der_pkcs8_bio(BIO *out, const void *key, int key_nid,
+                                key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+                                struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+
+    if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
+        return 0;
+
+    if (ctx->cipher_intent) {
+        X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+
+        if (p8 != NULL)
+            ret = i2d_PKCS8_bio(out, p8);
+
+        X509_SIG_free(p8);
+    } else {
+        PKCS8_PRIV_KEY_INFO *p8info =
+            key_to_p8info(key, key_nid, str, strtype, k2d);
+
+        if (p8info != NULL)
+            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
+
+        PKCS8_PRIV_KEY_INFO_free(p8info);
+    }
+
+    return ret;
+}
+
+static int key_to_pem_pkcs8_bio(BIO *out, const void *key, int key_nid,
+                                key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+                                struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+
+    if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
+        return 0;
+
+    if (ctx->cipher_intent) {
+        X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+
+        if (p8 != NULL)
+            ret = PEM_write_bio_PKCS8(out, p8);
+
+        X509_SIG_free(p8);
+    } else {
+        PKCS8_PRIV_KEY_INFO *p8info =
+            key_to_p8info(key, key_nid, str, strtype, k2d);
+
+        if (p8info != NULL)
+            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
+
+        PKCS8_PRIV_KEY_INFO_free(p8info);
+    }
+
+    return ret;
+}
+
+static int key_to_der_pubkey_bio(BIO *out, const void *key, int key_nid,
+                                 key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+                                 struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+    X509_PUBKEY *xpk = NULL;
+
+    if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
+        return 0;
+
+    xpk = key_to_pubkey(key, key_nid, str, strtype, k2d);
+
+    if (xpk != NULL)
+        ret = i2d_X509_PUBKEY_bio(out, xpk);
+
+    /* Also frees |str| */
+    X509_PUBKEY_free(xpk);
+    return ret;
+}
+
+static int key_to_pem_pubkey_bio(BIO *out, const void *key, int key_nid,
+                                 key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+                                 struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+    X509_PUBKEY *xpk = NULL;
+
+    if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
+        return 0;
+
+    xpk = key_to_pubkey(key, key_nid, str, strtype, k2d);
+
+    if (xpk != NULL)
+        ret = PEM_write_bio_X509_PUBKEY(out, xpk);
+
+    /* Also frees |str| */
+    X509_PUBKEY_free(xpk);
+    return ret;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DH
+# define dh_param_selection     OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+# define dh_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | dh_param_selection)
+# define dh_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | dh_param_selection)
+
+static int dh_type_to_evp(const DH *dh)
+{
+    return DH_test_flags(dh, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
+}
+
+static int prepare_dh_params(const void *dh, int nid,
+                             void **pstr, int *pstrtype)
+{
+    ASN1_STRING *params = ASN1_STRING_new();
+
+    if (params == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (nid == EVP_PKEY_DHX)
+        params->length = i2d_DHxparams(dh, &params->data);
+    else
+        params->length = i2d_DHparams(dh, &params->data);
+
+    if (params->length <= 0) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        ASN1_STRING_free(params);
+        return 0;
+    }
+    params->type = V_ASN1_SEQUENCE;
+
+    *pstr = params;
+    *pstrtype = V_ASN1_SEQUENCE;
+    return 1;
+}
+
+static int dh_pub_to_der(const void *dh, unsigned char **pder)
+{
+    const BIGNUM *bn = NULL;
+    ASN1_INTEGER *pub_key = NULL;
+    int ret;
+
+    if ((bn = DH_get0_pub_key(dh)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+        return 0;
+    }
+    if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
+        return 0;
+    }
+
+    ret = i2d_ASN1_INTEGER(pub_key, pder);
+
+    ASN1_STRING_clear_free(pub_key);
+    return ret;
+}
+
+static int dh_priv_to_der(const void *dh, unsigned char **pder)
+{
+    const BIGNUM *bn = NULL;
+    ASN1_INTEGER *priv_key = NULL;
+    int ret;
+
+    if ((bn = DH_get0_priv_key(dh)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+        return 0;
+    }
+    if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
+        return 0;
+    }
+
+    ret = i2d_ASN1_INTEGER(priv_key, pder);
+
+    ASN1_STRING_clear_free(priv_key);
+    return ret;
+}
+
+static int dh_params_to_der_bio(BIO *out, const void *key)
+{
+    return i2d_DHparams_bio(out, key);
+}
+
+static int dh_params_to_pem_bio(BIO *out, const void *key)
+{
+    return PEM_write_bio_DHparams(out, key);
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DSA
+# define dsa_param_selection    OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+# define dsa_pub_selection      (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | dsa_param_selection)
+# define dsa_priv_selection     (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | dsa_param_selection)
+
+# define dsa_type_to_evp(key) EVP_PKEY_DSA
+
+static int prepare_some_dsa_params(const void *dsa, int nid,
+                                   void **pstr, int *pstrtype)
+{
+    ASN1_STRING *params = ASN1_STRING_new();
+
+    if (params == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    params->length = i2d_DSAparams(dsa, &params->data);
+
+    if (params->length <= 0) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        ASN1_STRING_free(params);
+        return 0;
+    }
+
+    *pstrtype = V_ASN1_SEQUENCE;
+    *pstr = params;
+    return 1;
+}
+
+static int prepare_all_dsa_params(const void *dsa, int nid,
+                                  void **pstr, int *pstrtype)
+{
+    const BIGNUM *p = DSA_get0_p(dsa);
+    const BIGNUM *q = DSA_get0_q(dsa);
+    const BIGNUM *g = DSA_get0_g(dsa);
+
+    if (p != NULL && q != NULL && g != NULL)
+        return prepare_some_dsa_params(dsa, nid, pstr, pstrtype);
+
+    *pstr = NULL;
+    *pstrtype = V_ASN1_UNDEF;
+    return 1;
+}
+
+static int prepare_dsa_params(const void *dsa, int nid,
+                              void **pstr, int *pstrtype)
+{
+    /*
+     * TODO(v3.0) implement setting save_parameters, see dsa_pub_encode()
+     * in crypto/dsa/dsa_ameth.c
+     */
+    int save_parameters = 1;
+
+    return save_parameters
+        ?  prepare_all_dsa_params(dsa, nid, pstr, pstrtype)
+        :  prepare_some_dsa_params(dsa, nid, pstr, pstrtype);
+}
+
+static int dsa_pub_to_der(const void *dsa, unsigned char **pder)
+{
+    const BIGNUM *bn = NULL;
+    ASN1_INTEGER *pub_key = NULL;
+    int ret;
+
+    if ((bn = DSA_get0_pub_key(dsa)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+        return 0;
+    }
+    if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
+        return 0;
+    }
+
+    ret = i2d_ASN1_INTEGER(pub_key, pder);
+
+    ASN1_STRING_clear_free(pub_key);
+    return ret;
+}
+
+static int dsa_priv_to_der(const void *dsa, unsigned char **pder)
+{
+    const BIGNUM *bn = NULL;
+    ASN1_INTEGER *priv_key = NULL;
+    int ret;
+
+    if ((bn = DSA_get0_priv_key(dsa)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+        return 0;
+    }
+    if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
+        return 0;
+    }
+
+    ret = i2d_ASN1_INTEGER(priv_key, pder);
+
+    ASN1_STRING_clear_free(priv_key);
+    return ret;
+}
+
+static int dsa_params_to_der_bio(BIO *out, const void *key)
+{
+    return i2d_DSAparams_bio(out, key);
+}
+
+static int dsa_params_to_pem_bio(BIO *out, const void *key)
+{
+    return PEM_write_bio_DSAparams(out, key);
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_EC
+# define ec_param_selection     OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+# define ec_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | ec_param_selection)
+# define ec_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | ec_param_selection)
+
+# define ec_type_to_evp(key) EVP_PKEY_EC
+
+static int prepare_ec_explicit_params(const void *eckey,
+                                      void **pstr, int *pstrtype)
+{
+    ASN1_STRING *params = ASN1_STRING_new();
+
+    if (params == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    params->length = i2d_ECParameters(eckey, &params->data);
+    if (params->length <= 0) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        ASN1_STRING_free(params);
+        return 0;
+    }
+
+    *pstrtype = V_ASN1_SEQUENCE;
+    *pstr = params;
+    return 1;
+}
+
+static int prepare_ec_params(const void *eckey, int nid,
+                             void **pstr, int *pstrtype)
+{
+    int curve_nid;
+    const EC_GROUP *group = EC_KEY_get0_group(eckey);
+    ASN1_OBJECT *params = NULL;
+
+    if (group == NULL)
+        return 0;
+    curve_nid = EC_GROUP_get_curve_name(group);
+    if (curve_nid != NID_undef) {
+        params = OBJ_nid2obj(curve_nid);
+        if (params == NULL)
+            return 0;
+    }
+
+    if (curve_nid != NID_undef
+        && (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
+        if (OBJ_length(params) == 0) {
+            /* Some curves might not have an associated OID */
+            ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
+            ASN1_OBJECT_free(params);
+            return 0;
+        }
+        *pstr = params;
+        *pstrtype = V_ASN1_OBJECT;
+        return 1;
+    } else {
+        return prepare_ec_explicit_params(eckey, pstr, pstrtype);
+    }
+}
+
+static int ec_params_to_der_bio(BIO *out, const void *eckey)
+{
+    return i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
+}
+
+static int ec_params_to_pem_bio(BIO *out, const void *eckey)
+{
+    return PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
+}
+
+static int ec_pub_to_der(const void *eckey, unsigned char **pder)
+{
+    return i2o_ECPublicKey(eckey, pder);
+}
+
+static int ec_priv_to_der(const void *veckey, unsigned char **pder)
+{
+    EC_KEY *eckey = (EC_KEY *)veckey;
+    unsigned int old_flags;
+    int ret = 0;
+
+    /*
+     * For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object
+     * as the pkeyalg->parameter field. (For a named curve this is an OID)
+     * The pkey field is an octet string that holds the encoded
+     * ECPrivateKey SEQUENCE with the optional parameters field omitted.
+     * We omit this by setting the EC_PKEY_NO_PARAMETERS flag.
+     */
+    old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */
+    EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS);
+    ret = i2d_ECPrivateKey(eckey, pder);
+    EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */
+    return ret; /* return the length of the der encoded data */
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_EC
+# define ecx_pub_selection      OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+# define ecx_priv_selection     OSSL_KEYMGMT_SELECT_KEYPAIR
+
+# define ed25519_type_to_evp(key) EVP_PKEY_ED25519
+# define ed448_type_to_evp(key) EVP_PKEY_ED448
+# define x25519_type_to_evp(key) EVP_PKEY_X25519
+# define x448_type_to_evp(key) EVP_PKEY_X448
+
+# define prepare_ecx_params NULL
+
+static int ecx_pub_to_der(const void *vecxkey, unsigned char **pder)
+{
+    const ECX_KEY *ecxkey = vecxkey;
+    unsigned char *keyblob;
+
+    if (ecxkey == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen);
+    if (keyblob == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    *pder = keyblob;
+    return ecxkey->keylen;
+}
+
+static int ecx_priv_to_der(const void *vecxkey, unsigned char **pder)
+{
+    const ECX_KEY *ecxkey = vecxkey;
+    ASN1_OCTET_STRING oct;
+    int keybloblen;
+
+    if (ecxkey == NULL || ecxkey->privkey == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    oct.data = ecxkey->privkey;
+    oct.length = ecxkey->keylen;
+    oct.flags = 0;
+
+    keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder);
+    if (keybloblen < 0) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return keybloblen;
+}
+
+# define ecx_params_to_der_bio NULL
+# define ecx_params_to_pem_bio NULL
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#define rsa_param_selection     OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
+#define rsa_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | rsa_param_selection)
+#define rsa_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | rsa_param_selection)
+
+static int rsa_type_to_evp(const RSA *rsa)
+{
+    switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+    case RSA_FLAG_TYPE_RSA:
+        return EVP_PKEY_RSA;
+    case RSA_FLAG_TYPE_RSASSAPSS:
+        return EVP_PKEY_RSA_PSS;
+    }
+
+    /* Currently unsupported RSA key type */
+    return EVP_PKEY_NONE;
+}
+
+/*
+ * Helper functions to prepare RSA-PSS params for encoding.  We would
+ * have simply written the whole AlgorithmIdentifier, but existing libcrypto
+ * functionality doesn't allow that.
+ */
+
+static int prepare_rsa_params(const void *rsa, int nid,
+                              void **pstr, int *pstrtype)
+{
+    const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa);
+
+    *pstr = NULL;
+
+    switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+    case RSA_FLAG_TYPE_RSA:
+        /* If plain RSA, the parameters shall be NULL */
+        *pstrtype = V_ASN1_NULL;
+        return 1;
+    case RSA_FLAG_TYPE_RSASSAPSS:
+        if (rsa_pss_params_30_is_unrestricted(pss)) {
+            *pstrtype = V_ASN1_UNDEF;
+            return 1;
+        } else {
+            ASN1_STRING *astr = NULL;
+            WPACKET pkt;
+            unsigned char *str = NULL;
+            size_t str_sz = 0;
+            int i;
+
+            for (i = 0; i < 2; i++) {
+                switch (i) {
+                case 0:
+                    if (!WPACKET_init_null_der(&pkt))
+                        goto err;
+                    break;
+                case 1:
+                    if ((str = OPENSSL_malloc(str_sz)) == NULL
+                        || !WPACKET_init_der(&pkt, str, str_sz)) {
+                        goto err;
+                    }
+                    break;
+                }
+                if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss)
+                    || !WPACKET_finish(&pkt)
+                    || !WPACKET_get_total_written(&pkt, &str_sz))
+                    goto err;
+                WPACKET_cleanup(&pkt);
+
+                /*
+                 * If no PSS parameters are going to be written, there's no
+                 * point going for another iteration.
+                 * This saves us from getting |str| allocated just to have it
+                 * immediately de-allocated.
+                 */
+                if (str_sz == 0)
+                    break;
+            }
+
+            if ((astr = ASN1_STRING_new()) == NULL)
+                goto err;
+            *pstrtype = V_ASN1_SEQUENCE;
+            ASN1_STRING_set0(astr, str, (int)str_sz);
+            *pstr = astr;
+
+            return 1;
+         err:
+            OPENSSL_free(str);
+            return 0;
+        }
+    }
+
+    /* Currently unsupported RSA key type */
+    return 0;
+}
+
+#define rsa_params_to_der_bio NULL
+#define rsa_params_to_pem_bio NULL
+#define rsa_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey
+#define rsa_pub_to_der (i2d_of_void *)i2d_RSAPublicKey
+
+/* ---------------------------------------------------------------------- */
+
+static OSSL_FUNC_decoder_newctx_fn key2any_newctx;
+static OSSL_FUNC_decoder_freectx_fn key2any_freectx;
+
+static void *key2any_newctx(void *provctx)
+{
+    struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx != NULL)
+        ctx->provctx = provctx;
+
+    return ctx;
+}
+
+static void key2any_freectx(void *vctx)
+{
+    struct key2any_ctx_st *ctx = vctx;
+
+    ossl_pw_clear_passphrase_data(&ctx->pwdata);
+    EVP_CIPHER_free(ctx->cipher);
+    OPENSSL_free(ctx);
+}
+
+static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx)
+{
+    static const OSSL_PARAM settables[] = {
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_END,
+    };
+
+    return settables;
+}
+
+static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    struct key2any_ctx_st *ctx = vctx;
+    OPENSSL_CTX *libctx = PROV_CTX_get0_library_context(ctx->provctx);
+    const OSSL_PARAM *cipherp =
+        OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
+    const OSSL_PARAM *propsp =
+        OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
+
+    if (cipherp != NULL) {
+        const char *ciphername = NULL;
+        const char *props = NULL;
+
+        if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername))
+            return 0;
+        if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props))
+            return 0;
+
+        EVP_CIPHER_free(ctx->cipher);
+        ctx->cipher_intent = ciphername != NULL;
+        if (ciphername != NULL
+            && ((ctx->cipher =
+                 EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL))
+            return 0;
+    }
+    return 1;
+}
+
+static int key2any_encode(struct key2any_ctx_st *ctx,
+                          const void *key, int type,
+                          OSSL_CORE_BIO *cout, key_to_der_fn *writer,
+                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg,
+                          key_to_paramstring_fn *key2paramstring,
+                          i2d_of_void *key2der)
+{
+    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
+    int ret = 0;
+
+    if (out != NULL
+        && writer != NULL
+        && ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg))
+        ret = writer(out, key, type, key2paramstring, key2der, ctx);
+
+    BIO_free(out);
+    return ret;
+}
+
+static int key2any_encode_params(struct key2any_ctx_st *ctx, const void *key,
+                                 OSSL_CORE_BIO *cout,
+                                 write_bio_of_void_fn *writer)
+{
+    int ret = 0;
+    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
+
+    if (out != NULL && writer != NULL)
+        ret = writer(out, key);
+
+    BIO_free(out);
+
+    return ret;
+}
+
+#define ALLOWED_SELECTORS \
+    (OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR)
+
+#define MAKE_ENCODER_KIND(impl, kind, type, evp_type, output)           \
+    static OSSL_FUNC_encoder_encode_data_fn                             \
+    impl##_##kind##2##output##_encode_d;                                \
+    static OSSL_FUNC_encoder_encode_object_fn                           \
+    impl##_##kind##2##output##_encode_o;                                \
+    static int                                                          \
+    impl##_##kind##2##output##_encode_d(void *vctx,                     \
+                                        const OSSL_PARAM params[],      \
+                                        OSSL_CORE_BIO *cout,            \
+                                        OSSL_PASSPHRASE_CALLBACK *cb,   \
+                                        void *cbarg)                    \
+    {                                                                   \
+        struct key2any_ctx_st *ctx = vctx;                              \
+        int selection = type##_##kind##_selection;                      \
+        void *key = ossl_prov_import_key(impl##_keymgmt_functions,      \
+                                         ctx->provctx, selection,       \
+                                         params);                       \
+        int ret;                                                        \
+                                                                        \
+        if (key == NULL)                                                \
+            return 0;                                                   \
+                                                                        \
+        ret = impl##_##kind##2##output##_encode_o(ctx, key, cout,       \
+                                                  cb, cbarg);           \
+        ossl_prov_free_key(impl##_keymgmt_functions, key);              \
+        return ret;                                                     \
+    }                                                                   \
+    static int                                                          \
+    impl##_##kind##2##output##_encode_o(void *vctx, const void *key,    \
+                                        OSSL_CORE_BIO *cout,            \
+                                        OSSL_PASSPHRASE_CALLBACK *cb,   \
+                                        void *cbarg)                    \
+    {                                                                   \
+        int selection = type##_##kind##_selection;                      \
+                                                                        \
+        if (!ossl_assert(selection != 0)                                \
+            || !ossl_assert((selection & ~ALLOWED_SELECTORS) == 0)) {   \
+            ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);              \
+            return 0;                                                   \
+        }                                                               \
+        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)         \
+            return key2any_encode(vctx, key, impl##_type_to_evp(key),   \
+                                  cout, key_to_##output##_pkcs8_bio,    \
+                                  cb, cbarg,                            \
+                                  prepare_##type##_params,              \
+                                  type##_priv_to_der);                  \
+        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)          \
+            return key2any_encode(vctx, key, impl##_type_to_evp(key),   \
+                                  cout, key_to_##output##_pubkey_bio,   \
+                                  cb, cbarg,                            \
+                                  prepare_##type##_params,              \
+                                  type##_pub_to_der);                   \
+        return key2any_encode_params(vctx, key, cout,                   \
+                                     type##_params_to_##output##_bio);  \
+    }                                                                   \
+    const OSSL_DISPATCH                                                 \
+    impl##_##kind##_to_##output##_encoder_functions[] = {               \
+        { OSSL_FUNC_ENCODER_NEWCTX,                                     \
+          (void (*)(void))key2any_newctx },                             \
+        { OSSL_FUNC_ENCODER_FREECTX,                                    \
+          (void (*)(void))key2any_freectx },                            \
+        { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,                        \
+          (void (*)(void))key2any_settable_ctx_params },                \
+        { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,                             \
+          (void (*)(void))key2any_set_ctx_params },                     \
+        { OSSL_FUNC_ENCODER_ENCODE_DATA,                                \
+          (void (*)(void))impl##_##kind##2##output##_encode_d },        \
+        { OSSL_FUNC_ENCODER_ENCODE_OBJECT,                              \
+          (void (*)(void))impl##_##kind##2##output##_encode_o },        \
+        { 0, NULL }                                                     \
+    }
+
+#define MAKE_ENCODER(impl, type, evp_type, output)                      \
+    MAKE_ENCODER_KIND(impl, param, type, evp_type, output);             \
+    MAKE_ENCODER_KIND(impl, pub, type, evp_type, output);               \
+    MAKE_ENCODER_KIND(impl, priv, type, evp_type, output)
+
+#define MAKE_ENCODER_NOPARAM(impl, type, evp_type, output)              \
+    MAKE_ENCODER_KIND(impl, pub, type, evp_type, output);               \
+    MAKE_ENCODER_KIND(impl, priv, type, evp_type, output)
+
+#ifndef OPENSSL_NO_DH
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, der);
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, pem);
+#endif
+#ifndef OPENSSL_NO_DSA
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, der);
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, pem);
+#endif
+#ifndef OPENSSL_NO_EC
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, der);
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, pem);
+MAKE_ENCODER_NOPARAM(ed25519, ecx, EVP_PKEY_ED25519, der);
+MAKE_ENCODER_NOPARAM(ed25519, ecx, EVP_PKEY_ED25519, pem);
+MAKE_ENCODER_NOPARAM(ed448, ecx, EVP_PKEY_ED448, der);
+MAKE_ENCODER_NOPARAM(ed448, ecx, EVP_PKEY_ED448, pem);
+MAKE_ENCODER_NOPARAM(x25519, ecx, EVP_PKEY_X25519, der);
+MAKE_ENCODER_NOPARAM(x25519, ecx, EVP_PKEY_X25519, pem);
+MAKE_ENCODER_NOPARAM(x448, ecx, EVP_PKEY_ED448, der);
+MAKE_ENCODER_NOPARAM(x448, ecx, EVP_PKEY_ED448, pem);
+#endif
+/*
+ * RSA-PSS does have parameters, but we don't have a separate output for them,
+ * so we don't pretend we do.  Parameter handling remains internal within the
+ * RSA helper functions.
+ */
+MAKE_ENCODER_NOPARAM(rsa, rsa, EVP_PKEY_RSA, der);
+MAKE_ENCODER_NOPARAM(rsa, rsa, EVP_PKEY_RSA, pem);
diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c
new file mode 100644
index 0000000000..7f5ca2b7b7
--- /dev/null
+++ b/providers/implementations/encode_decode/encode_key2text.c
@@ -0,0 +1,891 @@
+/*
+ * Copyright 2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Low level APIs are deprecated for public use, but still ok for internal use.
+ */
+#include "internal/deprecated.h"
+
+#include <ctype.h>
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/safestack.h>
+#include "internal/ffc.h"
+#include "crypto/bn.h"           /* bn_get_words() */
+#include "crypto/dh.h"           /* dh_get0_params() */
+#include "crypto/dsa.h"          /* dsa_get0_params() */
+#include "crypto/ec.h"           /* ec_key_get_libctx */
+#include "crypto/ecx.h"          /* ECX_KEY, etc... */
+#include "crypto/rsa.h"          /* RSA_PSS_PARAMS_30, etc... */
+#include "prov/bio.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
+#include "endecoder_local.h"
+
+DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
+
+# ifdef SIXTY_FOUR_BIT_LONG
+#  define BN_FMTu "%lu"
+#  define BN_FMTx "%lx"
+# endif
+
+# ifdef SIXTY_FOUR_BIT
+#  define BN_FMTu "%llu"
+#  define BN_FMTx "%llx"
+# endif
+
+# ifdef THIRTY_TWO_BIT
+#  define BN_FMTu "%u"
+#  define BN_FMTx "%x"
+# endif
+
+static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn)
+{
+    int ret = 0, use_sep = 0;
+    char *hex_str = NULL, *p;
+    const char spaces[] = "    ";
+    const char *post_label_spc = " ";
+
+    const char *neg = "";
+    int bytes;
+
+    if (bn == NULL)
+        return 0;
+    if (label == NULL) {
+        label = "";
+        post_label_spc = "";
+    }
+
+    if (BN_is_zero(bn))
+        return BIO_printf(out, "%s%s0\n", label, post_label_spc);
+
+    if (BN_num_bytes(bn) <= BN_BYTES) {
+        BN_ULONG *words = bn_get_words(bn);
+
+        if (BN_is_negative(bn))
+            neg = "-";
+
+        return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n",
+                          label, post_label_spc, neg, words[0], neg, words[0]);
+    }
+
+    hex_str = BN_bn2hex(bn);
+    p = hex_str;
+    if (*p == '-') {
+        ++p;
+        neg = " (Negative)";
+    }
+    if (BIO_printf(out, "%s%s\n", label, neg) <= 0)
+        goto err;
+
+    /* Keep track of how many bytes we have printed out so far */
+    bytes = 0;
+
+    if (BIO_printf(out, "%s", spaces) <= 0)
+        goto err;
+
+    /* Add a leading 00 if the top bit is set */
+    if (*p >= '8') {
+        if (BIO_printf(out, "%02x", 0) <= 0)
+            goto err;
+        ++bytes;
+        use_sep = 1;
+    }
+    while (*p != '\0') {
+        /* Do a newline after every 15 hex bytes + add the space indent */
+        if ((bytes % 15) == 0 && bytes > 0) {
+            if (BIO_printf(out, ":\n%s", spaces) <= 0)
+                goto err;
+            use_sep = 0; /* The first byte on the next line doesnt have a : */
+        }
+        if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "",
+                       tolower(p[0]), tolower(p[1])) <= 0)
+            goto err;
+        ++bytes;
+        p += 2;
+        use_sep = 1;
+    }
+    if (BIO_printf(out, "\n") <= 0)
+        goto err;
+    ret = 1;
+err:
+    OPENSSL_free(hex_str);
+    return ret;
+}
+
+/* Number of octets per line */
+#define LABELED_BUF_PRINT_WIDTH    15
+
+static int print_labeled_buf(BIO *out, const char *label,
+                             const unsigned char *buf, size_t buflen)
+{
+    size_t i;
+
+    if (BIO_printf(out, "%s\n", label) <= 0)
+        return 0;
+
+    for (i = 0; i < buflen; i++) {
+        if ((i % LABELED_BUF_PRINT_WIDTH) == 0) {
+            if (i > 0 && BIO_printf(out, "\n") <= 0)
+                return 0;
+            if (BIO_printf(out, "    ") <= 0)
+                return 0;
+        }
+
+        if (BIO_printf(out, "%02x%s", buf[i],
+                                 (i == buflen - 1) ? "" : ":") <= 0)
+            return 0;
+    }
+    if (BIO_printf(out, "\n") <= 0)
+        return 0;
+
+    return 1;
+}
+
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA)
+static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc)
+{
+    if (ffc->nid != NID_undef) {
+#ifndef OPENSSL_NO_DH
+        const char *name = ffc_named_group_from_uid(ffc->nid);
+
+        if (name == NULL)
+            goto err;
+        if (BIO_printf(out, "GROUP: %s\n", name) <= 0)
+            goto err;
+        return 1;
+#else
+        /* How could this be? We should not have a nid in a no-dh build. */
+        goto err;
+#endif
+    }
+
+    if (!print_labeled_bignum(out, "P:   ", ffc->p))
+        goto err;
+    if (ffc->q != NULL) {
+        if (!print_labeled_bignum(out, "Q:   ", ffc->q))
+            goto err;
+    }
+    if (!print_labeled_bignum(out, "G:   ", ffc->g))
+        goto err;
+    if (ffc->j != NULL) {
+        if (!print_labeled_bignum(out, "J:   ", ffc->j))
+            goto err;
+    }
+    if (ffc->seed != NULL) {
+        if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen))
+            goto err;
+    }
+    if (ffc->gindex != -1) {
+        if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0)
+            goto err;
+    }
+    if (ffc->pcounter != -1) {
+        if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0)
+            goto err;
+    }
+    if (ffc->h != 0) {
+        if (BIO_printf(out, "h: %d\n", ffc->h) <= 0)
+            goto err;
+    }
+    return 1;
+err:
+    return 0;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DH
+# define dh_param_selection     OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+# define dh_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | dh_param_selection)
+# define dh_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | dh_param_selection)
+
+static int dh_to_text(BIO *out, const void *key, int selection)
+{
+    const DH *dh = key;
+    const char *type_label = NULL;
+    const BIGNUM *priv_key = NULL, *pub_key = NULL;
+    const FFC_PARAMS *params = NULL;
+    const BIGNUM *p = NULL;
+
+    if (out == NULL || dh == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        type_label = "DH Private-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+        type_label = "DH Public-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
+        type_label = "DH Parameters";
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        priv_key = DH_get0_priv_key(dh);
+        if (priv_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+            return 0;
+        }
+    }
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        pub_key = DH_get0_pub_key(dh);
+        if (pub_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+            return 0;
+        }
+    }
+    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+        params = dh_get0_params((DH *)dh);
+        if (params == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
+            return 0;
+        }
+    }
+
+    p = DH_get0_p(dh);
+    if (p == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+        return 0;
+    }
+
+    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
+        return 0;
+    if (priv_key != NULL
+        && !print_labeled_bignum(out, "private-key:", priv_key))
+        return 0;
+    if (pub_key != NULL
+        && !print_labeled_bignum(out, "public-key:", pub_key))
+        return 0;
+    if (params != NULL
+        && !ffc_params_to_text(out, params))
+        return 0;
+
+    return 1;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_DSA
+# define dsa_param_selection    OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+# define dsa_pub_selection      (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | dsa_param_selection)
+# define dsa_priv_selection     (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | dsa_param_selection)
+
+static int dsa_to_text(BIO *out, const void *key, int selection)
+{
+    const DSA *dsa = key;
+    const char *type_label = NULL;
+    const BIGNUM *priv_key = NULL, *pub_key = NULL;
+    const FFC_PARAMS *params = NULL;
+    const BIGNUM *p = NULL;
+
+    if (out == NULL || dsa == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        type_label = "Private-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+        type_label = "Public-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
+        type_label = "DSA-Parameters";
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        priv_key = DSA_get0_priv_key(dsa);
+        if (priv_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+            return 0;
+        }
+    }
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        pub_key = DSA_get0_pub_key(dsa);
+        if (pub_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+            return 0;
+        }
+    }
+    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+        params = dsa_get0_params((DSA *)dsa);
+        if (params == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
+            return 0;
+        }
+    }
+
+    p = DSA_get0_p(dsa);
+    if (p == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+        return 0;
+    }
+
+    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
+        return 0;
+    if (priv_key != NULL
+        && !print_labeled_bignum(out, "priv:", priv_key))
+        return 0;
+    if (pub_key != NULL
+        && !print_labeled_bignum(out, "pub: ", pub_key))
+        return 0;
+    if (params != NULL
+        && !ffc_params_to_text(out, params))
+        return 0;
+
+    return 1;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_EC
+# define ec_param_selection     OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+# define ec_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | ec_param_selection)
+# define ec_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | ec_param_selection)
+
+static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group,
+                                           BN_CTX *ctx)
+{
+    const char *plabel = "Prime:";
+    BIGNUM *p = NULL, *a = NULL, *b = NULL;
+
+    p = BN_CTX_get(ctx);
+    a = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    if (b == NULL
+        || !EC_GROUP_get_curve(group, p, a, b, ctx))
+        return 0;
+
+    if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
+        int basis_type = EC_GROUP_get_basis_type(group);
+
+        /* print the 'short name' of the base type OID */
+        if (basis_type == NID_undef
+            || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
+            return 0;
+        plabel = "Polynomial:";
+    }
+    return print_labeled_bignum(out, plabel, p)
+        && print_labeled_bignum(out, "A:   ", a)
+        && print_labeled_bignum(out, "B:   ", b);
+}
+
+static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group,
+                                         BN_CTX *ctx)
+{
+    const EC_POINT *point = NULL;
+    BIGNUM *gen = NULL;
+    const char *glabel = NULL;
+    point_conversion_form_t form;
+
+    form = EC_GROUP_get_point_conversion_form(group);
+    point = EC_GROUP_get0_generator(group);
+    gen = BN_CTX_get(ctx);
+
+    if (gen == NULL
+        || point == NULL
+        || EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
+        return 0;
+
+    if (gen != NULL) {
+        switch (form) {
+        case POINT_CONVERSION_COMPRESSED:
+           glabel = "Generator (compressed):";
+           break;
+        case POINT_CONVERSION_UNCOMPRESSED:
+            glabel = "Generator (uncompressed):";
+            break;
+        case POINT_CONVERSION_HYBRID:
+            glabel = "Generator (hybrid):";
+            break;
+        default:
+            return 0;
+        }
+        return print_labeled_bignum(out, glabel, gen);
+    }
+    return 1;
+}
+
+/* Print explicit parameters */
+static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group,
+                                     OPENSSL_CTX *libctx)
+{
+    int ret = 0, tmp_nid;
+    BN_CTX *ctx = NULL;
+    const BIGNUM *order = NULL, *cofactor = NULL;
+    const unsigned char *seed;
+    size_t seed_len = 0;
+
+    ctx = BN_CTX_new_ex(libctx);
+    if (ctx == NULL)
+        return 0;
+    BN_CTX_start(ctx);
+
+    tmp_nid = EC_GROUP_get_field_type(group);
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL)
+        goto err;
+
+    seed = EC_GROUP_get0_seed(group);
+    if (seed != NULL)
+        seed_len = EC_GROUP_get_seed_len(group);
+    cofactor = EC_GROUP_get0_cofactor(group);
+
+    /* print the 'short name' of the field type */
+    if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
+        || !ec_param_explicit_curve_to_text(out, group, ctx)
+        || !ec_param_explicit_gen_to_text(out, group, ctx)
+        || !print_labeled_bignum(out, "Order: ", order)
+        || (cofactor != NULL
+            && !print_labeled_bignum(out, "Cofactor: ", cofactor))
+        || (seed != NULL
+            && !print_labeled_buf(out, "Seed:", seed, seed_len)))
+        goto err;
+    ret = 1;
+err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    return ret;
+}
+
+static int ec_param_to_text(BIO *out, const EC_GROUP *group,
+                            OPENSSL_CTX *libctx)
+{
+    if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
+        const char *curve_name;
+        int curve_nid = EC_GROUP_get_curve_name(group);
+
+        /* Explicit parameters */
+        if (curve_nid == NID_undef)
+            return 0;
+
+        if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
+            return 0;
+
+        curve_name = EC_curve_nid2nist(curve_nid);
+        return (curve_name == NULL
+                || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
+    } else {
+        return ec_param_explicit_to_text(out, group, libctx);
+    }
+}
+
+static int ec_to_text(BIO *out, const void *key, int selection)
+{
+    const EC_KEY *ec = key;
+    const char *type_label = NULL;
+    unsigned char *priv = NULL, *pub = NULL;
+    size_t priv_len = 0, pub_len = 0;
+    const EC_GROUP *group;
+    int ret = 0;
+
+    if (out == NULL || ec == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if ((group = EC_KEY_get0_group(ec)) == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+        return 0;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+        type_label = "Private-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+        type_label = "Public-Key";
+    else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
+        type_label = "EC-Parameters";
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        const BIGNUM *priv_key = EC_KEY_get0_private_key(ec);
+
+        if (priv_key == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+            goto err;
+        }
+        priv_len = EC_KEY_priv2buf(ec, &priv);
+        if (priv_len == 0)
+            goto err;
+    }
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec);
+
+        if (pub_pt == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+            goto err;
+        }
+
+        pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL);
+        if (pub_len == 0)
+            goto err;
+    }
+
+    if (BIO_printf(out, "%s: (%d bit)\n", type_label,
+                   EC_GROUP_order_bits(group)) <= 0)
+        goto err;
+    if (priv != NULL
+        && !print_labeled_buf(out, "priv:", priv, priv_len))
+        goto err;
+    if (pub != NULL
+        && !print_labeled_buf(out, "pub:", pub, pub_len))
+        goto err;
+    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
+        ret = ec_param_to_text(out, group, ec_key_get_libctx(ec));
+err:
+    OPENSSL_clear_free(priv, priv_len);
+    OPENSSL_free(pub);
+    return ret;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_EC
+# define ecx_pub_selection      OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+# define ecx_priv_selection     OSSL_KEYMGMT_SELECT_KEYPAIR
+
+static int ecx_to_text(BIO *out, const void *key, int selection)
+{
+    const ECX_KEY *ecx = key;
+    const char *type_label = NULL;
+
+    if (out == NULL || ecx == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if (ecx->privkey == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+            return 0;
+        }
+
+        switch (ecx->type) {
+        case ECX_KEY_TYPE_X25519:
+            type_label = "X25519 Private-Key";
+            break;
+        case ECX_KEY_TYPE_X448:
+            type_label = "X448 Private-Key";
+            break;
+        case ECX_KEY_TYPE_ED25519:
+            type_label = "ED25519 Private-Key";
+            break;
+        case ECX_KEY_TYPE_ED448:
+            type_label = "ED448 Private-Key";
+            break;
+        }
+    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        /* ecx->pubkey is an array, not a pointer... */
+        if (!ecx->haspubkey) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+            return 0;
+        }
+
+        switch (ecx->type) {
+        case ECX_KEY_TYPE_X25519:
+            type_label = "X25519 Public-Key";
+            break;
+        case ECX_KEY_TYPE_X448:
+            type_label = "X448 Public-Key";
+            break;
+        case ECX_KEY_TYPE_ED25519:
+            type_label = "ED25519 Public-Key";
+            break;
+        case ECX_KEY_TYPE_ED448:
+            type_label = "ED448 Public-Key";
+            break;
+        }
+    }
+
+    if (BIO_printf(out, "%s:\n", type_label) <= 0)
+        return 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+        && !print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen))
+        return 0;
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
+        && !print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen))
+        return 0;
+
+    return 1;
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#define rsa_param_selection     OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
+#define rsa_pub_selection       (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
+                                 | rsa_param_selection)
+#define rsa_priv_selection      (OSSL_KEYMGMT_SELECT_KEYPAIR \
+                                 | rsa_param_selection)
+
+static int rsa_to_text(BIO *out, const void *key, int selection)
+{
+    const RSA *rsa = key;
+    const char *type_label = "RSA key";
+    const char *modulus_label;
+    const char *exponent_label;
+    const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
+    STACK_OF(BIGNUM_const) *factors = NULL;
+    STACK_OF(BIGNUM_const) *exps = NULL;
+    STACK_OF(BIGNUM_const) *coeffs = NULL;
+    int primes;
+    const RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30((RSA *)rsa);
+    int ret = 0;
+
+    if (out == NULL || rsa == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+
+    factors = sk_BIGNUM_const_new_null();
+    exps = sk_BIGNUM_const_new_null();
+    coeffs = sk_BIGNUM_const_new_null();
+
+    if (factors == NULL || exps == NULL || coeffs == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        type_label = "Private-Key";
+        modulus_label = "modulus:";
+        exponent_label = "publicExponent:";
+    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        type_label = "Public-Key";
+        modulus_label = "Modulus:";
+        exponent_label = "Exponent:";
+    }
+
+    RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
+    rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs);
+    primes = sk_BIGNUM_const_num(factors);
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if (BIO_printf(out, "%s: (%d bit, %d primes)\n",
+                       type_label, BN_num_bits(rsa_n), primes) <= 0)
+            goto err;
+    } else {
+        if (BIO_printf(out, "%s: (%d bit)\n",
+                       type_label, BN_num_bits(rsa_n)) <= 0)
+            goto err;
+    }
+
+    if (!print_labeled_bignum(out, modulus_label, rsa_n))
+        goto err;
+    if (!print_labeled_bignum(out, exponent_label, rsa_e))
+        goto err;
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        int i;
+
+        if (!print_labeled_bignum(out, "privateExponent:", rsa_d))
+            goto err;
+        if (!print_labeled_bignum(out, "prime1:",
+                                  sk_BIGNUM_const_value(factors, 0)))
+            goto err;
+        if (!print_labeled_bignum(out, "prime2:",
+                                  sk_BIGNUM_const_value(factors, 1)))
+            goto err;
+        if (!print_labeled_bignum(out, "exponent1:",
+                                  sk_BIGNUM_const_value(exps, 0)))
+            goto err;
+        if (!print_labeled_bignum(out, "exponent2:",
+                                  sk_BIGNUM_const_value(exps, 1)))
+            goto err;
+        if (!print_labeled_bignum(out, "coefficient:",
+                                  sk_BIGNUM_const_value(coeffs, 0)))
+            goto err;
+        for (i = 2; i < sk_BIGNUM_const_num(factors); i++) {
+            if (BIO_printf(out, "prime%d:", i + 1) <= 0)
+                goto err;
+            if (!print_labeled_bignum(out, NULL,
+                                      sk_BIGNUM_const_value(factors, i)))
+                goto err;
+            if (BIO_printf(out, "exponent%d:", i + 1) <= 0)
+                goto err;
+            if (!print_labeled_bignum(out, NULL,
+                                      sk_BIGNUM_const_value(exps, i)))
+                goto err;
+            if (BIO_printf(out, "coefficient%d:", i + 1) <= 0)
+                goto err;
+            if (!print_labeled_bignum(out, NULL,
+                                      sk_BIGNUM_const_value(coeffs, i - 1)))
+                goto err;
+        }
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) {
+        switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+        case RSA_FLAG_TYPE_RSA:
+            if (!rsa_pss_params_30_is_unrestricted(pss_params)) {
+                if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
+                    goto err;
+            }
+            break;
+        case RSA_FLAG_TYPE_RSASSAPSS:
+            if (rsa_pss_params_30_is_unrestricted(pss_params)) {
+                if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
+                    goto err;
+            } else {
+                int hashalg_nid = rsa_pss_params_30_hashalg(pss_params);
+                int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params);
+                int maskgenhashalg_nid =
+                    rsa_pss_params_30_maskgenhashalg(pss_params);
+                int saltlen = rsa_pss_params_30_saltlen(pss_params);
+                int trailerfield = rsa_pss_params_30_trailerfield(pss_params);
+
+                if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
+                    goto err;
+                if (BIO_printf(out, "  Hash Algorithm: %s%s\n",
+                               rsa_oaeppss_nid2name(hashalg_nid),
+                               (hashalg_nid == NID_sha1
+                                ? " (default)" : "")) <= 0)
+                    goto err;
+                if (BIO_printf(out, "  Mask Algorithm: %s with %s%s\n",
+                               rsa_mgf_nid2name(maskgenalg_nid),
+                               rsa_oaeppss_nid2name(maskgenhashalg_nid),
+                               (maskgenalg_nid == NID_mgf1
+                                && maskgenhashalg_nid == NID_sha1
+                                ? " (default)" : "")) <= 0)
+                    goto err;
+                if (BIO_printf(out, "  Minimum Salt Length: %d%s\n",
+                               saltlen,
+                               (saltlen == 20 ? " (default)" : "")) <= 0)
+                    goto err;
+                /*
+                 * TODO(3.0) Should we show the ASN.1 trailerField value, or
+                 * the actual trailerfield byte (i.e. 0xBC for 1)?
+                 * crypto/rsa/rsa_ameth.c isn't very clear on that, as it
+                 * does display 0xBC when the default applies, but the ASN.1
+                 * trailerField value otherwise...
+                 */
+                if (BIO_printf(out, "  Trailer Field: 0x%x%s\n",
+                               trailerfield,
+                               (trailerfield == 1 ? " (default)" : "")) <= 0)
+                    goto err;
+            }
+            break;
+        }
+    }
+
+    ret = 1;
+ err:
+    sk_BIGNUM_const_free(factors);
+    sk_BIGNUM_const_free(exps);
+    sk_BIGNUM_const_free(coeffs);
+    return ret;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void *key2text_newctx(void *provctx)
+{
+    return provctx;
+}
+
+static void key2text_freectx(ossl_unused void *vctx)
+{
+}
+
+static int key2text_encode(void *vctx, const void *key, int selection,
+                           OSSL_CORE_BIO *cout,
+                           int (*key2text)(BIO *out, const void *key,
+                                           int selection),
+                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+{
+    BIO *out = bio_new_from_core_bio(vctx, cout);
+    int ret;
+
+    if (out == NULL)
+        return 0;
+
+    ret = key2text(out, key, selection);
+    BIO_free(out);
+
+    return ret;
+}
+
+#define MAKE_TEXT_ENCODER_KIND(impl, kind, type)                        \
+    static OSSL_FUNC_encoder_encode_data_fn                             \
+    impl##_##kind##2text_encode_d;                                      \
+    static OSSL_FUNC_encoder_encode_object_fn                           \
+    impl##_##kind##2text_encode_o;                                      \
+    static int                                                          \
+    impl##_##kind##2text_encode_d(void *ctx, const OSSL_PARAM params[], \
+                                  OSSL_CORE_BIO *cout,                  \
+                                  OSSL_PASSPHRASE_CALLBACK *cb,         \
+                                  void *cbarg)                          \
+    {                                                                   \
+        int selection = type##_##kind##_selection;                      \
+        void *key = ossl_prov_import_key(impl##_keymgmt_functions,      \
+                                         ctx, selection, params);       \
+        int ret;                                                        \
+                                                                        \
+        if (key == NULL)                                                \
+            return 0;                                                   \
+                                                                        \
+        ret = impl##_##kind##2text_encode_o(ctx, key, cout, cb, cbarg); \
+        ossl_prov_free_key(impl##_keymgmt_functions, key);              \
+        return ret;                                                     \
+    }                                                                   \
+    static int                                                          \
+    impl##_##kind##2text_encode_o(void *vctx, const void *key,          \
+                                  OSSL_CORE_BIO *cout,                  \
+                                  OSSL_PASSPHRASE_CALLBACK *cb,         \
+                                  void *cbarg)                          \
+    {                                                                   \
+        int selection = type##_##kind##_selection;                      \
+                                                                        \
+        return key2text_encode(vctx, key, selection, cout,              \
+                               type##_to_text, cb, cbarg);              \
+    }                                                                   \
+    const OSSL_DISPATCH impl##_##kind##_to_text_encoder_functions[] = { \
+        { OSSL_FUNC_ENCODER_NEWCTX,                                     \
+          (void (*)(void))key2text_newctx },                            \
+        { OSSL_FUNC_ENCODER_FREECTX,                                    \
+          (void (*)(void))key2text_freectx },                           \
+        { OSSL_FUNC_ENCODER_ENCODE_DATA,                                \
+          (void (*)(void))impl##_##kind##2text_encode_d },              \
+        { OSSL_FUNC_ENCODER_ENCODE_OBJECT,                              \
+          (void (*)(void))impl##_##kind##2text_encode_o },              \
+        { 0, NULL }                                                     \
+    }
+
+#define MAKE_TEXT_ENCODER(impl, type)                                   \
+    MAKE_TEXT_ENCODER_KIND(impl, param, type);                          \
+    MAKE_TEXT_ENCODER_KIND(impl, pub, type);                            \
+    MAKE_TEXT_ENCODER_KIND(impl, priv, type)
+
+#define MAKE_TEXT_ENCODER_NOPARAM(impl, type)                           \
+    MAKE_TEXT_ENCODER_KIND(impl, pub, type);                            \
+    MAKE_TEXT_ENCODER_KIND(impl, priv, type)
+
+#ifndef OPENSSL_NO_DH
+MAKE_TEXT_ENCODER(dh, dh);
+#endif
+#ifndef OPENSSL_NO_DSA
+MAKE_TEXT_ENCODER(dsa, dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+MAKE_TEXT_ENCODER(ec, ec);
+MAKE_TEXT_ENCODER_NOPARAM(ed25519, ecx);
+MAKE_TEXT_ENCODER_NOPARAM(ed448, ecx);
+MAKE_TEXT_ENCODER_NOPARAM(x25519, ecx);
+MAKE_TEXT_ENCODER_NOPARAM(x448, ecx);
+#endif
+MAKE_TEXT_ENCODER_NOPARAM(rsa, rsa);
diff --git a/providers/implementations/encode_decode/encoder_common.c b/providers/implementations/encode_decode/encoder_common.c
deleted file mode 100644
index 4d8348b3fc..0000000000
--- a/providers/implementations/encode_decode/encoder_common.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/opensslconf.h> /* SIXTY_FOUR_BIT_LONG, ... */
-#include <openssl/err.h>
-#include <openssl/pem.h>         /* PEM_BUFSIZE */
-#include <openssl/pkcs12.h>      /* PKCS8_encrypt() */
-#include <openssl/types.h>
-#include <openssl/x509.h>        /* i2d_X509_PUBKEY_bio() */
-#include "crypto/bn.h"           /* bn_get_words() */
-#include "crypto/ctype.h"
-#include "crypto/ecx.h"
-#include "prov/bio.h"            /* ossl_prov_bio_printf() */
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
-#include "encoder_local.h"
-
-static PKCS8_PRIV_KEY_INFO *
-ossl_prov_p8info_from_obj(const void *obj, int obj_nid,
-                          void *params,
-                          int params_type,
-                          int (*k2d)(const void *obj,
-                                     unsigned char **pder))
-{
-    /* der, derlen store the key DER output and its length */
-    unsigned char *der = NULL;
-    int derlen;
-    /* The final PKCS#8 info */
-    PKCS8_PRIV_KEY_INFO *p8info = NULL;
-
-
-    if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL
-        || (derlen = k2d(obj, &der)) <= 0
-        || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(obj_nid), 0,
-                            params_type, params, der, derlen)) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        PKCS8_PRIV_KEY_INFO_free(p8info);
-        OPENSSL_free(der);
-        p8info = NULL;
-    }
-
-    return p8info;
-}
-
-static X509_SIG *ossl_prov_encp8_from_p8info(PKCS8_PRIV_KEY_INFO *p8info,
-                                             struct pkcs8_encrypt_ctx_st *ctx)
-{
-    X509_SIG *p8 = NULL;
-    char buf[PEM_BUFSIZE];
-    const void *kstr = ctx->cipher_pass;
-    size_t klen = ctx->cipher_pass_length;
-
-    if (ctx->cipher == NULL)
-        return NULL;
-
-    if (kstr == NULL) {
-        if (!ctx->cb(buf, sizeof(buf), &klen, NULL, ctx->cbarg)) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
-            return NULL;
-        }
-        kstr = buf;
-    }
-    /* NID == -1 means "standard" */
-    p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info);
-    if (kstr == buf)
-        OPENSSL_cleanse(buf, klen);
-    return p8;
-}
-
-static X509_SIG *ossl_prov_encp8_from_obj(const void *obj, int obj_nid,
-                                          void *params,
-                                          int params_type,
-                                          int (*k2d)(const void *obj,
-                                                     unsigned char **pder),
-                                          struct pkcs8_encrypt_ctx_st *ctx)
-{
-    PKCS8_PRIV_KEY_INFO *p8info =
-        ossl_prov_p8info_from_obj(obj, obj_nid, params, params_type, k2d);
-    X509_SIG *p8 = ossl_prov_encp8_from_p8info(p8info, ctx);
-
-    PKCS8_PRIV_KEY_INFO_free(p8info);
-    return p8;
-}
-
-static X509_PUBKEY *ossl_prov_pubkey_from_obj(const void *obj, int obj_nid,
-                                              void *params,
-                                              int params_type,
-                                              int (*k2d)(const void *obj,
-                                                         unsigned char **pder))
-{
-    /* der, derlen store the key DER output and its length */
-    unsigned char *der = NULL;
-    int derlen;
-    /* The final X509_PUBKEY */
-    X509_PUBKEY *xpk = NULL;
-
-
-    if ((xpk = X509_PUBKEY_new()) == NULL
-        || (derlen = k2d(obj, &der)) <= 0
-        || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(obj_nid),
-                                   params_type, params, der, derlen)) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        X509_PUBKEY_free(xpk);
-        OPENSSL_free(der);
-        xpk = NULL;
-    }
-
-    return xpk;
-}
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns)
-{
-    /* Pilfer the keymgmt dispatch table */
-    for (; fns->function_id != 0; fns++)
-        if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW)
-            return OSSL_FUNC_keymgmt_new(fns);
-
-    return NULL;
-}
-
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns)
-{
-    /* Pilfer the keymgmt dispatch table */
-    for (; fns->function_id != 0; fns++)
-        if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE)
-            return OSSL_FUNC_keymgmt_free(fns);
-
-    return NULL;
-}
-
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns)
-{
-    /* Pilfer the keymgmt dispatch table */
-    for (; fns->function_id != 0; fns++)
-        if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT)
-            return OSSL_FUNC_keymgmt_import(fns);
-
-    return NULL;
-}
-
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
-{
-    /* Pilfer the keymgmt dispatch table */
-    for (; fns->function_id != 0; fns++)
-        if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
-            return OSSL_FUNC_keymgmt_export(fns);
-
-    return NULL;
-}
-
-# ifdef SIXTY_FOUR_BIT_LONG
-#  define BN_FMTu "%lu"
-#  define BN_FMTx "%lx"
-# endif
-
-# ifdef SIXTY_FOUR_BIT
-#  define BN_FMTu "%llu"
-#  define BN_FMTx "%llx"
-# endif
-
-# ifdef THIRTY_TWO_BIT
-#  define BN_FMTu "%u"
-#  define BN_FMTx "%x"
-# endif
-
-int ossl_prov_print_labeled_bignum(BIO *out, const char *label,
-                                   const BIGNUM *bn)
-{
-    int ret = 0, use_sep = 0;
-    char *hex_str = NULL, *p;
-    const char spaces[] = "    ";
-    const char *post_label_spc = " ";
-
-    const char *neg = "";
-    int bytes;
-
-    if (bn == NULL)
-        return 0;
-    if (label == NULL) {
-        label = "";
-        post_label_spc = "";
-    }
-
-    if (BN_is_zero(bn))
-        return BIO_printf(out, "%s%s0\n", label, post_label_spc);
-
-    if (BN_num_bytes(bn) <= BN_BYTES) {
-        BN_ULONG *words = bn_get_words(bn);
-
-        if (BN_is_negative(bn))
-            neg = "-";
-
-        return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n",
-                          label, post_label_spc, neg, words[0], neg, words[0]);
-    }
-
-    hex_str = BN_bn2hex(bn);
-    p = hex_str;
-    if (*p == '-') {
-        ++p;
-        neg = " (Negative)";
-    }
-    if (BIO_printf(out, "%s%s\n", label, neg) <= 0)
-        goto err;
-
-    /* Keep track of how many bytes we have printed out so far */
-    bytes = 0;
-
-    if (BIO_printf(out, "%s", spaces) <= 0)
-        goto err;
-
-    /* Add a leading 00 if the top bit is set */
-    if (*p >= '8') {
-        if (BIO_printf(out, "%02x", 0) <= 0)
-            goto err;
-        ++bytes;
-        use_sep = 1;
-    }
-    while (*p != '\0') {
-        /* Do a newline after every 15 hex bytes + add the space indent */
-        if ((bytes % 15) == 0 && bytes > 0) {
-            if (BIO_printf(out, ":\n%s", spaces) <= 0)
-                goto err;
-            use_sep = 0; /* The first byte on the next line doesnt have a : */
-        }
-        if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "",
-                       ossl_tolower(p[0]), ossl_tolower(p[1])) <= 0)
-            goto err;
-        ++bytes;
-        p += 2;
-        use_sep = 1;
-    }
-    if (BIO_printf(out, "\n") <= 0)
-        goto err;
-    ret = 1;
-err:
-    OPENSSL_free(hex_str);
-    return ret;
-}
-
-/* Number of octets per line */
-#define LABELED_BUF_PRINT_WIDTH    15
-
-int ossl_prov_print_labeled_buf(BIO *out, const char *label,
-                                const unsigned char *buf, size_t buflen)
-{
-    size_t i;
-
-    if (BIO_printf(out, "%s\n", label) <= 0)
-        return 0;
-
-    for (i = 0; i < buflen; i++) {
-        if ((i % LABELED_BUF_PRINT_WIDTH) == 0) {
-            if (i > 0 && BIO_printf(out, "\n") <= 0)
-                return 0;
-            if (BIO_printf(out, "    ") <= 0)
-                return 0;
-        }
-
-        if (BIO_printf(out, "%02x%s", buf[i],
-                                 (i == buflen - 1) ? "" : ":") <= 0)
-            return 0;
-    }
-    if (BIO_printf(out, "\n") <= 0)
-        return 0;
-
-    return 1;
-}
-
-/* p2s = param to asn1, k2d = key to der */
-int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid,
-                                      int (*p2s)(const void *obj, int nid,
-                                                 void **str,
-                                                 int *strtype),
-                                      int (*k2d)(const void *obj,
-                                                 unsigned char **pder),
-                                      struct pkcs8_encrypt_ctx_st *ctx)
-{
-    int ret = 0;
-    void *str = NULL;
-    int strtype = V_ASN1_UNDEF;
-
-    if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
-        return 0;
-
-    if (ctx->cipher_intent) {
-        X509_SIG *p8 =
-            ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, k2d, ctx);
-
-        if (p8 != NULL)
-            ret = i2d_PKCS8_bio(out, p8);
-
-        X509_SIG_free(p8);
-    } else {
-        PKCS8_PRIV_KEY_INFO *p8info =
-            ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d);
-
-        if (p8info != NULL)
-            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
-
-        PKCS8_PRIV_KEY_INFO_free(p8info);
-    }
-
-    return ret;
-}
-
-int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid,
-                                      int (*p2s)(const void *obj, int nid,
-                                                 void **str,
-                                                 int *strtype),
-                                      int (*k2d)(const void *obj,
-                                                 unsigned char **pder),
-                                      struct pkcs8_encrypt_ctx_st *ctx)
-{
-    int ret = 0;
-    void *str = NULL;
-    int strtype = V_ASN1_UNDEF;
-
-    if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
-        return 0;
-
-    if (ctx->cipher_intent) {
-        X509_SIG *p8 = ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype,
-                                                k2d, ctx);
-
-        if (p8 != NULL)
-            ret = PEM_write_bio_PKCS8(out, p8);
-
-        X509_SIG_free(p8);
-    } else {
-        PKCS8_PRIV_KEY_INFO *p8info =
-            ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d);
-
-        if (p8info != NULL)
-            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
-
-        PKCS8_PRIV_KEY_INFO_free(p8info);
-    }
-
-    return ret;
-}
-
-int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid,
-                                     int (*p2s)(const void *obj, int nid,
-                                                void **str,
-                                                int *strtype),
-                                     int (*k2d)(const void *obj,
-                                                unsigned char **pder))
-{
-    int ret = 0;
-    void *str = NULL;
-    int strtype = V_ASN1_UNDEF;
-    X509_PUBKEY *xpk = NULL;
-
-    if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
-        return 0;
-
-    xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d);
-
-    if (xpk != NULL)
-        ret = i2d_X509_PUBKEY_bio(out, xpk);
-
-    /* Also frees |str| */
-    X509_PUBKEY_free(xpk);
-    return ret;
-}
-
-int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid,
-                                     int (*p2s)(const void *obj, int nid,
-                                                void **str,
-                                                int *strtype),
-                                     int (*k2d)(const void *obj,
-                                                unsigned char **pder))
-{
-    int ret = 0;
-    void *str = NULL;
-    int strtype = V_ASN1_UNDEF;
-    X509_PUBKEY *xpk = NULL;
-
-    if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
-        return 0;
-
-    xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d);
-
-    if (xpk != NULL)
-        ret = PEM_write_bio_X509_PUBKEY(out, xpk);
-
-    /* Also frees |str| */
-    X509_PUBKEY_free(xpk);
-    return ret;
-}
diff --git a/providers/implementations/encode_decode/encoder_dh.c b/providers/implementations/encode_decode/encoder_dh.c
deleted file mode 100644
index d9578f46c4..0000000000
--- a/providers/implementations/encode_decode/encoder_dh.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DH low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/err.h>
-#include "prov/bio.h"             /* ossl_prov_bio_printf() */
-#include "prov/implementations.h" /* rsa_keymgmt_functions */
-#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
-#include "internal/ffc.h"
-#include "crypto/dh.h"
-#include "encoder_local.h"
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void)
-{
-    return ossl_prov_get_keymgmt_new(dh_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void)
-{
-    return ossl_prov_get_keymgmt_free(dh_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void)
-{
-    return ossl_prov_get_keymgmt_import(dh_keymgmt_functions);
-}
-
-int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type)
-{
-    const char *type_label = NULL;
-    const BIGNUM *priv_key = NULL, *pub_key = NULL;
-    const BIGNUM *p = NULL;
-
-    switch (type) {
-    case dh_print_priv:
-        type_label = "DH Private-Key";
-        break;
-    case dh_print_pub:
-        type_label = "DH Public-Key";
-        break;
-    case dh_print_params:
-        type_label = "DH Parameters";
-        break;
-    }
-
-    if (type == dh_print_priv) {
-        priv_key = DH_get0_priv_key(dh);
-        if (priv_key == NULL)
-            goto null_err;
-    }
-
-    if (type == dh_print_priv || type == dh_print_pub) {
-        pub_key = DH_get0_pub_key(dh);
-        if (pub_key == NULL)
-            goto null_err;
-    }
-
-    p = DH_get0_p(dh);
-    if (p == NULL)
-        goto null_err;
-
-    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p))
-        <= 0)
-        goto err;
-    if (priv_key != NULL
-        && !ossl_prov_print_labeled_bignum(out, "private-key:", priv_key))
-        goto err;
-    if (pub_key != NULL
-        && !ossl_prov_print_labeled_bignum(out, "public-key:", pub_key))
-        goto err;
-    if (!ffc_params_prov_print(out, dh_get0_params(dh)))
-        goto err;
-
-    return 1;
- err:
-    return 0;
- null_err:
-    ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-    goto err;
-}
-
-int ossl_prov_prepare_dh_params(const void *dh, int nid,
-                                void **pstr, int *pstrtype)
-{
-    ASN1_STRING *params = ASN1_STRING_new();
-
-    if (params == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    if (nid == EVP_PKEY_DHX)
-        params->length = i2d_DHxparams(dh, &params->data);
-    else
-        params->length = i2d_DHparams(dh, &params->data);
-
-    if (params->length <= 0) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        ASN1_STRING_free(params);
-        return 0;
-    }
-    params->type = V_ASN1_SEQUENCE;
-
-    *pstr = params;
-    *pstrtype = V_ASN1_SEQUENCE;
-    return 1;
-}
-
-int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder)
-{
-    const BIGNUM *bn = NULL;
-    ASN1_INTEGER *pub_key = NULL;
-    int ret;
-
-    if ((bn = DH_get0_pub_key(dh)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
-        return 0;
-    }
-    if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
-        return 0;
-    }
-
-    ret = i2d_ASN1_INTEGER(pub_key, pder);
-
-    ASN1_STRING_clear_free(pub_key);
-    return ret;
-}
-
-int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder)
-{
-    const BIGNUM *bn = NULL;
-    ASN1_INTEGER *priv_key = NULL;
-    int ret;
-
-    if ((bn = DH_get0_priv_key(dh)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
-        return 0;
-    }
-    if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
-        return 0;
-    }
-
-    ret = i2d_ASN1_INTEGER(priv_key, pder);
-
-    ASN1_STRING_clear_free(priv_key);
-    return ret;
-}
-
-
-int ossl_prov_dh_type_to_evp(const DH *dh)
-{
-    return DH_test_flags(dh, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
-}
diff --git a/providers/implementations/encode_decode/encoder_dh_param.c b/providers/implementations/encode_decode/encoder_dh_param.c
deleted file mode 100644
index 32c8769b5e..0000000000
--- a/providers/implementations/encode_decode/encoder_dh_param.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DH low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/pem.h>
-#include <openssl/dh.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn dh_param_newctx;
-static OSSL_FUNC_encoder_freectx_fn dh_param_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dh_param_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_param_der;
-static OSSL_FUNC_encoder_encode_data_fn dh_param_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_param_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn dh_param_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_param_print;
-
-/* Parameters : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *dh_param_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dh_param_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int dh_param_der_data(void *ctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dh_param_der(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_param_der(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-    ret = i2d_DHparams_bio(out, dh);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int dh_param_pem_data(void *ctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dh_param_pem(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_param_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = PEM_write_bio_DHparams(out, dh);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int dh_param_print_data(void *ctx, const OSSL_PARAM params[],
-                               OSSL_CORE_BIO *out,
-                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dh_param_print(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_param_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dh(out, dh, dh_print_params);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dh_param_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_param_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_param_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_param_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_param_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dh_param_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_dh_priv.c b/providers/implementations/encode_decode/encoder_dh_priv.c
deleted file mode 100644
index dd94223084..0000000000
--- a/providers/implementations/encode_decode/encoder_dh_priv.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DH low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/dh.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define DH_SELECT_PRIVATE_IMPORTABLE                                           \
-    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
-
-static OSSL_FUNC_encoder_newctx_fn dh_priv_newctx;
-static OSSL_FUNC_encoder_freectx_fn dh_priv_freectx;
-static OSSL_FUNC_encoder_set_ctx_params_fn dh_priv_set_ctx_params;
-static OSSL_FUNC_encoder_settable_ctx_params_fn dh_priv_settable_ctx_params;
-static OSSL_FUNC_encoder_encode_data_fn dh_priv_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_priv_der;
-static OSSL_FUNC_encoder_encode_data_fn dh_pem_priv_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_pem_priv;
-
-static OSSL_FUNC_encoder_newctx_fn dh_print_newctx;
-static OSSL_FUNC_encoder_freectx_fn dh_print_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dh_priv_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_priv_print;
-
-/*
- * Context used for private key encoding.
- */
-struct dh_priv_ctx_st {
-    void *provctx;
-
-    struct pkcs8_encrypt_ctx_st sc;
-};
-
-/* Private key : context */
-static void *dh_priv_newctx(void *provctx)
-{
-    struct dh_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-    }
-    return ctx;
-}
-
-static void dh_priv_freectx(void *vctx)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_free(ctx->sc.cipher_pass);
-    OPENSSL_free(ctx);
-}
-
-static const OSSL_PARAM *dh_priv_settable_ctx_params(ossl_unused void *provctx)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int dh_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
-        != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
-        const char *props = NULL;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
-                == NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_free(ctx->sc.cipher_pass);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
-/* Private key : DER */
-static int dh_priv_der_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        if ((dh = dh_new(ctx->provctx)) != NULL
-            && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
-            && dh_priv_der(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_priv_der(void *vctx, void *dh, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    int ret;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_der_from_obj(out, dh,
-                                            ossl_prov_dh_type_to_evp(dh),
-                                            ossl_prov_prepare_dh_params,
-                                            ossl_prov_dh_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Private key : PEM */
-static int dh_pem_priv_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        if ((dh = dh_new(ctx->provctx)) != NULL
-            && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
-            && dh_pem_priv(ctx->provctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_pem_priv(void *vctx, void *dh, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    int ret;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_pem_from_obj(out, dh,
-                                            ossl_prov_dh_type_to_evp(dh),
-                                            ossl_prov_prepare_dh_params,
-                                            ossl_prov_dh_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/*
- * There's no specific print context, so we use the provider context
- */
-static void *dh_print_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dh_print_freectx(void *ctx)
-{
-}
-
-static int dh_priv_print_data(void *vctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dh_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        if ((dh = dh_new(ctx->provctx)) != NULL
-            && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
-            && dh_priv_print(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_priv_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dh(out, dh, dh_print_priv);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dh_priv_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))dh_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dh_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_priv_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_priv_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))dh_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dh_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pem_priv_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pem_priv },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_priv_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_print_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_print_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dh_priv_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_dh_pub.c b/providers/implementations/encode_decode/encoder_dh_pub.c
deleted file mode 100644
index 583dcd9c5a..0000000000
--- a/providers/implementations/encode_decode/encoder_dh_pub.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DH low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/dh.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn dh_pub_newctx;
-static OSSL_FUNC_encoder_freectx_fn dh_pub_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dh_pub_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_pub_der;
-static OSSL_FUNC_encoder_encode_data_fn dh_pub_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_pub_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn dh_pub_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dh_pub_print;
-
-#define DH_SELECT_PUBLIC_IMPORTABLE                                            \
-    (OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
-
-/* Public key : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *dh_pub_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dh_pub_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int dh_pub_der_data(void *ctx, const OSSL_PARAM params[],
-                           OSSL_CORE_BIO *out,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
-            && dh_pub_der(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_pub_der(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_der_from_obj(out, dh,
-                                           ossl_prov_dh_type_to_evp(dh),
-                                           ossl_prov_prepare_dh_params,
-                                           ossl_prov_dh_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int dh_pub_pem_data(void *ctx, const OSSL_PARAM params[],
-                           OSSL_CORE_BIO *out,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
-            && dh_pub_pem(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_pub_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_pem_from_obj(out, dh,
-                                           ossl_prov_dh_type_to_evp(dh),
-                                           ossl_prov_prepare_dh_params,
-                                           ossl_prov_dh_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int dh_pub_print_data(void *ctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
-    OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
-    OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
-    int ok = 0;
-
-    if (dh_import != NULL) {
-        DH *dh;
-
-        /* ctx == provctx */
-        if ((dh = dh_new(ctx)) != NULL
-            && dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
-            && dh_pub_print(ctx, dh, out, cb, cbarg))
-            ok = 1;
-        dh_free(dh);
-    }
-    return ok;
-}
-
-static int dh_pub_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dh(out, dh, dh_print_pub);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dh_pub_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pub_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_pub_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pub_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dh_pub_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dh_pub_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_dsa.c b/providers/implementations/encode_decode/encoder_dsa.c
deleted file mode 100644
index 838079902e..0000000000
--- a/providers/implementations/encode_decode/encoder_dsa.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/dsa.h>
-#include <openssl/err.h>
-#include "prov/bio.h"             /* ossl_prov_bio_printf() */
-#include "prov/implementations.h" /* rsa_keymgmt_functions */
-#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
-#include "encoder_local.h"
-#include "internal/ffc.h"
-#include "crypto/dsa.h"
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void)
-{
-    return ossl_prov_get_keymgmt_new(dsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void)
-{
-    return ossl_prov_get_keymgmt_free(dsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void)
-{
-    return ossl_prov_get_keymgmt_import(dsa_keymgmt_functions);
-}
-
-int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type)
-{
-    const char *type_label = NULL;
-    const BIGNUM *priv_key = NULL, *pub_key = NULL;
-    const BIGNUM *p = NULL;
-
-
-    switch (type) {
-    case dsa_print_priv:
-        type_label = "Private-Key";
-        break;
-    case dsa_print_pub:
-        type_label = "Public-Key";
-        break;
-    case dsa_print_params:
-        type_label = "DSA-Parameters";
-        break;
-    }
-
-    if (type == dsa_print_priv) {
-        priv_key = DSA_get0_priv_key(dsa);
-        if (priv_key == NULL)
-            goto null_err;
-    }
-
-    if (type == dsa_print_priv || type == dsa_print_pub) {
-        pub_key = DSA_get0_pub_key(dsa);
-        if (pub_key == NULL)
-            goto null_err;
-    }
-
-
-    p = DSA_get0_p(dsa);
-    if (p == NULL)
-        goto null_err;
-
-    if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
-        goto err;
-    if (priv_key != NULL
-        && !ossl_prov_print_labeled_bignum(out, "priv:", priv_key))
-        goto err;
-    if (pub_key != NULL
-        && !ossl_prov_print_labeled_bignum(out, "pub: ", pub_key))
-        goto err;
-    if (!ffc_params_prov_print(out, dsa_get0_params(dsa)))
-        goto err;
-
-    return 1;
- err:
-    return 0;
- null_err:
-    ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-    goto err;
-}
-
-int ossl_prov_prepare_dsa_params(const void *dsa, int nid,
-                                 void **pstr, int *pstrtype)
-{
-    ASN1_STRING *params = ASN1_STRING_new();
-
-    if (params == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    params->length = i2d_DSAparams(dsa, &params->data);
-
-    if (params->length <= 0) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        ASN1_STRING_free(params);
-        return 0;
-    }
-
-    *pstrtype = V_ASN1_SEQUENCE;
-    *pstr = params;
-    return 1;
-}
-
-int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid,
-                                     void **pstr, int *pstrtype)
-{
-    const BIGNUM *p = DSA_get0_p(dsa);
-    const BIGNUM *q = DSA_get0_q(dsa);
-    const BIGNUM *g = DSA_get0_g(dsa);
-
-    if (p != NULL && q != NULL && g != NULL)
-        return ossl_prov_prepare_dsa_params(dsa, nid, pstr, pstrtype);
-
-    *pstr = NULL;
-    *pstrtype = V_ASN1_UNDEF;
-    return 1;
-}
-
-int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder)
-{
-    const BIGNUM *bn = NULL;
-    ASN1_INTEGER *pub_key = NULL;
-    int ret;
-
-    if ((bn = DSA_get0_pub_key(dsa)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
-        return 0;
-    }
-    if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
-        return 0;
-    }
-
-    ret = i2d_ASN1_INTEGER(pub_key, pder);
-
-    ASN1_STRING_clear_free(pub_key);
-    return ret;
-}
-
-int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder)
-{
-    const BIGNUM *bn = NULL;
-    ASN1_INTEGER *priv_key = NULL;
-    int ret;
-
-    if ((bn = DSA_get0_priv_key(dsa)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
-        return 0;
-    }
-    if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
-        return 0;
-    }
-
-    ret = i2d_ASN1_INTEGER(priv_key, pder);
-
-    ASN1_STRING_clear_free(priv_key);
-    return ret;
-}
diff --git a/providers/implementations/encode_decode/encoder_dsa_param.c b/providers/implementations/encode_decode/encoder_dsa_param.c
deleted file mode 100644
index 0438b14cc8..0000000000
--- a/providers/implementations/encode_decode/encoder_dsa_param.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/pem.h>
-#include <openssl/dsa.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn dsa_param_newctx;
-static OSSL_FUNC_encoder_freectx_fn dsa_param_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dsa_param_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_param_der;
-static OSSL_FUNC_encoder_encode_data_fn dsa_param_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_param_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn dsa_param_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_param_print;
-
-/* Parameters : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *dsa_param_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dsa_param_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int dsa_param_der_data(void *ctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dsa_param_der(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_param_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = i2d_DSAparams_bio(out, dsa);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int dsa_param_pem_data(void *ctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dsa_param_pem(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_param_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = PEM_write_bio_DSAparams(out, dsa);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int dsa_param_print_data(void *ctx, const OSSL_PARAM params[],
-                                OSSL_CORE_BIO *out,
-                                OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
-            && dsa_param_print(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_param_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dsa(out, dsa, dsa_print_params);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dsa_param_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_param_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_param_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_param_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_param_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dsa_param_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_dsa_priv.c b/providers/implementations/encode_decode/encoder_dsa_priv.c
deleted file mode 100644
index be5b7ee326..0000000000
--- a/providers/implementations/encode_decode/encoder_dsa_priv.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/dsa.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define DSA_SELECT_PRIVATE_IMPORTABLE                                          \
-    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
-
-static OSSL_FUNC_encoder_newctx_fn dsa_priv_newctx;
-static OSSL_FUNC_encoder_freectx_fn dsa_priv_freectx;
-static OSSL_FUNC_encoder_set_ctx_params_fn dsa_priv_set_ctx_params;
-static OSSL_FUNC_encoder_settable_ctx_params_fn dsa_priv_settable_ctx_params;
-static OSSL_FUNC_encoder_encode_data_fn dsa_priv_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_priv_der;
-static OSSL_FUNC_encoder_encode_data_fn dsa_pem_priv_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_pem_priv;
-
-static OSSL_FUNC_encoder_newctx_fn dsa_print_newctx;
-static OSSL_FUNC_encoder_freectx_fn dsa_print_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dsa_priv_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_priv_print;
-
-/*
- * Context used for private key encoding.
- */
-struct dsa_priv_ctx_st {
-    void *provctx;
-
-    struct pkcs8_encrypt_ctx_st sc;
-};
-
-/* Private key : context */
-static void *dsa_priv_newctx(void *provctx)
-{
-    struct dsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-    }
-    return ctx;
-}
-
-static void dsa_priv_freectx(void *vctx)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_free(ctx->sc.cipher_pass);
-    OPENSSL_free(ctx);
-}
-
-static const OSSL_PARAM *dsa_priv_settable_ctx_params(ossl_unused void *provctx)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int dsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
-        != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
-        const char *props = NULL;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
-                == NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_free(ctx->sc.cipher_pass);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
-/* Private key : DER */
-static int dsa_priv_der_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        if ((dsa = dsa_new(ctx->provctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && dsa_priv_der(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_priv_der(void *vctx, void *dsa, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_der_from_obj(out, dsa, EVP_PKEY_DSA,
-                                            ossl_prov_prepare_dsa_params,
-                                            ossl_prov_dsa_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Private key : PEM */
-static int dsa_pem_priv_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        if ((dsa = dsa_new(ctx->provctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && dsa_pem_priv(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_pem_priv(void *vctx, void *dsa, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_pem_from_obj(out, dsa, EVP_PKEY_DSA,
-                                            ossl_prov_prepare_dsa_params,
-                                            ossl_prov_dsa_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/*
- * There's no specific print context, so we use the provider context
- */
-static void *dsa_print_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dsa_print_freectx(void *ctx)
-{
-}
-
-static int dsa_priv_print_data(void *vctx, const OSSL_PARAM params[],
-                               OSSL_CORE_BIO *out,
-                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct dsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        if ((dsa = dsa_new(ctx->provctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && dsa_priv_print(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_priv_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dsa(out, dsa, dsa_print_priv);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dsa_priv_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))dsa_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dsa_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_priv_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_priv_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_priv_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))dsa_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))dsa_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pem_priv_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pem_priv },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_priv_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_print_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_print_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_priv_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dsa_priv_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_dsa_pub.c b/providers/implementations/encode_decode/encoder_dsa_pub.c
deleted file mode 100644
index e1201634b9..0000000000
--- a/providers/implementations/encode_decode/encoder_dsa_pub.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * DSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/dsa.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define DSA_SELECT_PUBLIC_IMPORTABLE                                           \
-    (OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
-
-static OSSL_FUNC_encoder_newctx_fn dsa_pub_newctx;
-static OSSL_FUNC_encoder_freectx_fn dsa_pub_freectx;
-static OSSL_FUNC_encoder_encode_data_fn dsa_pub_der_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_pub_der;
-static OSSL_FUNC_encoder_encode_data_fn dsa_pub_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_pub_pem;
-static OSSL_FUNC_encoder_encode_data_fn dsa_pub_print_data;
-static OSSL_FUNC_encoder_encode_object_fn dsa_pub_print;
-
-/* Public key : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *dsa_pub_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void dsa_pub_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int dsa_pub_der_data(void *ctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && dsa_pub_der(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_pub_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    /*
-     * TODO(v3.0) implement setting save_parameters, see dsa_pub_encode()
-     * in crypto/dsa/dsa_ameth.c
-     */
-    int save_parameters = 1;
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret =
-        save_parameters
-        ? ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA,
-                                           ossl_prov_prepare_all_dsa_params,
-                                           ossl_prov_dsa_pub_to_der)
-        : ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA,
-                                           ossl_prov_prepare_dsa_params,
-                                           ossl_prov_dsa_pub_to_der);
-
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int dsa_pub_pem_data(void *ctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && dsa_pub_pem(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_pub_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_pem_from_obj(out, dsa, EVP_PKEY_DSA,
-                                           ossl_prov_prepare_dsa_params,
-                                           ossl_prov_dsa_pub_to_der);
-
-    BIO_free(out);
-
-    return ret;
-}
-
-static int dsa_pub_print_data(void *ctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
-    OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
-    OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
-    int ok = 0;
-
-    if (dsa_import != NULL) {
-        DSA *dsa;
-
-        /* ctx == provctx */
-        if ((dsa = dsa_new(ctx)) != NULL
-            && dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && dsa_pub_print(ctx, dsa, out, cb, cbarg))
-            ok = 1;
-        dsa_free(dsa);
-    }
-    return ok;
-}
-
-static int dsa_pub_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_dsa(out, dsa, dsa_print_pub);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH dsa_pub_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pub_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_pub_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pub_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH dsa_pub_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))dsa_pub_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_ec.c b/providers/implementations/encode_decode/encoder_ec.c
deleted file mode 100644
index ab8e82eb6e..0000000000
--- a/providers/implementations/encode_decode/encoder_ec.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/err.h>
-#include "crypto/ec.h"
-#include "prov/bio.h"             /* ossl_prov_bio_printf() */
-#include "prov/implementations.h" /* ec_keymgmt_functions */
-#include "prov/providercommonerr.h" /* PROV_R_MISSING_OID */
-#include "encoder_local.h"
-
-void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
-                            OSSL_FUNC_keymgmt_free_fn **ec_free,
-                            OSSL_FUNC_keymgmt_import_fn **ec_import)
-{
-    *ec_new = ossl_prov_get_keymgmt_new(ec_keymgmt_functions);
-    *ec_free = ossl_prov_get_keymgmt_free(ec_keymgmt_functions);
-    *ec_import = ossl_prov_get_keymgmt_import(ec_keymgmt_functions);
-}
-
-static int ossl_prov_print_ec_param_explicit_curve(BIO *out,
-                                                   const EC_GROUP *group,
-                                                   BN_CTX *ctx)
-{
-    const char *plabel = "Prime:";
-    BIGNUM *p = NULL, *a = NULL, *b = NULL;
-
-    p = BN_CTX_get(ctx);
-    a = BN_CTX_get(ctx);
-    b = BN_CTX_get(ctx);
-    if (b == NULL
-        || !EC_GROUP_get_curve(group, p, a, b, ctx))
-        return 0;
-
-    if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
-        int basis_type = EC_GROUP_get_basis_type(group);
-
-        /* print the 'short name' of the base type OID */
-        if (basis_type == NID_undef
-            || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
-            return 0;
-        plabel = "Polynomial:";
-    }
-    return ossl_prov_print_labeled_bignum(out, plabel, p)
-           && ossl_prov_print_labeled_bignum(out, "A:   ", a)
-           && ossl_prov_print_labeled_bignum(out, "B:   ", b);
-}
-
-static int ossl_prov_print_ec_param_explicit_gen(BIO *out,
-                                                 const EC_GROUP *group,
-                                                 BN_CTX *ctx)
-{
-    const EC_POINT *point = NULL;
-    BIGNUM *gen = NULL;
-    const char *glabel = NULL;
-    point_conversion_form_t form;
-
-    form = EC_GROUP_get_point_conversion_form(group);
-    point = EC_GROUP_get0_generator(group);
-    gen = BN_CTX_get(ctx);
-
-    if (gen == NULL
-        || point == NULL
-        || EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
-        return 0;
-
-    switch (form) {
-    case POINT_CONVERSION_COMPRESSED:
-       glabel = "Generator (compressed):";
-       break;
-    case POINT_CONVERSION_UNCOMPRESSED:
-        glabel = "Generator (uncompressed):";
-        break;
-    case POINT_CONVERSION_HYBRID:
-        glabel = "Generator (hybrid):";
-        break;
-    default:
-        return 0;
-    }
-    return ossl_prov_print_labeled_bignum(out, glabel, gen);
-}
-
-/* Print explicit parameters */
-static int ossl_prov_print_ec_param_explicit(BIO *out, const EC_GROUP *group,
-                                             OPENSSL_CTX *libctx)
-{
-    int ret = 0, tmp_nid;
-    BN_CTX *ctx = NULL;
-    const BIGNUM *order = NULL, *cofactor = NULL;
-    const unsigned char *seed;
-    size_t seed_len = 0;
-
-    ctx = BN_CTX_new_ex(libctx);
-    if (ctx == NULL)
-        return 0;
-    BN_CTX_start(ctx);
-
-    tmp_nid = EC_GROUP_get_field_type(group);
-    order = EC_GROUP_get0_order(group);
-    if (order == NULL)
-        goto err;
-
-    seed = EC_GROUP_get0_seed(group);
-    if (seed != NULL)
-        seed_len = EC_GROUP_get_seed_len(group);
-    cofactor = EC_GROUP_get0_cofactor(group);
-
-    /* print the 'short name' of the field type */
-    if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
-        || !ossl_prov_print_ec_param_explicit_curve(out, group, ctx)
-        || !ossl_prov_print_ec_param_explicit_gen(out, group, ctx)
-        || !ossl_prov_print_labeled_bignum(out, "Order: ", order)
-        || (cofactor != NULL
-            && !ossl_prov_print_labeled_bignum(out, "Cofactor: ", cofactor))
-        || (seed != NULL
-            && !ossl_prov_print_labeled_buf(out, "Seed:", seed, seed_len)))
-        goto err;
-    ret = 1;
-err:
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    return ret;
-}
-
-static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group,
-                                    OPENSSL_CTX *libctx)
-{
-    if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
-        const char *curve_name;
-        int curve_nid = EC_GROUP_get_curve_name(group);
-
-        /* Explicit parameters */
-        if (curve_nid == NID_undef)
-            return 0;
-
-        if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
-            return 0;
-
-        /* TODO(3.0): Only named curves are currently supported */
-        curve_name = EC_curve_nid2nist(curve_nid);
-        return (curve_name == NULL
-                || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
-    } else {
-        return ossl_prov_print_ec_param_explicit(out, group, libctx);
-    }
-}
-
-int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
-{
-    int ret = 0;
-    const char *type_label = NULL;
-    unsigned char *priv = NULL, *pub = NULL;
-    size_t priv_len = 0, pub_len = 0;
-    const EC_GROUP *group;
-
-    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
-        goto null_err;
-
-    switch (type) {
-    case ec_print_priv:
-        type_label = "Private-Key";
-        break;
-    case ec_print_pub:
-        type_label = "Public-Key";
-        break;
-    case ec_print_params:
-        type_label = "EC-Parameters";
-        break;
-    }
-
-    if (type == ec_print_priv) {
-        const BIGNUM *priv_key = EC_KEY_get0_private_key(eckey);
-
-        if (priv_key == NULL)
-            goto null_err;
-        priv_len = EC_KEY_priv2buf(eckey, &priv);
-        if (priv_len == 0)
-            goto err;
-    }
-
-    if (type == ec_print_priv || type == ec_print_pub) {
-        const EC_POINT *pub_pt = EC_KEY_get0_public_key(eckey);
-
-        if (pub_pt == NULL)
-            goto null_err;
-
-        pub_len = EC_KEY_key2buf(eckey, EC_KEY_get_conv_form(eckey), &pub, NULL);
-        if (pub_len == 0)
-            goto err;
-    }
-
-    if (BIO_printf(out, "%s: (%d bit)\n", type_label,
-                   EC_GROUP_order_bits(group)) <= 0)
-        goto err;
-    if (priv != NULL
-        && !ossl_prov_print_labeled_buf(out, "priv:", priv, priv_len))
-        goto err;
-    if (pub != NULL
-        && !ossl_prov_print_labeled_buf(out, "pub:", pub, pub_len))
-        goto err;
-    ret = ossl_prov_print_ec_param(out, group, ec_key_get_libctx(eckey));
-err:
-    OPENSSL_clear_free(priv, priv_len);
-    OPENSSL_free(pub);
-    return ret;
-null_err:
-    ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-    goto err;
-}
-
-static int ossl_prov_prepare_ec_explicit_params(const void *eckey,
-                                                void **pstr, int *pstrtype)
-{
-    ASN1_STRING *params = ASN1_STRING_new();
-
-    if (params == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    params->length = i2d_ECParameters(eckey, &params->data);
-    if (params->length <= 0) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        ASN1_STRING_free(params);
-        return 0;
-    }
-
-    *pstrtype = V_ASN1_SEQUENCE;
-    *pstr = params;
-    return 1;
-}
-
-int ossl_prov_prepare_ec_params(const void *eckey, int nid,
-                                void **pstr, int *pstrtype)
-{
-    int curve_nid;
-    const EC_GROUP *group = EC_KEY_get0_group(eckey);
-    ASN1_OBJECT *params = NULL;
-
-    if (group == NULL)
-        return 0;
-    curve_nid = EC_GROUP_get_curve_name(group);
-    if (curve_nid != NID_undef) {
-        params = OBJ_nid2obj(curve_nid);
-        if (params == NULL)
-            return 0;
-    }
-
-    if (curve_nid != NID_undef
-        && (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
-        if (OBJ_length(params) == 0) {
-            /* Some curves might not have an associated OID */
-            ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
-            ASN1_OBJECT_free(params);
-            return 0;
-        }
-        *pstr = params;
-        *pstrtype = V_ASN1_OBJECT;
-        return 1;
-    } else {
-        return ossl_prov_prepare_ec_explicit_params(eckey, pstr, pstrtype);
-    }
-}
-
-int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder)
-{
-    return i2o_ECPublicKey(eckey, pder);
-}
-
-int ossl_prov_ec_priv_to_der(const void *veckey, unsigned char **pder)
-{
-    EC_KEY *eckey = (EC_KEY *)veckey;
-    unsigned int old_flags;
-    int ret = 0;
-
-    /*
-     * For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object
-     * as the pkeyalg->parameter field. (For a named curve this is an OID)
-     * The pkey field is an octet string that holds the encoded
-     * ECPrivateKey SEQUENCE with the optional parameters field omitted.
-     * We omit this by setting the EC_PKEY_NO_PARAMETERS flag.
-     */
-    old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */
-    EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS);
-    ret = i2d_ECPrivateKey(eckey, pder);
-    EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */
-    return ret; /* return the length of the der encoded data */
-}
diff --git a/providers/implementations/encode_decode/encoder_ec_param.c b/providers/implementations/encode_decode/encoder_ec_param.c
deleted file mode 100644
index 2f6637d80e..0000000000
--- a/providers/implementations/encode_decode/encoder_ec_param.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/pem.h>
-#include <openssl/ec.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn ec_param_newctx;
-static OSSL_FUNC_encoder_freectx_fn ec_param_freectx;
-static OSSL_FUNC_encoder_encode_data_fn ec_param_der_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_param_der;
-static OSSL_FUNC_encoder_encode_data_fn ec_param_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_param_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn ec_param_print_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_param_print;
-
-
-/* There is no specific implementation context, so use the provider context */
-static void *ec_param_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void ec_param_freectx(void *vctx)
-{
-}
-
-/* Public key : DER */
-static int ec_param_der_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* vctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
-            && ec_param_der(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_param_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(vctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* vctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
-            && ec_param_pem(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_param_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(vctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
-    BIO_free(out);
-
-    return ret;
-}
-
-static int ec_param_print_data(void *vctx, const OSSL_PARAM params[],
-                               OSSL_CORE_BIO *out,
-                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* vctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
-            && ec_param_print(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(vctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_eckey(out, eckey, ec_print_params);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH ec_param_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_param_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_param_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_param_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_param_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))ec_param_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_ec_priv.c b/providers/implementations/encode_decode/encoder_ec_priv.c
deleted file mode 100644
index ea8a1ba92b..0000000000
--- a/providers/implementations/encode_decode/encoder_ec_priv.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ec.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn ec_priv_newctx;
-static OSSL_FUNC_encoder_freectx_fn ec_priv_freectx;
-static OSSL_FUNC_encoder_set_ctx_params_fn ec_priv_set_ctx_params;
-static OSSL_FUNC_encoder_settable_ctx_params_fn ec_priv_settable_ctx_params;
-static OSSL_FUNC_encoder_encode_data_fn ec_priv_der_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_priv_der;
-static OSSL_FUNC_encoder_encode_data_fn ec_pem_priv_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_pem_priv;
-
-static OSSL_FUNC_encoder_newctx_fn ec_print_newctx;
-static OSSL_FUNC_encoder_freectx_fn ec_print_freectx;
-static OSSL_FUNC_encoder_encode_data_fn ec_priv_print_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_priv_print;
-
-/*
- * Context used for private key encoding.
- */
-struct ec_priv_ctx_st {
-    void *provctx;
-
-    struct pkcs8_encrypt_ctx_st sc;
-};
-
-/* Private key : context */
-static void *ec_priv_newctx(void *provctx)
-{
-    struct ec_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-    }
-    return ctx;
-}
-
-static void ec_priv_freectx(void *vctx)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_free(ctx->sc.cipher_pass);
-    OPENSSL_free(ctx);
-}
-
-static const OSSL_PARAM *ec_priv_settable_ctx_params(ossl_unused void *provctx)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int ec_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
-        != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
-        const char *props = NULL;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
-                == NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_free(ctx->sc.cipher_pass);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
-/* Private key : DER */
-static int ec_priv_der_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        if ((eckey = ec_new(ctx->provctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
-            && ec_priv_der(ctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_priv_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_der_from_obj(out, eckey, EVP_PKEY_EC,
-                                            ossl_prov_prepare_ec_params,
-                                            ossl_prov_ec_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Private key : PEM */
-static int ec_pem_priv_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        if ((eckey = ec_new(ctx->provctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
-            && ec_pem_priv(ctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_pem_priv(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_pem_from_obj(out, eckey, EVP_PKEY_EC,
-                                            ossl_prov_prepare_ec_params,
-                                            ossl_prov_ec_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/*
- * There's no specific print context, so we use the provider context
- */
-static void *ec_print_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void ec_print_freectx(void *ctx)
-{
-}
-
-static int ec_priv_print_data(void *vctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ec_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        if ((eckey = ec_new(ctx->provctx)) != NULL
-            && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
-            && ec_priv_print(ctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_priv_print(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_eckey(out, eckey, ec_print_priv);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH ec_priv_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))ec_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))ec_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_priv_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_priv_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_priv_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))ec_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))ec_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pem_priv_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pem_priv },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_priv_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_print_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_print_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_priv_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))ec_priv_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_ec_pub.c b/providers/implementations/encode_decode/encoder_ec_pub.c
deleted file mode 100644
index 9ab121f7d2..0000000000
--- a/providers/implementations/encode_decode/encoder_ec_pub.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define EC_SELECT_PUBLIC_IMPORTABLE                                            \
-    OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
-
-static OSSL_FUNC_encoder_newctx_fn ec_pub_newctx;
-static OSSL_FUNC_encoder_freectx_fn ec_pub_freectx;
-static OSSL_FUNC_encoder_encode_data_fn ec_pub_der_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_pub_der;
-static OSSL_FUNC_encoder_encode_data_fn ec_pub_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_pub_pem;
-static OSSL_FUNC_encoder_encode_data_fn ec_pub_print_data;
-static OSSL_FUNC_encoder_encode_object_fn ec_pub_print;
-
-/* Public key : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *ec_pub_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void ec_pub_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int ec_pub_der_data(void *vctx, const OSSL_PARAM params[],
-                           OSSL_CORE_BIO *out,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* vctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
-            && ec_pub_der(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_pub_der(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
-                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_der_from_obj(out, eckey, EVP_PKEY_EC,
-                                           ossl_prov_prepare_ec_params,
-                                           ossl_prov_ec_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int ec_pub_pem_data(void *vctx, const OSSL_PARAM params[],
-                           OSSL_CORE_BIO *out,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* ctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
-            && ec_pub_pem(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_pub_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(vctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_pem_from_obj(out, eckey, EVP_PKEY_EC,
-                                           ossl_prov_prepare_ec_params,
-                                           ossl_prov_ec_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int ec_pub_print_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *ec_new;
-    OSSL_FUNC_keymgmt_free_fn *ec_free;
-    OSSL_FUNC_keymgmt_import_fn *ec_import;
-    int ok = 0;
-
-    ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
-
-    if (ec_import != NULL) {
-        EC_KEY *eckey;
-
-        /* ctx == provctx */
-        if ((eckey = ec_new(vctx)) != NULL
-            && ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
-            && ec_pub_print(vctx, eckey, out, cb, cbarg))
-            ok = 1;
-        ec_free(eckey);
-    }
-    return ok;
-}
-
-static int ec_pub_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(vctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_eckey(out, eckey, ec_print_pub);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH ec_pub_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pub_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_pub_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pub_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH ec_pub_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))ec_pub_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_ecx.c b/providers/implementations/encode_decode/encoder_ecx.c
deleted file mode 100644
index 83de9fe002..0000000000
--- a/providers/implementations/encode_decode/encoder_ecx.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/err.h>
-#include "crypto/ecx.h"
-#include "prov/bio.h"             /* ossl_prov_bio_printf() */
-#include "prov/implementations.h" /* ecx_keymgmt_functions */
-#include "encoder_local.h"
-
-void ecx_get_new_free_import(ECX_KEY_TYPE type,
-                             OSSL_FUNC_keymgmt_new_fn **ecx_new,
-                             OSSL_FUNC_keymgmt_free_fn **ecx_free,
-                             OSSL_FUNC_keymgmt_import_fn **ecx_import)
-{
-    if (type == ECX_KEY_TYPE_X25519) {
-        *ecx_new = ossl_prov_get_keymgmt_new(x25519_keymgmt_functions);
-        *ecx_free = ossl_prov_get_keymgmt_free(x25519_keymgmt_functions);
-        *ecx_import = ossl_prov_get_keymgmt_import(x25519_keymgmt_functions);
-    } else if (type == ECX_KEY_TYPE_X448) {
-        *ecx_new = ossl_prov_get_keymgmt_new(x448_keymgmt_functions);
-        *ecx_free = ossl_prov_get_keymgmt_free(x448_keymgmt_functions);
-        *ecx_import = ossl_prov_get_keymgmt_import(x448_keymgmt_functions);
-    } else if (type == ECX_KEY_TYPE_ED25519) {
-        *ecx_new = ossl_prov_get_keymgmt_new(ed25519_keymgmt_functions);
-        *ecx_free = ossl_prov_get_keymgmt_free(ed25519_keymgmt_functions);
-        *ecx_import = ossl_prov_get_keymgmt_import(ed25519_keymgmt_functions);
-    } else if (type == ECX_KEY_TYPE_ED448) {
-        *ecx_new = ossl_prov_get_keymgmt_new(ed448_keymgmt_functions);
-        *ecx_free = ossl_prov_get_keymgmt_free(ed448_keymgmt_functions);
-        *ecx_import = ossl_prov_get_keymgmt_import(ed448_keymgmt_functions);
-    } else {
-        *ecx_new = NULL;
-        *ecx_free = NULL;
-        *ecx_import = NULL;
-    }
-}
-
-
-int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type)
-{
-    const char *type_label = NULL;
-
-    switch (type) {
-    case ecx_print_priv:
-        switch (ecxkey->type) {
-        case ECX_KEY_TYPE_X25519:
-            type_label = "X25519 Private-Key";
-            break;
-        case ECX_KEY_TYPE_X448:
-            type_label = "X448 Private-Key";
-            break;
-        case ECX_KEY_TYPE_ED25519:
-            type_label = "ED25519 Private-Key";
-            break;
-        case ECX_KEY_TYPE_ED448:
-            type_label = "ED448 Private-Key";
-            break;
-        }
-        break;
-    case ecx_print_pub:
-        switch (ecxkey->type) {
-        case ECX_KEY_TYPE_X25519:
-            type_label = "X25519 Public-Key";
-            break;
-        case ECX_KEY_TYPE_X448:
-            type_label = "X448 Public-Key";
-            break;
-        case ECX_KEY_TYPE_ED25519:
-            type_label = "ED25519 Public-Key";
-            break;
-        case ECX_KEY_TYPE_ED448:
-            type_label = "ED448 Public-Key";
-            break;
-        }
-        break;
-    }
-
-    if (type == ecx_print_priv && ecxkey->privkey == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    if (BIO_printf(out, "%s:\n", type_label) <= 0)
-        return 0;
-    if (type == ecx_print_priv
-            && !ossl_prov_print_labeled_buf(out, "priv:", ecxkey->privkey,
-                                            ecxkey->keylen))
-        return 0;
-    if (!ossl_prov_print_labeled_buf(out, "pub:", ecxkey->pubkey,
-                                     ecxkey->keylen))
-        return 0;
-
-    return 1;
-}
-
-
-int ossl_prov_ecx_pub_to_der(const void *vecxkey, unsigned char **pder)
-{
-    const ECX_KEY *ecxkey = vecxkey;
-    unsigned char *keyblob;
-
-    if (ecxkey == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen);
-    if (keyblob == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    *pder = keyblob;
-    return ecxkey->keylen;
-}
-
-int ossl_prov_ecx_priv_to_der(const void *vecxkey, unsigned char **pder)
-{
-    const ECX_KEY *ecxkey = vecxkey;
-    ASN1_OCTET_STRING oct;
-    int keybloblen;
-
-    if (ecxkey == NULL || ecxkey->privkey == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    oct.data = ecxkey->privkey;
-    oct.length = ecxkey->keylen;
-    oct.flags = 0;
-
-    keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder);
-    if (keybloblen < 0) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    return keybloblen;
-}
diff --git a/providers/implementations/encode_decode/encoder_ecx_priv.c b/providers/implementations/encode_decode/encoder_ecx_priv.c
deleted file mode 100644
index cd0190aa7c..0000000000
--- a/providers/implementations/encode_decode/encoder_ecx_priv.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "crypto/ecx.h"
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn x25519_priv_newctx;
-static OSSL_FUNC_encoder_newctx_fn x448_priv_newctx;
-static OSSL_FUNC_encoder_newctx_fn ed25519_priv_newctx;
-static OSSL_FUNC_encoder_newctx_fn ed448_priv_newctx;
-static OSSL_FUNC_encoder_freectx_fn ecx_priv_freectx;
-static OSSL_FUNC_encoder_set_ctx_params_fn ecx_priv_set_ctx_params;
-static OSSL_FUNC_encoder_settable_ctx_params_fn ecx_priv_settable_ctx_params;
-static OSSL_FUNC_encoder_encode_data_fn ecx_priv_der_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_priv_der;
-static OSSL_FUNC_encoder_encode_data_fn ecx_priv_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_priv_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn ecx_priv_print_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_priv_print;
-
-/*
- * Context used for private key encoding.
- */
-struct ecx_priv_ctx_st {
-    void *provctx;
-
-    struct pkcs8_encrypt_ctx_st sc;
-    ECX_KEY_TYPE type;
-};
-
-/* Private key : context */
-static void *ecx_priv_newctx(void *provctx, ECX_KEY_TYPE type)
-{
-    struct ecx_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-        ctx->type = type;
-    }
-    return ctx;
-}
-
-static void *x25519_priv_newctx(void *provctx)
-{
-    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X25519);
-}
-
-static void *x448_priv_newctx(void *provctx)
-{
-    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X448);
-}
-
-static void *ed25519_priv_newctx(void *provctx)
-{
-    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED25519);
-}
-
-static void *ed448_priv_newctx(void *provctx)
-{
-    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED448);
-}
-
-static void ecx_priv_freectx(void *vctx)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_free(ctx->sc.cipher_pass);
-    OPENSSL_free(ctx);
-}
-
-static const OSSL_PARAM *ecx_priv_settable_ctx_params(ossl_unused void *provctx)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int ecx_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
-    if (p != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
-        const char *props;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
-                == NULL))
-            return 0;
-    }
-    p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS);
-    if (p != NULL) {
-        OPENSSL_free(ctx->sc.cipher_pass);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
-/* Private key : DER */
-static int ecx_priv_der_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx->provctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
-            && ecx_priv_der(ctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_priv_der(void *vctx, void *vecxkey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    ECX_KEY *ecxkey = vecxkey;
-    int ret;
-    int nid = KEYTYPE2NID(ctx->type);
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_der_from_obj(out, ecxkey,
-                                            nid,
-                                            NULL,
-                                            ossl_prov_ecx_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Private key : PEM */
-static int ecx_priv_pem_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx->provctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
-            && ecx_priv_pem(ctx->provctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_priv_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    int ret;
-    int nid = KEYTYPE2NID(ctx->type);
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_pem_from_obj(out, ecxkey,
-                                            nid,
-                                            NULL,
-                                            ossl_prov_ecx_priv_to_der,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int ecx_priv_print_data(void *vctx, const OSSL_PARAM params[],
-                               OSSL_CORE_BIO *out,
-                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx->provctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
-            && ecx_priv_print(ctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_priv_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_priv_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_priv);
-    BIO_free(out);
-
-    return ret;
-}
-
-#define MAKE_ENCODER_FUNCTIONS(alg, type)                               \
-    const OSSL_DISPATCH alg##_priv_##type##_encoder_functions[] = {     \
-        { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
-        { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
-        { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,                             \
-          (void (*)(void))ecx_priv_set_ctx_params },                    \
-        { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,                        \
-          (void (*)(void))ecx_priv_settable_ctx_params },               \
-        { OSSL_FUNC_ENCODER_ENCODE_DATA,                                \
-          (void (*)(void))ecx_priv_##type##_data },                     \
-        { OSSL_FUNC_ENCODER_ENCODE_OBJECT,                              \
-          (void (*)(void))ecx_priv_##type },                            \
-        { 0, NULL }                                                     \
-    };
-
-#define MAKE_ENCODER_FUNCTIONS_GROUP(alg)                               \
-    MAKE_ENCODER_FUNCTIONS(alg, der)                                    \
-        MAKE_ENCODER_FUNCTIONS(alg, pem)                                \
-        const OSSL_DISPATCH alg##_priv_print_encoder_functions[] = {    \
-        { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
-        { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
-        { OSSL_FUNC_ENCODER_ENCODE_OBJECT,                              \
-          (void (*)(void))ecx_priv_print },                             \
-        { OSSL_FUNC_ENCODER_ENCODE_DATA,                                \
-          (void (*)(void))ecx_priv_print_data },                        \
-        { 0, NULL }                                                     \
-    };
-
-MAKE_ENCODER_FUNCTIONS_GROUP(x25519)
-MAKE_ENCODER_FUNCTIONS_GROUP(x448)
-MAKE_ENCODER_FUNCTIONS_GROUP(ed25519)
-MAKE_ENCODER_FUNCTIONS_GROUP(ed448)
diff --git a/providers/implementations/encode_decode/encoder_ecx_pub.c b/providers/implementations/encode_decode/encoder_ecx_pub.c
deleted file mode 100644
index a4350d84cf..0000000000
--- a/providers/implementations/encode_decode/encoder_ecx_pub.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_dispatch.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "crypto/ecx.h"
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-static OSSL_FUNC_encoder_newctx_fn x25519_pub_newctx;
-static OSSL_FUNC_encoder_newctx_fn x448_pub_newctx;
-static OSSL_FUNC_encoder_newctx_fn ed25519_pub_newctx;
-static OSSL_FUNC_encoder_newctx_fn ed448_pub_newctx;
-static OSSL_FUNC_encoder_freectx_fn ecx_pub_freectx;
-static OSSL_FUNC_encoder_encode_data_fn ecx_pub_der_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_pub_der;
-static OSSL_FUNC_encoder_encode_data_fn ecx_pub_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_pub_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn ecx_pub_print_data;
-static OSSL_FUNC_encoder_encode_object_fn ecx_pub_print;
-
-/*
- * Context used for public key encoding.
- */
-struct ecx_pub_ctx_st {
-    void *provctx;
-    ECX_KEY_TYPE type;
-};
-
-/* Public key : context */
-static void *ecx_pub_newctx(void *provctx, ECX_KEY_TYPE type)
-{
-    struct ecx_pub_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-        ctx->type = type;
-    }
-    return ctx;
-}
-
-static void *x25519_pub_newctx(void *provctx)
-{
-    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X25519);
-}
-
-static void *x448_pub_newctx(void *provctx)
-{
-    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X448);
-}
-
-static void *ed25519_pub_newctx(void *provctx)
-{
-    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED25519);
-}
-
-static void *ed448_pub_newctx(void *provctx)
-{
-    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED448);
-}
-
-static void ecx_pub_freectx(void *ctx)
-{
-    OPENSSL_free(ctx);
-}
-
-/* Public key : DER */
-static int ecx_pub_der_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx->provctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
-            && ecx_pub_der(ctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_pub_der(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_der_from_obj(out, ecxkey,
-                                           KEYTYPE2NID(ctx->type),
-                                           NULL,
-                                           ossl_prov_ecx_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int ecx_pub_pem_data(void *vctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx->provctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
-            && ecx_pub_pem(ctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_pub_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_pem_from_obj(out, ecxkey,
-                                           KEYTYPE2NID(ctx->type),
-                                           NULL,
-                                           ossl_prov_ecx_pub_to_der);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int ecx_pub_print_data(void *vctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *ecx_new;
-    OSSL_FUNC_keymgmt_free_fn *ecx_free;
-    OSSL_FUNC_keymgmt_import_fn *ecx_import;
-    int ok = 0;
-
-    ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
-
-    if (ecx_import != NULL) {
-        ECX_KEY *ecxkey;
-
-        if ((ecxkey = ecx_new(ctx)) != NULL
-            && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
-            && ecx_pub_print(ctx, ecxkey, out, cb, cbarg))
-            ok = 1;
-        ecx_free(ecxkey);
-    }
-    return ok;
-}
-
-static int ecx_pub_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct ecx_pub_ctx_st *ctx = vctx;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_pub);
-    BIO_free(out);
-
-    return ret;
-}
-
-#define MAKE_ENCODER_FUNCTIONS(alg, type)                               \
-    const OSSL_DISPATCH alg##_pub_##type##_encoder_functions[] = {      \
-        { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_pub_newctx }, \
-        { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_pub_freectx }, \
-        { OSSL_FUNC_ENCODER_ENCODE_DATA,                                \
-          (void (*)(void))ecx_pub_##type##_data },                      \
-        { OSSL_FUNC_ENCODER_ENCODE_OBJECT,                              \
-          (void (*)(void))ecx_pub_##type },                             \
-        { 0, NULL }                                                     \
-    };
-
-#define MAKE_ENCODER_FUNCTIONS_GROUP(alg)       \
-    MAKE_ENCODER_FUNCTIONS(alg, der)            \
-        MAKE_ENCODER_FUNCTIONS(alg, pem)        \
-        MAKE_ENCODER_FUNCTIONS(alg, print)
-
-MAKE_ENCODER_FUNCTIONS_GROUP(x25519)
-MAKE_ENCODER_FUNCTIONS_GROUP(x448)
-MAKE_ENCODER_FUNCTIONS_GROUP(ed25519)
-MAKE_ENCODER_FUNCTIONS_GROUP(ed448)
diff --git a/providers/implementations/encode_decode/encoder_ffc_params.c b/providers/implementations/encode_decode/encoder_ffc_params.c
deleted file mode 100644
index 67ec50c9b8..0000000000
--- a/providers/implementations/encode_decode/encoder_ffc_params.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/* Utility function for printing DSA/DH params. */
-
-#include "prov/bio.h"
-#include "encoder_local.h"
-
-int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc)
-{
-    if (ffc->nid != NID_undef) {
-#ifndef OPENSSL_NO_DH
-        const char *name = ffc_named_group_from_uid(ffc->nid);
-
-        if (name == NULL)
-            goto err;
-        if (BIO_printf(out, "GROUP: %s\n", name) <= 0)
-            goto err;
-        return 1;
-#else
-        /* How could this be? We should not have a nid in a no-dh build. */
-        goto err;
-#endif
-    }
-
-    if (!ossl_prov_print_labeled_bignum(out, "P:   ", ffc->p))
-        goto err;
-    if (ffc->q != NULL) {
-        if (!ossl_prov_print_labeled_bignum(out, "Q:   ", ffc->q))
-            goto err;
-    }
-    if (!ossl_prov_print_labeled_bignum(out, "G:   ", ffc->g))
-        goto err;
-    if (ffc->j != NULL) {
-        if (!ossl_prov_print_labeled_bignum(out, "J:   ", ffc->j))
-            goto err;
-    }
-    if (ffc->seed != NULL) {
-        if (!ossl_prov_print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen))
-            goto err;
-    }
-    if (ffc->gindex != -1) {
-        if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0)
-            goto err;
-    }
-    if (ffc->pcounter != -1) {
-        if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0)
-            goto err;
-    }
-    if (ffc->h != 0) {
-        if (BIO_printf(out, "h: %d\n", ffc->h) <= 0)
-            goto err;
-    }
-    return 1;
-err:
-    return 0;
-}
diff --git a/providers/implementations/encode_decode/encoder_local.h b/providers/implementations/encode_decode/encoder_local.h
deleted file mode 100644
index 7a1f29f7e9..0000000000
--- a/providers/implementations/encode_decode/encoder_local.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core.h>
-#include <openssl/core_dispatch.h>
-#include <openssl/bn.h>
-#include <openssl/asn1.h>        /* i2d_of_void */
-#include <openssl/x509.h>        /* X509_SIG */
-#include <openssl/types.h>
-#include <crypto/ecx.h>
-#include "internal/ffc.h"
-
-struct pkcs8_encrypt_ctx_st {
-    /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
-    int cipher_intent;
-
-    EVP_CIPHER *cipher;
-    int pbe_nid;                 /* For future variation */
-
-    /* Passphrase that was passed by the caller */
-    void *cipher_pass;
-    size_t cipher_pass_length;
-
-    /* This callback is only used of |cipher_pass| is NULL */
-    OSSL_PASSPHRASE_CALLBACK *cb;
-    void *cbarg;
-};
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void);
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void);
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void);
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void);
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void);
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void);
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void);
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void);
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void);
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void);
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void);
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void);
-
-void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
-                            OSSL_FUNC_keymgmt_free_fn **ec_free,
-                            OSSL_FUNC_keymgmt_import_fn **ec_import);
-
-int ossl_prov_prepare_ec_params(const void *eckey, int nid,
-                                void **pstr, int *pstrtype);
-int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder);
-int ossl_prov_ec_priv_to_der(const void *eckey, unsigned char **pder);
-
-int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc);
-int ossl_prov_prepare_dh_params(const void *dh, int nid,
-                                void **pstr, int *pstrtype);
-int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder);
-int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder);
-int ossl_prov_dh_type_to_evp(const DH *dh);
-
-#ifndef OPENSSL_NO_EC
-void ecx_get_new_free_import(ECX_KEY_TYPE type,
-                             OSSL_FUNC_keymgmt_new_fn **ecx_new,
-                             OSSL_FUNC_keymgmt_free_fn **ecx_free,
-                             OSSL_FUNC_keymgmt_import_fn **ecx_import);
-int ossl_prov_ecx_pub_to_der(const void *ecxkey, unsigned char **pder);
-int ossl_prov_ecx_priv_to_der(const void *ecxkey, unsigned char **pder);
-#endif
-
-int ossl_prov_prepare_dsa_params(const void *dsa, int nid,
-                                void **pstr, int *pstrtype);
-/*
- * Special variant of ossl_prov_prepare_dsa_params() that requires all
- * three parameters (P, Q and G) to be set.  This is used when encoding
- * the public key.
- */
-int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid,
-                                     void **pstr, int *pstrtype);
-int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder);
-int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder);
-
-/*
- * ossl_prov_prepare_rsa_params() is designed to work with the ossl_prov_write_
- * functions, hence 'void *rsa' rather than 'RSA *rsa'.
- */
-int ossl_prov_prepare_rsa_params(const void *rsa, int nid,
-                                 void **pstr, int *pstrtype);
-int ossl_prov_rsa_type_to_evp(const RSA *rsa);
-
-int ossl_prov_print_labeled_bignum(BIO *out, const char *label,
-                                   const BIGNUM *bn);
-int ossl_prov_print_labeled_buf(BIO *out, const char *label,
-                                const unsigned char *buf, size_t buflen);
-int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv);
-
-enum dh_print_type {
-    dh_print_priv,
-    dh_print_pub,
-    dh_print_params
-};
-
-int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type);
-
-#ifndef OPENSSL_NO_EC
-enum ec_print_type {
-    ec_print_priv,
-    ec_print_pub,
-    ec_print_params
-};
-
-int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type);
-#endif /*  OPENSSL_NO_EC */
-
-enum dsa_print_type {
-    dsa_print_priv,
-    dsa_print_pub,
-    dsa_print_params
-};
-
-int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type);
-
-enum ecx_print_type {
-    ecx_print_priv,
-    ecx_print_pub
-};
-
-#ifndef OPENSSL_NO_EC
-int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type);
-#endif
-
-int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid,
-                                      int (*p2s)(const void *obj, int nid,
-                                                 void **str,
-                                                 int *strtype),
-                                      int (*k2d)(const void *obj,
-                                                 unsigned char **pder),
-                                      struct pkcs8_encrypt_ctx_st *ctx);
-int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid,
-                                      int (*p2s)(const void *obj, int nid,
-                                                 void **str,
-                                                 int *strtype),
-                                      int (*k2d)(const void *obj,
-                                                 unsigned char **pder),
-                                      struct pkcs8_encrypt_ctx_st *ctx);
-int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid,
-                                     int (*p2s)(const void *obj, int nid,
-                                                void **str,
-                                                int *strtype),
-                                     int (*k2d)(const void *obj,
-                                                unsigned char **pder));
-int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid,
-                                     int (*p2s)(const void *obj, int nid,
-                                                void **str,
-                                                int *strtype),
-                                     int (*k2d)(const void *obj,
-                                                unsigned char **pder));
-
-int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                       unsigned char **data, long *len);
-int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                       char **pem_name, char **pem_header,
-                       unsigned char **data, long *len);
-#ifndef OPENSSL_NO_DSA
-EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                                int *ispub);
-# ifndef OPENSSL_NO_RC4
-EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
-                             OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
-# endif
-#endif
-
-int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
-                          unsigned char *input_der, long input_der_len,
-                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
-
diff --git a/providers/implementations/encode_decode/encoder_rsa.c b/providers/implementations/encode_decode/encoder_rsa.c
deleted file mode 100644
index cd9ff3b7dd..0000000000
--- a/providers/implementations/encode_decode/encoder_rsa.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * RSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include "internal/packet.h"
-#include "crypto/rsa.h"           /* rsa_get0_all_params() */
-#include "prov/bio.h"             /* ossl_prov_bio_printf() */
-#include "prov/der_rsa.h"         /* DER_w_RSASSA_PSS_params() */
-#include "prov/implementations.h" /* rsa_keymgmt_functions */
-#include "encoder_local.h"
-
-DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void)
-{
-    return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void)
-{
-    return ossl_prov_get_keymgmt_new(rsapss_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void)
-{
-    return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void)
-{
-    return ossl_prov_get_keymgmt_import(rsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void)
-{
-    return ossl_prov_get_keymgmt_export(rsa_keymgmt_functions);
-}
-
-OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void)
-{
-    return ossl_prov_get_keymgmt_export(rsapss_keymgmt_functions);
-}
-
-int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
-{
-    const char *modulus_label;
-    const char *exponent_label;
-    const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
-    STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null();
-    STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null();
-    STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null();
-    RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa);
-    int ret = 0;
-
-    if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL)
-        goto err;
-
-    RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
-    rsa_get0_all_params(rsa, factors, exps, coeffs);
-
-    if (priv && rsa_d != NULL) {
-        if (BIO_printf(out, "Private-Key: (%d bit, %d primes)\n",
-                       BN_num_bits(rsa_n),
-                       sk_BIGNUM_const_num(factors)) <= 0)
-            goto err;
-        modulus_label = "modulus:";
-        exponent_label = "publicExponent:";
-    } else {
-        if (BIO_printf(out, "Public-Key: (%d bit)\n", BN_num_bits(rsa_n)) <= 0)
-            goto err;
-        modulus_label = "Modulus:";
-        exponent_label = "Exponent:";
-    }
-    if (!ossl_prov_print_labeled_bignum(out, modulus_label, rsa_n))
-        goto err;
-    if (!ossl_prov_print_labeled_bignum(out, exponent_label, rsa_e))
-        goto err;
-    if (priv) {
-        int i;
-
-        if (!ossl_prov_print_labeled_bignum(out, "privateExponent:", rsa_d))
-            goto err;
-        if (!ossl_prov_print_labeled_bignum(out, "prime1:",
-                                            sk_BIGNUM_const_value(factors, 0)))
-            goto err;
-        if (!ossl_prov_print_labeled_bignum(out, "prime2:",
-                                            sk_BIGNUM_const_value(factors, 1)))
-            goto err;
-        if (!ossl_prov_print_labeled_bignum(out, "exponent1:",
-                                            sk_BIGNUM_const_value(exps, 0)))
-            goto err;
-        if (!ossl_prov_print_labeled_bignum(out, "exponent2:",
-                                            sk_BIGNUM_const_value(exps, 1)))
-            goto err;
-        if (!ossl_prov_print_labeled_bignum(out, "coefficient:",
-                                            sk_BIGNUM_const_value(coeffs, 0)))
-            goto err;
-        for (i = 2; i < sk_BIGNUM_const_num(factors); i++) {
-            if (BIO_printf(out, "prime%d:", i + 1) <= 0)
-                goto err;
-            if (!ossl_prov_print_labeled_bignum(out, NULL,
-                                                sk_BIGNUM_const_value(factors,
-                                                                      i)))
-                goto err;
-            if (BIO_printf(out, "exponent%d:", i + 1) <= 0)
-                goto err;
-            if (!ossl_prov_print_labeled_bignum(out, NULL,
-                                                sk_BIGNUM_const_value(exps, i)))
-                goto err;
-            if (BIO_printf(out, "coefficient%d:", i + 1) <= 0)
-                goto err;
-            if (!ossl_prov_print_labeled_bignum(out, NULL,
-                                                sk_BIGNUM_const_value(coeffs,
-                                                                      i - 1)))
-                goto err;
-        }
-    }
-
-    switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
-    case RSA_FLAG_TYPE_RSA:
-        if (!rsa_pss_params_30_is_unrestricted(pss_params)) {
-            if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
-                goto err;
-        }
-        break;
-    case RSA_FLAG_TYPE_RSASSAPSS:
-        if (rsa_pss_params_30_is_unrestricted(pss_params)) {
-            if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
-                goto err;
-        } else {
-            int hashalg_nid = rsa_pss_params_30_hashalg(pss_params);
-            int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params);
-            int maskgenhashalg_nid =
-                rsa_pss_params_30_maskgenhashalg(pss_params);
-            int saltlen = rsa_pss_params_30_saltlen(pss_params);
-            int trailerfield = rsa_pss_params_30_trailerfield(pss_params);
-
-            if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
-                goto err;
-            if (BIO_printf(out, "  Hash Algorithm: %s%s\n",
-                           rsa_oaeppss_nid2name(hashalg_nid),
-                           (hashalg_nid == NID_sha1
-                           ? " (default)" : "")) <= 0)
-                goto err;
-            if (BIO_printf(out, "  Mask Algorithm: %s with %s%s\n",
-                           rsa_mgf_nid2name(maskgenalg_nid),
-                           rsa_oaeppss_nid2name(maskgenhashalg_nid),
-                           (maskgenalg_nid == NID_mgf1
-                            && maskgenhashalg_nid == NID_sha1
-                            ? " (default)" : "")) <= 0)
-                goto err;
-            if (BIO_printf(out, "  Minimum Salt Length: %d%s\n",
-                           saltlen,
-                           (saltlen == 20 ? " (default)" : "")) <= 0)
-                goto err;
-            /*
-             * TODO(3.0) Should we show the ASN.1 trailerField value, or
-             * the actual trailerfield byte (i.e. 0xBC for 1)?
-             * crypto/rsa/rsa_ameth.c isn't very clear on that, as it
-             * does display 0xBC when the default applies, but the ASN.1
-             * trailerField value otherwise...
-             */
-            if (BIO_printf(out, "  Trailer Field: 0x%x%s\n",
-                           trailerfield,
-                           (trailerfield == 1 ? " (default)" : ""))
-                <= 0)
-                goto err;
-        }
-        break;
-    }
-
-    ret = 1;
- err:
-    sk_BIGNUM_const_free(factors);
-    sk_BIGNUM_const_free(exps);
-    sk_BIGNUM_const_free(coeffs);
-    return ret;
-}
-
-/*
- * Helper functions to prepare RSA-PSS params for encoding.  We would
- * have simply written the whole AlgorithmIdentifier, but existing libcrypto
- * functionality doesn't allow that.
- */
-
-int ossl_prov_prepare_rsa_params(const void *rsa, int nid,
-                                 void **pstr, int *pstrtype)
-{
-    const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa);
-
-    *pstr = NULL;
-
-    switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
-    case RSA_FLAG_TYPE_RSA:
-        /* If plain RSA, the parameters shall be NULL */
-        *pstrtype = V_ASN1_NULL;
-        return 1;
-    case RSA_FLAG_TYPE_RSASSAPSS:
-        if (rsa_pss_params_30_is_unrestricted(pss)) {
-            *pstrtype = V_ASN1_UNDEF;
-            return 1;
-        } else {
-            ASN1_STRING *astr = NULL;
-            WPACKET pkt;
-            unsigned char *str = NULL;
-            size_t str_sz = 0;
-            int i;
-
-            for (i = 0; i < 2; i++) {
-                switch (i) {
-                case 0:
-                    if (!WPACKET_init_null_der(&pkt))
-                        goto err;
-                    break;
-                case 1:
-                    if ((str = OPENSSL_malloc(str_sz)) == NULL
-                        || !WPACKET_init_der(&pkt, str, str_sz)) {
-                        goto err;
-                    }
-                    break;
-                }
-                if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss)
-                    || !WPACKET_finish(&pkt)
-                    || !WPACKET_get_total_written(&pkt, &str_sz))
-                    goto err;
-                WPACKET_cleanup(&pkt);
-
-                /*
-                 * If no PSS parameters are going to be written, there's no
-                 * point going for another iteration.
-                 * This saves us from getting |str| allocated just to have it
-                 * immediately de-allocated.
-                 */
-                if (str_sz == 0)
-                    break;
-            }
-
-            if ((astr = ASN1_STRING_new()) == NULL)
-                goto err;
-            *pstrtype = V_ASN1_SEQUENCE;
-            ASN1_STRING_set0(astr, str, (int)str_sz);
-            *pstr = astr;
-
-            return 1;
-         err:
-            OPENSSL_free(str);
-            return 0;
-        }
-    }
-
-    /* Currently unsupported RSA key type */
-    return 0;
-}
-
-int ossl_prov_rsa_type_to_evp(const RSA *rsa)
-{
-    switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
-    case RSA_FLAG_TYPE_RSA:
-        return EVP_PKEY_RSA;
-    case RSA_FLAG_TYPE_RSASSAPSS:
-        return EVP_PKEY_RSA_PSS;
-    }
-
-    /* Currently unsupported RSA key type */
-    return EVP_PKEY_NONE;
-}
diff --git a/providers/implementations/encode_decode/encoder_rsa_priv.c b/providers/implementations/encode_decode/encoder_rsa_priv.c
deleted file mode 100644
index 7be37dd49a..0000000000
--- a/providers/implementations/encode_decode/encoder_rsa_priv.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * RSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/core_names.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include <openssl/safestack.h>
-#include "crypto/rsa.h"
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define RSA_SELECT_PRIVATE_IMPORTABLE                                          \
-    (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
-
-static OSSL_FUNC_encoder_newctx_fn rsa_priv_newctx;
-static OSSL_FUNC_encoder_freectx_fn rsa_priv_freectx;
-static OSSL_FUNC_encoder_set_ctx_params_fn rsa_priv_set_ctx_params;
-static OSSL_FUNC_encoder_settable_ctx_params_fn rsa_priv_settable_ctx_params;
-static OSSL_FUNC_encoder_encode_data_fn rsa_priv_der_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_priv_der;
-static OSSL_FUNC_encoder_encode_data_fn rsa_pem_priv_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_pem_priv;
-
-static OSSL_FUNC_encoder_newctx_fn rsa_print_newctx;
-static OSSL_FUNC_encoder_freectx_fn rsa_print_freectx;
-static OSSL_FUNC_encoder_encode_data_fn rsa_priv_print_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_priv_print;
-
-/*
- * Context used for private key encoding.
- */
-struct rsa_priv_ctx_st {
-    void *provctx;
-
-    struct pkcs8_encrypt_ctx_st sc;
-};
-
-/* Private key : context */
-static void *rsa_priv_newctx(void *provctx)
-{
-    struct rsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
-    if (ctx != NULL) {
-        ctx->provctx = provctx;
-        /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
-        ctx->sc.pbe_nid = -1;
-    }
-    return ctx;
-}
-
-static void rsa_priv_freectx(void *vctx)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-
-    EVP_CIPHER_free(ctx->sc.cipher);
-    OPENSSL_free(ctx->sc.cipher_pass);
-    OPENSSL_free(ctx);
-}
-
-static const OSSL_PARAM *rsa_priv_settable_ctx_params(ossl_unused void *provctx)
-{
-    static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
-        OSSL_PARAM_END,
-    };
-
-    return settables;
-}
-
-static int rsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    const OSSL_PARAM *p;
-
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
-        != NULL) {
-        const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
-        const char *props = NULL;
-
-        if (p->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
-            return 0;
-        props = (propsp != NULL ? propsp->data : NULL);
-
-        EVP_CIPHER_free(ctx->sc.cipher);
-        ctx->sc.cipher_intent = p->data != NULL;
-        if (p->data != NULL
-            && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
-                == NULL))
-            return 0;
-    }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
-        != NULL) {
-        OPENSSL_free(ctx->sc.cipher_pass);
-        ctx->sc.cipher_pass = NULL;
-        if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
-                                         &ctx->sc.cipher_pass_length))
-            return 0;
-    }
-    return 1;
-}
-
-/* Private key : DER */
-static int rsa_priv_der_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        if ((rsa = rsa_new(ctx->provctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && rsa_priv_der(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_priv_der(void *vctx, void *rsa, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    int ret;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_der_from_obj(out, rsa,
-                                            ossl_prov_rsa_type_to_evp(rsa),
-                                            ossl_prov_prepare_rsa_params,
-                                            (i2d_of_void *)i2d_RSAPrivateKey,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Private key : PEM */
-static int rsa_pem_priv_data(void *vctx, const OSSL_PARAM params[],
-                             OSSL_CORE_BIO *out,
-                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        if ((rsa = rsa_new(ctx->provctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && rsa_pem_priv(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_pem_priv(void *vctx, void *rsa, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    int ret;
-    BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
-
-    if (out == NULL)
-        return 0;
-
-    ctx->sc.cb = cb;
-    ctx->sc.cbarg = cbarg;
-
-    ret = ossl_prov_write_priv_pem_from_obj(out, rsa,
-                                            ossl_prov_rsa_type_to_evp(rsa),
-                                            ossl_prov_prepare_rsa_params,
-                                            (i2d_of_void *)i2d_RSAPrivateKey,
-                                            &ctx->sc);
-    BIO_free(out);
-
-    return ret;
-}
-
-/*
- * There's no specific print context, so we use the provider context
- */
-static void *rsa_print_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void rsa_print_freectx(void *ctx)
-{
-}
-
-static int rsa_priv_print_data(void *vctx, const OSSL_PARAM params[],
-                               OSSL_CORE_BIO *out,
-                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    struct rsa_priv_ctx_st *ctx = vctx;
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        if ((rsa = rsa_new(ctx->provctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
-            && rsa_priv_print(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_priv_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_rsa(out, rsa, 1);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH rsa_priv_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))rsa_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))rsa_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_priv_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_priv_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH rsa_priv_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_priv_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_priv_freectx },
-    { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
-      (void (*)(void))rsa_priv_set_ctx_params },
-    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
-      (void (*)(void))rsa_priv_settable_ctx_params },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pem_priv_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pem_priv },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH rsa_priv_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_print_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_print_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_priv_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))rsa_priv_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/encoder_rsa_pub.c b/providers/implementations/encode_decode/encoder_rsa_pub.c
deleted file mode 100644
index 73bb466767..0000000000
--- a/providers/implementations/encode_decode/encoder_rsa_pub.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2019-2020 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-/*
- * RSA low level APIs are deprecated for public use, but still ok for
- * internal use.
- */
-#include "internal/deprecated.h"
-
-#include <openssl/core_dispatch.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/types.h>
-#include <openssl/params.h>
-#include "prov/bio.h"
-#include "prov/implementations.h"
-#include "prov/providercommonerr.h"
-#include "prov/provider_ctx.h"
-#include "encoder_local.h"
-
-#define RSA_SELECT_PUBLIC_IMPORTABLE                                           \
-    (OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
-
-static OSSL_FUNC_encoder_newctx_fn rsa_pub_newctx;
-static OSSL_FUNC_encoder_freectx_fn rsa_pub_freectx;
-static OSSL_FUNC_encoder_encode_data_fn rsa_pub_der_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_pub_der;
-static OSSL_FUNC_encoder_encode_data_fn rsa_pub_pem_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_pub_pem;
-
-static OSSL_FUNC_encoder_encode_data_fn rsa_pub_print_data;
-static OSSL_FUNC_encoder_encode_object_fn rsa_pub_print;
-
-/* Public key : context */
-
-/*
- * There's no specific implementation context, so we use the provider context
- */
-static void *rsa_pub_newctx(void *provctx)
-{
-    return provctx;
-}
-
-static void rsa_pub_freectx(void *ctx)
-{
-}
-
-/* Public key : DER */
-static int rsa_pub_der_data(void *ctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        /* ctx == provctx */
-        if ((rsa = rsa_new(ctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && rsa_pub_der(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_pub_der(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_der_from_obj(out, rsa,
-                                           ossl_prov_rsa_type_to_evp(rsa),
-                                           ossl_prov_prepare_rsa_params,
-                                           (i2d_of_void *)i2d_RSAPublicKey);
-    BIO_free(out);
-
-    return ret;
-}
-
-/* Public key : PEM */
-static int rsa_pub_pem_data(void *ctx, const OSSL_PARAM params[],
-                            OSSL_CORE_BIO *out,
-                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        /* ctx == provctx */
-        if ((rsa = rsa_new(ctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && rsa_pub_pem(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_pub_pem(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_write_pub_pem_from_obj(out, rsa,
-                                           ossl_prov_rsa_type_to_evp(rsa),
-                                           ossl_prov_prepare_rsa_params,
-                                           (i2d_of_void *)i2d_RSAPublicKey);
-    BIO_free(out);
-
-    return ret;
-}
-
-static int rsa_pub_print_data(void *ctx, const OSSL_PARAM params[],
-                              OSSL_CORE_BIO *out,
-                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
-    OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
-    OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
-    int ok = 0;
-
-    if (rsa_import != NULL) {
-        RSA *rsa;
-
-        /* ctx == provctx */
-        if ((rsa = rsa_new(ctx)) != NULL
-            && rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
-            && rsa_pub_print(ctx, rsa, out, cb, cbarg))
-            ok = 1;
-        rsa_free(rsa);
-    }
-    return ok;
-}
-
-static int rsa_pub_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
-{
-    BIO *out = bio_new_from_core_bio(ctx, cout);
-    int ret;
-
-    if (out == NULL)
-        return 0;
-
-    ret = ossl_prov_print_rsa(out, rsa, 0);
-    BIO_free(out);
-
-    return ret;
-}
-
-const OSSL_DISPATCH rsa_pub_der_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pub_der_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_der },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH rsa_pub_pem_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pub_pem_data },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_pem },
-    { 0, NULL }
-};
-
-const OSSL_DISPATCH rsa_pub_text_encoder_functions[] = {
-    { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_print },
-    { OSSL_FUNC_ENCODER_ENCODE_DATA,
-      (void (*)(void))rsa_pub_print_data },
-    { 0, NULL }
-};
diff --git a/providers/implementations/encode_decode/endecoder_common.c b/providers/implementations/encode_decode/endecoder_common.c
new file mode 100644
index 0000000000..c85fe915ac
--- /dev/null
+++ b/providers/implementations/encode_decode/endecoder_common.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core.h>
+
+#include "endecoder_local.h"
+
+OSSL_FUNC_keymgmt_new_fn *
+ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns)
+{
+    /* Pilfer the keymgmt dispatch table */
+    for (; fns->function_id != 0; fns++)
+        if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW)
+            return OSSL_FUNC_keymgmt_new(fns);
+
+    return NULL;
+}
+
+OSSL_FUNC_keymgmt_free_fn *
+ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns)
+{
+    /* Pilfer the keymgmt dispatch table */
+    for (; fns->function_id != 0; fns++)
+        if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE)
+            return OSSL_FUNC_keymgmt_free(fns);
+
+    return NULL;
+}
+
+OSSL_FUNC_keymgmt_import_fn *
+ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns)
+{
+    /* Pilfer the keymgmt dispatch table */
+    for (; fns->function_id != 0; fns++)
+        if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT)
+            return OSSL_FUNC_keymgmt_import(fns);
+
+    return NULL;
+}
+
+OSSL_FUNC_keymgmt_export_fn *
+ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
+{
+    /* Pilfer the keymgmt dispatch table */
+    for (; fns->function_id != 0; fns++)
+        if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
+            return OSSL_FUNC_keymgmt_export(fns);
+
+    return NULL;
+}
+
+void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
+                           int selection, const OSSL_PARAM params[])
+{
+    OSSL_FUNC_keymgmt_new_fn *kmgmt_new = ossl_prov_get_keymgmt_new(fns);
+    OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns);
+    OSSL_FUNC_keymgmt_import_fn *kmgmt_import =
+        ossl_prov_get_keymgmt_import(fns);
+    void *key = NULL;
+
+    if (kmgmt_new != NULL && kmgmt_import != NULL && kmgmt_free != NULL) {
+        if ((key = kmgmt_new(provctx)) == NULL
+            || !kmgmt_import(key, selection, params)) {
+            kmgmt_free(key);
+            key = NULL;
+        }
+    }
+    return key;
+}
+
+void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key)
+{
+    OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns);
+
+    if (kmgmt_free != NULL)
+        kmgmt_free(key);
+}
+
diff --git a/providers/implementations/encode_decode/endecoder_local.h b/providers/implementations/encode_decode/endecoder_local.h
new file mode 100644
index 0000000000..ab431b8086
--- /dev/null
+++ b/providers/implementations/encode_decode/endecoder_local.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/types.h>
+#include "prov/provider_ctx.h"
+
+OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
+
+int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
+                          unsigned char *input_der, long input_der_len,
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
+
+void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
+                           int selection, const OSSL_PARAM params[]);
+void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key);
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index 7060a4b839..91c5df40ec 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -305,71 +305,72 @@ extern const OSSL_DISPATCH mac_legacy_cmac_signature_functions[];
 extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
 
 /* Encoders */
-extern const OSSL_DISPATCH rsa_priv_text_encoder_functions[];
-extern const OSSL_DISPATCH rsa_pub_text_encoder_functions[];
-extern const OSSL_DISPATCH rsa_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH rsa_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH rsa_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH rsa_pub_pem_encoder_functions[];
+extern const OSSL_DISPATCH rsa_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH rsa_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH rsa_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH rsa_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH rsa_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH rsa_pub_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH dh_priv_text_encoder_functions[];
-extern const OSSL_DISPATCH dh_pub_text_encoder_functions[];
-extern const OSSL_DISPATCH dh_param_text_encoder_functions[];
-extern const OSSL_DISPATCH dh_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH dh_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH dh_param_der_encoder_functions[];
-extern const OSSL_DISPATCH dh_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH dh_pub_pem_encoder_functions[];
-extern const OSSL_DISPATCH dh_param_pem_encoder_functions[];
+extern const OSSL_DISPATCH dh_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dh_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dh_param_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dh_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dh_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dh_param_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dh_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH dh_pub_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH dh_param_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH dsa_priv_text_encoder_functions[];
-extern const OSSL_DISPATCH dsa_pub_text_encoder_functions[];
-extern const OSSL_DISPATCH dsa_param_text_encoder_functions[];
-extern const OSSL_DISPATCH dsa_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH dsa_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH dsa_param_der_encoder_functions[];
-extern const OSSL_DISPATCH dsa_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH dsa_pub_pem_encoder_functions[];
-extern const OSSL_DISPATCH dsa_param_pem_encoder_functions[];
+extern const OSSL_DISPATCH dsa_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dsa_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dsa_param_to_text_encoder_functions[];
+extern const OSSL_DISPATCH dsa_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dsa_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dsa_param_to_der_encoder_functions[];
+extern const OSSL_DISPATCH dsa_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH dsa_pub_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH dsa_param_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH x25519_priv_print_encoder_functions[];
-extern const OSSL_DISPATCH x25519_pub_print_encoder_functions[];
-extern const OSSL_DISPATCH x25519_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH x25519_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH x25519_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH x25519_pub_pem_encoder_functions[];
+extern const OSSL_DISPATCH x25519_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH x25519_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH x25519_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH x25519_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH x25519_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH x25519_pub_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH x448_priv_print_encoder_functions[];
-extern const OSSL_DISPATCH x448_pub_print_encoder_functions[];
-extern const OSSL_DISPATCH x448_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH x448_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH x448_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH x448_pub_pem_encoder_functions[];
+extern const OSSL_DISPATCH x448_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH x448_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH x448_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH x448_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH x448_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH x448_pub_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH ed25519_priv_print_encoder_functions[];
-extern const OSSL_DISPATCH ed25519_pub_print_encoder_functions[];
-extern const OSSL_DISPATCH ed25519_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH ed25519_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH ed25519_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH ed25519_pub_pem_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH ed25519_pub_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH ed448_priv_print_encoder_functions[];
-extern const OSSL_DISPATCH ed448_pub_print_encoder_functions[];
-extern const OSSL_DISPATCH ed448_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH ed448_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH ed448_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH ed448_pub_pem_encoder_functions[];
+extern const OSSL_DISPATCH ed448_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ed448_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ed448_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ed448_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ed448_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH ed448_pub_to_pem_encoder_functions[];
 
-extern const OSSL_DISPATCH ec_priv_text_encoder_functions[];
-extern const OSSL_DISPATCH ec_pub_text_encoder_functions[];
-extern const OSSL_DISPATCH ec_param_text_encoder_functions[];
-extern const OSSL_DISPATCH ec_priv_der_encoder_functions[];
-extern const OSSL_DISPATCH ec_pub_der_encoder_functions[];
-extern const OSSL_DISPATCH ec_param_der_encoder_functions[];
-extern const OSSL_DISPATCH ec_priv_pem_encoder_functions[];
-extern const OSSL_DISPATCH ec_pub_pem_encoder_functions[];
-extern const OSSL_DISPATCH ec_param_pem_encoder_functions[];
+extern const OSSL_DISPATCH ec_priv_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ec_pub_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ec_param_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ec_priv_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ec_pub_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ec_param_to_der_encoder_functions[];
+extern const OSSL_DISPATCH ec_priv_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH ec_pub_to_pem_encoder_functions[];
+extern const OSSL_DISPATCH ec_param_to_pem_encoder_functions[];
 
+/* Decoders */
 extern const OSSL_DISPATCH der_to_dh_decoder_functions[];
 extern const OSSL_DISPATCH der_to_dhx_decoder_functions[];
 extern const OSSL_DISPATCH der_to_dsa_decoder_functions[];


More information about the openssl-commits mailing list