/* crypto/evp/bio_ok.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

/*
	From: Arne Ansper <arne@cyber.ee>

	Why BIO_f_reliable?

	I wrote function which took BIO* as argument, read data from it
	and processed it. Then I wanted to store the input file in 
	encrypted form. OK I pushed BIO_f_cipher to the BIO stack
	and everything was OK. BUT if user types wrong password 
	BIO_f_cipher outputs only garbage and my function crashes. Yes
	I can and I should fix my function, but BIO_f_cipher is 
	easy way to add encryption support to many existing applications
	and it's hard to debug and fix them all. 

	So I wanted another BIO which would catch the incorrect passwords and
	file damages which cause garbage on BIO_f_cipher's output. 

	The easy way is to push the BIO_f_md and save the checksum at 
	the end of the file. However there are several problems with this
	approach:

	1) you must somehow separate checksum from actual data. 
	2) you need lot's of memory when reading the file, because you 
	must read to the end of the file and verify the checksum before
	letting the application to read the data. 
	
	BIO_f_reliable tries to solve both problems, so that you can 
	read and write arbitrary long streams using only fixed amount
	of memory.

	BIO_f_reliable splits data stream into blocks. Each block is prefixed
	with it's length and suffixed with it's digest. So you need only 
	several Kbytes of memory to buffer single block before verifying 
	it's digest. 

	BIO_f_reliable goes further and adds several important capabilities:

	1) the digest of the block is computed over the whole stream 
	-- so nobody can rearrange the blocks or remove or replace them.

	2) to detect invalid passwords right at the start BIO_f_reliable 
	adds special prefix to the stream. In order to avoid known plain-text
	attacks this prefix is generated as follows:

		*) digest is initialized with random seed instead of 
		standardized one.
		*) same seed is written to output
		*) well-known text is then hashed and the output 
		of the digest is also written to output.

	reader can now read the seed from stream, hash the same string
	and then compare the digest output.

	Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I 
	initially wrote and tested this code on x86 machine and wrote the
	digests out in machine-dependent order :( There are people using
	this code and I cannot change this easily without making existing
	data files unreadable.

*/

#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/rand.h>

static int ok_write(BIO *h, const char *buf, int num);
static int ok_read(BIO *h, char *buf, int size);
static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int ok_new(BIO *h);
static int ok_free(BIO *data);
static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);

static void sig_out(BIO* b);
static void sig_in(BIO* b);
static void block_out(BIO* b);
static void block_in(BIO* b);
#define OK_BLOCK_SIZE	(1024*4)
#define OK_BLOCK_BLOCK	4
#define IOBS		(OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."

typedef struct ok_struct
	{
	size_t buf_len;
	size_t buf_off;
	size_t buf_len_save;
	size_t buf_off_save;
	int cont;		/* <= 0 when finished */
	int finished;
	EVP_MD_CTX md;
	int blockout;		/* output block is ready */ 
	int sigio;		/* must process signature */
	unsigned char buf[IOBS];
	} BIO_OK_CTX;

static BIO_METHOD methods_ok=
	{
	BIO_TYPE_CIPHER,"reliable",
	ok_write,
	ok_read,
	NULL, /* ok_puts, */
	NULL, /* ok_gets, */
	ok_ctrl,
	ok_new,
	ok_free,
	ok_callback_ctrl,
	};

BIO_METHOD *BIO_f_reliable(void)
	{
	return(&methods_ok);
	}

