  /*
   *  Object %name    : %
   *  State           :  %state%
   *  Creation date   :  Mon Mar 24 12:09:38 2009
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *
   *  \version SST_SEP_ATP_ECCAsymAuthenticator.c#1:csrc:1
   *  \author taniam
   *  \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
   *           All Rights reserved
   */

/************* Include Files ***********************************/
#include "stdio.h"
#include "SST_SEP_TST.h"
#include "DX_VOS_BaseTypes.h"
#include "extapp_err.h"
#include "sep_utils.h"
#include "SEP_ATP_UTIL_funcs.h"

/************************ Global Data **************************/
extern TST_ATP_ECCAuthTestDataStruct* TST_ATP_ECCAuthObjectTestData;
extern DxUint8_t*    GlobalMemBuff;
extern DxUint8_t*    CurrGlobalMemBuff;

/*****************************************************************************
 * Function Name:
 *  SST_TST_ATP_ECCAsymAuthenticator
 * 
 * Inputs:
 *  None
 *
 * Outputs:
 *  DxError_t - Function error return
 *
 * Description:
 * Test the creation, deletion, modification, opening, closing and usage of an ECC asymmetric key authenticator object.
 * And demonstration on the use of transaction with authenticator objects.
 *  
 * Algorithm:
 *    1.  Build a Private Key using CRYS for CRYS usage by calling: CRYS_RSA_Build_PrivKey (externally generated key).
 *    2.  Create a new session by calling: SST_SessionCreate.
 *    3.  Open a transaction by calling: SST_TransactionStart.
 *    4.  Create a new asymmetric key authenticator by calling: SST_AuthenticatorPubKeyECCCreate.
 *    5.  Close the transaction by calling: SST_TransactionClose.
 *    6.  Open a transaction by calling: SST_TransactionStart.
 *    7.  Open the new authenticator by calling: 
 *        i.   SST_AuthenticatorChallengeGet 
 *        ii.  CRYS_ECDSA_Sign
 *        iii. SST_AuthenticationOpen.
 *    8.  Close the transaction by calling: SST_TransactionClose.
 *    9.  Open a transaction by calling: SST_TransactionStart.
 *    10.Insert a new data object by calling: SST_InsertData.
 *    11.Close the authenticator by calling: SST_AuthenticationClose.
 *    12.Open the authenticator by calling: 
 *        i.   SST_AuthenticatorChallengeGet 
 *        ii.  CRYS_ECDSA_Sign
 *        iii. SST_AuthenticationOpen.
 *    13. Close the transaction by calling: SST_TransactionClose.
 *    14. Open a transaction by calling: SST_TransactionStart.
 *    15. Delete the data by calling: SST_DeleteData.
 *    16. Delete the authenticator by calling: SST_AuthenticatorDelete.
 *    17. Close the transaction by calling: SST_TransactionClose.
 *    18. Delete the session by calling: SST_SessionDelete.
 *
 *******************************************************************************/
