/*-
 * $Header: /smsa/bsd:include/dea_crypt.h:bsd  1.1  $
 * $Source: /smsa/bsd:include/dea_crypt.h: $
 *
 * Copyright (C) 1990 Acorn Computers Ltd
 *
 * $Log:	dea_crypt.h,v $
 * Revision 1.1  90/01/11  20:08:39  john
 * Modified dea interface for crypt
 * 
 * $Source: /smsa/bsd:include/dea_crypt.h: $
 *	Implementation of the DEA algorithm.  This
 *	is a byte/bit sex independent implementation of
 *	the (Australian) DEA encryption algorithm.  It
 *	encrypts or decrypts units of 8 bytes.
 */
#ifndef __dea_crypt_h
#define __dea_crypt_h

/*
 * The following constants define the direction of encryption or
 * decryption.
 */
#define DEA_DIRMASK (1 << 0)
#define DEA_ENCRYPT (0*DEA_DIRMASK)	/* Encrypt */
#define DEA_DECRYPT (1*DEA_DIRMASK)	/* Decrypt */

/*
 * The following types must be defined to appropriate
 * types of the particular machine.  On machines where
 * characters are not 8 bits in size CARD8 must be
 * capable of holding 8 bits (at least) and the input
 * block will have to be expanded into the BLOCK64
 * type.  These definitions are protected so that they
 * can be removed if there are already appropriately
 * defined (some X11 include files do this for example).
 */
#ifndef _CARD32
typedef unsigned long CARD32;
#define _CARD32 CARD32
#endif
#ifndef _CARD24
typedef unsigned long CARD24;
#define _CARD24 CARD24
#endif
#ifndef _CARD8
typedef unsigned char CARD8;
#define _CARD8 CARD8
#endif

/*
 * The following data structure contains the standard
 * values for the encrypt/decrypt data.  The structure is
 * read only.
 */
extern const struct {
	CARD8	IP[64];
	CARD8	E[48];
	CARD8	S[8][32];
	CARD8	P[32];
	CARD8	PC1[56];
	CARD8	PC2[48];
	CARD8	KS[16];
} _dea_data;

/*
 * The following types are machine independant - although
 * see the comments above about expanding an input (64 bit)
 * block to a BLOCK64.  Notice that a BLOCK48 consists of
 * two 24 bit values.
 */
typedef CARD8 BLOCK64[8];
typedef struct {
	CARD32	b0;
	CARD32	b1;
} CARD64;
typedef struct {
	CARD24	b0;
	CARD24	b1;
} CARD48;

/*
 * Throughout this code bit 1 is the high order bit of
 * the first n bit unit, bit n is the high order bit
 * of the second, and bit (n-1) is the low order bit
 * of the first.
 */

/*
 * Basic algorithms
 */
/*
 *	expand an input CARD32 value into a BLOCK48
 *	structure using the supplied expand array.  The
 *	E array says where each bit of the output comes
 *	from.  Only the relevant 48 bits of the result
 *	are defined.
 */
extern CARD48 _dea_expand(CARD32 input, const CARD8 E[48]);

/*
 *	Use the DEA S block selection functions to generate
 *	a 32 bit value from the input 48 bit value.  The
 *	selection function consists of 64 nibble (4 bit)
 *	values for each of the 8 input (6 bit) blocks organised
 *	as four rows of 16 nibbles.
 */
extern CARD32 _dea_select(CARD48 input, const CARD8 S[8][32]);

/*
 *	Permute the value according to the P array,
 *	returning a permuted 32 bit value.
 */
extern CARD32 _dea_permute(CARD32 input, const CARD8 P[32]);

/*
 *	Perform an input permutation on the given
 *	block, producing a CARD64 value.  Take account
 *	of byte sex issues here by translating 8 CARD8
 *	values into one CARD64 value.
 */
extern CARD64 _dea_inperm(BLOCK64 input, const CARD8 IP[64]);

/*
 *	Perform an output permutation - the inverse of the
 *	input permutation.  Convert a CARD64 back into a
 *	BLOCK64.  The IP argument is as passed to _dea_inperm.
 */
extern void _dea_outperm(BLOCK64 result, CARD64 input, const CARD8 IP[64]);

/*
 * Key schedule routines.
 *
 *	The algorithm adopted is not to form the complete
 *	key schedule initially, but to form it in line as
 *	required.  This is slower, but uses less space.
 */

/*
 *	Perform one dea function on an expanded (48 bit
 *	block) - combining it with the key schedule
 *	derived from the input CARD64 value (this represents
 *	56 bits, 28 in each CARD32 value).  The key schedule
 *	must be selected (under the control of PC2) and also
 *	rotated.  The rotate is a cumulative rotate left
 *	(towards the lower numbered bit).
 */
extern CARD48 _dea_function(CARD48 input, CARD64 key, const CARD8 PC2[48], int rotate);

/*
 *	Form a 56 (2*28) bit key by permuting the input
 *	value (64 bits including 8 parity bits as a
 *	normal 8 byte block).
 */
extern CARD64 _dea_key(BLOCK64 input, const CARD8 PC1[56]);

/*
 * Generic veneer function.
 */

/*
 *	Encrypt one block using the given S, P, E, IP
 *	values and the key, (derived from PC1) PC2 and
 *	KS values.
 */
extern void _dea_encrypt(
	BLOCK64		io,
	CARD64		key,
	int		decrypt,
	const CARD8	IP[64],
	const CARD8	E[48],
	const CARD8	PC2[48],
	const CARD8	KS[16],
	const CARD8	S[8][32],
	const CARD8	P[32]
);

/*
 * Interface functions.
 *
 *	The following functions provide the more normal
 *	interfaces to the required facilities.
 */

/*
 *	Encrypt or decrypt the given bytes.  The number of
 *	bytes must be a multiple of 8.  Encryption or decryption
 *	is performed according to the mode flag.
 */
extern void _dea_ecb(void *data, unsigned datalen, const BLOCK64 key, int mode);

/*
 *	Encrypt or decrypt the given bytes in cipher block chaining
 *	mode.  The number of bytes must be a multiple of 8.
 *	Encryption or decryption is performed according to the mode flag.
 */
extern void _dea_cbc(void *data, unsigned datalen, const BLOCK64 key, int mode, BLOCK64 ivec);

/*
 *	Equivalent to the UNIX crypt interface - calculates
 *	an encrypted password given a password (including
 *	salt information).  Notice that only 7 bits are used
 *	from each character, that these are the LOW order
 *	seven bits and that they are placed in bits 1-7 (etc)
 *	in big endian order.  Ie bit 8 is left as 0, and the
 *	other bits are shifted up one.
 */
extern char *_dea_crypt(const char *password, const char *salt);

#endif /* __dea_crypt_h */
