[openssl] master update

Richard Levitte levitte at openssl.org
Wed Jun 9 15:02:02 UTC 2021


The branch master has been updated
       via  ef2194c4ade7b765ccf9a6e8f97d88b0fa6b223d (commit)
       via  8ea5a6b523bf363751e52a1fddc93f5f9b11e803 (commit)
       via  6a2b8ff392a304bbb106528653397b864acc53fa (commit)
      from  320fc032b98cc452c5dc96600b16da40b155123b (commit)


- Log -----------------------------------------------------------------
commit ef2194c4ade7b765ccf9a6e8f97d88b0fa6b223d
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu May 27 12:51:04 2021 +0200

    DECODER & ENCODER: Add better tracing
    
    Now that we have functions to get the name and properties of the
    diverse implementations, we can as well display them for clarity.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15498)

commit 8ea5a6b523bf363751e52a1fddc93f5f9b11e803
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu May 27 12:44:19 2021 +0200

    DECODER: Adapt addition of extra decoder implementations
    
    The new PKCS#8 decoder implementation decodes from DER to DER.
    OSSL_DECODER_CTX_add_extra() wasn't suited for this case; we had to
    modify it to walk through all existing decoder implementations, and
    filter out those that aren't suitable.
    This also turns out to fix the possibility to have more than one extra
    decoder implementation that produces the same type of encoding, for
    example several different wrapper formats that all decoder into DER.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15498)

commit 6a2b8ff392a304bbb106528653397b864acc53fa
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu May 27 12:34:03 2021 +0200

    Decoding PKCS#8: separate decoding of encrypted and unencrypted PKCS#8
    
    This has us switch from the 'structure' "pkcs8" to "PrivateKeyInfo",
    which is sensible considering we already have "SubjectPublicKeyInfo".
    We also add "EncryptedPrivateKeyInfo", and use it for a special decoder
    that detects and decrypts an EncryptedPrivateKeyInfo structured DER
    blob into a PrivateKeyInfo structured DER blob and passes that on to
    the next decoder implementation.
    
    The result of this change is that PKCS#8 decryption should only happen
    once per decoding instead of once for every expected key type.
    Furthermore, this new decoder implementation sets the data type to the
    OID of the algorithmIdentifier field, thus reducing how many decoder
    implementations are tentativaly run further down the call chain.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15498)

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

Summary of changes:
 apps/rsa.c                                         |   2 +-
 crypto/asn1/d2i_pr.c                               |   2 +-
 crypto/asn1/i2d_evp.c                              |   2 +-
 crypto/encode_decode/decoder_lib.c                 | 228 ++++++++++++++-------
 crypto/encode_decode/decoder_meth.c                |   7 +-
 crypto/encode_decode/decoder_pkey.c                |  13 ++
 crypto/encode_decode/encoder_lib.c                 |  10 +-
 crypto/encode_decode/encoder_local.h               |   3 +-
 crypto/encode_decode/encoder_meth.c                |   7 +-
 crypto/evp/evp_pkey.c                              |   6 +-
 crypto/pem/pem_local.h                             |   2 +-
 crypto/pem/pem_pk8.c                               |   2 +-
 doc/man3/OSSL_ENCODER_to_bio.pod                   |   4 +-
 doc/man7/openssl-glossary.pod                      |  10 +-
 providers/decoders.inc                             |  31 +--
 providers/encoders.inc                             |  48 ++---
 providers/implementations/encode_decode/build.info |   2 +-
 .../implementations/encode_decode/decode_der2key.c |  89 +++-----
 .../encode_decode/decode_epki2pki.c                | 153 ++++++++++++++
 .../implementations/encode_decode/decode_pem2der.c |   4 +-
 .../implementations/encode_decode/encode_key2any.c | 228 ++++++++++++++-------
 .../implementations/include/prov/implementations.h |  67 +++---
 test/endecode_test.c                               |  10 +-
 test/evp_pkey_provided_test.c                      |   4 +-
 24 files changed, 619 insertions(+), 315 deletions(-)
 create mode 100644 providers/implementations/encode_decode/decode_epki2pki.c

diff --git a/apps/rsa.c b/apps/rsa.c
index c4f65cac10..3e9d320ea3 100644
--- a/apps/rsa.c
+++ b/apps/rsa.c
@@ -322,7 +322,7 @@ int rsa_main(int argc, char **argv)
             if (traditional)
                 output_structure = "pkcs1"; /* "type-specific" would work too */
             else
-                output_structure = "pkcs8";
+                output_structure = "PrivateKeyInfo";
         }
     }
 
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index 3b28460d4b..720b7fd6c0 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -32,7 +32,7 @@ d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
     EVP_PKEY *pkey = NULL, *bak_a = NULL;
     EVP_PKEY **ppkey = &pkey;
     const char *key_name = NULL;
-    const char *input_structures[] = { "type-specific", "pkcs8", NULL };
+    const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL };
     int i, ret;
 
     if (keytype != EVP_PKEY_NONE) {
diff --git a/crypto/asn1/i2d_evp.c b/crypto/asn1/i2d_evp.c
index e1d5b7c7c4..8b36388263 100644
--- a/crypto/asn1/i2d_evp.c
+++ b/crypto/asn1/i2d_evp.c
@@ -97,7 +97,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
     if (evp_pkey_is_provided(a)) {
         static const struct type_and_structure_st output_info[] = {
             { "DER", "type-specific" },
-            { "DER", "pkcs8" },
+            { "DER", "PrivateKeyInfo" },
             { NULL, }
         };
 
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index bf9b17f754..eb90a9eaf5 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -288,11 +288,11 @@ int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx,
     if (ok) {
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) Added decoder instance %p (decoder %p) with:\n",
-                       (void *)ctx, (void *)di, (void *)di->decoder);
-            BIO_printf(trc_out,
-                       "    input type: %s, input structure: %s\n",
-                       di->input_type, di->input_structure);
+                       "(ctx %p) Added decoder instance %p for decoder %p\n"
+                       "    %s with %s\n",
+                       (void *)ctx, (void *)di, (void *)di->decoder,
+                       OSSL_DECODER_get0_name(di->decoder),
+                       OSSL_DECODER_get0_properties(di->decoder));
         } OSSL_TRACE_END(DECODER);
     }
     return ok;
@@ -331,6 +331,105 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder)
     return 0;
 }
 
+struct collect_extra_decoder_data_st {
+    OSSL_DECODER_CTX *ctx;
+    const char *output_type;
+    /*
+     * 0 to check that the decoder's input type is the same as the decoder name
+     * 1 to check that the decoder's input type differs from the decoder name
+     */
+    enum { IS_SAME = 0, IS_DIFFERENT = 1 } type_check;
+    size_t w_prev_start, w_prev_end; /* "previous" decoders */
+    size_t w_new_start, w_new_end;   /* "new" decoders */
+};
+
+static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg)
+{
+    struct collect_extra_decoder_data_st *data = arg;
+    size_t j;
+    const OSSL_PROVIDER *prov = OSSL_DECODER_get0_provider(decoder);
+    void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
+
+    if (OSSL_DECODER_is_a(decoder, data->output_type)) {
+        void *decoderctx = NULL;
+        OSSL_DECODER_INSTANCE *di = NULL;
+
+        OSSL_TRACE_BEGIN(DECODER) {
+            BIO_printf(trc_out,
+                       "(ctx %p) [%d] Checking out decoder %p:\n"
+                       "    %s with %s\n",
+                       (void *)data->ctx, data->type_check, (void *)decoder,
+                       OSSL_DECODER_get0_name(decoder),
+                       OSSL_DECODER_get0_properties(decoder));
+        } OSSL_TRACE_END(DECODER);
+
+        /*
+         * Check that we don't already have this decoder in our stack,
+         * starting with the previous windows but also looking at what
+         * we have added in the current window.
+         */
+        for (j = data->w_prev_start; j < data->w_new_end; j++) {
+            OSSL_DECODER_INSTANCE *check_inst =
+                sk_OSSL_DECODER_INSTANCE_value(data->ctx->decoder_insts, j);
+
+            if (decoder->base.algodef == check_inst->decoder->base.algodef) {
+                /* We found it, so don't do anything more */
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "    REJECTED: already exists in the chain\n");
+                } OSSL_TRACE_END(DECODER);
+                return;
+            }
+        }
+
+        if ((decoderctx = decoder->newctx(provctx)) == NULL)
+            return;
+
+        if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) {
+            decoder->freectx(decoderctx);
+            return;
+        }
+
+        switch (data->type_check) {
+        case IS_SAME:
+            /* If it differs, this is not a decoder to add for now. */
+            if (!OSSL_DECODER_is_a(decoder,
+                                   OSSL_DECODER_INSTANCE_get_input_type(di))) {
+                ossl_decoder_instance_free(di);
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "    REJECTED: input type doesn't match output type\n");
+                } OSSL_TRACE_END(DECODER);
+                return;
+            }
+            break;
+        case IS_DIFFERENT:
+            /* If it's the same, this is not a decoder to add for now. */
+            if (OSSL_DECODER_is_a(decoder,
+                                  OSSL_DECODER_INSTANCE_get_input_type(di))) {
+                ossl_decoder_instance_free(di);
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "    REJECTED: input type matches output type\n");
+                } OSSL_TRACE_END(DECODER);
+                return;
+            }
+            break;
+        }
+
+        /*
+         * 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_inst(data->ctx, di)) {
+            ossl_decoder_instance_free(di);
+            return;
+        }
+
+        data->w_new_end++;
+    }
+}
+
 int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
                                OSSL_LIB_CTX *libctx, const char *propq)
 {
@@ -357,10 +456,9 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
      * +----------------+
      *                    <--- 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 */
