Fixes for Win32 build.
[openssl.git] / crypto / evp / bio_ok.c
1 /* crypto/evp/bio_ok.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 /*
60         From: Arne Ansper <arne@cyber.ee>
61
62         Why BIO_f_reliable?
63
64         I wrote function which took BIO* as argument, read data from it
65         and processed it. Then I wanted to store the input file in 
66         encrypted form. OK I pushed BIO_f_cipher to the BIO stack
67         and everything was OK. BUT if user types wrong password 
68         BIO_f_cipher outputs only garbage and my function crashes. Yes
69         I can and I should fix my function, but BIO_f_cipher is 
70         easy way to add encryption support to many existing applications
71         and it's hard to debug and fix them all. 
72
73         So I wanted another BIO which would catch the incorrect passwords and
74         file damages which cause garbage on BIO_f_cipher's output. 
75
76         The easy way is to push the BIO_f_md and save the checksum at 
77         the end of the file. However there are several problems with this
78         approach:
79
80         1) you must somehow separate checksum from actual data. 
81         2) you need lot's of memory when reading the file, because you 
82         must read to the end of the file and verify the checksum before
83         letting the application to read the data. 
84         
85         BIO_f_reliable tries to solve both problems, so that you can 
86         read and write arbitrary long streams using only fixed amount
87         of memory.
88
89         BIO_f_reliable splits data stream into blocks. Each block is prefixed
90         with it's length and suffixed with it's digest. So you need only 
91         several Kbytes of memory to buffer single block before verifying 
92         it's digest. 
93
94         BIO_f_reliable goes further and adds several important capabilities:
95
96         1) the digest of the block is computed over the whole stream 
97         -- so nobody can rearrange the blocks or remove or replace them.
98
99         2) to detect invalid passwords right at the start BIO_f_reliable 
100         adds special prefix to the stream. In order to avoid known plain-text
101         attacks this prefix is generated as follows:
102
103                 *) digest is initialized with random seed instead of 
104                 standardized one.
105                 *) same seed is written to ouput
106                 *) well-known text is then hashed and the output 
107                 of the digest is also written to output.
108
109         reader can now read the seed from stream, hash the same string
110         and then compare the digest output.
111
112         Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I 
113         initially wrote and tested this code on x86 machine and wrote the
114         digests out in machine-dependent order :( There are people using
115         this code and I cannot change this easily without making existing
116         data files unreadable.
117
118 */
119
120 #include <stdio.h>
121 #include <errno.h>
122 #include "cryptlib.h"
123 #include <openssl/buffer.h>
124 #include <openssl/bio.h>
125 #include <openssl/evp.h>
126 #include <openssl/rand.h>
127
128 static int ok_write(BIO *h, const char *buf, int num);
129 static int ok_read(BIO *h, char *buf, int size);
130 static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
131 static int ok_new(BIO *h);
132 static int ok_free(BIO *data);
133 static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
134
135 static void sig_out(BIO* b);
136 static void sig_in(BIO* b);
137 static void block_out(BIO* b);
138 static void block_in(BIO* b);
139 #define OK_BLOCK_SIZE   (1024*4)
140 #define OK_BLOCK_BLOCK  4
141 #define IOBS            (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
142 #define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
143
144 #ifndef L_ENDIAN
145 #define swapem(x) \
146         ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
147                              (((unsigned long int)(x) & 0x0000ff00U) <<  8) | \
148                              (((unsigned long int)(x) & 0x00ff0000U) >>  8) | \
149                              (((unsigned long int)(x) & 0xff000000U) >> 24)))
150 #else
151 #define swapem(x) (x)
152 #endif
153
154 typedef struct ok_struct
155         {
156         int buf_len;
157         int buf_off;
158         int buf_len_save;
159         int buf_off_save;
160         int cont;               /* <= 0 when finished */
161         int finished;
162         EVP_MD_CTX md;
163         int blockout;           /* output block is ready */ 
164         int sigio;              /* must process signature */
165         char buf[IOBS];
166         } BIO_OK_CTX;
167
168 static BIO_METHOD methods_ok=
169         {
170         BIO_TYPE_CIPHER,"reliable",
171         ok_write,
172         ok_read,
173         NULL, /* ok_puts, */
174         NULL, /* ok_gets, */
175         ok_ctrl,
176         ok_new,
177         ok_free,
178         ok_callback_ctrl,
179         };
180
181 BIO_METHOD *BIO_f_reliable(void)
182         {
183         return(&methods_ok);
184         }
185
186 static int ok_new(BIO *bi)
187         {
188         BIO_OK_CTX *ctx;
189
190         ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
191         if (ctx == NULL) return(0);
192
193         ctx->buf_len=0;
194         ctx->buf_off=0;
195         ctx->buf_len_save=0;
196         ctx->buf_off_save=0;
197         ctx->cont=1;
198         ctx->finished=0;
199         ctx->blockout= 0;
200         ctx->sigio=1;
201
202         bi->init=0;
203         bi->ptr=(char *)ctx;
204         bi->flags=0;
205         return(1);
206         }
207
208 static int ok_free(BIO *a)
209         {
210         if (a == NULL) return(0);
211         memset(a->ptr,0,sizeof(BIO_OK_CTX));
212         OPENSSL_free(a->ptr);
213         a->ptr=NULL;
214         a->init=0;
215         a->flags=0;
216         return(1);
217         }
218         
219 static int ok_read(BIO *b, char *out, int outl)
220         {
221         int ret=0,i,n;
222         BIO_OK_CTX *ctx;
223
224         if (out == NULL) return(0);
225         ctx=(BIO_OK_CTX *)b->ptr;
226
227         if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
228
229         while(outl > 0)
230                 {
231
232                 /* copy clean bytes to output buffer */
233                 if (ctx->blockout)
234                         {
235                         i=ctx->buf_len-ctx->buf_off;
236                         if (i > outl) i=outl;
237                         memcpy(out,&(ctx->buf[ctx->buf_off]),i);
238                         ret+=i;
239                         out+=i;
240                         outl-=i;
241                         ctx->buf_off+=i;
242
243                         /* all clean bytes are out */
244                         if (ctx->buf_len == ctx->buf_off)
245                                 {
246                                 ctx->buf_off=0;
247
248                                 /* copy start of the next block into proper place */
249                                 if(ctx->buf_len_save- ctx->buf_off_save > 0)
250                                         {
251                                         ctx->buf_len= ctx->buf_len_save- ctx->buf_off_save;
252                                         memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
253                                                         ctx->buf_len);
254                                         }
255                                 else
256                                         {
257                                         ctx->buf_len=0;
258                                         }
259                                 ctx->blockout= 0;
260                                 }
261                         }
262         
263                 /* output buffer full -- cancel */
264                 if (outl == 0) break;
265
266                 /* no clean bytes in buffer -- fill it */
267                 n=IOBS- ctx->buf_len;
268                 i=BIO_read(b->next_bio,&(ctx->buf[ctx->buf_len]),n);
269
270                 if (i <= 0) break;      /* nothing new */
271
272                 ctx->buf_len+= i;
273
274                 /* no signature yet -- check if we got one */
275                 if (ctx->sigio == 1) sig_in(b);
276
277                 /* signature ok -- check if we got block */
278                 if (ctx->sigio == 0) block_in(b);
279
280                 /* invalid block -- cancel */
281                 if (ctx->cont <= 0) break;
282
283                 }
284
285         BIO_clear_retry_flags(b);
286         BIO_copy_next_retry(b);
287         return(ret);
288         }
289
290 static int ok_write(BIO *b, const char *in, int inl)
291         {
292         int ret=0,n,i;
293         BIO_OK_CTX *ctx;
294
295         ctx=(BIO_OK_CTX *)b->ptr;
296         ret=inl;
297
298         if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);
299
300         if(ctx->sigio) sig_out(b);
301
302         do{
303                 BIO_clear_retry_flags(b);
304                 n=ctx->buf_len-ctx->buf_off;
305                 while (ctx->blockout && n > 0)
306                         {
307                         i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
308                         if (i <= 0)
309                                 {
310                                 BIO_copy_next_retry(b);
311                                 if(!BIO_should_retry(b))
312                                         ctx->cont= 0;
313                                 return(i);
314                                 }
315                         ctx->buf_off+=i;
316                         n-=i;
317                         }
318
319                 /* at this point all pending data has been written */
320                 ctx->blockout= 0;
321                 if (ctx->buf_len == ctx->buf_off)
322                         {
323                         ctx->buf_len=OK_BLOCK_BLOCK;
324                         ctx->buf_off=0;
325                         }
326         
327                 if ((in == NULL) || (inl <= 0)) return(0);
328
329                 n= (inl+ ctx->buf_len > OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) ? 
330                                 OK_BLOCK_SIZE+ OK_BLOCK_BLOCK- ctx->buf_len : inl;
331
332                 memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),(unsigned char *)in,n);
333                 ctx->buf_len+= n;
334                 inl-=n;
335                 in+=n;
336
337                 if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
338                         {
339                         block_out(b);
340                         }
341         }while(inl > 0);
342
343         BIO_clear_retry_flags(b);
344         BIO_copy_next_retry(b);
345         return(ret);
346         }
347
348 static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
349         {
350         BIO_OK_CTX *ctx;
351         EVP_MD *md;
352         const EVP_MD **ppmd;
353         long ret=1;
354         int i;
355
356         ctx=(BIO_OK_CTX *)b->ptr;
357
358         switch (cmd)
359                 {
360         case BIO_CTRL_RESET:
361                 ctx->buf_len=0;
362                 ctx->buf_off=0;
363                 ctx->buf_len_save=0;
364                 ctx->buf_off_save=0;
365                 ctx->cont=1;
366                 ctx->finished=0;
367                 ctx->blockout= 0;
368                 ctx->sigio=1;
369                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
370                 break;
371         case BIO_CTRL_EOF:      /* More to read */
372                 if (ctx->cont <= 0)
373                         ret=1;
374                 else
375                         ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
376                 break;
377         case BIO_CTRL_PENDING: /* More to read in buffer */
378         case BIO_CTRL_WPENDING: /* More to read in buffer */
379                 ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0;
380                 if (ret <= 0)
381                         ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
382                 break;
383         case BIO_CTRL_FLUSH:
384                 /* do a final write */
385                 if(ctx->blockout == 0)
386                         block_out(b);
387
388                 while (ctx->blockout)
389                         {
390                         i=ok_write(b,NULL,0);
391                         if (i < 0)
392                                 {
393                                 ret=i;
394                                 break;
395                                 }
396                         }
397
398                 ctx->finished=1;
399                 ctx->buf_off=ctx->buf_len=0;
400                 ctx->cont=(int)ret;
401                 
402                 /* Finally flush the underlying BIO */
403                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
404                 break;
405         case BIO_C_DO_STATE_MACHINE:
406                 BIO_clear_retry_flags(b);
407                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
408                 BIO_copy_next_retry(b);
409                 break;
410         case BIO_CTRL_INFO:
411                 ret=(long)ctx->cont;
412                 break;
413         case BIO_C_SET_MD:
414                 md=(EVP_MD *)ptr;
415                 EVP_DigestInit(&(ctx->md),md);
416                 b->init=1;
417                 break;
418         case BIO_C_GET_MD:
419                 if (b->init)
420                         {
421                         ppmd=(const EVP_MD **)ptr;
422                         *ppmd=ctx->md.digest;
423                         }
424                 else
425                         ret=0;
426                 break;
427         default:
428                 ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
429                 break;
430                 }
431         return(ret);
432         }
433
434 static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
435         {
436         long ret=1;
437
438         if (b->next_bio == NULL) return(0);
439         switch (cmd)
440                 {
441         default:
442                 ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
443                 break;
444                 }
445         return(ret);
446         }
447
448 static void longswap(void *_ptr, int len)
449 {
450 #ifndef L_ENDIAN
451         int i;
452         char *ptr=_ptr;
453
454         for(i= 0;i < len;i+= 4){
455                 *((unsigned long *)&(ptr[i]))= swapem(*((unsigned long *)&(ptr[i])));
456         }
457 #endif
458 }
459
460 static void sig_out(BIO* b)
461         {
462         BIO_OK_CTX *ctx;
463         EVP_MD_CTX *md;
464
465         ctx=(BIO_OK_CTX *)b->ptr;
466         md= &(ctx->md);
467
468         if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;
469
470         EVP_DigestInit(md, md->digest);
471         RAND_pseudo_bytes(&(md->md.base[0]), md->digest->md_size);
472         memcpy(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]), md->digest->md_size);
473         longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
474         ctx->buf_len+= md->digest->md_size;
475
476         EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
477         md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]));
478         ctx->buf_len+= md->digest->md_size;
479         ctx->blockout= 1;
480         ctx->sigio= 0;
481         }
482
483 static void 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
490         ctx=(BIO_OK_CTX *)b->ptr;
491         md= &(ctx->md);
492
493         if(ctx->buf_len- ctx->buf_off < 2* md->digest->md_size) return;
494
495         EVP_DigestInit(md, md->digest);
496         memcpy(&(md->md.base[0]), &(ctx->buf[ctx->buf_off]), md->digest->md_size);
497         longswap(&(md->md.base[0]), md->digest->md_size);
498         ctx->buf_off+= md->digest->md_size;
499
500         EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
501         md->digest->final(tmp, &(md->md.base[0]));
502         ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
503         ctx->buf_off+= md->digest->md_size;
504         if(ret == 1)
505                 {
506                 ctx->sigio= 0;
507                 if(ctx->buf_len != ctx->buf_off)
508                         {
509                         memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len- ctx->buf_off);
510                         }
511                 ctx->buf_len-= ctx->buf_off;
512                 ctx->buf_off= 0;
513                 }
514         else
515                 {
516                 ctx->cont= 0;
517                 }
518         }
519
520 static void block_out(BIO* b)
521         {
522         BIO_OK_CTX *ctx;
523         EVP_MD_CTX *md;
524         unsigned long tl;
525
526         ctx=(BIO_OK_CTX *)b->ptr;
527         md= &(ctx->md);
528
529         tl= ctx->buf_len- OK_BLOCK_BLOCK;
530         tl= swapem(tl);
531         memcpy(ctx->buf, &tl, OK_BLOCK_BLOCK);
532         tl= swapem(tl);
533         EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
534         md->digest->final(&(ctx->buf[ctx->buf_len]), &(md->md.base[0]));
535         ctx->buf_len+= md->digest->md_size;
536         ctx->blockout= 1;
537         }
538
539 static void block_in(BIO* b)
540         {
541         BIO_OK_CTX *ctx;
542         EVP_MD_CTX *md;
543         long tl= 0;
544         unsigned char tmp[EVP_MAX_MD_SIZE];
545
546         ctx=(BIO_OK_CTX *)b->ptr;
547         md= &(ctx->md);
548
549         memcpy(&tl, ctx->buf, OK_BLOCK_BLOCK);
550         tl= swapem(tl);
551         if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
552  
553         EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
554         md->digest->final(tmp, &(md->md.base[0]));
555         if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
556                 {
557                 /* there might be parts from next block lurking around ! */
558                 ctx->buf_off_save= tl+ OK_BLOCK_BLOCK+ md->digest->md_size;
559                 ctx->buf_len_save= ctx->buf_len;
560                 ctx->buf_off= OK_BLOCK_BLOCK;
561                 ctx->buf_len= tl+ OK_BLOCK_BLOCK;
562                 ctx->blockout= 1;
563                 }
564         else
565                 {
566                 ctx->cont= 0;
567                 }
568         }
569