DxError_t SEPQA_SST_ECCAsymAuthenticator ( void )
{
 /********* TST Variables Definitions ************/
    DxUint32_t                            TST_index=0;
    DxChar                                TST_MasterTestName[TST_FUNC_STRING_LEN] = "SST_TST_ATP_ECCAsymAuthenticator";
    SSTSessionId_t                        TST_SessionId; 
    SSTTxnId_t                            TST_TransactionId;
    SSTHandle_t                           TST_AuthHandle,TST_DataHandle;
    SSTChallengeId_t                      TST_ChallengeId;
    SSTDataType_t                         TST_SimpleData = TST_DATA_OBJECT;
    CRYS_ECPKI_UserPrivKey_t*             TST_CRYS_ECPKI_UserPrivKey;
    CRYS_ECDSA_SignUserContext_t*         TST_CRYS_ECDSA_SignUserContext;
    DxError_t                             TST_Status;

    /********* TST Variables initialization *********/
    TST_Status = TESTPASS;
    TST_AuthHandle.objId = SST_HANDLE_RANDOM_GENERATE;
    TST_DataHandle.objId = SST_HANDLE_RANDOM_GENERATE;


    /************************************************/
    /*********** Start of test **********************/
    /************************************************/
    ATP_LOG_TST_PRINT((SST_TST_MSG," ****************************************************************** \n"));
    ATP_LOG_TST_PRINT((SST_TST_MSG," ************ SEPQA_SST_ECCAsymAuthenticator Tests **************** \n"));
    ATP_LOG_TST_PRINT((SST_TST_MSG," ****************************************************************** \n \n"));

    ATP_LOG_TST_PRINT((SST_TST_MSG," ************************************ \n"));
    ATP_LOG_TST_PRINT((SST_TST_MSG," TEST using internal handles          \n"));
    ATP_LOG_TST_PRINT((SST_TST_MSG," ************************************ \n"));

     /*Allocate buffers*/

    /* allocate buffer from GlobalMemBuff for TST_CRYS_ECPKI_UserPrivKey*/
    if ((CurrGlobalMemBuff+sizeof(CRYS_ECPKI_UserPrivKey_t))>(GlobalMemBuff+TST_MAX_SEP_WORKSPACE_MEM))
                TST_Status = TESTFAIL;
    else
        TST_CRYS_ECPKI_UserPrivKey=(CRYS_ECPKI_UserPrivKey_t*)CurrGlobalMemBuff;

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TST_CRYS_ECPKI_UserPrivKey allocation",
                             "SEPQA_SST_RsaAsymAuthenticator",TST_MasterTestName);
    /*update CurrGlobalMemBuff*/
    CurrGlobalMemBuff=CurrGlobalMemBuff+sizeof(CRYS_ECPKI_UserPrivKey_t);



    /* allocate buffer from GlobalMemBuff for TST_CRYS_ECDSA_SignUserContext*/
    if ((CurrGlobalMemBuff+sizeof(CRYS_ECDSA_SignUserContext_t))>(GlobalMemBuff+TST_MAX_SEP_WORKSPACE_MEM))
                TST_Status = TESTFAIL;
    else
        TST_CRYS_ECDSA_SignUserContext=(CRYS_ECDSA_SignUserContext_t*)CurrGlobalMemBuff;

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TST_CRYS_ECDSA_SignUserContext allocation",
                             "SEPQA_SST_RsaAsymAuthenticator",TST_MasterTestName);
    /*update CurrGlobalMemBuff*/
    CurrGlobalMemBuff=CurrGlobalMemBuff+sizeof(CRYS_ECDSA_SignUserContext_t);


    /* Build the Private Key for CRYS usage */
    /*--------------------------------------*/
    TST_Status = CRYS_ECPKI_BuildPrivKey(CRYS_ECPKI_DomainID_secp256r1,
                                         TST_ATP_ECCAuthObjectTestData[TST_index].TST_ExternalPrivKey,
                                         TST_ATP_ECCAuthObjectTestData[TST_index].TST_ExternalPrivKeySize,
                                         TST_CRYS_ECPKI_UserPrivKey);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"CRYS_ECPKI_BuildPrivKey",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Create a session for operations */
    /*---------------------------------*/
    TST_Status = SST_SessionCreate(&TST_SessionId);

      TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_SessionCreate",
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                                 TST_MasterTestName);


    /* Open a transaction for operations */
    /*-----------------------------------*/
    TST_Status = SST_TransactionStart(&TST_TransactionId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionStart",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Create a new ECC authenticator */
    /*--------------------------------*/
    TST_Status = SST_AuthenticatorPubKeyECCCreate(TST_TransactionId,
                                                  TST_ATP_ECCAuthObjectTestData[TST_index].TST_ExternalPublKey,
                                                  TST_ATP_ECCAuthObjectTestData[TST_index].TST_ExternalPublKeySize,
                                                  &TST_AuthHandle,
                                                  TST_Workspace,
                                                  TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticatorPubKeyECCCreate",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Close the transaction */
    /*-----------------------*/
    TST_Status = SST_TransactionEnd(TST_TransactionId,
                                    DX_TRUE,/*reflash sensitive*/
                                    TST_Workspace,
                                    TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionEnd",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* re-open a transaction for operations */
    /*--------------------------------------*/
    TST_Status = SST_TransactionStart(&TST_TransactionId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionStart",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Open the authentication */
    /*-------------------------*/
    /* Get the challenge*/
    TST_Status = SST_AuthenticatorChallengeGet(TST_ATP_ECCAuthObjectTestData[TST_index].TST_ChallengeBuff,
                                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_ChallengeBuffSize,  
                                               &TST_ChallengeId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticatorChallengeGet",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    TST_Status = CRYS_ECDSA_Sign(TST_CRYS_ECDSA_SignUserContext,
                                 TST_CRYS_ECPKI_UserPrivKey,
                                 CRYS_ECPKI_HASH_SHA256_mode,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_ChallengeBuff,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_ChallengeBuffSize,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuff,
                                 &TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuffSize);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"CRYS_ECDSA_Sign",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Close the transaction */
    /*-----------------------*/
    TST_Status = SST_TransactionEnd(TST_TransactionId,
                                    DX_TRUE,/*reflash sensitive*/
                                    TST_Workspace,
                                    TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionEnd",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Open the authenticator */
    TST_Status = SST_AuthenticationOpen(TST_SessionId,
                                        TST_AuthHandle,
                                        TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuff,
                                        TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuffSize,
                                        TST_ChallengeId,
                                        TST_Workspace,
                                        TST_WorkspaceSizeInBytes);


    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticationOpen",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* re-open a transaction for operations */
    /*--------------------------------------*/
    TST_Status = SST_TransactionStart(&TST_TransactionId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionStart",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Insert a new Data object */
    /*--------------------------*/
    TST_Status = SST_DataInsert(TST_TransactionId,
                                TST_SessionId,
                                TST_AuthHandle,
                                TST_ATP_ECCAuthObjectTestData[TST_index].TST_Data,
                                TST_ATP_ECCAuthObjectTestData[TST_index].TST_DataSize,
                                DX_TRUE,
                                TST_SimpleData,
                                &TST_DataHandle,
                                TST_Workspace,
                                TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_DataInsert",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);



    /* Close the authentication */
    /*--------------------------*/
    TST_Status = SST_AuthenticationClose(TST_SessionId,TST_AuthHandle);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticationClose",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Re-open the authentication */
    /*----------------------------*/
    /* Get the challenge*/
    TST_Status = SST_AuthenticatorChallengeGet(TST_ATP_ECCAuthObjectTestData[TST_index].TST_NewChallengeBuff,
                                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_NewChallengeBuffSize,  
                                               &TST_ChallengeId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticatorChallengeGet",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Sign the Challenge buffer */
    TST_Status = CRYS_ECDSA_Sign(TST_CRYS_ECDSA_SignUserContext,
                                 TST_CRYS_ECPKI_UserPrivKey,
                                 CRYS_ECPKI_HASH_SHA256_mode,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_NewChallengeBuff,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_NewChallengeBuffSize,
                                 TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuff,
                                 &TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuffSize);


    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"CRYS_ECDSA_Sign",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Close the transaction */
    /*-----------------------*/
    TST_Status = SST_TransactionEnd(TST_TransactionId,
                                    DX_TRUE,/*reflash sensitive*/
                                    TST_Workspace,
                                    TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionEnd",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


     /* Open the authenticator */
     TST_Status = SST_AuthenticationOpen(TST_SessionId,
                                         TST_AuthHandle,
                                         TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuff,
                                         TST_ATP_ECCAuthObjectTestData[TST_index].TST_SignedChallengeBuffSize,
                                         TST_ChallengeId,
                                         TST_Workspace,
                                         TST_WorkspaceSizeInBytes);


    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticationOpen",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


     /* re-open a transaction for operations */
    /*--------------------------------------*/
    TST_Status = SST_TransactionStart(&TST_TransactionId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionStart",
                              TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                              TST_MasterTestName);


    /* Delete the data */
    /*-----------------*/
     TST_Status = SST_DataDelete(TST_TransactionId,
                                 TST_SessionId,
                                 TST_DataHandle,
                                 TST_Workspace,
                                 TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_DataDelete",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Close the authentication */
    /*--------------------------*/
    TST_Status = SST_AuthenticationClose(TST_SessionId,TST_AuthHandle);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticationClose",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Delete the authenticator */
    /*--------------------------*/
    TST_Status = SST_AuthenticatorDelete(TST_TransactionId,
                                         TST_AuthHandle);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_AuthenticatorDelete",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Close the transaction */
    /*-----------------------*/
    TST_Status = SST_TransactionEnd(TST_TransactionId,
                                    DX_TRUE,/*reflash sensitive*/
                                    TST_Workspace,
                                   TST_WorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_TransactionEnd",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


    /* Delete the session */
    /*--------------------*/
    TST_Status = SST_SessionDelete(TST_SessionId);

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"SST_SessionDelete",
                               TST_ATP_ECCAuthObjectTestData[TST_index].TST_Name,
                               TST_MasterTestName);


  EXIT_ON_ERROR:
    return TST_Status;
}/* End of SST_TST_ATP_ECCAsymAuthenticator */
