GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/evp/pmeth_fn.c Lines: 49 150 32.7 %
Date: 2017-11-13 Branches: 64 180 35.6 %

Line Branch Exec Source
1
/* $OpenBSD: pmeth_fn.c,v 1.6 2017/01/29 17:49:23 beck 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
			EVPerror(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
{
87
	int ret;
88
89

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

644
	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
107
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108
		return -2;
109
	}
110
161
	if (ctx->operation != EVP_PKEY_OP_SIGN) {
111
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
112
		return -1;
113
	}
114


632
	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
115
149
	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
116
161
}
117
118
int
119
EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120
{
121
	int ret;
122
123

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

10272
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
141
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
142
		return -2;
143
	}
144
2568
	if (ctx->operation != EVP_PKEY_OP_VERIFY) {
145
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
146
		return -1;
147
	}
148
2568
	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
149
2568
}
150
151
int
152
EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
153
{
154
	int ret;
155
156

8
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
157
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
158
		return -2;
159
	}
160
2
	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
161
2
	if (!ctx->pmeth->verify_recover_init)
162
2
		return 1;
163
	ret = ctx->pmeth->verify_recover_init(ctx);
164
	if (ret <= 0)
165
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
166
	return ret;
167
2
}
168
169
int
170
EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen,
171
    const unsigned char *sig, size_t siglen)
172
{
173

16
	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
174
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
175
		return -2;
176
	}
177
4
	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
178
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
179
		return -1;
180
	}
181


14
	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
182
2
	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
183
4
}
184
185
int
186
EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
187
{
188
	int ret;
189
190

12
	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
191
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
192
		return -2;
193
	}
194
3
	ctx->operation = EVP_PKEY_OP_ENCRYPT;
195
3
	if (!ctx->pmeth->encrypt_init)
196
3
		return 1;
197
	ret = ctx->pmeth->encrypt_init(ctx);
198
	if (ret <= 0)
199
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
200
	return ret;
201
3
}
202
203
int
204
EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
205
    const unsigned char *in, size_t inlen)
206
{
207

24
	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
208
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
209
		return -2;
210
	}
211
6
	if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
212
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
213
		return -1;
214
	}
215


21
	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
216
3
	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
217
6
}
218
219
int
220
EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
221
{
222
	int ret;
223
224

12
	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
225
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
226
		return -2;
227
	}
228
3
	ctx->operation = EVP_PKEY_OP_DECRYPT;
229
3
	if (!ctx->pmeth->decrypt_init)
230
3
		return 1;
231
	ret = ctx->pmeth->decrypt_init(ctx);
232
	if (ret <= 0)
233
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
234
	return ret;
235
3
}
236
237
int
238
EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
239
    const unsigned char *in, size_t inlen)
240
{
241

24
	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
242
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
243
		return -2;
244
	}
245
6
	if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
246
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
247
		return -1;
248
	}
249


21
	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
250
3
	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
251
6
}
252
253
int
254
EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
255
{
256
	int ret;
257
258
	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
259
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
260
		return -2;
261
	}
262
	ctx->operation = EVP_PKEY_OP_DERIVE;
263
	if (!ctx->pmeth->derive_init)
264
		return 1;
265
	ret = ctx->pmeth->derive_init(ctx);
266
	if (ret <= 0)
267
		ctx->operation = EVP_PKEY_OP_UNDEFINED;
268
	return ret;
269
}
270
271
int
272
EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
273
{
274
	int ret;
275
276
	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive ||
277
	    ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
278
	    !ctx->pmeth->ctrl) {
279
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
280
		return -2;
281
	}
282
	if (ctx->operation != EVP_PKEY_OP_DERIVE &&
283
	    ctx->operation != EVP_PKEY_OP_ENCRYPT &&
284
	    ctx->operation != EVP_PKEY_OP_DECRYPT) {
285
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
286
		return -1;
287
	}
288
289
	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
290
291
	if (ret <= 0)
292
		return ret;
293
294
	if (ret == 2)
295
		return 1;
296
297
	if (!ctx->pkey) {
298
		EVPerror(EVP_R_NO_KEY_SET);
299
		return -1;
300
	}
301
302
	if (ctx->pkey->type != peer->type) {
303
		EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
304
		return -1;
305
	}
306
307
	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
308
	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
309
	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
310
	 * (different key types) is impossible here because it is checked earlier.
311
	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
312
	if (!EVP_PKEY_missing_parameters(peer) &&
313
	    !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
314
		EVPerror(EVP_R_DIFFERENT_PARAMETERS);
315
		return -1;
316
	}
317
318
	EVP_PKEY_free(ctx->peerkey);
319
	ctx->peerkey = peer;
320
321
	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
322
323
	if (ret <= 0) {
324
		ctx->peerkey = NULL;
325
		return ret;
326
	}
327
328
	CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY);
329
	return 1;
330
}
331
332
int
333
EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
334
{
335
	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
336
		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
337
		return -2;
338
	}
339
	if (ctx->operation != EVP_PKEY_OP_DERIVE) {
340
		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
341
		return -1;
342
	}
343
	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
344
	return ctx->pmeth->derive(ctx, key, pkeylen);
345
}