예제 #1
0
/**
 * This function provide HASH function to process one buffer of data.
 * The function allocates an internal HASH Context , it initializes the 
 * HASH Context with the cryptographic attributes that are needed for 
 * the HASH block operation ( initialize H's value for the HASH algorithm ).
 * Then the function loads the Hardware with the initializing values and after 
 * that process the data block using the hardware to do hash .
 * At the end the function return the message digest of the data buffer .
 *
 * @param[in] OperationMode - The operation mode : MD5 or SHA1.
 * 
 * @param DataIn_ptr a pointer to the buffer that stores the data to be 
 *                       hashed .
 * 
 * @param DataInSize  The size of the data to be hashed in bytes. 
 *
 * @retval HashResultBuff a pointer to the target buffer where the 
 *                      HASE result stored in the context is loaded to.
 *
 * @return CRYSError_t on success the function returns CRYS_OK else non ZERO error.
 *
 */
CEXPORT_C CRYSError_t CRYS_HASH  ( CRYS_HASH_OperationMode_t    OperationMode,
                                   DxUint8_t*                   DataIn_ptr,
                                   DxUint32_t                   DataSize,
                                   CRYS_HASH_Result_t           HashResultBuff )
{    
	CRYSError_t Error = CRYS_OK;
	CRYS_HASHUserContext_t UserContext;
	
	Error = CRYS_HASH_Init( &UserContext, OperationMode);
	if (Error != CRYS_OK) {
		goto end;
	}

	Error = CRYS_HASH_Update( &UserContext, DataIn_ptr, DataSize );
	if (Error != CRYS_OK) {
		goto end;
	}

	Error = CRYS_HASH_Finish( &UserContext, HashResultBuff );
	
end:
	CRYS_HASH_Free( &UserContext );

	return Error;
}
예제 #2
0
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
{
    CRYSError_t ret = 0;
    CRYS_HASH_Result_t hashResult;

    if (sha256 == NULL || hash == NULL) {
        return BAD_FUNC_ARG;
    }

    ret = CRYS_HASH_Finish(&sha256->ctx, hashResult);

    if (ret != SA_SILIB_RET_OK){
        WOLFSSL_MSG("Error CRYS_HASH_Finish failed");
        return ret;
    }
    XMEMCPY(sha256->digest, hashResult, WC_SHA256_DIGEST_SIZE);

    XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);

    /* reset state */
    return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);
}
예제 #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_VerifyFinish(CRYS_RSAPubUserContext_t *UserContext_ptr,
                                 DxUint8_t *Sig_ptr)			      
{
   /* 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 buffer inside the context for manipulation of Data*/
   DxUint8_t   *ED_ptr;
   
   /*Parameter for the new size of the modulus N in bytes according to PKCS1 Ver 2.1*/
   DxUint16_t PrvNNewSizeBytes;/*rounded number of Bytes for padding2 length*/
	
   /*Temporary for the N size*/
   CRYSRSAPubKey_t *PubKey_ptr;
   
   /*Pointers to the Decrypted Data and Size*/
   DxUint8_t *D_ptr;
   DxUint16_t *DSize_ptr;
	
   /*The local variables for PKCS#1 Ver 1.5*/
   BerParserObj_t BerParserObj;
    	
   /* FUNCTION LOGIC */
   
   /* .................. initializing local variables ................... */
   /* ------------------------------------------------------------------- */   
   
   /* initializing the Error to O.K */
   Error = CRYS_OK;      

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

    RETURN_IF_RSA_UNSUPPORTED( UserContext_ptr , Sig_ptr , ccmWorkingContext_ptr , 
                              ED_ptr , PrvNNewSizeBytes , PubKey_ptr, D_ptr , 
                              DSize_ptr , BerParserObj.DigestAlg , 
                              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 pointer is DX_NULL return an error */
   if( UserContext_ptr == DX_NULL )
      return CRYS_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;          
   
   /* if the users context pointer is DX_NULL return an error */
   if( Sig_ptr == DX_NULL )
      return CRYS_RSA_INVALID_SIGNATURE_BUFFER_POINTER;

   #ifndef DX_OEM_FW
   /* sizeof signature need to be fixed */
   if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserContext_ptr, sizeof(CRYS_RSAPubUserContext_t)) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, Sig_ptr, sizeof(DxUint32_t))){
	   return CRYS_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
   }
   #endif

   /* if the users context TAG is illegal return an error - the context is invalid */
   if( UserContext_ptr->valid_tag != CRYS_RSA_VERIFY_CONTEXT_VALIDATION_TAG )
      return CRYS_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;   

   /* ................. aquiring the RSA context ............................. */
   /* ------------------------------------------------------------------------ */
   
   Error = CRYS_CCM_GetContext( UserContext_ptr,       				 /* the users context space - in */
                                (void **) &tempWorkingctx_ptr,    /* the CCM context returned - out */
                                DX_RSA_VERIFY_CONTEXT,                 
                                AES_DECRYPT_CONTEXT);			 	 /* need to decrypt context in AES_block*/   
    
    if( Error != CRYS_OK ) 
     return Error;                                       
   ccmWorkingContext_ptr = (RSAPubContext_t*)tempWorkingctx_ptr;
    
   ED_ptr = (DxUint8_t *)ccmWorkingContext_ptr->EBD;
   
   PubKey_ptr = (CRYSRSAPubKey_t *)ccmWorkingContext_ptr->PubUserKey.PublicKeyDbBuff;
   
   PrvNNewSizeBytes = (DxUint16_t)(PubKey_ptr->nSizeInBits/8);

  	/*rounding */   
   if(((PubKey_ptr->nSizeInBits) % 8) != 0)
    	PrvNNewSizeBytes++;
    	
   D_ptr = ccmWorkingContext_ptr->T_Buf;
   DSize_ptr = &ccmWorkingContext_ptr->T_BufSize;
   *DSize_ptr = sizeof(ccmWorkingContext_ptr->T_Buf);
   
   PLAT_LOG_DEV_PRINT(( 10 ," \n In RSA_VerifyFinish Before PRIM_Encrypt operation:\n" ));        
   PLAT_LOG_DEV_PRINT_DisplayBuffer(( 10 , (char *)" \nModulus N =\n" ,(DxUint8_t *)PubKey_ptr->n , PubKey_ptr->nSizeInBits/8));   	    
   PLAT_LOG_DEV_PRINT_DisplayBuffer(( 10 , (char *)" \nExp e =\n" ,(DxUint8_t *)PubKey_ptr->e , PubKey_ptr->eSizeInBits/8));   	        
      
	/* execute the expomnent - after correct building it is working with either CRT or PAIR mode*/ 
    Error = CRYS_RSA_PRIM_Encrypt(&ccmWorkingContext_ptr->PubUserKey,
                                  &ccmWorkingContext_ptr->PrimeData,
				                  Sig_ptr,
				                  PrvNNewSizeBytes,
				                  ED_ptr);
        
    if( Error != CRYS_OK ) 
     	goto END_WITH_ERROR;               

    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 10 , (char *)" \nSig in =\n" ,(DxUint8_t *)Sig_ptr , PrvNNewSizeBytes));   	    
    PLAT_LOG_DEV_PRINT_DisplayBuffer(( 10 , (char *)" \nIn RSA_VerifyFinish after CRYS_RSA_PRIM_Encrypt ; Output_ptr = " ,(DxUint8_t*)ED_ptr ,PrvNNewSizeBytes));				                  

	/*Initialize the Effective size in bits of the result*/
	ccmWorkingContext_ptr->EBDSizeInBits = CRYS_COMMON_GetBytesCounterEffectiveSizeInBits( ED_ptr,PrvNNewSizeBytes ); 			                        

   /*Operating the HASH Finish function only in case that Hash operation is needed*/
   if(ccmWorkingContext_ptr->HashOperationMode <= CRYS_RSA_HASH_SHA512_mode)
   	{
	   /*Operating the HASH Finish function*/
	   Error=CRYS_HASH_Finish(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
		                      ccmWorkingContext_ptr->HASH_Result);   		    
   	}		                      
	                      
   if( Error != CRYS_OK ) 
     goto END_WITH_ERROR;         

   switch(ccmWorkingContext_ptr->PKCS1_Version)
   {
#ifndef _INTERNAL_CRYS_NO_RSA_SCHEME_21_SUPPORT
	   case CRYS_PKCS1_VER21:
	      /*Operating the Verify primitive*/					                           
			Error = CRYS_RSA_PSS_Verify21(ccmWorkingContext_ptr);      

            if(Error!=CRYS_OK)
           		goto END_WITH_ERROR;
           		
			break;
#endif	   						
#ifndef _INTERNAL_CRYS_NO_RSA_SCHEME_15_SUPPORT
            case CRYS_PKCS1_VER15:	

			Error = CRYS_RSA_PKCS1_v1_5_Decode(ED_ptr,
												PrvNNewSizeBytes,
												D_ptr,
												DSize_ptr);
            if(Error!=CRYS_OK)
           		goto END_WITH_ERROR;
           			   						
		  	PLAT_LOG_DEV_PRINT_DisplayBuffer(( 10 , (char *)" \n In RSA_VerifyFinish ; After CRYS_RSA_PKCS1_v1_5_Decode ; D_ptr = " ,(DxUint8_t *)D_ptr ,*DSize_ptr));		               
		   
            /*Space for the Ber Parser output*/
		    BerParserObj.MessageDigest_ptr=ED_ptr;
				
		    /***********************
		     * Call the BER Parser - it can derive the hash mode from the input signature
		     ***********************/
		    Error=CRYS_RSA_BER_BerParser(   D_ptr, 
                                      		*DSize_ptr,
		                          			&BerParserObj);
		    if(Error!=CRYS_OK)
			   	goto END_WITH_ERROR;                     				 

				 		   /* setting the ber parser digest algorithm according to the selected HASH algorithm */
            switch(ccmWorkingContext_ptr->HashOperationMode)
			{
 		   		case CRYS_RSA_HASH_SHA1_mode:
 		   		case CRYS_RSA_After_SHA1_mode:	 		   
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_SHA1_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
                        goto END_WITH_ERROR;
                    }
			 		break;
			 		
			 	case CRYS_RSA_HASH_SHA224_mode:
 		   		case CRYS_RSA_After_SHA224_mode:	 		   
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_SHA224_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
                        goto END_WITH_ERROR;
                    }
			 		break;
			 
			 	case CRYS_RSA_HASH_SHA256_mode:
 		   		case CRYS_RSA_After_SHA256_mode:	 		   
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_SHA256_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
                        goto END_WITH_ERROR;
                    }
			 		break;
			 		
			 	case CRYS_RSA_HASH_SHA384_mode:
 		   		case CRYS_RSA_After_SHA384_mode:	 		   
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_SHA384_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
                        goto END_WITH_ERROR;
                    }
			 		break;		
			 		
			 	case CRYS_RSA_HASH_SHA512_mode:
 		   		case CRYS_RSA_After_SHA512_mode:	 		   
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_SHA512_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
                        goto END_WITH_ERROR;
                    }
			 		break;
			 	
				 		      			
 		   		case CRYS_RSA_HASH_MD5_mode:
 		   		case CRYS_RSA_After_MD5_mode:	 		   
				 		   		
                    if(BerParserObj.DigestAlg != (DxUint8_t)CRYS_HASH_MD5_mode)
                    {
                        /*check that the hash operation mode is consistent with the hash that was derived in the Ber encoder*/
                        Error = CRYS_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE;
			 		    goto END_WITH_ERROR;
                    }
			 		break;
			 		
                case CRYS_RSA_After_HASH_NOT_KNOWN_mode : /*used for PKCS1 v1.5 Verify only - possible to derive the hash mode from the signature*/
                        /*do nothing ==> the BER encoder already derived the correct hash function type*/
                        break;

				case CRYS_RSA_HASH_NO_HASH_mode:
 		      	default:
 		      			Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
 		      			goto END_WITH_ERROR;
            }		   				   
		   				   
	        if(DX_VOS_MemCmp(&BerParserObj.MessageDigest_ptr[0],(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result,ccmWorkingContext_ptr->HASH_Result_Size*4))/*The result Size is in words*/
	        {
	           Error = CRYS_RSA_ERROR_VER15_INCONSISTENT_VERIFY;
	           goto END_WITH_ERROR;     
	        }
						     
			break;
#endif
    default: 
			Error = CRYS_RSA_PKCS1_VER_ARG_ERROR;
			goto END_WITH_ERROR;

   }/*End of switch()*/
	    
   goto END;
   
   END:	/*On finish operation need to memset the context to zero so END and END_WITH_ERROR are the same*/
   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_VerifyFinish */