Blame crypto/ec/ec_pmeth.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
#include <stdio.h>
Packit Service 084de1
#include "internal/cryptlib.h"
Packit Service 084de1
#include <openssl/asn1t.h>
Packit Service 084de1
#include <openssl/x509.h>
Packit Service 084de1
#include <openssl/ec.h>
Packit Service 084de1
#include "ec_local.h"
Packit Service 084de1
#include <openssl/evp.h>
Packit Service 084de1
#include "crypto/evp.h"
Packit Service 084de1
Packit Service 084de1
/* EC pkey context structure */
Packit Service 084de1
Packit Service 084de1
typedef struct {
Packit Service 084de1
    /* Key and paramgen group */
Packit Service 084de1
    EC_GROUP *gen_group;
Packit Service 084de1
    /* message digest */
Packit Service 084de1
    const EVP_MD *md;
Packit Service 084de1
    /* Duplicate key if custom cofactor needed */
Packit Service 084de1
    EC_KEY *co_key;
Packit Service 084de1
    /* Cofactor mode */
Packit Service 084de1
    signed char cofactor_mode;
Packit Service 084de1
    /* KDF (if any) to use for ECDH */
Packit Service 084de1
    char kdf_type;
Packit Service 084de1
    /* Message digest to use for key derivation */
Packit Service 084de1
    const EVP_MD *kdf_md;
Packit Service 084de1
    /* User key material */
Packit Service 084de1
    unsigned char *kdf_ukm;
Packit Service 084de1
    size_t kdf_ukmlen;
Packit Service 084de1
    /* KDF output length */
Packit Service 084de1
    size_t kdf_outlen;
Packit Service 084de1
} EC_PKEY_CTX;
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_init(EVP_PKEY_CTX *ctx)
Packit Service 084de1
{
Packit Service 084de1
    EC_PKEY_CTX *dctx;
Packit Service 084de1
Packit Service 084de1
    if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    dctx->cofactor_mode = -1;
Packit Service 084de1
    dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
Packit Service 084de1
    ctx->data = dctx;
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
Packit Service 084de1
{
Packit Service 084de1
    EC_PKEY_CTX *dctx, *sctx;
Packit Service 084de1
    if (!pkey_ec_init(dst))
Packit Service 084de1
        return 0;
Packit Service 084de1
    sctx = src->data;
Packit Service 084de1
    dctx = dst->data;
Packit Service 084de1
    if (sctx->gen_group) {
Packit Service 084de1
        dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
Packit Service 084de1
        if (!dctx->gen_group)
Packit Service 084de1
            return 0;
Packit Service 084de1
    }
Packit Service 084de1
    dctx->md = sctx->md;
Packit Service 084de1
Packit Service 084de1
    if (sctx->co_key) {
Packit Service 084de1
        dctx->co_key = EC_KEY_dup(sctx->co_key);
Packit Service 084de1
        if (!dctx->co_key)
Packit Service 084de1
            return 0;
Packit Service 084de1
    }
Packit Service 084de1
    dctx->kdf_type = sctx->kdf_type;
Packit Service 084de1
    dctx->kdf_md = sctx->kdf_md;
Packit Service 084de1
    dctx->kdf_outlen = sctx->kdf_outlen;
Packit Service 084de1
    if (sctx->kdf_ukm) {
Packit Service 084de1
        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
Packit Service 084de1
        if (!dctx->kdf_ukm)
Packit Service 084de1
            return 0;
Packit Service 084de1
    } else
Packit Service 084de1
        dctx->kdf_ukm = NULL;
Packit Service 084de1
    dctx->kdf_ukmlen = sctx->kdf_ukmlen;
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
Packit Service 084de1
{
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    if (dctx != NULL) {
Packit Service 084de1
        EC_GROUP_free(dctx->gen_group);
Packit Service 084de1
        EC_KEY_free(dctx->co_key);
Packit Service 084de1
        OPENSSL_free(dctx->kdf_ukm);
Packit Service 084de1
        OPENSSL_free(dctx);
Packit Service 084de1
        ctx->data = NULL;
Packit Service 084de1
    }
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
Packit Service 084de1
                        const unsigned char *tbs, size_t tbslen)
Packit Service 084de1
{
Packit Service 084de1
    int ret, type;
Packit Service 084de1
    unsigned int sltmp;
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    EC_KEY *ec = ctx->pkey->pkey.ec;
Packit Service 084de1
    const int sig_sz = ECDSA_size(ec);
Packit Service 084de1
Packit Service 084de1
    /* ensure cast to size_t is safe */
Packit Service 084de1
    if (!ossl_assert(sig_sz > 0))
Packit Service 084de1
        return 0;
Packit Service 084de1
Packit Service 084de1
    if (sig == NULL) {
Packit Service 084de1
        *siglen = (size_t)sig_sz;
Packit Service 084de1
        return 1;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    if (*siglen < (size_t)sig_sz) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    type = (dctx->md != NULL) ? EVP_MD_type(dctx->md) : NID_sha1;
Packit Service 084de1
Packit Service 084de1
    ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
Packit Service 084de1
Packit Service 084de1
    if (ret <= 0)
Packit Service 084de1
        return ret;
Packit Service 084de1
    *siglen = (size_t)sltmp;
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
Packit Service 084de1
                          const unsigned char *sig, size_t siglen,
Packit Service 084de1
                          const unsigned char *tbs, size_t tbslen)
Packit Service 084de1
{
Packit Service 084de1
    int ret, type;
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    EC_KEY *ec = ctx->pkey->pkey.ec;
Packit Service 084de1
Packit Service 084de1
    if (dctx->md)
Packit Service 084de1
        type = EVP_MD_type(dctx->md);
Packit Service 084de1
    else
Packit Service 084de1
        type = NID_sha1;
Packit Service 084de1
Packit Service 084de1
    ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
Packit Service 084de1
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
#ifndef OPENSSL_NO_EC
Packit Service 084de1
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
Packit Service 084de1
{
Packit Service 084de1
    int ret;
Packit Service 084de1
    size_t outlen;
Packit Service 084de1
    const EC_POINT *pubkey = NULL;
Packit Service 084de1
    EC_KEY *eckey;
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    if (!ctx->pkey || !ctx->peerkey) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
Packit Service 084de1
Packit Service 084de1
    if (!key) {
Packit Service 084de1
        const EC_GROUP *group;
Packit Service 084de1
        group = EC_KEY_get0_group(eckey);
Packit Service 084de1
        *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
Packit Service 084de1
        return 1;
Packit Service 084de1
    }
Packit Service 084de1
    pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
Packit Service 084de1
Packit Service 084de1
    /*
Packit Service 084de1
     * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
Packit Service 084de1
     * an error, the result is truncated.
Packit Service 084de1
     */
Packit Service 084de1
Packit Service 084de1
    outlen = *keylen;
Packit Service 084de1
Packit Service 084de1
    ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
Packit Service 084de1
    if (ret <= 0)
Packit Service 084de1
        return 0;
Packit Service 084de1
    *keylen = ret;
Packit Service 084de1
    return 1;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
Packit Service 084de1
                              unsigned char *key, size_t *keylen)
Packit Service 084de1
{
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    unsigned char *ktmp = NULL;
Packit Service 084de1
    size_t ktmplen;
Packit Service 084de1
    int rv = 0;
Packit Service 084de1
    if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
Packit Service 084de1
        return pkey_ec_derive(ctx, key, keylen);
Packit Service 084de1
    if (!key) {
Packit Service 084de1
        *keylen = dctx->kdf_outlen;
Packit Service 084de1
        return 1;
Packit Service 084de1
    }
Packit Service 084de1
    if (*keylen != dctx->kdf_outlen)
Packit Service 084de1
        return 0;
Packit Service 084de1
    if (!pkey_ec_derive(ctx, NULL, &ktmplen))
Packit Service 084de1
        return 0;
Packit Service 084de1
    if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
    if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
Packit Service 084de1
        goto err;
Packit Service 084de1
    /* Do KDF stuff */
Packit Service 084de1
    if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen,
Packit Service 084de1
                        dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
Packit Service 084de1
        goto err;
Packit Service 084de1
    rv = 1;
Packit Service 084de1
Packit Service 084de1
 err:
Packit Service 084de1
    OPENSSL_clear_free(ktmp, ktmplen);
Packit Service 084de1
    return rv;
Packit Service 084de1
}
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
Packit Service 084de1
{
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    EC_GROUP *group;
Packit Service 084de1
    switch (type) {
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
Packit Service 084de1
        group = EC_GROUP_new_by_curve_name(p1);
Packit Service 084de1
        if (group == NULL) {
Packit Service 084de1
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
Packit Service 084de1
            return 0;
Packit Service 084de1
        }
Packit Service 084de1
        EC_GROUP_free(dctx->gen_group);
Packit Service 084de1
        dctx->gen_group = group;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_PARAM_ENC:
Packit Service 084de1
        if (!dctx->gen_group) {
Packit Service 084de1
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
Packit Service 084de1
            return 0;
Packit Service 084de1
        }
Packit Service 084de1
        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
#ifndef OPENSSL_NO_EC
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
Packit Service 084de1
        if (p1 == -2) {
Packit Service 084de1
            if (dctx->cofactor_mode != -1)
Packit Service 084de1
                return dctx->cofactor_mode;
Packit Service 084de1
            else {
Packit Service 084de1
                EC_KEY *ec_key = ctx->pkey->pkey.ec;
Packit Service 084de1
                return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
Packit Service 084de1
            }
Packit Service 084de1
        } else if (p1 < -1 || p1 > 1)
Packit Service 084de1
            return -2;
Packit Service 084de1
        dctx->cofactor_mode = p1;
Packit Service 084de1
        if (p1 != -1) {
Packit Service 084de1
            EC_KEY *ec_key = ctx->pkey->pkey.ec;
Packit Service 084de1
            if (!ec_key->group)
Packit Service 084de1
                return -2;
Packit Service 084de1
            /* If cofactor is 1 cofactor mode does nothing */
Packit Service 084de1
            if (BN_is_one(ec_key->group->cofactor))
Packit Service 084de1
                return 1;
Packit Service 084de1
            if (!dctx->co_key) {
Packit Service 084de1
                dctx->co_key = EC_KEY_dup(ec_key);
Packit Service 084de1
                if (!dctx->co_key)
Packit Service 084de1
                    return 0;
Packit Service 084de1
            }
Packit Service 084de1
            if (p1)
Packit Service 084de1
                EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
Packit Service 084de1
            else
Packit Service 084de1
                EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
Packit Service 084de1
        } else {
Packit Service 084de1
            EC_KEY_free(dctx->co_key);
Packit Service 084de1
            dctx->co_key = NULL;
Packit Service 084de1
        }
Packit Service 084de1
        return 1;
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_KDF_TYPE:
Packit Service 084de1
        if (p1 == -2)
Packit Service 084de1
            return dctx->kdf_type;
Packit Service 084de1
        if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
Packit Service 084de1
            return -2;
Packit Service 084de1
        dctx->kdf_type = p1;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_KDF_MD:
Packit Service 084de1
        dctx->kdf_md = p2;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_GET_EC_KDF_MD:
Packit Service 084de1
        *(const EVP_MD **)p2 = dctx->kdf_md;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
Packit Service 084de1
        if (p1 <= 0)
Packit Service 084de1
            return -2;
Packit Service 084de1
        dctx->kdf_outlen = (size_t)p1;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
Packit Service 084de1
        *(int *)p2 = dctx->kdf_outlen;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_EC_KDF_UKM:
Packit Service 084de1
        OPENSSL_free(dctx->kdf_ukm);
Packit Service 084de1
        dctx->kdf_ukm = p2;
Packit Service 084de1
        if (p2)
Packit Service 084de1
            dctx->kdf_ukmlen = p1;
Packit Service 084de1
        else
Packit Service 084de1
            dctx->kdf_ukmlen = 0;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
Packit Service 084de1
        *(unsigned char **)p2 = dctx->kdf_ukm;
Packit Service 084de1
        return dctx->kdf_ukmlen;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_MD:
Packit Service 084de1
        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha512 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
Packit Service 084de1
            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
Packit Service 084de1
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
Packit Service 084de1
            return 0;
Packit Service 084de1
        }
Packit Service 084de1
        dctx->md = p2;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_GET_MD:
Packit Service 084de1
        *(const EVP_MD **)p2 = dctx->md;
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    case EVP_PKEY_CTRL_PEER_KEY:
Packit Service 084de1
        /* Default behaviour is OK */
Packit Service 084de1
    case EVP_PKEY_CTRL_DIGESTINIT:
Packit Service 084de1
    case EVP_PKEY_CTRL_PKCS7_SIGN:
Packit Service 084de1
    case EVP_PKEY_CTRL_CMS_SIGN:
Packit Service 084de1
        return 1;
Packit Service 084de1
Packit Service 084de1
    default:
Packit Service 084de1
        return -2;
Packit Service 084de1
Packit Service 084de1
    }
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
Packit Service 084de1
                            const char *type, const char *value)
Packit Service 084de1
{
Packit Service 084de1
    if (strcmp(type, "ec_paramgen_curve") == 0) {
Packit Service 084de1
        int nid;
Packit Service 084de1
        nid = EC_curve_nist2nid(value);
Packit Service 084de1
        if (nid == NID_undef)
Packit Service 084de1
            nid = OBJ_sn2nid(value);
Packit Service 084de1
        if (nid == NID_undef)
Packit Service 084de1
            nid = OBJ_ln2nid(value);
Packit Service 084de1
        if (nid == NID_undef) {
Packit Service 084de1
            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
Packit Service 084de1
            return 0;
Packit Service 084de1
        }
Packit Service 084de1
        return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
Packit Service 084de1
    } else if (strcmp(type, "ec_param_enc") == 0) {
Packit Service 084de1
        int param_enc;
Packit Service 084de1
        if (strcmp(value, "explicit") == 0)
Packit Service 084de1
            param_enc = 0;
Packit Service 084de1
        else if (strcmp(value, "named_curve") == 0)
Packit Service 084de1
            param_enc = OPENSSL_EC_NAMED_CURVE;
Packit Service 084de1
        else
Packit Service 084de1
            return -2;
Packit Service 084de1
        return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
Packit Service 084de1
    } else if (strcmp(type, "ecdh_kdf_md") == 0) {
Packit Service 084de1
        const EVP_MD *md;
Packit Service 084de1
        if ((md = EVP_get_digestbyname(value)) == NULL) {
Packit Service 084de1
            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
Packit Service 084de1
            return 0;
Packit Service 084de1
        }
Packit Service 084de1
        return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
Packit Service 084de1
    } else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
Packit Service 084de1
        int co_mode;
Packit Service 084de1
        co_mode = atoi(value);
Packit Service 084de1
        return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
Packit Service 084de1
    }
Packit Service 084de1
Packit Service 084de1
    return -2;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
Packit Service 084de1
{
Packit Service 084de1
    EC_KEY *ec = NULL;
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    int ret;
Packit Service 084de1
Packit Service 084de1
    if (dctx->gen_group == NULL) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
    ec = EC_KEY_new();
Packit Service 084de1
    if (ec == NULL)
Packit Service 084de1
        return 0;
Packit Service 084de1
    if (!(ret = EC_KEY_set_group(ec, dctx->gen_group))
Packit Service 084de1
        || !ossl_assert(ret = EVP_PKEY_assign_EC_KEY(pkey, ec)))
Packit Service 084de1
        EC_KEY_free(ec);
Packit Service 084de1
    return ret;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
Packit Service 084de1
{
Packit Service 084de1
    EC_KEY *ec = NULL;
Packit Service 084de1
    EC_PKEY_CTX *dctx = ctx->data;
Packit Service 084de1
    int ret;
Packit Service 084de1
Packit Service 084de1
    if (ctx->pkey == NULL && dctx->gen_group == NULL) {
Packit Service 084de1
        ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
    ec = EC_KEY_new();
Packit Service 084de1
    if (ec == NULL)
Packit Service 084de1
        return 0;
Packit Service 084de1
    if (!ossl_assert(EVP_PKEY_assign_EC_KEY(pkey, ec))) {
Packit Service 084de1
        EC_KEY_free(ec);
Packit Service 084de1
        return 0;
Packit Service 084de1
    }
Packit Service 084de1
    /* Note: if error is returned, we count on caller to free pkey->pkey.ec */
Packit Service 084de1
    if (ctx->pkey != NULL)
Packit Service 084de1
        ret = EVP_PKEY_copy_parameters(pkey, ctx->pkey);
Packit Service 084de1
    else
Packit Service 084de1
        ret = EC_KEY_set_group(ec, dctx->gen_group);
Packit Service 084de1
Packit Service 084de1
    return ret ? EC_KEY_generate_key(ec) : 0;
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
const EVP_PKEY_METHOD ec_pkey_meth = {
Packit Service 084de1
    EVP_PKEY_EC,
Packit Service 084de1
    EVP_PKEY_FLAG_FIPS,
Packit Service 084de1
    pkey_ec_init,
Packit Service 084de1
    pkey_ec_copy,
Packit Service 084de1
    pkey_ec_cleanup,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    pkey_ec_paramgen,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    pkey_ec_keygen,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    pkey_ec_sign,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    pkey_ec_verify,
Packit Service 084de1
Packit Service 084de1
    0, 0,
Packit Service 084de1
Packit Service 084de1
    0, 0, 0, 0,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    0,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
    0,
Packit Service 084de1
Packit Service 084de1
    0,
Packit Service 084de1
#ifndef OPENSSL_NO_EC
Packit Service 084de1
    pkey_ec_kdf_derive,
Packit Service 084de1
#else
Packit Service 084de1
    0,
Packit Service 084de1
#endif
Packit Service 084de1
    pkey_ec_ctrl,
Packit Service 084de1
    pkey_ec_ctrl_str
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
const EVP_PKEY_METHOD *ec_pkey_method(void)
Packit Service 084de1
{
Packit Service 084de1
    return &ec_pkey_meth;
Packit Service 084de1
}