/*
 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * DSA low level APIs are deprecated for public use, but still ok for
 * internal use.
 */
#include "internal/deprecated.h"

#include <assert.h>
#include <stdio.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
#include "internal/namemap.h"
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/cmac.h>
#ifndef FIPS_MODULE
# include <openssl/engine.h>
#endif
#include <openssl/params.h>
#include <openssl/param_build.h>
#include <openssl/encoder.h>
#include <openssl/core_names.h>

#include "internal/numbers.h"   /* includes SIZE_MAX */
#include "internal/ffc.h"
#include "crypto/evp.h"
#include "crypto/dh.h"
#include "crypto/dsa.h"
#include "crypto/ec.h"
#include "crypto/ecx.h"
#include "crypto/rsa.h"
#ifndef FIPS_MODULE
# include "crypto/asn1.h"
# include "crypto/x509.h"
#endif
#include "internal/provider.h"
#include "evp_local.h"

static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
                         int len, EVP_KEYMGMT *keymgmt);
static void evp_pkey_free_it(EVP_PKEY *key);

#ifndef FIPS_MODULE

/* The type of parameters selected in key parameter functions */
# define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS

int EVP_PKEY_get_bits(const EVP_PKEY *pkey)
{
    int size = 0;

    if (pkey != NULL) {
        size = pkey->cache.bits;
        if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL)
            size = pkey->ameth->pkey_bits(pkey);
    }
    return size < 0 ? 0 : size;
}

int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey)
{
    int size = 0;

    if (pkey != NULL) {
        size = pkey->cache.security_bits;
        if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL)
            size = pkey->ameth->pkey_security_bits(pkey);
    }
    return size < 0 ? 0 : size;
}

int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
{
# ifndef OPENSSL_NO_DSA
    if (pkey->type == EVP_PKEY_DSA) {
        int ret = pkey->save_parameters;

        if (mode >= 0)
            pkey->save_parameters = mode;
        return ret;
    }
# endif
# ifndef OPENSSL_NO_EC
    if (pkey->type == EVP_PKEY_EC) {
        int ret = pkey->save_parameters;

        if (mode >= 0)
            pkey->save_parameters = mode;
        return ret;
    }
# endif
    return 0;
}

int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg)
{
    return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
}

void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx)
{
    return CRYPTO_get_ex_data(&key->ex_data, idx);
}

int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
{
    /*
     * Clean up legacy stuff from this function when legacy support is gone.
     */

    EVP_PKEY *downgraded_from = NULL;
    int ok = 0;

    /*
     * If |to| is a legacy key and |from| isn't, we must make a downgraded
     * copy of |from|.  If that fails, this function fails.
     */
    if (evp_pkey_is_legacy(to) && evp_pkey_is_provided(from)) {
        if (!evp_pkey_copy_downgraded(&downgraded_from, from))
            goto end;
        from = downgraded_from;
    }

    /*
     * Make sure |to| is typed.  Content is less important at this early
     * stage.
     *
     * 1.  If |to| is untyped, assign |from|'s key type to it.
     * 2.  If |to| contains a legacy key, compare its |type| to |from|'s.
     *     (|from| was already downgraded above)
     *
     * If |to| is a provided key, there's nothing more to do here, functions
     * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called
     * further down help us find out if they are the same or not.
     */
    if (evp_pkey_is_blank(to)) {
        if (evp_pkey_is_legacy(from)) {
            if (EVP_PKEY_set_type(to, from->type) == 0)
                goto end;
        } else {
            if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
                goto end;
        }
    } else if (evp_pkey_is_legacy(to)) {
        if (to->type != from->type) {
            ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
            goto end;
        }
    }

    if (EVP_PKEY_missing_parameters(from)) {
        ERR_raise(ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS);
        goto end;
    }

    if (!EVP_PKEY_missing_parameters(to)) {
        if (EVP_PKEY_parameters_eq(to, from) == 1)
            ok = 1;
        else
            ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS);
        goto end;
    }

    /* For purely provided keys, we just call the keymgmt utility */
    if (to->keymgmt != NULL && from->keymgmt != NULL) {
        ok = evp_keymgmt_util_copy(to, (EVP_PKEY *)from, SELECT_PARAMETERS);
        goto end;
    }

    /*
     * If |to| is provided, we know that |from| is legacy at this point.
     * Try exporting |from| to |to|'s keymgmt, then use evp_keymgmt_dup()
     * to copy the appropriate data to |to|'s keydata.
     * We cannot override existing data so do it only if there is no keydata
     * in |to| yet.
     */
    if (to->keymgmt != NULL && to->keydata == NULL) {
        EVP_KEYMGMT *to_keymgmt = to->keymgmt;
        void *from_keydata =
            evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
                                        NULL);

        /*
         * If we get a NULL, it could be an internal error, or it could be
         * that there's a key mismatch.  We're pretending the latter...
         */
        if (from_keydata == NULL)
            ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
        else
            ok = (to->keydata = evp_keymgmt_dup(to->keymgmt,
                                                from_keydata,
                                                SELECT_PARAMETERS)) != NULL;
        goto end;
    }

    /* Both keys are legacy */
    if (from->ameth != NULL && from->ameth->param_copy != NULL)
        ok = from->ameth->param_copy(to, from);
 end:
    EVP_PKEY_free(downgraded_from);
    return ok;
}

int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
{
    if (pkey != NULL) {
        if (pkey->keymgmt != NULL)
            return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
        else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
            return pkey->ameth->param_missing(pkey);
    }
    return 0;
}

/*
 * This function is called for any mixture of keys except pure legacy pair.
 * When legacy keys are gone, we replace a call to this functions with
 * a call to evp_keymgmt_util_match().
 */
static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
                            int selection)
{
    EVP_KEYMGMT *keymgmt1 = NULL, *keymgmt2 = NULL;
    void *keydata1 = NULL, *keydata2 = NULL, *tmp_keydata = NULL;

    /* If none of them are provided, this function shouldn't have been called */
    if (!ossl_assert(evp_pkey_is_provided(a) || evp_pkey_is_provided(b)))
        return -2;

    /* For purely provided keys, we just call the keymgmt utility */
    if (evp_pkey_is_provided(a) && evp_pkey_is_provided(b))
        return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);

    /*
     * At this point, one of them is provided, the other not.  This allows
     * us to compare types using legacy NIDs.
     */
    if (evp_pkey_is_legacy(a)
        && !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type)))
        return -1;               /* not the same key type */
    if (evp_pkey_is_legacy(b)
        && !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type)))
        return -1;               /* not the same key type */

    /*
     * We've determined that they both are the same keytype, so the next
     * step is to do a bit of cross export to ensure we have keydata for
     * both keys in the same keymgmt.
     */
    keymgmt1 = a->keymgmt;
    keydata1 = a->keydata;
    keymgmt2 = b->keymgmt;
    keydata2 = b->keydata;

    if (keymgmt2 != NULL && keymgmt2->match != NULL) {
        tmp_keydata =
            evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL);
        if (tmp_keydata != NULL) {
            keymgmt1 = keymgmt2;
            keydata1 = tmp_keydata;
        }
    }
    if (tmp_keydata == NULL && keymgmt1 != NULL && keymgmt1->match != NULL) {
        tmp_keydata =
            evp_pkey_export_to_provider((EVP_PKEY *)b, NULL, &keymgmt1, NULL);
        if (tmp_keydata != NULL) {
            keymgmt2 = keymgmt1;
            keydata2 = tmp_keydata;
        }
    }

    /* If we still don't have matching keymgmt implementations, we give up */
    if (keymgmt1 != keymgmt2)
        return -2;

    /* If the keymgmt implementations are NULL, the export failed */
    if (keymgmt1 == NULL)
        return -2;

    return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
}

