GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/evp/pmeth_fn.c Lines: 39 143 27.3 %
Date: 2016-12-06 Branches: 44 168 26.2 %

Line Branch Exec Source
1
/* $OpenBSD: pmeth_fn.c,v 1.5 2014/07/12 16:03:37 miod 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
62
#include <openssl/err.h>
63
#include <openssl/evp.h>
64
#include <openssl/objects.h>
65
66
#include "evp_locl.h"
67
68
#define M_check_autoarg(ctx, arg, arglen, err) \
69
	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
70
		{ \
71
		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
72
		if (!arg) \
73
			{ \
74
			*arglen = pksize; \
75
			return 1; \
76
			} \
77
		else if (*arglen < pksize) \
78
			{ \
79
			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
80
			return 0; \
81
			} \
82
		}
83
84
int
85
EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
86
2
{
87
	int ret;
88
89

2
	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
90
		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
91
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
92
		return -2;
93
	}
94
2
	ctx->operation = EVP_PKEY_OP_SIGN;
95
2
	if (!ctx->pmeth->sign_init)
96
2
		return 1;
97
	ret = ctx->pmeth->sign_init(ctx);
98
	if (ret <= 0)
99
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
100
	return ret;
101
}
102
103
int
104
EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
105
    const unsigned char *tbs, size_t tbslen)
106
4
{
107

4
	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
108
		EVPerr(EVP_F_EVP_PKEY_SIGN,
109
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
110
		return -2;
111
	}
112
4
	if (ctx->operation != EVP_PKEY_OP_SIGN) {
113
		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
114
		return -1;
115
	}
116

4
	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
117
2
	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
118
}
119
120
int
121
EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
122
11
{
123
	int ret;
124
125

11
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
126
		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
127
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
128
		return -2;
129
	}
130
11
	ctx->operation = EVP_PKEY_OP_VERIFY;
131
11
	if (!ctx->pmeth->verify_init)
132
11
		return 1;
133
	ret = ctx->pmeth->verify_init(ctx);
134
	if (ret <= 0)
135
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
136
	return ret;
137
}
138
139
int
140
EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
141
    const unsigned char *tbs, size_t tbslen)
142
11
{
143

11
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
144
		EVPerr(EVP_F_EVP_PKEY_VERIFY,
145
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
146
		return -2;
147
	}
148
11
	if (ctx->operation != EVP_PKEY_OP_VERIFY) {
149
		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150
		return -1;
151
	}
152
11
	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153
}
154
155
int
156
EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
157
{
158
	int ret;
159
160
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
161
		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
162
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
163
		return -2;
164
	}
165
	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
166
	if (!ctx->pmeth->verify_recover_init)
167
		return 1;
168
	ret = ctx->pmeth->verify_recover_init(ctx);
169
	if (ret <= 0)
170
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
171
	return ret;
172
}
173
174
int
175
EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
176
    const unsigned char *sig, size_t siglen)
177
{
178
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
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
		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
185
		    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
192
int
193
EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
194
1
{
195
	int ret;
196
197

1
	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
198
		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
199
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
200
		return -2;
201
	}
202
1
	ctx->operation = EVP_PKEY_OP_ENCRYPT;
203
1
	if (!ctx->pmeth->encrypt_init)
204
1
		return 1;
205
	ret = ctx->pmeth->encrypt_init(ctx);
206
	if (ret <= 0)
207
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
208
	return ret;
209
}
210
211
int
212
EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
213
    const unsigned char *in, size_t inlen)
214
2
{
215

2
	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
216
		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218
		return -2;
219
	}
220
2
	if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
221
		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
222
		return -1;
223
	}
224

2
	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
225
1
	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
226
}
227
228
int
229
EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230
1
{
231
	int ret;
232
233

1
	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
234
		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236
		return -2;
237
	}
238
1
	ctx->operation = EVP_PKEY_OP_DECRYPT;
239
1
	if (!ctx->pmeth->decrypt_init)
240
1
		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
247
int
248
EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
249
    const unsigned char *in, size_t inlen)
250
2
{
251

2
	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
252
		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
253
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
254
		return -2;
255
	}
256
2
	if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
257
		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
258
		return -1;
259
	}
260

2
	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
261
1
	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
262
}
263
264
int
265
EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
266
{
267
	int ret;
268
269
	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
270
		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
271
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
272
		return -2;
273
	}
274
	ctx->operation = EVP_PKEY_OP_DERIVE;
275
	if (!ctx->pmeth->derive_init)
276
		return 1;
277
	ret = ctx->pmeth->derive_init(ctx);
278
	if (ret <= 0)
279
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
280
	return ret;
281
}
282
283
int
284
EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
285
{
286
	int ret;
287
288
	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive ||
289
	    ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
290
	    !ctx->pmeth->ctrl) {
291
		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
292
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
293
		return -2;
294
	}
295
	if (ctx->operation != EVP_PKEY_OP_DERIVE &&
296
	    ctx->operation != EVP_PKEY_OP_ENCRYPT &&
297
	    ctx->operation != EVP_PKEY_OP_DECRYPT) {
298
		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
299
		    EVP_R_OPERATON_NOT_INITIALIZED);
300
		return -1;
301
	}
302
303
	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
304
305
	if (ret <= 0)
306
		return ret;
307
308
	if (ret == 2)
309
		return 1;
310
311
	if (!ctx->pkey) {
312
		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
313
		return -1;
314
	}
315
316
	if (ctx->pkey->type != peer->type) {
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
		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
330
		    EVP_R_DIFFERENT_PARAMETERS);
331
		return -1;
332
	}
333
334
	EVP_PKEY_free(ctx->peerkey);
335
	ctx->peerkey = peer;
336
337
	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
338
339
	if (ret <= 0) {
340
		ctx->peerkey = NULL;
341
		return ret;
342
	}
343
344
	CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
345
	return 1;
346
}
347
348
int
349
EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
350
{
351
	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
352
		EVPerr(EVP_F_EVP_PKEY_DERIVE,
353
		    EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
354
		return -2;
355
	}
356
	if (ctx->operation != EVP_PKEY_OP_DERIVE) {
357
		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
358
		return -1;
359
	}
360
	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
361
	return ctx->pmeth->derive(ctx, key, pkeylen);
362
}