pmeth_lib.c 18.4 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 62
 *
 * 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>
#include "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 70
#include "evp_locl.h"

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

168 169
    ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
    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 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
        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;
    ret->peerkey = NULL;
    ret->pkey_gencb = 0;
    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;
    pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
    if (!pmeth)
        return NULL;

    memset(pmeth, 0, sizeof(EVP_PKEY_METHOD));

    pmeth->pkey_id = id;
    pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;

    pmeth->init = 0;
    pmeth->copy = 0;
    pmeth->cleanup = 0;
    pmeth->paramgen_init = 0;
    pmeth->paramgen = 0;
    pmeth->keygen_init = 0;
    pmeth->keygen = 0;
    pmeth->sign_init = 0;
    pmeth->sign = 0;
    pmeth->verify_init = 0;
    pmeth->verify = 0;
    pmeth->verify_recover_init = 0;
    pmeth->verify_recover = 0;
    pmeth->signctx_init = 0;
    pmeth->signctx = 0;
    pmeth->verifyctx_init = 0;
    pmeth->verifyctx = 0;
    pmeth->encrypt_init = 0;
    pmeth->encrypt = 0;
    pmeth->decrypt_init = 0;
    pmeth->decrypt = 0;
    pmeth->derive_init = 0;
    pmeth->derive = 0;
    pmeth->ctrl = 0;
    pmeth->ctrl_str = 0;

    return pmeth;
}
237

238
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
239 240 241 242 243 244 245
                             const EVP_PKEY_METHOD *meth)
{
    if (ppkey_id)
        *ppkey_id = meth->pkey_id;
    if (pflags)
        *pflags = meth->flags;
}
246 247

void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
248
{
249

250 251 252
    dst->init = src->init;
    dst->copy = src->copy;
    dst->cleanup = src->cleanup;
253

254 255
    dst->paramgen_init = src->paramgen_init;
    dst->paramgen = src->paramgen;
256

257 258
    dst->keygen_init = src->keygen_init;
    dst->keygen = src->keygen;
259

260 261
    dst->sign_init = src->sign_init;
    dst->sign = src->sign;
262

263 264
    dst->verify_init = src->verify_init;
    dst->verify = src->verify;
265

266 267
    dst->verify_recover_init = src->verify_recover_init;
    dst->verify_recover = src->verify_recover;
268

269 270
    dst->signctx_init = src->signctx_init;
    dst->signctx = src->signctx;
271

272 273
    dst->verifyctx_init = src->verifyctx_init;
    dst->verifyctx = src->verifyctx;
274

275 276
    dst->encrypt_init = src->encrypt_init;
    dst->encrypt = src->encrypt;
277

278 279
    dst->decrypt_init = src->decrypt_init;
    dst->decrypt = src->decrypt;
280

281 282
    dst->derive_init = src->derive_init;
    dst->derive = src->derive;
283

284 285 286
    dst->ctrl = src->ctrl;
    dst->ctrl_str = src->ctrl_str;
}
287

288
void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
289 290 291 292
{
    if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
        OPENSSL_free(pmeth);
}
293

D
Dr. Stephen Henson 已提交
294
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
295 296 297
{
    return int_ctx_new(pkey, e, -1);
}
D
Dr. Stephen Henson 已提交
298 299

EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
300 301 302
{
    return int_ctx_new(NULL, e, id);
}
D
Dr. Stephen Henson 已提交
303

