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