GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/evp/pmeth_lib.c Lines: 79 223 35.4 %
Date: 2016-12-06 Branches: 38 106 35.8 %

Line Branch Exec Source
1
/* $OpenBSD: pmeth_lib.c,v 1.11 2015/02/11 03:19:37 doug Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 2006.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <stdio.h>
60
#include <stdlib.h>
61
#include <string.h>
62
63
#include <openssl/opensslconf.h>
64
65
#include <openssl/err.h>
66
#include <openssl/evp.h>
67
#include <openssl/objects.h>
68
69
#ifndef OPENSSL_NO_ENGINE
70
#include <openssl/engine.h>
71
#endif
72
73
#include "asn1_locl.h"
74
#include "evp_locl.h"
75
76
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
77
78
DECLARE_STACK_OF(EVP_PKEY_METHOD)
79
STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
80
81
extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
82
extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
83
extern const EVP_PKEY_METHOD gostimit_pkey_meth, gostr01_pkey_meth;
84
85
static const EVP_PKEY_METHOD *standard_methods[] = {
86
#ifndef OPENSSL_NO_RSA
87
	&rsa_pkey_meth,
88
#endif
89
#ifndef OPENSSL_NO_DH
90
	&dh_pkey_meth,
91
#endif
92
#ifndef OPENSSL_NO_DSA
93
	&dsa_pkey_meth,
94
#endif
95
#ifndef OPENSSL_NO_EC
96
	&ec_pkey_meth,
97
#endif
98
#ifndef OPENSSL_NO_GOST
99
	&gostr01_pkey_meth,
100
	&gostimit_pkey_meth,
101
#endif
102
	&hmac_pkey_meth,
103
	&cmac_pkey_meth,
104
};
105
106
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
107
    pmeth);
108
109
static int
110
pmeth_cmp(const EVP_PKEY_METHOD * const *a, const EVP_PKEY_METHOD * const *b)
111
167
{
112
167
	return ((*a)->pkey_id - (*b)->pkey_id);
113
}
114
115
230
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
116
    pmeth);
117
118
const EVP_PKEY_METHOD *
119
EVP_PKEY_meth_find(int type)
120
63
{
121
	EVP_PKEY_METHOD tmp;
122
63
	const EVP_PKEY_METHOD *t = &tmp, **ret;
123
124
63
	tmp.pkey_id = type;
125
63
	if (app_pkey_methods) {
126
		int idx;
127
		idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
128
		if (idx >= 0)
129
			return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
130
	}
131
63
	ret = OBJ_bsearch_pmeth(&t, standard_methods,
132
	    sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
133

63
	if (!ret || !*ret)
134
		return NULL;
135
63
	return *ret;
136
}
137
138
static EVP_PKEY_CTX *
139
int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
140
61
{
141
	EVP_PKEY_CTX *ret;
142
	const EVP_PKEY_METHOD *pmeth;
143
144
61
	if (id == -1) {
145

43
		if (!pkey || !pkey->ameth)
146
			return NULL;
147
43
		id = pkey->ameth->pkey_id;
148
	}
149
#ifndef OPENSSL_NO_ENGINE
150

61
	if (pkey && pkey->engine)
151
		e = pkey->engine;
152
	/* Try to find an ENGINE which implements this method */
153
61
	if (e) {
154
		if (!ENGINE_init(e)) {
155
			EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
156
			return NULL;
157
		}
158
	} else
159
61
		e = ENGINE_get_pkey_meth_engine(id);
160
161
	/* If an ENGINE handled this method look it up. Othewise
162
	 * use internal tables.
163
	 */
164
165
61
	if (e)
166
		pmeth = ENGINE_get_pkey_meth(e, id);
167
	else
168
#endif
169
61
		pmeth = EVP_PKEY_meth_find(id);
170
171
61
	if (pmeth == NULL) {
172
		EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
173
		return NULL;
174
	}
175
176
61
	ret = malloc(sizeof(EVP_PKEY_CTX));
