Make BIO_METHOD struct definitions consistent
[openssl.git] / crypto / evp / bio_ok.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 /*-
11         From: Arne Ansper
12
13         Why BIO_f_reliable?
14
15         I wrote function which took BIO* as argument, read data from it
16         and processed it. Then I wanted to store the input file in
17         encrypted form. OK I pushed BIO_f_cipher to the BIO stack
18         and everything was OK. BUT if user types wrong password
19         BIO_f_cipher outputs only garbage and my function crashes. Yes
20         I can and I should fix my function, but BIO_f_cipher is
21         easy way to add encryption support to many existing applications
22         and it's hard to debug and fix them all.
23
24         So I wanted another BIO which would catch the incorrect passwords and
25         file damages which cause garbage on BIO_f_cipher's output.
26
27         The easy way is to push the BIO_f_md and save the checksum at
28         the end of the file. However there are several problems with this
29         approach:
30
31         1) you must somehow separate checksum from actual data.
32         2) you need lot's of memory when reading the file, because you
33         must read to the end of the file and verify the checksum before
34         letting the application to read the data.
35
36         BIO_f_reliable tries to solve both problems, so that you can
37         read and write arbitrary long streams using only fixed amount
38         of memory.
39
40         BIO_f_reliable splits data stream into blocks. Each block is prefixed
41         with it's length and suffixed with it's digest. So you need only
42         several Kbytes of memory to buffer single block before verifying
43         it's digest.
44
45         BIO_f_reliable goes further and adds several important capabilities:
46
47         1) the digest of the block is computed over the whole stream
48         -- so nobody can rearrange the blocks or remove or replace them.
49
50         2) to detect invalid passwords right at the start BIO_f_reliable
51         adds special prefix to the stream. In order to avoid known plain-text
52         attacks this prefix is generated as follows:
53
54                 *) digest is initialized with random seed instead of
55                 standardized one.
56                 *) same seed is written to output
57                 *) well-known text is then hashed and the output
58                 of the digest is also written to output.
59
60         reader can now read the seed from stream, hash the same string
61         and then compare the digest output.
62
63         Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
64         initially wrote and tested this code on x86 machine and wrote the
65         digests out in machine-dependent order :( There are people using
66         this code and I cannot change this easily without making existing
67         data files unreadable.
68
69 */
70
71 #include <stdio.h>
72 #include <errno.h>
73 #include <assert.h>
74 #include "internal/cryptlib.h"
75 #include <openssl/buffer.h>
76 #include "internal/bio.h"
77 #include <openssl/evp.h>
78 #include <openssl/rand.h>
79 #include "internal/evp_int.h"
80
81 static int ok_write(BIO *h, const char *buf, int num);
82 static int ok_read(BIO *h, char *buf, int size);
83 static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
84 static int ok_new(BIO *h);
85 static int ok_free(BIO *data);
86 static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
87
88 static __owur int sig_out(BIO *b);
89 static __owur int sig_in(BIO *b);
90 static __owur int block_out(BIO *b);
91 static __owur int block_in(BIO *b);
92 #define OK_BLOCK_SIZE   (1024*4)
93 #define OK_BLOCK_BLOCK  4
94 #define IOBS            (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
95 #define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
96
97 typedef struct ok_struct {
98     size_t buf_len;
99     size_t buf_off;
100     size_t buf_len_save;
101     size_t buf_off_save;
102     int cont;                   /* <= 0 when finished */
103     int finished;
104     EVP_MD_CTX *md;
105     int blockout;               /* output block is ready */
106     int sigio;                  /* must process signature */
107     unsigned char buf[IOBS];
108 } BIO_OK_CTX;
109
110 static const BIO_METHOD methods_ok = {
111     BIO_TYPE_CIPHER,
112     "reliable",
113     /* TODO: Convert to new style write function */
114     bwrite_conv,
115     ok_write,
116     /* TODO: Convert to new style read function */
117     bread_conv,
118     ok_read,
119     NULL,                       /* ok_puts, */
120     NULL,                       /* ok_gets, */
121     ok_ctrl,
122     ok_new,
123     ok_free,
124     ok_callback_ctrl,
125 };
126
127 const BIO_METHOD *BIO_f_reliable(void)
128 {
129     return &methods_ok;
130 }
131
132 static int ok_new(BIO *bi)
133 {
134     BIO_OK_CTX *ctx;
135
136     ctx = OPENSSL_zalloc(sizeof(*ctx));
137     if (ctx == NULL)
138         return 0;
139
140     ctx->cont = 1;
141     ctx->sigio = 1;
142     ctx->md = EVP_MD_CTX_new();
143     if (ctx->md == NULL) {
144         OPENSSL_free(ctx);
145         return 0;
146     }
147     BIO_set_init(bi, 0);
148     BIO_set_data(bi, ctx);
149
150     return 1;
151 }
152
153 static int ok_free(BIO *a)
154 {
155     BIO_OK_CTX *ctx;
156
157     if (a == NULL)
158         return 0;
159
160     ctx = BIO_get_data(a);
161
162     EVP_MD_CTX_free(ctx->md);
163     OPENSSL_clear_free(ctx, sizeof(BIO_OK_CTX));
164     BIO_set_data(a, NULL);
165     BIO_set_init(a, 0);
166
167     return 1;
168 }
169
170 static int ok_read(BIO *b, char *out, int outl)
171 {
172     int ret = 0, i, n;
173     BIO_OK_CTX *ctx;
174     BIO *next;
175
176     if (out == NULL)
177         return 0;
178
179     ctx = BIO_get_data(b);
180     next = BIO_next(b);
181
182     if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
183         return 0;
184
185     while (outl > 0) {
186
187         /* copy clean bytes to output buffer */
188         if (ctx->blockout) {
189             i = ctx->buf_len - ctx->buf_off;
190             if (i > outl)
191                 i = outl;
192             memcpy(out, &(ctx->buf[ctx->buf_off]), i);
193             ret += i;
194             out += i;
195             outl -= i;
196             ctx->buf_off += i;
197
198             /* all clean bytes are out */
199             if (ctx->buf_len == ctx->buf_off) {
200                 ctx->buf_off = 0;
201
202                 /*
203                  * copy start of the next block into proper place
204                  */
205                 if (ctx->buf_len_save - ctx->buf_off_save > 0) {
206                     ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
207                     memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
208                             ctx->buf_len);
209                 } else {
210                     ctx->buf_len = 0;
211                 }
212                 ctx->blockout = 0;
213             }
214         }
215
216         /* output buffer full -- cancel */
217         if (outl == 0)
218             break;
219
220         /* no clean bytes in buffer -- fill it */
221         n = IOBS - ctx->buf_len;
222         i = BIO_read(next, &(ctx->buf[ctx->buf_len]), n);
223
224         if (i <= 0)
225             break;              /* nothing new */
226
227         ctx->buf_len += i;
228
229         /* no signature yet -- check if we got one */
230         if (ctx->sigio == 1) {
231             if (!sig_in(b)) {
232                 BIO_clear_retry_flags(b);
233                 return 0;
234             }
235         }
236
237         /* signature ok -- check if we got block */
238         if (ctx->sigio == 0) {
239             if (!block_in(b)) {
240                 BIO_clear_retry_flags(b);
241                 return 0;
242             }
243         }
244
245         /* invalid block -- cancel */
246         if (ctx->cont <= 0)
247             break;
248
249     }
250
251     BIO_clear_retry_flags(b);
252     BIO_copy_next_retry(b);
253     return ret;
254 }
255
256 static int ok_write(BIO *b, const char *in, int inl)
257 {
258     int ret = 0, n, i;
259     BIO_OK_CTX *ctx;
260     BIO *next;
261
262     if (inl <= 0)
263         return inl;
264
265     ctx = BIO_get_data(b);
266     next = BIO_next(b);
267     ret = inl;
268
269     if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
270         return 0;
271
272     if (ctx->sigio && !sig_out(b))
273         return 0;
274
275     do {
276         BIO_clear_retry_flags(b);
277         n = ctx->buf_len - ctx->buf_off;
278         while (ctx->blockout && n > 0) {
279             i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
280             if (i <= 0) {
281                 BIO_copy_next_retry(b);
282                 if (!BIO_should_retry(b))
283                     ctx->cont = 0;
284                 return i;
285             }
286             ctx->buf_off += i;
287             n -= i;
288         }
289
290         /* at this point all pending data has been written */
291         ctx->blockout = 0;
292         if (ctx->buf_len == ctx->buf_off) {
293             ctx->buf_len = OK_BLOCK_BLOCK;
294             ctx->buf_off = 0;
295         }
296
297         if ((in == NULL) || (inl <= 0))
298             return 0;
299
300         n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
301             (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
302
303         memcpy(&ctx->buf[ctx->buf_len], in, n);
304         ctx->buf_len += n;
305         inl -= n;
306         in += n;
307
308         if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
309             if (!block_out(b)) {
310                 BIO_clear_retry_flags(b);
311                 return 0;
312             }
313         }
314     } while (inl > 0);
315
316     BIO_clear_retry_flags(b);
317     BIO_copy_next_retry(b);
318     return ret;
319 }
320
321 static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
322 {
323     BIO_OK_CTX *ctx;
324     EVP_MD *md;
325     const EVP_MD **ppmd;
326     long ret = 1;
327     int i;
328     BIO *next;
329
330     ctx = BIO_get_data(b);
331     next = BIO_next(b);
332
333     switch (cmd) {
334     case BIO_CTRL_RESET:
335         ctx->buf_len = 0;
336         ctx->buf_off = 0;
337         ctx->buf_len_save = 0;
338         ctx->buf_off_save = 0;
339         ctx->cont = 1;
340         ctx->finished = 0;
341         ctx->blockout = 0;
342         ctx->sigio = 1;
343         ret = BIO_ctrl(next, cmd, num, ptr);
344         break;
345     case BIO_CTRL_EOF:         /* More to read */
346         if (ctx->cont <= 0)
347             ret = 1;
348         else
349             ret = BIO_ctrl(next, cmd, num, ptr);
350         break;
351     case BIO_CTRL_PENDING:     /* More to read in buffer */
352     case BIO_CTRL_WPENDING:    /* More to read in buffer */
353         ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
354         if (ret <= 0)
355             ret = BIO_ctrl(next, cmd, num, ptr);
356         break;
357     case BIO_CTRL_FLUSH:
358         /* do a final write */
359         if (ctx->blockout == 0)
360             if (!block_out(b))
361                 return 0;
362
363         while (ctx->blockout) {
364             i = ok_write(b, NULL, 0);
365             if (i < 0) {
366                 ret = i;
367                 break;
368             }
369         }
370
371         ctx->finished = 1;
372         ctx->buf_off = ctx->buf_len = 0;
373         ctx->cont = (int)ret;
374
375         /* Finally flush the underlying BIO */
376         ret = BIO_ctrl(next, cmd, num, ptr);
377         break;
378     case BIO_C_DO_STATE_MACHINE:
379         BIO_clear_retry_flags(b);
380         ret = BIO_ctrl(next, cmd, num, ptr);
381         BIO_copy_next_retry(b);
382         break;
383     case BIO_CTRL_INFO:
384         ret = (long)ctx->cont;
385         break;
386     case BIO_C_SET_MD:
387         md = ptr;
388         if (!EVP_DigestInit_ex(ctx->md, md, NULL))
389             return 0;
390         BIO_set_init(b, 1);
391         break;
392     case BIO_C_GET_MD:
393         if (BIO_get_init(b)) {
394             ppmd = ptr;
395             *ppmd = EVP_MD_CTX_md(ctx->md);
396         } else
397             ret = 0;
398         break;
399     default:
400         ret = BIO_ctrl(next, cmd, num, ptr);
401         break;
402     }
403     return ret;
404 }
405
406 static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
407 {
408     long ret = 1;
409     BIO *next;
410
411     next = BIO_next(b);
412
413     if (next == NULL)
414         return 0;
415
416     switch (cmd) {
417     default:
418         ret = BIO_callback_ctrl(next, cmd, fp);
419         break;
420     }
421
422     return ret;
423 }
424
425 static void longswap(void *_ptr, size_t len)
426 {
427     const union {
428         long one;
429         char little;
430     } is_endian = {
431         1
432     };
433
434     if (is_endian.little) {
435         size_t i;
436         unsigned char *p = _ptr, c;
437
438         for (i = 0; i < len; i += 4) {
439             c = p[0], p[0] = p[3], p[3] = c;
440             c = p[1], p[1] = p[2], p[2] = c;
441         }
442     }
443 }
444
445 static int sig_out(BIO *b)
446 {
447     BIO_OK_CTX *ctx;
448     EVP_MD_CTX *md;
449     const EVP_MD *digest;
450     int md_size;
451     void *md_data;
452
453     ctx = BIO_get_data(b);
454     md = ctx->md;
455     digest = EVP_MD_CTX_md(md);
456     md_size = EVP_MD_size(digest);
457     md_data = EVP_MD_CTX_md_data(md);
458
459     if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
460         return 1;
461
462     if (!EVP_DigestInit_ex(md, digest, NULL))
463         goto berr;
464     /*
465      * FIXME: there's absolutely no guarantee this makes any sense at all,
466      * particularly now EVP_MD_CTX has been restructured.
467      */
468     if (RAND_bytes(md_data, md_size) <= 0)
469         goto berr;
470     memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
471     longswap(&(ctx->buf[ctx->buf_len]), md_size);
472     ctx->buf_len += md_size;
473
474     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
475         goto berr;
476     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
477         goto berr;
478     ctx->buf_len += md_size;
479     ctx->blockout = 1;
480     ctx->sigio = 0;
481     return 1;
482  berr:
483     BIO_clear_retry_flags(b);
484     return 0;
485 }
486
487 static int sig_in(BIO *b)
488 {
489     BIO_OK_CTX *ctx;
490     EVP_MD_CTX *md;
491     unsigned char tmp[EVP_MAX_MD_SIZE];
492     int ret = 0;
493     const EVP_MD *digest;
494     int md_size;
495     void *md_data;
496
497     ctx = BIO_get_data(b);
498     md = ctx->md;
499     digest = EVP_MD_CTX_md(md);
500     md_size = EVP_MD_size(digest);
501     md_data = EVP_MD_CTX_md_data(md);
502
503     if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
504         return 1;
505
506     if (!EVP_DigestInit_ex(md, digest, NULL))
507         goto berr;
508     memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
509     longswap(md_data, md_size);
510     ctx->buf_off += md_size;
511
512     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
513         goto berr;
514     if (!EVP_DigestFinal_ex(md, tmp, NULL))
515         goto berr;
516     ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0;
517     ctx->buf_off += md_size;
518     if (ret == 1) {
519         ctx->sigio = 0;
520         if (ctx->buf_len != ctx->buf_off) {
521             memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
522                     ctx->buf_len - ctx->buf_off);
523         }
524         ctx->buf_len -= ctx->buf_off;
525         ctx->buf_off = 0;
526     } else {
527         ctx->cont = 0;
528     }
529     return 1;
530  berr:
531     BIO_clear_retry_flags(b);
532     return 0;
533 }
534
535 static int block_out(BIO *b)
536 {
537     BIO_OK_CTX *ctx;
538     EVP_MD_CTX *md;
539     unsigned long tl;
540     const EVP_MD *digest;
541     int md_size;
542
543     ctx = BIO_get_data(b);
544     md = ctx->md;
545     digest = EVP_MD_CTX_md(md);
546     md_size = EVP_MD_size(digest);
547
548     tl = ctx->buf_len - OK_BLOCK_BLOCK;
549     ctx->buf[0] = (unsigned char)(tl >> 24);
550     ctx->buf[1] = (unsigned char)(tl >> 16);
551     ctx->buf[2] = (unsigned char)(tl >> 8);
552     ctx->buf[3] = (unsigned char)(tl);
553     if (!EVP_DigestUpdate(md,
554                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
555         goto berr;
556     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
557         goto berr;
558     ctx->buf_len += md_size;
559     ctx->blockout = 1;
560     return 1;
561  berr:
562     BIO_clear_retry_flags(b);
563     return 0;
564 }
565
566 static int block_in(BIO *b)
567 {
568     BIO_OK_CTX *ctx;
569     EVP_MD_CTX *md;
570     unsigned long tl = 0;
571     unsigned char tmp[EVP_MAX_MD_SIZE];
572     int md_size;
573
574     ctx = BIO_get_data(b);
575     md = ctx->md;
576     md_size = EVP_MD_size(EVP_MD_CTX_md(md));
577
578     assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
579     tl = ctx->buf[0];
580     tl <<= 8;
581     tl |= ctx->buf[1];
582     tl <<= 8;
583     tl |= ctx->buf[2];
584     tl <<= 8;
585     tl |= ctx->buf[3];
586
587     if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
588         return 1;
589
590     if (!EVP_DigestUpdate(md,
591                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
592         goto berr;
593     if (!EVP_DigestFinal_ex(md, tmp, NULL))
594         goto berr;
595     if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
596         /* there might be parts from next block lurking around ! */
597         ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
598         ctx->buf_len_save = ctx->buf_len;
599         ctx->buf_off = OK_BLOCK_BLOCK;
600         ctx->buf_len = tl + OK_BLOCK_BLOCK;
601         ctx->blockout = 1;
602     } else {
603         ctx->cont = 0;
604     }
605     return 1;
606  berr:
607     BIO_clear_retry_flags(b);
608     return 0;
609 }