[openssl] master update

Richard Levitte levitte at openssl.org
Fri Aug 21 07:27:01 UTC 2020


The branch master has been updated
       via  93ec4f8f09bc1b0e8b478d7b6c07a3bdb537bb75 (commit)
       via  ece9304c96f71277ca95696d9bc49fdec51e9f17 (commit)
       via  f650993f1de3dbb5eda9009ad0c4895a7b1b7fe2 (commit)
      from  5a7734cd0219faaad336990c9ceebc8efc2776b0 (commit)


- Log -----------------------------------------------------------------
commit 93ec4f8f09bc1b0e8b478d7b6c07a3bdb537bb75
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Aug 16 21:26:13 2020 +0200

    Remove the OSSL_SERIALIZER / OSSL_DESERIALIZER renaming scripts
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12660)

commit ece9304c96f71277ca95696d9bc49fdec51e9f17
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Aug 16 21:25:08 2020 +0200

    Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
    
    Fixes #12455
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12660)

commit f650993f1de3dbb5eda9009ad0c4895a7b1b7fe2
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun Aug 16 21:22:02 2020 +0200

    Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
    
    These are the scripts that do the deed.
    
    Fixes #12455
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12660)

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

Summary of changes:
 CHANGES.md                                         |  30 +-
 NEWS.md                                            |   2 +-
 apps/list.c                                        | 139 +++---
 crypto/asn1/i2d_pr.c                               |  14 +-
 crypto/build.info                                  |   2 +-
 crypto/encode_decode/build.info                    |   8 +
 .../decoder_err.c}                                 |  14 +-
 crypto/encode_decode/decoder_lib.c                 | 483 ++++++++++++++++++
 crypto/encode_decode/decoder_meth.c                | 552 +++++++++++++++++++++
 .../decoder_pkey.c}                                | 141 +++---
 .../encoder_err.c}                                 |  16 +-
 .../encoder_lib.c}                                 |  12 +-
 crypto/encode_decode/encoder_local.h               | 140 ++++++
 crypto/encode_decode/encoder_meth.c                | 523 +++++++++++++++++++
 crypto/encode_decode/encoder_pkey.c                | 276 +++++++++++
 .../endecode_pass.c}                               |  34 +-
 crypto/err/err.c                                   |   4 +-
 crypto/err/openssl.ec                              |  12 +-
 crypto/err/openssl.txt                             |   6 +-
 crypto/evp/p_lib.c                                 |  20 +-
 crypto/evp/pmeth_gn.c                              |   1 -
 crypto/pem/pem_local.h                             |  38 +-
 crypto/pem/pem_pk8.c                               |  23 +-
 crypto/pem/pem_pkey.c                              |   1 -
 crypto/property/property_parse.c                   |   6 +-
 crypto/serializer/build.info                       |   8 -
 crypto/serializer/deserializer_lib.c               | 488 ------------------
 crypto/serializer/deserializer_meth.c              | 552 ---------------------
 crypto/serializer/serializer_err.c                 |  33 --
 crypto/serializer/serializer_local.h               | 140 ------
 crypto/serializer/serializer_meth.c                | 522 -------------------
 crypto/serializer/serializer_pkey.c                | 275 ----------
 crypto/x509/x_pubkey.c                             |  26 +-
 doc/man1/openssl-list.pod.in                       |  12 +-
 doc/man3/OSSL_DECODER.pod                          | 142 ++++++
 doc/man3/OSSL_DECODER_CTX.pod                      |  74 +++
 doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod      | 109 ++++
 doc/man3/OSSL_DECODER_from_bio.pod                 | 276 +++++++++++
 doc/man3/OSSL_DESERIALIZER.pod                     | 146 ------
 doc/man3/OSSL_DESERIALIZER_CTX.pod                 |  74 ---
 doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod | 111 -----
 doc/man3/OSSL_DESERIALIZER_from_bio.pod            | 280 -----------
 doc/man3/OSSL_ENCODER.pod                          | 126 +++++
 doc/man3/OSSL_ENCODER_CTX.pod                      |  93 ++++
 doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod      | 144 ++++++
 ...RIALIZER_to_bio.pod => OSSL_ENCODER_to_bio.pod} |  24 +-
 doc/man3/OSSL_SERIALIZER.pod                       | 129 -----
 doc/man3/OSSL_SERIALIZER_CTX.pod                   |  94 ----
 doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod   | 144 ------
 doc/man7/OSSL_PROVIDER-FIPS.pod                    |   2 +-
 doc/man7/OSSL_PROVIDER-base.pod                    |  22 +-
 doc/man7/OSSL_PROVIDER-default.pod                 |  16 +-
 ...rovider-serializer.pod => provider-encoder.pod} | 127 +++--
 doc/man7/provider.pod                              |  10 +-
 include/crypto/{serializer.h => encoder.h}         |   8 +-
 include/internal/cryptlib.h                        |   4 +-
 include/openssl/core_dispatch.h                    |  62 +--
 include/openssl/core_names.h                       |  26 +-
 include/openssl/decoder.h                          | 117 +++++
 .../openssl/{deserializererr.h => decodererr.h}    |  12 +-
 include/openssl/deserializer.h                     | 125 -----
 include/openssl/encoder.h                          | 100 ++++
 include/openssl/{serializererr.h => encodererr.h}  |  14 +-
 include/openssl/err.h                              |   4 +-
 include/openssl/serializer.h                       | 104 ----
 include/openssl/types.h                            |   8 +-
 providers/baseprov.c                               |  24 +-
 providers/decoders.inc                             |  42 ++
 providers/defltprov.c                              |  24 +-
 providers/deserializers.inc                        |  42 --
 providers/encoders.inc                             | 112 +++++
 providers/implementations/build.info               |   2 +-
 providers/implementations/encode_decode/build.info |  35 ++
 .../decode_common.c}                               |   2 +-
 .../decode_der2key.c}                              |  46 +-
 .../decode_ms2key.c}                               |  64 ++-
 .../decode_pem2der.c}                              |  40 +-
 .../encoder_common.c}                              |   2 +-
 .../serializer_dh.c => encode_decode/encoder_dh.c} |   2 +-
 .../encoder_dh_param.c}                            |  52 +-
 .../encoder_dh_priv.c}                             |  86 ++--
 .../encoder_dh_pub.c}                              |  58 +--
 .../encoder_dsa.c}                                 |   2 +-
 .../encoder_dsa_param.c}                           |  48 +-
 .../encoder_dsa_priv.c}                            |  84 ++--
 .../encoder_dsa_pub.c}                             |  48 +-
 .../serializer_ec.c => encode_decode/encoder_ec.c} |   2 +-
 .../encoder_ec_param.c}                            |  54 +-
 .../encoder_ec_priv.c}                             |  90 ++--
 .../encoder_ec_pub.c}                              |  49 +-
 .../encoder_ecx.c}                                 |   2 +-
 .../encoder_ecx_priv.c}                            | 108 ++--
 .../encoder_ecx_pub.c}                             |  60 +--
 .../encoder_ffc_params.c}                          |   2 +-
 .../encoder_local.h}                               |   2 +-
 .../encoder_rsa.c}                                 |   4 +-
 .../encoder_rsa_priv.c}                            |  84 ++--
 .../encoder_rsa_pub.c}                             |  48 +-
 .../implementations/include/prov/implementations.h | 146 +++---
 providers/implementations/serializers/build.info   |  35 --
 providers/serializers.inc                          | 112 -----
 test/build.info                                    |   8 +-
 test/{serdes_test.c => endecode_test.c}            | 230 ++++-----
 test/evp_pkey_provided_test.c                      |  60 +--
 ...er_deserializer.t => 04-test_encoder_decoder.t} |   4 +-
 util/libcrypto.num                                 | 114 ++---
 util/missingcrypto.txt                             |  16 +-
 util/other.syms                                    |  36 +-
 108 files changed, 4645 insertions(+), 4716 deletions(-)
 create mode 100644 crypto/encode_decode/build.info
 copy crypto/{serializer/deserializer_err.c => encode_decode/decoder_err.c} (55%)
 create mode 100644 crypto/encode_decode/decoder_lib.c
 create mode 100644 crypto/encode_decode/decoder_meth.c
 rename crypto/{serializer/deserializer_pkey.c => encode_decode/decoder_pkey.c} (65%)
 rename crypto/{serializer/deserializer_err.c => encode_decode/encoder_err.c} (51%)
 rename crypto/{serializer/serializer_lib.c => encode_decode/encoder_lib.c} (71%)
 create mode 100644 crypto/encode_decode/encoder_local.h
 create mode 100644 crypto/encode_decode/encoder_meth.c
 create mode 100644 crypto/encode_decode/encoder_pkey.c
 rename crypto/{serializer/serdes_pass.c => encode_decode/endecode_pass.c} (80%)
 delete mode 100644 crypto/serializer/build.info
 delete mode 100644 crypto/serializer/deserializer_lib.c
 delete mode 100644 crypto/serializer/deserializer_meth.c
 delete mode 100644 crypto/serializer/serializer_err.c
 delete mode 100644 crypto/serializer/serializer_local.h
 delete mode 100644 crypto/serializer/serializer_meth.c
 delete mode 100644 crypto/serializer/serializer_pkey.c
 create mode 100644 doc/man3/OSSL_DECODER.pod
 create mode 100644 doc/man3/OSSL_DECODER_CTX.pod
 create mode 100644 doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod
 create mode 100644 doc/man3/OSSL_DECODER_from_bio.pod
 delete mode 100644 doc/man3/OSSL_DESERIALIZER.pod
 delete mode 100644 doc/man3/OSSL_DESERIALIZER_CTX.pod
 delete mode 100644 doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
 delete mode 100644 doc/man3/OSSL_DESERIALIZER_from_bio.pod
 create mode 100644 doc/man3/OSSL_ENCODER.pod
 create mode 100644 doc/man3/OSSL_ENCODER_CTX.pod
 create mode 100644 doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod
 rename doc/man3/{OSSL_SERIALIZER_to_bio.pod => OSSL_ENCODER_to_bio.pod} (58%)
 delete mode 100644 doc/man3/OSSL_SERIALIZER.pod
 delete mode 100644 doc/man3/OSSL_SERIALIZER_CTX.pod
 delete mode 100644 doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod
 rename doc/man7/{provider-serializer.pod => provider-encoder.pod} (56%)
 rename include/crypto/{serializer.h => encoder.h} (53%)
 create mode 100644 include/openssl/decoder.h
 rename include/openssl/{deserializererr.h => decodererr.h} (68%)
 delete mode 100644 include/openssl/deserializer.h
 create mode 100644 include/openssl/encoder.h
 rename include/openssl/{serializererr.h => encodererr.h} (64%)
 delete mode 100644 include/openssl/serializer.h
 create mode 100644 providers/decoders.inc
 delete mode 100644 providers/deserializers.inc
 create mode 100644 providers/encoders.inc
 create mode 100644 providers/implementations/encode_decode/build.info
 rename providers/implementations/{serializers/deserialize_common.c => encode_decode/decode_common.c} (99%)
 rename providers/implementations/{serializers/deserialize_der2key.c => encode_decode/decode_der2key.c} (81%)
 rename providers/implementations/{serializers/deserialize_ms2key.c => encode_decode/decode_ms2key.c} (73%)
 rename providers/implementations/{serializers/deserialize_pem2der.c => encode_decode/decode_pem2der.c} (71%)
 rename providers/implementations/{serializers/serializer_common.c => encode_decode/encoder_common.c} (99%)
 rename providers/implementations/{serializers/serializer_dh.c => encode_decode/encoder_dh.c} (99%)
 rename providers/implementations/{serializers/serializer_dh_param.c => encode_decode/encoder_dh_param.c} (70%)
 rename providers/implementations/{serializers/serializer_dh_priv.c => encode_decode/encoder_dh_priv.c} (73%)
 rename providers/implementations/{serializers/serializer_dh_pub.c => encode_decode/encoder_dh_pub.c} (70%)
 rename providers/implementations/{serializers/serializer_dsa.c => encode_decode/encoder_dsa.c} (99%)
 rename providers/implementations/{serializers/serializer_dsa_param.c => encode_decode/encoder_dsa_param.c} (73%)
 rename providers/implementations/{serializers/serializer_dsa_priv.c => encode_decode/encoder_dsa_priv.c} (74%)
 rename providers/implementations/{serializers/serializer_dsa_pub.c => encode_decode/encoder_dsa_pub.c} (76%)
 rename providers/implementations/{serializers/serializer_ec.c => encode_decode/encoder_ec.c} (99%)
 rename providers/implementations/{serializers/serializer_ec_param.c => encode_decode/encoder_ec_param.c} (68%)
 rename providers/implementations/{serializers/serializer_ec_priv.c => encode_decode/encoder_ec_priv.c} (71%)
 rename providers/implementations/{serializers/serializer_ec_pub.c => encode_decode/encoder_ec_pub.c} (74%)
 rename providers/implementations/{serializers/serializer_ecx.c => encode_decode/encoder_ecx.c} (99%)
 rename providers/implementations/{serializers/serializer_ecx_priv.c => encode_decode/encoder_ecx_priv.c} (68%)
 rename providers/implementations/{serializers/serializer_ecx_pub.c => encode_decode/encoder_ecx_pub.c} (75%)
 rename providers/implementations/{serializers/serializer_ffc_params.c => encode_decode/encoder_ffc_params.c} (98%)
 rename providers/implementations/{serializers/serializer_local.h => encode_decode/encoder_local.h} (99%)
 rename providers/implementations/{serializers/serializer_rsa.c => encode_decode/encoder_rsa.c} (98%)
 rename providers/implementations/{serializers/serializer_rsa_priv.c => encode_decode/encoder_rsa_priv.c} (74%)
 rename providers/implementations/{serializers/serializer_rsa_pub.c => encode_decode/encoder_rsa_pub.c} (75%)
 delete mode 100644 providers/implementations/serializers/build.info
 delete mode 100644 providers/serializers.inc
 rename test/{serdes_test.c => endecode_test.c} (79%)
 rename test/recipes/{04-test_serializer_deserializer.t => 04-test_encoder_decoder.t} (89%)

diff --git a/CHANGES.md b/CHANGES.md
index 31e183f395..c2bbf0d167 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -612,22 +612,22 @@ OpenSSL 3.0
 
    *Rich Salz*
 
- * Introduced a new method type and API, OSSL_SERIALIZER, to
-   represent generic serializers.  An implementation is expected to
-   be able to serialize an object associated with a given name (such
+ * Introduced a new method type and API, OSSL_ENCODER, to
+   represent generic encoders.  An implementation is expected to
+   be able to encode an object associated with a given name (such
    as an algorithm name for an asymmetric key) into forms given by
    implementation properties.
 
-   Serializers are primarily used from inside libcrypto, through
+   Encoders are primarily used from inside libcrypto, through
    calls to functions like EVP_PKEY_print_private(),
    PEM_write_bio_PrivateKey() and similar.
 
-   Serializers are specified in such a way that they can be made to
+   Encoders are specified in such a way that they can be made to
    directly handle the provider side portion of an object, if this
-   provider side part comes from the same provider as the serializer
+   provider side part comes from the same provider as the encoder
    itself, but can also be made to handle objects in parametrized
    form (as an OSSL_PARAM array of data).  This allows a provider to
-   offer generic serializers as a service for any other provider.
+   offer generic encoders as a service for any other provider.
 
    *Richard Levitte*
 
@@ -769,13 +769,13 @@ OpenSSL 3.0
    *Richard Levitte*
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -1255,13 +1255,13 @@ OpenSSL 1.1.1
    *Matthias St. Pierre*
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -2025,13 +2025,13 @@ OpenSSL 1.1.0
 ### Changes between 1.1.0k and 1.1.0l [10 Sep 2019]
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
@@ -3822,13 +3822,13 @@ OpenSSL 1.0.2
 ### Changes between 1.0.2s and 1.0.2t [10 Sep 2019]
 
  * For built-in EC curves, ensure an EC_GROUP built from the curve name is
-   used even when parsing explicit parameters, when loading a serialized key
+   used even when parsing explicit parameters, when loading a encoded key
    or calling `EC_GROUP_new_from_ecpkparameters()`/
    `EC_GROUP_new_from_ecparameters()`.
    This prevents bypass of security hardening and performance gains,
    especially for curves with specialized EC_METHODs.
    By default, if a key encoded with explicit parameters is loaded and later
-   serialized, the output is still encoded with explicit parameters, even if
+   encoded, the output is still encoded with explicit parameters, even if
    internally a "named" EC_GROUP is used for computation.
 
    *Nicola Tuveri*
diff --git a/NEWS.md b/NEWS.md
index e40b2932b3..4b0171fb50 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -43,7 +43,7 @@ OpenSSL 3.0
   * Added a proper HTTP(S) client to libcrypto supporting GET and POST,
     redirection, plain and ASN.1-encoded contents, proxies, and timeouts.
   * Added util/check-format.pl for checking adherence to the coding guidelines.
-  * Added OSSL_SERIALIZER, a generic serializer API.
+  * Added OSSL_ENCODER, a generic encoder API.
   * Added OSSL_PARAM_BLD, an easier to use API to OSSL_PARAM.
   * Added error raising macros, ERR_raise() and ERR_raise_data().
   * Deprecated ERR_put_error().
diff --git a/apps/list.c b/apps/list.c
index 69a516763c..c891bf7213 100644
--- a/apps/list.c
+++ b/apps/list.c
@@ -16,8 +16,8 @@
 #include <openssl/provider.h>
 #include <openssl/safestack.h>
 #include <openssl/kdf.h>
-#include <openssl/serializer.h>
-#include <openssl/deserializer.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
 #include <openssl/core_names.h>
 #include "apps.h"
 #include "app_params.h"
@@ -355,124 +355,124 @@ static void list_random_generators(void)
 }
 
 /*
- * Serializers
+ * Encoders
  */
-DEFINE_STACK_OF(OSSL_SERIALIZER)
-static int serializer_cmp(const OSSL_SERIALIZER * const *a,
-                          const OSSL_SERIALIZER * const *b)
+DEFINE_STACK_OF(OSSL_ENCODER)
+static int encoder_cmp(const OSSL_ENCODER * const *a,
+                       const OSSL_ENCODER * const *b)
 {
-    int ret = OSSL_SERIALIZER_number(*a) - OSSL_SERIALIZER_number(*b);
+    int ret = OSSL_ENCODER_number(*a) - OSSL_ENCODER_number(*b);
 
     if (ret == 0)
-        ret = strcmp(OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*a)),
-                     OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*b)));
+        ret = strcmp(OSSL_PROVIDER_name(OSSL_ENCODER_provider(*a)),
+                     OSSL_PROVIDER_name(OSSL_ENCODER_provider(*b)));
     return ret;
 }
 
-static void collect_serializers(OSSL_SERIALIZER *serializer, void *stack)
+static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
 {
-    STACK_OF(OSSL_SERIALIZER) *serializer_stack = stack;
+    STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
 
-    sk_OSSL_SERIALIZER_push(serializer_stack, serializer);
-    OSSL_SERIALIZER_up_ref(serializer);
+    sk_OSSL_ENCODER_push(encoder_stack, encoder);
+    OSSL_ENCODER_up_ref(encoder);
 }
 
-static void list_serializers(void)
+static void list_encoders(void)
 {
-    STACK_OF(OSSL_SERIALIZER) *serializers;
+    STACK_OF(OSSL_ENCODER) *encoders;
     int i;
 
-    serializers = sk_OSSL_SERIALIZER_new(serializer_cmp);
-    if (serializers == NULL) {
+    encoders = sk_OSSL_ENCODER_new(encoder_cmp);
+    if (encoders == NULL) {
         BIO_printf(bio_err, "ERROR: Memory allocation\n");
         return;
     }
-    BIO_printf(bio_out, "Provided SERIALIZERs:\n");
-    OSSL_SERIALIZER_do_all_provided(NULL, collect_serializers, serializers);
-    sk_OSSL_SERIALIZER_sort(serializers);
+    BIO_printf(bio_out, "Provided ENCODERs:\n");
+    OSSL_ENCODER_do_all_provided(NULL, collect_encoders, encoders);
+    sk_OSSL_ENCODER_sort(encoders);
 
-    for (i = 0; i < sk_OSSL_SERIALIZER_num(serializers); i++) {
-        OSSL_SERIALIZER *k = sk_OSSL_SERIALIZER_value(serializers, i);
+    for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) {
+        OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i);
         STACK_OF(OPENSSL_CSTRING) *names =
             sk_OPENSSL_CSTRING_new(name_cmp);
 
-        OSSL_SERIALIZER_names_do_all(k, collect_names, names);
+        OSSL_ENCODER_names_do_all(k, collect_names, names);
 
         BIO_printf(bio_out, "  ");
         print_names(bio_out, names);
         BIO_printf(bio_out, " @ %s (%s)\n",
-                   OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(k)),
-                   OSSL_SERIALIZER_properties(k));
+                   OSSL_PROVIDER_name(OSSL_ENCODER_provider(k)),
+                   OSSL_ENCODER_properties(k));
 
         sk_OPENSSL_CSTRING_free(names);
 
         if (verbose) {
             print_param_types("settable operation parameters",
-                              OSSL_SERIALIZER_settable_ctx_params(k), 4);
+                              OSSL_ENCODER_settable_ctx_params(k), 4);
         }
     }
-    sk_OSSL_SERIALIZER_pop_free(serializers, OSSL_SERIALIZER_free);
+    sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free);
 }
 
 /*
- * Deserializers
+ * Decoders
  */
-DEFINE_STACK_OF(OSSL_DESERIALIZER)
-static int deserializer_cmp(const OSSL_DESERIALIZER * const *a,
-                            const OSSL_DESERIALIZER * const *b)
+DEFINE_STACK_OF(OSSL_DECODER)
+static int decoder_cmp(const OSSL_DECODER * const *a,
+                       const OSSL_DECODER * const *b)
 {
-    int ret = OSSL_DESERIALIZER_number(*a) - OSSL_DESERIALIZER_number(*b);
+    int ret = OSSL_DECODER_number(*a) - OSSL_DECODER_number(*b);
 
     if (ret == 0)
-        ret = strcmp(OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*a)),
-                     OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*b)));
+        ret = strcmp(OSSL_PROVIDER_name(OSSL_DECODER_provider(*a)),
+                     OSSL_PROVIDER_name(OSSL_DECODER_provider(*b)));
     return ret;
 }
 
-static void collect_deserializers(OSSL_DESERIALIZER *deserializer, void *stack)
+static void collect_decoders(OSSL_DECODER *decoder, void *stack)
 {
-    STACK_OF(OSSL_DESERIALIZER) *deserializer_stack = stack;
+    STACK_OF(OSSL_DECODER) *decoder_stack = stack;
 
-    sk_OSSL_DESERIALIZER_push(deserializer_stack, deserializer);
-    OSSL_DESERIALIZER_up_ref(deserializer);
+    sk_OSSL_DECODER_push(decoder_stack, decoder);
+    OSSL_DECODER_up_ref(decoder);
 }
 
-static void list_deserializers(void)
+static void list_decoders(void)
 {
-    STACK_OF(OSSL_DESERIALIZER) *deserializers;
+    STACK_OF(OSSL_DECODER) *decoders;
     int i;
 
-    deserializers = sk_OSSL_DESERIALIZER_new(deserializer_cmp);
-    if (deserializers == NULL) {
+    decoders = sk_OSSL_DECODER_new(decoder_cmp);
+    if (decoders == NULL) {
         BIO_printf(bio_err, "ERROR: Memory allocation\n");
         return;
     }
-    BIO_printf(bio_out, "Provided DESERIALIZERs:\n");
-    OSSL_DESERIALIZER_do_all_provided(NULL, collect_deserializers,
-                                      deserializers);
-    sk_OSSL_DESERIALIZER_sort(deserializers);
+    BIO_printf(bio_out, "Provided DECODERs:\n");
+    OSSL_DECODER_do_all_provided(NULL, collect_decoders,
+                                 decoders);
+    sk_OSSL_DECODER_sort(decoders);
 
-    for (i = 0; i < sk_OSSL_DESERIALIZER_num(deserializers); i++) {
-        OSSL_DESERIALIZER *k = sk_OSSL_DESERIALIZER_value(deserializers, i);
+    for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) {
+        OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i);
         STACK_OF(OPENSSL_CSTRING) *names =
             sk_OPENSSL_CSTRING_new(name_cmp);
 
-        OSSL_DESERIALIZER_names_do_all(k, collect_names, names);
+        OSSL_DECODER_names_do_all(k, collect_names, names);
 
         BIO_printf(bio_out, "  ");
         print_names(bio_out, names);
         BIO_printf(bio_out, " @ %s (%s)\n",
-                   OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(k)),
-                   OSSL_DESERIALIZER_properties(k));
+                   OSSL_PROVIDER_name(OSSL_DECODER_provider(k)),
+                   OSSL_DECODER_properties(k));
 
         sk_OPENSSL_CSTRING_free(names);
 
         if (verbose) {
             print_param_types("settable operation parameters",
-                              OSSL_DESERIALIZER_settable_ctx_params(k), 4);
+                              OSSL_DECODER_settable_ctx_params(k), 4);
         }
     }
-    sk_OSSL_DESERIALIZER_pop_free(deserializers, OSSL_DESERIALIZER_free);
+    sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free);
 }
 
 static void list_missing_help(void)
@@ -554,7 +554,7 @@ static void list_options_for_command(const char *command)
             break;
     if (fp->name == NULL) {
         BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
-                command);
+                   command);
         return;
     }
 
@@ -821,8 +821,8 @@ typedef enum HELPLIST_CHOICE {
     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
-    OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_SERIALIZERS,
-    OPT_DESERIALIZERS,
+    OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_ENCODERS,
+    OPT_DECODERS,
     OPT_MISSING_HELP, OPT_OBJECTS,
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     OPT_ENGINES, 
@@ -847,15 +847,14 @@ const OPTIONS list_options[] = {
     {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
      "List of key derivation and pseudo random function algorithms"},
     {"random-generators", OPT_RANDOM_GENERATORS, '-',
-      "List of random number generators"},
+     "List of random number generators"},
     {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
      "List of message authentication code algorithms"},
     {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
     {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
      "List of cipher algorithms"},
-    {"serializers", OPT_SERIALIZERS, '-', "List of serialization methods" },
-    {"deserializers", OPT_DESERIALIZERS, '-',
-      "List of deserialization methods" },
+    {"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
+    {"decoders", OPT_DECODERS, '-', "List of decoding methods" },
     {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
      "List of public key algorithms"},
 #ifndef OPENSSL_NO_DEPRECATED_3_0
@@ -890,8 +889,8 @@ int list_main(int argc, char **argv)
         unsigned int mac_algorithms:1;
         unsigned int cipher_commands:1;
         unsigned int cipher_algorithms:1;
-        unsigned int serializer_algorithms:1;
-        unsigned int deserializer_algorithms:1;
+        unsigned int encoder_algorithms:1;
+        unsigned int decoder_algorithms:1;
         unsigned int pk_algorithms:1;
         unsigned int pk_method:1;
 #ifndef OPENSSL_NO_DEPRECATED_3_0
@@ -943,11 +942,11 @@ opthelp:
         case OPT_CIPHER_ALGORITHMS:
             todo.cipher_algorithms = 1;
             break;
-        case OPT_SERIALIZERS:
-            todo.serializer_algorithms = 1;
+        case OPT_ENCODERS:
+            todo.encoder_algorithms = 1;
             break;
-        case OPT_DESERIALIZERS:
-            todo.deserializer_algorithms = 1;
+        case OPT_DECODERS:
+            todo.decoder_algorithms = 1;
             break;
         case OPT_PK_ALGORITHMS:
             todo.pk_algorithms = 1;
@@ -1003,10 +1002,10 @@ opthelp:
         list_type(FT_cipher, one);
     if (todo.cipher_algorithms)
         list_ciphers();
-    if (todo.serializer_algorithms)
-        list_serializers();
-    if (todo.deserializer_algorithms)
-        list_deserializers();
+    if (todo.encoder_algorithms)
+        list_encoders();
+    if (todo.decoder_algorithms)
+        list_decoders();
     if (todo.pk_algorithms)
         list_pkey();
 #ifndef OPENSSL_NO_DEPRECATED_3_0
diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c
index 545300cbab..84513db5bf 100644
--- a/crypto/asn1/i2d_pr.c
+++ b/crypto/asn1/i2d_pr.c
@@ -10,7 +10,7 @@
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 #include <openssl/buffer.h>
 #include <openssl/x509.h>
 #include "crypto/asn1.h"
@@ -31,17 +31,17 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
         return ret;
     }
     if (a->keymgmt != NULL) {
-        const char *serprop = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ;
-        OSSL_SERIALIZER_CTX *ctx =
-            OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
+        const char *encprop = OSSL_ENCODER_PrivateKey_TO_DER_PQ;
+        OSSL_ENCODER_CTX *ctx =
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
         BIO *out = BIO_new(BIO_s_mem());
         BUF_MEM *buf = NULL;
         int ret = -1;
 
         if (ctx != NULL
             && out != NULL
-            && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL
-            && OSSL_SERIALIZER_to_bio(ctx, out)
+            && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
+            && OSSL_ENCODER_to_bio(ctx, out)
             && BIO_get_mem_ptr(out, &buf) > 0) {
             ret = buf->length;
 
@@ -57,7 +57,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
             }
         }
         BIO_free(out);
-        OSSL_SERIALIZER_CTX_free(ctx);
+        OSSL_ENCODER_CTX_free(ctx);
         return ret;
     }
     ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
diff --git a/crypto/build.info b/crypto/build.info
index 83625029c0..07e3dd526f 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \
         md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \
         siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
         seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
-        err comp http ocsp cms ts srp cmac ct async ess crmf cmp serializer \
+        err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \
         ffc
 
 LIBS=../libcrypto
diff --git a/crypto/encode_decode/build.info b/crypto/encode_decode/build.info
new file mode 100644
index 0000000000..4686c4a19d
--- /dev/null
+++ b/crypto/encode_decode/build.info
@@ -0,0 +1,8 @@
+SOURCE[../../libcrypto]=endecode_pass.c
+
+SOURCE[../../libcrypto]=encoder_meth.c encoder_lib.c encoder_pkey.c
+SOURCE[../../libcrypto]=decoder_meth.c decoder_lib.c \
+        decoder_pkey.c
+
+SOURCE[../../libcrypto]=encoder_err.c
+SOURCE[../../libcrypto]=decoder_err.c
diff --git a/crypto/serializer/deserializer_err.c b/crypto/encode_decode/decoder_err.c
similarity index 55%
copy from crypto/serializer/deserializer_err.c
copy to crypto/encode_decode/decoder_err.c
index 2cc245996f..984f7abeb9 100644
--- a/crypto/serializer/deserializer_err.c
+++ b/crypto/encode_decode/decoder_err.c
@@ -9,23 +9,23 @@
  */
 
 #include <openssl/err.h>
-#include <openssl/deserializererr.h>
+#include <openssl/decodererr.h>
 
 #ifndef OPENSSL_NO_ERR
 
-static const ERR_STRING_DATA OSSL_DESERIALIZER_str_reasons[] = {
-    {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, OSSL_DESERIALIZER_R_MISSING_GET_PARAMS),
-    "missing get params"},
+static const ERR_STRING_DATA OSSL_DECODER_str_reasons[] = {
+    {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_MISSING_GET_PARAMS),
+     "missing get params"},
     {0, NULL}
 };
 
 #endif
 
-int ERR_load_OSSL_DESERIALIZER_strings(void)
+int ERR_load_OSSL_DECODER_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
-    if (ERR_reason_error_string(OSSL_DESERIALIZER_str_reasons[0].error) == NULL)
-        ERR_load_strings_const(OSSL_DESERIALIZER_str_reasons);
+    if (ERR_reason_error_string(OSSL_DECODER_str_reasons[0].error) == NULL)
+        ERR_load_strings_const(OSSL_DECODER_str_reasons);
 #endif
     return 1;
 }
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
new file mode 100644
index 0000000000..21b4703084
--- /dev/null
+++ b/crypto/encode_decode/decoder_lib.c
@@ -0,0 +1,483 @@
+/*
+ * 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/params.h>
+#include <openssl/provider.h>
+#include "encoder_local.h"
+#include "e_os.h"
+
+struct decoder_process_data_st {
+    OSSL_DECODER_CTX *ctx;
+
+    /* Current BIO */
+    BIO *bio;
+
+    /* Index of the current decoder instance to be processed */
+    size_t current_deser_inst_index;
+};
+
+static int decoder_process(const OSSL_PARAM params[], void *arg);
+
+int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in)
+{
+    struct decoder_process_data_st data;
+    int ok = 0;
+
+    memset(&data, 0, sizeof(data));
+    data.ctx = ctx;
+    data.bio = in;
+
+    ok = decoder_process(NULL, &data);
+
+    /* Clear any internally cached passphrase */
+    if (!ctx->flag_user_passphrase) {
+        OSSL_DECODER_CTX_set_passphrase(ctx, NULL, 0);
+        ctx->flag_user_passphrase = 0;
+    }
+    return ok;
+}
+
+#ifndef OPENSSL_NO_STDIO
+static BIO *bio_from_file(FILE *fp)
+{
+    BIO *b;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB);
+        return NULL;
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    return b;
+}
+
+int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp)
+{
+    BIO *b = bio_from_file(fp);
+    int ret = 0;
+
+    if (b != NULL)
+        ret = OSSL_DECODER_from_bio(ctx, b);
+
+    BIO_free(b);
+    return ret;
+}
+#endif
+
+int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+                                    const char *input_type)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    /*
+     * NULL is a valid starting input type, and means that the caller leaves
+     * it to code to discover what the starting input type is.
+     */
+    ctx->start_input_type = input_type;
+    return 1;
+}
+
+int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder)
+{
+    OSSL_DECODER_INSTANCE *decoder_inst = NULL;
+    const OSSL_PROVIDER *prov = NULL;
+    OSSL_PARAM params[2];
+    void *provctx = NULL;
+
+    if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (decoder->get_params == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER,
+                  OSSL_DECODER_R_MISSING_GET_PARAMS);
+        return 0;
+    }
+
+    if (ctx->decoder_insts == NULL
+        && (ctx->decoder_insts =
+            sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!OSSL_DECODER_up_ref(decoder)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    decoder_inst->decoder = decoder;
+
+    prov = OSSL_DECODER_provider(decoder_inst->decoder);
+    provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
+
+    /* Cache the input type for this encoder */
+    params[0] =
+        OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_TYPE,
+                                      (char **)&decoder_inst->input_type, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (!decoder_inst->decoder->get_params(params)
+        || !OSSL_PARAM_modified(&params[0]))
+        goto err;
+
+    if ((decoder_inst->deserctx = decoder_inst->decoder->newctx(provctx))
+        == NULL)
+        goto err;
+
+    if (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, decoder_inst) <= 0)
+        goto err;
+
+    return 1;
+ err:
+    if (decoder_inst != NULL) {
+        if (decoder_inst->decoder != NULL)
+            decoder_inst->decoder->freectx(decoder_inst->deserctx);
+        OSSL_DECODER_free(decoder_inst->decoder);
+        OPENSSL_free(decoder_inst);
+    }
+    return 0;
+}
+
+int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
+                               OPENSSL_CTX *libctx, const char *propq)
+{
+    /*
+     * This function goes through existing decoder methods in
+     * |ctx->decoder_insts|, and tries to fetch new decoders that produce
+     * what the existing ones want as input, and push those newly fetched
+     * decoders on top of the same stack.
+     * Then it does the same again, but looping over the newly fetched
+     * decoders, until there are no more encoders to be fetched, or
+     * when we have done this 10 times.
+     *
+     * we do this with sliding windows on the stack by keeping track of indexes
+     * and of the end.
+     *
+     * +----------------+
+     * |   DER to RSA   | <--- w_prev_start
+     * +----------------+
+     * |   DER to DSA   |
+     * +----------------+
+     * |   DER to DH    |
+     * +----------------+
+     * |   PEM to DER   | <--- w_prev_end, w_new_start
+     * +----------------+
+     *                    <--- w_new_end
+     */
+    size_t w_prev_start, w_prev_end; /* "previous" decoders */
+    size_t w_new_start, w_new_end;   /* "new" decoders */
+    size_t count = 0; /* Calculates how many were added in each iteration */
+    size_t depth = 0; /* Counts the number of iterations */
+
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    /*
+     * If there is no stack of OSSL_DECODER_INSTANCE, we have nothing
+     * more to add.  That's fine.
+     */
+    if (ctx->decoder_insts == NULL)
+        return 1;
+
+    w_prev_start = 0;
+    w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+    do {
+        size_t i;
+
+        w_new_start = w_new_end = w_prev_end;
+
+        for (i = w_prev_start; i < w_prev_end; i++) {
+            OSSL_DECODER_INSTANCE *decoder_inst =
+                sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+            const char *name = decoder_inst->input_type;
+            OSSL_DECODER *decoder = NULL;
+
+            /*
+             * If the caller has specified what the initial input should be,
+             * and the decoder implementation we're looking at has that
+             * input type, there's no point adding on more implementations
+             * on top of this one, so we don't.
+             */
+            if (ctx->start_input_type != NULL
+                && strcasecmp(ctx->start_input_type,
+                              decoder_inst->input_type) != 0)
+                continue;
+
+            ERR_set_mark();
+            decoder = OSSL_DECODER_fetch(libctx, name, propq);
+            ERR_pop_to_mark();
+
+            if (decoder != NULL) {
+                size_t j;
+
+                /*
+                 * Check that we don't already have this decoder in our
+                 * stack We only need to check among the newly added ones.
+                 */
+                for (j = w_new_start; j < w_new_end; j++) {
+                    OSSL_DECODER_INSTANCE *check_inst =
+                        sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, j);
+
+                    if (decoder == check_inst->decoder) {
+                        /* We found it, so drop the new fetch */
+                        OSSL_DECODER_free(decoder);
+                        decoder = NULL;
+                        break;
+                    }
+                }
+            }
+
+            if (decoder == NULL)
+                continue;
+
+            /*
+             * Apart from keeping w_new_end up to date, We don't care about
+             * errors here.  If it doesn't collect, then it doesn't...
+             */
+            if (OSSL_DECODER_CTX_add_decoder(ctx, decoder)) /* ref++ */
+                w_new_end++;
+            OSSL_DECODER_free(decoder); /* ref-- */
+        }
+        /* How many were added in this iteration */
+        count = w_new_end - w_new_start;
+
+        /* Slide the "previous decoder" windows */
+        w_prev_start = w_new_start;
+        w_prev_end = w_new_end;
+
+        depth++;
+    } while (count != 0 && depth <= 10);
+
+    return 1;
+}
+
+int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx)
+{
+    if (ctx == NULL || ctx->decoder_insts == NULL)
+        return 0;
+    return sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+}
+
+int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+                                   OSSL_DECODER_CONSTRUCT *construct)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    ctx->construct = construct;
+    return 1;
+}
+
+int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+                                        void *construct_data)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    ctx->construct_data = construct_data;
+    return 1;
+}
+
+int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+                                 OSSL_DECODER_CLEANUP *cleanup)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    ctx->cleanup = cleanup;
+    return 1;
+}
+
+OSSL_DECODER_CONSTRUCT *
+OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+    return ctx->construct;
+}
+
+void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+    return ctx->construct_data;
+}
+
+OSSL_DECODER_CLEANUP *
+OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx)
+{
+    if (ctx == NULL)
+        return NULL;
+    return ctx->cleanup;
+}
+
+int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+                        void *reference, size_t reference_sz,
+                        OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+    if (!(ossl_assert(decoder_inst != NULL)
+          && ossl_assert(reference != NULL)
+          && ossl_assert(export_cb != NULL)
+          && ossl_assert(export_cbarg != NULL))) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return decoder_inst->decoder->export_object(decoder_inst->deserctx,
+                                                reference, reference_sz,
+                                                export_cb, export_cbarg);
+}
+
+OSSL_DECODER *OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+    if (decoder_inst == NULL)
+        return NULL;
+    return decoder_inst->decoder;
+}
+
+void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+    if (decoder_inst == NULL)
+        return NULL;
+    return decoder_inst->deserctx;
+}
+
+static int decoder_process(const OSSL_PARAM params[], void *arg)
+{
+    struct decoder_process_data_st *data = arg;
+    OSSL_DECODER_CTX *ctx = data->ctx;
+    OSSL_DECODER_INSTANCE *decoder_inst = NULL;
+    OSSL_DECODER *decoder = NULL;
+    BIO *bio = data->bio;
+    long loc;
+    size_t i;
+    int ok = 0;
+    /* For recursions */
+    struct decoder_process_data_st new_data;
+
+    memset(&new_data, 0, sizeof(new_data));
+    new_data.ctx = data->ctx;
+
+    if (params == NULL) {
+        /* First iteration, where we prepare for what is to come */
+
+        data->current_deser_inst_index =
+            OSSL_DECODER_CTX_num_decoders(ctx);
+
+        bio = data->bio;
+    } else {
+        const OSSL_PARAM *p;
+
+        decoder_inst =
+            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts,
+                                           data->current_deser_inst_index);
+        decoder = OSSL_DECODER_INSTANCE_decoder(decoder_inst);
+
+        if (ctx->construct != NULL
+            && ctx->construct(decoder_inst, params, ctx->construct_data)) {
+            ok = 1;
+            goto end;
+        }
+
+        /* The constructor didn't return success */
+
+        /*
+         * so we try to use the object we got and feed it to any next
+         * decoder that will take it.  Object references are not
+         * allowed for this.
+         * If this data isn't present, decoding has failed.
+         */
+
+        p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_DATA);
+        if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
+            goto end;
+        new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size);
+        if (new_data.bio == NULL)
+            goto end;
+        bio = new_data.bio;
+    }
+
+    /*
+     * If we have no more decoders to look through at this point,
+     * we failed
+     */
+    if (data->current_deser_inst_index == 0)
+        goto end;
+
+    if ((loc = BIO_tell(bio)) < 0) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB);
+        goto end;
+    }
+
+    for (i = data->current_deser_inst_index; i-- > 0;) {
+        OSSL_DECODER_INSTANCE *new_deser_inst =
+            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+        OSSL_DECODER *new_deser =
+            OSSL_DECODER_INSTANCE_decoder(new_deser_inst);
+
+        /*
+         * If |decoder| is NULL, it means we've just started, and the caller
+         * may have specified what it expects the initial input to be.  If
+         * that's the case, we do this extra check.
+         */
+        if (decoder == NULL && ctx->start_input_type != NULL
+            && strcasecmp(ctx->start_input_type,
+                          new_deser_inst->input_type) != 0)
+            continue;
+
+        /*
+         * If we have a previous decoder, we check that the input type
+         * of the next to be used matches the type of this previous one.
+         * decoder_inst->input_type is a cache of the parameter "input-type"
+         * value for that decoder.
+         */
+        if (decoder != NULL
+            && !OSSL_DECODER_is_a(decoder, new_deser_inst->input_type))
+            continue;
+
+        /*
+         * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
+         * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
+         * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero
+         * no matter where we are in the underlying buffer we're reading from.
+         *
+         * So, we simply do a BIO_seek(), and use BIO_tell() that we're back
+         * at the same position.  This is a best effort attempt, but BIO_seek()
+         * and BIO_tell() should come as a pair...
+         */
+        (void)BIO_seek(bio, loc);
+        if (BIO_tell(bio) != loc)
+            goto end;
+
+        /* Recurse */
+        new_data.current_deser_inst_index = i;
+        ok = new_deser->decode(new_deser_inst->deserctx, (OSSL_CORE_BIO *)bio,
+                               decoder_process, &new_data,
+                               ctx->passphrase_cb, new_data.ctx);
+        if (ok)
+            break;
+    }
+
+ end:
+    BIO_free(new_data.bio);
+    return ok;
+}
diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
new file mode 100644
index 0000000000..2259c6348a
--- /dev/null
+++ b/crypto/encode_decode/decoder_meth.c
@@ -0,0 +1,552 @@
+/*
+ * 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/decoder.h>
+#include <openssl/ui.h>
+#include "internal/core.h"
+#include "internal/namemap.h"
+#include "internal/property.h"
+#include "internal/provider.h"
+#include "crypto/encoder.h"
+#include "encoder_local.h"
+
+static void OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *instance);
+
+/*
+ * Decoder can have multiple names, separated with colons in a name string
+ */
+#define NAME_SEPARATOR ':'
+
+/* Simple method structure constructor and destructor */
+static OSSL_DECODER *ossl_decoder_new(void)
+{
+    OSSL_DECODER *decoder = NULL;
+
+    if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL
+        || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
+        OSSL_DECODER_free(decoder);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    decoder->base.refcnt = 1;
+
+    return decoder;
+}
+
+int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
+{
+    int ref = 0;
+
+    CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
+    return 1;
+}
+
+void OSSL_DECODER_free(OSSL_DECODER *decoder)
+{
+    int ref = 0;
+
+    if (decoder == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock);
+    if (ref > 0)
+        return;
+    ossl_provider_free(decoder->base.prov);
+    CRYPTO_THREAD_lock_free(decoder->base.lock);
+    OPENSSL_free(decoder);
+}
+
+/* Permanent decoder method store, constructor and destructor */
+static void decoder_store_free(void *vstore)
+{
+    ossl_method_store_free(vstore);
+}
+
+static void *decoder_store_new(OPENSSL_CTX *ctx)
+{
+    return ossl_method_store_new(ctx);
+}
+
+
+static const OPENSSL_CTX_METHOD decoder_store_method = {
+    decoder_store_new,
+    decoder_store_free,
+};
+
+/* Data to be passed through ossl_method_construct() */
+struct decoder_data_st {
+    OPENSSL_CTX *libctx;
+    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
+    int id;                      /* For get_decoder_from_store() */
+    const char *names;           /* For get_decoder_from_store() */
+    const char *propquery;       /* For get_decoder_from_store() */
+};
+
+/*
+ * Generic routines to fetch / create DECODER methods with
+ * ossl_method_construct()
+ */
+
+/* Temporary decoder method store, constructor and destructor */
+static void *alloc_tmp_decoder_store(OPENSSL_CTX *ctx)
+{
+    return ossl_method_store_new(ctx);
+}
+
+static void dealloc_tmp_decoder_store(void *store)
+{
+    if (store != NULL)
+        ossl_method_store_free(store);
+}
+
+/* Get the permanent decoder store */
+static OSSL_METHOD_STORE *get_decoder_store(OPENSSL_CTX *libctx)
+{
+    return openssl_ctx_get_data(libctx, OPENSSL_CTX_DECODER_STORE_INDEX,
+                                &decoder_store_method);
+}
+
+/* Get decoder methods from a store, or put one in */
+static void *get_decoder_from_store(OPENSSL_CTX *libctx, void *store,
+                                    void *data)
+{
+    struct decoder_data_st *methdata = data;
+    void *method = NULL;
+    int id;
+
+    if ((id = methdata->id) == 0) {
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        id = ossl_namemap_name2num(namemap, methdata->names);
+    }
+
+    if (store == NULL
+        && (store = get_decoder_store(libctx)) == NULL)
+        return NULL;
+
+    if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
+        return NULL;
+    return method;
+}
+
+static int put_decoder_in_store(OPENSSL_CTX *libctx, void *store,
+                                void *method, const OSSL_PROVIDER *prov,
+                                int operation_id, const char *names,
+                                const char *propdef, void *unused)
+{
+    OSSL_NAMEMAP *namemap;
+    int id;
+
+    if ((namemap = ossl_namemap_stored(libctx)) == NULL
+        || (id = ossl_namemap_name2num(namemap, names)) == 0)
+        return 0;
+
+    if (store == NULL && (store = get_decoder_store(libctx)) == NULL)
+        return 0;
+
+    return ossl_method_store_add(store, prov, id, propdef, method,
+                                 (int (*)(void *))OSSL_DECODER_up_ref,
+                                 (void (*)(void *))OSSL_DECODER_free);
+}
+
+/* Create and populate a decoder method */
+static void *decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
+                                   OSSL_PROVIDER *prov)
+{
+    OSSL_DECODER *decoder = NULL;
+    const OSSL_DISPATCH *fns = algodef->implementation;
+
+    if ((decoder = ossl_decoder_new()) == NULL)
+        return NULL;
+    decoder->base.id = id;
+    decoder->base.propdef = algodef->property_definition;
+
+    for (; fns->function_id != 0; fns++) {
+        switch (fns->function_id) {
+        case OSSL_FUNC_DECODER_NEWCTX:
+            if (decoder->newctx == NULL)
+                decoder->newctx = OSSL_FUNC_decoder_newctx(fns);
+            break;
+        case OSSL_FUNC_DECODER_FREECTX:
+            if (decoder->freectx == NULL)
+                decoder->freectx = OSSL_FUNC_decoder_freectx(fns);
+            break;
+        case OSSL_FUNC_DECODER_GET_PARAMS:
+            if (decoder->get_params == NULL)
+                decoder->get_params =
+                    OSSL_FUNC_decoder_get_params(fns);
+            break;
+        case OSSL_FUNC_DECODER_GETTABLE_PARAMS:
+            if (decoder->gettable_params == NULL)
+                decoder->gettable_params =
+                    OSSL_FUNC_decoder_gettable_params(fns);
+            break;
+        case OSSL_FUNC_DECODER_SET_CTX_PARAMS:
+            if (decoder->set_ctx_params == NULL)
+                decoder->set_ctx_params =
+                    OSSL_FUNC_decoder_set_ctx_params(fns);
+            break;
+        case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS:
+            if (decoder->settable_ctx_params == NULL)
+                decoder->settable_ctx_params =
+                    OSSL_FUNC_decoder_settable_ctx_params(fns);
+            break;
+        case OSSL_FUNC_DECODER_DECODE:
+            if (decoder->decode == NULL)
+                decoder->decode = OSSL_FUNC_decoder_decode(fns);
+            break;
+        case OSSL_FUNC_DECODER_EXPORT_OBJECT:
+            if (decoder->export_object == NULL)
+                decoder->export_object = OSSL_FUNC_decoder_export_object(fns);
+            break;
+        }
+    }
+    /*
+     * Try to check that the method is sensible.
+     * If you have a constructor, you must have a destructor and vice versa.
+     * You must have at least one of the encoding driver functions.
+     */
+    if (!((decoder->newctx == NULL && decoder->freectx == NULL)
+          || (decoder->newctx != NULL && decoder->freectx != NULL))
+        || (decoder->decode == NULL && decoder->export_object == NULL)) {
+        OSSL_DECODER_free(decoder);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
+        return NULL;
+    }
+
+    if (prov != NULL && !ossl_provider_up_ref(prov)) {
+        OSSL_DECODER_free(decoder);
+        return NULL;
+    }
+
+    decoder->base.prov = prov;
+    return decoder;
+}
+
+
+/*
+ * The core fetching functionality passes the names of the implementation.
+ * This function is responsible to getting an identity number for them,
+ * then call decoder_from_dispatch() with that identity number.
+ */
+static void *construct_decoder(const OSSL_ALGORITHM *algodef,
+                               OSSL_PROVIDER *prov, void *unused)
+{
+    /*
+     * This function is only called if get_decoder_from_store() returned
+     * NULL, so it's safe to say that of all the spots to create a new
+     * namemap entry, this is it.  Should the name already exist there, we
+     * know that ossl_namemap_add() will return its corresponding number.
+     */
+    OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    const char *names = algodef->algorithm_names;
+    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+    void *method = NULL;
+
+    if (id != 0)
+        method = decoder_from_dispatch(id, algodef, prov);
+
+    return method;
+}
+
+/* Intermediary function to avoid ugly casts, used below */
+static void destruct_decoder(void *method, void *data)
+{
+    OSSL_DECODER_free(method);
+}
+
+static int up_ref_decoder(void *method)
+{
+    return OSSL_DECODER_up_ref(method);
+}
+
+static void free_decoder(void *method)
+{
+    OSSL_DECODER_free(method);
+}
+
+/* Fetching support.  Can fetch by numeric identity or by name */
+static OSSL_DECODER *inner_ossl_decoder_fetch(OPENSSL_CTX *libctx, int id,
+                                              const char *name,
+                                              const char *properties)
+{
+    OSSL_METHOD_STORE *store = get_decoder_store(libctx);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    void *method = NULL;
+
+    if (store == NULL || namemap == NULL)
+        return NULL;
+
+    /*
+     * If we have been passed neither a name_id or a name, we have an
+     * internal programming error.
+     */
+    if (!ossl_assert(id != 0 || name != NULL))
+        return NULL;
+
+    if (id == 0)
+        id = ossl_namemap_name2num(namemap, name);
+
+    if (id == 0
+        || !ossl_method_store_cache_get(store, id, properties, &method)) {
+        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
+            alloc_tmp_decoder_store,
+            dealloc_tmp_decoder_store,
+            get_decoder_from_store,
+            put_decoder_in_store,
+            construct_decoder,
+            destruct_decoder
+        };
+        struct decoder_data_st mcmdata;
+
+        mcmdata.libctx = libctx;
+        mcmdata.mcm = &mcm;
+        mcmdata.id = id;
+        mcmdata.names = name;
+        mcmdata.propquery = properties;
+        if ((method = ossl_method_construct(libctx, OSSL_OP_DECODER,
+                                            0 /* !force_cache */,
+                                            &mcm, &mcmdata)) != NULL) {
+            /*
+             * If construction did create a method for us, we know that
+             * there is a correct name_id and meth_id, since those have
+             * already been calculated in get_decoder_from_store() and
+             * put_decoder_in_store() above.
+             */
+            if (id == 0)
+                id = ossl_namemap_name2num(namemap, name);
+            ossl_method_store_cache_set(store, id, properties, method,
+                                        up_ref_decoder, free_decoder);
+        }
+    }
+
+    return method;
+}
+
+OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *libctx, const char *name,
+                                 const char *properties)
+{
+    return inner_ossl_decoder_fetch(libctx, 0, name, properties);
+}
+
+OSSL_DECODER *ossl_decoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties)
+{
+    return inner_ossl_decoder_fetch(libctx, id, NULL, properties);
+}
+
+/*
+ * Library of basic method functions
+ */
+
+const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *decoder)
+{
+    if (!ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return decoder->base.prov;
+}
+
+const char *OSSL_DECODER_properties(const OSSL_DECODER *decoder)
+{
+    if (!ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return decoder->base.propdef;
+}
+
+int OSSL_DECODER_number(const OSSL_DECODER *decoder)
+{
+    if (!ossl_assert(decoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return decoder->base.id;
+}
+
+int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name)
+{
+    if (decoder->base.prov != NULL) {
+        OPENSSL_CTX *libctx = ossl_provider_library_context(decoder->base.prov);
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        return ossl_namemap_name2num(namemap, name) == decoder->base.id;
+    }
+    return 0;
+}
+
+struct decoder_do_all_data_st {
+    void (*user_fn)(void *method, void *arg);
+    void *user_arg;
+};
+
+static void decoder_do_one(OSSL_PROVIDER *provider,
+                           const OSSL_ALGORITHM *algodef,
+                           int no_store, void *vdata)
+{
+    struct decoder_do_all_data_st *data = vdata;
+    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    const char *names = algodef->algorithm_names;
+    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+    void *method = NULL;
+
+    if (id != 0)
+        method =
+            decoder_from_dispatch(id, algodef, provider);
+
+    if (method != NULL) {
+        data->user_fn(method, data->user_arg);
+        OSSL_DECODER_free(method);
+    }
+}
+
+void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+                                  void (*fn)(OSSL_DECODER *decoder, void *arg),
+                                  void *arg)
+{
+    struct decoder_do_all_data_st data;
+
+    data.user_fn = (void (*)(void *, void *))fn;
+    data.user_arg = arg;
+    ossl_algorithm_do_all(libctx, OSSL_OP_DECODER, NULL,
+                          NULL, decoder_do_one, NULL,
+                          &data);
+}
+
+void OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
+                               void (*fn)(const char *name, void *data),
+                               void *data)
+{
+    if (decoder == NULL)
+        return;
+
+    if (decoder->base.prov != NULL) {
+        OPENSSL_CTX *libctx = ossl_provider_library_context(decoder->base.prov);
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        ossl_namemap_doall_names(namemap, decoder->base.id, fn, data);
+    }
+}
+
+const OSSL_PARAM *
+OSSL_DECODER_gettable_params(OSSL_DECODER *decoder)
+{
+    if (decoder != NULL && decoder->gettable_params != NULL) {
+        void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder));
+
+        return decoder->gettable_params(provctx);
+    }
+    return NULL;
+}
+
+int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[])
+{
+    if (decoder != NULL && decoder->get_params != NULL)
+        return decoder->get_params(params);
+    return 0;
+}
+
+const OSSL_PARAM *
+OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder)
+{
+    if (decoder != NULL && decoder->settable_ctx_params != NULL) {
+        void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder));
+
+        return decoder->settable_ctx_params(provctx);
+    }
+    return NULL;
+}
+
+/*
+ * Decoder context support
+ */
+
+/*
+ * |encoder| value NULL is valid, and signifies that there is no decoder.
+ * This is useful to provide fallback mechanisms.
+ *  Functions that want to verify if there is a decoder can do so with
+ * OSSL_DECODER_CTX_get_decoder()
+ */
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void)
+{
+    OSSL_DECODER_CTX *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ctx->passphrase_cb = ossl_decoder_passphrase_in_cb;
+    return ctx;
+}
+
+int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+                                const OSSL_PARAM params[])
+{
+    size_t i;
+    size_t l;
+
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (ctx->decoder_insts == NULL)
+        return 1;
+
+    l = (size_t)sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+    for (i = 0; i < l; i++) {
+        OSSL_DECODER_INSTANCE *decoder_inst =
+            sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+
+        if (decoder_inst->deserctx == NULL
+            || decoder_inst->decoder->set_ctx_params == NULL)
+            continue;
+        if (!decoder_inst->decoder->set_ctx_params(decoder_inst->deserctx, params))
+            return 0;
+    }
+    return 1;
+}
+
+static void
+OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *decoder_inst)
+{
+    if (decoder_inst != NULL) {
+        if (decoder_inst->decoder->freectx != NULL)
+            decoder_inst->decoder->freectx(decoder_inst->deserctx);
+        decoder_inst->deserctx = NULL;
+        OSSL_DECODER_free(decoder_inst->decoder);
+        decoder_inst->decoder = NULL;
+        OPENSSL_free(decoder_inst);
+        decoder_inst = NULL;
+    }
+}
+
+void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx)
+{
+    if (ctx != NULL) {
+        if (ctx->cleanup != NULL)
+            ctx->cleanup(ctx->construct_data);
+        sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts,
+                                          OSSL_DECODER_INSTANCE_free);
+        OSSL_DECODER_CTX_set_passphrase_ui(ctx, NULL, NULL);
+        OSSL_DECODER_CTX_set_passphrase(ctx, NULL, 0);
+        OPENSSL_free(ctx);
+    }
+}
diff --git a/crypto/serializer/deserializer_pkey.c b/crypto/encode_decode/decoder_pkey.c
similarity index 65%
rename from crypto/serializer/deserializer_pkey.c
rename to crypto/encode_decode/decoder_pkey.c
index 6375a29e36..7f468c2476 100644
--- a/crypto/serializer/deserializer_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -10,17 +10,17 @@
 #include <openssl/core_names.h>
 #include <openssl/evp.h>
 #include <openssl/ui.h>
-#include <openssl/deserializer.h>
+#include <openssl/decoder.h>
 #include <openssl/safestack.h>
 #include "crypto/evp.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
-                                         const unsigned char *kstr,
-                                         size_t klen)
+int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+                                    const unsigned char *kstr,
+                                    size_t klen)
 {
     if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
@@ -36,7 +36,7 @@ int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
             ctx->cached_passphrase_len = klen;
         }
         if (ctx->cached_passphrase == NULL) {
-            ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
             return 0;
         }
     }
@@ -44,7 +44,7 @@ int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
     return 1;
 }
 
-static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx)
+static void decoder_ctx_reset_passphrase_ui(OSSL_DECODER_CTX *ctx)
 {
     UI_destroy_method(ctx->allocated_ui_method);
     ctx->allocated_ui_method = NULL;
@@ -52,28 +52,28 @@ static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx)
     ctx->ui_data = NULL;
 }
 
-int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
-                                            const UI_METHOD *ui_method,
-                                            void *ui_data)
+int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+                                       const UI_METHOD *ui_method,
+                                       void *ui_data)
 {
     if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
-    deserializer_ctx_reset_passphrase_ui(ctx);
+    decoder_ctx_reset_passphrase_ui(ctx);
     ctx->ui_method = ui_method;
     ctx->ui_data = ui_data;
     return 1;
 }
 
-int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                              pem_password_cb *cb, void *cbarg)
+int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+                                         pem_password_cb *cb, void *cbarg)
 {
     UI_METHOD *ui_method = NULL;
 
     if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
@@ -84,10 +84,10 @@ int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
      */
     if (cb == NULL
         || (ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) != NULL) {
-        deserializer_ctx_reset_passphrase_ui(ctx);
+        decoder_ctx_reset_passphrase_ui(ctx);
         ctx->ui_method = ctx->allocated_ui_method = ui_method;
         ctx->ui_data = cbarg;
-        ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
+        ctx->passphrase_cb = ossl_decoder_passphrase_in_cb;
         return 1;
     }
 
@@ -95,26 +95,26 @@ int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
 }
 
 /*
- * Support for OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY:
+ * Support for OSSL_DECODER_CTX_new_by_EVP_PKEY:
  * The construct data, and collecting keymgmt information for it
  */
 
 DEFINE_STACK_OF(EVP_KEYMGMT)
 
-struct deser_EVP_PKEY_data_st {
+struct decoder_EVP_PKEY_data_st {
     char *object_type;           /* recorded object data type, may be NULL */
     void **object;               /* Where the result should end up */
     STACK_OF(EVP_KEYMGMT) *keymgmts; /* The EVP_KEYMGMTs we handle */
 };
 
-static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
-                                    const OSSL_PARAM *params,
-                                    void *construct_data)
+static int decoder_construct_EVP_PKEY(OSSL_DECODER_INSTANCE *decoder_inst,
+                                      const OSSL_PARAM *params,
+                                      void *construct_data)
 {
-    struct deser_EVP_PKEY_data_st *data = construct_data;
-    OSSL_DESERIALIZER *deser =
-        OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst);
-    void *deserctx = OSSL_DESERIALIZER_INSTANCE_deserializer_ctx(deser_inst);
+    struct decoder_EVP_PKEY_data_st *data = construct_data;
+    OSSL_DECODER *decoder =
+        OSSL_DECODER_INSTANCE_decoder(decoder_inst);
+    void *deserctx = OSSL_DECODER_INSTANCE_decoder_ctx(decoder_inst);
     size_t i, end_i;
     /*
      * |object_ref| points to a provider reference to an object, its exact
@@ -128,7 +128,7 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
     size_t object_ref_sz = 0;
     const OSSL_PARAM *p;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA_TYPE);
+    p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_DATA_TYPE);
     if (p != NULL) {
         char *object_type = NULL;
 
@@ -143,7 +143,7 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
      * reference for the moment.  This enforces that the key data itself
      * remains with the provider.
      */
-    p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_REFERENCE);
+    p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_REFERENCE);
     if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
         return 0;
     object_ref = p->data;
@@ -160,35 +160,35 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
          * 1.  If the object data type (recorded in |data->object_type|)
          *     is defined, by checking it using EVP_KEYMGMT_is_a().
          * 2.  If the object data type is NOT defined, by comparing the
-         *     EVP_KEYMGMT and OSSL_DESERIALIZER method numbers.  Since
-         *     EVP_KEYMGMT and OSSL_DESERIALIZE operate with the same
+         *     EVP_KEYMGMT and OSSL_DECODER method numbers.  Since
+         *     EVP_KEYMGMT and OSSL_DECODE operate with the same
          *     namemap, we know that the method numbers must match.
          *
-         * This allows individual deserializers to specify variants of keys,
-         * such as a DER to RSA deserializer finding a RSA-PSS key, without
-         * having to deserialize the exact same DER blob into the exact same
+         * This allows individual decoders to specify variants of keys,
+         * such as a DER to RSA decoder finding a RSA-PSS key, without
+         * having to decode the exact same DER blob into the exact same
          * internal structure twice.  This is, of course, entirely at the
-         * discretion of the deserializer implementations.
+         * discretion of the decoder implementations.
          */
         if (data->object_type != NULL
             ? EVP_KEYMGMT_is_a(keymgmt, data->object_type)
-            : EVP_KEYMGMT_number(keymgmt) == OSSL_DESERIALIZER_number(deser)) {
+            : EVP_KEYMGMT_number(keymgmt) == OSSL_DECODER_number(decoder)) {
             EVP_PKEY *pkey = NULL;
             void *keydata = NULL;
             const OSSL_PROVIDER *keymgmt_prov =
                 EVP_KEYMGMT_provider(keymgmt);
-            const OSSL_PROVIDER *deser_prov =
-                OSSL_DESERIALIZER_provider(deser);
+            const OSSL_PROVIDER *decoder_prov =
+                OSSL_DECODER_provider(decoder);
 
             /*
-             * If the EVP_KEYMGMT and the OSSL_DESERIALIZER are from the
+             * If the EVP_KEYMGMT and the OSSL_DECODER are from the
              * same provider, we assume that the KEYMGMT has a key loading
              * function that can handle the provider reference we hold.
              *
-             * Otherwise, we export from the deserializer and import the
+             * Otherwise, we export from the decoder and import the
              * result in the keymgmt.
              */
-            if (keymgmt_prov == deser_prov) {
+            if (keymgmt_prov == decoder_prov) {
                 keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz);
             } else {
                 struct evp_keymgmt_util_try_import_data_st import_data;
@@ -201,9 +201,9 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
                  * No need to check for errors here, the value of
                  * |import_data.keydata| is as much an indicator.
                  */
-                (void)deser->export_object(deserctx, object_ref, object_ref_sz,
-                                           &evp_keymgmt_util_try_import,
-                                           &import_data);
+                (void)decoder->export_object(deserctx, object_ref, object_ref_sz,
+                                             &evp_keymgmt_util_try_import,
+                                             &import_data);
                 keydata = import_data.keydata;
                 import_data.keydata = NULL;
             }
@@ -225,9 +225,9 @@ static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst,
     return (*data->object != NULL);
 }
 
-static void deser_clean_EVP_PKEY_construct_arg(void *construct_data)
+static void decoder_clean_EVP_PKEY_construct_arg(void *construct_data)
 {
-    struct deser_EVP_PKEY_data_st *data = construct_data;
+    struct decoder_EVP_PKEY_data_st *data = construct_data;
 
     if (data != NULL) {
         sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free);
@@ -239,9 +239,9 @@ static void deser_clean_EVP_PKEY_construct_arg(void *construct_data)
 DEFINE_STACK_OF_CSTRING()
 
 struct collected_data_st {
-    struct deser_EVP_PKEY_data_st *process_data;
+    struct decoder_EVP_PKEY_data_st *process_data;
     STACK_OF(OPENSSL_CSTRING) *names;
-    OSSL_DESERIALIZER_CTX *ctx;
+    OSSL_DECODER_CTX *ctx;
 
     unsigned int error_occured:1;
 };
@@ -280,7 +280,7 @@ static void collect_name(const char *name, void *arg)
     data->error_occured = 0;         /* All is good now */
 }
 
-static void collect_deserializer(OSSL_DESERIALIZER *deser, void *arg)
+static void collect_decoder(OSSL_DECODER *decoder, void *arg)
 {
     struct collected_data_st *data = arg;
     size_t i, end_i;
@@ -294,37 +294,36 @@ static void collect_deserializer(OSSL_DESERIALIZER *deser, void *arg)
     for (i = 0; i < end_i; i++) {
         const char *name = sk_OPENSSL_CSTRING_value(data->names, i);
 
-        if (!OSSL_DESERIALIZER_is_a(deser, name))
+        if (!OSSL_DECODER_is_a(decoder, name))
             continue;
-        (void)OSSL_DESERIALIZER_CTX_add_deserializer(data->ctx, deser);
+        (void)OSSL_DECODER_CTX_add_decoder(data->ctx, decoder);
     }
 
     data->error_occured = 0;         /* All is good now */
 }
 
-OSSL_DESERIALIZER_CTX *
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
-                                      const char *input_type,
-                                      OPENSSL_CTX *libctx,
-                                      const char *propquery)
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
+                                                   const char *input_type,
+                                                   OPENSSL_CTX *libctx,
+                                                   const char *propquery)
 {
-    OSSL_DESERIALIZER_CTX *ctx = NULL;
+    OSSL_DECODER_CTX *ctx = NULL;
     struct collected_data_st *data = NULL;
     size_t i, end_i;
 
-    if ((ctx = OSSL_DESERIALIZER_CTX_new()) == NULL
+    if ((ctx = OSSL_DECODER_CTX_new()) == NULL
         || (data = OPENSSL_zalloc(sizeof(*data))) == NULL
         || (data->process_data =
             OPENSSL_zalloc(sizeof(*data->process_data))) == NULL
         || (data->process_data->keymgmts
             = sk_EVP_KEYMGMT_new_null()) == NULL
         || (data->names = sk_OPENSSL_CSTRING_new_null()) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     data->process_data->object = (void **)pkey;
     data->ctx = ctx;
-    OSSL_DESERIALIZER_CTX_set_input_type(ctx, input_type);
+    OSSL_DECODER_CTX_set_input_type(ctx, input_type);
 
     /* First, find all keymgmts to form goals */
     EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data);
@@ -345,30 +344,30 @@ OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey,
     }
 
     /*
-     * Finally, find all deserializers that have any keymgmt of the collected
+     * Finally, find all decoders that have any keymgmt of the collected
      * keymgmt names
      */
-    OSSL_DESERIALIZER_do_all_provided(libctx, collect_deserializer, data);
+    OSSL_DECODER_do_all_provided(libctx, collect_decoder, data);
 
     if (data->error_occured)
         goto err;
 
-    /* If we found no deserializers to match the keymgmts, we err */
-    if (OSSL_DESERIALIZER_CTX_num_deserializers(ctx) == 0)
+    /* If we found no decoders to match the keymgmts, we err */
+    if (OSSL_DECODER_CTX_num_decoders(ctx) == 0)
         goto err;
 
-    /* Finally, collect extra deserializers based on what we already have */
-    (void)OSSL_DESERIALIZER_CTX_add_extra(ctx, libctx, propquery);
+    /* Finally, collect extra decoders based on what we already have */
+    (void)OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery);
 
-    if (!OSSL_DESERIALIZER_CTX_set_construct(ctx, deser_construct_EVP_PKEY)
-        || !OSSL_DESERIALIZER_CTX_set_construct_data(ctx, data->process_data)
-        || !OSSL_DESERIALIZER_CTX_set_cleanup
-                (ctx, deser_clean_EVP_PKEY_construct_arg))
+    if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY)
+        || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data)
+        || !OSSL_DECODER_CTX_set_cleanup(ctx,
+                                         decoder_clean_EVP_PKEY_construct_arg))
         goto err;
 
     data->process_data = NULL;
  err:
-    deser_clean_EVP_PKEY_construct_arg(data->process_data);
+    decoder_clean_EVP_PKEY_construct_arg(data->process_data);
     sk_OPENSSL_CSTRING_free(data->names);
     OPENSSL_free(data);
     return ctx;
diff --git a/crypto/serializer/deserializer_err.c b/crypto/encode_decode/encoder_err.c
similarity index 51%
rename from crypto/serializer/deserializer_err.c
rename to crypto/encode_decode/encoder_err.c
index 2cc245996f..5416f8390e 100644
--- a/crypto/serializer/deserializer_err.c
+++ b/crypto/encode_decode/encoder_err.c
@@ -9,23 +9,25 @@
  */
 
 #include <openssl/err.h>
-#include <openssl/deserializererr.h>
+#include <openssl/encodererr.h>
 
 #ifndef OPENSSL_NO_ERR
 
-static const ERR_STRING_DATA OSSL_DESERIALIZER_str_reasons[] = {
-    {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, OSSL_DESERIALIZER_R_MISSING_GET_PARAMS),
-    "missing get params"},
+static const ERR_STRING_DATA OSSL_ENCODER_str_reasons[] = {
+    {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY),
+     "incorrect property query"},
+    {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_ENCODER_NOT_FOUND),
+     "encoder not found"},
     {0, NULL}
 };
 
 #endif
 
-int ERR_load_OSSL_DESERIALIZER_strings(void)
+int ERR_load_OSSL_ENCODER_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
-    if (ERR_reason_error_string(OSSL_DESERIALIZER_str_reasons[0].error) == NULL)
-        ERR_load_strings_const(OSSL_DESERIALIZER_str_reasons);
+    if (ERR_reason_error_string(OSSL_ENCODER_str_reasons[0].error) == NULL)
+        ERR_load_strings_const(OSSL_ENCODER_str_reasons);
 #endif
     return 1;
 }
diff --git a/crypto/serializer/serializer_lib.c b/crypto/encode_decode/encoder_lib.c
similarity index 71%
rename from crypto/serializer/serializer_lib.c
rename to crypto/encode_decode/encoder_lib.c
index 932ef1e3ae..b083fa2d4c 100644
--- a/crypto/serializer/serializer_lib.c
+++ b/crypto/encode_decode/encoder_lib.c
@@ -8,10 +8,10 @@
  */
 
 #include <openssl/bio.h>
-#include <openssl/serializer.h>
-#include "serializer_local.h"
+#include <openssl/encoder.h>
+#include "encoder_local.h"
 
-int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
+int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out)
 {
     return ctx->do_output(ctx, out);
 }
@@ -22,20 +22,20 @@ static BIO *bio_from_file(FILE *fp)
     BIO *b;
 
     if ((b = BIO_new(BIO_s_file())) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_BUF_LIB);
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_BUF_LIB);
         return NULL;
     }
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     return b;
 }
 
-int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp)
+int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp)
 {
     BIO *b = bio_from_file(fp);
     int ret = 0;
 
     if (b != NULL)
-        ret = OSSL_SERIALIZER_to_bio(ctx, b);
+        ret = OSSL_ENCODER_to_bio(ctx, b);
 
     BIO_free(b);
     return ret;
diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h
new file mode 100644
index 0000000000..34931d4e43
--- /dev/null
+++ b/crypto/encode_decode/encoder_local.h
@@ -0,0 +1,140 @@
+/*
+ * 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_dispatch.h>
+#include <openssl/types.h>
+#include <openssl/safestack.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
+#include "internal/cryptlib.h"
+#include "internal/refcount.h"
+
+struct ossl_serdes_base_st {
+    OSSL_PROVIDER *prov;
+    int id;
+    const char *propdef;
+
+    CRYPTO_REF_COUNT refcnt;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct ossl_encoder_st {
+    struct ossl_serdes_base_st base;
+    OSSL_FUNC_encoder_newctx_fn *newctx;
+    OSSL_FUNC_encoder_freectx_fn *freectx;
+    OSSL_FUNC_encoder_set_ctx_params_fn *set_ctx_params;
+    OSSL_FUNC_encoder_settable_ctx_params_fn *settable_ctx_params;
+    OSSL_FUNC_encoder_encode_data_fn *encode_data;
+    OSSL_FUNC_encoder_encode_object_fn *encode_object;
+};
+
+struct ossl_decoder_st {
+    struct ossl_serdes_base_st base;
+    OSSL_FUNC_decoder_newctx_fn *newctx;
+    OSSL_FUNC_decoder_freectx_fn *freectx;
+    OSSL_FUNC_decoder_get_params_fn *get_params;
+    OSSL_FUNC_decoder_gettable_params_fn *gettable_params;
+    OSSL_FUNC_decoder_set_ctx_params_fn *set_ctx_params;
+    OSSL_FUNC_decoder_settable_ctx_params_fn *settable_ctx_params;
+    OSSL_FUNC_decoder_decode_fn *decode;
+    OSSL_FUNC_decoder_export_object_fn *export_object;
+};
+
+struct ossl_encoder_ctx_st {
+    OSSL_ENCODER *encoder;
+    void *serctx;
+
+    int selection;
+
+    /*-
+     * Output / encoding data, used by OSSL_ENCODER_to_{bio,fp}
+     *
+     * |object|         is the libcrypto object to handle.
+     * |do_output|      performs the actual encoding.
+     *
+     * |do_output| must have intimate knowledge of |object|.
+     */
+    const void *object;
+    int (*do_output)(OSSL_ENCODER_CTX *ctx, BIO *out);
+
+    /* For any function that needs a passphrase reader */
+    const UI_METHOD *ui_method;
+    void *ui_data;
+    /*
+     * if caller used OSSL_ENCODER_CTX_set_passphrase_cb(), we need
+     * intermediary storage.
+     */
+    UI_METHOD *allocated_ui_method;
+};
+
+struct ossl_decoder_instance_st {
+    OSSL_DECODER *decoder;    /* Never NULL */
+    void *deserctx;              /* Never NULL */
+    const char *input_type;      /* Never NULL */
+};
+
+DEFINE_STACK_OF(OSSL_DECODER_INSTANCE)
+
+struct ossl_decoder_ctx_st {
+    /*
+     * The caller may know the input type of the data they pass.  If not,
+     * this will remain NULL and the decoding functionality will start
+     * with trying to decode with any desencoder in |decoder_insts|,
+     * regardless of their respective input type.
+     */
+    const char *start_input_type;
+
+    /*
+     * Decoders that are components of any current decoding path.
+     */
+    STACK_OF(OSSL_DECODER_INSTANCE) *decoder_insts;
+
+    /*
+     * The constructors of a decoding, and its caller argument.
+     */
+    OSSL_DECODER_CONSTRUCT *construct;
+    OSSL_DECODER_CLEANUP *cleanup;
+    void *construct_data;
+
+    /* For any function that needs a passphrase reader */
+    OSSL_PASSPHRASE_CALLBACK *passphrase_cb;
+    const UI_METHOD *ui_method;
+    void *ui_data;
+    /*
+     * if caller used OSSL_ENCODER_CTX_set_pem_password_cb(), we need
+     * intermediary storage.
+     */
+    UI_METHOD *allocated_ui_method;
+    /*
+     * Because the same input may pass through more than one decoder,
+     * we cache any passphrase passed to us.  The desrializing processor
+     * must clear this at the end of a run.
+     */
+    unsigned char *cached_passphrase;
+    size_t cached_passphrase_len;
+
+    /*
+     * Flag section.  Keep these together
+     */
+
+    /*
+     * The passphrase was passed to us by the user.  In that case, it
+     * should only be freed when freeing this context.
+     */
+    unsigned int flag_user_passphrase:1;
+};
+
+/* Passphrase callbacks, found in serdes_pass.c */
+
+/*
+ * Encoders typically want to get an outgoing passphrase, while
+ * decoders typically want to get en incoming passphrase.
+ */
+OSSL_PASSPHRASE_CALLBACK ossl_encoder_passphrase_out_cb;
+OSSL_PASSPHRASE_CALLBACK ossl_decoder_passphrase_in_cb;
diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c
new file mode 100644
index 0000000000..ef3c24433e
--- /dev/null
+++ b/crypto/encode_decode/encoder_meth.c
@@ -0,0 +1,523 @@
+/*
+ * 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/encoder.h>
+#include <openssl/ui.h>
+#include "internal/core.h"
+#include "internal/namemap.h"
+#include "internal/property.h"
+#include "internal/provider.h"
+#include "crypto/encoder.h"
+#include "encoder_local.h"
+
+/*
+ * Encoder can have multiple names, separated with colons in a name string
+ */
+#define NAME_SEPARATOR ':'
+
+/* Simple method structure constructor and destructor */
+static OSSL_ENCODER *ossl_encoder_new(void)
+{
+    OSSL_ENCODER *encoder = NULL;
+
+    if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL
+        || (encoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
+        OSSL_ENCODER_free(encoder);
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    encoder->base.refcnt = 1;
+
+    return encoder;
+}
+
+int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder)
+{
+    int ref = 0;
+
+    CRYPTO_UP_REF(&encoder->base.refcnt, &ref, encoder->base.lock);
+    return 1;
+}
+
+void OSSL_ENCODER_free(OSSL_ENCODER *encoder)
+{
+    int ref = 0;
+
+    if (encoder == NULL)
+        return;
+
+    CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref, encoder->base.lock);
+    if (ref > 0)
+        return;
+    ossl_provider_free(encoder->base.prov);
+    CRYPTO_THREAD_lock_free(encoder->base.lock);
+    OPENSSL_free(encoder);
+}
+
+/* Permanent encoder method store, constructor and destructor */
+static void encoder_store_free(void *vstore)
+{
+    ossl_method_store_free(vstore);
+}
+
+static void *encoder_store_new(OPENSSL_CTX *ctx)
+{
+    return ossl_method_store_new(ctx);
+}
+
+
+static const OPENSSL_CTX_METHOD encoder_store_method = {
+    encoder_store_new,
+    encoder_store_free,
+};
+
+/* Data to be passed through ossl_method_construct() */
+struct encoder_data_st {
+    OPENSSL_CTX *libctx;
+    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
+    int id;                      /* For get_encoder_from_store() */
+    const char *names;           /* For get_encoder_from_store() */
+    const char *propquery;       /* For get_encoder_from_store() */
+};
+
+/*
+ * Generic routines to fetch / create ENCODER methods with
+ * ossl_method_construct()
+ */
+
+/* Temporary encoder method store, constructor and destructor */
+static void *alloc_tmp_encoder_store(OPENSSL_CTX *ctx)
+{
+    return ossl_method_store_new(ctx);
+}
+
+static void dealloc_tmp_encoder_store(void *store)
+{
+    if (store != NULL)
+        ossl_method_store_free(store);
+}
+
+/* Get the permanent encoder store */
+static OSSL_METHOD_STORE *get_encoder_store(OPENSSL_CTX *libctx)
+{
+    return openssl_ctx_get_data(libctx, OPENSSL_CTX_ENCODER_STORE_INDEX,
+                                &encoder_store_method);
+}
+
+/* Get encoder methods from a store, or put one in */
+static void *get_encoder_from_store(OPENSSL_CTX *libctx, void *store,
+                                    void *data)
+{
+    struct encoder_data_st *methdata = data;
+    void *method = NULL;
+    int id;
+
+    if ((id = methdata->id) == 0) {
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        id = ossl_namemap_name2num(namemap, methdata->names);
+    }
+
+    if (store == NULL
+        && (store = get_encoder_store(libctx)) == NULL)
+        return NULL;
+
+    if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
+        return NULL;
+    return method;
+}
+
+static int put_encoder_in_store(OPENSSL_CTX *libctx, void *store,
+                                void *method, const OSSL_PROVIDER *prov,
+                                int operation_id, const char *names,
+                                const char *propdef, void *unused)
+{
+    OSSL_NAMEMAP *namemap;
+    int id;
+
+    if ((namemap = ossl_namemap_stored(libctx)) == NULL
+        || (id = ossl_namemap_name2num(namemap, names)) == 0)
+        return 0;
+
+    if (store == NULL && (store = get_encoder_store(libctx)) == NULL)
+        return 0;
+
+    return ossl_method_store_add(store, prov, id, propdef, method,
+                                 (int (*)(void *))OSSL_ENCODER_up_ref,
+                                 (void (*)(void *))OSSL_ENCODER_free);
+}
+
+/* Create and populate a encoder method */
+static void *encoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
+                                   OSSL_PROVIDER *prov)
+{
+    OSSL_ENCODER *encoder = NULL;
+    const OSSL_DISPATCH *fns = algodef->implementation;
+
+    if ((encoder = ossl_encoder_new()) == NULL)
+        return NULL;
+    encoder->base.id = id;
+    encoder->base.propdef = algodef->property_definition;
+
+    for (; fns->function_id != 0; fns++) {
+        switch (fns->function_id) {
+        case OSSL_FUNC_ENCODER_NEWCTX:
+            if (encoder->newctx == NULL)
+                encoder->newctx =
+                    OSSL_FUNC_encoder_newctx(fns);
+            break;
+        case OSSL_FUNC_ENCODER_FREECTX:
+            if (encoder->freectx == NULL)
+                encoder->freectx =
+                    OSSL_FUNC_encoder_freectx(fns);
+            break;
+        case OSSL_FUNC_ENCODER_SET_CTX_PARAMS:
+            if (encoder->set_ctx_params == NULL)
+                encoder->set_ctx_params =
+                    OSSL_FUNC_encoder_set_ctx_params(fns);
+            break;
+        case OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS:
+            if (encoder->settable_ctx_params == NULL)
+                encoder->settable_ctx_params =
+                    OSSL_FUNC_encoder_settable_ctx_params(fns);
+            break;
+        case OSSL_FUNC_ENCODER_ENCODE_DATA:
+            if (encoder->encode_data == NULL)
+                encoder->encode_data =
+                    OSSL_FUNC_encoder_encode_data(fns);
+            break;
+        case OSSL_FUNC_ENCODER_ENCODE_OBJECT:
+            if (encoder->encode_object == NULL)
+                encoder->encode_object =
+                    OSSL_FUNC_encoder_encode_object(fns);
+            break;
+        }
+    }
+    /*
+     * Try to check that the method is sensible.
+     * If you have a constructor, you must have a destructor and vice versa.
+     * You must have at least one of the encoding driver functions.
+     */
+    if (!((encoder->newctx == NULL && encoder->freectx == NULL)
+          || (encoder->newctx != NULL && encoder->freectx != NULL))
+        || (encoder->encode_data == NULL && encoder->encode_object == NULL)) {
+        OSSL_ENCODER_free(encoder);
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
+        return NULL;
+    }
+
+    if (prov != NULL && !ossl_provider_up_ref(prov)) {
+        OSSL_ENCODER_free(encoder);
+        return NULL;
+    }
+
+    encoder->base.prov = prov;
+    return encoder;
+}
+
+
+/*
+ * The core fetching functionality passes the names of the implementation.
+ * This function is responsible to getting an identity number for them,
+ * then call encoder_from_dispatch() with that identity number.
+ */
+static void *construct_encoder(const OSSL_ALGORITHM *algodef,
+                               OSSL_PROVIDER *prov, void *unused)
+{
+    /*
+     * This function is only called if get_encoder_from_store() returned
+     * NULL, so it's safe to say that of all the spots to create a new
+     * namemap entry, this is it.  Should the name already exist there, we
+     * know that ossl_namemap_add() will return its corresponding number.
+     */
+    OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    const char *names = algodef->algorithm_names;
+    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+    void *method = NULL;
+
+    if (id != 0)
+        method = encoder_from_dispatch(id, algodef, prov);
+
+    return method;
+}
+
+/* Intermediary function to avoid ugly casts, used below */
+static void destruct_encoder(void *method, void *data)
+{
+    OSSL_ENCODER_free(method);
+}
+
+static int up_ref_encoder(void *method)
+{
+    return OSSL_ENCODER_up_ref(method);
+}
+
+static void free_encoder(void *method)
+{
+    OSSL_ENCODER_free(method);
+}
+
+/* Fetching support.  Can fetch by numeric identity or by name */
+static OSSL_ENCODER *inner_ossl_encoder_fetch(OPENSSL_CTX *libctx,
+                                              int id, const char *name,
+                                              const char *properties)
+{
+    OSSL_METHOD_STORE *store = get_encoder_store(libctx);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    void *method = NULL;
+
+    if (store == NULL || namemap == NULL)
+        return NULL;
+
+    /*
+     * If we have been passed neither a name_id or a name, we have an
+     * internal programming error.
+     */
+    if (!ossl_assert(id != 0 || name != NULL))
+        return NULL;
+
+    if (id == 0)
+        id = ossl_namemap_name2num(namemap, name);
+
+    if (id == 0
+        || !ossl_method_store_cache_get(store, id, properties, &method)) {
+        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
+            alloc_tmp_encoder_store,
+            dealloc_tmp_encoder_store,
+            get_encoder_from_store,
+            put_encoder_in_store,
+            construct_encoder,
+            destruct_encoder
+        };
+        struct encoder_data_st mcmdata;
+
+        mcmdata.libctx = libctx;
+        mcmdata.mcm = &mcm;
+        mcmdata.id = id;
+        mcmdata.names = name;
+        mcmdata.propquery = properties;
+        if ((method = ossl_method_construct(libctx, OSSL_OP_ENCODER,
+                                            0 /* !force_cache */,
+                                            &mcm, &mcmdata)) != NULL) {
+            /*
+             * If construction did create a method for us, we know that
+             * there is a correct name_id and meth_id, since those have
+             * already been calculated in get_encoder_from_store() and
+             * put_encoder_in_store() above.
+             */
+            if (id == 0)
+                id = ossl_namemap_name2num(namemap, name);
+            ossl_method_store_cache_set(store, id, properties, method,
+                                        up_ref_encoder, free_encoder);
+        }
+    }
+
+    return method;
+}
+
+OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *libctx, const char *name,
+                                 const char *properties)
+{
+    return inner_ossl_encoder_fetch(libctx, 0, name, properties);
+}
+
+OSSL_ENCODER *ossl_encoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties)
+{
+    return inner_ossl_encoder_fetch(libctx, id, NULL, properties);
+}
+
+/*
+ * Library of basic method functions
+ */
+
+const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder)
+{
+    if (!ossl_assert(encoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return encoder->base.prov;
+}
+
+const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder)
+{
+    if (!ossl_assert(encoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return encoder->base.propdef;
+}
+
+int OSSL_ENCODER_number(const OSSL_ENCODER *encoder)
+{
+    if (!ossl_assert(encoder != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return encoder->base.id;
+}
+
+int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name)
+{
+    if (encoder->base.prov != NULL) {
+        OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        return ossl_namemap_name2num(namemap, name) == encoder->base.id;
+    }
+    return 0;
+}
+
+struct encoder_do_all_data_st {
+    void (*user_fn)(void *method, void *arg);
+    void *user_arg;
+};
+
+static void encoder_do_one(OSSL_PROVIDER *provider,
+                           const OSSL_ALGORITHM *algodef,
+                           int no_store, void *vdata)
+{
+    struct encoder_do_all_data_st *data = vdata;
+    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    const char *names = algodef->algorithm_names;
+    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
+    void *method = NULL;
+
+    if (id != 0)
+        method =
+            encoder_from_dispatch(id, algodef, provider);
+
+    if (method != NULL) {
+        data->user_fn(method, data->user_arg);
+        OSSL_ENCODER_free(method);
+    }
+}
+
+void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+                                  void (*fn)(OSSL_ENCODER *encoder, void *arg),
+                                  void *arg)
+{
+    struct encoder_do_all_data_st data;
+
+    data.user_fn = (void (*)(void *, void *))fn;
+    data.user_arg = arg;
+
+    /*
+     * No pre- or post-condition for this call, as this only creates methods
+     * temporarly and then promptly destroys them.
+     */
+    ossl_algorithm_do_all(libctx, OSSL_OP_ENCODER, NULL, NULL,
+                          encoder_do_one, NULL, &data);
+}
+
+void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+                               void (*fn)(const char *name, void *data),
+                               void *data)
+{
+    if (encoder == NULL)
+        return;
+
+    if (encoder->base.prov != NULL) {
+        OPENSSL_CTX *libctx = ossl_provider_library_context(encoder->base.prov);
+        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+        ossl_namemap_doall_names(namemap, encoder->base.id, fn, data);
+    }
+}
+
+const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder)
+{
+    if (encoder != NULL && encoder->settable_ctx_params != NULL) {
+        void *provctx = ossl_provider_ctx(OSSL_ENCODER_provider(encoder));
+
+        return encoder->settable_ctx_params(provctx);
+    }
+    return NULL;
+}
+
+/*
+ * Encoder context support
+ */
+
+/*
+ * |encoder| value NULL is valid, and signifies that there is no encoder.
+ * This is useful to provide fallback mechanisms.
+ *  Functions that want to verify if there is a encoder can do so with
+ * OSSL_ENCODER_CTX_get_encoder()
+ */
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(OSSL_ENCODER *encoder)
+{
+    OSSL_ENCODER_CTX *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ctx->encoder = encoder;
+    if (encoder != NULL && encoder->newctx != NULL) {
+        const OSSL_PROVIDER *prov = OSSL_ENCODER_provider(encoder);
+        void *provctx = ossl_provider_ctx(prov);
+
+        if (OSSL_ENCODER_up_ref(encoder)) {
+            ctx->serctx = encoder->newctx(provctx);
+        } else {
+            OSSL_ENCODER_free(encoder);
+            OPENSSL_free(ctx);
+            ctx = NULL;
+        }
+    }
+
+    return ctx;
+}
+
+const OSSL_ENCODER *
+OSSL_ENCODER_CTX_get_encoder(OSSL_ENCODER_CTX *ctx)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return ctx->encoder;
+}
+
+
+int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
+                                const OSSL_PARAM params[])
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (ctx->encoder != NULL && ctx->encoder->set_ctx_params != NULL)
+        return ctx->encoder->set_ctx_params(ctx->serctx, params);
+    return 0;
+}
+
+void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx)
+{
+    if (ctx != NULL) {
+        if (ctx->encoder != NULL && ctx->encoder->freectx != NULL)
+            ctx->encoder->freectx(ctx->serctx);
+        OSSL_ENCODER_free(ctx->encoder);
+        UI_destroy_method(ctx->allocated_ui_method);
+        OPENSSL_free(ctx);
+    }
+}
diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c
new file mode 100644
index 0000000000..dc776c023e
--- /dev/null
+++ b/crypto/encode_decode/encoder_pkey.c
@@ -0,0 +1,276 @@
+/*
+ * 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/err.h>
+#include <openssl/ui.h>
+#include <openssl/params.h>
+#include <openssl/encoder.h>
+#include <openssl/core_names.h>
+#include <openssl/safestack.h>
+#include "internal/provider.h"
+#include "internal/property.h"
+#include "crypto/evp.h"
+#include "encoder_local.h"
+
+DEFINE_STACK_OF_CSTRING()
+
+int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
+                                const char *cipher_name,
+                                const char *propquery)
+{
+    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
+
+    params[0] =
+        OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER,
+                                         (void *)cipher_name, 0);
+    params[1] =
+        OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES,
+                                         (void *)propquery, 0);
+
+    return OSSL_ENCODER_CTX_set_params(ctx, params);
+}
+
+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);
+}
+
+static void encoder_ctx_reset_passphrase_ui(OSSL_ENCODER_CTX *ctx)
+{
+    UI_destroy_method(ctx->allocated_ui_method);
+    ctx->allocated_ui_method = NULL;
+    ctx->ui_method = NULL;
+    ctx->ui_data = NULL;
+}
+
+int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
+                                       const UI_METHOD *ui_method,
+                                       void *ui_data)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    encoder_ctx_reset_passphrase_ui(ctx);
+    ctx->ui_method = ui_method;
+    ctx->ui_data = ui_data;
+    return 1;
+}
+
+int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
+                                       pem_password_cb *cb, void *cbarg)
+{
+    if (!ossl_assert(ctx != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    encoder_ctx_reset_passphrase_ui(ctx);
+    if (cb == NULL)
+        return 1;
+    ctx->ui_method =
+        ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 1);
+    ctx->ui_data = cbarg;
+
+    return ctx->ui_method != NULL;
+}
+
+/*
+ * Support for OSSL_ENCODER_CTX_new_by_TYPE:
+ * finding a suitable encoder
+ */
+
+struct selected_encoder_st {
+    STACK_OF(OPENSSL_CSTRING) *names;
+    int error;
+};
+
+static void cache_encoders(const char *name, void *data)
+{
+    struct selected_encoder_st *d = data;
+
+    if (sk_OPENSSL_CSTRING_push(d->names, name) <= 0)
+        d->error = 1;
+}
+
+/*
+ * Support for OSSL_ENCODER_to_bio:
+ * writing callback for the OSSL_PARAM (the implementation doesn't have
+ * intimate knowledge of the provider side object)
+ */
+
+struct encoder_write_data_st {
+    OSSL_ENCODER_CTX *ctx;
+    BIO *out;
+};
+
+static int encoder_write_cb(const OSSL_PARAM params[], void *arg)
+{
+    struct encoder_write_data_st *write_data = arg;
+    OSSL_ENCODER_CTX *ctx = write_data->ctx;
+    BIO *out = write_data->out;
+
+    return ctx->encoder->encode_data(ctx->serctx, params, (OSSL_CORE_BIO *)out,
+                                     ossl_encoder_passphrase_out_cb, ctx);
+}
+
+/*
+ * Support for OSSL_ENCODER_to_bio:
+ * Perform the actual output.
+ */
+
+static int encoder_EVP_PKEY_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out)
+{
+    const EVP_PKEY *pkey = ctx->object;
+    void *keydata = pkey->keydata;
+    EVP_KEYMGMT *keymgmt = pkey->keymgmt;
+
+    /*
+     * OSSL_ENCODER_CTX_new() creates a context, even when the
+     * encoder it's given is NULL.  Callers can detect the lack
+     * of encoder with OSSL_ENCODER_CTX_get_encoder() and
+     * should take precautions, possibly call a fallback instead of
+     * OSSL_ENCODER_to_bio() / OSSL_ENCODER_to_fp().  If it's
+     * come this far, we return an error.
+     */
+    if (ctx->encoder == NULL)
+        return 0;
+
+    if (ctx->encoder->encode_object == NULL
+        || (OSSL_ENCODER_provider(ctx->encoder)
+            != EVP_KEYMGMT_provider(keymgmt))) {
+        struct encoder_write_data_st write_data;
+
+        write_data.ctx = ctx;
+        write_data.out = out;
+
+        return evp_keymgmt_export(keymgmt, keydata, ctx->selection,
+                                  &encoder_write_cb, &write_data);
+    }
+
+    return ctx->encoder->encode_object(ctx->serctx, keydata,
+                                       (OSSL_CORE_BIO *)out,
+                                       ossl_encoder_passphrase_out_cb, ctx);
+}
+
+/*
+ * OSSL_ENCODER_CTX_new_by_EVP_PKEY() returns a ctx with no encoder if
+ * it couldn't find a suitable encoder.  This allows a caller to detect if
+ * a suitable encoder was found, with OSSL_ENCODER_CTX_get_encoder(),
+ * and to use fallback methods if the result is NULL.
+ */
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
+                                                   const char *propquery)
+{
+    OSSL_ENCODER_CTX *ctx = NULL;
+    OSSL_ENCODER *encoder = NULL;
+    EVP_KEYMGMT *keymgmt = pkey->keymgmt;
+    int selection = OSSL_KEYMGMT_SELECT_ALL;
+
+    if (!ossl_assert(pkey != NULL && propquery != NULL)) {
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if (keymgmt != NULL) {
+        const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt);
+        OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov);
+        struct selected_encoder_st sel_data;
+        OSSL_ENCODER *first = NULL;
+        const char *name;
+        int i;
+
+        /*
+         * Select the encoder in two steps.  First, get the names of all of
+         * the encoders.  Then determine which is the best one to use.
+         * This has to be broken because it isn't possible to fetch the
+         * serialisers inside EVP_KEYMGMT_names_do_all() due to locking
+         * order inversions with the store lock.
+         */
+        sel_data.error = 0;
+        sel_data.names = sk_OPENSSL_CSTRING_new_null();
+        if (sel_data.names == NULL)
+            return NULL;
+        EVP_KEYMGMT_names_do_all(keymgmt, cache_encoders, &sel_data);
+        /*
+         * Ignore memory allocation errors that are indicated in sel_data.error
+         * in case a suitable provider does get found regardless.
+         */
+
+        /*
+         * Encoders offer two functions, one that handles object data in
+         * the form of a OSSL_PARAM array, and one that directly handles a
+         * provider side object.  The latter requires that the encoder
+         * is offered by the same provider that holds that object, but is
+         * more desirable because it usually provides faster encoding.
+         *
+         * When looking up possible encoders, we save the first that can
+         * handle an OSSL_PARAM array in |first| and use that if nothing
+         * better turns up.
+         */
+        for (i = 0; i < sk_OPENSSL_CSTRING_num(sel_data.names); i++) {
+            name = sk_OPENSSL_CSTRING_value(sel_data.names, i);
+            encoder = OSSL_ENCODER_fetch(libctx, name, propquery);
+            if (encoder != NULL) {
+                if (OSSL_ENCODER_provider(encoder) == desired_prov
+                        && encoder->encode_object != NULL) {
+                    OSSL_ENCODER_free(first);
+                    break;
+                }
+                if (first == NULL && encoder->encode_data != NULL)
+                    first = encoder;
+                else
+                    OSSL_ENCODER_free(encoder);
+                encoder = NULL;
+            }
+        }
+        sk_OPENSSL_CSTRING_free(sel_data.names);
+        if (encoder == NULL)
+            encoder = first;
+
+        if (encoder != NULL) {
+            OSSL_PROPERTY_LIST *check = NULL, *current_props = NULL;
+
+            check = ossl_parse_query(libctx, "type=parameters");
+            current_props =
+                ossl_parse_property(libctx, OSSL_ENCODER_properties(encoder));
+            if (ossl_property_match_count(check, current_props) > 0)
+                selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
+            ossl_property_free(current_props);
+            ossl_property_free(check);
+        } else {
+            if (sel_data.error)
+                ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE);
+            else
+                ERR_raise(ERR_LIB_OSSL_ENCODER,
+                          OSSL_ENCODER_R_ENCODER_NOT_FOUND);
+        }
+    }
+
+    ctx = OSSL_ENCODER_CTX_new(encoder); /* refcnt(encoder)++ */
+    OSSL_ENCODER_free(encoder);          /* refcnt(encoder)-- */
+
+    if (ctx != NULL) {
+        /* Setup for OSSL_ENCODE_to_bio() */
+        ctx->selection = selection;
+        ctx->object = pkey;
+        ctx->do_output = encoder_EVP_PKEY_to_bio;
+    }
+
+    return ctx;
+}
+
diff --git a/crypto/serializer/serdes_pass.c b/crypto/encode_decode/endecode_pass.c
similarity index 80%
rename from crypto/serializer/serdes_pass.c
rename to crypto/encode_decode/endecode_pass.c
index 75200955b5..113f5eeb84 100644
--- a/crypto/serializer/serdes_pass.c
+++ b/crypto/encode_decode/endecode_pass.c
@@ -11,7 +11,7 @@
 #include <openssl/ui.h>
 #include <openssl/core_names.h>
 #include "internal/cryptlib.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 /* Passphrase callbacks for any who need it */
 
@@ -56,7 +56,7 @@ static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len,
 
     /* Get an application constructed prompt */
     prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
-   if (prompt == NULL) {
+    if (prompt == NULL) {
         ERR_raise(errlib, ERR_R_MALLOC_FAILURE);
         goto end;
     }
@@ -107,33 +107,33 @@ static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len,
 }
 
 /*
- * Serializers typically want to get an outgoing passphrase, while
- * deserializers typically want to get en incoming passphrase.
+ * Encoders typically want to get an outgoing passphrase, while
+ * decoders typically want to get en incoming passphrase.
  */
-int ossl_serializer_passphrase_out_cb(char *pass, size_t pass_size,
-                                      size_t *pass_len,
-                                      const OSSL_PARAM params[], void *arg)
+int ossl_encoder_passphrase_out_cb(char *pass, size_t pass_size,
+                                   size_t *pass_len,
+                                   const OSSL_PARAM params[], void *arg)
 {
-    OSSL_SERIALIZER_CTX *ctx = arg;
+    OSSL_ENCODER_CTX *ctx = arg;
 
     if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
     return do_passphrase(pass, pass_size, pass_len, params, arg, 1,
                          ctx->ui_method, ctx->ui_data,
-                         ERR_LIB_OSSL_SERIALIZER);
+                         ERR_LIB_OSSL_ENCODER);
 }
 
-int ossl_deserializer_passphrase_in_cb(char *pass, size_t pass_size,
-                                       size_t *pass_len,
-                                       const OSSL_PARAM params[], void *arg)
+int ossl_decoder_passphrase_in_cb(char *pass, size_t pass_size,
+                                  size_t *pass_len,
+                                  const OSSL_PARAM params[], void *arg)
 {
-    OSSL_DESERIALIZER_CTX *ctx = arg;
+    OSSL_DECODER_CTX *ctx = arg;
 
     if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
 
@@ -147,13 +147,13 @@ int ossl_deserializer_passphrase_in_cb(char *pass, size_t pass_size,
         return 1;
     } else {
         if ((ctx->cached_passphrase = OPENSSL_zalloc(pass_size)) == NULL) {
-            ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
             return 0;
         }
     }
     if (do_passphrase(pass, pass_size, pass_len, params, arg, 0,
                       ctx->ui_method, ctx->ui_data,
-                      ERR_LIB_OSSL_DESERIALIZER)) {
+                      ERR_LIB_OSSL_DECODER)) {
         memcpy(ctx->cached_passphrase, pass, *pass_len);
         ctx->cached_passphrase_len = *pass_len;
         return 1;
diff --git a/crypto/err/err.c b/crypto/err/err.c
index e2d70d7a58..9098112d1c 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -75,8 +75,8 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
     {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"},
     {ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
     {ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
-    {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"},
-    {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, 0), "DESERIALIZER routines"},
+    {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, 0), "ENCODER routines"},
+    {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, 0), "DECODER routines"},
     {ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
     {0, NULL},
 };
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index f1bed12795..037611d759 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -40,16 +40,16 @@ L OSSL_STORE    include/openssl/store.h         crypto/store/store_err.c
 L ESS           include/openssl/ess.h           crypto/ess/ess_err.c
 L PROP          include/internal/property.h     crypto/property/property_err.c
 L PROV          providers/common/include/prov/providercommon.h providers/common/provider_err.c
-L OSSL_SERIALIZER include/openssl/serializer.h  crypto/serializer/serializer_err.c
-L OSSL_DESERIALIZER include/openssl/deserializer.h  crypto/serializer/deserializer_err.c
+L OSSL_ENCODER  include/openssl/encoder.h       crypto/encoder/encoder_err.c
+L OSSL_DECODER  include/openssl/decoder.h       crypto/encoder/decoder_err.c
 L HTTP          include/openssl/http.h          crypto/http/http_err.c
 
 # additional header files to be scanned for function names
 L NONE          include/openssl/x509_vfy.h      NONE
-L NONE          crypto/ec/ec_local.h              NONE
-L NONE          crypto/cms/cms_local.h            NONE
-L NONE          crypto/ct/ct_local.h             NONE
-L NONE          ssl/ssl_local.h                  NONE
+L NONE          crypto/ec/ec_local.h            NONE
+L NONE          crypto/cms/cms_local.h          NONE
+L NONE          crypto/ct/ct_local.h            NONE
+L NONE          ssl/ssl_local.h                 NONE
 
 # SSL/TLS alerts
 R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE          1010
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 10531ead7a..3a5a5b5692 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2702,9 +2702,9 @@ OCSP_R_STATUS_TOO_OLD:127:status too old
 OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest
 OCSP_R_UNKNOWN_NID:120:unknown nid
 OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type
-OSSL_DESERIALIZER_R_MISSING_GET_PARAMS:100:missing get params
-OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query
-OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND:101:serializer not found
+OSSL_DECODER_R_MISSING_GET_PARAMS:100:missing get params
+OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query
+OSSL_ENCODER_R_ENCODER_NOT_FOUND:101:encoder not found
 OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
 OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read
 OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index bee6337a88..7a79816788 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -29,7 +29,7 @@
 #include <openssl/engine.h>
 #include <openssl/params.h>
 #include <openssl/param_build.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 #include <openssl/core_names.h>
 
 #include "crypto/asn1.h"
@@ -1143,23 +1143,23 @@ static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
 }
 
 static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
-                      const char *propquery /* For provided serialization */,
+                      const char *propquery /* For provided encoding */,
                       int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
                                           int indent, ASN1_PCTX *pctx),
                       ASN1_PCTX *legacy_pctx /* For legacy print */)
 {
     int pop_f_prefix;
     long saved_indent;
-    OSSL_SERIALIZER_CTX *ctx = NULL;
+    OSSL_ENCODER_CTX *ctx = NULL;
     int ret = -2;                /* default to unsupported */
 
     if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
         return 0;
 
-    ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
-    if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
-        ret = OSSL_SERIALIZER_to_bio(ctx, out);
-    OSSL_SERIALIZER_CTX_free(ctx);
+    ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, propquery);
+    if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL)
+        ret = OSSL_ENCODER_to_bio(ctx, out);
+    OSSL_ENCODER_CTX_free(ctx);
 
     if (ret != -2)
         goto end;
@@ -1178,7 +1178,7 @@ static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent, OSSL_ENCODER_PUBKEY_TO_TEXT_PQ,
                       (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
                       pctx);
 }
@@ -1186,7 +1186,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                            int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent, OSSL_ENCODER_PrivateKey_TO_TEXT_PQ,
                       (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
                       pctx);
 }
@@ -1194,7 +1194,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent, OSSL_ENCODER_Parameters_TO_TEXT_PQ,
                       (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
                       pctx);
 }
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 1ab309329d..2f9346d998 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -27,7 +27,6 @@
 /* TODO(3.0) remove when provider SM2 key generation is implemented */
 #ifdef TMP_SM2_HACK
 # include <openssl/ec.h>
-# include <openssl/serializer.h>
 # include "internal/sizes.h"
 #endif
 
diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h
index 2fb1e6f4d5..81d1718e32 100644
--- a/crypto/pem/pem_local.h
+++ b/crypto/pem/pem_local.h
@@ -13,17 +13,17 @@
  */
 
 #include <openssl/pem.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 
-/* Alternative IMPLEMENT macros for provided serializers */
+/* Alternative IMPLEMENT macros for provided encoders */
 
 # define IMPLEMENT_PEM_provided_write_body_vars(type, asn1)             \
     int ret = 0;                                                        \
-    const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ;                \
-    OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \
+    const char *pq = OSSL_ENCODER_##asn1##_TO_PEM_PQ;                   \
+    OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_##type(x, pq);      \
                                                                         \
-    if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \
-        OSSL_SERIALIZER_CTX_free(ctx);                                  \
+    if (ctx != NULL && OSSL_ENCODER_CTX_get_encoder(ctx) == NULL) {     \
+        OSSL_ENCODER_CTX_free(ctx);                                     \
         goto legacy;                                                    \
     }
 # define IMPLEMENT_PEM_provided_write_body_pass()                       \
@@ -38,31 +38,31 @@
     }                                                                   \
     if (enc != NULL) {                                                  \
         ret = 0;                                                        \
-        if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc),   \
-                                           NULL)) {                     \
+        if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc),      \
+                                        NULL)) {                        \
             ret = 1;                                                    \
             if (kstr != NULL                                            \
-                && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \
+                && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen))   \
                 ret = 0;                                                \
             else if (cb != NULL                                         \
-                     && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx,     \
-                                                               cb, u))  \
+                     && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx,        \
+                                                            cb, u))     \
                 ret = 0;                                                \
         }                                                               \
     }                                                                   \
     if (!ret) {                                                         \
-        OSSL_SERIALIZER_CTX_free(ctx);                                  \
+        OSSL_ENCODER_CTX_free(ctx);                                     \
         return 0;                                                       \
     }
 # define IMPLEMENT_PEM_provided_write_body_main(type, outtype)          \
-    ret = OSSL_SERIALIZER_to_##outtype(ctx, out);                       \
-    OSSL_SERIALIZER_CTX_free(ctx);                                      \
+    ret = OSSL_ENCODER_to_##outtype(ctx, out);                          \
+    OSSL_ENCODER_CTX_free(ctx);                                         \
     return ret
 # define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1,          \
                                                     writename)          \
     legacy:                                                             \
     return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out,    \
-                                  x, NULL, NULL, 0, NULL, NULL)
+                                x, NULL, NULL, 0, NULL, NULL)
 # define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1,       \
                                                        writename)       \
     legacy:                                                             \
@@ -114,15 +114,15 @@
     IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1)     \
     IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1)
 
-# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \
-    IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1)  \
+# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1)         \
+    IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1)          \
     IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1)
 
-# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \
+# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1)       \
     IMPLEMENT_PEM_read(name, type, str, asn1)                   \
     IMPLEMENT_PEM_provided_write(name, type, str, asn1)
 
-# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \
+# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1)    \
     IMPLEMENT_PEM_read(name, type, str, asn1)                   \
     IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1)
 
diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c
index 12a25b7a82..84d431820b 100644
--- a/crypto/pem/pem_pk8.c
+++ b/crypto/pem/pem_pk8.c
@@ -15,7 +15,7 @@
 #include <openssl/x509.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pem.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 
 static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder,
                       int nid, const EVP_CIPHER *enc,
@@ -69,9 +69,9 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
 {
     int ret = 0;
     const char *pq = isder
-        ? OSSL_SERIALIZER_PrivateKey_TO_DER_PQ
-        : OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ;
-    OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(x, pq);
+        ? OSSL_ENCODER_PrivateKey_TO_DER_PQ
+        : OSSL_ENCODER_PrivateKey_TO_PEM_PQ;
+    OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(x, pq);
 
     if (ctx == NULL)
         return 0;
@@ -90,12 +90,11 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
         }
     }
 
-    if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) {
+    if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL) {
         ret = 1;
         if (enc != NULL) {
             ret = 0;
-            if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc),
-                                               NULL)) {
+            if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), NULL)) {
                 const unsigned char *ukstr = (const unsigned char *)kstr;
 
                 /*
@@ -106,14 +105,14 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
                  */
                 ret = 1;
                 if (kstr != NULL
-                    && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, ukstr, klen))
+                    && !OSSL_ENCODER_CTX_set_passphrase(ctx, ukstr, klen))
                     ret = 0;
                 else if (cb != NULL
-                         && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, cb, u))
+                         && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx, cb, u))
                     ret = 0;
             }
         }
-        ret = ret && OSSL_SERIALIZER_to_bio(ctx, bp);
+        ret = ret && OSSL_ENCODER_to_bio(ctx, bp);
     } else {
         X509_SIG *p8;
         PKCS8_PRIV_KEY_INFO *p8inf;
@@ -153,7 +152,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
      legacy_end:
         PKCS8_PRIV_KEY_INFO_free(p8inf);
     }
-    OSSL_SERIALIZER_CTX_free(ctx);
+    OSSL_ENCODER_CTX_free(ctx);
     return ret;
 }
 
@@ -261,4 +260,4 @@ IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
 
 
 IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
-             PKCS8_PRIV_KEY_INFO)
+                 PKCS8_PRIV_KEY_INFO)
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 4ee5bb7009..e355afe5f9 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -19,7 +19,6 @@
 #include <openssl/dh.h>
 #include <openssl/store.h>
 #include <openssl/ui.h>
-#include <openssl/serializer.h>
 #include "crypto/store.h"
 #include "crypto/asn1.h"
 #include "crypto/evp.h"
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index 91b830c2e5..6d6ca9b266 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -596,9 +596,9 @@ int ossl_property_parse_init(OPENSSL_CTX *ctx)
         "provider",     /* Name of provider (default, legacy, fips) */
         "version",      /* Version number of this provider */
         "fips",         /* FIPS validated or FIPS supporting algorithm */
-        "format",       /* output format for serializers */
-        "type",         /* output type for serializers */
-        "input",        /* input type for deserializers */
+        "format",       /* output format for encoders */
+        "type",         /* output type for encoders */
+        "input",        /* input type for decoders */
     };
     size_t i;
 
diff --git a/crypto/serializer/build.info b/crypto/serializer/build.info
deleted file mode 100644
index 11f8889b6b..0000000000
--- a/crypto/serializer/build.info
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCE[../../libcrypto]=serdes_pass.c
-
-SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c
-SOURCE[../../libcrypto]=deserializer_meth.c deserializer_lib.c \
-        deserializer_pkey.c
-
-SOURCE[../../libcrypto]=serializer_err.c
-SOURCE[../../libcrypto]=deserializer_err.c
diff --git a/crypto/serializer/deserializer_lib.c b/crypto/serializer/deserializer_lib.c
deleted file mode 100644
index aa3b552786..0000000000
--- a/crypto/serializer/deserializer_lib.c
+++ /dev/null
@@ -1,488 +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/params.h>
-#include <openssl/provider.h>
-#include "serializer_local.h"
-#include "e_os.h"
-
-struct deser_process_data_st {
-    OSSL_DESERIALIZER_CTX *ctx;
-
-    /* Current BIO */
-    BIO *bio;
-
-    /* Index of the current deserializer instance to be processed */
-    size_t current_deser_inst_index;
-};
-
-static int deser_process(const OSSL_PARAM params[], void *arg);
-
-int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in)
-{
-    struct deser_process_data_st data;
-    int ok = 0;
-
-    memset(&data, 0, sizeof(data));
-    data.ctx = ctx;
-    data.bio = in;
-
-    ok = deser_process(NULL, &data);
-
-    /* Clear any internally cached passphrase */
-    if (!ctx->flag_user_passphrase) {
-        OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
-        ctx->flag_user_passphrase = 0;
-    }
-    return ok;
-}
-
-#ifndef OPENSSL_NO_STDIO
-static BIO *bio_from_file(FILE *fp)
-{
-    BIO *b;
-
-    if ((b = BIO_new(BIO_s_file())) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB);
-        return NULL;
-    }
-    BIO_set_fp(b, fp, BIO_NOCLOSE);
-    return b;
-}
-
-int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp)
-{
-    BIO *b = bio_from_file(fp);
-    int ret = 0;
-
-    if (b != NULL)
-        ret = OSSL_DESERIALIZER_from_bio(ctx, b);
-
-    BIO_free(b);
-    return ret;
-}
-#endif
-
-int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
-                                         const char *input_type)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    /*
-     * NULL is a valid starting input type, and means that the caller leaves
-     * it to code to discover what the starting input type is.
-     */
-    ctx->start_input_type = input_type;
-    return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
-                                           OSSL_DESERIALIZER *deser)
-{
-    OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL;
-    const OSSL_PROVIDER *prov = NULL;
-    OSSL_PARAM params[2];
-    void *provctx = NULL;
-
-    if (!ossl_assert(ctx != NULL) || !ossl_assert(deser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    if (deser->get_params == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER,
-                  OSSL_DESERIALIZER_R_MISSING_GET_PARAMS);
-        return 0;
-    }
-
-    if (ctx->deser_insts == NULL
-        && (ctx->deser_insts =
-            sk_OSSL_DESERIALIZER_INSTANCE_new_null()) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    if ((deser_inst = OPENSSL_zalloc(sizeof(*deser_inst))) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    if (!OSSL_DESERIALIZER_up_ref(deser)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
-    deser_inst->deser = deser;
-
-    prov = OSSL_DESERIALIZER_provider(deser_inst->deser);
-    provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
-
-    /* Cache the input type for this serializer */
-    params[0] =
-        OSSL_PARAM_construct_utf8_ptr(OSSL_DESERIALIZER_PARAM_INPUT_TYPE,
-                                      (char **)&deser_inst->input_type, 0);
-    params[1] = OSSL_PARAM_construct_end();
-
-    if (!deser_inst->deser->get_params(params)
-        || !OSSL_PARAM_modified(&params[0]))
-        goto err;
-
-    if ((deser_inst->deserctx = deser_inst->deser->newctx(provctx))
-        == NULL)
-        goto err;
-
-    if (sk_OSSL_DESERIALIZER_INSTANCE_push(ctx->deser_insts, deser_inst) <= 0)
-        goto err;
-
-    return 1;
- err:
-    if (deser_inst != NULL) {
-        if (deser_inst->deser != NULL)
-            deser_inst->deser->freectx(deser_inst->deserctx);
-        OSSL_DESERIALIZER_free(deser_inst->deser);
-        OPENSSL_free(deser_inst);
-    }
-    return 0;
-}
-
-int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx,
-                                    OPENSSL_CTX *libctx, const char *propq)
-{
-    /*
-     * This function goes through existing deserializer methods in
-     * |ctx->deser_insts|, and tries to fetch new deserializers that produce
-     * what the existing ones want as input, and push those newly fetched
-     * deserializers on top of the same stack.
-     * Then it does the same again, but looping over the newly fetched
-     * deserializers, until there are no more serializers to be fetched, or
-     * when we have done this 10 times.
-     *
-     * we do this with sliding windows on the stack by keeping track of indexes
-     * and of the end.
-     *
-     * +----------------+
-     * |   DER to RSA   | <--- w_prev_start
-     * +----------------+
-     * |   DER to DSA   |
-     * +----------------+
-     * |   DER to DH    |
-     * +----------------+
-     * |   PEM to DER   | <--- w_prev_end, w_new_start
-     * +----------------+
-     *                    <--- w_new_end
-     */
-    size_t w_prev_start, w_prev_end; /* "previous" deserializers */
-    size_t w_new_start, w_new_end;   /* "new" deserializers */
-    size_t count = 0; /* Calculates how many were added in each iteration */
-    size_t depth = 0; /* Counts the number of iterations */
-
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    /*
-     * If there is no stack of OSSL_DESERIALIZER_INSTANCE, we have nothing
-     * more to add.  That's fine.
-     */
-    if (ctx->deser_insts == NULL)
-        return 1;
-
-    w_prev_start = 0;
-    w_prev_end = sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
-    do {
-        size_t i;
-
-        w_new_start = w_new_end = w_prev_end;
-
-        for (i = w_prev_start; i < w_prev_end; i++) {
-            OSSL_DESERIALIZER_INSTANCE *deser_inst =
-                sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
-            const char *name = deser_inst->input_type;
-            OSSL_DESERIALIZER *deser = NULL;
-
-            /*
-             * If the caller has specified what the initial input should be,
-             * and the deserializer implementation we're looking at has that
-             * input type, there's no point adding on more implementations
-             * on top of this one, so we don't.
-             */
-            if (ctx->start_input_type != NULL
-                && strcasecmp(ctx->start_input_type,
-                              deser_inst->input_type) != 0)
-                continue;
-
-            ERR_set_mark();
-            deser = OSSL_DESERIALIZER_fetch(libctx, name, propq);
-            ERR_pop_to_mark();
-
-            if (deser != NULL) {
-                size_t j;
-
-                /*
-                 * Check that we don't already have this deserializer in our
-                 * stack We only need to check among the newly added ones.
-                 */
-                for (j = w_new_start; j < w_new_end; j++) {
-                    OSSL_DESERIALIZER_INSTANCE *check_inst =
-                        sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, j);
-
-                    if (deser == check_inst->deser) {
-                        /* We found it, so drop the new fetch */
-                        OSSL_DESERIALIZER_free(deser);
-                        deser = NULL;
-                        break;
-                    }
-                }
-            }
-
-            if (deser == NULL)
-                continue;
-
-            /*
-             * Apart from keeping w_new_end up to date, We don't care about
-             * errors here.  If it doesn't collect, then it doesn't...
-             */
-            if (OSSL_DESERIALIZER_CTX_add_deserializer(ctx, deser)) /* ref++ */
-                w_new_end++;
-            OSSL_DESERIALIZER_free(deser); /* ref-- */
-        }
-        /* How many were added in this iteration */
-        count = w_new_end - w_new_start;
-
-        /* Slide the "previous deserializer" windows */
-        w_prev_start = w_new_start;
-        w_prev_end = w_new_end;
-
-        depth++;
-    } while (count != 0 && depth <= 10);
-
-    return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx)
-{
-    if (ctx == NULL || ctx->deser_insts == NULL)
-        return 0;
-    return sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
-}
-
-int OSSL_DESERIALIZER_CTX_set_construct(OSSL_DESERIALIZER_CTX *ctx,
-                                        OSSL_DESERIALIZER_CONSTRUCT *construct)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-    ctx->construct = construct;
-    return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_set_construct_data(OSSL_DESERIALIZER_CTX *ctx,
-                                             void *construct_data)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-    ctx->construct_data = construct_data;
-    return 1;
-}
-
-int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx,
-                                      OSSL_DESERIALIZER_CLEANUP *cleanup)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-    ctx->cleanup = cleanup;
-    return 1;
-}
-
-OSSL_DESERIALIZER_CONSTRUCT *
-OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx)
-{
-    if (ctx == NULL)
-        return NULL;
-    return ctx->construct;
-}
-
-void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx)
-{
-    if (ctx == NULL)
-        return NULL;
-    return ctx->construct_data;
-}
-
-OSSL_DESERIALIZER_CLEANUP *
-OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx)
-{
-    if (ctx == NULL)
-        return NULL;
-    return ctx->cleanup;
-}
-
-int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
-                             void *reference, size_t reference_sz,
-                             OSSL_CALLBACK *export_cb, void *export_cbarg)
-{
-    if (!(ossl_assert(deser_inst != NULL)
-          && ossl_assert(reference != NULL)
-          && ossl_assert(export_cb != NULL)
-          && ossl_assert(export_cbarg != NULL))) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return deser_inst->deser->export_object(deser_inst->deserctx,
-                                            reference, reference_sz,
-                                            export_cb, export_cbarg);
-}
-
-OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
-    (OSSL_DESERIALIZER_INSTANCE *deser_inst)
-{
-    if (deser_inst == NULL)
-        return NULL;
-    return deser_inst->deser;
-}
-
-void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-    (OSSL_DESERIALIZER_INSTANCE *deser_inst)
-{
-    if (deser_inst == NULL)
-        return NULL;
-    return deser_inst->deserctx;
-}
-
-static int deser_process(const OSSL_PARAM params[], void *arg)
-{
-    struct deser_process_data_st *data = arg;
-    OSSL_DESERIALIZER_CTX *ctx = data->ctx;
-    OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL;
-    OSSL_DESERIALIZER *deser = NULL;
-    BIO *bio = data->bio;
-    long loc;
-    size_t i;
-    int ok = 0;
-    /* For recursions */
-    struct deser_process_data_st new_data;
-
-    memset(&new_data, 0, sizeof(new_data));
-    new_data.ctx = data->ctx;
-
-    if (params == NULL) {
-        /* First iteration, where we prepare for what is to come */
-
-        data->current_deser_inst_index =
-            OSSL_DESERIALIZER_CTX_num_deserializers(ctx);
-
-        bio = data->bio;
-    } else {
-        const OSSL_PARAM *p;
-
-        deser_inst =
-            sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts,
-                                                data->current_deser_inst_index);
-        deser = OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst);
-
-        if (ctx->construct != NULL
-            && ctx->construct(deser_inst, params, ctx->construct_data)) {
-            ok = 1;
-            goto end;
-        }
-
-        /* The constructor didn't return success */
-
-        /*
-         * so we try to use the object we got and feed it to any next
-         * deserializer that will take it.  Object references are not
-         * allowed for this.
-         * If this data isn't present, deserialization has failed.
-         */
-
-        p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA);
-        if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING)
-            goto end;
-        new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size);
-        if (new_data.bio == NULL)
-            goto end;
-        bio = new_data.bio;
-    }
-
-    /*
-     * If we have no more deserializers to look through at this point,
-     * we failed
-     */
-    if (data->current_deser_inst_index == 0)
-        goto end;
-
-    if ((loc = BIO_tell(bio)) < 0) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB);
-        goto end;
-    }
-
-    for (i = data->current_deser_inst_index; i-- > 0;) {
-        OSSL_DESERIALIZER_INSTANCE *new_deser_inst =
-            sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
-        OSSL_DESERIALIZER *new_deser =
-            OSSL_DESERIALIZER_INSTANCE_deserializer(new_deser_inst);
-
-        /*
-         * If |deser| is NULL, it means we've just started, and the caller
-         * may have specified what it expects the initial input to be.  If
-         * that's the case, we do this extra check.
-         */
-        if (deser == NULL && ctx->start_input_type != NULL
-            && strcasecmp(ctx->start_input_type,
-                          new_deser_inst->input_type) != 0)
-            continue;
-
-        /*
-         * If we have a previous deserializer, we check that the input type
-         * of the next to be used matches the type of this previous one.
-         * deser_inst->input_type is a cache of the parameter "input-type"
-         * value for that deserializer.
-         */
-        if (deser != NULL
-            && !OSSL_DESERIALIZER_is_a(deser, new_deser_inst->input_type))
-            continue;
-
-        /*
-         * Checking the return value of BIO_reset() or BIO_seek() is unsafe.
-         * Furthermore, BIO_reset() is unsafe to use if the source BIO happens
-         * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero
-         * no matter where we are in the underlying buffer we're reading from.
-         *
-         * So, we simply do a BIO_seek(), and use BIO_tell() that we're back
-         * at the same position.  This is a best effort attempt, but BIO_seek()
-         * and BIO_tell() should come as a pair...
-         */
-        (void)BIO_seek(bio, loc);
-        if (BIO_tell(bio) != loc)
-            goto end;
-
-        /* Recurse */
-        new_data.current_deser_inst_index = i;
-        ok = new_deser->deserialize(new_deser_inst->deserctx,
-                                    (OSSL_CORE_BIO *)bio,
-                                    deser_process, &new_data,
-                                    ctx->passphrase_cb,
-                                    new_data.ctx);
-        if (ok)
-            break;
-    }
-
- end:
-    BIO_free(new_data.bio);
-    return ok;
-}
diff --git a/crypto/serializer/deserializer_meth.c b/crypto/serializer/deserializer_meth.c
deleted file mode 100644
index 69099f5e95..0000000000
--- a/crypto/serializer/deserializer_meth.c
+++ /dev/null
@@ -1,552 +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.h>
-#include <openssl/core_dispatch.h>
-#include <openssl/deserializer.h>
-#include <openssl/ui.h>
-#include "internal/core.h"
-#include "internal/namemap.h"
-#include "internal/property.h"
-#include "internal/provider.h"
-#include "crypto/serializer.h"
-#include "serializer_local.h"
-
-static void OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *instance);
-
-/*
- * Deserializer can have multiple names, separated with colons in a name string
- */
-#define NAME_SEPARATOR ':'
-
-/* Simple method structure constructor and destructor */
-static OSSL_DESERIALIZER *ossl_deserializer_new(void)
-{
-    OSSL_DESERIALIZER *deser = NULL;
-
-    if ((deser = OPENSSL_zalloc(sizeof(*deser))) == NULL
-        || (deser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
-        OSSL_DESERIALIZER_free(deser);
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-
-    deser->base.refcnt = 1;
-
-    return deser;
-}
-
-int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deser)
-{
-    int ref = 0;
-
-    CRYPTO_UP_REF(&deser->base.refcnt, &ref, deser->base.lock);
-    return 1;
-}
-
-void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deser)
-{
-    int ref = 0;
-
-    if (deser == NULL)
-        return;
-
-    CRYPTO_DOWN_REF(&deser->base.refcnt, &ref, deser->base.lock);
-    if (ref > 0)
-        return;
-    ossl_provider_free(deser->base.prov);
-    CRYPTO_THREAD_lock_free(deser->base.lock);
-    OPENSSL_free(deser);
-}
-
-/* Permanent deserializer method store, constructor and destructor */
-static void deserializer_store_free(void *vstore)
-{
-    ossl_method_store_free(vstore);
-}
-
-static void *deserializer_store_new(OPENSSL_CTX *ctx)
-{
-    return ossl_method_store_new(ctx);
-}
-
-
-static const OPENSSL_CTX_METHOD deserializer_store_method = {
-    deserializer_store_new,
-    deserializer_store_free,
-};
-
-/* Data to be passed through ossl_method_construct() */
-struct deserializer_data_st {
-    OPENSSL_CTX *libctx;
-    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
-    int id;                      /* For get_deserializer_from_store() */
-    const char *names;           /* For get_deserializer_from_store() */
-    const char *propquery;       /* For get_deserializer_from_store() */
-};
-
-/*
- * Generic routines to fetch / create DESERIALIZER methods with
- * ossl_method_construct()
- */
-
-/* Temporary deserializer method store, constructor and destructor */
-static void *alloc_tmp_deserializer_store(OPENSSL_CTX *ctx)
-{
-    return ossl_method_store_new(ctx);
-}
-
- static void dealloc_tmp_deserializer_store(void *store)
-{
-    if (store != NULL)
-        ossl_method_store_free(store);
-}
-
-/* Get the permanent deserializer store */
-static OSSL_METHOD_STORE *get_deserializer_store(OPENSSL_CTX *libctx)
-{
-    return openssl_ctx_get_data(libctx, OPENSSL_CTX_DESERIALIZER_STORE_INDEX,
-                                &deserializer_store_method);
-}
-
-/* Get deserializer methods from a store, or put one in */
-static void *get_deserializer_from_store(OPENSSL_CTX *libctx, void *store,
-                                         void *data)
-{
-    struct deserializer_data_st *methdata = data;
-    void *method = NULL;
-    int id;
-
-    if ((id = methdata->id) == 0) {
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        id = ossl_namemap_name2num(namemap, methdata->names);
-    }
-
-    if (store == NULL
-        && (store = get_deserializer_store(libctx)) == NULL)
-        return NULL;
-
-    if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
-        return NULL;
-    return method;
-}
-
-static int put_deserializer_in_store(OPENSSL_CTX *libctx, void *store,
-                                     void *method, const OSSL_PROVIDER *prov,
-                                     int operation_id, const char *names,
-                                     const char *propdef, void *unused)
-{
-    OSSL_NAMEMAP *namemap;
-    int id;
-
-    if ((namemap = ossl_namemap_stored(libctx)) == NULL
-        || (id = ossl_namemap_name2num(namemap, names)) == 0)
-        return 0;
-
-    if (store == NULL && (store = get_deserializer_store(libctx)) == NULL)
-        return 0;
-
-    return ossl_method_store_add(store, prov, id, propdef, method,
-                                 (int (*)(void *))OSSL_DESERIALIZER_up_ref,
-                                 (void (*)(void *))OSSL_DESERIALIZER_free);
-}
-
-/* Create and populate a deserializer method */
-static void *deserializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
-                                        OSSL_PROVIDER *prov)
-{
-    OSSL_DESERIALIZER *deser = NULL;
-    const OSSL_DISPATCH *fns = algodef->implementation;
-
-    if ((deser = ossl_deserializer_new()) == NULL)
-        return NULL;
-    deser->base.id = id;
-    deser->base.propdef = algodef->property_definition;
-
-    for (; fns->function_id != 0; fns++) {
-        switch (fns->function_id) {
-        case OSSL_FUNC_DESERIALIZER_NEWCTX:
-            if (deser->newctx == NULL)
-                deser->newctx = OSSL_FUNC_deserializer_newctx(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_FREECTX:
-            if (deser->freectx == NULL)
-                deser->freectx = OSSL_FUNC_deserializer_freectx(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_GET_PARAMS:
-            if (deser->get_params == NULL)
-                deser->get_params =
-                    OSSL_FUNC_deserializer_get_params(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS:
-            if (deser->gettable_params == NULL)
-                deser->gettable_params =
-                    OSSL_FUNC_deserializer_gettable_params(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS:
-            if (deser->set_ctx_params == NULL)
-                deser->set_ctx_params =
-                    OSSL_FUNC_deserializer_set_ctx_params(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS:
-            if (deser->settable_ctx_params == NULL)
-                deser->settable_ctx_params =
-                    OSSL_FUNC_deserializer_settable_ctx_params(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_DESERIALIZE:
-            if (deser->deserialize == NULL)
-                deser->deserialize = OSSL_FUNC_deserializer_deserialize(fns);
-            break;
-        case OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT:
-            if (deser->export_object == NULL)
-                deser->export_object = OSSL_FUNC_deserializer_export_object(fns);
-            break;
-        }
-    }
-    /*
-     * Try to check that the method is sensible.
-     * If you have a constructor, you must have a destructor and vice versa.
-     * You must have at least one of the serializing driver functions.
-     */
-    if (!((deser->newctx == NULL && deser->freectx == NULL)
-          || (deser->newctx != NULL && deser->freectx != NULL))
-        || (deser->deserialize == NULL && deser->export_object == NULL)) {
-        OSSL_DESERIALIZER_free(deser);
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
-    }
-
-    if (prov != NULL && !ossl_provider_up_ref(prov)) {
-        OSSL_DESERIALIZER_free(deser);
-        return NULL;
-    }
-
-    deser->base.prov = prov;
-    return deser;
-}
-
-
-/*
- * The core fetching functionality passes the names of the implementation.
- * This function is responsible to getting an identity number for them,
- * then call deserializer_from_dispatch() with that identity number.
- */
-static void *construct_deserializer(const OSSL_ALGORITHM *algodef,
-                                    OSSL_PROVIDER *prov, void *unused)
-{
-    /*
-     * This function is only called if get_deserializer_from_store() returned
-     * NULL, so it's safe to say that of all the spots to create a new
-     * namemap entry, this is it.  Should the name already exist there, we
-     * know that ossl_namemap_add() will return its corresponding number.
-     */
-    OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    const char *names = algodef->algorithm_names;
-    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
-    void *method = NULL;
-
-    if (id != 0)
-        method = deserializer_from_dispatch(id, algodef, prov);
-
-    return method;
-}
-
-/* Intermediary function to avoid ugly casts, used below */
-static void destruct_deserializer(void *method, void *data)
-{
-    OSSL_DESERIALIZER_free(method);
-}
-
-static int up_ref_deserializer(void *method)
-{
-    return OSSL_DESERIALIZER_up_ref(method);
-}
-
-static void free_deserializer(void *method)
-{
-    OSSL_DESERIALIZER_free(method);
-}
-
-/* Fetching support.  Can fetch by numeric identity or by name */
-static OSSL_DESERIALIZER *inner_ossl_deserializer_fetch(OPENSSL_CTX *libctx,
-                                                        int id,
-                                                        const char *name,
-                                                        const char *properties)
-{
-    OSSL_METHOD_STORE *store = get_deserializer_store(libctx);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    void *method = NULL;
-
-    if (store == NULL || namemap == NULL)
-        return NULL;
-
-    /*
-     * If we have been passed neither a name_id or a name, we have an
-     * internal programming error.
-     */
-    if (!ossl_assert(id != 0 || name != NULL))
-        return NULL;
-
-    if (id == 0)
-        id = ossl_namemap_name2num(namemap, name);
-
-    if (id == 0
-        || !ossl_method_store_cache_get(store, id, properties, &method)) {
-        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
-            alloc_tmp_deserializer_store,
-            dealloc_tmp_deserializer_store,
-            get_deserializer_from_store,
-            put_deserializer_in_store,
-            construct_deserializer,
-            destruct_deserializer
-        };
-        struct deserializer_data_st mcmdata;
-
-        mcmdata.libctx = libctx;
-        mcmdata.mcm = &mcm;
-        mcmdata.id = id;
-        mcmdata.names = name;
-        mcmdata.propquery = properties;
-        if ((method = ossl_method_construct(libctx, OSSL_OP_DESERIALIZER,
-                                            0 /* !force_cache */,
-                                            &mcm, &mcmdata)) != NULL) {
-            /*
-             * If construction did create a method for us, we know that
-             * there is a correct name_id and meth_id, since those have
-             * already been calculated in get_deserializer_from_store() and
-             * put_deserializer_in_store() above.
-             */
-            if (id == 0)
-                id = ossl_namemap_name2num(namemap, name);
-            ossl_method_store_cache_set(store, id, properties, method,
-                                        up_ref_deserializer, free_deserializer);
-        }
-    }
-
-    return method;
-}
-
-OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx,
-                                           const char *name,
-                                           const char *properties)
-{
-    return inner_ossl_deserializer_fetch(libctx, 0, name, properties);
-}
-
-OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx,
-                                                     int id,
-                                                     const char *properties)
-{
-    return inner_ossl_deserializer_fetch(libctx, id, NULL, properties);
-}
-
-/*
- * Library of basic method functions
- */
-
-const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *deser)
-{
-    if (!ossl_assert(deser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return deser->base.prov;
-}
-
-const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser)
-{
-    if (!ossl_assert(deser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return deser->base.propdef;
-}
-
-int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deser)
-{
-    if (!ossl_assert(deser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return deser->base.id;
-}
-
-int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deser, const char *name)
-{
-    if (deser->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov);
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        return ossl_namemap_name2num(namemap, name) == deser->base.id;
-    }
-    return 0;
-}
-
-struct deserializer_do_all_data_st {
-    void (*user_fn)(void *method, void *arg);
-    void *user_arg;
-};
-
-static void deserializer_do_one(OSSL_PROVIDER *provider,
-                                const OSSL_ALGORITHM *algodef,
-                                int no_store, void *vdata)
-{
-    struct deserializer_do_all_data_st *data = vdata;
-    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    const char *names = algodef->algorithm_names;
-    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
-    void *method = NULL;
-
-    if (id != 0)
-        method =
-            deserializer_from_dispatch(id, algodef, provider);
-
-    if (method != NULL) {
-        data->user_fn(method, data->user_arg);
-        OSSL_DESERIALIZER_free(method);
-    }
-}
-
-void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                       void (*fn)(OSSL_DESERIALIZER *deser,
-                                                  void *arg),
-                                       void *arg)
-{
-    struct deserializer_do_all_data_st data;
-
-    data.user_fn = (void (*)(void *, void *))fn;
-    data.user_arg = arg;
-    ossl_algorithm_do_all(libctx, OSSL_OP_DESERIALIZER, NULL,
-                          NULL, deserializer_do_one, NULL,
-                          &data);
-}
-
-void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deser,
-                                    void (*fn)(const char *name, void *data),
-                                    void *data)
-{
-    if (deser == NULL)
-        return;
-
-    if (deser->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov);
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        ossl_namemap_doall_names(namemap, deser->base.id, fn, data);
-    }
-}
-
-const OSSL_PARAM *
-OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser)
-{
-    if (deser != NULL && deser->gettable_params != NULL)
-        return deser->gettable_params(
-                   ossl_provider_ctx(OSSL_DESERIALIZER_provider(deser)));
-    return NULL;
-}
-
-int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[])
-{
-    if (deser != NULL && deser->get_params != NULL)
-        return deser->get_params(params);
-    return 0;
-}
-
-const OSSL_PARAM *
-OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser)
-{
-    if (deser != NULL && deser->settable_ctx_params != NULL)
-        return deser->settable_ctx_params(
-                   ossl_provider_ctx(OSSL_DESERIALIZER_provider(deser)));
-    return NULL;
-}
-
-/*
- * Deserializer context support
- */
-
-/*
- * |ser| value NULL is valid, and signifies that there is no deserializer.
- * This is useful to provide fallback mechanisms.
- *  Functions that want to verify if there is a deserializer can do so with
- * OSSL_DESERIALIZER_CTX_get_deserializer()
- */
-OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void)
-{
-    OSSL_DESERIALIZER_CTX *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-
-    ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb;
-    return ctx;
-}
-
-int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
-                                     const OSSL_PARAM params[])
-{
-    size_t i;
-    size_t l;
-
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    if (ctx->deser_insts == NULL)
-        return 1;
-
-    l = (size_t)sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts);
-    for (i = 0; i < l; i++) {
-        OSSL_DESERIALIZER_INSTANCE *deser_inst =
-            sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i);
-
-        if (deser_inst->deserctx == NULL
-            || deser_inst->deser->set_ctx_params == NULL)
-            continue;
-        if (!deser_inst->deser->set_ctx_params(deser_inst->deserctx, params))
-            return 0;
-    }
-    return 1;
-}
-
-static void
-OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *deser_inst)
-{
-    if (deser_inst != NULL) {
-        if (deser_inst->deser->freectx != NULL)
-            deser_inst->deser->freectx(deser_inst->deserctx);
-        deser_inst->deserctx = NULL;
-        OSSL_DESERIALIZER_free(deser_inst->deser);
-        deser_inst->deser = NULL;
-        OPENSSL_free(deser_inst);
-        deser_inst = NULL;
-    }
-}
-
-void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx)
-{
-    if (ctx != NULL) {
-        if (ctx->cleanup != NULL)
-            ctx->cleanup(ctx->construct_data);
-        sk_OSSL_DESERIALIZER_INSTANCE_pop_free(ctx->deser_insts,
-                                               OSSL_DESERIALIZER_INSTANCE_free);
-        OSSL_DESERIALIZER_CTX_set_passphrase_ui(ctx, NULL, NULL);
-        OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0);
-        OPENSSL_free(ctx);
-    }
-}
diff --git a/crypto/serializer/serializer_err.c b/crypto/serializer/serializer_err.c
deleted file mode 100644
index 2ea8b8bede..0000000000
--- a/crypto/serializer/serializer_err.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-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 <openssl/serializererr.h>
-
-#ifndef OPENSSL_NO_ERR
-
-static const ERR_STRING_DATA OSSL_SERIALIZER_str_reasons[] = {
-    {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY),
-    "incorrect property query"},
-    {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND),
-    "serializer not found"},
-    {0, NULL}
-};
-
-#endif
-
-int ERR_load_OSSL_SERIALIZER_strings(void)
-{
-#ifndef OPENSSL_NO_ERR
-    if (ERR_reason_error_string(OSSL_SERIALIZER_str_reasons[0].error) == NULL)
-        ERR_load_strings_const(OSSL_SERIALIZER_str_reasons);
-#endif
-    return 1;
-}
diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h
deleted file mode 100644
index d139e402d7..0000000000
--- a/crypto/serializer/serializer_local.h
+++ /dev/null
@@ -1,140 +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_dispatch.h>
-#include <openssl/types.h>
-#include <openssl/safestack.h>
-#include <openssl/serializer.h>
-#include <openssl/deserializer.h>
-#include "internal/cryptlib.h"
-#include "internal/refcount.h"
-
-struct ossl_serdes_base_st {
-    OSSL_PROVIDER *prov;
-    int id;
-    const char *propdef;
-
-    CRYPTO_REF_COUNT refcnt;
-    CRYPTO_RWLOCK *lock;
-};
-
-struct ossl_serializer_st {
-    struct ossl_serdes_base_st base;
-    OSSL_FUNC_serializer_newctx_fn *newctx;
-    OSSL_FUNC_serializer_freectx_fn *freectx;
-    OSSL_FUNC_serializer_set_ctx_params_fn *set_ctx_params;
-    OSSL_FUNC_serializer_settable_ctx_params_fn *settable_ctx_params;
-    OSSL_FUNC_serializer_serialize_data_fn *serialize_data;
-    OSSL_FUNC_serializer_serialize_object_fn *serialize_object;
-};
-
-struct ossl_deserializer_st {
-    struct ossl_serdes_base_st base;
-    OSSL_FUNC_deserializer_newctx_fn *newctx;
-    OSSL_FUNC_deserializer_freectx_fn *freectx;
-    OSSL_FUNC_deserializer_get_params_fn *get_params;
-    OSSL_FUNC_deserializer_gettable_params_fn *gettable_params;
-    OSSL_FUNC_deserializer_set_ctx_params_fn *set_ctx_params;
-    OSSL_FUNC_deserializer_settable_ctx_params_fn *settable_ctx_params;
-    OSSL_FUNC_deserializer_deserialize_fn *deserialize;
-    OSSL_FUNC_deserializer_export_object_fn *export_object;
-};
-
-struct ossl_serializer_ctx_st {
-    OSSL_SERIALIZER *ser;
-    void *serctx;
-
-    int selection;
-
-    /*-
-     * Output / serializing data, used by OSSL_SERIALIZER_to_{bio,fp}
-     *
-     * |object|         is the libcrypto object to handle.
-     * |do_output|      performs the actual serialization.
-     *
-     * |do_output| must have intimate knowledge of |object|.
-     */
-    const void *object;
-    int (*do_output)(OSSL_SERIALIZER_CTX *ctx, BIO *out);
-
-    /* For any function that needs a passphrase reader */
-    const UI_METHOD *ui_method;
-    void *ui_data;
-    /*
-     * if caller used OSSL_SERIALIZER_CTX_set_passphrase_cb(), we need
-     * intermediary storage.
-     */
-    UI_METHOD *allocated_ui_method;
-};
-
-struct ossl_deserializer_instance_st {
-    OSSL_DESERIALIZER *deser;    /* Never NULL */
-    void *deserctx;              /* Never NULL */
-    const char *input_type;      /* Never NULL */
-};
-
-DEFINE_STACK_OF(OSSL_DESERIALIZER_INSTANCE)
-
-struct ossl_deserializer_ctx_st {
-    /*
-     * The caller may know the input type of the data they pass.  If not,
-     * this will remain NULL and the deserializing functionality will start
-     * with trying to deserialize with any desserializer in |deser_insts|,
-     * regardless of their respective input type.
-     */
-    const char *start_input_type;
-
-    /*
-     * Deserializers that are components of any current deserialization path.
-     */
-    STACK_OF(OSSL_DESERIALIZER_INSTANCE) *deser_insts;
-
-    /*
-     * The constructors of a deserialization, and its caller argument.
-     */
-    OSSL_DESERIALIZER_CONSTRUCT *construct;
-    OSSL_DESERIALIZER_CLEANUP *cleanup;
-    void *construct_data;
-
-    /* For any function that needs a passphrase reader */
-    OSSL_PASSPHRASE_CALLBACK *passphrase_cb;
-    const UI_METHOD *ui_method;
-    void *ui_data;
-    /*
-     * if caller used OSSL_SERIALIZER_CTX_set_pem_password_cb(), we need
-     * intermediary storage.
-     */
-    UI_METHOD *allocated_ui_method;
-    /*
-     * Because the same input may pass through more than one deserializer,
-     * we cache any passphrase passed to us.  The desrializing processor
-     * must clear this at the end of a run.
-     */
-    unsigned char *cached_passphrase;
-    size_t cached_passphrase_len;
-
-    /*
-     * Flag section.  Keep these together
-     */
-
-    /*
-     * The passphrase was passed to us by the user.  In that case, it
-     * should only be freed when freeing this context.
-     */
-    unsigned int flag_user_passphrase:1;
-};
-
-/* Passphrase callbacks, found in serdes_pass.c */
-
-/*
- * Serializers typically want to get an outgoing passphrase, while
- * deserializers typically want to get en incoming passphrase.
- */
-OSSL_PASSPHRASE_CALLBACK ossl_serializer_passphrase_out_cb;
-OSSL_PASSPHRASE_CALLBACK ossl_deserializer_passphrase_in_cb;
diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c
deleted file mode 100644
index 1489fff890..0000000000
--- a/crypto/serializer/serializer_meth.c
+++ /dev/null
@@ -1,522 +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/serializer.h>
-#include <openssl/ui.h>
-#include "internal/core.h"
-#include "internal/namemap.h"
-#include "internal/property.h"
-#include "internal/provider.h"
-#include "crypto/serializer.h"
-#include "serializer_local.h"
-
-/*
- * Serializer can have multiple names, separated with colons in a name string
- */
-#define NAME_SEPARATOR ':'
-
-/* Simple method structure constructor and destructor */
-static OSSL_SERIALIZER *ossl_serializer_new(void)
-{
-    OSSL_SERIALIZER *ser = NULL;
-
-    if ((ser = OPENSSL_zalloc(sizeof(*ser))) == NULL
-        || (ser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) {
-        OSSL_SERIALIZER_free(ser);
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-
-    ser->base.refcnt = 1;
-
-    return ser;
-}
-
-int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser)
-{
-    int ref = 0;
-
-    CRYPTO_UP_REF(&ser->base.refcnt, &ref, ser->base.lock);
-    return 1;
-}
-
-void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser)
-{
-    int ref = 0;
-
-    if (ser == NULL)
-        return;
-
-    CRYPTO_DOWN_REF(&ser->base.refcnt, &ref, ser->base.lock);
-    if (ref > 0)
-        return;
-    ossl_provider_free(ser->base.prov);
-    CRYPTO_THREAD_lock_free(ser->base.lock);
-    OPENSSL_free(ser);
-}
-
-/* Permanent serializer method store, constructor and destructor */
-static void serializer_store_free(void *vstore)
-{
-    ossl_method_store_free(vstore);
-}
-
-static void *serializer_store_new(OPENSSL_CTX *ctx)
-{
-    return ossl_method_store_new(ctx);
-}
-
-
-static const OPENSSL_CTX_METHOD serializer_store_method = {
-    serializer_store_new,
-    serializer_store_free,
-};
-
-/* Data to be passed through ossl_method_construct() */
-struct serializer_data_st {
-    OPENSSL_CTX *libctx;
-    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
-    int id;                      /* For get_serializer_from_store() */
-    const char *names;           /* For get_serializer_from_store() */
-    const char *propquery;       /* For get_serializer_from_store() */
-};
-
-/*
- * Generic routines to fetch / create SERIALIZER methods with
- * ossl_method_construct()
- */
-
-/* Temporary serializer method store, constructor and destructor */
-static void *alloc_tmp_serializer_store(OPENSSL_CTX *ctx)
-{
-    return ossl_method_store_new(ctx);
-}
-
- static void dealloc_tmp_serializer_store(void *store)
-{
-    if (store != NULL)
-        ossl_method_store_free(store);
-}
-
-/* Get the permanent serializer store */
-static OSSL_METHOD_STORE *get_serializer_store(OPENSSL_CTX *libctx)
-{
-    return openssl_ctx_get_data(libctx, OPENSSL_CTX_SERIALIZER_STORE_INDEX,
-                                &serializer_store_method);
-}
-
-/* Get serializer methods from a store, or put one in */
-static void *get_serializer_from_store(OPENSSL_CTX *libctx, void *store,
-                                       void *data)
-{
-    struct serializer_data_st *methdata = data;
-    void *method = NULL;
-    int id;
-
-    if ((id = methdata->id) == 0) {
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        id = ossl_namemap_name2num(namemap, methdata->names);
-    }
-
-    if (store == NULL
-        && (store = get_serializer_store(libctx)) == NULL)
-        return NULL;
-
-    if (!ossl_method_store_fetch(store, id, methdata->propquery, &method))
-        return NULL;
-    return method;
-}
-
-static int put_serializer_in_store(OPENSSL_CTX *libctx, void *store,
-                                   void *method, const OSSL_PROVIDER *prov,
-                                   int operation_id, const char *names,
-                                   const char *propdef, void *unused)
-{
-    OSSL_NAMEMAP *namemap;
-    int id;
-
-    if ((namemap = ossl_namemap_stored(libctx)) == NULL
-        || (id = ossl_namemap_name2num(namemap, names)) == 0)
-        return 0;
-
-    if (store == NULL && (store = get_serializer_store(libctx)) == NULL)
-        return 0;
-
-    return ossl_method_store_add(store, prov, id, propdef, method,
-                                 (int (*)(void *))OSSL_SERIALIZER_up_ref,
-                                 (void (*)(void *))OSSL_SERIALIZER_free);
-}
-
-/* Create and populate a serializer method */
-static void *serializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef,
-                                      OSSL_PROVIDER *prov)
-{
-    OSSL_SERIALIZER *ser = NULL;
-    const OSSL_DISPATCH *fns = algodef->implementation;
-
-    if ((ser = ossl_serializer_new()) == NULL)
-        return NULL;
-    ser->base.id = id;
-    ser->base.propdef = algodef->property_definition;
-
-    for (; fns->function_id != 0; fns++) {
-        switch (fns->function_id) {
-        case OSSL_FUNC_SERIALIZER_NEWCTX:
-            if (ser->newctx == NULL)
-                ser->newctx =
-                    OSSL_FUNC_serializer_newctx(fns);
-            break;
-        case OSSL_FUNC_SERIALIZER_FREECTX:
-            if (ser->freectx == NULL)
-                ser->freectx =
-                    OSSL_FUNC_serializer_freectx(fns);
-            break;
-        case OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS:
-            if (ser->set_ctx_params == NULL)
-                ser->set_ctx_params =
-                    OSSL_FUNC_serializer_set_ctx_params(fns);
-            break;
-        case OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS:
-            if (ser->settable_ctx_params == NULL)
-                ser->settable_ctx_params =
-                    OSSL_FUNC_serializer_settable_ctx_params(fns);
-            break;
-        case OSSL_FUNC_SERIALIZER_SERIALIZE_DATA:
-            if (ser->serialize_data == NULL)
-                ser->serialize_data =
-                    OSSL_FUNC_serializer_serialize_data(fns);
-            break;
-        case OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT:
-            if (ser->serialize_object == NULL)
-                ser->serialize_object =
-                    OSSL_FUNC_serializer_serialize_object(fns);
-            break;
-        }
-    }
-    /*
-     * Try to check that the method is sensible.
-     * If you have a constructor, you must have a destructor and vice versa.
-     * You must have at least one of the serializing driver functions.
-     */
-    if (!((ser->newctx == NULL && ser->freectx == NULL)
-          || (ser->newctx != NULL && ser->freectx != NULL))
-        || (ser->serialize_data == NULL && ser->serialize_object == NULL)) {
-        OSSL_SERIALIZER_free(ser);
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
-    }
-
-    if (prov != NULL && !ossl_provider_up_ref(prov)) {
-        OSSL_SERIALIZER_free(ser);
-        return NULL;
-    }
-
-    ser->base.prov = prov;
-    return ser;
-}
-
-
-/*
- * The core fetching functionality passes the names of the implementation.
- * This function is responsible to getting an identity number for them,
- * then call serializer_from_dispatch() with that identity number.
- */
-static void *construct_serializer(const OSSL_ALGORITHM *algodef,
-                                  OSSL_PROVIDER *prov, void *unused)
-{
-    /*
-     * This function is only called if get_serializer_from_store() returned
-     * NULL, so it's safe to say that of all the spots to create a new
-     * namemap entry, this is it.  Should the name already exist there, we
-     * know that ossl_namemap_add() will return its corresponding number.
-     */
-    OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    const char *names = algodef->algorithm_names;
-    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
-    void *method = NULL;
-
-    if (id != 0)
-        method = serializer_from_dispatch(id, algodef, prov);
-
-    return method;
-}
-
-/* Intermediary function to avoid ugly casts, used below */
-static void destruct_serializer(void *method, void *data)
-{
-    OSSL_SERIALIZER_free(method);
-}
-
-static int up_ref_serializer(void *method)
-{
-    return OSSL_SERIALIZER_up_ref(method);
-}
-
-static void free_serializer(void *method)
-{
-    OSSL_SERIALIZER_free(method);
-}
-
-/* Fetching support.  Can fetch by numeric identity or by name */
-static OSSL_SERIALIZER *inner_ossl_serializer_fetch(OPENSSL_CTX *libctx,
-                                                    int id, const char *name,
-                                                    const char *properties)
-{
-    OSSL_METHOD_STORE *store = get_serializer_store(libctx);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    void *method = NULL;
-
-    if (store == NULL || namemap == NULL)
-        return NULL;
-
-    /*
-     * If we have been passed neither a name_id or a name, we have an
-     * internal programming error.
-     */
-    if (!ossl_assert(id != 0 || name != NULL))
-        return NULL;
-
-    if (id == 0)
-        id = ossl_namemap_name2num(namemap, name);
-
-    if (id == 0
-        || !ossl_method_store_cache_get(store, id, properties, &method)) {
-        OSSL_METHOD_CONSTRUCT_METHOD mcm = {
-            alloc_tmp_serializer_store,
-            dealloc_tmp_serializer_store,
-            get_serializer_from_store,
-            put_serializer_in_store,
-            construct_serializer,
-            destruct_serializer
-        };
-        struct serializer_data_st mcmdata;
-
-        mcmdata.libctx = libctx;
-        mcmdata.mcm = &mcm;
-        mcmdata.id = id;
-        mcmdata.names = name;
-        mcmdata.propquery = properties;
-        if ((method = ossl_method_construct(libctx, OSSL_OP_SERIALIZER,
-                                            0 /* !force_cache */,
-                                            &mcm, &mcmdata)) != NULL) {
-            /*
-             * If construction did create a method for us, we know that
-             * there is a correct name_id and meth_id, since those have
-             * already been calculated in get_serializer_from_store() and
-             * put_serializer_in_store() above.
-             */
-            if (id == 0)
-                id = ossl_namemap_name2num(namemap, name);
-            ossl_method_store_cache_set(store, id, properties, method,
-                                        up_ref_serializer, free_serializer);
-        }
-    }
-
-    return method;
-}
-
-OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx, const char *name,
-                                       const char *properties)
-{
-    return inner_ossl_serializer_fetch(libctx, 0, name, properties);
-}
-
-OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
-                                                 const char *properties)
-{
-    return inner_ossl_serializer_fetch(libctx, id, NULL, properties);
-}
-
-/*
- * Library of basic method functions
- */
-
-const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser)
-{
-    if (!ossl_assert(ser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return ser->base.prov;
-}
-
-const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser)
-{
-    if (!ossl_assert(ser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return ser->base.propdef;
-}
-
-int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser)
-{
-    if (!ossl_assert(ser != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return ser->base.id;
-}
-
-int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, const char *name)
-{
-    if (ser->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov);
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        return ossl_namemap_name2num(namemap, name) == ser->base.id;
-    }
-    return 0;
-}
-
-struct serializer_do_all_data_st {
-    void (*user_fn)(void *method, void *arg);
-    void *user_arg;
-};
-
-static void serializer_do_one(OSSL_PROVIDER *provider,
-                              const OSSL_ALGORITHM *algodef,
-                              int no_store, void *vdata)
-{
-    struct serializer_do_all_data_st *data = vdata;
-    OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
-    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-    const char *names = algodef->algorithm_names;
-    int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
-    void *method = NULL;
-
-    if (id != 0)
-        method =
-            serializer_from_dispatch(id, algodef, provider);
-
-    if (method != NULL) {
-        data->user_fn(method, data->user_arg);
-        OSSL_SERIALIZER_free(method);
-    }
-}
-
-void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                     void (*fn)(OSSL_SERIALIZER *ser,
-                                                void *arg),
-                                     void *arg)
-{
-    struct serializer_do_all_data_st data;
-
-    data.user_fn = (void (*)(void *, void *))fn;
-    data.user_arg = arg;
-
-    /*
-     * No pre- or post-condition for this call, as this only creates methods
-     * temporarly and then promptly destroys them.
-     */
-    ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, NULL,
-                          serializer_do_one, NULL, &data);
-}
-
-void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser,
-                                  void (*fn)(const char *name, void *data),
-                                  void *data)
-{
-    if (ser == NULL)
-        return;
-
-    if (ser->base.prov != NULL) {
-        OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov);
-        OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
-
-        ossl_namemap_doall_names(namemap, ser->base.id, fn, data);
-    }
-}
-
-const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser)
-{
-    if (ser != NULL && ser->settable_ctx_params != NULL)
-        return ser->settable_ctx_params(
-                   ossl_provider_ctx(OSSL_SERIALIZER_provider(ser)));
-    return NULL;
-}
-
-/*
- * Serializer context support
- */
-
-/*
- * |ser| value NULL is valid, and signifies that there is no serializer.
- * This is useful to provide fallback mechanisms.
- *  Functions that want to verify if there is a serializer can do so with
- * OSSL_SERIALIZER_CTX_get_serializer()
- */
-OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser)
-{
-    OSSL_SERIALIZER_CTX *ctx;
-
-    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-
-    ctx->ser = ser;
-    if (ser != NULL && ser->newctx != NULL) {
-        const OSSL_PROVIDER *prov = OSSL_SERIALIZER_provider(ser);
-        void *provctx = ossl_provider_ctx(prov);
-
-        if (OSSL_SERIALIZER_up_ref(ser)) {
-            ctx->serctx = ser->newctx(provctx);
-        } else {
-            OSSL_SERIALIZER_free(ser);
-            OPENSSL_free(ctx);
-            ctx = NULL;
-        }
-    }
-
-    return ctx;
-}
-
-const OSSL_SERIALIZER *
-OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    return ctx->ser;
-}
-
-
-int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx,
-                                   const OSSL_PARAM params[])
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    if (ctx->ser != NULL && ctx->ser->set_ctx_params != NULL)
-        return ctx->ser->set_ctx_params(ctx->serctx, params);
-    return 0;
-}
-
-void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx)
-{
-    if (ctx != NULL) {
-        if (ctx->ser != NULL && ctx->ser->freectx != NULL)
-            ctx->ser->freectx(ctx->serctx);
-        OSSL_SERIALIZER_free(ctx->ser);
-        UI_destroy_method(ctx->allocated_ui_method);
-        OPENSSL_free(ctx);
-    }
-}
diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c
deleted file mode 100644
index d31b3cce8b..0000000000
--- a/crypto/serializer/serializer_pkey.c
+++ /dev/null
@@ -1,275 +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/err.h>
-#include <openssl/ui.h>
-#include <openssl/params.h>
-#include <openssl/serializer.h>
-#include <openssl/core_names.h>
-#include <openssl/safestack.h>
-#include "internal/provider.h"
-#include "internal/property.h"
-#include "crypto/evp.h"
-#include "serializer_local.h"
-
-DEFINE_STACK_OF_CSTRING()
-
-int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx,
-                                   const char *cipher_name,
-                                   const char *propquery)
-{
-    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
-
-    params[0] =
-        OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER,
-                                         (void *)cipher_name, 0);
-    params[1] =
-        OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_PROPERTIES,
-                                         (void *)propquery, 0);
-
-    return OSSL_SERIALIZER_CTX_set_params(ctx, params);
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_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_SERIALIZER_PARAM_PASS,
-                                                  (void *)kstr, klen);
-
-    return OSSL_SERIALIZER_CTX_set_params(ctx, params);
-}
-
-static void serializer_ctx_reset_passphrase_ui(OSSL_SERIALIZER_CTX *ctx)
-{
-    UI_destroy_method(ctx->allocated_ui_method);
-    ctx->allocated_ui_method = NULL;
-    ctx->ui_method = NULL;
-    ctx->ui_data = NULL;
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx,
-                                          const UI_METHOD *ui_method,
-                                          void *ui_data)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    serializer_ctx_reset_passphrase_ui(ctx);
-    ctx->ui_method = ui_method;
-    ctx->ui_data = ui_data;
-    return 1;
-}
-
-int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx,
-                                          pem_password_cb *cb, void *cbarg)
-{
-    if (!ossl_assert(ctx != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-
-    serializer_ctx_reset_passphrase_ui(ctx);
-    if (cb == NULL)
-        return 1;
-    ctx->ui_method =
-        ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 1);
-    ctx->ui_data = cbarg;
-
-    return ctx->ui_method != NULL;
-}
-
-/*
- * Support for OSSL_SERIALIZER_CTX_new_by_TYPE:
- * finding a suitable serializer
- */
-
-struct selected_serializer_st {
-    STACK_OF(OPENSSL_CSTRING) *names;
-    int error;
-};
-
-static void cache_serializers(const char *name, void *data)
-{
-    struct selected_serializer_st *d = data;
-
-    if (sk_OPENSSL_CSTRING_push(d->names, name) <= 0)
-        d->error = 1;
-}
-
-/*
- * Support for OSSL_SERIALIZER_to_bio:
- * writing callback for the OSSL_PARAM (the implementation doesn't have
- * intimate knowledge of the provider side object)
- */
-
-struct serializer_write_data_st {
-    OSSL_SERIALIZER_CTX *ctx;
-    BIO *out;
-};
-
-static int serializer_write_cb(const OSSL_PARAM params[], void *arg)
-{
-    struct serializer_write_data_st *write_data = arg;
-    OSSL_SERIALIZER_CTX *ctx = write_data->ctx;
-    BIO *out = write_data->out;
-
-    return ctx->ser->serialize_data(ctx->serctx, params, (OSSL_CORE_BIO *)out,
-                                    ossl_serializer_passphrase_out_cb, ctx);
-}
-
-/*
- * Support for OSSL_SERIALIZER_to_bio:
- * Perform the actual output.
- */
-
-static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
-{
-    const EVP_PKEY *pkey = ctx->object;
-    void *keydata = pkey->keydata;
-    EVP_KEYMGMT *keymgmt = pkey->keymgmt;
-
-    /*
-     * OSSL_SERIALIZER_CTX_new() creates a context, even when the
-     * serializer it's given is NULL.  Callers can detect the lack
-     * of serializer with OSSL_SERIALIZER_CTX_get_serializer() and
-     * should take precautions, possibly call a fallback instead of
-     * OSSL_SERIALIZER_to_bio() / OSSL_SERIALIZER_to_fp().  If it's
-     * come this far, we return an error.
-     */
-    if (ctx->ser == NULL)
-        return 0;
-
-    if (ctx->ser->serialize_object == NULL
-        || OSSL_SERIALIZER_provider(ctx->ser) != EVP_KEYMGMT_provider(keymgmt)) {
-        struct serializer_write_data_st write_data;
-
-        write_data.ctx = ctx;
-        write_data.out = out;
-
-        return evp_keymgmt_export(keymgmt, keydata, ctx->selection,
-                                  &serializer_write_cb, &write_data);
-    }
-
-    return ctx->ser->serialize_object(ctx->serctx, keydata,
-                                      (OSSL_CORE_BIO *)out,
-                                      ossl_serializer_passphrase_out_cb, ctx);
-}
-
-/*
- * OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a ctx with no serializer if
- * it couldn't find a suitable serializer.  This allows a caller to detect if
- * a suitable serializer was found, with OSSL_SERIALIZER_CTX_get_serializer(),
- * and to use fallback methods if the result is NULL.
- */
-OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                                         const char *propquery)
-{
-    OSSL_SERIALIZER_CTX *ctx = NULL;
-    OSSL_SERIALIZER *ser = NULL;
-    EVP_KEYMGMT *keymgmt = pkey->keymgmt;
-    int selection = OSSL_KEYMGMT_SELECT_ALL;
-
-    if (!ossl_assert(pkey != NULL && propquery != NULL)) {
-        ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER);
-        return NULL;
-    }
-
-    if (keymgmt != NULL) {
-        const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt);
-        OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov);
-        struct selected_serializer_st sel_data;
-        OSSL_SERIALIZER *first = NULL;
-        const char *name;
-        int i;
-
-        /*
-         * Select the serializer in two steps.  First, get the names of all of
-         * the serializers.  Then determine which is the best one to use.
-         * This has to be broken because it isn't possible to fetch the
-         * serialisers inside EVP_KEYMGMT_names_do_all() due to locking
-         * order inversions with the store lock.
-         */
-        sel_data.error = 0;
-        sel_data.names = sk_OPENSSL_CSTRING_new_null();
-        if (sel_data.names == NULL)
-            return NULL;
-        EVP_KEYMGMT_names_do_all(keymgmt, cache_serializers, &sel_data);
-        /*
-         * Ignore memory allocation errors that are indicated in sel_data.error
-         * in case a suitable provider does get found regardless.
-         */
-
-        /*
-         * Serializers offer two functions, one that handles object data in
-         * the form of a OSSL_PARAM array, and one that directly handles a
-         * provider side object.  The latter requires that the serializer
-         * is offered by the same provider that holds that object, but is
-         * more desirable because it usually provides faster serialization.
-         *
-         * When looking up possible serializers, we save the first that can
-         * handle an OSSL_PARAM array in |first| and use that if nothing
-         * better turns up.
-         */
-        for (i = 0; i < sk_OPENSSL_CSTRING_num(sel_data.names); i++) {
-            name = sk_OPENSSL_CSTRING_value(sel_data.names, i);
-            ser = OSSL_SERIALIZER_fetch(libctx, name, propquery);
-            if (ser != NULL) {
-                if (OSSL_SERIALIZER_provider(ser) == desired_prov
-                        && ser->serialize_object != NULL) {
-                    OSSL_SERIALIZER_free(first);
-                    break;
-                }
-                if (first == NULL && ser->serialize_data != NULL)
-                    first = ser;
-                else
-                    OSSL_SERIALIZER_free(ser);
-                ser = NULL;
-            }
-        }
-        sk_OPENSSL_CSTRING_free(sel_data.names);
-        if (ser == NULL)
-            ser = first;
-
-        if (ser != NULL) {
-            OSSL_PROPERTY_LIST *check = NULL, *current_props = NULL;
-
-            check = ossl_parse_query(libctx, "type=parameters");
-            current_props =
-                ossl_parse_property(libctx, OSSL_SERIALIZER_properties(ser));
-            if (ossl_property_match_count(check, current_props) > 0)
-                selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
-            ossl_property_free(current_props);
-            ossl_property_free(check);
-        } else {
-            if (sel_data.error)
-                ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE);
-            else
-                ERR_raise(ERR_LIB_OSSL_SERIALIZER,
-                          OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND);
-        }
-    }
-
-    ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */
-    OSSL_SERIALIZER_free(ser);          /* refcnt(ser)-- */
-
-    if (ctx != NULL) {
-        /* Setup for OSSL_SERIALIZE_to_bio() */
-        ctx->selection = selection;
-        ctx->object = pkey;
-        ctx->do_output = serializer_EVP_PKEY_to_bio;
-    }
-
-    return ctx;
-}
-
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
index 59f4a14895..cb47f917ad 100644
--- a/crypto/x509/x_pubkey.c
+++ b/crypto/x509/x_pubkey.c
@@ -22,7 +22,7 @@
 #include "crypto/x509.h"
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 
 struct X509_pubkey_st {
     X509_ALGOR *algor;
@@ -97,18 +97,18 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
         }
     } else if (pkey->keymgmt != NULL) {
         BIO *bmem = BIO_new(BIO_s_mem());
-        const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
-        OSSL_SERIALIZER_CTX *sctx =
-            OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, serprop);
+        const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+        OSSL_ENCODER_CTX *ectx =
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, encprop);
 
-        if (OSSL_SERIALIZER_to_bio(sctx, bmem)) {
+        if (OSSL_ENCODER_to_bio(ectx, bmem)) {
             const unsigned char *der = NULL;
             long derlen = BIO_get_mem_data(bmem, (char **)&der);
 
             pk = d2i_X509_PUBKEY(NULL, &der, derlen);
         }
 
-        OSSL_SERIALIZER_CTX_free(sctx);
+        OSSL_ENCODER_CTX_free(ectx);
         BIO_free(bmem);
     }
 
@@ -124,7 +124,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
 
     /*
      * pk->pkey is NULL when using the legacy routine, but is non-NULL when
-     * going through the serializer, and for all intents and purposes, it's
+     * going through the encoder, and for all intents and purposes, it's
      * a perfect copy of |pkey|, just not the same instance.  In that case,
      * we could simply return early, right here.
      * However, in the interest of being cautious leaning on paranoia, some
@@ -303,16 +303,16 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
         }
         X509_PUBKEY_free(xpk);
     } else if (a->keymgmt != NULL) {
-        const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
-        OSSL_SERIALIZER_CTX *ctx =
-            OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop);
+        const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+        OSSL_ENCODER_CTX *ctx =
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
         BIO *out = BIO_new(BIO_s_mem());
         BUF_MEM *buf = NULL;
 
         if (ctx != NULL
             && out != NULL
-            && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL
-            && OSSL_SERIALIZER_to_bio(ctx, out)
+            && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
+            && OSSL_ENCODER_to_bio(ctx, out)
             && BIO_get_mem_ptr(out, &buf) > 0) {
             ret = buf->length;
 
@@ -328,7 +328,7 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
             }
         }
         BIO_free(out);
-        OSSL_SERIALIZER_CTX_free(ctx);
+        OSSL_ENCODER_CTX_free(ctx);
     }
 
     return ret;
diff --git a/doc/man1/openssl-list.pod.in b/doc/man1/openssl-list.pod.in
index df970a0959..26680849a2 100644
--- a/doc/man1/openssl-list.pod.in
+++ b/doc/man1/openssl-list.pod.in
@@ -19,8 +19,8 @@ B<openssl list>
 [B<-random-generators>]
 [B<-cipher-commands>]
 [B<-cipher-algorithms>]
-[B<-serializers>]
-[B<-deserializers>]
+[B<-encoders>]
+[B<-decoders>]
 [B<-public-key-algorithms>]
 {- output_off() if $disabled{"deprecated-3.0"}; ""
 -}[B<-public-key-methods>]
@@ -84,18 +84,18 @@ Display a list of random number generators.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
-=item B<-serializers>
+=item B<-encoders>
 
-Display a list of serializers.
+Display a list of encoders.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
 In verbose mode, the algorithms provided by a provider will get additional
 information on what parameters each implementation supports.
 
-=item B<-deserializers>
+=item B<-decoders>
 
-Display a list of deserializers.
+Display a list of decoders.
 See L</Display of algorithm names> for a description of how names are
 displayed.
 
diff --git a/doc/man3/OSSL_DECODER.pod b/doc/man3/OSSL_DECODER.pod
new file mode 100644
index 0000000000..96d0a51ca5
--- /dev/null
+++ b/doc/man3/OSSL_DECODER.pod
@@ -0,0 +1,142 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER,
+OSSL_DECODER_fetch,
+OSSL_DECODER_up_ref,
+OSSL_DECODER_free,
+OSSL_DECODER_provider,
+OSSL_DECODER_properties,
+OSSL_DECODER_is_a,
+OSSL_DECODER_number,
+OSSL_DECODER_do_all_provided,
+OSSL_DECODER_names_do_all,
+OSSL_DECODER_gettable_params,
+OSSL_DECODER_get_params
+- Decoder method routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ typedef struct ossl_decoder_st OSSL_DECODER;
+
+ OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *ctx, const char *name,
+                                  const char *properties);
+ int OSSL_DECODER_up_ref(OSSL_DECODER *decoder);
+ void OSSL_DECODER_free(OSSL_DECODER *decoder);
+ const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *decoder);
+ const char *OSSL_DECODER_properties(const OSSL_DECODER *decoder);
+ int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name);
+ int OSSL_DECODER_number(const OSSL_DECODER *decoder);
+ void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+                                   void (*fn)(OSSL_DECODER *decoder, void *arg),
+                                   void *arg);
+ void OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder,
+                                void (*fn)(const char *name, void *data),
+                                void *data);
+ const OSSL_PARAM *OSSL_DECODER_gettable_params(OSSL_DECODER *decoder);
+ int OSSL_DECODER_get_params(OSSL_DECODER_CTX *ctx, const OSSL_PARAM params[]);
+
+=head1 DESCRIPTION
+
+B<OSSL_DECODER> is a method for decoders, which know how to
+decode encoded data into an object of some type that the rest
+of OpenSSL knows how to handle.
+
+OSSL_DECODER_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<name> and the properties given by I<properties>.
+The I<name> determines what type of object the fetched decoder
+method is expected to be able to decode, and the properties are
+used to determine the expected output type.
+For known properties and the values they may have, please have a look
+in L<provider-encoder(7)/Names and properties>.
+
+OSSL_DECODER_up_ref() increments the reference count for the given
+I<decoder>.
+
+OSSL_DECODER_free() decrements the reference count for the given
+I<decoder>, and when the count reaches zero, frees it.
+
+OSSL_DECODER_provider() returns the provider of the given
+I<decoder>.
+
+OSSL_DECODER_properties() returns the property definition associated
+with the given I<decoder>.
+
+OSSL_DECODER_is_a() checks if I<decoder> is an implementation
+of an algorithm that's identifiable with I<name>.
+
+OSSL_DECODER_number() returns the internal dynamic number assigned
+to the given I<decoder>.
+
+OSSL_DECODER_names_do_all() traverses all names for the given
+I<decoder>, and calls I<fn> with each name and I<data>.
+
+OSSL_DECODER_do_all_provided() traverses all encoder
+implementations by all activated providers in the library context
+I<libctx>, and for each of the implementations, calls I<fn> with the
+implementation method and I<data> as arguments.
+
+OSSL_DECODER_gettable_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DECODER_get_params() attempts to get parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
+implementation doesn't recognise should be ignored.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_fetch() returns a pointer to an OSSL_DECODER object,
+or NULL on error.
+
+OSSL_DECODER_up_ref() returns 1 on success, or 0 on error.
+
+OSSL_DECODER_free() doesn't return any value.
+
+OSSL_DECODER_provider() returns a pointer to a provider object, or
+NULL on error.
+
+OSSL_DECODER_properties() returns a pointer to a property
+definition string, or NULL on error.
+
+OSSL_DECODER_is_a() returns 1 if I<decoder> was identifiable,
+otherwise 0.
+
+OSSL_DECODER_number() returns an integer.
+
+=head1 NOTES
+
+OSSL_DECODER_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER_CTX(3)>, L<OSSL_DECODER_from_bio(3)>,
+L<OSSL_DECODER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_CTX.pod b/doc/man3/OSSL_DECODER_CTX.pod
new file mode 100644
index 0000000000..7dbd7550df
--- /dev/null
+++ b/doc/man3/OSSL_DECODER_CTX.pod
@@ -0,0 +1,74 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_CTX,
+OSSL_DECODER_CTX_new,
+OSSL_DECODER_settable_ctx_params,
+OSSL_DECODER_CTX_set_params,
+OSSL_DECODER_CTX_free
+- Encoder context routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ typedef struct ossl_decoder_ctx_st OSSL_DECODER_CTX;
+
+ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(OPENSSL_CTX *libctx);
+ const OSSL_PARAM *OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder);
+ int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+                                 const OSSL_PARAM params[]);
+ void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx);
+
+=head1 DESCRIPTION
+
+B<OSSL_DECODER_CTX> is a context with which B<OSSL_DECODER>
+operations are performed.  The context typically holds values, both
+internal and supplied by the application, which are useful for the
+implementations supplied by providers.
+
+OSSL_DECODER_CTX_new() creates a new empty B<OSSL_DECODER_CTX>.
+
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_DECODER_CTX_set_params() attempts to set parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  These parameters are passed
+to all decoders that have been added to the I<ctx> so far.
+Parameters that an implementation doesn't recognise should be ignored
+by it.
+
+OSSL_DECODER_CTX_free() frees the given context I<ctx>.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_CTX_new() returns a pointer to a
+B<OSSL_DECODER_CTX>, or NULL if the context structure couldn't be
+allocated.
+
+OSSL_DECODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array, or NULL if none is available.
+
+OSSL_DECODER_CTX_set_params() returns 1 if all recognised
+parameters were valid, or 0 if one of them was invalid or caused some
+other failure in the implementation.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER(3)>, L<OSSL_DECODER_from_bio(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod
new file mode 100644
index 0000000000..4486e6b001
--- /dev/null
+++ b/doc/man3/OSSL_DECODER_CTX_new_by_EVP_PKEY.pod
@@ -0,0 +1,109 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY,
+OSSL_DECODER_CTX_set_passphrase,
+OSSL_DECODER_CTX_set_pem_password_cb,
+OSSL_DECODER_CTX_set_passphrase_ui
+- Decoder routines to decode EVP_PKEYs
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ OSSL_DECODER_CTX *
+ OSSL_DECODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, const char *input_type,
+                                  OPENSSL_CTX *libctx, const char *propquery);
+
+ int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+                                     const unsigned char *kstr,
+                                     size_t klen);
+ int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+                                          pem_password_cb *cb,
+                                          void *cbarg);
+ int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+                                        const UI_METHOD *ui_method,
+                                        void *ui_data);
+
+=head1 DESCRIPTION
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY() is a utility function that
+creates a B<OSSL_DECODER_CTX>, finds all applicable decoder
+implementations and sets them up, so all the caller has to do next is
+call functions like OSSL_DECODE_from_bio().
+
+Internally OSSL_DECODER_CTX_new_by_EVP_PKEY() searches for all
+available L<EVP_KEYMGMT(3)> implementations, and then builds a list of all
+potential decoder implementations that may be able to process the
+encoded input into data suitable for B<EVP_PKEY>s.  All these
+implementations are implicitly fetched using I<libctx> and I<propquery>.
+
+The search of decoder implementations can be limited with
+I<input_type>, which specifies a starting input type.  This is further
+explained in L<OSSL_DECODER_CTX_set_input_type(3)>.
+
+If no suitable decoder was found, OSSL_DECODER_CTX_new_by_EVP_PKEY()
+still creates a B<OSSL_DECODER_CTX>, but with no associated
+decoder (L<OSSL_DECODER_CTX_num_decoders(3)> returns
+zero).  This helps the caller distinguish between an error when
+creating the B<OSSL_DECODER_CTX>, and the lack the decoder
+support and act accordingly.
+
+OSSL_DECODER_CTX_set_passphrase() gives the implementation a
+pass phrase to use when decrypting the encoded private key.
+Alternatively, a pass phrase callback may be specified with the
+following functions.
+
+OSSL_DECODER_CTX_set_pem_password_cb() and
+OSSL_DECODER_CTX_set_passphrase_ui() set up a callback method that
+the implementation can use to prompt for a pass phrase, giving the caller
+the choice of prefered pass phrase callback form.  These are called
+indirectly, through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+
+The internal B<OSSL_PASSPHRASE_CALLBACK> function caches the pass phrase, to
+be re-used in all decodings that are performed in the same
+decoding run
+(for example, within one L<OSSL_DECODER_from_bio(3)> call).
+
+=for comment the name OSSL_DECODER_CTX_set_pem_password_cb() leaves
+open the future possibility of having a function where the caller can set a
+B<OSSL_PASSPHRASE_CALLBACK> method as another option.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_CTX_new_by_EVP_PKEY() returns a pointer to a
+B<OSSL_DECODER_CTX>, or NULL if it couldn't be created.
+
+OSSL_DECODER_CTX_set_passphrase(),
+OSSL_DECODER_CTX_set_pem_password_cb() and
+OSSL_DECODER_CTX_set_passphrase_ui()
+all return 1 on success, or 0 on failure.
+
+=head1 NOTES
+
+Parts of the function names are made to match already existing OpenSSL
+names.
+
+B<EVP_PKEY> in OSSL_DECODER_CTX_new_by_EVP_PKEY() matches the type
+name, thus making for the naming pattern
+B<OSSL_DECODER_CTX_new_by_I<TYPE>>() when new types are handled.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER(3)>, L<OSSL_DECODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DECODER_from_bio.pod b/doc/man3/OSSL_DECODER_from_bio.pod
new file mode 100644
index 0000000000..1beb74d5ff
--- /dev/null
+++ b/doc/man3/OSSL_DECODER_from_bio.pod
@@ -0,0 +1,276 @@
+=pod
+
+=head1 NAME
+
+OSSL_DECODER_from_bio,
+OSSL_DECODER_from_fp,
+OSSL_DECODER_CTX_set_input_type,
+OSSL_DECODER_CTX_add_decoder,
+OSSL_DECODER_CTX_add_extra,
+OSSL_DECODER_CTX_num_decoders,
+OSSL_DECODER_INSTANCE,
+OSSL_DECODER_CONSTRUCT,
+OSSL_DECODER_CLEANUP,
+OSSL_DECODER_CTX_set_construct,
+OSSL_DECODER_CTX_set_construct_data,
+OSSL_DECODER_CTX_set_cleanup,
+OSSL_DECODER_CTX_get_construct,
+OSSL_DECODER_CTX_get_construct_data,
+OSSL_DECODER_CTX_get_cleanup,
+OSSL_DECODER_export,
+OSSL_DECODER_INSTANCE_decoder,
+OSSL_DECODER_INSTANCE_decoder_ctx
+- Routines to perform a decoding
+
+=head1 SYNOPSIS
+
+ #include <openssl/decoder.h>
+
+ int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in);
+ int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp);
+
+ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+                                     const char *input_type);
+ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder);
+ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx);
+ int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx);
+
+ typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE;
+ OSSL_DECODER *
+ OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst);
+ void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst);
+
+ typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst,
+                                      const OSSL_PARAM *params,
+                                      void *construct_data);
+ typedef void (OSSL_DECODER_CLEANUP)(void *construct_data);
+
+ int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+                                    OSSL_DECODER_CONSTRUCT *construct);
+ int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+                                         void *construct_data);
+ int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+                                  OSSL_DECODER_CLEANUP *cleanup);
+ OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx);
+ void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx);
+ OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx);
+
+ int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+                         void *reference, size_t reference_sz,
+                         OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+Feature availability macros:
+
+=over 4
+
+=item OSSL_DECODER_from_fp() is only available when B<OPENSSL_NO_STDIO>
+is undefined.
+
+=back
+
+=head1 DESCRIPTION
+
+The B<OSSL_DECODER_CTX> holds data about multiple decoders, as
+needed to figure out what the input data is and to attempt to unpack it into
+one of several possible related results.  This also includes chaining
+decoders, so the output from one can become the input for another.
+This allows having generic format decoders such as PEM to DER, as well
+as more specialized decoders like DER to RSA.
+
+The chains may be limited by specifying an input type, which is considered a
+starting point.
+This is both considered by OSSL_DECODER_CTX_add_extra(), which will
+stop adding on more decoder implementations when it has already added
+those that take the specified input type, and OSSL_DECODER_from_bio(),
+which will only start the decoding process with the decoder
+implementations that take that input type.  For example, if the input type
+is set to C<DER>, a PEM to DER decoder will be ignored.
+
+The input type can also be NULL, which means that the caller doesn't know
+what type of input they have.  In this case, OSSL_DECODER_from_bio()
+will simply try with one decoder implementation after the other, and
+thereby discover what kind of input the caller gave it.
+
+For every decoding done, even an intermediary one, a constructor
+provided by the caller is called to attempt to construct an appropriate type
+/ structure that the caller knows how to handle from the current
+decoding result.
+The constructor is set with OSSL_DECODER_CTX_set_construct().
+
+B<OSSL_DECODER_INSTANCE> is an opaque structure that contains
+data about the decoder that was just used, and that may be
+useful for the constructor.  There are some functions to extract data
+from this type, described further down.
+
+=head2 Functions
+
+OSSL_DECODER_from_bio() runs the decoding process for the
+context I<ctx>, with the input coming from the B<BIO> I<in>.  Should
+it make a difference, it's recommended to have the BIO set in binary
+mode rather than text mode.
+
+OSSL_DECODER_from_fp() does the same thing as OSSL_DECODER_from_bio(),
+except that the input is coming from the B<FILE> I<fp>.
+
+OSSL_DECODER_CTX_add_decoder() populates the B<OSSL_DECODER_CTX>
+I<ctx> with a decoder, to be used to attempt to decode some
+encoded input.
+
+OSSL_DECODER_CTX_add_extra() finds decoders that generate
+input for already added decoders, and adds them as well.  This is
+used to build decoder chains.
+
+OSSL_DECODER_CTX_set_input_type() sets the starting input type.  This
+limits the decoder chains to be considered, as explained in the general
+description above.
+
+OSSL_DECODER_CTX_num_decoders() gets the number of
+decoders currently added to the context I<ctx>.
+
+OSSL_DECODER_CTX_set_construct() sets the constructor I<construct>.
+
+OSSL_DECODER_CTX_set_construct_data() sets the constructor data that is
+passed to the constructor every time it's called.
+
+OSSL_DECODER_CTX_set_cleanup() sets the constructor data I<cleanup>
+function.  This is called by L<OSSL_DECODER_CTX_free(3)>.
+
+OSSL_DECODER_CTX_get_construct(),
+OSSL_DECODER_CTX_get_construct_data() and
+OSSL_DECODER_CTX_get_cleanup()
+return the values that have been set by
+OSSL_DECODER_CTX_set_construct(),
+OSSL_DECODER_CTX_set_construct_data() and
+OSSL_DECODER_CTX_set_cleanup() respectively.
+
+OSSL_DECODER_export() is a fallback function for constructors that
+cannot use the data they get directly for diverse reasons.  It takes the same
+decode instance I<decoder_inst> that the constructor got and an object
+I<reference>, unpacks the object which it refers to, and exports it by creating
+an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>, along with
+I<export_arg>.
+
+OSSL_DECODER_INSTANCE_decoder() can be used to get the
+decoder method from a decoder instance I<decoder_inst>.
+
+OSSL_DECODER_INSTANCE_decoder-ctx() can be used to get the
+decoder method's provider context from a decoder instance
+I<decoder_inst>.
+
+=head2 Constructor
+
+A B<OSSL_DECODER_CONSTRUCT> gets the following arguments:
+
+=over 4
+
+=item I<decoder_inst>
+
+The B<OSSL_DECODER_INSTANCE> for the decoder from which
+the constructor gets its data.
+
+=item I<params>
+
+The data produced by the decoder, further described below.
+
+=item I<construct_data>
+
+The pointer that was set with OSSL_DECODE_CTX_set_construct_data().
+
+=back
+
+The constructor is expected to return 1 when the data it receives can
+be constructed, otherwise 0.
+
+The globally known parameters that the constructor can get in I<params>
+are:
+
+=over 4
+
+=item "data-type" (B<OSSL_DECODER_PARAM_DATA_TYPE>) <UTF8 string>
+
+This is a detected content type that some decoders may provide.
+For example, PEM input sometimes has a type specified in its header,
+and some decoders may add that information as this parameter.
+This is an optional parameter, but may be useful for extra checks in
+the constructor.
+
+=item "data" (B<OSSL_DECODER_PARAM_DATA>) <octet string>
+
+The decoded data itself, as an octet string.  This is produced by
+decoders when it's possible to pass an object in this form.  Most
+often, this is simply meant to be passed to the next decoder in a
+chain, but could be considered final data as well, at the discretion
+of the constructor.
+
+=item "reference" (B<OSSL_DECODER_PARAM_DATA>) <octet string>
+
+The decoded data itself, as a reference to an object.  The
+reference itself is an octet string, and can be passed to other
+operations and functions within the same provider as the one that
+provides I<decoder>.
+
+=back
+
+At least one of "data" or "reference" must be present, and it's
+possible that both can be.  A constructor should choose to use the
+"reference" parameter if possible, otherwise it should use the "data"
+parameter.
+
+If it's not possible to use the "reference" parameter, but that's
+still what a constructor wants to do, it is possible to use
+OSSL_DECODER_export() as a fallback.
+
+=head1 RETURN VALUES
+
+OSSL_DECODER_from_bio() and OSSL_DECODER_from_fp() return 1 on
+success, or 0 on failure.
+
+OSSL_DECODER_CTX_add_decoder(),
+OSSL_DECODER_CTX_add_extra(),
+OSSL_DECODER_CTX_set_construct(),
+OSSL_DECODER_CTX_set_construct_data() and
+OSSL_DECODER_CTX_set_cleanup() return 1 on success, or 0 on
+failure.
+
+OSSL_DECODER_CTX_get_construct(),
+OSSL_DECODER_CTX_get_construct_data() and
+OSSL_DECODER_CTX_get_cleanup() return the current pointers to the
+cosntructor, the constructor data and the cleanup functions, respectively.
+
+OSSL_DECODER_CTX_num_decoders() returns the current
+number of decoders.  It returns 0 if I<ctx> is NULL.
+
+OSSL_DECODER_export() returns 1 on success, or 0 on failure.
+
+OSSL_DECODER_INSTANCE_decoder() returns an
+B<OSSL_DECODER> pointer on success, or NULL on failure.
+
+OSSL_DECODER_INSTANCE_decoder_ctx() returns a provider
+context pointer on success, or NULL on failure.>
+
+=begin comment TODO(3.0) Add examples!
+
+=head1 EXAMPLES
+
+Text, because pod2xxx doesn't like empty sections
+
+=end comment
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_DECODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_DESERIALIZER.pod b/doc/man3/OSSL_DESERIALIZER.pod
deleted file mode 100644
index 5562a8122b..0000000000
--- a/doc/man3/OSSL_DESERIALIZER.pod
+++ /dev/null
@@ -1,146 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER,
-OSSL_DESERIALIZER_fetch,
-OSSL_DESERIALIZER_up_ref,
-OSSL_DESERIALIZER_free,
-OSSL_DESERIALIZER_provider,
-OSSL_DESERIALIZER_properties,
-OSSL_DESERIALIZER_is_a,
-OSSL_DESERIALIZER_number,
-OSSL_DESERIALIZER_do_all_provided,
-OSSL_DESERIALIZER_names_do_all,
-OSSL_DESERIALIZER_gettable_params,
-OSSL_DESERIALIZER_get_params
-- Deserializer method routines
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- typedef struct ossl_deserializer_st OSSL_DESERIALIZER;
-
- OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name,
-                                            const char *properties);
- int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deserializer);
- void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deserializer);
- const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER
-                                                 *deserializer);
- const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deserializer,
-                            const char *name);
- int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deserializer);
- void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                        void (*fn)(OSSL_DESERIALIZER *deserializer,
-                                                   void *arg),
-                                        void *arg);
- void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deserializer,
-                                     void (*fn)(const char *name, void *data),
-                                     void *data);
- const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER_CTX *ctx,
-                                  const OSSL_PARAM params[]);
-
-=head1 DESCRIPTION
-
-B<OSSL_DESERIALIZER> is a method for deserializers, which know how to
-deserialize serialized data into an object of some type that the rest
-of OpenSSL knows how to handle.
-
-OSSL_DESERIALIZER_fetch() looks for an algorithm within the provider that
-has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
-name given by I<name> and the properties given by I<properties>.
-The I<name> determines what type of object the fetched deserializer
-method is expected to be able to deserialize, and the properties are
-used to determine the expected output type.
-For known properties and the values they may have, please have a look
-in L<provider-serializer(7)/Names and properties>.
-
-OSSL_DESERIALIZER_up_ref() increments the reference count for the given
-I<deserializer>.
-
-OSSL_DESERIALIZER_free() decrements the reference count for the given
-I<deserializer>, and when the count reaches zero, frees it.
-
-OSSL_DESERIALIZER_provider() returns the provider of the given
-I<deserializer>.
-
-OSSL_DESERIALIZER_properties() returns the property definition associated
-with the given I<deserializer>.
-
-OSSL_DESERIALIZER_is_a() checks if I<deserializer> is an implementation
-of an algorithm that's identifiable with I<name>.
-
-OSSL_DESERIALIZER_number() returns the internal dynamic number assigned
-to the given I<deserializer>.
-
-OSSL_DESERIALIZER_names_do_all() traverses all names for the given
-I<deserializer>, and calls I<fn> with each name and I<data>.
-
-OSSL_DESERIALIZER_do_all_provided() traverses all serializer
-implementations by all activated providers in the library context
-I<libctx>, and for each of the implementations, calls I<fn> with the
-implementation method and I<data> as arguments.
-
-OSSL_DESERIALIZER_gettable_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_DESERIALIZER_get_params() attempts to get parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
-implementation doesn't recognise should be ignored.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_fetch() returns a pointer to an OSSL_DESERIALIZER object,
-or NULL on error.
-
-OSSL_DESERIALIZER_up_ref() returns 1 on success, or 0 on error.
-
-OSSL_DESERIALIZER_free() doesn't return any value.
-
-OSSL_DESERIALIZER_provider() returns a pointer to a provider object, or
-NULL on error.
-
-OSSL_DESERIALIZER_properties() returns a pointer to a property
-definition string, or NULL on error.
-
-OSSL_DESERIALIZER_is_a() returns 1 if I<deserializer> was identifiable,
-otherwise 0.
-
-OSSL_DESERIALIZER_number() returns an integer.
-
-=head1 NOTES
-
-OSSL_DESERIALIZER_fetch() may be called implicitly by other fetching
-functions, using the same library context and properties.
-Any other API that uses keys will typically do this.
-
-=begin comment TODO(3.0) Add examples!
-
-=head1 EXAMPLES
-
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>, L<OSSL_DESERIALIZER_from_bio(3)>,
-L<OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_CTX.pod b/doc/man3/OSSL_DESERIALIZER_CTX.pod
deleted file mode 100644
index 413584f8dc..0000000000
--- a/doc/man3/OSSL_DESERIALIZER_CTX.pod
+++ /dev/null
@@ -1,74 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_CTX,
-OSSL_DESERIALIZER_CTX_new,
-OSSL_DESERIALIZER_settable_ctx_params,
-OSSL_DESERIALIZER_CTX_set_params,
-OSSL_DESERIALIZER_CTX_free
-- Serializer context routines
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX;
-
- OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(OPENSSL_CTX *libctx);
- const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
-                                      const OSSL_PARAM params[]);
- void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx);
-
-=head1 DESCRIPTION
-
-B<OSSL_DESERIALIZER_CTX> is a context with which B<OSSL_DESERIALIZER>
-operations are performed.  The context typically holds values, both
-internal and supplied by the application, which are useful for the
-implementations supplied by providers.
-
-OSSL_DESERIALIZER_CTX_new() creates a new empty B<OSSL_DESERIALIZER_CTX>.
-
-OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_DESERIALIZER_CTX_set_params() attempts to set parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  These parameters are passed
-to all deserializers that have been added to the I<ctx> so far.
-Parameters that an implementation doesn't recognise should be ignored
-by it.
-
-OSSL_DESERIALIZER_CTX_free() frees the given context I<ctx>.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_CTX_new() returns a pointer to a
-B<OSSL_DESERIALIZER_CTX>, or NULL if the context structure couldn't be
-allocated.
-
-OSSL_DESERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array, or NULL if none is available.
-
-OSSL_DESERIALIZER_CTX_set_params() returns 1 if all recognised
-parameters were valid, or 0 if one of them was invalid or caused some
-other failure in the implementation.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER(3)>, L<OSSL_DESERIALIZER_from_bio(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
deleted file mode 100644
index c8466657c9..0000000000
--- a/doc/man3/OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY.pod
+++ /dev/null
@@ -1,111 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY,
-OSSL_DESERIALIZER_CTX_set_passphrase,
-OSSL_DESERIALIZER_CTX_set_pem_password_cb,
-OSSL_DESERIALIZER_CTX_set_passphrase_ui
-- Deserializer routines to deserialize EVP_PKEYs
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- OSSL_DESERIALIZER_CTX *
- OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                       const char *input_type,
-                                       OPENSSL_CTX *libctx,
-                                       const char *propquery);
-
- int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
-                                          const unsigned char *kstr,
-                                          size_t klen);
- int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                               pem_password_cb *cb,
-                                               void *cbarg);
- int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
-                                             const UI_METHOD *ui_method,
-                                             void *ui_data);
-
-=head1 DESCRIPTION
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() is a utility function that
-creates a B<OSSL_DESERIALIZER_CTX>, finds all applicable deserializer
-implementations and sets them up, so all the caller has to do next is
-call functions like OSSL_DESERIALIZE_from_bio().
-
-Internally OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() searches for all
-available L<EVP_KEYMGMT(3)> implementations, and then builds a list of all
-potential deserializer implementations that may be able to process the
-serialized input into data suitable for B<EVP_PKEY>s.  All these
-implementations are implicitly fetched using I<libctx> and I<propquery>.
-
-The search of deserializer implementations can be limited with
-I<input_type>, which specifies a starting input type.  This is further
-explained in L<OSSL_DESERIALIZER_CTX_set_input_type(3)>.
-
-If no suitable deserializer was found, OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY()
-still creates a B<OSSL_DESERIALIZER_CTX>, but with no associated
-deserializer (L<OSSL_DESERIALIZER_CTX_num_deserializers(3)> returns
-zero).  This helps the caller distinguish between an error when
-creating the B<OSSL_DESERIALIZER_CTX>, and the lack the deserializer
-support and act accordingly.
-
-OSSL_DESERIALIZER_CTX_set_passphrase() gives the implementation a
-pass phrase to use when decrypting the serialized private key.
-Alternatively, a pass phrase callback may be specified with the
-following functions.
-
-OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui() set up a callback method that
-the implementation can use to prompt for a pass phrase, giving the caller
-the choice of prefered pass phrase callback form.  These are called
-indirectly, through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
-
-The internal B<OSSL_PASSPHRASE_CALLBACK> function caches the pass phrase, to
-be re-used in all deserializations that are performed in the same
-deserialization run
-(for example, within one L<OSSL_DESERIALIZER_from_bio(3)> call).
-
-=for comment the name OSSL_DESERIALIZER_CTX_set_pem_password_cb() leaves
-open the future possibility of having a function where the caller can set a
-B<OSSL_PASSPHRASE_CALLBACK> method as another option.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() returns a pointer to a
-B<OSSL_DESERIALIZER_CTX>, or NULL if it couldn't be created.
-
-OSSL_DESERIALIZER_CTX_set_passphrase(),
-OSSL_DESERIALIZER_CTX_set_pem_password_cb() and
-OSSL_DESERIALIZER_CTX_set_passphrase_ui()
-all return 1 on success, or 0 on failure.
-
-=head1 NOTES
-
-Parts of the function names are made to match already existing OpenSSL
-names.
-
-B<EVP_PKEY> in OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY() matches the type
-name, thus making for the naming pattern
-B<OSSL_DESERIALIZER_CTX_new_by_I<TYPE>>() when new types are handled.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER(3)>, L<OSSL_DESERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_DESERIALIZER_from_bio.pod b/doc/man3/OSSL_DESERIALIZER_from_bio.pod
deleted file mode 100644
index 1aa54899a5..0000000000
--- a/doc/man3/OSSL_DESERIALIZER_from_bio.pod
+++ /dev/null
@@ -1,280 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_DESERIALIZER_from_bio,
-OSSL_DESERIALIZER_from_fp,
-OSSL_DESERIALIZER_CTX_set_input_type,
-OSSL_DESERIALIZER_CTX_add_deserializer,
-OSSL_DESERIALIZER_CTX_add_extra,
-OSSL_DESERIALIZER_CTX_num_deserializers,
-OSSL_DESERIALIZER_INSTANCE,
-OSSL_DESERIALIZER_CONSTRUCT,
-OSSL_DESERIALIZER_CLEANUP,
-OSSL_DESERIALIZER_CTX_set_construct,
-OSSL_DESERIALIZER_CTX_set_construct_data,
-OSSL_DESERIALIZER_CTX_set_cleanup,
-OSSL_DESERIALIZER_CTX_get_construct,
-OSSL_DESERIALIZER_CTX_get_construct_data,
-OSSL_DESERIALIZER_CTX_get_cleanup,
-OSSL_DESERIALIZER_export,
-OSSL_DESERIALIZER_INSTANCE_deserializer,
-OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-- Routines to perform a deserialization
-
-=head1 SYNOPSIS
-
- #include <openssl/deserializer.h>
-
- int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in);
- int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp);
-
- int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
-                                          const char *input_type);
- int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
-                                            OSSL_DESERIALIZER *deser);
- int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx);
- int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx);
-
- typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE;
- OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst);
- void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst);
-
- typedef int (OSSL_DESERIALIZER_CONSTRUCT)
-     (OSSL_DESERIALIZER_INSTANCE *deser_inst,
-      const OSSL_PARAM *params, void *construct_data);
- typedef void (OSSL_DESERIALIZER_CLEANUP)(void *construct_data);
-
- int OSSL_DESERIALIZER_CTX_set_construct
-     (OSSL_DESERIALIZER_CTX *ctx, OSSL_DESERIALIZER_CONSTRUCT *construct);
- int OSSL_DESERIALIZER_CTX_set_construct_data
-     (OSSL_DESERIALIZER_CTX *ctx, void *construct_data);
- int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx,
-                                       OSSL_DESERIALIZER_CLEANUP *cleanup);
- OSSL_DESERIALIZER_CONSTRUCT *
- OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx);
- void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx);
- OSSL_DESERIALIZER_CLEANUP *
- OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx);
-
- int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
-                              void *reference, size_t reference_sz,
-                              OSSL_CALLBACK *export_cb, void *export_cbarg);
-
-Feature availability macros:
-
-=over 4
-
-=item OSSL_DESERIALIZER_from_fp() is only available when B<OPENSSL_NO_STDIO>
-is undefined.
-
-=back
-
-=head1 DESCRIPTION
-
-The B<OSSL_DESERIALIZER_CTX> holds data about multiple deserializers, as
-needed to figure out what the input data is and to attempt to unpack it into
-one of several possible related results.  This also includes chaining
-deserializers, so the output from one can become the input for another.
-This allows having generic format deserializers such as PEM to DER, as well
-as more specialized deserializers like DER to RSA.
-
-The chains may be limited by specifying an input type, which is considered a
-starting point.
-This is both considered by OSSL_DESERIALIZER_CTX_add_extra(), which will
-stop adding on more deserializer implementations when it has already added
-those that take the specified input type, and OSSL_DESERIALIZER_from_bio(),
-which will only start the deserializing process with the deserializer
-implementations that take that input type.  For example, if the input type
-is set to C<DER>, a PEM to DER deserializer will be ignored.
-
-The input type can also be NULL, which means that the caller doesn't know
-what type of input they have.  In this case, OSSL_DESERIALIZER_from_bio()
-will simply try with one deserializer implementation after the other, and
-thereby discover what kind of input the caller gave it.
-
-For every deserialization done, even an intermediary one, a constructor
-provided by the caller is called to attempt to construct an appropriate type
-/ structure that the caller knows how to handle from the current
-deserialization result.
-The constructor is set with OSSL_DESERIALIZER_CTX_set_construct().
-
-B<OSSL_DESERIALIZER_INSTANCE> is an opaque structure that contains
-data about the deserializer that was just used, and that may be
-useful for the constructor.  There are some functions to extract data
-from this type, described further down.
-
-=head2 Functions
-
-OSSL_DESERIALIZER_from_bio() runs the deserialization process for the
-context I<ctx>, with the input coming from the B<BIO> I<in>.  Should
-it make a difference, it's recommended to have the BIO set in binary
-mode rather than text mode.
-
-OSSL_DESERIALIZER_from_fp() does the same thing as OSSL_DESERIALIZER_from_bio(),
-except that the input is coming from the B<FILE> I<fp>.
-
-OSSL_DESERIALIZER_CTX_add_deserializer() populates the B<OSSL_DESERIALIZER_CTX>
-I<ctx> with a deserializer, to be used to attempt to deserialize some
-serialized input.
-
-OSSL_DESERIALIZER_CTX_add_extra() finds deserializers that generate
-input for already added deserializers, and adds them as well.  This is
-used to build deserializer chains.
-
-OSSL_DESERIALIZER_CTX_set_input_type() sets the starting input type.  This
-limits the deserializer chains to be considered, as explained in the general
-description above.
-
-OSSL_DESERIALIZER_CTX_num_deserializers() gets the number of
-deserializers currently added to the context I<ctx>.
-
-OSSL_DESERIALIZER_CTX_set_construct() sets the constructor I<construct>.
-
-OSSL_DESERIALIZER_CTX_set_construct_data() sets the constructor data that is
-passed to the constructor every time it's called.
-
-OSSL_DESERIALIZER_CTX_set_cleanup() sets the constructor data I<cleanup>
-function.  This is called by L<OSSL_DESERIALIZER_CTX_free(3)>.
-
-OSSL_DESERIALIZER_CTX_get_construct(),
-OSSL_DESERIALIZER_CTX_get_construct_data() and
-OSSL_DESERIALIZER_CTX_get_cleanup()
-return the values that have been set by
-OSSL_DESERIALIZER_CTX_set_construct(),
-OSSL_DESERIALIZER_CTX_set_construct_data() and
-OSSL_DESERIALIZER_CTX_set_cleanup() respectively.
-
-OSSL_DESERIALIZER_export() is a fallback function for constructors that
-cannot use the data they get directly for diverse reasons.  It takes the same
-deserialize instance I<deser_inst> that the constructor got and an object
-I<reference>, unpacks the object which it refers to, and exports it by creating
-an L<OSSL_PARAM(3)> array that it then passes to I<export_cb>, along with
-I<export_arg>.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer() can be used to get the
-deserializer method from a deserializer instance I<deser_inst>.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer-ctx() can be used to get the
-deserializer method's provider context from a deserializer instance
-I<deser_inst>.
-
-=head2 Constructor
-
-A B<OSSL_DESERIALIZER_CONSTRUCT> gets the following arguments:
-
-=over 4
-
-=item I<deser_inst>
-
-The B<OSSL_DESERIALIZER_INSTANCE> for the deserializer from which
-the constructor gets its data.
-
-=item I<params>
-
-The data produced by the deserializer, further described below.
-
-=item I<construct_data>
-
-The pointer that was set with OSSL_DESERIALIZE_CTX_set_construct_data().
-
-=back
-
-The constructor is expected to return 1 when the data it receives can
-be constructed, otherwise 0.
-
-The globally known parameters that the constructor can get in I<params>
-are:
-
-=over 4
-
-=item "data-type" (B<OSSL_DESERIALIZER_PARAM_DATA_TYPE>) <UTF8 string>
-
-This is a detected content type that some deserializers may provide.
-For example, PEM input sometimes has a type specified in its header,
-and some deserializers may add that information as this parameter.
-This is an optional parameter, but may be useful for extra checks in
-the constructor.
-
-=item "data" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
-
-The deserialized data itself, as an octet string.  This is produced by
-deserializers when it's possible to pass an object in this form.  Most
-often, this is simply meant to be passed to the next deserializer in a
-chain, but could be considered final data as well, at the discretion
-of the constructor.
-
-=item "reference" (B<OSSL_DESERIALIZER_PARAM_DATA>) <octet string>
-
-The deserialized data itself, as a reference to an object.  The
-reference itself is an octet string, and can be passed to other
-operations and functions within the same provider as the one that
-provides I<deser>.
-
-=back
-
-At least one of "data" or "reference" must be present, and it's
-possible that both can be.  A constructor should choose to use the
-"reference" parameter if possible, otherwise it should use the "data"
-parameter.
-
-If it's not possible to use the "reference" parameter, but that's
-still what a constructor wants to do, it is possible to use
-OSSL_DESERIALIZER_export() as a fallback.
-
-=head1 RETURN VALUES
-
-OSSL_DESERIALIZER_from_bio() and OSSL_DESERIALIZER_from_fp() return 1 on
-success, or 0 on failure.
-
-OSSL_DESERIALIZER_CTX_add_deserializer(),
-OSSL_DESERIALIZER_CTX_add_extra(),
-OSSL_DESERIALIZER_CTX_set_construct(),
-OSSL_DESERIALIZER_CTX_set_construct_data() and
-OSSL_DESERIALIZER_CTX_set_cleanup() return 1 on success, or 0 on
-failure.
-
-OSSL_DESERIALIZER_CTX_get_construct(),
-OSSL_DESERIALIZER_CTX_get_construct_data() and
-OSSL_DESERIALIZER_CTX_get_cleanup() return the current pointers to the
-cosntructor, the constructor data and the cleanup functions, respectively.
-
-OSSL_DESERIALIZER_CTX_num_deserializers() returns the current
-number of deserializers.  It returns 0 if I<ctx> is NULL.
-
-OSSL_DESERIALIZER_export() returns 1 on success, or 0 on failure.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer() returns an
-B<OSSL_DESERIALIZER> pointer on success, or NULL on failure.
-
-OSSL_DESERIALIZER_INSTANCE_deserializer_ctx() returns a provider
-context pointer on success, or NULL on failure.>
-
-=begin comment TODO(3.0) Add examples!
-
-=head1 EXAMPLES
-
-Text, because pod2xxx doesn't like empty sections
-
-=end comment
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_DESERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_ENCODER.pod b/doc/man3/OSSL_ENCODER.pod
new file mode 100644
index 0000000000..d8998310bd
--- /dev/null
+++ b/doc/man3/OSSL_ENCODER.pod
@@ -0,0 +1,126 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER,
+OSSL_ENCODER_fetch,
+OSSL_ENCODER_up_ref,
+OSSL_ENCODER_free,
+OSSL_ENCODER_provider,
+OSSL_ENCODER_properties,
+OSSL_ENCODER_is_a,
+OSSL_ENCODER_number,
+OSSL_ENCODER_do_all_provided,
+OSSL_ENCODER_names_do_all
+- Encoder method routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ typedef struct ossl_encoder_st OSSL_ENCODER;
+
+ OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *ctx, const char *name,
+                                  const char *properties);
+ int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder);
+ void OSSL_ENCODER_free(OSSL_ENCODER *encoder);
+ const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder);
+ const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder);
+ int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name);
+ int OSSL_ENCODER_number(const OSSL_ENCODER *encoder);
+ void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+                                   void (*fn)(OSSL_ENCODER *encoder, void *arg),
+                                   void *arg);
+ void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+                                void (*fn)(const char *name, void *data),
+                                void *data);
+
+=head1 DESCRIPTION
+
+=for comment Future development should also talk about decoding
+
+B<OSSL_ENCODER> is a method for encoders, which know how to
+encode an object of some kind to a encoded form, such as PEM,
+DER, or even human readable text.
+
+OSSL_ENCODER_fetch() looks for an algorithm within the provider that
+has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
+name given by I<name> and the properties given by I<properties>.
+The I<name> determines what type of object the fetched encoder
+method is expected to be able to encode, and the properties are
+used to determine the expected output type.
+For known properties and the values they may have, please have a look
+in L<provider-encoder(7)/Names and properties>.
+
+OSSL_ENCODER_up_ref() increments the reference count for the given
+I<encoder>.
+
+OSSL_ENCODER_free() decrements the reference count for the given
+I<encoder>, and when the count reaches zero, frees it.
+
+OSSL_ENCODER_provider() returns the provider of the given
+I<encoder>.
+
+OSSL_ENCODER_provider() returns the property definition associated
+with the given I<encoder>.
+
+OSSL_ENCODER_is_a() checks if I<encoder> is an implementation of an
+algorithm that's identifiable with I<name>.
+
+OSSL_ENCODER_number() returns the internal dynamic number assigned to
+the given I<encoder>.
+
+OSSL_ENCODER_names_do_all() traverses all names for the given
+I<encoder>, and calls I<fn> with each name and I<data>.
+
+OSSL_ENCODER_do_all_provided() traverses all encoder
+implementations by all activated providers in the library context
+I<libctx>, and for each of the implementations, calls I<fn> with the
+implementation method and I<data> as arguments.
+
+=head1 NOTES
+
+OSSL_ENCODER_fetch() may be called implicitly by other fetching
+functions, using the same library context and properties.
+Any other API that uses keys will typically do this.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_fetch() returns a pointer to the key management
+implementation represented by an OSSL_ENCODER object, or NULL on
+error.
+
+OSSL_ENCODER_up_ref() returns 1 on success, or 0 on error.
+
+OSSL_ENCODER_free() doesn't return any value.
+
+OSSL_ENCODER_provider() returns a pointer to a provider object, or
+NULL on error.
+
+OSSL_ENCODER_properties() returns a pointer to a property
+definition string, or NULL on error.
+
+OSSL_ENCODER_is_a() returns 1 of I<encoder> was identifiable,
+otherwise 0.
+
+OSSL_ENCODER_number() returns an integer.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER_CTX(3)>, L<OSSL_ENCODER_to_bio(3)>,
+L<OSSL_ENCODER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_ENCODER_CTX.pod b/doc/man3/OSSL_ENCODER_CTX.pod
new file mode 100644
index 0000000000..bf339c6a4f
--- /dev/null
+++ b/doc/man3/OSSL_ENCODER_CTX.pod
@@ -0,0 +1,93 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER_CTX,
+OSSL_ENCODER_CTX_new,
+OSSL_ENCODER_CTX_get_encoder,
+OSSL_ENCODER_settable_ctx_params,
+OSSL_ENCODER_CTX_set_params,
+OSSL_ENCODER_CTX_free
+- Encoder context routines
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ typedef struct ossl_encoder_ctx_st OSSL_ENCODER_CTX;
+
+ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(OSSL_ENCODER *encoder);
+ const OSSL_ENCODER *OSSL_ENCODER_CTX_get_encoder(OSSL_ENCODER_CTX *ctx);
+ const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder);
+ int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
+                                 const OSSL_PARAM params[]);
+ void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx);
+
+=head1 DESCRIPTION
+
+B<OSSL_ENCODER_CTX> is a context with which B<OSSL_ENCODER>
+operations are performed.  The context typically holds values, both
+internal and supplied by the application, which are useful for the
+implementations supplied by providers.
+
+OSSL_ENCODER_CTX_new() creates a B<OSSL_ENCODER_CTX> associated
+with the encoder I<encoder>.  NULL is a valid I<encoder>, the context will
+be created anyway, it's just not very useful.  This is intentional, to
+distinguish between errors in allocating the context or assigning it
+values on one hand, and the lack of encoder support on the other.
+
+=begin comment
+
+The above distinction makes it possible for other routines to sense if
+they need to report an error or fall back on other methods to
+encode.
+
+=end comment
+
+OSSL_ENCODER_CTX_get_encoder() gets the encoder method
+currently associated with the context I<ctx>.
+
+OSSL_ENCODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array of parameter descriptors.
+
+OSSL_ENCODER_CTX_set_params() attempts to set parameters specified
+with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
+implementation doesn't recognise should be ignored.
+
+OSSL_ENCODER_CTX_free() frees the given context I<ctx>.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_CTX_new() returns a pointer to a
+B<OSSL_ENCODER_CTX>, or NULL if the context structure couldn't be
+allocated.
+
+OSSL_ENCODER_CTX_get_encoder() returns a pointer to the
+encoder method associated with I<ctx>.  NULL is a valid return
+value and signifies that there is no associated encoder method.
+
+OSSL_ENCODER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
+array, or NULL if none is available.
+
+OSSL_ENCODER_CTX_set_params() returns 1 if all recognised
+parameters were valid, or 0 if one of them was invalid or caused some
+other failure in the implementation.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod
new file mode 100644
index 0000000000..2aa103fd14
--- /dev/null
+++ b/doc/man3/OSSL_ENCODER_CTX_new_by_EVP_PKEY.pod
@@ -0,0 +1,144 @@
+=pod
+
+=head1 NAME
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY,
+OSSL_ENCODER_CTX_set_cipher,
+OSSL_ENCODER_CTX_set_passphrase,
+OSSL_ENCODER_CTX_set_passphrase_cb,
+OSSL_ENCODER_CTX_set_passphrase_ui,
+OSSL_ENCODER_PUBKEY_TO_PEM_PQ,
+OSSL_ENCODER_PrivateKey_TO_PEM_PQ,
+OSSL_ENCODER_Parameters_TO_PEM_PQ,
+OSSL_ENCODER_PUBKEY_TO_DER_PQ,
+OSSL_ENCODER_PrivateKey_TO_DER_PQ,
+OSSL_ENCODER_Parameters_TO_DER_PQ,
+OSSL_ENCODER_PUBKEY_TO_TEXT_PQ,
+OSSL_ENCODER_PrivateKey_TO_TEXT_PQ,
+OSSL_ENCODER_Parameters_TO_TEXT_PQ
+- Encoder routines to encode EVP_PKEYs
+
+=head1 SYNOPSIS
+
+ #include <openssl/encoder.h>
+
+ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
+                                                    const char *propquery);
+
+ int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
+                                 const char *cipher_name,
+                                 const char *propquery);
+ int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
+                                     const unsigned char *kstr,
+                                     size_t klen);
+ int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
+                                        pem_password_cb *cb, void *cbarg);
+ int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
+                                        const UI_METHOD *ui_method,
+                                        void *ui_data);
+
+ #define OSSL_ENCODER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
+ #define OSSL_ENCODER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
+
+ #define OSSL_ENCODER_PUBKEY_TO_DER_PQ "format=der,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_DER_PQ "format=der,type=private"
+ #define OSSL_ENCODER_Parameters_TO_DER_PQ "format=der,type=parameters"
+
+ #define OSSL_ENCODER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
+ #define OSSL_ENCODER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
+ #define OSSL_ENCODER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
+
+=head1 DESCRIPTION
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY() creates a B<OSSL_ENCODER_CTX>
+with a suitable attached output routine for B<EVP_PKEY>s.  It will
+search for a encoder implementation that matches the algorithm of
+the B<EVP_PKEY> and the property query given with I<propquery>.  It
+will prefer to find a encoder from the same provider as the key
+data of the B<EVP_PKEY> itself, but failing that, it will choose the
+first encoder that supplies a generic encoding function.
+
+If no suitable encoder was found, OSSL_ENCODER_CTX_new_by_EVP_PKEY()
+still creates a B<OSSL_ENCODER_CTX>, but with no associated
+encoder (L<OSSL_ENCODER_CTX_get_encoder(3)> returns NULL).
+This helps the caller distinguish between an error when creating
+the B<OSSL_ENCODER_CTX>, and the lack the encoder support and
+act accordingly.
+
+OSSL_ENCODER_CTX_set_cipher() tells the implementation what cipher
+should be used to encrypt encoded keys.  The cipher is given by
+name I<cipher_name>.  The interpretation of that I<cipher_name> is
+implementation dependent.  The implementation may implement the digest
+directly itself or by other implementations, or it may choose to fetch
+it.  If the implementation supports fetching the cipher, then it may
+use I<propquery> as properties to be queried for when fetching.
+I<cipher_name> may also be NULL, which will result in unencrypted
+encoding.
+
+OSSL_ENCODER_CTX_set_passphrase() gives the implementation a
+pass phrase to use when encrypting the encoded private key.
+Alternatively, a pass phrase callback may be specified with the
+following functions.
+
+OSSL_ENCODER_CTX_set_passphrase_cb() and
+OSSL_ENCODER_CTX_set_passphrase_ui() sets up a callback method that
+the implementation can use to prompt for a pass phrase.
+
+=for comment Note that the callback method is called indirectly,
+through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
+
+The macros B<OSSL_ENCODER_PUBKEY_TO_PEM_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_PEM_PQ>,
+B<OSSL_ENCODER_Parameters_TO_PEM_PQ>,
+B<OSSL_ENCODER_PUBKEY_TO_DER_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_DER_PQ>,
+B<OSSL_ENCODER_Parameters_TO_DER_PQ>,
+B<OSSL_ENCODER_PUBKEY_TO_TEXT_PQ>,
+B<OSSL_ENCODER_PrivateKey_TO_TEXT_PQ>,
+B<OSSL_ENCODER_Parameters_TO_TEXT_PQ> are convenience macros with
+property queries to encode the B<EVP_PKEY> as a public key, private
+key or parameters to B<PEM>, to B<DER>, or to text.
+
+=head1 RETURN VALUES
+
+OSSL_ENCODER_CTX_new_by_EVP_PKEY() returns a pointer to a
+B<OSSL_ENCODER_CTX>, or NULL if it couldn't be created.
+
+OSSL_ENCODER_CTX_set_cipher(),
+OSSL_ENCODER_CTX_set_passphrase(),
+OSSL_ENCODER_CTX_set_passphrase_cb(), and
+OSSL_ENCODER_CTX_set_passphrase_ui() all return 1 on success, or 0
+on failure.
+
+=head1 NOTES
+
+Parts of the function and macro names are made to match already
+existing OpenSSL names.
+
+B<EVP_PKEY> in OSSL_ENCODER_CTX_new_by_EVP_PKEY() matches the type
+name, thus making for the naming pattern
+B<OSSL_ENCODER_CTX_new_by_I<TYPE>>() when new types are handled.
+
+B<PUBKEY>, B<PrivateKey> and B<Parameters> in the macro names match
+the B<I<TYPE>> part of B<PEM_write_bio_I<TYPE>> functions as well
+as B<i2d_I<TYPE>_bio> functions.
+
+=head1 SEE ALSO
+
+L<provider(7)>, L<OSSL_ENCODER(3)>, L<OSSL_ENCODER_CTX(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_SERIALIZER_to_bio.pod b/doc/man3/OSSL_ENCODER_to_bio.pod
similarity index 58%
rename from doc/man3/OSSL_SERIALIZER_to_bio.pod
rename to doc/man3/OSSL_ENCODER_to_bio.pod
index 3ed68a17ed..ee9998b2eb 100644
--- a/doc/man3/OSSL_SERIALIZER_to_bio.pod
+++ b/doc/man3/OSSL_ENCODER_to_bio.pod
@@ -2,46 +2,46 @@
 
 =head1 NAME
 
-OSSL_SERIALIZER_to_bio,
-OSSL_SERIALIZER_to_fp
-- Serializer file output routines
+OSSL_ENCODER_to_bio,
+OSSL_ENCODER_to_fp
+- Encoder file output routines
 
 =head1 SYNOPSIS
 
- #include <openssl/serializer.h>
+ #include <openssl/encoder.h>
 
- int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out);
- int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp);
+ int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out);
+ int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp);
 
 Feature availability macros:
 
 =over 4
 
-=item OSSL_SERIALIZER_to_fp() is only available when B<OPENSSL_NO_STDIO>
+=item OSSL_ENCODER_to_fp() is only available when B<OPENSSL_NO_STDIO>
 is undefined.
 
 =back
 
 =head1 DESCRIPTION
 
-OSSL_SERIALIZER_to_bio() runs the serialization process for the
+OSSL_ENCODER_to_bio() runs the encoding process for the
 context I<ctx>, with the output going to the B<BIO> I<out>.  The
 application is required to set up the B<BIO> properly, for example to
 have it in text or binary mode if that's appropriate.
 
-=for comment Know your serializer!
+=for comment Know your encoder!
 
-OSSL_SERIALIZER_to_fp() does the same thing as OSSL_SERIALIZER_to_bio(),
+OSSL_ENCODER_to_fp() does the same thing as OSSL_ENCODER_to_bio(),
 except that the output is going to the B<FILE> I<fp>.
 
 =head1 RETURN VALUES
 
-OSSL_SERIALIZER_to_bio() and OSSL_SERIALIZER_to_fp() return 1 on
+OSSL_ENCODER_to_bio() and OSSL_ENCODER_to_fp() return 1 on
 success, or 0 on failure.
 
 =head1 SEE ALSO
 
-L<provider(7)>, L<OSSL_SERIALIZER_CTX(3)>
+L<provider(7)>, L<OSSL_ENCODER_CTX(3)>
 
 =head1 HISTORY
 
diff --git a/doc/man3/OSSL_SERIALIZER.pod b/doc/man3/OSSL_SERIALIZER.pod
deleted file mode 100644
index 05b889bf60..0000000000
--- a/doc/man3/OSSL_SERIALIZER.pod
+++ /dev/null
@@ -1,129 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER,
-OSSL_SERIALIZER_fetch,
-OSSL_SERIALIZER_up_ref,
-OSSL_SERIALIZER_free,
-OSSL_SERIALIZER_provider,
-OSSL_SERIALIZER_properties,
-OSSL_SERIALIZER_is_a,
-OSSL_SERIALIZER_number,
-OSSL_SERIALIZER_do_all_provided,
-OSSL_SERIALIZER_names_do_all
-- Serializer method routines
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- typedef struct ossl_serializer_st OSSL_SERIALIZER;
-
- OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *ctx, const char *name,
-                                        const char *properties);
- int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *serializer);
- void OSSL_SERIALIZER_free(OSSL_SERIALIZER *serializer);
- const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER
-                                               *serializer);
- const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser);
- int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *serializer,
-                          const char *name);
- int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *serializer);
- void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                      void (*fn)(OSSL_SERIALIZER *serializer,
-                                                 void *arg),
-                                      void *arg);
- void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *serializer,
-                                   void (*fn)(const char *name, void *data),
-                                   void *data);
-
-=head1 DESCRIPTION
-
-=for comment Future development should also talk about deserialization
-
-B<OSSL_SERIALIZER> is a method for serializers, which know how to
-serialize an object of some kind to a serialized form, such as PEM,
-DER, or even human readable text.
-
-OSSL_SERIALIZER_fetch() looks for an algorithm within the provider that
-has been loaded into the B<OPENSSL_CTX> given by I<ctx>, having the
-name given by I<name> and the properties given by I<properties>.
-The I<name> determines what type of object the fetched serializer
-method is expected to be able to serialize, and the properties are
-used to determine the expected output type.
-For known properties and the values they may have, please have a look
-in L<provider-serializer(7)/Names and properties>.
-
-OSSL_SERIALIZER_up_ref() increments the reference count for the given
-I<serializer>.
-
-OSSL_SERIALIZER_free() decrements the reference count for the given
-I<serializer>, and when the count reaches zero, frees it.
-
-OSSL_SERIALIZER_provider() returns the provider of the given
-I<serializer>.
-
-OSSL_SERIALIZER_provider() returns the property definition associated
-with the given I<serializer>.
-
-OSSL_SERIALIZER_is_a() checks if I<serializer> is an implementation of an
-algorithm that's identifiable with I<name>.
-
-OSSL_SERIALIZER_number() returns the internal dynamic number assigned to
-the given I<serializer>.
-
-OSSL_SERIALIZER_names_do_all() traverses all names for the given
-I<serializer>, and calls I<fn> with each name and I<data>.
-
-OSSL_SERIALIZER_do_all_provided() traverses all serializer
-implementations by all activated providers in the library context
-I<libctx>, and for each of the implementations, calls I<fn> with the
-implementation method and I<data> as arguments.
-
-=head1 NOTES
-
-OSSL_SERIALIZER_fetch() may be called implicitly by other fetching
-functions, using the same library context and properties.
-Any other API that uses keys will typically do this.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_fetch() returns a pointer to the key management
-implementation represented by an OSSL_SERIALIZER object, or NULL on
-error.
-
-OSSL_SERIALIZER_up_ref() returns 1 on success, or 0 on error.
-
-OSSL_SERIALIZER_free() doesn't return any value.
-
-OSSL_SERIALIZER_provider() returns a pointer to a provider object, or
-NULL on error.
-
-OSSL_SERIALIZER_properties() returns a pointer to a property
-definition string, or NULL on error.
-
-OSSL_SERIALIZER_is_a() returns 1 of I<serializer> was identifiable,
-otherwise 0.
-
-OSSL_SERIALIZER_number() returns an integer.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER_CTX(3)>, L<OSSL_SERIALIZER_to_bio(3)>,
-L<OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(3)>, L<OPENSSL_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2019 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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_SERIALIZER_CTX.pod b/doc/man3/OSSL_SERIALIZER_CTX.pod
deleted file mode 100644
index d446b842d0..0000000000
--- a/doc/man3/OSSL_SERIALIZER_CTX.pod
+++ /dev/null
@@ -1,94 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER_CTX,
-OSSL_SERIALIZER_CTX_new,
-OSSL_SERIALIZER_CTX_get_serializer,
-OSSL_SERIALIZER_settable_ctx_params,
-OSSL_SERIALIZER_CTX_set_params,
-OSSL_SERIALIZER_CTX_free
-- Serializer context routines
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
-
- OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser);
- const OSSL_SERIALIZER *
- OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx);
- const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser);
- int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx,
-                                    const OSSL_PARAM params[]);
- void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx);
-
-=head1 DESCRIPTION
-
-B<OSSL_SERIALIZER_CTX> is a context with which B<OSSL_SERIALIZER>
-operations are performed.  The context typically holds values, both
-internal and supplied by the application, which are useful for the
-implementations supplied by providers.
-
-OSSL_SERIALIZER_CTX_new() creates a B<OSSL_SERIALIZER_CTX> associated
-with the serializer I<ser>.  NULL is a valid I<ser>, the context will
-be created anyway, it's just not very useful.  This is intentional, to
-distinguish between errors in allocating the context or assigning it
-values on one hand, and the lack of serializer support on the other.
-
-=begin comment
-
-The above distinction makes it possible for other routines to sense if
-they need to report an error or fall back on other methods to
-serialize.
-
-=end comment
-
-OSSL_SERIALIZER_CTX_get_serializer() gets the serializer method
-currently associated with the context I<ctx>.
-
-OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array of parameter descriptors.
-
-OSSL_SERIALIZER_CTX_set_params() attempts to set parameters specified
-with an L<OSSL_PARAM(3)> array I<params>.  Parameters that the
-implementation doesn't recognise should be ignored.
-
-OSSL_SERIALIZER_CTX_free() frees the given context I<ctx>.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_CTX_new() returns a pointer to a
-B<OSSL_SERIALIZER_CTX>, or NULL if the context structure couldn't be
-allocated.
-
-OSSL_SERIALIZER_CTX_get_serializer() returns a pointer to the
-serializer method associated with I<ctx>.  NULL is a valid return
-value and signifies that there is no associated serializer method.
-
-OSSL_SERIALIZER_settable_ctx_params() returns an L<OSSL_PARAM(3)>
-array, or NULL if none is available.
-
-OSSL_SERIALIZER_CTX_set_params() returns 1 if all recognised
-parameters were valid, or 0 if one of them was invalid or caused some
-other failure in the implementation.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-Copyright 2019 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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod b/doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod
deleted file mode 100644
index 5797ab1caa..0000000000
--- a/doc/man3/OSSL_SERIALIZER_CTX_new_by_EVP_PKEY.pod
+++ /dev/null
@@ -1,144 +0,0 @@
-=pod
-
-=head1 NAME
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY,
-OSSL_SERIALIZER_CTX_set_cipher,
-OSSL_SERIALIZER_CTX_set_passphrase,
-OSSL_SERIALIZER_CTX_set_passphrase_cb,
-OSSL_SERIALIZER_CTX_set_passphrase_ui,
-OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
-OSSL_SERIALIZER_Parameters_TO_PEM_PQ,
-OSSL_SERIALIZER_PUBKEY_TO_DER_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
-OSSL_SERIALIZER_Parameters_TO_DER_PQ,
-OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
-OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
-OSSL_SERIALIZER_Parameters_TO_TEXT_PQ
-- Serializer routines to serialize EVP_PKEYs
-
-=head1 SYNOPSIS
-
- #include <openssl/serializer.h>
-
- OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                                          const char *propquery);
-
- int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx,
-                                    const char *cipher_name,
-                                    const char *propquery);
- int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx,
-                                        const unsigned char *kstr,
-                                        size_t klen);
- int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx,
-                                           pem_password_cb *cb, void *cbarg);
- int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx,
-                                           const UI_METHOD *ui_method,
-                                           void *ui_data);
-
- #define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
-
- #define OSSL_SERIALIZER_PUBKEY_TO_DER_PQ "format=der,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_DER_PQ "format=der,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_DER_PQ "format=der,type=parameters"
-
- #define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
- #define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
- #define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
-
-=head1 DESCRIPTION
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() creates a B<OSSL_SERIALIZER_CTX>
-with a suitable attached output routine for B<EVP_PKEY>s.  It will
-search for a serializer implementation that matches the algorithm of
-the B<EVP_PKEY> and the property query given with I<propquery>.  It
-will prefer to find a serializer from the same provider as the key
-data of the B<EVP_PKEY> itself, but failing that, it will choose the
-first serializer that supplies a generic serializing function.
-
-If no suitable serializer was found, OSSL_SERIALIZER_CTX_new_by_EVP_PKEY()
-still creates a B<OSSL_SERIALIZER_CTX>, but with no associated
-serializer (L<OSSL_SERIALIZER_CTX_get_serializer(3)> returns NULL).
-This helps the caller distinguish between an error when creating
-the B<OSSL_SERIALIZER_CTX>, and the lack the serializer support and
-act accordingly.
-
-OSSL_SERIALIZER_CTX_set_cipher() tells the implementation what cipher
-should be used to encrypt serialized keys.  The cipher is given by
-name I<cipher_name>.  The interpretation of that I<cipher_name> is
-implementation dependent.  The implementation may implement the digest
-directly itself or by other implementations, or it may choose to fetch
-it.  If the implementation supports fetching the cipher, then it may
-use I<propquery> as properties to be queried for when fetching.
-I<cipher_name> may also be NULL, which will result in unencrypted
-serialization.
-
-OSSL_SERIALIZER_CTX_set_passphrase() gives the implementation a
-pass phrase to use when encrypting the serialized private key.
-Alternatively, a pass phrase callback may be specified with the
-following functions.
-
-OSSL_SERIALIZER_CTX_set_passphrase_cb() and
-OSSL_SERIALIZER_CTX_set_passphrase_ui() sets up a callback method that
-the implementation can use to prompt for a pass phrase.
-
-=for comment Note that the callback method is called indirectly,
-through an internal B<OSSL_PASSPHRASE_CALLBACK> function.
-
-The macros B<OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_PEM_PQ>,
-B<OSSL_SERIALIZER_PUBKEY_TO_DER_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_DER_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_DER_PQ>,
-B<OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ>,
-B<OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ>,
-B<OSSL_SERIALIZER_Parameters_TO_TEXT_PQ> are convenience macros with
-property queries to serialize the B<EVP_PKEY> as a public key, private
-key or parameters to B<PEM>, to B<DER>, or to text.
-
-=head1 RETURN VALUES
-
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a pointer to a
-B<OSSL_SERIALIZER_CTX>, or NULL if it couldn't be created.
-
-OSSL_SERIALIZER_CTX_set_cipher(),
-OSSL_SERIALIZER_CTX_set_passphrase(),
-OSSL_SERIALIZER_CTX_set_passphrase_cb(), and
-OSSL_SERIALIZER_CTX_set_passphrase_ui() all return 1 on success, or 0
-on failure.
-
-=head1 NOTES
-
-Parts of the function and macro names are made to match already
-existing OpenSSL names.
-
-B<EVP_PKEY> in OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() matches the type
-name, thus making for the naming pattern
-B<OSSL_SERIALIZER_CTX_new_by_I<TYPE>>() when new types are handled.
-
-B<PUBKEY>, B<PrivateKey> and B<Parameters> in the macro names match
-the B<I<TYPE>> part of B<PEM_write_bio_I<TYPE>> functions as well
-as B<i2d_I<TYPE>_bio> functions.
-
-=head1 SEE ALSO
-
-L<provider(7)>, L<OSSL_SERIALIZER(3)>, L<OSSL_SERIALIZER_CTX(3)>
-
-=head1 HISTORY
-
-The functions described here were added in OpenSSL 3.0.
-
-=head1 COPYRIGHT
-
-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
-L<https://www.openssl.org/source/license.html>.
-
-=cut
diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod
index dd4d21f7cc..fc9c191855 100644
--- a/doc/man7/OSSL_PROVIDER-FIPS.pod
+++ b/doc/man7/OSSL_PROVIDER-FIPS.pod
@@ -35,7 +35,7 @@ make sure to get implementations of this provider and none other.
 The "fips=yes" property can be use to make sure only FIPS approved
 implementations are used for crypto operations.  This may also include
 other non-crypto support operations that are not in the fips provider,
-such as asymmetric key serializers,
+such as asymmetric key encoders,
 see L<OSSL_PROVIDER-default(7)/Asymmetric Key Management>.
 
 =head1 OPERATIONS AND ALGORITHMS
diff --git a/doc/man7/OSSL_PROVIDER-base.pod b/doc/man7/OSSL_PROVIDER-base.pod
index 5896c5a91e..06b608be60 100644
--- a/doc/man7/OSSL_PROVIDER-base.pod
+++ b/doc/man7/OSSL_PROVIDER-base.pod
@@ -6,7 +6,7 @@ OSSL_PROVIDER-base - OpenSSL base provider
 
 =head1 DESCRIPTION
 
-The OpenSSL base provider supplies the serialization for OpenSSL's
+The OpenSSL base provider supplies the encoding for OpenSSL's
 asymmetric cryptography.
 
 =head2 Properties
@@ -36,7 +36,7 @@ implementations of this provider and none other.
 =back
 
 These may be used in a property query string with fetching functions to select
-which data are to be serialized.  Either the private key material, the public
+which data are to be encoded.  Either the private key material, the public
 key material or the domain parameters can be selected.
 
 =over 4
@@ -50,32 +50,32 @@ key material or the domain parameters can be selected.
 =back
 
 These may be used in a property query string with fetching functions to select
-the serialization output format.  Either the DER, PEM and plaintext are
+the encoding output format.  Either the DER, PEM and plaintext are
 currently permitted.
 
 =head1 OPERATIONS AND ALGORITHMS
 
 The OpenSSL base provider supports these operations and algorithms:
 
-=head2 Asymmetric Key Serializer
+=head2 Asymmetric Key Encoder
 
-In addition to "provider=base", some of these serializers define the
+In addition to "provider=base", some of these encoders define the
 property "fips=yes", to allow them to be used together with the FIPS
 provider.
 
 =over 4
 
-=item RSA, see L<OSSL_SERIALIZER-RSA(7)>
+=item RSA, see L<OSSL_ENCODER-RSA(7)>
 
-=item DH, see L<OSSL_SERIALIZER-DH(7)>
+=item DH, see L<OSSL_ENCODER-DH(7)>
 
-=item DSA, see L<OSSL_SERIALIZER-DSA(7)>
+=item DSA, see L<OSSL_ENCODER-DSA(7)>
 
-=item EC, see L<OSSL_SERIALIZER-EC(7)>
+=item EC, see L<OSSL_ENCODER-EC(7)>
 
-=item X25519, see L<OSSL_SERIALIZER-X25519(7)>
+=item X25519, see L<OSSL_ENCODER-X25519(7)>
 
-=item X448, see L<OSSL_SERIALIZER-X448(7)>
+=item X448, see L<OSSL_ENCODER-X448(7)>
 
 =back
 
diff --git a/doc/man7/OSSL_PROVIDER-default.pod b/doc/man7/OSSL_PROVIDER-default.pod
index f82f8d8551..0b477b56c1 100644
--- a/doc/man7/OSSL_PROVIDER-default.pod
+++ b/doc/man7/OSSL_PROVIDER-default.pod
@@ -192,25 +192,25 @@ The OpenSSL default provider supports these operations and algorithms:
 
 =back
 
-=head2 Asymmetric Key Serializer
+=head2 Asymmetric Key Encoder
 
-The default provider also includes all of the serialization algorithms
+The default provider also includes all of the encoding algorithms
 present in the base provider.  Some of these have the property "fips=yes",
 to allow them to be used together with the FIPS provider.
 
 =over 4
 
-=item RSA, see L<OSSL_SERIALIZER-RSA(7)>
+=item RSA, see L<OSSL_ENCODER-RSA(7)>
 
-=item DH, see L<OSSL_SERIALIZER-DH(7)>
+=item DH, see L<OSSL_ENCODER-DH(7)>
 
-=item DSA, see L<OSSL_SERIALIZER-DSA(7)>
+=item DSA, see L<OSSL_ENCODER-DSA(7)>
 
-=item EC, see L<OSSL_SERIALIZER-EC(7)>
+=item EC, see L<OSSL_ENCODER-EC(7)>
 
-=item X25519, see L<OSSL_SERIALIZER-X25519(7)>
+=item X25519, see L<OSSL_ENCODER-X25519(7)>
 
-=item X448, see L<OSSL_SERIALIZER-X448(7)>
+=item X448, see L<OSSL_ENCODER-X448(7)>
 
 =back
 
diff --git a/doc/man7/provider-serializer.pod b/doc/man7/provider-encoder.pod
similarity index 56%
rename from doc/man7/provider-serializer.pod
rename to doc/man7/provider-encoder.pod
index 0c1662837f..99787e7040 100644
--- a/doc/man7/provider-serializer.pod
+++ b/doc/man7/provider-encoder.pod
@@ -2,16 +2,10 @@
 
 =head1 NAME
 
-provider-serializer - The SERIALIZER library E<lt>-E<gt> provider functions
+provider-encoder - The ENCODER library E<lt>-E<gt> provider functions
 
 =head1 SYNOPSIS
 
-=begin comment
-
-Future development will also include deserializing functions.
-
-=end comment
-
  #include <openssl/core_dispatch.h>
 
  /*
@@ -20,39 +14,42 @@ Future development will also include deserializing functions.
   * pointers in OSSL_DISPATCH arrays.
   */
 
- /* Functions to construct / destruct / manipulate the serializer context */
- void *OSSL_FUNC_serializer_newctx(void *provctx);
- void OSSL_FUNC_serializer_freectx(void *ctx);
- int OSSL_FUNC_serializer_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
- const OSSL_PARAM *OSSL_FUNC_serializer_settable_ctx_params(void *provctx)
+ /* Functions to construct / destruct / manipulate the encoder context */
+ void *OSSL_FUNC_encoder_newctx(void *provctx);
+ void OSSL_FUNC_encoder_freectx(void *ctx);
+ int OSSL_FUNC_encoder_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OSSL_FUNC_encoder_settable_ctx_params(void *provctx)
 
- /* Functions to serialize object data */
- int OSSL_FUNC_serializer_serialize_data(void *ctx, const OSSL_PARAM *data,
+ /* Functions to encode object data */
+ int OSSL_FUNC_encoder_encode_data(void *ctx, const OSSL_PARAM *data,
                                          OSSL_CORE_BIO *out,
                                          OSSL_PASSPHRASE_CALLBACK *cb,
                                          void *cbarg);
- int OSSL_FUNC_serializer_serialize_object(void *ctx, void *obj, OSSL_CORE_BIO *out,
+ int OSSL_FUNC_encoder_encode_object(void *ctx, void *obj, OSSL_CORE_BIO *out,
                                            OSSL_PASSPHRASE_CALLBACK *cb,
                                            void *cbarg);
 
 =head1 DESCRIPTION
 
-The SERIALIZER is a generic method to serialize any set of object data
+I<We use the wide term "encode" in this manual.  This includes but is
+not limited to serialization.>
+
+The ENCODER is a generic method to encode any set of object data
 in L<OSSL_PARAM(3)> array form, or any provider side object into
-serialized form, and write it to the given OSSL_CORE_BIO.  If the caller wants
-to get the serialized stream to memory, it should provide a
+encoded form, and write it to the given OSSL_CORE_BIO.  If the caller wants
+to get the encoded stream to memory, it should provide a
 L<BIO_s_membuf(3)>.
 
-The serializer doesn't need to know more about the B<OSSL_CORE_BIO> pointer than
+The encoder doesn't need to know more about the B<OSSL_CORE_BIO> pointer than
 being able to pass it to the appropriate BIO upcalls (see
 L<provider-base(7)/Core functions>).
 
-The serialization using the L<OSSL_PARAM(3)> array form allows a
-serializer to be used for data that's been exported from another
+The encoding using the L<OSSL_PARAM(3)> array form allows a
+encoder to be used for data that's been exported from another
 provider, and thereby allow them to exist independently of each
 other.
 
-The serialization using a provider side object can only be safely used
+The encoding using a provider side object can only be safely used
 with provider data coming from the same provider, for example keys
 with the L<KEYMGMT|provider-keymgmt(7)> provider.
 
@@ -66,34 +63,34 @@ All these "functions" have a corresponding function type definition
 named B<OSSL_{name}_fn>, and a helper function to retrieve the
 function pointer from a B<OSSL_DISPATCH> element named
 B<OSSL_FUNC_{name}>.
-For example, the "function" OSSL_FUNC_serializer_serialize_data() has these:
+For example, the "function" OSSL_FUNC_encoder_encode_data() has these:
 
  typedef int
-     (OSSL_FUNC_serializer_serialize_data_fn)(void *provctx,
+     (OSSL_FUNC_encoder_encode_data_fn)(void *provctx,
                                             const OSSL_PARAM params[],
                                             OSSL_CORE_BIO *out);
- static ossl_inline OSSL_FUNC_serializer_serialize_data_fn
-     OSSL_FUNC_serializer_serialize_data(const OSSL_DISPATCH *opf);
+ static ossl_inline OSSL_FUNC_encoder_encode_data_fn
+     OSSL_FUNC_encoder_encode_data(const OSSL_DISPATCH *opf);
 
 B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
 macros in L<openssl-core_dispatch.h(7)>, as follows:
 
- OSSL_FUNC_serializer_newctx              OSSL_FUNC_SERIALIZER_NEWCTX
- OSSL_FUNC_serializer_freectx             OSSL_FUNC_SERIALIZER_FREECTX
- OSSL_FUNC_serializer_set_ctx_params      OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS
- OSSL_FUNC_serializer_settable_ctx_params OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS
+ OSSL_FUNC_encoder_newctx              OSSL_FUNC_ENCODER_NEWCTX
+ OSSL_FUNC_encoder_freectx             OSSL_FUNC_ENCODER_FREECTX
+ OSSL_FUNC_encoder_set_ctx_params      OSSL_FUNC_ENCODER_SET_CTX_PARAMS
+ OSSL_FUNC_encoder_settable_ctx_params OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS
 
- OSSL_FUNC_serializer_serialize_data      OSSL_FUNC_SERIALIZER_SERIALIZE_DATA
- OSSL_FUNC_serializer_serialize_object    OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT
+ OSSL_FUNC_encoder_encode_data      OSSL_FUNC_ENCODER_ENCODE_DATA
+ OSSL_FUNC_encoder_encode_object    OSSL_FUNC_ENCODER_ENCODE_OBJECT
 
 =head2 Names and properties
 
 The name of an implementation should match the type of object it
-handles.  For example, an implementation that serializes an RSA key
+handles.  For example, an implementation that encodes an RSA key
 should be named accordingly.
 
-To be able to specify exactly what serialization format and what type
-of data a serializer implementation is expected to handle, two
+To be able to specify exactly what encoding format and what type
+of data a encoder implementation is expected to handle, two
 additional properties may be given:
 
 =over 4
@@ -156,77 +153,77 @@ know anything about.
 
 =head2 Context functions
 
-OSSL_FUNC_serializer_newctx() returns a context to be used with the rest of
+OSSL_FUNC_encoder_newctx() returns a context to be used with the rest of
 the functions.
 
-OSSL_FUNC_serializer_freectx() frees the given I<ctx>, if it was created by
-OSSL_FUNC_serializer_newctx().
+OSSL_FUNC_encoder_freectx() frees the given I<ctx>, if it was created by
+OSSL_FUNC_encoder_newctx().
 
-OSSL_FUNC_serializer_set_ctx_params() sets context data according to
+OSSL_FUNC_encoder_set_ctx_params() sets context data according to
 parameters from I<params> that it recognises.  Unrecognised parameters
 should be ignored.
 
-OSSL_FUNC_serializer_settable_ctx_params() returns a constant B<OSSL_PARAM>
-array describing the parameters that OSSL_FUNC_serializer_set_ctx_params()
+OSSL_FUNC_encoder_settable_ctx_params() returns a constant B<OSSL_PARAM>
+array describing the parameters that OSSL_FUNC_encoder_set_ctx_params()
 can handle.
 
 See L<OSSL_PARAM(3)> for further details on the parameters structure used
-by OSSL_FUNC_serializer_set_ctx_params() and OSSL_FUNC_serializer_settable_ctx_params().
+by OSSL_FUNC_encoder_set_ctx_params() and OSSL_FUNC_encoder_settable_ctx_params().
 
-=head2 Serializing functions
+=head2 Encoding functions
 
-=for comment There will be a "Deserializing functions" title as well
+=for comment There will be a "Decoding functions" title as well
 
-OSSL_FUNC_serializer_serialize_data() should take an array of B<OSSL_PARAM>,
+OSSL_FUNC_encoder_encode_data() should take an array of B<OSSL_PARAM>,
 I<data>, and if it contains the data necessary for the object type
 that the implementation handles, it should output the object in
-serialized form to the B<OSSL_CORE_BIO>.
+encoded form to the B<OSSL_CORE_BIO>.
 
-OSSL_FUNC_serializer_serialize_object() should take a pointer to an object
-that it knows intimately, and output that object in serialized form to
+OSSL_FUNC_encoder_encode_object() should take a pointer to an object
+that it knows intimately, and output that object in encoded form to
 the B<OSSL_CORE_BIO>.  The caller I<must> ensure that this function is called
 with a pointer that the provider of this function is familiar with.
 It is not suitable to use with object pointers coming from other
 providers.
 
-Both serialization functions also take an B<OSSL_PASSPHRASE_CALLBACK>
+Both encoding functions also take an B<OSSL_PASSPHRASE_CALLBACK>
 function pointer along with a pointer to application data I<cbarg>,
 which should be used when a pass phrase prompt is needed.
 
-=head2 Serializer parameters
+=head2 Encoder parameters
 
-Parameters currently recognised by built-in serializers are as
+Parameters currently recognised by built-in encoders are as
 follows:
 
 =over 4
 
-=item "cipher" (B<OSSL_SERIALIZER_PARAM_CIPHER>) <UTF8 string>
+=item "cipher" (B<OSSL_ENCODER_PARAM_CIPHER>) <UTF8 string>
 
 The name of the encryption cipher to be used when generating encrypted
-serialization.  This is used when serializing private keys, as well as
+encoding.  This is used when encoding private keys, as well as
 other objects that need protection.
 
-If this name is invalid for the serialization implementation, the
-implementation should refuse to perform the serialization, i.e.
-OSSL_FUNC_serializer_serialize_data() and OSSL_FUNC_serializer_serialize_object()
+If this name is invalid for the encoding implementation, the
+implementation should refuse to perform the encoding, i.e.
+OSSL_FUNC_encoder_encode_data() and OSSL_FUNC_encoder_encode_object()
 should return an error.
 
-=item "properties" (B<OSSL_SERIALIZER_PARAM_PROPERTIES>) <UTF8 string>
+=item "properties" (B<OSSL_ENCODER_PARAM_PROPERTIES>) <UTF8 string>
 
 The properties to be queried when trying to fetch the algorithm given
 with the "cipher" parameter.
 This must be given together with the "cipher" parameter to be
 considered valid.
 
-The serialization implementation isn't obligated to use this value.
+The encoding implementation isn't obligated to use this value.
 However, it is recommended that implementations that do not handle
 property strings return an error on receiving this parameter unless
 its value NULL or the empty string.
 
-=item "passphrase" (B<OSSL_SERIALIZER_PARAM_PASS>) <octet string>
+=item "passphrase" (B<OSSL_ENCODER_PARAM_PASS>) <octet string>
 
 A pass phrase provided by the application.  When this is given, the
-built-in serializers will not attempt to use the passphrase callback.
+built-in encoders will not attempt to use the passphrase callback.
 
 =back
 
@@ -244,16 +241,16 @@ of object it's being prompted for.
 
 =head1 RETURN VALUES
 
-OSSL_FUNC_serializer_newctx() returns a pointer to a context, or NULL on
+OSSL_FUNC_encoder_newctx() returns a pointer to a context, or NULL on
 failure.
 
-OSSL_FUNC_serializer_set_ctx_params() returns 1, unless a recognised
+OSSL_FUNC_encoder_set_ctx_params() returns 1, unless a recognised
 parameters was invalid or caused an error, for which 0 is returned.
 
-OSSL_FUNC_serializer_settable_ctx_params() returns a pointer to an array of
+OSSL_FUNC_encoder_settable_ctx_params() returns a pointer to an array of
 constant B<OSSL_PARAM> elements.
 
-OSSL_FUNC_serializer_serialize_data() and OSSL_FUNC_serializer_serialize_object()
+OSSL_FUNC_encoder_encode_data() and OSSL_FUNC_encoder_encode_object()
 return 1 on success, or 0 on failure.
 
 =head1 SEE ALSO
@@ -262,7 +259,7 @@ L<provider(7)>
 
 =head1 HISTORY
 
-The SERIALIZER interface was introduced in OpenSSL 3.0.
+The ENCODER interface was introduced in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
diff --git a/doc/man7/provider.pod b/doc/man7/provider.pod
index 62ff8695f1..2f7f019650 100644
--- a/doc/man7/provider.pod
+++ b/doc/man7/provider.pod
@@ -154,13 +154,13 @@ The number for this operation is B<OSSL_OP_ASYM_CIPHER>.
 The functions the provider can offer are described in
 L<provider-asym_cipher(7)>
 
-=item Serialization
+=item Encoding
 
 In the OpenSSL libraries, the corresponding method object is
-B<OSSL_SERIALIZER>.
-The number for this operation is B<OSSL_OP_SERIALIZER>.
+B<OSSL_ENCODER>.
+The number for this operation is B<OSSL_OP_ENCODER>.
 The functions the provider can offer are described in
-L<provider-serializer(7)>
+L<provider-encoder(7)>
 
 =back
 
@@ -277,7 +277,7 @@ The base provider is built in as part of the F<libcrypto> library.
 Should it be needed (if other providers are loaded and offer
 implementations of the same algorithms), the property "provider=base"
 can be used as a search criterion for these implementations. Some
-non-cryptographic algorithms (such as serializers for loading keys and
+non-cryptographic algorithms (such as encoders for loading keys and
 parameters from files) are not FIPS algorithm implementations in themselves but
 support algorithms from the FIPS provider and are allowed for use in "FIPS
 mode". The property "fips=yes" can be used to select such algorithms.
diff --git a/include/crypto/serializer.h b/include/crypto/encoder.h
similarity index 53%
rename from include/crypto/serializer.h
rename to include/crypto/encoder.h
index 84d6b54de7..f75a031c32 100644
--- a/include/crypto/serializer.h
+++ b/include/crypto/encoder.h
@@ -9,7 +9,7 @@
 
 #include <openssl/types.h>
 
-OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
-                                                 const char *properties);
-OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx, int id,
-                                                     const char *properties);
+OSSL_ENCODER *ossl_encoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties);
+OSSL_DECODER *ossl_decoder_fetch_by_number(OPENSSL_CTX *libctx, int id,
+                                           const char *properties);
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index d0dd6fe2b5..3075bd70c0 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -155,8 +155,8 @@ typedef struct ossl_ex_data_global_st {
 # define OPENSSL_CTX_RAND_CRNGT_INDEX               7
 # define OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX     8
 # define OPENSSL_CTX_FIPS_PROV_INDEX                9
-# define OPENSSL_CTX_SERIALIZER_STORE_INDEX        10
-# define OPENSSL_CTX_DESERIALIZER_STORE_INDEX      11
+# define OPENSSL_CTX_ENCODER_STORE_INDEX        10
+# define OPENSSL_CTX_DECODER_STORE_INDEX      11
 # define OPENSSL_CTX_SELF_TEST_CB_INDEX            12
 # define OPENSSL_CTX_BIO_PROV_INDEX                13
 # define OPENSSL_CTX_GLOBAL_PROPERTIES             14
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index 55144f126b..ee589eae6b 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -191,8 +191,8 @@ OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx))
 # define OSSL_OP_SIGNATURE                          12
 # define OSSL_OP_ASYM_CIPHER                        13
 /* New section for non-EVP operations */
-# define OSSL_OP_SERIALIZER                         20
-# define OSSL_OP_DESERIALIZER                       21
+# define OSSL_OP_ENCODER                         20
+# define OSSL_OP_DECODER                       21
 /* Highest known operation number */
 # define OSSL_OP__HIGHEST                           21
 
@@ -713,50 +713,50 @@ OSSL_CORE_MAKE_FUNC(int, asym_cipher_set_ctx_params,
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_settable_ctx_params,
                     (void *provctx))
 
-/* Serializers and deserializers */
-# define OSSL_FUNC_SERIALIZER_NEWCTX                1
-# define OSSL_FUNC_SERIALIZER_FREECTX               2
-# define OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS        3
-# define OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS   4
-# define OSSL_FUNC_SERIALIZER_SERIALIZE_DATA       10
-# define OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT     11
-OSSL_CORE_MAKE_FUNC(void *, serializer_newctx, (void *provctx))
-OSSL_CORE_MAKE_FUNC(void, serializer_freectx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, serializer_set_ctx_params,
+/* Encoders and decoders */
+# define OSSL_FUNC_ENCODER_NEWCTX                      1
+# define OSSL_FUNC_ENCODER_FREECTX                     2
+# define OSSL_FUNC_ENCODER_SET_CTX_PARAMS              3
+# define OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS         4
+# define OSSL_FUNC_ENCODER_ENCODE_DATA                10
+# define OSSL_FUNC_ENCODER_ENCODE_OBJECT              11
+OSSL_CORE_MAKE_FUNC(void *, encoder_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, encoder_freectx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, encoder_set_ctx_params,
                     (void *ctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, serializer_settable_ctx_params,
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, encoder_settable_ctx_params,
                     (void *provctx))
 
-OSSL_CORE_MAKE_FUNC(int, serializer_serialize_data,
+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, serializer_serialize_object,
+OSSL_CORE_MAKE_FUNC(int, encoder_encode_object,
                     (void *ctx, void *obj, OSSL_CORE_BIO *out,
                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
 
-# define OSSL_FUNC_DESERIALIZER_NEWCTX              1
-# define OSSL_FUNC_DESERIALIZER_FREECTX             2
-# define OSSL_FUNC_DESERIALIZER_GET_PARAMS          3
-# define OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS     4
-# define OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS      5
-# define OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS 6
-# define OSSL_FUNC_DESERIALIZER_DESERIALIZE        10
-# define OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT      11
-OSSL_CORE_MAKE_FUNC(void *, deserializer_newctx, (void *provctx))
-OSSL_CORE_MAKE_FUNC(void, deserializer_freectx, (void *ctx))
-OSSL_CORE_MAKE_FUNC(int, deserializer_get_params, (OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_gettable_params,
+# define OSSL_FUNC_DECODER_NEWCTX                      1
+# define OSSL_FUNC_DECODER_FREECTX                     2
+# define OSSL_FUNC_DECODER_GET_PARAMS                  3
+# define OSSL_FUNC_DECODER_GETTABLE_PARAMS             4
+# define OSSL_FUNC_DECODER_SET_CTX_PARAMS              5
+# define OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS         6
+# define OSSL_FUNC_DECODER_DECODE                     10
+# define OSSL_FUNC_DECODER_EXPORT_OBJECT              11
+OSSL_CORE_MAKE_FUNC(void *, decoder_newctx, (void *provctx))
+OSSL_CORE_MAKE_FUNC(void, decoder_freectx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, decoder_get_params, (OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_gettable_params,
                     (void *provctx))
-OSSL_CORE_MAKE_FUNC(int, deserializer_set_ctx_params,
+OSSL_CORE_MAKE_FUNC(int, decoder_set_ctx_params,
                     (void *ctx, const OSSL_PARAM params[]))
-OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_settable_ctx_params,
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_settable_ctx_params,
                     (void *provctx))
 
-OSSL_CORE_MAKE_FUNC(int, deserializer_deserialize,
+OSSL_CORE_MAKE_FUNC(int, decoder_decode,
                     (void *ctx, OSSL_CORE_BIO *in,
                      OSSL_CALLBACK *metadata_cb, void *metadata_cbarg,
                      OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg))
-OSSL_CORE_MAKE_FUNC(int, deserializer_export_object,
+OSSL_CORE_MAKE_FUNC(int, decoder_export_object,
                     (void *ctx, const void *objref, size_t objref_sz,
                      OSSL_CALLBACK *export_cb, void *export_cbarg))
 
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 97c4d65949..7538d9ce93 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -400,23 +400,23 @@ extern "C" {
 #define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION   "tls-negotiated-version"
 
 /*
- * Serializer / deserializer parameters
+ * Encoder / decoder parameters
  */
 /* The passphrase may be passed as a utf8 string or an octet string */
-#define OSSL_SERIALIZER_PARAM_CIPHER            OSSL_ALG_PARAM_CIPHER
-#define OSSL_SERIALIZER_PARAM_PROPERTIES        OSSL_ALG_PARAM_PROPERTIES
-#define OSSL_SERIALIZER_PARAM_PASS              "passphrase"
-
-#define OSSL_DESERIALIZER_PARAM_CIPHER          OSSL_ALG_PARAM_CIPHER
-#define OSSL_DESERIALIZER_PARAM_PROPERTIES      OSSL_ALG_PARAM_PROPERTIES
-#define OSSL_DESERIALIZER_PARAM_PASS            "passphrase"
-#define OSSL_DESERIALIZER_PARAM_INPUT_TYPE      "input-type"
-#define OSSL_DESERIALIZER_PARAM_DATA_TYPE       "data-type"
-#define OSSL_DESERIALIZER_PARAM_DATA            "data"
-#define OSSL_DESERIALIZER_PARAM_REFERENCE       "reference"
+#define OSSL_ENCODER_PARAM_CIPHER       OSSL_ALG_PARAM_CIPHER
+#define OSSL_ENCODER_PARAM_PROPERTIES   OSSL_ALG_PARAM_PROPERTIES
+#define OSSL_ENCODER_PARAM_PASS         "passphrase"
+
+#define OSSL_DECODER_PARAM_CIPHER       OSSL_ALG_PARAM_CIPHER
+#define OSSL_DECODER_PARAM_PROPERTIES   OSSL_ALG_PARAM_PROPERTIES
+#define OSSL_DECODER_PARAM_PASS         "passphrase"
+#define OSSL_DECODER_PARAM_INPUT_TYPE   "input-type"
+#define OSSL_DECODER_PARAM_DATA_TYPE    "data-type"
+#define OSSL_DECODER_PARAM_DATA         "data"
+#define OSSL_DECODER_PARAM_REFERENCE    "reference"
 
 /* Passphrase callback parameters */
-#define OSSL_PASSPHRASE_PARAM_INFO              "info"
+#define OSSL_PASSPHRASE_PARAM_INFO      "info"
 
 /* Keygen callback parameters, from provider to libcrypto */
 #define OSSL_GEN_PARAM_POTENTIAL            "potential" /* integer */
diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h
new file mode 100644
index 0000000000..cb5a404b89
--- /dev/null
+++ b/include/openssl/decoder.h
@@ -0,0 +1,117 @@
+/*
+ * 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
+ */
+
+#ifndef OPENSSL_DECODER_H
+# define OPENSSL_DECODER_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+# include <stddef.h>
+# include <openssl/decodererr.h>
+# include <openssl/types.h>
+# include <openssl/core.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+OSSL_DECODER *OSSL_DECODER_fetch(OPENSSL_CTX *libctx, const char *name,
+                                 const char *properties);
+int OSSL_DECODER_up_ref(OSSL_DECODER *encoder);
+void OSSL_DECODER_free(OSSL_DECODER *encoder);
+
+const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *encoder);
+const char *OSSL_DECODER_properties(const OSSL_DECODER *encoder);
+int OSSL_DECODER_number(const OSSL_DECODER *encoder);
+int OSSL_DECODER_is_a(const OSSL_DECODER *encoder, const char *name);
+
+void OSSL_DECODER_do_all_provided(OPENSSL_CTX *libctx,
+                                  void (*fn)(OSSL_DECODER *encoder, void *arg),
+                                  void *arg);
+void OSSL_DECODER_names_do_all(const OSSL_DECODER *encoder,
+                               void (*fn)(const char *name, void *data),
+                               void *data);
+const OSSL_PARAM *OSSL_DECODER_gettable_params(OSSL_DECODER *decoder);
+int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[]);
+
+const OSSL_PARAM *OSSL_DECODER_settable_ctx_params(OSSL_DECODER *encoder);
+OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void);
+int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx,
+                                const OSSL_PARAM params[]);
+void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx);
+
+/* Utilities that help set specific parameters */
+int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx,
+                                    const unsigned char *kstr,
+                                    size_t klen);
+int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx,
+                                         pem_password_cb *cb,
+                                         void *cbarg);
+int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx,
+                                       const UI_METHOD *ui_method,
+                                       void *ui_data);
+
+/*
+ * Utilities to read the object to decode, with the result sent to cb.
+ * These will discover all provided methods
+ */
+
+int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
+                                    const char *input_type);
+int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder);
+int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
+                               OPENSSL_CTX *libctx, const char *propq);
+int OSSL_DECODER_CTX_num_decoders(OSSL_DECODER_CTX *ctx);
+
+typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE;
+OSSL_DECODER *
+OSSL_DECODER_INSTANCE_decoder(OSSL_DECODER_INSTANCE *decoder_inst);
+void *OSSL_DECODER_INSTANCE_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst);
+
+typedef int (OSSL_DECODER_CONSTRUCT)(OSSL_DECODER_INSTANCE *decoder_inst,
+                                     const OSSL_PARAM *params,
+                                     void *construct_data);
+typedef void (OSSL_DECODER_CLEANUP)(void *construct_data);
+
+int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
+                                   OSSL_DECODER_CONSTRUCT *construct);
+int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
+                                        void *construct_data);
+int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
+                                 OSSL_DECODER_CLEANUP *cleanup);
+OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx);
+void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx);
+OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx);
+
+int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
+                        void *reference, size_t reference_sz,
+                        OSSL_CALLBACK *export_cb, void *export_cbarg);
+
+int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in);
+#ifndef OPENSSL_NO_STDIO
+int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *in);
+#endif
+
+/*
+ * Create the OSSL_DECODER_CTX with an associated type.  This will perform
+ * an implicit OSSL_DECODER_fetch(), suitable for the object of that type.
+ */
+OSSL_DECODER_CTX *
+OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, const char *input_type,
+                                 OPENSSL_CTX *libctx, const char *propquery);
+
+# ifdef __cplusplus
+}
+# endif
+#endif
diff --git a/include/openssl/deserializererr.h b/include/openssl/decodererr.h
similarity index 68%
rename from include/openssl/deserializererr.h
rename to include/openssl/decodererr.h
index 1c6573afb6..8da9157814 100644
--- a/include/openssl/deserializererr.h
+++ b/include/openssl/decodererr.h
@@ -8,8 +8,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef OPENSSL_OSSL_DESERIALIZERERR_H
-# define OPENSSL_OSSL_DESERIALIZERERR_H
+#ifndef OPENSSL_OSSL_DECODERERR_H
+# define OPENSSL_OSSL_DECODERERR_H
 # pragma once
 
 # include <openssl/opensslconf.h>
@@ -19,17 +19,17 @@
 # ifdef  __cplusplus
 extern "C"
 # endif
-int ERR_load_OSSL_DESERIALIZER_strings(void);
+int ERR_load_OSSL_DECODER_strings(void);
 
 /*
- * OSSL_DESERIALIZER function codes.
+ * OSSL_DECODER function codes.
  */
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 # endif
 
 /*
- * OSSL_DESERIALIZER reason codes.
+ * OSSL_DECODER reason codes.
  */
-# define OSSL_DESERIALIZER_R_MISSING_GET_PARAMS           100
+# define OSSL_DECODER_R_MISSING_GET_PARAMS           100
 
 #endif
diff --git a/include/openssl/deserializer.h b/include/openssl/deserializer.h
deleted file mode 100644
index 0133785b50..0000000000
--- a/include/openssl/deserializer.h
+++ /dev/null
@@ -1,125 +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
- */
-
-#ifndef OPENSSL_DESERIALIZER_H
-# define OPENSSL_DESERIALIZER_H
-# pragma once
-
-# include <openssl/opensslconf.h>
-
-# ifndef OPENSSL_NO_STDIO
-#  include <stdio.h>
-# endif
-# include <stdarg.h>
-# include <stddef.h>
-# include <openssl/deserializererr.h>
-# include <openssl/types.h>
-# include <openssl/core.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx,
-                                           const char *name,
-                                           const char *properties);
-int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *ser);
-void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *ser);
-
-const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *ser);
-const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *ser);
-int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *ser);
-int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *ser,
-                           const char *name);
-
-void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                       void (*fn)(OSSL_DESERIALIZER *ser,
-                                                  void *arg),
-                                       void *arg);
-void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *ser,
-                                    void (*fn)(const char *name, void *data),
-                                    void *data);
-const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser);
-int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[]);
-
-const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *ser);
-OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void);
-int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx,
-                                     const OSSL_PARAM params[]);
-void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx);
-
-/* Utilities that help set specific parameters */
-int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx,
-                                         const unsigned char *kstr,
-                                         size_t klen);
-int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx,
-                                              pem_password_cb *cb,
-                                              void *cbarg);
-int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx,
-                                            const UI_METHOD *ui_method,
-                                            void *ui_data);
-
-/*
- * Utilities to read the object to deserialize, with the result sent to cb.
- * These will discover all provided methods
- */
-
-int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx,
-                                         const char *input_type);
-int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx,
-                                           OSSL_DESERIALIZER *deser);
-int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx,
-                                    OPENSSL_CTX *libctx, const char *propq);
-int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx);
-
-typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE;
-OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer
-    (OSSL_DESERIALIZER_INSTANCE *deser_inst);
-void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx
-    (OSSL_DESERIALIZER_INSTANCE *deser_inst);
-
-typedef int (OSSL_DESERIALIZER_CONSTRUCT)
-    (OSSL_DESERIALIZER_INSTANCE *deser_inst,
-     const OSSL_PARAM *params, void *construct_data);
-typedef void (OSSL_DESERIALIZER_CLEANUP)(void *construct_data);
-
-int OSSL_DESERIALIZER_CTX_set_construct(OSSL_DESERIALIZER_CTX *ctx,
-                                        OSSL_DESERIALIZER_CONSTRUCT *construct);
-int OSSL_DESERIALIZER_CTX_set_construct_data(OSSL_DESERIALIZER_CTX *ctx,
-                                             void *construct_data);
-int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx,
-                                      OSSL_DESERIALIZER_CLEANUP *cleanup);
-OSSL_DESERIALIZER_CONSTRUCT *
-OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx);
-void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx);
-OSSL_DESERIALIZER_CLEANUP *
-OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx);
-
-int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst,
-                             void *reference, size_t reference_sz,
-                             OSSL_CALLBACK *export_cb, void *export_cbarg);
-
-int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in);
-#ifndef OPENSSL_NO_STDIO
-int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *in);
-#endif
-
-/*
- * Create the OSSL_DESERIALIZER_CTX with an associated type.  This will perform
- * an implicit OSSL_DESERIALIZER_fetch(), suitable for the object of that type.
- */
-OSSL_DESERIALIZER_CTX *
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, const char *input_type,
-                                      OPENSSL_CTX *libctx,
-                                      const char *propquery);
-
-# ifdef __cplusplus
-}
-# endif
-#endif
diff --git a/include/openssl/encoder.h b/include/openssl/encoder.h
new file mode 100644
index 0000000000..10b2bc9188
--- /dev/null
+++ b/include/openssl/encoder.h
@@ -0,0 +1,100 @@
+/*
+ * 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
+ */
+
+#ifndef OPENSSL_ENCODER_H
+# define OPENSSL_ENCODER_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+# include <stddef.h>
+# include <openssl/encodererr.h>
+# include <openssl/types.h>
+# include <openssl/core.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+OSSL_ENCODER *OSSL_ENCODER_fetch(OPENSSL_CTX *libctx, const char *name,
+                                 const char *properties);
+int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder);
+void OSSL_ENCODER_free(OSSL_ENCODER *encoder);
+
+const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder);
+const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder);
+int OSSL_ENCODER_number(const OSSL_ENCODER *encoder);
+int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name);
+
+void OSSL_ENCODER_do_all_provided(OPENSSL_CTX *libctx,
+                                  void (*fn)(OSSL_ENCODER *encoder, void *arg),
+                                  void *arg);
+void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder,
+                               void (*fn)(const char *name, void *data),
+                               void *data);
+
+const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder);
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(OSSL_ENCODER *encoder);
+const OSSL_ENCODER *OSSL_ENCODER_CTX_get_encoder(OSSL_ENCODER_CTX *ctx);
+int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx,
+                                const OSSL_PARAM params[]);
+void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx);
+
+/* Utilities that help set specific parameters */
+int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx,
+                                const char *cipher_name,
+                                const char *propquery);
+int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
+                                    const unsigned char *kstr,
+                                    size_t klen);
+int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx,
+                                       pem_password_cb *cb, void *cbarg);
+int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,
+                                       const UI_METHOD *ui_method,
+                                       void *ui_data);
+
+/* Utilities to output the object to encode */
+int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out);
+#ifndef OPENSSL_NO_STDIO
+int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp);
+#endif
+
+/*
+ * Create the OSSL_ENCODER_CTX with an associated type.  This will perform
+ * an implicit OSSL_ENCODER_fetch(), suitable for the object of that type.
+ * This is more useful than calling OSSL_ENCODER_CTX_new().
+ */
+OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
+                                                   const char *propquery);
+
+/*
+ * These macros define the last argument to pass to
+ * OSSL_ENCODER_CTX_new_by_TYPE().
+ */
+# define OSSL_ENCODER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
+# define OSSL_ENCODER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
+# define OSSL_ENCODER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
+
+# define OSSL_ENCODER_PUBKEY_TO_DER_PQ "format=der,type=public"
+# define OSSL_ENCODER_PrivateKey_TO_DER_PQ "format=der,type=private"
+# define OSSL_ENCODER_Parameters_TO_DER_PQ "format=der,type=parameters"
+
+/* Corresponding macros for text output */
+# define OSSL_ENCODER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
+# define OSSL_ENCODER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
+# define OSSL_ENCODER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
+
+# ifdef __cplusplus
+}
+# endif
+#endif
diff --git a/include/openssl/serializererr.h b/include/openssl/encodererr.h
similarity index 64%
rename from include/openssl/serializererr.h
rename to include/openssl/encodererr.h
index f99143b4d1..007070e0c0 100644
--- a/include/openssl/serializererr.h
+++ b/include/openssl/encodererr.h
@@ -8,8 +8,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef OPENSSL_OSSL_SERIALIZERERR_H
-# define OPENSSL_OSSL_SERIALIZERERR_H
+#ifndef OPENSSL_OSSL_ENCODERERR_H
+# define OPENSSL_OSSL_ENCODERERR_H
 # pragma once
 
 # include <openssl/opensslconf.h>
@@ -19,18 +19,18 @@
 # ifdef  __cplusplus
 extern "C"
 # endif
-int ERR_load_OSSL_SERIALIZER_strings(void);
+int ERR_load_OSSL_ENCODER_strings(void);
 
 /*
- * OSSL_SERIALIZER function codes.
+ * OSSL_ENCODER function codes.
  */
 # ifndef OPENSSL_NO_DEPRECATED_3_0
 # endif
 
 /*
- * OSSL_SERIALIZER reason codes.
+ * OSSL_ENCODER reason codes.
  */
-# define OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY       100
-# define OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND           101
+# define OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY       100
+# define OSSL_ENCODER_R_ENCODER_NOT_FOUND           101
 
 #endif
diff --git a/include/openssl/err.h b/include/openssl/err.h
index 77bbba4f9f..4dd69c6a3f 100644
--- a/include/openssl/err.h
+++ b/include/openssl/err.h
@@ -113,8 +113,8 @@ struct err_state_st {
 # define ERR_LIB_CRMF            56
 # define ERR_LIB_PROV            57
 # define ERR_LIB_CMP             58
-# define ERR_LIB_OSSL_SERIALIZER 59
-# define ERR_LIB_OSSL_DESERIALIZER 60
+# define ERR_LIB_OSSL_ENCODER 59
+# define ERR_LIB_OSSL_DECODER 60
 # define ERR_LIB_HTTP            61
 
 # define ERR_LIB_USER            128
diff --git a/include/openssl/serializer.h b/include/openssl/serializer.h
deleted file mode 100644
index 50c85d617f..0000000000
--- a/include/openssl/serializer.h
+++ /dev/null
@@ -1,104 +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
- */
-
-#ifndef OPENSSL_SERIALIZER_H
-# define OPENSSL_SERIALIZER_H
-# pragma once
-
-# include <openssl/opensslconf.h>
-
-# ifndef OPENSSL_NO_STDIO
-#  include <stdio.h>
-# endif
-# include <stdarg.h>
-# include <stddef.h>
-# include <openssl/serializererr.h>
-# include <openssl/types.h>
-# include <openssl/core.h>
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx,
-                                       const char *name,
-                                       const char *properties);
-int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser);
-void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser);
-
-const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser);
-const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser);
-int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser);
-int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser,
-                         const char *name);
-
-void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx,
-                                     void (*fn)(OSSL_SERIALIZER *ser,
-                                                void *arg),
-                                     void *arg);
-void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser,
-                                  void (*fn)(const char *name, void *data),
-                                  void *data);
-
-const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser);
-OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser);
-const OSSL_SERIALIZER *
-OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx);
-int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx,
-                                   const OSSL_PARAM params[]);
-void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx);
-
-/* Utilities that help set specific parameters */
-int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx,
-                                   const char *cipher_name,
-                                   const char *propquery);
-int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx,
-                                       const unsigned char *kstr,
-                                       size_t klen);
-int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx,
-                                          pem_password_cb *cb, void *cbarg);
-int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx,
-                                          const UI_METHOD *ui_method,
-                                          void *ui_data);
-
-/* Utilities to output the object to serialize */
-int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out);
-#ifndef OPENSSL_NO_STDIO
-int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp);
-#endif
-
-/*
- * Create the OSSL_SERIALIZER_CTX with an associated type.  This will perform
- * an implicit OSSL_SERIALIZER_fetch(), suitable for the object of that type.
- * This is more useful than calling OSSL_SERIALIZER_CTX_new().
- */
-OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey,
-                                                         const char *propquery);
-
-/*
- * These macros define the last argument to pass to
- * OSSL_SERIALIZER_CTX_new_by_TYPE().
- */
-# define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public"
-# define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private"
-# define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters"
-
-# define OSSL_SERIALIZER_PUBKEY_TO_DER_PQ "format=der,type=public"
-# define OSSL_SERIALIZER_PrivateKey_TO_DER_PQ "format=der,type=private"
-# define OSSL_SERIALIZER_Parameters_TO_DER_PQ "format=der,type=parameters"
-
-/* Corresponding macros for text output */
-# define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public"
-# define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private"
-# define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters"
-
-# ifdef __cplusplus
-}
-# endif
-#endif
diff --git a/include/openssl/types.h b/include/openssl/types.h
index 496f42a101..cd0c51e8bf 100644
--- a/include/openssl/types.h
+++ b/include/openssl/types.h
@@ -212,10 +212,10 @@ typedef struct ossl_param_bld_st OSSL_PARAM_BLD;
 
 typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
 
-typedef struct ossl_serializer_st OSSL_SERIALIZER;
-typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
-typedef struct ossl_deserializer_st OSSL_DESERIALIZER;
-typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX;
+typedef struct ossl_encoder_st OSSL_ENCODER;
+typedef struct ossl_encoder_ctx_st OSSL_ENCODER_CTX;
+typedef struct ossl_decoder_st OSSL_DECODER;
+typedef struct ossl_decoder_ctx_st OSSL_DECODER_CTX;
 
 typedef struct ossl_self_test_st OSSL_SELF_TEST;
 
diff --git a/providers/baseprov.c b/providers/baseprov.c
index 917bf680d4..eb0e4afbd3 100644
--- a/providers/baseprov.c
+++ b/providers/baseprov.c
@@ -64,37 +64,37 @@ static int base_get_params(void *provctx, OSSL_PARAM params[])
     return 1;
 }
 
-static const OSSL_ALGORITHM base_serializer[] = {
-#define SER(name, fips, format, type, func_table)                           \
+static const OSSL_ALGORITHM base_encoder[] = {
+#define ENCODER(name, fips, format, type, func_table)                           \
     { name,                                                                 \
       "provider=base,fips=" fips ",format=" format ",type=" type,           \
       (func_table) }
 
-#include "serializers.inc"
+#include "encoders.inc"
     { NULL, NULL, NULL }
 };
-#undef SER
+#undef ENCODER
 
-static const OSSL_ALGORITHM base_deserializer[] = {
-#define DESER(name, fips, input, func_table)                                \
+static const OSSL_ALGORITHM base_decoder[] = {
+#define DECODER(name, fips, input, func_table)                                \
     { name,                                                                 \
       "provider=base,fips=" fips ",input=" input,                           \
       (func_table) }
 
-#include "deserializers.inc"
+#include "decoders.inc"
     { NULL, NULL, NULL }
 };
-#undef DESER
+#undef DECODER
 
 static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id,
                                          int *no_cache)
 {
     *no_cache = 0;
     switch (operation_id) {
-    case OSSL_OP_SERIALIZER:
-        return base_serializer;
-    case OSSL_OP_DESERIALIZER:
-        return base_deserializer;
+    case OSSL_OP_ENCODER:
+        return base_encoder;
+    case OSSL_OP_DECODER:
+        return base_decoder;
     }
     return NULL;
 }
diff --git a/providers/decoders.inc b/providers/decoders.inc
new file mode 100644
index 0000000000..d8c6da72e1
--- /dev/null
+++ b/providers/decoders.inc
@@ -0,0 +1,42 @@
+/*
+ * 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
+ */
+
+#ifndef DECODER
+# error Macro DECODER undefined
+#endif
+
+#ifndef OPENSSL_NO_DH
+    DECODER("DH", "yes", "der", der_to_dh_decoder_functions),
+    DECODER("DHX", "yes", "der", der_to_dhx_decoder_functions),
+#endif
+#ifndef OPENSSL_NO_DSA
+    DECODER("DSA", "yes", "der", der_to_dsa_decoder_functions),
+    DECODER("DSA", "yes", "mblob", msblob_to_dsa_decoder_functions),
+# ifndef OPENSSL_NO_RC4
+    DECODER("DSA", "yes", "pvk", pvk_to_dsa_decoder_functions),
+# endif
+#endif
+#ifndef OPENSSL_NO_EC
+    DECODER("EC", "yes", "der", der_to_ec_decoder_functions),
+    DECODER("ED25519", "yes", "der", der_to_ed25519_decoder_functions),
+    DECODER("ED448", "yes", "der", der_to_ed448_decoder_functions),
+    DECODER("X25519", "yes", "der", der_to_x25519_decoder_functions),
+    DECODER("X448", "yes", "der", der_to_x448_decoder_functions),
+#endif
+    DECODER("RSA", "yes", "der", der_to_rsa_decoder_functions),
+    DECODER("RSA-PSS", "yes", "der", der_to_rsapss_decoder_functions),
+#ifndef OPENSSL_NO_DSA
+    DECODER("RSA", "yes", "mblob", msblob_to_rsa_decoder_functions),
+# ifndef OPENSSL_NO_RC4
+    DECODER("RSA", "yes", "pvk", pvk_to_rsa_decoder_functions),
+# endif
+#endif
+
+    DECODER("DER", "yes", "pem", pem_to_der_decoder_functions),
+
diff --git a/providers/defltprov.c b/providers/defltprov.c
index 083373a066..9aefa801a1 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -395,27 +395,27 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = {
     { NULL, NULL, NULL }
 };
 
-static const OSSL_ALGORITHM deflt_serializer[] = {
-#define SER(name, fips, format, type, func_table)                           \
+static const OSSL_ALGORITHM deflt_encoder[] = {
+#define ENCODER(name, fips, format, type, func_table)                           \
     { name,                                                                 \
       "provider=default,fips=" fips ",format=" format ",type=" type,        \
       (func_table) }
 
-#include "serializers.inc"
+#include "encoders.inc"
     { NULL, NULL, NULL }
 };
-#undef SER
+#undef ENCODER
 
-static const OSSL_ALGORITHM deflt_deserializer[] = {
-#define DESER(name, fips, input, func_table)                                \
+static const OSSL_ALGORITHM deflt_decoder[] = {
+#define DECODER(name, fips, input, func_table)                                \
     { name,                                                                 \
       "provider=default,fips=" fips ",input=" input,                        \
       (func_table) }
 
-#include "deserializers.inc"
+#include "decoders.inc"
     { NULL, NULL, NULL }
 };
-#undef DESER
+#undef DECODER
 
 static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id,
                                          int *no_cache)
@@ -441,10 +441,10 @@ static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id,
         return deflt_signature;
     case OSSL_OP_ASYM_CIPHER:
         return deflt_asym_cipher;
-    case OSSL_OP_SERIALIZER:
-        return deflt_serializer;
-    case OSSL_OP_DESERIALIZER:
-        return deflt_deserializer;
+    case OSSL_OP_ENCODER:
+        return deflt_encoder;
+    case OSSL_OP_DECODER:
+        return deflt_decoder;
     }
     return NULL;
 }
diff --git a/providers/deserializers.inc b/providers/deserializers.inc
deleted file mode 100644
index 2e363143b8..0000000000
--- a/providers/deserializers.inc
+++ /dev/null
@@ -1,42 +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
- */
-
-#ifndef DESER
-# error Macro DESER undefined
-#endif
-
-#ifndef OPENSSL_NO_DH
-    DESER("DH", "yes", "der", der_to_dh_deserializer_functions),
-    DESER("DHX", "yes", "der", der_to_dhx_deserializer_functions),
-#endif
-#ifndef OPENSSL_NO_DSA
-    DESER("DSA", "yes", "der", der_to_dsa_deserializer_functions),
-    DESER("DSA", "yes", "mblob", msblob_to_dsa_deserializer_functions),
-# ifndef OPENSSL_NO_RC4
-    DESER("DSA", "yes", "pvk", pvk_to_dsa_deserializer_functions),
-# endif
-#endif
-#ifndef OPENSSL_NO_EC
-    DESER("EC", "yes", "der", der_to_ec_deserializer_functions),
-    DESER("ED25519", "yes", "der", der_to_ed25519_deserializer_functions),
-    DESER("ED448", "yes", "der", der_to_ed448_deserializer_functions),
-    DESER("X25519", "yes", "der", der_to_x25519_deserializer_functions),
-    DESER("X448", "yes", "der", der_to_x448_deserializer_functions),
-#endif
-    DESER("RSA", "yes", "der", der_to_rsa_deserializer_functions),
-    DESER("RSA-PSS", "yes", "der", der_to_rsapss_deserializer_functions),
-#ifndef OPENSSL_NO_DSA
-    DESER("RSA", "yes", "mblob", msblob_to_rsa_deserializer_functions),
-# ifndef OPENSSL_NO_RC4
-    DESER("RSA", "yes", "pvk", pvk_to_rsa_deserializer_functions),
-# endif
-#endif
-
-    DESER("DER", "yes", "pem", pem_to_der_deserializer_functions),
-
diff --git a/providers/encoders.inc b/providers/encoders.inc
new file mode 100644
index 0000000000..4d894a73e5
--- /dev/null
+++ b/providers/encoders.inc
@@ -0,0 +1,112 @@
+/*
+ * 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
+ */
+
+#ifndef ENCODER
+# 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-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),
+
+#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("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),
+#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", "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),
+#endif
+
+#ifndef OPENSSL_NO_EC
+    ENCODER("X25519", "yes", "text", "private",
+        x25519_priv_print_encoder_functions),
+    ENCODER("X25519", "yes", "text", "public",
+        x25519_pub_print_encoder_functions),
+    ENCODER("X25519", "yes", "der", "private",
+        x25519_priv_der_encoder_functions),
+    ENCODER("X25519", "yes", "der", "public", x25519_pub_der_encoder_functions),
+    ENCODER("X25519", "yes", "pem", "private",
+        x25519_priv_pem_encoder_functions),
+    ENCODER("X25519", "yes", "pem", "public", x25519_pub_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("ED25519", "yes", "text", "private",
+        ed25519_priv_print_encoder_functions),
+    ENCODER("ED25519", "yes", "text", "public",
+        ed25519_pub_print_encoder_functions),
+    ENCODER("ED25519", "yes", "der", "private",
+        ed25519_priv_der_encoder_functions),
+    ENCODER("ED25519", "yes", "der", "public",
+        ed25519_pub_der_encoder_functions),
+    ENCODER("ED25519", "yes", "pem", "private",
+        ed25519_priv_pem_encoder_functions),
+    ENCODER("ED25519", "yes", "pem", "public",
+        ed25519_pub_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("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),
+#endif
diff --git a/providers/implementations/build.info b/providers/implementations/build.info
index 839478ef36..54392cf68b 100644
--- a/providers/implementations/build.info
+++ b/providers/implementations/build.info
@@ -1,2 +1,2 @@
 SUBDIRS=digests ciphers rands macs kdfs exchange keymgmt signature asymciphers \
-        serializers
+        encode_decode
diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info
new file mode 100644
index 0000000000..3e78849dfc
--- /dev/null
+++ b/providers/implementations/encode_decode/build.info
@@ -0,0 +1,35 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$ENCODER_GOAL=../../libimplementations.a
+$DECODER_GOAL=../../libimplementations.a
+$RSA_GOAL=../../libimplementations.a
+$FFC_GOAL=../../libimplementations.a
+$DH_GOAL=../../libimplementations.a
+$DSA_GOAL=../../libimplementations.a
+$ECX_GOAL=../../libimplementations.a
+$EC_GOAL=../../libimplementations.a
+
+SOURCE[$ENCODER_GOAL]=encoder_common.c decode_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
diff --git a/providers/implementations/serializers/deserialize_common.c b/providers/implementations/encode_decode/decode_common.c
similarity index 99%
rename from providers/implementations/serializers/deserialize_common.c
rename to providers/implementations/encode_decode/decode_common.c
index 54c63347fd..1b5eea4c8d 100644
--- a/providers/implementations/serializers/deserialize_common.c
+++ b/providers/implementations/encode_decode/decode_common.c
@@ -18,7 +18,7 @@
 #include "crypto/asn1.h"
 #include "prov/bio.h"               /* ossl_prov_bio_printf() */
 #include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
                        unsigned char **data, long *len)
diff --git a/providers/implementations/serializers/deserialize_der2key.c b/providers/implementations/encode_decode/decode_der2key.c
similarity index 81%
rename from providers/implementations/serializers/deserialize_der2key.c
rename to providers/implementations/encode_decode/decode_der2key.c
index 6975c9ceab..6af1c0927d 100644
--- a/providers/implementations/serializers/deserialize_der2key.c
+++ b/providers/implementations/encode_decode/decode_der2key.c
@@ -20,15 +20,15 @@
 #include <openssl/x509.h>
 #include "prov/bio.h"
 #include "prov/implementations.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx;
+static OSSL_FUNC_decoder_newctx_fn der2rsa_newctx;
 
-static OSSL_FUNC_deserializer_freectx_fn der2key_freectx;
-static OSSL_FUNC_deserializer_gettable_params_fn der2key_gettable_params;
-static OSSL_FUNC_deserializer_get_params_fn der2key_get_params;
-static OSSL_FUNC_deserializer_deserialize_fn der2key_deserialize;
-static OSSL_FUNC_deserializer_export_object_fn der2key_export_object;
+static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
+static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params;
+static OSSL_FUNC_decoder_get_params_fn der2key_get_params;
+static OSSL_FUNC_decoder_decode_fn der2key_decode;
+static OSSL_FUNC_decoder_export_object_fn der2key_export_object;
 
 typedef void *(extract_key_fn)(EVP_PKEY *);
 typedef void (free_key_fn)(void *);
@@ -46,7 +46,7 @@ struct keytype_desc_st {
 };
 
 /*
- * Context used for DER to key deserialization.
+ * Context used for DER to key decoding.
  */
 struct der2key_ctx_st {
     PROV_CTX *provctx;
@@ -75,7 +75,7 @@ static void der2key_freectx(void *vctx)
 static const OSSL_PARAM *der2key_gettable_params(void *provctx)
 {
     static const OSSL_PARAM gettables[] = {
-        { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+        { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
         OSSL_PARAM_END,
     };
 
@@ -86,16 +86,16 @@ static int der2key_get_params(OSSL_PARAM params[])
 {
     OSSL_PARAM *p;
 
-    p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE);
+    p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER"))
         return 0;
 
     return 1;
 }
 
-static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
-                               OSSL_CALLBACK *data_cb, void *data_cbarg,
-                               OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin,
+                          OSSL_CALLBACK *data_cb, void *data_cbarg,
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     struct der2key_ctx_st *ctx = vctx;
     void *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
@@ -160,11 +160,11 @@ static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
         OSSL_PARAM params[3];
 
         params[0] =
-            OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE,
+            OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_DATA_TYPE,
                                              (char *)ctx->desc->name, 0);
         /* The address of the key becomes the octet string */
         params[1] =
-            OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE,
+            OSSL_PARAM_construct_octet_string(OSSL_DECODER_PARAM_REFERENCE,
                                               &key, sizeof(key));
         params[2] = OSSL_PARAM_construct_end();
 
@@ -203,18 +203,18 @@ static int der2key_export_object(void *vctx,
     {                                                                   \
         return der2key_newctx(provctx, &keytype##_desc);                \
     }                                                                   \
-    const OSSL_DISPATCH der_to_##keytype##_deserializer_functions[] = { \
-        { OSSL_FUNC_DESERIALIZER_NEWCTX,                                \
+    const OSSL_DISPATCH der_to_##keytype##_decoder_functions[] = {      \
+        { OSSL_FUNC_DECODER_NEWCTX,                                     \
           (void (*)(void))der2##keytype##_newctx },                     \
-        { OSSL_FUNC_DESERIALIZER_FREECTX,                               \
+        { OSSL_FUNC_DECODER_FREECTX,                                    \
           (void (*)(void))der2key_freectx },                            \
-        { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,                       \
+        { OSSL_FUNC_DECODER_GETTABLE_PARAMS,                            \
           (void (*)(void))der2key_gettable_params },                    \
-        { OSSL_FUNC_DESERIALIZER_GET_PARAMS,                            \
+        { OSSL_FUNC_DECODER_GET_PARAMS,                                 \
           (void (*)(void))der2key_get_params },                         \
-        { OSSL_FUNC_DESERIALIZER_DESERIALIZE,                           \
-          (void (*)(void))der2key_deserialize },                        \
-        { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,                         \
+        { OSSL_FUNC_DECODER_DECODE,                                     \
+          (void (*)(void))der2key_decode },                             \
+        { OSSL_FUNC_DECODER_EXPORT_OBJECT,                              \
           (void (*)(void))der2key_export_object },                      \
         { 0, NULL }                                                     \
     }
diff --git a/providers/implementations/serializers/deserialize_ms2key.c b/providers/implementations/encode_decode/decode_ms2key.c
similarity index 73%
rename from providers/implementations/serializers/deserialize_ms2key.c
rename to providers/implementations/encode_decode/decode_ms2key.c
index 8b9ddec6a0..453e8188b3 100644
--- a/providers/implementations/serializers/deserialize_ms2key.c
+++ b/providers/implementations/encode_decode/decode_ms2key.c
@@ -21,19 +21,19 @@
 #include "internal/pem.h"        /* For PVK and "blob" PEM headers */
 #include "prov/bio.h"
 #include "prov/implementations.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_deserializer_freectx_fn ms2key_freectx;
-static OSSL_FUNC_deserializer_gettable_params_fn ms2key_gettable_params;
-static OSSL_FUNC_deserializer_get_params_fn msblob2key_get_params;
+static OSSL_FUNC_decoder_freectx_fn ms2key_freectx;
+static OSSL_FUNC_decoder_gettable_params_fn ms2key_gettable_params;
+static OSSL_FUNC_decoder_get_params_fn msblob2key_get_params;
 #ifndef OPENSSL_NO_RC4
-static OSSL_FUNC_deserializer_get_params_fn pvk2key_get_params;
+static OSSL_FUNC_decoder_get_params_fn pvk2key_get_params;
 #endif
-static OSSL_FUNC_deserializer_deserialize_fn msblob2key_deserialize;
+static OSSL_FUNC_decoder_decode_fn msblob2key_decode;
 #ifndef OPENSSL_NO_RC4
-static OSSL_FUNC_deserializer_deserialize_fn pvk2key_deserialize;
+static OSSL_FUNC_decoder_decode_fn pvk2key_decode;
 #endif
-static OSSL_FUNC_deserializer_export_object_fn ms2key_export_object;
+static OSSL_FUNC_decoder_export_object_fn ms2key_export_object;
 
 typedef void *(extract_key_fn)(EVP_PKEY *);
 typedef void (free_key_fn)(void *);
@@ -51,7 +51,7 @@ struct keytype_desc_st {
 };
 
 /*
- * Context used for DER to key deserialization.
+ * Context used for DER to key decoding.
  */
 struct ms2key_ctx_st {
     PROV_CTX *provctx;
@@ -80,7 +80,7 @@ static void ms2key_freectx(void *vctx)
 static const OSSL_PARAM *ms2key_gettable_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM gettables[] = {
-        { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+        { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
         OSSL_PARAM_END,
     };
 
@@ -91,7 +91,7 @@ static int msblob2key_get_params(OSSL_PARAM params[])
 {
     OSSL_PARAM *p;
 
-    p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE);
+    p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "MSBLOB"))
         return 0;
 
@@ -103,7 +103,7 @@ static int pvk2key_get_params(OSSL_PARAM params[])
 {
     OSSL_PARAM *p;
 
-    p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE);
+    p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PVK"))
         return 0;
 
@@ -134,11 +134,11 @@ static int ms2key_post(struct ms2key_ctx_st *ctx, EVP_PKEY *pkey,
         OSSL_PARAM params[3];
 
         params[0] =
-            OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE,
+            OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_DATA_TYPE,
                                              (char *)ctx->desc->name, 0);
         /* The address of the key becomes the octet string */
         params[1] =
-            OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE,
+            OSSL_PARAM_construct_octet_string(OSSL_DECODER_PARAM_REFERENCE,
                                               &key, sizeof(key));
         params[2] = OSSL_PARAM_construct_end();
 
@@ -149,10 +149,9 @@ static int ms2key_post(struct ms2key_ctx_st *ctx, EVP_PKEY *pkey,
     return ok;
 }
 
-static int msblob2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
-                                  OSSL_CALLBACK *data_cb, void *data_cbarg,
-                                  OSSL_PASSPHRASE_CALLBACK *pw_cb,
-                                  void *pw_cbarg)
+static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin,
+                             OSSL_CALLBACK *data_cb, void *data_cbarg,
+                             OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     struct ms2key_ctx_st *ctx = vctx;
     int ispub = -1;
@@ -164,10 +163,9 @@ static int msblob2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
 }
 
 #ifndef OPENSSL_NO_RC4
-static int pvk2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
-                               OSSL_CALLBACK *data_cb, void *data_cbarg,
-                               OSSL_PASSPHRASE_CALLBACK *pw_cb,
-                               void *pw_cbarg)
+static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin,
+                          OSSL_CALLBACK *data_cb, void *data_cbarg,
+                          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);
@@ -179,8 +177,8 @@ static int pvk2key_deserialize(void *vctx, OSSL_CORE_BIO *cin,
 #endif
 
 static int ms2key_export_object(void *vctx,
-                                 const void *reference, size_t reference_sz,
-                                 OSSL_CALLBACK *export_cb, void *export_cbarg)
+                                const void *reference, size_t reference_sz,
+                                OSSL_CALLBACK *export_cb, void *export_cbarg)
 {
     struct ms2key_ctx_st *ctx = vctx;
     OSSL_FUNC_keymgmt_export_fn *export =
@@ -199,7 +197,7 @@ static int ms2key_export_object(void *vctx,
 
 #define IMPLEMENT_TYPE(KEYTYPEstr, KEYTYPE, keytype, extract, free)     \
     static const struct keytype_desc_st keytype##_desc;                 \
-    static OSSL_FUNC_deserializer_newctx_fn ms2##keytype##_newctx;      \
+    static OSSL_FUNC_decoder_newctx_fn ms2##keytype##_newctx;           \
     static void *ms2##keytype##_newctx(void *provctx)                   \
     {                                                                   \
         return ms2key_newctx(provctx, &keytype##_desc);                 \
@@ -211,18 +209,18 @@ static int ms2key_export_object(void *vctx,
 
 #define IMPLEMENT_MS(mstype, keytype)                                   \
     const OSSL_DISPATCH                                                 \
-    mstype##_to_##keytype##_deserializer_functions[] = {                \
-        { OSSL_FUNC_DESERIALIZER_NEWCTX,                                \
+        mstype##_to_##keytype##_decoder_functions[] = {                 \
+        { OSSL_FUNC_DECODER_NEWCTX,                                     \
           (void (*)(void))ms2##keytype##_newctx },                      \
-        { OSSL_FUNC_DESERIALIZER_FREECTX,                               \
+        { OSSL_FUNC_DECODER_FREECTX,                                    \
           (void (*)(void))ms2key_freectx },                             \
-        { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,                       \
+        { OSSL_FUNC_DECODER_GETTABLE_PARAMS,                            \
           (void (*)(void))ms2key_gettable_params },                     \
-        { OSSL_FUNC_DESERIALIZER_GET_PARAMS,                            \
+        { OSSL_FUNC_DECODER_GET_PARAMS,                                 \
           (void (*)(void))mstype##2key_get_params },                    \
-        { OSSL_FUNC_DESERIALIZER_DESERIALIZE,                           \
-          (void (*)(void))mstype##2key_deserialize },                   \
-        { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,                         \
+        { OSSL_FUNC_DECODER_DECODE,                                     \
+          (void (*)(void))mstype##2key_decode },                        \
+        { OSSL_FUNC_DECODER_EXPORT_OBJECT,                              \
           (void (*)(void))ms2key_export_object },                       \
         { 0, NULL }                                                     \
     }
diff --git a/providers/implementations/serializers/deserialize_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
similarity index 71%
rename from providers/implementations/serializers/deserialize_pem2der.c
rename to providers/implementations/encode_decode/decode_pem2der.c
index ea43bd8319..7ba1cbe3d3 100644
--- a/providers/implementations/serializers/deserialize_pem2der.c
+++ b/providers/implementations/encode_decode/decode_pem2der.c
@@ -24,16 +24,16 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_deserializer_newctx_fn pem2der_newctx;
-static OSSL_FUNC_deserializer_freectx_fn pem2der_freectx;
-static OSSL_FUNC_deserializer_gettable_params_fn pem2der_gettable_params;
-static OSSL_FUNC_deserializer_get_params_fn pem2der_get_params;
-static OSSL_FUNC_deserializer_deserialize_fn pem2der_deserialize;
+static OSSL_FUNC_decoder_newctx_fn pem2der_newctx;
+static OSSL_FUNC_decoder_freectx_fn pem2der_freectx;
+static OSSL_FUNC_decoder_gettable_params_fn pem2der_gettable_params;
+static OSSL_FUNC_decoder_get_params_fn pem2der_get_params;
+static OSSL_FUNC_decoder_decode_fn pem2der_decode;
 
 /*
- * Context used for PEM to DER deserialization.
+ * Context used for PEM to DER decoding.
  */
 struct pem2der_ctx_st {
     PROV_CTX *provctx;
@@ -58,7 +58,7 @@ static void pem2der_freectx(void *vctx)
 static const OSSL_PARAM *pem2der_gettable_params(void *provctx)
 {
     static const OSSL_PARAM gettables[] = {
-        { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+        { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
         OSSL_PARAM_END,
     };
 
@@ -69,7 +69,7 @@ static int pem2der_get_params(OSSL_PARAM params[])
 {
     OSSL_PARAM *p;
 
-    p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE);
+    p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PEM"))
         return 0;
 
@@ -94,9 +94,9 @@ static int pem2der_pass_helper(char *buf, int num, int w, void *data)
     return (int)plen;
 }
 
-static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin,
-                               OSSL_CALLBACK *data_cb, void *data_cbarg,
-                               OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin,
+                          OSSL_CALLBACK *data_cb, void *data_cbarg,
+                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     struct pem2der_ctx_st *ctx = vctx;
     char *pem_name = NULL, *pem_header = NULL;
@@ -130,10 +130,10 @@ static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin,
         OSSL_PARAM params[3];
 
         params[0] =
-            OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE,
+            OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_DATA_TYPE,
                                              pem_name, 0);
         params[1] =
-            OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_DATA,
+            OSSL_PARAM_construct_octet_string(OSSL_DECODER_PARAM_DATA,
                                               der, der_len);
         params[2] = OSSL_PARAM_construct_end();
 
@@ -147,13 +147,13 @@ static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin,
     return ok;
 }
 
-const OSSL_DISPATCH pem_to_der_deserializer_functions[] = {
-    { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))pem2der_newctx },
-    { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))pem2der_freectx },
-    { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,
+const OSSL_DISPATCH pem_to_der_decoder_functions[] = {
+    { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))pem2der_newctx },
+    { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))pem2der_freectx },
+    { OSSL_FUNC_DECODER_GETTABLE_PARAMS,
       (void (*)(void))pem2der_gettable_params },
-    { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
+    { OSSL_FUNC_DECODER_GET_PARAMS,
       (void (*)(void))pem2der_get_params },
-    { OSSL_FUNC_DESERIALIZER_DESERIALIZE, (void (*)(void))pem2der_deserialize },
+    { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2der_decode },
     { 0, NULL }
 };
diff --git a/providers/implementations/serializers/serializer_common.c b/providers/implementations/encode_decode/encoder_common.c
similarity index 99%
rename from providers/implementations/serializers/serializer_common.c
rename to providers/implementations/encode_decode/encoder_common.c
index 58d7a27e60..4d8348b3fc 100644
--- a/providers/implementations/serializers/serializer_common.c
+++ b/providers/implementations/encode_decode/encoder_common.c
@@ -19,7 +19,7 @@
 #include "prov/bio.h"            /* ossl_prov_bio_printf() */
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 static PKCS8_PRIV_KEY_INFO *
 ossl_prov_p8info_from_obj(const void *obj, int obj_nid,
diff --git a/providers/implementations/serializers/serializer_dh.c b/providers/implementations/encode_decode/encoder_dh.c
similarity index 99%
rename from providers/implementations/serializers/serializer_dh.c
rename to providers/implementations/encode_decode/encoder_dh.c
index d1b1d27cf6..d9578f46c4 100644
--- a/providers/implementations/serializers/serializer_dh.c
+++ b/providers/implementations/encode_decode/encoder_dh.c
@@ -19,7 +19,7 @@
 #include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
 #include "internal/ffc.h"
 #include "crypto/dh.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void)
 {
diff --git a/providers/implementations/serializers/serializer_dh_param.c b/providers/implementations/encode_decode/encoder_dh_param.c
similarity index 70%
rename from providers/implementations/serializers/serializer_dh_param.c
rename to providers/implementations/encode_decode/encoder_dh_param.c
index 49c0857734..23cda024c4 100644
--- a/providers/implementations/serializers/serializer_dh_param.c
+++ b/providers/implementations/encode_decode/encoder_dh_param.c
@@ -22,17 +22,17 @@
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn dh_param_newctx;
-static OSSL_FUNC_serializer_freectx_fn dh_param_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dh_param_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_param_der;
-static OSSL_FUNC_serializer_serialize_data_fn dh_param_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_param_pem;
+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_serializer_serialize_data_fn dh_param_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_param_print;
+static OSSL_FUNC_encoder_encode_data_fn dh_param_print_data;
+static OSSL_FUNC_encoder_encode_object_fn dh_param_print;
 
 /* Parameters : context */
 
@@ -109,7 +109,7 @@ static int dh_param_pem_data(void *ctx, const OSSL_PARAM params[],
 }
 
 static int dh_param_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -146,7 +146,7 @@ static int dh_param_print_data(void *ctx, const OSSL_PARAM params[],
 }
 
 static int dh_param_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -160,27 +160,27 @@ static int dh_param_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dh_param_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_param_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_param_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_dh_priv.c b/providers/implementations/encode_decode/encoder_dh_priv.c
similarity index 73%
rename from providers/implementations/serializers/serializer_dh_priv.c
rename to providers/implementations/encode_decode/encoder_dh_priv.c
index 0e974ac401..a9373df96a 100644
--- a/providers/implementations/serializers/serializer_dh_priv.c
+++ b/providers/implementations/encode_decode/encoder_dh_priv.c
@@ -23,24 +23,24 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
-
-static OSSL_FUNC_serializer_newctx_fn dh_priv_newctx;
-static OSSL_FUNC_serializer_freectx_fn dh_priv_freectx;
-static OSSL_FUNC_serializer_set_ctx_params_fn dh_priv_set_ctx_params;
-static OSSL_FUNC_serializer_settable_ctx_params_fn dh_priv_settable_ctx_params;
-static OSSL_FUNC_serializer_serialize_data_fn dh_priv_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_priv_der;
-static OSSL_FUNC_serializer_serialize_data_fn dh_pem_priv_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_pem_priv;
-
-static OSSL_FUNC_serializer_newctx_fn dh_print_newctx;
-static OSSL_FUNC_serializer_freectx_fn dh_print_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dh_priv_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_priv_print;
-
- /*
- * Context used for private key serialization.
+#include "encoder_local.h"
+
+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;
@@ -74,8 +74,8 @@ static void dh_priv_freectx(void *vctx)
 static const OSSL_PARAM *dh_priv_settable_ctx_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
         OSSL_PARAM_END,
     };
 
@@ -87,10 +87,10 @@ 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_SERIALIZER_PARAM_CIPHER))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
         != NULL) {
         const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES);
+            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
         const char *props = NULL;
 
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
@@ -106,7 +106,7 @@ static int dh_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
                 == NULL))
             return 0;
     }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
         != NULL) {
         OPENSSL_free(ctx->sc.cipher_pass);
         ctx->sc.cipher_pass = NULL;
@@ -141,7 +141,7 @@ static int dh_priv_der_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int dh_priv_der(void *vctx, void *dh, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     struct dh_priv_ctx_st *ctx = vctx;
     int ret;
@@ -258,35 +258,35 @@ static int dh_priv_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dh_priv_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))dh_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_priv_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_priv_der },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))dh_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pem_priv_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pem_priv },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_print_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_print_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_priv_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_dh_pub.c b/providers/implementations/encode_decode/encoder_dh_pub.c
similarity index 70%
rename from providers/implementations/serializers/serializer_dh_pub.c
rename to providers/implementations/encode_decode/encoder_dh_pub.c
index b79f1df216..99f9532c34 100644
--- a/providers/implementations/serializers/serializer_dh_pub.c
+++ b/providers/implementations/encode_decode/encoder_dh_pub.c
@@ -22,17 +22,17 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn dh_pub_newctx;
-static OSSL_FUNC_serializer_freectx_fn dh_pub_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dh_pub_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_pub_der;
-static OSSL_FUNC_serializer_serialize_data_fn dh_pub_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_pub_pem;
+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_serializer_serialize_data_fn dh_pub_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dh_pub_print;
+static OSSL_FUNC_encoder_encode_data_fn dh_pub_print_data;
+static OSSL_FUNC_encoder_encode_object_fn dh_pub_print;
 
 /* Public key : context */
 
@@ -50,8 +50,8 @@ 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_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();
@@ -72,7 +72,7 @@ static int dh_pub_der_data(void *ctx, const OSSL_PARAM params[],
 }
 
 static int dh_pub_der(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -113,7 +113,7 @@ static int dh_pub_pem_data(void *ctx, const OSSL_PARAM params[],
 }
 
 static int dh_pub_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                      OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -153,7 +153,7 @@ static int dh_pub_print_data(void *ctx, const OSSL_PARAM params[],
 }
 
 static int dh_pub_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -167,27 +167,27 @@ static int dh_pub_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dh_pub_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pub_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pub_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_dsa.c b/providers/implementations/encode_decode/encoder_dsa.c
similarity index 99%
rename from providers/implementations/serializers/serializer_dsa.c
rename to providers/implementations/encode_decode/encoder_dsa.c
index 1f986b62d5..838079902e 100644
--- a/providers/implementations/serializers/serializer_dsa.c
+++ b/providers/implementations/encode_decode/encoder_dsa.c
@@ -18,7 +18,7 @@
 #include "prov/bio.h"             /* ossl_prov_bio_printf() */
 #include "prov/implementations.h" /* rsa_keymgmt_functions */
 #include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
-#include "serializer_local.h"
+#include "encoder_local.h"
 #include "internal/ffc.h"
 #include "crypto/dsa.h"
 
diff --git a/providers/implementations/serializers/serializer_dsa_param.c b/providers/implementations/encode_decode/encoder_dsa_param.c
similarity index 73%
rename from providers/implementations/serializers/serializer_dsa_param.c
rename to providers/implementations/encode_decode/encoder_dsa_param.c
index fff577df39..87abde7212 100644
--- a/providers/implementations/serializers/serializer_dsa_param.c
+++ b/providers/implementations/encode_decode/encoder_dsa_param.c
@@ -22,17 +22,17 @@
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn dsa_param_newctx;
-static OSSL_FUNC_serializer_freectx_fn dsa_param_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_param_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_param_der;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_param_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_param_pem;
+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_serializer_serialize_data_fn dsa_param_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_param_print;
+static OSSL_FUNC_encoder_encode_data_fn dsa_param_print_data;
+static OSSL_FUNC_encoder_encode_object_fn dsa_param_print;
 
 /* Parameters : context */
 
@@ -161,27 +161,27 @@ static int dsa_param_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dsa_param_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_param_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_param_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_dsa_priv.c b/providers/implementations/encode_decode/encoder_dsa_priv.c
similarity index 74%
rename from providers/implementations/serializers/serializer_dsa_priv.c
rename to providers/implementations/encode_decode/encoder_dsa_priv.c
index 0db3ef49e4..c37c9f9f3c 100644
--- a/providers/implementations/serializers/serializer_dsa_priv.c
+++ b/providers/implementations/encode_decode/encoder_dsa_priv.c
@@ -23,24 +23,24 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
-
-static OSSL_FUNC_serializer_newctx_fn dsa_priv_newctx;
-static OSSL_FUNC_serializer_freectx_fn dsa_priv_freectx;
-static OSSL_FUNC_serializer_set_ctx_params_fn dsa_priv_set_ctx_params;
-static OSSL_FUNC_serializer_settable_ctx_params_fn dsa_priv_settable_ctx_params;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_priv_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_priv_der;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_pem_priv_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_pem_priv;
-
-static OSSL_FUNC_serializer_newctx_fn dsa_print_newctx;
-static OSSL_FUNC_serializer_freectx_fn dsa_print_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_priv_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_priv_print;
-
- /*
- * Context used for private key serialization.
+#include "encoder_local.h"
+
+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;
@@ -74,8 +74,8 @@ static void dsa_priv_freectx(void *vctx)
 static const OSSL_PARAM *dsa_priv_settable_ctx_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
         OSSL_PARAM_END,
     };
 
@@ -87,10 +87,10 @@ 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_SERIALIZER_PARAM_CIPHER))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
         != NULL) {
         const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES);
+            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
         const char *props = NULL;
 
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
@@ -106,7 +106,7 @@ static int dsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
                 == NULL))
             return 0;
     }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
         != NULL) {
         OPENSSL_free(ctx->sc.cipher_pass);
         ctx->sc.cipher_pass = NULL;
@@ -256,35 +256,35 @@ static int dsa_priv_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dsa_priv_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))dsa_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_priv_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_priv_der },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))dsa_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pem_priv_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pem_priv },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_print_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_print_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_priv_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_dsa_pub.c b/providers/implementations/encode_decode/encoder_dsa_pub.c
similarity index 76%
rename from providers/implementations/serializers/serializer_dsa_pub.c
rename to providers/implementations/encode_decode/encoder_dsa_pub.c
index 787bbb541e..ca7dd4bf1e 100644
--- a/providers/implementations/serializers/serializer_dsa_pub.c
+++ b/providers/implementations/encode_decode/encoder_dsa_pub.c
@@ -22,17 +22,17 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn dsa_pub_newctx;
-static OSSL_FUNC_serializer_freectx_fn dsa_pub_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_pub_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_der;
-static OSSL_FUNC_serializer_serialize_data_fn dsa_pub_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_pem;
+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_serializer_serialize_data_fn dsa_pub_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_print;
+static OSSL_FUNC_encoder_encode_data_fn dsa_pub_print_data;
+static OSSL_FUNC_encoder_encode_object_fn dsa_pub_print;
 
 /* Public key : context */
 
@@ -177,27 +177,27 @@ static int dsa_pub_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH dsa_pub_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pub_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pub_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_ec.c b/providers/implementations/encode_decode/encoder_ec.c
similarity index 99%
rename from providers/implementations/serializers/serializer_ec.c
rename to providers/implementations/encode_decode/encoder_ec.c
index 0dbc889d34..8c256fe448 100644
--- a/providers/implementations/serializers/serializer_ec.c
+++ b/providers/implementations/encode_decode/encoder_ec.c
@@ -12,7 +12,7 @@
 #include "prov/bio.h"             /* ossl_prov_bio_printf() */
 #include "prov/implementations.h" /* ec_keymgmt_functions */
 #include "prov/providercommonerr.h" /* PROV_R_MISSING_OID */
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
                             OSSL_FUNC_keymgmt_free_fn **ec_free,
diff --git a/providers/implementations/serializers/serializer_ec_param.c b/providers/implementations/encode_decode/encoder_ec_param.c
similarity index 68%
rename from providers/implementations/serializers/serializer_ec_param.c
rename to providers/implementations/encode_decode/encoder_ec_param.c
index 95fbd555a0..2f6637d80e 100644
--- a/providers/implementations/serializers/serializer_ec_param.c
+++ b/providers/implementations/encode_decode/encoder_ec_param.c
@@ -16,17 +16,17 @@
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn ec_param_newctx;
-static OSSL_FUNC_serializer_freectx_fn ec_param_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn ec_param_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_param_der;
-static OSSL_FUNC_serializer_serialize_data_fn ec_param_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_param_pem;
+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_serializer_serialize_data_fn ec_param_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_param_print;
+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 */
@@ -65,7 +65,7 @@ static int ec_param_der_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_param_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(vctx, cout);
     int ret;
@@ -105,7 +105,7 @@ static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_param_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(vctx, cout);
     int ret;
@@ -144,7 +144,7 @@ static int ec_param_print_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                           OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(vctx, cout);
     int ret;
@@ -158,27 +158,27 @@ static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH ec_param_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_ec_priv.c b/providers/implementations/encode_decode/encoder_ec_priv.c
similarity index 71%
rename from providers/implementations/serializers/serializer_ec_priv.c
rename to providers/implementations/encode_decode/encoder_ec_priv.c
index 25dc8dbcca..ea8a1ba92b 100644
--- a/providers/implementations/serializers/serializer_ec_priv.c
+++ b/providers/implementations/encode_decode/encoder_ec_priv.c
@@ -17,24 +17,24 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
-
-static OSSL_FUNC_serializer_newctx_fn ec_priv_newctx;
-static OSSL_FUNC_serializer_freectx_fn ec_priv_freectx;
-static OSSL_FUNC_serializer_set_ctx_params_fn ec_priv_set_ctx_params;
-static OSSL_FUNC_serializer_settable_ctx_params_fn ec_priv_settable_ctx_params;
-static OSSL_FUNC_serializer_serialize_data_fn ec_priv_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_priv_der;
-static OSSL_FUNC_serializer_serialize_data_fn ec_pem_priv_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_pem_priv;
-
-static OSSL_FUNC_serializer_newctx_fn ec_print_newctx;
-static OSSL_FUNC_serializer_freectx_fn ec_print_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn ec_priv_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_priv_print;
-
- /*
- * Context used for private key serialization.
+#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;
@@ -68,8 +68,8 @@ static void ec_priv_freectx(void *vctx)
 static const OSSL_PARAM *ec_priv_settable_ctx_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
         OSSL_PARAM_END,
     };
 
@@ -81,10 +81,10 @@ 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_SERIALIZER_PARAM_CIPHER))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
         != NULL) {
         const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES);
+            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
         const char *props = NULL;
 
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
@@ -100,7 +100,7 @@ static int ec_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
                 == NULL))
             return 0;
     }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
         != NULL) {
         OPENSSL_free(ctx->sc.cipher_pass);
         ctx->sc.cipher_pass = NULL;
@@ -137,7 +137,7 @@ static int ec_priv_der_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_priv_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     struct ec_priv_ctx_st *ctx = vctx;
     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
@@ -184,7 +184,7 @@ static int ec_pem_priv_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_pem_priv(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
-                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     struct ec_priv_ctx_st *ctx = vctx;
     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
@@ -242,7 +242,7 @@ static int ec_priv_print_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ec_priv_print(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
-                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     BIO *out = bio_new_from_core_bio(ctx, cout);
     int ret;
@@ -256,35 +256,35 @@ static int ec_priv_print(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH ec_priv_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))ec_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_priv_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_priv_der },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))ec_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pem_priv_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pem_priv },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_print_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_print_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_priv_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_ec_pub.c b/providers/implementations/encode_decode/encoder_ec_pub.c
similarity index 74%
rename from providers/implementations/serializers/serializer_ec_pub.c
rename to providers/implementations/encode_decode/encoder_ec_pub.c
index 42fb4f96f2..9ab121f7d2 100644
--- a/providers/implementations/serializers/serializer_ec_pub.c
+++ b/providers/implementations/encode_decode/encoder_ec_pub.c
@@ -15,20 +15,19 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 #define EC_SELECT_PUBLIC_IMPORTABLE                                            \
     OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
 
-static OSSL_FUNC_serializer_newctx_fn ec_pub_newctx;
-static OSSL_FUNC_serializer_freectx_fn ec_pub_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn ec_pub_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_pub_der;
-static OSSL_FUNC_serializer_serialize_data_fn ec_pub_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_pub_pem;
-
-static OSSL_FUNC_serializer_serialize_data_fn ec_pub_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn ec_pub_print;
+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 */
 
@@ -167,27 +166,27 @@ static int ec_pub_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH ec_pub_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pub_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pub_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_ecx.c b/providers/implementations/encode_decode/encoder_ecx.c
similarity index 99%
rename from providers/implementations/serializers/serializer_ecx.c
rename to providers/implementations/encode_decode/encoder_ecx.c
index ef16d97b97..83de9fe002 100644
--- a/providers/implementations/serializers/serializer_ecx.c
+++ b/providers/implementations/encode_decode/encoder_ecx.c
@@ -11,7 +11,7 @@
 #include "crypto/ecx.h"
 #include "prov/bio.h"             /* ossl_prov_bio_printf() */
 #include "prov/implementations.h" /* ecx_keymgmt_functions */
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 void ecx_get_new_free_import(ECX_KEY_TYPE type,
                              OSSL_FUNC_keymgmt_new_fn **ecx_new,
diff --git a/providers/implementations/serializers/serializer_ecx_priv.c b/providers/implementations/encode_decode/encoder_ecx_priv.c
similarity index 68%
rename from providers/implementations/serializers/serializer_ecx_priv.c
rename to providers/implementations/encode_decode/encoder_ecx_priv.c
index 7df1e01fd5..cd0190aa7c 100644
--- a/providers/implementations/serializers/serializer_ecx_priv.c
+++ b/providers/implementations/encode_decode/encoder_ecx_priv.c
@@ -17,25 +17,25 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
-
-static OSSL_FUNC_serializer_newctx_fn x25519_priv_newctx;
-static OSSL_FUNC_serializer_newctx_fn x448_priv_newctx;
-static OSSL_FUNC_serializer_newctx_fn ed25519_priv_newctx;
-static OSSL_FUNC_serializer_newctx_fn ed448_priv_newctx;
-static OSSL_FUNC_serializer_freectx_fn ecx_priv_freectx;
-static OSSL_FUNC_serializer_set_ctx_params_fn ecx_priv_set_ctx_params;
-static OSSL_FUNC_serializer_settable_ctx_params_fn ecx_priv_settable_ctx_params;
-static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_der;
-static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_pem;
-
-static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_print;
-
- /*
- * Context used for private key serialization.
+#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;
@@ -91,8 +91,8 @@ static void ecx_priv_freectx(void *vctx)
 static const OSSL_PARAM *ecx_priv_settable_ctx_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
         OSSL_PARAM_END,
     };
 
@@ -104,10 +104,10 @@ 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_SERIALIZER_PARAM_CIPHER);
+    p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
     if (p != NULL) {
         const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES);
+            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
         const char *props;
 
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
@@ -123,7 +123,7 @@ static int ecx_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
                 == NULL))
             return 0;
     }
-    p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS);
+    p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS);
     if (p != NULL) {
         OPENSSL_free(ctx->sc.cipher_pass);
         ctx->sc.cipher_pass = NULL;
@@ -210,7 +210,7 @@ static int ecx_priv_pem_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ecx_priv_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                       OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     struct ecx_priv_ctx_st *ctx = vctx;
     int ret;
@@ -258,7 +258,7 @@ static int ecx_priv_print_data(void *vctx, const OSSL_PARAM params[],
 }
 
 static int ecx_priv_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
-                         OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
 {
     struct ecx_priv_ctx_st *ctx = vctx;
     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
@@ -273,35 +273,35 @@ static int ecx_priv_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-#define MAKE_SERIALIZER_FUNCTIONS(alg, type) \
-    const OSSL_DISPATCH alg##_priv_##type##_serializer_functions[] = { \
-        { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
-        { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
-        { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, \
-          (void (*)(void))ecx_priv_set_ctx_params }, \
-        { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, \
-          (void (*)(void))ecx_priv_settable_ctx_params }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \
-          (void (*)(void))ecx_priv_##type##_data }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \
-          (void (*)(void))ecx_priv_##type }, \
-        { 0, NULL } \
+#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_SERIALIZER_FUNCTIONS_GROUP(alg) \
-    MAKE_SERIALIZER_FUNCTIONS(alg, der) \
-    MAKE_SERIALIZER_FUNCTIONS(alg, pem) \
-    const OSSL_DISPATCH alg##_priv_print_serializer_functions[] = { \
-        { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
-        { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \
-          (void (*)(void))ecx_priv_print }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \
-          (void (*)(void))ecx_priv_print_data }, \
-        { 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_SERIALIZER_FUNCTIONS_GROUP(x25519)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(x448)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448)
+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/serializers/serializer_ecx_pub.c b/providers/implementations/encode_decode/encoder_ecx_pub.c
similarity index 75%
rename from providers/implementations/serializers/serializer_ecx_pub.c
rename to providers/implementations/encode_decode/encoder_ecx_pub.c
index fa15e5a8c4..6f082c2b4c 100644
--- a/providers/implementations/serializers/serializer_ecx_pub.c
+++ b/providers/implementations/encode_decode/encoder_ecx_pub.c
@@ -16,23 +16,23 @@
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn x25519_pub_newctx;
-static OSSL_FUNC_serializer_newctx_fn x448_pub_newctx;
-static OSSL_FUNC_serializer_newctx_fn ed25519_pub_newctx;
-static OSSL_FUNC_serializer_newctx_fn ed448_pub_newctx;
-static OSSL_FUNC_serializer_freectx_fn ecx_pub_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_der;
-static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_pem;
+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_serializer_serialize_data_fn ecx_pub_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_print;
+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 serialization.
+ * Context used for public key encoding.
  */
 struct ecx_pub_ctx_st {
     void *provctx;
@@ -204,23 +204,23 @@ static int ecx_pub_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-#define MAKE_SERIALIZER_FUNCTIONS(alg, type) \
-    const OSSL_DISPATCH alg##_pub_##type##_serializer_functions[] = { \
-        { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_pub_newctx }, \
-        { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_pub_freectx }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \
-          (void (*)(void))ecx_pub_##type##_data }, \
-        { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \
-          (void (*)(void))ecx_pub_##type }, \
-        { 0, NULL } \
+#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_SERIALIZER_FUNCTIONS_GROUP(alg) \
-    MAKE_SERIALIZER_FUNCTIONS(alg, der) \
-    MAKE_SERIALIZER_FUNCTIONS(alg, pem) \
-    MAKE_SERIALIZER_FUNCTIONS(alg, print)
+#define MAKE_ENCODER_FUNCTIONS_GROUP(alg)       \
+    MAKE_ENCODER_FUNCTIONS(alg, der)            \
+        MAKE_ENCODER_FUNCTIONS(alg, pem)        \
+        MAKE_ENCODER_FUNCTIONS(alg, print)
 
-MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(x448)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519)
-MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448)
+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/serializers/serializer_ffc_params.c b/providers/implementations/encode_decode/encoder_ffc_params.c
similarity index 98%
rename from providers/implementations/serializers/serializer_ffc_params.c
rename to providers/implementations/encode_decode/encoder_ffc_params.c
index ad96c4ddd0..67ec50c9b8 100644
--- a/providers/implementations/serializers/serializer_ffc_params.c
+++ b/providers/implementations/encode_decode/encoder_ffc_params.c
@@ -10,7 +10,7 @@
 /* Utility function for printing DSA/DH params. */
 
 #include "prov/bio.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
 int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc)
 {
diff --git a/providers/implementations/serializers/serializer_local.h b/providers/implementations/encode_decode/encoder_local.h
similarity index 99%
rename from providers/implementations/serializers/serializer_local.h
rename to providers/implementations/encode_decode/encoder_local.h
index 14c6073246..7a1f29f7e9 100644
--- a/providers/implementations/serializers/serializer_local.h
+++ b/providers/implementations/encode_decode/encoder_local.h
@@ -79,7 +79,7 @@ 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 serializing
+ * 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,
diff --git a/providers/implementations/serializers/serializer_rsa.c b/providers/implementations/encode_decode/encoder_rsa.c
similarity index 98%
rename from providers/implementations/serializers/serializer_rsa.c
rename to providers/implementations/encode_decode/encoder_rsa.c
index 9250d49735..cd9ff3b7dd 100644
--- a/providers/implementations/serializers/serializer_rsa.c
+++ b/providers/implementations/encode_decode/encoder_rsa.c
@@ -18,7 +18,7 @@
 #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 "serializer_local.h"
+#include "encoder_local.h"
 
 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
 
@@ -189,7 +189,7 @@ int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
 }
 
 /*
- * Helper functions to prepare RSA-PSS params for serialization.  We would
+ * 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.
  */
diff --git a/providers/implementations/serializers/serializer_rsa_priv.c b/providers/implementations/encode_decode/encoder_rsa_priv.c
similarity index 74%
rename from providers/implementations/serializers/serializer_rsa_priv.c
rename to providers/implementations/encode_decode/encoder_rsa_priv.c
index 5a589ae020..3ba648f360 100644
--- a/providers/implementations/serializers/serializer_rsa_priv.c
+++ b/providers/implementations/encode_decode/encoder_rsa_priv.c
@@ -26,24 +26,24 @@
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
-
-static OSSL_FUNC_serializer_newctx_fn rsa_priv_newctx;
-static OSSL_FUNC_serializer_freectx_fn rsa_priv_freectx;
-static OSSL_FUNC_serializer_set_ctx_params_fn rsa_priv_set_ctx_params;
-static OSSL_FUNC_serializer_settable_ctx_params_fn rsa_priv_settable_ctx_params;
-static OSSL_FUNC_serializer_serialize_data_fn rsa_priv_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_priv_der;
-static OSSL_FUNC_serializer_serialize_data_fn rsa_pem_priv_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_pem_priv;
-
-static OSSL_FUNC_serializer_newctx_fn rsa_print_newctx;
-static OSSL_FUNC_serializer_freectx_fn rsa_print_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn rsa_priv_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_priv_print;
-
- /*
- * Context used for private key serialization.
+#include "encoder_local.h"
+
+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;
@@ -76,8 +76,8 @@ static void rsa_priv_freectx(void *vctx)
 static const OSSL_PARAM *rsa_priv_settable_ctx_params(ossl_unused void *provctx)
 {
     static const OSSL_PARAM settables[] = {
-        OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
         OSSL_PARAM_END,
     };
 
@@ -89,10 +89,10 @@ 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_SERIALIZER_PARAM_CIPHER))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
         != NULL) {
         const OSSL_PARAM *propsp =
-            OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES);
+            OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
         const char *props = NULL;
 
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
@@ -108,7 +108,7 @@ static int rsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
                 == NULL))
             return 0;
     }
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS))
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
         != NULL) {
         OPENSSL_free(ctx->sc.cipher_pass);
         ctx->sc.cipher_pass = NULL;
@@ -260,35 +260,35 @@ static int rsa_priv_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH rsa_priv_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))rsa_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_priv_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_priv_der },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_priv_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_priv_freectx },
-    { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS,
+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_SERIALIZER_SETTABLE_CTX_PARAMS,
+    { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
       (void (*)(void))rsa_priv_settable_ctx_params },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pem_priv_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pem_priv },
+    { 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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_print_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_print_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_priv_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/serializers/serializer_rsa_pub.c b/providers/implementations/encode_decode/encoder_rsa_pub.c
similarity index 75%
rename from providers/implementations/serializers/serializer_rsa_pub.c
rename to providers/implementations/encode_decode/encoder_rsa_pub.c
index 72c290ee44..29e71cc093 100644
--- a/providers/implementations/serializers/serializer_rsa_pub.c
+++ b/providers/implementations/encode_decode/encoder_rsa_pub.c
@@ -22,17 +22,17 @@
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
-#include "serializer_local.h"
+#include "encoder_local.h"
 
-static OSSL_FUNC_serializer_newctx_fn rsa_pub_newctx;
-static OSSL_FUNC_serializer_freectx_fn rsa_pub_freectx;
-static OSSL_FUNC_serializer_serialize_data_fn rsa_pub_der_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_der;
-static OSSL_FUNC_serializer_serialize_data_fn rsa_pub_pem_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_pem;
+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_serializer_serialize_data_fn rsa_pub_print_data;
-static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_print;
+static OSSL_FUNC_encoder_encode_data_fn rsa_pub_print_data;
+static OSSL_FUNC_encoder_encode_object_fn rsa_pub_print;
 
 /* Public key : context */
 
@@ -167,27 +167,27 @@ static int rsa_pub_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
     return ret;
 }
 
-const OSSL_DISPATCH rsa_pub_der_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pub_der_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_der },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pub_pem_data },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_pem },
+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_serializer_functions[] = {
-    { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx },
-    { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_print },
-    { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
+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/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index f4c2a5adf5..f07a7b00f0 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -299,84 +299,84 @@ extern const OSSL_DISPATCH ecdsa_signature_functions[];
 /* Asym Cipher */
 extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
 
-/* Serializers */
-extern const OSSL_DISPATCH rsa_priv_text_serializer_functions[];
-extern const OSSL_DISPATCH rsa_pub_text_serializer_functions[];
-extern const OSSL_DISPATCH rsa_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH rsa_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH rsa_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH rsa_pub_pem_serializer_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 dh_priv_text_serializer_functions[];
-extern const OSSL_DISPATCH dh_pub_text_serializer_functions[];
-extern const OSSL_DISPATCH dh_param_text_serializer_functions[];
-extern const OSSL_DISPATCH dh_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH dh_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH dh_param_der_serializer_functions[];
-extern const OSSL_DISPATCH dh_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH dh_pub_pem_serializer_functions[];
-extern const OSSL_DISPATCH dh_param_pem_serializer_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 dsa_priv_text_serializer_functions[];
-extern const OSSL_DISPATCH dsa_pub_text_serializer_functions[];
-extern const OSSL_DISPATCH dsa_param_text_serializer_functions[];
-extern const OSSL_DISPATCH dsa_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH dsa_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH dsa_param_der_serializer_functions[];
-extern const OSSL_DISPATCH dsa_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH dsa_pub_pem_serializer_functions[];
-extern const OSSL_DISPATCH dsa_param_pem_serializer_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 x25519_priv_print_serializer_functions[];
-extern const OSSL_DISPATCH x25519_pub_print_serializer_functions[];
-extern const OSSL_DISPATCH x25519_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH x25519_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH x25519_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH x25519_pub_pem_serializer_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 x448_priv_print_serializer_functions[];
-extern const OSSL_DISPATCH x448_pub_print_serializer_functions[];
-extern const OSSL_DISPATCH x448_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH x448_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH x448_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH x448_pub_pem_serializer_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 ed25519_priv_print_serializer_functions[];
-extern const OSSL_DISPATCH ed25519_pub_print_serializer_functions[];
-extern const OSSL_DISPATCH ed25519_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH ed25519_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH ed25519_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH ed25519_pub_pem_serializer_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 ed448_priv_print_serializer_functions[];
-extern const OSSL_DISPATCH ed448_pub_print_serializer_functions[];
-extern const OSSL_DISPATCH ed448_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH ed448_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH ed448_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH ed448_pub_pem_serializer_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 ec_priv_text_serializer_functions[];
-extern const OSSL_DISPATCH ec_pub_text_serializer_functions[];
-extern const OSSL_DISPATCH ec_param_text_serializer_functions[];
-extern const OSSL_DISPATCH ec_priv_der_serializer_functions[];
-extern const OSSL_DISPATCH ec_pub_der_serializer_functions[];
-extern const OSSL_DISPATCH ec_param_der_serializer_functions[];
-extern const OSSL_DISPATCH ec_priv_pem_serializer_functions[];
-extern const OSSL_DISPATCH ec_pub_pem_serializer_functions[];
-extern const OSSL_DISPATCH ec_param_pem_serializer_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 der_to_dh_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_dhx_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_dsa_deserializer_functions[];
-extern const OSSL_DISPATCH msblob_to_dsa_deserializer_functions[];
-extern const OSSL_DISPATCH pvk_to_dsa_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_ec_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_x25519_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_x448_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_ed25519_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_ed448_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_rsa_deserializer_functions[];
-extern const OSSL_DISPATCH der_to_rsapss_deserializer_functions[];
-extern const OSSL_DISPATCH msblob_to_rsa_deserializer_functions[];
-extern const OSSL_DISPATCH pvk_to_rsa_deserializer_functions[];
-extern const OSSL_DISPATCH pem_to_der_deserializer_functions[];
+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[];
+extern const OSSL_DISPATCH msblob_to_dsa_decoder_functions[];
+extern const OSSL_DISPATCH pvk_to_dsa_decoder_functions[];
+extern const OSSL_DISPATCH der_to_ec_decoder_functions[];
+extern const OSSL_DISPATCH der_to_x25519_decoder_functions[];
+extern const OSSL_DISPATCH der_to_x448_decoder_functions[];
+extern const OSSL_DISPATCH der_to_ed25519_decoder_functions[];
+extern const OSSL_DISPATCH der_to_ed448_decoder_functions[];
+extern const OSSL_DISPATCH der_to_rsa_decoder_functions[];
+extern const OSSL_DISPATCH der_to_rsapss_decoder_functions[];
+extern const OSSL_DISPATCH msblob_to_rsa_decoder_functions[];
+extern const OSSL_DISPATCH pvk_to_rsa_decoder_functions[];
+extern const OSSL_DISPATCH pem_to_der_decoder_functions[];
diff --git a/providers/implementations/serializers/build.info b/providers/implementations/serializers/build.info
deleted file mode 100644
index 04f230b334..0000000000
--- a/providers/implementations/serializers/build.info
+++ /dev/null
@@ -1,35 +0,0 @@
-# We make separate GOAL variables for each algorithm, to make it easy to
-# switch each to the Legacy provider when needed.
-
-$SERIALIZER_GOAL=../../libimplementations.a
-$DESERIALIZER_GOAL=../../libimplementations.a
-$RSA_GOAL=../../libimplementations.a
-$FFC_GOAL=../../libimplementations.a
-$DH_GOAL=../../libimplementations.a
-$DSA_GOAL=../../libimplementations.a
-$ECX_GOAL=../../libimplementations.a
-$EC_GOAL=../../libimplementations.a
-
-SOURCE[$SERIALIZER_GOAL]=serializer_common.c deserialize_common.c
-
-SOURCE[$DESERIALIZER_GOAL]=deserialize_der2key.c deserialize_pem2der.c
-IF[{- !$disabled{dsa} -}]
-  SOURCE[$DESERIALIZER_GOAL]=deserialize_ms2key.c
-ENDIF
-
-SOURCE[$RSA_GOAL]=serializer_rsa.c serializer_rsa_priv.c serializer_rsa_pub.c
-DEPEND[serializer_rsa.o]=../../common/include/prov/der_rsa.h
-
-IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}]
-  SOURCE[$FFC_GOAL]=serializer_ffc_params.c
-ENDIF
-IF[{- !$disabled{dh} -}]
-  SOURCE[$DH_GOAL]=serializer_dh.c serializer_dh_priv.c serializer_dh_pub.c serializer_dh_param.c
-ENDIF
-IF[{- !$disabled{dsa} -}]
-  SOURCE[$DSA_GOAL]=serializer_dsa.c serializer_dsa_priv.c serializer_dsa_pub.c serializer_dsa_param.c
-ENDIF
-IF[{- !$disabled{ec} -}]
-  SOURCE[$ECX_GOAL]=serializer_ecx.c serializer_ecx_priv.c serializer_ecx_pub.c
-  SOURCE[$EC_GOAL]=serializer_ec.c serializer_ec_priv.c serializer_ec_pub.c serializer_ec_param.c
-ENDIF
diff --git a/providers/serializers.inc b/providers/serializers.inc
deleted file mode 100644
index 749c1bbb67..0000000000
--- a/providers/serializers.inc
+++ /dev/null
@@ -1,112 +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
- */
-
-#ifndef SER
-# error Macro SER undefined
-#endif
-
-    SER("RSA", "yes", "text", "private", rsa_priv_text_serializer_functions),
-    SER("RSA", "yes", "text", "public", rsa_pub_text_serializer_functions),
-    SER("RSA", "yes", "der", "private", rsa_priv_der_serializer_functions),
-    SER("RSA", "yes", "der", "public", rsa_pub_der_serializer_functions),
-    SER("RSA", "yes", "pem", "private", rsa_priv_pem_serializer_functions),
-    SER("RSA", "yes", "pem", "public", rsa_pub_pem_serializer_functions),
-    SER("RSA-PSS", "yes", "text", "private",
-        rsa_priv_text_serializer_functions),
-    SER("RSA-PSS", "yes", "text", "public", rsa_pub_text_serializer_functions),
-    SER("RSA-PSS", "yes", "der", "private", rsa_priv_der_serializer_functions),
-    SER("RSA-PSS", "yes", "der", "public", rsa_pub_der_serializer_functions),
-    SER("RSA-PSS", "yes", "pem", "private", rsa_priv_pem_serializer_functions),
-    SER("RSA-PSS", "yes", "pem", "public", rsa_pub_pem_serializer_functions),
-
-#ifndef OPENSSL_NO_DH
-    SER("DH", "yes", "text", "private", dh_priv_text_serializer_functions),
-    SER("DH", "yes", "text", "public", dh_pub_text_serializer_functions),
-    SER("DH", "yes", "text", "parameters", dh_param_text_serializer_functions),
-    SER("DH", "yes", "der", "private", dh_priv_der_serializer_functions),
-    SER("DH", "yes", "der", "public", dh_pub_der_serializer_functions),
-    SER("DH", "yes", "der", "parameters", dh_param_der_serializer_functions),
-    SER("DH", "yes", "pem", "private", dh_priv_pem_serializer_functions),
-    SER("DH", "yes", "pem", "public", dh_pub_pem_serializer_functions),
-    SER("DH", "yes", "pem", "parameters", dh_param_pem_serializer_functions),
-
-    SER("DHX", "yes", "text", "private", dh_priv_text_serializer_functions),
-    SER("DHX", "yes", "text", "public", dh_pub_text_serializer_functions),
-    SER("DHX", "yes", "text", "parameters", dh_param_text_serializer_functions),
-    SER("DHX", "yes", "der", "private", dh_priv_der_serializer_functions),
-    SER("DHX", "yes", "der", "public", dh_pub_der_serializer_functions),
-    SER("DHX", "yes", "der", "parameters", dh_param_der_serializer_functions),
-    SER("DHX", "yes", "pem", "private", dh_priv_pem_serializer_functions),
-    SER("DHX", "yes", "pem", "public", dh_pub_pem_serializer_functions),
-    SER("DHX", "yes", "pem", "parameters", dh_param_pem_serializer_functions),
-#endif
-
-#ifndef OPENSSL_NO_DSA
-    SER("DSA", "yes", "text", "private", dsa_priv_text_serializer_functions),
-    SER("DSA", "yes", "text", "public", dsa_pub_text_serializer_functions),
-    SER("DSA", "yes", "text", "parameters",
-        dsa_param_text_serializer_functions),
-    SER("DSA", "yes", "der", "private", dsa_priv_der_serializer_functions),
-    SER("DSA", "yes", "der", "public", dsa_pub_der_serializer_functions),
-    SER("DSA", "yes", "der", "parameters", dsa_param_der_serializer_functions),
-    SER("DSA", "yes", "pem", "private", dsa_priv_pem_serializer_functions),
-    SER("DSA", "yes", "pem", "public", dsa_pub_pem_serializer_functions),
-    SER("DSA", "yes", "pem", "parameters", dsa_param_pem_serializer_functions),
-#endif
-
-#ifndef OPENSSL_NO_EC
-    SER("X25519", "yes", "text", "private",
-        x25519_priv_print_serializer_functions),
-    SER("X25519", "yes", "text", "public",
-        x25519_pub_print_serializer_functions),
-    SER("X25519", "yes", "der", "private",
-        x25519_priv_der_serializer_functions),
-    SER("X25519", "yes", "der", "public", x25519_pub_der_serializer_functions),
-    SER("X25519", "yes", "pem", "private",
-        x25519_priv_pem_serializer_functions),
-    SER("X25519", "yes", "pem", "public", x25519_pub_pem_serializer_functions),
-
-    SER("X448", "no", "text", "private", x448_priv_print_serializer_functions),
-    SER("X448", "no", "text", "public", x448_pub_print_serializer_functions),
-    SER("X448", "no", "der", "private", x448_priv_der_serializer_functions),
-    SER("X448", "no", "der", "public", x448_pub_der_serializer_functions),
-    SER("X448", "no", "pem", "private", x448_priv_pem_serializer_functions),
-    SER("X448", "no", "pem", "public", x448_pub_pem_serializer_functions),
-
-    SER("ED25519", "yes", "text", "private",
-        ed25519_priv_print_serializer_functions),
-    SER("ED25519", "yes", "text", "public",
-        ed25519_pub_print_serializer_functions),
-    SER("ED25519", "yes", "der", "private",
-        ed25519_priv_der_serializer_functions),
-    SER("ED25519", "yes", "der", "public",
-        ed25519_pub_der_serializer_functions),
-    SER("ED25519", "yes", "pem", "private",
-        ed25519_priv_pem_serializer_functions),
-    SER("ED25519", "yes", "pem", "public",
-        ed25519_pub_pem_serializer_functions),
-
-    SER("ED448", "no", "text", "private",
-        ed448_priv_print_serializer_functions),
-    SER("ED448", "no", "text", "public", ed448_pub_print_serializer_functions),
-    SER("ED448", "no", "der", "private", ed448_priv_der_serializer_functions),
-    SER("ED448", "no", "der", "public", ed448_pub_der_serializer_functions),
-    SER("ED448", "no", "pem", "private", ed448_priv_pem_serializer_functions),
-    SER("ED448", "no", "pem", "public", ed448_pub_pem_serializer_functions),
-
-    SER("EC", "yes", "text", "private", ec_priv_text_serializer_functions),
-    SER("EC", "yes", "text", "public", ec_pub_text_serializer_functions),
-    SER("EC", "yes", "text", "parameters", ec_param_text_serializer_functions),
-    SER("EC", "yes", "der", "private", ec_priv_der_serializer_functions),
-    SER("EC", "yes", "der", "public", ec_pub_der_serializer_functions),
-    SER("EC", "yes", "der", "parameters", ec_param_der_serializer_functions),
-    SER("EC", "yes", "pem", "private", ec_priv_pem_serializer_functions),
-    SER("EC", "yes", "pem", "public", ec_pub_pem_serializer_functions),
-    SER("EC", "yes", "pem", "parameters", ec_param_pem_serializer_functions),
-#endif
diff --git a/test/build.info b/test/build.info
index 3ad16b51b1..134a473195 100644
--- a/test/build.info
+++ b/test/build.info
@@ -780,10 +780,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[hexstr_test]=.. ../include ../apps/include
   DEPEND[hexstr_test]=../libcrypto.a libtestutil.a
 
-  PROGRAMS{noinst}=serdes_test
-  SOURCE[serdes_test]=serdes_test.c
-  INCLUDE[serdes_test]=.. ../include ../apps/include
-  DEPEND[serdes_test]=../libcrypto.a libtestutil.a
+  PROGRAMS{noinst}=endecode_test
+  SOURCE[endecode_test]=endecode_test.c
+  INCLUDE[endecode_test]=.. ../include ../apps/include
+  DEPEND[endecode_test]=../libcrypto.a libtestutil.a
 
   PROGRAMS{noinst}=namemap_internal_test
   SOURCE[namemap_internal_test]=namemap_internal_test.c
diff --git a/test/serdes_test.c b/test/endecode_test.c
similarity index 79%
rename from test/serdes_test.c
rename to test/endecode_test.c
index f4afe53eac..5f3fa3d220 100644
--- a/test/serdes_test.c
+++ b/test/endecode_test.c
@@ -13,8 +13,8 @@
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
 #include <openssl/params.h>
-#include <openssl/serializer.h>
-#include <openssl/deserializer.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
 
 #include "internal/pem.h"        /* For PVK and "blob" PEM headers */
 #include "internal/cryptlib.h"   /* ossl_assert */
@@ -26,7 +26,7 @@
  * provider side EVP_PKEYs (which don't necessarily have an ameth)
  *
  * In the mean time, we use separate "downgraded" EVP_PKEYs to test
- * serializing/deserializing with "traditional" keys.
+ * encoding/decoding with "traditional" keys.
  */
 
 static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
@@ -85,36 +85,36 @@ static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
  * (TEST_strn2_eq(), for example).
  */
 
-typedef int (serializer)(void **serialized, long *serialized_len,
+typedef int (encoder)(void **encoded, long *encoded_len,
                          void *object, const char *pass, const char *pcipher,
-                         const char *ser_propq);
-typedef int (deserializer)(void **object,
-                           void *serialized, long serialized_len,
+                         const char *encoder_propq);
+typedef int (decoder)(void **object,
+                           void *encoded, long encoded_len,
                            const char *pass);
 typedef int (tester)(const void *data1, size_t data1_len,
                      const void *data2, size_t data2_len);
 typedef int (checker)(const char *type, const void *data, size_t data_len);
 typedef void (dumper)(const char *label, const void *data, size_t data_len);
 
-static int test_serialize_deserialize(const char *type, EVP_PKEY *pkey,
+static int test_encode_decode(const char *type, EVP_PKEY *pkey,
                                       const char *pass, const char *pcipher,
-                                      serializer *serialize_cb,
-                                      deserializer *deserialize_cb,
+                                      encoder *encode_cb,
+                                      decoder *decode_cb,
                                       tester *test_cb,
                                       checker *check_cb, dumper *dump_cb,
-                                      const char *ser_propq, int make_legacy)
+                                      const char *encoder_propq, int make_legacy)
 {
-    void *serialized = NULL;
-    long serialized_len = 0;
+    void *encoded = NULL;
+    long encoded_len = 0;
     EVP_PKEY *pkey2 = NULL;
-    void *serialized2 = NULL;
-    long serialized2_len = 0;
+    void *encoded2 = NULL;
+    long encoded2_len = 0;
     int ok = 0;
 
-    if (!serialize_cb(&serialized, &serialized_len, pkey,
-                      pass, pcipher, ser_propq)
-        || !check_cb(type, serialized, serialized_len)
-        || !deserialize_cb((void **)&pkey2, serialized, serialized_len,
+    if (!encode_cb(&encoded, &encoded_len, pkey,
+                      pass, pcipher, encoder_propq)
+        || !check_cb(type, encoded, encoded_len)
+        || !decode_cb((void **)&pkey2, encoded, encoded_len,
                            pass)
         || !TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
         goto end;
@@ -128,100 +128,100 @@ static int test_serialize_deserialize(const char *type, EVP_PKEY *pkey,
         goto end;
 
     /*
-     * Double check the serialization, but only for unprotected keys,
+     * Double check the encoding, but only for unprotected keys,
      * as protected keys have a random component, which makes the output
      * differ.
      */
     if ((pass == NULL && pcipher == NULL)
-        && (!serialize_cb(&serialized2, &serialized2_len, pkey2,
-                          pass, pcipher, ser_propq)
-            || !test_cb(serialized, serialized_len,
-                        serialized2, serialized2_len)))
+        && (!encode_cb(&encoded2, &encoded2_len, pkey2,
+                          pass, pcipher, encoder_propq)
+            || !test_cb(encoded, encoded_len,
+                        encoded2, encoded2_len)))
         goto end;
 
     ok = 1;
  end:
     if (!ok) {
-        if (serialized != NULL && serialized_len != 0)
-            dump_cb("serialized result", serialized, serialized_len);
-        if (serialized2 != NULL && serialized2_len != 0)
-            dump_cb("re-serialized result", serialized2, serialized2_len);
+        if (encoded != NULL && encoded_len != 0)
+            dump_cb("encoded result", encoded, encoded_len);
+        if (encoded2 != NULL && encoded2_len != 0)
+            dump_cb("re-encoded result", encoded2, encoded2_len);
     }
 
-    OPENSSL_free(serialized);
-    OPENSSL_free(serialized2);
+    OPENSSL_free(encoded);
+    OPENSSL_free(encoded2);
     EVP_PKEY_free(pkey2);
     return ok;
 }
 
-/* Serializing and desserializing methods */
+/* Encoding and desencoding methods */
 
-static int serialize_EVP_PKEY_prov(void **serialized, long *serialized_len,
+static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
                                    void *object,
                                    const char *pass, const char *pcipher,
-                                   const char *ser_propq)
+                                   const char *encoder_propq)
 {
     EVP_PKEY *pkey = object;
-    OSSL_SERIALIZER_CTX *sctx = NULL;
+    OSSL_ENCODER_CTX *ectx = NULL;
     BIO *mem_ser = NULL;
     BUF_MEM *mem_buf = NULL;
     const unsigned char *upass = (const unsigned char *)pass;
     int ok = 0;
 
-    if (!TEST_ptr(sctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, ser_propq))
+    if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, encoder_propq))
         || (pass != NULL
-            && !TEST_true(OSSL_SERIALIZER_CTX_set_passphrase(sctx, upass,
+            && !TEST_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
                                                              strlen(pass))))
         || (pcipher != NULL
-            && !TEST_true(OSSL_SERIALIZER_CTX_set_cipher(sctx, pcipher, NULL)))
+            && !TEST_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
         || !TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
-        || !TEST_true(OSSL_SERIALIZER_to_bio(sctx, mem_ser))
+        || !TEST_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
         || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*serialized = mem_buf->data)
-        || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
+        || !TEST_ptr(*encoded = mem_buf->data)
+        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
-    /* Detach the serialized output */
+    /* Detach the encoded output */
     mem_buf->data = NULL;
     mem_buf->length = 0;
     ok = 1;
  end:
     BIO_free(mem_ser);
-    OSSL_SERIALIZER_CTX_free(sctx);
+    OSSL_ENCODER_CTX_free(ectx);
     return ok;
 }
 
-static int deserialize_EVP_PKEY_prov(void **object,
-                                     void *serialized, long serialized_len,
+static int decode_EVP_PKEY_prov(void **object,
+                                     void *encoded, long encoded_len,
                                      const char *pass)
 {
     EVP_PKEY *pkey = NULL;
-    OSSL_DESERIALIZER_CTX *dctx = NULL;
+    OSSL_DECODER_CTX *dctx = NULL;
     BIO *mem_deser = NULL;
     const unsigned char *upass = (const unsigned char *)pass;
     int ok = 0;
 
-    if (!TEST_ptr(dctx = OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(&pkey, NULL,
+    if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL,
                                                                NULL, NULL))
         || (pass != NULL
-            && !OSSL_DESERIALIZER_CTX_set_passphrase(dctx, upass,
+            && !OSSL_DECODER_CTX_set_passphrase(dctx, upass,
                                                      strlen(pass)))
-        || !TEST_ptr(mem_deser = BIO_new_mem_buf(serialized, serialized_len))
-        || !TEST_true(OSSL_DESERIALIZER_from_bio(dctx, mem_deser)))
+        || !TEST_ptr(mem_deser = BIO_new_mem_buf(encoded, encoded_len))
+        || !TEST_true(OSSL_DECODER_from_bio(dctx, mem_deser)))
         goto end;
     ok = 1;
     *object = pkey;
  end:
     BIO_free(mem_deser);
-    OSSL_DESERIALIZER_CTX_free(dctx);
+    OSSL_DECODER_CTX_free(dctx);
     return ok;
 }
 
-static int serialize_EVP_PKEY_legacy_PEM(void **serialized,
-                                         long *serialized_len,
+static int encode_EVP_PKEY_legacy_PEM(void **encoded,
+                                         long *encoded_len,
                                          void *object,
                                          const char *pass, const char *pcipher,
-                                         ossl_unused const char *ser_propq)
+                                         ossl_unused const char *encoder_propq)
 {
     EVP_PKEY *pkey = object;
     EVP_CIPHER *cipher = NULL;
@@ -242,11 +242,11 @@ static int serialize_EVP_PKEY_legacy_PEM(void **serialized,
                                                            upass, passlen,
                                                            NULL, NULL))
         || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*serialized = mem_buf->data)
-        || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
+        || !TEST_ptr(*encoded = mem_buf->data)
+        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
-    /* Detach the serialized output */
+    /* Detach the encoded output */
     mem_buf->data = NULL;
     mem_buf->length = 0;
     ok = 1;
@@ -257,12 +257,12 @@ static int serialize_EVP_PKEY_legacy_PEM(void **serialized,
 }
 
 #ifndef OPENSSL_NO_DSA
-static int serialize_EVP_PKEY_MSBLOB(void **serialized,
-                                     long *serialized_len,
+static int encode_EVP_PKEY_MSBLOB(void **encoded,
+                                     long *encoded_len,
                                      void *object,
                                      ossl_unused const char *pass,
                                      ossl_unused const char *pcipher,
-                                     ossl_unused const char *ser_propq)
+                                     ossl_unused const char *encoder_propq)
 {
     EVP_PKEY *pkey = object;
     BIO *mem_ser = NULL;
@@ -272,11 +272,11 @@ static int serialize_EVP_PKEY_MSBLOB(void **serialized,
     if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
         || !TEST_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0)
         || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*serialized = mem_buf->data)
-        || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
+        || !TEST_ptr(*encoded = mem_buf->data)
+        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
-    /* Detach the serialized output */
+    /* Detach the encoded output */
     mem_buf->data = NULL;
     mem_buf->length = 0;
     ok = 1;
@@ -285,12 +285,12 @@ static int serialize_EVP_PKEY_MSBLOB(void **serialized,
     return ok;
 }
 
-static int serialize_public_EVP_PKEY_MSBLOB(void **serialized,
-                                            long *serialized_len,
+static int encode_public_EVP_PKEY_MSBLOB(void **encoded,
+                                            long *encoded_len,
                                             void *object,
                                             ossl_unused const char *pass,
                                             ossl_unused const char *pcipher,
-                                            ossl_unused const char *ser_propq)
+                                            ossl_unused const char *encoder_propq)
 {
     EVP_PKEY *pkey = object;
     BIO *mem_ser = NULL;
@@ -300,11 +300,11 @@ static int serialize_public_EVP_PKEY_MSBLOB(void **serialized,
     if (!TEST_ptr(mem_ser = BIO_new(BIO_s_mem()))
         || !TEST_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0)
         || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*serialized = mem_buf->data)
-        || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
+        || !TEST_ptr(*encoded = mem_buf->data)
+        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
-    /* Detach the serialized output */
+    /* Detach the encoded output */
     mem_buf->data = NULL;
     mem_buf->length = 0;
     ok = 1;
@@ -321,11 +321,11 @@ static int pass_pw(char *buf, int size, int rwflag, void *userdata)
     return strlen(userdata);
 }
 
-static int serialize_EVP_PKEY_PVK(void **serialized, long *serialized_len,
+static int encode_EVP_PKEY_PVK(void **encoded, long *encoded_len,
                                   void *object,
                                   const char *pass,
                                   ossl_unused const char *pcipher,
-                                  ossl_unused const char *ser_propq)
+                                  ossl_unused const char *encoder_propq)
 {
     EVP_PKEY *pkey = object;
     BIO *mem_ser = NULL;
@@ -337,11 +337,11 @@ static int serialize_EVP_PKEY_PVK(void **serialized, long *serialized_len,
         || !TEST_int_ge(i2b_PVK_bio(mem_ser, pkey, enc,
                                     pass_pw, (void *)pass), 0)
         || !TEST_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
-        || !TEST_ptr(*serialized = mem_buf->data)
-        || !TEST_long_gt(*serialized_len = mem_buf->length, 0))
+        || !TEST_ptr(*encoded = mem_buf->data)
+        || !TEST_long_gt(*encoded_len = mem_buf->length, 0))
         goto end;
 
-    /* Detach the serialized output */
+    /* Detach the encoded output */
     mem_buf->data = NULL;
     mem_buf->length = 0;
     ok = 1;
@@ -396,12 +396,12 @@ static int check_unprotected_PKCS8_DER(const char *type,
 
 static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_unprotected_PKCS8_DER, dump_der,
-                                      OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
+                                      OSSL_ENCODER_PrivateKey_TO_DER_PQ,
                                       0);
 }
 
@@ -415,12 +415,12 @@ static int check_unprotected_PKCS8_PEM(const char *type,
 
 static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_text,
                                       check_unprotected_PKCS8_PEM, dump_pem,
-                                      OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
+                                      OSSL_ENCODER_PrivateKey_TO_PEM_PQ,
                                       0);
 }
 
@@ -437,9 +437,9 @@ static int check_unprotected_legacy_PEM(const char *type,
 
 static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_legacy_PEM,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_legacy_PEM,
+                                      decode_EVP_PKEY_prov,
                                       test_text,
                                       check_unprotected_legacy_PEM, dump_pem,
                                       NULL, 1);
@@ -458,9 +458,9 @@ static int check_MSBLOB(const char *type, const void *data, size_t data_len)
 
 static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_MSBLOB,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_MSBLOB,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_MSBLOB, dump_der,
                                       NULL, 0);
@@ -478,9 +478,9 @@ static int check_PVK(const char *type, const void *data, size_t data_len)
 
 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_PVK,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_PVK,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_PVK, dump_der,
                                       NULL, 0);
@@ -504,12 +504,12 @@ static int check_protected_PKCS8_DER(const char *type,
 
 static int test_protected_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, pass, pass_cipher,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, pass, pass_cipher,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_protected_PKCS8_DER, dump_der,
-                                      OSSL_SERIALIZER_PrivateKey_TO_DER_PQ,
+                                      OSSL_ENCODER_PrivateKey_TO_DER_PQ,
                                       0);
 }
 
@@ -523,12 +523,12 @@ static int check_protected_PKCS8_PEM(const char *type,
 
 static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, pass, pass_cipher,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, pass, pass_cipher,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_text,
                                       check_protected_PKCS8_PEM, dump_pem,
-                                      OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ,
+                                      OSSL_ENCODER_PrivateKey_TO_PEM_PQ,
                                       0);
 }
 
@@ -546,9 +546,9 @@ static int check_protected_legacy_PEM(const char *type,
 
 static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, pass, pass_cipher,
-                                      serialize_EVP_PKEY_legacy_PEM,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, pass, pass_cipher,
+                                      encode_EVP_PKEY_legacy_PEM,
+                                      decode_EVP_PKEY_prov,
                                       test_text,
                                       check_protected_legacy_PEM, dump_pem,
                                       NULL, 1);
@@ -557,9 +557,9 @@ static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
 static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, pass, NULL,
-                                      serialize_EVP_PKEY_PVK,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, pass, NULL,
+                                      encode_EVP_PKEY_PVK,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_PVK, dump_der,
                                       NULL, 0);
@@ -578,12 +578,12 @@ static int check_public_DER(const char *type, const void *data, size_t data_len)
 
 static int test_public_via_DER(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_public_DER, dump_der,
-                                      OSSL_SERIALIZER_PUBKEY_TO_DER_PQ,
+                                      OSSL_ENCODER_PUBKEY_TO_DER_PQ,
                                       0);
 }
 
@@ -597,12 +597,12 @@ static int check_public_PEM(const char *type, const void *data, size_t data_len)
 
 static int test_public_via_PEM(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_EVP_PKEY_prov,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_EVP_PKEY_prov,
+                                      decode_EVP_PKEY_prov,
                                       test_text,
                                       check_public_PEM, dump_pem,
-                                      OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ,
+                                      OSSL_ENCODER_PUBKEY_TO_PEM_PQ,
                                       0);
 }
 
@@ -620,9 +620,9 @@ static int check_public_MSBLOB(const char *type,
 
 static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
 {
-    return test_serialize_deserialize(type, key, NULL, NULL,
-                                      serialize_public_EVP_PKEY_MSBLOB,
-                                      deserialize_EVP_PKEY_prov,
+    return test_encode_decode(type, key, NULL, NULL,
+                                      encode_public_EVP_PKEY_MSBLOB,
+                                      decode_EVP_PKEY_prov,
                                       test_mem,
                                       check_public_MSBLOB, dump_der,
                                       NULL, 0);
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index 7e063bb77b..3678dc0584 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -10,7 +10,7 @@
 #include <string.h> /* memset */
 #include <openssl/evp.h>
 #include <openssl/pem.h>
-#include <openssl/serializer.h>
+#include <openssl/encoder.h>
 #include <openssl/provider.h>
 #include <openssl/param_build.h>
 #include <openssl/core_names.h>
@@ -152,41 +152,41 @@ static int test_print_key_using_pem(const char *alg, const EVP_PKEY *pk)
     return ret;
 }
 
-static int test_print_key_type_using_serializer(const char *alg, int type,
+static int test_print_key_type_using_encoder(const char *alg, int type,
                                                 const EVP_PKEY *pk)
 {
     const char *pq;
-    OSSL_SERIALIZER_CTX *ctx = NULL;
+    OSSL_ENCODER_CTX *ctx = NULL;
     BIO *membio = BIO_new(BIO_s_mem());
     int ret = 0;
 
     switch (type) {
     case PRIV_TEXT:
-        pq = OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ;
+        pq = OSSL_ENCODER_PrivateKey_TO_TEXT_PQ;
         break;
 
     case PRIV_PEM:
-        pq = OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ;
+        pq = OSSL_ENCODER_PrivateKey_TO_PEM_PQ;
         break;
 
     case PRIV_DER:
-        pq = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ;
+        pq = OSSL_ENCODER_PrivateKey_TO_DER_PQ;
         break;
 
     case PUB_TEXT:
-        pq = OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ;
+        pq = OSSL_ENCODER_PUBKEY_TO_TEXT_PQ;
         break;
 
     case PUB_PEM:
-        pq = OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ;
+        pq = OSSL_ENCODER_PUBKEY_TO_PEM_PQ;
         break;
 
     case PUB_DER:
-        pq = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
+        pq = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
         break;
 
     default:
-        TEST_error("Invalid serialization type");
+        TEST_error("Invalid encoding type");
         goto err;
     }
 
@@ -194,58 +194,58 @@ static int test_print_key_type_using_serializer(const char *alg, int type,
         goto err;
 
     /* Make a context, it's valid for several prints */
-    TEST_note("Setting up a OSSL_SERIALIZER context with passphrase");
-    if (!TEST_ptr(ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pk, pq))
+    TEST_note("Setting up a OSSL_ENCODER context with passphrase");
+    if (!TEST_ptr(ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pk, pq))
         /* Check that this operation is supported */
-        || !TEST_ptr(OSSL_SERIALIZER_CTX_get_serializer(ctx)))
+        || !TEST_ptr(OSSL_ENCODER_CTX_get_encoder(ctx)))
         goto err;
 
     /* Use no cipher.  This should give us an unencrypted PEM */
     TEST_note("Testing with no encryption");
-    if (!TEST_true(OSSL_SERIALIZER_to_bio(ctx, membio))
+    if (!TEST_true(OSSL_ENCODER_to_bio(ctx, membio))
         || !TEST_true(compare_with_file(alg, type, membio)))
         goto err;
 
     if (type == PRIV_PEM) {
         /* Set a passphrase to be used later */
-        if (!TEST_true(OSSL_SERIALIZER_CTX_set_passphrase(ctx,
+        if (!TEST_true(OSSL_ENCODER_CTX_set_passphrase(ctx,
                                                           (unsigned char *)"pass",
                                                           4)))
             goto err;
 
         /* Use a valid cipher name */
         TEST_note("Displaying PEM encrypted with AES-256-CBC");
-        if (!TEST_true(OSSL_SERIALIZER_CTX_set_cipher(ctx, "AES-256-CBC", NULL))
-            || !TEST_true(OSSL_SERIALIZER_to_bio(ctx, bio_out)))
+        if (!TEST_true(OSSL_ENCODER_CTX_set_cipher(ctx, "AES-256-CBC", NULL))
+            || !TEST_true(OSSL_ENCODER_to_bio(ctx, bio_out)))
             goto err;
 
         /* Use an invalid cipher name, which should generate no output */
         TEST_note("NOT Displaying PEM encrypted with (invalid) FOO");
-        if (!TEST_false(OSSL_SERIALIZER_CTX_set_cipher(ctx, "FOO", NULL))
-            || !TEST_false(OSSL_SERIALIZER_to_bio(ctx, bio_out)))
+        if (!TEST_false(OSSL_ENCODER_CTX_set_cipher(ctx, "FOO", NULL))
+            || !TEST_false(OSSL_ENCODER_to_bio(ctx, bio_out)))
             goto err;
 
         /* Clear the cipher.  This should give us an unencrypted PEM again */
         TEST_note("Testing with encryption cleared (no encryption)");
-        if (!TEST_true(OSSL_SERIALIZER_CTX_set_cipher(ctx, NULL, NULL))
-            || !TEST_true(OSSL_SERIALIZER_to_bio(ctx, membio))
+        if (!TEST_true(OSSL_ENCODER_CTX_set_cipher(ctx, NULL, NULL))
+            || !TEST_true(OSSL_ENCODER_to_bio(ctx, membio))
             || !TEST_true(compare_with_file(alg, type, membio)))
             goto err;
     }
     ret = 1;
 err:
     BIO_free(membio);
-    OSSL_SERIALIZER_CTX_free(ctx);
+    OSSL_ENCODER_CTX_free(ctx);
     return ret;
 }
 
-static int test_print_key_using_serializer(const char *alg, const EVP_PKEY *pk)
+static int test_print_key_using_encoder(const char *alg, const EVP_PKEY *pk)
 {
     int i;
     int ret = 1;
 
     for (i = 0; i < 6; i++)
-        ret = ret && test_print_key_type_using_serializer(alg, i, pk);
+        ret = ret && test_print_key_type_using_encoder(alg, i, pk);
 
     return ret;
 }
@@ -326,7 +326,7 @@ static int test_fromdata_rsa(void)
             goto err;
     }
     ret = test_print_key_using_pem("RSA", pk)
-          && test_print_key_using_serializer("RSA", pk);
+          && test_print_key_using_encoder("RSA", pk);
  err:
     BN_free(bn_from);
     BN_free(bn);
@@ -512,7 +512,7 @@ static int test_fromdata_dh_named_group(void)
         goto err;
 
     ret = test_print_key_using_pem("DH", pk)
-          && test_print_key_using_serializer("DH", pk);
+          && test_print_key_using_encoder("DH", pk);
 err:
     BN_free(p);
     BN_free(q);
@@ -648,7 +648,7 @@ static int test_fromdata_dh_fips186_4(void)
         goto err;
 
     ret = test_print_key_using_pem("DH", pk)
-          && test_print_key_using_serializer("DH", pk);
+          && test_print_key_using_encoder("DH", pk);
 err:
     BN_free(p);
     BN_free(q);
@@ -876,7 +876,7 @@ static int test_fromdata_ecx(int tst)
         goto err;
 
     ret = test_print_key_using_pem(alg, pk)
-          && test_print_key_using_serializer(alg, pk);
+          && test_print_key_using_encoder(alg, pk);
 
 err:
     EVP_PKEY_free(pk);
@@ -977,7 +977,7 @@ static int test_fromdata_ec(void)
         goto err;
 
     ret = test_print_key_using_pem(alg, pk)
-          && test_print_key_using_serializer(alg, pk);
+          && test_print_key_using_encoder(alg, pk);
 err:
     BN_free(bn_priv);
     BN_free(ec_priv_bn);
@@ -1193,7 +1193,7 @@ static int test_fromdata_dsa_fips186_4(void)
         goto err;
 
     ret = test_print_key_using_pem("DSA", pk)
-          && test_print_key_using_serializer("DSA", pk);
+          && test_print_key_using_encoder("DSA", pk);
  err:
     OSSL_PARAM_BLD_free_params(fromdata_params);
     OSSL_PARAM_BLD_free(bld);
diff --git a/test/recipes/04-test_serializer_deserializer.t b/test/recipes/04-test_encoder_decoder.t
similarity index 89%
rename from test/recipes/04-test_serializer_deserializer.t
rename to test/recipes/04-test_encoder_decoder.t
index 905fc3fccc..2041eb1fb9 100644
--- a/test/recipes/04-test_serializer_deserializer.t
+++ b/test/recipes/04-test_encoder_decoder.t
@@ -13,11 +13,11 @@ use OpenSSL::Test::Simple;
 use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir/;
 use Cwd qw(abs_path);
 
-setup("test_serializer_deserializer");
+setup("test_encoder_decoder");
 
 plan tests => 1;
 
 $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("providers"));
 $ENV{OPENSSL_CONF} = abs_path(srctop_file("test", "default-and-legacy.cnf"));
 
-ok(run(test(["serdes_test"])));
+ok(run(test(["endecode_test"])));
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 19a9b4c9d3..2d85c13eef 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4872,28 +4872,28 @@ EVP_PKEY_meth_set_digestsign            ?	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0
 EVP_PKEY_meth_set_digestverify          ?	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0
 EVP_PKEY_meth_get_digestsign            ?	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0
 EVP_PKEY_meth_get_digestverify          ?	3_0_0	EXIST::FUNCTION:DEPRECATEDIN_3_0
-OSSL_SERIALIZER_up_ref                  ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_free                    ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_fetch                   ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_number                  ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_is_a                    ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_provider                ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_do_all_provided         ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_names_do_all            ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_settable_ctx_params     ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_new                 ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_get_serializer      ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_set_params          ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_free                ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_properties              ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_to_bio                  ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_to_fp                   ?	3_0_0	EXIST::FUNCTION:STDIO
-OSSL_SERIALIZER_CTX_new_by_EVP_PKEY     ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_set_cipher          ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_set_passphrase      ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_set_passphrase_cb   ?	3_0_0	EXIST::FUNCTION:
-OSSL_SERIALIZER_CTX_set_passphrase_ui   ?	3_0_0	EXIST::FUNCTION:
-ERR_load_OSSL_SERIALIZER_strings        ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_up_ref                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_free                       ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_fetch                      ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_number                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_is_a                       ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_provider                   ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_do_all_provided            ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_names_do_all               ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_settable_ctx_params        ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_new                    ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_get_encoder            ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_set_params             ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_free                   ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_properties                 ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_to_bio                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_to_fp                      ?	3_0_0	EXIST::FUNCTION:STDIO
+OSSL_ENCODER_CTX_new_by_EVP_PKEY        ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_set_cipher             ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_set_passphrase         ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_set_passphrase_cb      ?	3_0_0	EXIST::FUNCTION:
+OSSL_ENCODER_CTX_set_passphrase_ui      ?	3_0_0	EXIST::FUNCTION:
+ERR_load_OSSL_ENCODER_strings           ?	3_0_0	EXIST::FUNCTION:
 PEM_read_X509_PUBKEY                    ?	3_0_0	EXIST::FUNCTION:STDIO
 PEM_write_X509_PUBKEY                   ?	3_0_0	EXIST::FUNCTION:STDIO
 PEM_read_bio_X509_PUBKEY                ?	3_0_0	EXIST::FUNCTION:
@@ -5155,35 +5155,35 @@ X509_STORE_load_store_with_libctx       ?	3_0_0	EXIST::FUNCTION:
 X509_STORE_load_locations_with_libctx   ?	3_0_0	EXIST::FUNCTION:
 X509_STORE_set_default_paths_with_libctx ?	3_0_0	EXIST::FUNCTION:
 OSSL_STORE_open_with_libctx             ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_fetch                 ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_up_ref                ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_free                  ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_provider              ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_properties            ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_number                ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_is_a                  ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_do_all_provided       ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_names_do_all          ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_settable_ctx_params   ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_new               ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_params        ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_free              ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_passphrase    ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_pem_password_cb ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_passphrase_ui ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_from_bio              ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_from_fp               ?	3_0_0	EXIST::FUNCTION:STDIO
-OSSL_DESERIALIZER_CTX_add_deserializer  ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_add_extra         ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_num_deserializers ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_input_type    ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_export                ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_INSTANCE_deserializer ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_INSTANCE_deserializer_ctx ?	3_0_0	EXIST::FUNCTION:
-ERR_load_OSSL_DESERIALIZER_strings      ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_gettable_params       ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_get_params            ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY   ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_fetch                      ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_up_ref                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_free                       ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_provider                   ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_properties                 ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_number                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_is_a                       ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_do_all_provided            ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_names_do_all               ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_settable_ctx_params        ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_new                    ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_params             ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_free                   ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_passphrase         ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_pem_password_cb    ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_passphrase_ui      ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_from_bio                   ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_from_fp                    ?	3_0_0	EXIST::FUNCTION:STDIO
+OSSL_DECODER_CTX_add_decoder            ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_add_extra              ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_num_decoders           ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_input_type         ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_export                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_INSTANCE_decoder           ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_INSTANCE_decoder_ctx       ?	3_0_0	EXIST::FUNCTION:
+ERR_load_OSSL_DECODER_strings           ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_gettable_params            ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_get_params                 ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_new_by_EVP_PKEY        ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_set1_X25519                    ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_get0_X25519                    ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_get1_X25519                    ?	3_0_0	EXIST::FUNCTION:EC
@@ -5196,12 +5196,12 @@ EVP_PKEY_get1_ED25519                   ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_set1_ED448                     ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_get0_ED448                     ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_get1_ED448                     ?	3_0_0	EXIST::FUNCTION:EC
-OSSL_DESERIALIZER_CTX_set_construct     ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_construct_data ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_set_cleanup       ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_get_construct     ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_get_construct_data ?	3_0_0	EXIST::FUNCTION:
-OSSL_DESERIALIZER_CTX_get_cleanup       ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_construct          ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_construct_data     ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_set_cleanup            ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_get_construct          ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_get_construct_data     ?	3_0_0	EXIST::FUNCTION:
+OSSL_DECODER_CTX_get_cleanup            ?	3_0_0	EXIST::FUNCTION:
 RAND_get0_primary                       ?	3_0_0	EXIST::FUNCTION:
 RAND_get0_public                        ?	3_0_0	EXIST::FUNCTION:
 RAND_get0_private                       ?	3_0_0	EXIST::FUNCTION:
diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt
index 97208d364e..54ff9cc1b7 100644
--- a/util/missingcrypto.txt
+++ b/util/missingcrypto.txt
@@ -633,8 +633,8 @@ ERR_load_HTTP_strings(3)
 ERR_load_KDF_strings(3)
 ERR_load_OBJ_strings(3)
 ERR_load_OCSP_strings(3)
-ERR_load_OSSL_SERIALIZER_strings(3)
-ERR_load_OSSL_DESERIALIZER_strings(3)
+ERR_load_OSSL_ENCODER_strings(3)
+ERR_load_OSSL_DECODER_strings(3)
 ERR_load_OSSL_STORE_strings(3)
 ERR_load_PEM_strings(3)
 ERR_load_PKCS12_strings(3)
@@ -910,12 +910,12 @@ OPENSSL_utf82uni(3)
 OSSL_CRMF_CERTID_dup(3)
 OSSL_PARAM_modified(3)
 OSSL_PARAM_set_all_unmodified(3)
-OSSL_SERIALIZER-DH(7)
-OSSL_SERIALIZER-DSA(7)
-OSSL_SERIALIZER-EC(7)
-OSSL_SERIALIZER-RSA(7)
-OSSL_SERIALIZER-X25519(7)
-OSSL_SERIALIZER-X448(7)
+OSSL_ENCODER-DH(7)
+OSSL_ENCODER-DSA(7)
+OSSL_ENCODER-EC(7)
+OSSL_ENCODER-RSA(7)
+OSSL_ENCODER-X25519(7)
+OSSL_ENCODER-X448(7)
 OSSL_STORE_do_all_loaders(3)
 OSSL_STORE_vctrl(3)
 OTHERNAME_cmp(3)
diff --git a/util/other.syms b/util/other.syms
index bfe320396b..97f71906da 100644
--- a/util/other.syms
+++ b/util/other.syms
@@ -41,17 +41,17 @@ GEN_SESSION_CB                          datatype
 OPENSSL_Applink                         external
 OPENSSL_CTX                             datatype
 NAMING_AUTHORITY                        datatype
-OSSL_DESERIALIZER                       datatype
-OSSL_DESERIALIZER_CTX                   datatype
-OSSL_DESERIALIZER_CONSTRUCT             datatype
-OSSL_DESERIALIZER_CLEANUP               datatype
-OSSL_DESERIALIZER_INSTANCE              datatype
-OSSL_DESERIALIZER_CTX                   datatype
+OSSL_DECODER                            datatype
+OSSL_DECODER_CTX                        datatype
+OSSL_DECODER_CONSTRUCT                  datatype
+OSSL_DECODER_CLEANUP                    datatype
+OSSL_DECODER_INSTANCE                   datatype
+OSSL_DECODER_CTX                        datatype
 OSSL_HTTP_bio_cb_t                      datatype
 OSSL_PARAM                              datatype
 OSSL_PROVIDER                           datatype
-OSSL_SERIALIZER                         datatype
-OSSL_SERIALIZER_CTX                     datatype
+OSSL_ENCODER                            datatype
+OSSL_ENCODER_CTX                        datatype
 OSSL_STORE_CTX                          datatype
 OSSL_STORE_INFO                         datatype
 OSSL_STORE_LOADER                       datatype
@@ -266,7 +266,7 @@ EVP_PKEY_CTX_set1_scrypt_salt           define
 EVP_PKEY_CTX_set1_tls1_prf_secret       define
 EVP_PKEY_CTX_set_dh_paramgen_generator  define
 EVP_PKEY_CTX_set_dh_paramgen_prime_len  define
-EVP_PKEY_CTX_set_dh_paramgen_subprime_len     define
+EVP_PKEY_CTX_set_dh_paramgen_subprime_len define
 EVP_PKEY_CTX_set_dh_paramgen_type       define
 EVP_PKEY_CTX_set_dh_kdf_md              define
 EVP_PKEY_CTX_set_dh_kdf_outlen          define
@@ -412,15 +412,15 @@ OSSL_PARAM_utf8_string                  define
 OSSL_PARAM_get_TYPE                     generic
 OSSL_PARAM_END                          define
 OSSL_PARAM_set_TYPE                     generic
-OSSL_SERIALIZER_PUBKEY_TO_DER_PQ        define
-OSSL_SERIALIZER_PrivateKey_TO_DER_PQ    define
-OSSL_SERIALIZER_Parameters_TO_DER_PQ    define
-OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ        define
-OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ    define
-OSSL_SERIALIZER_Parameters_TO_PEM_PQ    define
-OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ       define
-OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ   define
-OSSL_SERIALIZER_Parameters_TO_TEXT_PQ   define
+OSSL_ENCODER_PUBKEY_TO_DER_PQ           define
+OSSL_ENCODER_PrivateKey_TO_DER_PQ       define
+OSSL_ENCODER_Parameters_TO_DER_PQ       define
+OSSL_ENCODER_PUBKEY_TO_PEM_PQ           define
+OSSL_ENCODER_PrivateKey_TO_PEM_PQ       define
+OSSL_ENCODER_Parameters_TO_PEM_PQ       define
+OSSL_ENCODER_PUBKEY_TO_TEXT_PQ          define
+OSSL_ENCODER_PrivateKey_TO_TEXT_PQ      define
+OSSL_ENCODER_Parameters_TO_TEXT_PQ      define
 PEM_FLAG_EAY_COMPATIBLE                 define
 PEM_FLAG_ONLY_B64                       define
 PEM_FLAG_SECURE                         define


More information about the openssl-commits mailing list