/*
* Creation date : Tues Mar 27 09:00:00 2007
* Last modified : %modify_time%
*/
/** @file
* \brief This file contains implementation of 
* C2 functions. 
*
* \version CE2_C2.c#1:csrc:1
* \author Yermalayeu Ihar
* \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
* All Rights reserved
*/

/************************ Include Files ***********************/
#include "CE2_C2.h"
#include "LLF_C2.h"

/************************ Defines *****************************/
/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Global Data *************************/
/************************ Private function prototype **********/
/************************ Private Functions *******************/
/************************ Public Functions ********************/

/**
****************************************************************
* Function Name: 
*  CE2_C2
*
*  @param Key_ptr [in] - A pointer to a buffer of the key to 
*                        operate the C2Cipher operations.
*  @param EncryptDecryptFlag [in] - A flag that determines what 
*                                   operation is performed - 
*                                   encrypting the data or 
*                                   decrypting the data.
*  @param OperationMode [in] - The operation mode of the C2Cipher
*                              (ECB or C-CBC);
*  @param DataIn_ptr [in] - A pointer to a buffer of the input 
*                           data that the C2Cipher operation will 
*                           be executed on.
*  @param DataInSize [in] - The size of the input data block in bytes
*                           Must be a multiple of 8 bytes.
*  @param DataOut_ptr [out] - A pointer to the output buffer that 
*                             shall contain the results.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*   - CE2_C2_CIPHER_INVALID_USER_CONTEXT_POINTER_ERROR
*       The user passed an illegal context pointer.
*   - CE2_C2_CIPHER_ILLEGAL_OPERATION_MODE_ERROR
*       The user passed an illegal operation mode.
*   - CE2_C2_CIPHER_INVALID_KEY_POINTER_ERROR
*       The user passed and invalid key pointer.
*   - CE2_C2_CIPHER_INVALID_ENCRYPT_MODE_ERROR
*       The user passed an illegal Encrypt/Decrypt mode.
*   - CE2_C2_CIPHER_DATA_IN_POINTER_INVALID_ERROR
*       The user passed an illegal input data pointer.
*   - CE2_C2_CIPHER_DATA_OUT_POINTER_INVALID_ERROR
*       The user passed an illegal output data pointer.
*   - CE2_C2_CIPHER_DATA_SIZE_ILLEGAL
*       The user passed a size of data that is not a multiple of 8.
*   - CE2_C2_CIPHER_DATA_OUT_DATA_IN_OVERLLAP_ERROR
*       A partially overlap between the input and the output buffers. 
*
* \brief \b 
* Description:
*  This function provides a C2 function for processing data.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_C2; 
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_C2(
      CE2_C2Cipher_Key_t           Key_ptr,            /*in*/     
      CE2_C2Cipher_EncryptMode_t   EncryptDecryptFlag, /*in*/
      CE2_C2Cipher_OperationMode_t OperationMode ,     /*in*/ 
      DxUint8_t                    *DataIn_ptr,        /*in*/ 
      DxUint32_t                   DataInSize,         /*in*/ 
      DxUint8_t                    *DataOut_ptr )     /*in/out*/
{
  if (Key_ptr == DX_NULL)
    return CE2_C2_CIPHER_INVALID_KEY_POINTER_ERROR;

  if (EncryptDecryptFlag < 0 || 
    EncryptDecryptFlag >= CE2_C2Cipher_NumOfEncryptModes)
    return CE2_C2_CIPHER_INVALID_ENCRYPT_MODE_ERROR;

  if (OperationMode < 0 || 
    OperationMode >= CE2_C2Cipher_NumOfOperationModes)
    return CE2_C2_CIPHER_ILLEGAL_OPERATION_MODE_ERROR;

  if (DataIn_ptr == DX_NULL)
    return CE2_C2_CIPHER_DATA_IN_POINTER_INVALID_ERROR;

  if (DataOut_ptr == DX_NULL)
    return CE2_C2_CIPHER_DATA_OUT_POINTER_INVALID_ERROR;

  if (DataInSize%CE2_C2_BLOCK_SIZE_IN_BYTES != 0)
    return CE2_C2_CIPHER_DATA_SIZE_ILLEGAL;

  if (((DataIn_ptr + DataInSize > DataOut_ptr) && (DataIn_ptr <= DataOut_ptr)) ||  
    ((DataIn_ptr < DataOut_ptr + DataInSize) && (DataIn_ptr >= DataOut_ptr)))
    return CE2_C2_CIPHER_DATA_OUT_DATA_IN_OVERLLAP_ERROR;

  return LLF_C2(Key_ptr, EncryptDecryptFlag, OperationMode ,
    DataIn_ptr, DataInSize, DataOut_ptr); 
} /* End of CE2_C2 */

/**
****************************************************************
* Function Name: 
*  CE2_C2_HASH
*
*  @param[in] DataIn_ptr - A pointer to the buffer that stores the data 
*                          to be hashed .
*  @param[in] DataInSize - The size of the data to be hashed in bytes. 
*  @param[out] HashResultBuff - A pointer to the target buffer where the 
*                               C2 HASH result stored in the context is 
*                               loaded to.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  This function performs all C2 HASH operations on one buffer of data.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_C2_HASH; 
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_C2_HASH(DxUint8_t              *DataIn_ptr,
                                 DxUint32_t              DataSize,
                                 CE2_C2HASH_Result_t    HashResultBuff)
{
  if (DataIn_ptr == DX_NULL && DataSize != 0)
    return CE2_C2_HASH_DATA_IN_PTR_ERROR;

  if (HashResultBuff == DX_NULL)
    return CE2_C2_HASH_RESULT_BUFFER_PTR_ERROR;

  return LLF_C2_HASH(DataIn_ptr, DataSize, HashResultBuff);
} /* End of CE2_C2_HASH */

/**
****************************************************************
* Function Name: 
*  CE2_C2_OneWayFunc
*
*  @param[in] Data1_ptr - The pointer to the buffer of the input Data1 
*                         used as encrypting key. The pointer need to 
*                         be aligned to 32 bits.
*  @param[in] Data2 - The pointer to the 64-bits buffer of the input 
*                     Data2. The pointer need to be aligned to 32 bits.
*  @param[in/out] DataOut_ptr - The pointer to the 64-bits buffer for 
*                               output data. The pointer need to be 
*                               aligned to 32 bits. 
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - error code:
*
* \brief \b 
* Description:
*  This function is used to perform C2 One Way operation on 64-bit block 
*  of data. The function executes the following major steps:
*  1. Executing the C2 ECB encrypt operation of Data2 with key = Data1 
*  by calling the low level function LLF_C2_ECB_Encrypt.
*  2. Performs XOR of encrypt output with Data2 and output this result.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_C2_OneWayFunc; 
***************************************************************/
CE2CIMPORT_C CE2Error_t  CE2_C2_OneWayFunc(CE2_C2Cipher_Key_t   Data1_ptr,     
                                        CE2_C2_BLOCK_BYTES_t Data2_ptr,
                                        CE2_C2_BLOCK_BYTES_t DataOut_ptr)
{
  if (Data1_ptr == DX_NULL)
    return CE2_C2_ONEWAYFUNC_DATA1_PTR_ERROR;

  if (Data2_ptr == DX_NULL)
    return CE2_C2_ONEWAYFUNC_DATA2_PTR_ERROR;

  if (DataOut_ptr == DX_NULL)
    return CE2_C2_ONEWAYFUNC_DATAOUT_PTR_ERROR;

  return LLF_C2_OneWayFunc(Data1_ptr, Data2_ptr, DataOut_ptr);
} /* End of CE2_C2_OneWayFunc */
