
  /*
   *  Object %name    : %
   *  State           :  %state%
   *  Creation date   :  Tue Nov 25 10:17:10 2007
   *  Last modified   :  %modify_time%
   */
  /** @file 
   *  \brief A brief description of this module 
   *
   *  \version CRYS_ATP_TST_RC4FLOW.c#1:csrc:1
   *  \author Annag
   *  \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
   *           All Rights reserved
   */
/************* Include Files ****************/
#include "CRYS.h"

#include "CRYS_ATP_TST_Defines.h"
#include "CRYS_ATP_TST_UTIL_Funcs.h"
#include "CRYS_ATP_TST_UTIL_OTF_Funcs.h"
#include "CRYS_ATP_TST_RC4FLOW_Acceptance.h"
#include "CRYS_ATP_TST_AESFLOW_Acceptance.h"
#include "CRYS_ATP_TST_HASHFLOW_Acceptance.h"
#include "CRYS_ATP_TST_DESFLOW_Acceptance.h"
#include "CRYS_ATP_TST_RC4FLOW_Acceptance_test_vectors.h"
#include "CRYS_ATP_TST_FLOW_Defines.h"
#include "gen.h"
#include "CRYS_INIT_TST.h"
#include "CRYS_FLOW.h"
#include "CRYS_FLOW_error.h"
#include "DX_VOS_Mem.h"
#include "FLOW_error.h"

#if TST_USE_FLOW_DATA
#if FLOW_RC4_Support


/************************ Defines *******************************/
/************************ Enums *********************************/
/************************ Typedefs ******************************/
/************************ Global Data ***************************/

extern DxUint8_t 	                       TST_Input_Data[TST_FLOW_DATA_VEC_SIZE_IN_BYTS];
extern DxUint64_t	                       TST_FLOW_InputData[TST_FLOW_DATA_VEC_SIZE_IN_BYTS/8];

extern DxUint64_t						   TST_FLOW_OutputData[TST_FLOW_NUMBER_OF_SUPPORTED_ENGINES][TST_FLOW_DATA_VEC_SIZE_IN_BYTS/8];

/* common data for one test vector */
extern TST_FLOW_TestCommonDataStruct       TST_TestData;

/* input data size */
extern DxUint32_t                          TST_FLOW_InputDataSize;
extern CRYS_FLOW_Params_t                  TST_FLOWParamsInfo;


/* output data of HASH/AES_MAC result */
extern DxUint32_t                          TST_FLOW_Hash_OutputData[CRYS_HASH_RESULT_SIZE_IN_WORDS];

/* output data for integrated engines */
extern DxUint64_t	                       TST_FLOW_OutputDataForIntegratedEngines[TST_FLOW_DATA_VEC_SIZE_IN_BYTS/8];

/* indication if data size in function finish should be zero */
extern DxBool_t                            TST_FLOW_IsFinishSizeZero;

/* flow input buffers */
extern CRYS_FLOW_BufferData_t              TST_InputBuffers[TST_FLOW_DATA_MAX_NUM_OF_FLOWBUFFERS];

/* flow output buffers */
extern CRYS_FLOW_BufferData_t              TST_OutputBuffers[TST_FLOW_NUMBER_OF_SUPPORTED_ENGINES][TST_FLOW_DATA_MAX_NUM_OF_FLOWBUFFERS];

/* RC4 engine data */
CRYS_FLOW_RC4Engine_Data_t                 TST_FLOWRC4EngineData;


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


/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_InitRC4EngineData
 *  
 * Inputs:
 *  TST_index - test index
 *  None
 *
 * Outputs:                                 
 *
 * Description:                                                                 
 *  This function initializes engine data for RC4 FLOW operation
 * Algorithm:     
 *	This function initializes RC4 flow engine data struct with values from the test vector.
 ******************************************************************************/                                
void CRYS_ATP_TST_FLOW_InitRC4EngineData ( int TST_index ) 
{
    
    /* initialize key value */
    TST_FLOWRC4EngineData.Key_ptr = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Key;                      
  
    TST_FLOWRC4EngineData.KeySize = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_KeySize; 
}


 
/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_InitRC4Flow
 *  
 * Inputs:
 *  TST_index          - test index
 *  flowType           - flow type
 *  TST_MasterTestName - test name
 *  TST_RC4FlowId      - output RC4 flow id
 *  pRC4FlowParamsInfo - flow params info
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *	This function starts RC4 flow.
 *
 * Algorithm:     
 *	This function starts RC4 flow.
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_InitRC4Flow ( int                     TST_index,
                                       CRYS_FLOW_Type_t        flowType,
                                       char                   *TST_MasterTestName, 
                                       DxUint32_t             *TST_RC4FlowId,
                                       CRYS_FLOW_Params_t     *pRC4FlowParamsInfo ) 
{
    /********* TST Variables Definitions ************/
    CRYSError_t  TST_TestStatus = TESTPASS;
    
    TST_TestData.inputBigEndianOrderFlag  = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBigEndianOrderFlag;
	TST_TestData.inputBuffersArraySize    = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
	TST_TestData.inputInterruptId         = TST_RC4FLOW_Acceptance_TestData[TST_index].inputInterruptId;
	TST_TestData.outputBigEndianOrderFlag = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBigEndianOrderFlag;
	TST_TestData.outputBuffersArraySize   = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;
	TST_TestData.outputInterruptId        = TST_RC4FLOW_Acceptance_TestData[TST_index].outputInterruptId;
	TST_TestData.wordsBuffersOrderFlag    = TST_RC4FLOW_Acceptance_TestData[TST_index].wordsBuffersOrderFlag;
	
    
    /* initialize flow init parameters */
 	CRYS_ATP_TST_FLOW_InitParams(TST_index, DX_TRUE, &TST_TestData, pRC4FlowParamsInfo, CRYS_FLOW_RC4);
 	    
 	/* initialize RC4 engine data */
 	CRYS_ATP_TST_FLOW_InitRC4EngineData(TST_index);
         	
    
    /* Init RC4 flow */
 	/*****************/
 	TST_ATP_Error = CRYS_FLOW_RC4Init(flowType,
                 	                  pRC4FlowParamsInfo,
                                      &TST_FLOWRC4EngineData,  
                                      TST_RC4FlowId);
                      
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_RC4Init is done\n"));
                        
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_RC4Init",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);
    
    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
    
    return TST_TestStatus;
} /* CRYS_ATP_TST_InitRC4Flow */