+    struct collect_extra_decoder_data_st data;
     size_t depth = 0; /* Counts the number of iterations */
+    size_t count; /* Calculates how many were added in each iteration */
 
     if (!ossl_assert(ctx != NULL)) {
         ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
@@ -374,71 +472,48 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
     if (ctx->decoder_insts == NULL)
         return 1;
 
-    w_prev_start = 0;
-    w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts);
+    OSSL_TRACE_BEGIN(DECODER) {
+        BIO_printf(trc_out, "(ctx %p) Looking for extra decoders\n",
+                   (void *)ctx);
+    } OSSL_TRACE_END(DECODER);
+
+    memset(&data, 0, sizeof(data));
+    data.ctx = ctx;
+    data.w_prev_start = 0;
+    data.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 *input_type =
-                OSSL_DECODER_INSTANCE_get_input_type(decoder_inst);
-            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, input_type) == 0)
-                continue;
-
-            ERR_set_mark();
-            decoder = OSSL_DECODER_fetch(libctx, input_type, 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;
-                    }
-                }
-            }
+        data.w_new_start = data.w_new_end = data.w_prev_end;
+
+        /*
+         * Two iterations:
+         * 0.  All decoders that have the same name as their input type.
+         *     This allows for decoders that unwrap some data in a specific
+         *     encoding, and pass the result on with the same encoding.
+         * 1.  All decoders that a different name than their input type.
+         */
+        for (data.type_check = IS_SAME;
+             data.type_check <= IS_DIFFERENT;
+             data.type_check++) {
+            for (i = data.w_prev_start; i < data.w_prev_end; i++) {
+                OSSL_DECODER_INSTANCE *decoder_inst =
+                    sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
+
+                data.output_type
+                    = OSSL_DECODER_INSTANCE_get_input_type(decoder_inst);
 
-            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-- */
+                OSSL_DECODER_do_all_provided(libctx,
+                                             collect_extra_decoder, &data);
+            }
         }
         /* How many were added in this iteration */
-        count = w_new_end - w_new_start;
+        count = data.w_new_end - data.w_new_start;
 
         /* Slide the "previous decoder" windows */
-        w_prev_start = w_new_start;
-        w_prev_end = w_new_end;
+        data.w_prev_start = data.w_new_start;
+        data.w_prev_end = data.w_new_end;
 
         depth++;
     } while (count != 0 && depth <= 10);
@@ -619,7 +694,21 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
 
         data->flag_construct_called = 0;
         if (ctx->construct != NULL) {
-            int rv = ctx->construct(decoder_inst, params, ctx->construct_data);
+            int rv;
+
+            OSSL_TRACE_BEGIN(DECODER) {
+                BIO_printf(trc_out,
+                           "(ctx %p) %s Running constructor\n",
+                           (void *)new_data.ctx, LEVEL);
+            } OSSL_TRACE_END(DECODER);
+
+            rv = ctx->construct(decoder_inst, params, ctx->construct_data);
+
+            OSSL_TRACE_BEGIN(DECODER) {
+                BIO_printf(trc_out,
+                           "(ctx %p) %s Running constructor => %d\n",
+                           (void *)new_data.ctx, LEVEL, rv);
+            } OSSL_TRACE_END(DECODER);
 
             data->flag_construct_called = 1;
             ok = (rv > 0);
@@ -715,11 +804,12 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
 
         OSSL_TRACE_BEGIN(DECODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) %s [%u] Considering decoder instance %p, which has:\n"
-                       "    input type: %s, input structure: %s, decoder: %p\n",
+                       "(ctx %p) %s [%u] Considering decoder instance %p (decoder %p):\n"
+                       "    %s with %s\n",
                        (void *)new_data.ctx, LEVEL, (unsigned int)i,
-                       (void *)new_decoder_inst, new_input_type,
-                       new_input_structure, (void *)new_decoder);
+                       (void *)new_decoder_inst, (void *)new_decoder,
+                       OSSL_DECODER_get0_name(new_decoder),
+                       OSSL_DECODER_get0_properties(new_decoder));
         } OSSL_TRACE_END(DECODER);
 
         /*
diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
index e203c5fe66..2177e539ef 100644
--- a/crypto/encode_decode/decoder_meth.c
+++ b/crypto/encode_decode/decoder_meth.c
@@ -176,8 +176,7 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
         OSSL_DECODER_free(decoder);
         return NULL;
     }
-    decoder->base.propdef = algodef->property_definition;
-    decoder->base.description = algodef->algorithm_description;
+    decoder->base.algodef = algodef;
     decoder->base.parsed_propdef
         = ossl_parse_property(libctx, algodef->property_definition);
 
@@ -422,7 +421,7 @@ const char *OSSL_DECODER_get0_properties(const OSSL_DECODER *decoder)
         return 0;
     }
 
-    return decoder->base.propdef;
+    return decoder->base.algodef->property_definition;
 }
 
 const OSSL_PROPERTY_LIST *
@@ -453,7 +452,7 @@ const char *OSSL_DECODER_get0_name(const OSSL_DECODER *decoder)
 
 const char *OSSL_DECODER_get0_description(const OSSL_DECODER *decoder)
 {
-    return decoder->base.description;
+    return decoder->base.algodef->algorithm_description;
 }
 
 int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name)
diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c
index c9ccb2200a..cdd9841ea9 100644
--- a/crypto/encode_decode/decoder_pkey.c
+++ b/crypto/encode_decode/decoder_pkey.c
@@ -265,7 +265,20 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg)
                 return;
             }
 
+            OSSL_TRACE_BEGIN(DECODER) {
+                BIO_printf(trc_out,
+                           "(ctx %p) Checking out decoder %p:\n"
+                           "    %s with %s\n",
+                           (void *)data->ctx, (void *)decoder,
+                           OSSL_DECODER_get0_name(decoder),
+                           OSSL_DECODER_get0_properties(decoder));
+            } OSSL_TRACE_END(DECODER);
+
             if (!decoder_check_input_structure(data->ctx, di)) {
+                OSSL_TRACE_BEGIN(DECODER) {
+                    BIO_printf(trc_out,
+                               "    REJECTED: not the desired input structure\n");
+                } OSSL_TRACE_END(DECODER);
                 ossl_decoder_instance_free(di);
                 /* Not a fatal error. Just return */
                 return;
diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c
index cb47e8bc71..6c20fbb3d1 100644
--- a/crypto/encode_decode/encoder_lib.c
+++ b/crypto/encode_decode/encoder_lib.c
@@ -265,11 +265,11 @@ static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx,
     if (ok) {
         OSSL_TRACE_BEGIN(ENCODER) {
             BIO_printf(trc_out,
-                       "(ctx %p) Added encoder instance %p (encoder %p) with:\n",
-                       (void *)ctx, (void *)ei, (void *)ei->encoder);
-            BIO_printf(trc_out,
-                       "    output type: %s, output structure: %s\n",
-                       ei->output_type, ei->output_structure);
+                       "(ctx %p) Added encoder instance %p (encoder %p):\n"
+                       "    %s with %s\n",
+                       (void *)ctx, (void *)ei, (void *)ei->encoder,
+                       OSSL_ENCODER_get0_name(ei->encoder),
+                       OSSL_ENCODER_get0_properties(ei->encoder));
         } OSSL_TRACE_END(ENCODER);
     }
     return ok;
diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h
index a0b10dcd5e..c1885ffc77 100644
--- a/crypto/encode_decode/encoder_local.h
+++ b/crypto/encode_decode/encoder_local.h
@@ -21,8 +21,7 @@ struct ossl_endecode_base_st {
     OSSL_PROVIDER *prov;
     int id;
     char *name;
-    const char *propdef;
-    const char *description;
+    const OSSL_ALGORITHM *algodef;
     OSSL_PROPERTY_LIST *parsed_propdef;
 
     CRYPTO_REF_COUNT refcnt;
diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c
index d50f1dcd0b..5e57848054 100644
--- a/crypto/encode_decode/encoder_meth.c
+++ b/crypto/encode_decode/encoder_meth.c
@@ -176,8 +176,7 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
         OSSL_ENCODER_free(encoder);
         return NULL;
     }
-    encoder->base.propdef = algodef->property_definition;
-    encoder->base.description = algodef->algorithm_description;
+    encoder->base.algodef = algodef;
     encoder->base.parsed_propdef
         = ossl_parse_property(libctx, algodef->property_definition);
 
@@ -432,7 +431,7 @@ const char *OSSL_ENCODER_get0_properties(const OSSL_ENCODER *encoder)
         return 0;
     }
 
-    return encoder->base.propdef;
+    return encoder->base.algodef->property_definition;
 }
 
 const OSSL_PROPERTY_LIST *
@@ -463,7 +462,7 @@ const char *OSSL_ENCODER_get0_name(const OSSL_ENCODER *encoder)
 
 const char *OSSL_ENCODER_get0_description(const OSSL_ENCODER *encoder)
 {
-    return encoder->base.description;
+    return encoder->base.algodef->algorithm_description;
 }
 
 int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name)
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 420b69399a..683f4bec54 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -79,8 +79,8 @@ EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx,
 
     p8_data = encoded_data;
     len = encoded_len;
-    dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "pkcs8", EVP_PKEY_NONE,
-                                         0, libctx, propq);
+    dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", "PrivateKeyInfo",
+                                         EVP_PKEY_NONE, 0, libctx, propq);
     if (dctx == NULL
         || !OSSL_DECODER_from_data(dctx, &p8_data, &len))
         /* try legacy */
@@ -115,7 +115,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey)
         const unsigned char *pp;
 
         if ((ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
-                                                 "DER", "pkcs8",
+                                                 "DER", "PrivateKeyInfo",
                                                  NULL)) == NULL
             || !OSSL_ENCODER_to_data(ctx, &der, &derlen))
             goto error;
diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h
index a84ca80be1..5cc1c76fdb 100644
--- a/crypto/pem/pem_local.h
+++ b/crypto/pem/pem_local.h
@@ -31,7 +31,7 @@
  * Properties, named according to the ASN.1 names used throughout libcrypto.
  */
 # define PEM_STRUCTURE_PUBKEY "SubjectPublicKeyInfo"
-# define PEM_STRUCTURE_PrivateKey "pkcs8"
+# define PEM_STRUCTURE_PrivateKey "PrivateKeyInfo"
 # define PEM_STRUCTURE_Parameters "type-specific"
 
 # define PEM_STRUCTURE_RSAPrivateKey "type-specific"
diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c
index ab86448db9..4742f02fef 100644
--- a/crypto/pem/pem_pk8.c
+++ b/crypto/pem/pem_pk8.c
@@ -74,7 +74,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
     const char *outtype = isder ? "DER" : "PEM";
     OSSL_ENCODER_CTX *ctx =
         OSSL_ENCODER_CTX_new_for_pkey(x, OSSL_KEYMGMT_SELECT_ALL,
-                                      outtype, "pkcs8", propq);
+                                      outtype, "PrivateKeyInfo", propq);
 
     if (ctx == NULL)
         return 0;
diff --git a/doc/man3/OSSL_ENCODER_to_bio.pod b/doc/man3/OSSL_ENCODER_to_bio.pod
index 315f0a5122..365c74ad05 100644
--- a/doc/man3/OSSL_ENCODER_to_bio.pod
+++ b/doc/man3/OSSL_ENCODER_to_bio.pod
@@ -61,7 +61,7 @@ To encode a pkey as PKCS#8 with PEM format into a bio:
 
  OSSL_ENCODER_CTX *ectx;
  const char *format = "PEM";
- const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const char *structure = "PrivateKeyInfo"; /* PKCS#8 structure */
  const unsigned char *pass = "my password";
 
  ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
@@ -86,7 +86,7 @@ AES-256-CBC into a buffer:
 
  OSSL_ENCODER_CTX *ectx;
  const char *format = "DER";
- const char *structure = "pkcs8"; /* PKCS#8 structure */
+ const char *structure = "PrivateKeyInfo"; /* PKCS#8 structure */
  const unsigned char *pass = "my password";
  unsigned char *data = NULL;
  size_t datalen;
diff --git a/doc/man7/openssl-glossary.pod b/doc/man7/openssl-glossary.pod
index fad11e5695..16ff2f3176 100644
--- a/doc/man7/openssl-glossary.pod
+++ b/doc/man7/openssl-glossary.pod
@@ -158,11 +158,13 @@ This is defined in IETF RFC 1421:
 
 L<https://tools.ietf.org/html/rfc1421>
 
-=item PKCS#8 (also known as "pkcs8" in some parts of OpenSSL)
+=item PKCS#8
 
-PKCS#8 is a specification of an ASN.1 structure that OpenSSL uses for
-storing or transmitting any private key in a key type agnostic manner, and
-has both an unencrypted and an encrypted form.
+PKCS#8 is a specification of ASN.1 structures that OpenSSL uses for storing
+or transmitting any private key in a key type agnostic manner.
+There are two structures worth noting for OpenSSL use, one that contains the
+key data in unencrypted form (known as "PrivateKeyInfo") and an encrypted
+wrapper structure (known as "EncryptedPrivateKeyInfo").
 
 This is specified in RFC 5208:
 
diff --git a/providers/decoders.inc b/providers/decoders.inc
index a92abe03e2..02b2b32c3f 100644
--- a/providers/decoders.inc
+++ b/providers/decoders.inc
@@ -15,7 +15,8 @@
 #define DECODER_STRUCTURE_type_specific_params          "type-specific"
 #define DECODER_STRUCTURE_type_specific                 "type-specific"
 #define DECODER_STRUCTURE_type_specific_no_pub          "type-specific"
-#define DECODER_STRUCTURE_PKCS8                         "pkcs8"
+#define DECODER_STRUCTURE_EncryptedPrivateKeyInfo       "EncryptedPrivateKeyInfo"
+#define DECODER_STRUCTURE_PrivateKeyInfo                "PrivateKeyInfo"
 #define DECODER_STRUCTURE_SubjectPublicKeyInfo          "SubjectPublicKeyInfo"
 #define DECODER_STRUCTURE_DH                            "dh"
 #define DECODER_STRUCTURE_DHX                           "dhx"
