sign_tool.cpp 40 KB

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