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