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 */  				  
示例#2
0
  /**
   @brief Generates a pair of private and public keys  
          in little endian ordinary (non-Montgomery) form. 
	  
	  This function generates a new key pair and initializes 
	  the variables and structures so that these can be used by other EC primitives. 
	  The function performs the following:
		1. Checks the validity of all of the function inputs. If one of the received 
		    parameters is not valid, it returns an error. The major checks are:
		   - Whether DomainID is valid 
		   - Whether the user private key pointer(UserPrivKey_ptr) is not NULL 
		   - Whether the User Public Key pointer (UserPublKey_ptr) is not NULL 
		   - Whether the User passed temp data buffer is not NULL.
		2. Cleans buffers for private and public key structures.
		3. Calls the low level function  LLF_ECPKI_GenKeyPair.
		4. Outputs user public and private key structures in little endian form.
		5. Cleans temporary buffers. 
		6. Exits. 
 
   @param[in]  DomainID        - The enumerator variable defines current EC domain.
   @param[out] UserPrivKey_ptr - A pointer to the private key structure.                                  
   @param[out] UserPubKey_ptr  - A pointer to the public key structure.                                  
   @param[in]  TempData_ptr    - Temporary buffers of size defined in CRYS_ECPKI_KG_TempData_t.

   @return <b>CRYSError_t</b>: <br> 
			 CRYS_OK<br> 
                         CRYS_ECPKI_GEN_KEY_ILLEGAL_D0MAIN_ID_ERROR<br>
			 CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR<br>
			 CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR<br>
			 CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR<br>
*/
CEXPORT_C CRYSError_t CRYS_ECPKI_GenKeyPair(
			CRYS_ECPKI_DomainID_t  	    DomainID,	        /*in*/   
			CRYS_ECPKI_UserPrivKey_t   *UserPrivKey_ptr,    /*out*/
			CRYS_ECPKI_UserPublKey_t   *UserPublKey_ptr,    /*out*/   
			CRYS_ECPKI_KG_TempData_t   *TempData_ptr        /*in*/ )
{
/* LOCAL INITIALIZATIONS AND DECLERATIONS */

/* the error identifier */
CRYSError_t Error;   


/* FUNCTION LOGIC */

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

RETURN_IF_ECPKI_UNSUPPORTED( DomainID, UserPrivKey_ptr, UserPublKey_ptr, TempData_ptr, 
			Error, Error, Error, Error, Error, Error, 
			Error, Error, Error, Error, Error, Error, 
			Error, Error, Error, Error, Error, Error );							 
		      
#ifndef CRYS_NO_HASH_SUPPORT                                   
#ifndef CRYS_NO_ECPKI_SUPPORT                                      

	/* ................. checking the validity of the pointer arguments ...... */
	/* ----------------------------------------------------------------------- */
	
	/* ...... checking the EC domain ID.................... */
	if( DomainID >= CRYS_ECPKI_DomainID_OffMode )
		return CRYS_ECPKI_GEN_KEY_ILLEGAL_D0MAIN_ID_ERROR;
	
	/* ...... checking the validity of the user private key pointer .......... */
	if( UserPrivKey_ptr == DX_NULL )
		return CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR;
	
	/* ...... checking the validity of the user public key pointer ........... */
	if( UserPublKey_ptr == DX_NULL )
		return CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR;
	
	/* ...... checking the validity of temp buffers         .................. */
	if( TempData_ptr == DX_NULL )
		return CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR;  
	
	if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPrivKey_ptr, sizeof(CRYS_ECPKI_UserPrivKey_t)) || 
	    DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPublKey_ptr, sizeof(CRYS_ECPKI_UserPublKey_t)) || 
	    ((TempData_ptr != DX_NULL) && DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, TempData_ptr, sizeof(CRYS_ECPKI_KG_TempData_t)))){
		return CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
	}
	
	/* ................ initializations  ............ */
	/* ---------------------------------------------- */
	
	/* initialize the error identifier to OK */
	Error = CRYS_OK;
	
	
	/* ................ clear all input structures ............................. */
	/* ------------------------------------------------------------------------- */
	
	DX_VOS_MemSet( UserPrivKey_ptr, 0, sizeof(CRYS_ECPKI_UserPrivKey_t) ); 
	DX_VOS_MemSet( UserPublKey_ptr, 0, sizeof(CRYS_ECPKI_UserPublKey_t) ); 
	
	/*     executing the key generation   */   
	
	Error = LLF_ECPKI_GenKeyPairCall( DomainID, UserPrivKey_ptr, 
				     UserPublKey_ptr, TempData_ptr );
	
	/*     on failure exit the function   */
	if( Error != CRYS_OK )  
		goto End;          
	
	/*     set the key valid tags         */   
	UserPrivKey_ptr->valid_tag  = CRYS_ECPKI_PRIV_KEY_VALIDATION_TAG; 
	UserPublKey_ptr->valid_tag  = CRYS_ECPKI_PUBL_KEY_VALIDATION_TAG; 
	
