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);
}
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 */			      
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 ;
}