/*! \file    
**********************************************************************************	
* Title:						Discretix SST API Source file						 					
*																			
* Filename:						sst_api_authentication.c															
*																			
* Project, Target, subsystem:	SST Host IF, APIs	
*                               
* Created:						01.07.2007																
*                               
* Modified:																				
*                               
* \Author						Ira Boguslavsky															
*																			
* \Remarks						
*           Copyright (C) 2006 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/

/*----------- External include files ----------------------------------------*/
#include "DX_VOS_Mem.h"
#include "SEPDriver.h"
#include "error.h"
#include "sst_errors.h"
#include "sst_sep_errors.h"
#include "sst_types.h"
#include "sst_host_util.h"
#include "sst_host_def.h"
/*----------- Local include files -------------------------------------------*/
#include "sst_test_flags.h"
#include "sst_host_op_code.h"

/*----------- Local include files -------------------------------------------*/
/*----------- Local Variable declarations -----------------------------------*/
/*----------- Local function declarations -----------------------------------*/
/*----------- Local constant definitions  -----------------------------------*/

/*---------------------------------------------------------------------------*/
/*               API FUNCTIONS                                               */
/*---------------------------------------------------------------------------*/
 /*Authentication and Authorization services*/



/*SST_AuthenticatorPasswordCreate*/
/* Note: This function has parameter (aPwd_ptr) with variable length, which must be written into shared memory. */
/*       Because of we do not know which endian use these or another platform, we send this buffer separately   */ 
/*       Thus, we cannot use here SST_SendOneMsgGetResponse function                                            */
DxError_t SST_AuthenticatorPasswordCreate( SSTTxnId_t      aTransactionId,
                                           SSTSessionId_t  aSessionId, 
                                           DxByte_t       *aPwd_ptr,
                                           DxUint32_t      aPwdsizeInBytes,
                                           DxUint32_t      aMaxNumOfTrials,
                                           SSTHandle_t     aInitialCtrlAuth,
                                           SSTHandle_t    *aAuthHandle_ptr,
                                           DxByte_t       *aWorkspace_ptr,
                                           DxUint32_t      aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_10_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_4_WORDS_PARAMS];
    DxError_t               errorRC;
    DxUint32_t				pwdSMPhy;
    DxUint32_t				pwdSMVirt;
    
    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;

    if(DX_IS_NULL_PARAM(aAuthHandle_ptr))
        return SST_RC_ERROR_NULL_POINTER;
	
	/*check password size limit for SEP*/
	if (SST_AUTH_PWD_MAX_SIZE_IN_BYTES < aPwdsizeInBytes)
		return SST_RC_ERROR_SEP_AUTH_PWD_SIZE_INVALID;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/  
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /*allocate memory in SM*/
	if(DX_NULL != aPwd_ptr)
	{		
		errorRC = SEPDriver_AllocateDataPoolMemory(aPwd_ptr, 
	                                               aPwdsizeInBytes, 
	                                               &pwdSMPhy, 
	                                               &pwdSMVirt);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_psw_create) ;
		errorRC = SEPDriver_WriteToDataPoolMemory(pwdSMVirt, 
	                                             (DxUint8_t*)aPwd_ptr, 
	                                              aPwdsizeInBytes);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_psw_create) ;
	}
	
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_PASSWORD_CREATE;

    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aSessionId; 
    paramInBuffer_ptr[3] = (DxUint32_t)aPwdsizeInBytes;
    paramInBuffer_ptr[4] = (DxUint32_t)aMaxNumOfTrials;
    paramInBuffer_ptr[5] = (DxUint32_t)aInitialCtrlAuth.objDigest;
    paramInBuffer_ptr[6] = (DxUint32_t)aInitialCtrlAuth.objId;
    paramInBuffer_ptr[7] = (DxUint32_t)aAuthHandle_ptr->objDigest;
    paramInBuffer_ptr[8] = (DxUint32_t)aAuthHandle_ptr->objId;
	paramInBuffer_ptr[9] = ((aPwd_ptr == DX_NULL)?(DxUint32_t)0:(DxUint32_t)pwdSMPhy);

	/************************************************************************/
	/* Send an input buffer to SeP and wait for output parameters           */
	/************************************************************************/
	errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										/* Input buffer length */
										DX_10_WORDS_PARAMS * sizeof(DxUint32_t), 
										paramOutBuffer_ptr,
										DX_4_WORDS_PARAMS * sizeof(DxUint32_t));
	if (DX_OK != errorRC)
		goto exit_auth_psw_create;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_PASSWORD_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_psw_create;
    }

    /* RC */    
    errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_psw_create);

    /* Output parameters */
    aAuthHandle_ptr->objDigest = paramOutBuffer_ptr[2];
    aAuthHandle_ptr->objId     = paramOutBuffer_ptr[3];