/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FinishRC4Flow
 *  
 * Inputs:
 *  TST_index          - test index
 *  TST_RC4            - flow id
 *  TST_MasterTestName - test name
 *  blockSize          - block size for finish
 *  pRC4FlowParamsInfo - flow params info
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *	This function finishes RC4 flow and checks results.
 *
 * Algorithm:     
 *	1. Finish RC4 flow
 *  2. Get results
 *  3. Compare output buffers with expected results
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FinishRC4Flow ( int                     TST_index, 
                                         DxUint32_t              TST_RC4FlowId, 
                                         char                   *TST_MasterTestName,
                                         DxUint32_t              blockSize,
                                         CRYS_FLOW_Params_t     *pRC4FlowParamsInfo ) 
{
    DxUint8_t    *pExpectedOut;
    CRYSError_t  TST_TestStatus = TESTPASS;
    int          j = 0; 
    
    /* Finish RC4 flow with size of the last input buffer */
    /******************************************************/
    TST_ATP_Error = CRYS_FLOW_Finish(TST_RC4FlowId,
                                     blockSize);  
                     
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Finish is done\n"));                             
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Finish",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
                     
    /* Get results */
    /***************/
    do
    {
        
        TST_ATP_Error = CRYS_FLOW_GetResults(TST_RC4FlowId, 	
                                             DX_NULL,
    								         0);
	
    }while(TST_ATP_Error == DX_SEP_FLOW_GET_RESULT_NOT_READY_ERROR);
    
								          
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_GetResults is done\n"));
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_GetResults",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  

    
    pExpectedOut = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Expected_output_data;
	
    /* Compare output buffers with expected results */
	/************************************************/
    for (j = 0; j < pRC4FlowParamsInfo->outputBuffersArraySize; ++j)
	{
		/* compare and prints results of test */
		TST_ATP_Error += (CRYSError_t)DX_VOS_MemCmp(
												pRC4FlowParamsInfo->outputBuffersArrays[j].buffer_ptr,
                                 				pExpectedOut + 	j*pRC4FlowParamsInfo->outputBuffersArrays[j].bufferSize,
                                 				pRC4FlowParamsInfo->outputBuffersArrays[j].bufferSize);
                                    
                                     			
		/*Print the outputted and then the expected result after mem compare */
		ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
								   "\nData outputted by engine [output buffer]-- \n",
								   (DxUint8_t*)pRC4FlowParamsInfo->outputBuffersArrays[j].buffer_ptr, 
								   pRC4FlowParamsInfo->outputBuffersArrays[j].bufferSize); 

 		ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
								  "\nData Expected by engine --\n",
								   (DxUint8_t*)pExpectedOut + 	j*pRC4FlowParamsInfo->outputBuffersArrays[j].bufferSize,
								   pRC4FlowParamsInfo->outputBuffersArrays[j].bufferSize);                 	                                     			
	}
			
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
    
    return TST_TestStatus;
}


/*****************************************************************************
* Function Name:                                                           
*  CRYS_ATP_TST_FLOW_CheckRC4Operation
*  
* Inputs:
*  TST_index - test index,
*  TST_MasterTestName - test name
*  None
*
* Outputs: 
*  CRYSError_t - Function error return                                     
*
* Description:                                                                 
*  This function checks some RC4 operation
* Algorithm:     
* 1. Execute some RC4 operation 
* 2. Compare result to expected one
******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_CheckRC4Operation () 
{
    /********* TST Variables Definitions ************/
	CRYSError_t   TST_TestStatus = TESTPASS;
	/* use test index = 0 */
	DxUint32_t   TST_index = 0;
    DxUint32_t   ExpectedSize = TST_FLOW_InputDataSize;
		      
    /* Run CRYS_RC4 function */
	/*************************/
    CRYS_RC4(TST_RC4FLOW_Acceptance_TestData[0].TST_Key,
             TST_RC4FLOW_Acceptance_TestData[0].TST_KeySize,
             (DxUint8_t*)TST_Input_Data,
             TST_FLOW_InputDataSize,
             (DxUint8_t*)TST_FLOW_OutputDataForIntegratedEngines);

	/* compare RC4 result with one expected */
	/****************************************/
	TST_ATP_Error = (CRYSError_t)DX_VOS_MemCmp(
		TST_FLOW_OutputDataForIntegratedEngines,
		TST_RC4FLOW_Acceptance_TestData[0].TST_Expected_output_data,
		ExpectedSize);					      

	ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CheckRC4Operation is done\n"));
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CheckRC4Operation",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
	return TST_ATP_Error;

}


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

