123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #pragma once
- #ifndef _PROTECTED_FS_H_
- #define _PROTECTED_FS_H_
- #include "protected_fs_nodes.h"
- #include "lru_cache.h"
- #include "sgx_error.h"
- #include "sgx_tcrypto.h"
- #include "errno.h"
- #include <sgx_thread.h>
- #include "sgx_tprotected_fs.h"
- typedef enum
- {
- SGX_FILE_STATUS_OK = 0,
- SGX_FILE_STATUS_NOT_INITIALIZED,
- SGX_FILE_STATUS_FLUSH_ERROR,
- SGX_FILE_STATUS_WRITE_TO_DISK_FAILED,
- SGX_FILE_STATUS_CRYPTO_ERROR,
- SGX_FILE_STATUS_CORRUPTED,
- SGX_FILE_STATUS_MEMORY_CORRUPTED,
- //SGX_FILE_STATUS_WRITE_TO_DISK_FAILED_NEED_MC,
- //SGX_FILE_STATUS_MC_NOT_INCREMENTED,
- SGX_FILE_STATUS_CLOSED,
- } protected_fs_status_e;
- #define MAX_PAGES_IN_CACHE 48
- COMPILE_TIME_ASSERT(filename_length, FILENAME_MAX_LEN == FILENAME_MAX);
- typedef void FILE;
- typedef union
- {
- struct
- {
- uint8_t read :1;
- uint8_t write :1;
- uint8_t append :1;
- uint8_t binary: 1;
- uint8_t update: 1;
- };
- uint8_t raw;
- } open_mode_t;
- #define FILE_MHT_NODE_TYPE 1
- #define FILE_DATA_NODE_TYPE 2
- #define PATHNAME_MAX_LEN (512)
- #define FULLNAME_MAX_LEN (PATHNAME_MAX_LEN+FILENAME_MAX_LEN)
- #define RECOVERY_FILE_MAX_LEN (FULLNAME_MAX_LEN+10)
- #pragma pack(push, 1)
- /*
- the following 2 structures are almost identical, i do not merge them (union or c++ inheritance from parent class) for 2 reasons:
- 1. when the code was written, they were much more different, during time the differences were almost gone, but "if it's working don't fix it", so i leave it this way
- 2. the code is more readable this way, it is clear when we deal with each type
- */
- typedef struct _file_mht_node
- {
- /* these are exactly the same as file_data_node_t below, any change should apply to both (both are saved in the cache as void*) */
- uint8_t type;
- uint64_t mht_node_number;
- struct _file_mht_node* parent;
- bool need_writing;
- bool new_node;
- union {
- struct {
- uint64_t physical_node_number;
- encrypted_node_t encrypted; // the actual data from the disk
- };
- recovery_node_t recovery_node;
- };
- /* from here the structures are different */
- mht_node_t plain; // decrypted data
- } file_mht_node_t;
- typedef struct _file_data_node
- {
- /* these are exactly the same as file_mht_node_t above, any change should apply to both (both are saved in the cache as void*) */
- uint8_t type;
- uint64_t data_node_number;
- file_mht_node_t* parent;
- bool need_writing;
- bool new_node;
- union {
- struct {
- uint64_t physical_node_number;
- encrypted_node_t encrypted; // the actual data from the disk
- };
- recovery_node_t recovery_node;
- };
- /* from here the structures are different */
- data_node_t plain; // decrypted data
- } file_data_node_t;
- class protected_fs_file
- {
- private:
- 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);
- public:
- 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);
- ~protected_fs_file();
- 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);
- };
- #pragma pack(pop)
- #endif // _PROTECTED_FS_H_
|