sign_tool.cpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301
  1. /*
  2. * Copyright (C) 2011-2017 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. // SignTool.cpp : Defines the entry point for the console application.
  32. //
  33. /**
  34. * File:
  35. * sign_tool.cpp
  36. *Description:
  37. * Defines the entry point for the application.
  38. *
  39. */
  40. #include "ippcp.h"
  41. #include "ippcore.h"
  42. #include "metadata.h"
  43. #include "manage_metadata.h"
  44. #include "ipp_wrapper.h"
  45. #include "parse_key_file.h"
  46. #include "enclave_creator_sign.h"
  47. #include "util_st.h"
  48. #include "se_trace.h"
  49. #include "sgx_error.h"
  50. #include "se_map.h"
  51. #include "loader.h"
  52. #include "parserfactory.h"
  53. #include "elf_helper.h"
  54. #include <unistd.h>
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <time.h>
  58. #include <assert.h>
  59. #include <string>
  60. #include <memory>
  61. #include <sstream>
  62. #define SIGNATURE_SIZE 384
  63. typedef enum _command_mode_t
  64. {
  65. SIGN = 0,
  66. GENDATA,
  67. CATSIG,
  68. COMPARE,
  69. DUMP
  70. } command_mode_t;
  71. typedef enum _file_path_t
  72. {
  73. DLL = 0,
  74. XML = 1,
  75. KEY,
  76. OUTPUT,
  77. SIG,
  78. UNSIGNED,
  79. REVIEW_ENCLAVE,
  80. DUMPFILE
  81. } file_path_t;
  82. static bool get_time(uint32_t *date)
  83. {
  84. assert(date != NULL);
  85. time_t rawtime = 0;
  86. if(time( &rawtime) == -1)
  87. return false;
  88. struct tm *timeinfo = gmtime(&rawtime);
  89. if(timeinfo == NULL)
  90. return false;
  91. uint32_t tmp_date = (timeinfo->tm_year+1900)*10000 + (timeinfo->tm_mon+1)*100 + timeinfo->tm_mday;
  92. stringstream ss;
  93. ss<<"0x"<<tmp_date;
  94. ss>>hex>>tmp_date;
  95. *date = tmp_date;
  96. return true;
  97. }
  98. static int load_enclave(BinParser *parser, metadata_t *metadata)
  99. {
  100. std::unique_ptr<CLoader> ploader(new CLoader(const_cast<uint8_t *>(parser->get_start_addr()), *parser));
  101. return ploader->load_enclave_ex(NULL, 0, metadata, NULL);
  102. }
  103. #define THE_INVALID_HANDLE (-1)
  104. static int open_file(const char* dllpath)
  105. {
  106. FILE *fp = fopen(dllpath, "rb");
  107. if (fp == NULL)
  108. return THE_INVALID_HANDLE;
  109. return fileno(fp);
  110. }
  111. static void close_handle(int fd)
  112. {
  113. close(fd);
  114. }
  115. static bool get_enclave_info(BinParser *parser, bin_fmt_t *bf, uint64_t * meta_offset, bool is_dump_mode = false)
  116. {
  117. uint64_t meta_rva = parser->get_metadata_offset();
  118. const uint8_t *base_addr = parser->get_start_addr();
  119. metadata_t *metadata = GET_PTR(metadata_t, base_addr, meta_rva);
  120. if(metadata->magic_num == METADATA_MAGIC && is_dump_mode == false)
  121. {
  122. se_trace(SE_TRACE_ERROR, ENCLAVE_ALREADY_SIGNED_ERROR);
  123. return false;
  124. }
  125. *bf = parser->get_bin_format();
  126. *meta_offset = meta_rva;
  127. return true;
  128. }
  129. // measure_enclave():
  130. // 1. Get the enclave hash by loading enclave
  131. // 2. Get the enclave info - metadata offset and enclave file format
  132. static bool measure_enclave(uint8_t *hash, const char *dllpath, const xml_parameter_t *parameter, bool ignore_rel_error, metadata_t *metadata, bin_fmt_t *bin_fmt, uint64_t *meta_offset)
  133. {
  134. assert(hash && dllpath && metadata && bin_fmt && meta_offset);
  135. bool res = false;
  136. uint32_t file_size = 0;
  137. uint64_t quota = 0;
  138. se_file_handle_t fh = open_file(dllpath);
  139. if (fh == THE_INVALID_HANDLE)
  140. {
  141. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, dllpath);
  142. return false;
  143. }
  144. // Probably we can use `decltype' if all major supported compilers support that.
  145. std::unique_ptr<map_handle_t, void (*)(map_handle_t*)> mh(map_file(fh, &file_size), unmap_file);
  146. if (!mh)
  147. {
  148. close_handle(fh);
  149. return false;
  150. }
  151. // Parse enclave
  152. std::unique_ptr<BinParser> parser(binparser::get_parser(mh->base_addr, (size_t)file_size));
  153. assert(parser != NULL);
  154. sgx_status_t status = parser->run_parser();
  155. if (status != SGX_SUCCESS)
  156. {
  157. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  158. close_handle(fh);
  159. return false;
  160. }
  161. // generate metadata
  162. CMetadata meta(metadata, parser.get());
  163. if(meta.build_metadata(parameter) == false)
  164. {
  165. close_handle(fh);
  166. return false;
  167. }
  168. // Collect enclave info
  169. if(get_enclave_info(parser.get(), bin_fmt, meta_offset) == false)
  170. {
  171. close_handle(fh);
  172. return false;
  173. }
  174. bool no_rel = false;
  175. if (*bin_fmt == BF_ELF64)
  176. {
  177. no_rel = ElfHelper<64>::dump_textrels(parser.get());
  178. }
  179. else
  180. {
  181. no_rel = ElfHelper<32>::dump_textrels(parser.get());
  182. }
  183. if(no_rel == false && ignore_rel_error == false)
  184. {
  185. close_handle(fh);
  186. se_trace(SE_TRACE_ERROR, TEXT_REL_ERROR);
  187. return false;
  188. }
  189. // Load enclave to get enclave hash
  190. int ret = load_enclave(parser.release(), metadata);
  191. close_handle(fh);
  192. switch(ret)
  193. {
  194. case SGX_ERROR_INVALID_METADATA:
  195. se_trace(SE_TRACE_ERROR, OUT_OF_EPC_ERROR);
  196. res = false;
  197. break;
  198. case SGX_ERROR_INVALID_VERSION:
  199. se_trace(SE_TRACE_ERROR, META_VERSION_ERROR);
  200. res = false;
  201. break;
  202. case SGX_ERROR_INVALID_ENCLAVE:
  203. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  204. res = false;
  205. break;
  206. case SGX_SUCCESS:
  207. ret = dynamic_cast<EnclaveCreatorST*>(get_enclave_creator())->get_enclave_info(hash, SGX_HASH_SIZE, &quota);
  208. if(ret != SGX_SUCCESS)
  209. {
  210. res = false;
  211. break;
  212. }
  213. se_trace(SE_TRACE_ERROR, REQUIRED_ENCLAVE_SIZE, quota);
  214. res = true;
  215. break;
  216. default:
  217. res = false;
  218. break;
  219. }
  220. return res;
  221. }
  222. static void set_meta_attributes(metadata_t *meta)
  223. {
  224. assert(meta != NULL);
  225. //set metadata.attributes
  226. //low 64 bit: it's the same as enclave_css
  227. memset(&meta->attributes, 0, sizeof(sgx_attributes_t));
  228. meta->attributes.flags = meta->enclave_css.body.attributes.flags;
  229. //high 64 bit
  230. //set bits that will not be checked
  231. meta->attributes.xfrm = ~meta->enclave_css.body.attribute_mask.xfrm;
  232. //set bits that have been set '1' and need to be checked
  233. meta->attributes.xfrm |= (meta->enclave_css.body.attributes.xfrm & meta->enclave_css.body.attribute_mask.xfrm);
  234. return;
  235. }
  236. //fill_enclave_css()
  237. // file the enclave_css_t structure with the parameter, enclave_hash
  238. // If the RSA_key is not null, fill the key part
  239. // If RSA_key == NULL, fill the header and body(GENDATA mode)
  240. // If the path[UNSIGNED] != NULL, update the header.date(CATSIG mode)
  241. static bool fill_enclave_css(const IppsRSAPublicKeyState *pub_key, const xml_parameter_t *para, const uint8_t *enclave_hash,
  242. const char **path, enclave_css_t *css, bin_fmt_t bf)
  243. {
  244. assert(para != NULL && enclave_hash != NULL && path != NULL && css != NULL);
  245. enclave_css_t enclave_css;
  246. memset(&enclave_css, 0, sizeof(enclave_css_t));
  247. uint32_t date = 0;
  248. if(false == get_time(&date))
  249. return false;
  250. //*****fill the header*******************
  251. uint8_t header[12] = {6, 0, 0, 0, 0xE1, 0, 0, 0, 0, 0, 1, 0};
  252. uint8_t header2[16] = {1, 1, 0, 0, 0x60, 0, 0, 0, 0x60, 0, 0, 0, 1, 0, 0, 0};
  253. memcpy_s(&enclave_css.header.header, sizeof(enclave_css.header.header), &header, sizeof(header));
  254. memcpy_s(&enclave_css.header.header2, sizeof(enclave_css.header.header2), &header2, sizeof(header2));
  255. // For 'type', signing tool clears the bit 31 for product enclaves
  256. // and set the bit 31 for debug enclaves
  257. enclave_css.header.type = (para[RELEASETYPE].value & 0x01) ? (1<<31) : 0;
  258. enclave_css.header.module_vendor = (para[INTELSIGNED].value&0x01) ? 0x8086 : 0;
  259. enclave_css.header.date = date;
  260. //if pub_key is not NULL, fill the key part
  261. if(pub_key)
  262. {
  263. int exponent_size = 0;
  264. int modulus_size = 0;
  265. IppStatus error_code = get_pub_key(pub_key, &exponent_size,
  266. (Ipp32u *)&enclave_css.key.exponent,
  267. &modulus_size,
  268. (Ipp32u *)&enclave_css.key.modulus);
  269. if(error_code != ippStsNoErr)
  270. {
  271. return false;
  272. }
  273. exponent_size = (uint32_t)(ROUND_TO(exponent_size, sizeof(Ipp32u)) / sizeof(Ipp32u));
  274. modulus_size = (uint32_t)(ROUND_TO(modulus_size, sizeof(Ipp32u)) / sizeof(Ipp32u));
  275. assert(enclave_css.key.exponent[0] == 0x03);
  276. assert(exponent_size == 0x1);
  277. assert(modulus_size == 0x60);
  278. }
  279. //hardware version
  280. enclave_css.header.hw_version = (uint32_t)para[HW].value;
  281. //****************************fill the body***********************
  282. // Misc_select/Misc_mask
  283. enclave_css.body.misc_select = (uint32_t)para[MISCSELECT].value;
  284. enclave_css.body.misc_mask = (uint32_t)para[MISCMASK].value;
  285. //low 64 bit
  286. enclave_css.body.attributes.flags = 0;
  287. enclave_css.body.attribute_mask.flags = ~SGX_FLAGS_DEBUG;
  288. if(para[DISABLEDEBUG].value == 1)
  289. {
  290. enclave_css.body.attributes.flags &= ~SGX_FLAGS_DEBUG;
  291. enclave_css.body.attribute_mask.flags |= SGX_FLAGS_DEBUG;
  292. }
  293. if(para[PROVISIONKEY].value == 1)
  294. {
  295. enclave_css.body.attributes.flags |= SGX_FLAGS_PROVISION_KEY;
  296. enclave_css.body.attribute_mask.flags |= SGX_FLAGS_PROVISION_KEY;
  297. }
  298. if(para[LAUNCHKEY].value == 1)
  299. {
  300. enclave_css.body.attributes.flags |= SGX_FLAGS_EINITTOKEN_KEY;
  301. enclave_css.body.attribute_mask.flags |= SGX_FLAGS_EINITTOKEN_KEY;
  302. }
  303. if(bf == BF_PE64 || bf == BF_ELF64)
  304. {
  305. enclave_css.body.attributes.flags |= SGX_FLAGS_MODE64BIT;
  306. enclave_css.body.attribute_mask.flags |= SGX_FLAGS_MODE64BIT;
  307. }
  308. // high 64 bit
  309. //default setting
  310. enclave_css.body.attributes.xfrm = SGX_XFRM_LEGACY; // SGX requires SSE and x87, so set legacy bits to be checked
  311. enclave_css.body.attribute_mask.xfrm = SGX_XFRM_LEGACY | SGX_XFRM_RESERVED; // LEGACY and reserved bits would be checked.
  312. memcpy_s(&enclave_css.body.enclave_hash, sizeof(enclave_css.body.enclave_hash), enclave_hash, SGX_HASH_SIZE);
  313. enclave_css.body.isv_prod_id = (uint16_t)para[PRODID].value;
  314. enclave_css.body.isv_svn = (uint16_t)para[ISVSVN].value;
  315. //Copy the css to output css buffer
  316. memcpy_s(css, sizeof(enclave_css_t), &enclave_css, sizeof(enclave_css_t));
  317. if(path[UNSIGNED] != NULL)
  318. {
  319. // In catsig mode, update the header.date as the time when the unsigned file is generated.
  320. memset(&enclave_css, 0, sizeof(enclave_css));
  321. size_t fsize = get_file_size(path[UNSIGNED]);
  322. if(fsize != sizeof(enclave_css.header) + sizeof(enclave_css.body))
  323. {
  324. se_trace(SE_TRACE_ERROR, UNSIGNED_FILE_ERROR, path[UNSIGNED]);
  325. return false;
  326. }
  327. uint8_t *buf = new uint8_t[fsize];
  328. memset(buf, 0, fsize);
  329. if(read_file_to_buf(path[UNSIGNED], buf, fsize) == false)
  330. {
  331. se_trace(SE_TRACE_ERROR, READ_FILE_ERROR, path[UNSIGNED]);
  332. delete [] buf;
  333. return false;
  334. }
  335. memcpy_s(&enclave_css.header, sizeof(enclave_css.header), buf, sizeof(enclave_css.header));
  336. memcpy_s(&enclave_css.body, sizeof(enclave_css.body), buf + sizeof(enclave_css.header), fsize - sizeof(enclave_css.header));
  337. delete [] buf;
  338. css->header.date = enclave_css.header.date;
  339. // Verify the header and body read from the unsigned file to make sure it's the same as that generated from xml file
  340. if(memcmp(&enclave_css.header, &css->header, sizeof(enclave_css.header)) || memcmp(&enclave_css.body, &css->body, sizeof(enclave_css.body)))
  341. {
  342. se_trace(SE_TRACE_ERROR, UNSIGNED_FILE_XML_MISMATCH);
  343. return false;
  344. }
  345. }
  346. return true;
  347. }
  348. static IppStatus calc_RSAq1q2(int length_s, const Ipp32u *data_s, int length_m, const Ipp32u *data_m,
  349. int *length_q1, Ipp32u *data_q1, int *length_q2, Ipp32u *data_q2)
  350. {
  351. IppStatus error_code = ippStsSAReservedErr1;
  352. IppsBigNumState *pM=0, *pS=0, *pQ1=0, *pQ2=0, *ptemp1=0, *ptemp2=0;
  353. IppsBigNumSGN sgn = IppsBigNumPOS;
  354. int length_in_bit = 0;
  355. Ipp32u *pdata = NULL;
  356. //create 6 big number
  357. if(!data_s || !data_m || !length_q1 || !data_q1 || !length_q2
  358. || !data_q2 || length_s <= 0 || length_m <= 0)
  359. {
  360. error_code = ippStsBadArgErr;
  361. goto clean_return;
  362. }
  363. error_code = newBN(data_s, length_s, &pS);
  364. if(error_code != ippStsNoErr)
  365. {
  366. goto clean_return;
  367. }
  368. error_code = newBN(data_m, length_m, &pM);
  369. if(error_code != ippStsNoErr)
  370. {
  371. goto clean_return;
  372. }
  373. error_code = newBN(0, length_m, &pQ1);
  374. if(error_code != ippStsNoErr)
  375. {
  376. goto clean_return;
  377. }
  378. error_code = newBN(0, length_m, &pQ2);
  379. if(error_code != ippStsNoErr)
  380. {
  381. goto clean_return;
  382. }
  383. error_code = newBN(0, length_m*2, &ptemp1);
  384. if(error_code != ippStsNoErr)
  385. {
  386. goto clean_return;
  387. }
  388. error_code = newBN(0, length_m, &ptemp2);
  389. if(error_code != ippStsNoErr)
  390. {
  391. goto clean_return;
  392. }
  393. //signed big number operation
  394. //multiplies pS and pS, ptemp1 is the multiplication result
  395. error_code = ippsMul_BN(pS, pS, ptemp1);
  396. if(error_code != ippStsNoErr)
  397. {
  398. goto clean_return;
  399. }
  400. //ptemp1: dividend, pM: divisor, pQ1: qutient, ptemp2: remainder
  401. error_code = ippsDiv_BN(ptemp1, pM, pQ1, ptemp2);
  402. if(error_code != ippStsNoErr)
  403. {
  404. goto clean_return;
  405. }
  406. error_code = ippsMul_BN(pS, ptemp2, ptemp1);
  407. if(error_code != ippStsNoErr)
  408. {
  409. goto clean_return;
  410. }
  411. error_code = ippsDiv_BN(ptemp1, pM, pQ2, ptemp2);
  412. if(error_code != ippStsNoErr)
  413. {
  414. goto clean_return;
  415. }
  416. //extract the sign and value of the integer big number from the input structure(pQ1)
  417. error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, pQ1);
  418. if(error_code != ippStsNoErr)
  419. {
  420. goto clean_return;
  421. }
  422. *length_q1 = ROUND_TO(length_in_bit, 8)/8;
  423. memset(data_q1, 0, *length_q1);
  424. memcpy_s(data_q1, *length_q1, pdata, *length_q1);
  425. error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, pQ2);
  426. if(error_code != ippStsNoErr)
  427. {
  428. goto clean_return;
  429. }
  430. *length_q2 = ROUND_TO(length_in_bit, 8)/8;
  431. memset(data_q2, 0, *length_q2);
  432. memcpy_s(data_q2, *length_q2, pdata, *length_q2);
  433. goto clean_return;
  434. clean_return:
  435. secure_free_BN(pM, length_m);
  436. secure_free_BN(pS, length_s);
  437. secure_free_BN(pQ1, length_m);
  438. secure_free_BN(pQ2, length_m);
  439. secure_free_BN(ptemp1, length_m*2);
  440. secure_free_BN(ptemp2, length_m);
  441. return error_code;
  442. }
  443. static bool create_signature(const IppsRSAPrivateKeyState *pri_key1, const char *sigpath, enclave_css_t *enclave_css)
  444. {
  445. IppStatus error_code = ippStsNoErr;
  446. assert(enclave_css != NULL);
  447. assert(!(pri_key1 == NULL && sigpath == NULL) && !(pri_key1 != NULL && sigpath != NULL));
  448. uint8_t signature[SIGNATURE_SIZE]; // keep the signature in big endian
  449. memset(signature, 0, SIGNATURE_SIZE);
  450. //**********get the signature*********
  451. if(sigpath != NULL)//CATSIG mode
  452. {
  453. if(get_file_size(sigpath) != SIGNATURE_SIZE)
  454. {
  455. se_trace(SE_TRACE_ERROR, SIG_FILE_ERROR, sigpath);
  456. return false;
  457. }
  458. if(read_file_to_buf(sigpath, signature, SIGNATURE_SIZE) == false)
  459. {
  460. se_trace(SE_TRACE_ERROR, READ_FILE_ERROR, sigpath);
  461. return false;
  462. }
  463. }
  464. else //SIGN mode
  465. {
  466. size_t buffer_size = sizeof(enclave_css->header) + sizeof(enclave_css->body);
  467. Ipp8u * temp_buffer = (Ipp8u *)malloc(buffer_size * sizeof(char));
  468. if(NULL == temp_buffer)
  469. {
  470. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  471. return false;
  472. }
  473. memcpy_s(temp_buffer, buffer_size, &enclave_css->header, sizeof(enclave_css->header));
  474. memcpy_s(temp_buffer + sizeof(enclave_css->header), buffer_size - sizeof(enclave_css->header),
  475. &enclave_css->body, sizeof(enclave_css->body));
  476. int pri1_size = 0;
  477. if(ippsRSA_GetBufferSizePrivateKey(&pri1_size, pri_key1) != ippStsNoErr)
  478. {
  479. free(temp_buffer);
  480. return false;
  481. }
  482. Ipp8u *scratch_buf = (Ipp8u *)malloc(pri1_size);
  483. if(NULL == scratch_buf)
  484. {
  485. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  486. free(temp_buffer);
  487. return false;
  488. }
  489. memset(scratch_buf, 0, pri1_size);
  490. error_code = ippsRSASign_PKCS1v15((const Ipp8u *)temp_buffer, (int)buffer_size, (Ipp8u *)signature, pri_key1, NULL, ippHashAlg_SHA256, scratch_buf);
  491. free(scratch_buf);
  492. free(temp_buffer);
  493. if(error_code != ippStsNoErr)
  494. {
  495. return false;
  496. }
  497. }
  498. for(int i = 0; i<SIGNATURE_SIZE; i++)
  499. {
  500. (enclave_css->key.signature)[i] = signature[SIGNATURE_SIZE-1-i];
  501. }
  502. //************************calculate q1 and q2*********************
  503. int length_q1 = 0, length_q2 = 0;
  504. error_code = calc_RSAq1q2(sizeof(enclave_css->key.signature),
  505. (Ipp32u *)&enclave_css->key.signature,
  506. sizeof(enclave_css->key.modulus),
  507. (Ipp32u *)&enclave_css->key.modulus,
  508. &length_q1,
  509. (Ipp32u *)&enclave_css->buffer.q1,
  510. &length_q2,
  511. (Ipp32u *)&enclave_css->buffer.q2);
  512. if(error_code != ippStsNoErr)
  513. {
  514. return false;
  515. }
  516. return true;
  517. }
  518. static bool verify_signature(const rsa_params_t *rsa, const enclave_css_t *enclave_css, int *signature_verified)
  519. {
  520. assert(rsa != NULL && enclave_css != NULL && signature_verified != NULL);
  521. IppsRSAPublicKeyState *pub_key = NULL;
  522. IppStatus error_code = create_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, rsa->n, rsa->e, &pub_key);
  523. if(error_code != ippStsNoErr)
  524. {
  525. return false;
  526. }
  527. size_t buffer_size = sizeof(enclave_css->header) + sizeof(enclave_css->body);
  528. Ipp8u * temp_buffer = (Ipp8u *)malloc(buffer_size * sizeof(char));
  529. if(NULL == temp_buffer)
  530. {
  531. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  532. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  533. return false;
  534. }
  535. memcpy_s(temp_buffer, buffer_size, &enclave_css->header, sizeof(enclave_css->header));
  536. memcpy_s(temp_buffer + sizeof(enclave_css->header), buffer_size-sizeof(enclave_css->header),
  537. &enclave_css->body, sizeof(enclave_css->body));
  538. uint8_t signature[SIGNATURE_SIZE];
  539. for(int i=0; i<SIGNATURE_SIZE; i++)
  540. {
  541. signature[i] = enclave_css->key.signature[SIGNATURE_SIZE-1-i];
  542. }
  543. int pub_size = 0;
  544. if(ippsRSA_GetBufferSizePublicKey(&pub_size, pub_key) != ippStsNoErr)
  545. {
  546. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  547. free(temp_buffer);
  548. return false;
  549. }
  550. Ipp8u *scratch_buf = (Ipp8u *)malloc(pub_size);
  551. if(NULL == scratch_buf)
  552. {
  553. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  554. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  555. free(temp_buffer);
  556. return false;
  557. }
  558. memset(scratch_buf, 0, pub_size);
  559. error_code = ippsRSAVerify_PKCS1v15((const Ipp8u *)temp_buffer, (int)buffer_size, (Ipp8u *)signature, signature_verified, pub_key, ippHashAlg_SHA256, scratch_buf);
  560. free(temp_buffer);
  561. free(scratch_buf);
  562. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  563. if(error_code != ippStsNoErr)
  564. {
  565. se_trace(SE_TRACE_DEBUG, "ippsRSASSAVerify_SHA256_PKCSv15() returns failure. The ipperrorCode is %d \n", error_code);
  566. return false;
  567. }
  568. else
  569. {
  570. se_trace(SE_TRACE_DEBUG, "RSAVerify() returns success. The signature_verified is %d\n", *signature_verified);
  571. return true;
  572. }
  573. }
  574. static bool gen_enclave_signing_file(const enclave_css_t *enclave_css, const char *outpath)
  575. {
  576. assert(enclave_css != NULL);
  577. size_t size = sizeof(enclave_css->header) + sizeof(enclave_css->body);
  578. uint8_t *buffer = (uint8_t *)malloc(size);
  579. if(buffer == NULL)
  580. {
  581. se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR);
  582. return false;
  583. }
  584. memcpy_s(buffer, sizeof(enclave_css->header), &enclave_css->header, sizeof(enclave_css->header));
  585. memcpy_s(buffer + sizeof(enclave_css->header), sizeof(enclave_css->body), &enclave_css->body, sizeof(enclave_css->body));
  586. if(write_data_to_file(outpath, std::ios::out|std::ios::binary, buffer, size) == false)
  587. {
  588. free(buffer);
  589. return false;
  590. }
  591. free(buffer);
  592. return true;
  593. }
  594. static bool cmdline_parse(unsigned int argc, char *argv[], int *mode, const char **path, bool *ignore_rel_error)
  595. {
  596. assert(mode!=NULL && path != NULL);
  597. if(argc<2)
  598. {
  599. se_trace(SE_TRACE_ERROR, LACK_PARA_ERROR);
  600. return false;
  601. }
  602. if(argc == 2 && !STRCMP(argv[1], "-help"))
  603. {
  604. se_trace(SE_TRACE_ERROR, USAGE_STRING);
  605. *mode = -1;
  606. return true;
  607. }
  608. enum { PAR_REQUIRED, PAR_OPTIONAL, PAR_INVALID };
  609. typedef struct _param_struct_{
  610. const char *name; //options
  611. char *value; //keep the path
  612. int flag; //indicate this parameter is required(0), optional(1) or invalid(2)
  613. }param_struct_t; //keep the parameter pairs
  614. param_struct_t params_sign[] = {
  615. {"-enclave", NULL, PAR_REQUIRED},
  616. {"-config", NULL, PAR_OPTIONAL},
  617. {"-key", NULL, PAR_REQUIRED},
  618. {"-out", NULL, PAR_REQUIRED},
  619. {"-sig", NULL, PAR_INVALID},
  620. {"-unsigned", NULL, PAR_INVALID},
  621. {"-review_enclave", NULL, PAR_INVALID},
  622. {"-dumpfile", NULL, PAR_OPTIONAL}};
  623. param_struct_t params_gendata[] = {
  624. {"-enclave", NULL, PAR_REQUIRED},
  625. {"-config", NULL, PAR_OPTIONAL},
  626. {"-key", NULL, PAR_INVALID},
  627. {"-out", NULL, PAR_REQUIRED},
  628. {"-sig", NULL, PAR_INVALID},
  629. {"-unsigned", NULL, PAR_INVALID},
  630. {"-review_enclave", NULL, PAR_INVALID},
  631. {"-dumpfile", NULL, PAR_INVALID}};
  632. param_struct_t params_catsig[] = {
  633. {"-enclave", NULL, PAR_REQUIRED},
  634. {"-config", NULL, PAR_OPTIONAL},
  635. {"-key", NULL, PAR_REQUIRED},
  636. {"-out", NULL, PAR_REQUIRED},
  637. {"-sig", NULL, PAR_REQUIRED},
  638. {"-unsigned", NULL, PAR_REQUIRED},
  639. {"-review_enclave", NULL, PAR_INVALID},
  640. {"-dumpfile", NULL, PAR_OPTIONAL}};
  641. param_struct_t params_compare[] = {
  642. {"-enclave", NULL, PAR_REQUIRED},
  643. {"-config", NULL, PAR_OPTIONAL},
  644. {"-key", NULL, PAR_INVALID},
  645. {"-out", NULL, PAR_INVALID},
  646. {"-sig", NULL, PAR_INVALID},
  647. {"-unsigned", NULL, PAR_REQUIRED},
  648. {"-review_enclave", NULL, PAR_REQUIRED},
  649. {"-dumpfile", NULL, PAR_INVALID}};
  650. param_struct_t params_dump[] = {
  651. {"-enclave", NULL, PAR_REQUIRED},
  652. {"-config", NULL, PAR_INVALID},
  653. {"-key", NULL, PAR_INVALID},
  654. {"-out", NULL, PAR_INVALID},
  655. {"-sig", NULL, PAR_INVALID},
  656. {"-unsigned", NULL, PAR_INVALID},
  657. {"-review_enclave", NULL, PAR_INVALID},
  658. {"-dumpfile", NULL, PAR_REQUIRED}};
  659. const char *mode_m[] ={"sign", "gendata","catsig", "compare", "dump"};
  660. param_struct_t *params[] = {params_sign, params_gendata, params_catsig, params_compare, params_dump};
  661. unsigned int tempidx=0;
  662. for(; tempidx<sizeof(mode_m)/sizeof(mode_m[0]); tempidx++)
  663. {
  664. if(!STRCMP(mode_m[tempidx], argv[1]))//match
  665. {
  666. break;
  667. }
  668. }
  669. unsigned int tempmode = tempidx;
  670. if(tempmode>=sizeof(mode_m)/sizeof(mode_m[0]))
  671. {
  672. se_trace(SE_TRACE_ERROR, UNREC_CMD_ERROR, argv[1]);
  673. return false;
  674. }
  675. unsigned int err_idx = 2;
  676. for(; err_idx < argc; err_idx++)
  677. {
  678. if(!STRCMP(argv[err_idx], "-ignore-rel-error"))
  679. break;
  680. }
  681. unsigned int params_count = (unsigned)(sizeof(params_sign)/sizeof(params_sign[0]));
  682. unsigned int params_count_min = 0;
  683. unsigned int params_count_max =0;
  684. for(unsigned int i=0; i< params_count; i++)
  685. {
  686. params_count_max ++;
  687. if(params[tempmode][i].flag == PAR_REQUIRED)
  688. params_count_min ++;
  689. }
  690. unsigned int additional_param = 2;
  691. if(err_idx != argc)
  692. additional_param++;
  693. if(argc<params_count_min * 2 + additional_param)
  694. return false;
  695. if(argc>params_count_max * 2 + additional_param)
  696. return false;
  697. for(unsigned int i=2; i<argc; i=i+2)
  698. {
  699. if(i == err_idx)
  700. {
  701. i++;
  702. continue;
  703. }
  704. unsigned int j=0;
  705. for(; j<params_count; j++)
  706. {
  707. if(STRCMP(argv[i], params[tempmode][j].name)==0) //match
  708. {
  709. if((i<argc-1)&&(STRNCMP(argv[i+1],"-", 1))) // assuming pathname doesn't contain "-"
  710. {
  711. if(params[tempmode][j].value != NULL)
  712. {
  713. se_trace(SE_TRACE_ERROR, REPEAT_OPTION_ERROR, params[tempmode][j].name);
  714. return false;
  715. }
  716. params[tempmode][j].value = argv[i+1];
  717. break;
  718. }
  719. else //didn't match: 1) no path parameter behind option parameter 2) parameters format error.
  720. {
  721. se_trace(SE_TRACE_ERROR, INVALID_FILE_NAME_ERROR, params[tempmode][j].name);
  722. return false;
  723. }
  724. }
  725. }
  726. if(j>=params_count_max)
  727. {
  728. return false;
  729. }
  730. }
  731. for(unsigned int i = 0; i < params_count; i ++)
  732. {
  733. if(params[tempmode][i].flag == PAR_REQUIRED && params[tempmode][i].value == NULL)
  734. {
  735. se_trace(SE_TRACE_ERROR, LACK_REQUIRED_OPTION_ERROR, params[tempmode][i].name, mode_m[tempmode]);
  736. return false;
  737. }
  738. if(params[tempmode][i].flag == PAR_INVALID && params[tempmode][i].value != NULL)
  739. {
  740. se_trace(SE_TRACE_ERROR, GIVE_INVALID_OPTION_ERROR, params[tempmode][i].name, mode_m[tempmode]);
  741. return false;
  742. }
  743. }
  744. for(unsigned int i = 0; i < params_count; i++)
  745. {
  746. path[i] = params[tempmode][i].value;
  747. }
  748. *mode = tempmode;
  749. if(err_idx != argc)
  750. *ignore_rel_error = true;
  751. return true;
  752. }
  753. static bool fill_meta_without_signature(const IppsRSAPublicKeyState *pub_key, const char **path, const uint8_t *enclave_hash,
  754. const xml_parameter_t *para, metadata_t *metadata, bin_fmt_t bf)
  755. {
  756. assert(path && enclave_hash && para && metadata);
  757. if(false == fill_enclave_css(pub_key, para, enclave_hash, path, &metadata->enclave_css, bf))
  758. {
  759. return false;
  760. }
  761. set_meta_attributes(metadata);
  762. return true;
  763. }
  764. //generate_output:
  765. // To generate the final output file
  766. // SIGN- need to fill the enclave_css_t(key part included), sign the header and body and
  767. // update the metadata in the out file
  768. // GENDATA- need to fill the enclave_css_t(key part excluded), get the body and header,
  769. // and then write the whole out file with body+header+hash
  770. // CATSIG- need to fill the enclave_css_t(include key), read the signature from the sigpath,
  771. // and then update the metadata in the out file
  772. static bool generate_output(int mode, int ktype, const uint8_t *enclave_hash, const xml_parameter_t *para, const rsa_params_t *rsa, metadata_t *metadata,
  773. const char **path, bin_fmt_t bf, uint64_t meta_offset)
  774. {
  775. assert(enclave_hash != NULL && para != NULL && metadata != NULL && path != NULL && rsa != NULL);
  776. IppsRSAPrivateKeyState *pri_key1 = NULL;
  777. IppsRSAPublicKeyState *pub_key = NULL;
  778. int validate_result = IS_INVALID_KEY;
  779. IppStatus error_code = ippStsNoErr;
  780. switch(mode)
  781. {
  782. case SIGN:
  783. {
  784. if(ktype != PRIVATE_KEY)
  785. {
  786. se_trace(SE_TRACE_ERROR, LACK_PRI_KEY_ERROR);
  787. return false;
  788. }
  789. error_code = create_validate_rsa_key_pair(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, rsa->n, rsa->d, rsa->e,
  790. rsa->p, rsa->q, rsa->dmp1, rsa->dmq1, rsa->iqmp, &pri_key1, &pub_key, &validate_result);
  791. if(error_code != ippStsNoErr || validate_result != IS_VALID_KEY)
  792. {
  793. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  794. secure_free_rsa_pri1_key(N_SIZE_IN_BYTES, D_SIZE_IN_BYTES, pri_key1);
  795. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  796. return false;
  797. }
  798. if(false == fill_meta_without_signature(pub_key, path, enclave_hash, para, metadata, bf))
  799. {
  800. secure_free_rsa_pri1_key(N_SIZE_IN_BYTES, D_SIZE_IN_BYTES, pri_key1);
  801. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  802. return false;
  803. }
  804. if(false == create_signature(pri_key1, NULL, &(metadata->enclave_css)))
  805. {
  806. secure_free_rsa_pri1_key(N_SIZE_IN_BYTES, D_SIZE_IN_BYTES, pri_key1);
  807. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  808. return false;
  809. }
  810. secure_free_rsa_pri1_key(N_SIZE_IN_BYTES, D_SIZE_IN_BYTES, pri_key1);
  811. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  812. if(false == update_metadata(path[OUTPUT], metadata, meta_offset))
  813. {
  814. return false;
  815. }
  816. break;
  817. }
  818. case GENDATA:
  819. {
  820. if(false == fill_meta_without_signature(NULL, path, enclave_hash, para, metadata, bf))
  821. {
  822. return false;
  823. }
  824. if(false == gen_enclave_signing_file(&(metadata->enclave_css), path[OUTPUT]))
  825. {
  826. return false;
  827. }
  828. break;
  829. }
  830. case CATSIG:
  831. {
  832. if(ktype != PUBLIC_KEY)
  833. {
  834. se_trace(SE_TRACE_ERROR, LACK_PUB_KEY_ERROR);
  835. return false;
  836. }
  837. if(create_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, rsa->n, rsa->e, &pub_key) != ippStsNoErr)
  838. {
  839. se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR);
  840. return false;
  841. }
  842. if(false == fill_meta_without_signature(pub_key, path, enclave_hash, para, metadata, bf))
  843. {
  844. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  845. return false;
  846. }
  847. secure_free_rsa_pub_key(N_SIZE_IN_BYTES, E_SIZE_IN_BYTES, pub_key);
  848. if(false == create_signature(NULL, path[SIG], &(metadata->enclave_css)))
  849. {
  850. return false;
  851. }
  852. if(false == update_metadata(path[OUTPUT], metadata, meta_offset))
  853. {
  854. return false;
  855. }
  856. break;
  857. }
  858. default:
  859. {
  860. return false;
  861. }
  862. }
  863. return true;
  864. }
  865. //compare two enclaves
  866. static bool compare_enclave(const char **path, const xml_parameter_t *para)
  867. {
  868. assert(path != NULL && para != NULL);
  869. bool res = false;
  870. int ret = SGX_SUCCESS;
  871. sgx_status_t status1 = SGX_SUCCESS, status2 = SGX_SUCCESS;
  872. uint32_t file_size1 =0 , file_size2 = 0;
  873. size_t file_size = 0;
  874. bin_fmt_t bin_fmt1 = BF_UNKNOWN, bin_fmt2 = BF_UNKNOWN;
  875. uint8_t enclave_hash[SGX_HASH_SIZE] = {0};
  876. uint8_t *buf = NULL;
  877. uint64_t quota = 0;
  878. CMetadata *meta = NULL;
  879. metadata_t metadata;
  880. enclave_diff_info_t enclave_diff_info1, enclave_diff_info2;
  881. enclave_css_t enclave_css;
  882. memset(&enclave_css, 0, sizeof(enclave_css_t));
  883. memset(&enclave_diff_info1, 0, sizeof(enclave_diff_info_t));
  884. memset(&enclave_diff_info2, 0, sizeof(enclave_diff_info_t));
  885. memset(&metadata, 0, sizeof(metadata_t));
  886. se_file_handle_t fh1 = open_file(path[DLL]);
  887. if (fh1 == THE_INVALID_HANDLE)
  888. {
  889. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, path[DLL]);
  890. return false;
  891. }
  892. se_file_handle_t fh2 = open_file(path[REVIEW_ENCLAVE]);
  893. if (fh2 == THE_INVALID_HANDLE)
  894. {
  895. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, path[REVIEW_ENCLAVE]);
  896. close_handle(fh1);
  897. return false;
  898. }
  899. std::unique_ptr<map_handle_t, void (*)(map_handle_t*)> mh1(map_file(fh1, &file_size1), unmap_file);
  900. if (!mh1)
  901. {
  902. close_handle(fh1);
  903. close_handle(fh2);
  904. return false;
  905. }
  906. std::unique_ptr<map_handle_t, void (*)(map_handle_t*)> mh2(map_file(fh2, &file_size2), unmap_file);
  907. if (!mh2)
  908. {
  909. close_handle(fh1);
  910. close_handle(fh2);
  911. return false;
  912. }
  913. //check if file_size is the same
  914. if(file_size1 != file_size2)
  915. {
  916. close_handle(fh1);
  917. close_handle(fh2);
  918. return false;
  919. }
  920. // Parse enclave
  921. std::unique_ptr<BinParser> parser1(binparser::get_parser(mh1->base_addr, (size_t)file_size1));
  922. assert(parser1 != NULL);
  923. std::unique_ptr<BinParser> parser2(binparser::get_parser(mh2->base_addr, (size_t)file_size2));
  924. assert(parser2 != NULL);
  925. status1 = parser1->run_parser();
  926. if (status1 != SGX_SUCCESS)
  927. {
  928. goto clear_return;
  929. }
  930. status2 = parser2->run_parser();
  931. if (status2 != SGX_SUCCESS)
  932. {
  933. goto clear_return;
  934. }
  935. // Collect enclave info
  936. bin_fmt1 = parser1->get_bin_format();
  937. bin_fmt2 = parser2->get_bin_format();
  938. //two enclave should have same format
  939. if(bin_fmt1 != bin_fmt2)
  940. {
  941. goto clear_return;
  942. }
  943. //modify some info of enclave: timestamp etc.
  944. status1 = parser1->get_info(&enclave_diff_info1);
  945. if(status1 != SGX_SUCCESS)
  946. {
  947. goto clear_return;
  948. }
  949. status2 = parser2->get_info(&enclave_diff_info2);
  950. if(status2 != SGX_SUCCESS)
  951. {
  952. goto clear_return;
  953. }
  954. status2 = parser2->modify_info(&enclave_diff_info1);
  955. if(status2 != SGX_SUCCESS)
  956. {
  957. goto clear_return;
  958. }
  959. //get enclave hash from unsigned file
  960. file_size = get_file_size(path[UNSIGNED]);
  961. if (file_size != sizeof(enclave_css.header) + sizeof(enclave_css.body) &&
  962. file_size != sizeof(enclave_css.header) + sizeof(enclave_css.body) + sizeof(enclave_css.key))
  963. {
  964. goto clear_return;
  965. }
  966. buf = (uint8_t *)malloc(file_size);
  967. if (buf == NULL)
  968. {
  969. goto clear_return;
  970. }
  971. memset(buf, 0, file_size);
  972. if(read_file_to_buf(path[UNSIGNED], buf, file_size) == false)
  973. {
  974. free(buf);
  975. goto clear_return;
  976. }
  977. memcpy_s(&enclave_css.header, sizeof(enclave_css.header), buf, sizeof(enclave_css.header));
  978. memcpy_s(&enclave_css.body, sizeof(enclave_css.body), buf + (file_size - sizeof(enclave_css.body)), sizeof(enclave_css.body));
  979. free(buf);
  980. // Load enclave to get enclave hash
  981. meta = new CMetadata(&metadata, parser2.get());
  982. if(meta->build_metadata(para) == false)
  983. {
  984. delete meta;
  985. goto clear_return;
  986. }
  987. delete meta;
  988. ret = load_enclave(parser2.release(), &metadata);
  989. if(ret != SGX_SUCCESS)
  990. {
  991. goto clear_return;
  992. }
  993. ret = dynamic_cast<EnclaveCreatorST*>(get_enclave_creator())->get_enclave_info(enclave_hash, SGX_HASH_SIZE, &quota);
  994. if(ret != SGX_SUCCESS)
  995. {
  996. goto clear_return;
  997. }
  998. //make path[UNSIGNED] = NULL, so fill_meta_without_signature won't treat it as catsig
  999. path[UNSIGNED] = NULL;
  1000. if(false == fill_meta_without_signature(NULL, path, enclave_hash, para, &metadata, bin_fmt2))
  1001. {
  1002. goto clear_return;
  1003. }
  1004. //compare
  1005. metadata.enclave_css.header.date = 0;
  1006. enclave_css.header.date = 0;
  1007. if(memcmp(&metadata.enclave_css.header, &enclave_css.header, sizeof(enclave_css.header)) != 0)
  1008. {
  1009. goto clear_return;
  1010. }
  1011. if(memcmp(&metadata.enclave_css.body, &enclave_css.body, sizeof(enclave_css.body)) != 0)
  1012. {
  1013. goto clear_return;
  1014. }
  1015. res = true;
  1016. clear_return:
  1017. close_handle(fh1);
  1018. close_handle(fh2);
  1019. return res;
  1020. }
  1021. static bool dump_enclave_metadata(const char *enclave_path, const char *dumpfile_path)
  1022. {
  1023. assert(enclave_path != NULL && dumpfile_path != NULL);
  1024. uint64_t meta_offset = 0;
  1025. bin_fmt_t bin_fmt = BF_UNKNOWN;
  1026. uint32_t file_size = 0;
  1027. se_file_handle_t fh = open_file(enclave_path);
  1028. if (fh == THE_INVALID_HANDLE)
  1029. {
  1030. se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, enclave_path);
  1031. return false;
  1032. }
  1033. std::unique_ptr<map_handle_t, void (*)(map_handle_t*)> mh(map_file(fh, &file_size), unmap_file);
  1034. if (!mh)
  1035. {
  1036. close_handle(fh);
  1037. return false;
  1038. }
  1039. // Parse enclave
  1040. std::unique_ptr<BinParser> parser(binparser::get_parser(mh->base_addr, (size_t)file_size));
  1041. assert(parser != NULL);
  1042. sgx_status_t status = parser->run_parser();
  1043. if (status != SGX_SUCCESS)
  1044. {
  1045. se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR);
  1046. close_handle(fh);
  1047. return false;
  1048. }
  1049. // Collect enclave info
  1050. if(get_enclave_info(parser.get(), &bin_fmt, &meta_offset, true) == false)
  1051. {
  1052. close_handle(fh);
  1053. return false;
  1054. }
  1055. const metadata_t *metadata = GET_PTR(metadata_t, mh->base_addr, meta_offset);
  1056. if(print_metadata(dumpfile_path, metadata) == false)
  1057. {
  1058. close_handle(fh);
  1059. remove(dumpfile_path);
  1060. return false;
  1061. }
  1062. close_handle(fh);
  1063. return true;
  1064. }
  1065. int main(int argc, char* argv[])
  1066. {
  1067. xml_parameter_t parameter[] = {{"ProdID", 0xFFFF, 0, 0, 0},
  1068. {"ISVSVN", 0xFFFF, 0, 0, 0},
  1069. {"ReleaseType", 1, 0, 0, 0},
  1070. {"IntelSigned", 1, 0, 0, 0},
  1071. {"ProvisionKey",1,0,0,0},
  1072. {"LaunchKey",1,0,0,0},
  1073. {"DisableDebug",1,0,0,0},
  1074. {"HW", 0x10,0,0,0},
  1075. {"TCSNum",0xFFFFFFFF,TCS_NUM_MIN,1,0},
  1076. {"TCSPolicy",TCS_POLICY_UNBIND,TCS_POLICY_BIND,TCS_POLICY_UNBIND,0},
  1077. {"StackMaxSize",0x1FFFFFFFFF,STACK_SIZE_MIN,0x40000,0},
  1078. {"HeapMaxSize",0x1FFFFFFFFF,HEAP_SIZE_MIN,0x100000,0},
  1079. {"MiscSelect", 0xFFFFFFFF, 0, DEFAULT_MISC_SELECT, 0},
  1080. {"MiscMask", 0xFFFFFFFF, 0, DEFAULT_MISC_MASK, 0}};
  1081. const char *path[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  1082. uint8_t enclave_hash[SGX_HASH_SIZE] = {0};
  1083. metadata_t metadata;
  1084. int res = -1, mode = -1;
  1085. int key_type = UNIDENTIFIABLE_KEY; //indicate the type of the input key file
  1086. size_t parameter_count = sizeof(parameter)/sizeof(parameter[0]);
  1087. bin_fmt_t bin_fmt = BF_UNKNOWN;
  1088. uint64_t meta_offset = 0;
  1089. bool ignore_rel_error = false;
  1090. rsa_params_t rsa;
  1091. memset(&rsa, 0, sizeof(rsa));
  1092. memset(&metadata, 0, sizeof(metadata));
  1093. //Parse command line
  1094. if(cmdline_parse(argc, argv, &mode, path, &ignore_rel_error) == false)
  1095. {
  1096. se_trace(SE_TRACE_ERROR, USAGE_STRING);
  1097. goto clear_return;
  1098. }
  1099. if(mode == -1) // User only wants to get the help info
  1100. {
  1101. return 0;
  1102. }
  1103. else if(mode == COMPARE)
  1104. {
  1105. //compare two enclaves
  1106. //Parse the xml file to get the metadata
  1107. if(parse_metadata_file(path[XML], parameter, (int)parameter_count) == false)
  1108. {
  1109. goto clear_return;
  1110. }
  1111. if(compare_enclave(path, parameter) == false)
  1112. {
  1113. se_trace(SE_TRACE_ERROR, "The two enclaves are not matched\n");
  1114. return -1;
  1115. }
  1116. se_trace(SE_TRACE_ERROR, "The two enclaves are matched\n");
  1117. return 0;
  1118. }
  1119. else if(mode == DUMP)
  1120. {
  1121. // dump metadata info
  1122. if(dump_enclave_metadata(path[DLL], path[DUMPFILE]) == false)
  1123. {
  1124. se_trace(SE_TRACE_ERROR, DUMP_METADATA_ERROR, path[DUMPFILE]);
  1125. return -1;
  1126. }
  1127. else
  1128. {
  1129. se_trace(SE_TRACE_ERROR, SUCCESS_EXIT);
  1130. return 0;
  1131. }
  1132. }
  1133. //Other modes
  1134. //
  1135. //Parse the xml file to get the metadata
  1136. if(parse_metadata_file(path[XML], parameter, (int)parameter_count) == false)
  1137. {
  1138. goto clear_return;
  1139. }
  1140. //Parse the key file
  1141. if(parse_key_file(path[KEY], &rsa, &key_type) == false && key_type != NO_KEY)
  1142. {
  1143. goto clear_return;
  1144. }
  1145. if(copy_file(path[DLL], path[OUTPUT]) == false)
  1146. {
  1147. se_trace(SE_TRACE_ERROR, OVERALL_ERROR);
  1148. goto clear_return;
  1149. }
  1150. if(measure_enclave(enclave_hash, path[OUTPUT], parameter, ignore_rel_error, &metadata, &bin_fmt, &meta_offset) == false)
  1151. {
  1152. se_trace(SE_TRACE_ERROR, OVERALL_ERROR);
  1153. goto clear_return;
  1154. }
  1155. if((generate_output(mode, key_type, enclave_hash, parameter, &rsa, &metadata, path, bin_fmt, meta_offset)) == false)
  1156. {
  1157. se_trace(SE_TRACE_ERROR, OVERALL_ERROR);
  1158. goto clear_return;
  1159. }
  1160. //to verify
  1161. if(mode == SIGN || mode == CATSIG)
  1162. {
  1163. int signature_verified = ippFalse;
  1164. if(verify_signature(&rsa, &(metadata.enclave_css), &signature_verified) == false || signature_verified != ippTrue)
  1165. {
  1166. se_trace(SE_TRACE_ERROR, OVERALL_ERROR);
  1167. goto clear_return;
  1168. }
  1169. }
  1170. if(path[DUMPFILE] != NULL)
  1171. {
  1172. if(print_metadata(path[DUMPFILE], &metadata) == false)
  1173. {
  1174. se_trace(SE_TRACE_ERROR, DUMP_METADATA_ERROR, path[DUMPFILE]);
  1175. goto clear_return;
  1176. }
  1177. }
  1178. se_trace(SE_TRACE_ERROR, SUCCESS_EXIT);
  1179. res = 0;
  1180. clear_return:
  1181. if(res == -1 && path[OUTPUT])
  1182. remove(path[OUTPUT]);
  1183. if(res == -1 && path[DUMPFILE])
  1184. remove(path[DUMPFILE]);
  1185. return res;
  1186. }