/*! \file 
**********************************************************************************
*Title:                         Discretix OMA DRM v2 Secure RO Handling ATP Test source file
*
* Filename:                     ODRM_SecROHandling_JoinDomain_ATP.c 
*
* 
* Created:                      17.03.2009
*
*
* \Author                      Shelly Lerman
*
* \Remarks
*           Copyright (C) 2007 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/
/************* Include Files ***********************************/
#include "DX_VOS_BaseTypes.h"
#include "DX_VOS_Mem.h"
#include "DX_VOS_Stdio.h"
#include "DX_VOS_String.h"

#include "CRYS.h"
#include "CRYS_KMNG.h"


#include "KMNG_Defs.h" 
#include "KMNG_API.h"

#include "ODRM_SecROHandling_data.h"
#include "ODRM_SecROHandling_JoinDomain_ATP.h"

#include "tlk_cert_types.h"

#include "tlk_sclk_api_types.h"
#include "tlk_sclk_api.h"


#include "MW_ATP_UTIL_funcs.h"
#include "ODRM_SecROHandling_Utils_ATP.h"

#include <stdio.h>


/*****************************************************************************
* Function Name:                                                           
*  TST_ATP_SEC_RO_JoinDomainProcess
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* TEST DESCRIPTION:
*  Test Join-Domain Process in Secure License Handling 
* Algorithm:
* 1.Get workspace size. 
* 2.Create key ring and initialize it with device private key
* 3.Initialize Secure Clock descriptor
* 4.Call to TLK_ODRM_ProcessJoinDomain() API 
* 5.Verify that usage flag indicate that domain key was produced by TLK_ODRM_ProcessJoinDomain()  function 
* 6.Call to TLK_ODRM_VerifyDomainRoBeforeInstall() API with Domain key from step 4.
* 7.Activate content license using  TLK_ODRM_RetrieveKey() with KMAC and KREK keys from step 4 and secure clock descriptor from step 3.
* 8.Validate that  this is correct RO key.
*   8.1  Encrypt Plain text with the activated RO key from    TLK_ODRM_RetrieveKey().
*   8.2 compare it to the Encrypted plain text with the 
*       original RO key.
*******************************************************************************/   
DxError_t TST_ATP_SEC_RO_JoinDomainProcess(void)
{

    DxUint32_t TST_Error = 0;

    TLK_ODRM_KMNGKeyRing_t keyRingDeviceStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingDomainStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingKmacKrecStruct = {0};

    TLK_ODRM_KMNGKey_t  TST_KeyDevice = {0};
    TLK_ODRM_KMNGKey_t  TST_KeyDomain = {0};
    TLK_ODRM_KMNGKey_t  TST_kmacKey = {0};
    TLK_ODRM_KMNGKey_t  TST_krecKey = {0};
    TLK_ODRM_Buffer_t   TST_DomainXML = {0};
    TLK_ODRM_Buffer_t   TST_RightsXML = {0};
    TLK_ODRM_Buffer_t   TST_groupKey = {0};
    DxUint32_t  TST_KeyRingSize = 0;

    KMNG_AES_WrappedKey_t  TST_WrappedKey;

    KMNG_UserSpecificKeyData_t  TST_UserSpecificKeyData = {0,0};
    TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDescr = {0};
    TLK_ODRM_Buffer_t  TST_RoXmlStructure;

    DxUint32_t TST_NumOfSymKeys = 0;
    DxUint32_t TST_NumOfRSAKeys = 0;
    DxUint32_t TST_NumOfDHKeys  = 0;

    /*******************Set password to RI ID ****************/
    TLK_ODRM_Buffer_t passwordBuff;
    passwordBuff.buff_ptr        = TST_RiIDKey;
    passwordBuff.buffSizeInBytes = DX_VOS_StrLen(TST_RiIDKey);
    TST_KRING_Clean();


    ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n******************************************** \n"));
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"***** TST_ATP_SEC_RO_JoinDomainProcess *****\n"));     
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"********************************************\n \n"));
    
    /*Initialize domain struct*/
    TST_DomainXML.buffSizeInBytes = DX_VOS_StrLen(DomainXML);
    TST_DomainXML.buff_ptr = (DxByte*)DomainXML;

    /*Initialize rights  struct*/
    TST_RightsXML.buffSizeInBytes = DX_VOS_StrLen(DomainRightsXmlStr);
    TST_RightsXML.buff_ptr = (DxByte*)DomainRightsXmlStr;

    /*Initialize RO XML  struct*/
    TST_RoXmlStructure.buffSizeInBytes = DX_VOS_StrLen(DomainRoXml);
    TST_RoXmlStructure.buff_ptr = (DxByte*)DomainRoXml;

    /* 1. Get work space size */
    TST_Error = TLK_ODRM_WorkspaceSizeGet(TLK_ODRM_MIN_WORKSPACE, &RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_WorkspaceSizeGet",
                               "TST_ATP_SEC_RO_JoinDomainProcess", 
                               "TST_ATP_SEC_RO_JoinDomainProcess");


    if(RO_TST_gWorkspaceSizeInBytes < ODRMTLK_TST_WORKSPACE_SIZE)
       TST_Error = TST_FAIL;

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "Insufficient Workspace Size",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    

    /* 2. Create key ring and initialize it with device private key */
    TST_NumOfSymKeys = 0;
    TST_NumOfRSAKeys = 1;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDevice);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDevice",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    TST_NumOfSymKeys = 1;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDomain);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDomain",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    TST_NumOfSymKeys = 2;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error = KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingKmacKrec);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingKmacKrec",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    TST_KeyDevice.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDevice.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_KeyDomain.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDomain.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_kmacKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_kmacKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_krecKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_krecKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;


    TST_Error = KMNG_ImportRsaUserKey(passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      KMNG_KeyTypeRSAPair,                    /*keyType*/
                                      ODRMTLK_TST_RSA_1024_KEY_SIZE_IN_BYTES, /*keySize*/ 
                                      KMNG_KEY_USAGE_ODRM | KMNG_KEY_USAGE_SIGNING,                    /*keyUsage*/
                                      TLK_ODRM_KEY_RESTRICTION,               /*keyRestriction*/
                                      TST_UserSpecificKeyData,                    /*UserSpecificKeyData*/
                                      PrivModulus,                           /*modulus_ptr*/
                                      MODULUS_SIZE,                       /*modulusSize*/
                                      PubExponent,                       /*E_ptr*/
                                      PUB_EXP_SIZE,                    /*E_Size*/
                                      PrivExponent,                       /*D_ptr*/
                                      PRIV_EXP_SIZE,                   /*D_Size*/
                                      &TST_KeyDevice.keyId,
                                      TST_gKeyRingDevice);


    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_ImportRsaUserKey ",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");
    
    keyRingDeviceStruct.keyKmngRing_ptr = TST_gKeyRingDevice;
    keyRingDeviceStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDeviceStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;
    
    keyRingDomainStruct.keyKmngRing_ptr = TST_gKeyRingDomain;
    keyRingDomainStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDomainStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;
    
    keyRingKmacKrecStruct.keyKmngRing_ptr = TST_gKeyRingKmacKrec;
    keyRingKmacKrecStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingKmacKrecStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;

   
    /* 3.initialize secure clock descriptor*/
    TST_Error = TLK_SCLK_Init(RO_TST_gWorkspace, RO_TST_gWorkspaceSizeInBytes);
    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_SCLK_Init",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    TST_Error = TST_SCLK_Init(&TST_ServiceDescr);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TST_SCLK_Init",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /*4.Call to TLK_ODRM_ProcessJoinDomain() API. Domain key has to be returned */
    TST_Error = TLK_ODRM_ProcessJoinDomain(&TST_DomainXML,
                                           &keyRingDeviceStruct,
                                           &TST_KeyDevice,
                                           &keyRingDomainStruct,
                                           &TST_KeyDomain,
                                           RO_TST_gWorkspace,
                                           RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_ProcessJoinDomain",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /* 5.Verify that usage flag indicate that domain key was 
      produced by TLK_ODRM_ProcessJoinDomain()  function */
    TST_Error = TST_VerifyKeyUsageFlag(TST_KeyDomain.keyId, 
                                       keyRingDomainStruct.keyKmngRing_ptr,
                                       KMNG_KEY_USAGE_ODRM);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TST_VerifyKeyUsageFlag",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /* 6.Call to TLK_ODRM_VerifyDomainRoBeforeInstall() API with Domain key from step 3*/
    TST_Error = TLK_ODRM_VerifyDomainRoBeforeInstall(&TST_RoXmlStructure,
                                                     &keyRingDomainStruct,
                                                     &TST_KeyDomain,
                                                     0,
                                                     &keyRingKmacKrecStruct,
                                                     &TST_kmacKey,
                                                     &TST_krecKey,
                                                     RO_TST_gWorkspace,
                                                     RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_VerifyDomainRoBeforeInstall",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /* 7.Activate content license using  TLK_ODRM_RetrieveKey() with KMAC and KREK keys 
         from step 4 and secure clock descriptor from step 3.*/
    TST_Error = TLK_ODRM_RetrieveKey(&TST_RoXmlStructure,
                                     &keyRingKmacKrecStruct,
                                     &TST_kmacKey,
                                     &TST_krecKey,
                                     "cid:cid61331_jpg",
                                     &TST_ServiceDescr,
                                     DX_NULL,
                                     DX_NULL,
                                     DX_NULL,
                                     DX_NULL,
                                     0,
                                     TST_WrappedKey,
                                     RO_TST_gWorkspace,
                                     RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_RetrieveKey",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /* 8.Validate that  this is correct RO key.*/

    /*8.1  Encrypt Plain text with the activated RO key from    TLK_ODRM_RetrieveKey().*/     
    TST_Error = CRYS_KMNG_AES(TST_WrappedKey,
                              IvCounter,
                              CRYS_AES_Encrypt,
                              CRYS_AES_ECB_mode,
                              TST_PlainBuffCid61331,
                              ODRMTLK_TST_AES_KEY_SIZE,
                              TST_DataoutBuff);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "CRYS_KMNG_AES",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

    /* 8.2 compare it to the Encrypted plain text with the original RO key.*/
    TST_Error = DX_VOS_MemCmp(TST_DataoutBuff, TST_EncryptBuffCid61331, TEMP_BUFF_LEN);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "DX_VOS_MemCmp",
                               "TST_ATP_SEC_RO_JoinDomainProcess",
                               "TST_ATP_SEC_RO_JoinDomainProcess");

EXIT_ON_ERROR:
    TLK_SCLK_Terminate(RO_TST_gWorkspace, RO_TST_gWorkspaceSizeInBytes);
    return TST_Error;
}


/*****************************************************************************
* Function Name:                                                           
*  TST_ATP_SEC_RO_InvalidKeyInJoinDomain
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* Description:                                                                 
*   To test Join-Domain Process with Invalid Domain Key in Secure License Handling  
*  
* Algorithm: 
* 1.Get workspace size. 
* 2.Create key ring and initialize it with device private key
* 3.Call to TLK_ODRM_ProcessJoinDomain() API with invalid Domain key in XML structure
* 4.Verify that TLK_ODRM_RC_ERROR_CRYS error was returned
*******************************************************************************/   
DxError_t TST_ATP_SEC_RO_InvalidKeyInJoinDomain(void)
{
    DxUint32_t TST_Error = 0;

    TLK_ODRM_KMNGKeyRing_t keyRingDeviceStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingDomainStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingKmacKrecStruct = {0};

    TLK_ODRM_KMNGKey_t  TST_KeyDevice = {0};
    TLK_ODRM_KMNGKey_t  TST_KeyDomain = {0};
    TLK_ODRM_KMNGKey_t  TST_kmacKey = {0};
    TLK_ODRM_KMNGKey_t  TST_krecKey = {0};
    TLK_ODRM_Buffer_t   TST_DomainXML = {0};
    TLK_ODRM_Buffer_t   TST_RightsXML = {0};
    DxUint32_t  TST_KeyRingSize = 0;

    KMNG_UserSpecificKeyData_t  TST_UserSpecificKeyData = {0,0};
    TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDescr = {0};

    DxUint32_t TST_NumOfSymKeys = 0;
    DxUint32_t TST_NumOfRSAKeys = 0;
    DxUint32_t TST_NumOfDHKeys  = 0;

    /*******************initialize password for key ring ****************/
    TLK_ODRM_Buffer_t passwordBuff;
    passwordBuff.buff_ptr        = TST_RiIDKey;
    passwordBuff.buffSizeInBytes = DX_VOS_StrLen(TST_RiIDKey);
    TST_KRING_Clean();

    ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n************************************************* \n"));
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"***** TST_ATP_SEC_RO_InvalidKeyInJoinDomain *****\n"));     
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"*************************************************\n \n"));

    /*Initialize domain struct*/
    TST_DomainXML.buffSizeInBytes = DX_VOS_StrLen(InvalidKeyDomainXML);
    TST_DomainXML.buff_ptr = (DxByte*)InvalidKeyDomainXML;

    /*Initialize rights  struct*/
    TST_RightsXML.buffSizeInBytes = DX_VOS_StrLen(DomainRightsXmlStr);
    TST_RightsXML.buff_ptr = (DxByte*)DomainRightsXmlStr;

    /* 1. Get work space size */
    TST_Error = TLK_ODRM_WorkspaceSizeGet(TLK_ODRM_MIN_WORKSPACE, &RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_WorkspaceSizeGet",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain", 
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");


    if(RO_TST_gWorkspaceSizeInBytes < ODRMTLK_TST_WORKSPACE_SIZE)
        TST_Error = TST_FAIL;

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "Insufficient Workspace Size",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

    /* 2. Create key ring and initialize it with device private key */
    TST_NumOfSymKeys = 0;
    TST_NumOfRSAKeys = 1;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDevice);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDevice",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

    TST_NumOfSymKeys = 1;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDomain);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

    TST_NumOfSymKeys = 2;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error = KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                 passwordBuff.buff_ptr,
                                 TST_NumOfSymKeys,
                                 TST_NumOfRSAKeys,
                                 TST_NumOfDHKeys,
                                 TST_gKeyRingKmacKrec);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingKmacKrec",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

    TST_KeyDevice.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDevice.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_KeyDomain.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDomain.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_kmacKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_kmacKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_krecKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_krecKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_Error = KMNG_ImportRsaUserKey(passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      KMNG_KeyTypeRSAPair,                    /*keyType*/
                                      ODRMTLK_TST_RSA_1024_KEY_SIZE_IN_BYTES, /*keySize*/ 
                                      KMNG_KEY_USAGE_ODRM| KMNG_KEY_USAGE_SIGNING,                    /*keyUsage*/
                                      TLK_ODRM_KEY_RESTRICTION,               /*keyRestriction*/
                                      TST_UserSpecificKeyData,                    /*UserSpecificKeyData*/
                                      PrivModulus,                           /*modulus_ptr*/
                                      MODULUS_SIZE,                       /*modulusSize*/
                                      PubExponent,                       /*E_ptr*/
                                      PUB_EXP_SIZE,                    /*E_Size*/
                                      PrivExponent,                       /*D_ptr*/
                                      PRIV_EXP_SIZE,                   /*D_Size*/
                                      &TST_KeyDevice.keyId,
                                      TST_gKeyRingDevice);


    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_ImportRsaUserKey ",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

    keyRingDeviceStruct.keyKmngRing_ptr = TST_gKeyRingDevice;
    keyRingDeviceStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDeviceStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    keyRingDomainStruct.keyKmngRing_ptr = TST_gKeyRingDomain;
    keyRingDomainStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDomainStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    keyRingKmacKrecStruct.keyKmngRing_ptr = TST_gKeyRingKmacKrec;
    keyRingKmacKrecStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingKmacKrecStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;


    /*3.Call to TLK_ODRM_ProcessJoinDomain() API with Invalid Key in Domain XML */
    TST_Error = TLK_ODRM_ProcessJoinDomain( &TST_DomainXML,
                                            &keyRingDeviceStruct,
                                            &TST_KeyDevice,
                                            &keyRingDomainStruct,
                                            &TST_KeyDomain,
                                            RO_TST_gWorkspace,
                                            RO_TST_gWorkspaceSizeInBytes);
    if(TST_Error != TLK_ODRM_RC_ERROR_CRYS)
        TST_Error = TST_FAIL;
    else
        TST_Error = DX_SUCCESS;
    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_ProcessJoinDomain with invalid Domain Key failed. Test ",
                                          "TST_ATP_SEC_RO_InvalidKeyInJoinDomain",
                                          "TST_ATP_SEC_RO_InvalidKeyInJoinDomain");

  
