enclave_creator_sim.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. #include "enclave_creator_sim.h"
  32. #include "enclave_mngr.h"
  33. #include "se_detect.h"
  34. #include "driver_api.h"
  35. #include "enclave.h"
  36. #include "rts.h"
  37. #include "routine.h"
  38. #include "cpu_features.h"
  39. #include "se_error_internal.h"
  40. #include "util.h"
  41. #include "cpusvn_util.h"
  42. #include "rts_sim.h"
  43. #include <assert.h>
  44. #include <time.h>
  45. #include <openssl/evp.h>
  46. #include <openssl/err.h>
  47. __attribute__((constructor))
  48. static void init_openssl(void)
  49. {
  50. OpenSSL_add_all_algorithms();
  51. ERR_load_crypto_strings();
  52. }
  53. __attribute__((destructor))
  54. static void cleanup_openssl(void)
  55. {
  56. EVP_cleanup();
  57. CRYPTO_cleanup_all_ex_data();
  58. ERR_remove_thread_state(NULL);
  59. ERR_free_strings();
  60. }
  61. EnclaveCreator* g_enclave_creator = new EnclaveCreatorSim();
  62. int EnclaveCreatorSim::create_enclave(secs_t *secs, sgx_enclave_id_t *enclave_id, void **start_addr, bool ae)
  63. {
  64. UNUSED(ae);
  65. return ::create_enclave(secs, enclave_id, start_addr);
  66. }
  67. int EnclaveCreatorSim::add_enclave_page(sgx_enclave_id_t enclave_id, void *src, uint64_t offset, const sec_info_t &sinfo, uint32_t attr)
  68. {
  69. void* source = src;
  70. uint8_t color_page[SE_PAGE_SIZE];
  71. if(!source)
  72. {
  73. memset(color_page, 0, SE_PAGE_SIZE);
  74. source = reinterpret_cast<void*>(&color_page);
  75. }
  76. return ::add_enclave_page(enclave_id, source, (size_t)offset, sinfo, attr);
  77. }
  78. int EnclaveCreatorSim::init_enclave(sgx_enclave_id_t enclave_id, enclave_css_t *enclave_css, SGXLaunchToken *lc, le_prd_css_file_t *prd_css_file)
  79. {
  80. UNUSED(prd_css_file);
  81. sgx_launch_token_t token;
  82. memset(token, 0, sizeof(sgx_launch_token_t));
  83. int ret = lc->get_launch_token(&token);
  84. if(ret != SGX_SUCCESS)
  85. return ret;
  86. return ::init_enclave(enclave_id, enclave_css, reinterpret_cast<token_t *>(token));
  87. }
  88. int EnclaveCreatorSim::get_misc_attr(sgx_misc_attribute_t *sgx_misc_attr, metadata_t *metadata, SGXLaunchToken * const lc, uint32_t debug_flag)
  89. {
  90. sgx_attributes_t *required_attr;
  91. enclave_css_t *enclave_css;
  92. sgx_attributes_t *secs_attr;
  93. uint64_t xcr0 = 0;
  94. assert(sgx_misc_attr != NULL);
  95. assert(metadata != NULL);
  96. required_attr = &metadata->attributes;
  97. enclave_css = &metadata->enclave_css;
  98. secs_attr = &sgx_misc_attr->secs_attr;
  99. // Make sure that FP/SSE is set.
  100. if (SGX_XFRM_LEGACY != (required_attr->xfrm & SGX_XFRM_LEGACY))
  101. {
  102. SE_TRACE(SE_TRACE_WARNING, "FP/SSE are must-have attributes\n");
  103. return SGX_ERROR_INVALID_ATTRIBUTE;
  104. }
  105. if (debug_flag)
  106. {
  107. //If enclave is signed as product enclave, but is launched as debug enclave, we need report specific error code.
  108. if((enclave_css->body.attribute_mask.flags & SGX_FLAGS_DEBUG)
  109. && !(enclave_css->body.attributes.flags & SGX_FLAGS_DEBUG)
  110. )
  111. {
  112. return SGX_ERROR_NDEBUG_ENCLAVE;
  113. }
  114. required_attr->flags |= SGX_FLAGS_DEBUG;
  115. }
  116. else
  117. required_attr->flags &= (~SGX_FLAGS_DEBUG);
  118. secs_attr->flags = required_attr->flags;
  119. if (! try_read_xcr0(&xcr0))
  120. {
  121. // read_xcr0() failed
  122. secs_attr->xfrm = SGX_XFRM_LEGACY;
  123. }
  124. else
  125. {
  126. secs_attr->xfrm = xcr0 & required_attr->xfrm;
  127. }
  128. // Check the signature structure xfrm attribute restrictions.
  129. if((enclave_css->body.attribute_mask.xfrm & secs_attr->xfrm)
  130. != (enclave_css->body.attribute_mask.xfrm & enclave_css->body.attributes.xfrm))
  131. {
  132. SE_TRACE(SE_TRACE_WARNING, "secs attributes.xfrm does NOT match signature attributes.xfrm\n");
  133. return SGX_ERROR_INVALID_ATTRIBUTE;
  134. }
  135. // Check the signature structure flags attribute restrictions.
  136. if((enclave_css->body.attribute_mask.flags & secs_attr->flags)
  137. != (enclave_css->body.attribute_mask.flags & enclave_css->body.attributes.flags))
  138. {
  139. SE_TRACE(SE_TRACE_WARNING, "secs attributes.flag does NOT match signature attributes.flag\n");
  140. return SGX_ERROR_INVALID_ATTRIBUTE;
  141. }
  142. if(lc != NULL)
  143. {
  144. sgx_launch_token_t token;
  145. memset(&token, 0, sizeof(token));
  146. if(lc->get_launch_token(&token) != SGX_SUCCESS)
  147. return SGX_ERROR_UNEXPECTED;
  148. token_t *launch = (token_t *)token;
  149. if( 1 == launch->body.valid)
  150. {
  151. // Debug launch enclave cannot launch production enclave
  152. if( !(secs_attr->flags & SGX_FLAGS_DEBUG)
  153. && (launch->attributes_le.flags & SGX_FLAGS_DEBUG) )
  154. {
  155. SE_TRACE(SE_TRACE_WARNING, "secs attributes is non-debug, \n");
  156. return SE_ERROR_INVALID_LAUNCH_TOKEN;
  157. }
  158. // Verify attributes in lictoken are the same as the enclave
  159. if(memcmp(&launch->body.attributes, secs_attr, sizeof(sgx_attributes_t)))
  160. {
  161. SE_TRACE(SE_TRACE_WARNING, "secs attributes does NOT match launch token attributes\n");
  162. return SGX_ERROR_INVALID_ATTRIBUTE;
  163. }
  164. }
  165. }
  166. return SGX_SUCCESS;
  167. }
  168. int EnclaveCreatorSim::destroy_enclave(sgx_enclave_id_t enclave_id, uint64_t enclave_size)
  169. {
  170. UNUSED(enclave_size);
  171. CEnclave *enclave = CEnclavePool::instance()->get_enclave(enclave_id);
  172. if(enclave == NULL)
  173. return SGX_ERROR_INVALID_ENCLAVE_ID;
  174. return ::destroy_enclave(enclave_id);
  175. }
  176. int EnclaveCreatorSim::initialize(sgx_enclave_id_t enclave_id)
  177. {
  178. CEnclave *enclave = CEnclavePool::instance()->get_enclave(enclave_id);
  179. if(enclave == NULL)
  180. {
  181. SE_TRACE(SE_TRACE_WARNING, "enclave (id = %llu) not found.\n", enclave_id);
  182. return SGX_ERROR_INVALID_ENCLAVE_ID;
  183. }
  184. // Save the SECS address (EGETKEY/EREPORT needs to know SECS).
  185. CEnclaveMngr *mngr = CEnclaveMngr::get_instance();
  186. CEnclaveSim *ce = mngr->get_enclave(enclave_id);
  187. if (ce == NULL)
  188. {
  189. SE_TRACE(SE_TRACE_WARNING, "enclave (id = %llu) not found.\n", enclave_id);
  190. return SGX_ERROR_INVALID_ENCLAVE_ID;
  191. }
  192. global_data_sim_t *global_data_sim_ptr = (global_data_sim_t *)enclave->get_symbol_address("g_global_data_sim");
  193. //We have check the symbol of "g_global_data_sim" in urts_com.h::_create_enclave(), so here global_data_sim_ptr won't be NULL.
  194. assert(global_data_sim_ptr != NULL);
  195. // Initialize the `seed' to `g_global_data_sim'.
  196. global_data_sim_ptr->seed = (uint64_t)time(NULL);
  197. global_data_sim_ptr->secs_ptr = ce->get_secs();
  198. sgx_cpu_svn_t temp_cpusvn = {{0}};
  199. int status = get_cpusvn(&temp_cpusvn);
  200. assert(status == SGX_SUCCESS);
  201. memcpy_s(&(global_data_sim_ptr->cpusvn_sim),sizeof(global_data_sim_ptr->cpusvn_sim), &temp_cpusvn, sizeof(temp_cpusvn));
  202. //Since CPUID instruction is NOT supported within enclave, we emuerate the cpu features here and send to tRTS.
  203. system_features_t info;
  204. info.cpu_features = 0;
  205. get_cpu_features(&info.cpu_features, (unsigned int*)info.cpuinfo_table);
  206. info.version = SDK_VERSION_1_5;
  207. status = enclave->ecall(ECMD_INIT_ENCLAVE, NULL, reinterpret_cast<void *>(&info));
  208. //free the tcs used by initialization;
  209. enclave->get_thread_pool()->reset();
  210. if(SGX_SUCCESS == status)
  211. {
  212. return SGX_SUCCESS;
  213. }
  214. else
  215. {
  216. SE_TRACE(SE_TRACE_WARNING, "initialize enclave failed\n");
  217. return SGX_ERROR_UNEXPECTED;
  218. }
  219. }
  220. bool EnclaveCreatorSim::use_se_hw() const
  221. {
  222. return false;
  223. }
  224. bool EnclaveCreatorSim::is_EDMM_supported(sgx_enclave_id_t enclave_id)
  225. {
  226. UNUSED(enclave_id);
  227. return false;
  228. }
  229. bool EnclaveCreatorSim::is_driver_compatible()
  230. {
  231. return true;
  232. }
  233. bool EnclaveCreatorSim::is_in_kernel_driver()
  234. {
  235. return false;
  236. }
  237. bool EnclaveCreatorSim::get_plat_cap(sgx_misc_attribute_t *se_attr)
  238. {
  239. UNUSED(se_attr);
  240. return false;
  241. }
  242. int EnclaveCreatorSim::emodpr(uint64_t addr, uint64_t size, uint64_t flag)
  243. {
  244. UNUSED(addr);
  245. UNUSED(size);
  246. UNUSED(flag);
  247. return SGX_SUCCESS;
  248. }
  249. int EnclaveCreatorSim::mktcs(uint64_t tcs_addr)
  250. {
  251. UNUSED(tcs_addr);
  252. return SGX_SUCCESS;
  253. }
  254. int EnclaveCreatorSim::trim_range(uint64_t fromaddr, uint64_t toaddr)
  255. {
  256. UNUSED(fromaddr);
  257. UNUSED(toaddr);
  258. return SGX_SUCCESS;
  259. }
  260. int EnclaveCreatorSim::trim_accept(uint64_t addr)
  261. {
  262. UNUSED(addr);
  263. return SGX_SUCCESS;
  264. }
  265. int EnclaveCreatorSim::remove_range(uint64_t fromaddr, uint64_t numpages)
  266. {
  267. UNUSED(fromaddr);
  268. UNUSED(numpages);
  269. return SGX_SUCCESS;
  270. }