manage_metadata.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. /*
  2. * Copyright (C) 2011-2016 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. /**
  32. * File:
  33. * manage_metadata.cpp
  34. * Description:
  35. * Parse the xml file to get the metadata and generate the output DLL
  36. * with metadata.
  37. */
  38. #include "metadata.h"
  39. #include "tinyxml.h"
  40. #include "manage_metadata.h"
  41. #include "se_trace.h"
  42. #include "util_st.h"
  43. #include "section.h"
  44. #include "se_page_attr.h"
  45. #include "elf_util.h"
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <errno.h>
  49. #include <assert.h>
  50. #include <iostream>
  51. #define ALIGN_SIZE 0x1000
  52. static bool traverser_parameter(const char *temp_name, const char *temp_text, xml_parameter_t *parameter, int parameter_count)
  53. {
  54. assert(temp_name != NULL && parameter != NULL);
  55. uint32_t temp_value=0;
  56. if(temp_text == NULL)
  57. {
  58. se_trace(SE_TRACE_ERROR, LACK_VALUE_FOR_ELEMENT_ERROR, temp_name);
  59. return false;
  60. }
  61. else
  62. {
  63. if(strchr(temp_text, '-'))
  64. {
  65. se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name);
  66. return false;
  67. }
  68. errno = 0;
  69. char* endptr = NULL;
  70. temp_value = (uint32_t)strtoul(temp_text, &endptr, 0);
  71. if(*endptr!='\0'||errno!=0) //Invalid value or valid value but out of the representable range
  72. {
  73. se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name);
  74. return false;
  75. }
  76. }
  77. //Look for the matched one
  78. int i=0;
  79. for(;i<parameter_count&&STRCMP(temp_name,parameter[i].name);i++);
  80. if(i>=parameter_count) //no matched, return false
  81. {
  82. se_trace(SE_TRACE_ERROR, UNREC_ELEMENT_ERROR, temp_name);
  83. return false;
  84. }
  85. //found one matched
  86. if(parameter[i].flag==1) //repeated definition of XML element, return false
  87. {
  88. se_trace(SE_TRACE_ERROR, REPEATED_DEFINE_ERROR, temp_name);
  89. return false;
  90. }
  91. parameter[i].flag = 1;
  92. if((temp_value<parameter[i].min_value)||
  93. (temp_value>parameter[i].max_value)) // the value is invalid, return false
  94. {
  95. se_trace(SE_TRACE_ERROR, VALUE_OUT_OF_RANGE_ERROR, temp_name);
  96. return false;
  97. }
  98. parameter[i].value = temp_value;
  99. return true;
  100. }
  101. bool parse_metadata_file(const char *xmlpath, xml_parameter_t *parameter, int parameter_count)
  102. {
  103. const char* temp_name=NULL;
  104. assert(parameter != NULL);
  105. if(xmlpath == NULL) // user didn't define the metadata xml file.
  106. {
  107. se_trace(SE_TRACE_NOTICE, "Use default metadata...\n");
  108. return true;
  109. }
  110. //use the metadata file that user gives us. parse xml file
  111. TiXmlDocument doc(xmlpath);
  112. bool loadOkay = doc.LoadFile();
  113. if(!loadOkay)
  114. {
  115. if(doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE)
  116. {
  117. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, xmlpath);
  118. }
  119. else
  120. {
  121. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  122. }
  123. return false;
  124. }
  125. doc.Print();//Write the document to standard out using formatted printing ("pretty print").
  126. TiXmlNode *pmetadata_node = doc.FirstChild("EnclaveConfiguration");
  127. if(!pmetadata_node)
  128. {
  129. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  130. return false;
  131. }
  132. TiXmlNode *sub_node = NULL;
  133. sub_node = pmetadata_node->FirstChild();
  134. const char *temp_text = NULL;
  135. while(sub_node)//parse xml node
  136. {
  137. switch(sub_node->Type())
  138. {
  139. case TiXmlNode::TINYXML_ELEMENT:
  140. if(sub_node->ToElement()->FirstAttribute() != NULL)
  141. {
  142. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  143. return false;
  144. }
  145. temp_name = sub_node->ToElement()->Value();
  146. temp_text = sub_node->ToElement()->GetText();
  147. //traverse every node. Compare with the default value.
  148. if(traverser_parameter(temp_name, temp_text, parameter, parameter_count) == false)
  149. {
  150. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  151. return false;
  152. }
  153. break;
  154. case TiXmlNode::TINYXML_DECLARATION:
  155. case TiXmlNode::TINYXML_COMMENT:
  156. break;
  157. default:
  158. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  159. return false;
  160. }
  161. sub_node=pmetadata_node->IterateChildren(sub_node);
  162. }
  163. return true;
  164. }
  165. CMetadata::CMetadata(metadata_t *metadata, BinParser *parser)
  166. : m_metadata(metadata)
  167. , m_parser(parser)
  168. {
  169. memset(m_metadata, 0, sizeof(metadata_t));
  170. memset(&m_create_param, 0, sizeof(m_create_param));
  171. }
  172. CMetadata::~CMetadata()
  173. {
  174. }
  175. bool CMetadata::build_metadata(const xml_parameter_t *parameter)
  176. {
  177. if(!modify_metadata(parameter))
  178. {
  179. return false;
  180. }
  181. // layout table
  182. if(!build_layout_table())
  183. {
  184. return false;
  185. }
  186. // patch table
  187. if(!build_patch_table())
  188. {
  189. return false;
  190. }
  191. return true;
  192. }
  193. bool CMetadata::modify_metadata(const xml_parameter_t *parameter)
  194. {
  195. assert(parameter != NULL);
  196. m_metadata->version = META_DATA_MAKE_VERSION(MAJOR_VERSION,MINOR_VERSION );
  197. m_metadata->size = offsetof(metadata_t, data);
  198. m_metadata->tcs_policy = parameter[TCSPOLICY].value;
  199. m_metadata->ssa_frame_size = SSA_FRAME_SIZE;
  200. //stack/heap must be page-align
  201. if(parameter[STACKMAXSIZE].value % ALIGN_SIZE)
  202. {
  203. se_trace(SE_TRACE_ERROR, SET_STACK_SIZE_ERROR);
  204. return false;
  205. }
  206. if(parameter[HEAPMAXSIZE].value % ALIGN_SIZE)
  207. {
  208. se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_ERROR);
  209. return false;
  210. }
  211. // LE setting: HW != 0, Licensekey = 1
  212. // Other enclave setting: HW = 0, Licensekey = 0
  213. if((parameter[HW].value == 0 && parameter[LAUNCHKEY].value != 0) ||
  214. (parameter[HW].value != 0 && parameter[LAUNCHKEY].value == 0))
  215. {
  216. se_trace(SE_TRACE_ERROR, SET_HW_LE_ERROR);
  217. return false;
  218. }
  219. m_metadata->max_save_buffer_size = MAX_SAVE_BUF_SIZE;
  220. m_metadata->magic_num = METADATA_MAGIC;
  221. m_metadata->desired_misc_select = 0;
  222. m_metadata->enclave_css.body.misc_select = parameter[MISCSELECT].value;
  223. m_metadata->enclave_css.body.misc_mask = parameter[MISCMASK].value;
  224. m_create_param.heap_max_size = parameter[HEAPMAXSIZE].value;
  225. m_create_param.ssa_frame_size = SSA_FRAME_SIZE;
  226. m_create_param.stack_max_size = parameter[STACKMAXSIZE].value;
  227. m_create_param.tcs_max_num = parameter[TCSNUM].value;
  228. m_create_param.tcs_policy = m_metadata->tcs_policy;
  229. return true;
  230. }
  231. void *CMetadata::alloc_buffer_from_metadata(uint32_t size)
  232. {
  233. void *addr = GET_PTR(void, m_metadata, m_metadata->size);
  234. m_metadata->size += size;
  235. if((m_metadata->size < size) || (m_metadata->size > METADATA_SIZE))
  236. {
  237. return NULL;
  238. }
  239. return addr;
  240. }
  241. bool CMetadata::build_layout_entries(vector<layout_t> &layouts)
  242. {
  243. uint32_t size = (uint32_t)(layouts.size() * sizeof(layout_t));
  244. layout_t *layout_table = (layout_t *) alloc_buffer_from_metadata(size);
  245. if(layout_table == NULL)
  246. {
  247. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  248. return false;
  249. }
  250. m_metadata->dirs[DIR_LAYOUT].offset = (uint32_t)PTR_DIFF(layout_table, m_metadata);
  251. m_metadata->dirs[DIR_LAYOUT].size = size;
  252. uint64_t rva = calculate_sections_size();
  253. for(uint32_t i = 0; i < layouts.size(); i++)
  254. {
  255. memcpy_s(layout_table, sizeof(layout_t), &layouts[i], sizeof(layout_t));
  256. if(!IS_GROUP_ID(layouts[i].entry.id))
  257. {
  258. layout_table->entry.rva = rva;
  259. rva += (uint64_t)layouts[i].entry.page_count << SE_PAGE_SHIFT;
  260. }
  261. else
  262. {
  263. for (uint32_t j = 0; j < layouts[i].group.entry_count; j++)
  264. {
  265. layout_table->group.load_step += (uint64_t)layouts[i-j-1].entry.page_count << SE_PAGE_SHIFT;
  266. }
  267. rva += layouts[i].group.load_times * layout_table->group.load_step;
  268. }
  269. layout_table++;
  270. }
  271. // enclave virtual size
  272. m_metadata->enclave_size = calculate_enclave_size(rva);
  273. if(m_metadata->enclave_size == (uint64_t)-1)
  274. {
  275. se_trace(SE_TRACE_ERROR, OUT_OF_EPC_ERROR);
  276. return false;
  277. }
  278. // the last guard page entry to round the enclave size to power of 2
  279. if(m_metadata->enclave_size - rva > 0)
  280. {
  281. layout_table = (layout_t *)alloc_buffer_from_metadata(sizeof(layout_t));
  282. if(layout_table == NULL)
  283. {
  284. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  285. return false;
  286. }
  287. layout_table->entry.id = LAYOUT_ID_GUARD;
  288. layout_table->entry.rva = rva;
  289. layout_table->entry.page_count = (uint32_t)((m_metadata->enclave_size - rva) >> SE_PAGE_SHIFT);
  290. m_metadata->dirs[DIR_LAYOUT].size += (uint32_t)sizeof(layout_t);
  291. }
  292. return true;
  293. }
  294. bool CMetadata::build_layout_table()
  295. {
  296. vector <layout_t> layouts;
  297. layout_t layout;
  298. memset(&layout, 0, sizeof(layout));
  299. layout_t guard_page;
  300. memset(&guard_page, 0, sizeof(guard_page));
  301. guard_page.entry.id = LAYOUT_ID_GUARD;
  302. guard_page.entry.page_count = SE_GUARD_PAGE_SIZE >> SE_PAGE_SHIFT;
  303. // heap
  304. layout.entry.id = LAYOUT_ID_HEAP;
  305. layout.entry.page_count = (uint32_t)(m_create_param.heap_max_size >> SE_PAGE_SHIFT);
  306. layout.entry.attributes = ADD_PAGE_ONLY;
  307. layout.entry.si_flags = SI_FLAGS_RW;
  308. layouts.push_back(layout);
  309. // thread context memory layout
  310. // guard page | stack | TCS | SSA | guard page | TLS
  311. // guard page
  312. layouts.push_back(guard_page);
  313. // stack
  314. layout.entry.id = LAYOUT_ID_STACK;
  315. layout.entry.page_count = (uint32_t)(m_create_param.stack_max_size >> SE_PAGE_SHIFT);
  316. layout.entry.attributes = ADD_EXTEND_PAGE;
  317. layout.entry.si_flags = SI_FLAGS_RW;
  318. layout.entry.content_size = 0xCCCCCCCC;
  319. layouts.push_back(layout);
  320. // guard page
  321. layouts.push_back(guard_page);
  322. // tcs
  323. layout.entry.id = LAYOUT_ID_TCS;
  324. layout.entry.page_count = TCS_SIZE >> SE_PAGE_SHIFT;
  325. layout.entry.attributes = ADD_EXTEND_PAGE;
  326. layout.entry.si_flags = SI_FLAGS_TCS;
  327. tcs_t *tcs_template = (tcs_t *) alloc_buffer_from_metadata(TCS_TEMPLATE_SIZE);
  328. if(tcs_template == NULL)
  329. {
  330. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  331. return false;
  332. }
  333. layout.entry.content_offset = (uint32_t)PTR_DIFF(tcs_template, m_metadata),
  334. layout.entry.content_size = TCS_TEMPLATE_SIZE;
  335. layouts.push_back(layout);
  336. memset(&layout, 0, sizeof(layout));
  337. // ssa
  338. layout.entry.id = LAYOUT_ID_SSA;
  339. layout.entry.page_count = SSA_FRAME_SIZE * SSA_NUM;
  340. layout.entry.attributes = ADD_EXTEND_PAGE;
  341. layout.entry.si_flags = SI_FLAGS_RW;
  342. layouts.push_back(layout);
  343. // guard page
  344. layouts.push_back(guard_page);
  345. // td
  346. layout.entry.id = LAYOUT_ID_TD;
  347. layout.entry.page_count = 1;
  348. const Section *section = m_parser->get_tls_section();
  349. if(section)
  350. {
  351. layout.entry.page_count += (uint32_t)(ROUND_TO_PAGE(section->virtual_size()) >> SE_PAGE_SHIFT);
  352. }
  353. layout.entry.attributes = ADD_EXTEND_PAGE;
  354. layout.entry.si_flags = SI_FLAGS_RW;
  355. layouts.push_back(layout);
  356. // group for thread context
  357. if (m_create_param.tcs_max_num > 1)
  358. {
  359. memset(&layout, 0, sizeof(layout));
  360. layout.group.id = LAYOUT_ID_THREAD_GROUP;
  361. layout.group.entry_count = (uint16_t) (layouts.size() - 1);
  362. layout.group.load_times = m_create_param.tcs_max_num-1;
  363. layouts.push_back(layout);
  364. }
  365. // build layout table
  366. if(false == build_layout_entries(layouts))
  367. {
  368. return false;
  369. }
  370. // tcs template
  371. if(false == build_tcs_template(tcs_template))
  372. {
  373. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  374. return false;
  375. }
  376. return true;
  377. }
  378. bool CMetadata::build_patch_entries(vector<patch_entry_t> &patches)
  379. {
  380. uint32_t size = (uint32_t)(patches.size() * sizeof(patch_entry_t));
  381. patch_entry_t *patch_table = (patch_entry_t *) alloc_buffer_from_metadata(size);
  382. if(patch_table == NULL)
  383. {
  384. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  385. return false;
  386. }
  387. m_metadata->dirs[DIR_PATCH].offset = (uint32_t)PTR_DIFF(patch_table, m_metadata);
  388. m_metadata->dirs[DIR_PATCH].size = size;
  389. for(uint32_t i = 0; i < patches.size(); i++)
  390. {
  391. memcpy_s(patch_table, sizeof(patch_entry_t), &patches[i], sizeof(patch_entry_t));
  392. patch_table++;
  393. }
  394. return true;
  395. }
  396. bool CMetadata::build_patch_table()
  397. {
  398. const uint8_t *base_addr = (const uint8_t *)m_parser->get_start_addr();
  399. vector<patch_entry_t> patches;
  400. patch_entry_t patch;
  401. memset(&patch, 0, sizeof(patch));
  402. // td template
  403. uint8_t buf[200];
  404. uint32_t size = 200;
  405. memset(buf, 0, size);
  406. if(false == build_gd_template(buf, &size))
  407. {
  408. return false;
  409. }
  410. uint8_t *gd_template = (uint8_t *)alloc_buffer_from_metadata(size);
  411. if(gd_template == NULL)
  412. {
  413. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  414. return false;
  415. }
  416. memcpy_s(gd_template, size, buf, size);
  417. uint64_t rva = m_parser->get_symbol_rva("g_global_data");
  418. if(0 == rva)
  419. {
  420. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  421. return false;
  422. }
  423. patch.dst = (uint64_t)PTR_DIFF(get_rawdata_by_rva(rva), base_addr);
  424. patch.src = (uint32_t)PTR_DIFF(gd_template, m_metadata);
  425. patch.size = size;
  426. patches.push_back(patch);
  427. // patch the image header
  428. uint64_t *zero = (uint64_t *)alloc_buffer_from_metadata(sizeof(*zero));
  429. if(zero == NULL)
  430. {
  431. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  432. return false;
  433. }
  434. *zero = 0;
  435. bin_fmt_t bf = m_parser->get_bin_format();
  436. if(bf == BF_ELF32)
  437. {
  438. Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)base_addr;
  439. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shnum, base_addr);
  440. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  441. patch.size = (uint32_t)sizeof(elf_hdr->e_shnum);
  442. patches.push_back(patch);
  443. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr);
  444. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  445. patch.size = (uint32_t)sizeof(elf_hdr->e_shoff);
  446. patches.push_back(patch);
  447. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr);
  448. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  449. patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx);
  450. patches.push_back(patch);
  451. // Modify GNU_RELRO info to eliminate the impact of enclave measurement.
  452. Elf32_Phdr *prg_hdr = GET_PTR(Elf32_Phdr, base_addr, elf_hdr->e_phoff);
  453. for (unsigned idx = 0; idx < elf_hdr->e_phnum; ++idx, ++prg_hdr)
  454. {
  455. if(prg_hdr->p_type == PT_GNU_RELRO)
  456. {
  457. patch.dst = (uint64_t)PTR_DIFF(prg_hdr, base_addr);
  458. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  459. patch.size = (uint32_t)sizeof(Elf32_Phdr);
  460. patches.push_back(patch);
  461. break;
  462. }
  463. }
  464. }
  465. else if(bf == BF_ELF64)
  466. {
  467. Elf64_Ehdr *elf_hdr = (Elf64_Ehdr *)base_addr;
  468. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shnum, base_addr);
  469. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  470. patch.size = (uint32_t)sizeof(elf_hdr->e_shnum);
  471. patches.push_back(patch);
  472. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr);
  473. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  474. patch.size = (uint32_t)sizeof(elf_hdr->e_shoff);
  475. patches.push_back(patch);
  476. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr);
  477. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  478. patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx);
  479. patches.push_back(patch);
  480. }
  481. if(false == build_patch_entries(patches))
  482. {
  483. return false;
  484. }
  485. return true;
  486. }
  487. layout_entry_t *CMetadata::get_entry_by_id(uint16_t id)
  488. {
  489. layout_entry_t *layout_start = GET_PTR(layout_entry_t, m_metadata, m_metadata->dirs[DIR_LAYOUT].offset);
  490. layout_entry_t *layout_end = GET_PTR(layout_entry_t, m_metadata, m_metadata->dirs[DIR_LAYOUT].offset + m_metadata->dirs[DIR_LAYOUT].size);
  491. for (layout_entry_t *layout = layout_start; layout < layout_end; layout++)
  492. {
  493. if(layout->id == id)
  494. return layout;
  495. }
  496. assert(false);
  497. return NULL;
  498. }
  499. bool CMetadata::build_gd_template(uint8_t *data, uint32_t *data_size)
  500. {
  501. m_create_param.stack_limit_addr = get_entry_by_id(LAYOUT_ID_STACK)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva;
  502. m_create_param.stack_base_addr = ((uint64_t)get_entry_by_id(LAYOUT_ID_STACK)->page_count << SE_PAGE_SHIFT) + m_create_param.stack_limit_addr;
  503. m_create_param.first_ssa_gpr = get_entry_by_id(LAYOUT_ID_SSA)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva
  504. + SSA_FRAME_SIZE * SE_PAGE_SIZE - (uint64_t)sizeof(ssa_gpr_t);
  505. m_create_param.enclave_size = m_metadata->enclave_size;
  506. m_create_param.heap_offset = get_entry_by_id(LAYOUT_ID_HEAP)->rva;
  507. uint64_t tmp_tls_addr = get_entry_by_id(LAYOUT_ID_TD)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva;
  508. m_create_param.td_addr = tmp_tls_addr + (((uint64_t)get_entry_by_id(LAYOUT_ID_TD)->page_count - 1) << SE_PAGE_SHIFT);
  509. const Section *section = m_parser->get_tls_section();
  510. if(section)
  511. {
  512. /* adjust the tls_addr to be the pointer to the actual TLS data area */
  513. m_create_param.tls_addr = m_create_param.td_addr - section->virtual_size();
  514. assert(TRIM_TO_PAGE(m_create_param.tls_addr) == tmp_tls_addr);
  515. }
  516. else
  517. m_create_param.tls_addr = tmp_tls_addr;
  518. if(false == m_parser->update_global_data(&m_create_param, data, data_size))
  519. {
  520. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR); // metadata structure doesnot have enough memory for global_data template
  521. return false;
  522. }
  523. return true;
  524. }
  525. bool CMetadata::build_tcs_template(tcs_t *tcs)
  526. {
  527. tcs->oentry = m_parser->get_symbol_rva("enclave_entry");
  528. if(tcs->oentry == 0)
  529. {
  530. return false;
  531. }
  532. tcs->nssa = SSA_NUM;
  533. tcs->cssa = 0;
  534. tcs->ossa = get_entry_by_id(LAYOUT_ID_SSA)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva;
  535. //fs/gs pointer at TLS/TD
  536. tcs->ofs_base = tcs->ogs_base = get_entry_by_id(LAYOUT_ID_TD)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva + (((uint64_t)get_entry_by_id(LAYOUT_ID_TD)->page_count - 1) << SE_PAGE_SHIFT);
  537. tcs->ofs_limit = tcs->ogs_limit = (uint32_t)-1;
  538. return true;
  539. }
  540. void* CMetadata::get_rawdata_by_rva(uint64_t rva)
  541. {
  542. std::vector<Section*> sections = m_parser->get_sections();
  543. for(unsigned int i = 0; i < sections.size() ; i++)
  544. {
  545. uint64_t start_rva = TRIM_TO_PAGE(sections[i]->get_rva());
  546. uint64_t end_rva = ROUND_TO_PAGE(sections[i]->get_rva() + sections[i]->virtual_size());
  547. if(start_rva <= rva && rva < end_rva)
  548. {
  549. uint64_t offset = rva - sections[i]->get_rva();
  550. if (offset > sections[i]->raw_data_size())
  551. {
  552. return 0;
  553. }
  554. return GET_PTR(void, sections[i]->raw_data(), offset);
  555. }
  556. }
  557. return 0;
  558. }
  559. uint64_t CMetadata::calculate_sections_size()
  560. {
  561. std::vector<Section*> sections = m_parser->get_sections();
  562. uint64_t max_rva = 0;
  563. Section *last_section = NULL;
  564. for(unsigned int i = 0; i < sections.size() ; i++)
  565. {
  566. if(sections[i]->get_rva() > max_rva) {
  567. max_rva = sections[i]->get_rva();
  568. last_section = sections[i];
  569. }
  570. }
  571. uint64_t size = (NULL == last_section) ? (0) : (last_section->get_rva() + last_section->virtual_size());
  572. size = ROUND_TO_PAGE(size);
  573. return size;
  574. }
  575. uint64_t CMetadata::calculate_enclave_size(uint64_t size)
  576. {
  577. uint64_t enclave_max_size = m_parser->get_enclave_max_size();
  578. if(size > enclave_max_size)
  579. return (uint64_t)-1;
  580. uint64_t round_size = 1;
  581. while (round_size < size)
  582. {
  583. round_size <<=1;
  584. if(!round_size)
  585. return (uint64_t)-1;
  586. }
  587. if(round_size > enclave_max_size)
  588. return (uint64_t)-1;
  589. return round_size;
  590. }
  591. bool update_metadata(const char *path, const metadata_t *metadata, uint64_t meta_offset)
  592. {
  593. assert(path != NULL && metadata != NULL);
  594. return write_data_to_file(path, std::ios::in | std::ios::binary| std::ios::out,
  595. reinterpret_cast<uint8_t *>(const_cast<metadata_t *>( metadata)), metadata->size, (long)meta_offset);
  596. }