End:  
	
	/*     clear the KG data structure    */
	DX_VOS_MemSet ( TempData_ptr, 0, sizeof(CRYS_ECPKI_KG_TempData_t) );  
	
	return Error;
	

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

}/* END OF CRYS_ECPKI_GenKeyPair */                                       
CEXPORT_C CRYSError_t _DX_RSA_VerifyUpdate(CRYS_RSAPubUserContext_t *UserContext_ptr,
                                 DxUint8_t     *DataIn_ptr,
                                 DxUint32_t     DataInSize)
{
   /* 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;
   
   /* FUNCTION LOGIC */
   
   /* .................. initializing local variables ................... */
   /* ------------------------------------------------------------------- */   
   
   /* initializing the Error to O.K */
   Error = CRYS_OK;      
 
   /* ............... if not supported exit .............................. */
   /* -------------------------------------------------------------------- */   

   RETURN_IF_RSA_UNSUPPORTED( UserContext_ptr , DataIn_ptr , DataInSize , 
                              ccmWorkingContext_ptr , Error , Error, Error , 
                              Error , Error , 
                              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 Data In pointer is illegal and the data size is not 0 return an error */
   if( DataIn_ptr == DX_NULL && DataInSize )
      return CRYS_RSA_DATA_POINTER_INVALID_ERROR;
           
   /* if the data size is larger then 2^29 (to prevant an overflow on the transition to bits ) 
      return error */
   if( DataInSize >= (1UL << 29) )
      return CRYS_RSA_INVALID_MESSAGE_DATA_SIZE; 
	  
   #ifndef DX_OEM_FW
   /* DataIn can be smart pointer but it is tested either in the hash or in bypass operations */
   if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserContext_ptr, sizeof(CRYS_RSAPubUserContext_t)) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, DataIn_ptr, DataInSize)){
	   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;
    
   switch(ccmWorkingContext_ptr->HashOperationMode)
   {    
   /* The mode is either SHA1 or MD5 */
		case CRYS_RSA_HASH_SHA1_mode:
		case CRYS_RSA_HASH_MD5_mode:
   		case CRYS_RSA_HASH_SHA224_mode:
		case CRYS_RSA_HASH_SHA256_mode:
		case CRYS_RSA_HASH_SHA384_mode:
		case CRYS_RSA_HASH_SHA512_mode:
		
				/*Operate the Hash update function for relevant versions*/   			
				Error=CRYS_HASH_Update(((CRYS_HASHUserContext_t *)(ccmWorkingContext_ptr->CRYSPKAHashCtxBuff)),
							 			            DataIn_ptr,
										            DataInSize );
											
				if(Error != CRYS_OK)
				 	goto END_WITH_ERROR;   			
				 	
   				break;

		case CRYS_RSA_After_SHA1_mode:
		
		   		if(DataInSize != CRYS_HASH_SHA1_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
  			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;
		
		case CRYS_RSA_After_SHA224_mode:
		
		   		if(DataInSize != CRYS_HASH_SHA224_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;
		   		
		case CRYS_RSA_After_SHA256_mode:
		
		   		if(DataInSize != CRYS_HASH_SHA256_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;
		   		
		case CRYS_RSA_After_SHA384_mode:
		
		   		if(DataInSize != CRYS_HASH_SHA384_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		      
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;
		
		case CRYS_RSA_After_SHA512_mode:
		
		   		if(DataInSize != CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;
		   		   		
		case CRYS_RSA_After_MD5_mode:
				   		
		   		if(DataInSize != CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES)
		   		{	/* DataInSize must fit exactly to the size of Hash output that we support */
		   			Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
	   				goto END_WITH_ERROR;
	   			}
	   			
			        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	   		
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		   		break;		   		
		   		
		case CRYS_RSA_HASH_NO_HASH_mode:
				/*Do nothing*/
				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*/

			    if( DataInSize > CRYS_HASH_SHA512_DIGEST_SIZE_IN_BYTES ||
					DataInSize < CRYS_HASH_MD5_DIGEST_SIZE_IN_BYTES )
				{	
					/* DataInSize must fit exactly to the size of Hash output that we support */
					Error = CRYS_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
					goto END_WITH_ERROR;
				}
				/* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/	
				Error = CRYS_Bypass(DataIn_ptr,DataInSize,(DxUint8_t *)ccmWorkingContext_ptr->HASH_Result);
				if (Error != CRYS_OK)
					goto END_WITH_ERROR; 
		                /* set message size */
				ccmWorkingContext_ptr->HASH_Result_Size = (DxUint16_t)DataInSize / sizeof(DxUint32_t);				
				break;		   		
				
		default:
		 		Error = CRYS_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
		 		goto END_WITH_ERROR;
   }
   
   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_VerifyUpdate */			      		
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 */			      
/**
 	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;
							 	
		
	
}
/**
 * @brief CRYS_RSA_Build_PubKey populates a CRYSRSAPubKey_t structure with
 *       the provided modulus and exponent.
 *
 *	Assumption : the modulus and the exponent are presented in big endian.
 *
 * @param[out] PubKey_ptr - a pointer to the public key structure. This structure will be
 *            used as an input to the CRYS_RSA_PRIM_Encrypt API.
 *
 * @param[in] Exponent_ptr - a pointer to the exponent stream of bytes ( Big endian ).
 * @param[in] ExponentSize - The size of the exponent in bytes.  
 * @param[in] Modulus_ptr  - a pointer to the modulus stream of bytes ( Big endian ) the MS
 *           bit must be set to '1'.
 * @param[in] ModulusSize  - The size of the modulus in bytes. Sizes supported according to
 *           used platform from 64 to 256 bytes and in some platforms up to 512 bytes.  
 * 
 * @return CRYSError_t - On success CRYS_OK is returned, on failure a
 *                        value MODULE_* as defined in .
 */
CEXPORT_C CRYSError_t CRYS_RSA_Build_PubKey(  
					CRYS_RSAUserPubKey_t *UserPubKey_ptr,
					DxUint8_t *Exponent_ptr,
					DxUint16_t ExponentSize,
					DxUint8_t *Modulus_ptr,
					DxUint16_t ModulusSize )
{
   /* FUNCTION DECLARATIONS */

   /* the counter compare result */
   CRYS_COMMON_CmpCounter_t CounterCmpResult; 

   /* the effective size in bits of the modulus buffer */
   DxUint32_t ModulusEffectiveSizeInBits;
  
   /* the effective size in bits of the exponent buffer */
   DxUint32_t ExponentEffectiveSizeInBits;
   
   /* the public key database pointer */
   CRYSRSAPubKey_t *PubKey_ptr;

   /* the Error return code identifier */
   CRYSError_t Error = CRYS_OK; 

   /* Max Size of buffers in Key structure */
   DxUint32_t  buffSizeBytes = CRYS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES;

   /* FUNCTION LOGIC */

  
   /* ............... if not supported exit .............................. */
   /* -------------------------------------------------------------------- */   
   RETURN_IF_RSA_UNSUPPORTED( UserPubKey_ptr, Exponent_ptr, ExponentSize, 
                              Modulus_ptr, ModulusSize, CounterCmpResult, 
                              ModulusEffectiveSizeInBits, ExponentEffectiveSizeInBits, 
                              PubKey_ptr, buffSizeBytes, Error, Error, Error, Error, 
                              Error, Error, Error, Error, Error, Error, Error, Error); 
                              
   #ifndef CRYS_NO_HASH_SUPPORT                                      
   #ifndef CRYS_NO_PKI_SUPPORT                                      
   /* ................. checking the validity of the pointer arguments ....... */
   /* ------------------------------------------------------------------------ */
   

   #ifndef DX_OEM_FW
   if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPubKey_ptr, sizeof(CRYS_RSAUserPubKey_t)) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, Exponent_ptr, ExponentSize) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, Modulus_ptr, ModulusSize)){
	   return CRYS_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
   }
   #endif

   /* ...... checking the key database handle pointer .................... */
   if( UserPubKey_ptr == DX_NULL )
      return CRYS_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
      
   /* ...... checking the validity of the exponent pointer ............... */
   if( Exponent_ptr == DX_NULL )
      return CRYS_RSA_INVALID_EXPONENT_POINTER_ERROR;
      
   /* ...... checking the validity of the modulus pointer .............. */
   if( Modulus_ptr == DX_NULL )
      return CRYS_RSA_INVALID_MODULUS_POINTER_ERROR;

   if( ModulusSize > CRYS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES )
	   return CRYS_RSA_INVALID_MODULUS_SIZE;

   if( ExponentSize > CRYS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES )
	   return CRYS_RSA_INVALID_EXPONENT_SIZE;
   
   /* .................. copy the buffers to the key handle structure .... */
   /* -------------------------------------------------------------------- */
   /* setting the pointer to the key database */
   PubKey_ptr = ( CRYSRSAPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
   
   /* clear the public key db */
   DX_VOS_MemSet( PubKey_ptr , 0 , sizeof(CRYSRSAPubKey_t) );

   /* loading the buffers to little endian order of words in array; each word is loaded according to CPU endianness */
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PubKey_ptr->n, buffSizeBytes, Modulus_ptr, ModulusSize);
   if(Error)
	   return Error;

   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PubKey_ptr->e, buffSizeBytes, Exponent_ptr, ExponentSize);
   if(Error)
	   return Error;

   /* .................. initializing local variables ................... */
   /* ------------------------------------------------------------------- */
         
   /* .......... initializing the effective counters size in bits .......... */
   ModulusEffectiveSizeInBits =  CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PubKey_ptr->n, (ModulusSize+3)/4); 
   ExponentEffectiveSizeInBits = CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PubKey_ptr->e, (ExponentSize+3)/4);   

   /* .................. checking the validity of the counters ............... */
   /* ------------------------------------------------------------------------ */
   if((ModulusEffectiveSizeInBits < CRYS_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
      (ModulusEffectiveSizeInBits > CRYS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
      (ModulusEffectiveSizeInBits % CRYS_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)){

	   Error = CRYS_RSA_INVALID_MODULUS_SIZE;    
	   goto End;
   }     
   /*  verifying the modulus is odd  */
   if((PubKey_ptr->n[0] & 1UL) == 0){
	   Error = CRYS_RSA_MODULUS_EVEN_ERROR; 
	   goto End;
   }   
   
   /*  checking the exponent size is not 0 in bytes */
   if( ExponentEffectiveSizeInBits == 0 ){
	   Error = CRYS_RSA_INVALID_EXPONENT_SIZE;
	   goto End;
   }    
      
   /*  verifying the exponent is less then the modulus */
   CounterCmpResult = CRYS_COMMON_CmpMsbUnsignedCounters(Exponent_ptr, ExponentSize, Modulus_ptr, ModulusSize);
     
   if(CounterCmpResult != CRYS_COMMON_CmpCounter2GraterThenCounter1){
	   Error = CRYS_RSA_INVALID_EXPONENT_VAL;
	   goto End;
   }   
    
   /*  verifying the exponent is not less then 3 */
   if(ExponentEffectiveSizeInBits < 32 && PubKey_ptr->e[0] < CRYS_RSA_MIN_PUB_EXP_VALUE){       
	    Error = CRYS_RSA_INVALID_EXPONENT_VAL;
	    goto End;
   }   
        
   /* ................. building the structure ............................. */
   /* ---------------------------------------------------------------------- */
     
   /* setting the modulus and exponent size in bits */ 
   PubKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;   
   PubKey_ptr->eSizeInBits = ExponentEffectiveSizeInBits;
  
   /* ................ initialize the low level data .............. */
   Error = LLF_PKI_RSA_InitPubKeyDb(PubKey_ptr);
   
   if(Error)
     goto End; 
           
   /* ................ set the tag ................ */  
   UserPubKey_ptr->valid_tag = CRYS_RSA_PUB_KEY_VALIDATION_TAG;
   
   /* ................. end of the function .................................. */
   /* ------------------------------------------------------------------------ */
   
   End:
        
   /* if the structure created is not valid - clear it */
   if( Error != CRYS_OK ){
      DX_VOS_MemSet(UserPubKey_ptr, 0, sizeof(CRYS_RSAUserPubKey_t));
   }

   return Error;

   #endif /* !CRYS_NO_HASH_SUPPORT */
   #endif /* !CRYS_NO_PKI_SUPPORT */                                     

}/* END OF CRYS_RSA_Build_PubKey */
/******************************************************************************************

   @brief CRYS_RSA_Build_PrivKeyCRT populates a CRYSRSAPrivKey_t structure with
          the provided parameters, marking the key as a "CRT" key.
 
	Note: The "First" factor P must be great, than the "Second" factor Q.
 

   @param[out] UserPrivKey_ptr - A pointer to the public key structure. 
        		    This structure is used as input to the CRYS_RSA_PRIM_Decrypt API.
   @param[in] P_ptr - A pointer to the first factor stream of bytes (Big-Endian format)
   @param[in] PSize - The size of the first factor, in bytes.
   @param[in] Q_ptr - A pointer to the second factor stream of bytes (Big-Endian format)
   @param[in] QSize - The size of the second factor, in bytes.
   @param[in] dP_ptr - A pointer to the first factor's CRT exponent stream of bytes (Big-Endian format)
   @param[in] dPSize - The size of the first factor's CRT exponent, in bytes.
   @param[in] dQ_ptr - A pointer to the second factor's CRT exponent stream of bytes (Big-Endian format)
   @param[in] dQSize - The size of the second factor's CRT exponent, in bytes.
   @param[in] qInv_ptr - A pointer to the first CRT coefficient stream of bytes (Big-Endian format)
   @param[in] qInvSize - The size of the first CRT coefficient, in bytes.

*/
CEXPORT_C CRYSError_t CRYS_RSA_Build_PrivKeyCRT(
				CRYS_RSAUserPrivKey_t *UserPrivKey_ptr,
				DxUint8_t *P_ptr, 
				DxUint16_t PSize,
				DxUint8_t *Q_ptr,
				DxUint16_t QSize,
				DxUint8_t *dP_ptr, 
				DxUint16_t dPSize,
				DxUint8_t *dQ_ptr,
				DxUint16_t dQSize,
				DxUint8_t *qInv_ptr,
				DxUint16_t qInvSize)
{				                   
   /* FUNCTION DECLARATIONS */

    /* the counter compare result */
   CRYS_COMMON_CmpCounter_t CounterCmpResult; 

   /* the effective size in bits of the modulus factors buffer */
   DxUint32_t P_EffectiveSizeInBits;
   DxUint32_t Q_EffectiveSizeInBits;
   DxUint32_t dP_EffectiveSizeInBits;
   DxUint32_t dQ_EffectiveSizeInBits;
   DxUint32_t qInv_EffectiveSizeInBits;
   DxUint32_t ModulusEffectiveSizeInBits;

   /* the private key database pointer */
   CRYSRSAPrivKey_t *PrivKey_ptr;

   /* Max Size of buffers in CRT Key structure */
   DxUint32_t  buffSizeBytes = 4*((PSize + 3)/4) + 4;

   /* the Error return code identifier */
   CRYSError_t Error = CRYS_OK; 
  
   /* FUNCTION LOGIC */

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

   RETURN_IF_RSA_UNSUPPORTED( UserPrivKey_ptr, P_ptr, PSize, Q_ptr, QSize, dP_ptr, 
                              dPSize, dQ_ptr, dQSize, qInv_ptr, qInvSize, qInv_ptr, qInvSize,
                              CounterCmpResult, P_EffectiveSizeInBits, Q_EffectiveSizeInBits,
                              dP_EffectiveSizeInBits, dQ_EffectiveSizeInBits, qInv_EffectiveSizeInBits,
                              ModulusEffectiveSizeInBits, PrivKey_ptr, Error ); 
                              
   #ifndef CRYS_NO_HASH_SUPPORT                                      
   #ifndef CRYS_NO_PKI_SUPPORT                                      

   /* ................. checking the validity of the pointer arguments ....... */
   /* ------------------------------------------------------------------------ */
   
   /* ...... checking the key database handle pointer .................... */
   if(UserPrivKey_ptr == DX_NULL)
      return CRYS_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
      
   /* checking the first factor pointer validity */
   if(P_ptr == DX_NULL)
      return CRYS_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR;   

   /* checking the second factor pointer validity */
   if(Q_ptr == DX_NULL)
      return CRYS_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR; 
   
   /* checking the first factor exponent pointer validity */
   if(dP_ptr == DX_NULL)
      return CRYS_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR;   

   /* checking the second factor exponent pointer validity */
   if(dQ_ptr == DX_NULL)
      return CRYS_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR;
      
   /* checking the CRT coefficient */
   if(qInv_ptr == DX_NULL)
      return CRYS_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR;

   /* checking the input sizes */
   if(dPSize > PSize ||
      dQSize > QSize ||
      qInvSize > PSize){
	   return CRYS_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
   }

   #ifndef DX_OEM_FW
   if (DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPrivKey_ptr, sizeof(CRYS_RSAUserPrivKey_t)) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, P_ptr, PSize) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, Q_ptr, QSize) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, dP_ptr, dPSize) ||
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, dQ_ptr, dQSize) || 
       DxCcAcl_IsBuffAccessOk(ACCESS_READ, qInv_ptr, qInvSize)){
	   return CRYS_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
   }
   #endif 
   
   /* verifying the first factor exponent is less then the first factor */
   CounterCmpResult = 
      CRYS_COMMON_CmpMsbUnsignedCounters(dP_ptr, dPSize, P_ptr, PSize);
     
   if(CounterCmpResult != CRYS_COMMON_CmpCounter2GraterThenCounter1){ 
      Error = CRYS_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL;   
      goto End;
   }
     
   /* verifying the second factor exponent is less then the second factor */
   CounterCmpResult = 
      CRYS_COMMON_CmpMsbUnsignedCounters(dQ_ptr, dQSize, Q_ptr, QSize);
     
   if(CounterCmpResult != CRYS_COMMON_CmpCounter2GraterThenCounter1){ 
      Error = CRYS_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL;
      goto End;
   }   
      
   /* verifying the CRT coefficient is less then the first factor */
   CounterCmpResult = 
      CRYS_COMMON_CmpMsbUnsignedCounters(qInv_ptr, qInvSize, P_ptr, PSize);
     
   if(CounterCmpResult != CRYS_COMMON_CmpCounter2GraterThenCounter1){ 
      Error = CRYS_RSA_INVALID_CRT_COEFF_VAL;
      goto End;
   } 

    
   /* .................. copy the buffers to the key handle structure .... */
   /* -------------------------------------------------------------------- */

   /* setting the pointer to the key database */
   PrivKey_ptr = (CRYSRSAPrivKey_t*)UserPrivKey_ptr->PrivateKeyDbBuff;

   /* clear the private key db */
   DX_VOS_MemSet(PrivKey_ptr, 0, sizeof(CRYSRSAPrivKey_t));

   /* load the buffers to the data base */
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.P, buffSizeBytes, P_ptr, PSize);
   if(Error)
       return Error;
                              
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.Q, buffSizeBytes, Q_ptr, QSize);
   if(Error)
       return Error;
                              
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dP, buffSizeBytes, dP_ptr, dPSize);
   if(Error)
       return Error;
                              
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dQ, buffSizeBytes, dQ_ptr, dQSize);
   if(Error)
       return Error;
                              
   Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.qInv, buffSizeBytes, qInv_ptr, qInvSize);
   if(Error)
       return Error;

   /* ............... initialize local variables ......................... */
   /* -------------------------------------------------------------------- */
   
   /* initializing the effective counters size in bits */
   P_EffectiveSizeInBits = 
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.P, (PSize+3)/4);
       
   Q_EffectiveSizeInBits = 
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.Q, (QSize+3)/4);   
      
   dP_EffectiveSizeInBits = 
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dP, (dPSize+3)/4); 
      
   dQ_EffectiveSizeInBits = 
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dQ, (dQSize+3)/4);
      
   qInv_EffectiveSizeInBits = 
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.qInv, (qInvSize+3)/4); 
  
   /*  the first factor size is not 0 in bits */
   if(P_EffectiveSizeInBits == 0){
     Error = CRYS_RSA_INVALID_CRT_FIRST_FACTOR_SIZE;
     goto End;
   }  

   /* the second factor size is not 0 in bits */
   if(Q_EffectiveSizeInBits == 0){
     Error = CRYS_RSA_INVALID_CRT_SECOND_FACTOR_SIZE;
     goto End;
   }  

   /* checking that sizes of dP, dQ, qInv > 0 */
   if(dP_EffectiveSizeInBits == 0 || dQ_EffectiveSizeInBits == 0 || qInv_EffectiveSizeInBits == 0){
	   Error = CRYS_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
	   goto End;
   }



   /* ............... calculate the modulus N ........................... */
   /* -------------------------------------------------------------------- */
  
  
   Error = LLF_PKI_RSA_CallRMul(PrivKey_ptr->PriveKeyDb.Crt.P, P_EffectiveSizeInBits,
                                PrivKey_ptr->PriveKeyDb.Crt.Q, PrivKey_ptr->n);
   if(Error)
     goto End;                              
 
   ModulusEffectiveSizeInBits =  
      CRYS_COMMON_GetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (2*P_EffectiveSizeInBits+31)/32); 
   
   /* .................. checking the validity of the counters ............... */
   /* ------------------------------------------------------------------------ */
   
   /* the size of the modulus  */
   if(( ModulusEffectiveSizeInBits < CRYS_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS) ||
      ( ModulusEffectiveSizeInBits > CRYS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) ||
      ( ModulusEffectiveSizeInBits % CRYS_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)){
      Error = CRYS_RSA_INVALID_MODULUS_SIZE;    
      goto End;
   }   
   
   if((P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits) &&
      (P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits - 1)){    
      Error = CRYS_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE;
      goto End;
   }   
     
  
   /* ................. building the structure ............................. */
   /* ---------------------------------------------------------------------- */

   /* set the mode to CRT mode */
   PrivKey_ptr->OperationMode = CRYS_RSA_Crt;
   
   /* set the key source as external */
   PrivKey_ptr->KeySource = CRYS_RSA_ExternalKey;
   
   /* loading to structure the buffer sizes... */
   
   PrivKey_ptr->PriveKeyDb.Crt.PSizeInBits    = P_EffectiveSizeInBits; 
   PrivKey_ptr->PriveKeyDb.Crt.QSizeInBits    = Q_EffectiveSizeInBits; 
   PrivKey_ptr->PriveKeyDb.Crt.dPSizeInBits   = dP_EffectiveSizeInBits; 
   PrivKey_ptr->PriveKeyDb.Crt.dQSizeInBits   = dQ_EffectiveSizeInBits;
   PrivKey_ptr->PriveKeyDb.Crt.qInvSizeInBits = qInv_EffectiveSizeInBits;
   PrivKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
 
   /* ................ initialize the low level data .............. */
   Error = LLF_PKI_RSA_InitPrivKeyDb(PrivKey_ptr);
   
   if( Error != CRYS_OK )
   
     goto End; 
     							
   /* ................ set the tag ................ */  
   UserPrivKey_ptr->valid_tag = CRYS_RSA_PRIV_KEY_VALIDATION_TAG;

   /* ................. end of the function .................................. */
   /* ------------------------------------------------------------------------ */

   End:
 
   /* if the structure created is not valid - clear it */
   if(Error)
   
      DX_VOS_MemSet(UserPrivKey_ptr, 0, sizeof(CRYS_RSAUserPrivKey_t)); 

   return Error;
 
   #endif /* !CRYS_NO_HASH_SUPPORT */
   #endif /* !CRYS_NO_PKI_SUPPORT */                                     
      
}/* END OF CRYS_RSA_Build_PrivKeyCRT */
/*!\brief Builds (imports) the user private key structure from an existing 
            private key so that this structure can be used by other EC
            primitives.

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

		    The function performs the following operations:
			  - Checks validity of incoming variables and pointers.
			  - Checks, that 0 < PrivKey < r (r - EC generator order).
			  - Converts incoming key data from big endian into little endian form.
			  - Initializes variables and structures. 
   
   @param[in]  DomainID           The enumerator variable defines current EC domain.
   @param[in]  PrivKeyIn_ptr      Pointer to private key data. 
   @param[in]  PrivKeySizeInBytes Size of private key data in bytes. Must be great than null and
                                  less or equall to EC OrderSizeInBytes.
   @param[out] UserPrivKey_ptr    Pointer to the private key structure. 
                                  This structure is used as input to the ECPKI 
                                  cryptographic primitives.
   @return   CRYSError_t: 
			CRYS_OK
			CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR
			CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR
			CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR			 
*/	
CEXPORT_C CRYSError_t CRYS_ECPKI_BuildPrivKey(
				CRYS_ECPKI_DomainID_t      DomainID,	      /*in */   
				DxUint8_t  	          *PrivKeyIn_ptr,     /*in*/
				DxUint32_t                 PrivKeySizeInBytes,/*in*/
				CRYS_ECPKI_UserPrivKey_t  *UserPrivKey_ptr    /*out*/ ) 
{
	/* FUNCTION DECLARATIONS */
	
	/* the private key structure pointer */
	CRYS_ECPKI_PrivKey_t *PrivKey_ptr;
	
	/*  EC domain info structure and parameters */
	CRYS_ECPKI_DomainInfo_t  DomainInfo;  
	DxUint32_t  OrderSizeInBytes;
	
	/* the Error return code identifier */
	CRYSError_t Error; 
	
	
	
	/* FUNCTION LOGIC */
	
	/* ............... if not supported exit .............................. */
	/* -------------------------------------------------------------------- */   
	
	RETURN_IF_ECPKI_UNSUPPORTED( DomainID , PrivKeyIn_ptr , PrivKeySizeInBytes , 
			      UserPrivKey_ptr , PrivKey_ptr , DomainInfo.EC_ModulusSizeInBits ,                              
			      OrderSizeInBytes ,Error ,  Error , Error , Error , Error , Error , Error ,
			      Error , Error , Error , Error , Error , Error , Error ,Error ); 
				   
	
#ifndef CRYS_NO_ECPKI_SUPPORT  
    
	/* Error initialization */
	Error = CRYS_OK;
	
	/* ................. checking the validity of the pointer arguments ....... */
	/* ------------------------------------------------------------------------ */
	
	/* ...... checking the key database handle pointer ....................     */
	if( PrivKeyIn_ptr == DX_NULL )   
		return  CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR;   	   
	 
	/* ...... checking the validity of the User Private Key pointer ........... */
	if( UserPrivKey_ptr == DX_NULL ) 
		return  CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR;   		
	
	/* ...... checking the EC domain ID.................... */
	if( DomainID >= CRYS_ECPKI_DomainID_OffMode )
		return  CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR;  	
	
	if(DxCcAcl_IsBuffAccessOk(ACCESS_READ, PrivKeyIn_ptr, PrivKeySizeInBytes) || 
	   DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPrivKey_ptr, sizeof(CRYS_ECPKI_UserPrivKey_t))){
		return CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
	}
	
	/* Get EC Domain information from LLF level */
	Error = LLF_ECPKI_GetDomainInfo(DomainID, &DomainInfo);
	
	if( Error != CRYS_OK ) 
		 goto End;  
	
	/* EC order size in bytes */ 
	OrderSizeInBytes = (DomainInfo.EC_OrderSizeInBits + 7) / 8;
	
	if( PrivKeySizeInBytes == 0 || PrivKeySizeInBytes > OrderSizeInBytes)
		return  CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR; 
	
	/****************  FUNCTION LOGIC  **************************************/
	
	/* ...... copy the buffers to the key handle structure ................ */
	/* -------------------------------------------------------------------- */
	
	/* setting the pointer to the key database */
	PrivKey_ptr = (CRYS_ECPKI_PrivKey_t *)((void*)UserPrivKey_ptr->PrivKeyDbBuff);
	
	/* clear the private key db */
	DX_VOS_MemSet(PrivKey_ptr , 0 , sizeof(CRYS_ECPKI_PrivKey_t));
	
	/* loading the private key db to little endian and domain ID */
	Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(
		PrivKey_ptr->PrivKey, sizeof(PrivKey_ptr->PrivKey), 
		PrivKeyIn_ptr, PrivKeySizeInBytes);
	if(Error != CRYS_OK)
		return Error;
			     
	PrivKey_ptr->DomainID = DomainID;                         
	
	/* partly check the validity of the private key */
	Error = LLF_ECPKI_CheckPrivKeySize(DomainID, PrivKey_ptr->PrivKey, PrivKeySizeInBytes );
	
	if( Error != CRYS_OK )      
		goto End;
	
	/* initialize LLF private key database */
	Error = LLF_ECPKI_InitPrivKeyDb( PrivKey_ptr);
	
	if( Error != CRYS_OK )      
		goto End;
	
	/* ................. end of the function ................................. */
	/* ----------------------------------------------------------------------- */
	
	End:      
	/* if the created structure is not valid - clear it */
	if( Error != CRYS_OK )
	{
		DX_VOS_MemSet( UserPrivKey_ptr , 0 , sizeof(CRYS_ECPKI_UserPrivKey_t) ); 
		
		return Error;
	}
	
	/* ................ set the private key validation tag ................... */  
	UserPrivKey_ptr->valid_tag = CRYS_ECPKI_PRIV_KEY_VALIDATION_TAG;
	
	return Error;
	