/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance
 *  
 * Inputs:
 *  TST_index          - test index
 *  TST_MasterTestName - test name
 *  flowType           - flow type (static or dynamic)
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *  This function Is a Acceptance test for static AES FLOW API's
 
 * Algorithm:     
 *  1. Init RC4 flow
 *  2. Send interrupts that input and output buffers are ready
 *  3. Finish RC4 flow, read data from the output buffers and compare to expected results
 *  4. Terminate flow
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance ( int              TST_index, 
                                                       char            *TST_MasterTestName,
                                                       CRYS_FLOW_Type_t flowType ) 
{
/********* TST Variables Definitions ************/
	CRYSError_t             	TST_TestStatus = TESTPASS;
	
	/* flow id */
	DxUint32_t                   flowId = 0;
	DxUint32_t                   i = 0;
	DxUint16_t                   blockSize;
	

	/************************************************/
	/*********** Start of test **********************/
	/************************************************/
	
    /* input block size */
    blockSize       = TST_FLOW_InputDataSize/TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
	
    /* initialize input buffer: */
    DX_VOS_FastMemCpy((DxUint8_t*)TST_FLOW_InputData, TST_Input_Data, TST_FLOW_InputDataSize);
	
	
	/* Initialize RC4 flow parameters and init RC4 flow by calling function */
	/* CRYS_FLOW_RC4Init                                                    */
	/************************************************************************/
	TST_TestStatus = CRYS_ATP_TST_InitRC4Flow(TST_index, flowType, TST_MasterTestName, &flowId, &TST_FLOWParamsInfo);
	
	#if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
        return TESTFAIL;
    #endif  

	
	/* Send interrupts that input and output buffers are ready */
	/***********************************************************/
	

	/* Send interrupt that input buffers are ready */
	if (TST_FLOW_IsFinishSizeZero == DX_TRUE)
	{
	    for (i = 0; i < TST_FLOWParamsInfo.inputBuffersArraySize; ++i)
	        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.inputInterruptId);
	        
        blockSize = 0;		        
	}
	else
	{
	    for (i = 0; i < TST_FLOWParamsInfo.inputBuffersArraySize - 1; ++i)
	        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.inputInterruptId);
	}


	/* Send interrupt that output buffers are ready */
	for (i = 0; i < TST_FLOWParamsInfo.outputBuffersArraySize; ++i)
	    CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.outputInterruptId);

		

	/* Finish RC4 flow, get results and compare results with expected  */
    /* by calling functions CRYS_FLOW_Finish and CRYS_FLOW_GetResults  */
    /*******************************************************************/
	TST_TestStatus = CRYS_ATP_TST_FinishRC4Flow(TST_index, flowId, TST_MasterTestName, blockSize, &TST_FLOWParamsInfo);
	
	#if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
        return TESTFAIL;
    #endif  
	

    /* terminate flow */
    /******************/
	TST_ATP_Error = CRYS_FLOW_Terminate(flowId);
	
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Terminate is done\n"));                             
	
	TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Terminate",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
	if (TST_TestStatus != TESTPASS) 
		return TESTFAIL;
#endif  

	return TST_TestStatus;    
}/* End of CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance*/ 

/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance
 *  
 * Inputs:
 *  None
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *  This function Is a Acceptance test for static RC4 FLOW API's
 
 * Algorithm:     
 *	This function goes through all tests vectors and execute RC4 static flow acceptance test
 *  for each vector
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	TST_index;
	CRYSError_t             	TST_TestStatus = TESTPASS;
	char                     	TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance"; 
	
	
	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;
	TST_FLOWRC4EngineData.Key_ptr          = DX_NULL;


	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n \n"));


	/* go through all tests vectors and execute DES flow acceptance test for each vector */
    /*************************************************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
	{
		TST_TestStatus = CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance(TST_index, TST_MasterTestName, CRYS_FLOW_TypeStatic);
		

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  

	}/* End of TST_index */     

	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance*/ 

/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance
 *  
 * Inputs:
 *  None
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *  This function Is a Acceptance test for static RC4 FLOW API's
 
 * Algorithm:     
 *	This function goes through all tests vectors and execute RC4 dynamic flow acceptance test
 *  for each vector
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	TST_index;
	CRYSError_t             	TST_TestStatus = TESTPASS;
	char                     	TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance"; 
	
	
	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;
	TST_FLOWRC4EngineData.Key_ptr          = DX_NULL;


	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n \n"));


	/* go through all tests vectors and execute DES flow acceptance test for each vector */
    /*************************************************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
	{
		TST_TestStatus = CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance(TST_index, TST_MasterTestName, CRYS_FLOW_TypeDynamic);
		

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  

	}/* End of TST_index */     

	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance*/


