RT4660: BIO_METHODs should be const.
[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
64 static int enc_write(BIO *h, const char *buf, int num);
65 static int enc_read(BIO *h, char *buf, int size);
66 /*
67  * static int enc_puts(BIO *h, const char *str);
68  */
69 /*
70  * static int enc_gets(BIO *h, char *str, int size);
71  */
72 static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
73 static int enc_new(BIO *h);
74 static int enc_free(BIO *data);
75 static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
76 #define ENC_BLOCK_SIZE  (1024*4)
77 #define BUF_OFFSET      (EVP_MAX_BLOCK_LENGTH*2)
78
79 typedef struct enc_struct {
80     int buf_len;
81     int buf_off;
82     int cont;                   /* <= 0 when finished */
83     int finished;
84     int ok;                     /* bad decrypt */
85     EVP_CIPHER_CTX *cipher;
86     /*
87      * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
88      * up to a block more data than is presented to it
89      */
90     char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2];
91 } BIO_ENC_CTX;
92
93 static const BIO_METHOD methods_enc = {
94     BIO_TYPE_CIPHER, "cipher",
95     enc_write,
96     enc_read,
97     NULL,                       /* enc_puts, */
98     NULL,                       /* enc_gets, */
99     enc_ctrl,
100     enc_new,
101     enc_free,
102     enc_callback_ctrl,
103 };
104
105 const BIO_METHOD *BIO_f_cipher(void)
106 {
107     return (&methods_enc);
108 }
109
110 static int enc_new(BIO *bi)
111 {
112     BIO_ENC_CTX *ctx;
113
114     ctx = OPENSSL_zalloc(sizeof(*ctx));
115     if (ctx == NULL)
116         return 0;
117
118     ctx->cipher = EVP_CIPHER_CTX_new();
119     if (ctx->cipher == NULL) {
120         OPENSSL_free(ctx);
121         return 0;
122     }
123     ctx->cont = 1;
124     ctx->ok = 1;
125     bi->init = 0;
126     bi->ptr = (char *)ctx;
127     bi->flags = 0;
128     return 1;
129 }
130
131 static int enc_free(BIO *a)
132 {
133     BIO_ENC_CTX *b;
134
135     if (a == NULL)
136         return (0);
137     b = (BIO_ENC_CTX *)a->ptr;
138     EVP_CIPHER_CTX_free(b->cipher);
139     OPENSSL_clear_free(a->ptr, sizeof(BIO_ENC_CTX));
140     a->ptr = NULL;
141     a->init = 0;
142     a->flags = 0;
143     return (1);
144 }
145
146 static int enc_read(BIO *b, char *out, int outl)
147 {
148     int ret = 0, i;
149     BIO_ENC_CTX *ctx;
150
151     if (out == NULL)
152         return (0);
153     ctx = (BIO_ENC_CTX *)b->ptr;
154
155     if ((ctx == NULL) || (b->next_bio == NULL))
156         return (0);
157
158     /* First check if there are bytes decoded/encoded */
159     if (ctx->buf_len > 0) {
160         i = ctx->buf_len - ctx->buf_off;
161         if (i > outl)
162             i = outl;
163         memcpy(out, &(ctx->buf[ctx->buf_off]), i);
164         ret = i;
165         out += i;
166         outl -= i;
167         ctx->buf_off += i;
168         if (ctx->buf_len == ctx->buf_off) {
169             ctx->buf_len = 0;
170             ctx->buf_off = 0;
171         }
172     }
173
174     /*
175      * At this point, we have room of outl bytes and an empty buffer, so we
176      * should read in some more.
177      */
178
179     while (outl > 0) {
180         if (ctx->cont <= 0)
181             break;
182
183         /*
184          * read in at IV offset, read the EVP_Cipher documentation about why
185          */
186         i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE);
187
188         if (i <= 0) {
189             /* Should be continue next time we are called? */
190             if (!BIO_should_retry(b->next_bio)) {
191                 ctx->cont = i;
192                 i = EVP_CipherFinal_ex(ctx->cipher,
193                                        (unsigned char *)ctx->buf,
194                                        &(ctx->buf_len));
195                 ctx->ok = i;
196                 ctx->buf_off = 0;
197             } else {
198                 ret = (ret == 0) ? i : ret;
199                 break;
200             }
201         } else {
202             if (!EVP_CipherUpdate(ctx->cipher,
203                                   (unsigned char *)ctx->buf, &ctx->buf_len,
204                                   (unsigned char *)&(ctx->buf[BUF_OFFSET]),
205                                   i)) {
206                 BIO_clear_retry_flags(b);
207                 return 0;
208             }
209             ctx->cont = 1;
210             /*
211              * Note: it is possible for EVP_CipherUpdate to decrypt zero
212              * bytes because this is or looks like the final block: if this
213              * happens we should retry and either read more data or decrypt
214              * the final block
215              */
216             if (ctx->buf_len == 0)
217                 continue;
218         }
219
220         if (ctx->buf_len <= outl)
221             i = ctx->buf_len;
222         else
223             i = outl;
224         if (i <= 0)
225             break;
226         memcpy(out, ctx->buf, i);
227         ret += i;
228         ctx->buf_off = i;
229         outl -= i;
230         out += i;
231     }
232
233     BIO_clear_retry_flags(b);
234     BIO_copy_next_retry(b);
235     return ((ret == 0) ? ctx->cont : ret);
236 }
237
238 static int enc_write(BIO *b, const char *in, int inl)
239 {
240     int ret = 0, n, i;
241     BIO_ENC_CTX *ctx;
242
243     ctx = (BIO_ENC_CTX *)b->ptr;
244     ret = inl;
245
246     BIO_clear_retry_flags(b);
247     n = ctx->buf_len - ctx->buf_off;
248     while (n > 0) {
249         i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
250         if (i <= 0) {
251             BIO_copy_next_retry(b);
252             return (i);
253         }
254         ctx->buf_off += i;
255         n -= i;
256     }
257     /* at this point all pending data has been written */
258
259     if ((in == NULL) || (inl <= 0))
260         return (0);
261
262     ctx->buf_off = 0;
263     while (inl > 0) {
264         n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
265         if (!EVP_CipherUpdate(ctx->cipher,
266                               (unsigned char *)ctx->buf, &ctx->buf_len,
267                               (unsigned char *)in, n)) {
268             BIO_clear_retry_flags(b);
269             return 0;
270         }
271         inl -= n;
272         in += n;
273
274         ctx->buf_off = 0;
275         n = ctx->buf_len;
276         while (n > 0) {
277             i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
278             if (i <= 0) {
279                 BIO_copy_next_retry(b);
280                 return (ret == inl) ? i : ret - inl;
281             }
282             n -= i;
283             ctx->buf_off += i;
284         }
285         ctx->buf_len = 0;
286         ctx->buf_off = 0;
287     }
288     BIO_copy_next_retry(b);
289     return (ret);
290 }
291
292 static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
293 {
294     BIO *dbio;
295     BIO_ENC_CTX *ctx, *dctx;
296     long ret = 1;
297     int i;
298     EVP_CIPHER_CTX **c_ctx;
299
300     ctx = (BIO_ENC_CTX *)b->ptr;
301
302     switch (cmd) {
303     case BIO_CTRL_RESET:
304         ctx->ok = 1;
305         ctx->finished = 0;
306         if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
307                                EVP_CIPHER_CTX_encrypting(ctx->cipher)))
308             return 0;
309         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
310         break;
311     case BIO_CTRL_EOF:         /* More to read */
312         if (ctx->cont <= 0)
313             ret = 1;
314         else
315             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
316         break;
317     case BIO_CTRL_WPENDING:
318         ret = ctx->buf_len - ctx->buf_off;
319         if (ret <= 0)
320             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
321         break;
322     case BIO_CTRL_PENDING:     /* More to read in buffer */
323         ret = ctx->buf_len - ctx->buf_off;
324         if (ret <= 0)
325             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
326         break;
327     case BIO_CTRL_FLUSH:
328         /* do a final write */
329  again:
330         while (ctx->buf_len != ctx->buf_off) {
331             i = enc_write(b, NULL, 0);
332             if (i < 0)
333                 return i;
334         }
335
336         if (!ctx->finished) {
337             ctx->finished = 1;
338             ctx->buf_off = 0;
339             ret = EVP_CipherFinal_ex(ctx->cipher,
340                                      (unsigned char *)ctx->buf,
341                                      &(ctx->buf_len));
342             ctx->ok = (int)ret;
343             if (ret <= 0)
344                 break;
345
346             /* push out the bytes */
347             goto again;
348         }
349
350         /* Finally flush the underlying BIO */
351         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
352         break;
353     case BIO_C_GET_CIPHER_STATUS:
354         ret = (long)ctx->ok;
355         break;
356     case BIO_C_DO_STATE_MACHINE:
357         BIO_clear_retry_flags(b);
358         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
359         BIO_copy_next_retry(b);
360         break;
361     case BIO_C_GET_CIPHER_CTX:
362         c_ctx = (EVP_CIPHER_CTX **)ptr;
363         *c_ctx = ctx->cipher;
364         b->init = 1;
365         break;
366     case BIO_CTRL_DUP:
367         dbio = (BIO *)ptr;
368         dctx = (BIO_ENC_CTX *)dbio->ptr;
369         dctx->cipher = EVP_CIPHER_CTX_new();
370         if (dctx->cipher == NULL)
371             return 0;
372         ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
373         if (ret)
374             dbio->init = 1;
375         break;
376     default:
377         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
378         break;
379     }
380     return (ret);
381 }
382
383 static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
384 {
385     long ret = 1;
386
387     if (b->next_bio == NULL)
388         return (0);
389     switch (cmd) {
390     default:
391         ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
392         break;
393     }
394     return (ret);
395 }
396
397 /*-
398 void BIO_set_cipher_ctx(b,c)
399 BIO *b;
400 EVP_CIPHER_ctx *c;
401         {
402         if (b == NULL) return;
403
404         if ((b->callback != NULL) &&
405                 (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
406                 return;
407
408         b->init=1;
409         ctx=(BIO_ENC_CTX *)b->ptr;
410         memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
411
412         if (b->callback != NULL)
413                 b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
414         }
415 */
416
417 int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
418                    const unsigned char *i, int e)
419 {
420     BIO_ENC_CTX *ctx;
421
422     if (b == NULL)
423         return 0;
424
425     if ((b->callback != NULL) &&
426         (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <=
427          0))
428         return 0;
429
430     b->init = 1;
431     ctx = (BIO_ENC_CTX *)b->ptr;
432     if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
433         return 0;
434
435     if (b->callback != NULL)
436         return b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
437                            1L);
438     return 1;
439 }