Branch data Line data Source code
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 : :
82 : 368 : int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
83 : : {
84 : : int ret;
85 [ + - ][ + - ]: 368 : if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
[ - + ]
86 : : {
87 : 0 : EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
88 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
89 : 0 : return -2;
90 : : }
91 : 368 : ctx->operation = EVP_PKEY_OP_SIGN;
92 [ - + ]: 368 : if (!ctx->pmeth->sign_init)
93 : : return 1;
94 : 0 : ret = ctx->pmeth->sign_init(ctx);
95 [ # # ]: 0 : if (ret <= 0)
96 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
97 : 0 : return ret;
98 : : }
99 : :
100 : 341 : 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 [ + - ][ + - ]: 341 : if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
[ - + ]
105 : : {
106 : 0 : EVPerr(EVP_F_EVP_PKEY_SIGN,
107 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108 : 0 : return -2;
109 : : }
110 [ - + ]: 341 : if (ctx->operation != EVP_PKEY_OP_SIGN)
111 : : {
112 : 0 : EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
113 : 0 : return -1;
114 : : }
115 [ + - ][ + + ]: 341 : M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
[ - + ]
116 : 269 : return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117 : : }
118 : :
119 : 1111 : int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120 : : {
121 : : int ret;
122 [ + - ][ + - ]: 1111 : if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
[ - + ]
123 : : {
124 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
125 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
126 : 0 : return -2;
127 : : }
128 : 1111 : ctx->operation = EVP_PKEY_OP_VERIFY;
129 [ - + ]: 1111 : if (!ctx->pmeth->verify_init)
130 : : return 1;
131 : 0 : ret = ctx->pmeth->verify_init(ctx);
132 [ # # ]: 0 : if (ret <= 0)
133 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
134 : 0 : return ret;
135 : : }
136 : :
137 : 1111 : 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 [ + - ][ + - ]: 1111 : if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
[ - + ]
142 : : {
143 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY,
144 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145 : 0 : return -2;
146 : : }
147 [ - + ]: 1111 : if (ctx->operation != EVP_PKEY_OP_VERIFY)
148 : : {
149 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150 : 0 : return -1;
151 : : }
152 : 1111 : return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153 : : }
154 : :
155 : 0 : int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
156 : : {
157 : : int ret;
158 [ # # ][ # # ]: 0 : if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
[ # # ]
159 : : {
160 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
161 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
162 : 0 : return -2;
163 : : }
164 : 0 : ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165 [ # # ]: 0 : if (!ctx->pmeth->verify_recover_init)
166 : : return 1;
167 : 0 : ret = ctx->pmeth->verify_recover_init(ctx);
168 [ # # ]: 0 : if (ret <= 0)
169 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
170 : 0 : return ret;
171 : : }
172 : :
173 : 0 : 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 [ # # ][ # # ]: 0 : if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
[ # # ]
178 : : {
179 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
180 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
181 : 0 : return -2;
182 : : }
183 [ # # ]: 0 : if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
184 : : {
185 : 0 : EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
186 : 0 : return -1;
187 : : }
188 [ # # ][ # # ]: 0 : M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
[ # # ]
189 : 0 : return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190 : : }
191 : :
192 : 41 : int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
193 : : {
194 : : int ret;
195 [ + - ][ + - ]: 41 : if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
[ - + ]
196 : : {
197 : 0 : EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
198 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
199 : 0 : return -2;
200 : : }
201 : 41 : ctx->operation = EVP_PKEY_OP_ENCRYPT;
202 [ - + ]: 41 : if (!ctx->pmeth->encrypt_init)
203 : : return 1;
204 : 0 : ret = ctx->pmeth->encrypt_init(ctx);
205 [ # # ]: 0 : if (ret <= 0)
206 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
207 : 0 : return ret;
208 : : }
209 : :
210 : 82 : 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 [ + - ][ + - ]: 82 : if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
[ - + ]
215 : : {
216 : 0 : EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218 : 0 : return -2;
219 : : }
220 [ - + ]: 82 : if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221 : : {
222 : 0 : EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
223 : 0 : return -1;
224 : : }
225 [ + - ][ + + ]: 82 : M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
[ - + ]
226 : 41 : return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227 : : }
228 : :
229 : 21 : int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230 : : {
231 : : int ret;
232 [ + - ][ + - ]: 21 : if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
[ - + ]
233 : : {
234 : 0 : EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236 : 0 : return -2;
237 : : }
238 : 21 : ctx->operation = EVP_PKEY_OP_DECRYPT;
239 [ - + ]: 21 : if (!ctx->pmeth->decrypt_init)
240 : : return 1;
241 : 0 : ret = ctx->pmeth->decrypt_init(ctx);
242 [ # # ]: 0 : if (ret <= 0)
243 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
244 : 0 : return ret;
245 : : }
246 : :
247 : 42 : 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 [ + - ][ + - ]: 42 : if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
[ - + ]
252 : : {
253 : 0 : EVPerr(EVP_F_EVP_PKEY_DECRYPT,
254 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
255 : 0 : return -2;
256 : : }
257 [ - + ]: 42 : if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258 : : {
259 : 0 : EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
260 : 0 : return -1;
261 : : }
262 [ + - ][ + + ]: 42 : M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
[ - + ]
263 : 21 : return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264 : : }
265 : :
266 : :
267 : 8 : int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
268 : : {
269 : : int ret;
270 [ + - ][ + - ]: 8 : if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
[ - + ]
271 : : {
272 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
273 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
274 : 0 : return -2;
275 : : }
276 : 8 : ctx->operation = EVP_PKEY_OP_DERIVE;
277 [ - + ]: 8 : if (!ctx->pmeth->derive_init)
278 : : return 1;
279 : 0 : ret = ctx->pmeth->derive_init(ctx);
280 [ # # ]: 0 : if (ret <= 0)
281 : 0 : ctx->operation = EVP_PKEY_OP_UNDEFINED;
282 : 0 : return ret;
283 : : }
284 : :
285 : 8 : int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
286 : : {
287 : : int ret;
288 [ + - ][ + - ]: 8 : if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
[ - + ][ # # ]
[ # # ][ - + ]
289 : : {
290 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
291 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
292 : 0 : return -2;
293 : : }
294 [ - + ][ # # ]: 8 : if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
295 : : {
296 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
297 : : EVP_R_OPERATON_NOT_INITIALIZED);
298 : 0 : return -1;
299 : : }
300 : :
301 : 8 : ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302 : :
303 [ + - ]: 8 : if (ret <= 0)
304 : : return ret;
305 : :
306 [ + - ]: 8 : if (ret == 2)
307 : : return 1;
308 : :
309 [ - + ]: 8 : if (!ctx->pkey)
310 : : {
311 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
312 : 0 : return -1;
313 : : }
314 : :
315 [ - + ]: 8 : if (ctx->pkey->type != peer->type)
316 : : {
317 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
318 : : EVP_R_DIFFERENT_KEY_TYPES);
319 : 0 : 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 [ + - - + ]: 16 : if (!EVP_PKEY_missing_parameters(peer) &&
328 : 8 : !EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329 : : {
330 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
331 : : EVP_R_DIFFERENT_PARAMETERS);
332 : 0 : return -1;
333 : : }
334 : :
335 [ - + ]: 8 : if (ctx->peerkey)
336 : 0 : EVP_PKEY_free(ctx->peerkey);
337 : 8 : ctx->peerkey = peer;
338 : :
339 : 8 : ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340 : :
341 [ - + ]: 8 : if (ret <= 0)
342 : : {
343 : 0 : ctx->peerkey = NULL;
344 : 0 : return ret;
345 : : }
346 : :
347 : 8 : CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
348 : 8 : return 1;
349 : : }
350 : :
351 : :
352 : 8 : int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353 : : {
354 [ + - ][ + - ]: 8 : if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
[ - + ]
355 : : {
356 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE,
357 : : EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
358 : 0 : return -2;
359 : : }
360 [ - + ]: 8 : if (ctx->operation != EVP_PKEY_OP_DERIVE)
361 : : {
362 : 0 : EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
363 : 0 : return -1;
364 : : }
365 [ - + ][ # # ]: 8 : M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
[ # # ]
366 : 8 : return ctx->pmeth->derive(ctx, key, pkeylen);
367 : : }
368 : :
|