enclave_creator_sim.cpp 9.9 KB

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