static int ok_new(BIO *bi)
	{
	BIO_OK_CTX *ctx;

	ctx=(BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
	if (ctx == NULL) return(0);

	ctx->buf_len=0;
	ctx->buf_off=0;
	ctx->buf_len_save=0;
	ctx->buf_off_save=0;
	ctx->cont=1;
	ctx->finished=0;
	ctx->blockout= 0;
	ctx->sigio=1;

	EVP_MD_CTX_init(&ctx->md);

	bi->init=0;
	bi->ptr=(char *)ctx;
	bi->flags=0;
	return(1);
	}

static int ok_free(BIO *a)
	{
	if (a == NULL) return(0);
	EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
	OPENSSL_cleanse(a->ptr,sizeof(BIO_OK_CTX));
	OPENSSL_free(a->ptr);
	a->ptr=NULL;
	a->init=0;
	a->flags=0;
	return(1);
	}
	
static int ok_read(BIO *b, char *out, int outl)
	{
	int ret=0,i,n;
	BIO_OK_CTX *ctx;

	if (out == NULL) return(0);
	ctx=(BIO_OK_CTX *)b->ptr;

	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);

	while(outl > 0)
		{

		/* copy clean bytes to output buffer */
		if (ctx->blockout)
			{
			i=ctx->buf_len-ctx->buf_off;
			if (i > outl) i=outl;
			memcpy(out,&(ctx->buf[ctx->buf_off]),i);
			ret+=i;
			out+=i;
			outl-=i;
			ctx->buf_off+=i;

			/* all clean bytes are out */
			if (ctx->buf_len == ctx->buf_off)
				{
				ctx->buf_off=0;

				/* copy start of the next block into proper place */
				if(ctx->buf_len_save- ctx->buf_off_save > 0)
					{
					ctx->buf_len= ctx->buf_len_save- ctx->buf_off_save;
					memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
							ctx->buf_len);
					}
				else
					{
					ctx->buf_len=0;
					}
				ctx->blockout= 0;
				}
			}
	
		/* output buffer full -- cancel */
		if (outl == 0) break;

		/* no clean bytes in buffer -- fill it */
		n=IOBS- ctx->buf_len;
		i=BIO_read(b->next_bio,&(ctx->buf[ctx->buf_len]),n);

		if (i <= 0) break;	/* nothing new */

		ctx->buf_len+= i;

		/* no signature yet -- check if we got one */
		if (ctx->sigio == 1) sig_in(b);

		/* signature ok -- check if we got block */
		if (ctx->sigio == 0) block_in(b);

		/* invalid block -- cancel */
		if (ctx->cont <= 0) break;

		}

	BIO_clear_retry_flags(b);
	BIO_copy_next_retry(b);
	return(ret);
	}

static int ok_write(BIO *b, const char *in, int inl)
	{
	int ret=0,n,i;
	BIO_OK_CTX *ctx;

	if (inl <= 0) return inl;

	ctx=(BIO_OK_CTX *)b->ptr;
	ret=inl;

	if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0);

	if(ctx->sigio) sig_out(b);

	do{
		BIO_clear_retry_flags(b);
		n=ctx->buf_len-ctx->buf_off;
		while (ctx->blockout && n > 0)
			{
			i=BIO_write(b->next_bio,&(ctx->buf[ctx->buf_off]),n);
			if (i <= 0)
				{
				BIO_copy_next_retry(b);
				if(!BIO_should_retry(b))
					ctx->cont= 0;
				return(i);
				}
			ctx->buf_off+=i;
			n-=i;
			}

		/* at this point all pending data has been written */
		ctx->blockout= 0;
		if (ctx->buf_len == ctx->buf_off)
			{
			ctx->buf_len=OK_BLOCK_BLOCK;
			ctx->buf_off=0;
			}
	
		if ((in == NULL) || (inl <= 0)) return(0);

		n= (inl+ ctx->buf_len > OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) ? 
			(int)(OK_BLOCK_SIZE+OK_BLOCK_BLOCK-ctx->buf_len) : inl;

		memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),(unsigned char *)in,n);
		ctx->buf_len+= n;
		inl-=n;
		in+=n;

		if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK)
			{
			block_out(b);
			}
	}while(inl > 0);

	BIO_clear_retry_flags(b);
	BIO_copy_next_retry(b);
	return(ret);
	}

static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
	{
	BIO_OK_CTX *ctx;
	EVP_MD *md;
	const EVP_MD **ppmd;
	long ret=1;
	int i;

	ctx=b->ptr;

	switch (cmd)
		{
	case BIO_CTRL_RESET:
		ctx->buf_len=0;
		ctx->buf_off=0;
		ctx->buf_len_save=0;
		ctx->buf_off_save=0;
		ctx->cont=1;
		ctx->finished=0;
		ctx->blockout= 0;
		ctx->sigio=1;
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_EOF:	/* More to read */
		if (ctx->cont <= 0)
			ret=1;
		else
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_PENDING: /* More to read in buffer */
	case BIO_CTRL_WPENDING: /* More to read in buffer */
		ret=ctx->blockout ? ctx->buf_len-ctx->buf_off : 0;
		if (ret <= 0)
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_CTRL_FLUSH:
		/* do a final write */
		if(ctx->blockout == 0)
			block_out(b);

		while (ctx->blockout)
			{
			i=ok_write(b,NULL,0);
			if (i < 0)
				{
				ret=i;
				break;
				}
			}

		ctx->finished=1;
		ctx->buf_off=ctx->buf_len=0;
		ctx->cont=(int)ret;
		
		/* Finally flush the underlying BIO */
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
	case BIO_C_DO_STATE_MACHINE:
		BIO_clear_retry_flags(b);
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		BIO_copy_next_retry(b);
		break;
	case BIO_CTRL_INFO:
		ret=(long)ctx->cont;
		break;
	case BIO_C_SET_MD:
		md=ptr;
		EVP_DigestInit_ex(&ctx->md, md, NULL);
		b->init=1;
		break;
	case BIO_C_GET_MD:
		if (b->init)
			{
			ppmd=ptr;
			*ppmd=ctx->md.digest;
			}
		else
			ret=0;
		break;
	default:
		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		break;
		}
	return(ret);
	}

