]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/bio_enc.c
Copyright consolidation 04/10
[thirdparty/openssl.git] / crypto / evp / bio_enc.c
1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10 #include <stdio.h>
11 #include <errno.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/buffer.h>
14 #include <openssl/evp.h>
15 #include "internal/bio.h"
16
17 static int enc_write(BIO *h, const char *buf, int num);
18 static int enc_read(BIO *h, char *buf, int size);
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 */
25 static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
26 static int enc_new(BIO *h);
27 static int enc_free(BIO *data);
28 static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
29 #define ENC_BLOCK_SIZE (1024*4)
30 #define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2)
31
32 typedef 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 */
38 EVP_CIPHER_CTX *cipher;
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
46 static const BIO_METHOD methods_enc = {
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 };
57
58 const BIO_METHOD *BIO_f_cipher(void)
59 {
60 return (&methods_enc);
61 }
62
63 static int enc_new(BIO *bi)
64 {
65 BIO_ENC_CTX *ctx;
66
67 ctx = OPENSSL_zalloc(sizeof(*ctx));
68 if (ctx == NULL)
69 return 0;
70
71 ctx->cipher = EVP_CIPHER_CTX_new();
72 if (ctx->cipher == NULL) {
73 OPENSSL_free(ctx);
74 return 0;
75 }
76 ctx->cont = 1;
77 ctx->ok = 1;
78 BIO_set_data(bi, ctx);
79 BIO_set_init(bi, 1);
80
81 return 1;
82 }
83
84 static int enc_free(BIO *a)
85 {
86 BIO_ENC_CTX *b;
87
88 if (a == NULL)
89 return 0;
90
91 b = BIO_get_data(a);
92 if (b == NULL)
93 return 0;
94
95 EVP_CIPHER_CTX_free(b->cipher);
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;
101 }
102
103 static int enc_read(BIO *b, char *out, int outl)
104 {
105 int ret = 0, i;
106 BIO_ENC_CTX *ctx;
107 BIO *next;
108
109 if (out == NULL)
110 return (0);
111 ctx = BIO_get_data(b);
112
113 next = BIO_next(b);
114 if ((ctx == NULL) || (next == NULL))
115 return 0;
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 */
145 i = BIO_read(next, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
146
147 if (i <= 0) {
148 /* Should be continue next time we are called? */
149 if (!BIO_should_retry(next)) {
150 ctx->cont = i;
151 i = EVP_CipherFinal_ex(ctx->cipher,
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 {
161 if (!EVP_CipherUpdate(ctx->cipher,
162 (unsigned char *)ctx->buf, &ctx->buf_len,
163 (unsigned char *)&(ctx->buf[BUF_OFFSET]),
164 i)) {
165 BIO_clear_retry_flags(b);
166 return 0;
167 }
168 ctx->cont = 1;
169 /*
170 * Note: it is possible for EVP_CipherUpdate to decrypt zero
171 * bytes because this is or looks like the final block: if this
172 * happens we should retry and either read more data or decrypt
173 * the final block
174 */
175 if (ctx->buf_len == 0)
176 continue;
177 }
178
179 if (ctx->buf_len <= outl)
180 i = ctx->buf_len;
181 else
182 i = outl;
183 if (i <= 0)
184 break;
185 memcpy(out, ctx->buf, i);
186 ret += i;
187 ctx->buf_off = i;
188 outl -= i;
189 out += i;
190 }
191
192 BIO_clear_retry_flags(b);
193 BIO_copy_next_retry(b);
194 return ((ret == 0) ? ctx->cont : ret);
195 }
196
197 static int enc_write(BIO *b, const char *in, int inl)
198 {
199 int ret = 0, n, i;
200 BIO_ENC_CTX *ctx;
201 BIO *next;
202
203 ctx = BIO_get_data(b);
204 next = BIO_next(b);
205 if ((ctx == NULL) || (next == NULL))
206 return 0;
207
208 ret = inl;
209
210 BIO_clear_retry_flags(b);
211 n = ctx->buf_len - ctx->buf_off;
212 while (n > 0) {
213 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
214 if (i <= 0) {
215 BIO_copy_next_retry(b);
216 return (i);
217 }
218 ctx->buf_off += i;
219 n -= i;
220 }
221 /* at this point all pending data has been written */
222
223 if ((in == NULL) || (inl <= 0))
224 return (0);
225
226 ctx->buf_off = 0;
227 while (inl > 0) {
228 n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
229 if (!EVP_CipherUpdate(ctx->cipher,
230 (unsigned char *)ctx->buf, &ctx->buf_len,
231 (unsigned char *)in, n)) {
232 BIO_clear_retry_flags(b);
233 return 0;
234 }
235 inl -= n;
236 in += n;
237
238 ctx->buf_off = 0;
239 n = ctx->buf_len;
240 while (n > 0) {
241 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
242 if (i <= 0) {
243 BIO_copy_next_retry(b);
244 return (ret == inl) ? i : ret - inl;
245 }
246 n -= i;
247 ctx->buf_off += i;
248 }
249 ctx->buf_len = 0;
250 ctx->buf_off = 0;
251 }
252 BIO_copy_next_retry(b);
253 return (ret);
254 }
255
256 static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
257 {
258 BIO *dbio;
259 BIO_ENC_CTX *ctx, *dctx;
260 long ret = 1;
261 int i;
262 EVP_CIPHER_CTX **c_ctx;
263 BIO *next;
264
265 ctx = BIO_get_data(b);
266 next = BIO_next(b);
267 if (ctx == NULL)
268 return 0;
269
270 switch (cmd) {
271 case BIO_CTRL_RESET:
272 ctx->ok = 1;
273 ctx->finished = 0;
274 if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
275 EVP_CIPHER_CTX_encrypting(ctx->cipher)))
276 return 0;
277 ret = BIO_ctrl(next, cmd, num, ptr);
278 break;
279 case BIO_CTRL_EOF: /* More to read */
280 if (ctx->cont <= 0)
281 ret = 1;
282 else
283 ret = BIO_ctrl(next, cmd, num, ptr);
284 break;
285 case BIO_CTRL_WPENDING:
286 ret = ctx->buf_len - ctx->buf_off;
287 if (ret <= 0)
288 ret = BIO_ctrl(next, cmd, num, ptr);
289 break;
290 case BIO_CTRL_PENDING: /* More to read in buffer */
291 ret = ctx->buf_len - ctx->buf_off;
292 if (ret <= 0)
293 ret = BIO_ctrl(next, cmd, num, ptr);
294 break;
295 case BIO_CTRL_FLUSH:
296 /* do a final write */
297 again:
298 while (ctx->buf_len != ctx->buf_off) {
299 i = enc_write(b, NULL, 0);
300 if (i < 0)
301 return i;
302 }
303
304 if (!ctx->finished) {
305 ctx->finished = 1;
306 ctx->buf_off = 0;
307 ret = EVP_CipherFinal_ex(ctx->cipher,
308 (unsigned char *)ctx->buf,
309 &(ctx->buf_len));
310 ctx->ok = (int)ret;
311 if (ret <= 0)
312 break;
313
314 /* push out the bytes */
315 goto again;
316 }
317
318 /* Finally flush the underlying BIO */
319 ret = BIO_ctrl(next, cmd, num, ptr);
320 break;
321 case BIO_C_GET_CIPHER_STATUS:
322 ret = (long)ctx->ok;
323 break;
324 case BIO_C_DO_STATE_MACHINE:
325 BIO_clear_retry_flags(b);
326 ret = BIO_ctrl(next, cmd, num, ptr);
327 BIO_copy_next_retry(b);
328 break;
329 case BIO_C_GET_CIPHER_CTX:
330 c_ctx = (EVP_CIPHER_CTX **)ptr;
331 *c_ctx = ctx->cipher;
332 BIO_set_init(b, 1);
333 break;
334 case BIO_CTRL_DUP:
335 dbio = (BIO *)ptr;
336 dctx = BIO_get_data(dbio);
337 dctx->cipher = EVP_CIPHER_CTX_new();
338 if (dctx->cipher == NULL)
339 return 0;
340 ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
341 if (ret)
342 BIO_set_init(dbio, 1);
343 break;
344 default:
345 ret = BIO_ctrl(next, cmd, num, ptr);
346 break;
347 }
348 return (ret);
349 }
350
351 static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
352 {
353 long ret = 1;
354 BIO *next = BIO_next(b);
355
356 if (next == NULL)
357 return (0);
358 switch (cmd) {
359 default:
360 ret = BIO_callback_ctrl(next, cmd, fp);
361 break;
362 }
363 return (ret);
364 }
365
366 /*-
367 void BIO_set_cipher_ctx(b,c)
368 BIO *b;
369 EVP_CIPHER_ctx *c;
370 {
371 if (b == NULL) return;
372
373 if ((b->callback != NULL) &&
374 (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
375 return;
376
377 b->init=1;
378 ctx=(BIO_ENC_CTX *)b->ptr;
379 memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
380
381 if (b->callback != NULL)
382 b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
383 }
384 */
385
386 int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
387 const unsigned char *i, int e)
388 {
389 BIO_ENC_CTX *ctx;
390 long (*callback) (struct bio_st *, int, const char *, int, long, long);
391
392 ctx = BIO_get_data(b);
393 if (ctx == NULL)
394 return 0;
395
396 callback = BIO_get_callback(b);
397
398 if ((callback != NULL) &&
399 (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
400 0L) <= 0))
401 return 0;
402
403 BIO_set_init(b, 1);
404
405 if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
406 return 0;
407
408 if (callback != NULL)
409 return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
410 return 1;
411 }