738ced464ace52209c15537a51a0ccf580cd2ce6
[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, "reliable",
112     /* TODO: Convert to new style write function */
113     bwrite_conv,
114     ok_write,
115     /* TODO: Convert to new style read function */
116     bread_conv,
117     ok_read,
118     NULL,                       /* ok_puts, */
119     NULL,                       /* ok_gets, */
120     ok_ctrl,
121     ok_new,
122     ok_free,
123     ok_callback_ctrl,
124 };
125
126 const BIO_METHOD *BIO_f_reliable(void)
127 {
128     return &methods_ok;
129 }
130
131 static int ok_new(BIO *bi)
132 {
133     BIO_OK_CTX *ctx;
134
135     ctx = OPENSSL_zalloc(sizeof(*ctx));
136     if (ctx == NULL)
137         return 0;
138
139     ctx->cont = 1;
140     ctx->sigio = 1;
141     ctx->md = EVP_MD_CTX_new();
142     if (ctx->md == NULL) {
143         OPENSSL_free(ctx);
144         return 0;
145     }
146     BIO_set_init(bi, 0);
147     BIO_set_data(bi, ctx);
148
149     return 1;
150 }
151
152 static int ok_free(BIO *a)
153 {
154     BIO_OK_CTX *ctx;
155
156     if (a == NULL)
157         return 0;
158
159     ctx = BIO_get_data(a);
160
161     EVP_MD_CTX_free(ctx->md);
162     OPENSSL_clear_free(ctx, sizeof(BIO_OK_CTX));
163     BIO_set_data(a, NULL);
164     BIO_set_init(a, 0);
165
166     return 1;
167 }
168
169 static int ok_read(BIO *b, char *out, int outl)
170 {
171     int ret = 0, i, n;
172     BIO_OK_CTX *ctx;
173     BIO *next;
174
175     if (out == NULL)
176         return 0;
177
178     ctx = BIO_get_data(b);
179     next = BIO_next(b);
180
181     if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
182         return 0;
183
184     while (outl > 0) {
185
186         /* copy clean bytes to output buffer */
187         if (ctx->blockout) {
188             i = ctx->buf_len - ctx->buf_off;
189             if (i > outl)
190                 i = outl;
191             memcpy(out, &(ctx->buf[ctx->buf_off]), i);
192             ret += i;
193             out += i;
194             outl -= i;
195             ctx->buf_off += i;
196
197             /* all clean bytes are out */
198             if (ctx->buf_len == ctx->buf_off) {
199                 ctx->buf_off = 0;
200
201                 /*
202                  * copy start of the next block into proper place
203                  */
204                 if (ctx->buf_len_save - ctx->buf_off_save > 0) {
205                     ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
206                     memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
207                             ctx->buf_len);
208                 } else {
209                     ctx->buf_len = 0;
210                 }
211                 ctx->blockout = 0;
212             }
213         }
214
215         /* output buffer full -- cancel */
216         if (outl == 0)
217             break;
218
219         /* no clean bytes in buffer -- fill it */
220         n = IOBS - ctx->buf_len;
221         i = BIO_read(next, &(ctx->buf[ctx->buf_len]), n);
222
223         if (i <= 0)
224             break;              /* nothing new */
225
226         ctx->buf_len += i;
227
228         /* no signature yet -- check if we got one */
229         if (ctx->sigio == 1) {
230             if (!sig_in(b)) {
231                 BIO_clear_retry_flags(b);
232                 return 0;
233             }
234         }
235
236         /* signature ok -- check if we got block */
237         if (ctx->sigio == 0) {
238             if (!block_in(b)) {
239                 BIO_clear_retry_flags(b);
240                 return 0;
241             }
242         }
243
244         /* invalid block -- cancel */
245         if (ctx->cont <= 0)
246             break;
247
248     }
249
250     BIO_clear_retry_flags(b);
251     BIO_copy_next_retry(b);
252     return ret;
253 }
254
255 static int ok_write(BIO *b, const char *in, int inl)
256 {
257     int ret = 0, n, i;
258     BIO_OK_CTX *ctx;
259     BIO *next;
260
261     if (inl <= 0)
262         return inl;
263
264     ctx = BIO_get_data(b);
265     next = BIO_next(b);
266     ret = inl;
267
268     if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
269         return 0;
270
271     if (ctx->sigio && !sig_out(b))
272         return 0;
273
274     do {
275         BIO_clear_retry_flags(b);
276         n = ctx->buf_len - ctx->buf_off;
277         while (ctx->blockout && n > 0) {
278             i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
279             if (i <= 0) {
280                 BIO_copy_next_retry(b);
281                 if (!BIO_should_retry(b))
282                     ctx->cont = 0;
283                 return i;
284             }
285             ctx->buf_off += i;
286             n -= i;
287         }
288
289         /* at this point all pending data has been written */
290         ctx->blockout = 0;
291         if (ctx->buf_len == ctx->buf_off) {
292             ctx->buf_len = OK_BLOCK_BLOCK;
293             ctx->buf_off = 0;
294         }
295
296         if ((in == NULL) || (inl <= 0))
297             return 0;
298
299         n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
300             (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
301
302         memcpy(&ctx->buf[ctx->buf_len], in, n);
303         ctx->buf_len += n;
304         inl -= n;
305         in += n;
306
307         if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
308             if (!block_out(b)) {
309                 BIO_clear_retry_flags(b);
310                 return 0;
311             }
312         }
313     } while (inl > 0);
314
315     BIO_clear_retry_flags(b);
316     BIO_copy_next_retry(b);
317     return ret;
318 }
319
320 static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
321 {
322     BIO_OK_CTX *ctx;
323     EVP_MD *md;
324     const EVP_MD **ppmd;
325     long ret = 1;
326     int i;
327     BIO *next;
328
329     ctx = BIO_get_data(b);
330     next = BIO_next(b);
331
332     switch (cmd) {
333     case BIO_CTRL_RESET:
334         ctx->buf_len = 0;
335         ctx->buf_off = 0;
336         ctx->buf_len_save = 0;
337         ctx->buf_off_save = 0;
338         ctx->cont = 1;
339         ctx->finished = 0;
340         ctx->blockout = 0;
341         ctx->sigio = 1;
342         ret = BIO_ctrl(next, cmd, num, ptr);
343         break;
344     case BIO_CTRL_EOF:         /* More to read */
345         if (ctx->cont <= 0)
346             ret = 1;
347         else
348             ret = BIO_ctrl(next, cmd, num, ptr);
349         break;
350     case BIO_CTRL_PENDING:     /* More to read in buffer */
351     case BIO_CTRL_WPENDING:    /* More to read in buffer */
352         ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
353         if (ret <= 0)
354             ret = BIO_ctrl(next, cmd, num, ptr);
355         break;
356     case BIO_CTRL_FLUSH:
357         /* do a final write */
358         if (ctx->blockout == 0)
359             if (!block_out(b))
360                 return 0;
361
362         while (ctx->blockout) {
363             i = ok_write(b, NULL, 0);
364             if (i < 0) {
365                 ret = i;
366                 break;
367             }
368         }
369
370         ctx->finished = 1;
371         ctx->buf_off = ctx->buf_len = 0;
372         ctx->cont = (int)ret;
373
374         /* Finally flush the underlying BIO */
375         ret = BIO_ctrl(next, cmd, num, ptr);
376         break;
377     case BIO_C_DO_STATE_MACHINE:
378         BIO_clear_retry_flags(b);
379         ret = BIO_ctrl(next, cmd, num, ptr);
380         BIO_copy_next_retry(b);
381         break;
382     case BIO_CTRL_INFO:
383         ret = (long)ctx->cont;
384         break;
385     case BIO_C_SET_MD:
386         md = ptr;
387         if (!EVP_DigestInit_ex(ctx->md, md, NULL))
388             return 0;
389         BIO_set_init(b, 1);
390         break;
391     case BIO_C_GET_MD:
392         if (BIO_get_init(b)) {
393             ppmd = ptr;
394             *ppmd = EVP_MD_CTX_md(ctx->md);
395         } else
396             ret = 0;
397         break;
398     default:
399         ret = BIO_ctrl(next, cmd, num, ptr);
400         break;
401     }
402     return ret;
403 }
404
405 static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
406 {
407     long ret = 1;
408     BIO *next;
409
410     next = BIO_next(b);
411
412     if (next == NULL)
413         return 0;
414
415     switch (cmd) {
416     default:
417         ret = BIO_callback_ctrl(next, cmd, fp);
418         break;
419     }
420
421     return ret;
422 }
423
424 static void longswap(void *_ptr, size_t len)
425 {
426     const union {
427         long one;
428         char little;
429     } is_endian = {
430         1
431     };
432
433     if (is_endian.little) {
434         size_t i;
435         unsigned char *p = _ptr, c;
436
437         for (i = 0; i < len; i += 4) {
438             c = p[0], p[0] = p[3], p[3] = c;
439             c = p[1], p[1] = p[2], p[2] = c;
440         }
441     }
442 }
443
444 static int sig_out(BIO *b)
445 {
446     BIO_OK_CTX *ctx;
447     EVP_MD_CTX *md;
448     const EVP_MD *digest;
449     int md_size;
450     void *md_data;
451
452     ctx = BIO_get_data(b);
453     md = ctx->md;
454     digest = EVP_MD_CTX_md(md);
455     md_size = EVP_MD_size(digest);
456     md_data = EVP_MD_CTX_md_data(md);
457
458     if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
459         return 1;
460
461     if (!EVP_DigestInit_ex(md, digest, NULL))
462         goto berr;
463     /*
464      * FIXME: there's absolutely no guarantee this makes any sense at all,
465      * particularly now EVP_MD_CTX has been restructured.
466      */
467     if (RAND_bytes(md_data, md_size) <= 0)
468         goto berr;
469     memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
470     longswap(&(ctx->buf[ctx->buf_len]), md_size);
471     ctx->buf_len += md_size;
472
473     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
474         goto berr;
475     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
476         goto berr;
477     ctx->buf_len += md_size;
478     ctx->blockout = 1;
479     ctx->sigio = 0;
480     return 1;
481  berr:
482     BIO_clear_retry_flags(b);
483     return 0;
484 }
485
486 static int sig_in(BIO *b)
487 {
488     BIO_OK_CTX *ctx;
489     EVP_MD_CTX *md;
490     unsigned char tmp[EVP_MAX_MD_SIZE];
491     int ret = 0;
492     const EVP_MD *digest;
493     int md_size;
494     void *md_data;
495
496     ctx = BIO_get_data(b);
497     md = ctx->md;
498     digest = EVP_MD_CTX_md(md);
499     md_size = EVP_MD_size(digest);
500     md_data = EVP_MD_CTX_md_data(md);
501
502     if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
503         return 1;
504
505     if (!EVP_DigestInit_ex(md, digest, NULL))
506         goto berr;
507     memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
508     longswap(md_data, md_size);
509     ctx->buf_off += md_size;
510
511     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
512         goto berr;
513     if (!EVP_DigestFinal_ex(md, tmp, NULL))
514         goto berr;
515     ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0;
516     ctx->buf_off += md_size;
517     if (ret == 1) {
518         ctx->sigio = 0;
519         if (ctx->buf_len != ctx->buf_off) {
520             memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
521                     ctx->buf_len - ctx->buf_off);
522         }
523         ctx->buf_len -= ctx->buf_off;
524         ctx->buf_off = 0;
525     } else {
526         ctx->cont = 0;
527     }
528     return 1;
529  berr:
530     BIO_clear_retry_flags(b);
531     return 0;
532 }
533
534 static int block_out(BIO *b)
535 {
536     BIO_OK_CTX *ctx;
537     EVP_MD_CTX *md;
538     unsigned long tl;
539     const EVP_MD *digest;
540     int md_size;
541
542     ctx = BIO_get_data(b);
543     md = ctx->md;
544     digest = EVP_MD_CTX_md(md);
545     md_size = EVP_MD_size(digest);
546
547     tl = ctx->buf_len - OK_BLOCK_BLOCK;
548     ctx->buf[0] = (unsigned char)(tl >> 24);
549     ctx->buf[1] = (unsigned char)(tl >> 16);
550     ctx->buf[2] = (unsigned char)(tl >> 8);
551     ctx->buf[3] = (unsigned char)(tl);
552     if (!EVP_DigestUpdate(md,
553                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
554         goto berr;
555     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
556         goto berr;
557     ctx->buf_len += md_size;
558     ctx->blockout = 1;
559     return 1;
560  berr:
561     BIO_clear_retry_flags(b);
562     return 0;
563 }
564
565 static int block_in(BIO *b)
566 {
567     BIO_OK_CTX *ctx;
568     EVP_MD_CTX *md;
569     unsigned long tl = 0;
570     unsigned char tmp[EVP_MAX_MD_SIZE];
571     int md_size;
572
573     ctx = BIO_get_data(b);
574     md = ctx->md;
575     md_size = EVP_MD_size(EVP_MD_CTX_md(md));
576
577     assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
578     tl = ctx->buf[0];
579     tl <<= 8;
580     tl |= ctx->buf[1];
581     tl <<= 8;
582     tl |= ctx->buf[2];
583     tl <<= 8;
584     tl |= ctx->buf[3];
585
586     if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
587         return 1;
588
589     if (!EVP_DigestUpdate(md,
590                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
591         goto berr;
592     if (!EVP_DigestFinal_ex(md, tmp, NULL))
593         goto berr;
594     if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
595         /* there might be parts from next block lurking around ! */
596         ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
597         ctx->buf_len_save = ctx->buf_len;
598         ctx->buf_off = OK_BLOCK_BLOCK;
599         ctx->buf_len = tl + OK_BLOCK_BLOCK;
600         ctx->blockout = 1;
601     } else {
602         ctx->cont = 0;
603     }
604     return 1;
605  berr:
606     BIO_clear_retry_flags(b);
607     return 0;
608 }