# ifndef OPENSSL_NO_DEPRECATED_3_0
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
    return EVP_PKEY_parameters_eq(a, b);
}
#endif

int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b)
{
    /*
     * This will just call evp_keymgmt_util_match when legacy support
     * is gone.
     */

    if (a->keymgmt != NULL || b->keymgmt != NULL)
        return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);

    /* All legacy keys */
    if (a->type != b->type)
        return -1;
    if (a->ameth != NULL && a->ameth->param_cmp != NULL)
        return a->ameth->param_cmp(a, b);
    return -2;
}

# ifndef OPENSSL_NO_DEPRECATED_3_0
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
{
    return EVP_PKEY_eq(a, b);
}
#endif

int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b)
{
    /*
     * This will just call evp_keymgmt_util_match when legacy support
     * is gone.
     */

    /* Trivial shortcuts */
    if (a == b)
        return 1;
    if (a == NULL || b == NULL)
        return 0;

    if (a->keymgmt != NULL || b->keymgmt != NULL)
        return evp_pkey_cmp_any(a, b, (SELECT_PARAMETERS
                                       | OSSL_KEYMGMT_SELECT_KEYPAIR));

    /* All legacy keys */
    if (a->type != b->type)
        return -1;

    if (a->ameth != NULL) {
        int ret;
        /* Compare parameters if the algorithm has them */
        if (a->ameth->param_cmp != NULL) {
            ret = a->ameth->param_cmp(a, b);
            if (ret <= 0)
                return ret;
        }

        if (a->ameth->pub_cmp != NULL)
            return a->ameth->pub_cmp(a, b);
    }

    return -2;
}


static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx,
                                 const char *strtype,
                                 const char *propq,
                                 int nidtype,
                                 ENGINE *e,
                                 const unsigned char *key,
                                 size_t len,
                                 int key_is_priv)
{
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;
    int result = 0;

# ifndef OPENSSL_NO_ENGINE
    /* Check if there is an Engine for this type */
    if (e == NULL) {
        ENGINE *tmpe = NULL;

        if (strtype != NULL)
            ameth = EVP_PKEY_asn1_find_str(&tmpe, strtype, -1);
        else if (nidtype != EVP_PKEY_NONE)
            ameth = EVP_PKEY_asn1_find(&tmpe, nidtype);

        /* If tmpe is NULL then no engine is claiming to support this type */
        if (tmpe == NULL)
            ameth = NULL;

        ENGINE_finish(tmpe);
    }
# endif

    if (e == NULL && ameth == NULL) {
        /*
         * No engine is claiming to support this type, so lets see if we have
         * a provider.
         */
        ctx = EVP_PKEY_CTX_new_from_name(libctx,
                                         strtype != NULL ? strtype
                                                         : OBJ_nid2sn(nidtype),
                                         propq);
        if (ctx == NULL)
            goto err;
        /* May fail if no provider available */
        ERR_set_mark();
        if (EVP_PKEY_fromdata_init(ctx) == 1) {
            OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };

            ERR_clear_last_mark();
            params[0] = OSSL_PARAM_construct_octet_string(
                            key_is_priv ? OSSL_PKEY_PARAM_PRIV_KEY
                                        : OSSL_PKEY_PARAM_PUB_KEY,
                            (void *)key, len);

            if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1) {
                ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
                goto err;
            }

            EVP_PKEY_CTX_free(ctx);

            return pkey;
        }
        ERR_pop_to_mark();
        /* else not supported so fallback to legacy */
    }

    /* Legacy code path */

    pkey = EVP_PKEY_new();
    if (pkey == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!pkey_set_type(pkey, e, nidtype, strtype, -1, NULL)) {
        /* EVPerr already called */
        goto err;
    }

    if (!ossl_assert(pkey->ameth != NULL))
        goto err;

    if (key_is_priv) {
        if (pkey->ameth->set_priv_key == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
            goto err;
        }

        if (!pkey->ameth->set_priv_key(pkey, key, len)) {
            ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
            goto err;
        }
    } else {
        if (pkey->ameth->set_pub_key == NULL) {
            ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
            goto err;
        }

        if (!pkey->ameth->set_pub_key(pkey, key, len)) {
            ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
            goto err;
        }
    }

    result = 1;
 err:
    if (!result) {
        EVP_PKEY_free(pkey);
        pkey = NULL;
    }
    EVP_PKEY_CTX_free(ctx);
    return pkey;
}

EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx,
                                          const char *keytype,
                                          const char *propq,
                                          const unsigned char *priv, size_t len)
{
    return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv,
                           len, 1);
}

EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
                                       const unsigned char *priv,
                                       size_t len)
{
    return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1);
}

EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx,
                                         const char *keytype, const char *propq,
                                         const unsigned char *pub, size_t len)
{
    return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub,
                           len, 0);
}

EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
                                      const unsigned char *pub,
                                      size_t len)
{
    return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0);
}

struct raw_key_details_st
{
    unsigned char **key;
    size_t *len;
    int selection;
};

static OSSL_CALLBACK get_raw_key_details;
static int get_raw_key_details(const OSSL_PARAM params[], void *arg)
{
    const OSSL_PARAM *p = NULL;
    struct raw_key_details_st *raw_key = arg;

    if (raw_key->selection == OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
        if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY))
                != NULL)
            return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
                                               raw_key->key == NULL ? 0 : *raw_key->len,
                                               raw_key->len);
    } else if (raw_key->selection == OSSL_KEYMGMT_SELECT_PUBLIC_KEY) {
        if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY))
                != NULL)
            return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
                                               raw_key->key == NULL ? 0 : *raw_key->len,
                                               raw_key->len);
    }

    return 0;
}

int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
                                 size_t *len)
{
    if (pkey->keymgmt != NULL) {
        struct raw_key_details_st raw_key;

        raw_key.key = priv == NULL ? NULL : &priv;
        raw_key.len = len;
        raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY;

        return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
                                       get_raw_key_details, &raw_key);
    }

    if (pkey->ameth == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

    if (pkey->ameth->get_priv_key == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

    if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
        ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED);
        return 0;
    }

    return 1;
}

int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
                                size_t *len)
{
    if (pkey->keymgmt != NULL) {
        struct raw_key_details_st raw_key;

        raw_key.key = pub == NULL ? NULL : &pub;
        raw_key.len = len;
        raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY;

        return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
                                       get_raw_key_details, &raw_key);
    }

    if (pkey->ameth == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

     if (pkey->ameth->get_pub_key == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

    if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
        ERR_raise(ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED);
        return 0;
    }

    return 1;
}

static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len,
                                  const char *cipher_name,
                                  const EVP_CIPHER *cipher,
                                  OSSL_LIB_CTX *libctx,
                                  const char *propq, ENGINE *e)
{
# ifndef OPENSSL_NO_CMAC
#  ifndef OPENSSL_NO_ENGINE
    const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
#  endif
    OSSL_PARAM params[5], *p = params;
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx;

    if (cipher != NULL)
        cipher_name = EVP_CIPHER_get0_name(cipher);

    if (cipher_name == NULL) {
        ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
        return NULL;
    }

    ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq);
    if (ctx == NULL)
        goto err;

    if (EVP_PKEY_fromdata_init(ctx) <= 0) {
        ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
        goto err;
    }

    *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
                                            (void *)priv, len);
    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER,
                                            (char *)cipher_name, 0);
    if (propq != NULL)
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES,
                                                (char *)propq, 0);
#  ifndef OPENSSL_NO_ENGINE
    if (engine_id != NULL)
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE,
                                                (char *)engine_id, 0);
#  endif
    *p = OSSL_PARAM_construct_end();

    if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
        ERR_raise(ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED);
        goto err;
    }

 err:
    EVP_PKEY_CTX_free(ctx);

    return pkey;
# else
    ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    return NULL;
# endif
}

EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                size_t len, const EVP_CIPHER *cipher)
{
    return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e);
}

int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
{
    return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
}

int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
{
    return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
}

# ifndef OPENSSL_NO_ENGINE
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
{
    if (e != NULL) {
        if (!ENGINE_init(e)) {
            ERR_raise(ERR_LIB_EVP, ERR_R_ENGINE_LIB);
            return 0;
        }
        if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
            ENGINE_finish(e);
            ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM);
            return 0;
        }
    }
    ENGINE_finish(pkey->pmeth_engine);
    pkey->pmeth_engine = e;
    return 1;
}

ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
{
    return pkey->engine;
}
# endif

# ifndef OPENSSL_NO_DEPRECATED_3_0
static void detect_foreign_key(EVP_PKEY *pkey)
{
    switch (pkey->type) {
    case EVP_PKEY_RSA:
        pkey->foreign = pkey->pkey.rsa != NULL
                        && ossl_rsa_is_foreign(pkey->pkey.rsa);
        break;
#  ifndef OPENSSL_NO_EC
    case EVP_PKEY_SM2:
    case EVP_PKEY_EC:
        pkey->foreign = pkey->pkey.ec != NULL
                        && ossl_ec_key_is_foreign(pkey->pkey.ec);
        break;
#  endif
#  ifndef OPENSSL_NO_DSA
    case EVP_PKEY_DSA:
        pkey->foreign = pkey->pkey.dsa != NULL
                        && ossl_dsa_is_foreign(pkey->pkey.dsa);
        break;
#endif
#  ifndef OPENSSL_NO_DH
    case EVP_PKEY_DH:
        pkey->foreign = pkey->pkey.dh != NULL
                        && ossl_dh_is_foreign(pkey->pkey.dh);
        break;
#endif
    default:
        pkey->foreign = 0;
        break;
    }
}

int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
#  ifndef OPENSSL_NO_EC
    int pktype;

    pktype = EVP_PKEY_type(type);
    if ((key != NULL) && (pktype == EVP_PKEY_EC || pktype == EVP_PKEY_SM2)) {
        const EC_GROUP *group = EC_KEY_get0_group(key);

        if (group != NULL) {
            int curve = EC_GROUP_get_curve_name(group);

            /*
             * Regardless of what is requested the SM2 curve must be SM2 type,
             * and non SM2 curves are EC type.
             */
            if (curve == NID_sm2 && pktype == EVP_PKEY_EC)
                type = EVP_PKEY_SM2;
            else if(curve != NID_sm2 && pktype == EVP_PKEY_SM2)
                type = EVP_PKEY_EC;
        }
    }
#  endif

    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
        return 0;

    pkey->pkey.ptr = key;
    detect_foreign_key(pkey);

    return (key != NULL);
}
# endif

void *EVP_PKEY_get0(const EVP_PKEY *pkey)
{
    if (pkey == NULL)
        return NULL;

    if (!evp_pkey_is_provided(pkey))
        return pkey->pkey.ptr;

    return NULL;
}

const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
{
    const ASN1_OCTET_STRING *os = NULL;
    if (pkey->type != EVP_PKEY_HMAC) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY);
        return NULL;
    }
    os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
    if (os != NULL) {
        *len = os->length;
        return os->data;
    }
    return NULL;
}

# ifndef OPENSSL_NO_POLY1305
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
{
    const ASN1_OCTET_STRING *os = NULL;
    if (pkey->type != EVP_PKEY_POLY1305) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY);
        return NULL;
    }
    os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
    if (os != NULL) {
        *len = os->length;
        return os->data;
    }
    return NULL;
}
# endif

# ifndef OPENSSL_NO_SIPHASH
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
{
    const ASN1_OCTET_STRING *os = NULL;

    if (pkey->type != EVP_PKEY_SIPHASH) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY);
        return NULL;
    }
    os = evp_pkey_get_legacy((EVP_PKEY *)pkey);
    if (os != NULL) {
        *len = os->length;
        return os->data;
    }
    return NULL;
}
# endif

# ifndef OPENSSL_NO_DSA
static DSA *evp_pkey_get0_DSA_int(const EVP_PKEY *pkey)
{
    if (pkey->type != EVP_PKEY_DSA) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY);
        return NULL;
    }
    return evp_pkey_get_legacy((EVP_PKEY *)pkey);
}

const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
{
    return evp_pkey_get0_DSA_int(pkey);
}

int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
{
    int ret = EVP_PKEY_assign_DSA(pkey, key);
    if (ret)
        DSA_up_ref(key);
    return ret;
}
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
{
    DSA *ret = evp_pkey_get0_DSA_int(pkey);

    if (ret != NULL)
        DSA_up_ref(ret);
    return ret;
}
# endif /*  OPENSSL_NO_DSA */

# ifndef OPENSSL_NO_EC
static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type)
{
    if (EVP_PKEY_get_base_id(pkey) != type) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY);
        return NULL;
    }
    return evp_pkey_get_legacy((EVP_PKEY *)pkey);
}

static ECX_KEY *evp_pkey_get1_ECX_KEY(EVP_PKEY *pkey, int type)
{
    ECX_KEY *ret = (ECX_KEY *)evp_pkey_get0_ECX_KEY(pkey, type);

    if (ret != NULL && !ossl_ecx_key_up_ref(ret))
        ret = NULL;
    return ret;
}

#  define IMPLEMENT_ECX_VARIANT(NAME)                                   \
    ECX_KEY *ossl_evp_pkey_get1_##NAME(EVP_PKEY *pkey)                  \
    {                                                                   \
        return evp_pkey_get1_ECX_KEY(pkey, EVP_PKEY_##NAME);            \
    }
IMPLEMENT_ECX_VARIANT(X25519)
IMPLEMENT_ECX_VARIANT(X448)
IMPLEMENT_ECX_VARIANT(ED25519)
IMPLEMENT_ECX_VARIANT(ED448)

# endif

# if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)

int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey)
{
    int ret, type;

    /*
     * ossl_dh_is_named_safe_prime_group() returns 1 for named safe prime groups
     * related to ffdhe and modp (which cache q = (p - 1) / 2),
     * and returns 0 for all other dh parameter generation types including
     * RFC5114 named groups.
     *
     * The EVP_PKEY_DH type is used for dh parameter generation types:
     *  - named safe prime groups related to ffdhe and modp
     *  - safe prime generator
     *
     * The type EVP_PKEY_DHX is used for dh parameter generation types
     *  - fips186-4 and fips186-2
     *  - rfc5114 named groups.
     *
     * The EVP_PKEY_DH type is used to save PKCS#3 data than can be stored
     * without a q value.
     * The EVP_PKEY_DHX type is used to save X9.42 data that requires the
     * q value to be stored.
     */
    if (ossl_dh_is_named_safe_prime_group(dhkey))
        type = EVP_PKEY_DH;
    else
        type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;

    ret = EVP_PKEY_assign(pkey, type, dhkey);

    if (ret)
        DH_up_ref(dhkey);
    return ret;
}

DH *evp_pkey_get0_DH_int(const EVP_PKEY *pkey)
{
    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
        ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY);
        return NULL;
    }
    return evp_pkey_get_legacy((EVP_PKEY *)pkey);
}

const DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
{
    return evp_pkey_get0_DH_int(pkey);
}

DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
{
    DH *ret = evp_pkey_get0_DH_int(pkey);

    if (ret != NULL)
        DH_up_ref(ret);
    return ret;
}
# endif

int EVP_PKEY_type(int type)
{
    int ret;
    const EVP_PKEY_ASN1_METHOD *ameth;
    ENGINE *e;
    ameth = EVP_PKEY_asn1_find(&e, type);
    if (ameth)
        ret = ameth->pkey_id;
    else
        ret = NID_undef;
# ifndef OPENSSL_NO_ENGINE
    ENGINE_finish(e);
# endif
    return ret;
}

