ta/wallet_ta.c
/**
  * Initialise a wallet (load it if it's there).
  * \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.
  */
Initialise a wallet (load it if it's there).
\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.
Initialise a wallet ( load it if it ' s there ) . \ 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 init_wallet(Session_data * session_data, uint32_t param_types, TEE_Param params[4])
{
	WalletErrors wallet_error = WALLET_NO_ERROR;
	TEE_Result result = TEE_SUCCESS;
	uint32_t exp_param_types;
	uint8_t hash[CHECKSUM_LENGTH];
	uint8_t uuid[UUID_LENGTH];
	TEE_Param read_params[4];
	uint32_t read_param_types;
	TEE_Param dasec_params[4];
	uint32_t dasec_param_types;
	TEE_Param rwr_params[4];
	uint32_t rwr_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);
	read_param_types = TEE_PARAM_TYPES(
									TEE_PARAM_TYPE_MEMREF_OUTPUT,
									TEE_PARAM_TYPE_VALUE_INOUT,
									TEE_PARAM_TYPE_NONE,
									TEE_PARAM_TYPE_NONE);
	dasec_param_types = TEE_PARAM_TYPES(
							TEE_PARAM_TYPE_MEMREF_INPUT,
							TEE_PARAM_TYPE_MEMREF_INPUT,
							TEE_PARAM_TYPE_NONE,
							TEE_PARAM_TYPE_NONE);
	rwr_param_types = TEE_PARAM_TYPES(
							TEE_PARAM_TYPE_MEMREF_OUTPUT,
							TEE_PARAM_TYPE_VALUE_INPUT,
							TEE_PARAM_TYPE_NONE,
							TEE_PARAM_TYPE_NONE);
	if (exp_param_types != param_types)
		return TEE_ERROR_BAD_PARAMETERS;
	session_data->wallet_nv_address = (params[1].value.a) * sizeof(WalletRecord);
	read_params[0].memref.buffer = (uint8_t*)uuid;
	read_params[0].memref.size = (size_t)UUID_LENGTH;
	read_params[1].value.a = (uint32_t)((session_data->wallet_nv_address) + offsetof(WalletRecord, unencrypted.uuid) + (uint32_t)GLOBAL_PARTITION_SIZE);
	result = read_cache_wallet_storage(session_data,
										read_param_types,
										read_params);
	if (result != TEE_SUCCESS)
	{
		#ifdef OP_TEE_TA
		DMSG("Failed to read from the cache: 0x%x", result);
		#endif
		wallet_error = WALLET_READ_ERROR;
		goto cleanup1;
	}
	dasec_params[0].memref.buffer = (uint8_t*)uuid;
    dasec_params[0].memref.size = (size_t)UUID_LENGTH;
    dasec_params[1].memref.buffer = (uint8_t*)(params[0].memref.buffer);
    dasec_params[1].memref.size = (size_t)(params[0].memref.size);
	result = derive_and_set_encryption_key(session_data,
											dasec_param_types,
											dasec_params);
	if (result != TEE_SUCCESS)
	{
		#ifdef OP_TEE_TA
		DMSG("Failed to derive_and_set_encryption_key : 0x%x", result);
		#endif
		wallet_error = WALLET_INVALID_OPERATION;
		goto cleanup1;
	}
	rwr_params[0].memref.buffer = (WalletRecord*)(session_data->current_wallet);
	rwr_params[0].memref.size = sizeof(WalletRecord);
	rwr_params[1].value.a = session_data->wallet_nv_address;
	result = read_wallet_record(session_data, rwr_param_types, rwr_params);
	if (result != TEE_SUCCESS)
	{
		#ifdef OP_TEE_TA
		DMSG("Failed to read wallet record: 0x%x", result);
		#endif
		if (result == TEE_ERROR_BAD_FORMAT)
        	wallet_error = WALLET_INVALID_OPERATION;
        else if (result == TEE_ERROR_BAD_STATE)
            wallet_error = WALLET_READ_ERROR;
        goto cleanup1;
	}
	if (session_data->current_wallet->unencrypted.version == VERSION_NOTHING_THERE)
		session_data->is_hidden_wallet = true;
	else
	{
		if ((session_data->current_wallet->unencrypted.version == VERSION_UNENCRYPTED)
			|| (session_data->current_wallet->unencrypted.version == VERSION_IS_ENCRYPTED))
			session_data->is_hidden_wallet = false;
		else
		{
			result = TEE_ERROR_BAD_STATE;
			wallet_error = WALLET_NOT_THERE;
			goto cleanup1;
		}
	}
	result = calculate_wallet_checksum_internal(session_data, hash);
	if(result != TEE_SUCCESS)
	{
		#ifdef OP_TEE_TA
		DMSG("Failed to calculate_wallet_checksum: 0x%x", result);
		#endif
		wallet_error = WALLET_INVALID_OPERATION;
		goto cleanup1;
	}
	if (big_compare_variable_size_internal(
						session_data->current_wallet->encrypted.checksum,
						hash,
						CHECKSUM_LENGTH) != BIGCMP_EQUAL)
	{
		#ifdef OP_TEE_TA
		DMSG("Failed to compare checksums");
		#endif
		result = TEE_ERROR_BAD_STATE;
		wallet_error = WALLET_NOT_THERE;
		goto cleanup1;
	}
	session_data->wallet_loaded = true;
	wallet_error = WALLET_NO_ERROR;
	cleanup1:
		params[1].value.b = (uint32_t)wallet_error;
		return result;
}
static TEE_Result init_wallet ( Session_data * session_data , uint32_t param_types , TEE_Param params [ 4 ] ) { WalletErrors wallet_error = WALLET_NO_ERROR ; TEE_Result result = TEE_SUCCESS ; uint32_t exp_param_types ; uint8_t hash [ CHECKSUM_LENGTH ] ; uint8_t uuid [ UUID_LENGTH ] ; TEE_Param read_params [ 4 ] ; uint32_t read_param_types ; TEE_Param dasec_params [ 4 ] ; uint32_t dasec_param_types ; TEE_Param rwr_params [ 4 ] ; uint32_t rwr_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 ) ; read_param_types = TEE_PARAM_TYPES ( TEE_PARAM_TYPE_MEMREF_OUTPUT , TEE_PARAM_TYPE_VALUE_INOUT , TEE_PARAM_TYPE_NONE , TEE_PARAM_TYPE_NONE ) ; dasec_param_types = TEE_PARAM_TYPES ( TEE_PARAM_TYPE_MEMREF_INPUT , TEE_PARAM_TYPE_MEMREF_INPUT , TEE_PARAM_TYPE_NONE , TEE_PARAM_TYPE_NONE ) ; rwr_param_types = TEE_PARAM_TYPES ( TEE_PARAM_TYPE_MEMREF_OUTPUT , TEE_PARAM_TYPE_VALUE_INPUT , TEE_PARAM_TYPE_NONE , TEE_PARAM_TYPE_NONE ) ; if ( exp_param_types != param_types ) return TEE_ERROR_BAD_PARAMETERS ; session_data -> wallet_nv_address = ( params [ 1 ] . value . a ) * sizeof ( WalletRecord ) ; read_params [ 0 ] . memref . buffer = ( uint8_t * ) uuid ; read_params [ 0 ] . memref . size = ( size_t ) UUID_LENGTH ; read_params [ 1 ] . value . a = ( uint32_t ) ( ( session_data -> wallet_nv_address ) + offsetof ( WalletRecord , unencrypted . uuid ) + ( uint32_t ) GLOBAL_PARTITION_SIZE ) ; result = read_cache_wallet_storage ( session_data , read_param_types , read_params ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif wallet_error = WALLET_READ_ERROR ; goto cleanup1 ; } dasec_params [ 0 ] . memref . buffer = ( uint8_t * ) uuid ; dasec_params [ 0 ] . memref . size = ( size_t ) UUID_LENGTH ; dasec_params [ 1 ] . memref . buffer = ( uint8_t * ) ( params [ 0 ] . memref . buffer ) ; dasec_params [ 1 ] . memref . size = ( size_t ) ( params [ 0 ] . memref . size ) ; result = derive_and_set_encryption_key ( session_data , dasec_param_types , dasec_params ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif wallet_error = WALLET_INVALID_OPERATION ; goto cleanup1 ; } rwr_params [ 0 ] . memref . buffer = ( WalletRecord * ) ( session_data -> current_wallet ) ; rwr_params [ 0 ] . memref . size = sizeof ( WalletRecord ) ; rwr_params [ 1 ] . value . a = session_data -> wallet_nv_address ; result = read_wallet_record ( session_data , rwr_param_types , rwr_params ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif if ( result == TEE_ERROR_BAD_FORMAT ) wallet_error = WALLET_INVALID_OPERATION ; else if ( result == TEE_ERROR_BAD_STATE ) wallet_error = WALLET_READ_ERROR ; goto cleanup1 ; } if ( session_data -> current_wallet -> unencrypted . version == VERSION_NOTHING_THERE ) session_data -> is_hidden_wallet = true ; else { if ( ( session_data -> current_wallet -> unencrypted . version == VERSION_UNENCRYPTED ) || ( session_data -> current_wallet -> unencrypted . version == VERSION_IS_ENCRYPTED ) ) session_data -> is_hidden_wallet = false ; else { result = TEE_ERROR_BAD_STATE ; wallet_error = WALLET_NOT_THERE ; goto cleanup1 ; } } result = calculate_wallet_checksum_internal ( session_data , hash ) ; if ( result != TEE_SUCCESS ) { #ifdef OP_TEE_TA DMSG ( " " , result ) ; #endif wallet_error = WALLET_INVALID_OPERATION ; goto cleanup1 ; } if ( big_compare_variable_size_internal ( session_data -> current_wallet -> encrypted . checksum , hash , CHECKSUM_LENGTH ) != BIGCMP_EQUAL ) { #ifdef OP_TEE_TA DMSG ( " " ) ; #endif result = TEE_ERROR_BAD_STATE ; wallet_error = WALLET_NOT_THERE ; goto cleanup1 ; } session_data -> wallet_loaded = true ; wallet_error = WALLET_NO_ERROR ; cleanup1 : params [ 1 ] . value . b = ( uint32_t ) wallet_error ; return result ; }
Initialise a wallet (load it if it's there).
Initialise a wallet ( load it if it ' s there ) .
/* Declare parameters that will be used in read operations */ /* Declare deriveAndSetEncryptionKey operation parameters */ /* Declare readWalletRecord operation parameters */ /*
	 * Expected:
	 * [IN]  params[0].memref.buffer -> Password.
	 * [IN]  params[0].memref.size   -> Length of the password.
	 * [IN]  params[1].value.a       -> Wallet specification number.
	 * [OUT] params[1].value.b       -> Wallet last error.
	 */ /*
	 * Read parameters:
	 * [OUT] params[0].memref.buffer -> Buffer to store the read data.
	 * [OUT] params[0].memref.size   -> Size of the buffer.
	 * [IN]  params[1].value.a       -> Starting address of the reading.
	 * [OUT] params[1].value.b       -> Size actually read.
	 */ /*
	 * deriveAndSetEncryptionKey parameters:
	 * [IN]  params[0].memref.buffer -> UUID.
	 * [IN]  params[0].memref.size   -> Length of the UUID.
	 * [IN]  params[1].memref.buffer -> Password.
	 * [IN]  params[1].memref.size   -> Length of the password.
	 */ /*
	 * readWalletRecord parameters:
	 * [OUT] params[0].memref.buffer -> Structure to write the wallet record read.
	 * [OUT] params[0].memref.size   -> Size of the wallet record to be read.
	 * [IN]  params[1].value.a       -> Address to read the wallet record from.
	 */ /* Sanity check on the parameters received */ /* Define the read operation parameters */ /* Define deriveAndSetEncryptionKey parameters */ /* Here should be an generic error but as it is not available ... */ /* Define readWalletRecord parameters */ /* Calculate the wallet checksum and check if it matches */ /* Here should be an generic error but as it is not available ... */ /* Not really needed but ... */ /* Resource cleanup */