Intel Protected FS
Intel protected fs
Overall Description
The Intel Protected FS are implemented as a combination of a untrusted component and a trusted component. Informally, the untrusted component calls the OS API to persist and retrieve data (in ciphertext) to/from the OS file system, the trusted component takes charge of encryption, decryption, integrity protection and caching. The trusted component exposes the similar file operation API to the applications.
Internally, a file is represented as a tree of nodes. The leaves nodes are data nodes and the non-leaf nodes are MHT nodes. Currently, one node hold can 4KB data. One one-leaf node has 96 children.
##Calling graph of write
protected_fs_file::write()
|
--> get_data_node()
|
--> internal_flush()
|
--> update_all_data_and_mht_nodes() --> sgx_rijndael128GCM_encrypt()
+ |
update_meta_data() ---------------
+
set_update_flag() ------------> u_sgxprotectedfs_fwrite_node()
+ |
clear_update_flag() ----------|
+ |
write_all_changes_to_disk() --|
##Overall Description
EDL definition (common/inc/sgx_tprotected_fs.edl
)
36 untrusted {
37 void* u_sgxprotectedfs_exclusive_file_open([in, string] const char* filename, uint8_t read_only, [out] int64_t* file_size, [out] int32_t* error_code);
38 uint8_t u_sgxprotectedfs_check_if_file_exists([in, string] const char* filename);
39 int32_t u_sgxprotectedfs_fread_node([user_check] void* f, uint64_t node_number, [out, size=node_size] uint8_t* buffer, uint32_t node_size);
40 int32_t u_sgxprotectedfs_fwrite_node([user_check] void* f, uint64_t node_number, [in, size=node_size] uint8_t* buffer, uint32_t node_size);
41 int32_t u_sgxprotectedfs_fclose([user_check] void* f);
42 uint8_t u_sgxprotectedfs_fflush([user_check] void* f);
43 int32_t u_sgxprotectedfs_remove([in, string] const char* filename);
44
45 void* u_sgxprotectedfs_recovery_file_open([in, string] const char* filename);
46 uint8_t u_sgxprotectedfs_fwrite_recovery_node([user_check] void* f, [in, count=data_length] uint8_t* data, uint32_t data_length);
47 int32_t u_sgxprotectedfs_do_file_recovery([in, string] const char* filename, [in, string] const char* recovery_filename, uint32_t node_size);
48 };
file_mht_node
94 typedef struct _file_mht_node
95 {
96 /* 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*) */
97 uint8_t type;
98 uint64_t mht_node_number;
99 struct _file_mht_node* parent;
100 bool need_writing;
101 bool new_node;
102 union {
103 struct {
104 uint64_t physical_node_number;
105 encrypted_node_t encrypted; // the actual data from the disk
106 };
107 recovery_node_t recovery_node;
108 };
109 /* from here the structures are different */
110 mht_node_t plain; // decrypted data
111 } file_mht_node_t;
112
file_data_node
114 typedef struct _file_data_node
115 {
116 /* 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*) */
117 uint8_t type;
118 uint64_t data_node_number;
119 file_mht_node_t* parent;
120 bool need_writing;
121 bool new_node;
122 union {
123 struct {
124 uint64_t physical_node_number;
125 encrypted_node_t encrypted; // the actual data from the disk
126 };
127 recovery_node_t recovery_node;
128 };
129 /* from here the structures are different */
130 data_node_t plain; // decrypted data
131 } file_data_node_t;
meta_data_plain
58 typedef struct _meta_data_plain
59 {
60 uint64_t file_id;
61 uint8_t major_version;
62 uint8_t minor_version;
63
64 sgx_key_id_t meta_data_key_id;
65 sgx_cpu_svn_t cpu_svn;
66 sgx_isv_svn_t isv_svn;
67 uint8_t use_user_kdk_key;
68 sgx_attributes_t attribute_mask;
69
70 sgx_aes_gcm_128bit_tag_t meta_data_gmac;
71
72 uint8_t update_flag;
73 } meta_data_plain_t;
74
75 // these are all defined as relative to node size, so we can decrease node size in tests and have deeper tree
76 #define FILENAME_MAX_LEN 260
77 #define MD_USER_DATA_SIZE (NODE_SIZE*3/4) // 3072
78 COMPILE_TIME_ASSERT(md_user_data_size, MD_USER_DATA_SIZE == 3072);
meta_data_encrypted
80 typedef struct _meta_data_encrypted
81 {
82 char clean_filename[FILENAME_MAX_LEN];
83 int64_t size;
84
85 sgx_mc_uuid_t mc_uuid; // not used
86 uint32_t mc_value; // not used
87
88 sgx_aes_gcm_128bit_key_t mht_key;
89 sgx_aes_gcm_128bit_tag_t mht_gmac;
90
91 uint8_t data[MD_USER_DATA_SIZE];
92 } meta_data_encrypted_t;
93
94 typedef uint8_t meta_data_encrypted_blob_t[sizeof(meta_data_encrypted_t)];