exit_auth_psw_create: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}

/*SST_AuthenticatorPubKeyRSACreate*/    
DxError_t SST_AuthenticatorPubKeyRSACreate( SSTTxnId_t   aTransactionId,
											DxByte_t    *aN_ptr,
											DxByte_t    *aE_ptr,
											DxUint32_t   aESize,
											SSTHandle_t *aAuthHandle_ptr,
											DxByte_t    *aWorkspace_ptr,
											DxUint32_t   aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_7_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_4_WORDS_PARAMS];
    DxError_t               errorRC;  
    DxUint32_t				nSMPhy;
    DxUint32_t				eSMPhy;
    DxUint32_t				nSMVirt;
    DxUint32_t				eSMVirt;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;

    if(DX_IS_NULL_3PARAMS(aN_ptr, aE_ptr,aAuthHandle_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	/*allocate memory in SM*/
	errorRC = SEPDriver_AllocateDataPoolMemory( aN_ptr, 
                                                SST_AUTH_PK_MODULU_SIZE_IN_BYTES, 
                                                &nSMPhy,
                                                &nSMVirt);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_rsa) ;
	errorRC = SEPDriver_AllocateDataPoolMemory( aE_ptr, 
                                                aESize, 
                                                &eSMPhy,
                                                &eSMVirt);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_rsa) ;

	/*copy data to SM*/
	errorRC = SEPDriver_WriteToDataPoolMemory(nSMVirt, 
                                              aN_ptr, 
                                              SST_AUTH_PK_MODULU_SIZE_IN_BYTES);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_rsa) ;
	errorRC = SEPDriver_WriteToDataPoolMemory(eSMVirt, aE_ptr, aESize);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_rsa) ;

	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_PUB_KEY_RSA_CREATE;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)nSMPhy;
    paramInBuffer_ptr[3] = (DxUint32_t)eSMPhy;
    paramInBuffer_ptr[4] = (DxUint32_t)aESize;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthHandle_ptr->objDigest;
    paramInBuffer_ptr[6] = (DxUint32_t)aAuthHandle_ptr->objId;

    /************************************************************************/
    /* Send an input buffer to SeP and wait for output parameters           */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										/* Input buffer length */
										DX_7_WORDS_PARAMS * sizeof(DxUint32_t), 
										paramOutBuffer_ptr,
										/* Output buffer length */
										DX_4_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_pub_key_rsa;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_PUB_KEY_RSA_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_pub_key_rsa;
    }

    /* RC */    
    errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_pub_key_rsa);

    /* Fill out output parameters */
    aAuthHandle_ptr->objDigest = paramOutBuffer_ptr[2];
    aAuthHandle_ptr->objId     = paramOutBuffer_ptr[3];

exit_auth_pub_key_rsa: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}

