pmeth_lib.c 17.6 KB
Newer Older
1
/* pmeth_lib.c */
2 3 4
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 * 2006.
5 6 7 8 9 10 11 12 13
 */
/* ====================================================================
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include <stdlib.h>
62
#include "internal/cryptlib.h"
63
#include <openssl/objects.h>
64
#include <openssl/evp.h>
65
#ifndef OPENSSL_NO_ENGINE
66
# include <openssl/engine.h>
67
#endif
68
#include "internal/asn1_int.h"
69
#include "internal/evp_int.h"
70

71
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
B
Ben Laurie 已提交
72

73
DECLARE_STACK_OF(EVP_PKEY_METHOD)
B
Ben Laurie 已提交
74
STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
75

76
extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
77
extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
78
extern const EVP_PKEY_METHOD dhx_pkey_meth;
79

80
static const EVP_PKEY_METHOD *standard_methods[] = {
D
Dr. Stephen Henson 已提交
81
#ifndef OPENSSL_NO_RSA
82
    &rsa_pkey_meth,
D
Dr. Stephen Henson 已提交
83 84
#endif
#ifndef OPENSSL_NO_DH
85
    &dh_pkey_meth,
D
Dr. Stephen Henson 已提交
86 87
#endif
#ifndef OPENSSL_NO_DSA
88
    &dsa_pkey_meth,
D
Dr. Stephen Henson 已提交
89
#endif
90
#ifndef OPENSSL_NO_EC
91
    &ec_pkey_meth,
92
#endif
93 94
    &hmac_pkey_meth,
    &cmac_pkey_meth,
95
#ifndef OPENSSL_NO_DH
96
    &dhx_pkey_meth
97
#endif
98
};
99

D
Dr. Stephen Henson 已提交
100
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
101
                           pmeth);
102

103 104 105 106 107
static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
                     const EVP_PKEY_METHOD *const *b)
{
    return ((*a)->pkey_id - (*b)->pkey_id);
}
108

D
Dr. Stephen Henson 已提交
109
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
110
                             pmeth);
111

112
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
{
    EVP_PKEY_METHOD tmp;
    const EVP_PKEY_METHOD *t = &tmp, **ret;
    tmp.pkey_id = type;
    if (app_pkey_methods) {
        int idx;
        idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
        if (idx >= 0)
            return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
    }
    ret = OBJ_bsearch_pmeth(&t, standard_methods,
                            sizeof(standard_methods) /
                            sizeof(EVP_PKEY_METHOD *));
    if (!ret || !*ret)
        return NULL;
    return *ret;
}
130

D
Dr. Stephen Henson 已提交
131
static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
132 133 134 135 136 137 138 139
{
    EVP_PKEY_CTX *ret;
    const EVP_PKEY_METHOD *pmeth;
    if (id == -1) {
        if (!pkey || !pkey->ameth)
            return NULL;
        id = pkey->ameth->pkey_id;
    }
D
Dr. Stephen Henson 已提交
140
#ifndef OPENSSL_NO_ENGINE
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
    if (pkey && pkey->engine)
        e = pkey->engine;
    /* Try to find an ENGINE which implements this method */
    if (e) {
        if (!ENGINE_init(e)) {
            EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
            return NULL;
        }
    } else
        e = ENGINE_get_pkey_meth_engine(id);

    /*
     * If an ENGINE handled this method look it up. Othewise use internal
     * tables.
     */

    if (e)
        pmeth = ENGINE_get_pkey_meth(e, id);
    else
D
Dr. Stephen Henson 已提交
160
#endif
161
        pmeth = EVP_PKEY_meth_find(id);
162

163 164 165 166
    if (pmeth == NULL) {
        EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
        return NULL;
    }
167

R
Rich Salz 已提交
168
    ret = OPENSSL_zalloc(sizeof(*ret));
169
    if (!ret) {
D
Dr. Stephen Henson 已提交
170
#ifndef OPENSSL_NO_ENGINE
171 172
        if (e)
            ENGINE_finish(e);
D
Dr. Stephen Henson 已提交
173
#endif
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
        EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ret->engine = e;
    ret->pmeth = pmeth;
    ret->operation = EVP_PKEY_OP_UNDEFINED;
    ret->pkey = pkey;
    if (pkey)
        CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
    ret->data = NULL;

    if (pmeth->init) {
        if (pmeth->init(ret) <= 0) {
            EVP_PKEY_CTX_free(ret);
            return NULL;
        }
    }

    return ret;
}

EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
{
    EVP_PKEY_METHOD *pmeth;
R
Rich Salz 已提交
198

R
Rich Salz 已提交
199
    pmeth = OPENSSL_zalloc(sizeof(*pmeth));
200 201 202 203 204 205 206
    if (!pmeth)
        return NULL;

    pmeth->pkey_id = id;
    pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
    return pmeth;
}
207

208
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
209 210 211 212 213 214 215
                             const EVP_PKEY_METHOD *meth)
{
    if (ppkey_id)
        *ppkey_id = meth->pkey_id;
    if (pflags)
        *pflags = meth->flags;
}
216 217

