예제 #1
0
/************************************************************************
*   The function performs  Hash update for data with the size not        
*   aligned to Hash block. 
*
*   Note: remBuffSize_ptr - a pointer to the remaining size of the 
*         temp buffer to fill by the data.
*
************************************************************************/
static CRYSError_t _DX_KDF_HASH_UnalignUpdate(
					CRYS_HASHUserContext_t  *hashContext_ptr, 
					DxUint8_t *data_ptr, DxUint32_t dataSize, 
					DxUint8_t *buff_ptr, DxUint32_t *remBuffSize_ptr)
{
	CRYSError_t error = CRYS_OK;
	DxUint32_t  tmpSize;
	DxUint8_t *tmp_ptr;

	/* set buff_ptr to begin of empty part of temp buffer */
	tmp_ptr = buff_ptr + CRYS_HASH_BLOCK_SIZE_IN_BYTES - *remBuffSize_ptr;
	
	/* if the temp buffer not empty, append it by the data and update Hash on it */
	if(*remBuffSize_ptr < CRYS_HASH_BLOCK_SIZE_IN_BYTES) {
		if(dataSize > *remBuffSize_ptr) {

			DX_VOS_FastMemCpy(buff_ptr, data_ptr, *remBuffSize_ptr);
			
			/* update on the data in temp buffer */
			error = CRYS_HASH_Update( hashContext_ptr, buff_ptr, 
						CRYS_HASH_BLOCK_SIZE_IN_BYTES);
			if(error != CRYS_OK)
				return error; 

			/* update pointers and sizes */
			data_ptr += *remBuffSize_ptr;
			dataSize -= *remBuffSize_ptr;
			*remBuffSize_ptr = CRYS_HASH_BLOCK_SIZE_IN_BYTES;
			tmp_ptr = buff_ptr;
		}
		else if(dataSize < *remBuffSize_ptr) {
			DX_VOS_FastMemCpy(tmp_ptr, data_ptr, dataSize);
			*remBuffSize_ptr -= dataSize;
			return error;
		}
	}

	/* Update Hash on remaining input data */
	tmpSize = dataSize % CRYS_HASH_BLOCK_SIZE_IN_BYTES;
	if (tmpSize > 0)
	{
		dataSize -= tmpSize;
		DX_VOS_FastMemCpy(tmp_ptr, data_ptr + dataSize, tmpSize);
		*remBuffSize_ptr -= tmpSize;
	} 

	if(dataSize > 0)
		error = CRYS_HASH_Update( hashContext_ptr, data_ptr, dataSize);

	return error;
}
/**
 * @brief This function generates a key pair
 *         
 *
 * @param[in] PubKey_ptr - the public key database.
 * @param[in] PrivKey_ptr - the private key database.
 *
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a
 *                        value MODULE_* as defined in .
 */