int EVP_PKEY_get_id(const EVP_PKEY *pkey)
{
    return pkey->type;
}

int EVP_PKEY_get_base_id(const EVP_PKEY *pkey)
{
    return EVP_PKEY_type(pkey->type);
}

/*
 * These hard coded cases are pure hackery to get around the fact
 * that names in crypto/objects/objects.txt are a mess.  There is
 * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's
 * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1,
 * the NID of which is used for EVP_PKEY_RSA.  Strangely enough,
 * "DSA" is accurate...  but still, better be safe and hard-code
 * names that we know.
 * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in
 * EVP_PKEY_EC, because of aliasing.
 * This should be cleaned away along with all other #legacy support.
 */
static const OSSL_ITEM standard_name2type[] = {
    { EVP_PKEY_RSA,     "RSA" },
    { EVP_PKEY_RSA_PSS, "RSA-PSS" },
    { EVP_PKEY_EC,      "EC" },
    { EVP_PKEY_ED25519, "ED25519" },
    { EVP_PKEY_ED448,   "ED448" },
    { EVP_PKEY_X25519,  "X25519" },
    { EVP_PKEY_X448,    "X448" },
    { EVP_PKEY_SM2,     "SM2" },
    { EVP_PKEY_DH,      "DH" },
    { EVP_PKEY_DHX,     "X9.42 DH" },
    { EVP_PKEY_DHX,     "DHX" },
    { EVP_PKEY_DSA,     "DSA" },
};

int evp_pkey_name2type(const char *name)
{
    int type;
    size_t i;

    for (i = 0; i < OSSL_NELEM(standard_name2type); i++) {
        if (OPENSSL_strcasecmp(name, standard_name2type[i].ptr) == 0)
            return (int)standard_name2type[i].id;
    }

    if ((type = EVP_PKEY_type(OBJ_sn2nid(name))) != NID_undef)
        return type;
    return EVP_PKEY_type(OBJ_ln2nid(name));
}

const char *evp_pkey_type2name(int type)
{
    size_t i;

    for (i = 0; i < OSSL_NELEM(standard_name2type); i++) {
        if (type == (int)standard_name2type[i].id)
            return standard_name2type[i].ptr;
    }

    return OBJ_nid2sn(type);
}

int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
{
    if (pkey->keymgmt == NULL) {
        int type = evp_pkey_name2type(name);

        return pkey->type == type;
    }
    return EVP_KEYMGMT_is_a(pkey->keymgmt, name);
}

int EVP_PKEY_type_names_do_all(const EVP_PKEY *pkey,
                               void (*fn)(const char *name, void *data),
                               void *data)
{
    if (!evp_pkey_is_typed(pkey))
        return 0;

    if (!evp_pkey_is_provided(pkey)) {
        const char *name = OBJ_nid2sn(EVP_PKEY_get_id(pkey));

        fn(name, data);
        return 1;
    }
    return EVP_KEYMGMT_names_do_all(pkey->keymgmt, fn, data);
}

int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
{
    if (pkey->keymgmt == NULL) {
        switch (EVP_PKEY_get_base_id(pkey)) {
        case EVP_PKEY_RSA:
            return 1;
# ifndef OPENSSL_NO_DSA
        case EVP_PKEY_DSA:
            return 1;
# endif
# ifndef OPENSSL_NO_EC
        case EVP_PKEY_ED25519:
        case EVP_PKEY_ED448:
            return 1;
        case EVP_PKEY_EC:        /* Including SM2 */
            return EC_KEY_can_sign(pkey->pkey.ec);
# endif
        default:
            break;
        }
    } else {
        const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);
        OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov);
        const char *supported_sig =
            pkey->keymgmt->query_operation_name != NULL
            ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE)
            : EVP_KEYMGMT_get0_name(pkey->keymgmt);
        EVP_SIGNATURE *signature = NULL;

        signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL);
        if (signature != NULL) {
            EVP_SIGNATURE_free(signature);
            return 1;
        }
    }
    return 0;
}

static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
{
    BIO_set_indent(*out, saved_indent);
    if (pop_f_prefix) {
        BIO *next = BIO_pop(*out);

        BIO_free(*out);
        *out = next;
    }
    return 1;
}

static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
                            long indent)
{
    *pop_f_prefix = 0;
    *saved_indent = 0;
    if (indent > 0) {
        long i = BIO_get_indent(*out);

        *saved_indent =  (i < 0 ? 0 : i);
        if (BIO_set_indent(*out, indent) <= 0) {
            if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL)
                return 0;
            *pop_f_prefix = 1;
        }
        if (BIO_set_indent(*out, indent) <= 0) {
            print_reset_indent(out, *pop_f_prefix, *saved_indent);
            return 0;
        }
    }
    return 1;
}

static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
                     const char *kstr)
{
    return BIO_indent(out, indent, 128)
        && BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
                      kstr, OBJ_nid2ln(pkey->type)) > 0;
}

static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
                      int selection /* For provided encoding */,
                      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_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_ENCODER_CTX_new_for_pkey(pkey, selection, "TEXT", NULL,
                                        propquery);
    if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0)
        ret = OSSL_ENCODER_to_bio(ctx, out);
    OSSL_ENCODER_CTX_free(ctx);

    if (ret != -2)
        goto end;

    /* legacy fallback */
    if (legacy_print != NULL)
        ret = legacy_print(out, pkey, 0, legacy_pctx);
    else
        ret = unsup_alg(out, pkey, 0, "Public Key");

 end:
    print_reset_indent(&out, pop_f_prefix, saved_indent);
    return ret;
}

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx)
{
    return print_pkey(pkey, out, indent, EVP_PKEY_PUBLIC_KEY, NULL,
                      (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
                      pctx);
}

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
{
    return print_pkey(pkey, out, indent, EVP_PKEY_KEYPAIR, NULL,
                      (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
                      pctx);
}

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                          int indent, ASN1_PCTX *pctx)
{
    return print_pkey(pkey, out, indent, EVP_PKEY_KEY_PARAMETERS, NULL,
                      (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
                      pctx);
}

# ifndef OPENSSL_NO_STDIO
int EVP_PKEY_print_public_fp(FILE *fp, const EVP_PKEY *pkey,
                             int indent, ASN1_PCTX *pctx)
{
    int ret;
    BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);

    if (b == NULL)
        return 0;
    ret = EVP_PKEY_print_public(b, pkey, indent, pctx);
    BIO_free(b);
    return ret;
}

int EVP_PKEY_print_private_fp(FILE *fp, const EVP_PKEY *pkey,
                              int indent, ASN1_PCTX *pctx)
{
    int ret;
    BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);

    if (b == NULL)
        return 0;
    ret = EVP_PKEY_print_private(b, pkey, indent, pctx);
    BIO_free(b);
    return ret;
}

int EVP_PKEY_print_params_fp(FILE *fp, const EVP_PKEY *pkey,
                             int indent, ASN1_PCTX *pctx)
{
    int ret;
    BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);

    if (b == NULL)
        return 0;
    ret = EVP_PKEY_print_params(b, pkey, indent, pctx);
    BIO_free(b);
    return ret;
}
# endif

static void mdname2nid(const char *mdname, void *data)
{
    int *nid = (int *)data;

    if (*nid != NID_undef)
        return;

    *nid = OBJ_sn2nid(mdname);
    if (*nid == NID_undef)
        *nid = OBJ_ln2nid(mdname);
}