/*SST_AuthenticatorPubKeyECCCreate*/    
DxError_t SST_AuthenticatorPubKeyECCCreate(SSTTxnId_t   aTransactionId,
										   DxByte_t    *aECCPubKey_ptr,
										   DxUint32_t   aECCPubKeySizeInBytes,
										   SSTHandle_t *aAuthHandle_ptr,
										   DxByte_t    *aWorkspace_ptr,
										   DxUint32_t   aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_6_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_4_WORDS_PARAMS];
    DxError_t               errorRC;    
    DxUint32_t				eccPubKeySMPhy;
    DxUint32_t				eccPubKeySMVirt;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;

    if(DX_IS_NULL_2PARAMS(aECCPubKey_ptr,aAuthHandle_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }	
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	/*allocate memory in SM*/
	errorRC = SEPDriver_AllocateDataPoolMemory( aECCPubKey_ptr, 
                                                aECCPubKeySizeInBytes, 
                                                &eccPubKeySMPhy,
                                                &eccPubKeySMVirt);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_ecc) ;
	/*copy to the SM*/
	errorRC = SEPDriver_WriteToDataPoolMemory(eccPubKeySMVirt, aECCPubKey_ptr, aECCPubKeySizeInBytes);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_pub_key_ecc) ;
	
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_PUB_KEY_ECC_CREATE;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)eccPubKeySMPhy;
    paramInBuffer_ptr[3] = (DxUint32_t)aECCPubKeySizeInBytes;
    paramInBuffer_ptr[4] = (DxUint32_t)aAuthHandle_ptr->objDigest;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthHandle_ptr->objId;

    /************************************************************************/
    /* Send an input buffer to SeP and wait for output parameters           */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										 /* Input buffer length */
										 DX_6_WORDS_PARAMS * sizeof(DxUint32_t), 
										 paramOutBuffer_ptr,
										 /* Output buffer maximal length */
										 DX_4_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_pub_key_ecc;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_PUB_KEY_ECC_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_pub_key_ecc;
    }

    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_pub_key_ecc);

    /* Fill out output parameters */
    aAuthHandle_ptr->objDigest = paramOutBuffer_ptr[2];
    aAuthHandle_ptr->objId     = paramOutBuffer_ptr[3];

exit_auth_pub_key_ecc: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}

/*SST_AuthenticatorAESSharedSecretCreate*/    
DxError_t SST_AuthenticatorAESSharedSecretCreate(SSTTxnId_t      aTransactionId,
                                                 DxByte_t       *aAesKey_ptr,
                                                 SSTAESKeyType_t aKeyType,
                                                 SSTHandle_t    *aAuthHandle_ptr,
                                                 DxByte_t       *aWorkspace_ptr,
                                                 DxUint32_t      aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_6_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_4_WORDS_PARAMS];
    DxError_t               errorRC;
    DxUint32_t				aesKeySMPhy;
    DxUint32_t				aesKeySMVirt;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;

    if(DX_IS_NULL_2PARAMS(aAesKey_ptr, aAuthHandle_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	/*allocate memory in SM*/
	errorRC = SEPDriver_AllocateDataPoolMemory( aAesKey_ptr, 
                                                SST_AUTH_AES_KEY_SIZE_IN_BYTES, 
                                                &aesKeySMPhy,
                                                &aesKeySMVirt);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_aes_shared_sec_create) ;
	/*copy to the SM*/
	errorRC = SEPDriver_WriteToDataPoolMemory(aesKeySMVirt, aAesKey_ptr, SST_AUTH_AES_KEY_SIZE_IN_BYTES);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_aes_shared_sec_create) ;
	
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_AES_SHARED_SECRET_CREATE;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aesKeySMPhy;
    paramInBuffer_ptr[3] = (DxUint32_t)aKeyType;
    paramInBuffer_ptr[4] = (DxUint32_t)aAuthHandle_ptr->objDigest;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthHandle_ptr->objId;

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										/* Input buffer length */
										DX_6_WORDS_PARAMS * sizeof(DxUint32_t), 
										paramOutBuffer_ptr,
										/* Output buffer maximal length */
										DX_4_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_aes_shared_sec_create;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_AES_SHARED_SECRET_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_aes_shared_sec_create;
    }

    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_aes_shared_sec_create);

    /* Output parameters */
    aAuthHandle_ptr->objDigest = paramOutBuffer_ptr[2];
    aAuthHandle_ptr->objId     = paramOutBuffer_ptr[3];

exit_auth_aes_shared_sec_create:   
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
  
    return errorRC;
}

/*SST_AuthenticatorDelete*/    
DxError_t SST_AuthenticatorDelete( SSTTxnId_t aTransactionId,
                                  SSTHandle_t aAuthHandle)
{
    DxUint32_t              paramInBuffer_ptr [DX_4_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_DELETE;
    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aAuthHandle.objDigest;
    paramInBuffer_ptr[3] = (DxUint32_t)aAuthHandle.objId;

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
        /* Input buffer length */
        DX_4_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)        
        goto exit_auth_delete;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_DELETE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_delete;
    }

    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_delete);

exit_auth_delete: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}