177
61
	if (!ret) {
178
#ifndef OPENSSL_NO_ENGINE
179
		if (e)
180
			ENGINE_finish(e);
181
#endif
182
		EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
183
		return NULL;
184
	}
185
61
	ret->engine = e;
186
61
	ret->pmeth = pmeth;
187
61
	ret->operation = EVP_PKEY_OP_UNDEFINED;
188
61
	ret->pkey = pkey;
189
61
	ret->peerkey = NULL;
190
61
	ret->pkey_gencb = 0;
191
61
	if (pkey)
192
43
		CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
193
61
	ret->data = NULL;
194
195
61
	if (pmeth->init) {
196
61
		if (pmeth->init(ret) <= 0) {
197
			EVP_PKEY_CTX_free(ret);
198
			return NULL;
199
		}
200
	}
201
202
61
	return ret;
203
}
204
205
EVP_PKEY_METHOD*
206
EVP_PKEY_meth_new(int id, int flags)
207
{
208
	EVP_PKEY_METHOD *pmeth;
209
210
	pmeth = calloc(1, sizeof(EVP_PKEY_METHOD));
211
	if (!pmeth)
212
		return NULL;
213
214
	pmeth->pkey_id = id;
215
	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
216
217
	pmeth->init = 0;
218
	pmeth->copy = 0;
219
	pmeth->cleanup = 0;
220
	pmeth->paramgen_init = 0;
221
	pmeth->paramgen = 0;
222
	pmeth->keygen_init = 0;
223
	pmeth->keygen = 0;
224
	pmeth->sign_init = 0;
225
	pmeth->sign = 0;
226
	pmeth->verify_init = 0;
227
	pmeth->verify = 0;
228
	pmeth->verify_recover_init = 0;
229
	pmeth->verify_recover = 0;
230
	pmeth->signctx_init = 0;
231
	pmeth->signctx = 0;
232
	pmeth->verifyctx_init = 0;
233
	pmeth->verifyctx = 0;
234
	pmeth->encrypt_init = 0;
235
	pmeth->encrypt = 0;
236
	pmeth->decrypt_init = 0;
237
	pmeth->decrypt = 0;
238
	pmeth->derive_init = 0;
239
	pmeth->derive = 0;
240
	pmeth->ctrl = 0;
241
	pmeth->ctrl_str = 0;
242
243
	return pmeth;
244
}
245
246
void
247
EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth)
248
{
249
	if (ppkey_id)
250
		*ppkey_id = meth->pkey_id;
251
	if (pflags)
252
		*pflags = meth->flags;
253
}
254
255
void
256
EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
257
{
258
	dst->init = src->init;
259
	dst->copy = src->copy;
260
	dst->cleanup = src->cleanup;
261
262
	dst->paramgen_init = src->paramgen_init;
263
	dst->paramgen = src->paramgen;
264
265
	dst->keygen_init = src->keygen_init;
266
	dst->keygen = src->keygen;
267
268
	dst->sign_init = src->sign_init;
269
	dst->sign = src->sign;
270
271
	dst->verify_init = src->verify_init;
272
	dst->verify = src->verify;
273
274
	dst->verify_recover_init = src->verify_recover_init;
275
	dst->verify_recover = src->verify_recover;
276
277
	dst->signctx_init = src->signctx_init;
278
	dst->signctx = src->signctx;
279
280
	dst->verifyctx_init = src->verifyctx_init;
281
	dst->verifyctx = src->verifyctx;
282
283
	dst->encrypt_init = src->encrypt_init;
284
	dst->encrypt = src->encrypt;
285
286
	dst->decrypt_init = src->decrypt_init;
287
	dst->decrypt = src->decrypt;
288
289
	dst->derive_init = src->derive_init;
290
	dst->derive = src->derive;
291
292
	dst->ctrl = src->ctrl;
293
	dst->ctrl_str = src->ctrl_str;
294
}
295
296
void
297
EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
298
{
299
	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
300
		free(pmeth);
301
}
302
303
EVP_PKEY_CTX *
304
EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
305
43
{
306
43
	return int_ctx_new(pkey, e, -1);
307
}
308
309
EVP_PKEY_CTX *
310
EVP_PKEY_CTX_new_id(int id, ENGINE *e)
311
18
{
312
18
	return int_ctx_new(NULL, e, id);
313
}
314
315
EVP_PKEY_CTX *
316
EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
317
45
{
318
	EVP_PKEY_CTX *rctx;
319
320

45
	if (!pctx->pmeth || !pctx->pmeth->copy)
321
		return NULL;
322
#ifndef OPENSSL_NO_ENGINE
323
	/* Make sure it's safe to copy a pkey context using an ENGINE */
324

45
	if (pctx->engine && !ENGINE_init(pctx->engine)) {
325
		EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
326
		return 0;
327
	}
328
#endif
329
45
	rctx = malloc(sizeof(EVP_PKEY_CTX));
330
45
	if (!rctx)
331
		return NULL;
332
333
45
	rctx->pmeth = pctx->pmeth;
334
#ifndef OPENSSL_NO_ENGINE
335
45
	rctx->engine = pctx->engine;
336
#endif
337
338
45
	if (pctx->pkey)
339
45
		CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
340
341
45
	rctx->pkey = pctx->pkey;
342
343
45
	if (pctx->peerkey)
344
		CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
345
346
45
	rctx->peerkey = pctx->peerkey;
347
348
45
	rctx->data = NULL;
349
45
	rctx->app_data = NULL;
350
45
	rctx->operation = pctx->operation;
351
352
45
	if (pctx->pmeth->copy(rctx, pctx) > 0)
353
45
		return rctx;
354
355
	EVP_PKEY_CTX_free(rctx);
356
	return NULL;
357
}
358
359
int
360
EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
361
{
362
	if (app_pkey_methods == NULL) {
363
		app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
364
		if (!app_pkey_methods)
365
			return 0;
366
	}
367
	if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
368
		return 0;
369
	sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
370
	return 1;
371
}
372
373
void
374
EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
375
317024
{
376
317024
	if (ctx == NULL)
377
316918
		return;
378

106
	if (ctx->pmeth && ctx->pmeth->cleanup)
379
106
		ctx->pmeth->cleanup(ctx);
380
106
	EVP_PKEY_free(ctx->pkey);
381
106
	EVP_PKEY_free(ctx->peerkey);
382
#ifndef OPENSSL_NO_ENGINE
383
106
	if (ctx->engine)
384
		/* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
385
		 * functional reference we held for this reason. */
386
		ENGINE_finish(ctx->engine);
387
#endif
388
106
	free(ctx);
389
}
390
391
int
392
EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
393
    int p1, void *p2)
