
  /*
   *  Object %name    : %
   *  State           :  %state%
   *  Creation date   :  Wed Nov 17 17:25:55 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *
   *  \version CRYS_AES.c#1:csrc:6
   *  \author adams
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */



/************* Include Files ****************/

/* .............. CRYS level includes ................. */

#include "DX_VOS_Mem.h"
#include "CRYS.h"
#include "CRYS_AES_error.h"
#include "dx_hw_defs.h"
#include "crys_host_op_code.h"

/* .............. LLF level includes .................. */

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

/************************ MACROS ***************************************/

/************************ Global Data ***********************************/
const dx_hw_pub_dispatcher_ptr DX_HW_Dispatcher_ptr = (dx_hw_pub_dispatcher_ptr)DxHwDispatcherPhysicalAddr;

/************* Private function prototype *******************************/


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


/****************************************************************************************************/
/** 
 * @brief This function is used to initialize the AES machine or SW structures.
 *        To perform the AES operations this should be the first function called.
 *
 *        The actual macros, that will be used by the user for calling this function, are described 
 *        in CRYS_AES.h file.
 *
 *        The function executes the following major steps:
 *
 *        1. Validates all of the inputs of the function. If one of the received 
 *           parameters is not valid it shall return an error:
 *        2. Decrypts the received context to the working context after capturing 
 *           the working context by calling the CRYS_CCM_GetContext() call.
 *        3. Initializes the working context by the parameters used in other AES operations.
 *           On some modes  calculates derived keys (for XCBC,CMAC)or Tweak value (for XTS).
 *        4. Encrypts the working context and stores it to the users received context. 
 *           Releases the working context by calling the CRYS_CCM_EncryptAndReleaseContext call.
 *        5. Exits the handler with the OK code.
 *
 *
 * @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, 512 bits):
 *                        On XCBC mode allowed 128 bit size only, on XTS - 256 or 512 bit, on other modes <= 256 bit.
 * @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 Encrypt.
 * @param[in] OperationMode - The operation mode: ECB, CBC, MAC, CTR, XCBC (PRF and 96), CMAC.
 * @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). 
 *
 * @return CRYSError_t - On success the value CRYS_OK is returned, and on failure - a value from CRYS_AES_error.h
 */

CEXPORT_C CRYSError_t  _DX_AES_Init( 
						   CRYS_AESUserContext_t   *ContextID_ptr,
                           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 )
{
 
   return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_INIT_OP_CODE, 7,
							    /* PARAMETERS: */
								ContextID_ptr, 
								IVCounter_ptr,
								Key_ptr, KeySize,
								EncryptDecryptFlag,
								OperationMode,
								is_secret_key );
   
}/* END OF _DX_AES_Init */   
                         


/****************************************************************************************************/
/** 
 * @brief This function is used to operate a block of data on the SW or on AES machine.
 *        This function should be called after the appropriate CRYS AES init function 
 *        (according to used AES operation mode).
 *
 *        The function executes the following major steps:
 *
 *        1.Checks the validity of all inputs of the function.
 *          If one of the received parameters is not valid it shall return an error.
 *        2.Decrypts the received context to the working context after 
 *          capturing the working context by calling the CRYS_CCM_GetContext() call.
 *        3.Executes the AES operation on the software or hardware by calling the 
 *          low level AES function LLF_AES_Block or LLF_AES_XTS_Block.
 *        4.Encrypts the working context and stores it to the users received context. 
 *          Releases the working context by calling the CRYS_CCM_ReleaseContext call.
 *        5.Exits the handler with the OK code.  
 *      
 *
 * @param[in] ContextID_ptr - A pointer to the AES context buffer allocated by the user that
 *                            is used for the AES machine operation. This should be the same context that was
 *                            used on the previous call of this session.
 *
 * @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 following cases:
 *                             - in CTR, XCBC, CMAC modes the size of the last block may be also 0 and not 
 *                               multiple of 16 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). On all MAC modes (MAC,XCBC, CMAC) CSI 
 *                             output is not allowed. 
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a
 *                       value MODULE_* CRYS_DES_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_Block( CRYS_AESUserContext_t   *ContextID_ptr,   
                                        DxUint8_t               *DataIn_ptr,     
                                        DxUint32_t               DataInSize,     
                                        DxUint8_t               *DataOut_ptr )
 {                              
   
		return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_BLOCK_CODE, 4,
   									 /* PARAMETERS: */
									 ContextID_ptr,
									 DataIn_ptr, DataInSize,
									 DataOut_ptr );
    
}/* END OF CRYS_AES_Block */ 