static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
	{
	long ret=1;

	if (b->next_bio == NULL) return(0);
	switch (cmd)
		{
	default:
		ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
		break;
		}
	return(ret);
	}

static void longswap(void *_ptr, size_t len)
{	const union { long one; char little; } is_endian = {1};

	if (is_endian.little) {
		size_t i;
		unsigned char *p=_ptr,c;

		for(i= 0;i < len;i+= 4) {
			c=p[0],p[0]=p[3],p[3]=c;
			c=p[1],p[1]=p[2],p[2]=c;
		}
	}
}

static void sig_out(BIO* b)
	{
	BIO_OK_CTX *ctx;
	EVP_MD_CTX *md;

	ctx=b->ptr;
	md=&ctx->md;

	if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return;

	EVP_DigestInit_ex(md, md->digest, NULL);
	/* FIXME: there's absolutely no guarantee this makes any sense at all,
	 * particularly now EVP_MD_CTX has been restructured.
	 */
	RAND_pseudo_bytes(md->md_data, md->digest->md_size);
	memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
	longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
	ctx->buf_len+= md->digest->md_size;

	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
	ctx->buf_len+= md->digest->md_size;
	ctx->blockout= 1;
	ctx->sigio= 0;
	}

static void sig_in(BIO* b)
	{
	BIO_OK_CTX *ctx;
	EVP_MD_CTX *md;
	unsigned char tmp[EVP_MAX_MD_SIZE];
	int ret= 0;

	ctx=b->ptr;
	md=&ctx->md;

	if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return;

	EVP_DigestInit_ex(md, md->digest, NULL);
	memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
	longswap(md->md_data, md->digest->md_size);
	ctx->buf_off+= md->digest->md_size;

	EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN));
	EVP_DigestFinal_ex(md, tmp, NULL);
	ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
	ctx->buf_off+= md->digest->md_size;
	if(ret == 1)
		{
		ctx->sigio= 0;
		if(ctx->buf_len != ctx->buf_off)
			{
			memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), ctx->buf_len- ctx->buf_off);
			}
		ctx->buf_len-= ctx->buf_off;
		ctx->buf_off= 0;
		}
	else
		{
		ctx->cont= 0;
		}
	}

static void block_out(BIO* b)
	{
	BIO_OK_CTX *ctx;
	EVP_MD_CTX *md;
	unsigned long tl;

	ctx=b->ptr;
	md=&ctx->md;

	tl= ctx->buf_len- OK_BLOCK_BLOCK;
	ctx->buf[0]=(unsigned char)(tl>>24);
	ctx->buf[1]=(unsigned char)(tl>>16);
	ctx->buf[2]=(unsigned char)(tl>>8);
	ctx->buf[3]=(unsigned char)(tl);
	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
	EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL);
	ctx->buf_len+= md->digest->md_size;
	ctx->blockout= 1;
	}

static void block_in(BIO* b)
	{
	BIO_OK_CTX *ctx;
	EVP_MD_CTX *md;
	unsigned long tl= 0;
	unsigned char tmp[EVP_MAX_MD_SIZE];

	ctx=b->ptr;
	md=&ctx->md;

	assert(sizeof(tl)>=OK_BLOCK_BLOCK);	/* always true */
	tl =ctx->buf[0]; tl<<=8;
	tl|=ctx->buf[1]; tl<<=8;
	tl|=ctx->buf[2]; tl<<=8;
	tl|=ctx->buf[3];

	if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return;
 
	EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl);
	EVP_DigestFinal_ex(md, tmp, NULL);
	if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0)
		{
		/* there might be parts from next block lurking around ! */
		ctx->buf_off_save= tl+ OK_BLOCK_BLOCK+ md->digest->md_size;
		ctx->buf_len_save= ctx->buf_len;
		ctx->buf_off= OK_BLOCK_BLOCK;
		ctx->buf_len= tl+ OK_BLOCK_BLOCK;
		ctx->blockout= 1;
		}
	else
		{
		ctx->cont= 0;
		}
	}