/*****************************************************************************
* Function Name:                                                           
*  CRYS_ATP_TST_FLOW_RC4DYNAMIC_AddBuffers_Acceptance
*  
* Inputs:
*  None
*
* Outputs: 
*  CRYSError_t - Function error return                                     
*
* Description:                                                                 
*  This function Is a Acceptance test for dynamic RC4 FLOW API's

* Algorithm:     
*  1. Initialize RC4 flow with dynamic type and other parameters
*  2. Init RC4 flow
*  3. Send interrupts that input and output buffers are ready
*  4. Add buffers to dynamic flow
*  5. Send interrupts that added input and output buffers are ready
*  6. Finish RC4 flow
*  7. Get results
*  8. Read data from the output buffers and compare to expected results
******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4DYNAMIC_AddBuffers_Acceptance ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	 TST_index;
	CRYSError_t             	 TST_TestStatus = TESTPASS;
	char                     	 TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4DYNAMIC_AddBuffers_Acceptance"; 
	DxUint8_t                   *pExpectedOut;
	/* flow id */
	DxUint32_t                   flowId = 0;
	int                          j = 0; 
	
    DxUint32_t                   inputBuffersArraySize = 1;
	DxUint32_t                   outputBuffersArraySize = 1;
    CRYS_FLOW_BufferData_t       inputBuffersArray_ptr[TST_FLOW_DATA_MAX_NUM_OF_FLOWBUFFERS];
    CRYS_FLOW_BufferData_t       outputBuffersArray_ptr[TST_FLOW_DATA_MAX_NUM_OF_FLOWBUFFERS];
    DxUint16_t                   blockSize;
	DxUint16_t                   outputBlockSize;

	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;

	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4DYNAMIC_AddBuffers_Acceptance Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n \n"));


	/************************************************/
	/*********** Start of test **********************/
	/************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
	{
		TST_TestData.inputBigEndianOrderFlag  = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBigEndianOrderFlag;
		TST_TestData.inputBuffersArraySize    = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
		TST_TestData.inputInterruptId         = TST_RC4FLOW_Acceptance_TestData[TST_index].inputInterruptId;
		TST_TestData.outputBigEndianOrderFlag = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBigEndianOrderFlag;
		TST_TestData.outputBuffersArraySize   = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;
		TST_TestData.outputInterruptId        = TST_RC4FLOW_Acceptance_TestData[TST_index].outputInterruptId;
		TST_TestData.wordsBuffersOrderFlag    = TST_RC4FLOW_Acceptance_TestData[TST_index].wordsBuffersOrderFlag;

		/* Initializing DES Flow with dynamic type and other parameters */
		/*****************************/
		blockSize       = TST_FLOW_InputDataSize/TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
		outputBlockSize = TST_FLOW_InputDataSize/TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;

	    /* prepare input buffer: */
		DX_VOS_FastMemCpy((DxUint8_t*)TST_FLOW_InputData, TST_Input_Data, TST_FLOW_InputDataSize);
		

		/* initialize flow init parameters */
		CRYS_ATP_TST_FLOW_InitParams(TST_index, DX_FALSE, &TST_TestData, &TST_FLOWParamsInfo, CRYS_FLOW_RC4);

		/* initialize RC4 engine data */
		CRYS_ATP_TST_FLOW_InitRC4EngineData(TST_index);

	
		/* Init RC4 flow */
		/*****************/
		TST_ATP_Error = CRYS_FLOW_RC4Init(CRYS_FLOW_TypeDynamic,
			                              &TST_FLOWParamsInfo,
			                              &TST_FLOWRC4EngineData,  
			                              &flowId);


		ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_RC4Init is done\n"));

		TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_InitRC4",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  

		/* Send interrupts that input and output buffers are ready */
        /***********************************************************/
            
		/* Send interrupt that input buffers are ready */
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);
        
        
        /* Send interrupt that output buffers are ready */
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.outputInterruptId);


		inputBuffersArraySize  = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
		outputBuffersArraySize = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;

		/* prepare buffers to add */
		for (j = 0; j < inputBuffersArraySize - 1; ++j )
		{
			/* point to the second block of the input buffer */
			inputBuffersArray_ptr[j].buffer_ptr = (DxUint8_t*)TST_FLOW_InputData + (j+1)*blockSize;
                
			inputBuffersArray_ptr[j].bufferSize = blockSize;                
		}

	
		for (j = 0; j < outputBuffersArraySize - 1; ++j )
		{
			/* point to the second block of the output data */
			outputBuffersArray_ptr[j].buffer_ptr = (DxUint8_t*)TST_FLOW_OutputData[CRYS_FLOW_RC4] + (j+1)*outputBlockSize;

			outputBuffersArray_ptr[j].bufferSize = outputBlockSize;                
		}

	
		/* Add input and output buffers to the dynamic flow */
		/******************************************************/
		TST_ATP_Error = CRYS_FLOW_AddBuffers(flowId,
                        				inputBuffersArray_ptr,
                        				inputBuffersArraySize - 1,
                        				outputBuffersArray_ptr,
                        				outputBuffersArraySize - 1);
                        				
        ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_AddBuffers is done\n"));

		TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_AddBuffers",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  
                        				
        /* Send interrupts that added input and output buffers are ready */
        /*****************************************************************/               				
			
        /* Send interrupt that input buffers are ready */
        for (j = 0; j < inputBuffersArraySize - 1; ++j )
            CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);
                
        blockSize = 0;    
        
        /* Send interrupt that output buffers are ready */
        for (j = 0; j < outputBuffersArraySize - 1; ++j )
            CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.outputInterruptId);                                 

		/* Finish RC4 flow with size of the last input buffer */
		/******************************************************/
		TST_ATP_Error = CRYS_FLOW_Finish(flowId,
			                             blockSize); 

		ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Finish is done\n"));                             
		
		TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Finish",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  


		/* Get results */
		/***************/
		do
        {
            
            TST_ATP_Error = CRYS_FLOW_GetResults(flowId,
			                                 (DxUint8_t*)TST_FLOW_Hash_OutputData,
			                                 CRYS_HASH_RESULT_SIZE_IN_WORDS);
    	
        }while(TST_ATP_Error == DX_SEP_FLOW_GET_RESULT_NOT_READY_ERROR);
		
		
        ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_GetResults is done\n"));
        
        TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_GetResults",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  
		
		/* terminate flow */
		TST_ATP_Error = CRYS_FLOW_Terminate(flowId);
		
	    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Terminate is done\n"));                             
		
		TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Terminate",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  	

		/* Read data from the output buffers and compare to expected result */
		/********************************************************************/
		pExpectedOut = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Expected_output_data;
		

		for (j = 0; j < 1; ++j)
		{
			/* compare and prints results of test */
			TST_ATP_Error = (CRYSError_t)DX_VOS_MemCmp(
				TST_FLOWParamsInfo.outputBuffersArrays[j].buffer_ptr,
				pExpectedOut + 	j*TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize,
				TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize);


			/*Print the outputted and then the expected result after mem compare */
			ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
				"\nData outputted by engine [output buffer]-- \n",
				(DxUint8_t*)TST_FLOWParamsInfo.outputBuffersArrays[j].buffer_ptr, 
				TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize); 

			ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
				"\nData Expected by engine --\n",
				(DxUint8_t*)pExpectedOut + 	j*TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize,
				TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize);                 	                                     			
		}

		/* compare and prints results of test */
		for (j = 0; j < inputBuffersArraySize - 1; ++j )
		{
			TST_ATP_Error = (CRYSError_t)DX_VOS_MemCmp(
				outputBuffersArray_ptr[j].buffer_ptr,
				pExpectedOut + 	(j+1)*outputBuffersArray_ptr[j].bufferSize,
				outputBuffersArray_ptr[j].bufferSize);
				
            /*Print the outputted and then the expected result after mem compare */
			ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
				"\nData outputted by engine [output buffer]-- \n",
				(DxUint8_t*)	outputBuffersArray_ptr[j].buffer_ptr, 
				outputBuffersArray_ptr[j].bufferSize); 

			ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
				"\nData Expected by engine --\n",
				(DxUint8_t*)pExpectedOut + 	(j+1)*outputBuffersArray_ptr[j].bufferSize,
				outputBuffersArray_ptr[j].bufferSize);                 	                                     							
		}
		
		TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  

	}/* End of TST_index */     

	
	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4DYNAMIC_AddBuffers_Acceptance*/
 