304
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
305 306 307 308
{
    EVP_PKEY_CTX *rctx;
    if (!pctx->pmeth || !pctx->pmeth->copy)
        return NULL;
309
#ifndef OPENSSL_NO_ENGINE
310 311 312 313 314
    /* 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;
    }
315
#endif
316 317 318
    rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
    if (!rctx)
        return NULL;
319

320
    rctx->pmeth = pctx->pmeth;
321
#ifndef OPENSSL_NO_ENGINE
322
    rctx->engine = pctx->engine;
323
#endif
324

325 326
    if (pctx->pkey)
        CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
327

328
    rctx->pkey = pctx->pkey;
329

330 331
    if (pctx->peerkey)
        CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
332

333
    rctx->peerkey = pctx->peerkey;
334

335 336 337
    rctx->data = NULL;
    rctx->app_data = NULL;
    rctx->operation = pctx->operation;
338

339 340
    if (pctx->pmeth->copy(rctx, pctx) > 0)
        return rctx;
341

342 343
    EVP_PKEY_CTX_free(rctx);
    return NULL;
344

345
}
346

347
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
348 349 350 351 352 353 354 355 356 357 358
{
    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;
}
359

360
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
361 362 363 364 365 366 367 368 369
{
    if (ctx == NULL)
        return;
    if (ctx->pmeth && ctx->pmeth->cleanup)
        ctx->pmeth->cleanup(ctx);
    if (ctx->pkey)
        EVP_PKEY_free(ctx->pkey);
    if (ctx->peerkey)
        EVP_PKEY_free(ctx->peerkey);
370
#ifndef OPENSSL_NO_ENGINE
371 372 373 374 375 376
    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);
377
#endif
378 379
    OPENSSL_free(ctx);
}
380

381
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
                      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;

}
410

411
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
                          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;
    }
    if (!strcmp(name, "digest")) {
        const EVP_MD *md;
        if (!value || !(md = EVP_get_digestbyname(value))) {
            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 已提交
428

429
int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
430 431 432
{
    return ctx->operation;
}
433 434

void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
435 436 437 438
{
    ctx->keygen_info = dat;
    ctx->keygen_info_count = datlen;
}
439

D
Dr. Stephen Henson 已提交
440
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
441 442 443
{
    ctx->data = data;
}
D
Dr. Stephen Henson 已提交
444 445

void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
446 447 448
{
    return ctx->data;
}
D
Dr. Stephen Henson 已提交
449

450
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
451 452 453
{
    return ctx->pkey;
}
454

455
EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
456 457 458 459
{
    return ctx->peerkey;
}

D
Dr. Stephen Henson 已提交
460
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
461 462 463
{
    ctx->app_data = data;
}
D
Dr. Stephen Henson 已提交
464 465

void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
466 467 468
{
    return ctx->app_data;
}
469 470

void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
471 472 473 474
                            int (*init) (EVP_PKEY_CTX *ctx))
{
    pmeth->init = init;
}
475 476

void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
477 478 479 480 481
                            int (*copy) (EVP_PKEY_CTX *dst,
                                         EVP_PKEY_CTX *src))
{
    pmeth->copy = copy;
}
482 483

void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
484 485 486 487
                               void (*cleanup) (EVP_PKEY_CTX *ctx))
{
    pmeth->cleanup = cleanup;
}
488 489

void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
490 491 492 493 494 495 496
                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
                                int (*paramgen) (EVP_PKEY_CTX *ctx,
                                                 EVP_PKEY *pkey))
{
    pmeth->paramgen_init = paramgen_init;
    pmeth->paramgen = paramgen;
}
497 498

void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
499 500 501 502 503 504 505
                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
                              int (*keygen) (EVP_PKEY_CTX *ctx,
                                             EVP_PKEY *pkey))
{
    pmeth->keygen_init = keygen_init;
    pmeth->keygen = keygen;
}
506 507

void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
508 509 510 511 512 513 514 515 516
                            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;
}
517 518

void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
519 520 521 522 523 524 525 526 527 528
                              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;
}
529 530

void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
531 532 533 534 535 536 537 538 539 540 541 542 543 544
                                      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;
}
545 546

void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
547 548 549 550 551 552 553 554 555 556
                               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;
}
557 558

void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
559 560 561 562 563 564 565 566 567 568
                                 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;
}
569 570

void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
571 572 573 574 575 576 577 578 579 580
                               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;
}
581 582

void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
583 584 585 586 587 588 589 590 591 592
                               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;
}
593 594

void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
595 596 597 598 599 600 601 602
                              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;
}
603 604

void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
605 606 607 608 609 610 611 612 613
                            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;
}