static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
                                     int arg1, void *arg2)
{
    if (pkey->keymgmt == NULL)
        return 0;
    switch (op) {
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
        {
            char mdname[80] = "";
            int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
                                                      sizeof(mdname));

            if (rv > 0) {
                int mdnum;
                OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkey->keymgmt->prov);
                /* Make sure the MD is in the namemap if available */
                EVP_MD *md;
                OSSL_NAMEMAP *namemap;
                int nid = NID_undef;

                (void)ERR_set_mark();
                md = EVP_MD_fetch(libctx, mdname, NULL);
                (void)ERR_pop_to_mark();
                namemap = ossl_namemap_stored(libctx);

                /*
                 * The only reason to fetch the MD was to make sure it is in the
                 * namemap. We can immediately free it.
                 */
                EVP_MD_free(md);
                mdnum = ossl_namemap_name2num(namemap, mdname);
                if (mdnum == 0)
                    return 0;

                /*
                 * We have the namemap number - now we need to find the
                 * associated nid
                 */
                if (!ossl_namemap_doall_names(namemap, mdnum, mdname2nid, &nid))
                    return 0;
                *(int *)arg2 = nid;
            }
            return rv;
        }
    default:
        return -2;
    }
}

static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
{
    if (pkey->ameth == NULL)
        return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
    if (pkey->ameth->pkey_ctrl == NULL)
        return -2;
    return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
}

int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
{
    return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
}

int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
                                     char *mdname, size_t mdname_sz)
{
    if (pkey->ameth == NULL)
        return evp_keymgmt_util_get_deflt_digest_name(pkey->keymgmt,
                                                      pkey->keydata,
                                                      mdname, mdname_sz);

    {
        int nid = NID_undef;
        int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
        const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;

        if (rv > 0)
            OPENSSL_strlcpy(mdname, name, mdname_sz);
        return rv;
    }
}

int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *gname, size_t gname_sz,
                            size_t *gname_len)
{
    return EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
                                          gname, gname_sz, gname_len);
}

int EVP_PKEY_digestsign_supports_digest(EVP_PKEY *pkey, OSSL_LIB_CTX *libctx,
                                        const char *name, const char *propq)
{
    int rv;
    EVP_MD_CTX *ctx = NULL;

    if ((ctx = EVP_MD_CTX_new()) == NULL)
        return -1;

    ERR_set_mark();
    rv = EVP_DigestSignInit_ex(ctx, NULL, name, libctx,
                               propq, pkey, NULL);
    ERR_pop_to_mark();

    EVP_MD_CTX_free(ctx);
    return rv;
}

int EVP_PKEY_set1_encoded_public_key(EVP_PKEY *pkey, const unsigned char *pub,
                                     size_t publen)
{
    if (pkey != NULL && evp_pkey_is_provided(pkey))
        return
            EVP_PKEY_set_octet_string_param(pkey,
                                            OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
                                            (unsigned char *)pub, publen);

    if (publen > INT_MAX)
        return 0;
    /* Historically this function was EVP_PKEY_set1_tls_encodedpoint */
    if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, publen,
                           (void *)pub) <= 0)
        return 0;
    return 1;
}

size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY *pkey, unsigned char **ppub)
{
    int rv;

    if (pkey != NULL && evp_pkey_is_provided(pkey)) {
        size_t return_size = OSSL_PARAM_UNMODIFIED;

        /*
         * We know that this is going to fail, but it will give us a size
         * to allocate.
         */
        EVP_PKEY_get_octet_string_param(pkey,
                                        OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
                                        NULL, 0, &return_size);
        if (return_size == OSSL_PARAM_UNMODIFIED)
            return 0;

        *ppub = OPENSSL_malloc(return_size);
        if (*ppub == NULL)
            return 0;

        if (!EVP_PKEY_get_octet_string_param(pkey,
                                             OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY,
                                             *ppub, return_size, NULL))
            return 0;
        return return_size;
    }


    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppub);
    if (rv <= 0)
        return 0;
    return rv;
}

#endif /* FIPS_MODULE */

/*- All methods below can also be used in FIPS_MODULE */

EVP_PKEY *EVP_PKEY_new(void)
{
    EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));

    if (ret == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    ret->type = EVP_PKEY_NONE;
    ret->save_type = EVP_PKEY_NONE;
    ret->references = 1;

    ret->lock = CRYPTO_THREAD_lock_new();
    if (ret->lock == NULL) {
        EVPerr(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
        goto err;
    }

#ifndef FIPS_MODULE
    ret->save_parameters = 1;
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
        goto err;
    }
#endif
    return ret;

 err:
    CRYPTO_THREAD_lock_free(ret->lock);
    OPENSSL_free(ret);
    return NULL;
}

/*
 * Setup a public key management method.
 *
 * For legacy keys, either |type| or |str| is expected to have the type
 * information.  In this case, the setup consists of finding an ASN1 method
 * and potentially an ENGINE, and setting those fields in |pkey|.
 *
 * For provider side keys, |keymgmt| is expected to be non-NULL.  In this
 * case, the setup consists of setting the |keymgmt| field in |pkey|.
 *
 * If pkey is NULL just return 1 or 0 if the key management method exists.
 */

static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
                         int len, EVP_KEYMGMT *keymgmt)
{
#ifndef FIPS_MODULE
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;
    ENGINE **eptr = (e == NULL) ? &e :  NULL;
#endif

    /*
     * The setups can't set both legacy and provider side methods.
     * It is forbidden
     */
    if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL)
        || !ossl_assert(e == NULL || keymgmt == NULL)) {
        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    if (pkey != NULL) {
        int free_it = 0;

#ifndef FIPS_MODULE
        free_it = free_it || pkey->pkey.ptr != NULL;
#endif
        free_it = free_it || pkey->keydata != NULL;
        if (free_it)
            evp_pkey_free_it(pkey);
#ifndef FIPS_MODULE
        /*
         * If key type matches and a method exists then this lookup has
         * succeeded once so just indicate success.
         */
        if (pkey->type != EVP_PKEY_NONE
            && type == pkey->save_type
            && pkey->ameth != NULL)
            return 1;
# ifndef OPENSSL_NO_ENGINE
        /* If we have ENGINEs release them */
        ENGINE_finish(pkey->engine);
        pkey->engine = NULL;
        ENGINE_finish(pkey->pmeth_engine);
        pkey->pmeth_engine = NULL;
# endif
#endif
    }
#ifndef FIPS_MODULE
    if (str != NULL)
        ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
    else if (type != EVP_PKEY_NONE)
        ameth = EVP_PKEY_asn1_find(eptr, type);
# ifndef OPENSSL_NO_ENGINE
    if (pkey == NULL && eptr != NULL)
        ENGINE_finish(e);
# endif
#endif


    {
        int check = 1;

#ifndef FIPS_MODULE
        check = check && ameth == NULL;
#endif
        check = check && keymgmt == NULL;
        if (check) {
            ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM);
            return 0;
        }
    }
    if (pkey != NULL) {
        if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) {
            ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
            return 0;
        }

        pkey->keymgmt = keymgmt;

        pkey->save_type = type;
        pkey->type = type;

#ifndef FIPS_MODULE
        /*
         * If the internal "origin" key is provider side, don't save |ameth|.
         * The main reason is that |ameth| is one factor to detect that the
         * internal "origin" key is a legacy one.
         */
        if (keymgmt == NULL)
            pkey->ameth = ameth;

        /*
         * The EVP_PKEY_ASN1_METHOD |pkey_id| retains its legacy key purpose
         * for any key type that has a legacy implementation, regardless of
         * if the internal key is a legacy or a provider side one.  When
         * there is no legacy implementation for the key, the type becomes
         * EVP_PKEY_KEYMGMT, which indicates that one should be cautious
         * with functions that expect legacy internal keys.
         */
        if (ameth != NULL) {
            if (type == EVP_PKEY_NONE)
                pkey->type = ameth->pkey_id;
        } else {
            pkey->type = EVP_PKEY_KEYMGMT;
        }
# ifndef OPENSSL_NO_ENGINE
        if (eptr == NULL && e != NULL && !ENGINE_init(e)) {
            ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
            return 0;
        }
