protected_fs_file.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (C) 2011-2018 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. #define MAX_PAGES_IN_CACHE 48
  55. COMPILE_TIME_ASSERT(filename_length, FILENAME_MAX_LEN == FILENAME_MAX);
  56. typedef void FILE;
  57. typedef union
  58. {
  59. struct
  60. {
  61. uint8_t read :1;
  62. uint8_t write :1;
  63. uint8_t append :1;
  64. uint8_t binary: 1;
  65. uint8_t update: 1;
  66. };
  67. uint8_t raw;
  68. } open_mode_t;
  69. #define FILE_MHT_NODE_TYPE 1
  70. #define FILE_DATA_NODE_TYPE 2
  71. #define PATHNAME_MAX_LEN (512)
  72. #define FULLNAME_MAX_LEN (PATHNAME_MAX_LEN+FILENAME_MAX_LEN)
  73. #define RECOVERY_FILE_MAX_LEN (FULLNAME_MAX_LEN+10)
  74. #pragma pack(push, 1)
  75. /*
  76. the following 2 structures are almost identical, i do not merge them (union or c++ inheritance from parent class) for 2 reasons:
  77. 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
  78. 2. the code is more readable this way, it is clear when we deal with each type
  79. */
  80. typedef struct _file_mht_node
  81. {
  82. /* 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*) */
  83. uint8_t type;
  84. uint64_t mht_node_number;
  85. struct _file_mht_node* parent;
  86. bool need_writing;
  87. bool new_node;
  88. union {
  89. struct {
  90. uint64_t physical_node_number;
  91. encrypted_node_t encrypted; // the actual data from the disk
  92. };
  93. recovery_node_t recovery_node;
  94. };
  95. /* from here the structures are different */
  96. mht_node_t plain; // decrypted data
  97. } file_mht_node_t;
  98. typedef struct _file_data_node
  99. {
  100. /* 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*) */
  101. uint8_t type;
  102. uint64_t data_node_number;
  103. file_mht_node_t* parent;
  104. bool need_writing;
  105. bool new_node;
  106. union {
  107. struct {
  108. uint64_t physical_node_number;
  109. encrypted_node_t encrypted; // the actual data from the disk
  110. };
  111. recovery_node_t recovery_node;
  112. };
  113. /* from here the structures are different */
  114. data_node_t plain; // decrypted data
  115. } file_data_node_t;
  116. class protected_fs_file
  117. {
  118. private:
  119. union {
  120. struct {
  121. uint64_t meta_data_node_number; // for recovery purpose, so it is easy to write this node
  122. meta_data_node_t file_meta_data; // actual data from disk's meta data node
  123. };
  124. recovery_node_t meta_data_recovery_node;
  125. };
  126. meta_data_encrypted_t encrypted_part_plain; // encrypted part of meta data node, decrypted
  127. file_mht_node_t root_mht; // the root of the mht is always needed (for files bigger than 3KB)
  128. FILE* file; // OS's FILE pointer
  129. open_mode_t open_mode;
  130. uint8_t read_only;
  131. int64_t offset; // current file position (user's view)
  132. bool end_of_file; // flag
  133. int64_t real_file_size;
  134. bool need_writing; // flag
  135. uint32_t last_error; // last operation error
  136. protected_fs_status_e file_status;
  137. sgx_thread_mutex_t mutex;
  138. uint8_t use_user_kdk_key;
  139. sgx_aes_gcm_128bit_key_t user_kdk_key; // recieved from user, used instead of the seal key
  140. sgx_aes_gcm_128bit_key_t cur_key;
  141. sgx_aes_gcm_128bit_key_t session_master_key;
  142. uint32_t master_key_count;
  143. char recovery_filename[RECOVERY_FILE_MAX_LEN]; // might include full path to the file
  144. lru_cache cache;
  145. // these don't change after init...
  146. sgx_iv_t empty_iv;
  147. sgx_report_t report;
  148. void init_fields();
  149. bool cleanup_filename(const char* src, char* dest);
  150. bool parse_mode(const char* mode);
  151. bool file_recovery(const char* filename);
  152. bool init_existing_file(const char* filename, const char* clean_filename, const sgx_aes_gcm_128bit_key_t* import_key);
  153. bool init_new_file(const char* clean_filename);
  154. 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);
  155. bool generate_secure_blob_from_user_kdk(bool restore);
  156. bool init_session_master_key();
  157. bool derive_random_node_key(uint64_t physical_node_number);
  158. bool generate_random_meta_data_key();
  159. bool restore_current_meta_data_key(const sgx_aes_gcm_128bit_key_t* import_key);
  160. file_data_node_t* get_data_node();
  161. file_data_node_t* read_data_node();
  162. file_data_node_t* append_data_node();
  163. file_mht_node_t* get_mht_node();
  164. file_mht_node_t* read_mht_node(uint64_t mht_node_number);
  165. file_mht_node_t* append_mht_node(uint64_t mht_node_number);
  166. bool write_recovery_file();
  167. bool set_update_flag(bool flush_to_disk);
  168. void clear_update_flag();
  169. bool update_all_data_and_mht_nodes();
  170. bool update_meta_data_node();
  171. bool write_all_changes_to_disk(bool flush_to_disk);
  172. void erase_recovery_file();
  173. bool internal_flush(/*bool mc,*/ bool flush_to_disk);
  174. public:
  175. 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);
  176. ~protected_fs_file();
  177. size_t write(const void* ptr, size_t size, size_t count);
  178. size_t read(void* ptr, size_t size, size_t count);
  179. int64_t tell();
  180. int seek(int64_t new_offset, int origin);
  181. bool get_eof();
  182. uint32_t get_error();
  183. void clear_error();
  184. int32_t clear_cache();
  185. bool flush(/*bool mc*/);
  186. bool pre_close(sgx_key_128bit_t* key, bool import);
  187. static int32_t remove(const char* filename);
  188. };
  189. #pragma pack(pop)
  190. #endif // _PROTECTED_FS_H_