manage_metadata.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  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. /**
  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 "tinyxml2.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. #include <iomanip>
  52. #include <fstream>
  53. using namespace tinyxml2;
  54. #define ALIGN_SIZE 0x1000
  55. static bool traverser_parameter(const char *temp_name, const char *temp_text, xml_parameter_t *parameter, int parameter_count)
  56. {
  57. assert(temp_name != NULL && parameter != NULL);
  58. uint64_t temp_value=0;
  59. if(temp_text == NULL)
  60. {
  61. se_trace(SE_TRACE_ERROR, LACK_VALUE_FOR_ELEMENT_ERROR, temp_name);
  62. return false;
  63. }
  64. else
  65. {
  66. if(strchr(temp_text, '-'))
  67. {
  68. se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name);
  69. return false;
  70. }
  71. errno = 0;
  72. char* endptr = NULL;
  73. temp_value = (uint64_t)strtoull(temp_text, &endptr, 0);
  74. if(*endptr!='\0'||errno!=0) //Invalid value or valid value but out of the representable range
  75. {
  76. se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name);
  77. return false;
  78. }
  79. }
  80. //Look for the matched one
  81. int i=0;
  82. for(; i<parameter_count&&STRCMP(temp_name,parameter[i].name); i++);
  83. if(i>=parameter_count) //no matched, return false
  84. {
  85. se_trace(SE_TRACE_ERROR, UNREC_ELEMENT_ERROR, temp_name);
  86. return false;
  87. }
  88. //found one matched
  89. if(parameter[i].flag==1) //repeated definition of XML element, return false
  90. {
  91. se_trace(SE_TRACE_ERROR, REPEATED_DEFINE_ERROR, temp_name);
  92. return false;
  93. }
  94. parameter[i].flag = 1;
  95. if((temp_value<parameter[i].min_value)||
  96. (temp_value>parameter[i].max_value)) // the value is invalid, return false
  97. {
  98. se_trace(SE_TRACE_ERROR, VALUE_OUT_OF_RANGE_ERROR, temp_name);
  99. return false;
  100. }
  101. parameter[i].value = temp_value;
  102. return true;
  103. }
  104. bool parse_metadata_file(const char *xmlpath, xml_parameter_t *parameter, int parameter_count)
  105. {
  106. const char* temp_name=NULL;
  107. assert(parameter != NULL);
  108. if(xmlpath == NULL) // user didn't define the metadata xml file.
  109. {
  110. se_trace(SE_TRACE_NOTICE, "Use default metadata...\n");
  111. return true;
  112. }
  113. //use the metadata file that user gives us. parse xml file
  114. tinyxml2::XMLDocument doc;
  115. XMLError loadOkay = doc.LoadFile(xmlpath);
  116. if(loadOkay != XML_SUCCESS)
  117. {
  118. if(doc.ErrorID() == XML_ERROR_FILE_COULD_NOT_BE_OPENED)
  119. {
  120. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, xmlpath);
  121. }
  122. else if(doc.ErrorID() == XML_ERROR_FILE_NOT_FOUND)
  123. {
  124. se_trace(SE_TRACE_ERROR, XML_NOT_FOUND_ERROR, xmlpath);
  125. }
  126. else
  127. {
  128. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  129. }
  130. return false;
  131. }
  132. doc.Print();//Write the document to standard out using formatted printing ("pretty print").
  133. XMLElement *pmetadata_element = doc.FirstChildElement("EnclaveConfiguration");
  134. if(!pmetadata_element || pmetadata_element->GetText() != NULL)
  135. {
  136. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  137. return false;
  138. }
  139. XMLElement *sub_element = NULL;
  140. sub_element = pmetadata_element->FirstChildElement();
  141. const char *temp_text = NULL;
  142. while(sub_element)//parse xml node
  143. {
  144. if(sub_element->FirstAttribute() != NULL)
  145. {
  146. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  147. return false;
  148. }
  149. temp_name = sub_element->Value();
  150. temp_text = sub_element->GetText();
  151. //traverse every node. Compare with the default value.
  152. if(traverser_parameter(temp_name, temp_text, parameter, parameter_count) == false)
  153. {
  154. se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR);
  155. return false;
  156. }
  157. sub_element= sub_element->NextSiblingElement();
  158. }
  159. return true;
  160. }
  161. CMetadata::CMetadata(metadata_t *metadata, BinParser *parser)
  162. : m_metadata(metadata)
  163. , m_parser(parser), m_rva(0), m_gd_size(0), m_gd_template(NULL)
  164. {
  165. memset(m_metadata, 0, sizeof(metadata_t));
  166. memset(&m_create_param, 0, sizeof(m_create_param));
  167. }
  168. CMetadata::~CMetadata()
  169. {
  170. }
  171. bool CMetadata::build_metadata(const xml_parameter_t *parameter)
  172. {
  173. if(!modify_metadata(parameter))
  174. {
  175. return false;
  176. }
  177. // layout table
  178. if(!build_layout_table())
  179. {
  180. return false;
  181. }
  182. // patch table
  183. if(!build_patch_table())
  184. {
  185. return false;
  186. }
  187. if(!build_layout_entries())
  188. {
  189. return false;
  190. }
  191. if(!build_gd_template(m_gd_template, &m_gd_size))
  192. {
  193. return false;
  194. }
  195. return true;
  196. }
  197. #include <sstream>
  198. #include <time.h>
  199. bool CMetadata::get_time(uint32_t *date)
  200. {
  201. assert(date != NULL);
  202. time_t rawtime = 0;
  203. if(time( &rawtime) == -1)
  204. return false;
  205. struct tm *timeinfo = gmtime(&rawtime);
  206. if(timeinfo == NULL)
  207. return false;
  208. uint32_t tmp_date = (timeinfo->tm_year+1900)*10000 + (timeinfo->tm_mon+1)*100 + timeinfo->tm_mday;
  209. stringstream ss;
  210. ss<<"0x"<<tmp_date;
  211. ss>>hex>>tmp_date;
  212. *date = tmp_date;
  213. return true;
  214. }
  215. bool CMetadata::fill_enclave_css(const xml_parameter_t *para)
  216. {
  217. assert(para != NULL);
  218. uint32_t date = 0;
  219. if(false == get_time(&date))
  220. return false;
  221. //*****fill the header*******************
  222. uint8_t header[12] = {6, 0, 0, 0, 0xE1, 0, 0, 0, 0, 0, 1, 0};
  223. uint8_t header2[16] = {1, 1, 0, 0, 0x60, 0, 0, 0, 0x60, 0, 0, 0, 1, 0, 0, 0};
  224. memcpy_s(&m_metadata->enclave_css.header.header, sizeof(m_metadata->enclave_css.header.header), &header, sizeof(header));
  225. memcpy_s(&m_metadata->enclave_css.header.header2, sizeof(m_metadata->enclave_css.header.header2), &header2, sizeof(header2));
  226. // For 'type', signing tool clears the bit 31 for product enclaves
  227. // and set the bit 31 for debug enclaves
  228. m_metadata->enclave_css.header.type = (para[RELEASETYPE].value & 0x01) ? (1<<31) : 0;
  229. m_metadata->enclave_css.header.module_vendor = (para[INTELSIGNED].value&0x01) ? 0x8086 : 0;
  230. m_metadata->enclave_css.header.date = date;
  231. //hardware version
  232. m_metadata->enclave_css.header.hw_version = (uint32_t)para[HW].value;
  233. // Misc_select/Misc_mask
  234. m_metadata->enclave_css.body.misc_select = (uint32_t)para[MISCSELECT].value;
  235. m_metadata->enclave_css.body.misc_mask = (uint32_t)para[MISCMASK].value;
  236. //low 64 bit
  237. m_metadata->enclave_css.body.attributes.flags = 0;
  238. m_metadata->enclave_css.body.attribute_mask.flags = ~SGX_FLAGS_DEBUG;
  239. if(para[DISABLEDEBUG].value == 1)
  240. {
  241. m_metadata->enclave_css.body.attributes.flags &= ~SGX_FLAGS_DEBUG;
  242. m_metadata->enclave_css.body.attribute_mask.flags |= SGX_FLAGS_DEBUG;
  243. }
  244. if(para[PROVISIONKEY].value == 1)
  245. {
  246. m_metadata->enclave_css.body.attributes.flags |= SGX_FLAGS_PROVISION_KEY;
  247. m_metadata->enclave_css.body.attribute_mask.flags |= SGX_FLAGS_PROVISION_KEY;
  248. }
  249. if(para[LAUNCHKEY].value == 1)
  250. {
  251. m_metadata->enclave_css.body.attributes.flags |= SGX_FLAGS_EINITTOKEN_KEY;
  252. m_metadata->enclave_css.body.attribute_mask.flags |= SGX_FLAGS_EINITTOKEN_KEY;
  253. }
  254. bin_fmt_t bf = m_parser->get_bin_format();
  255. if(bf == BF_PE64 || bf == BF_ELF64)
  256. {
  257. m_metadata->enclave_css.body.attributes.flags |= SGX_FLAGS_MODE64BIT;
  258. m_metadata->enclave_css.body.attribute_mask.flags |= SGX_FLAGS_MODE64BIT;
  259. }
  260. // high 64 bit
  261. //default setting
  262. m_metadata->enclave_css.body.attributes.xfrm = SGX_XFRM_LEGACY;
  263. m_metadata->enclave_css.body.attribute_mask.xfrm = SGX_XFRM_LEGACY | SGX_XFRM_RESERVED; // LEGACY and reservied bits would be checked.
  264. m_metadata->enclave_css.body.isv_prod_id = (uint16_t)para[PRODID].value;
  265. m_metadata->enclave_css.body.isv_svn = (uint16_t)para[ISVSVN].value;
  266. return true;
  267. }
  268. bool CMetadata::modify_metadata(const xml_parameter_t *parameter)
  269. {
  270. assert(parameter != NULL);
  271. if(!check_xml_parameter(parameter))
  272. return false;
  273. if(!fill_enclave_css(parameter))
  274. return false;
  275. m_metadata->version = META_DATA_MAKE_VERSION(MAJOR_VERSION,MINOR_VERSION );
  276. m_metadata->size = offsetof(metadata_t, data);
  277. m_metadata->tcs_policy = (uint32_t)parameter[TCSPOLICY].value;
  278. m_metadata->ssa_frame_size = SSA_FRAME_SIZE;
  279. m_metadata->max_save_buffer_size = MAX_SAVE_BUF_SIZE;
  280. m_metadata->magic_num = METADATA_MAGIC;
  281. m_metadata->desired_misc_select = 0;
  282. m_metadata->tcs_min_pool = (uint32_t)parameter[TCSMINPOOL].value;
  283. m_metadata->enclave_css.body.misc_select = (uint32_t)parameter[MISCSELECT].value;
  284. m_metadata->enclave_css.body.misc_mask = (uint32_t)parameter[MISCMASK].value;
  285. //set metadata.attributes
  286. //low 64 bit: it's the same as enclave_css
  287. memset(&m_metadata->attributes, 0, sizeof(sgx_attributes_t));
  288. m_metadata->attributes.flags = m_metadata->enclave_css.body.attributes.flags;
  289. //high 64 bit
  290. //set bits that will not be checked
  291. m_metadata->attributes.xfrm = ~m_metadata->enclave_css.body.attribute_mask.xfrm;
  292. //set bits that have been set '1' and need to be checked
  293. m_metadata->attributes.xfrm |= (m_metadata->enclave_css.body.attributes.xfrm & m_metadata->enclave_css.body.attribute_mask.xfrm);
  294. return true;
  295. }
  296. bool CMetadata::check_xml_parameter(const xml_parameter_t *parameter)
  297. {
  298. //stack/heap must be page-align
  299. if( (parameter[STACKMAXSIZE].value % ALIGN_SIZE)
  300. || (parameter[STACKMINSIZE].value % ALIGN_SIZE) )
  301. {
  302. se_trace(SE_TRACE_ERROR, SET_STACK_SIZE_ERROR);
  303. return false;
  304. }
  305. if(parameter[STACKMINSIZE].value > parameter[STACKMAXSIZE].value)
  306. {
  307. se_trace(SE_TRACE_ERROR, SET_STACK_SIZE_ERROR);
  308. return false;
  309. }
  310. if( (parameter[HEAPMAXSIZE].value % ALIGN_SIZE)
  311. || (parameter[HEAPMINSIZE].value % ALIGN_SIZE)
  312. || (parameter[HEAPINITSIZE].value % ALIGN_SIZE) )
  313. {
  314. se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_ALIGN_ERROR);
  315. return false;
  316. }
  317. if (parameter[HEAPINITSIZE].flag != 0)
  318. {
  319. if (parameter[HEAPINITSIZE].value > parameter[HEAPMAXSIZE].value)
  320. {
  321. se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_INIT_MAX_ERROR);
  322. return false;
  323. }
  324. if (parameter[HEAPMINSIZE].value > parameter[HEAPINITSIZE].value)
  325. {
  326. se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_INIT_MIN_ERROR);
  327. return false;
  328. }
  329. }
  330. else
  331. {
  332. if (parameter[HEAPMINSIZE].value > parameter[HEAPMAXSIZE].value)
  333. {
  334. se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_MAX_MIN_ERROR);
  335. return false;
  336. }
  337. }
  338. // LE setting: HW != 0, Licensekey = 1
  339. // Other enclave setting: HW = 0, Licensekey = 0
  340. if((parameter[HW].value == 0 && parameter[LAUNCHKEY].value != 0) ||
  341. (parameter[HW].value != 0 && parameter[LAUNCHKEY].value == 0))
  342. {
  343. se_trace(SE_TRACE_ERROR, SET_HW_LE_ERROR);
  344. return false;
  345. }
  346. if (parameter[TCSMAXNUM].flag != 0)
  347. {
  348. if (parameter[TCSMAXNUM].value < parameter[TCSNUM].value)
  349. {
  350. se_trace(SE_TRACE_ERROR, SET_TCS_MAX_NUM_ERROR);
  351. return false;
  352. }
  353. if ((parameter[TCSMINPOOL].flag != 0)
  354. && (parameter[TCSMINPOOL].value > parameter[TCSMAXNUM].value))
  355. {
  356. se_trace(SE_TRACE_ERROR, SET_TCS_MIN_POOL_ERROR);
  357. return false;
  358. }
  359. }
  360. else if ((parameter[TCSMINPOOL].flag != 0)
  361. && (parameter[TCSMINPOOL].value > parameter[TCSNUM].value))
  362. {
  363. se_trace(SE_TRACE_ERROR, SET_TCS_MIN_POOL_ERROR);
  364. return false;
  365. }
  366. m_create_param.heap_init_size = parameter[HEAPINITSIZE].flag ? parameter[HEAPINITSIZE].value : parameter[HEAPMAXSIZE].value;
  367. m_create_param.heap_min_size = parameter[HEAPMINSIZE].value;
  368. m_create_param.heap_max_size = parameter[HEAPMAXSIZE].value;
  369. m_create_param.stack_max_size = parameter[STACKMAXSIZE].value;
  370. m_create_param.stack_min_size = parameter[STACKMINSIZE].value;
  371. m_create_param.tcs_num = (uint32_t)parameter[TCSNUM].value;
  372. m_create_param.tcs_max_num = (uint32_t)(parameter[TCSMAXNUM].flag ? parameter[TCSMAXNUM].value : parameter[TCSNUM].value);
  373. m_create_param.tcs_min_pool = (uint32_t)parameter[TCSMINPOOL].value;
  374. m_create_param.tcs_policy = (uint32_t)parameter[TCSPOLICY].value;
  375. se_trace(SE_TRACE_ERROR, "tcs_num %d, tcs_max_num %d, tcs_min_pool %d\n", m_create_param.tcs_num, m_create_param.tcs_max_num, m_create_param.tcs_min_pool);
  376. return true;
  377. }
  378. void *CMetadata::alloc_buffer_from_metadata(uint32_t size)
  379. {
  380. void *addr = GET_PTR(void, m_metadata, m_metadata->size);
  381. m_metadata->size += size;
  382. if((m_metadata->size < size) || (m_metadata->size > METADATA_SIZE))
  383. {
  384. return NULL;
  385. }
  386. return addr;
  387. }
  388. /*
  389. * Called within build_layout_table(), used to assign the rva to entry layout
  390. * and load_step to group layout.
  391. */
  392. bool CMetadata::update_layout_entries()
  393. {
  394. m_rva = calculate_sections_size();
  395. if(m_rva == 0)
  396. {
  397. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  398. return false;
  399. }
  400. for(uint32_t i = 0; i < m_layouts.size(); i++)
  401. {
  402. if(!IS_GROUP_ID(m_layouts[i].entry.id))
  403. {
  404. m_layouts[i].entry.rva = m_rva;
  405. m_rva += (((uint64_t)m_layouts[i].entry.page_count) << SE_PAGE_SHIFT);
  406. }
  407. else
  408. {
  409. for (uint32_t j = 0; j < m_layouts[i].group.entry_count; j++)
  410. {
  411. m_layouts[i].group.load_step += ((uint64_t)(m_layouts[i-j-1].entry.page_count)) << SE_PAGE_SHIFT;
  412. }
  413. m_rva += m_layouts[i].group.load_times * m_layouts[i].group.load_step;
  414. }
  415. }
  416. return true;
  417. }
  418. bool CMetadata::build_layout_entries()
  419. {
  420. uint32_t size = (uint32_t)(m_layouts.size() * sizeof(layout_t));
  421. layout_t *layout_table = (layout_t *) alloc_buffer_from_metadata(size);
  422. if(layout_table == NULL)
  423. {
  424. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  425. return false;
  426. }
  427. m_metadata->dirs[DIR_LAYOUT].offset = (uint32_t)PTR_DIFF(layout_table, m_metadata);
  428. m_metadata->dirs[DIR_LAYOUT].size = size;
  429. for(uint32_t i = 0; i < m_layouts.size(); i++, layout_table++)
  430. {
  431. memcpy_s(layout_table, sizeof(layout_t), &m_layouts[i], sizeof(layout_t));
  432. }
  433. // enclave virtual size
  434. m_metadata->enclave_size = calculate_enclave_size(m_rva);
  435. if(m_metadata->enclave_size == (uint64_t)-1)
  436. {
  437. se_trace(SE_TRACE_ERROR, OUT_OF_EPC_ERROR);
  438. return false;
  439. }
  440. // the last guard page entry to round the enclave size to power of 2
  441. if(m_metadata->enclave_size - m_rva > 0)
  442. {
  443. layout_table = (layout_t *)alloc_buffer_from_metadata(sizeof(layout_t));
  444. if(layout_table == NULL)
  445. {
  446. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  447. return false;
  448. }
  449. layout_table->entry.id = LAYOUT_ID_GUARD;
  450. layout_table->entry.rva = m_rva;
  451. layout_table->entry.page_count = (uint32_t)((m_metadata->enclave_size - m_rva) >> SE_PAGE_SHIFT);
  452. m_metadata->dirs[DIR_LAYOUT].size += (uint32_t)sizeof(layout_t);
  453. }
  454. return true;
  455. }
  456. bool CMetadata::build_layout_table()
  457. {
  458. layout_t layout;
  459. memset(&layout, 0, sizeof(layout));
  460. layout_t guard_page;
  461. memset(&guard_page, 0, sizeof(guard_page));
  462. guard_page.entry.id = LAYOUT_ID_GUARD;
  463. guard_page.entry.page_count = SE_GUARD_PAGE_SIZE >> SE_PAGE_SHIFT;
  464. size_t thread_start;
  465. size_t thread_end;
  466. // heap
  467. layout.entry.id = LAYOUT_ID_HEAP_MIN;
  468. layout.entry.page_count = (uint32_t)(m_create_param.heap_min_size >> SE_PAGE_SHIFT);
  469. layout.entry.attributes = PAGE_ATTR_EADD;
  470. layout.entry.si_flags = SI_FLAGS_RW;
  471. m_layouts.push_back(layout);
  472. if(m_create_param.heap_init_size > m_create_param.heap_min_size)
  473. {
  474. layout.entry.id = LAYOUT_ID_HEAP_INIT;
  475. layout.entry.page_count = (uint32_t)((m_create_param.heap_init_size - m_create_param.heap_min_size) >> SE_PAGE_SHIFT);
  476. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_POST_REMOVE | PAGE_ATTR_POST_ADD;
  477. layout.entry.si_flags = SI_FLAGS_RW;
  478. m_layouts.push_back(layout);
  479. }
  480. if(m_create_param.heap_max_size > m_create_param.heap_init_size)
  481. {
  482. layout.entry.id = LAYOUT_ID_HEAP_MAX;
  483. layout.entry.page_count = (uint32_t)((m_create_param.heap_max_size - m_create_param.heap_init_size) >> SE_PAGE_SHIFT);
  484. layout.entry.attributes = PAGE_ATTR_POST_ADD;
  485. layout.entry.si_flags = SI_FLAGS_RW;
  486. m_layouts.push_back(layout);
  487. }
  488. // thread context memory layout
  489. // guard page | stack | TCS | SSA | guard page | TLS
  490. thread_start = m_layouts.size();
  491. //ulitity tcs
  492. // guard page
  493. m_layouts.push_back(guard_page);
  494. // stack
  495. if(m_create_param.stack_max_size > m_create_param.stack_min_size)
  496. {
  497. layout.entry.id = LAYOUT_ID_STACK_MAX;
  498. layout.entry.page_count = (uint32_t)((m_create_param.stack_max_size - m_create_param.stack_min_size) >> SE_PAGE_SHIFT);
  499. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_EEXTEND | PAGE_DIR_GROW_DOWN; // | PAGE_ATTR_POST_ADD | PAGE_ATTR_POST_REMOVE;
  500. layout.entry.si_flags = SI_FLAGS_RW;
  501. layout.entry.content_size = 0xCCCCCCCC;
  502. m_layouts.push_back(layout);
  503. }
  504. layout.entry.id = LAYOUT_ID_STACK_MIN;
  505. layout.entry.page_count = (uint32_t)(m_create_param.stack_min_size >> SE_PAGE_SHIFT);
  506. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_EEXTEND;
  507. layout.entry.si_flags = SI_FLAGS_RW;
  508. layout.entry.content_size = 0xCCCCCCCC;
  509. m_layouts.push_back(layout);
  510. // guard page
  511. m_layouts.push_back(guard_page);
  512. // tcs
  513. layout.entry.id = LAYOUT_ID_TCS;
  514. layout.entry.page_count = TCS_SIZE >> SE_PAGE_SHIFT;
  515. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_EEXTEND;
  516. layout.entry.si_flags = SI_FLAGS_TCS;
  517. tcs_t *tcs_template = (tcs_t *) alloc_buffer_from_metadata(TCS_TEMPLATE_SIZE);
  518. if(tcs_template == NULL)
  519. {
  520. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  521. return false;
  522. }
  523. layout.entry.content_offset = (uint32_t)PTR_DIFF(tcs_template, m_metadata),
  524. layout.entry.content_size = TCS_TEMPLATE_SIZE;
  525. m_layouts.push_back(layout);
  526. memset(&layout, 0, sizeof(layout));
  527. // ssa
  528. layout.entry.id = LAYOUT_ID_SSA;
  529. layout.entry.page_count = SSA_FRAME_SIZE * SSA_NUM;
  530. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_EEXTEND;
  531. layout.entry.si_flags = SI_FLAGS_RW;
  532. m_layouts.push_back(layout);
  533. // guard page
  534. m_layouts.push_back(guard_page);
  535. // td
  536. layout.entry.id = LAYOUT_ID_TD;
  537. layout.entry.page_count = 1;
  538. const Section *section = m_parser->get_tls_section();
  539. if(section)
  540. {
  541. layout.entry.page_count += (uint32_t)(ROUND_TO_PAGE(section->virtual_size()) >> SE_PAGE_SHIFT);
  542. }
  543. layout.entry.attributes = PAGE_ATTR_EADD | PAGE_ATTR_EEXTEND;
  544. layout.entry.si_flags = SI_FLAGS_RW;
  545. m_layouts.push_back(layout);
  546. thread_end = m_layouts.size();
  547. uint32_t tcs_min_pool = 0;
  548. uint32_t tcs_eremove = 0;
  549. if(m_create_param.tcs_min_pool > m_create_param.tcs_num - 1)
  550. {
  551. tcs_min_pool = m_create_param.tcs_num - 1;
  552. tcs_eremove = 0;
  553. }
  554. else
  555. {
  556. tcs_min_pool = m_create_param.tcs_min_pool;
  557. tcs_eremove = m_create_param.tcs_num -1 - m_create_param.tcs_min_pool;
  558. }
  559. //tcs to fill the tcs mini pool
  560. if (tcs_min_pool > 0)
  561. {
  562. // group for static thread contexts
  563. memset(&layout, 0, sizeof(layout));
  564. layout.group.id = LAYOUT_ID_THREAD_GROUP;
  565. layout.group.entry_count = (uint16_t)(thread_end - thread_start);
  566. layout.group.load_times = tcs_min_pool;
  567. m_layouts.push_back(layout);
  568. }
  569. //tcs will be eremoved
  570. if (tcs_eremove > 0)
  571. {
  572. for(size_t i = thread_start; i < thread_end; i++)
  573. {
  574. layout = m_layouts[i];
  575. if(layout.entry.id != LAYOUT_ID_GUARD)
  576. {
  577. layout.entry.attributes |= PAGE_ATTR_EREMOVE;
  578. }
  579. m_layouts.push_back(layout);
  580. }
  581. if (tcs_eremove > 1)
  582. {
  583. memset(&layout, 0, sizeof(layout));
  584. layout.group.id = LAYOUT_ID_THREAD_GROUP;
  585. layout.group.entry_count = (uint16_t)(thread_end - thread_start);
  586. layout.group.load_times = tcs_eremove-1;
  587. m_layouts.push_back(layout);
  588. }
  589. }
  590. // dynamic thread contexts
  591. if (m_create_param.tcs_max_num > tcs_min_pool + 1)
  592. {
  593. for(size_t i = thread_start; i < thread_end; i++)
  594. {
  595. layout = m_layouts[i];
  596. if(layout.entry.id == LAYOUT_ID_STACK_MAX)
  597. {
  598. layout.entry.id = (uint16_t)(LAYOUT_ID_HEAP_DYN_MIN - LAYOUT_ID_HEAP_MIN + layout.entry.id);
  599. layout.entry.attributes = PAGE_ATTR_POST_ADD | PAGE_DIR_GROW_DOWN;
  600. }
  601. else if(layout.entry.id != LAYOUT_ID_GUARD)
  602. {
  603. layout.entry.id = (uint16_t)(LAYOUT_ID_HEAP_DYN_MIN - LAYOUT_ID_HEAP_MIN + layout.entry.id);
  604. layout.entry.attributes = PAGE_ATTR_POST_ADD | PAGE_ATTR_DYN_THREAD;
  605. }
  606. m_layouts.push_back(layout);
  607. }
  608. // dynamic thread group
  609. if (m_create_param.tcs_max_num > m_create_param.tcs_min_pool)
  610. {
  611. memset(&layout, 0, sizeof(layout));
  612. layout.group.id = LAYOUT_ID_THREAD_GROUP_DYN;
  613. layout.group.entry_count = (uint16_t)(thread_end - thread_start);
  614. layout.group.load_times = m_create_param.tcs_max_num - tcs_min_pool - 1;
  615. m_layouts.push_back(layout);
  616. }
  617. }
  618. // update layout entries
  619. if(false == update_layout_entries())
  620. {
  621. return false;
  622. }
  623. // tcs template
  624. if(false == build_tcs_template(tcs_template))
  625. {
  626. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  627. return false;
  628. }
  629. return true;
  630. }
  631. bool CMetadata::build_patch_entries(vector<patch_entry_t> &patches)
  632. {
  633. uint32_t size = (uint32_t)(patches.size() * sizeof(patch_entry_t));
  634. patch_entry_t *patch_table = (patch_entry_t *) alloc_buffer_from_metadata(size);
  635. if(patch_table == NULL)
  636. {
  637. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  638. return false;
  639. }
  640. m_metadata->dirs[DIR_PATCH].offset = (uint32_t)PTR_DIFF(patch_table, m_metadata);
  641. m_metadata->dirs[DIR_PATCH].size = size;
  642. for(uint32_t i = 0; i < patches.size(); i++)
  643. {
  644. memcpy_s(patch_table, sizeof(patch_entry_t), &patches[i], sizeof(patch_entry_t));
  645. patch_table++;
  646. }
  647. return true;
  648. }
  649. bool CMetadata::build_patch_table()
  650. {
  651. const uint8_t *base_addr = (const uint8_t *)m_parser->get_start_addr();
  652. vector<patch_entry_t> patches;
  653. patch_entry_t patch;
  654. memset(&patch, 0, sizeof(patch));
  655. // td template
  656. m_gd_size = m_parser->get_global_data_size();
  657. m_gd_template = (uint8_t *)alloc_buffer_from_metadata(m_gd_size);
  658. if(m_gd_template == NULL)
  659. {
  660. return false;
  661. }
  662. uint64_t rva = m_parser->get_symbol_rva("g_global_data");
  663. if(0 == rva)
  664. {
  665. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  666. return false;
  667. }
  668. patch.dst = (uint64_t)PTR_DIFF(get_rawdata_by_rva(rva), base_addr);
  669. patch.src = (uint32_t)PTR_DIFF(m_gd_template, m_metadata);
  670. patch.size = m_gd_size;
  671. patches.push_back(patch);
  672. // patch the image header
  673. uint64_t *zero = (uint64_t *)alloc_buffer_from_metadata(sizeof(*zero));
  674. if(zero == NULL)
  675. {
  676. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  677. return false;
  678. }
  679. *zero = 0;
  680. bin_fmt_t bf = m_parser->get_bin_format();
  681. if(bf == BF_ELF32)
  682. {
  683. Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)base_addr;
  684. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shnum, base_addr);
  685. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  686. patch.size = (uint32_t)sizeof(elf_hdr->e_shnum);
  687. patches.push_back(patch);
  688. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr);
  689. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  690. patch.size = (uint32_t)sizeof(elf_hdr->e_shoff);
  691. patches.push_back(patch);
  692. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr);
  693. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  694. patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx);
  695. patches.push_back(patch);
  696. // Modify GNU_RELRO info to eliminate the impact of enclave measurement.
  697. Elf32_Phdr *prg_hdr = GET_PTR(Elf32_Phdr, base_addr, elf_hdr->e_phoff);
  698. for (unsigned idx = 0; idx < elf_hdr->e_phnum; ++idx, ++prg_hdr)
  699. {
  700. if(prg_hdr->p_type == PT_GNU_RELRO)
  701. {
  702. patch.dst = (uint64_t)PTR_DIFF(prg_hdr, base_addr);
  703. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  704. patch.size = (uint32_t)sizeof(Elf32_Phdr);
  705. patches.push_back(patch);
  706. break;
  707. }
  708. }
  709. }
  710. else if(bf == BF_ELF64)
  711. {
  712. Elf64_Ehdr *elf_hdr = (Elf64_Ehdr *)base_addr;
  713. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shnum, base_addr);
  714. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  715. patch.size = (uint32_t)sizeof(elf_hdr->e_shnum);
  716. patches.push_back(patch);
  717. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shoff, base_addr);
  718. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  719. patch.size = (uint32_t)sizeof(elf_hdr->e_shoff);
  720. patches.push_back(patch);
  721. patch.dst = (uint64_t)PTR_DIFF(&elf_hdr->e_shstrndx, base_addr);
  722. patch.src = (uint32_t)PTR_DIFF(zero, m_metadata);
  723. patch.size = (uint32_t)sizeof(elf_hdr->e_shstrndx);
  724. patches.push_back(patch);
  725. }
  726. if(false == build_patch_entries(patches))
  727. {
  728. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  729. return false;
  730. }
  731. return true;
  732. }
  733. layout_entry_t *CMetadata::get_entry_by_id(uint16_t id)
  734. {
  735. for (uint32_t i = 0; i < m_layouts.size(); i++)
  736. {
  737. if(m_layouts[i].entry.id == id)
  738. return (layout_entry_t *)&m_layouts[i];
  739. }
  740. assert(false);
  741. return NULL;
  742. }
  743. bool CMetadata::get_xsave_size(uint64_t xfrm, uint32_t *xsave_size)
  744. {
  745. assert (xsave_size != NULL);
  746. struct {
  747. uint64_t bits;
  748. uint32_t size;
  749. } xsave_size_table[] = { // Note that the xsave_size should be in ascending order
  750. {SGX_XFRM_LEGACY, 512 + 64}, // 512 for legacy features, 64 for xsave header
  751. {SGX_XFRM_AVX, 512 + 64 + 256}, // 256 for YMM0_H - YMM15_H registers
  752. {SGX_XFRM_MPX, 512 + 64 + 256 + 256}, // 256 for MPX
  753. {SGX_XFRM_AVX512, 512 + 64 + 256 + 256 + 1600}, // 1600 for k0 - k7, ZMM0_H - ZMM15_H, ZMM16 - ZMM31
  754. // PT, PKRU ...
  755. };
  756. bool ret = true;
  757. *xsave_size = 0;
  758. if(!xfrm || (xfrm & SGX_XFRM_RESERVED))
  759. {
  760. return false;
  761. }
  762. for(size_t i = 0; i < sizeof(xsave_size_table)/sizeof(xsave_size_table[0]); i++)
  763. {
  764. if((xfrm & xsave_size_table[i].bits) == xsave_size_table[i].bits)
  765. {
  766. *xsave_size = xsave_size_table[i].size;
  767. }
  768. }
  769. return ret;
  770. }
  771. bool CMetadata::build_gd_template(uint8_t *data, uint32_t *data_size)
  772. {
  773. if(false == get_xsave_size(m_metadata->attributes.xfrm, &m_create_param.xsave_size))
  774. {
  775. return false;
  776. }
  777. m_create_param.stack_base_addr = (size_t)(get_entry_by_id(LAYOUT_ID_STACK_MIN)->rva + m_create_param.stack_min_size - get_entry_by_id(LAYOUT_ID_TCS)->rva);
  778. m_create_param.stack_limit_addr = (size_t)(m_create_param.stack_base_addr - m_create_param.stack_max_size);
  779. m_create_param.ssa_base_addr = (size_t)(get_entry_by_id(LAYOUT_ID_SSA)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva);
  780. m_create_param.enclave_size = m_metadata->enclave_size;
  781. m_create_param.heap_offset = (size_t)get_entry_by_id(LAYOUT_ID_HEAP_MIN)->rva;
  782. size_t tmp_tls_addr = (size_t)(get_entry_by_id(LAYOUT_ID_TD)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva);
  783. m_create_param.td_addr = tmp_tls_addr + (size_t)((get_entry_by_id(LAYOUT_ID_TD)->page_count - 1) << SE_PAGE_SHIFT);
  784. const Section *section = m_parser->get_tls_section();
  785. if(section)
  786. {
  787. /* adjust the tls_addr to be the pointer to the actual TLS data area */
  788. m_create_param.tls_addr = (size_t)(m_create_param.td_addr - section->virtual_size());
  789. assert(TRIM_TO_PAGE(m_create_param.tls_addr) == tmp_tls_addr);
  790. }
  791. else
  792. m_create_param.tls_addr = tmp_tls_addr;
  793. if(false == m_parser->update_global_data(m_metadata, &m_create_param, data, data_size))
  794. {
  795. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR); // metadata structure doesnot have enough memory for global_data template
  796. return false;
  797. }
  798. return true;
  799. }
  800. bool CMetadata::build_tcs_template(tcs_t *tcs)
  801. {
  802. tcs->oentry = m_parser->get_symbol_rva("enclave_entry");
  803. if(tcs->oentry == 0)
  804. {
  805. return false;
  806. }
  807. tcs->nssa = SSA_NUM;
  808. tcs->cssa = 0;
  809. tcs->ossa = get_entry_by_id(LAYOUT_ID_SSA)->rva - get_entry_by_id(LAYOUT_ID_TCS)->rva;
  810. //fs/gs pointer at TLS/TD
  811. 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);
  812. tcs->ofs_limit = tcs->ogs_limit = (uint32_t)-1;
  813. return true;
  814. }
  815. void* CMetadata::get_rawdata_by_rva(uint64_t rva)
  816. {
  817. std::vector<Section*> sections = m_parser->get_sections();
  818. for(unsigned int i = 0; i < sections.size() ; i++)
  819. {
  820. uint64_t start_rva = TRIM_TO_PAGE(sections[i]->get_rva());
  821. uint64_t end_rva = ROUND_TO_PAGE(sections[i]->get_rva() + sections[i]->virtual_size());
  822. if(start_rva <= rva && rva < end_rva)
  823. {
  824. uint64_t offset = rva - sections[i]->get_rva();
  825. if (offset > sections[i]->raw_data_size())
  826. {
  827. return 0;
  828. }
  829. return GET_PTR(void, sections[i]->raw_data(), offset);
  830. }
  831. }
  832. return 0;
  833. }
  834. uint64_t CMetadata::calculate_sections_size()
  835. {
  836. std::vector<Section*> sections = m_parser->get_sections();
  837. uint64_t max_rva = 0;
  838. Section *last_section = NULL;
  839. for(unsigned int i = 0; i < sections.size() ; i++)
  840. {
  841. if(sections[i]->get_rva() > max_rva) {
  842. max_rva = sections[i]->get_rva();
  843. last_section = sections[i];
  844. }
  845. }
  846. uint64_t size = (NULL == last_section) ? (0) : (last_section->get_rva() + last_section->virtual_size());
  847. size = ROUND_TO_PAGE(size);
  848. return size;
  849. }
  850. uint64_t CMetadata::calculate_enclave_size(uint64_t size)
  851. {
  852. uint64_t enclave_max_size = m_parser->get_enclave_max_size();
  853. if(size > enclave_max_size)
  854. return (uint64_t)-1;
  855. uint64_t round_size = 1;
  856. while (round_size < size)
  857. {
  858. round_size <<=1;
  859. if(!round_size)
  860. return (uint64_t)-1;
  861. }
  862. if(round_size > enclave_max_size)
  863. return (uint64_t)-1;
  864. return round_size;
  865. }
  866. bool update_metadata(const char *path, const metadata_t *metadata, uint64_t meta_offset)
  867. {
  868. assert(path != NULL && metadata != NULL);
  869. return write_data_to_file(path, std::ios::in | std::ios::binary| std::ios::out,
  870. reinterpret_cast<uint8_t *>(const_cast<metadata_t *>( metadata)), METADATA_SIZE, (long)meta_offset);
  871. }
  872. #define PRINT_ELEMENT(stream, structure, element) \
  873. do { \
  874. (stream) << #structure << "->" << #element << ": " << std::hex << "0x" << structure->element << std::endl; \
  875. }while(0)
  876. #define PRINT_ARRAY(stream, structure, array, size) \
  877. do{ \
  878. (stream) << #structure << "->" << #array << ":" << std::hex; \
  879. for(size_t i = 0; i < size; i++) \
  880. { \
  881. if (i % 16 == 0) (stream) << std::endl; \
  882. (stream) << "0x" << std::setfill('0') << std::setw(2) << (uint32_t)(structure)->array[i] << " "; \
  883. } \
  884. (stream) << std::endl; \
  885. }while(0)
  886. #define CONCAT(name, num) name##num
  887. #define A(num) CONCAT(metadata, num)
  888. bool print_metadata(const char *path, const metadata_t *metadata)
  889. {
  890. assert(path != NULL && metadata != NULL);
  891. std::ofstream meta_ofs(path, std::ofstream::out | std::ofstream::trunc);
  892. if (!meta_ofs.good())
  893. {
  894. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, path);
  895. return false;
  896. }
  897. meta_ofs << "The metadata information:" << std::endl
  898. << "=========================" << std::endl;
  899. PRINT_ELEMENT(meta_ofs, metadata, magic_num);
  900. PRINT_ELEMENT(meta_ofs, metadata, version);
  901. PRINT_ELEMENT(meta_ofs, metadata, size);
  902. PRINT_ELEMENT(meta_ofs, metadata, tcs_policy);
  903. PRINT_ELEMENT(meta_ofs, metadata, ssa_frame_size);
  904. PRINT_ELEMENT(meta_ofs, metadata, max_save_buffer_size);
  905. PRINT_ELEMENT(meta_ofs, metadata, desired_misc_select);
  906. PRINT_ELEMENT(meta_ofs, metadata, enclave_size);
  907. PRINT_ELEMENT(meta_ofs, metadata, attributes.flags);
  908. PRINT_ELEMENT(meta_ofs, metadata, attributes.xfrm);
  909. // css.header
  910. PRINT_ARRAY(meta_ofs, metadata, enclave_css.header.header, 12);
  911. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.header.type);
  912. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.header.module_vendor);
  913. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.header.date);
  914. PRINT_ARRAY(meta_ofs, metadata, enclave_css.header.header2, 16);
  915. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.header.hw_version);
  916. // css.key
  917. PRINT_ARRAY(meta_ofs, metadata, enclave_css.key.modulus, SE_KEY_SIZE);
  918. PRINT_ARRAY(meta_ofs, metadata, enclave_css.key.exponent, SE_EXPONENT_SIZE);
  919. PRINT_ARRAY(meta_ofs, metadata, enclave_css.key.signature, SE_KEY_SIZE);
  920. // css.body
  921. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.misc_select);
  922. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.misc_mask);
  923. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.attributes.flags);
  924. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.attributes.xfrm);
  925. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.attribute_mask.flags);
  926. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.attribute_mask.xfrm);
  927. PRINT_ARRAY(meta_ofs, metadata, enclave_css.body.enclave_hash.m, SGX_HASH_SIZE);
  928. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.isv_prod_id);
  929. PRINT_ELEMENT(meta_ofs, metadata, enclave_css.body.isv_svn);
  930. // css.buffer
  931. PRINT_ARRAY(meta_ofs, metadata, enclave_css.buffer.q1, SE_KEY_SIZE);
  932. PRINT_ARRAY(meta_ofs, metadata, enclave_css.buffer.q2, SE_KEY_SIZE);
  933. metadata_t *metadata2 = GET_PTR(metadata_t, metadata, metadata->size);
  934. if (metadata2->version == META_DATA_MAKE_VERSION(SGX_1_9_MAJOR_VERSION, SGX_1_9_MINOR_VERSION) &&
  935. metadata2->magic_num == METADATA_MAGIC)
  936. {
  937. // Print the compatible metadata info
  938. meta_ofs << std::endl << std::endl
  939. << "The compatible metadata information: " << std::endl
  940. << "====================================" << std::endl;
  941. PRINT_ELEMENT(meta_ofs, metadata2, magic_num);
  942. PRINT_ELEMENT(meta_ofs, metadata2, version);
  943. PRINT_ELEMENT(meta_ofs, metadata2, size);
  944. PRINT_ELEMENT(meta_ofs, metadata2, tcs_policy);
  945. PRINT_ELEMENT(meta_ofs, metadata2, ssa_frame_size);
  946. PRINT_ELEMENT(meta_ofs, metadata2, max_save_buffer_size);
  947. PRINT_ELEMENT(meta_ofs, metadata2, desired_misc_select);
  948. PRINT_ELEMENT(meta_ofs, metadata2, enclave_size);
  949. PRINT_ELEMENT(meta_ofs, metadata2, attributes.flags);
  950. PRINT_ELEMENT(meta_ofs, metadata2, attributes.xfrm);
  951. // css.header
  952. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.header.header, 12);
  953. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.header.type);
  954. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.header.module_vendor);
  955. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.header.date);
  956. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.header.header2, 16);
  957. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.header.hw_version);
  958. // css.key
  959. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.key.modulus, SE_KEY_SIZE);
  960. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.key.exponent, SE_EXPONENT_SIZE);
  961. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.key.signature, SE_KEY_SIZE);
  962. // css.body
  963. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.misc_select);
  964. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.misc_mask);
  965. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.attributes.flags);
  966. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.attributes.xfrm);
  967. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.attribute_mask.flags);
  968. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.attribute_mask.xfrm);
  969. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.body.enclave_hash.m, SGX_HASH_SIZE);
  970. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.isv_prod_id);
  971. PRINT_ELEMENT(meta_ofs, metadata2, enclave_css.body.isv_svn);
  972. // css.buffer
  973. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.buffer.q1, SE_KEY_SIZE);
  974. PRINT_ARRAY(meta_ofs, metadata2, enclave_css.buffer.q2, SE_KEY_SIZE);
  975. }
  976. meta_ofs.close();
  977. return true;
  978. }