/*! \file 
**********************************************************************************
*Title:                         Discretix OMA DRM v2 Toolkit ATP Test source file
*
* Filename:                      ODRM_TLK_ATP_aes_key_decrypt_and_store.c 
*
* 
* Created:                      10.12.2007
*
*
* \Author                      Sagit Ben Tsur
*
* \Remarks
*           Copyright (C) 2007 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/
/************* Include Files ***********************************/
#include "DX_VOS_BaseTypes.h"
#include "CRYS.h"
#include "tlk_odrm_types.h"
#include "KMNG_Defs.h" 
#include "ODRM_TLK_ATP_UTIL.h"
#include "KMNG_API.h"
#include "ODRM_TLK_ATP_data.h"
#include "tlk_odrm_api.h"
#include "DX_VOS_Mem.h"
#include "ODRM_TLK_ATP_tests.h"
#include "DX_VOS_Stdio.h"
#include "CRYS_KMNG.h"
#include "MW_ATP_UTIL_funcs.h"

/*****************************************************************************
* Function Name:                                                           
*  TST_ATP_TLK_ODRM_AesUnwrapAndStore
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* Description:                                                                 
*    Test TLK_ODRM_AesUnwrapAndStore
*  
* Algorithm: 
* 1.Get work space size. 
* 2.Encrypt The key data.
* 3.Init the key ring.
* 4.Insert The Encrypting Key to the key ring. 
* 5.load parameters and  Call Call TLK_ODRM_AesKeyDecryptAndStore                                
*   input the encrypted Key date buffer  and encrypting key id , output - decrypted key data id. 
* 6.Activate the key data from the key ring using the handle we got in the previous operation.
* 7.Validate this is the same key we inserted in step 5.
*  7.1.Encrypt Plain text with the decrypted key from Key Ring ( from the id we received from the toolkit).
*  7.2.Encrypt Plain text with the original key data before encryption.
*  7.3.Compare results.
*******************************************************************************/  
DxError_t _TST_ATP_TLK_ODRM_AesKeyDecryptAndStore(CRYS_AES_OperationMode_t   aesOperationMode)
{
  
  DxError_t                   TST_Error;
  TLK_ODRM_KMNGKey_t          TLKkey;
  TLK_ODRM_KMNGKey_t          TLKkeyOut;
  KMNG_AES_WrappedKey_t       WrappedKey;
  TLK_ODRM_Buffer_t           TLKEncryptKeyData;
  KMNG_UserSpecificKeyData_t  UserSpecificKeyData = {0,0};
  TLK_ODRM_KMNGKeyRing_t      keyesRing;
  DxChar modName[4];

  TST_gNumOfSymKeys = 2;
  TST_gNumOfRSAKeys = 0;
  TST_gNumOfDHKeys  = 0;

  #ifdef  ODRM_TLK_CLEAR_KEY_RING
    DX_VOS_MemSetZero(TST_gKeyRingBuf,ODRMTLK_TST_MAX_SIZE_KEY_RING_BUF);
    DX_VOS_MemSetZero(TST_gDevKeyRingBuf,ODRMTLK_TST_MAX_SIZE_DEV_KEY_RING_BUF);
  #endif

  if(aesOperationMode == CRYS_AES_CBC_mode )
    DX_VOS_SPrintf(modName ,4, "CBC");     
  else
    DX_VOS_SPrintf(modName ,4, "CTR");    

  
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ****************************************************** \n"));
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TST_ATP_TLK_ODRM_AesKeyDecryptAndStore  %s mode Test  \n",modName));     
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ****************************************************** \n \n"));

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


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

   if(TST_gWorkspaceSizeInBytes < ODRMTLK_TST_WORKSPACE_SIZE)
    TST_Error = TST_FAIL;
   else
    TST_Error = TST_PASS;
  
   
  TST_ATP_CHECK_ERROR_RETURN(TST_Error,"Insufficient Workspace Size ",
                                                "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");
 


  /* 2. Encrypt The Key data*/
   TST_Error = CRYS_AES ( TST_gIvCounter,
                          TST_gKey,
                          CRYS_AES_Key128BitSize,
                          CRYS_AES_Encrypt,
                          aesOperationMode,
                          TST_gKeyData,
                          ODRMTLK_TST_AES_KEY_SIZE,
                          TST_gEncryptKeyData);

   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"CRYS_AES Encrypt",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");


  /************************************************************************/
  /* 3.Init the key ring                                                   */
  /************************************************************************/

  /* Get key ring expected buffer size */
   TST_Error = KMNG_GetKeyRingBufferSize(TST_gNumOfSymKeys, 
                                         TST_gNumOfRSAKeys,
                                         TST_gNumOfDHKeys, 
                                         &TST_gRequiredBufSizeInBytes); 

   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"KMNG_GetKeyRingBufferSize",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");



  TST_Error = KMNG_KeyRingInit(TST_gPasswordSize,
                               TST_gPassword,
                               TST_gNumOfSymKeys,
                               TST_gNumOfRSAKeys,
                               TST_gNumOfDHKeys,
                               TST_gKeyRingBuf);

   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"KMNG_KeyRingInit",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

  
  
  /************************************************************************/
  /*4.  Insert The Encrypting Key to the Key Ring                          */
  /************************************************************************/
   TST_Error = KMNG_ImportSymUserKey(TST_gPassword,
                                     TST_gPasswordSize,
                                     TST_gPassword,
                                     TST_gPasswordSize,
                                     KMNG_KeyTypeAES,
                                     ODRMTLK_TST_AES_KEY_SIZE,
                                     KMNG_KEY_USAGE_STORAGE,
                                     TLK_ODRM_KEY_RESTRICTION,
                                     UserSpecificKeyData, 
                                     TST_gKey,
                                     &TLKkey.keyId,
                                     TST_gKeyRingBuf);


   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"KMNG_ImportSymUserKey",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

   
    /***************************************************************************************************/
    /* 5. load parameters and  Call Call TLK_ODRM_AesKeyDecryptAndStore                                */
    /*    input the encrypted Key date buffer  and encrypting key id , output - decrypted key data id  */
    /***************************************************************************************************/
    /************************************************************************/
    /* load key ring parameters                                             */
    /************************************************************************/
    keyesRing.keyKmngRing_ptr               = TST_gKeyRingBuf;
    keyesRing.keyKmngRingPassword_ptr       = TST_gPassword;
    keyesRing.keyKmngRingPasswordLenInBytes = TST_gPasswordSize;


    /************************************************************************/
    /* load EncryptKeyData  parameters                                      */
    /************************************************************************/
    TLKEncryptKeyData.buff_ptr          = TST_gEncryptKeyData;
    TLKEncryptKeyData.buffSizeInBytes   = ODRMTLK_TST_AES_KEY_SIZE;
  
    /************************************************************************/
    /* load Key parameters                                                  */
    /************************************************************************/
    TLKkey.keyPassword_ptr                = TST_gPassword;
    TLKkey.keyPasswordLenInBytes          = TST_gPasswordSize;
     /************************************************************************/
    /* load Key out parameters                                               */
    /************************************************************************/
    TLKkeyOut.keyPassword_ptr                = TST_gPassword;
    TLKkeyOut.keyPasswordLenInBytes          = TST_gPasswordSize;
   
    
    TST_Error = TLK_ODRM_AesKeyDecryptAndStore(&keyesRing,
                                               &TLKkey,
                                               &TLKEncryptKeyData,
                                               TST_gIvCounter,
                                               aesOperationMode,
                                               &TLKkeyOut,
                                               TST_gWorkspace,
                                               ODRMTLK_TST_WORKSPACE_SIZE);

    TST_ATP_CHECK_ERROR_RETURN(TST_Error,"TLK_ODRM_AesKeyDecryptAndStore",
                                                  "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                  "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

  

    /**************************************************************************************************/
    /*6. Activate the key data from the key ring using the handle we got in the previous operation    */
    /**************************************************************************************************/	
   
    /*prepares the decrypted Key data for CRYS function*/
    TST_Error = KMNG_ActivateAESKey(TST_gPassword,
                                    TST_gPasswordSize,
                                    TLKkeyOut.keyPassword_ptr, 
                                    TLKkeyOut.keyPasswordLenInBytes,
                                    TLKkeyOut.keyId,
                                    TST_gKeyRingBuf,
                                    WrappedKey);

   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"KMNG_ActivateAESKey TLKkeyOut",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

  

    /***************************************************************************************/
    /* 7. Validate this is the same key we inserted in step 2                               */
    /***************************************************************************************/	
    /* 7.1 Encrypt Plain text with the decrypted key from Key Ring ( from the id we received from the toolkit)*/
      TST_Error = CRYS_KMNG_AES(WrappedKey,
                                TST_gIvCounter,       
                                CRYS_AES_Encrypt, 
                                aesOperationMode,       
                                TST_gPlainBuff,        
                                ODRMTLK_TST_AES_KEY_SIZE,         
                                TST_gEncryptedDataOut); 
   
   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"CRYS_KMNG_AES  - Key",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                 "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

    /* 7.2Encrypt Plain text with the original key data before Encryption*/
    TST_Error = CRYS_AES (TST_gIvCounter,
                          TST_gKeyData,
                          CRYS_AES_Key128BitSize,
                          CRYS_AES_Encrypt,
                          aesOperationMode,
                          TST_gPlainBuff,
                          ODRMTLK_TST_AES_KEY_SIZE,
                          TST_gEncryptKeyData);

   TST_ATP_CHECK_ERROR_RETURN(TST_Error,"CRYS_AES Encrypt",
                                                "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

   
   /* 7.3 compare results*/
    if(0 != DX_VOS_MemCmp(TST_gEncryptKeyData,TST_gEncryptedDataOut,ODRMTLK_TST_AES_KEY_SIZE))
      TST_Error =TST_FAIL; 
    else
      TST_Error = TST_PASS; 
    TST_ATP_CHECK_ERROR_RETURN(TST_Error,"DX_VOS_MemCmp - TST_gKeyData",
                                                  "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore",
                                                  "TST_ATP_TLK_ODRM_AesKeyDecryptAndStore");

   

   ATP_LOG_TST_PRINT((MW_ATP_MSG," ***************************************************************** \n\n"));
   ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TST_ATP_TLK_ODRM_AesKeyDecryptAndStore %s mode Test  PASS !!!  \n",modName));     
   ATP_LOG_TST_PRINT((MW_ATP_MSG," **************************************************************** \n \n"));
EXIT_ON_ERROR:
  return TST_Error;
}

/*****************************************************************************
* Function Name:                                                           
*  TST_ATP_TLK_ODRM_AesKeyDecryptAndStoreAllModes
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return                                        
*
* Description:                                                                 
*    calls _TST_ATP_TLK_ODRM_AesKeyDecryptAndStore with CBC mode and CTR mode 
*******************************************************************************/  
DxError_t TST_ATP_TLK_ODRM_AesKeyDecryptAndStoreAllModes()
{
  DxError_t  TST_TestStatus = TST_PASS;
  
  
  TST_TestStatus = _TST_ATP_TLK_ODRM_AesKeyDecryptAndStore(CRYS_AES_CBC_mode) ;
  if(TST_TestStatus == TST_FAIL )
   return TST_TestStatus;

  TST_TestStatus = _TST_ATP_TLK_ODRM_AesKeyDecryptAndStore(CRYS_AES_CTR_mode);
  if(TST_TestStatus == TST_FAIL )
    return TST_TestStatus;

  return TST_TestStatus;
}