394
158
{
395
	int ret;
396
397

158
	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
398
		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
399
		return -2;
400
	}
401

158
	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
402
		return -1;
403
404
158
	if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
405
		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
406
		return -1;
407
	}
408
409

158
	if ((optype != -1) && !(ctx->operation & optype)) {
410
		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
411
		return -1;
412
	}
413
414
158
	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
415
416
158
	if (ret == -2)
417
		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
418
419
158
	return ret;
420
421
}
422
423
int
424
EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value)
425
{
426
	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
427
		EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
428
		    EVP_R_COMMAND_NOT_SUPPORTED);
429
		return -2;
430
	}
431
	if (!strcmp(name, "digest")) {
432
		const EVP_MD *md;
433
		if (!value || !(md = EVP_get_digestbyname(value))) {
434
			EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
435
			    EVP_R_INVALID_DIGEST);
436
			return 0;
437
		}
438
		return EVP_PKEY_CTX_set_signature_md(ctx, md);
439
	}
440
	return ctx->pmeth->ctrl_str(ctx, name, value);
441
}
442
443
int
444
EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
445
{
446
	return ctx->operation;
447
}
448
449
void
450
EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
451
{
452
	ctx->keygen_info = dat;
453
	ctx->keygen_info_count = datlen;
454
}
455
456
void
457
EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
458
24
{
459
24
	ctx->data = data;
460
24
}
461
462
void *
463
EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
464
72
{
465
72
	return ctx->data;
466
}
467
468
EVP_PKEY *
469
EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
470
8
{
471
8
	return ctx->pkey;
472
}
473
474
EVP_PKEY *
475
EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
476
{
477
	return ctx->peerkey;
478
}
479
480
void
481
EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
482
{
483
	ctx->app_data = data;
484
}
485
486
void *
487
EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
488
{
489
	return ctx->app_data;
490
}
491
492
void
493
EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
494
    int (*init)(EVP_PKEY_CTX *ctx))