@@ -35,17 +36,17 @@
       (ossl_##_structure##_##_input##_to_##_output##_decoder_functions) }
 
 #ifndef OPENSSL_NO_DH
-DECODER_w_structure("DH", der, PKCS8, dh, yes),
+DECODER_w_structure("DH", der, PrivateKeyInfo, dh, yes),
 DECODER_w_structure("DH", der, SubjectPublicKeyInfo, dh, yes),
 DECODER_w_structure("DH", der, type_specific_params, dh, yes),
 DECODER_w_structure("DH", der, DH, dh, yes),
-DECODER_w_structure("DHX", der, PKCS8, dhx, yes),
+DECODER_w_structure("DHX", der, PrivateKeyInfo, dhx, yes),
 DECODER_w_structure("DHX", der, SubjectPublicKeyInfo, dhx, yes),
 DECODER_w_structure("DHX", der, type_specific_params, dhx, yes),
 DECODER_w_structure("DHX", der, DHX, dhx, yes),
 #endif
 #ifndef OPENSSL_NO_DSA
-DECODER_w_structure("DSA", der, PKCS8, dsa, yes),
+DECODER_w_structure("DSA", der, PrivateKeyInfo, dsa, yes),
 DECODER_w_structure("DSA", der, SubjectPublicKeyInfo, dsa, yes),
 DECODER_w_structure("DSA", der, type_specific, dsa, yes),
 DECODER_w_structure("DSA", der, DSA, dsa, yes),
@@ -53,30 +54,36 @@ DECODER("DSA", msblob, dsa, yes),
 DECODER("DSA", pvk, dsa, yes),
 #endif
 #ifndef OPENSSL_NO_EC
-DECODER_w_structure("EC", der, PKCS8, ec, yes),
+DECODER_w_structure("EC", der, PrivateKeyInfo, ec, yes),
 DECODER_w_structure("EC", der, SubjectPublicKeyInfo, ec, yes),
 DECODER_w_structure("EC", der, type_specific_no_pub, ec, yes),
 DECODER_w_structure("EC", der, EC, ec, yes),
-DECODER_w_structure("ED25519", der, PKCS8, ed25519, yes),
+DECODER_w_structure("ED25519", der, PrivateKeyInfo, ed25519, yes),
 DECODER_w_structure("ED25519", der, SubjectPublicKeyInfo, ed25519, yes),
-DECODER_w_structure("ED448", der, PKCS8, ed448, yes),
+DECODER_w_structure("ED448", der, PrivateKeyInfo, ed448, yes),
 DECODER_w_structure("ED448", der, SubjectPublicKeyInfo, ed448, yes),
-DECODER_w_structure("X25519", der, PKCS8, x25519, yes),
+DECODER_w_structure("X25519", der, PrivateKeyInfo, x25519, yes),
 DECODER_w_structure("X25519", der, SubjectPublicKeyInfo, x25519, yes),
-DECODER_w_structure("X448", der, PKCS8, x448, yes),
+DECODER_w_structure("X448", der, PrivateKeyInfo, x448, yes),
 DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes),
 # ifndef OPENSSL_NO_SM2
-DECODER_w_structure("SM2", der, PKCS8, sm2, yes),
+DECODER_w_structure("SM2", der, PrivateKeyInfo, sm2, yes),
 DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, yes),
 # endif
 #endif
-DECODER_w_structure("RSA", der, PKCS8, rsa, yes),
+DECODER_w_structure("RSA", der, PrivateKeyInfo, rsa, yes),
 DECODER_w_structure("RSA", der, SubjectPublicKeyInfo, rsa, yes),
 DECODER_w_structure("RSA", der, type_specific_keypair, rsa, yes),
 DECODER_w_structure("RSA", der, RSA, rsa, yes),
-DECODER_w_structure("RSA-PSS", der, PKCS8, rsapss, yes),
+DECODER_w_structure("RSA-PSS", der, PrivateKeyInfo, rsapss, yes),
 DECODER_w_structure("RSA-PSS", der, SubjectPublicKeyInfo, rsapss, yes),
 DECODER("RSA", msblob, rsa, yes),
 DECODER("RSA", pvk, rsa, yes),
 
 DECODER("DER", pem, der, yes),
+/*
+ * A decoder that recognises PKCS#8 EncryptedPrivateKeyInfo structure
+ * and decrypts it, passing on the unencrypted PrivateKeyInfo in DER
+ * form to the next decoder.
+ */
+DECODER_w_structure("DER", der, EncryptedPrivateKeyInfo, der, yes),
diff --git a/providers/encoders.inc b/providers/encoders.inc
index 71f4f13848..a1034f45de 100644
--- a/providers/encoders.inc
+++ b/providers/encoders.inc
@@ -15,7 +15,7 @@
 #define ENCODER_STRUCTURE_type_specific_params          "type-specific"
 #define ENCODER_STRUCTURE_type_specific                 "type-specific"
 #define ENCODER_STRUCTURE_type_specific_no_pub          "type-specific"
-#define ENCODER_STRUCTURE_PKCS8                         "pkcs8"
+#define ENCODER_STRUCTURE_PrivateKeyInfo                "PrivateKeyInfo"
 #define ENCODER_STRUCTURE_SubjectPublicKeyInfo          "SubjectPublicKeyInfo"
 #define ENCODER_STRUCTURE_DH                            "dh"
 #define ENCODER_STRUCTURE_DHX                           "dhx"
@@ -127,70 +127,70 @@ ENCODER("DSA", dsa, yes, pvk),
 #endif
 
 /*
- * Entries for PKCS#8 and SubjectPublicKeyInfo.
+ * Entries for PKCS#8 (PrivateKeyInfo) and SubjectPublicKeyInfo.
  * The "der" ones are added convenience for any user that wants to use
  * OSSL_ENCODER directly.
  * The "pem" ones also support PEM_write_bio_PrivateKey() and
  * PEM_write_bio_PUBKEY().
  */
