protected_fs_file.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (C) 2011-2017 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #pragma once
  32. #ifndef _PROTECTED_FS_H_
  33. #define _PROTECTED_FS_H_
  34. #include "protected_fs_nodes.h"
  35. #include "lru_cache.h"
  36. #include "sgx_error.h"
  37. #include "sgx_tcrypto.h"
  38. #include "errno.h"
  39. #include <sgx_thread.h>
  40. #include "sgx_tprotected_fs.h"
  41. typedef enum
  42. {
  43. SGX_FILE_STATUS_OK = 0,
  44. SGX_FILE_STATUS_NOT_INITIALIZED,
  45. SGX_FILE_STATUS_FLUSH_ERROR,
  46. SGX_FILE_STATUS_WRITE_TO_DISK_FAILED,
  47. SGX_FILE_STATUS_CRYPTO_ERROR,
  48. SGX_FILE_STATUS_CORRUPTED,
  49. SGX_FILE_STATUS_MEMORY_CORRUPTED,
  50. //SGX_FILE_STATUS_WRITE_TO_DISK_FAILED_NEED_MC,
  51. //SGX_FILE_STATUS_MC_NOT_INCREMENTED,
  52. SGX_FILE_STATUS_CLOSED,
  53. } protected_fs_status_e;
  54. /* copied from tseal_internal.h */
  55. /* set MISCMASK.exinfo_bit = 0 for data migration to the enclave
  56. built with the SDK that supports exinfo bit */
  57. #define SGX_MISCSEL_EXINFO 0x00000001 /* report #PF and #GP inside enclave */
  58. #define TSEAL_DEFAULT_MISCMASK (~SGX_MISCSEL_EXINFO)
  59. /* end of copied... */
  60. #define MAX_PAGES_IN_CACHE 48
  61. COMPILE_TIME_ASSERT(filename_length, FILENAME_MAX_LEN == FILENAME_MAX);
  62. typedef void FILE;
  63. typedef union
  64. {
  65. struct
  66. {
  67. uint8_t read :1;
  68. uint8_t write :1;
  69. uint8_t append :1;
  70. uint8_t binary: 1;
  71. uint8_t update: 1;
  72. };
  73. uint8_t raw;
  74. } open_mode_t;
  75. #define FILE_MHT_NODE_TYPE 1
  76. #define FILE_DATA_NODE_TYPE 2
  77. #define PATHNAME_MAX_LEN (512)
  78. #define FULLNAME_MAX_LEN (PATHNAME_MAX_LEN+FILENAME_MAX_LEN)
  79. #define RECOVERY_FILE_MAX_LEN (FULLNAME_MAX_LEN+10)
  80. #pragma pack(push, 1)
  81. /*
  82. the following 2 structures are almost identical, i do not merge them (union or c++ inheritance from parent class) for 2 reasons:
  83. 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
  84. 2. the code is more readable this way, it is clear when we deal with each type
  85. */
  86. typedef struct _file_mht_node
  87. {
  88. /* 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*) */
  89. uint8_t type;
  90. uint64_t mht_node_number;
  91. struct _file_mht_node* parent;
  92. bool need_writing;
  93. bool new_node;
  94. union {
  95. struct {
  96. uint64_t physical_node_number;
  97. encrypted_node_t encrypted; // the actual data from the disk
  98. };
  99. recovery_node_t recovery_node;
  100. };
  101. /* from here the structures are different */
  102. mht_node_t plain; // decrypted data
  103. } file_mht_node_t;
  104. typedef struct _file_data_node
  105. {
  106. /* 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*) */
  107. uint8_t type;
  108. uint64_t data_node_number;
  109. file_mht_node_t* parent;
  110. bool need_writing;
  111. bool new_node;
  112. union {
  113. struct {
  114. uint64_t physical_node_number;
  115. encrypted_node_t encrypted; // the actual data from the disk
  116. };
  117. recovery_node_t recovery_node;
  118. };
  119. /* from here the structures are different */
  120. data_node_t plain; // decrypted data
  121. } file_data_node_t;
  122. class protected_fs_file
  123. {
  124. private:
  125. union {
  126. struct {
  127. uint64_t meta_data_node_number; // for recovery purpose, so it is easy to write this node
  128. meta_data_node_t file_meta_data; // actual data from disk's meta data node
  129. };
  130. recovery_node_t meta_data_recovery_node;
  131. };
  132. meta_data_encrypted_t encrypted_part_plain; // encrypted part of meta data node, decrypted
  133. file_mht_node_t root_mht; // the root of the mht is always needed (for files bigger than 3KB)
  134. FILE* file; // OS's FILE pointer
  135. open_mode_t open_mode;
  136. uint8_t read_only;
  137. int64_t offset; // current file position (user's view)
  138. bool end_of_file; // flag
  139. int64_t real_file_size;
  140. bool need_writing; // flag
  141. uint32_t last_error; // last operation error
  142. protected_fs_status_e file_status;
  143. sgx_thread_mutex_t mutex;
  144. uint8_t use_user_kdk_key;
  145. sgx_aes_gcm_128bit_key_t user_kdk_key; // recieved from user, used instead of the seal key
  146. sgx_aes_gcm_128bit_key_t cur_key;
  147. sgx_aes_gcm_128bit_key_t session_master_key;
  148. uint32_t master_key_count;
  149. char recovery_filename[RECOVERY_FILE_MAX_LEN]; // might include full path to the file
  150. lru_cache cache;
  151. // these don't change after init...
  152. sgx_iv_t empty_iv;
  153. sgx_report_t report;
  154. void init_fields();
  155. bool cleanup_filename(const char* src, char* dest);
  156. bool parse_mode(const char* mode);
  157. bool file_recovery(const char* filename);
  158. bool init_existing_file(const char* filename, const char* clean_filename, const sgx_aes_gcm_128bit_key_t* import_key);
  159. bool init_new_file(const char* clean_filename);
  160. 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);
  161. bool generate_secure_blob_from_user_kdk(bool restore);
  162. bool init_session_master_key();
  163. bool derive_random_node_key(uint64_t physical_node_number);
  164. bool generate_random_meta_data_key();
  165. bool restore_current_meta_data_key(const sgx_aes_gcm_128bit_key_t* import_key);
  166. file_data_node_t* get_data_node();
  167. file_data_node_t* read_data_node();
  168. file_data_node_t* append_data_node();
  169. file_mht_node_t* get_mht_node();
  170. file_mht_node_t* read_mht_node(uint64_t mht_node_number);
  171. file_mht_node_t* append_mht_node(uint64_t mht_node_number);
  172. bool write_recovery_file();
  173. bool set_update_flag(bool flush_to_disk);
  174. void clear_update_flag();
  175. bool update_all_data_and_mht_nodes();
  176. bool update_meta_data_node();
  177. bool write_all_changes_to_disk(bool flush_to_disk);
  178. void erase_recovery_file();
  179. bool internal_flush(/*bool mc,*/ bool flush_to_disk);
  180. public:
  181. 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);
  182. ~protected_fs_file();
  183. size_t write(const void* ptr, size_t size, size_t count);
  184. size_t read(void* ptr, size_t size, size_t count);
  185. int64_t tell();
  186. int seek(int64_t new_offset, int origin);
  187. bool get_eof();
  188. uint32_t get_error();
  189. void clear_error();
  190. int32_t clear_cache();
  191. bool flush(/*bool mc*/);
  192. bool pre_close(sgx_key_128bit_t* key, bool import);
  193. static int32_t remove(const char* filename);
  194. };
  195. #pragma pack(pop)
  196. #endif // _PROTECTED_FS_H_