/*SST_SessionCreate*/    
DxError_t SST_SessionCreate( SSTSessionId_t *aSessionId_ptr )
{
    DxUint32_t              paramInBuffer_ptr [DX_1_WORD_PARAM];
    DxUint32_t              paramOutBuffer_ptr[DX_3_WORDS_PARAMS];
    DxError_t               errorRC;

    if(DX_IS_NULL_PARAM(aSessionId_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_SESSION_CREATE;

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
        /* Input buffer length */
        DX_1_WORD_PARAM * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer length */
        DX_3_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_session_create;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_SESSION_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_session_create;
    }

    /* RC */    
    errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_session_create);

	/* output Parameters */
	(*aSessionId_ptr) = (SSTSessionId_t)paramOutBuffer_ptr[2];

exit_session_create: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}



/*SST_SessionDelete*/    
DxError_t SST_SessionDelete(SSTSessionId_t  aSessionId)
{
    DxUint32_t              paramInBuffer_ptr [DX_2_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_SESSION_DELETE;
    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aSessionId;

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
        /* Input buffer length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_session_delete;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_SESSION_DELETE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_session_delete;
    }

    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_session_delete);

exit_session_delete:
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
     
    return errorRC;
}

/*SST_AuthenticatorChallengeGet*/    
DxError_t SST_AuthenticatorChallengeGet(DxByte_t          *aChallengeBuff_ptr,
                                        DxUint32_t         aChallengeBuffsizeInBytes,  
                                        SSTChallengeId_t  *aChallengeId_ptr)
{
    DxUint32_t              paramInBuffer_ptr [DX_3_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_3_WORDS_PARAMS];
    DxError_t               errorRC;
    DxError_t               sepErrorRC;
    DxUint32_t				challengeSMPhyAddress;
    DxUint32_t				challengeSMVirtAddress;

    if(DX_IS_NULL_2PARAMS(aChallengeBuff_ptr, aChallengeId_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	/*allocate in SM*/
	errorRC = SEPDriver_AllocateDataPoolMemory(aChallengeBuff_ptr, 
                                               aChallengeBuffsizeInBytes, 
                                               &challengeSMPhyAddress,
                                               &challengeSMVirtAddress);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_challenge_get) ;

	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_CHALLENGE_GET;

    /* Input parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)challengeSMPhyAddress;
    paramInBuffer_ptr[2] = (DxUint32_t)aChallengeBuffsizeInBytes;

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse(paramInBuffer_ptr,
        /* Input buffer length */
        DX_3_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer maximal length */
        DX_3_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_challenge_get;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_CHALLENGE_GET)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_challenge_get;
    }
    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_challenge_get);

    /* Fill out output parameters */
    *aChallengeId_ptr = paramOutBuffer_ptr[2];

	/*copy from SM*/
	sepErrorRC = SEPDriver_ReadFromDataPoolMemory(challengeSMVirtAddress,
                                              aChallengeBuff_ptr, 
									          aChallengeBuffsizeInBytes);
	SST_HOST_DRIVER_ERROR_CHECK(sepErrorRC,exit_auth_challenge_get) ;

exit_auth_challenge_get: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}

/*SST_AuthenticationOpen*/    
DxError_t SST_AuthenticationOpen(SSTSessionId_t    aSessionId,
                                 SSTHandle_t       aAuthHandle,
                                 DxByte_t         *aAuthBuff_ptr,
                                 DxUint32_t        aAuthBuffSizeInBytes,
                                 SSTChallengeId_t  aChallengeId,
                                 DxByte_t         *aWorkspace_ptr,
                                 DxUint32_t        aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_7_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;
    DxUint32_t				authBuffSMPhy;
    DxUint32_t				authBuffSMVirt;
    
    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;
    

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	if(DX_NULL != aAuthBuff_ptr)
	{			
		/*allocate memory in SM*/
		errorRC = SEPDriver_AllocateDataPoolMemory( aAuthBuff_ptr, 
	                                                aAuthBuffSizeInBytes, 
	                                                &authBuffSMPhy,
	                                                &authBuffSMVirt);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_open) ;
		/*copy to SM*/
		errorRC = SEPDriver_WriteToDataPoolMemory(authBuffSMVirt, aAuthBuff_ptr, aAuthBuffSizeInBytes);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_open) ;
	}
	
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_OPEN;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aSessionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aAuthHandle.objDigest;
    paramInBuffer_ptr[3] = (DxUint32_t)aAuthHandle.objId;
    
    paramInBuffer_ptr[4] = ((aAuthBuff_ptr == DX_NULL)? (DxUint32_t)0:(DxUint32_t)authBuffSMPhy);
    
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthBuffSizeInBytes;
    paramInBuffer_ptr[6] = (DxUint32_t)aChallengeId;
    
    

    /************************************************************************/
    /* Send an input buffer to SeP  and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse(paramInBuffer_ptr,
        /* Input buffer length */
        DX_7_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer maximal length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_open;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_OPEN)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_open;
    }
    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_open);