-ENCODER_w_structure("RSA", rsa, yes, der, PKCS8),
-ENCODER_w_structure("RSA", rsa, yes, pem, PKCS8),
+ENCODER_w_structure("RSA", rsa, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("RSA", rsa, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("RSA", rsa, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("RSA-PSS", rsapss, yes, der, PKCS8),
-ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, PKCS8),
+ENCODER_w_structure("RSA-PSS", rsapss, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("RSA-PSS", rsapss, yes, pem, SubjectPublicKeyInfo),
 
 #ifndef OPENSSL_NO_DH
-ENCODER_w_structure("DH", dh, yes, der, PKCS8),
-ENCODER_w_structure("DH", dh, yes, pem, PKCS8),
+ENCODER_w_structure("DH", dh, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DH", dh, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DH", dh, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("DH", dh, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("DHX", dhx, yes, der, PKCS8),
-ENCODER_w_structure("DHX", dhx, yes, pem, PKCS8),
+ENCODER_w_structure("DHX", dhx, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DHX", dhx, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DHX", dhx, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("DHX", dhx, yes, pem, SubjectPublicKeyInfo),
 #endif
 
 #ifndef OPENSSL_NO_DSA
-ENCODER_w_structure("DSA", dsa, yes, der, PKCS8),
-ENCODER_w_structure("DSA", dsa, yes, pem, PKCS8),
+ENCODER_w_structure("DSA", dsa, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("DSA", dsa, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("DSA", dsa, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("DSA", dsa, yes, pem, SubjectPublicKeyInfo),
 #endif
 
 #ifndef OPENSSL_NO_EC
-ENCODER_w_structure("EC", ec, yes, der, PKCS8),
-ENCODER_w_structure("EC", ec, yes, pem, PKCS8),
+ENCODER_w_structure("EC", ec, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("EC", ec, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("EC", ec, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("EC", ec, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("X25519", x25519, yes, der, PKCS8),
-ENCODER_w_structure("X25519", x25519, yes, pem, PKCS8),
+ENCODER_w_structure("X25519", x25519, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("X25519", x25519, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("X448", x448, yes, der, PKCS8),
-ENCODER_w_structure("X448", x448, yes, pem, PKCS8),
+ENCODER_w_structure("X448", x448, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("X448", x448, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("X448", x448, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("X448", x448, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("ED25519", ed25519, yes, der, PKCS8),
-ENCODER_w_structure("ED25519", ed25519, yes, pem, PKCS8),
+ENCODER_w_structure("ED25519", ed25519, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ED25519", ed25519, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("ED25519", ed25519, yes, pem, SubjectPublicKeyInfo),
 
-ENCODER_w_structure("ED448", ed448, yes, der, PKCS8),
-ENCODER_w_structure("ED448", ed448, yes, pem, PKCS8),
+ENCODER_w_structure("ED448", ed448, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ED448", ed448, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo),
 
 # ifndef OPENSSL_NO_SM2
-ENCODER_w_structure("SM2", sm2, yes, der, PKCS8),
-ENCODER_w_structure("SM2", sm2, yes, pem, PKCS8),
+ENCODER_w_structure("SM2", sm2, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("SM2", sm2, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("SM2", sm2, yes, pem, SubjectPublicKeyInfo),
 # endif
diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info
index 537d393261..22f11cbceb 100644
--- a/providers/implementations/encode_decode/build.info
+++ b/providers/implementations/encode_decode/build.info
@@ -6,7 +6,7 @@ $DECODER_GOAL=../../libdefault.a
 
 SOURCE[$ENCODER_GOAL]=endecoder_common.c
 
-SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c \
+SOURCE[$DECODER_GOAL]=decode_der2key.c decode_epki2pki.c decode_pem2der.c \
                       decode_msblob2key.c decode_pvk2key.c
 
 SOURCE[$ENCODER_GOAL]=encode_key2any.c encode_key2text.c encode_key2ms.c
diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c
index 22ee075b19..7de44ed75d 100644
--- a/providers/implementations/encode_decode/decode_der2key.c
+++ b/providers/implementations/encode_decode/decode_der2key.c
@@ -41,8 +41,7 @@ typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
 typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
 typedef void free_key_fn(void *);
 typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long,
-                           struct der2key_ctx_st *,
-                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
+                           struct der2key_ctx_st *);
 struct keytype_desc_st {
     const char *keytype_name;
     const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
@@ -65,7 +64,7 @@ struct keytype_desc_st {
     d2i_of_void *d2i_private_key; /* From type-specific DER */
     d2i_of_void *d2i_public_key;  /* From type-specific DER */
     d2i_of_void *d2i_key_params;  /* From type-specific DER */
-    d2i_PKCS8_fn *d2i_PKCS8;      /* Wrapped in a PKCS#8, possibly encrypted */
+    d2i_PKCS8_fn *d2i_PKCS8;      /* Wrapped in a PrivateKeyInfo */
     d2i_of_void *d2i_PUBKEY;      /* Wrapped in a SubjectPublicKeyInfo */
 
     /*
@@ -114,36 +113,13 @@ typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf,
                                OSSL_LIB_CTX *libctx, const char *propq);
 static void *der2key_decode_p8(const unsigned char **input_der,
                                long input_der_len, struct der2key_ctx_st *ctx,
-                               OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg,
                                key_from_pkcs8_t *key_from_pkcs8)
 {
-    X509_SIG *p8 = NULL;
     PKCS8_PRIV_KEY_INFO *p8inf = NULL;
     const X509_ALGOR *alg = NULL;
     void *key = NULL;
 
-    ctx->flag_fatal = 0;
-
-    ERR_set_mark();
-    if ((p8 = d2i_X509_SIG(NULL, input_der, input_der_len)) != NULL) {
-        char pbuf[PEM_BUFSIZE];
-        size_t plen = 0;
-
-        ERR_clear_last_mark();
-
-        if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg))
-            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE);
-        else
-            p8inf = PKCS8_decrypt_ex(p8, pbuf, plen, PROV_LIBCTX_OF(ctx->provctx), NULL);
-        if (p8inf == NULL)
-            ctx->flag_fatal = 1;
-        X509_SIG_free(p8);
-    } else {
-        /* Pop any errors that might have been raised by d2i_X509_SIG. */
-        ERR_pop_to_mark();
-        p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len);
-    }
-    if (p8inf != NULL
+    if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL
         && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)
         && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type)
         key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), NULL);
@@ -247,8 +223,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
         derp = der;
         if (ctx->desc->d2i_PKCS8 != NULL) {
-            key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx,
-                                       pw_cb, pw_cbarg);
+            key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx);
             if (ctx->flag_fatal)
                 goto end;
         } else if (ctx->desc->d2i_private_key != NULL) {
@@ -360,10 +335,9 @@ static int der2key_export_object(void *vctx,
 # define dh_d2i_key_params              (d2i_of_void *)d2i_DHparams
 
 static void *dh_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                          struct der2key_ctx_st *ctx,
-                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                          struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_dh_key_from_pkcs8);
 }
 
@@ -396,10 +370,9 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx)
 # define dsa_d2i_key_params             (d2i_of_void *)d2i_DSAparams
 
 static void *dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                           struct der2key_ctx_st *ctx,
-                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                           struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_dsa_key_from_pkcs8);
 }
 
@@ -422,10 +395,9 @@ static void dsa_adjust(void *key, struct der2key_ctx_st *ctx)
 # define ec_d2i_key_params              (d2i_of_void *)d2i_ECParameters
 
 static void *ec_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                          struct der2key_ctx_st *ctx,
-                          OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                          struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8);
 }
 
@@ -452,10 +424,9 @@ static void ec_adjust(void *key, struct der2key_ctx_st *ctx)
  */
 
 static void *ecx_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                           struct der2key_ctx_st *ctx,
-                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                           struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_ecx_key_from_pkcs8);
 }
 
@@ -511,10 +482,9 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx)
 #  define sm2_d2i_key_params            (d2i_of_void *)d2i_ECParameters
 
 static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                           struct der2key_ctx_st *ctx,
-                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                           struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8);
 }
 
@@ -533,10 +503,9 @@ static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
 #define rsa_d2i_key_params              NULL
 
 static void *rsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
-                           struct der2key_ctx_st *ctx,
-                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+                           struct der2key_ctx_st *ctx)
 {
-    return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg,
+    return der2key_decode_p8(der, der_len, ctx,
                              (key_from_pkcs8_t *)ossl_rsa_key_from_pkcs8);
 }
 
@@ -650,8 +619,8 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx)
         keytype##_adjust,                               \
         keytype##_free
 
-#define DO_PKCS8(keytype)                               \
-    "pkcs8", keytype##_evp_type,                        \
+#define DO_PrivateKeyInfo(keytype)                      \
+    "PrivateKeyInfo", keytype##_evp_type,               \
         ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ),            \
         NULL,                                           \
         NULL,                                           \
@@ -785,42 +754,42 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx)
     }
 
 #ifndef OPENSSL_NO_DH
-MAKE_DECODER("DH", dh, dh, PKCS8);
+MAKE_DECODER("DH", dh, dh, PrivateKeyInfo);
 MAKE_DECODER("DH", dh, dh, SubjectPublicKeyInfo);
 MAKE_DECODER("DH", dh, dh, type_specific_params);
 MAKE_DECODER("DH", dh, dh, DH);
-MAKE_DECODER("DHX", dhx, dhx, PKCS8);
+MAKE_DECODER("DHX", dhx, dhx, PrivateKeyInfo);
 MAKE_DECODER("DHX", dhx, dhx, SubjectPublicKeyInfo);
 MAKE_DECODER("DHX", dhx, dhx, type_specific_params);
 MAKE_DECODER("DHX", dhx, dhx, DHX);
 #endif
 #ifndef OPENSSL_NO_DSA
-MAKE_DECODER("DSA", dsa, dsa, PKCS8);
+MAKE_DECODER("DSA", dsa, dsa, PrivateKeyInfo);
 MAKE_DECODER("DSA", dsa, dsa, SubjectPublicKeyInfo);
 MAKE_DECODER("DSA", dsa, dsa, type_specific);
 MAKE_DECODER("DSA", dsa, dsa, DSA);
 #endif
 #ifndef OPENSSL_NO_EC
-MAKE_DECODER("EC", ec, ec, PKCS8);
+MAKE_DECODER("EC", ec, ec, PrivateKeyInfo);
 MAKE_DECODER("EC", ec, ec, SubjectPublicKeyInfo);
 MAKE_DECODER("EC", ec, ec, type_specific_no_pub);
 MAKE_DECODER("EC", ec, ec, EC);
-MAKE_DECODER("X25519", x25519, ecx, PKCS8);
+MAKE_DECODER("X25519", x25519, ecx, PrivateKeyInfo);
 MAKE_DECODER("X25519", x25519, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("X448", x448, ecx, PKCS8);
+MAKE_DECODER("X448", x448, ecx, PrivateKeyInfo);
 MAKE_DECODER("X448", x448, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("ED25519", ed25519, ecx, PKCS8);
+MAKE_DECODER("ED25519", ed25519, ecx, PrivateKeyInfo);
 MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo);
-MAKE_DECODER("ED448", ed448, ecx, PKCS8);
+MAKE_DECODER("ED448", ed448, ecx, PrivateKeyInfo);
 MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo);
 # ifndef OPENSSL_NO_SM2
-MAKE_DECODER("SM2", sm2, ec, PKCS8);
+MAKE_DECODER("SM2", sm2, ec, PrivateKeyInfo);
 MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo);
 # endif
 #endif
-MAKE_DECODER("RSA", rsa, rsa, PKCS8);
+MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo);
 MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo);
 MAKE_DECODER("RSA", rsa, rsa, type_specific_keypair);
 MAKE_DECODER("RSA", rsa, rsa, RSA);
