pmeth_lib.c 18.3 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_malloc(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 198 199
        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;
R
Rich Salz 已提交
200

R
Rich Salz 已提交
201
    pmeth = OPENSSL_zalloc(sizeof(*pmeth));
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
    if (!pmeth)
        return NULL;

    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;
}
235

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

void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
246
{
247

248 249 250
    dst->init = src->init;
    dst->copy = src->copy;
    dst->cleanup = src->cleanup;
251

252 253
    dst->paramgen_init = src->paramgen_init;
    dst->paramgen = src->paramgen;
254

255 256
    dst->keygen_init = src->keygen_init;
    dst->keygen = src->keygen;
257

258 259
    dst->sign_init = src->sign_init;
    dst->sign = src->sign;
260

261 262
    dst->verify_init = src->verify_init;
    dst->verify = src->verify;
263

264 265
    dst->verify_recover_init = src->verify_recover_init;
    dst->verify_recover = src->verify_recover;
266

267 268
    dst->signctx_init = src->signctx_init;
    dst->signctx = src->signctx;
269

270 271
    dst->verifyctx_init = src->verifyctx_init;
    dst->verifyctx = src->verifyctx;
272

273 274
    dst->encrypt_init = src->encrypt_init;
    dst->encrypt = src->encrypt;
275

276 277
    dst->decrypt_init = src->decrypt_init;
    dst->decrypt = src->decrypt;
278

279 280
    dst->derive_init = src->derive_init;
    dst->derive = src->derive;
281

282 283 284
    dst->ctrl = src->ctrl;
    dst->ctrl_str = src->ctrl_str;
}
285

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

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

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

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

318
    rctx->pmeth = pctx->pmeth;
319
#ifndef OPENSSL_NO_ENGINE
320
    rctx->engine = pctx->engine;
321
#endif
322

323 324
    if (pctx->pkey)
        CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
325

326
    rctx->pkey = pctx->pkey;
327

328 329
    if (pctx->peerkey)
        CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
330

331
    rctx->peerkey = pctx->peerkey;
332

333 334 335
    rctx->data = NULL;
    rctx->app_data = NULL;
    rctx->operation = pctx->operation;
336

337 338
    if (pctx->pmeth->copy(rctx, pctx) > 0)
        return rctx;
339

340 341
    EVP_PKEY_CTX_free(rctx);
    return NULL;
342

343
}
344

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

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

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

}
406

407
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
408 409 410 411 412 413
                          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 已提交
414
    if (strcmp(name, "digest") == 0) {
415
        const EVP_MD *md;
416
        if (value == NULL || (md = EVP_get_digestbyname(value)) == NULL) {
417 418 419 420 421 422 423
            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 已提交
424

425
int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
426 427 428
{
    return ctx->operation;
}
429 430

void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
431 432 433 434
{
    ctx->keygen_info = dat;
    ctx->keygen_info_count = datlen;
}
435

D
Dr. Stephen Henson 已提交
436
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
437 438 439
{
    ctx->data = data;
}
D
Dr. Stephen Henson 已提交
440 441

void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
442 443 444
{
    return ctx->data;
}
D
Dr. Stephen Henson 已提交
445

446
EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
447 448 449
{
    return ctx->pkey;
}
450

451
EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
452 453 454 455
{
    return ctx->peerkey;
}

D
Dr. Stephen Henson 已提交
456
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
457 458 459
{
    ctx->app_data = data;
}
D
Dr. Stephen Henson 已提交
460 461

void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
462 463 464
{
    return ctx->app_data;
}
465 466

void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
467 468 469 470
                            int (*init) (EVP_PKEY_CTX *ctx))
{
    pmeth->init = init;
}
471 472

void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
473 474 475 476 477
                            int (*copy) (EVP_PKEY_CTX *dst,
                                         EVP_PKEY_CTX *src))
{
    pmeth->copy = copy;
}
478 479

void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
480 481 482 483
                               void (*cleanup) (EVP_PKEY_CTX *ctx))
{
    pmeth->cleanup = cleanup;
}
484 485

void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
486 487 488 489 490 491 492
                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
                                int (*paramgen) (EVP_PKEY_CTX *ctx,
                                                 EVP_PKEY *pkey))
{
    pmeth->paramgen_init = paramgen_init;
    pmeth->paramgen = paramgen;
}
493 494

void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
495 496 497 498 499 500 501
                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
                              int (*keygen) (EVP_PKEY_CTX *ctx,
                                             EVP_PKEY *pkey))
{
    pmeth->keygen_init = keygen_init;
    pmeth->keygen = keygen;
}
502 503

void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
504 505 506 507 508 509 510 511 512
                            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;
}
513 514

void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
515 516 517 518 519 520 521 522 523 524
                              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;
}
525 526

void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
527 528 529 530 531 532 533 534 535 536 537 538 539 540
                                      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;
}
541 542

void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
543 544 545 546 547 548 549 550 551 552
                               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;
}
553 554

void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
555 556 557 558 559 560 561 562 563 564
                                 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;
}
565 566

void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
567 568 569 570 571 572 573 574 575 576
                               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;
}
577 578

void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
579 580 581 582 583 584 585 586 587 588
                               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;
}
589 590

void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
591 592 593 594 595 596 597 598
                              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;
}
599 600

void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
601 602 603 604 605 606 607 608 609
                            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;
}