/*! \file 
**********************************************************************************
*Title:                        Discretix OMA DRM v2 Toolkit source file
*
* Filename:                     Toolkit, Certificate Handling
*
* Project, Target, subsystem:   Toolkit, OMA DRM
* 
* Created:                      02.04.2008
*
* Modified:                     02.04.2008
*
* \Author                       Ira Boguslavsky
*
* \Remarks
*           Copyright (C) 2007 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/
/*----------- External include files ----------------------------------------*/
#include "DX_VOS_Mem.h"
#include "DX_VOS_String.h"
#include "DX_VOS_Stdio.h"
#include "DX_VOS_BaseTypes.h"

#include "error.h"

#include "SEPDriver.h"

#ifndef DX_NO_TLK_SCLK_SUPPORT
#include "tlk_sclk_api_types.h"
#include "tlk_sclk_api_defs.h"
#else
	#include "tlk_cert_sclk_api_stub.h"
	#include "tlk_cert_sclk_api_stub_types.h"
#endif
/*----------- Local include files -------------------------------------------*/
#include "tlk_cert_api.h"
#include "tlk_cert_errors.h"
#include "tlk_cert_def.h"
#include "tlk_cert_host_op_code.h"


DxError_t TLK_CERT_WorkspaceCheck(DxByte_t			            *workspace_ptr,
                                  DxUint32_t			         workspaceSizeInBytes,
                                  DxUint32_t			         requiredWorkspaceSize);


/*MACRO for checking return code form driver*/
#define TLK_CERT_HOST_DRIVER_ERROR_CHECK(errorRC,exitMark)          \
		if (DX_SUCCESS != errorRC)									\
		{	errorRC = TLK_CERT_RC_ERROR_API_FAIL;		    		\
			goto exitMark;}


#ifdef TLK_CERT_SEP_SIMULATOR
	#include "tlk_cert_api_duplicate_wrapper.h"
	#include "tlk_cert_llf_duplicate_wrapper.h"
	#define TLK_CERT_START_OFFSET                       0x8
#else
	#define TLK_CERT_START_OFFSET                       0x0
#endif

#define TLK_CERT_WORD_ALLIGN(arg)                                                           \
                                 /*lint -save -e778*/                                           \
                                ((((DxUint32_t)(arg)) & (0x3)) ?                                \
                                (((((DxUint32_t)(arg))>>(2))+1)<<(2)) : ((DxUint32_t)(arg)))    \
                                /*lint -restore */

/*---------------------------------------------------------------------------*/
/*               API FUNCTIONS                                               */
/*---------------------------------------------------------------------------*/
/************************************************************************/
/* TLK_CERT_CertificateIdCompute                                        */
/************************************************************************/