-MAKE_DECODER("RSA-PSS", rsapss, rsapss, PKCS8);
+MAKE_DECODER("RSA-PSS", rsapss, rsapss, PrivateKeyInfo);
 MAKE_DECODER("RSA-PSS", rsapss, rsapss, SubjectPublicKeyInfo);
diff --git a/providers/implementations/encode_decode/decode_epki2pki.c b/providers/implementations/encode_decode/decode_epki2pki.c
new file mode 100644
index 0000000000..c0d014aef1
--- /dev/null
+++ b/providers/implementations/encode_decode/decode_epki2pki.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * 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/core_names.h>
+#include <openssl/core_object.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include <openssl/proverr.h>
+#include "internal/asn1.h"
+#include "internal/sizes.h"
+#include "prov/bio.h"
+#include "prov/implementations.h"
+#include "endecoder_local.h"
+
+static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx;
+static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx;
+static OSSL_FUNC_decoder_decode_fn epki2pki_decode;
+
+/*
+ * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding.
+ */
+struct epki2pki_ctx_st {
+    PROV_CTX *provctx;
+};
+
+static void *epki2pki_newctx(void *provctx)
+{
+    struct epki2pki_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx != NULL)
+        ctx->provctx = provctx;
+    return ctx;
+}
+
+static void epki2pki_freectx(void *vctx)
+{
+    struct epki2pki_ctx_st *ctx = vctx;
+
+    OPENSSL_free(ctx);
+}
+
+/*
+ * The selection parameter in epki2pki_decode() is not used by this function
+ * because it's not relevant just to decode EncryptedPrivateKeyInfo to
+ * PrivateKeyInfo.
+ */
+static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
+                           OSSL_CALLBACK *data_cb, void *data_cbarg,
+                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+    struct epki2pki_ctx_st *ctx = vctx;
+    BUF_MEM *mem = NULL;
+    unsigned char *der = NULL;
+    const unsigned char *pder = NULL;
+    long der_len = 0;
+    X509_SIG *p8 = NULL;
+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+    const X509_ALGOR *alg = NULL;
+    BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin);
+    int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+
+    BIO_free(in);
+
+    /* We return "empty handed".  This is not an error. */
+    if (!ok)
+        return 1;
+
+    pder = der = (unsigned char *)mem->data;
+    der_len = (long)mem->length;
+    OPENSSL_free(mem);
+
+    ok = 1;                      /* Assume good */
+    ERR_set_mark();
+    if ((p8 = d2i_X509_SIG(NULL, &pder, der_len)) != NULL) {
+        char pbuf[1024];
+        size_t plen = 0;
+
+        ERR_clear_last_mark();
+
+        if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE);
+        } else {
+            const ASN1_OCTET_STRING *oct;
+            unsigned char *new_der = NULL;
+            int new_der_len = 0;
+
+            X509_SIG_get0(p8, &alg, &oct);
+            if (!PKCS12_pbe_crypt_ex(alg, pbuf, plen,
+                                     oct->data, oct->length,
+                                     &new_der, &new_der_len, 0,
+                                     PROV_LIBCTX_OF(ctx->provctx), NULL)) {
+                ok = 0;
+            } else {
+                OPENSSL_free(der);
+                der = new_der;
+                der_len = new_der_len;
+            }
+            alg = NULL;
+        }
+        X509_SIG_free(p8);
+    } else {
+        ERR_pop_to_mark();
+    }
+
+    ERR_set_mark();
+    pder = der;
+    p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &pder, der_len);
+    ERR_pop_to_mark();
+
+    if (p8inf != NULL && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)) {
+        /*
+         * We have something and recognised it as PrivateKeyInfo, so let's
+         * pass all the applicable data to the callback.
+         */
+        char keytype[OSSL_MAX_NAME_SIZE];
+        OSSL_PARAM params[5], *p = params;
+        int objtype = OSSL_OBJECT_PKEY;
+
+        OBJ_obj2txt(keytype, sizeof(keytype), alg->algorithm, 0);
+
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+                                                keytype, 0);
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
+                                                "PrivateKeyInfo", 0);
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
+                                                 der, der_len);
+        *p++ = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
+        *p = OSSL_PARAM_construct_end();
+
+        ok = data_cb(params, data_cbarg);
+    }
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    OPENSSL_free(der);
+    return ok;
+}
+
+const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[] = {
+    { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))epki2pki_newctx },
+    { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))epki2pki_freectx },
+    { OSSL_FUNC_DECODER_DECODE, (void (*)(void))epki2pki_decode },
+    { 0, NULL }
+};
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c
index 318efcc6af..16f3322354 100644
--- a/providers/implementations/encode_decode/decode_pem2der.c
+++ b/providers/implementations/encode_decode/decode_pem2der.c
@@ -101,8 +101,8 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
          * These entries should be in longest to shortest order to avoid
          * mixups.
          */
-        { "ENCRYPTED PRIVATE KEY", "pkcs8" },
-        { "PRIVATE KEY", "pkcs8" },
+        { "ENCRYPTED PRIVATE KEY", "EncryptedPrivateKeyInfo" },
+        { "PRIVATE KEY", "PrivateKeyInfo" },
         { "PUBLIC KEY", "SubjectPublicKeyInfo" },
         { "PARAMETERS", NULL }
 
diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c
index f986ec124e..855866cbfe 100644
--- a/providers/implementations/encode_decode/encode_key2any.c
+++ b/providers/implementations/encode_decode/encode_key2any.c
@@ -128,12 +128,14 @@ static X509_SIG *key_to_encp8(const void *key, int key_nid,
 {
     PKCS8_PRIV_KEY_INFO *p8info =
         key_to_p8info(key, key_nid, params, params_type, k2d);
-    X509_SIG *p8 = p8info_to_encp8(p8info, ctx);
+    X509_SIG *p8 = NULL;
 
-    if (p8info == NULL)
+    if (p8info == NULL) {
         free_asn1_data(params_type, params);
-
-    PKCS8_PRIV_KEY_INFO_free(p8info);
+    } else {
+        p8 = p8info_to_encp8(p8info, ctx);
+        PKCS8_PRIV_KEY_INFO_free(p8info);
+    }
     return p8;
 }
 
@@ -162,81 +164,141 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid,
 }
 
 /*
- * key_to_pkcs8_* produce encoded output with the key data pkcs8
- * in a structure.  For private keys, that structure is PKCS#8, and for
- * public keys, it's X.509 SubjectPublicKeyInfo.  Parameters don't have
- * any defined envelopment of that kind.
+ * key_to_epki_* produce encoded output with the private key data in a
+ * EncryptedPrivateKeyInfo structure (defined by PKCS#8).  They require
+ * that there's an intent to encrypt, anything else is an error.
+ * They are currently only called from the corresponding key_to_pki_ function.
+ *
+ * key_to_pki_* primarly produce encoded output with the private key data
+ * in a PrivateKeyInfo structure (also defined by PKCS#8).  However, if
+ * there is an intent to encrypt the data, the corresponding key_to_epki_*
+ * function is used instead.
+ *
+ * key_to_spki_* produce encoded output with the public key data in an
+ * X.509 SubjectPublicKeyInfo.
+ *
+ * Key parameters don't have any defined envelopment of this kind, but are
+ * included in some manner in the output from the functions described above,
+ * either in the AlgorithmIdentifier's parameter field, or as part of the
+ * key data itself.
  */
-static int key_to_pkcs8_der_priv_bio(BIO *out, const void *key,
-                                     int key_nid,
-                                     ossl_unused const char *pemname,
-                                     key_to_paramstring_fn *p2s,
-                                     i2d_of_void *k2d,
-                                     struct key2any_ctx_st *ctx)
+
+static int key_to_epki_der_priv_bio(BIO *out, const void *key,
+                                    int key_nid,
+                                    ossl_unused const char *pemname,
+                                    key_to_paramstring_fn *p2s,
+                                    i2d_of_void *k2d,
+                                    struct key2any_ctx_st *ctx)
 {
     int ret = 0;
     void *str = NULL;
     int strtype = V_ASN1_UNDEF;
+    X509_SIG *p8;
+
+    if (!ctx->cipher_intent)
+        return 0;
 
     if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
                             &str, &strtype))
         return 0;
 
