April 8, 2021 at 11:46 am

class protected_fs_file
	union {
		struct {
			uint64_t meta_data_node_number; // for recovery purpose, so it is easy to write this node
			meta_data_node_t file_meta_data; // actual data from disk's meta data node
		recovery_node_t meta_data_recovery_node;

	meta_data_encrypted_t encrypted_part_plain; // encrypted part of meta data node, decrypted
	file_mht_node_t root_mht; // the root of the mht is always needed (for files bigger than 3KB)

	FILE* file; // OS's FILE pointer
	open_mode_t open_mode;
	uint8_t read_only;
	int64_t offset; // current file position (user's view)
	bool end_of_file; // flag

	int64_t real_file_size;
	bool need_writing; // flag
	uint32_t last_error; // last operation error
	protected_fs_status_e file_status;
	sgx_thread_mutex_t mutex;

	uint8_t use_user_kdk_key;
	sgx_aes_gcm_128bit_key_t user_kdk_key; // recieved from user, used instead of the seal key

	sgx_aes_gcm_128bit_key_t cur_key;
	sgx_aes_gcm_128bit_key_t session_master_key;
	uint32_t master_key_count;
	char recovery_filename[RECOVERY_FILE_MAX_LEN]; // might include full path to the file

	lru_cache cache;

	// these don't change after init...
	sgx_iv_t empty_iv;
	sgx_report_t report;

	void init_fields();
	bool cleanup_filename(const char* src, char* dest);
	bool parse_mode(const char* mode);
	bool file_recovery(const char* filename);
	bool init_existing_file(const char* filename, const char* clean_filename, const sgx_aes_gcm_128bit_key_t* import_key);
	bool init_new_file(const char* clean_filename);
	bool generate_secure_blob(sgx_aes_gcm_128bit_key_t* key, const char* label, uint64_t physical_node_number, sgx_aes_gcm_128bit_tag_t* output);
	bool generate_secure_blob_from_user_kdk(bool restore);
	bool init_session_master_key();
	bool derive_random_node_key(uint64_t physical_node_number);
	bool generate_random_meta_data_key();
	bool restore_current_meta_data_key(const sgx_aes_gcm_128bit_key_t* import_key);
	file_data_node_t* get_data_node();
	file_data_node_t* read_data_node();
	file_data_node_t* append_data_node();
	file_mht_node_t* get_mht_node();
	file_mht_node_t* read_mht_node(uint64_t mht_node_number);
	file_mht_node_t* append_mht_node(uint64_t mht_node_number);
	bool write_recovery_file();
	bool set_update_flag(bool flush_to_disk);
	void clear_update_flag();
	bool update_all_data_and_mht_nodes();
	bool update_meta_data_node();
	bool write_all_changes_to_disk(bool flush_to_disk);
	void erase_recovery_file();
	bool internal_flush(/*bool mc,*/ bool flush_to_disk);

	protected_fs_file(const char* filename, const char* mode, const sgx_aes_gcm_128bit_key_t* import_key, const sgx_aes_gcm_128bit_key_t* kdk_key);

	size_t write(const void* ptr, size_t size, size_t count);
	size_t read(void* ptr, size_t size, size_t count);
	int64_t tell();
	int seek(int64_t new_offset, int origin);
	bool get_eof();
	uint32_t get_error();
	void clear_error();
	int32_t clear_cache();
	bool flush(/*bool mc*/);
	bool pre_close(sgx_key_128bit_t* key, bool import);
	static int32_t remove(const char* filename);