ta/wallet_ta.c
/**
  * Writes in the write cache and when needed flushes the data into the wallet
  * storage.
  * \param session_data A data pointer to a session context.
  * \param param_types The types of the four parameters.
  * \param params A pointer to an array of four parameters.
  * \return TEE_SUCCESS in case of success otherwise returns the result
  *         received from the failed operation. The information about all
  *         possible returns is present in TEE Client API Specification - 4.4.2
  *         published by GlobalPlatform.
  */
Writes in the write cache and when needed flushes the data into the wallet
storage.
\param session_data A data pointer to a session context.
\param param_types The types of the four parameters.
\param params A pointer to an array of four parameters.
\return TEE_SUCCESS in case of success otherwise returns the result
received from the failed operation. The information about all
possible returns is present in TEE Client API Specification - 4.4.2
published by GlobalPlatform.
Writes in the write cache and when needed flushes the data into the wallet storage . \ param session_data A data pointer to a session context . \ param param_types The types of the four parameters . \ param params A pointer to an array of four parameters . \ return TEE_SUCCESS in case of success otherwise returns the result received from the failed operation . The information about all possible returns is present in TEE Client API Specification - 4 . 4 . 2 published by GlobalPlatform .
static TEE_Result write_cache_wallet_storage(Session_data * session_data, uint32_t param_types, TEE_Param params[4])
{
	NonVolatileReturn nv_error = NV_NO_ERROR;
	TEE_Result result = TEE_SUCCESS;
	uint32_t address_tag;
	uint32_t address;
	uint32_t length;
    uint32_t end;
    uint32_t data_index;
    uint32_t exp_param_types;
	exp_param_types =  TEE_PARAM_TYPES(
							TEE_PARAM_TYPE_MEMREF_INPUT,
							TEE_PARAM_TYPE_VALUE_INOUT,
							TEE_PARAM_TYPE_NONE,
							TEE_PARAM_TYPE_NONE);
	if (param_types != exp_param_types || params[0].memref.buffer == NULL)
	{
		result = TEE_ERROR_BAD_PARAMETERS;
		nv_error = NV_IO_ERROR;
		goto cleanup1;
	}
	if (session_data->is_storage_open == false)
	{
		result = TEE_ERROR_BAD_STATE;
		nv_error = NV_IO_ERROR;
		goto cleanup1;
	}
    address = params[1].value.a;
    length = params[0].memref.size;
    end = address + length;
    data_index = 0;
    while (address < end)
    {
    	address_tag = address & SECTOR_TAG_MASK;
    	if (!(session_data->write_cache_valid)
    		|| (address_tag != (session_data->write_cache_tag)))
    	{
    		if (session_data->write_cache_valid)
    		{
    			result = flush_wallet_storage_internal(session_data, &nv_error);
    			if (result != TEE_SUCCESS || nv_error != NV_NO_ERROR)
			    {
			    	#ifdef OP_TEE_TA
			    	DMSG("Failed to flush into the wallet storage: 0x%x", result);
			    	#endif
			    	goto cleanup1;
			    }
    		}
    		session_data->write_cache_valid = true;
    		session_data->write_cache_tag = address_tag;
    		result = read_wallet_storage_internal(
    						session_data,
    						(uint8_t*)(session_data->write_cache),
    						(size_t)SECTOR_SIZE,
    						address_tag);
    		if (result != TEE_SUCCESS)
		    {
		    	#ifdef OP_TEE_TA
		    	DMSG("Failed to read from the wallet storage: 0x%x", result);
		    	#endif
		    	goto cleanup1;
		    }
    	}
    	(session_data->write_cache)[address & SECTOR_OFFSET_MASK] = ((uint8_t*)(params[0].memref.buffer))[data_index];
    	address++;
    	data_index++;
    }
    cleanup1:
    	params[1].value.b = (uint32_t)nv_error;
		return result;
}
static TEE_Result write_cache_wallet_storage ( Session_data * session_data , uint32_t param_types , TEE_Param params [ 4 ] ) { NonVolatileReturn nv_error = NV_NO_ERROR ; TEE_Result result = TEE_SUCCESS ; uint32_t address_tag ; uint32_t address ; uint32_t length ; uint32_t end ; uint32_t data_index ; uint32_t exp_param_types ; exp_param_types = TEE_PARAM_TYPES ( TEE_PARAM_TYPE_MEMREF_INPUT , TEE_PARAM_TYPE_VALUE_INOUT , TEE_PARAM_TYPE_NONE , TEE_PARAM_TYPE_NONE ) ; if ( param_types != exp_param_types || params [ 0 ] . memref . buffer == NULL ) { result = TEE_ERROR_BAD_PARAMETERS ; nv_error = NV_IO_ERROR ; goto cleanup1 ; } if ( session_data -> is_storage_open == false ) { result = TEE_ERROR_BAD_STATE ; nv_error = NV_IO_ERROR ; goto cleanup1 ; } address = params [ 1 ] . value . a ; length = params [ 0 ] . memref . size ; end = address + length ; data_index = 0 ; while ( address < end ) { address_tag = address & SECTOR_TAG_MASK ; if ( ! ( session_data -> write_cache_valid ) || ( address_tag != ( session_data -> write_cache_tag ) ) ) { if ( session_data -> write_cache_valid ) { result = flush_wallet_storage_internal ( session_data , & nv_error ) ; if ( result != TEE_SUCCESS || nv_error != NV_NO_ERROR ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif goto cleanup1 ; } } session_data -> write_cache_valid = true ; session_data -> write_cache_tag = address_tag ; result = read_wallet_storage_internal ( session_data , ( uint8_t * ) ( session_data -> write_cache ) , ( size_t ) SECTOR_SIZE , address_tag ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif goto cleanup1 ; } } ( session_data -> write_cache ) [ address & SECTOR_OFFSET_MASK ] = ( ( uint8_t * ) ( params [ 0 ] . memref . buffer ) ) [ data_index ] ; address ++ ; data_index ++ ; } cleanup1 : params [ 1 ] . value . b = ( uint32_t ) nv_error ; return result ; }
Writes in the write cache and when needed flushes the data into the wallet
 storage.
Writes in the write cache and when needed flushes the data into the wallet storage .
/*
	 * Expected:
	 * [IN]  params[0].memref.buffer-> Data to write in the storage.
	 * [IN]  params[0].memref.size  -> Size of the data to write in the storage.
	 * [IN]  params[1].value.a 	    -> Address where the data will be written to.
	 * [OUT] params[1].value.b 	    -> NonVolatileReturn error;
	 */ /* Sanity check */ /* Check if the wallet storage is open */ /* Set the end of the region to write */ /* Initialize data index variable */ /* Process till the end of the data to be written */ /* Setting the address of the sector to be written */ /*
         * If it write_cache is not valid or the address of the write_cache is
         * different from the address of the sector to be written
         */ /* Address is not in cache; load sector into memory */ /* Flush the cache to secure storage */ /* Set up the new values for the write cache */ /* Read the sector to be written from the secure storage */ /* Address is guaranteed to be in cache; write to the cache. */ /* End while (address < end) */ /* Resource cleanup */