# endif
        pkey->engine = e;
#endif
    }
    return 1;
}

#ifndef FIPS_MODULE
static void find_ameth(const char *name, void *data)
{
    const char **str = data;

    /*
     * The error messages from pkey_set_type() are uninteresting here,
     * and misleading.
     */
    ERR_set_mark();

    if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name),
                      NULL)) {
        if (str[0] == NULL)
            str[0] = name;
        else if (str[1] == NULL)
            str[1] = name;
    }

    ERR_pop_to_mark();
}
#endif

int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
{
#ifndef FIPS_MODULE
# define EVP_PKEY_TYPE_STR str[0]
# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
    /*
     * Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD
     * Ideally, only one should be found.  If two (or more) are found, the
     * match is ambiguous.  This should never happen, but...
     */
    const char *str[2] = { NULL, NULL };

    if (!EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str)
            || str[1] != NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
        return 0;
    }
#else
# define EVP_PKEY_TYPE_STR NULL
# define EVP_PKEY_TYPE_STRLEN -1
#endif
    return pkey_set_type(pkey, NULL, EVP_PKEY_NONE,
                         EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN,
                         keymgmt);

#undef EVP_PKEY_TYPE_STR
#undef EVP_PKEY_TYPE_STRLEN
}

int EVP_PKEY_up_ref(EVP_PKEY *pkey)
{
    int i;

    if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
        return 0;

    REF_PRINT_COUNT("EVP_PKEY", pkey);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
}

#ifndef FIPS_MODULE
EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
{
    EVP_PKEY *dup_pk;

    if (pkey == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }

    if ((dup_pk = EVP_PKEY_new()) == NULL)
        return NULL;

    if (evp_pkey_is_blank(pkey))
        goto done;

    if (evp_pkey_is_provided(pkey)) {
        if (!evp_keymgmt_util_copy(dup_pk, pkey,
                                   OSSL_KEYMGMT_SELECT_ALL))
            goto err;
        goto done;
    }

    if (evp_pkey_is_legacy(pkey)) {
        const EVP_PKEY_ASN1_METHOD *ameth = pkey->ameth;

        if (ameth == NULL || ameth->copy == NULL) {
            if (pkey->pkey.ptr == NULL /* empty key, just set type */
                && EVP_PKEY_set_type(dup_pk, pkey->type) != 0)
                goto done;
            ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE);
            goto err;
        }
        if (!ameth->copy(dup_pk, pkey))
            goto err;
        goto done;
    }

    goto err;
done:
    /* copy auxiliary data */
    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EVP_PKEY,
                            &dup_pk->ex_data, &pkey->ex_data))
        goto err;

    if (pkey->attributes != NULL) {
        if ((dup_pk->attributes = ossl_x509at_dup(pkey->attributes)) == NULL)
            goto err;
    }
    return dup_pk;
err:
    EVP_PKEY_free(dup_pk);
    return NULL;
}

void evp_pkey_free_legacy(EVP_PKEY *x)
{
    const EVP_PKEY_ASN1_METHOD *ameth = x->ameth;
    ENGINE *tmpe = NULL;

    if (ameth == NULL && x->legacy_cache_pkey.ptr != NULL)
        ameth = EVP_PKEY_asn1_find(&tmpe, x->type);

    if (ameth != NULL) {
        if (x->legacy_cache_pkey.ptr != NULL) {
            /*
             * We should never have both a legacy origin key, and a key in the
             * legacy cache.
             */
            assert(x->pkey.ptr == NULL);
            /*
             * For the purposes of freeing we make the legacy cache look like
             * a legacy origin key.
             */
            x->pkey = x->legacy_cache_pkey;
            x->legacy_cache_pkey.ptr = NULL;
        }
        if (ameth->pkey_free != NULL)
            ameth->pkey_free(x);
        x->pkey.ptr = NULL;
    }
# ifndef OPENSSL_NO_ENGINE
    ENGINE_finish(tmpe);
    ENGINE_finish(x->engine);
    x->engine = NULL;
    ENGINE_finish(x->pmeth_engine);
    x->pmeth_engine = NULL;
# endif
}
#endif  /* FIPS_MODULE */

static void evp_pkey_free_it(EVP_PKEY *x)
{
    /* internal function; x is never NULL */
    evp_keymgmt_util_clear_operation_cache(x, 1);
#ifndef FIPS_MODULE
    evp_pkey_free_legacy(x);
#endif

    if (x->keymgmt != NULL) {
        evp_keymgmt_freedata(x->keymgmt, x->keydata);
        EVP_KEYMGMT_free(x->keymgmt);
        x->keymgmt = NULL;
        x->keydata = NULL;
    }
    x->type = EVP_PKEY_NONE;
}

void EVP_PKEY_free(EVP_PKEY *x)
{
    int i;

    if (x == NULL)
        return;

    CRYPTO_DOWN_REF(&x->references, &i, x->lock);
    REF_PRINT_COUNT("EVP_PKEY", x);
    if (i > 0)
        return;
    REF_ASSERT_ISNT(i < 0);
    evp_pkey_free_it(x);
#ifndef FIPS_MODULE
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
#endif
    CRYPTO_THREAD_lock_free(x->lock);
#ifndef FIPS_MODULE
    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
#endif
    OPENSSL_free(x);
}

int EVP_PKEY_get_size(const EVP_PKEY *pkey)
{
    int size = 0;

    if (pkey != NULL) {
        size = pkey->cache.size;
#ifndef FIPS_MODULE
        if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
            size = pkey->ameth->pkey_size(pkey);
#endif
    }
    return size < 0 ? 0 : size;
}

const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey)
{
    if (!evp_pkey_is_assigned(pkey))
        return NULL;

    if (evp_pkey_is_provided(pkey) && pkey->keymgmt->description != NULL)
        return pkey->keymgmt->description;
#ifndef FIPS_MODULE
    if (pkey->ameth != NULL)
        return pkey->ameth->info;
#endif
    return NULL;
}

void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx,
                                  EVP_KEYMGMT **keymgmt,
                                  const char *propquery)
{
    EVP_KEYMGMT *allocated_keymgmt = NULL;
    EVP_KEYMGMT *tmp_keymgmt = NULL;
    void *keydata = NULL;
    int check;

    if (pk == NULL)
        return NULL;

    /* No key data => nothing to export */
    check = 1;
#ifndef FIPS_MODULE
    check = check && pk->pkey.ptr == NULL;
#endif
    check = check && pk->keydata == NULL;
    if (check)
        return NULL;

#ifndef FIPS_MODULE
    if (pk->pkey.ptr != NULL) {
        /*
         * If the legacy key doesn't have an dirty counter or export function,
         * give up
         */
        if (pk->ameth->dirty_cnt == NULL || pk->ameth->export_to == NULL)
            return NULL;
    }
#endif

    if (keymgmt != NULL) {
        tmp_keymgmt = *keymgmt;
        *keymgmt = NULL;
    }

    /*
     * If no keymgmt was given or found, get a default keymgmt.  We do so by
     * letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it.
     */
    if (tmp_keymgmt == NULL) {
        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);

        if (ctx == NULL)
            goto end;
        tmp_keymgmt = ctx->keymgmt;
        ctx->keymgmt = NULL;
        EVP_PKEY_CTX_free(ctx);
    }

    /* If there's still no keymgmt to be had, give up */
    if (tmp_keymgmt == NULL)
        goto end;

