xref: /openbsd-src/lib/libcrypto/evp/pmeth_fn.c (revision 474ea8ba179719239431070606a28b55464f844c)
1*474ea8baStb /* $OpenBSD: pmeth_fn.c,v 1.11 2024/04/12 09:41:39 tb Exp $ */
2f1535dc8Sdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3f1535dc8Sdjm  * project 2006.
4f1535dc8Sdjm  */
5f1535dc8Sdjm /* ====================================================================
6f1535dc8Sdjm  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7f1535dc8Sdjm  *
8f1535dc8Sdjm  * Redistribution and use in source and binary forms, with or without
9f1535dc8Sdjm  * modification, are permitted provided that the following conditions
10f1535dc8Sdjm  * are met:
11f1535dc8Sdjm  *
12f1535dc8Sdjm  * 1. Redistributions of source code must retain the above copyright
13f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer.
14f1535dc8Sdjm  *
15f1535dc8Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
16f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer in
17f1535dc8Sdjm  *    the documentation and/or other materials provided with the
18f1535dc8Sdjm  *    distribution.
19f1535dc8Sdjm  *
20f1535dc8Sdjm  * 3. All advertising materials mentioning features or use of this
21f1535dc8Sdjm  *    software must display the following acknowledgment:
22f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
23f1535dc8Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24f1535dc8Sdjm  *
25f1535dc8Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f1535dc8Sdjm  *    endorse or promote products derived from this software without
27f1535dc8Sdjm  *    prior written permission. For written permission, please contact
28f1535dc8Sdjm  *    licensing@OpenSSL.org.
29f1535dc8Sdjm  *
30f1535dc8Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
31f1535dc8Sdjm  *    nor may "OpenSSL" appear in their names without prior written
32f1535dc8Sdjm  *    permission of the OpenSSL Project.
33f1535dc8Sdjm  *
34f1535dc8Sdjm  * 6. Redistributions of any form whatsoever must retain the following
35f1535dc8Sdjm  *    acknowledgment:
36f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
37f1535dc8Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38f1535dc8Sdjm  *
39f1535dc8Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f1535dc8Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f1535dc8Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f1535dc8Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f1535dc8Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f1535dc8Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f1535dc8Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f1535dc8Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f1535dc8Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f1535dc8Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f1535dc8Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f1535dc8Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
51f1535dc8Sdjm  * ====================================================================
52f1535dc8Sdjm  *
53f1535dc8Sdjm  * This product includes cryptographic software written by Eric Young
54f1535dc8Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
55f1535dc8Sdjm  * Hudson (tjh@cryptsoft.com).
56f1535dc8Sdjm  *
57f1535dc8Sdjm  */
58f1535dc8Sdjm 
59f1535dc8Sdjm #include <stdio.h>
60f1535dc8Sdjm #include <stdlib.h>
61b6ab114eSjsing 
62b6ab114eSjsing #include <openssl/err.h>
63f1535dc8Sdjm #include <openssl/evp.h>
64b6ab114eSjsing #include <openssl/objects.h>
65b6ab114eSjsing 
66c9675a23Stb #include "evp_local.h"
67f1535dc8Sdjm 
68f1535dc8Sdjm #define M_check_autoarg(ctx, arg, arglen, err) \
69f1535dc8Sdjm 	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
70f1535dc8Sdjm 		{ \
71f1535dc8Sdjm 		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
72f1535dc8Sdjm 		if (!arg) \
73f1535dc8Sdjm 			{ \
74f1535dc8Sdjm 			*arglen = pksize; \
75f1535dc8Sdjm 			return 1; \
76f1535dc8Sdjm 			} \
77f1535dc8Sdjm 		else if (*arglen < pksize) \
78f1535dc8Sdjm 			{ \
795067ae9fSbeck 			EVPerror(EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
80f1535dc8Sdjm 			return 0; \
81f1535dc8Sdjm 			} \
82f1535dc8Sdjm 		}
83f1535dc8Sdjm 
84f7631d64Sjsing int
EVP_PKEY_sign_init(EVP_PKEY_CTX * ctx)85f7631d64Sjsing EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
86f1535dc8Sdjm {
87f1535dc8Sdjm 	int ret;
88f7631d64Sjsing 
89f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
905067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
91f1535dc8Sdjm 		return -2;
92f1535dc8Sdjm 	}
93f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_SIGN;
94f1535dc8Sdjm 	if (!ctx->pmeth->sign_init)
95f1535dc8Sdjm 		return 1;
96f1535dc8Sdjm 	ret = ctx->pmeth->sign_init(ctx);
97f1535dc8Sdjm 	if (ret <= 0)
98f1535dc8Sdjm 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
99f1535dc8Sdjm 	return ret;
100f1535dc8Sdjm }
1019bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_sign_init);
102f1535dc8Sdjm 
103f7631d64Sjsing int
EVP_PKEY_sign(EVP_PKEY_CTX * ctx,unsigned char * sig,size_t * siglen,const unsigned char * tbs,size_t tbslen)104f7631d64Sjsing EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
105f1535dc8Sdjm     const unsigned char *tbs, size_t tbslen)
106f1535dc8Sdjm {
107f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
1085067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
109f1535dc8Sdjm 		return -2;
110f1535dc8Sdjm 	}
111f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_SIGN) {
1125067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
113f1535dc8Sdjm 		return -1;
114f1535dc8Sdjm 	}
115f1535dc8Sdjm 	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116f1535dc8Sdjm 	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117f1535dc8Sdjm }
1189bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_sign);
119f1535dc8Sdjm 
120f7631d64Sjsing int
EVP_PKEY_verify_init(EVP_PKEY_CTX * ctx)121f7631d64Sjsing EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
122f1535dc8Sdjm {
123f1535dc8Sdjm 	int ret;
124f7631d64Sjsing 
125f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
1265067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
127f1535dc8Sdjm 		return -2;
128f1535dc8Sdjm 	}
129f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_VERIFY;
130f1535dc8Sdjm 	if (!ctx->pmeth->verify_init)
131f1535dc8Sdjm 		return 1;
132f1535dc8Sdjm 	ret = ctx->pmeth->verify_init(ctx);
133f1535dc8Sdjm 	if (ret <= 0)
134f1535dc8Sdjm 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
135f1535dc8Sdjm 	return ret;
136f1535dc8Sdjm }
1379bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_verify_init);
138f1535dc8Sdjm 
139f7631d64Sjsing int
EVP_PKEY_verify(EVP_PKEY_CTX * ctx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)140f7631d64Sjsing EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
141f1535dc8Sdjm     const unsigned char *tbs, size_t tbslen)
142f1535dc8Sdjm {
143f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
1445067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145f1535dc8Sdjm 		return -2;
146f1535dc8Sdjm 	}
147f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_VERIFY) {
1485067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
149f1535dc8Sdjm 		return -1;
150f1535dc8Sdjm 	}
151f1535dc8Sdjm 	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
152f1535dc8Sdjm }
1539bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_verify);
154f1535dc8Sdjm 
155f7631d64Sjsing int
EVP_PKEY_verify_recover_init(EVP_PKEY_CTX * ctx)156f7631d64Sjsing EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
157f1535dc8Sdjm {
158*474ea8baStb 	if (ctx == NULL || ctx->pmeth == NULL ||
159*474ea8baStb 	    ctx->pmeth->verify_recover == NULL) {
1605067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
161f1535dc8Sdjm 		return -2;
162f1535dc8Sdjm 	}
163*474ea8baStb 
164f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165*474ea8baStb 
166f1535dc8Sdjm 	return 1;
167f1535dc8Sdjm }
1689bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_verify_recover_init);
169f1535dc8Sdjm 
170f7631d64Sjsing int
EVP_PKEY_verify_recover(EVP_PKEY_CTX * ctx,unsigned char * rout,size_t * routlen,const unsigned char * sig,size_t siglen)171f7631d64Sjsing EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
172f1535dc8Sdjm     const unsigned char *sig, size_t siglen)
173f1535dc8Sdjm {
174f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
1755067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
176f1535dc8Sdjm 		return -2;
177f1535dc8Sdjm 	}
178f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
1795067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
180f1535dc8Sdjm 		return -1;
181f1535dc8Sdjm 	}
182f1535dc8Sdjm 	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
183f1535dc8Sdjm 	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
184f1535dc8Sdjm }
1859bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_verify_recover);
186f1535dc8Sdjm 
187f7631d64Sjsing int
EVP_PKEY_encrypt_init(EVP_PKEY_CTX * ctx)188f7631d64Sjsing EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
189f1535dc8Sdjm {
190*474ea8baStb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
1915067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
192f1535dc8Sdjm 		return -2;
193f1535dc8Sdjm 	}
194*474ea8baStb 
195f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_ENCRYPT;
196*474ea8baStb 
197f1535dc8Sdjm 	return 1;
198f1535dc8Sdjm }
1999bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_encrypt_init);
200f1535dc8Sdjm 
201f7631d64Sjsing int
EVP_PKEY_encrypt(EVP_PKEY_CTX * ctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)202f7631d64Sjsing EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
203f1535dc8Sdjm     const unsigned char *in, size_t inlen)
204f1535dc8Sdjm {
205f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
2065067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
207f1535dc8Sdjm 		return -2;
208f1535dc8Sdjm 	}
209f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
2105067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
211f1535dc8Sdjm 		return -1;
212f1535dc8Sdjm 	}
213f1535dc8Sdjm 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
214f1535dc8Sdjm 	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
215f1535dc8Sdjm }
2169bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_encrypt);
217f1535dc8Sdjm 
218f7631d64Sjsing int
EVP_PKEY_decrypt_init(EVP_PKEY_CTX * ctx)219f7631d64Sjsing EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
220f1535dc8Sdjm {
221*474ea8baStb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) {
2225067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
223f1535dc8Sdjm 		return -2;
224f1535dc8Sdjm 	}
225*474ea8baStb 
226f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_DECRYPT;
227*474ea8baStb 
228f1535dc8Sdjm 	return 1;
229f1535dc8Sdjm }
2309bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_decrypt_init);
231f1535dc8Sdjm 
232f7631d64Sjsing int
EVP_PKEY_decrypt(EVP_PKEY_CTX * ctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)233f7631d64Sjsing EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
234f1535dc8Sdjm     const unsigned char *in, size_t inlen)
235f1535dc8Sdjm {
236f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
2375067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
238f1535dc8Sdjm 		return -2;
239f1535dc8Sdjm 	}
240f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
2415067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
242f1535dc8Sdjm 		return -1;
243f1535dc8Sdjm 	}
244f1535dc8Sdjm 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
245f1535dc8Sdjm 	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
246f1535dc8Sdjm }
2479bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_decrypt);
248f1535dc8Sdjm 
249f7631d64Sjsing int
EVP_PKEY_derive_init(EVP_PKEY_CTX * ctx)250f7631d64Sjsing EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
251f1535dc8Sdjm {
252f1535dc8Sdjm 	int ret;
253f7631d64Sjsing 
254f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
2555067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
256f1535dc8Sdjm 		return -2;
257f1535dc8Sdjm 	}
258f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_DERIVE;
259f1535dc8Sdjm 	if (!ctx->pmeth->derive_init)
260f1535dc8Sdjm 		return 1;
261f1535dc8Sdjm 	ret = ctx->pmeth->derive_init(ctx);
262f1535dc8Sdjm 	if (ret <= 0)
263f1535dc8Sdjm 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
264f1535dc8Sdjm 	return ret;
265f1535dc8Sdjm }
2669bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_derive_init);
267f1535dc8Sdjm 
268f7631d64Sjsing int
EVP_PKEY_derive_set_peer(EVP_PKEY_CTX * ctx,EVP_PKEY * peer)269f7631d64Sjsing EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
270f1535dc8Sdjm {
271f1535dc8Sdjm 	int ret;
272f7631d64Sjsing 
273f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive ||
274f7631d64Sjsing 	    ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
275f7631d64Sjsing 	    !ctx->pmeth->ctrl) {
2765067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
277f1535dc8Sdjm 		return -2;
278f1535dc8Sdjm 	}
279f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_DERIVE &&
280f7631d64Sjsing 	    ctx->operation != EVP_PKEY_OP_ENCRYPT &&
281f7631d64Sjsing 	    ctx->operation != EVP_PKEY_OP_DECRYPT) {
2825067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
283f1535dc8Sdjm 		return -1;
284f1535dc8Sdjm 	}
285f1535dc8Sdjm 
286f1535dc8Sdjm 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
287f1535dc8Sdjm 
288f1535dc8Sdjm 	if (ret <= 0)
289f1535dc8Sdjm 		return ret;
290f1535dc8Sdjm 
291f1535dc8Sdjm 	if (ret == 2)
292f1535dc8Sdjm 		return 1;
293f1535dc8Sdjm 
294f7631d64Sjsing 	if (!ctx->pkey) {
2955067ae9fSbeck 		EVPerror(EVP_R_NO_KEY_SET);
296f1535dc8Sdjm 		return -1;
297f1535dc8Sdjm 	}
298f1535dc8Sdjm 
299f7631d64Sjsing 	if (ctx->pkey->type != peer->type) {
3005067ae9fSbeck 		EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
301f1535dc8Sdjm 		return -1;
302f1535dc8Sdjm 	}
303f1535dc8Sdjm 
304f1535dc8Sdjm 	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
305f1535dc8Sdjm 	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
306f1535dc8Sdjm 	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
307f1535dc8Sdjm 	 * (different key types) is impossible here because it is checked earlier.
308f1535dc8Sdjm 	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
309f1535dc8Sdjm 	if (!EVP_PKEY_missing_parameters(peer) &&
310f7631d64Sjsing 	    !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
3115067ae9fSbeck 		EVPerror(EVP_R_DIFFERENT_PARAMETERS);
312f1535dc8Sdjm 		return -1;
313f1535dc8Sdjm 	}
314f1535dc8Sdjm 
315f1535dc8Sdjm 	EVP_PKEY_free(ctx->peerkey);
316f1535dc8Sdjm 	ctx->peerkey = peer;
317f1535dc8Sdjm 
318f1535dc8Sdjm 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
319f1535dc8Sdjm 
320f7631d64Sjsing 	if (ret <= 0) {
321f1535dc8Sdjm 		ctx->peerkey = NULL;
322f1535dc8Sdjm 		return ret;
323f1535dc8Sdjm 	}
324f1535dc8Sdjm 
325f1535dc8Sdjm 	CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
326f1535dc8Sdjm 	return 1;
327f1535dc8Sdjm }
3289bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_derive_set_peer);
329f1535dc8Sdjm 
330f7631d64Sjsing int
EVP_PKEY_derive(EVP_PKEY_CTX * ctx,unsigned char * key,size_t * pkeylen)331f7631d64Sjsing EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
332f1535dc8Sdjm {
333f7631d64Sjsing 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
3345067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
335f1535dc8Sdjm 		return -2;
336f1535dc8Sdjm 	}
337f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_DERIVE) {
3385067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
339f1535dc8Sdjm 		return -1;
340f1535dc8Sdjm 	}
341f1535dc8Sdjm 	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
342f1535dc8Sdjm 	return ctx->pmeth->derive(ctx, key, pkeylen);
343f1535dc8Sdjm }
3449bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_derive);
345