#endif /* !CRYS_NO_ECPKI_SUPPORT */

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

	When operating the EC cryptographic algorithms with imported EC public
	key, this function should be called before using of the public key.
	
	The user must call this function by appropriate macros, according to necessary
	validation level [SEC1. ECC standard: 3.2]:
	- full checking of public key - CRYS_ECPKI_BuildPublKeyFullCheck,
	- partly checking of public key - CRYS_ECPKI_BuildPublKeyPartCheck,
	- checking the input pointers and sizes only - CRYS_ECPKI_BuildPublKey.
	
	The function performs the following operations:
	- Checks validity of incoming variables and pointers;
	- Converts incoming key data from big endian into little endian as follows:
	  If public key is given in uncompressed form the function converts 
	  coordinates X and Y separately to words arrays with little endian order of 
	  the wordsand copies them in output buffer, else returns an error;
	-   according to CheckMode parameter performs full or partly checking of public 
	    key validaty by calling the LLF function.
	-   Initializes variables and structures. 
	
	Incoming public key PublKeyIn is given in big endianness as butes array, containing
	concatenation PC||X||Y, where: 
		PC - point control single byte, defining the type of point: 0x4 - uncompressed,
		     other types not supported. 
		X,Y - EC point coordinates of public key,  size of X and Y equal to size of EC modulus,  
		      Size of buffers for X and also Y must be equal ModSizeInBytes.
 
   @param[in]  ECPKI_DomainID  - The enumerator variable defines current EC domain.
   @param[in]  PublKeyIn_ptr   - The pointer to private key data.
   @param[in]  PublKeySizeInBytes - Size of private key data in bytes 2*modulusSize + 1byte.
   @param[in]  CheckMode       - The parameter defining what checking of public key is necessary:
                                 preliminary check - 0, partly check - 1, full check - 2 .
   @param[out] UserPublKey_ptr - A pointer to the private key structure.
   @param[in]  TempBuff_ptr    - A pointer to the temp buffer structure for build function.

   @return CRYSError_t - CRYS_OK,
			CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR
			CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR
			CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR
			CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR
			CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR
*/
CEXPORT_C CRYSError_t _DX_ECPKI_BuildPublKey(
					CRYS_ECPKI_DomainID_t        DomainID,	          /*in*/				
					DxUint8_t	            *PublKeyIn_ptr,       /*in*/									
					DxUint32_t                   PublKeySizeInBytes,  /*in*/
					EC_PublKeyCheckMode_t        CheckMode,           /*in*/
					CRYS_ECPKI_UserPublKey_t    *UserPublKey_ptr,     /*out*/
					CRYS_ECPKI_BUILD_TempData_t *TempBuff_ptr         /*in*/ )
{
	/* FUNCTION DECLARATIONS */
	
	/* the private key structure pointer */
	CRYS_ECPKI_PublKey_t *PublKey_ptr;
	
	/* structure containing part of domain information */
	CRYS_ECPKI_DomainInfo_t   DomainInfo;
	
	/* EC modulus size in bytes*/
	DxUint32_t  ModSizeInBytes; 
	
	/* Point control PC ( 1 byte) PC and PC1 = PC&6*/
	DxUint8_t     PC, PC1;
	
	/* the Error return code identifier */
	CRYSError_t Error; 
	
	/* FUNCTION LOGIC */
	
	/* ............... if not supported exit .............................. */
	/* -------------------------------------------------------------------- */   
	
	RETURN_IF_ECPKI_UNSUPPORTED( DomainID, PublKeyIn_ptr, PublKeySizeInBytes, CheckMode, 
				UserPublKey_ptr, TempBuff_ptr, PublKey_ptr,                                 
				DomainInfo.EC_ModulusSizeInBits, ModSizeInBytes, PC, PC1, 
				Error, Error, Error, Error, Error, Error, Error, 
				Error, Error, Error, Error );   
				  
#ifndef CRYS_NO_ECPKI_SUPPORT  

	/* ...... checking the validity of the User Private Key pointer ......... */
	if( UserPublKey_ptr == DX_NULL ) 
		return  CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR;  
	
	/* ...... checking the key database handle pointer ....................  */
	if(PublKeyIn_ptr == DX_NULL)    
	   return  CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR;   	   
	
	/* ...... checking the EC domain ID.................... */
	if(DomainID >= CRYS_ECPKI_DomainID_OffMode)
		return  CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR;  
	
	if( CheckMode >= PublKeyChecingOffMode )
		return  CRYS_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR;
	
	if(CheckMode != CheckPointersAndSizesOnly && TempBuff_ptr == DX_NULL)
		return  CRYS_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR;
	
	if(DxCcAcl_IsBuffAccessOk(ACCESS_READ, PublKeyIn_ptr, PublKeySizeInBytes) || 
	DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, UserPublKey_ptr, sizeof(CRYS_ECPKI_UserPublKey_t)) ||
	((TempBuff_ptr != DX_NULL) && DxCcAcl_IsBuffAccessOk(ACCESS_READ_WRITE, TempBuff_ptr, sizeof(CRYS_ECPKI_BUILD_TempData_t)))){
		return CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR;
	}
	
	/* ...... Initializations  ............... */ 
	
	Error = CRYS_OK;
	
	/* get domain info and modulus size */
	Error = LLF_ECPKI_GetDomainInfo(DomainID, &DomainInfo);
	
	if(Error != CRYS_OK) 
		return Error;
	
	ModSizeInBytes = (DomainInfo.EC_ModulusSizeInBits + 7)/8;
	
	/* point control */
	PC = PublKeyIn_ptr[0];
	PC1 = PC & 0x6;
	
	/* preliminary check key size */
        if( PublKeySizeInBytes != 2*ModSizeInBytes + 1)
   		return  CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR; 

	/* ...... copy the buffers to the key handle structure ................ */
	/* -------------------------------------------------------------------- */
	
	/* setting the pointer to the key database */
	PublKey_ptr = (CRYS_ECPKI_PublKey_t *)((void*)UserPublKey_ptr->PublKeyDbBuff);
	
	/* clear the public key db */
	DX_VOS_MemSet((DxUint8_t*)UserPublKey_ptr , 0 , sizeof(CRYS_ECPKI_UserPublKey_t));
	
	/* Set DomainID into Builded public key */
	PublKey_ptr->DomainID = DomainID;
	
	if(PC1 == CRYS_EC_PointUncompressed || PC1 == CRYS_EC_PointHybrid)  /*  PC1 = 4 or PC1 = 6 */
	{
		/* Reverse mem copy public key Xin to X, Yin to Y */
		Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PublKey_ptr->PublKeyX, sizeof(PublKey_ptr->PublKeyX),
							PublKeyIn_ptr + 1, ModSizeInBytes);
		if(Error != CRYS_OK)
			return Error;
		
		Error = CRYS_COMMON_ConvertMsbLsbBytesToLswMswWords(PublKey_ptr->PublKeyY, sizeof(PublKey_ptr->PublKeyY),
							PublKeyIn_ptr + 1 + ModSizeInBytes, ModSizeInBytes);
		if(Error != CRYS_OK)
			return Error;                              
	}
	else
		return CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR;
	
	
	/* initialize LLF public key database   */
	/*--------------------------------------*/
	LLF_ECPKI_InitPubKeyDb( PublKey_ptr);
	
	
	/*................ checking the public key ............................*/
	/*---------------------------------------------------------------------*/
	if(CheckMode >= ECpublKeyPartlyCheck){
		/* full checking of the public key validity */
		Error = LLF_ECPKI_CheckPublKeyCall(PublKey_ptr, CheckMode, (DxUint32_t*)TempBuff_ptr);
	}
	else{
		/* partly checking of the public key validity */
		Error = LLF_ECPKI_CheckPublKeySize(DomainID, PublKey_ptr->PublKeyX, 2*ModSizeInBytes);
	}
	
	if(Error != CRYS_OK){
		/* if created structure is not valid - clear it and exit */
		DX_VOS_MemSet(UserPublKey_ptr, 0, sizeof(CRYS_ECPKI_UserPublKey_t));    	    
		return Error;
	}
	
	/* ................ set the private key validation tag ................... */  
	UserPublKey_ptr->valid_tag = CRYS_ECPKI_PUBL_KEY_VALIDATION_TAG;
	
	
	/* ................. end of the function ................................. */
	/* ----------------------------------------------------------------------- */
	
	return Error;
	

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