CRYSError_t LLF_PKI_RSA_GenerateKeyPair( 
                                         CRYSRSAPubKey_t  *PubKey_ptr,
                                         CRYSRSAPrivKey_t *PrivKey_ptr,
                                         CRYS_RSAKGData_t *KeyGenData_ptr )
{
   /* LOCAL DECLARATIONS */

   /* error identification */
   CRYSError_t Error;

   /* the P,Q primitive pointers */
   DxUint32_t *P_ptr,*Q_ptr;
   
   DxUint32_t Success, maxCountRegs, regSizeWords;

   /* the virtual address - localy defined just for code clearnce */
   DxUint32_t VirtualHwBaseAddr = 0;
   
   
   /* FUNCTION LOGIC */


   /* check that key size is not great, than allowed for Key Generation
      because pKA memory limit */
   if( PubKey_ptr->nSizeInBits > LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS )
	   return LLF_PKI_KG_UNSUPPORTED_KEY_SIZE;
   
   /* ............... initialize local variables ......................... */
   /* -------------------------------------------------------------------- */
   
   /* initialize the error identifier to the CRYS_OK ( success ) */
   Error = CRYS_OK;
   
   /* for avoid compailer warning */
   Success = 0;

   /* ............... getting the hardware semaphore ..................... */
   /* -------------------------------------------------------------------- */
   
   Error = DX_VOS_SemWait( SemPkaId , DX_INFINITE );
   
   if(Error) 
     goto Return;

   /* ............... mapping the physical memory to the virtual one ...... */
   /* --------------------------------------------------------------------- */
   
   Error = DX_VOS_MemMap( PLAT_CryptoCellBaseAddr,        /* low address - in */
                          LLF_PKI_HW_CRYPTO_ADDR_SPACE,   /* 16 LS bit space - in */
                          &VirtualHwBaseAddr );           /* The virtual address - out */
    
   if(Error)
     goto End_OnlySemRelease;
 
   /* ...................   initialize the PKA .............................*/
   
   /* maximal count of allocated registers */
   regSizeWords = (LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS/32)/2 + 1;
 
   /* maximal count registers */
   maxCountRegs = LLF_PKI_PKA_MAX_REGS_MEM_SIZE_BYTES / ((LLF_PKI_PKA_MAX_KEY_GENERATION_SIZE_BITS/8)/2 + 4);
   maxCountRegs = maxCountRegs > LLF_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS ? LLF_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS : maxCountRegs;
   
   Error = LLF_PKI_PKA_DefaultInitPKA( PubKey_ptr->nSizeInBits/2, 
                                       regSizeWords, 
                                       VirtualHwBaseAddr );
   if( Error != CRYS_OK )
       	   goto End;

   /* initialize the P,Q pointers to the buffers on the keygen data structure */
   P_ptr = KeyGenData_ptr->KGData.p;
   Q_ptr = KeyGenData_ptr->KGData.q;


   /* ............... calling the Non CRT or CRT KeyGen functions ......... */
   /* --------------------------------------------------------------------- */

   if( PrivKey_ptr->OperationMode == CRYS_RSA_NoCrt )
   {
     do
     {
	    Error = LLF_PKI_genKeyNonCrt(
				PubKey_ptr->e,  PubKey_ptr->eSizeInBits,    
				PubKey_ptr->nSizeInBits,
				0, /*testsCount should be set automatically*/ 
				&Success, 
				P_ptr,
				Q_ptr,
				PubKey_ptr->n,  
				PrivKey_ptr->PriveKeyDb.NonCrt.d, 
				((LLF_pki_key_gen_db_t *)(KeyGenData_ptr->KGData.crysRSAKGDataIntBuff))->temp, 
				VirtualHwBaseAddr );
					                
       if( Error != CRYS_OK )
	       goto End;
   
    #if !defined RSA_KG_NO_RND    
       if( !Success )
       {
   		   Error = CRYS_RSA_GenerateVectorInRangeX931( PubKey_ptr->nSizeInBits/(2*32), P_ptr);          
		   if( Error != CRYS_OK )			   
			   goto End;

		   Error = CRYS_RSA_GenerateVectorInRangeX931( PubKey_ptr->nSizeInBits/(2*32), Q_ptr);          
		   if( Error != CRYS_OK )			   
			   goto End;
       }
    #endif

     }while(!Success);
     
	/* set the key source as external - a PATCH since 'D' is not decrypted in SK2 */
	PrivKey_ptr->KeySource = CRYS_RSA_ExternalKey;
     
	 /* set the length of d in bits */
	 PrivKey_ptr->PriveKeyDb.NonCrt.dSizeInBits = \
			CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(
						PrivKey_ptr->PriveKeyDb.NonCrt.d, 
						(DxUint16_t)(PubKey_ptr->nSizeInBits+31)/32);

   }/* end of non CRT case */
   
   else  
   {        /* CRT case */ 
       do
       {
          Error = LLF_PKI_genKeyCrt(
			PubKey_ptr->e , PubKey_ptr->eSizeInBits,  
			PubKey_ptr->nSizeInBits,
			0, /*testsCount should be set automatically*/
			&Success,
			P_ptr, 
			Q_ptr,
			PubKey_ptr->n , 
			PrivKey_ptr->PriveKeyDb.Crt.dP,
			PrivKey_ptr->PriveKeyDb.Crt.dQ,
			PrivKey_ptr->PriveKeyDb.Crt.qInv,
			((LLF_pki_key_gen_db_t *)(KeyGenData_ptr->KGData.crysRSAKGDataIntBuff))->temp, 
			VirtualHwBaseAddr);

         if( Error != CRYS_OK )        
             goto End;
	
     #if !defined RSA_KG_NO_RND
         if( !Success )
         {
   		    Error = CRYS_RSA_GenerateVectorInRangeX931(PubKey_ptr->nSizeInBits/(2*32), P_ptr);          
		    if( Error != CRYS_OK )			   
			    goto End;

		    Error = CRYS_RSA_GenerateVectorInRangeX931(PubKey_ptr->nSizeInBits/(2*32), Q_ptr);          
		    if( Error != CRYS_OK )			   
			    goto End;
         }
     #endif     
       
       }while( !Success );
					                              
       /* Load P,Q vectors */
       DX_VOS_FastMemCpy(PrivKey_ptr->PriveKeyDb.Crt.P , P_ptr , PubKey_ptr->nSizeInBits / 16);  					                      
       DX_VOS_FastMemCpy(PrivKey_ptr->PriveKeyDb.Crt.Q , Q_ptr , PubKey_ptr->nSizeInBits / 16); 
	   
   }/* end of CRT case */	    					                      
           
   /* load 'n' to the private */
   DX_VOS_FastMemCpy(PrivKey_ptr->n , PubKey_ptr->n , PubKey_ptr->nSizeInBits / 8); 
   
End:
   /* clear secure sensitive data from allocated registers, including rT0,rT1 */
   LLF_PKI_PKA_ClearBlockOfRegs(0/*first*/, maxCountRegs - 2/*CountOfRegs*/, LenIDn+1, VirtualHwBaseAddr);
   LLF_PKI_PKA_ClearBlockOfRegs(30/*first*/, 2/*CountOfRegs*/, LenIDn+1, VirtualHwBaseAddr);
 

   /* end of PKA operations */
   LLF_PKI_PKA_FinishPKA( VirtualHwBaseAddr );	  


   /* .... un mappping the physical memory and releasing the semaphore ...... */
   /*-------------------------------------------------------------------------*/
   
   DX_VOS_MemUnMap( &VirtualHwBaseAddr,              /* virtual address - in */
                    LLF_PKI_HW_CRYPTO_ADDR_SPACE );  /* 16 LS bit space - in */

   
 End_OnlySemRelease:
   
   /* release the hardware semaphore */
   DX_VOS_SemGive ( SemPkaId );
            
 Return:   

   return Error;
   
    
}/* END OF CC_LLF_PKI_RSA_GenerateKeyPair */
예제 #3
0
/**
 * @brief CRYS_KDF_KeyDerivFunc performs key derivation according to one of some modes defined in standards: 
		ANSI X9.42-2001, ANSI X9.63, OMA_TS_DRM_DRM_V2_0-20050712-C, ISO/IEC 18033-2.
	
	The present implementation of the function allows the following operation modes:
	- CRYS_KDF_ASN1_DerivMode - mode based on  ASN.1 DER encoding;
	- CRYS_KDF_ConcatDerivMode - mode based on concatenation;
	- CRYS_KDF_X963_DerivMode = CRYS_KDF_ConcatDerivMode;
	- CRYS_KDF_OMA_DRM_DerivMode - specific mode for OMA DRM;
	- CRYS_KDF_ISO18033_KDF1_DerivMode - specific mode according to 
		ECIES-KEM algorithm (ISO/IEC 18033-2).

	The purpose of this function is to derive a keying data from the shared secret value and some 
	other optional shared information (SharedInfo).
		
	For calling the API on some specific modes may be used the following macros:
	- CRYS_KDF_ASN1_KeyDerivFunc ;			
	- CRYS_KDF_ConcatKeyDerivFunc ;
	- CRYS_KDF_OMADRM_DerivFunc.
 			
  \note The length in Bytes of the hash result buffer is denoted by "hashlen".
  \note All buffers arguments are represented in Big-Endian format.
 
  @param[in] ZZSecret_ptr - A pointer to shared secret value octet string. 
  @param[in] ZZSecretSize - The size of the shared secret value in bytes. The maximal
		size is defined as: CRYS_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE.
  @param[in] OtherInfo - The  pointer to structure , containing the data, 
		shared by two entities of agreement and the data sizes. 
		This argument is optional for some modes (if it is not needed - set NULL).
		On KDF OMA_DRM and two ISO/IEC 18033-2 modes - set NULL. 
        	On KDF ASN1 mode the OtherInfo and its AlgorithmID entry are mandatory.
  @param[in] KDFhashMode - The KDF identifier of hash function to be used. 
		The hash function output must be at least 160 bits.
  @param[in] derivation_mode - Specifies one of above described derivation modes.
  @param[out] KeyingData_ptr - A pointer to the buffer for derived keying data.
  @param[in] KeyingDataSizeBytes - The size in bytes of the keying data to be derived. 
		The maximal size is defined as: CRYS_KDF_MAX_SIZE_OF_KEYING_DATA.
 
  @return CRYSError_t - On success the value CRYS_OK is returned, 
			and on failure an ERROR as defined in CRYS_KDF_error.h:
			CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR
			CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR
			CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR
			CRYS_KDF_INVALID_SIZE_OF_DATA_TO_HASHING_ERROR
			CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR
			CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR
			CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR
*/
CEXPORT_C CRYSError_t  CRYS_KDF_KeyDerivFunc( 
					DxUint8_t                *ZZSecret_ptr,
					DxUint32_t                ZZSecretSize,
					CRYS_KDF_OtherInfo_t     *OtherInfo_ptr,
					CRYS_KDF_HASH_OpMode_t    KDFhashMode,
					CRYS_KDF_DerivFuncMode_t  derivation_mode,
					DxUint8_t                *KeyingData_ptr,
					DxUint32_t                KeyingDataSizeBytes )				                    
{

	/* FUNCTION DECLARATIONS */
	
	/* The return error identifier */
	CRYSError_t Error;
	/* HASH function context structure buffer and parameters  */
	CRYS_HASHUserContext_t  HashContext;
	CRYS_HASH_OperationMode_t hashMode;
	DxUint32_t  HashOutputSizeBytes;
	
	/*The result buffer for the Hash*/
	CRYS_HASH_Result_t   HashResultBuff;
	/* Total count of full HASH blockss for deriving the keying data */
	DxUint32_t  CountOfHashBlocks;

	/* Loop counters */
	DxUint32_t  i, j;
	/*counter of Hash blocks (to be hashed with ZZ and OtherInfo) */
	DxUint32_t Counter;
	/* Current output buffer position */
	DxUint32_t CurrentOutputBuffPos = 0;

	DxUint32_t  *OtherInfoEntry_ptr;
	DxUint8_t   *temp_ptr;
	DxUint32_t  remBuffSize;

	/*.... HASH Init function .....*/
	
	/* FUNCTION LOGIC */
	
	/* ............... local initializations .............................. */
	/* -------------------------------------------------------------------- */
	
	/* initializing the Error to O.K */
	Error = CRYS_OK;
	
	/* ............... if not supported exit .............................. */
	/* -------------------------------------------------------------------- */   
	PRINT_INFO("--->NOW inter into CRYS_KDF_KeyDerivFunc\n");
	RETURN_IF_KDF_UNSUPPORTED( ZZSecret_ptr , ZZSecretSize , OtherInfo_ptr , KDFhashMode , 
				derivation_mode , KeyingData_ptr , KeyingDataSizeBytes , hashMode , 
				HashOutputSizeBytes , HashContext.valid_tag , CountOfHashBlocks , 
				i , j , Counter , CurrentOutputBuffPos , HashResultBuff[0] , 
				OtherInfoEntry_ptr , temp_ptr ,  remBuffSize , Error , Error ); 
			      
	#ifndef CRYS_NO_HASH_SUPPORT 
	#ifndef CRYS_NO_KDF_SUPPORT 
			  
	
	/* ............... checking the parameters validity ................... */
	/* -------------------------------------------------------------------- */
	
	/* if an argument pointer is DX_NULL return an error */
	if( ZZSecret_ptr == DX_NULL || KeyingData_ptr == DX_NULL )
		return CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR;
	
	if( derivation_mode >= CRYS_KDF_DerivFunc_NumOfModes )
		return CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR;

	if( derivation_mode == CRYS_KDF_ASN1_DerivMode && 
	   (OtherInfo_ptr == DX_NULL || OtherInfo_ptr->SizeOfAlgorithmID == 0))
		return CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR;
	
	/*On KDF1 and KDF2 derivation modes set OtherInfo_ptr = DX_NULL */
	if(derivation_mode == CRYS_KDF_ISO18033_KDF1_DerivMode ||
	   derivation_mode == CRYS_KDF_ISO18033_KDF2_DerivMode){
		OtherInfo_ptr = DX_NULL;
	}
        
	/* Check sizes of the input data to be hashed according to KDF        * 
	*  limitations) 						      */
	if(ZZSecretSize == 0 || ZZSecretSize > CRYS_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE )
   		return CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR;
	
   	if( OtherInfo_ptr != DX_NULL )
	{
		if( OtherInfo_ptr->SizeOfAlgorithmID > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY )
		    return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR;

		if( OtherInfo_ptr->SizeOfPartyUInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY )
		    return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR;

		if( OtherInfo_ptr->SizeOfPartyVInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY )
		    return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR;

		if( OtherInfo_ptr->SizeOfSuppPrivInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY )
	  	    return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR;

		if( OtherInfo_ptr->SizeOfSuppPubInfo > CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY )
		    return CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR;
	}
	
	/* Check the size of keying data  */
	if( KeyingDataSizeBytes == 0 || KeyingDataSizeBytes > CRYS_KDF_MAX_SIZE_OF_KEYING_DATA) 
		return CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR;


	/*................ Setting parameters according to current operation modes .......... */
	/*------------------------------------------------------------------------------------*/
	switch( KDFhashMode )
	{
		case CRYS_KDF_HASH_SHA1_mode:
			hashMode = CRYS_HASH_SHA1_mode;
			HashOutputSizeBytes = CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
			break;
		case CRYS_KDF_HASH_SHA224_mode:
			hashMode = CRYS_HASH_SHA224_mode;
			HashOutputSizeBytes = CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
			break;
		case CRYS_KDF_HASH_SHA256_mode:
			hashMode = CRYS_HASH_SHA256_mode;
			HashOutputSizeBytes = CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
			break;
	
		case CRYS_KDF_HASH_SHA384_mode:
			hashMode = CRYS_HASH_SHA384_mode;
			HashOutputSizeBytes = CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
			break;
		case CRYS_KDF_HASH_SHA512_mode:
			hashMode = CRYS_HASH_SHA512_mode;
			HashOutputSizeBytes = CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
			break;
	
		default:
		    return CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR;
	}
	
	
	/* Count of HASH blocks needed for key derivation etc. */
	CountOfHashBlocks = ( KeyingDataSizeBytes + HashOutputSizeBytes - 1 )/ HashOutputSizeBytes;
	temp_ptr = (DxUint8_t*)&gKdfHashTempBuff[0];
	remBuffSize = CRYS_HASH_BLOCK_SIZE_IN_BYTES;

	/* **********  Keying data derivation loop ************ */

	for( i = 0; i < CountOfHashBlocks; i++ )
	{
		/*.... HASH Init function .....*/
		Error = CRYS_HASH_Init(&HashContext,
                           		hashMode);
		PRINT_INFO("--->NOW after CRYS_HASH_Init\n");		
		if(Error != CRYS_OK)
			return Error; 

		/*....... Hashing input data by calling HASH_Update function .......*/
		/*------------------------------------------------------------------*/

		/*.... Hashing of the shared secret value ....*/
		Error = _DX_KDF_HASH_UnalignUpdate(&HashContext,  
						ZZSecret_ptr,ZZSecretSize, 
						temp_ptr, &remBuffSize);
		PRINT_INFO("--->NOW after  _DX_KDF_HASH_UnalignUpdate\n");
		if(Error != CRYS_OK)
			goto End; 

		/*.... Hashing of the AlgorithmID (on ASN1 Derivation Mode only) ....*/
		if( derivation_mode == CRYS_KDF_ASN1_DerivMode )
		{
			Error = _DX_KDF_HASH_UnalignUpdate(&HashContext,  
						(DxUint8_t *)(OtherInfo_ptr->AlgorithmID),
						OtherInfo_ptr->SizeOfAlgorithmID, 
						temp_ptr, &remBuffSize);
			 PRINT_INFO("--->NOW after derivation_mode == CRYS_KDF_ASN1_DerivMode , _DX_KDF_HASH_UnalignUpdate\n");
			if(Error != CRYS_OK)
				goto End; 
		} 

		/* Set the blocks counter in big endianness mode */
		if(derivation_mode == CRYS_KDF_ISO18033_KDF1_DerivMode)
			Counter = CRYS_COMMON_REVERSE32(i);
		else		
			Counter = CRYS_COMMON_REVERSE32(i+1);
             PRINT_INFO("--->NOW after CRYS_COMMON_REVERSE32()\n");
		/*.... Hashing of the blocks counter ....*/ 
		Error = _DX_KDF_HASH_UnalignUpdate(&HashContext,  
					(DxUint8_t *)&Counter,
					sizeof(DxUint32_t), 
					temp_ptr, &remBuffSize);
		if(Error != CRYS_OK)
			goto End; 

		/* ..... Hashing of remaining data of the OtherInfo ..... */
		if( OtherInfo_ptr != DX_NULL )
		{
			/* Set OtherInfoEntry_ptr to second entry pointer */
			OtherInfoEntry_ptr = (DxUint32_t*)OtherInfo_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4 + 1;

			/* OtherInfo data concatenating and hashing loop */
			for( j = 0; j < CRYS_KDF_COUNT_OF_OTHER_INFO_ENTRIES - 1; j++ )
			{
				/* if entry exists hash it */
				if( *(OtherInfoEntry_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4) != 0 )
				{
					Error = _DX_KDF_HASH_UnalignUpdate(&HashContext,  
							(DxUint8_t *)OtherInfoEntry_ptr/*pointer to entry*/,
							*(OtherInfoEntry_ptr + CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4)/*size of entry*/, 
							temp_ptr, &remBuffSize);
					if(Error != CRYS_OK)
						goto End; 
				}
				/* Shift the pointer to the next entry */
				OtherInfoEntry_ptr += CRYS_KDF_MAX_SIZE_OF_OTHER_INFO_ENTRY/4 + 1;
			}
		} 

		/* last Hash update on remaining data in the temp buffer */
		if(remBuffSize < CRYS_HASH_BLOCK_SIZE_IN_BYTES) {
			Error = CRYS_HASH_Update(&HashContext, temp_ptr, 
						CRYS_HASH_BLOCK_SIZE_IN_BYTES - remBuffSize);
			 PRINT_INFO("--->NOW after CRYS_HASH_Update()\n");
			if(Error != CRYS_OK)
				goto End; 
		}

		/* ..........  HASH Finish operation ............. */
		Error = CRYS_HASH_Finish( &HashContext ,
					HashResultBuff );
		PRINT_INFO("--->NOW after CRYS_HASH_Finish()\n");
		if(Error != CRYS_OK)
			goto End; 

		/* Correction of output data size for last block ( if it is not full ) */
		if( i == CountOfHashBlocks - 1 )		
			HashOutputSizeBytes = KeyingDataSizeBytes - i * HashOutputSizeBytes;
		PRINT_INFO("--->NOW begin DX_VOS_FastMemCpy\n");
		/* Copying HASH data into output buffer */
		DX_VOS_FastMemCpy(&KeyingData_ptr[CurrentOutputBuffPos],(DxUint8_t *)HashResultBuff, HashOutputSizeBytes);
		
		/* Increment the output buffer position */
		CurrentOutputBuffPos += HashOutputSizeBytes;
	}
End:
	DX_VOS_MemSetZero(gKdfHashTempBuff, sizeof(gKdfHashTempBuff));
	
	return Error;

  #endif /*CRYS_NO_KDF_SUPPORT*/
  #endif /*CRYS_NO_HASH_SUPPORT*/

}/* END OF CRYS_KDF_KeyDerivationFunc */	
CEXPORT_C CRYSError_t _DX_RSA_VerifyInit(CRYS_RSAPubUserContext_t *UserContext_ptr,
                               CRYS_RSAUserPubKey_t *UserPubKey_ptr,
                               CRYS_RSA_HASH_OpMode_t hashFunc,
                               CRYS_PKCS1_MGF_t MGF,
                               DxUint16_t SaltLen,			      
                               CRYS_PKCS1_version PKCS1_ver)
{
   /* FUNCTION DECLERATIONS */

   /* The return error identifier */
   CRYSError_t Error;
      
   /* This pointer is allocated in order to remove compiler alias problems */
   void *tempWorkingctx_ptr;
   /* defining a pointer to the active context allcated by the CCM */
   RSAPubContext_t *ccmWorkingContext_ptr ;
         
   /*Pointer to the public key for lengths checking*/
   CRYSRSAPubKey_t *PubKey_ptr;

   /*The size of the modulus for lengths checking*/
   DxUint16_t ModulusSizeBytes;

   /* FUNCTION LOGIC */
   
   /* ............... local initializations .............................. */
   /* -------------------------------------------------------------------- */
   
   /* initializing the Error to O.K */
   Error = CRYS_OK;
   
   /* initialize the module size to cancel compilers warnings */
   ModulusSizeBytes = 0;
    

    /* ............... if not supported exit .............................. */
    /* -------------------------------------------------------------------- */   

    RETURN_IF_RSA_UNSUPPORTED(UserContext_ptr , UserPubKey_ptr , hashFunc , 
                              MGF , SaltLen , PKCS1_ver, ccmWorkingContext_ptr , 
                              PubKey_ptr , ModulusSizeBytes , Error , Error , 
                              Error , Error , Error , Error , Error , Error ,
                              Error , Error , Error , Error , Error); 
                              
    #ifndef CRYS_NO_HASH_SUPPORT                                      
    #ifndef CRYS_NO_PKI_SUPPORT                                      
      
   /* ............... checking the parameters validity ................... */
   /* -------------------------------------------------------------------- */
   
   
   /* if the users context ID pointer is DX_NULL return an error */
   if( UserContext_ptr == DX_NULL )
   
      return CRYS_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
      
   /*if the private key object is DX_NULL return an error*/   
   if (UserPubKey_ptr == DX_NULL)
   	  return CRYS_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
      
   /* check if the hash operation mode is legal */
   if( hashFunc >= CRYS_RSA_HASH_NumOfModes)
      return CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
      
   /* check if the MGF operation mode is legal */   
   if(MGF >= CRYS_RSA_NumOfMGFFunctions)
   	  return CRYS_RSA_MGF_ILLEGAL_ARG_ERROR;
   	  
   /* check that the PKCS1 version argument is legal*/
   if(PKCS1_ver >= CRYS_RSA_NumOf_PKCS1_versions)
   	  return CRYS_RSA_PKCS1_VER_ARG_ERROR;
   
   /*According to the PKCS1 ver 2.1 standart it is not recommended to use MD5 hash
   	therefore we do not support it */
   if(PKCS1_ver == CRYS_PKCS1_VER21 && hashFunc == CRYS_RSA_HASH_MD5_mode)
   		return CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
   
   #ifndef DX_OEM_FW
   if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserContext_ptr, sizeof(CRYS_RSAPubUserContext_t)) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, UserPubKey_ptr, sizeof(CRYS_RSAUserPubKey_t))){
	   return CRYS_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
   }
   #endif      
   
   /*If the validation tag is incorrect*/
   if(UserPubKey_ptr->valid_tag != CRYS_RSA_PUB_KEY_VALIDATION_TAG)
   	  return CRYS_RSA_PUB_KEY_VALIDATION_TAG_ERROR;   
		   
   		   
   /*Checking if a check on salt length is needed*/
   if(SaltLen != CRYS_RSA_VERIFY_SALT_LENGTH_UNKNOWN && PKCS1_ver == CRYS_PKCS1_VER21)
   {
        /*Initializing the Modulus Size in Bytes needed for SaltLength parameter check*/
        PubKey_ptr = (CRYSRSAPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff;

        /*Note: the (-1) is due to the PKCS#1 Ver2.1 standard section 9.1.1*/
        ModulusSizeBytes =  (DxUint16_t)((PubKey_ptr->nSizeInBits -1) / 8);
        if((PubKey_ptr->nSizeInBits -1) % 8)
   		        ModulusSizeBytes++;
   }

   /* .................. initializing local variables ................... */
   /* ------------------------------------------------------------------- */   
   
   /* ................. aquiring the RSA context ............................. */
   /* ----------------------------------------------------------------------- */
   
   	  
   /*Get the working context*/
   Error = CRYS_CCM_GetContext( UserContext_ptr,       				 /* the users context space - in */
				&tempWorkingctx_ptr,    /* the CCM context returned - out */
				DX_RSA_VERIFY_CONTEXT,                      /* AES type - in */ 
				AES_DONT_DECRYPT_CONTEXT);			 /* need to decrypt context in AES_block*/   
    
    if(Error != CRYS_OK ) 
	return Error;      
    ccmWorkingContext_ptr = (RSAPubContext_t*)tempWorkingctx_ptr;
   
    

   /*Reset the Context handler for improper previous values initialized*/
   DX_VOS_MemSet(ccmWorkingContext_ptr,0,sizeof(RSAPubContext_t));     
   
	                             
   /* ................. loading the context .................................. */
   /* ------------------------------------------------------------------------ */
 


   /*Initializing the Hash operation mode in the RSA Context level*/
   ccmWorkingContext_ptr->HashOperationMode = hashFunc;
   
   switch(ccmWorkingContext_ptr->HashOperationMode)
   {
   		 case CRYS_RSA_HASH_MD5_mode : 
				 ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_MD5_DIGEST_SIZE_IN_WORDS;	
                                       								   
			     Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)((ccmWorkingContext_ptr->CRYSPKAHashCtxBuff))),
	              		              CRYS_HASH_MD5_mode);		/*The MD5 mode according to the Hash level enum*/
	                           
			    if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      										 						
			   		
				break;
				
       case CRYS_RSA_HASH_SHA1_mode: 
            ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA1_DIGEST_SIZE_IN_WORDS;
       	    Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff))	,
	                    		       CRYS_HASH_SHA1_mode);	/*The SHA1 mode according to the Hash level enum*/
	                           
	   			if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      
			   		
			 	  break;
			 	  
	   case CRYS_RSA_HASH_SHA224_mode: 
            ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA224_DIGEST_SIZE_IN_WORDS;
       	    Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
	                    		       CRYS_HASH_SHA224_mode);	/*The SHA224 mode according to the Hash level enum*/
	                           
	   			if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      
			   		
			 	  break;
		
	   case CRYS_RSA_HASH_SHA256_mode: 
            ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA256_DIGEST_SIZE_IN_WORDS;
       	    Error = CRYS_HASH_Init( ((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
	                    		       CRYS_HASH_SHA256_mode);	/*The SHA256 mode according to the Hash level enum*/
	                           
	   			if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      
			   		
			 	  break;
			 	  
	   case CRYS_RSA_HASH_SHA384_mode: 
            ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA384_DIGEST_SIZE_IN_WORDS;
       	    Error = CRYS_HASH_Init(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
	                    		       CRYS_HASH_SHA384_mode);	/*The SHA384 mode according to the Hash level enum*/
	                           
	   			if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      
			   		
			 	  break;
			 	  
		case CRYS_RSA_HASH_SHA512_mode: 
            ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA512_DIGEST_SIZE_IN_WORDS;
       	    Error = CRYS_HASH_Init(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
	                    		       CRYS_HASH_SHA512_mode);	/*The SHA512 mode according to the Hash level enum*/
	                           
	   			if(Error != CRYS_OK)
			   		goto END_WITH_ERROR;      
			   		
			 	break;	  
			 	 	  
       case CRYS_RSA_After_MD5_mode: /*For PKCS1 v1.5 when the data in is already hashed with MD5*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_MD5_DIGEST_SIZE_IN_WORDS;
          break;	
			 	
       case CRYS_RSA_After_SHA1_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA1*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA1_DIGEST_SIZE_IN_WORDS;
          break;
          
       case CRYS_RSA_After_SHA224_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA224*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA224_DIGEST_SIZE_IN_WORDS;
          break;
          
       case CRYS_RSA_After_SHA256_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA256*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA256_DIGEST_SIZE_IN_WORDS;
          break;
       
       case CRYS_RSA_After_SHA384_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA384*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA384_DIGEST_SIZE_IN_WORDS;
          break;
          
       case CRYS_RSA_After_SHA512_mode: /*For PKCS1 v1.5 when the data in is already hashed with SHA512*/
          ccmWorkingContext_ptr->HASH_Result_Size = CRYS_HASH_SHA512_DIGEST_SIZE_IN_WORDS;
          break;	
			 				 	
       case CRYS_RSA_HASH_NO_HASH_mode:	/*Used for PKCS1 v1.5 Encrypt and Decrypt - not relevant in Sign-Verify*/

		   break;	/*do nothing*/		 						

	   case CRYS_RSA_After_HASH_NOT_KNOWN_mode : /*used for PKCS1 v1.5 Verify only - possible to derive the hash mode from the signature*/
           
		   if( PKCS1_ver == CRYS_PKCS1_VER21)
		   {
			   Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
			   goto END_WITH_ERROR;
		   }
		   
		   break;	/*do nothing*/		 						
         		
	   default: 
	 		Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
	 		goto END_WITH_ERROR;
	}   

   switch(PKCS1_ver)
   {
   		case CRYS_PKCS1_VER15: 
   		
   		    ccmWorkingContext_ptr->PKCS1_Version=CRYS_PKCS1_VER15;
          break;
          
   		case CRYS_PKCS1_VER21: 
   		
   		    ccmWorkingContext_ptr->PKCS1_Version=CRYS_PKCS1_VER21;
                  
          /*Checking restriction of Salt Length ; Hash output size and the mosulus*/
          if(SaltLen != CRYS_RSA_VERIFY_SALT_LENGTH_UNKNOWN &&
             ModulusSizeBytes < (DxUint32_t)(ccmWorkingContext_ptr->HASH_Result_Size*4 + SaltLen + 2))
             {
                 Error = CRYS_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR; 
                 goto END_WITH_ERROR;
             }
             break;
             
      default: 
								
             Error = CRYS_RSA_PKCS1_VER_ARG_ERROR; 
             goto END_WITH_ERROR;
   }

   switch(MGF)
   {
   		case CRYS_PKCS1_MGF1:
		case CRYS_PKCS1_NO_MGF:
   				ccmWorkingContext_ptr->MGF_2use = MGF;
				break;   									
   		default:
   				Error = CRYS_RSA_MGF_ILLEGAL_ARG_ERROR;
   				goto END_WITH_ERROR;
   }
   
   /*Copying the RSA Pub key argument to the context*/    
   DX_VOS_FastMemCpy((DxUint8_t *)&ccmWorkingContext_ptr->PubUserKey,(DxUint8_t *)UserPubKey_ptr,sizeof(CRYS_RSAUserPubKey_t));         
   
   /*Initial the Salt random length relevant for PKCS#1 Ver2.1*/
   ccmWorkingContext_ptr->SaltLen = SaltLen;
   
   /* Initialize the size of the modulus */
   ccmWorkingContext_ptr->nSizeInBytes = (((CRYSRSAPubKey_t*)UserPubKey_ptr->PublicKeyDbBuff)->nSizeInBits+7)/8;
      
   /* set the RSA tag to the users context */
   UserContext_ptr->valid_tag = CRYS_RSA_VERIFY_CONTEXT_VALIDATION_TAG;   
   
   goto END;
   
   END:
   /* ................. release the context ................................. */
   /* ----------------------------------------------------------------------- */
   
   Error = CRYS_CCM_ReleaseContext(UserContext_ptr,		/* the users context space - in */
                           ccmWorkingContext_ptr,       /* the CCM context returned - in */
                           DX_RSA_VERIFY_CONTEXT);      /* RSA type - in */ 
   
   return Error;
	
   END_WITH_ERROR:
   /* ................. release the context ................................. */
   /* ----------------------------------------------------------------------- */
   {   
   		CRYSError_t Error1 = CRYS_CCM_ReleaseContext(UserContext_ptr,			/* the users context space - in */
						                           ccmWorkingContext_ptr,       /* the CCM context returned - in */
						                           DX_RSA_VERIFY_CONTEXT);      /* RSA type - in */ 
						                           
	
		if(Error1 != CRYS_OK)
        {
			PLAT_LOG_DEV_PRINT(( 10 ," \n Error1 from CRYS_CCM_ReleaseContext is %lX \n" ,Error1));                              
        }
   }      

   /* .............. clearing the users context in case of error.......... */
   /* -------------------------------------------------------------------- */                           
   DX_VOS_MemSet(UserContext_ptr,0,sizeof(CRYS_RSAPubUserContext_t));
   
   return Error;
   
   #endif /* !CRYS_NO_HASH_SUPPORT */
   #endif /* !CRYS_NO_PKI_SUPPORT */                                     
	
}/* END OF _DX_RSA_VerifyInit */  				  
/**
 	Function Name: CRYS_RSA_PKCS1_v1_5_Decode
 	Date:   18-01-2005
 	Author:	Ohad Shperling
 
 
    \brief CRYS_RSA_PKCS1_v1_5_Encode implements EME-PKCS1_v1_5_Encoding algorithm 
   as defined in PKCS#1 v1.5 Sec 8.1
 
   @param[in] EncryptedBlock - Pointer to the Encrypted block to parse - given after an exponent operation
   @param[in] K - The modulus size denoted in octets.   
   @param[out] D_ptr - Pointer to the output Data - to parse out of the EncryptedBlock buffer
   @param[out] DSize - Denotes the Data size
	Note BlockType - 
					BlockType for PUB Key is 02
					BlockType for Priv Key is 01
					
   @return CRYSError_t - CRYS_OK,
                         
*/
CRYSError_t CRYS_RSA_PKCS1_v1_5_Decode(DxUint8_t     *EncryptedBlock,
									   DxUint16_t     K,
                                       DxUint8_t     *D_ptr,
                                       DxUint16_t    *DSize_ptr)
{
	/* The return error identifier */
	CRYSError_t Error;
	
	/* Padding String Size                   */
	DxUint16_t  I = 0;      
  
    /*The block Type parsed from the input*/
	CRYS_PKCS1_Block_Type 	BlockType;
	
	DxUint8_t Mask=0x00;
	
	/* FUNCTION LOGIC */
	/* .................. initializing local variables ................... */
	/* ------------------------------------------------------------------- */   
   
	/* initializing the Error to O.K */
	Error = CRYS_OK;      

		 /*-------------------------------------------*/
		 /*                                           */
		 /* Step 4 : Decrypted block parsing          */
		 /*                                           */
		 /*          00 || BT || PS || 00 || D        */
		 /*                                           */
		 /*          MSB                     LSB      */
		 /*          |<----- Size = K ------->|       */
		 /*                                           */
		 /*                                           */
		 /*-------------------------------------------*/
		 
	if(EncryptedBlock[0] != 0)
		return CRYS_RSA_15_ERROR_IN_DECRYPTED_BLOCK_PARSING;
		
	BlockType = (CRYS_PKCS1_Block_Type)EncryptedBlock[1];

	switch(BlockType)
	{
		  case CRYS_RSA_PKCS1_15_MODE00:  /*Mask=0x00;*/

			  /* Please refer to PKCS1 Ver 1.5 Standart for the security argument why
			     not to use this kind of Block Type */
			  return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED ;
		  								  
		  case CRYS_RSA_PKCS1_15_MODE01:  
			    
			  Mask=0xFF;
		  	  break;

		  case CRYS_RSA_PKCS1_15_MODE02:  
			  
			  Mask=Mask; /* junk - was created using Random */
		  	  break;

		  default:
			  return CRYS_RSA_15_ERROR_IN_DECRYPTED_BLOCK_PARSING;
	}
	
		  /* scan and check the padding string for CRYS_RSA_PKCS1_15_MODE01 */
		  if(BlockType==CRYS_RSA_PKCS1_15_MODE01)
		  {
			  for(I=2;I<K;I++)
			  {
			     if(EncryptedBlock[I]!=Mask) /* start scanning from cell 3 */
			        break;
			  }

			  /* check that the current octet (next after after PS) is 0x00 */
			  if( EncryptedBlock[I] != 0 )
				  return CRYS_RSA_15_ERROR_IN_DECRYPTED_DATA;
		  }	
          
		  /* scan the padding string for CRYS_RSA_PKCS1_15_MODE02 */
  		  if(BlockType==CRYS_RSA_PKCS1_15_MODE02)
  		  {
		 	  for(I=2;I<K;I++)
			  {
			     if(EncryptedBlock[I] == 0x00)
			     	break;
			  }
  		  }
  		  
		  /* check that PS size is not less than 8;   
		     note: at this point I is equal to PS size + 2  */
		  if( I - 2 < 8 )	
			  	return CRYS_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE;
			  	
		  /*Checking that the Output buffer Size is enough large for result output */
	      if( *DSize_ptr < (DxUint16_t)(K-(I+1)) )
	      {
		      *DSize_ptr = (DxUint16_t)(K-(I+1));
		      return CRYS_RSA_DECRYPT_INVALID_OUTPUT_SIZE;
	      }

		  else if( *DSize_ptr > (DxUint16_t)(K-(I+1))) 
			  /* set actual size of decrypted message */
			  *DSize_ptr = (DxUint16_t)(K-(I+1));		  		    		  

          /* copy decrypted message into output */
		  /*note - if I+1 == K than the decrypted data size is zero*/
		  DX_VOS_FastMemCpy( D_ptr, &EncryptedBlock[I+1], *DSize_ptr );
		   
		  return Error;
		  
}
CRYSError_t  CRYS_RSA_BER_BerParser(DxUint8_t 		*Data_ptr,
			   				        DxUint16_t 		DataSize,
                                    BerParserObj_t 	*BerParserObj_ptr)
{

    /*** Variables definitions and initializations ***/
    
    static const DxUint8_t AlgorithmID_MD5[]       ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04};
    static const DxUint8_t AlgorithmID_MD5_V2[]    ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05};
    static const DxUint8_t AlgorithmID_SHA[]       ={0x2b,0x0e,0x03,0x02,0x1a};
    static const DxUint8_t AlgorithmID_SHA224[]    ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04};
	static const DxUint8_t AlgorithmID_SHA256[]    ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01};
	static const DxUint8_t AlgorithmID_SHA384[]    ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02};
	static const DxUint8_t AlgorithmID_SHA512[]    ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03};

    /* Temporary variable for size*/
    DxUint16_t	TempLength=0;
    /* Calculated size of passed data and size of Message Digest (HASH) */
    DxUint16_t	CalcSize = 0, MDSize = 0;
    
    /* Certificate pointer */
    DxUint8_t*	Cert_ptr = Data_ptr;
    
    /* to avoid compilers warnings */
    DataSize = DataSize;

    /***** FUNCTION LOGIC ****/

    /* skip on the DigestInfo sequence tag */
    Cert_ptr++; /* skip on SEQUENCE tag */
    CRT_API_GetLengthField(&Cert_ptr, &TempLength);

    /* skip on the AlgorithmIdentifier sequence tag */
    Cert_ptr++; /* skip on SEQUENCE tag */
    CRT_API_GetLengthField(&Cert_ptr, &TempLength);

    /* skip on the OBJECT IDENTIFIER length field */
    if(*Cert_ptr++ != ASN1_OBJECT_IDENTIFIER)/* skip on OBJECT IDENTIFIER tag */
		return (CRYS_RSA_ERROR_BER_PARSING);
    
    CRT_API_GetLengthField(&Cert_ptr, &TempLength);
    
    if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_MD5,TempLength))         /* md5 hash algorithm */
    {
        BerParserObj_ptr->DigestAlg = CRYS_HASH_MD5_mode;
       
        MDSize = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES;
    }

    else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_MD5_V2,TempLength)) /* md5_v2 hash algorithm */
  	{
    	BerParserObj_ptr->DigestAlg =CRYS_HASH_MD5_mode;
    	
        MDSize = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES;
  	}
  
    else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA,TempLength))    /* sha1 hash algorithm */
	{
        BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA1_mode;
        
        MDSize = CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
    }
    
    else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA224,TempLength)) /* sha224 hash algorithm */
	{
		BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA224_mode;
		
        MDSize = CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
	    
	}

	else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA256,TempLength)) /* sha256 hash algorithm */
	{
		BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA256_mode;
		
        MDSize = CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
	}

	else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA384,TempLength)) /* sha384 hash algorithm */
	{
		BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA384_mode;
		
	    MDSize = CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES;	    
	}
	
	else if(!DX_VOS_MemCmp(Cert_ptr,AlgorithmID_SHA512,TempLength)) /* sha512 hash algorithm */
	{
		BerParserObj_ptr->DigestAlg = CRYS_HASH_SHA512_mode;
		
		MDSize = CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES;	
	}
	
	else

		return (CRYS_RSA_ERROR_BER_PARSING);/* unknown algorithm */


    /* move the Cert_ptr to next position */
    Cert_ptr += TempLength;

    /* skip on the DX_NULL tag */
    if(*Cert_ptr ++ != ASN1_NULL)/* skip on DX_NULL tag */
		return (CRYS_RSA_ERROR_BER_PARSING);
    
    CRT_API_GetLengthField(&Cert_ptr, &TempLength);

    /* skip on the BIT STRING length field + 0 (unused) byte */
    if(*Cert_ptr ++ != ASN1_OCTET_STRING) /* skip on BIT STRING tag */
		return (CRYS_RSA_ERROR_BER_PARSING);
    
    CRT_API_GetLengthField(&Cert_ptr, &TempLength);
    
    /* Countermeasure against CVE-2006-4339 (candidate) when using an RSA key with exponent 3,
       which allows remote attackers to forge a PKCS #1 v1.5 signature that is signed by the RSA */
            
    /* Calculate data size = the actual size we progress untill now (should be equal to
      the ASN.1 size)  + HASH size in bytes */
    CalcSize = (DxUint16_t)(Cert_ptr - Data_ptr) + MDSize;
      
    /* if there is more data (passed garbage), than return an error */
    if (DataSize > CalcSize)
       
         return CRYS_RSA_ERROR_BER_PARSING;


    /* Write a Message digest from the certificate to the output parameter */
    /*
       BerParserObj_ptr->MessageDigest_ptr = Cert_ptr;
    */
    switch(BerParserObj_ptr->DigestAlg)
    {
    	case CRYS_HASH_MD5_mode:
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES));        
		    /* MD5 size */
		    DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES);
			PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES));
		    break;
		    	
    	case CRYS_HASH_SHA1_mode:
    	
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES));               
	        /* SHA1 size */
	        DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES);
		    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES));
	    	break;
	    	
	    case CRYS_HASH_SHA224_mode:
    	
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES));               
	        /* SHA224 size */
	        DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES);
		    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES));
	    	break;
	    	
    	case CRYS_HASH_SHA256_mode:
    	
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES));               
	        /* SHA256 size */
	        DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES);
		    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES));
	    	break;
	    	
    	case CRYS_HASH_SHA384_mode:
    	
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES));               
	        /* SHA384 size */
	        DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES);
		    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES));
	    	break;
	    	
    	case CRYS_HASH_SHA512_mode:
    			
    		PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD before copy = " ,(DxUint8_t *)Cert_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES));               
	        /* SHA512 size */
	        DX_VOS_FastMemCpy((DxUint8_t*)BerParserObj_ptr->MessageDigest_ptr,(DxUint8_t*)Cert_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES);
		    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe MD After copy = " ,(DxUint8_t *)BerParserObj_ptr->MessageDigest_ptr,CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES));
	    	break;
    	
    	default:
    		break;
    }
      
    return (CRYS_OK);
}
CRYSError_t CRYS_RSA_BER_BerEncoder( DxUint8_t 		**Buffer_ptr,
			   		    DxUint8_t         *BufferSize,
			   		    DxUint16_t        BufferTotalSize,
                        BerParserObj_t 	*BerParserObj_ptr)
{

 /*
    The structure of the buffer that need to be formated

    step 1  : [30  = Object TAG]
    step 2  : [ Total size  ]
    step 2.1: [30  = Object TAG]
    step 2.2: [ The Size of the Digest Algo info upto 00]
    step 3  : [06 =  Object TAG]
    step 4  : [The size of Digest Alg ]
    step 5  : [The Digest Alg ident]
    step 6  : [05] [00] | [04]
    step 7  : [The Size of Message Digest]
    step 8  : [ The Message digest ]
 */

 static const DxUint8_t AlgorithmID_MD5_V2[] ={0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05};
 static const DxUint8_t AlgorithmID_SHA[]    ={0x2b,0x0e,0x03,0x02,0x1a};
 static const DxUint8_t AlgorithmID_SHA224[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04};
 static const DxUint8_t AlgorithmID_SHA256[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01};
 static const DxUint8_t AlgorithmID_SHA384[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02};
 static const DxUint8_t AlgorithmID_SHA512[] ={0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03};
 

 DxUint8_t TotalSize=0;
 DxUint8_t  *BufferInt_ptr;
 DxUint8_t  MDSize  = (DxUint8_t)(BerParserObj_ptr->MessageDigestSize);

 #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED
 DxUint8_t TotalSizeTmp;
 #endif

 BufferInt_ptr=*Buffer_ptr+BufferTotalSize;

 PLAT_LOG_DEV_PRINT(( 25 ," \nStart Printing from CRYS_RSA_BER_BerEncoder\n" ));

 PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe input buffer pointer (*Buffer_ptr)  =  " ,(DxUint8_t *)*Buffer_ptr,*BufferSize));            
 PLAT_LOG_DEV_PRINT(( 25 ," \nThe input buffer pointer after copy (BufferInt_ptr)= %p \n", BufferInt_ptr)); 
 PLAT_LOG_DEV_PRINT(( 25 ," \nTotal size = %d \n", BufferTotalSize));  
 

 /* step 8 : Set the MD at the end of the buffer */
 BufferInt_ptr-= MDSize;
 DX_VOS_FastMemCpy(BufferInt_ptr, BerParserObj_ptr->MessageDigest_ptr, MDSize);

 PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 8 - adding MD =   " ,(DxUint8_t *)BufferInt_ptr,MDSize));             

 /******************************************************************
  * Need to check the type of the size  ( at this stage its 1 octet)
  ******************************************************************/

 /* step 7 */
 BufferInt_ptr-=1;
 *BufferInt_ptr=MDSize;
 
 #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 TotalSizeTmp = CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES +1 ;
 /* TotalSizeTmp+=1;*/
 PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 7 - adding MD size " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));              
 #endif
 
  /* step 6 */
 BufferInt_ptr-= 3;
 *(BufferInt_ptr+0)=0x05;
 *(BufferInt_ptr+1)=0x00;
 *(BufferInt_ptr+2)=0x04;

 
 #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 TotalSizeTmp+=3;
 PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 6 - adding 050004 =  " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));               
 #endif


  /*step 5 + 4  */
 switch(BerParserObj_ptr->DigestAlg){
  case CRYS_HASH_MD5_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \nCRYS_ALG_HASH_MD_5 size = %d pointer before %p \n",sizeof(AlgorithmID_MD5_V2),BufferInt_ptr));
  							BufferInt_ptr-=sizeof(AlgorithmID_MD5_V2);

							PLAT_LOG_DEV_PRINT(( 25 ," \n BufferInt_ptr after = %p \n",BufferInt_ptr));
                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_MD5_V2,sizeof(AlgorithmID_MD5_V2));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=sizeof(AlgorithmID_MD5_V2);
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                               
                            #endif							

                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_MD5_V2);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));
 							#endif
 							TotalSize+=sizeof(AlgorithmID_MD5_V2);
                            break;
                            
  case CRYS_HASH_SHA1_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_1 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA),BufferInt_ptr));  							
									  
  							BufferInt_ptr-=sizeof(AlgorithmID_SHA);

							PLAT_LOG_DEV_PRINT(( 25 ," \n  BufferInt_ptr after = %p \n",BufferInt_ptr));  							

                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA,sizeof(AlgorithmID_SHA));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=TotalSizeTmp;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                
 							#endif


                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_SHA);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                 							    
 							#endif

                            TotalSize+=sizeof(AlgorithmID_SHA);
							break;
  
  case CRYS_HASH_SHA224_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_224 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA224),BufferInt_ptr));  							
									  
  							BufferInt_ptr-=sizeof(AlgorithmID_SHA224);

							PLAT_LOG_DEV_PRINT(( 25 ," \n  BufferInt_ptr after = %p \n",BufferInt_ptr));  							

                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA224,sizeof(AlgorithmID_SHA224));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=TotalSizeTmp;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                
 							#endif


                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_SHA224);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                 							    
 							#endif

                            TotalSize+=sizeof(AlgorithmID_SHA224);
							break;
							
							
  case CRYS_HASH_SHA256_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_256 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA256),BufferInt_ptr));  							
									  
  							BufferInt_ptr-=sizeof(AlgorithmID_SHA256);

							PLAT_LOG_DEV_PRINT(( 25 ," \n  BufferInt_ptr after = %p \n",BufferInt_ptr));  							

                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA256,sizeof(AlgorithmID_SHA256));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=TotalSizeTmp;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                
 							#endif


                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_SHA256);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                 							    
 							#endif

                            TotalSize+=sizeof(AlgorithmID_SHA256);
							break;
							
  case CRYS_HASH_SHA384_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_384 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA384),BufferInt_ptr));  							
									  
  							BufferInt_ptr-=sizeof(AlgorithmID_SHA384);

							PLAT_LOG_DEV_PRINT(( 25 ," \n  BufferInt_ptr after = %p \n",BufferInt_ptr));  							

                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA384,sizeof(AlgorithmID_SHA384));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=TotalSizeTmp;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                
 							#endif


                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_SHA384);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                 							    
 							#endif

                            TotalSize+=sizeof(AlgorithmID_SHA384);
							break;
  case CRYS_HASH_SHA512_mode:
							PLAT_LOG_DEV_PRINT(( 25 ," \n CRYS_ALG_HASH_SHA_512 size = %d pointer before %p \n",sizeof(AlgorithmID_SHA512),BufferInt_ptr));  							
									  
  							BufferInt_ptr-=sizeof(AlgorithmID_SHA512);

							PLAT_LOG_DEV_PRINT(( 25 ," \n  BufferInt_ptr after = %p \n",BufferInt_ptr));  							

                            DX_VOS_FastMemCpy(BufferInt_ptr,AlgorithmID_SHA512,sizeof(AlgorithmID_SHA512));

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
                                TotalSizeTmp+=TotalSizeTmp;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 5 - adding digest = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                
 							#endif


                            BufferInt_ptr-=1;
                            /* step 4 */
 							*BufferInt_ptr=sizeof(AlgorithmID_SHA512);

							#if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
 							    TotalSizeTmp+=1;
								PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 4 - adding digest size = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));                                 							    
 							#endif

                            TotalSize+=sizeof(AlgorithmID_SHA512);
							break;
							
  default :

							PLAT_LOG_DEV_PRINT(( 25 ," \n  Error in BerParserObj_ptr->HashType = %d ",BerParserObj_ptr->DigestAlg));  							       

       return  CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
 }

 /* step 3 */
 BufferInt_ptr-=1;
 *BufferInt_ptr=0x06;
 
 #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED
    TotalSizeTmp+=1;
	PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 3 - adding 06 = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));
 #endif

 /* step 2.2 */
  BufferInt_ptr-=1;
  *BufferInt_ptr = (DxUint8_t)(TotalSize + 4); /* total size stores the step5 size */

 /* step 2.1 */
  BufferInt_ptr-=1;
  *BufferInt_ptr =0x30;

 /* step 2 */

 BufferInt_ptr-=1 ;
 *BufferInt_ptr= (DxUint8_t)(4  + TotalSize+ 4 + MDSize);

 #if CRYS_LOG_DEV_MAX_LEVEL_ENABLED 
    TotalSizeTmp=*BufferInt_ptr;
	PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after step 2 - adding total size of buffer = " ,(DxUint8_t *)BufferInt_ptr,TotalSizeTmp));    
 #endif

 *BufferSize=(DxUint8_t)(*BufferInt_ptr+2); /* The +1 is for the octet of the suze and
                                      +1 is for the octet 30 that will be added in the next step */


 /* step 1 */
 BufferInt_ptr-=1;
 *BufferInt_ptr=0x30  ;


 /**********************************
  * At this point BufferInt_ptr points to the start of the data to send to
  **********************************/

  *Buffer_ptr=BufferInt_ptr;

  PLAT_LOG_DEV_PRINT(( 25 ," \n  The input buffer pointer            (*Buffer_ptr)  = %p",*Buffer_ptr));  							       
  PLAT_LOG_DEV_PRINT(( 25 ," \n  The input buffer pointer            (**Buffer_ptr )= %p",**Buffer_ptr));  							       
  PLAT_LOG_DEV_PRINT(( 25 ," \nThe input buffer pointer after copy (BufferInt_ptr)= %p",BufferInt_ptr));  							       
  PLAT_LOG_DEV_PRINT(( 25 ," \nTotal size = %d",*BufferSize));  							       
  PLAT_LOG_DEV_PRINT_DisplayBuffer(( 25 , (char *)" \nThe Buffer after formating = " ,(DxUint8_t *)BufferInt_ptr,CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES));    

  return CRYS_RSA_BER_ENCODING_OK ;
}
/**
 	Function Name: CRYS_RSA_PKCS1_v1_5_Encode
 	Date:   18-01-2005
 	Author:	Ohad Shperling
 
 
    \brief CRYS_RSA_PKCS1_v1_5_Encode implements EME-PKCS1_v1_5_Encoding algorithm 
   as defined in PKCS#1 v1.5 Sec 8.1
 
   @param[in] K - The modulus size denoted in octets.
   @param[in] M_ptr - Pointer to the Message to pad the ouput stream
   @param[in] MSize - Denotes the Message size
   @param[in] BlockType - 
					BlockType for PUB Key is 02
					BlockType for Priv Key is 01
   @param[out] Output_ptr - Pointer to a buffer which is at least K octets long
   
   @return CRYSError_t - CRYS_OK,
                         
*/
CRYSError_t CRYS_RSA_PKCS1_v1_5_Encode(DxUint16_t K,
									   CRYS_PKCS1_Block_Type 	BlockType,
                                       DxUint8_t     *M_ptr,
                                       DxUint32_t     MSize,
                                       DxUint8_t     *Output_ptr)
{

	/* The return error identifier */
	CRYSError_t Error;
	
	/* Padding String Size                   */
	DxUint16_t  PSSize,I,J;      
  
    
	/* FUNCTION LOGIC */
   
	/* .................. initializing local variables ................... */
	/* ------------------------------------------------------------------- */   
   
	/* initializing the Error to O.K */
	Error = CRYS_OK;      

	/*Initializing the EB buffer to zero*/
	DX_VOS_MemSet(Output_ptr,0x0,K);
	
	/* ............... checking the parameters validity ................... */
	/* -------------------------------------------------------------------- */	
	
	if(MSize>(DxUint32_t)(K-11))
		return CRYS_RSA_ENCODE_15_MSG_OUT_OF_RANGE;
		
	/*-------------------------------------------*/
	/*                                           */
	/* Step 1 : Encryption block formating       */
	/*                                           */
	/*          00 || BT || PS || 00 || D        */
	/*         MSByte                   LSByte   */
	/* Note: - 						    		 */
	/*       - BT for PUBKey is 02               */
	/*       - PS size is k-3-||D|| , padding    */
	/*            value is pseudorandomly non    */
	/*            zero                           */
	/*-------------------------------------------*/

	Output_ptr[0]=0x00; /* set the 00     */
	Output_ptr[1]=BlockType;    /* set Block Type */
	
	PSSize=(DxUint16_t)(K-3-MSize);
	
			  /*  In PKCS#1 V2 : The padding string PS in EME-PKCS1-v1_5
		      is at least eight octets long, which is a security 
		      condition for public-key operations that prevents an
		      attacker from recovering data by trying all possible 
		      encryption blocks. */
		      
	if(PSSize<0x08)
 	{		      
 		return CRYS_RSA_ENCODE_15_PS_TOO_SHORT;
 	}
 	
 	
	switch(BlockType)
	{

				 	 case CRYS_RSA_PKCS1_15_MODE00: 
				 	 		/* Please refer to PKCS1 Ver 1.5 Standart for the security argument why
				 	 		   not to use this kind of Block Type*/
				 	 		return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED ;
											   
					 case CRYS_RSA_PKCS1_15_MODE01:  DX_VOS_MemSet(&Output_ptr[2],0xFF,PSSize);
											    break;
					 case CRYS_RSA_PKCS1_15_MODE02:

				            Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]);
							if(Error != CRYS_OK)
							{
								return Error;
							}
							/*The random generation should not generate a zero octet according to the standart*/	
							J = K-2;
					 		for(I=2;I<PSSize+2;I++)
					 		{
					 			if(Output_ptr[I] == 0x00)
					 			{
					 			    /*Take a non zero octet from the end of the vector*/
					 				while(Output_ptr[J] == 0)
					 				{
					 				   J--;
					 				   continue;
					 				}
					 				
					 				/*Change the zero octet*/
									Output_ptr[I] = Output_ptr[J];
									J--;
								}
								if(J == I)
								{	/*This happens in very low probability*/
									/*All the extra random generated octets are zero or used*/
									/*regenerate */
									Error = CRYS_RND_GenerateVector((DxUint16_t)(K-2),&Output_ptr[2]);
									if(Error != CRYS_OK)
									{
										return Error;
									}															
									J = K-2;
									I=1;/*go back to the start of the loop*/
								}
							}
									
					 		break;
					 default:
					 		return CRYS_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED;
			 
	}

					
	/* add 00 */
	Output_ptr[K-MSize-1]=0x00;
	
	/* copy the data */
	DX_VOS_FastMemCpy(&Output_ptr[K-MSize],M_ptr,MSize);
	
	return CRYS_OK;
							 	
		
	
}