/*
   *  Object %name    : CC_MNG_Functions.c
   *  State           :  %state%
   *  Creation date   :  Aug 4 17:39:24 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief Generic Secure Boot implemtation of CC functions
   *
   *  \version 
   *  \author Danb
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */
#include "CRYS_RSA_Types.h"
#include "MNG_Functions.h"
#include "mng_host_op_code.h"
#include "gen.h"
#include "error.h"
#include "SEPDriver.h"


/*---------------------
    FUNCTIONS
-----------------------*/
















/*
*   @brief  The CC executes the following:
*               1) verifying that the SHA256 of { E||N } is correlate with the value stored in the OTP according to the key type.
*               2) Executes the CRYS RSA build operation and returns the UserPubKey object
*   
*   @param[in] keyType - the key type : 1 - OEM , 0 - SJTAG.
*   @param[in] keyIndex - in case of the OEM key, the index of the key
*   @param[in] E[in]- The public exponent.
*   @param[in] N_len[in] - the modulus length.
*   @param[in] N_ptr[in] - the modulus vector.
*   @param[out] UserPubKey_ptr[out] - the RSA public key object.
*
*   Returns:  Status of the operation.
*/
DxError_t DX_MNG_RSA_BuildPlatformPubKey(DxUint32_t             keyType,
                                         DxUint32_t             keyIndex, 
                                         CRYS_RSAUserPubKey_t*  UserPubKey_ptr,
                                         DxUint8_t*             E_ptr,					
                                         DxUint32_t             E_len,
                                 		     DxUint32_t             N_len,
                                         DxUint8_t*             N_ptr)
{
  /* The return error identifier */
  DxError_t           Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[4];
  
  /* max length */
  DxUint32_t          maxLength;
  
  /*----------------------------------
      CODE
  ------------------------------------*/
   
  /* .................. initializing local variables ................... */
  /* ------------------------------------------------------------------- */   
   
  /* initializing the Error to O.K */
  Error = DX_OK;      
                         
   /* lock access to the SEP */
   Error = SEPDriver_Lock();
   
   if(Error != DX_OK)
   {
       goto end_function;
   }
  
  /*----------------------------
      start sending message to SEP 
  -----------------------------*/
  sramOffset = 0;
   
  /* start the message */
  SEPDriver_StartMessage(&sramOffset);
  
  /* prepare params */
  messageParam[0] = DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RSA_BUILD_VERIFY_PUB_KEY_OP_CODE;
  messageParam[1] = keyType;
  messageParam[2] = keyIndex;
  messageParam[3] = E_len;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 4 ,
                           sizeof(DxUint32_t) * 4 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  /* send E */
  Error = SEPDriver_WriteParamater((DxUint32_t)E_ptr ,
                           E_len ,
                           sizeof(DxUint32_t) * 64 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }

  /* Send N length */
  Error = SEPDriver_WriteParamater((DxUint32_t)&N_len ,
                           sizeof(DxUint32_t),
                           sizeof(DxUint32_t),
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }


  /* send N */
  Error = SEPDriver_WriteParamater((DxUint32_t)N_ptr ,
                           N_len ,
                           sizeof(DxUint32_t) * 64 ,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                           
  
  SEPDriver_EndMessage(sramOffset);
            
  /* wait for the response */
  Error = SEPDriver_POLL_FOR_REPONSE();
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
                                            
  /*-------------------
    start reading message from the SEP 
  ---------------------*/
   
  /* start the message */
  Error = SEPDriver_StartIncomingMessage(&sramOffset);
  if(Error != DX_OK)
  {
  	goto end_function_unlock;
  }
   
  /* read opcode + status  */
  Error = SEPDriver_ReadParamater((DxUint32_t)messageParam ,
                          sizeof(DxUint32_t) * 2,
                          sizeof(DxUint32_t) * 2,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
   
  /* check the opcode */
  if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCOL_HOST_MNG_RSA_BUILD_VERIFY_PUB_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != DX_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
  
  /* read Pub Key data out */
  maxLength = ((sizeof(CRYS_RSAUserPubKey_t) + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_ReadParamater((DxUint32_t)UserPubKey_ptr,
                          sizeof(CRYS_RSAUserPubKey_t),
                          maxLength,
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  

  /* ...................... end of function ................................ */   

end_function_unlock:   

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

end_function:

  return Error;                                  

}/* DX_CC_MNG_RSA_BuildPlatformPubKey */