/*****************************************************************************
* Function Name:                                                           
*  CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance_WithAdditionalEngines
*  
* Inputs:
*  None
*
* Outputs: 
*  CRYSError_t - Function error return                                     
*
* Description:                                                                 
*  This function Is a Acceptance test for RC4 FLOW API's with additional engines.

* Algorithm:     
*  1. Init RC4 flow 
*  2. Send several interrupts that input and output buffers are ready
*  3. Execute some HASH operation and compare the result of the HASH to expected
*  4. Send several interrupts that input and output buffers are ready, 
*  5. Execute some AES operation and compare the result of the DES to expected
*  6. Send several interrupts that input and output buffers are ready, 
*  7. Execute some DES operation and compare the result of the AES to expected
*  8. Finish DES flow 
*  9. Execute some AES operation and compare with expected result
*  10. Get result
*  11.Terminate flow
*  12.Read data from the output buffers and compare to expected results
******************************************************************************/
CRYSError_t CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance_WithAdditionalEngines ( 
                                                                int              TST_index, 
                                                                char             *TST_MasterTestName,
                                                                CRYS_FLOW_Type_t flowType ) 
{

	/********* TST Variables Definitions ************/
    CRYSError_t             	 TST_TestStatus = TESTPASS;
	DxUint8_t                   *pExpectedOut;
	/* flow id */
	DxUint32_t                   flowId = 0;
    int                          j = 0; 
    int                          i = 0;
    DxUint16_t                   blockSize;
	

	/************************************************/
	/*********** Start of test **********************/
	/************************************************/
	TST_TestData.inputBigEndianOrderFlag  = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBigEndianOrderFlag;
	TST_TestData.inputBuffersArraySize    = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
	TST_TestData.inputInterruptId         = TST_RC4FLOW_Acceptance_TestData[TST_index].inputInterruptId;
	TST_TestData.outputBigEndianOrderFlag = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBigEndianOrderFlag;
	TST_TestData.outputBuffersArraySize   = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;
	TST_TestData.outputInterruptId        = TST_RC4FLOW_Acceptance_TestData[TST_index].outputInterruptId;
	TST_TestData.wordsBuffersOrderFlag    = TST_RC4FLOW_Acceptance_TestData[TST_index].wordsBuffersOrderFlag;

	/* input block size */
    blockSize       = TST_FLOW_InputDataSize/TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;


    /* copy input to aligned input buffer: */
    DX_VOS_FastMemCpy((DxUint8_t*)TST_FLOW_InputData, TST_Input_Data, TST_FLOW_InputDataSize);
    

    /* Initialize RC4 flow parameters and init RC4 flow by calling function */
    /* CRYS_FLOW_RC4Init                                                    */
	/************************************************************************/
    TST_TestStatus = CRYS_ATP_TST_InitRC4Flow(TST_index, flowType, TST_MasterTestName, &flowId, &TST_FLOWParamsInfo);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    	return TESTFAIL;
    #endif  
    
    /* Send interrupts that input and output buffers are ready */
    /***********************************************************/

    /* Send interrupt that input buffers are ready */
    CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);


    /* Send interrupt that output buffers are ready */
    CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.outputInterruptId);


    /* execute HASH operation and compare with expected result */
    /***********************************************************/
    TST_ATP_Error = CRYS_ATP_TST_FLOW_CheckHASHOperation();

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"HASH operation",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    return TESTFAIL;
    #endif  

    /* Send interrupts that input and output buffers are ready */
    /***********************************************************/
	    
    /* Send interrupt that input buffers are ready */
    CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);


    /* Send interrupt that output buffers are ready */
    CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.outputInterruptId);


    /* execute AES operation and compare with expected result */
    /***********************************************************/
    TST_ATP_Error = CRYS_ATP_TST_FLOW_CheckAESOperation();

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"AES operation",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
        return TESTFAIL;
    #endif  

    /* Send interrupts that input and output buffers are ready */
    /***********************************************************/
	    
    /* Send interrupt that input buffers are ready */
    if ((TST_FLOW_IsFinishSizeZero == DX_TRUE) ||
        (TST_FLOWParamsInfo.inputBuffersArraySize < 3)) 
    {
        for (i = 0; i < TST_FLOWParamsInfo.inputBuffersArraySize - 2; ++i)
        {
            CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);
        }
        
        blockSize = 0;
    }
    else
    {
        for (i = 0; i < TST_FLOWParamsInfo.inputBuffersArraySize - 3; ++i)
        {
            CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.inputInterruptId);
        }
    }

    /* Send interrupt that output buffers are ready */
    for (i = 0; i < TST_FLOWParamsInfo.outputBuffersArraySize - 2; ++i)
    {
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_TestData.outputInterruptId);
    }


    /* execute DES operation and compare with expected result */
	/***********************************************************/
    TST_ATP_Error = CRYS_ATP_TST_FLOW_CheckDESOperation();

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"DES operation",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
        return TESTFAIL;
    #endif  

    /* Finish DES flow with size of the last input buffer */
    /******************************************************/
    TST_ATP_Error = CRYS_FLOW_Finish(flowId,
    	                             blockSize);
    	                               
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Finish is done\n"));                             

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Finish",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    return TESTFAIL;
    #endif  	                             
    				                             
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Finish is done\n"));                             

    /* execute some AES operation and compare with expected result*/
	/**************************************************************/
    TST_ATP_Error = CRYS_ATP_TST_FLOW_CheckAESOperation();

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"AES operation",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    	return TESTFAIL;
    #endif  
    

    /* Get results */
    /***************/
    do
    {
        
        TST_ATP_Error = CRYS_FLOW_GetResults(flowId,
    	                                (DxUint8_t*)TST_FLOW_Hash_OutputData,
    	                                 CRYS_HASH_RESULT_SIZE_IN_WORDS);
	
    }while(TST_ATP_Error == DX_SEP_FLOW_GET_RESULT_NOT_READY_ERROR);
    

    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_GetResults is done\n"));

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_GetResults",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    return TESTFAIL;
    #endif  

    /* Terminate flow */
    /******************/
    TST_ATP_Error = CRYS_FLOW_Terminate(flowId);

    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Terminate is done\n"));                             

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Terminate",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
        return TESTFAIL;
    #endif  

    /* Read data from the output buffers and compare to expected result */
    /********************************************************************/
    pExpectedOut = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Expected_output_data;
    

    for (j = 0; j < TST_FLOWParamsInfo.outputBuffersArraySize; ++j)
    {
    	/* compare and prints results of test */
    	TST_ATP_Error += (CRYSError_t)DX_VOS_MemCmp(
    		TST_FLOWParamsInfo.outputBuffersArrays[j].buffer_ptr,
    		pExpectedOut + 	j*TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize,
    		TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize);


    	/*Print the outputted and then the expected result after mem compare */
    	ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
    		"\nData outputted by engine [output buffer]-- \n",
    		(DxUint8_t*)TST_FLOWParamsInfo.outputBuffersArrays[j].buffer_ptr, 
    		TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize); 

    	ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
    		"\nData Expected by engine --\n",
    		(DxUint8_t*)pExpectedOut + 	j*TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize,
    		TST_FLOWParamsInfo.outputBuffersArrays[j].bufferSize);                 	                                     			
    }

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
    if (TST_TestStatus != TESTPASS) 
    	return TESTFAIL;
    #endif  

	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance_WithAdditionalEngines*/ 

