#ifndef __CRYS_FLOW_API_H__
#define __CRYS_FLOW_API_H__


#ifdef __cplusplus
extern "C"
{
#endif

/*
   *  Object %name    : CRYS_FLOW_API.h
   *  State           :  %state%
   *  Creation date   :  Wed Nov 17 17:39:24 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief CRYS  FLOW h file (API and structures )
   *
   *  \version 
   *  \author yevgenys
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */


/*------------------------------
    DEFINES
--------------------------------*/


/*-------------------------------
  STRUCTURES
---------------------------------*/
/*
  enum that defines the type of the flow: static or dynamic
*/
typedef enum
{
  CRYS_FLOW_TypeStatic = 0,
  CRYS_FLOW_TypeDynamic = 1,
  
  CRYS_FLOW_TypeLast    = 0x7FFFFFFF,
}CRYS_FLOW_Type_t;

/*
  flow operation - AES,DES or HASH
*/
typedef enum
{
  FLOW_AES_InitOperation  = 0,
  FLOW_HASH_InitOperation = 1,
  FLOW_DES_InitOperation  = 2,
  FLOW_HMAC_InitOperation = 3,
  FLOW_RC4_InitOperation  = 4,
  
  CRYS_FLOW_INITOPLast    = 0x7FFFFFFF,
}CRYS_FLOW_Op_t;
/*
*/
typedef struct _CRYS_FLOW_DataBase_t
{
  CRYS_FLOW_Type_t  flowType;
  DxUint32_t        opMode;
  CRYS_FLOW_Op_t    opType;   
}CRYS_FLOW_DataBase_t;

/*
*/
typedef struct _CRYS_FLOW_BufferData_t
{
  /* buffer pointer */
  DxUint8_t*   buffer_ptr;
  
  /* buffer size */
  DxUint32_t   bufferSize;
  
}CRYS_FLOW_BufferData_t;

/*
*/
typedef struct _CRYS_FLOW_AESEngineData_t
{
  /* iv counter */
  CRYS_AES_IvCounter_t      IVCounter_ptr;
  
  /* key */
  CRYS_AES_Key_t            Key_ptr;
  
  /* key size */
  CRYS_AES_KeySize_t        KeySize;
  
  /* encrypt/decrypt flag */
  CRYS_AES_EncryptMode_t    EncryptDecryptFlag;
  
  /* operation mode */
  CRYS_AES_OperationMode_t  OperationMode;
  
}CRYS_FLOW_AESEngineData_t;

/*
*/
typedef struct _CRYS_FLOW_DESEngineData_t
{
  /* iv counter */
  CRYS_DES_Iv_t             IV_ptr;
  
  /* key _ptr */
  CRYS_DES_Key_t*           Key_ptr;
  
  /* num of keys */
  CRYS_DES_NumOfKeys_t      NumOfKeys;
  
  /* encrypt/decrypt */
  CRYS_DES_EncryptMode_t    EncryptDecryptFlag;
  
  /* operation mode */
  CRYS_DES_OperationMode_t  OperationMode;
  
}CRYS_FLOW_DESEngineData_t;

/*
*/
typedef struct _CRYS_FLOW_HASHEngine_Data_t
{
  /* operation mode */
  CRYS_HASH_OperationMode_t opMode;
  
}CRYS_FLOW_HASHEngine_Data_t;

/*
*/
typedef struct _CRYS_FLOW_HMACEngine_Data_t
{
  /* operation mode */
  CRYS_HASH_OperationMode_t opMode;
  
  /* key size */
  DxUint16_t                KeySize;

  /* Key pointer */
  DxUint8_t*                Key_ptr;
  
}CRYS_FLOW_HMACEngine_Data_t;

/*
*/
typedef struct _CRYS_FLOW_RC4Engine_Data_t
{
  /* key size */
  DxUint32_t   KeySize;

  /* Key pointer */
  DxUint8_t*   Key_ptr;
  
}CRYS_FLOW_RC4Engine_Data_t;


/*
*/
typedef struct _CRYS_FLOW_Params_t
{
  /* input interrupt id */
  DxUint32_t              inputInterruptId;
  
  /* output interrupt id */
  DxUint32_t              outputInterruptId;
  
  /* if the data in the buffers are in words and not bytes */ 
  DxUint32_t              wordsBuffersOrderFlag;
  
  /* array of pointers to the input buffers */
  CRYS_FLOW_BufferData_t* inputBuffersArrays;
  
  /* number of input buffers */
  DxUint32_t              inputBuffersArraySize;
  
  /* flag if  endian order of the input buffers is big */
  DxUint32_t              inputBigEndianOrderFlag;
  
  /* array of pointers to the input buffers */
  CRYS_FLOW_BufferData_t* outputBuffersArrays;
  
  /* number of input buffers */
  DxUint32_t              outputBuffersArraySize;
  
  /* flag if  endian order of the output buffers is big */
  DxUint32_t              outputBigEndianOrderFlag;
  
}CRYS_FLOW_Params_t;

/*------------------------------------------------
    FUNCTIONS
--------------------------------------------------*/


/**
 * @brief       This function initializes the AES flow 
 *
 *    NOTE: 1) Static requests same buffer sizes for in and out (number of input buffers can be different from number of output buffers)
 *          2) In/Out buffer sizes must be modulus 16.
 * 
 * @param[in] flowType - type of flow, static or dynamic
 * @param[in] flowParams_ptr - flow parameters for the operation.
 * @param[in] aesData_ptr - aes data parameters
 * @param[out] flowId_ptr - the id of the created flow
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_AESInit(CRYS_FLOW_Type_t            flowType,
                            CRYS_FLOW_Params_t*         flowParams_ptr,
                            CRYS_FLOW_AESEngineData_t*  aesData_ptr,
                            DxUint32_t*                 flowId_ptr);
                       
/**
 * @brief       This function initializes the DES flow 
 *
 *    NOTE: Static requests same buffer sizes for in and out (number of input buffers can be different from number of output buffers)
 * 
 * @param[in] flowType - type of flow, static or dynamic
 * @param[in] flowParams_ptr - flow parameters for the operation.
 * @param[in] desData_ptr - des data parameters
 * @param[out] flowId_ptr - the id of the created flow
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_DESInit(CRYS_FLOW_Type_t            flowType,
                            CRYS_FLOW_Params_t*         flowParams_ptr,
                            CRYS_FLOW_DESEngineData_t*  desData_ptr,
                            DxUint32_t*                 flowId_ptr);
                    
/**
 * @brief       This function initializes the HASH flow 
 *
 *    NOTE: 1) buffer size must be modulus 64 or modulus 128 (in SHA384|SHA512) HW smallest HASH input. 
 *          2) Static requests same buffer sizes for in and out (number of input buffers can be different from number of output buffers)
 * 
 * @param[in] flowType - type of flow, static or dynamic
 * @param[in] flowParams_ptr - flow parameters for the operation.
 * @param[in] hashData_ptr - hash data parameters
 * @param[out] flowId_ptr - the id of the created flow
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_HASHInit(CRYS_FLOW_Type_t               flowType,
                             CRYS_FLOW_Params_t*            flowParams_ptr,
                             CRYS_FLOW_HASHEngine_Data_t*   hashData_ptr,
                             DxUint32_t*                    flowId_ptr);


/**
 * @brief       This function initializes the HAMC flow 
 *
 *    NOTE: 1) Static requests same buffer sizes for in and out (number of input buffers can be different from number of output buffers)
 *          2) Key size is limited to be <= 64 bytes
 * 
 * @param[in] flowType - type of flow, static or dynamic
 * @param[in] flowParams_ptr - flow parameters for the operation.
 * @param[in] hmacData_ptr - hmac data parameters
 * @param[out] flowId_ptr - the id of the created flow
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_HMACInit(CRYS_FLOW_Type_t               flowType,
                             CRYS_FLOW_Params_t*            flowParams_ptr,
                             CRYS_FLOW_HMACEngine_Data_t*   hmacData_ptr,
                             DxUint32_t*                    flowId_ptr);


/**
 * @brief       This function initializes the RC4 flow 
 *
 *    NOTE: 1) Static requests same buffer sizes for in and out (number of input buffers can be different from number of output buffers)
 *          2) Key size is limited to 4-16 bytes.
 *          3) In/Out buffers size must be modulus 8.
 * 
 * @param[in] flowType - type of flow, static or dynamic
 * @param[in] flowParams_ptr - flow parameters for the operation.
 * @param[in] rc4Data_ptr - rc4 data parameters
 * @param[out] flowId_ptr - the id of the created flow
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_RC4Init(CRYS_FLOW_Type_t               flowType,
                            CRYS_FLOW_Params_t*            flowParams_ptr,
                            CRYS_FLOW_RC4Engine_Data_t*    rc4Data_ptr,
                            DxUint32_t*                    flowId_ptr);

/**
 * @brief       This function allos to add buffers to a dynamic flow
 * 
 *    NOTE: Add buffer should be only after all input buffers of the Init function were executed. (in no OS environment)
 *      
 * @param[in] flowId - id of the flow to add buffers to
 * @param[in] inputBuffersArray_ptr - array of input buffers. If no input buffers to add, the this parameter shoud be NULL
 * @param[in] inputBuffersArraySize - number of entries in the array of input buffers to add. If no input buffers to add, the this parameter shoud be 0
 * @param[in] outputBuffersArray_ptr - array of output buffers. If no output buffers to add, the this parameter shoud be NULL
 * @param[in] outputBuffersArraySize - number of entries in the array of output buffers to add. If no output buffers to add, the this parameter shoud be 0
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_AddBuffers(DxUint32_t               flowId,
                               CRYS_FLOW_BufferData_t*  inputBuffersArray_ptr,
                               DxUint32_t               inputBuffersArraySize,
                               CRYS_FLOW_BufferData_t*  outputBuffersArray_ptr,
                               DxUint32_t               outputBuffersArraySize);
                          

/**
 * @brief       This function finishes the flow. It sends (if needed), the last data for symmetric operation, and recieves the output (HASH,AES-MAC ), and the current state of the engine (IV/CTR) 
 *
 * Notes: After finish is done any additional input interrupt causes unexpectable behavior.
 *        It is user responsibilty.
 * 
 * @param[in] flowId - id of the flow to add buffers to
 * @param[in] dataInSize - size of the last data.Should be 0, if no data is needed to be passed
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_Finish(DxUint32_t   flowId,
                           DxUint32_t   dataInSize);  
                           
/**
 * @brief       This function receives the output of the flow, if needed (HASH, AES_MAC). If the results are not ready
 *              yet - appropriate error code will be returned
 * 
 * @param[in] flowId - id of the flow to add buffers to
 * @param[in] outputBuffer_ptr - address of the buffer , to where the result will be written
 * @param[in] outputBufferSize - size of the input buffer
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_GetResults(DxUint32_t   flowId,
                               DxUint8_t*   outputBuffer_ptr,
                               DxUint32_t   outputBufferSize); 
                               
/**
 * @brief       This function terminates the flow immediatly
 * 
 * @param[in] flowId - id of the flow to add buffers to
 *
 * @return DXError_t - On success DX_OK is returned, on failure a
 *                        value MODULE_* CRYS_FLOW_error.h
 */
DxError_t CRYS_FLOW_Terminate(DxUint32_t  flowId);                        
                         
#ifdef __cplusplus
}
#endif

#endif