EXIT_ON_ERROR:
    return TST_Error;
}


/*****************************************************************************
* Function Name:                                                           
*  TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* Description:                                                                 
*  To test join-domain process in secure license handling, with invalid usage flag
*  
* Algorithm: 
* 1.	Get workspace size. 
* 2.	Create key ring and initialize it with device private key
* 3.	Import a device private key with invalid usage flag.
* 4.	Call to TLK_ODRM_ProcessJoinDomain() API .
* 5.	Verify that TLK_ODRM_RC_ERROR_INCORRECT_KEY_PERMISSIONS error was returned
*******************************************************************************/   
DxError_t TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain(void)
{
    DxUint32_t TST_Error = 0;

    TLK_ODRM_KMNGKeyRing_t keyRingDeviceStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingDomainStruct = {0};
    TLK_ODRM_KMNGKeyRing_t keyRingKmacKrecStruct = {0};

    TLK_ODRM_KMNGKey_t  TST_KeyDevice = {0};
    TLK_ODRM_KMNGKey_t  TST_KeyDomain = {0};
    TLK_ODRM_KMNGKey_t  TST_kmacKey = {0};
    TLK_ODRM_KMNGKey_t  TST_krecKey = {0};
    TLK_ODRM_Buffer_t   TST_DomainXML = {0};
    TLK_ODRM_Buffer_t   TST_RightsXML = {0};
    DxUint32_t  TST_KeyRingSize = 0;

    

    KMNG_UserSpecificKeyData_t  TST_UserSpecificKeyData = {0,0};
    TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDescr = {0};

    DxUint32_t TST_NumOfSymKeys = 0;
    DxUint32_t TST_NumOfRSAKeys = 0;
    DxUint32_t TST_NumOfDHKeys  = 0;

    /*******************Set password to RI ID****************/
    TLK_ODRM_Buffer_t passwordBuff;
    passwordBuff.buff_ptr        = TST_RiIDKey;
    passwordBuff.buffSizeInBytes = DX_VOS_StrLen(TST_RiIDKey);
    TST_KRING_Clean();



    ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n******************************************************* \n"));
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"***** TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain *****\n"));     
    ATP_LOG_TST_PRINT((MW_ATP_MSG,"*******************************************************\n \n"));

    /*Initialize domain struct*/
    TST_DomainXML.buffSizeInBytes = DX_VOS_StrLen(DomainXML);
    TST_DomainXML.buff_ptr = (DxByte*)DomainXML;

    /*Initialize rights  struct*/
    TST_RightsXML.buffSizeInBytes = DX_VOS_StrLen(DomainRightsXmlStr);
    TST_RightsXML.buff_ptr = (DxByte*)DomainRightsXmlStr;

    /* 1. Get work space size */
    TST_Error = TLK_ODRM_WorkspaceSizeGet(TLK_ODRM_MIN_WORKSPACE, &RO_TST_gWorkspaceSizeInBytes);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_WorkspaceSizeGet",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain", 
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");


    if(RO_TST_gWorkspaceSizeInBytes < ODRMTLK_TST_WORKSPACE_SIZE)
        TST_Error = TST_FAIL;

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "Insufficient Workspace Size",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");

    /* 2. Create key ring and initialize it with device private key */
    TST_NumOfSymKeys = 0;
    TST_NumOfRSAKeys = 1;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDevice);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDevice",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");
    TST_NumOfSymKeys = 1;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error =  KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                  passwordBuff.buff_ptr,
                                  TST_NumOfSymKeys,
                                  TST_NumOfRSAKeys,
                                  TST_NumOfDHKeys,
                                  TST_gKeyRingDomain);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");
    TST_NumOfSymKeys = 2;
    TST_NumOfRSAKeys = 0;
    TST_NumOfDHKeys  = 0;
    TST_Error = KMNG_KeyRingInit(passwordBuff.buffSizeInBytes,
                                 passwordBuff.buff_ptr,
                                 TST_NumOfSymKeys,
                                 TST_NumOfRSAKeys,
                                 TST_NumOfDHKeys,
                                 TST_gKeyRingKmacKrec);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_KeyRingInit - TST_gKeyRingKmacKrec",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");

    TST_KeyDevice.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDevice.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_KeyDomain.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_KeyDomain.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_kmacKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_kmacKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    TST_krecKey.keyPassword_ptr =passwordBuff.buff_ptr;
    TST_krecKey.keyPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    /*3.Import a device private key with invalid, for Join Domain Process, usage flag*/
    TST_Error = KMNG_ImportRsaUserKey(passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      passwordBuff.buff_ptr, 
                                      passwordBuff.buffSizeInBytes,
                                      KMNG_KeyTypeRSAPair,                    /*keyType*/
                                      ODRMTLK_TST_RSA_1024_KEY_SIZE_IN_BYTES, /*keySize*/ 
                                      KMNG_KEY_USAGE_LEGACY,                    /*keyUsage*/
                                      TLK_ODRM_KEY_RESTRICTION,               /*keyRestriction*/
                                      TST_UserSpecificKeyData,                    /*UserSpecificKeyData*/
                                      PrivModulus,                           /*modulus_ptr*/
                                      MODULUS_SIZE,                       /*modulusSize*/
                                      PubExponent,                       /*E_ptr*/
                                      PUB_EXP_SIZE,                    /*E_Size*/
                                      PrivExponent,                       /*D_ptr*/
                                      PRIV_EXP_SIZE,                   /*D_Size*/
                                      &TST_KeyDevice.keyId,
                                      TST_gKeyRingDevice);


    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "KMNG_ImportRsaUserKey ",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");

    keyRingDeviceStruct.keyKmngRing_ptr = TST_gKeyRingDevice;
    keyRingDeviceStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDeviceStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    keyRingDomainStruct.keyKmngRing_ptr = TST_gKeyRingDomain;
    keyRingDomainStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingDomainStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;

    keyRingKmacKrecStruct.keyKmngRing_ptr = TST_gKeyRingKmacKrec;
    keyRingKmacKrecStruct.keyKmngRingPassword_ptr = passwordBuff.buff_ptr;
    keyRingKmacKrecStruct.keyKmngRingPasswordLenInBytes = passwordBuff.buffSizeInBytes;


    /*4.Call to TLK_ODRM_ProcessJoinDomain() API with Invalid Usage in Device Key */
    TST_Error = TLK_ODRM_ProcessJoinDomain( &TST_DomainXML,
                                            &keyRingDeviceStruct,
                                            &TST_KeyDevice,
                                            &keyRingDomainStruct,
                                            &TST_KeyDomain,
                                            RO_TST_gWorkspace,
                                            RO_TST_gWorkspaceSizeInBytes);
    if(TST_Error != TLK_ODRM_RC_ERROR_INCORRECT_KEY_PERMISSIONS)
        TST_Error = TST_FAIL;
    else
        TST_Error = DX_SUCCESS;

    TST_ATP_CHECK_ERROR_RETURN(TST_Error, "TLK_ODRM_ProcessJoinDomain  with invalid Usage Flag in Device Key failed. Test ",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain",
                               "TST_ATP_SEC_RO_InvalidUsageFlagInJoinDomain");


EXIT_ON_ERROR:
    return TST_Error;
}