exit_auth_open: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}


/*SST_AuthenticationClose*/
DxError_t SST_AuthenticationClose(SSTSessionId_t aSessionId,
                                  SSTHandle_t    aAuthHandle)
{
    DxUint32_t              paramInBuffer_ptr [DX_4_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_CLOSE;

    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aSessionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aAuthHandle.objDigest;
    paramInBuffer_ptr[3] = (DxUint32_t)aAuthHandle.objId;

    /************************************************************************/
    /* Send an input buffer to SeP and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse(paramInBuffer_ptr,
                                        /* Input buffer length */
                                        DX_4_WORDS_PARAMS * sizeof(DxUint32_t), 
                                        paramOutBuffer_ptr,
                                        /* Output buffer maximal length */
                                        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));
    if (DX_OK != errorRC)
        goto exit_auth_close;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_CLOSE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_close;
    }
    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_close);

exit_auth_close:
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
     
    return errorRC;
}


/*SST_AuthenticatorPasswordResetAndChange*/    
/* Note: This function has parameter (aNewPwd_ptr) with variable length, which must be written into shared memory. */
/*       Because of we do not know which endian use these or another platform, we send this buffer separately.     */ 
/*       Thus, we cannot use here SST_SendOneMsgGetResponse function                                               */
DxError_t SST_AuthenticatorPasswordResetAndChange(SSTTxnId_t      aTransactionId,
                                                  SSTSessionId_t  aSessionId,
                                                  SSTHandle_t     aAuthHandle,
                                                  DxUint32_t      aNewPwdsizeInBytes,
                                                  DxByte_t       *aNewPwd_ptr,
                                                  DxUint32_t      aNewMaxRetry,
                                                  DxByte_t       *aWorkspace_ptr,
                                                  DxUint32_t      aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_8_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;
    DxUint32_t				newPwdSMPhy;
    DxUint32_t				newPwdSMVirt;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;
    
    if(DX_IS_NULL_PARAM(aNewPwd_ptr))
        return SST_RC_ERROR_NULL_POINTER;

	/*check password size limit for SEP*/
	if (SST_AUTH_PWD_MAX_SIZE_IN_BYTES < aNewPwdsizeInBytes)
		return SST_RC_ERROR_NULL_POINTER/*SST_RC_ERROR_SEP_AUTH_PWD_SIZE_INVALID*/;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_OK != errorRC)
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
	/*allocate memory in SM*/
	errorRC = SEPDriver_AllocateDataPoolMemory( aNewPwd_ptr, 
                                                aNewPwdsizeInBytes, 
                                                &newPwdSMPhy,
                                                &newPwdSMVirt);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_psw_reset_and_change) ;
	/*copy password to the SM*/
	errorRC = SEPDriver_WriteToDataPoolMemory(newPwdSMVirt, aNewPwd_ptr, aNewPwdsizeInBytes);
	SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_psw_reset_and_change) ;
	
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_PASSWORD_RESET_AND_CHANGE;

    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aSessionId;
    paramInBuffer_ptr[3] = (DxUint32_t)aAuthHandle.objDigest;
    paramInBuffer_ptr[4] = (DxUint32_t)aAuthHandle.objId;
    paramInBuffer_ptr[5] = (DxUint32_t)aNewPwdsizeInBytes;
	paramInBuffer_ptr[6] = (DxUint32_t)aNewMaxRetry;
	paramInBuffer_ptr[7] = (DxUint32_t)newPwdSMPhy;

	/************************************************************************/
	/* Send an input buffer to SeP and wait for output parameters           */
	/************************************************************************/
	errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										/* Input buffer length */
										DX_8_WORDS_PARAMS * sizeof(DxUint32_t), 
										paramOutBuffer_ptr,
										/* Output buffer length */
										DX_2_WORDS_PARAMS * sizeof(DxUint32_t));
	if (DX_OK != errorRC)
		goto exit_psw_reset_and_change;
	
    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_PASSWORD_RESET_AND_CHANGE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_psw_reset_and_change;
    }

    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_psw_reset_and_change);

