
  /*
   *  Object %name    : %CRYS_ECPKI_BUILD.c
   *  State           :  %state%
   *  Creation date   :  02.02.2006
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *         The file includes definitions of CRYS level functions
   *         for populating of elliptic curves private 
   *         and public keys
   *
   *  \version CRYS_ECPKI_BUILD.c#1:csrc:1
   *  \author  R.Levin
   *  \remarks Copyright (C) 2006 by Discretix Technologies Ltd.
   *           All Rights reserved
   */

/************* Include Files ****************/

/* .............. CRYS level includes ................. */

#include <linux/module.h>
#include "CRYS_RND.h"
#include "CRYS_ECPKI_KG.h"
#include "CRYS_ECPKI_error.h"
#include "CRYS_ECPKI_BUILD.h"
#include "SEPDriver.h"
#include "host_op_code.h"
#include "error.h"

/* .............. LLF level includes and definitions.............. */

/* canceling the lint warning:
   Info 717: do ... while(0) */
/*lint --e{717} */

/* canceling the lint warning:
   Use of goto is deprecated */
/*lint --e{801} */

/* canceling the lint warning:
Info 716: while(1) ... */ 
/*lint --e{716} */

/************************ Defines ***************************************/

/************************ Enums *****************************************/

/************************ Typedefs **************************************/

/************************ Global Data ***********************************/

/************* Private function prototype *******************************/

/************************ Public Functions ******************************/


/**********************************************************************************
 *                    CRYS_ECPKI_BuildPrivKey function                            *
 **********************************************************************************/