void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
218
{
219

220 221 222
    dst->init = src->init;
    dst->copy = src->copy;
    dst->cleanup = src->cleanup;
223

224 225
    dst->paramgen_init = src->paramgen_init;
    dst->paramgen = src->paramgen;
226

227 228
    dst->keygen_init = src->keygen_init;
    dst->keygen = src->keygen;
229

230 231
    dst->sign_init = src->sign_init;
    dst->sign = src->sign;
232

233 234
    dst->verify_init = src->verify_init;
    dst->verify = src->verify;
235

236 237
    dst->verify_recover_init = src->verify_recover_init;
    dst->verify_recover = src->verify_recover;
238

239 240
    dst->signctx_init = src->signctx_init;
    dst->signctx = src->signctx;
241

242 243
    dst->verifyctx_init = src->verifyctx_init;
    dst->verifyctx = src->verifyctx;
244

245 246
    dst->encrypt_init = src->encrypt_init;
    dst->encrypt = src->encrypt;
247

248 249
    dst->decrypt_init = src->decrypt_init;
    dst->decrypt = src->decrypt;
250

251 252
    dst->derive_init = src->derive_init;
    dst->derive = src->derive;
253

254 255 256
    dst->ctrl = src->ctrl;
    dst->ctrl_str = src->ctrl_str;
}
257

258
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
259 260 261 262
{
    if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
        OPENSSL_free(pmeth);
}
263

D
Dr. Stephen Henson 已提交
264
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
265 266 267
{
    return int_ctx_new(pkey, e, -1);
}
D
Dr. Stephen Henson 已提交
268 269

EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
270 271 272
{
    return int_ctx_new(NULL, e, id);
}
D
Dr. Stephen Henson 已提交
273

274
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
275 276 277 278
{
    EVP_PKEY_CTX *rctx;
    if (!pctx->pmeth || !pctx->pmeth->copy)
        return NULL;
279
#ifndef OPENSSL_NO_ENGINE
280 281 282 283 284
    /* Make sure it's safe to copy a pkey context using an ENGINE */
    if (pctx->engine && !ENGINE_init(pctx->engine)) {
        EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
        return 0;
    }
285
#endif
R
Rich Salz 已提交
286
    rctx = OPENSSL_malloc(sizeof(*rctx));
287 288
    if (!rctx)
        return NULL;
289

290
    rctx->pmeth = pctx->pmeth;
291
#ifndef OPENSSL_NO_ENGINE
292
    rctx->engine = pctx->engine;
293
#endif
294

295 296
    if (pctx->pkey)
        CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
297

298
    rctx->pkey = pctx->pkey;
299

300 301
    if (pctx->peerkey)
        CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
302

303
    rctx->peerkey = pctx->peerkey;
304

305 306 307
    rctx->data = NULL;
    rctx->app_data = NULL;
    rctx->operation = pctx->operation;
308

309 310
    if (pctx->pmeth->copy(rctx, pctx) > 0)
        return rctx;
311

312 313
    EVP_PKEY_CTX_free(rctx);
    return NULL;
314

315
}
316

317
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
318 319 320 321 322 323 324 325 326 327 328
{
    if (app_pkey_methods == NULL) {
        app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
        if (!app_pkey_methods)
            return 0;
    }
    if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
        return 0;
    sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
    return 1;
}
329

330
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
331 332 333 334 335
{
    if (ctx == NULL)
        return;
    if (ctx->pmeth && ctx->pmeth->cleanup)
        ctx->pmeth->cleanup(ctx);
R
Rich Salz 已提交
336 337
    EVP_PKEY_free(ctx->pkey);
    EVP_PKEY_free(ctx->peerkey);
338
#ifndef OPENSSL_NO_ENGINE
339 340 341 342 343 344
    if (ctx->engine)
        /*
         * The EVP_PKEY_CTX we used belongs to an ENGINE, release the
         * functional reference we held for this reason.
         */
        ENGINE_finish(ctx->engine);
345
#endif
346 347
    OPENSSL_free(ctx);
}
348

349
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
                      int cmd, int p1, void *p2)
{
    int ret;
    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
        return -2;
    }
    if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
        return -1;

    if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
        return -1;
    }

    if ((optype != -1) && !(ctx->operation & optype)) {
        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
        return -1;
    }

    ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);

    if (ret == -2)
        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);

    return ret;

}
378

379
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
380 381 382 383 384 385
                          const char *name, const char *value)
{
    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
        return -2;
    }
R
Rich Salz 已提交
386
    if (strcmp(name, "digest") == 0) {
387
        const EVP_MD *md;
388
        if (value == NULL || (md = EVP_get_digestbyname(value)) == NULL) {
389 390 391 392 393 394 395
            EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST);
            return 0;
        }
        return EVP_PKEY_CTX_set_signature_md(ctx, md);
    }
    return ctx->pmeth->ctrl_str(ctx, name, value);
}
D
Dr. Stephen Henson 已提交
396

397
int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
398 399 400
{
    return ctx->operation;
}
401 402

void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
403 404 405 406
{
    ctx->keygen_info = dat;
    ctx->keygen_info_count = datlen;
}
407