exit_psw_reset_and_change:   
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
  
    return errorRC;
}


/*SST_AuthenticatorBind*/    
DxError_t SST_AuthenticatorBind(SSTTxnId_t        aTransactionId,  
                                SSTSessionId_t    aSessionId, 
                                SSTHandle_t       aObjHandle,              
                                SSTHandle_t       aAuthToBind,             
                                SSTPermissions_t  aPermission,
                                DxByte_t         *aWorkspace_ptr,
                                DxUint32_t        aWorkspaceSizeInBytes)                                
{
    DxUint32_t              paramInBuffer_ptr [DX_8_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;
    
	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_BIND;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aSessionId;
    paramInBuffer_ptr[3] = (DxUint32_t)aObjHandle.objDigest;
    paramInBuffer_ptr[4] = (DxUint32_t)aObjHandle.objId;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthToBind.objDigest;
    paramInBuffer_ptr[6] = (DxUint32_t)aAuthToBind.objId;
    paramInBuffer_ptr[7] = (DxUint32_t)aPermission;

    /************************************************************************/
    /* Send an input buffer to SeP and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse(paramInBuffer_ptr,
        /* Input buffer length */
        DX_8_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer maximal length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));

    if (DX_OK != errorRC)
        goto exit_bind;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_BIND)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_bind;
    }
    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_bind);

exit_bind:  
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
   
    return errorRC;
}

/*SST_AuthenticatorUnbind*/
DxError_t SST_AuthenticatorUnbind(SSTTxnId_t        aTransactionId,   
                                  SSTSessionId_t    aSessionId,
                                  SSTHandle_t       aObjHandle,              
                                  SSTHandle_t       aAuthToUnbind,
                                  SSTPermissions_t  aPermission,
                                  DxByte_t         *aWorkspace_ptr,
                                  DxUint32_t        aWorkspaceSizeInBytes)                                
{
    DxUint32_t              paramInBuffer_ptr [DX_8_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_2_WORDS_PARAMS];
    DxError_t               errorRC;

    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;
    
	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_UNBIND;

    /*  Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aSessionId;
    paramInBuffer_ptr[3] = (DxUint32_t)aObjHandle.objDigest;
    paramInBuffer_ptr[4] = (DxUint32_t)aObjHandle.objId;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthToUnbind.objDigest;
    paramInBuffer_ptr[6] = (DxUint32_t)aAuthToUnbind.objId;
    paramInBuffer_ptr[7] = (DxUint32_t)aPermission;

    /************************************************************************/
    /* Send an input buffer to SeP and wait for output parameters          */
    /************************************************************************/
    errorRC = SST_SendOneMsgGetResponse(paramInBuffer_ptr,
        /* Input buffer length */
        DX_8_WORDS_PARAMS * sizeof(DxUint32_t), 
        paramOutBuffer_ptr,
        /* Output buffer maximal length */
        DX_2_WORDS_PARAMS * sizeof(DxUint32_t));

    if (DX_OK != errorRC)
        goto exit_unbind;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_UNBIND)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_unbind;
    }
    /* RC */    
	errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_unbind);

exit_unbind: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}