/*!\brief 	Builds (imports) the user private key structure from an existing private key
            so that this structure can be used by other EC primitives.

            When operating the EC cryptographic operations with existing and saved 
            EC private keys, this function should be called first.

		    The function performs the following operations:
			  - Checks validity of incoming variables and pointers.
			  - Checks, that 0 < PrivKey < r (r - EC generator order).
			  - Converts incoming key data from big endian into little endian form.
			  - Initializes variables and structures. 
   
   @param[in]  DomainID           The enumerator variable defines current EC domain.
   @param[in]  PrivKeyIn_ptr      Pointer to private key data. 
   @param[in]  PrivKeySizeInBytes Size of private key data in bytes. Must be great than null and
                                  less or equall to EC OrderSizeInBytes.
   @param[out] UserPrivKey_ptr    Pointer to the private key structure. 
                                  This structure is used as input to the ECPKI 
                                  cryptographic primitives.
   @return   CRYSError_t: 
			 CRYS_OK
             CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR
			 CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR
			 CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR			 
*/	
CEXPORT_C CRYSError_t CRYS_ECPKI_BuildPrivKey(CRYS_ECPKI_DomainID_t     DomainID,	      /*in */   
                                      				DxUint8_t                 *PrivKeyIn_ptr,     /*in*/
                                      				DxUint32_t                PrivKeySizeInBytes,/*in*/
                                      				CRYS_ECPKI_UserPrivKey_t  *UserPrivKey_ptr    /*out*/ ) 
 {
  /* the Error return code identifier */
  CRYSError_t         Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[3];
  
  /* max length */
  DxUint32_t          maxLength;  
 
  /*--------------------------------------
      CODE
  ----------------------------------------*/
 
   
  #ifndef CRYS_NO_HASH_SUPPORT
  #ifndef CRYS_NO_ECPKI_SUPPORT  
    
  /* Error initialization */
  Error = CRYS_OK;
  
  /* ................. checking the validity of the pointer arguments ....... */
  /* ------------------------------------------------------------------------ */
  
  /* ...... checking the key database handle pointer ....................     */
  if( PrivKeyIn_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR;
    goto end_function;
  } 
         
  /* ...... checking the validity of the User Private Key pointer ........... */
  if( UserPrivKey_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR;
    goto end_function;
  } 
 
  /* ...... checking the EC domain ID.................... */
  if( DomainID >= CRYS_ECPKI_DomainID_OffMode )
  {
    Error = CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR;
    goto end_function;
  }
   
   /* 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_ECC_BUILD_PRIV_KEY_OP_CODE;
  messageParam[1] = DomainID;
  messageParam[2] = PrivKeySizeInBytes;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 3,
                           sizeof(DxUint32_t) * 3,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send private key */
  maxLength = ((PrivKeySizeInBytes + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_WriteParamater((DxUint32_t)PrivKeyIn_ptr ,
                            PrivKeySizeInBytes,
                            maxLength,
                            &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_ECC_BUILD_PRIV_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != CRYS_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                          
  /* read data out */
  maxLength = ((sizeof(CRYS_ECPKI_UserPrivKey_t) + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_ReadParamater((DxUint32_t)UserPrivKey_ptr ,
                          sizeof(CRYS_ECPKI_UserPrivKey_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;	

  #endif /* !CRYS_NO_ECPKI_SUPPORT */
  #endif /* !CRYS_NO_HASH_SUPPORT */                                    

} /* End of CRYS_ECPKI_BuildPrivKey() */


EXPORT_SYMBOL(CRYS_ECPKI_BuildPrivKey);
 
 


/**********************************************************************************
 *	              _DX_ECPKI_BuildPublKey function                                *
 **********************************************************************************/
/**
   @brief 	The _DX_ECPKI_BuildPublKey function checks the validity and builds the user public 
            key structure from imported public key data for using  it in other ECC primitives. 

            When operating the EC cryptographic algorithms with imported EC public
            key, this function should be called before using of the public key.

			The user must to call this function by appropriate macros, according to necessary
			validation level [SEC1. ECC standard: 3.2]:
			     - full checking of public key - CRYS_ECPKI_BuildPublKeyFullCheck,
 			     - partly checking of public key - CRYS_ECPKI_BuildPublKeyPartCheck,
                 - checking the input pointers and sizes only - CRYS_ECPKI_BuildPublKeyo.

			The function performs the following operations:
			-	Checks validity of incoming variables and pointers;
			-   Converts incoming key data from big endian into little endian form
			    as follows:
			      - For WMDRM  the function reverts endians of public key 
				    (EC point coordinates X,Y) and copies they into output aligned buffer;
                  - For other domains:  
				    * If public key is given in uncompressed form the function reverts 
					  endians of key point coordinates X and Y separately and copies 
					  they in output buffer.
			        * If public key is given in compressed form, the function reverts 
					  endians and converts the point to uncompressed form and outputs 
					  the key. 
		    -   according to CheckMode parameter performs full or partly checking of public 
			    key validaty by calling the LLF function.
			-   Initializes variables and structures. 

			Incoming public key data PublKeyIn is given in big endianess as follows :
			    - for WMDRM:   X||Y ,
				- for other domains (according to IEEE 1363-2000): 
				    * PC||X||Y - for uncompressed and for hybrid points,
					* PC||X    - for compressed point,  
				  where: X,Y - EC point coordinates of public key,  size of X and Y 
				               equal to size of EC modulus,  
						 PC - single byte point control, defines type of point,
						 Size of buffers for X and also Y must be equal ModSizeInBytes.

   			NOTE: At this stage the said compressed or hybrid forms are not implemented 
			      and the function returns an error in this case.			    

   @param[in]  ECPKI_DomainID  - The enumerator variable defines current EC domain.
   @param[in]  PublKeyIn_ptr   - The pointer to private key data.
   @param[in]  PublKeySizeInBytes - Size of private key data in bytes (according to EC domain),
               it should be equal to 2*modulusSize (CRYS_ECPKI_DomainID_WMDRM10) or 
			   2*modulusSize + 1byte (other domains).
   @param[in]  CheckMode       - The parameter defining what checking of public key is necessary:
                                 preliminary check - 0, partly check - 1, full check - 2 .
   @param[out] UserPublKey_ptr - A pointer to the private key structure.
   @param[in]  TempBuff_ptr    - A pointer to the temp buffer structure for build function.

   @return CRYSError_t - CRYS_OK,
                         CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR
						 CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR
						 CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR
						 CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR
						 CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR
*/
 CEXPORT_C CRYSError_t _DX_ECPKI_BuildPublKey(CRYS_ECPKI_DomainID_t       DomainID,	          /*in*/				
                            									DxUint8_t                   *PublKeyIn_ptr,       /*in*/									
                            									DxUint32_t                  PublKeySizeInBytes,  /*in*/
                            									EC_PublKeyCheckMode_t       CheckMode,           /*in*/
                            									CRYS_ECPKI_UserPublKey_t    *UserPublKey_ptr,     /*out*/
                            									CRYS_ECPKI_BUILD_TempData_t *TempBuff_ptr         /*in*/ )
 {
  /* the Error return code identifier */
  CRYSError_t         Error; 

  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[4];
  
  /* max length */
  DxUint32_t          maxLength; 
  
  /*------------------------------
      CODE
  --------------------------------*/
 
                             
  #ifndef CRYS_NO_HASH_SUPPORT
  #ifndef CRYS_NO_ECPKI_SUPPORT  

  Error = CRYS_OK;

  /* ...... checking the validity of the User Private Key pointer ......... */
  if( UserPublKey_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR;
    goto end_function;
  }
	

  /* ...... checking the key database handle pointer ....................  */
  if( PublKeyIn_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR;
    goto end_function;
  }   

 
  /* ...... checking the EC domain ID.................... */
  if( DomainID >= CRYS_ECPKI_DomainID_OffMode )
  {
    Error = CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR;
    goto end_function;
  }
   

  if( CheckMode >= PublKeyChecingOffMode )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR;
    goto end_function;
  }
	 
  
  if( CheckMode != CheckPointersAndSizesOnly && TempBuff_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR;
    goto end_function;
  }

   /* 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_ECC_BUILD_PUB_KEY_OP_CODE;
  messageParam[1] = DomainID;
  messageParam[2] = CheckMode;
  messageParam[3] = PublKeySizeInBytes;
  
  /* 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 public key */
  maxLength = ((PublKeySizeInBytes + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_WriteParamater((DxUint32_t)PublKeyIn_ptr ,
                            PublKeySizeInBytes,
                            maxLength,
                            &sramOffset,
                            DX_TRUE);
  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_ECC_BUILD_PUB_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != CRYS_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
                          
  /* read data out */
  maxLength = ((sizeof(CRYS_ECPKI_UserPublKey_t) + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_ReadParamater((DxUint32_t)UserPublKey_ptr ,
                          sizeof(CRYS_ECPKI_UserPublKey_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;


  #endif /* !CRYS_NO_ECPKI_SUPPORT */
  #endif /* !CRYS_NO_HASH_SUPPORT */             
 
 } /* End of _DX_ECPKI_BuildPublKey() */
 
 EXPORT_SYMBOL(_DX_ECPKI_BuildPublKey);

 /***********************************************************************************
  *                     CRYS_ECPKI_ExportPublKey function                           *
  ***********************************************************************************/
 /**
   @brief The function converts an existed public key into the big endian and outputs it.

		  The function performs the following steps:
		  - checks input parameters,
		  - Converts the X,Y coordinates of public key EC point to big endians.
		  - Sets the public key as follows:
		    - In case WMDRM: PubKey = X||Y;
			- For other EC domains (according to IEEE 1363-2000):
			  * In case "Uncompressed"  PubKey = PC||X||Y, PC = 0x4 - single byte,
			  * In case "Compressed" PubKey = PC||X, where PC = 0x2|(LSBit of Y),
			  * In case "Hybrid"  PubKey = PC||X||Y, PC = 0x6|(LSBit of Y).
		  - Exits.

		  NOTE: - At this stage the said compressed form is not implemented  
			      and the function returns an error in this case,
				- Size of buffers for X and also Y is equal ModSizeInBytes.
     
   @param[in]  UserPublKey_ptr -   A pointer to the public key structure (in little 
                                   endian form). 
   @param[in]  Compression     -   An enumerator parameter, defines point compression.
   @param[out] ExternPublKey_ptr - A pointer to the exported public key structure in big 
                                   endian and point compression as defined by input parameter
								   Size of buffer must be not less than:
								     2*ModSiseInBytes - for WM DRM,
									 2*ModSiseInBytes+1 - for other domains.   
   @param[out] PublKeySizeInBytes - A pointer to variable for input size of user passed
                                    buffer for public key and output the size of converted 
                                    public key in bytes.

   @return CRYSError_t - CRYS_OK,
                         CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR      
                         CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR       
                         CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR    
                         CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR      
                         CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR          
                         CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR  
*/
CEXPORT_C CRYSError_t CRYS_ECPKI_ExportPublKey(CRYS_ECPKI_UserPublKey_t       *UserPublKey_ptr,       /*in*/
                                  					   CRYS_ECPKI_PointCompression_t  Compression,           /*in*/
                                  					   DxUint8_t                      *ExternPublKey_ptr,     /*in*/
                                  				     DxUint32_t                     *PublKeySizeInBytes_ptr /*in/out*/ )
{	 
  /* the Error return code identifier */
  CRYSError_t         Error;
  
  /* offset */
  DxUint32_t          sramOffset;
   
  /* read param */
  DxUint32_t          messageParam[2];
  
  /* max length */
  DxUint32_t          maxLength;  

  /*--------------------
      CODE
  ---------------------*/
  
  #ifndef CRYS_NO_HASH_SUPPORT                                    
  #ifndef CRYS_NO_ECPKI_SUPPORT  
 
  /* .................. INITIALIZATIONS  ................................. */ 
	   
  Error = CRYS_OK; /* Error initialization */


  /*............. Checking input parameters   ..............................*/

  /* ...... checking the key database handle pointer ....................  */
  if( UserPublKey_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR;
    goto end_function;
  }
         
  /* ...... checking the validity of the extern Public Key pointer ........ */
  if( ExternPublKey_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR;
    goto end_function;
  } 
	  
  /* ... checking the validity of the extern Public Key size pointer ...... */
  if( PublKeySizeInBytes_ptr == DX_NULL )
  {
    Error = CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR;
    goto end_function;
  } 


   /* 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_ECC_EXPORT_PUB_KEY_OP_CODE;
  messageParam[1] = Compression;
  
  /* send params */
  Error = SEPDriver_WriteParamater((DxUint32_t)messageParam ,
                           sizeof(DxUint32_t) * 2,
                           sizeof(DxUint32_t) * 2,
                           &sramOffset , 
                           DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
  
  /* send public key */
  maxLength = ((sizeof(CRYS_ECPKI_UserPublKey_t) + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_WriteParamater((DxUint32_t)UserPublKey_ptr ,
                            sizeof(CRYS_ECPKI_UserPublKey_t),
                            maxLength,
                            &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_ECC_EXPORT_PUB_KEY_OP_CODE)
  {
    Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
    goto end_function_unlock;
  }
   
  /* check the status */
  if(messageParam[1] != CRYS_OK)
  {
    Error = messageParam[1];
    goto end_function_unlock;
  }
  
  /* read data size */
  Error = SEPDriver_ReadParamater((DxUint32_t)PublKeySizeInBytes_ptr ,
                          sizeof(DxUint32_t),
                          sizeof(DxUint32_t),
                          &sramOffset , 
                          DX_FALSE);
  if(Error != DX_OK)
  {
      goto end_function_unlock;
  }
                          
  /* read data out */
  maxLength = ((*PublKeySizeInBytes_ptr + 3) / sizeof(DxUint32_t)) * sizeof(DxUint32_t);
  Error = SEPDriver_ReadParamater((DxUint32_t)ExternPublKey_ptr ,
                          *PublKeySizeInBytes_ptr,
                          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;

  #endif /* !CRYS_NO_ECPKI_SUPPORT */
  #endif /* !CRYS_NO_HASH_SUPPORT */             
 
} /* End of CRYS_ECPKI_ExportPublKey */

EXPORT_SYMBOL(CRYS_ECPKI_ExportPublKey);



