Blame crypto/dh/dh_pmeth.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <stdio.h>
Packit c4476c
#include "internal/cryptlib.h"
Packit c4476c
#include <openssl/asn1t.h>
Packit c4476c
#include <openssl/x509.h>
Packit c4476c
#include <openssl/evp.h>
Packit c4476c
#include "dh_local.h"
Packit c4476c
#include <openssl/bn.h>
Packit c4476c
#include <openssl/dsa.h>
Packit c4476c
#include <openssl/objects.h>
Packit c4476c
#include "crypto/evp.h"
Packit c4476c
Packit c4476c
/* DH pkey context structure */
Packit c4476c
Packit c4476c
typedef struct {
Packit c4476c
    /* Parameter gen parameters */
Packit c4476c
    int prime_len;
Packit c4476c
    int generator;
Packit c4476c
    int use_dsa;
Packit c4476c
    int subprime_len;
Packit c4476c
    int pad;
Packit c4476c
    /* message digest used for parameter generation */
Packit c4476c
    const EVP_MD *md;
Packit c4476c
    int rfc5114_param;
Packit c4476c
    int param_nid;
Packit c4476c
    /* Keygen callback info */
Packit c4476c
    int gentmp[2];
Packit c4476c
    /* KDF (if any) to use for DH */
Packit c4476c
    char kdf_type;
Packit c4476c
    /* OID to use for KDF */
Packit c4476c
    ASN1_OBJECT *kdf_oid;
Packit c4476c
    /* Message digest to use for key derivation */
Packit c4476c
    const EVP_MD *kdf_md;
Packit c4476c
    /* User key material */
Packit c4476c
    unsigned char *kdf_ukm;
Packit c4476c
    size_t kdf_ukmlen;
Packit c4476c
    /* KDF output length */
Packit c4476c
    size_t kdf_outlen;
Packit c4476c
} DH_PKEY_CTX;
Packit c4476c
Packit c4476c
static int pkey_dh_init(EVP_PKEY_CTX *ctx)
Packit c4476c
{
Packit c4476c
    DH_PKEY_CTX *dctx;
Packit c4476c
Packit c4476c
    if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
Packit c4476c
        DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
    dctx->prime_len = 2048;
Packit c4476c
    dctx->subprime_len = -1;
Packit c4476c
    dctx->generator = 2;
Packit c4476c
    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
Packit c4476c
Packit c4476c
    ctx->data = dctx;
Packit c4476c
    ctx->keygen_info = dctx->gentmp;
Packit c4476c
    ctx->keygen_info_count = 2;
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
Packit c4476c
{
Packit c4476c
    DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
    if (dctx != NULL) {
Packit c4476c
        OPENSSL_free(dctx->kdf_ukm);
Packit c4476c
        ASN1_OBJECT_free(dctx->kdf_oid);
Packit c4476c
        OPENSSL_free(dctx);
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
Packit c4476c
static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
Packit c4476c
{
Packit c4476c
    DH_PKEY_CTX *dctx, *sctx;
Packit c4476c
    if (!pkey_dh_init(dst))
Packit c4476c
        return 0;
Packit c4476c
    sctx = src->data;
Packit c4476c
    dctx = dst->data;
Packit c4476c
    dctx->prime_len = sctx->prime_len;
Packit c4476c
    dctx->subprime_len = sctx->subprime_len;
Packit c4476c
    dctx->generator = sctx->generator;
Packit c4476c
    dctx->use_dsa = sctx->use_dsa;
Packit c4476c
    dctx->pad = sctx->pad;
Packit c4476c
    dctx->md = sctx->md;
Packit c4476c
    dctx->rfc5114_param = sctx->rfc5114_param;
Packit c4476c
    dctx->param_nid = sctx->param_nid;
Packit c4476c
Packit c4476c
    dctx->kdf_type = sctx->kdf_type;
Packit c4476c
    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
Packit c4476c
    if (dctx->kdf_oid == NULL)
Packit c4476c
        return 0;
Packit c4476c
    dctx->kdf_md = sctx->kdf_md;
Packit c4476c
    if (sctx->kdf_ukm != NULL) {
Packit c4476c
        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
Packit c4476c
        if (dctx->kdf_ukm == NULL)
Packit c4476c
          return 0;
Packit c4476c
        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
Packit c4476c
    }
Packit c4476c
    dctx->kdf_outlen = sctx->kdf_outlen;
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
Packit c4476c
{
Packit c4476c
    DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
    switch (type) {
Packit c4476c
    case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
Packit c4476c
        if (p1 < 256)
Packit c4476c
            return -2;
Packit c4476c
        dctx->prime_len = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
Packit c4476c
        if (dctx->use_dsa == 0)
Packit c4476c
            return -2;
Packit c4476c
        dctx->subprime_len = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_PAD:
Packit c4476c
        dctx->pad = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
Packit c4476c
        if (dctx->use_dsa)
Packit c4476c
            return -2;
Packit c4476c
        dctx->generator = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
Packit c4476c
#ifdef OPENSSL_NO_DSA
Packit c4476c
        if (p1 != 0)
Packit c4476c
            return -2;
Packit c4476c
#else
Packit c4476c
        if (p1 < 0 || p1 > 2)
Packit c4476c
            return -2;
Packit c4476c
#endif
Packit c4476c
        dctx->use_dsa = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_RFC5114:
Packit c4476c
        if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
Packit c4476c
            return -2;
Packit c4476c
        dctx->rfc5114_param = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_NID:
Packit c4476c
        if (p1 <= 0 || dctx->rfc5114_param != 0)
Packit c4476c
            return -2;
Packit c4476c
        dctx->param_nid = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_PEER_KEY:
Packit c4476c
        /* Default behaviour is OK */
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_KDF_TYPE:
Packit c4476c
        if (p1 == -2)
Packit c4476c
            return dctx->kdf_type;
Packit c4476c
#ifdef OPENSSL_NO_CMS
Packit c4476c
        if (p1 != EVP_PKEY_DH_KDF_NONE)
Packit c4476c
#else
Packit c4476c
        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
Packit c4476c
#endif
Packit c4476c
            return -2;
Packit c4476c
        dctx->kdf_type = p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_KDF_MD:
Packit c4476c
        dctx->kdf_md = p2;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
Packit c4476c
        *(const EVP_MD **)p2 = dctx->kdf_md;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
Packit c4476c
        if (p1 <= 0)
Packit c4476c
            return -2;
Packit c4476c
        dctx->kdf_outlen = (size_t)p1;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
Packit c4476c
        *(int *)p2 = dctx->kdf_outlen;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_KDF_UKM:
Packit c4476c
        OPENSSL_free(dctx->kdf_ukm);
Packit c4476c
        dctx->kdf_ukm = p2;
Packit c4476c
        if (p2)
Packit c4476c
            dctx->kdf_ukmlen = p1;
Packit c4476c
        else
Packit c4476c
            dctx->kdf_ukmlen = 0;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
Packit c4476c
        *(unsigned char **)p2 = dctx->kdf_ukm;
Packit c4476c
        return dctx->kdf_ukmlen;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_DH_KDF_OID:
Packit c4476c
        ASN1_OBJECT_free(dctx->kdf_oid);
Packit c4476c
        dctx->kdf_oid = p2;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
Packit c4476c
        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    default:
Packit c4476c
        return -2;
Packit c4476c
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
Packit c4476c
                            const char *type, const char *value)
Packit c4476c
{
Packit c4476c
    if (strcmp(type, "dh_paramgen_prime_len") == 0) {
Packit c4476c
        int len;
Packit c4476c
        len = atoi(value);
Packit c4476c
        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_rfc5114") == 0) {
Packit c4476c
        DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
        int len;
Packit c4476c
        len = atoi(value);
Packit c4476c
        if (len < 0 || len > 3)
Packit c4476c
            return -2;
Packit c4476c
        dctx->rfc5114_param = len;
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_param") == 0) {
Packit c4476c
        DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
        int nid = OBJ_sn2nid(value);
Packit c4476c
Packit c4476c
        if (nid == NID_undef) {
Packit c4476c
            DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
Packit c4476c
            return -2;
Packit c4476c
        }
Packit c4476c
        dctx->param_nid = nid;
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_paramgen_generator") == 0) {
Packit c4476c
        int len;
Packit c4476c
        len = atoi(value);
Packit c4476c
        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
Packit c4476c
        int len;
Packit c4476c
        len = atoi(value);
Packit c4476c
        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_paramgen_type") == 0) {
Packit c4476c
        int typ;
Packit c4476c
        typ = atoi(value);
Packit c4476c
        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
Packit c4476c
    }
Packit c4476c
    if (strcmp(type, "dh_pad") == 0) {
Packit c4476c
        int pad;
Packit c4476c
        pad = atoi(value);
Packit c4476c
        return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
Packit c4476c
    }
Packit c4476c
    return -2;
Packit c4476c
}
Packit c4476c
Packit c4476c
#ifndef OPENSSL_NO_DSA
Packit c4476c
Packit c4476c
extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
Packit c4476c
                                const EVP_MD *evpmd,
Packit c4476c
                                const unsigned char *seed_in, size_t seed_len,
Packit c4476c
                                unsigned char *seed_out, int *counter_ret,
Packit c4476c
                                unsigned long *h_ret, BN_GENCB *cb);
Packit c4476c
Packit c4476c
extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
Packit c4476c
                                 const EVP_MD *evpmd,
Packit c4476c
                                 const unsigned char *seed_in,
Packit c4476c
                                 size_t seed_len, int idx,
Packit c4476c
                                 unsigned char *seed_out, int *counter_ret,
Packit c4476c
                                 unsigned long *h_ret, BN_GENCB *cb);
Packit c4476c
Packit c4476c
static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
Packit c4476c
{
Packit c4476c
    DSA *ret;
Packit c4476c
    int rv = 0;
Packit c4476c
    int prime_len = dctx->prime_len;
Packit c4476c
    int subprime_len = dctx->subprime_len;
Packit c4476c
    const EVP_MD *md = dctx->md;
Packit c4476c
    if (dctx->use_dsa > 2)
Packit c4476c
        return NULL;
Packit c4476c
    ret = DSA_new();
Packit c4476c
    if (ret == NULL)
Packit c4476c
        return NULL;
Packit c4476c
    if (subprime_len == -1) {
Packit c4476c
        if (prime_len >= 2048)
Packit c4476c
            subprime_len = 256;
Packit c4476c
        else
Packit c4476c
            subprime_len = 160;
Packit c4476c
    }
Packit c4476c
    if (md == NULL) {
Packit c4476c
        if (prime_len >= 2048)
Packit c4476c
            md = EVP_sha256();
Packit c4476c
        else
Packit c4476c
            md = EVP_sha1();
Packit c4476c
    }
Packit c4476c
    if (dctx->use_dsa == 1)
Packit c4476c
        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
Packit c4476c
                                  NULL, 0, NULL, NULL, NULL, pcb);
Packit c4476c
    else if (dctx->use_dsa == 2)
Packit c4476c
        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
Packit c4476c
                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
Packit c4476c
    if (rv <= 0) {
Packit c4476c
        DSA_free(ret);
Packit c4476c
        return NULL;
Packit c4476c
    }
Packit c4476c
    return ret;
Packit c4476c
}
Packit c4476c
Packit c4476c
#endif
Packit c4476c
Packit c4476c
static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
Packit c4476c
{
Packit c4476c
    DH *dh = NULL;
Packit c4476c
    DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
    BN_GENCB *pcb;
Packit c4476c
    int ret;
Packit c4476c
    if (dctx->rfc5114_param) {
Packit c4476c
        switch (dctx->rfc5114_param) {
Packit c4476c
        case 1:
Packit c4476c
            dh = DH_get_1024_160();
Packit c4476c
            break;
Packit c4476c
Packit c4476c
        case 2:
Packit c4476c
            dh = DH_get_2048_224();
Packit c4476c
            break;
Packit c4476c
Packit c4476c
        case 3:
Packit c4476c
            dh = DH_get_2048_256();
Packit c4476c
            break;
Packit c4476c
Packit c4476c
        default:
Packit c4476c
            return -2;
Packit c4476c
        }
Packit c4476c
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (dctx->param_nid != 0) {
Packit c4476c
        if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
Packit c4476c
            return 0;
Packit c4476c
        EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (ctx->pkey_gencb) {
Packit c4476c
        pcb = BN_GENCB_new();
Packit c4476c
        if (pcb == NULL)
Packit c4476c
            return 0;
Packit c4476c
        evp_pkey_set_cb_translate(pcb, ctx);
Packit c4476c
    } else
Packit c4476c
        pcb = NULL;
Packit c4476c
#ifndef OPENSSL_NO_DSA
Packit c4476c
    if (dctx->use_dsa) {
Packit c4476c
        DSA *dsa_dh;
Packit c4476c
        dsa_dh = dsa_dh_generate(dctx, pcb);
Packit c4476c
        BN_GENCB_free(pcb);
Packit c4476c
        if (dsa_dh == NULL)
Packit c4476c
            return 0;
Packit c4476c
        dh = DSA_dup_DH(dsa_dh);
Packit c4476c
        DSA_free(dsa_dh);
Packit c4476c
        if (!dh)
Packit c4476c
            return 0;
Packit c4476c
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
#endif
Packit c4476c
    dh = DH_new();
Packit c4476c
    if (dh == NULL) {
Packit c4476c
        BN_GENCB_free(pcb);
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
    ret = DH_generate_parameters_ex(dh,
Packit c4476c
                                    dctx->prime_len, dctx->generator, pcb);
Packit c4476c
    BN_GENCB_free(pcb);
Packit c4476c
    if (ret)
Packit c4476c
        EVP_PKEY_assign_DH(pkey, dh);
Packit c4476c
    else
Packit c4476c
        DH_free(dh);
Packit c4476c
    return ret;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
Packit c4476c
{
Packit c4476c
    DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
    DH *dh = NULL;
Packit c4476c
Packit c4476c
    if (ctx->pkey == NULL && dctx->param_nid == 0) {
Packit c4476c
        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
    if (dctx->param_nid != 0)
Packit c4476c
        dh = DH_new_by_nid(dctx->param_nid);
Packit c4476c
    else
Packit c4476c
        dh = DH_new();
Packit c4476c
    if (dh == NULL)
Packit c4476c
        return 0;
Packit c4476c
    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
Packit c4476c
    /* Note: if error return, pkey is freed by parent routine */
Packit c4476c
    if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
Packit c4476c
        return 0;
Packit c4476c
    return DH_generate_key(pkey->pkey.dh);
Packit c4476c
}
Packit c4476c
Packit c4476c
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
Packit c4476c
                          size_t *keylen)
Packit c4476c
{
Packit c4476c
    int ret;
Packit c4476c
    DH *dh;
Packit c4476c
    DH_PKEY_CTX *dctx = ctx->data;
Packit c4476c
    BIGNUM *dhpub;
Packit c4476c
    if (!ctx->pkey || !ctx->peerkey) {
Packit c4476c
        DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
    dh = ctx->pkey->pkey.dh;
Packit c4476c
    dhpub = ctx->peerkey->pkey.dh->pub_key;
Packit c4476c
    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
Packit c4476c
        if (key == NULL) {
Packit c4476c
            *keylen = DH_size(dh);
Packit c4476c
            return 1;
Packit c4476c
        }
Packit c4476c
        if (dctx->pad)
Packit c4476c
            ret = DH_compute_key_padded(key, dhpub, dh);
Packit c4476c
        else
Packit c4476c
            ret = DH_compute_key(key, dhpub, dh);
Packit c4476c
        if (ret < 0)
Packit c4476c
            return ret;
Packit c4476c
        *keylen = ret;
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
#ifndef OPENSSL_NO_CMS
Packit c4476c
    else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
Packit c4476c
Packit c4476c
        unsigned char *Z = NULL;
Packit c4476c
        size_t Zlen = 0;
Packit c4476c
        if (!dctx->kdf_outlen || !dctx->kdf_oid)
Packit c4476c
            return 0;
Packit c4476c
        if (key == NULL) {
Packit c4476c
            *keylen = dctx->kdf_outlen;
Packit c4476c
            return 1;
Packit c4476c
        }
Packit c4476c
        if (*keylen != dctx->kdf_outlen)
Packit c4476c
            return 0;
Packit c4476c
        ret = 0;
Packit c4476c
        Zlen = DH_size(dh);
Packit c4476c
        Z = OPENSSL_malloc(Zlen);
Packit c4476c
        if (Z == NULL) {
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
Packit c4476c
            goto err;
Packit c4476c
        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
Packit c4476c
                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
Packit c4476c
            goto err;
Packit c4476c
        *keylen = dctx->kdf_outlen;
Packit c4476c
        ret = 1;
Packit c4476c
 err:
Packit c4476c
        OPENSSL_clear_free(Z, Zlen);
Packit c4476c
        return ret;
Packit c4476c
    }
Packit c4476c
#endif
Packit c4476c
    return 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
const EVP_PKEY_METHOD dh_pkey_meth = {
Packit c4476c
    EVP_PKEY_DH,
Packit c4476c
    EVP_PKEY_FLAG_FIPS,
Packit c4476c
    pkey_dh_init,
Packit c4476c
    pkey_dh_copy,
Packit c4476c
    pkey_dh_cleanup,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_paramgen,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_keygen,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    0,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0, 0, 0, 0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_derive,
Packit c4476c
Packit c4476c
    pkey_dh_ctrl,
Packit c4476c
    pkey_dh_ctrl_str
Packit c4476c
};
Packit c4476c
Packit c4476c
const EVP_PKEY_METHOD *dh_pkey_method(void)
Packit c4476c
{
Packit c4476c
    return &dh_pkey_meth;
Packit c4476c
}
Packit c4476c
Packit c4476c
const EVP_PKEY_METHOD dhx_pkey_meth = {
Packit c4476c
    EVP_PKEY_DHX,
Packit c4476c
    EVP_PKEY_FLAG_FIPS,
Packit c4476c
    pkey_dh_init,
Packit c4476c
    pkey_dh_copy,
Packit c4476c
    pkey_dh_cleanup,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_paramgen,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_keygen,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    0,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0, 0, 0, 0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0, 0,
Packit c4476c
Packit c4476c
    0,
Packit c4476c
    pkey_dh_derive,
Packit c4476c
Packit c4476c
    pkey_dh_ctrl,
Packit c4476c
    pkey_dh_ctrl_str
Packit c4476c
};
Packit c4476c
Packit c4476c
const EVP_PKEY_METHOD *dhx_pkey_method(void)
Packit c4476c
{
Packit c4476c
    return &dhx_pkey_meth;
Packit c4476c
}