DxError_t TLK_CERT_CertificateIdCompute(    const   TLK_CERT_Buffer_t           *certificate_ptr, 
                                                    DxSha1Result_t               certificateId)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    DxUint32_t   certSMPhy;
    DxUint32_t   certSMVirt;
    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS +       /*op code*/
                                DX_1_WORD_PARAMS +       /*certificate_ptr*/    /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS];                              /*buff_ptr*/
    DxUint32_t   paramOutBuffer[sizeof(DxSha1Result_t)]; /*certificateId*/

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_PARAM( certificate_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
    
  /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();
    
	/************************************************************************/
    /*  Address Convertion                                                  */
    /************************************************************************/
	error = SEPDriver_AllocateDataPoolMemory(  certificate_ptr->buff_ptr, 
                                               certificate_ptr->buffSizeInBytes, 
                                               &certSMPhy, 
                                               &certSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(certSMVirt, 
                                             (DxUint8_t*)certificate_ptr->buff_ptr, 
                                              certificate_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;


    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CERTIFICATE_ID_COMPUTE_MSG_OP_CODE;
    paramInBuffer[1] = certificate_ptr->buffSizeInBytes;
    paramInBuffer[2] = certSMPhy;

     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);


    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CERTIFICATE_ID_COMPUTE_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

	sramOffset += 4;
	
    /* Get certificateId */
    error = SEPDriver_ReadParamater((DxUint32_t)( certificateId),
                                                  sizeof(DxSha1Result_t),
                                                  TLK_CERT_WORD_ALLIGN(sizeof(DxSha1Result_t)),
                                                 &sramOffset,
                                                  DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

end_function_unlock:   

    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}

DxError_t TLK_CERT_CertificateParamGet(     const   TLK_CERT_Buffer_t           *certificate_ptr, 
                                                    TLK_CERT_CertParameters_t   *certificateParamList_ptr)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    DxUint32_t   certSMPhy;
    DxUint32_t   certSMVirt;
    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS +       /*op code*/
                                DX_1_WORD_PARAMS +       /*certificate_ptr*/    /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS];                              /*buff_ptr*/
    DxUint32_t   paramOutBuffer[sizeof(TLK_CERT_CertParameters_t)]; /*certificateParamList_ptr*/

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_PARAM( certificate_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
    
     /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();

	/************************************************************************/
    /*  Address Convertion                                                  */
    /************************************************************************/
	error = SEPDriver_AllocateDataPoolMemory(  certificate_ptr->buff_ptr, 
                                               certificate_ptr->buffSizeInBytes, 
                                               &certSMPhy, 
                                               &certSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(certSMVirt, 
                                             (DxUint8_t*)certificate_ptr->buff_ptr, 
                                              certificate_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

   

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CERTIFICATE_PARAMGET_MSG_OP_CODE;
    paramInBuffer[1] = (DxUint32_t)(certificate_ptr->buffSizeInBytes);
    paramInBuffer[2] = (DxUint32_t)certSMPhy;

     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);


    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CERTIFICATE_PARAMGET_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

	sramOffset += 4;
    /* Get certificateParamList_ptr */
    error = SEPDriver_ReadParamater((DxUint32_t)( certificateParamList_ptr),
                                                  sizeof(TLK_CERT_CertParameters_t),
                                                  sizeof(TLK_CERT_CertParameters_t),
                                                 &sramOffset,
                                                  DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    
end_function_unlock:   

    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}

/*TLK_CERT_ChainValidationInit*/
DxError_t TLK_CERT_ChainValidationInit(     TLK_CERT_ContextObj_t       *contextObject_ptr)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   		/*offset into SRAM*/
    DxUint32_t   contObjSMPhy;
    DxUint32_t   contObjSMVirt;


    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS +        /*op code*/
                                DX_1_WORD_PARAMS +		  /*contextObject_ptr*/		/*buffSizeInBytes*/
                                DX_1_WORD_PARAMS];									/*buff_ptr*/

                                
    DxUint32_t   paramOutBuffer[sizeof(TLK_CERT_ContextObj_t)]; /*contextObject_ptr*/

    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();
    
    /************************************************************************/
    /*  Address Conversion                                                  */
    /************************************************************************/    
    error = SEPDriver_AllocateDataPoolMemory(  (DxUint8_t*)contextObject_ptr, 
                                               sizeof(TLK_CERT_ContextObj_t), 
                                               &contObjSMPhy, 
                                               &contObjSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(  contObjSMVirt, 
                                             (DxUint8_t*)contextObject_ptr, 
                                              sizeof(TLK_CERT_ContextObj_t));
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_PARAM( contextObject_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CHAIN_VALIDATION_INIT_MSG_OP_CODE;
    paramInBuffer[1] = sizeof(TLK_CERT_ContextObj_t);
    paramInBuffer[2] = contObjSMPhy;

     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CHAIN_VALIDATION_INIT_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

    error = SEPDriver_ReadFromDataPoolMemory(contObjSMVirt,
    										 (DxUint8_t*)contextObject_ptr,
    									 	sizeof(TLK_CERT_ContextObj_t));
		    										
                                                  
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
    
end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}

#define DX_ALIGN_TO_WORD(arg)   ((((DxUint32_t)(arg)) & (0x3)) ? \
    (((((DxUint32_t)(arg))>>(2))+1)<<(2)) : ((DxUint32_t)(arg)))

/*TLK_CERT_ChainValidationProcess*/
DxError_t TLK_CERT_ChainValidationProcess(  const   TLK_CERT_Buffer_t                   *prevCertificate_ptr,
                                            const   TLK_CERT_Buffer_t                   *currCertificate_ptr, 
                                            const   TLK_SCLK_ServiceClockDescriptor_t   *servClkDesc_ptr,
													TLK_CERT_Buffer_t                   *servClkPwd_ptr,
                                                    TLK_CERT_ContextObj_t               *contextObject_ptr,
                                                    DxUint8_t                           *workspace_ptr,
                                            const   DxUint32_t                           workspaceSizeInBytes)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    DxUint32_t   prevCertSMPhy;
    DxUint32_t   prevCertSMVirt;
    DxUint32_t   currCertSMPhy;
    DxUint32_t   currCertSMVirt;
    DxUint32_t   contObjSMPhy;
    DxUint32_t   contObjSMVirt;
    
#ifdef DX_NO_TLK_SCLK_SUPPORT
  	DxUint32_t servClkDesc;
#endif
  
    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS +       /*op code*/
                                DX_1_WORD_PARAMS +       /*prevCertificate_ptr*/    /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS +                                  /*buff_ptr*/
                                DX_1_WORD_PARAMS +       /*currCertificate_ptr*/    /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS +                                  /*buff_ptr*/
								DX_1_WORD_PARAMS +		 /*contextObject_ptr*/		/*buffSizeInBytes*/
								DX_1_WORD_PARAMS +		                      		/*buff_ptr*/
                                DX_1_WORD_PARAMS];									/*pwd len*/
    DxUint32_t   paramOutBuffer[DX_2_WORDS_PARAMS]; 


    /* Check input parameters */
    if (TLK_CERT_IS_NULL_3PARAMS( prevCertificate_ptr,
    							  currCertificate_ptr,
                                  contextObject_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
    
#ifndef DX_NO_TLK_SCLK_SUPPORT
	if (TLK_CERT_IS_NULL_PARAM(servClkDesc_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
#endif

	/************************************************************************/
    /*  Update Base Address of previous certificate                         */
    /************************************************************************/
    //g_TLK_CERT_PrevCertificateBaseAddress.buff_ptr 		  = currCertificate_ptr->buff_ptr;
	//g_TLK_CERT_PrevCertificateBaseAddress.buffSizeInBytes = currCertificate_ptr->buffSizeInBytes;

    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();
    
    /************************************************************************/
    /*  Address Conversion                                                  */
    /************************************************************************/
    /* Allocate memory for the priv certificate if it is not NULL */    
    if (prevCertificate_ptr->buff_ptr!=DX_NULL)
    {
    	
		error = SEPDriver_AllocateDataPoolMemory(  (DxUint8_t*)(prevCertificate_ptr->buff_ptr), 
	                                               DX_ALIGN_TO_WORD(prevCertificate_ptr->buffSizeInBytes), 
	                                               &prevCertSMPhy, 
	                                               &prevCertSMVirt);
		TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

		error = SEPDriver_WriteToDataPoolMemory(  prevCertSMVirt, 
	                                             (DxUint8_t*)prevCertificate_ptr->buff_ptr, 
	                                              prevCertificate_ptr->buffSizeInBytes);
		TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
    }
	else
	{
		prevCertSMPhy = DX_NULL;
		prevCertSMVirt = DX_NULL;
	}
    
     /* Allocate memory for the current certificate */ 
	error = SEPDriver_AllocateDataPoolMemory(  currCertificate_ptr->buff_ptr, 
                                               DX_ALIGN_TO_WORD(currCertificate_ptr->buffSizeInBytes), 
                                               &currCertSMPhy, 
                                               &currCertSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(  currCertSMVirt, 
                                             (DxUint8_t*)currCertificate_ptr->buff_ptr, 
                                              currCertificate_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
	
	 /* Allocate memory for the context object */ 
    error = SEPDriver_AllocateDataPoolMemory(  (DxUint8_t*)contextObject_ptr, 
                                               sizeof(TLK_CERT_ContextObj_t), 
                                               &contObjSMPhy, 
                                               &contObjSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(  contObjSMVirt, 
                                             (DxUint8_t*)contextObject_ptr, 
                                              sizeof(TLK_CERT_ContextObj_t));
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CHAIN_VALIDATION_PROCESS_MSG_OP_CODE;
    if (prevCertificate_ptr->buff_ptr!=DX_NULL)
    {
    	paramInBuffer[1] = prevCertificate_ptr->buffSizeInBytes;
    	paramInBuffer[2] = prevCertSMPhy;    	
    }
    else
    {
		paramInBuffer[1] = 0;
    	paramInBuffer[2] = 0;    	
    }
    paramInBuffer[3] = currCertificate_ptr->buffSizeInBytes;
    paramInBuffer[4] = currCertSMPhy;
    paramInBuffer[5] = sizeof(TLK_CERT_ContextObj_t);
	paramInBuffer[6] = contObjSMPhy;
	paramInBuffer[7] = servClkPwd_ptr->buffSizeInBytes;

     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_8_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_8_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

	error = SEPDriver_WriteParamater((DxUint32_t)servClkPwd_ptr->buff_ptr,
												 servClkPwd_ptr->buffSizeInBytes,
											 	TLK_SCLK_MAX_PWD_LEN_IN_BYTES,
												&sramOffset,
												DX_FALSE);

	if(error != DX_SUCCESS)
	{
		goto end_function_unlock;
	}
	/* Send Service Descriptor */
    
#ifndef DX_NO_TLK_SCLK_SUPPORT
    error = SEPDriver_WriteParamater((DxUint32_t)servClkDesc_ptr,
                                      sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                      TLK_SCLK_WORD_ALLIGN(sizeof(TLK_SCLK_ServiceClockDescriptor_t)),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
#else
	servClkDesc	= 0;
    error = SEPDriver_WriteParamater((DxUint32_t)&servClkDesc,
                                      sizeof(servClkDesc),
                                      sizeof(servClkDesc),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
	
#endif
    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CHAIN_VALIDATION_PROCESS_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }
	
    /* Get contextObject_ptr */
    error = SEPDriver_ReadFromDataPoolMemory(contObjSMVirt,
    										 (DxUint8_t*)contextObject_ptr,
    										sizeof(TLK_CERT_ContextObj_t));
    										
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
    
    /* Update context object base address => must be equal to prev, because in the 
    next function call this certificate will be prev */
    
    contextObject_ptr->certificateBaseAddress = (prevCertSMPhy&0x00FFFFFF)|0xA0000000;
    
end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}

/*TLK_CERT_ChainValidationTerminate*/
DxError_t TLK_CERT_ChainValidationTerminate(        TLK_CERT_ContextObj_t       *contextObject_ptr,
                                                    TLK_CERT_CPVO_t             *cvpoObject_ptr)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    DxUint32_t   contObjSMPhy;
    DxUint32_t   contObjSMVirt;
    DxUint32_t   cvpoSMPhy;
    DxUint32_t   cvpoSMVirt;
    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS +       /*op code*/
                                DX_1_WORD_PARAMS +       /*contextObject_ptr*/  
                                DX_1_WORD_PARAMS];       /*cvpoObject_ptr*/    
    
    DxUint32_t   paramOutBuffer[DX_2_WORDS_PARAMS]; /*contextObject_ptr*/
    

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_2PARAMS( cvpoObject_ptr,
                                  contextObject_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
    
    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();

    /************************************************************************/
    /*  Address Conversion                                                  */
    /************************************************************************/
	error = SEPDriver_AllocateDataPoolMemory(  (DxUint8_t*)contextObject_ptr, 
                                               sizeof(TLK_CERT_ContextObj_t), 
                                               &contObjSMPhy, 
                                               &contObjSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(  contObjSMVirt, 
                                             (DxUint8_t*)contextObject_ptr, 
                                              sizeof(TLK_CERT_ContextObj_t));
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

    error = SEPDriver_AllocateDataPoolMemory(  (DxUint8_t*)cvpoObject_ptr, 
                                               sizeof(TLK_CERT_CPVO_t), 
                                               &cvpoSMPhy, 
                                               &cvpoSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

/*	error = SEPDriver_WriteToDataPoolMemory(  cvpoSMVirt, 
                                             (DxUint8_t*)cvpoObject_ptr, 
                                              sizeof(TLK_CERT_CPVO_t));
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;*/



    

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CHAIN_VALIDATION_TERMINATE_MSG_OP_CODE;
    paramInBuffer[1] = contObjSMPhy;
    paramInBuffer[2] = cvpoSMPhy;


     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CHAIN_VALIDATION_TERMINATE_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

    /* Get cvpoObject_ptr */
	error = SEPDriver_ReadFromDataPoolMemory(cvpoSMVirt,
    									     (DxUint8_t*)cvpoObject_ptr,
    										 sizeof(TLK_CERT_CPVO_t));
    										
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}

/*TLK_CERT_NonceIssuance*/
DxError_t TLK_CERT_NonceIssuance(   TLK_CERT_Nonce_t                     *nonce_ptr,
									TLK_SCLK_ServiceClockDescriptor_t    *servClkDesc_ptr,
								    TLK_CERT_Buffer_t                    *servClkPwd_ptr,
									DxUint8_t                            *workspace_ptr,
									DxUint32_t                            workspaceSizeInBytes)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/

    DxUint32_t   paramInBuffer [DX_2_WORDS_PARAMS];       /*op code*/

    DxUint32_t   paramOutBuffer[sizeof(TLK_CERT_ContextObj_t)]; /*contextObject_ptr*/
    
#ifdef DX_NO_TLK_SCLK_SUPPORT
  	DxUint32_t servClkDesc;
#endif

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_PARAM( nonce_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }

#ifndef DX_NO_TLK_SCLK_SUPPORT
	if (TLK_CERT_IS_NULL_PARAM(servClkDesc_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
#endif
    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

	paramInBuffer[0] = TLK_CERT_NONCE_ISSUANCE_MSG_OP_CODE;
	paramInBuffer[1] = servClkPwd_ptr->buffSizeInBytes;

     /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_2_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_2_WORDS_PARAMS,
                                                 &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
    
	error = SEPDriver_WriteParamater((DxUint32_t)servClkPwd_ptr->buff_ptr,
		servClkPwd_ptr->buffSizeInBytes,
		TLK_SCLK_MAX_PWD_LEN_IN_BYTES,
		&sramOffset,
		DX_FALSE);

	if(error != DX_SUCCESS)
	{
		goto end_function_unlock;
	}
    /* Send Service Descriptor */   
#ifndef DX_NO_TLK_SCLK_SUPPORT
    error = SEPDriver_WriteParamater((DxUint32_t)servClkDesc_ptr,
                                      sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                      TLK_SCLK_WORD_ALLIGN(sizeof(TLK_SCLK_ServiceClockDescriptor_t)),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
#else
	servClkDesc = 0;
	
    error = SEPDriver_WriteParamater((DxUint32_t)&servClkDesc,
                                      sizeof(servClkDesc),
                                      sizeof(servClkDesc),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
	
#endif

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_NONCE_ISSUANCE_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

    /* Get nonce_ptr */
    error = SEPDriver_ReadParamater((DxUint32_t)( nonce_ptr),
                                                  sizeof(TLK_CERT_Nonce_t),
                                                  sizeof(TLK_CERT_Nonce_t),
                                                 &sramOffset,
                                                  DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
    
    /* Get servClkDesc */
    error = SEPDriver_ReadParamater((DxUint32_t)( servClkDesc_ptr),
    											  sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                                  sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                                 &sramOffset,
                                                  DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }											
    
end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}


DxError_t TLK_CERT_ResponseProcess(         const   TLK_CERT_Buffer_t                   *response_ptr,
                                            const   TLK_CERT_Nonce_t                    *nonce_ptr,
                                            const   TLK_CERT_Buffer_t                   *certForCheck_ptr,
                                            const   TLK_CERT_Buffer_t                   *certResponder_ptr,
                                            const   TLK_CERT_Buffer_t                   *certCA_ptr,
                                            		TLK_SCLK_ServiceClockDescriptor_t   *servClkDescNonceValid_ptr,
                                            		TLK_CERT_Buffer_t					*servClkDescNonceValidPwd_ptr,
                                                    TLK_SCLK_ServiceClockDescriptor_t   *servClkDesc_ptr,
								    				TLK_CERT_Buffer_t                   *servClkPwd_ptr,
                                                    TLK_CERT_RV0_t                      *rvo_ptr,
                                                    DxUint8_t                           *workspace_ptr,
                                                    DxUint32_t                           workspaceSizeInBytes)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    DxUint32_t   responseSMPhy;
    DxUint32_t   responseSMVirt;
    DxUint32_t   certForCheckSMPhy;
    DxUint32_t   certForCheckSMVirt;
    DxUint32_t   certResponderSMPhy;
    DxUint32_t   certResponderSMVirt;
    DxUint32_t   certCASMPhy;
    DxUint32_t   certCASMVirt;
	TLK_CERT_Nonce_t dummyNonce = {0x0};
	TLK_CERT_Nonce_t *localNoncePtr;
    
#ifdef DX_NO_TLK_SCLK_SUPPORT
  	DxUint32_t servClkDesc;
  	DxUint32_t servClkDescNonceValid;
#endif



    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS + /*op code*/
                                DX_1_WORD_PARAMS + /*response_ptr*/         /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS +                          /*buff_ptr*/  
                                DX_1_WORD_PARAMS + /*certForCheck_ptr*/     /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS +                          /*buff_ptr*/  
                                DX_1_WORD_PARAMS + /*certResponder_ptr*/    /*buffSizeInBytes*/
                                DX_1_WORD_PARAMS +                          /*buff_ptr*/  
                                DX_1_WORD_PARAMS + /*certCA_ptr*/           /*buffSizeInBytes*/
								DX_1_WORD_PARAMS +                          /*buff_ptr*/
								DX_1_WORD_PARAMS +                          /*nonce_ptr*/
                                DX_1_WORD_PARAMS + 							/*nonce valid pwd len */
                                DX_1_WORD_PARAMS];							/*pwd len*/
                                

    DxUint32_t   paramOutBuffer[sizeof(TLK_CERT_ContextObj_t)]; /*contextObject_ptr*/

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_2PARAMS( response_ptr,
                                  certForCheck_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }

    if (TLK_CERT_IS_NULL_2PARAMS( certCA_ptr,
                                  rvo_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }

#ifndef DX_NO_TLK_SCLK_SUPPORT
	if (TLK_CERT_IS_NULL_PARAM(servClkDesc_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }
#endif
    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();
    

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);
    
	/************************************************************************/
    /*  Address Convertion                                                  */
    /************************************************************************/
	/* response_ptr */
	error = SEPDriver_AllocateDataPoolMemory(  response_ptr->buff_ptr, 
                                               response_ptr->buffSizeInBytes, 
                                               &responseSMPhy, 
                                               &responseSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(			 responseSMVirt, 
                                             (DxUint8_t*)response_ptr->buff_ptr, 
                                              			 response_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
	
	/* certForCheck_ptr */
	error = SEPDriver_AllocateDataPoolMemory(  certForCheck_ptr->buff_ptr, 
                                               certForCheck_ptr->buffSizeInBytes, 
                                               &certForCheckSMPhy, 
                                               &certForCheckSMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(			 certForCheckSMVirt, 
                                             (DxUint8_t*)certForCheck_ptr->buff_ptr, 
                                              			 certForCheck_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
	
	if (certResponder_ptr != DX_NULL)
	{
		/* certResponder_ptr */
		error = SEPDriver_AllocateDataPoolMemory(  certResponder_ptr->buff_ptr, 
	                                               certResponder_ptr->buffSizeInBytes, 
	                                               &certResponderSMPhy, 
	                                               &certResponderSMVirt);
		TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

		error = SEPDriver_WriteToDataPoolMemory(			 certResponderSMVirt, 
	                                             (DxUint8_t*)certForCheck_ptr->buff_ptr, 
	                                              			 certForCheck_ptr->buffSizeInBytes);
		TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
	}
	/* certCA_ptr */
	error = SEPDriver_AllocateDataPoolMemory(  certCA_ptr->buff_ptr, 
                                               certCA_ptr->buffSizeInBytes, 
                                               &certCASMPhy, 
                                               &certCASMVirt);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

	error = SEPDriver_WriteToDataPoolMemory(			 certCASMVirt, 
                                             (DxUint8_t*)certCA_ptr->buff_ptr, 
                                              			 certCA_ptr->buffSizeInBytes);
	TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
                                                
	/************************************************************************/
    /*  Prepare Input parameters                                            */
    /************************************************************************/

    paramInBuffer[0] = TLK_CERT_RESPONSE_PROCESS_MSG_OP_CODE;
    paramInBuffer[1] = response_ptr->buffSizeInBytes;
    paramInBuffer[2] = responseSMPhy;
    paramInBuffer[3] = certForCheck_ptr->buffSizeInBytes;
    paramInBuffer[4] = certForCheckSMPhy;
	if (certResponder_ptr != DX_NULL)
	{
		paramInBuffer[5] = certResponder_ptr->buffSizeInBytes;
    	paramInBuffer[6] = certResponderSMPhy;
	}
	else
	{
		paramInBuffer[5] = 0;
    	paramInBuffer[6] = 0;
	}
    paramInBuffer[7] = certCA_ptr->buffSizeInBytes;
	paramInBuffer[8] = certCASMPhy;
	

	if (nonce_ptr == DX_NULL)
	{
		paramInBuffer[9] = 0x0;
		localNoncePtr = &dummyNonce;
	}
	else
	{
		paramInBuffer[9] = 0x1;
		localNoncePtr = (TLK_CERT_Nonce_t *)nonce_ptr;
	}
	paramInBuffer[10] = servClkDescNonceValidPwd_ptr->buffSizeInBytes;
	paramInBuffer[11] = servClkPwd_ptr->buffSizeInBytes;

	/* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
       	                                         sizeof(DxUint32_t) * DX_12_WORDS_PARAMS,
           	                                     sizeof(DxUint32_t) * DX_12_WORDS_PARAMS,
               	                                &sramOffset,
                   	                             DX_FALSE);
	if(error != DX_SUCCESS)
	{
	    goto end_function_unlock;
	}

	/* Send nonce */
	error = SEPDriver_WriteParamater((DxUint32_t)localNoncePtr,
	                                             sizeof(TLK_CERT_Nonce_t),
	                                             TLK_CERT_WORD_ALLIGN(sizeof(TLK_CERT_Nonce_t)),
	                                             &sramOffset,
	                                             DX_FALSE);	
	if(error != DX_SUCCESS)
	{
	    goto end_function_unlock;
	}
	 
	/* Send nonce validation service clock passwrod */
	error = SEPDriver_WriteParamater((DxUint32_t)servClkDescNonceValidPwd_ptr->buff_ptr,
										servClkDescNonceValidPwd_ptr->buffSizeInBytes,
										TLK_SCLK_MAX_PWD_LEN_IN_BYTES,
										&sramOffset,
										DX_FALSE);
	if(error != DX_SUCCESS)
	{
		goto end_function_unlock;
	}

	/* Send service clock passwrod */
	error = SEPDriver_WriteParamater((DxUint32_t)servClkPwd_ptr->buff_ptr,
										servClkPwd_ptr->buffSizeInBytes,
										TLK_SCLK_MAX_PWD_LEN_IN_BYTES,
										&sramOffset,
										DX_FALSE);
	if(error != DX_SUCCESS)
	{
		goto end_function_unlock;
	}

	/* Send nonce validation service descriptor */
#ifndef DX_NO_TLK_SCLK_SUPPORT
    error = SEPDriver_WriteParamater((DxUint32_t)servClkDescNonceValid_ptr,
                                      sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                      TLK_SCLK_WORD_ALLIGN(sizeof(TLK_SCLK_ServiceClockDescriptor_t)),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
#else
	servClkDesc  = 0;
    error = SEPDriver_WriteParamater((DxUint32_t)&servClkDescNonceValid,
                                      sizeof(servClkDesc),
                                      sizeof(servClkDesc),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
	
#endif

	/* Send Service Descriptor */   
#ifndef DX_NO_TLK_SCLK_SUPPORT
    error = SEPDriver_WriteParamater((DxUint32_t)servClkDesc_ptr,
                                      sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                      TLK_SCLK_WORD_ALLIGN(sizeof(TLK_SCLK_ServiceClockDescriptor_t)),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
#else
	servClkDesc  = 0;
    error = SEPDriver_WriteParamater((DxUint32_t)&servClkDesc,
                                      sizeof(servClkDesc),
                                      sizeof(servClkDesc),
                                     &sramOffset,
                                     DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
	
#endif

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_RESPONSE_PROCESS_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

	sramOffset+=4;
	
    /* Get rvo_ptr */
    error = SEPDriver_ReadParamater((DxUint32_t)( rvo_ptr),
                                    sizeof(TLK_CERT_RV0_t),
                                    sizeof(TLK_CERT_RV0_t),
                                    &sramOffset,
                                    DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

	error = SEPDriver_ReadParamater((DxUint32_t)( servClkDesc_ptr),
                                    sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                    sizeof(TLK_SCLK_ServiceClockDescriptor_t),
                                    &sramOffset,
                                    DX_FALSE);
end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}


DxError_t TLK_CERT_CertFromResponseExtract( const   TLK_CERT_Buffer_t           *response_ptr,
                                                    TLK_CERT_Buffer_t           *cert_ptr, 
                                                    DxGeneralizedTime_t         *exparationTime_ptr)
{
    DxError_t    error        = TLK_CERT_RC_OK;
    DxUint32_t   sramOffset   = TLK_CERT_START_OFFSET;   /*offset into SRAM*/
    
    DxUint32_t   responseSMPhy;
    DxUint32_t   responseSMVirt;

    DxUint32_t   paramInBuffer [DX_1_WORD_PARAMS+       /*op code*/
								DX_1_WORD_PARAMS+		/*response_ptr->buffSizeInBytes*/
								DX_1_WORD_PARAMS];		/*response_ptr->buff_ptr*/
    DxUint32_t   paramOutBuffer[sizeof(TLK_CERT_ContextObj_t)]; /*contextObject_ptr*/

    /* Check input parameters */
    if (TLK_CERT_IS_NULL_2PARAMS( cert_ptr,
                                  exparationTime_ptr))
    {
        return TLK_CERT_RC_ERROR_API_NULL_POINTER;
    }

    /************************************************************************/
    /*  Lock access to SEP                                                  */
    /************************************************************************/
    SEPDriver_Lock();
    
    /* certResponder_ptr */
		error = SEPDriver_AllocateDataPoolMemory(  response_ptr->buff_ptr, 
	                                             response_ptr->buffSizeInBytes, 
	                                             &responseSMPhy, 
	                                             &responseSMVirt);
		TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;
		
    error = SEPDriver_WriteToDataPoolMemory(responseSMVirt, 
                                            (DxUint8_t*)response_ptr->buff_ptr, 
                                            response_ptr->buffSizeInBytes);
	  TLK_CERT_HOST_DRIVER_ERROR_CHECK(error,end_function_unlock) ;

    /************************************************************************/
    /* Start sending message to SeP                                         */
    /************************************************************************/
    SEPDriver_StartMessage(&sramOffset);

    paramInBuffer[0] = TLK_CERT_CERT_FROM_RESPONSE_EXTRACT_MSG_OP_CODE;
    paramInBuffer[1] = response_ptr->buffSizeInBytes;
    paramInBuffer[2] = (DxUint32_t)responseSMPhy/*(response_ptr->buff_ptr)*/;

    /* Send constant part */
    error = SEPDriver_WriteParamater((DxUint32_t)paramInBuffer,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                 sizeof(DxUint32_t) * DX_3_WORDS_PARAMS,
                                                &sramOffset,
                                                 DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* End message                                                          */
    /************************************************************************/
    SEPDriver_EndMessage(sramOffset);

    /************************************************************************/
    /* Wait for the response                                                */
    /************************************************************************/
    error = SEPDriver_POLL_FOR_REPONSE();
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /************************************************************************/
    /* Start reading message from the SEP                                   */
    /************************************************************************/
    /* Start the message */
    error = SEPDriver_StartIncomingMessage(&sramOffset);
    if(error)
    {
        goto end_function_unlock;
    }
    /* Read opcode + status  */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer,
                                                sizeof(DxUint32_t) * 2,
                                                sizeof(DxUint32_t) * 2,
                                               &sramOffset ,
                                                DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* check the opcode */
    if(paramOutBuffer[0] != TLK_CERT_CERT_FROM_RESPONSE_EXTRACT_MSG_OP_CODE)
    {
        error = DX_WRONG_OPCODE_FROM_SEP_ERR;
        goto end_function_unlock;
    }

    /* check the status */
    if(paramOutBuffer[1] != TLK_CERT_RC_OK)
    {
        error = paramOutBuffer[1];
        goto end_function_unlock;
    }

    /* Get cvpoObject_ptr */
    error = SEPDriver_ReadParamater((DxUint32_t)paramOutBuffer/*( cert_ptr)*/,
                                    sizeof(TLK_CERT_Buffer_t),
                                    sizeof(TLK_CERT_Buffer_t),
                                    &sramOffset,
                                    DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }

    /* set the num of bytes */
    cert_ptr->buffSizeInBytes = paramOutBuffer[0];
    
    /* copy the extracted string from pool */
    error = SEPDriver_ReadFromDataPoolMemory(responseSMVirt + paramOutBuffer[1] - responseSMPhy, 
                                            (DxUint8_t*)cert_ptr->buff_ptr, 
                                            cert_ptr->buffSizeInBytes);
    
  
	  sramOffset+=4;
    /* Get exparationTime_ptr */
    error = SEPDriver_ReadParamater((DxUint32_t)( exparationTime_ptr),
                                    sizeof(DxGeneralizedTime_t),
                                    sizeof(DxGeneralizedTime_t),
                                    &sramOffset,
                                    DX_FALSE);
    if(error != DX_SUCCESS)
    {
        goto end_function_unlock;
    }
end_function_unlock:   
    /* lock access to the SEP */
    SEPDriver_Unlock();

    return error;
}


