GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/evp/bio_enc.c Lines: 117 169 69.2 %
Date: 2017-11-13 Branches: 40 82 48.8 %

Line Branch Exec Source
1
/* $OpenBSD: bio_enc.c,v 1.20 2017/05/02 03:59:44 deraadt Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <errno.h>
60
#include <stdio.h>
61
#include <string.h>
62
63
#include <openssl/buffer.h>
64
#include <openssl/evp.h>
65
66
static int enc_write(BIO *h, const char *buf, int num);
67
static int enc_read(BIO *h, char *buf, int size);
68
/*static int enc_puts(BIO *h, const char *str); */
69
/*static int enc_gets(BIO *h, char *str, int size); */
70
static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
71
static int enc_new(BIO *h);
72
static int enc_free(BIO *data);
73
static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
74
#define ENC_BLOCK_SIZE	(1024*4)
75
#define BUF_OFFSET	(EVP_MAX_BLOCK_LENGTH*2)
76
77
typedef struct enc_struct {
78
	int buf_len;
79
	int buf_off;
80
	int cont;		/* <= 0 when finished */
81
	int finished;
82
	int ok;			/* bad decrypt */
83
	EVP_CIPHER_CTX cipher;
84
	/* buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate
85
	 * can return up to a block more data than is presented to it
86
	 */
87
	char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
88
} BIO_ENC_CTX;
89
90
static BIO_METHOD methods_enc = {
91
	.type = BIO_TYPE_CIPHER,
92
	.name = "cipher",
93
	.bwrite = enc_write,
94
	.bread = enc_read,
95
	.ctrl = enc_ctrl,
96
	.create = enc_new,
97
	.destroy = enc_free,
98
	.callback_ctrl = enc_callback_ctrl
99
};
100
101
BIO_METHOD *
102
BIO_f_cipher(void)
103
{
104
1220
	return (&methods_enc);
105
}
106
107
static int
108
enc_new(BIO *bi)
109
{
110
	BIO_ENC_CTX *ctx;
111
112
1220
	ctx = malloc(sizeof(BIO_ENC_CTX));
113
610
	if (ctx == NULL)
114
		return (0);
115
610
	EVP_CIPHER_CTX_init(&ctx->cipher);
116
117
610
	ctx->buf_len = 0;
118
610
	ctx->buf_off = 0;
119
610
	ctx->cont = 1;
120
610
	ctx->finished = 0;
121
610
	ctx->ok = 1;
122
123
610
	bi->init = 0;
124
610
	bi->ptr = (char *)ctx;
125
610
	bi->flags = 0;
126
610
	return (1);
127
610
}
128
129
static int
130
enc_free(BIO *a)
131
{
132
	BIO_ENC_CTX *b;
133
134
1220
	if (a == NULL)
135
		return (0);
136
610
	b = (BIO_ENC_CTX *)a->ptr;
137
610
	EVP_CIPHER_CTX_cleanup(&(b->cipher));
138
610
	freezero(a->ptr, sizeof(BIO_ENC_CTX));
139
610
	a->ptr = NULL;
140
610
	a->init = 0;
141
610
	a->flags = 0;
142
610
	return (1);
143
610
}
144
145
static int
146
enc_read(BIO *b, char *out, int outl)
147
{
148
	int ret = 0, i;
149
	BIO_ENC_CTX *ctx;
150
151
12
	if (out == NULL)
152
		return (0);
153
6
	ctx = (BIO_ENC_CTX *)b->ptr;
154
155

12
	if ((ctx == NULL) || (b->next_bio == NULL))
156
		return (0);
157
158
	/* First check if there are bytes decoded/encoded */
159
6
	if (ctx->buf_len > 0) {
160
3
		i = ctx->buf_len - ctx->buf_off;
161
3
		if (i > outl)
162
			i = outl;
163
3
		memcpy(out, &(ctx->buf[ctx->buf_off]), i);
164
		ret = i;
165
3
		out += i;
166
3
		outl -= i;
167
3
		ctx->buf_off += i;
168
3
		if (ctx->buf_len == ctx->buf_off) {
169
3
			ctx->buf_len = 0;
170
3
			ctx->buf_off = 0;
171
3
		}
172
	}
173
174
	/* At this point, we have room of outl bytes and an empty
175
	 * buffer, so we should read in some more. */
176
177
24
	while (outl > 0) {
178
12
		if (ctx->cont <= 0)
179
			break;
180
181
		/* read in at IV offset, read the EVP_Cipher
182
		 * documentation about why */
183
6
		i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
184
185
6
		if (i <= 0) {
186
			/* Should be continue next time we are called? */
187
3
			if (!BIO_should_retry(b->next_bio)) {
188
3
				ctx->cont = i;
189
6
				i = EVP_CipherFinal_ex(&(ctx->cipher),
190
3
				    (unsigned char *)ctx->buf,
191
				    &(ctx->buf_len));
192
3
				ctx->ok = i;
193
3
				ctx->buf_off = 0;
194
			} else {
195
				ret = (ret == 0) ? i : ret;
196
				break;
197
			}
198
3
		} else {
199
6
			EVP_CipherUpdate(&(ctx->cipher),
200
3
			    (unsigned char *)ctx->buf, &ctx->buf_len,
201
			    (unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
202
3
			ctx->cont = 1;
203
			/* Note: it is possible for EVP_CipherUpdate to
204
			 * decrypt zero bytes because this is or looks like
205
			 * the final block: if this happens we should retry
206
			 * and either read more data or decrypt the final
207
			 * block
208
			 */
209
3
			if (ctx->buf_len == 0)
210
				continue;
211
		}
212
213
6
		if (ctx->buf_len <= outl)
214
6
			i = ctx->buf_len;
215
		else
216
			i = outl;
217
6
		if (i <= 0)
218
			break;
219
6
		memcpy(out, ctx->buf, i);
220
6
		ret += i;
221
6
		ctx->buf_off = i;
222
6
		outl -= i;
223
6
		out += i;
224
	}
225
226
6
	BIO_clear_retry_flags(b);
227
6
	BIO_copy_next_retry(b);
228
18
	return ((ret == 0) ? ctx->cont : ret);
229
6
}
230
231
static int
232
enc_write(BIO *b, const char *in, int inl)
233
{
234
	int ret = 0, n, i;
235
	BIO_ENC_CTX *ctx;
236
237
6564
	ctx = (BIO_ENC_CTX *)b->ptr;
238
	ret = inl;
239
240
3282
	BIO_clear_retry_flags(b);
241
3282
	n = ctx->buf_len - ctx->buf_off;
242
7210
	while (n > 0) {
243
323
		i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
244
323
		if (i <= 0) {
245
			BIO_copy_next_retry(b);
246
			return (i);
247
		}
248
323
		ctx->buf_off += i;
249
323
		n -= i;
250
	}
251
	/* at this point all pending data has been written */
252
253
3282
	if ((in == NULL) || (inl <= 0))
254
323
		return (0);
255
256
	ctx->buf_off = 0;
257
11836
	while (inl > 0) {
258
2959
		n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
259
5918
		EVP_CipherUpdate(&(ctx->cipher),
260
2959
		    (unsigned char *)ctx->buf, &ctx->buf_len,
261
		    (unsigned char *)in, n);
262
2959
		inl -= n;
263
2959
		in += n;
264
265
2959
		ctx->buf_off = 0;
266
2959
		n = ctx->buf_len;
267
11836
		while (n > 0) {
268
2959
			i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
269
2959
			if (i <= 0) {
270
				BIO_copy_next_retry(b);
271
				return (ret == inl) ? i : ret - inl;
272
			}
273
2959
			n -= i;
274
2959
			ctx->buf_off += i;
275
		}
276
2959
		ctx->buf_len = 0;
277
		ctx->buf_off = 0;
278
	}
279
2959
	BIO_copy_next_retry(b);
280
2959
	return (ret);
281
3282
}
282
283
static long
284
enc_ctrl(BIO *b, int cmd, long num, void *ptr)
285
{
286
	BIO *dbio;
287
	BIO_ENC_CTX *ctx, *dctx;
288
	long ret = 1;
289
	int i;
290
	EVP_CIPHER_CTX **c_ctx;
291
292
3678
	ctx = (BIO_ENC_CTX *)b->ptr;
293
294


1839
	switch (cmd) {
295
	case BIO_CTRL_RESET:
296
		ctx->ok = 1;
297
		ctx->finished = 0;
298
		EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL,
299
		    ctx->cipher.encrypt);
300
		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
301
		break;
302
	case BIO_CTRL_EOF:	/* More to read */
303
		if (ctx->cont <= 0)
304
			ret = 1;
305
		else
306
			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
307
		break;
308
	case BIO_CTRL_WPENDING:
309
		ret = ctx->buf_len - ctx->buf_off;
310
		if (ret <= 0)
311
			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
312
		break;
313
	case BIO_CTRL_PENDING: /* More to read in buffer */
314
		ret = ctx->buf_len - ctx->buf_off;
315
		if (ret <= 0)
316
			ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
317
610
		break;
318
	case BIO_CTRL_FLUSH:
319
		/* do a final write */
320
again:
321
3080
		while (ctx->buf_len != ctx->buf_off) {
322
323
			i = enc_write(b, NULL, 0);
323
323
			if (i < 0)
324
				return i;
325
		}
326
327
1217
		if (!ctx->finished) {
328
607
			ctx->finished = 1;
329
607
			ctx->buf_off = 0;
330
1214
			ret = EVP_CipherFinal_ex(&(ctx->cipher),
331
607
			    (unsigned char *)ctx->buf,
332
			    &(ctx->buf_len));
333
607
			ctx->ok = (int)ret;
334
607
			if (ret <= 0)
335
				break;
336
337
			/* push out the bytes */
338
607
			goto again;
339
		}
340
341
		/* Finally flush the underlying BIO */
342
610
		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
343
610
		break;
344
	case BIO_C_GET_CIPHER_STATUS:
345
3
		ret = (long)ctx->ok;
346
3
		break;
347
	case BIO_C_DO_STATE_MACHINE:
348
		BIO_clear_retry_flags(b);
349
		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
350
		BIO_copy_next_retry(b);
351
		break;
352
	case BIO_C_GET_CIPHER_CTX:
353
610
		c_ctx = (EVP_CIPHER_CTX **)ptr;
354
610
		(*c_ctx) = &(ctx->cipher);
355
610
		b->init = 1;
356
610
		break;
357
	case BIO_CTRL_DUP:
358
		dbio = (BIO *)ptr;
359
		dctx = (BIO_ENC_CTX *)dbio->ptr;
360
		EVP_CIPHER_CTX_init(&dctx->cipher);
361
		ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher);
362
		if (ret)
363
			dbio->init = 1;
364
		break;
365
	default:
366
616
		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
367
616
		break;
368
	}
369
1839
	return (ret);
370
1839
}
371
372
static long
373
enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
374
{
375
	long ret = 1;
376
377
	if (b->next_bio == NULL)
378
		return (0);
379
	switch (cmd) {
380
	default:
381
		ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
382
		break;
383
	}
384
	return (ret);
385
}
386
387
/*
388
void BIO_set_cipher_ctx(b,c)
389
BIO *b;
390
EVP_CIPHER_ctx *c;
391
	{
392
	if (b == NULL) return;
393
394
	if ((b->callback != NULL) &&
395
		(b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
396
		return;
397
398
	b->init=1;
399
	ctx=(BIO_ENC_CTX *)b->ptr;
400
	memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
401
402
	if (b->callback != NULL)
403
		b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
404
	}
405
*/
406
407
void
408
BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
409
    const unsigned char *i, int e)
410
{
411
	BIO_ENC_CTX *ctx;
412
413
	if (b == NULL)
414
		return;
415
416
	if ((b->callback != NULL) &&
417
	    (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= 0))
418
		return;
419
420
	b->init = 1;
421
	ctx = (BIO_ENC_CTX *)b->ptr;
422
	EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e);
423
424
	if (b->callback != NULL)
425
		b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
426
}