/*****************************************************************************
* Function Name:                                                           
*  CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines
*  
* Inputs:
*  None
*
* Outputs: 
*  CRYSError_t - Function error return                                     
*
* Description:                                                                 
*  This function Is a Acceptance test for static RC4 FLOW API's with additional engines.

* Algorithm:     
*  This function goes through all flow vectors and execute acceptance test with 
*  additional engines for each vector
******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	 TST_index;
	CRYSError_t             	 TST_TestStatus = TESTPASS;
	char                     	 TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines"; 


	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;


	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"******************************************************************************************* \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"******************************************************************************************* \n \n"));


	/* go through all flow vectors and execute acceptance test */
	/***********************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
	{
		TST_TestStatus = CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance_WithAdditionalEngines(
		                                                           TST_index,
	                                                               TST_MasterTestName,
	                                                               CRYS_FLOW_TypeStatic);
	                                                               
#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  
	                                                               
	}/* End of TST_index */     

	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines*/ 


/*****************************************************************************
* Function Name:                                                           
*  CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance_WithAdditionalEngines
*  
* Inputs:
*  None
*
* Outputs: 
*  CRYSError_t - Function error return                                     
*
* Description:                                                                 
*  This function Is a Acceptance test for static RC4 FLOW API's with additional engines.

* Algorithm:     
*  This function goes through all flow vectors and execute acceptance test with 
*  additional engines for each vector
******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance_WithAdditionalEngines ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	 TST_index;
	CRYSError_t             	 TST_TestStatus = TESTPASS;
	char                     	 TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance_WithAdditionalEngines"; 
	
	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;


	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"******************************************************************************************* \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance_WithAdditionalEngines Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"******************************************************************************************* \n \n"));


	/* go through all flow vectors and execute acceptance test */
	/***********************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
	{
		TST_TestStatus = CRYS_ATP_TST_FLOW_RC4_ONETEST_Acceptance_WithAdditionalEngines(
		                                                           TST_index,
	                                                               TST_MasterTestName,
	                                                               CRYS_FLOW_TypeDynamic);
	                                                               
#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
			return TESTFAIL;
#endif  
	                                                               
	}/* End of TST_index */     

	return TST_TestStatus;
}/* End of CRYS_ATP_TST_FLOW_RC4DYNAMIC_Acceptance_WithAdditionalEngines*/ 