#ifndef FIPS_MODULE
    if (pk->pkey.ptr != NULL) {
        OP_CACHE_ELEM *op;

        /*
         * If the legacy "origin" hasn't changed since last time, we try
         * to find our keymgmt in the operation cache.  If it has changed,
         * |i| remains zero, and we will clear the cache further down.
         */
        if (pk->ameth->dirty_cnt(pk) == pk->dirty_cnt_copy) {
            if (!CRYPTO_THREAD_read_lock(pk->lock))
                goto end;
            op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt);

            /*
             * If |tmp_keymgmt| is present in the operation cache, it means
             * that export doesn't need to be redone.  In that case, we take
             * token copies of the cached pointers, to have token success
             * values to return.
             */
            if (op != NULL && op->keymgmt != NULL) {
                keydata = op->keydata;
                CRYPTO_THREAD_unlock(pk->lock);
                goto end;
            }
            CRYPTO_THREAD_unlock(pk->lock);
        }

        /* Make sure that the keymgmt key type matches the legacy NID */
        if (!EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type)))
            goto end;

        if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
            goto end;

        if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt->import,
                                  libctx, propquery)) {
            evp_keymgmt_freedata(tmp_keymgmt, keydata);
            keydata = NULL;
            goto end;
        }

        /*
         * If the dirty counter changed since last time, then clear the
         * operation cache.  In that case, we know that |i| is zero.  Just
         * in case this is a re-export, we increment then decrement the
         * keymgmt reference counter.
         */
        if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { /* refcnt++ */
            evp_keymgmt_freedata(tmp_keymgmt, keydata);
            keydata = NULL;
            goto end;
        }

        if (!CRYPTO_THREAD_write_lock(pk->lock))
            goto end;
        if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy
                && !evp_keymgmt_util_clear_operation_cache(pk, 0)) {
            CRYPTO_THREAD_unlock(pk->lock);
            evp_keymgmt_freedata(tmp_keymgmt, keydata);
            keydata = NULL;
            EVP_KEYMGMT_free(tmp_keymgmt);
            goto end;
        }
        EVP_KEYMGMT_free(tmp_keymgmt); /* refcnt-- */

        /* Check to make sure some other thread didn't get there first */
        op = evp_keymgmt_util_find_operation_cache(pk, tmp_keymgmt);
        if (op != NULL && op->keymgmt != NULL) {
            void *tmp_keydata = op->keydata;

            CRYPTO_THREAD_unlock(pk->lock);
            evp_keymgmt_freedata(tmp_keymgmt, keydata);
            keydata = tmp_keydata;
            goto end;
        }

        /* Add the new export to the operation cache */
        if (!evp_keymgmt_util_cache_keydata(pk, tmp_keymgmt, keydata)) {
            CRYPTO_THREAD_unlock(pk->lock);
            evp_keymgmt_freedata(tmp_keymgmt, keydata);
            keydata = NULL;
            goto end;
        }

        /* Synchronize the dirty count */
        pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);

        CRYPTO_THREAD_unlock(pk->lock);
        goto end;
    }
#endif  /* FIPS_MODULE */

    keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);

 end:
    /*
     * If nothing was exported, |tmp_keymgmt| might point at a freed
     * EVP_KEYMGMT, so we clear it to be safe.  It shouldn't be useful for
     * the caller either way in that case.
     */
    if (keydata == NULL)
        tmp_keymgmt = NULL;

    if (keymgmt != NULL)
        *keymgmt = tmp_keymgmt;

    EVP_KEYMGMT_free(allocated_keymgmt);
    return keydata;
}

#ifndef FIPS_MODULE
int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src)
{
    if (!ossl_assert(dest != NULL))
        return 0;

    if (evp_pkey_is_assigned(src) && evp_pkey_is_provided(src)) {
        EVP_KEYMGMT *keymgmt = src->keymgmt;
        void *keydata = src->keydata;
        int type = src->type;
        const char *keytype = NULL;

        keytype = EVP_KEYMGMT_get0_name(keymgmt);

        /*
         * If the type is EVP_PKEY_NONE, then we have a problem somewhere
         * else in our code.  If it's not one of the well known EVP_PKEY_xxx
         * values, it should at least be EVP_PKEY_KEYMGMT at this point.
         * The check is kept as a safety measure.
         */
        if (!ossl_assert(type != EVP_PKEY_NONE)) {
            ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
                           "keymgmt key type = %s but legacy type = EVP_PKEY_NONE",
                           keytype);
            return 0;
        }

        /* Prefer the legacy key type name for error reporting */
        if (type != EVP_PKEY_KEYMGMT)
            keytype = OBJ_nid2sn(type);

        /* Make sure we have a clean slate to copy into */
        if (*dest == NULL) {
            *dest = EVP_PKEY_new();
            if (*dest == NULL) {
                ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
                return 0;
            }
        } else {
            evp_pkey_free_it(*dest);
        }

        if (EVP_PKEY_set_type(*dest, type)) {
            /* If the key is typed but empty, we're done */
            if (keydata == NULL)
                return 1;

            if ((*dest)->ameth->import_from == NULL) {
                ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
                               "key type = %s", keytype);
            } else {
                /*
                 * We perform the export in the same libctx as the keymgmt
                 * that we are using.
                 */
                OSSL_LIB_CTX *libctx =
                    ossl_provider_libctx(keymgmt->prov);
                EVP_PKEY_CTX *pctx =
                    EVP_PKEY_CTX_new_from_pkey(libctx, *dest, NULL);

                if (pctx == NULL)
                    ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);

                if (pctx != NULL
                    && evp_keymgmt_export(keymgmt, keydata,
                                          OSSL_KEYMGMT_SELECT_ALL,
                                          (*dest)->ameth->import_from,
                                          pctx)) {
                    /* Synchronize the dirty count */
                    (*dest)->dirty_cnt_copy = (*dest)->ameth->dirty_cnt(*dest);

                    EVP_PKEY_CTX_free(pctx);
                    return 1;
                }
                EVP_PKEY_CTX_free(pctx);
            }

            ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,
                           "key type = %s", keytype);
        }
    }

    return 0;
}

void *evp_pkey_get_legacy(EVP_PKEY *pk)
{
    EVP_PKEY *tmp_copy = NULL;
    void *ret = NULL;

    if (!ossl_assert(pk != NULL))
        return NULL;

    /*
     * If this isn't an assigned provider side key, we just use any existing
     * origin legacy key.
     */
    if (!evp_pkey_is_assigned(pk))
        return NULL;
    if (!evp_pkey_is_provided(pk))
        return pk->pkey.ptr;

    if (!CRYPTO_THREAD_read_lock(pk->lock))
        return NULL;

    ret = pk->legacy_cache_pkey.ptr;

    if (!CRYPTO_THREAD_unlock(pk->lock))
        return NULL;

    if (ret != NULL)
        return ret;

    if (!evp_pkey_copy_downgraded(&tmp_copy, pk))
        return NULL;

    if (!CRYPTO_THREAD_write_lock(pk->lock))
        goto err;

    /* Check again in case some other thread has updated it in the meantime */
    ret = pk->legacy_cache_pkey.ptr;
    if (ret == NULL) {
        /* Steal the legacy key reference from the temporary copy */
        ret = pk->legacy_cache_pkey.ptr = tmp_copy->pkey.ptr;
        tmp_copy->pkey.ptr = NULL;
    }

    if (!CRYPTO_THREAD_unlock(pk->lock)) {
        ret = NULL;
        goto err;
    }

 err:
    EVP_PKEY_free(tmp_copy);

    return ret;
}
#endif  /* FIPS_MODULE */

