#ifndef CE2_HASH_H
#define CE2_HASH_H

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

#ifdef __cplusplus
extern "C"
{
#endif

  /*
   *  Object %CE2_HASH.h    : %
   *  State           :  %state%
   *  Creation date   :  Sun Nov 28 20:51:23 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief This file contains all of the enums and definitions 
   *         that are used for the CE2 HASH APIs, as well as the APIs themselves
   *
   *  \version CE2_HASH.h#1:incl:13
   *  \author adams
   *  \remarks Copyright (C) 2005 by Discretix Technologies Ltd.
   *           All Rights reserved
   */
 
/************************ Defines ******************************/

/* The hash result in words 
#define CE2_HASH_RESULT_SIZE_IN_WORDS 5*/
/* The maximum hash result is 512 bits for SHA512 */
#define CE2_HASH_RESULT_SIZE_IN_WORDS	16

/* The MD5 digest result size in bytes */
#define CE2_HASH_MD5_DIGEST_SIZE_IN_BYTES 16

/* The MD5 digest result size in words */
#define CE2_HASH_MD5_DIGEST_SIZE_IN_WORDS 4

/* The SHA-1 digest result size in bytes */
#define CE2_HASH_SHA1_DIGEST_SIZE_IN_BYTES 20

/* The SHA-1 digest result size in words */
#define CE2_HASH_SHA1_DIGEST_SIZE_IN_WORDS 5

/* The SHA-256 digest result size in bytes */
#define CE2_HASH_SHA224_DIGEST_SIZE_IN_WORDS 7

/* The SHA-256 digest result size in bytes */
#define CE2_HASH_SHA256_DIGEST_SIZE_IN_WORDS 8

/* The SHA-384 digest result size in bytes */
#define CE2_HASH_SHA384_DIGEST_SIZE_IN_WORDS 12

/* The SHA-512 digest result size in bytes */
#define CE2_HASH_SHA512_DIGEST_SIZE_IN_WORDS 16

/* The SHA-256 digest result size in bytes */
#define CE2_HASH_SHA224_DIGEST_SIZE_IN_BYTES 28

/* The SHA-256 digest result size in bytes */
#define CE2_HASH_SHA256_DIGEST_SIZE_IN_BYTES 32

/* The SHA-384 digest result size in bytes */
#define CE2_HASH_SHA384_DIGEST_SIZE_IN_BYTES 48

/* The SHA-512 digest result size in bytes */
#define CE2_HASH_SHA512_DIGEST_SIZE_IN_BYTES 64 

/* The SHA1 hash block size in words */
#define CE2_HASH_BLOCK_SIZE_IN_WORDS 16

/* The SHA1 hash block size in bytes */
#define CE2_HASH_BLOCK_SIZE_IN_BYTES 64

/* The SHA2 hash block size in words */
#define CE2_HASH_SHA2_BLOCK_SIZE_IN_WORDS	32

/* The SHA2 hash block size in bytes */
#define CE2_HASH_SHA2_BLOCK_SIZE_IN_BYTES	128



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

/* Defines the enum for the HASH operation mode */
typedef enum
{
   CE2_HASH_SHA1_mode 		= 0,
   CE2_HASH_SHA224_mode	= 1,
   CE2_HASH_SHA256_mode	= 2,
   CE2_HASH_SHA384_mode	= 3,
   CE2_HASH_SHA512_mode	= 4,
   CE2_HASH_MD5_mode		= 5,

   CE2_HASH_NumOfModes

}CE2_HASH_OperationMode_t;   

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

/* Defines the IV counter buffer */
typedef DxUint32_t CE2_HASH_Result_t[CE2_HASH_RESULT_SIZE_IN_WORDS];

/************************ Structures ****************************/

/* The context data base used by the HASH functions on the low level */
typedef struct
{
	CE2_HASH_Result_t        HASH_Result;
	CE2_HASH_OperationMode_t OperationMode;

	/* A block buffer used for all cases where the update data size 
	is not aligned to a block size - we cannot load the block to the hardware 
	therefore the first block is always loaded from this buffer 
	The size of the block is aligned to the SHA-2, since it requires bigger buffer */
	DxUint32_t DataFromThePreviousUpdateBuff[CE2_HASH_SHA2_BLOCK_SIZE_IN_WORDS]; 
	DxUint64_t Length;
	DxUint32_t CurLength;
}CE2_HASHContext_t; 

/* The user's context prototype - the argument type that will be passed by the user 
   to the APIs called by him */
typedef struct CE2_HASHUserContext_t
{
	DxUint32_t valid_tag;
	DxUint8_t  context_buff[sizeof(CE2_HASHContext_t)];
}CE2_HASHUserContext_t;

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


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

/**
****************************************************************
* Function Name: 
*  CE2_HASH_Init
*
* Inputs:
* @param ContextID_ptr [in] - A pointer to the HASH context buffer allocated by the user 
*                      that is used for the HASH machine operation.
* @param OperationMode [in] - The operation mode:
*                      CE2_HASH_SHA1_mode, CE2_HASH_SHA224_mode, CE2_HASH_SHA256_mode,
*                      CE2_HASH_SHA384_mode, CE2_HASH_SHA512_mode, CE2_HASH_MD5_mode.
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_HASH_INVALID_USER_CONTEXT_POINTER_ERROR
*   - CE2_HASH_ILLEGAL_HASH_OP_MODE_ERROR
*
* \brief \b
* Description:
*  This function initializes the HASH machine on the CE2 level.
* This function allocates and initializes the HASH Context.
* The function receives as input a pointer to store the context handle to the HASH Context,
* and it initializes the HASH Context with the cryptographic attributes that are needed for 
* the HASH block operation (initializes H's value for the HASH algorithm).
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_HASH_Init
*     to initilize HASH context with using inputted data.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_HASH_Init(CE2_HASHUserContext_t		*ContextID_ptr,
									  CE2_HASH_OperationMode_t	OperationMode);

/**
****************************************************************
* Function Name: 
*  CE2_HASH_Update
*
* Inputs:
* @param ContextID_ptr [in] - A pointer to the HASH context buffer allocated by the user 
*                      that is used for the HASH machine operation.
* @param DataIn_ptr [in] - A pointer to the buffer that stores the data to be hashed;
* @param DataSize [in] - The size of the data to be hashed in bytes;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_HASH_INVALID_USER_CONTEXT_POINTER_ERROR
*   - CE2_HASH_INVALID_DATA_IN_PTR_ERROR
*
* \brief \b
* Description:
*  This function process a block of data via the HASH Hardware/Software.
* The function receives as input an handle to the HASH Context that was previously 
* initialized by a CE2_HASH_Init function or by another call to a CE2_HASH_Update function. \n
* The function sets the last H's value that was stored in 
* the CE2 HASH context, and then processes the data block. 
* At the end of the process, the function stores in the HASH context the H's value, 
* together with the cryptographic attributes that are needed for 
* the HASH block operation (initialize H's value for the HASH algorithm).
* This function is used in cases where the data is not all arranged in one 
* continuous buffer. \n
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_HASH_Update
*     to calculate HASH of inputted data with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_HASH_Update(CE2_HASHUserContext_t	*ContextID_ptr,
										DxUint8_t				*DataIn_ptr,
										DxUint32_t				DataInSize );

/**
****************************************************************
* Function Name: 
*  CE2_HASH_Finish
*
* Inputs:
* @param ContextID_ptr [in] - A pointer to the HASH context buffer allocated by the user 
*                      that is used for the HASH machine operation.
* @param HashResultBuff [out] - A pointer to the target buffer where the 
*                  HASH result stored in the context is loaded to.
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_HASH_INVALID_USER_CONTEXT_POINTER_ERROR
*   - CE2_HASH_INVALID_HASH_RESULT_BUFF_PTR_ERROR
*
* \brief \b
* Description:
*   This function finalizes the hashing process of data block.
* The function receives as input an handle to the HASH Context , that was initialized before
* by an CE2_HASH_Init function or by CE2_HASH_Update function.
* The function "adds" an header to the data block as the specific hash standard 
* specifics, then it loads the engine and reads the final message digest.
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_HASH_Finish
*     to calculate HASH of inputted data with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_HASH_Finish(CE2_HASHUserContext_t	*ContextID_ptr,
										CE2_HASH_Result_t		HashResultBuff);

/**
****************************************************************
* Function Name: 
*  CE2_HASH_Free
*
* Inputs:
* @param ContextID_ptr [in] - A pointer to the HASH context buffer allocated by the user 
*                      that is used for the HASH machine operation.
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_HASH_INVALID_USER_CONTEXT_POINTER_ERROR
*
* \brief \b
* Description:
*  This function is a utility function that frees the context if the operation has failed.
*
*        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 main checks that are run over the received parameters:
*           - verifying that the context pointer is not DX_NULL (*ContextID_ptr). 
*        2. Clears the user's context.
*        3. Exits the handler with the OK code.
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_HASH_Free
*     to calculate HASH of inputted data with using LibTomCrypt.
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_HASH_Free(CE2_HASHUserContext_t *ContextID_ptr);

/**
****************************************************************
* Function Name: 
*  CE2_HASH
*
* Inputs:
* @param OperationMode [in] - The operation mode : MD5 or SHA1;
* @param DataIn_ptr [in] - A pointer to the buffer that stores the data to be hashed;
* @param DataSize [in] - The size of the data to be hashed in bytes;
* @param HashResultBuff [out] - A pointer to the target buffer where the 
*                  HASH result stored in the context is loaded to.
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code:
*   - CE2_HASH_ILLEGAL_HASH_OP_MODE_ERROR
*   - CE2_HASH_INVALID_DATA_IN_PTR_ERROR
*   - CE2_HASH_INVALID_HASH_RESULT_BUFF_PTR_ERROR
*
* \brief \b
* Description:
*   The function allocates an internal HASH Context, and initializes the 
* HASH Context with the cryptographic attributes that are needed for 
* the HASH block operation (initialize H's value for the HASH algorithm).
* Next the function loads the engine with the initializing values, 
* and then processes the data block, calculating the hash.
* Finally, the function return the message digest of the data buffer .
*
* \b
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_HASH
*     to calculate HASH of inputted data with using LibTomCrypt.
***************************************************************/

CE2CIMPORT_C CE2Error_t CE2_HASH  ( CE2_HASH_OperationMode_t  OperationMode,
                         DxUint8_t                   *DataIn_ptr,
                         DxUint32_t                   DataSize,
                         CE2_HASH_Result_t         HashResultBuff );


#ifdef __cplusplus
}
#endif

#endif
