]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/bio_enc.c
test/smcont.txt: trigger assertion in bio_enc.c.
[thirdparty/openssl.git] / crypto / evp / bio_enc.c
CommitLineData
62867571
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
62867571
RS
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
10#include <stdio.h>
11#include <errno.h>
b39fc560 12#include "internal/cryptlib.h"
ec577822
BM
13#include <openssl/buffer.h>
14#include <openssl/evp.h>
a146ae55 15#include "internal/bio.h"
d02b48c6 16
0e1c0612
UM
17static int enc_write(BIO *h, const char *buf, int num);
18static int enc_read(BIO *h, char *buf, int size);
0f113f3e
MC
19/*
20 * static int enc_puts(BIO *h, const char *str);
21 */
22/*
23 * static int enc_gets(BIO *h, char *str, int size);
24 */
0e1c0612 25static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
d02b48c6
RE
26static int enc_new(BIO *h);
27static int enc_free(BIO *data);
13083215 28static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
0f113f3e
MC
29#define ENC_BLOCK_SIZE (1024*4)
30#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
31
32typedef struct enc_struct {
33 int buf_len;
34 int buf_off;
35 int cont; /* <= 0 when finished */
36 int finished;
37 int ok; /* bad decrypt */
846ec07d 38 EVP_CIPHER_CTX *cipher;
0f113f3e
MC
39 /*
40 * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
41 * up to a block more data than is presented to it
42 */
43 char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
44} BIO_ENC_CTX;
45
04f6b0fd 46static const BIO_METHOD methods_enc = {
0f113f3e
MC
47 BIO_TYPE_CIPHER, "cipher",
48 enc_write,
49 enc_read,
50 NULL, /* enc_puts, */
51 NULL, /* enc_gets, */
52 enc_ctrl,
53 enc_new,
54 enc_free,
55 enc_callback_ctrl,
56};
d02b48c6 57
04f6b0fd 58const BIO_METHOD *BIO_f_cipher(void)
0f113f3e
MC
59{
60 return (&methods_enc);
61}
d02b48c6 62
6b691a5c 63static int enc_new(BIO *bi)
0f113f3e
MC
64{
65 BIO_ENC_CTX *ctx;
66
64b25758 67 ctx = OPENSSL_zalloc(sizeof(*ctx));
0f113f3e 68 if (ctx == NULL)
846ec07d 69 return 0;
0f113f3e 70
846ec07d
RL
71 ctx->cipher = EVP_CIPHER_CTX_new();
72 if (ctx->cipher == NULL) {
73 OPENSSL_free(ctx);
74 return 0;
75 }
0f113f3e 76 ctx->cont = 1;
0f113f3e 77 ctx->ok = 1;
a146ae55
MC
78 BIO_set_data(bi, ctx);
79 BIO_set_init(bi, 1);
80
846ec07d 81 return 1;
0f113f3e 82}
d02b48c6 83
6b691a5c 84static int enc_free(BIO *a)
0f113f3e
MC
85{
86 BIO_ENC_CTX *b;
87
88 if (a == NULL)
a146ae55
MC
89 return 0;
90
91 b = BIO_get_data(a);
92 if (b == NULL)
93 return 0;
94
846ec07d 95 EVP_CIPHER_CTX_free(b->cipher);
a146ae55
MC
96 OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX));
97 BIO_set_data(a, NULL);
98 BIO_set_init(a, 0);
99
100 return 1;
0f113f3e
MC
101}
102
6b691a5c 103static int enc_read(BIO *b, char *out, int outl)
0f113f3e
MC
104{
105 int ret = 0, i;
106 BIO_ENC_CTX *ctx;
a146ae55 107 BIO *next;
0f113f3e
MC
108
109 if (out == NULL)
110 return (0);
a146ae55 111 ctx = BIO_get_data(b);
0f113f3e 112
a146ae55
MC
113 next = BIO_next(b);
114 if ((ctx == NULL) || (next == NULL))
115 return 0;
0f113f3e
MC
116
117 /* First check if there are bytes decoded/encoded */
118 if (ctx->buf_len > 0) {
119 i = ctx->buf_len - ctx->buf_off;
120 if (i > outl)
121 i = outl;
122 memcpy(out, &(ctx->buf[ctx->buf_off]), i);
123 ret = i;
124 out += i;
125 outl -= i;
126 ctx->buf_off += i;
127 if (ctx->buf_len == ctx->buf_off) {
128 ctx->buf_len = 0;
129 ctx->buf_off = 0;
130 }
131 }
132
133 /*
134 * At this point, we have room of outl bytes and an empty buffer, so we
135 * should read in some more.
136 */
137
138 while (outl > 0) {
139 if (ctx->cont <= 0)
140 break;
141
142 /*
143 * read in at IV offset, read the EVP_Cipher documentation about why
144 */
a146ae55 145 i = BIO_read(next, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
0f113f3e
MC
146
147 if (i <= 0) {
148 /* Should be continue next time we are called? */
a146ae55 149 if (!BIO_should_retry(next)) {
0f113f3e 150 ctx->cont = i;
846ec07d 151 i = EVP_CipherFinal_ex(ctx->cipher,
0f113f3e
MC
152 (unsigned char *)ctx->buf,
153 &(ctx->buf_len));
154 ctx->ok = i;
155 ctx->buf_off = 0;
156 } else {
157 ret = (ret == 0) ? i : ret;
158 break;
159 }
160 } else {
846ec07d 161 if (!EVP_CipherUpdate(ctx->cipher,
0f113f3e
MC
162 (unsigned char *)ctx->buf, &ctx->buf_len,
163 (unsigned char *)&(ctx->buf[BUF_OFFSET]),
164 i)) {
165 BIO_clear_retry_flags(b);
ee6ce5cc 166 ctx->ok = 0;
0f113f3e
MC
167 return 0;
168 }
169 ctx->cont = 1;
170 /*
171 * Note: it is possible for EVP_CipherUpdate to decrypt zero
172 * bytes because this is or looks like the final block: if this
173 * happens we should retry and either read more data or decrypt
174 * the final block
175 */
176 if (ctx->buf_len == 0)
177 continue;
178 }
179
180 if (ctx->buf_len <= outl)
181 i = ctx->buf_len;
182 else
183 i = outl;
184 if (i <= 0)
185 break;
186 memcpy(out, ctx->buf, i);
187 ret += i;
188 ctx->buf_off = i;
189 outl -= i;
190 out += i;
191 }
192
193 BIO_clear_retry_flags(b);
194 BIO_copy_next_retry(b);
195 return ((ret == 0) ? ctx->cont : ret);
196}
d02b48c6 197
0e1c0612 198static int enc_write(BIO *b, const char *in, int inl)
0f113f3e
MC
199{
200 int ret = 0, n, i;
201 BIO_ENC_CTX *ctx;
a146ae55
MC
202 BIO *next;
203
204 ctx = BIO_get_data(b);
205 next = BIO_next(b);
206 if ((ctx == NULL) || (next == NULL))
207 return 0;
0f113f3e 208
0f113f3e
MC
209 ret = inl;
210
211 BIO_clear_retry_flags(b);
212 n = ctx->buf_len - ctx->buf_off;
213 while (n > 0) {
a146ae55 214 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
0f113f3e
MC
215 if (i <= 0) {
216 BIO_copy_next_retry(b);
217 return (i);
218 }
219 ctx->buf_off += i;
220 n -= i;
221 }
222 /* at this point all pending data has been written */
223
224 if ((in == NULL) || (inl <= 0))
225 return (0);
226
227 ctx->buf_off = 0;
228 while (inl > 0) {
229 n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
846ec07d 230 if (!EVP_CipherUpdate(ctx->cipher,
0f113f3e
MC
231 (unsigned char *)ctx->buf, &ctx->buf_len,
232 (unsigned char *)in, n)) {
233 BIO_clear_retry_flags(b);
976ef6ad 234 ctx->ok = 0;
0f113f3e
MC
235 return 0;
236 }
237 inl -= n;
238 in += n;
239
240 ctx->buf_off = 0;
241 n = ctx->buf_len;
242 while (n > 0) {
a146ae55 243 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
0f113f3e
MC
244 if (i <= 0) {
245 BIO_copy_next_retry(b);
246 return (ret == inl) ? i : ret - inl;
247 }
248 n -= i;
249 ctx->buf_off += i;
250 }
251 ctx->buf_len = 0;
252 ctx->buf_off = 0;
253 }
254 BIO_copy_next_retry(b);
255 return (ret);
256}
d02b48c6 257
0e1c0612 258static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
259{
260 BIO *dbio;
261 BIO_ENC_CTX *ctx, *dctx;
262 long ret = 1;
263 int i;
264 EVP_CIPHER_CTX **c_ctx;
a146ae55 265 BIO *next;
0f113f3e 266
a146ae55
MC
267 ctx = BIO_get_data(b);
268 next = BIO_next(b);
269 if (ctx == NULL)
270 return 0;
0f113f3e
MC
271
272 switch (cmd) {
273 case BIO_CTRL_RESET:
274 ctx->ok = 1;
275 ctx->finished = 0;
846ec07d
RL
276 if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
277 EVP_CIPHER_CTX_encrypting(ctx->cipher)))
0f113f3e 278 return 0;
a146ae55 279 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
280 break;
281 case BIO_CTRL_EOF: /* More to read */
282 if (ctx->cont <= 0)
283 ret = 1;
284 else
a146ae55 285 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
286 break;
287 case BIO_CTRL_WPENDING:
288 ret = ctx->buf_len - ctx->buf_off;
289 if (ret <= 0)
a146ae55 290 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
291 break;
292 case BIO_CTRL_PENDING: /* More to read in buffer */
293 ret = ctx->buf_len - ctx->buf_off;
294 if (ret <= 0)
a146ae55 295 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
296 break;
297 case BIO_CTRL_FLUSH:
298 /* do a final write */
299 again:
300 while (ctx->buf_len != ctx->buf_off) {
301 i = enc_write(b, NULL, 0);
302 if (i < 0)
303 return i;
304 }
305
306 if (!ctx->finished) {
307 ctx->finished = 1;
308 ctx->buf_off = 0;
846ec07d 309 ret = EVP_CipherFinal_ex(ctx->cipher,
0f113f3e
MC
310 (unsigned char *)ctx->buf,
311 &(ctx->buf_len));
312 ctx->ok = (int)ret;
313 if (ret <= 0)
314 break;
315
316 /* push out the bytes */
317 goto again;
318 }
319
320 /* Finally flush the underlying BIO */
a146ae55 321 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
322 break;
323 case BIO_C_GET_CIPHER_STATUS:
324 ret = (long)ctx->ok;
325 break;
326 case BIO_C_DO_STATE_MACHINE:
327 BIO_clear_retry_flags(b);
a146ae55 328 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
329 BIO_copy_next_retry(b);
330 break;
331 case BIO_C_GET_CIPHER_CTX:
332 c_ctx = (EVP_CIPHER_CTX **)ptr;
846ec07d 333 *c_ctx = ctx->cipher;
a146ae55 334 BIO_set_init(b, 1);
0f113f3e
MC
335 break;
336 case BIO_CTRL_DUP:
337 dbio = (BIO *)ptr;
a146ae55 338 dctx = BIO_get_data(dbio);
846ec07d
RL
339 dctx->cipher = EVP_CIPHER_CTX_new();
340 if (dctx->cipher == NULL)
341 return 0;
342 ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
0f113f3e 343 if (ret)
a146ae55 344 BIO_set_init(dbio, 1);
0f113f3e
MC
345 break;
346 default:
a146ae55 347 ret = BIO_ctrl(next, cmd, num, ptr);
0f113f3e
MC
348 break;
349 }
350 return (ret);
351}
d02b48c6 352
13083215 353static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
0f113f3e
MC
354{
355 long ret = 1;
a146ae55 356 BIO *next = BIO_next(b);
0f113f3e 357
a146ae55 358 if (next == NULL)
0f113f3e
MC
359 return (0);
360 switch (cmd) {
361 default:
a146ae55 362 ret = BIO_callback_ctrl(next, cmd, fp);
0f113f3e
MC
363 break;
364 }
365 return (ret);
366}
d3442bc7 367
1d97c843 368/*-
58964a49
RE
369void BIO_set_cipher_ctx(b,c)
370BIO *b;
371EVP_CIPHER_ctx *c;
0f113f3e
MC
372 {
373 if (b == NULL) return;
374
375 if ((b->callback != NULL) &&
376 (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
377 return;
378
379 b->init=1;
380 ctx=(BIO_ENC_CTX *)b->ptr;
381 memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
382
383 if (b->callback != NULL)
384 b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
385 }
58964a49
RE
386*/
387
b6dcdbfc 388int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
0f113f3e
MC
389 const unsigned char *i, int e)
390{
391 BIO_ENC_CTX *ctx;
a146ae55 392 long (*callback) (struct bio_st *, int, const char *, int, long, long);
0f113f3e 393
a146ae55
MC
394 ctx = BIO_get_data(b);
395 if (ctx == NULL)
0f113f3e
MC
396 return 0;
397
a146ae55
MC
398 callback = BIO_get_callback(b);
399
400 if ((callback != NULL) &&
401 (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
402 0L) <= 0))
0f113f3e
MC
403 return 0;
404
a146ae55
MC
405 BIO_set_init(b, 1);
406
846ec07d 407 if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
0f113f3e
MC
408 return 0;
409
a146ae55
MC
410 if (callback != NULL)
411 return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
0f113f3e
MC
412 return 1;
413}