/* crypto/rijndael/rijndael.h */

#ifndef HEADER_RIJNDAEL_H
#define HEADER_RIJNDAEL_H

#ifdef  __cplusplus
extern "C" {
#endif


#ifdef NO_RIJNDAEL
#error RIJNDAEL is disabled.
#endif

/*------------------------------------------------------------------------*/
/* Rijndael specific defines                                              */
/*------------------------------------------------------------------------*/
#define RIJNDAEL_ENCRYPT	1
#define RIJNDAEL_DECRYPT	0
#define RIJNDAEL_MAXROUNDS	14
#define RIJNDAEL_BITSPERBLOCK   128 /* Can not be changed */
#define RIJNDAEL_BYTESPERBLOCK  (RIJNDAEL_BITSPERBLOCK/8) 
#define RIJNDAEL_MAX_KEY_SIZE   64 /* # of ASCII char's needed to represent a key */
#define RIJNDAEL_MAX_IV_SIZE    (RIJNDAEL_BITSPERBLOCK/8) /* # bytes needed to represent an IV  */
#define RIJNDAEL_MAXKC		(256/32)
/*------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*/
/* Generic defines that may have happend in other spots but is needed     */
/*------------------------------------------------------------------------*/
#if !defined TRUE
#define     TRUE                  1
#endif

#if !defined FALSE
#define     FALSE                 0
#endif

#if !defined BYTE
typedef unsigned char   BYTE;
#endif

#if !defined byte
typedef unsigned char	byte;
#endif

#if !defined word8
typedef unsigned char	word8;	
#endif

#if !defined word16
typedef unsigned short	word16;	
#endif

#if !defined word32
typedef unsigned int	word32;
#endif
/*------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*/
/* Key structure used by Rijndael					  */
/*------------------------------------------------------------------------*/
typedef struct {
    BYTE  direction;                /* Key used for encrypting or decrypting? */
    int   keyLen;                   /* Length of the key  */
    char  keyMaterial[RIJNDAEL_MAX_KEY_SIZE+1];  /* Raw key data in ASCII, e.g., user input or KAT values */
        /*  The following parameters are algorithm dependent, replace or add as necessary  */
	int   ROUNDS;                   /* key-length-dependent number of rounds */
    int   blockLen;                 /* block length */
    word8 keySched[RIJNDAEL_MAXROUNDS+1][4][4];	/* key schedule		*/
} Rijndael_key;
/*------------------------------------------------------------------------*/


/*------------------------------------------------------------------------*/
/* Rijndael Public API							  */
/*------------------------------------------------------------------------*/
int Rijndael_makeKey(Rijndael_key *key, BYTE direction, int keyLen, char *keyMaterial);
  /*int Rijndael_Init(Rijndael_cipherInstance *cipher, char *IV);*/
#if !defined EVP_CIPHER_CTX
int Rijndael_Encrypt_CBC( void *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Encrypt_ECB( void *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Decrypt_CBC( void *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Decrypt_ECB( void *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
#else
int Rijndael_Encrypt_CBC( EVP_CIPHER_CTX *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Encrypt_ECB( EVP_CIPHER_CTX *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Decrypt_CBC( EVP_CIPHER_CTX *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
int Rijndael_Decrypt_ECB( EVP_CIPHER_CTX *ctx, BYTE *input, int inputLen, BYTE *outBuffer, int outputLen);
#endif
/*------------------------------------------------------------------------*/

/*------------------------------------------------------------------------*/
/* Internal functions used by API - do not call directly	  	  */
/*------------------------------------------------------------------------*/
int rijndaelKeySched(word8 k[RIJNDAEL_MAXKC][4], word8 rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS);
int rijndaelKeyEncToDec(word8 W[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS);
int rijndaelEncrypt(word8 a[RIJNDAEL_BYTESPERBLOCK], word8 b[RIJNDAEL_BYTESPERBLOCK], word8 rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS);
int rijndaelDecrypt(word8 a[RIJNDAEL_BYTESPERBLOCK], word8 b[RIJNDAEL_BYTESPERBLOCK], word8 rk[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS);
/*------------------------------------------------------------------------*/

#ifdef  __cplusplus
};
#endif

#endif