/*SST_AuthenticatorAppIDCreate*/
/* Note: This function has parameter (aAppID_ptr) with variable length, which must be written into shared memory. */
/*       Because of we do not know which endian use these or another platform, we send this buffer separately   */ 
/*       Thus, we cannot use here SST_SendOneMsgGetResponse function                                            */
DxError_t SST_AuthenticatorAppIDCreate( SSTTxnId_t      aTransactionId,
										SSTSessionId_t  aSessionId,          
										DxByte_t       *aAppID_ptr,
										DxUint32_t      aAppIDsizeInBytes,
										SSTHandle_t    *aAuthHandle_ptr,
										DxByte_t       *aWorkspace_ptr,
										DxUint32_t      aWorkspaceSizeInBytes)
{
    DxUint32_t              paramInBuffer_ptr [DX_7_WORDS_PARAMS];
    DxUint32_t              paramOutBuffer_ptr[DX_4_WORDS_PARAMS];
    DxError_t               errorRC;
    DxUint32_t				appIdSMPhy;
    DxUint32_t				appIdSMVirt;
    
    /* Eliminating warnings regarding useless variables */
    aWorkspace_ptr = aWorkspace_ptr;
    aWorkspaceSizeInBytes = aWorkspaceSizeInBytes;

    if(DX_IS_NULL_PARAM(aAuthHandle_ptr))
        return SST_RC_ERROR_NULL_POINTER;
	
	/*check password/application id size limit for SEP*/
	if (SST_AUTH_PWD_MAX_SIZE_IN_BYTES < aAppIDsizeInBytes)
		return SST_RC_ERROR_SEP_AUTH_APP_ID_SIZE_INVALID;

	/************************************************************************/
	/*  Lock access to SEP                                                  */
	/************************************************************************/  
   errorRC = SEPDriver_Lock();
   if(DX_MNG_SEP_IS_DISABLE_ERR == errorRC)
   {
       errorRC = SST_RC_ERROR_SEP_DISABLED; 
       goto exit_function;
   }
   else if (DX_OK != errorRC)
   {
       errorRC = SST_RC_ERROR_SEP; 
       goto exit_function;
   }
	
	/************************************************************************/
    /* Prepare input buffer                                                 */
    /************************************************************************/
    /*allocate memory in SM*/
    if(DX_NULL != aAppID_ptr)
    {    	    
		errorRC = SEPDriver_AllocateDataPoolMemory(aAppID_ptr, 
	                                               aAppIDsizeInBytes, 
	                                               &appIdSMPhy, 
	                                               &appIdSMVirt);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_app_id_create) ;
		errorRC = SEPDriver_WriteToDataPoolMemory(appIdSMVirt, 
	                                             (DxUint8_t*)aAppID_ptr, 
	                                              aAppIDsizeInBytes);
		SST_HOST_DRIVER_ERROR_CHECK(errorRC,exit_auth_app_id_create) ;
    }
    
    
	/* Operation Code */
    paramInBuffer_ptr[0] = SST_SEP_OP_CODE_AUTH_APP_ID_CREATE;

    /* Input Parameters */
    paramInBuffer_ptr[1] = (DxUint32_t)aTransactionId;
    paramInBuffer_ptr[2] = (DxUint32_t)aSessionId; 
    paramInBuffer_ptr[3] = (DxUint32_t)aAppIDsizeInBytes;       
    paramInBuffer_ptr[4] = (DxUint32_t)aAuthHandle_ptr->objDigest;
    paramInBuffer_ptr[5] = (DxUint32_t)aAuthHandle_ptr->objId;
	paramInBuffer_ptr[6] = ((aAppID_ptr == DX_NULL)? (DxUint32_t)0:(DxUint32_t)appIdSMPhy);

	/************************************************************************/
	/* Send an input buffer to SeP and wait for output parameters           */
	/************************************************************************/
	errorRC = SST_SendOneMsgGetResponse( paramInBuffer_ptr,
										/* Input buffer length */
										DX_7_WORDS_PARAMS * sizeof(DxUint32_t), 
										paramOutBuffer_ptr,
										DX_4_WORDS_PARAMS * sizeof(DxUint32_t));
	if (DX_OK != errorRC)
		goto exit_auth_app_id_create;

    /************************************************************************/
    /* Analyze return buffer                                                */
    /************************************************************************/
    /* Op code */
    if (paramOutBuffer_ptr[0] != SST_SEP_OP_CODE_AUTH_APP_ID_CREATE)
    {
        errorRC = SST_RC_ERROR_SEP;
        goto exit_auth_app_id_create;
    }

    /* RC */    
    errorRC = paramOutBuffer_ptr[1];
	SST_HOST_RETURN_CODE_CHECK(errorRC,exit_auth_app_id_create);

    /* Output parameters */
    aAuthHandle_ptr->objDigest = paramOutBuffer_ptr[2];
    aAuthHandle_ptr->objId     = paramOutBuffer_ptr[3];


exit_auth_app_id_create: 
	/************************************************************************/
	/* UnLock access to  SEP                                                  */
	/************************************************************************/
	SEPDriver_Unlock();

exit_function:
    
    return errorRC;
}