495
{
496
	pmeth->init = init;
497
}
498
499
void
500
EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
501
    int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
502
{
503
	pmeth->copy = copy;
504
}
505
506
void
507
EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
508
    void (*cleanup)(EVP_PKEY_CTX *ctx))
509
{
510
	pmeth->cleanup = cleanup;
511
}
512
513
void
514
EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
515
    int (*paramgen_init)(EVP_PKEY_CTX *ctx),
516
    int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
517
{
518
	pmeth->paramgen_init = paramgen_init;
519
	pmeth->paramgen = paramgen;
520
}
521
522
void
523
EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
524
    int (*keygen_init)(EVP_PKEY_CTX *ctx),
525
    int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
526
{
527
	pmeth->keygen_init = keygen_init;
528
	pmeth->keygen = keygen;
529
}
530
531
void
532
EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
533
    int (*sign_init)(EVP_PKEY_CTX *ctx),
534
    int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
535
    const unsigned char *tbs, size_t tbslen))
536
{
537
	pmeth->sign_init = sign_init;
538
	pmeth->sign = sign;
539
}
540
541
void
542
EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
543
    int (*verify_init)(EVP_PKEY_CTX *ctx),
544
    int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
545
    const unsigned char *tbs, size_t tbslen))
546
{
547
	pmeth->verify_init = verify_init;
548
	pmeth->verify = verify;
549
}
550
551
void
552
EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
553
    int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
554
    int (*verify_recover)(EVP_PKEY_CTX *ctx,
555
    unsigned char *sig, size_t *siglen,
556
    const unsigned char *tbs, size_t tbslen))
557
{
558
	pmeth->verify_recover_init = verify_recover_init;
559
	pmeth->verify_recover = verify_recover;
560
}
561
562
void
563
EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
564
    int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
565
    int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
566
    EVP_MD_CTX *mctx))
567
{
568
	pmeth->signctx_init = signctx_init;
569
	pmeth->signctx = signctx;
570
}
571
572
void
573
EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
574
    int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
575
    int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
576
    EVP_MD_CTX *mctx))
577
{
578
	pmeth->verifyctx_init = verifyctx_init;
579
	pmeth->verifyctx = verifyctx;
580
}
581
582
void
583
EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
584
    int (*encrypt_init)(EVP_PKEY_CTX *ctx),
585
    int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
586
    const unsigned char *in, size_t inlen))
587
{
588
	pmeth->encrypt_init = encrypt_init;
589
	pmeth->encrypt = encryptfn;
590
}
591
592
void
593
EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
594
    int (*decrypt_init)(EVP_PKEY_CTX *ctx),
595
    int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
596
    const unsigned char *in, size_t inlen))
597
{
598
	pmeth->decrypt_init = decrypt_init;
599
	pmeth->decrypt = decrypt;
600
}
601
602
void
603
EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
604
    int (*derive_init)(EVP_PKEY_CTX *ctx),
605
    int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
606
{
607
	pmeth->derive_init = derive_init;
608
	pmeth->derive = derive;
609
}
610
611
void
612
EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
613
    int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
614
    int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
615
{
616
	pmeth->ctrl = ctrl;
617
	pmeth->ctrl_str = ctrl_str;
618
}