• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* pmeth_fn.c */
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 "cryptlib.h"
62 #include <openssl/objects.h>
63 #include <openssl/evp.h>
64 #include "evp_locl.h"
65 
66 #define M_check_autoarg(ctx, arg, arglen, err) \
67 	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
68 		{ \
69 		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
70 		if (!arg) \
71 			{ \
72 			*arglen = pksize; \
73 			return 1; \
74 			} \
75 		else if (*arglen < pksize) \
76 			{ \
77 			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
78 			return 0; \
79 			} \
80 		}
81 
EVP_PKEY_sign_init(EVP_PKEY_CTX * ctx)82 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
83 	{
84 	int ret;
85 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
86 		{
87 		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
88 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
89 		return -2;
90 		}
91 	ctx->operation = EVP_PKEY_OP_SIGN;
92 	if (!ctx->pmeth->sign_init)
93 		return 1;
94 	ret = ctx->pmeth->sign_init(ctx);
95 	if (ret <= 0)
96 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
97 	return ret;
98 	}
99 
EVP_PKEY_sign(EVP_PKEY_CTX * ctx,unsigned char * sig,size_t * siglen,const unsigned char * tbs,size_t tbslen)100 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
101 			unsigned char *sig, size_t *siglen,
102 			const unsigned char *tbs, size_t tbslen)
103 	{
104 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
105 		{
106 		EVPerr(EVP_F_EVP_PKEY_SIGN,
107 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108 		return -2;
109 		}
110 	if (ctx->operation != EVP_PKEY_OP_SIGN)
111 		{
112 		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
113 		return -1;
114 		}
115 	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116 	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117 	}
118 
EVP_PKEY_verify_init(EVP_PKEY_CTX * ctx)119 int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120 	{
121 	int ret;
122 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
123 		{
124 		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
125 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
126 		return -2;
127 		}
128 	ctx->operation = EVP_PKEY_OP_VERIFY;
129 	if (!ctx->pmeth->verify_init)
130 		return 1;
131 	ret = ctx->pmeth->verify_init(ctx);
132 	if (ret <= 0)
133 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
134 	return ret;
135 	}
136 
EVP_PKEY_verify(EVP_PKEY_CTX * ctx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)137 int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
138 			const unsigned char *sig, size_t siglen,
139 			const unsigned char *tbs, size_t tbslen)
140 	{
141 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
142 		{
143 		EVPerr(EVP_F_EVP_PKEY_VERIFY,
144 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145 		return -2;
146 		}
147 	if (ctx->operation != EVP_PKEY_OP_VERIFY)
148 		{
149 		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150 		return -1;
151 		}
152 	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153 	}
154 
EVP_PKEY_verify_recover_init(EVP_PKEY_CTX * ctx)155 int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
156 	{
157 	int ret;
158 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
159 		{
160 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
161 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
162 		return -2;
163 		}
164 	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165 	if (!ctx->pmeth->verify_recover_init)
166 		return 1;
167 	ret = ctx->pmeth->verify_recover_init(ctx);
168 	if (ret <= 0)
169 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
170 	return ret;
171 	}
172 
EVP_PKEY_verify_recover(EVP_PKEY_CTX * ctx,unsigned char * rout,size_t * routlen,const unsigned char * sig,size_t siglen)173 int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
174 			unsigned char *rout, size_t *routlen,
175 			const unsigned char *sig, size_t siglen)
176 	{
177 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
178 		{
179 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
180 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
181 		return -2;
182 		}
183 	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
184 		{
185 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
186 		return -1;
187 		}
188 	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
189 	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190 	}
191 
EVP_PKEY_encrypt_init(EVP_PKEY_CTX * ctx)192 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
193 	{
194 	int ret;
195 	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
196 		{
197 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
198 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
199 		return -2;
200 		}
201 	ctx->operation = EVP_PKEY_OP_ENCRYPT;
202 	if (!ctx->pmeth->encrypt_init)
203 		return 1;
204 	ret = ctx->pmeth->encrypt_init(ctx);
205 	if (ret <= 0)
206 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
207 	return ret;
208 	}
209 
EVP_PKEY_encrypt(EVP_PKEY_CTX * ctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)210 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
211 			unsigned char *out, size_t *outlen,
212 			const unsigned char *in, size_t inlen)
213 	{
214 	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
215 		{
216 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218 		return -2;
219 		}
220 	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221 		{
222 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
223 		return -1;
224 		}
225 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
226 	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227 	}
228 
EVP_PKEY_decrypt_init(EVP_PKEY_CTX * ctx)229 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230 	{
231 	int ret;
232 	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
233 		{
234 		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236 		return -2;
237 		}
238 	ctx->operation = EVP_PKEY_OP_DECRYPT;
239 	if (!ctx->pmeth->decrypt_init)
240 		return 1;
241 	ret = ctx->pmeth->decrypt_init(ctx);
242 	if (ret <= 0)
243 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
244 	return ret;
245 	}
246 
EVP_PKEY_decrypt(EVP_PKEY_CTX * ctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)247 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
248 			unsigned char *out, size_t *outlen,
249 			const unsigned char *in, size_t inlen)
250 	{
251 	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
252 		{
253 		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
254 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
255 		return -2;
256 		}
257 	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258 		{
259 		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
260 		return -1;
261 		}
262 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
263 	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264 	}
265 
266 
EVP_PKEY_derive_init(EVP_PKEY_CTX * ctx)267 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
268 	{
269 	int ret;
270 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
271 		{
272 		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
273 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
274 		return -2;
275 		}
276 	ctx->operation = EVP_PKEY_OP_DERIVE;
277 	if (!ctx->pmeth->derive_init)
278 		return 1;
279 	ret = ctx->pmeth->derive_init(ctx);
280 	if (ret <= 0)
281 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
282 	return ret;
283 	}
284 
EVP_PKEY_derive_set_peer(EVP_PKEY_CTX * ctx,EVP_PKEY * peer)285 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
286 	{
287 	int ret;
288 	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
289 		{
290 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
291 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
292 		return -2;
293 		}
294 	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
295 		{
296 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
297 					EVP_R_OPERATON_NOT_INITIALIZED);
298 		return -1;
299 		}
300 
301 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302 
303 	if (ret <= 0)
304 		return ret;
305 
306 	if (ret == 2)
307 		return 1;
308 
309 	if (!ctx->pkey)
310 		{
311 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
312 		return -1;
313 		}
314 
315 	if (ctx->pkey->type != peer->type)
316 		{
317 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
318 						EVP_R_DIFFERENT_KEY_TYPES);
319 		return -1;
320 		}
321 
322 	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
323 	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
324 	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
325 	 * (different key types) is impossible here because it is checked earlier.
326 	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
327 	if (!EVP_PKEY_missing_parameters(peer) &&
328 		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329 		{
330 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
331 						EVP_R_DIFFERENT_PARAMETERS);
332 		return -1;
333 		}
334 
335 	if (ctx->peerkey)
336 		EVP_PKEY_free(ctx->peerkey);
337 	ctx->peerkey = peer;
338 
339 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340 
341 	if (ret <= 0)
342 		{
343 		ctx->peerkey = NULL;
344 		return ret;
345 		}
346 
347 	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
348 	return 1;
349 	}
350 
351 
EVP_PKEY_derive(EVP_PKEY_CTX * ctx,unsigned char * key,size_t * pkeylen)352 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353 	{
354 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
355 		{
356 		EVPerr(EVP_F_EVP_PKEY_DERIVE,
357 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
358 		return -2;
359 		}
360 	if (ctx->operation != EVP_PKEY_OP_DERIVE)
361 		{
362 		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
363 		return -1;
364 		}
365 	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
366 	return ctx->pmeth->derive(ctx, key, pkeylen);
367 	}
368 
369