-    if (ctx->cipher_intent) {
-        X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+    p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+    if (p8 != NULL)
+        ret = i2d_PKCS8_bio(out, p8);
 
-        if (p8 != NULL)
-            ret = i2d_PKCS8_bio(out, p8);
+    X509_SIG_free(p8);
 
-        X509_SIG_free(p8);
-    } else {
-        PKCS8_PRIV_KEY_INFO *p8info =
-            key_to_p8info(key, key_nid, str, strtype, k2d);
+    return ret;
+}
 
-        if (p8info != NULL)
-            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
-        else
-            free_asn1_data(strtype, str);
+static int key_to_epki_pem_priv_bio(BIO *out, const void *key,
+                                    int key_nid,
+                                    ossl_unused const char *pemname,
+                                    key_to_paramstring_fn *p2s,
+                                    i2d_of_void *k2d,
+                                    struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+    X509_SIG *p8;
 
-        PKCS8_PRIV_KEY_INFO_free(p8info);
-    }
+    if (!ctx->cipher_intent)
+        return 0;
+
+    if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+                            &str, &strtype))
+        return 0;
+
+    p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+    if (p8 != NULL)
+        ret = PEM_write_bio_PKCS8(out, p8);
+
+    X509_SIG_free(p8);
 
     return ret;
 }
 
-static int key_to_pkcs8_pem_priv_bio(BIO *out, const void *key,
-                                     int key_nid,
-                                     ossl_unused const char *pemname,
-                                     key_to_paramstring_fn *p2s,
-                                     i2d_of_void *k2d,
-                                     struct key2any_ctx_st *ctx)
+static int key_to_pki_der_priv_bio(BIO *out, const void *key,
+                                   int key_nid,
+                                   ossl_unused const char *pemname,
+                                   key_to_paramstring_fn *p2s,
+                                   i2d_of_void *k2d,
+                                   struct key2any_ctx_st *ctx)
 {
     int ret = 0;
     void *str = NULL;
     int strtype = V_ASN1_UNDEF;
+    PKCS8_PRIV_KEY_INFO *p8info;
+
+    if (ctx->cipher_intent)
+        return key_to_epki_der_priv_bio(out, key, key_nid, pemname,
+                                        p2s, k2d, ctx);
 
     if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
                             &str, &strtype))
         return 0;
 
-    if (ctx->cipher_intent) {
-        X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+    p8info = key_to_p8info(key, key_nid, str, strtype, k2d);
 
-        if (p8 != NULL)
-            ret = PEM_write_bio_PKCS8(out, p8);
+    if (p8info != NULL)
+        ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
+    else
+        free_asn1_data(strtype, str);
 
-        X509_SIG_free(p8);
-    } else {
-        PKCS8_PRIV_KEY_INFO *p8info =
-            key_to_p8info(key, key_nid, str, strtype, k2d);
+    PKCS8_PRIV_KEY_INFO_free(p8info);
 
-        if (p8info != NULL)
-            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
-        else
-            free_asn1_data(strtype, str);
+    return ret;
+}
 
-        PKCS8_PRIV_KEY_INFO_free(p8info);
-    }
+static int key_to_pki_pem_priv_bio(BIO *out, const void *key,
+                                   int key_nid,
+                                   ossl_unused const char *pemname,
+                                   key_to_paramstring_fn *p2s,
+                                   i2d_of_void *k2d,
+                                   struct key2any_ctx_st *ctx)
+{
+    int ret = 0;
+    void *str = NULL;
+    int strtype = V_ASN1_UNDEF;
+    PKCS8_PRIV_KEY_INFO *p8info;
+
+    if (ctx->cipher_intent)
+        return key_to_epki_pem_priv_bio(out, key, key_nid, pemname,
+                                        p2s, k2d, ctx);
+
+    if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+                            &str, &strtype))
+        return 0;
+
+    p8info = key_to_p8info(key, key_nid, str, strtype, k2d);
+
+    if (p8info != NULL)
+        ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
+    else
+        free_asn1_data(strtype, str);
+
+    PKCS8_PRIV_KEY_INFO_free(p8info);
 
     return ret;
 }
@@ -427,7 +489,7 @@ static int dh_spki_pub_to_der(const void *dh, unsigned char **pder)
     return ret;
 }
 
-static int dh_pkcs8_priv_to_der(const void *dh, unsigned char **pder)
+static int dh_pki_priv_to_der(const void *dh, unsigned char **pder)
 {
     const BIGNUM *bn = NULL;
     ASN1_INTEGER *priv_key = NULL;
@@ -540,7 +602,7 @@ static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder)
     return ret;
 }
 
-static int dsa_pkcs8_priv_to_der(const void *dsa, unsigned char **pder)
+static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder)
 {
     const BIGNUM *bn = NULL;
     ASN1_INTEGER *priv_key = NULL;
@@ -639,7 +701,7 @@ static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder)
     return i2o_ECPublicKey(eckey, pder);
 }
 
-static int ec_pkcs8_priv_to_der(const void *veckey, unsigned char **pder)
+static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder)
 {
     EC_KEY *eckey = (EC_KEY *)veckey;
     unsigned int old_flags;
@@ -700,7 +762,7 @@ static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder)
     return ecxkey->keylen;
 }
 
-static int ecx_pkcs8_priv_to_der(const void *vecxkey, unsigned char **pder)
+static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder)
 {
     const ECX_KEY *ecxkey = vecxkey;
     ASN1_OCTET_STRING oct;
@@ -826,7 +888,7 @@ static int prepare_rsa_params(const void *rsa, int nid, int save,
  * RSA is extremely simple, as PKCS#1 is used for the PKCS#8 |privateKey|
  * field as well as the SubjectPublicKeyInfo |subjectPublicKey| field.
  */
-#define rsa_pkcs8_priv_to_der           rsa_type_specific_priv_to_der
+#define rsa_pki_priv_to_der             rsa_type_specific_priv_to_der
 #define rsa_spki_pub_to_der             rsa_type_specific_pub_to_der
 #define rsa_type_specific_priv_to_der   (i2d_of_void *)i2d_RSAPrivateKey
 #define rsa_type_specific_pub_to_der    (i2d_of_void *)i2d_RSAPublicKey
@@ -1041,10 +1103,18 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout,
  *      the same.
  */
 
-/* PKCS#8 is a structure for private keys only */
-#define DO_PKCS8_selection_mask DO_PRIVATE_KEY_selection_mask
-#define DO_PKCS8(impl, type, output)                                        \
-    DO_PRIVATE_KEY(impl, type, pkcs8, output)
+/*
+ * PKCS#8 defines two structures for private keys only:
+ * - PrivateKeyInfo             (raw unencrypted form)
+ * - EncryptedPrivateKeyInfo    (encrypted wrapping)
+ *
+ * To allow a certain amount of flexibility, we allow the routines
+ * for PrivateKeyInfo to also produce EncryptedPrivateKeyInfo if a
+ * passphrase callback has been passed to them.
+ */
+#define DO_PrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask
+#define DO_PrivateKeyInfo(impl, type, output)                               \
+    DO_PRIVATE_KEY(impl, type, pki, output)
 
 /* SubjectPublicKeyInfo is a structure for public keys only */
 #define DO_SubjectPublicKeyInfo_selection_mask DO_PUBLIC_KEY_selection_mask
@@ -1258,55 +1328,55 @@ MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem);
  * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(),
  * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters().
  */
-MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS8, der);
-MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS8, pem);
+MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, pem);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, pem);
-MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS8, der);
-MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS8, pem);
+MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, der);
+MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, pem);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, pem);
 #ifndef OPENSSL_NO_DH
-MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS8, der);
-MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS8, pem);
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, der);
+MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, pem);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, pem);
-MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PKCS8, der);
-MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PKCS8, pem);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, der);
+MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, pem);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, pem);
 #endif
 #ifndef OPENSSL_NO_DSA
-MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PKCS8, der);
-MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PKCS8, pem);
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, der);
+MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, pem);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, pem);
 #endif
 #ifndef OPENSSL_NO_EC
-MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PKCS8, der);
-MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PKCS8, pem);
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, der);
+MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, pem);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem);
 # ifndef OPENSSL_NO_SM2
-MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PKCS8, der);
-MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PKCS8, pem);
+MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, der);
+MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, pem);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem);
 # endif
-MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PKCS8, der);
-MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PKCS8, pem);
+MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, der);
+MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, pem);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, pem);
-MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PKCS8, der);
-MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PKCS8, pem);
+MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der);
+MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem);
-MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PKCS8, der);
-MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PKCS8, pem);
+MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, der);
+MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, pem);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, pem);
-MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PKCS8, der);
-MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PKCS8, pem);
+MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der);
+MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem);
 MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem);
 #endif
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index ae09ccd506..7b59e7308d 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -323,8 +323,8 @@ extern const OSSL_DISPATCH ossl_rsa_asym_kem_functions[];
 /* Encoders */
 extern const OSSL_DISPATCH ossl_rsa_to_PKCS1_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_PKCS1_pem_encoder_functions[];
-extern const OSSL_DISPATCH ossl_rsa_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_rsa_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsa_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsa_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_RSA_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_RSA_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsa_to_SubjectPublicKeyInfo_der_encoder_functions[];
@@ -337,8 +337,8 @@ extern const OSSL_DISPATCH ossl_rsa_to_type_specific_keypair_pem_encoder_functio
 
 extern const OSSL_DISPATCH ossl_rsapss_to_PKCS1_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_PKCS1_pem_encoder_functions[];
-extern const OSSL_DISPATCH ossl_rsapss_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_rsapss_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsapss_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_rsapss_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_rsapss_to_text_encoder_functions[];
@@ -347,8 +347,8 @@ extern const OSSL_DISPATCH ossl_dh_to_DH_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_DH_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PKCS3_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_PKCS3_pem_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dh_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dh_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dh_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dh_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dh_to_type_specific_params_der_encoder_functions[];
@@ -357,8 +357,8 @@ extern const OSSL_DISPATCH ossl_dh_to_text_encoder_functions[];
 
 extern const OSSL_DISPATCH ossl_dhx_to_DHX_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_DHX_pem_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dhx_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dhx_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dhx_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dhx_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dhx_to_X9_42_der_encoder_functions[];
@@ -369,8 +369,8 @@ extern const OSSL_DISPATCH ossl_dhx_to_text_encoder_functions[];
 
 extern const OSSL_DISPATCH ossl_dsa_to_DSA_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_DSA_pem_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dsa_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_dsa_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dsa_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_dsa_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_dsa_to_type_specific_pem_encoder_functions[];
@@ -382,8 +382,8 @@ extern const OSSL_DISPATCH ossl_dsa_to_text_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_EC_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_EC_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_blob_encoder_functions[];
-extern const OSSL_DISPATCH ossl_ec_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_ec_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ec_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ec_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ec_to_X9_62_der_encoder_functions[];
@@ -396,8 +396,8 @@ extern const OSSL_DISPATCH ossl_ec_to_text_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SM2_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SM2_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_blob_encoder_functions[];
-extern const OSSL_DISPATCH ossl_sm2_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_sm2_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_sm2_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_sm2_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_sm2_to_type_specific_no_pub_pem_encoder_functions[];
@@ -405,84 +405,85 @@ extern const OSSL_DISPATCH ossl_sm2_to_type_specific_no_pub_der_encoder_function
 extern const OSSL_DISPATCH ossl_sm2_to_text_encoder_functions[];
 #endif
 
-extern const OSSL_DISPATCH ossl_ed25519_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_ed25519_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed25519_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed25519_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed25519_to_text_encoder_functions[];
 
-extern const OSSL_DISPATCH ossl_ed448_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_ed448_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed448_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ed448_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_ed448_to_text_encoder_functions[];
 
-extern const OSSL_DISPATCH ossl_x25519_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_x25519_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x25519_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x25519_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x25519_to_text_encoder_functions[];
 
-extern const OSSL_DISPATCH ossl_x448_to_PKCS8_der_encoder_functions[];
-extern const OSSL_DISPATCH ossl_x448_to_PKCS8_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x448_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_x448_to_PrivateKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_SubjectPublicKeyInfo_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_SubjectPublicKeyInfo_pem_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_OSSL_current_der_encoder_functions[];
 extern const OSSL_DISPATCH ossl_x448_to_text_encoder_functions[];
 
 /* Decoders */
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_dh_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_dh_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_dh_decoder_functions[];
 extern const OSSL_DISPATCH ossl_type_specific_params_der_to_dh_decoder_functions[];
 extern const OSSL_DISPATCH ossl_DH_der_to_dh_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_dhx_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_dhx_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_dhx_decoder_functions[];
 extern const OSSL_DISPATCH ossl_type_specific_params_der_to_dhx_decoder_functions[];
 extern const OSSL_DISPATCH ossl_DHX_der_to_dhx_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_dsa_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_dsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_dsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_type_specific_der_to_dsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_DSA_der_to_dsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_msblob_to_dsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_pvk_to_dsa_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_ec_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ec_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ec_decoder_functions[];
 extern const OSSL_DISPATCH ossl_type_specific_no_pub_der_to_ec_decoder_functions[];
 extern const OSSL_DISPATCH ossl_EC_der_to_ec_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_x25519_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_x25519_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_x25519_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_x448_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_x448_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_x448_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_ed25519_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ed25519_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed25519_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_ed448_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ed448_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed448_decoder_functions[];
 
 #ifndef OPENSSL_NO_SM2
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_sm2_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_sm2_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_sm2_decoder_functions[];
 #endif
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_rsa_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_rsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_rsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_type_specific_keypair_der_to_rsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_RSA_der_to_rsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_msblob_to_rsa_decoder_functions[];
 extern const OSSL_DISPATCH ossl_pvk_to_rsa_decoder_functions[];
 
-extern const OSSL_DISPATCH ossl_PKCS8_der_to_rsapss_decoder_functions[];
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_rsapss_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_rsapss_decoder_functions[];
 
+extern const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[];
 extern const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[];
 
 extern const OSSL_DISPATCH ossl_file_store_functions[];
diff --git a/test/endecode_test.c b/test/endecode_test.c
index f800d7738c..d28ea3c812 100644
--- a/test/endecode_test.c
+++ b/test/endecode_test.c
@@ -526,7 +526,7 @@ static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
-                              "DER", "pkcs8", NULL, NULL,
+                              "DER", "PrivateKeyInfo", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_mem, check_unprotected_PKCS8_DER,
                               dump_der, 0);
@@ -548,7 +548,7 @@ static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
-                              "PEM", "pkcs8", NULL, NULL,
+                              "PEM", "PrivateKeyInfo", NULL, NULL,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_text, check_unprotected_PKCS8_PEM,
                               dump_pem, 0);
@@ -703,7 +703,8 @@ static int test_protected_via_DER(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
-                              "DER", "pkcs8", pass, pass_cipher,
+                              "DER", "PrivateKeyInfo",
+                              pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_mem, check_protected_PKCS8_DER,
                               dump_der, 0);
@@ -725,7 +726,8 @@ static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
     return test_encode_decode(__FILE__, __LINE__, type, key,
                               OSSL_KEYMGMT_SELECT_KEYPAIR
                               | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
-                              "PEM", "pkcs8", pass, pass_cipher,
+                              "PEM", "PrivateKeyInfo",
+                              pass, pass_cipher,
                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
                               test_text, check_protected_PKCS8_PEM,
                               dump_pem, 0);
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index bdfa3cd754..f075f40b0c 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -176,14 +176,14 @@ static int test_print_key_type_using_encoder(const char *alg, int type,
 
     case PRIV_PEM:
         output_type = "PEM";
-        output_structure = "pkcs8";
+        output_structure = "PrivateKeyInfo";
         selection = OSSL_KEYMGMT_SELECT_KEYPAIR
             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
         break;
 
     case PRIV_DER:
         output_type = "DER";
-        output_structure = "pkcs8";
+        output_structure = "PrivateKeyInfo";
         selection = OSSL_KEYMGMT_SELECT_KEYPAIR
             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
         break;


More information about the openssl-commits mailing list