sign_tool.cpp 39 KB

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