D
Dr. Stephen Henson 已提交
408
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
409 410 411
{
    ctx->data = data;
}
D
Dr. Stephen Henson 已提交
412 413

void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
414 415 416
{
    return ctx->data;
}
D
Dr. Stephen Henson 已提交
417

418
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
419 420 421
{
    return ctx->pkey;
}
422

423
EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
424 425 426 427
{
    return ctx->peerkey;
}

D
Dr. Stephen Henson 已提交
428
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
429 430 431
{
    ctx->app_data = data;
}
D
Dr. Stephen Henson 已提交
432 433

void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
434 435 436
{
    return ctx->app_data;
}
437 438

void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
439 440 441 442
                            int (*init) (EVP_PKEY_CTX *ctx))
{
    pmeth->init = init;
}
443 444

void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
445 446 447 448 449
                            int (*copy) (EVP_PKEY_CTX *dst,
                                         EVP_PKEY_CTX *src))
{
    pmeth->copy = copy;
}
450 451

void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
452 453 454 455
                               void (*cleanup) (EVP_PKEY_CTX *ctx))
{
    pmeth->cleanup = cleanup;
}
456 457

void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
458 459 460 461 462 463 464
                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
                                int (*paramgen) (EVP_PKEY_CTX *ctx,
                                                 EVP_PKEY *pkey))
{
    pmeth->paramgen_init = paramgen_init;
    pmeth->paramgen = paramgen;
}
465 466

void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
467 468 469 470 471 472 473
                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
                              int (*keygen) (EVP_PKEY_CTX *ctx,
                                             EVP_PKEY *pkey))
{
    pmeth->keygen_init = keygen_init;
    pmeth->keygen = keygen;
}
474 475

void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
476 477 478 479 480 481 482 483 484
                            int (*sign_init) (EVP_PKEY_CTX *ctx),
                            int (*sign) (EVP_PKEY_CTX *ctx,
                                         unsigned char *sig, size_t *siglen,
                                         const unsigned char *tbs,
                                         size_t tbslen))
{
    pmeth->sign_init = sign_init;
    pmeth->sign = sign;
}
485 486

void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
487 488 489 490 491 492 493 494 495 496
                              int (*verify_init) (EVP_PKEY_CTX *ctx),
                              int (*verify) (EVP_PKEY_CTX *ctx,
                                             const unsigned char *sig,
                                             size_t siglen,
                                             const unsigned char *tbs,
                                             size_t tbslen))
{
    pmeth->verify_init = verify_init;
    pmeth->verify = verify;
}
497 498

void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
499 500 501 502 503 504 505 506 507 508 509 510 511 512
                                      int (*verify_recover_init) (EVP_PKEY_CTX
                                                                  *ctx),
                                      int (*verify_recover) (EVP_PKEY_CTX
                                                             *ctx,
                                                             unsigned char
                                                             *sig,
                                                             size_t *siglen,
                                                             const unsigned
                                                             char *tbs,
                                                             size_t tbslen))
{
    pmeth->verify_recover_init = verify_recover_init;
    pmeth->verify_recover = verify_recover;
}
513 514

void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
515 516 517 518 519 520 521 522 523 524
                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
                                                    EVP_MD_CTX *mctx),
                               int (*signctx) (EVP_PKEY_CTX *ctx,
                                               unsigned char *sig,
                                               size_t *siglen,
                                               EVP_MD_CTX *mctx))
{
    pmeth->signctx_init = signctx_init;
    pmeth->signctx = signctx;
}
525 526

void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
527 528 529 530 531 532 533 534 535 536
                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
                                                        EVP_MD_CTX *mctx),
                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
                                                   const unsigned char *sig,
                                                   int siglen,
                                                   EVP_MD_CTX *mctx))
{
    pmeth->verifyctx_init = verifyctx_init;
    pmeth->verifyctx = verifyctx;
}
537 538

void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
539 540 541 542 543 544 545 546 547 548
                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
                                                 unsigned char *out,
                                                 size_t *outlen,
                                                 const unsigned char *in,
                                                 size_t inlen))
{
    pmeth->encrypt_init = encrypt_init;
    pmeth->encrypt = encryptfn;
}
549 550

void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
551 552 553 554 555 556 557 558 559 560
                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
                               int (*decrypt) (EVP_PKEY_CTX *ctx,
                                               unsigned char *out,
                                               size_t *outlen,
                                               const unsigned char *in,
                                               size_t inlen))
{
    pmeth->decrypt_init = decrypt_init;
    pmeth->decrypt = decrypt;
}
561 562

void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
563 564 565 566 567 568 569 570
                              int (*derive_init) (EVP_PKEY_CTX *ctx),
                              int (*derive) (EVP_PKEY_CTX *ctx,
                                             unsigned char *key,
                                             size_t *keylen))
{
    pmeth->derive_init = derive_init;
    pmeth->derive = derive;
}
571 572

void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
573 574 575 576 577 578 579 580 581
                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
                                         void *p2),
                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
                                             const char *type,
                                             const char *value))
{
    pmeth->ctrl = ctrl;
    pmeth->ctrl_str = ctrl_str;
}