/* crypto/bf/bf_enc.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.]
 */

#include <openssl/blowfish.h>
#include "bf_locl.h"

/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
 * (From LECTURE NOTES IN COIMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
 * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
 */

#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
to modify the code.
#endif

void BF_encrypt(BF_LONG *data, BF_KEY *key)
	{
#ifndef BF_PTR2
	register BF_LONG l,r,*p,*s;

	p=key->P;
	s= &(key->S[0]);
	l=data[0];
	r=data[1];

	l^=p[0];
	BF_ENC(r,l,s,p[ 1]);
	BF_ENC(l,r,s,p[ 2]);
	BF_ENC(r,l,s,p[ 3]);
	BF_ENC(l,r,s,p[ 4]);
	BF_ENC(r,l,s,p[ 5]);
	BF_ENC(l,r,s,p[ 6]);
	BF_ENC(r,l,s,p[ 7]);
	BF_ENC(l,r,s,p[ 8]);
	BF_ENC(r,l,s,p[ 9]);
	BF_ENC(l,r,s,p[10]);
	BF_ENC(r,l,s,p[11]);
	BF_ENC(l,r,s,p[12]);
	BF_ENC(r,l,s,p[13]);
	BF_ENC(l,r,s,p[14]);
	BF_ENC(r,l,s,p[15]);
	BF_ENC(l,r,s,p[16]);
#if BF_ROUNDS == 20
	BF_ENC(r,l,s,p[17]);
	BF_ENC(l,r,s,p[18]);
	BF_ENC(r,l,s,p[19]);
	BF_ENC(l,r,s,p[20]);
#endif
	r^=p[BF_ROUNDS+1];

	data[1]=l&0xffffffffL;
	data[0]=r&0xffffffffL;
#else
	register BF_LONG l,r,t,*k;

	l=data[0];
	r=data[1];
	k=(BF_LONG*)key;

	l^=k[0];
	BF_ENC(r,l,k, 1);
	BF_ENC(l,r,k, 2);
	BF_ENC(r,l,k, 3);
	BF_ENC(l,r,k, 4);
	BF_ENC(r,l,k, 5);
	BF_ENC(l,r,k, 6);
	BF_ENC(r,l,k, 7);
	BF_ENC(l,r,k, 8);
	BF_ENC(r,l,k, 9);
	BF_ENC(l,r,k,10);
	BF_ENC(r,l,k,11);
	BF_ENC(l,r,k,12);
	BF_ENC(r,l,k,13);
	BF_ENC(l,r,k,14);
	BF_ENC(r,l,k,15);
	BF_ENC(l,r,k,16);
#if BF_ROUNDS == 20
	BF_ENC(r,l,k,17);
	BF_ENC(l,r,k,18);
	BF_ENC(r,l,k,19);
	BF_ENC(l,r,k,20);
#endif
	r^=k[BF_ROUNDS+1];

	data[1]=l&0xffffffffL;
	data[0]=r&0xffffffffL;
#endif
	}

#ifndef BF_DEFAULT_OPTIONS

void BF_decrypt(BF_LONG *data, BF_KEY *key)
	{
#ifndef BF_PTR2
	register BF_LONG l,r,*p,*s;

	p=key->P;
	s= &(key->S[0]);
	l=data[0];
	r=data[1];

	l^=p[BF_ROUNDS+1];
#if BF_ROUNDS == 20
	BF_ENC(r,l,s,p[20]);
	BF_ENC(l,r,s,p[19]);
	BF_ENC(r,l,s,p[18]);
	BF_ENC(l,r,s,p[17]);
#endif
	BF_ENC(r,l,s,p[16]);
	BF_ENC(l,r,s,p[15]);
	BF_ENC(r,l,s,p[14]);
	BF_ENC(l,r,s,p[13]);
	BF_ENC(r,l,s,p[12]);
	BF_ENC(l,r,s,p[11]);
	BF_ENC(r,l,s,p[10]);
	BF_ENC(l,r,s,p[ 9]);
	BF_ENC(r,l,s,p[ 8]);
	BF_ENC(l,r,s,p[ 7]);
	BF_ENC(r,l,s,p[ 6]);
	BF_ENC(l,r,s,p[ 5]);
	BF_ENC(r,l,s,p[ 4]);
	BF_ENC(l,r,s,p[ 3]);
	BF_ENC(r,l,s,p[ 2]);
	BF_ENC(l,r,s,p[ 1]);
	r^=p[0];

	data[1]=l&0xffffffffL;
	data[0]=r&0xffffffffL;
#else
	register BF_LONG l,r,t,*k;

	l=data[0];
	r=data[1];
	k=(BF_LONG *)key;

	l^=k[BF_ROUNDS+1];
#if BF_ROUNDS == 20
	BF_ENC(r,l,k,20);
	BF_ENC(l,r,k,19);
	BF_ENC(r,l,k,18);
	BF_ENC(l,r,k,17);
#endif
	BF_ENC(r,l,k,16);
	BF_ENC(l,r,k,15);
	BF_ENC(r,l,k,14);
	BF_ENC(l,r,k,13);
	BF_ENC(r,l,k,12);
	BF_ENC(l,r,k,11);
	BF_ENC(r,l,k,10);
	BF_ENC(l,r,k, 9);
	BF_ENC(r,l,k, 8);
	BF_ENC(l,r,k, 7);
	BF_ENC(r,l,k, 6);
	BF_ENC(l,r,k, 5);
	BF_ENC(r,l,k, 4);
	BF_ENC(l,r,k, 3);
	BF_ENC(r,l,k, 2);
	BF_ENC(l,r,k, 1);
	r^=k[0];

	data[1]=l&0xffffffffL;
	data[0]=r&0xffffffffL;
#endif
	}

void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
	     BF_KEY *ks, unsigned char *iv, int encrypt)
	{
	register BF_LONG tin0,tin1;
	register BF_LONG tout0,tout1,xor0,xor1;
	register long l=length;
	BF_LONG tin[2];

	if (encrypt)
		{
		n2l(iv,tout0);
		n2l(iv,tout1);
		iv-=8;
		for (l-=8; l>=0; l-=8)
			{
			n2l(in,tin0);
			n2l(in,tin1);
			tin0^=tout0;
			tin1^=tout1;
			tin[0]=tin0;
			tin[1]=tin1;
			BF_encrypt(tin,ks);
			tout0=tin[0];
			tout1=tin[1];
			l2n(tout0,out);
			l2n(tout1,out);
			}
		if (l != -8)
			{
			n2ln(in,tin0,tin1,l+8);
			tin0^=tout0;
			tin1^=tout1;
			tin[0]=tin0;
			tin[1]=tin1;
			BF_encrypt(tin,ks);
			tout0=tin[0];
			tout1=tin[1];
			l2n(tout0,out);
			l2n(tout1,out);
			}
		l2n(tout0,iv);
		l2n(tout1,iv);
		}
	else
		{
		n2l(iv,xor0);
		n2l(iv,xor1);
		iv-=8;
		for (l-=8; l>=0; l-=8)
			{
			n2l(in,tin0);
			n2l(in,tin1);
			tin[0]=tin0;
			tin[1]=tin1;
			BF_decrypt(tin,ks);
			tout0=tin[0]^xor0;
			tout1=tin[1]^xor1;
			l2n(tout0,out);
			l2n(tout1,out);
			xor0=tin0;
			xor1=tin1;
			}
		if (l != -8)
			{
			n2l(in,tin0);
			n2l(in,tin1);
			tin[0]=tin0;
			tin[1]=tin1;
			BF_decrypt(tin,ks);
			tout0=tin[0]^xor0;
			tout1=tin[1]^xor1;
			l2nn(tout0,tout1,out,l+8);
			xor0=tin0;
			xor1=tin1;
			}
		l2n(xor0,iv);
		l2n(xor1,iv);
		}
	tin0=tin1=tout0=tout1=xor0=xor1=0;
	tin[0]=tin[1]=0;
	}

#endif
