Make BIO opaque
[openssl.git] / crypto / evp / bio_enc.c
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57
58 #include <stdio.h>
59 #include <errno.h>
60 #include "internal/cryptlib.h"
61 #include <openssl/buffer.h>
62 #include <openssl/evp.h>
63 #include "internal/bio.h"
64
65 static int enc_write(BIO *h, const char *buf, int num);
66 static int enc_read(BIO *h, char *buf, int size);
67 /*
68  * static int enc_puts(BIO *h, const char *str);
69  */
70 /*
71  * static int enc_gets(BIO *h, char *str, int size);
72  */
73 static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
74 static int enc_new(BIO *h);
75 static int enc_free(BIO *data);
76 static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
77 #define ENC_BLOCK_SIZE  (1024*4)
78 #define BUF_OFFSET      (EVP_MAX_BLOCK_LENGTH*2)
79
80 typedef struct enc_struct {
81     int buf_len;
82     int buf_off;
83     int cont;                   /* <= 0 when finished */
84     int finished;
85     int ok;                     /* bad decrypt */
86     EVP_CIPHER_CTX *cipher;
87     /*
88      * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
89      * up to a block more data than is presented to it
90      */
91     char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
92 } BIO_ENC_CTX;
93
94 static const BIO_METHOD methods_enc = {
95     BIO_TYPE_CIPHER, "cipher",
96     enc_write,
97     enc_read,
98     NULL,                       /* enc_puts, */
99     NULL,                       /* enc_gets, */
100     enc_ctrl,
101     enc_new,
102     enc_free,
103     enc_callback_ctrl,
104 };
105
106 const BIO_METHOD *BIO_f_cipher(void)
107 {
108     return (&methods_enc);
109 }
110
111 static int enc_new(BIO *bi)
112 {
113     BIO_ENC_CTX *ctx;
114
115     ctx = OPENSSL_zalloc(sizeof(*ctx));
116     if (ctx == NULL)
117         return 0;
118
119     ctx->cipher = EVP_CIPHER_CTX_new();
120     if (ctx->cipher == NULL) {
121         OPENSSL_free(ctx);
122         return 0;
123     }
124     ctx->cont = 1;
125     ctx->ok = 1;
126     BIO_set_data(bi, ctx);
127     BIO_set_init(bi, 1);
128
129     return 1;
130 }
131
132 static int enc_free(BIO *a)
133 {
134     BIO_ENC_CTX *b;
135
136     if (a == NULL)
137         return 0;
138
139     b = BIO_get_data(a);
140     if (b == NULL)
141         return 0;
142
143     EVP_CIPHER_CTX_free(b->cipher);
144     OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX));
145     BIO_set_data(a, NULL);
146     BIO_set_init(a, 0);
147
148     return 1;
149 }
150
151 static int enc_read(BIO *b, char *out, int outl)
152 {
153     int ret = 0, i;
154     BIO_ENC_CTX *ctx;
155     BIO *next;
156
157     if (out == NULL)
158         return (0);
159     ctx = BIO_get_data(b);
160
161     next = BIO_next(b);
162     if ((ctx == NULL) || (next == NULL))
163         return 0;
164
165     /* First check if there are bytes decoded/encoded */
166     if (ctx->buf_len > 0) {
167         i = ctx->buf_len - ctx->buf_off;
168         if (i > outl)
169             i = outl;
170         memcpy(out, &(ctx->buf[ctx->buf_off]), i);
171         ret = i;
172         out += i;
173         outl -= i;
174         ctx->buf_off += i;
175         if (ctx->buf_len == ctx->buf_off) {
176             ctx->buf_len = 0;
177             ctx->buf_off = 0;
178         }
179     }
180
181     /*
182      * At this point, we have room of outl bytes and an empty buffer, so we
183      * should read in some more.
184      */
185
186     while (outl > 0) {
187         if (ctx->cont <= 0)
188             break;
189
190         /*
191          * read in at IV offset, read the EVP_Cipher documentation about why
192          */
193         i = BIO_read(next, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
194
195         if (i <= 0) {
196             /* Should be continue next time we are called? */
197             if (!BIO_should_retry(next)) {
198                 ctx->cont = i;
199                 i = EVP_CipherFinal_ex(ctx->cipher,
200                                        (unsigned char *)ctx->buf,
201                                        &(ctx->buf_len));
202                 ctx->ok = i;
203                 ctx->buf_off = 0;
204             } else {
205                 ret = (ret == 0) ? i : ret;
206                 break;
207             }
208         } else {
209             if (!EVP_CipherUpdate(ctx->cipher,
210                                   (unsigned char *)ctx->buf, &ctx->buf_len,
211                                   (unsigned char *)&(ctx->buf[BUF_OFFSET]),
212                                   i)) {
213                 BIO_clear_retry_flags(b);
214                 return 0;
215             }
216             ctx->cont = 1;
217             /*
218              * Note: it is possible for EVP_CipherUpdate to decrypt zero
219              * bytes because this is or looks like the final block: if this
220              * happens we should retry and either read more data or decrypt
221              * the final block
222              */
223             if (ctx->buf_len == 0)
224                 continue;
225         }
226
227         if (ctx->buf_len <= outl)
228             i = ctx->buf_len;
229         else
230             i = outl;
231         if (i <= 0)
232             break;
233         memcpy(out, ctx->buf, i);
234         ret += i;
235         ctx->buf_off = i;
236         outl -= i;
237         out += i;
238     }
239
240     BIO_clear_retry_flags(b);
241     BIO_copy_next_retry(b);
242     return ((ret == 0) ? ctx->cont : ret);
243 }
244
245 static int enc_write(BIO *b, const char *in, int inl)
246 {
247     int ret = 0, n, i;
248     BIO_ENC_CTX *ctx;
249     BIO *next;
250
251     ctx = BIO_get_data(b);
252     next = BIO_next(b);
253     if ((ctx == NULL) || (next == NULL))
254         return 0;
255
256     ret = inl;
257
258     BIO_clear_retry_flags(b);
259     n = ctx->buf_len - ctx->buf_off;
260     while (n > 0) {
261         i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
262         if (i <= 0) {
263             BIO_copy_next_retry(b);
264             return (i);
265         }
266         ctx->buf_off += i;
267         n -= i;
268     }
269     /* at this point all pending data has been written */
270
271     if ((in == NULL) || (inl <= 0))
272         return (0);
273
274     ctx->buf_off = 0;
275     while (inl > 0) {
276         n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
277         if (!EVP_CipherUpdate(ctx->cipher,
278                               (unsigned char *)ctx->buf, &ctx->buf_len,
279                               (unsigned char *)in, n)) {
280             BIO_clear_retry_flags(b);
281             return 0;
282         }
283         inl -= n;
284         in += n;
285
286         ctx->buf_off = 0;
287         n = ctx->buf_len;
288         while (n > 0) {
289             i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
290             if (i <= 0) {
291                 BIO_copy_next_retry(b);
292                 return (ret == inl) ? i : ret - inl;
293             }
294             n -= i;
295             ctx->buf_off += i;
296         }
297         ctx->buf_len = 0;
298         ctx->buf_off = 0;
299     }
300     BIO_copy_next_retry(b);
301     return (ret);
302 }
303
304 static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
305 {
306     BIO *dbio;
307     BIO_ENC_CTX *ctx, *dctx;
308     long ret = 1;
309     int i;
310     EVP_CIPHER_CTX **c_ctx;
311     BIO *next;
312
313     ctx = BIO_get_data(b);
314     next = BIO_next(b);
315     if (ctx == NULL)
316         return 0;
317
318     switch (cmd) {
319     case BIO_CTRL_RESET:
320         ctx->ok = 1;
321         ctx->finished = 0;
322         if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
323                                EVP_CIPHER_CTX_encrypting(ctx->cipher)))
324             return 0;
325         ret = BIO_ctrl(next, cmd, num, ptr);
326         break;
327     case BIO_CTRL_EOF:         /* More to read */
328         if (ctx->cont <= 0)
329             ret = 1;
330         else
331             ret = BIO_ctrl(next, cmd, num, ptr);
332         break;
333     case BIO_CTRL_WPENDING:
334         ret = ctx->buf_len - ctx->buf_off;
335         if (ret <= 0)
336             ret = BIO_ctrl(next, cmd, num, ptr);
337         break;
338     case BIO_CTRL_PENDING:     /* More to read in buffer */
339         ret = ctx->buf_len - ctx->buf_off;
340         if (ret <= 0)
341             ret = BIO_ctrl(next, cmd, num, ptr);
342         break;
343     case BIO_CTRL_FLUSH:
344         /* do a final write */
345  again:
346         while (ctx->buf_len != ctx->buf_off) {
347             i = enc_write(b, NULL, 0);
348             if (i < 0)
349                 return i;
350         }
351
352         if (!ctx->finished) {
353             ctx->finished = 1;
354             ctx->buf_off = 0;
355             ret = EVP_CipherFinal_ex(ctx->cipher,
356                                      (unsigned char *)ctx->buf,
357                                      &(ctx->buf_len));
358             ctx->ok = (int)ret;
359             if (ret <= 0)
360                 break;
361
362             /* push out the bytes */
363             goto again;
364         }
365
366         /* Finally flush the underlying BIO */
367         ret = BIO_ctrl(next, cmd, num, ptr);
368         break;
369     case BIO_C_GET_CIPHER_STATUS:
370         ret = (long)ctx->ok;
371         break;
372     case BIO_C_DO_STATE_MACHINE:
373         BIO_clear_retry_flags(b);
374         ret = BIO_ctrl(next, cmd, num, ptr);
375         BIO_copy_next_retry(b);
376         break;
377     case BIO_C_GET_CIPHER_CTX:
378         c_ctx = (EVP_CIPHER_CTX **)ptr;
379         *c_ctx = ctx->cipher;
380         BIO_set_init(b, 1);
381         break;
382     case BIO_CTRL_DUP:
383         dbio = (BIO *)ptr;
384         dctx = BIO_get_data(dbio);
385         dctx->cipher = EVP_CIPHER_CTX_new();
386         if (dctx->cipher == NULL)
387             return 0;
388         ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
389         if (ret)
390             BIO_set_init(dbio, 1);
391         break;
392     default:
393         ret = BIO_ctrl(next, cmd, num, ptr);
394         break;
395     }
396     return (ret);
397 }
398
399 static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
400 {
401     long ret = 1;
402     BIO *next = BIO_next(b);
403
404     if (next == NULL)
405         return (0);
406     switch (cmd) {
407     default:
408         ret = BIO_callback_ctrl(next, cmd, fp);
409         break;
410     }
411     return (ret);
412 }
413
414 /*-
415 void BIO_set_cipher_ctx(b,c)
416 BIO *b;
417 EVP_CIPHER_ctx *c;
418         {
419         if (b == NULL) return;
420
421         if ((b->callback != NULL) &&
422                 (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
423                 return;
424
425         b->init=1;
426         ctx=(BIO_ENC_CTX *)b->ptr;
427         memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
428
429         if (b->callback != NULL)
430                 b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
431         }
432 */
433
434 int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
435                    const unsigned char *i, int e)
436 {
437     BIO_ENC_CTX *ctx;
438     long (*callback) (struct bio_st *, int, const char *, int, long, long);
439
440     ctx = BIO_get_data(b);
441     if (ctx == NULL)
442         return 0;
443
444     callback = BIO_get_callback(b);
445
446     if ((callback != NULL) &&
447             (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
448                       0L) <= 0))
449         return 0;
450
451     BIO_set_init(b, 1);
452
453     if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
454         return 0;
455
456     if (callback != NULL)
457         return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
458     return 1;
459 }