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 201

    pmeth = OPENSSL_malloc(sizeof(*pmeth));
202 203 204
    if (!pmeth)
        return NULL;

205
    memset(pmeth, 0, sizeof(*pmeth));
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 237

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

343 344
    EVP_PKEY_CTX_free(rctx);
    return NULL;
345

346
}
347

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

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

380
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
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 406 407 408
                      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;

}
409

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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