
#ifndef CRYS_AES_H
#define CRYS_AES_H

/*
 * All the includes that are needed for code using this module to
 * compile correctly should be #included here.
 */
#include "BaseTypes.h"
#include "CRYS_error.h"
#include "CRYS_Defs.h"
#include "LLF_AES_EngineInfo.h"

#ifdef __cplusplus
extern "C"
{
#endif

  /*
   *  Object % CRYS_AES.h    : %
   *  State           :  %state%
   *  Creation date   :  Wed Nov 17 16:42:30 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief This file contains all of the enums and definitions that are used for the 
   *         CRYS AES APIs, as well as the APIs themselves. 
   *
   *  \version CRYS_AES.h#1:incl:13
   *  \author adams
   *  \remarks Copyright (C) 2005 by Discretix Technologies Ltd.
   *           All Rights reserved
   */

/************************ Defines ******************************/

/** 
@brief - a definition describing the low level Engine type ( SW , Hardware , Etc )
*/

#define CRYS_AES_ENGINE_TYPE  LLF_AES_ENGINE_TYPE

/* The AES block size in words and in bytes */
#define CRYS_AES_BLOCK_SIZE_IN_WORDS 4
#define CRYS_AES_BLOCK_SIZE_IN_BYTES  (CRYS_AES_BLOCK_SIZE_IN_WORDS * sizeof(DxUint32_t))

/* The size of the IV or counter buffer */
#define CRYS_AES_IV_COUNTER_SIZE_IN_WORDS   CRYS_AES_BLOCK_SIZE_IN_WORDS
#define CRYS_AES_IV_COUNTER_SIZE_IN_BYTES  (CRYS_AES_IV_COUNTER_SIZE_IN_WORDS * sizeof(DxUint32_t))

/* The maximum size of the AES KEY in words and bytes */
#define CRYS_AES_KEY_MAX_SIZE_IN_WORDS 16
#define CRYS_AES_KEY_MAX_SIZE_IN_BYTES (CRYS_AES_KEY_MAX_SIZE_IN_WORDS * sizeof(DxUint32_t))

/* The AES_WRAP minimum data size in bytes  (one 64-bits block)  */
#define CRYS_AES_WRAP_DATA_MIN_SIZE_IN_BYTES   8

/* The AES_WRAP maximum data size in bytes:  2^28 */
#define CRYS_AES_WRAP_DATA_MAX_SIZE_IN_BYTES   0x10000000

/* The CRYS_AES_WRAP block size in bytes and in words */
#define CRYS_AES_WRAP_BLOCK_SIZE_IN_BYTES 8
#define CRYS_AES_WRAP_BLOCK_SIZE_IN_WORDS  (CRYS_AES_WRAP_BLOCK_SIZE_IN_BYTES / sizeof(DxUint32_t))


/************************ Enums ********************************/

/* Enum defining the user's key size argument */
typedef enum
{
   CRYS_AES_Key128BitSize   = 0,
   CRYS_AES_Key192BitSize   = 1,
   CRYS_AES_Key256BitSize   = 2,
   CRYS_AES_Key512BitSize   = 3,

   CRYS_AES_KeySizeNumOfOptions
   
}CRYS_AES_KeySize_t;  

/* Enum defining the Encrypt or Decrypt operation mode */
typedef enum 
{
   CRYS_AES_Encrypt = 0,
   CRYS_AES_Decrypt = 1,
   
   CRYS_AES_EncryptNumOfOptions

}CRYS_AES_EncryptMode_t;

/* Enum defining the AES operation mode */
typedef enum
{
   CRYS_AES_ECB_mode          = 0,
   CRYS_AES_CBC_mode          = 1,
   CRYS_AES_MAC_mode          = 2,
   CRYS_AES_CTR_mode          = 3,
   CRYS_AES_XCBC_MAC_mode     = 4,
   CRYS_AES_CMAC_mode         = 5,
   CRYS_AES_XTS_mode          = 6,
   
   CRYS_AES_NumOfModes

}CRYS_AES_OperationMode_t;

/************************ Typedefs  ****************************/

/* Defines the IV counter buffer  - 16 bytes array */
typedef DxUint8_t CRYS_AES_IvCounter_t[CRYS_AES_IV_COUNTER_SIZE_IN_BYTES];

/* Define the XTS Tweak value type - 16 bytes array */
typedef  CRYS_AES_IvCounter_t  CRYS_AES_XTS_Tweak_t;

/* Defines the AES key buffer */
typedef DxUint8_t CRYS_AES_Key_t[CRYS_AES_KEY_MAX_SIZE_IN_BYTES];

/* Defines the AES MAC result maximum size buffer */
typedef DxUint8_t CRYS_AES_MAX_MAC_RESULT_t[CRYS_AES_IV_COUNTER_SIZE_IN_BYTES];


/************************ context Structs  ******************************/

/* The context data-base used by the AES functions on the low level */

typedef struct  
{ 
   /* Fields that are common to all platforms and operation modes */

   /* AESContextIV contains: on CTR mode - Counter, on XTS mode - Tweak, on othet modes - IV */ 
   DxUint32_t                 AESContextIV[CRYS_AES_IV_COUNTER_SIZE_IN_WORDS];
   /* AES context working Key (on XTS mode - Key1). It's max size is 256 bit = 512/2*/
   DxUint32_t                 AESContextKey[CRYS_AES_KEY_MAX_SIZE_IN_WORDS / 2];
   CRYS_AES_KeySize_t         AESContextKeySize;
   /* Flags */
   CRYS_AES_EncryptMode_t     EncryptDecryptFlag;
   CRYS_AES_OperationMode_t   OperationMode;  
   DxUint8_t                  is_secret_key;   
     
   /* Fields that are used on XCBC, CMAC modes with all platforms */ 
     
   DxUint32_t  NotAddBlocks; /* flag prohibiting additional data blocks receiving */   
   /* last block size and value */
   DxUint32_t  lastBlockSize;   
   DxUint32_t  lastBlock[CRYS_AES_BLOCK_SIZE_IN_WORDS];
   /* previous IV */
   DxUint32_t  previousIV[CRYS_AES_BLOCK_SIZE_IN_WORDS];
   
   /* Specific data for XCBC, CMAC, XTS modes */
   union{
	   struct{
		   /* derived keys */
		   DxUint32_t  derivedKey1[CRYS_AES_BLOCK_SIZE_IN_WORDS];
		   DxUint32_t  derivedKey2[CRYS_AES_BLOCK_SIZE_IN_WORDS];
		   DxUint32_t  derivedKey3[CRYS_AES_BLOCK_SIZE_IN_WORDS];
	   } XCBC_CMAC_Data;

	   struct{
		   /* AES-XTS Key2. It's max size is 256 bit = 512/2 */
		   DxUint32_t  AES_XTS_Key2[CRYS_AES_KEY_MAX_SIZE_IN_WORDS / 2];
		   DxUint32_t  TempX[CRYS_AES_BLOCK_SIZE_IN_WORDS];
	   } XTS_Data;
   } SpecificData;
   
   /* Data specific to the platform we are working on - include from LLF */
   #include "LLF_AES_context_def.h"
   
   /* Dummy buffer - added for right AES encrypting of the context data.
      Note: This block must be alwais at the end of the context.  */
   DxUint8_t DummyBufAESBlockSize[CRYS_DEFS_DUMMY_AES_BLOCK_SIZE];
     
}AESContext_t; 


/* The user's context prototype - the argument type that will be passed by the user 
   to the APIs called by him */
typedef struct CRYS_AESUserContext_t 
{
   DxUint32_t valid_tag;
   DxUint32_t AES_iv;/* for use of the AES CBC mode of Encryption and Decryption of the context in CCM */ 
   DxUint32_t   OperationMode;  /* for using in non secured parts of programms */
   DxUint8_t  context_buff[ sizeof(AESContext_t) ]; 
}CRYS_AESUserContext_t;

/************************ Public Variables **********************/


/************************ Public Functions **********************/



/****************************************************************************************************/
/**
 * @brief This function is used to perform the AES operation in one integrated process.
 *
 *        The actual macros, that will be used by the user for calling this function, are described 
 *        in CRYS_AES.h file.
 *
 *        The input-output parameters of the function are the following:
 *
 * @param[in] ContextID_ptr - A pointer to the AES context buffer that is allocated by the user 
 *                            and is used for the AES machine operation.
 * @param[in] IVCounter_ptr - A buffer containing an initial value: IV, Counter or Tweak according 
 *                            to operation mode:
 *                            - on ECB, XCBC, CMAC mode this parameter is not used and may be NULL,
 *                            - on CBC and MAC modes it contains the IV value,
 *                            - on CTR mode it contains the init counter,
 *                            - on XTS mode it contains the initial tweak value - 128-bit consecutive number 
 *                              of data unit (in little endian).
 * @param[in] Key_ptr  -  A pointer to the user's key buffer.
 * @param[in] KeySize  -  An enum parameter, defines size of used key (128, 192, 256 bits).
 * @param[in] EncryptDecryptFlag - A flag specifying whether the AES should perform an Encrypt operation (0) 
 *                                 or a Decrypt operation (1). In XCBC and CMAC modes it must be 0.
 * @param[in] OperationMode - The operation mode: ECB, CBC, MAC, CTR, XCBC (PRF and 96), CMAC, XTS.
 * @param[in] is_secret_key - A parameter specifying whether to use a secret key (1) 
 *                            or to use a key defined by the user (0). 
 * @param[in] DataIn_ptr - A pointer to the buffer of the input data to the AES. The pointer does 
 *                         not need to be aligned. On CSI input mode the pointer must be equal to
 *                         value (0xFFFFFFFC | DataInAlignment). 
 *
 * @param[in] DataInSize - A size of the input data must be not 0 and must be multiple of 16 bytes, 
 *                         excluding the XCBC, CMAC modes where it may be also 0 and not multiple of 16 bytes.  
 *
 * @param[in] DataInSize - The size of the input data, it must be:
 *                         - on ECB,CBC,CTR, MAC modes must be not 0 and must be a multiple of 16 bytes,
 *                         - on XCBC and CMAC modes must be not 0,
 *                         - on XTS mode must be multiple of 16 bytes or must be not less than 17 bytes.
 * @param[out] DataOut_ptr - A pointer to the buffer of the output data from the AES. The pointer  does not 
 *                             need to be aligned. On CSI output mode the pointer must be equal to
 *                             value (0xFFFFFFFC | DataOutAlignment).
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a value defined in CRYS_AES_error.h
 *
 *     NOTES: 1. Temporarily it is not allowed, that both the Input and the Output simultaneously 
 *               were on CSI mode.
 *            2. Temporarily the CSI input or output are not allowed on XCBC, CMAC and XTS modes.    
 *
 */
CEXPORT_C CRYSError_t  CRYS_AES( CRYS_AES_IvCounter_t       IVCounter_ptr,       
		                        CRYS_AES_Key_t             Key_ptr,
										CRYS_AES_KeySize_t         KeySize,            
		                        CRYS_AES_EncryptMode_t     EncryptDecryptFlag, 
		                        CRYS_AES_OperationMode_t   OperationMode ,      
		                        DxUint8_t                  is_secret_key,       
		                        DxUint8_t                  *DataIn_ptr,        
		                        DxUint32_t                 DataInSize,         
		                        DxUint8_t                  *DataOut_ptr );     


#ifdef __cplusplus
}
#endif

#endif