/****************************************************************************************************/
/** 
 * @brief This function is used as finish operation of AES on XCBC, CMAC, CBC and other modes 
 *        besides XTS mode.
 *
 *        The function must be called after AES_Block operations on CRYS_AES_XCBC_MAC_mode and 
 *        CRYS_AES_CMAC_mode. On other modes it may be called also instead the CRYS_AES_Free
 *        function. 
 *
 *        The actual macros, that will be used by the user for calling this function on different modes, 
 *        are described in CRYS_AES.h file.
 *
 *        The function performs  specific operations for last blocks of data and puts out the result 
 *        authentication value on XCBC, CMAC and MAC modes. After all operations the function 
 *        cleanes secure sensitive data from context as follows:  
 *        
 *        1. Checks the validation of all of the inputs of the function.
 *           If one of the received parameters is not valid it shall return an error.
 *        2. If AES operation mode is not one of XCBC, CMAC or MAC goto step 5. 
 *        3. Decrypts the received context to the working context  by calling the 
 *           CRYS_CCM_GetContext function.
 *        4. If operation mode is XCBC or CMAC then the function calls the LLF_AES_Finish function.
 *        5. Outputs the MAC result and cleans working context.
 *        6. Exits   
 *      
 *
 * @param[in] ContextID_ptr - A pointer to the AES context buffer allocated by the user that
 *                            should be the same context that was used on the previous call
 *                            of this session.
 * @param[out] MacResult  - A pointer to the buffer for output MAC data result. This parameter 
 *                          is obligated for XCBC_MAC and CMAC modes, for MAC mode it is optional. 
 *                          The pointer does not need to be aligned. On other modes it is not needed and 
 *                          may be NULL. 
 * @return CRYSError_t    - On success CRYS_OK is returned, on failure - a value defined in CRYS_AES_error.h.
 */
 CEXPORT_C CRYSError_t  _DX_AES_Finish( CRYS_AESUserContext_t     *ContextID_ptr,  
                                        CRYS_AES_MAX_MAC_RESULT_t  MacResult )
 {                              
  
	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_FINISH_OP_CODE, 2,
	   							 /* PARAMETERS: */
								 ContextID_ptr,
								 MacResult );
 
}/* END OF _DX_AES_Finish */ 


/****************************************************************************************************/
/**
 * @brief This function is used to end the AES operation session on all modes besides XCBC,CMAC,XTS.
 *        It is the last function called on the AES operation on appropriate modes .
 *
 *
 *        The function executes the following major steps:
 *
 *        1. Checks the validity of all of the inputs of the function. 
 *           If one of the received parameters is not valid it shall return an error.
 *           The major checkers that are run over the received parameters:
 *           - verifying that the context pointer is not DX_NULL (*ContextID_ptr). 
 *        2. Clears the users context.
 *        3. Exits the handler with the OK code.
 *      
 *
 * @param[in] ContextID_ptr - a pointer to the AES context buffer allocated by the user that
 *                       is used for the AES machine operation. this should be the same context that was
 *                       used on the previous call of this session.
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure - a value defined in CRYS_AES_error.h
 */
CEXPORT_C CRYSError_t  CRYS_AES_Free(CRYS_AESUserContext_t  *ContextID_ptr )
{
   /* FUNCTION DECLERATIONS */

   /* The return error identifier */
   CRYSError_t Error;

   /* FUNCTION LOGIC */
 
   /* ............... local initializations .............................. */
   /* -------------------------------------------------------------------- */
   
   /* initializing the Error to O.K */
   Error = CRYS_OK;

   /* ............... checking the parameters validity ................... */
   /* -------------------------------------------------------------------- */

   /* if the users context ID pointer is DX_NULL return an error */
   if( ContextID_ptr == DX_NULL )
   {
      Error = CRYS_AES_INVALID_USER_CONTEXT_POINTER_ERROR;
      goto End;
   } 
   
   /* .............. clearing the users context .......................... */
   /* -------------------------------------------------------------------- */
   
   DX_VOS_MemSet6( ContextID_ptr , 0 , sizeof(CRYS_AESUserContext_t) );   

   /* ................. end of function .................................. */
   /* -------------------------------------------------------------------- */
    
   End:
   
   return Error;

}/* END OF CRYS_AES_Free */

/****************************************************************************************************/
/**
 * @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 - The size of the input data, it must be:
 *                         - on ECB,CBC,MAC modes must be not 0 and must be a multiple of 16 bytes,
 *                         - on CTR, XCBC and CMAC modes must be not 0,
 *                         - on XTS mode must be or multiple of 16 bytes (not 0), or 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). On all MAC modes (MAC,XCBC, CMAC) CSI 
 *                             output is not allowed.
 *
 * @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  _DX_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 )
{    

    return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_OP_CODE, 9, 
			   				     /* PARAMETERS: */
								 IVCounter_ptr,
								 Key_ptr, KeySize,
								 EncryptDecryptFlag,
								 OperationMode,
								 is_secret_key,
								 DataIn_ptr, DataInSize,
								 DataOut_ptr );

}/* END OF _DX_AES */   