/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_RC4STATIC_ONETEST_Cyclic_Acceptance
 *  
 * Inputs:
 *  TST_index          - test index
 *  TST_MasterTestName - test name 
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *  This function Is a Acceptance test for static cyclic DES FLOW API's
 
 * Algorithm:     
 * 1. Initialize RC4 flow with static type and other parameters 
 * 2. Init RC4 flow
 * 3. Send interrupts to execute cyclic flow operation 
 * 4. Finish RC4 flow
 * 5. Get results
 * 6. Terminate flow
 * 7. Read data from the output buffers and compare to expected result
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4STATIC_ONETEST_Cyclic_Acceptance ( int   TST_index,
                                                                    char *TST_MasterTestName  ) 
{

	/********* TST Variables Definitions ************/
    CRYSError_t             	 TST_TestStatus = TESTPASS;
	DxUint8_t                   *pExpectedOut;
	/* flow id */
	DxUint32_t                   flowId = 0;
	DxUint32_t                   blockSize = 0;
	int                          j = 0; 
	int                          i = 0; 
	
	volatile DxUint32_t          delay = 0;
	
	/* output to accumulate result from cyclic operation */
	DxUint32_t	                 TST_FLOW_Cyclic_OutputData[TST_FLOW_DATA_VEC_SIZE_IN_BYTS/4];
	DxUint8_t                    *pAccumulatorOutputData = (DxUint8_t*)TST_FLOW_Cyclic_OutputData;
    
    
    /* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;
	
	
	TST_FLOWParamsInfo.inputBigEndianOrderFlag  = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBigEndianOrderFlag;
	TST_FLOWParamsInfo.inputBuffersArraySize    = TST_RC4FLOW_Acceptance_TestData[TST_index].inputBuffersArraySize;
	TST_FLOWParamsInfo.inputInterruptId         = TST_RC4FLOW_Acceptance_TestData[TST_index].inputInterruptId;
	TST_FLOWParamsInfo.outputBigEndianOrderFlag = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBigEndianOrderFlag;
	TST_FLOWParamsInfo.outputBuffersArraySize   = TST_RC4FLOW_Acceptance_TestData[TST_index].outputBuffersArraySize;
	TST_FLOWParamsInfo.outputInterruptId        = TST_RC4FLOW_Acceptance_TestData[TST_index].outputInterruptId;
	TST_FLOWParamsInfo.wordsBuffersOrderFlag    = TST_RC4FLOW_Acceptance_TestData[TST_index].wordsBuffersOrderFlag;
	
    /* pointer to cyclic output data for accumulating */
    pAccumulatorOutputData = (DxUint8_t*)TST_FLOW_Cyclic_OutputData;
    
    /* prepare input buffer: */
    DX_VOS_FastMemCpy((DxUint8_t*)TST_FLOW_InputData, TST_Input_Data, TST_FLOW_InputDataSize);
    
	/* Initialize RC4 flow data */
    /****************************/
 	blockSize = TST_FLOW_DATA_VEC_SIZE_IN_BYTS/4;
 	
 	/* initialize input buffers */
 	for (j = 0; j < 2; ++j )
	{
		
		TST_InputBuffers[j].buffer_ptr = (DxUint8_t*)TST_FLOW_InputData + (j)*blockSize;
            
		TST_InputBuffers[j].bufferSize = blockSize;                
	}
    
   
    /* initialize output buffers */
    for (j = 0; j < 2; ++j )
	{
		/* point to the second block of the output data */
		TST_OutputBuffers[CRYS_FLOW_RC4][j].buffer_ptr = (DxUint8_t*)TST_FLOW_OutputData[CRYS_FLOW_RC4] + (j)*blockSize;
    
		TST_OutputBuffers[CRYS_FLOW_RC4][j].bufferSize = blockSize;                
	}
 	
    TST_FLOWParamsInfo.inputBuffersArrays    = TST_InputBuffers;
    TST_FLOWParamsInfo.inputBuffersArraySize = 2;
    
    TST_FLOWParamsInfo.outputBuffersArrays   = TST_OutputBuffers[CRYS_FLOW_RC4];
    TST_FLOWParamsInfo.outputBuffersArraySize = 2;

        	    	
 	/* initialize RC4 engine data */
 	CRYS_ATP_TST_FLOW_InitRC4EngineData(TST_index);
 	
 
    /* Init RC4 flow */
 	/*****************/
 	TST_ATP_Error = CRYS_FLOW_RC4Init(CRYS_FLOW_TypeStatic,
                 	                  &TST_FLOWParamsInfo,
                                      &TST_FLOWRC4EngineData,  
                                      &flowId);
                      
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_RC4Init is done\n"));
                        
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_RC4Init",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
    
   
    /* Send interrupts to execute cyclic flow operation */
    /****************************************************/
        
    /* several times send input and output interupts to execute*/
    /* several time flow operation */
    for (j = 0; j < 2; j++)
    {
        /* Send interrupt that input buffers are ready */
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.inputInterruptId);
        
        /* Send interrupt that input buffers are ready */
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.inputInterruptId);
        
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.outputInterruptId);
            
        CRYS_ATP_TST_FLOW_SendInterrupt(TST_FLOWParamsInfo.outputInterruptId);
		    
	
        /* wating for DMA operation to be finished and correct
           output data to be updated  */                       
        for (delay = 0; delay < 100000; delay++);
        
        /* accumulate output data after each cycle iteration */
        for (i = 0; i < TST_FLOWParamsInfo.outputBuffersArraySize; ++i)
		{
		    DX_VOS_FastMemCpy(pAccumulatorOutputData,
                              TST_FLOWParamsInfo.outputBuffersArrays[i].buffer_ptr,
                              TST_FLOWParamsInfo.outputBuffersArrays[i].bufferSize);       
                              
            pAccumulatorOutputData += TST_FLOWParamsInfo.outputBuffersArrays[i].bufferSize;                                                                                
		}
	
    }
	    
    
    /* Finish RC4 flow with size of the last input buffer */
    /******************************************************/
    TST_ATP_Error = CRYS_FLOW_Finish(flowId,
                                     0);  
                     
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Finish is done\n"));                             
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Finish",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
                     
   
    /* Get results */
    /******************************************************/
    do
    {
        
        TST_ATP_Error = CRYS_FLOW_GetResults(flowId,
		                                 (DxUint8_t*)TST_FLOW_Hash_OutputData,
		                                 CRYS_HASH_RESULT_SIZE_IN_WORDS);
	
    }while(TST_ATP_Error == DX_SEP_FLOW_GET_RESULT_NOT_READY_ERROR);
    
   
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_GetResults is done\n"));
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_GetResults",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
    
    /* Terminate flow */
    /******************/
    TST_ATP_Error = CRYS_FLOW_Terminate(flowId);
    
    ATP_LOG_TST_PRINT((CRYS_ATP_TST_DBG_HIGH,"CRYS_FLOW_Terminate is done\n"));                             
    
    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,"CRYS_FLOW_Terminate",TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

    #if CRYS_ATP_TST_EXIT_ON_ERROR
        if (TST_TestStatus != TESTPASS) 
            return TESTFAIL;
    #endif  
    
    /* Read data from the output buffers and compare to expected result */
    /********************************************************************/                             
    pExpectedOut = TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Expected_cyclicOperation_data;
	

    /* compare and prints results of test */
	TST_ATP_Error += (CRYSError_t)DX_VOS_MemCmp(
												TST_FLOW_Cyclic_OutputData,
                                 				pExpectedOut,
                                 				TST_FLOW_DATA_VEC_SIZE_IN_BYTS);
                                    
                                     			
	/*Print the outputted and then the expected result after mem compare */
	ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
							   "\nData outputted by engine [output buffer]-- \n",
							   (DxUint8_t*)TST_FLOW_Cyclic_OutputData, 
							   TST_FLOW_DATA_VEC_SIZE_IN_BYTS); 

	ATP_LOG_TST_DisplayBuffer (CRYS_ATP_TST_DBG_HIGH,
							  "\nData Expected by engine --\n",
							   (DxUint8_t*)pExpectedOut,
							   TST_FLOW_DATA_VEC_SIZE_IN_BYTS);                 	                                     			
		

    TST_TestStatus = TST_ATP_CheckErrorReturn(TST_ATP_Error,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_RC4FLOW_Acceptance_TestData[TST_index].TST_Name,TST_MasterTestName);

	#if CRYS_ATP_TST_EXIT_ON_ERROR
	if (TST_TestStatus != TESTPASS) 
    	return TESTFAIL;
    #endif  
    
	                                
  	return TST_TestStatus;
 }/* End of CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines*/ 


