/*
 * 16 Round Blowfish Production Implementation
 * This implementation: (c) 1999 Andreas Steinmetz
 * Blowfish Home Page: http://www.counterpane.com/
 *
 * License:
 * This code is in the public domain under the GNU public license
 * for use with the virtual private network daemon (vpnd).
 * The copyright holder will however retain the copyright.
 * In addition to vpnd this code is put in the public domain
 * for all GPL/LGPL based open source software products.
 * For all other software products please contact astmail@yahoo.com
 * for a license agreement. There is no guarantee for the fitness
 * and usability of this code for any purpose. The author takes no
 * responsibility for any damages caused by the use of this code.
 * Distribution and use of this code is explicitly granted provided
 * that the above header is not modified and the above conditions
 * are met.
 *
 * This implementation is tuned for speed.
 *
 * Note that the implementation is processor independent.
 * It does not depend on any run time library and
 * should be 64 bit clean.
 *
 * Data sizes:
 *
 * data block for en/decryption		WORD08[8]
 * en/decryption key			WORD08[1] to WORD08[72]
 * en/decryption key schedule		WORD32[1042]
 *
 * WORD08 means an unsigned word of 8 bits length
 * WORD32 means an unsigned word of at least 32 bits length
 *
 * Mode of operation:
 *
 * 1. Choose 1 to 72 bytes as a key
 * 2. Create the key schedule from the key
 * 3. Encrypt or decrypt 8 bytes with the key schedule
 */

/* definitions */

#define BLOWFISH_BLOCKSIZE	8
#define BLOWFISH_SCHEDULESIZE	1042
#define BLOWFISH_SCHEDULE(a)	WORD32 a[BLOWFISH_SCHEDULESIZE]
#define BLOWFISH_MAXKEY		72
#define BLOWFISH_KEYGRAIN	1

/*  encryption modes */

#define blowfish_encrypt_ecb(data,length,schedule)         encrypt_ecb(data,length,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule))
#ifndef BLOWFISH_NO_DECRYPT
#define blowfish_decrypt_ecb(data,length,schedule)         decrypt_ecb(data,length,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_decrypt),(void *)(schedule))
#endif
#define blowfish_encrypt_cbc(data,length,schedule,iv,mode) encrypt_cbc(data,length,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule),iv,mode)
#ifndef BLOWFISH_NO_DECRYPT
#define blowfish_decrypt_cbc(data,length,schedule,iv,mode) decrypt_cbc(data,length,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_decrypt),(void *)(schedule),iv,mode)
#endif
#define blowfish_encrypt_cfb(data,width,total,schedule,iv) encrypt_cfb(data,width,total,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule),iv)
#define blowfish_decrypt_cfb(data,width,total,schedule,iv) decrypt_cfb(data,width,total,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule),iv)
#define blowfish_encrypt_ofb(data,width,total,schedule,iv) crypt_ofb(data,width,total,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule),iv)
#define blowfish_decrypt_ofb(data,width,total,schedule,iv) crypt_ofb(data,width,total,(void (CRYPTOCALL *)(WORD08 *,void *))(blowfish_encrypt),(void *)(schedule),iv)

/* function prototypes */

extern void FASTCALL blowfish_key_schedule(WORD08 *key,WORD32 length,WORD32 *schedule);
extern void CRYPTOCALL blowfish_encrypt(WORD08 *data,WORD32 *schedule);
#ifndef BLOWFISH_NO_DECRYPT
extern void CRYPTOCALL blowfish_decrypt(WORD08 *data,WORD32 *schedule);
#endif
