#ifndef LLF_AES_H
#define LLF_AES_H

/*
* All the includes that are needed for code using this module to
* compile correctly should be #included here.
*/

#include "CE2_public.h"
#include "CE2_AES.h"

#ifdef __cplusplus
extern "C"
{
#endif

/*
*  Object name     :  LLF_AES.h
*  State           :  %state%
*  Creation date   :  23.02.2007
*  Last modified   :  %modify_time%
*/
/** @file
* \brief contains declarations of low level functions for 
*              AES (Advanced Encryption Standard).
*
*  \version LLF_AES.h#1:cinc:1
* \author Yermalayeu Ihar
* \remarks Copyright (C) 2006 by Discretix Technologies Ltd. All rights reserved.
*/

/************************ Defines *****************************/
/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Structs *****************************/
/************************ Public Variables ********************/
/************************ Public Functions ********************/

/**
****************************************************************
* Function Name: 
*  LLF_AES
*
* @param IVCounter_ptr [in] - This parameter is the buffer of the IV or 
*                  counters on mode CTR.
*                  In ECB, XCBC, CMAC mode this parameter is not used.
*                  In CBC and MAC modes this parameter should contain the IV values.
*                  In CTR mode this value should contain the init counter.
*                  In XCBC and CMAC modes it may be NULL
*  @param Key_ptr [in] - A pointer to the user's key buffer.
*  @param KeySize [in] - The size of the KEY used by the AES: 128, 192 or 256 bits, 
*            as defined in the enum.
*  @param EncryptDecryptFlag [in] - 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 OperationMode [in] - The operation mode: ECB, CBC, MAC, CTR, XCBC (PRF and 96), CMAC.
*  @param DataIn_ptr [in] - The pointer to the buffer of the input data to the AES. 
*               The pointer's value does not need to be word-aligned.
*  @param DataInSize [in] - The size of the input data (must be not 0 and must be multiple 
*               of 16 bytes, besides XCBC and CMAC).
*  @param DataOut_ptr [out] - The pointer to the buffer of the output data from the AES. 
*                The pointer does not need to be aligned to 32 bits. 
*                On XCBC and CMAC modes it may be NULL. 
*                The pointer's value does not need to be word-aligned.  
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*   - LLF_AES_MODULE_ERROR_BASE
*
* \brief \b 
* Description:
*  This function is used to operate the AES machine in one 
*  integrated operation.
*
*  \b 
* Algorithm:
* -# Initialize LibTomCrypt etc.
* -# Choose cipher mode 
* -# Make encryption/decryption corresponding selected mode.
***************************************************************/
CE2Error_t  LLF_AES(CE2_AES_IvCounter_t     IVCounter_ptr,       
  CE2_AES_Key_t           Key_ptr,                 
  CE2_AES_KeySize_t       KeySize,            
  CE2_AES_EncryptMode_t   EncryptDecryptFlag, 
  CE2_AES_OperationMode_t OperationMode ,           
  DxUint8_t                *DataIn_ptr,        
  DxUint32_t               DataInSize,         
  DxUint8_t                *DataOut_ptr );

/**
****************************************************************
* Function Name: 
*  LLF_AES_Wrap
*
* @param DataIn_ptr [in] - A pointer to plain text data to be wrapped
*               NOTE: Overlapping between the data input and data output buffer
*               is not allowed, except the inplace case that is legal . 			
* @param DataInLen [in]  - Length of data in bytes. DataLen must be multiple of 
*               8 bytes and  must be in range [16,  2^28].
* @param KeyData [in] - A pointer to  key data (key encryption key - KEK). 
* @param KeySize [in] - Enumerator variable, defines length of key.
* @param WrapDataOut_ptr [out] - A pointer to buffer for output of wrapped data.
* @param WrapDataLen_ptr [in/out] - A pointer to a buffer for input of size of 
*                    user passed buffer and for output actual 
*                    size of unwrapped data in bytes. Buffer size must 
*                    be not less than DataLen+CE2_AES_WRAP_BLOCK_SIZE_IN_BYTES.                         
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*   - LLF_AES_MODULE_ERROR_BASE
*
* \brief \b 
* Description:
*   The LLF_AES_Wrap function implements the following algorithm 
*   (rfc3394, Sept. 2002)
*  Inputs:  Plaintext DataIn, n 64-bit values {P1, P2, ..., Pn}, 
*   KeyData, K (the KEK).                
*  Outputs: Ciphertext, WrapDataOut (n+1) 64-bit values {C0, C1, ..., Cn}.
*
*  \b 
* Algorithm:
* -# Initialize LibTomCrypt etc.
* -# Calculate algorithm (rfc3394, Sept. 2002) 
* -# Output the results 
***************************************************************/
CE2Error_t LLF_AES_Wrap (
  DxUint8_t            *DataIn_ptr,      /*in*/   
  DxUint32_t            DataInLen,       /*in*/
  CE2_AES_Key_t        KeyData,         /*in*/
  CE2_AES_KeySize_t    KeySize,         /*in*/
  DxUint8_t            *WrapDataOut_ptr, /*out*/
  DxUint32_t           *WrapDataLen_ptr  /*in/out*/ );

/**
****************************************************************
* Function Name: 
*  LLF_AES_Unwrap
*
* @param WrapDataIn_ptr [in] - A pointer to wrapped data to be unwrapped 
*                   NOTE: Overlapping between the data input and 
*                   data output buffer is not allowed, except the 
*                   inplace case that is legal . 			
* @param WrapDataInLen [in] - Length of wrapped data in bytes. DataLen must be 
*                  multiple of 8 bytes and  must be in range [24, 2^29].
* @param KeyData [in] - A pointer to  key data (key encryption key - KEK). 
* @param KeySize [in] - Enumerator variable, defines length of key.
* @param DataOut_ptr [out] - A pointer to buffer for output of unwrapped data.
* @param DataOutLen_ptr [in/out] - A pointer to a buffer for input of size of user 
*                   passed buffer and for output of actual size of 
*                   unwrapped data in bytes. DataOutLen must be 
*                   multiple of 8 bytes and must be not less than 
*                   WrapDataInLen - CE2_AES_WRAP_BLOCK_SIZE_IN_BYTES.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*   - LLF_AES_MODULE_ERROR_BASE
*
* \brief \b 
* Description:
*   The LLF_AES_Unwrap function performs inverse AES_Wrap transformation 
*   and implements the following algorithm (rfc3394, Sept. 2002): 
*  Inputs:  Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn}, and
*   K  - key (the KEK).
*  Outputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}.
*
*  \b 
* Algorithm:
* -# Initialize LibTomCrypt etc.
* -# Calculate algorithm (rfc3394, Sept. 2002) 
* -# Output the results 
***************************************************************/
CE2Error_t LLF_AES_Unwrap(
  DxUint8_t            *WrapDataIn_ptr, /*in*/   
  DxUint32_t            WrapDataInLen,    /*in*/
  CE2_AES_Key_t        KeyData,        /*in*/
  CE2_AES_KeySize_t    KeySize,        /*in*/ 
  DxUint8_t            *DataOut_ptr,    /*out*/
  DxUint32_t           *DataOutLen_ptr     /*in/out*/ );

/**
****************************************************************
* Function Name: 
*  LLF_AES_GenerateTweakValue
*
* @param Tweak_dst [out] - This parameter is a return value from generator Tweak Value.
* @param Key_ptr [in] - This parameter is a key used for generator.
* @param KeySize [in] - Size of key.
* @param SectorNumber [in] - 64-bit sector number.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  Used for generating sector "tweak"
*
**  \b 
* Algorithm:
*  -# Verify input parameters;
*  -# 
***************************************************************/
CE2Error_t LLF_AES_GenerateTweakValue(CE2_AES_XTS_Tweak_t Tweak_dst,
									  CE2_AES_Key_t       Key_ptr,
									  CE2_AES_KeySize_t   KeySize,
									  CE2_AES_XTS_Tweak_t SectorNumber );
/**
****************************************************************
* Function Name: 
*  LLF_XTS_AES
*
* @param Tweak_ptr [in] - Pointer to buffer containing tweak value.
* @param Key_ptr [in] - Pointer to buffer containing AES key used for XTS-AES cipher.
* @param KeySize [in] - Size of AES key.
* @param EncryptDecryptFlag [in] - This flag specialize encrypt or decrypt operation.
* @param DataIn_ptr [in] - A pointer to input data.
* @param DataInSize [in] - Size of input data. It must be at least 16 bytes.
* @param DataOut_ptr [out] - A pointer to output data.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  This function is used to make XTS-AES operations;
*
*  \b 
* Algorithm:
*  -# 
***************************************************************/
CE2Error_t LLF_XTS_AES(CE2_AES_XTS_Tweak_t     Tweak_ptr,
                       CE2_AES_Key_t           Key_ptr,
                       CE2_AES_KeySize_t       KeySize,
                       CE2_AES_EncryptMode_t   EncryptDecryptFlag, 
                       DxUint8_t               *DataIn_ptr,        
                       DxUint32_t              DataInSize,         
                       DxUint8_t               *DataOut_ptr );

/**
****************************************************************
* Function Name: 
*  LLF_AES_CCM
*
* @param EncrDecrMode [in] - Enumerator variable defining operation mode (0 - encrypt; 1 - decrypt).
* @param CCM_Key [in] - A buffer, containing the AESCCM key passed by user (predefined size 128 bits).
* @param QFieldSize [in] - Byte-size of formatted field for writing significant bytes of the TextSizeQ 
*                          value. Valid values according to our implementation: [2,3,4]. 
* @param N_ptr [in] - A pointer to Nonce - unique value assigned to all data passed into CCM.
*                     Bytes order - big endian form (MSB is the first).
* @param SizeOfN [in] - The size of the user passed Nonce (in bytes). 	Valid values: 
*                       7 <= SizeOfN <= (15-QFieldSize). 
* @param ADataIn_ptr [in] - A pointer to the additional data buffer. The pointer does 
*                           not need to be aligned. On CSI input mode the pointer must be equal to 
*                           value (0xFFFFFFFC | DataInAlignment). 
* @param ADataInSize [in] - The size of the additional data in bytes;  
* @param TextDataIn_ptr [in] - A pointer to the input text data buffer (plain or cipher according to
*                              encrypt-decrypt mode). The pointer does not need to be aligned.
*                              On CSI input mode the pointer must be equal to value (0xFFFFFFFC | DataInAlignment). 
* @param TextDataInSize [in] - The size of the input text data in bytes;  
* @param TextDataOut_ptr [out] - The output text data pointer (cipher or plain text data). 
* @param TextDataOutSize [in] - The size of the output text data buffer. The size of buffer must be enough 
*                               for output the data:
*                                   - on Encrypt mode: TextDataOutSize >= TextDataInSize + SizeOfT.
*                                   - on Decrypt mode: TextDataOutSize >= TextDataInSize - SizeOfT.
* @param SizeOfT [in] - Size of AES-CCM MAC output T in bytes. Valid values: [4,6,8,10,12,14,16].   
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  This function is used to perform the AES_CCM operation in one integrated process.
*  The function preforms CCM algorithm according to NIST 800-38C.
*
*  \b 
* Algorithm:
*  -# Verify input parameters;
*  -# Call low level function LLF_AES_CCM().
***************************************************************/
CE2CIMPORT_C CE2Error_t LLF_AES_CCM(CE2_AES_EncryptMode_t  EncrDecrMode,
                                    CE2_AESCCM_Key_t       CCM_Key,
                                    DxUint8_t              QFieldSize,
                                    DxUint8_t             *N_ptr,
                                    DxUint8_t              SizeOfN,
                                    DxUint8_t             *ADataIn_ptr,
                                    DxUint32_t             ADataInSize,
                                    DxUint8_t             *TextDataIn_ptr,
                                    DxUint32_t             TextDataInSize,
                                    DxUint8_t             *TextDataOut_ptr,
                                    DxUint32_t             TextDataOutSize,
                                    DxUint8_t              SizeOfT);

/**
****************************************************************
* Function Name: 
*  LLF_AES_GCM
*
* @param Key_ptr [in] - This is a AES key used for CCM cipher.
* @param KeySize [in] - A size in bytes of the AES key.
* @param IV_ptr [in] - A pointer to buffer with IV (Initial Vector). 
*                      It maybe null if IVSize = 0.
* @param IVSize [in] - A size of IV buffer in bytes;
* @param AAD_ptr [in] - A pointer to AAD (Additional Authentication Data) buffer. 
*                       It maybe null if AADSize = 0.
* @param AADSize [in] - A size of AAD buffer in bytes.
* @param EncryptDecryptFlag [in] - This flag specialize encrypt or decrypt operation. 
* @param DataIn_ptr [in] - A pointer to input data.        
* @param DataInSize [in] - Size of input data. It must be multiple of 16 bytes.         
* @param DataOut_ptr [out] - A pointer to output data.
* @param Tag_ptr [out] - A pointer to output tag buffer. 
* @param TagSize_ptr [in/out] - A pointer to size of tag buffer.
*                               Note: maximal used size of tag is 16 bytes.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  This function is used to make GCM operations;
*
*  \b 
* Algorithm:
*  -# 
***************************************************************/
CE2Error_t LLF_AES_GCM(CE2_AES_Key_t         Key_ptr,
                       CE2_AES_KeySize_t     KeySize,
                       DxUint8_t             *IV_ptr, 
                       DxUint32_t            IVSize,
                       DxUint8_t             *AAD_ptr, 
                       DxUint32_t            AADSize,
                       CE2_AES_EncryptMode_t EncryptDecryptFlag, 
                       DxUint8_t             *DataIn_ptr,        
                       DxUint32_t            DataInSize,         
                       DxUint8_t             *DataOut_ptr,
                       DxUint8_t             *Tag_ptr, 
                       DxUint32_t            *TagSize_ptr);

#ifdef __cplusplus
}
#endif

#endif