int EVP_PKEY_get_bn_param(const EVP_PKEY *pkey, const char *key_name,
                          BIGNUM **bn)
{
    int ret = 0;
    OSSL_PARAM params[2];
    unsigned char buffer[2048];
    unsigned char *buf = NULL;
    size_t buf_sz = 0;

    if (key_name == NULL
        || bn == NULL)
        return 0;

    memset(buffer, 0, sizeof(buffer));
    params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
    params[1] = OSSL_PARAM_construct_end();
    if (!EVP_PKEY_get_params(pkey, params)) {
        if (!OSSL_PARAM_modified(params) || params[0].return_size == 0)
            return 0;
        buf_sz = params[0].return_size;
        /*
         * If it failed because the buffer was too small then allocate the
         * required buffer size and retry.
         */
        buf = OPENSSL_zalloc(buf_sz);
        if (buf == NULL)
            return 0;
        params[0].data = buf;
        params[0].data_size = buf_sz;

        if (!EVP_PKEY_get_params(pkey, params))
            goto err;
    }
    /* Fail if the param was not found */
    if (!OSSL_PARAM_modified(params))
        goto err;
    ret = OSSL_PARAM_get_BN(params, bn);
err:
    OPENSSL_free(buf);
    return ret;
}

int EVP_PKEY_get_octet_string_param(const EVP_PKEY *pkey, const char *key_name,
                                    unsigned char *buf, size_t max_buf_sz,
                                    size_t *out_len)
{
    OSSL_PARAM params[2];
    int ret1 = 0, ret2 = 0;

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
    params[1] = OSSL_PARAM_construct_end();
    if ((ret1 = EVP_PKEY_get_params(pkey, params)))
        ret2 = OSSL_PARAM_modified(params);
    if (ret2 && out_len != NULL)
        *out_len = params[0].return_size;
    return ret1 && ret2;
}

int EVP_PKEY_get_utf8_string_param(const EVP_PKEY *pkey, const char *key_name,
                                    char *str, size_t max_buf_sz,
                                    size_t *out_len)
{
    OSSL_PARAM params[2];
    int ret1 = 0, ret2 = 0;

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
    params[1] = OSSL_PARAM_construct_end();
    if ((ret1 = EVP_PKEY_get_params(pkey, params)))
        ret2 = OSSL_PARAM_modified(params);
    if (ret2 && out_len != NULL)
        *out_len = params[0].return_size;

    if (ret2 && params[0].return_size == max_buf_sz)
        /* There was no space for a NUL byte */
        return 0;
    /* Add a terminating NUL byte for good measure */
    if (ret2 && str != NULL)
        str[params[0].return_size] = '\0';

    return ret1 && ret2;
}

int EVP_PKEY_get_int_param(const EVP_PKEY *pkey, const char *key_name,
                           int *out)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_int(key_name, out);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_get_params(pkey, params)
        && OSSL_PARAM_modified(params);
}

int EVP_PKEY_get_size_t_param(const EVP_PKEY *pkey, const char *key_name,
                              size_t *out)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_size_t(key_name, out);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_get_params(pkey, params)
        && OSSL_PARAM_modified(params);
}

int EVP_PKEY_set_int_param(EVP_PKEY *pkey, const char *key_name, int in)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_int(key_name, &in);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_set_params(pkey, params);
}

int EVP_PKEY_set_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t in)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_size_t(key_name, &in);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_set_params(pkey, params);
}

int EVP_PKEY_set_bn_param(EVP_PKEY *pkey, const char *key_name,
                          const BIGNUM *bn)
{
    OSSL_PARAM params[2];
    unsigned char buffer[2048];
    int bsize = 0;

    if (key_name == NULL
        || bn == NULL
        || pkey == NULL
        || !evp_pkey_is_assigned(pkey))
        return 0;

    bsize = BN_num_bytes(bn);
    if (!ossl_assert(bsize <= (int)sizeof(buffer)))
        return 0;

    if (BN_bn2nativepad(bn, buffer, bsize) < 0)
        return 0;
    params[0] = OSSL_PARAM_construct_BN(key_name, buffer, bsize);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_set_params(pkey, params);
}

int EVP_PKEY_set_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
                                   const char *str)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_utf8_string(key_name, (char *)str, 0);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_set_params(pkey, params);
}

int EVP_PKEY_set_octet_string_param(EVP_PKEY *pkey, const char *key_name,
                                    const unsigned char *buf, size_t bsize)
{
    OSSL_PARAM params[2];

    if (key_name == NULL)
        return 0;

    params[0] = OSSL_PARAM_construct_octet_string(key_name,
                                                  (unsigned char *)buf, bsize);
    params[1] = OSSL_PARAM_construct_end();
    return EVP_PKEY_set_params(pkey, params);
}

const OSSL_PARAM *EVP_PKEY_settable_params(const EVP_PKEY *pkey)
{
    return (pkey != NULL && evp_pkey_is_provided(pkey))
        ? EVP_KEYMGMT_settable_params(pkey->keymgmt)
        : NULL;
}

int EVP_PKEY_set_params(EVP_PKEY *pkey, OSSL_PARAM params[])
{
    if (pkey != NULL) {
        if (evp_pkey_is_provided(pkey)) {
            pkey->dirty_cnt++;
            return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
        }
#ifndef FIPS_MODULE
        /*
         * We will hopefully never find the need to set individual data in
         * EVP_PKEYs with a legacy internal key, but we can't be entirely
         * sure.  This bit of code can be enabled if we find the need.  If
         * not, it can safely be removed when #legacy support is removed.
         */
# if 0
        else if (evp_pkey_is_legacy(pkey)) {
            return evp_pkey_set_params_to_ctrl(pkey, params);
        }
# endif
#endif
    }
    ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
    return 0;
}

const OSSL_PARAM *EVP_PKEY_gettable_params(const EVP_PKEY *pkey)
{
    return (pkey != NULL && evp_pkey_is_provided(pkey))
        ? EVP_KEYMGMT_gettable_params(pkey->keymgmt)
        : NULL;
}

int EVP_PKEY_get_params(const EVP_PKEY *pkey, OSSL_PARAM params[])
{
    if (pkey != NULL) {
        if (evp_pkey_is_provided(pkey))
            return evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params);
#ifndef FIPS_MODULE
        else if (evp_pkey_is_legacy(pkey))
            return evp_pkey_get_params_to_ctrl(pkey, params);
#endif
    }
    ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY);
    return 0;
}

#ifndef FIPS_MODULE
int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey)
{
    char name[80];
    size_t name_len;

    if (pkey == NULL)
        return 0;

    if (pkey->keymgmt == NULL
            || pkey->keydata == NULL) {
# ifndef OPENSSL_NO_EC
        /* Might work through the legacy route */
        const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);

        if (ec == NULL)
            return 0;

        return EC_KEY_get_conv_form(ec);
# else
        return 0;
# endif
    }

    if (!EVP_PKEY_get_utf8_string_param(pkey,
                                        OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
                                        name, sizeof(name), &name_len))
        return 0;

    if (strcmp(name, "uncompressed") == 0)
        return POINT_CONVERSION_UNCOMPRESSED;

    if (strcmp(name, "compressed") == 0)
        return POINT_CONVERSION_COMPRESSED;

    if (strcmp(name, "hybrid") == 0)
        return POINT_CONVERSION_HYBRID;

    return 0;
}

int EVP_PKEY_get_field_type(const EVP_PKEY *pkey)
{
    char fstr[80];
    size_t fstrlen;

    if (pkey == NULL)
        return 0;

    if (pkey->keymgmt == NULL
            || pkey->keydata == NULL) {
# ifndef OPENSSL_NO_EC
        /* Might work through the legacy route */
        const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
        const EC_GROUP *grp;

        if (ec == NULL)
            return 0;
        grp = EC_KEY_get0_group(ec);
        if (grp == NULL)
            return 0;

        return EC_GROUP_get_field_type(grp);
# else
        return 0;
# endif
    }

    if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_EC_FIELD_TYPE,
                                        fstr, sizeof(fstr), &fstrlen))
        return 0;

    if (strcmp(fstr, SN_X9_62_prime_field) == 0)
        return NID_X9_62_prime_field;
    else if (strcmp(fstr, SN_X9_62_characteristic_two_field))
        return NID_X9_62_characteristic_two_field;

    return 0;
}
#endif