/*****************************************************************************
 * Function Name:                                                           
 *  CRYS_ATP_TST_FLOW_RC4STATIC_Cyclic_Acceptance
 *  
 * Inputs:
 *  None
 *
 * Outputs: 
 *  CRYSError_t - Function error return                                     
 *
 * Description:                                                                 
 *  This function Is a Acceptance test for static cyclic RC4 FLOW API's
 
 * Algorithm:     
 *	This function initializes RC4 flow with static type and other parameters,
 * and executes several times flow on the same input buffer. It goes throw all test
 * vectors and check cyclic acceptance.
 ******************************************************************************/                                
CRYSError_t CRYS_ATP_TST_FLOW_RC4STATIC_Cyclic_Acceptance ( void ) 
{

	/********* TST Variables Definitions ************/
	int                     	 TST_index;
	CRYSError_t             	 TST_TestStatus = TESTPASS;
	char                     	 TST_MasterTestName[TST_FUNC_STRING_LEN] = "CRYS_ATP_TST_FLOW_RC4STATIC_Cyclic_Acceptance"; 
	

	/* initialize input and output buffers */
	TST_FLOWParamsInfo.inputBuffersArrays  = DX_NULL;
	TST_FLOWParamsInfo.outputBuffersArrays = DX_NULL;
	
	
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n"));
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"** CRYS_ATP_TST_FLOW_RC4STATIC_Cyclic_Acceptance Tests ********************* \n"));      
	ATP_LOG_TST_PRINT((CRYS_ATP_TST_MSG,"********************************************************** \n \n"));


	/* Go throw all test vectors and check cyclic acceptance */
	/*********************************************************/
	for (TST_index =0 ; TST_index < TST_NumberOf_RC4FLOW_AcceptanceTests ; TST_index++) /*To run on all test vectors*/
    {
     	
     	TST_TestStatus = CRYS_ATP_TST_FLOW_RC4STATIC_ONETEST_Cyclic_Acceptance(TST_index, TST_MasterTestName);
     	
#if CRYS_ATP_TST_EXIT_ON_ERROR
		if (TST_TestStatus != TESTPASS) 
		    return TESTFAIL;
#endif  		                                                               

	                            
	}/* End of TST_index */     
    
  	return TST_TestStatus;
 }/* End of CRYS_ATP_TST_FLOW_RC4STATIC_Acceptance_WithAdditionalEngines*/ 

 

#endif
#endif
