SgxProtobufLATransforms_Inititator.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include "sgx_eid.h"
  2. #include "error_codes.h"
  3. #include "datatypes.h"
  4. #include "sgx_urts.h"
  5. #include "sgx_dh.h"
  6. // For msg1
  7. #define SGX_TARGET_INFO_RESERVED1_BYTES 4
  8. #define SGX_TARGET_INFO_RESERVED2_BYTES 456
  9. #define SGX_ECP256_KEY_SIZE 32
  10. #define SGX_HASH_SIZE 32 /* SHA256 */
  11. // For msg2
  12. #define SGX_REPORT_DATA_SIZE 64
  13. #define SGX_KEYID_SIZE 32
  14. #define SGX_DH_MAC_SIZE 16
  15. #define SGX_REPORT_BODY_RESERVED1 28
  16. #define SGX_REPORT_BODY_RESERVED2 32
  17. #define SGX_REPORT_BODY_RESERVED3 96
  18. #define SGX_REPORT_BODY_RESERVED4 60
  19. #include <stdio.h>
  20. // For google protobufs and deserialization/serialization
  21. #include "ProtobufLAMessages.h"
  22. #include <google/protobuf/io/coded_stream.h>
  23. #include <google/protobuf/io/zero_copy_stream_impl.h>
  24. using namespace google::protobuf::io;
  25. #include <inttypes.h>
  26. int fit_32_into_uint8_t(google::protobuf::uint32 temp32, uint8_t* temp8)
  27. {
  28. if(temp32 > UINT8_MAX)
  29. return -1;
  30. else
  31. {
  32. // *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure.
  33. *temp8 = (uint8_t)temp32;
  34. return 0;
  35. }
  36. }
  37. int fit_32_into_uint16_t(google::protobuf::uint32 temp32, uint16_t* temp16)
  38. {
  39. if(temp32 > UINT16_MAX)
  40. return -1;
  41. else
  42. {
  43. // *temp8 = *(uint8_t*)&temp32; // Probably works irrespective of endianness but not sure.
  44. *temp16 = (uint16_t)temp32;
  45. return 0;
  46. }
  47. }
  48. int read_protobuf_msg_from_fd(int accept_fd, google::protobuf::MessageLite& message)
  49. {
  50. ZeroCopyInputStream* raw_input;
  51. CodedInputStream* coded_input;
  52. uint32_t size;
  53. CodedInputStream::Limit limit;
  54. raw_input = new FileInputStream(accept_fd);
  55. coded_input = new CodedInputStream(raw_input);
  56. if(!coded_input->ReadVarint32(&size))
  57. {
  58. printf("Error in reading size of msg");
  59. fflush(stdout);
  60. return -1;
  61. }
  62. //printf("size of msg was read to be %" PRIu32 " \n", size);
  63. //fflush(stdout);
  64. limit = coded_input->PushLimit(size);
  65. if(!message.ParseFromCodedStream(coded_input))
  66. {
  67. printf("Error in parsing msg");
  68. fflush(stdout);
  69. coded_input->PopLimit(limit);
  70. return -1;
  71. }
  72. coded_input->PopLimit(limit);
  73. return 0;
  74. }
  75. int write_protobuf_msg_to_fd(int accept_fd, google::protobuf::MessageLite& message)
  76. {
  77. ZeroCopyOutputStream* raw_output = new FileOutputStream(accept_fd);
  78. CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
  79. coded_output->WriteVarint32(message.ByteSize());
  80. if(!message.SerializeToCodedStream(coded_output))
  81. {
  82. printf("SerializeToCodedStream failed");
  83. fflush(stdout);
  84. return -1;
  85. }
  86. // As per this - https://stackoverflow.com/questions/22881876/protocol-buffers-how-to-serialize-and-deserialize-multiple-messages-into-a-file?noredirect=1&lq=1
  87. // TODO: There may be a better way to do this - 1) this happens with every accept now and 2) make it happen on the stack vs heap - destructor will be called on return from this function (main) and the items will then be written out. (We probably don't want that, actually)
  88. delete coded_output;
  89. delete raw_output;
  90. fflush(stdout);
  91. return 0;
  92. }
  93. void encode_ec256_public_key_to_protobuf(protobuf_sgx_ec256_public_t* protobuf_g_a , sgx_ec256_public_t* g_a)
  94. {
  95. printf("\n ec256 public key gx and gy \n");
  96. int counter; google::protobuf::uint32 temp32;
  97. for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
  98. {
  99. temp32 = g_a->gx[counter];
  100. protobuf_g_a->add_gx(temp32);
  101. printf("%d ", temp32);
  102. temp32 = g_a->gy[counter];
  103. protobuf_g_a->add_gy(temp32);
  104. printf("%d ", temp32);
  105. }
  106. printf("\n");
  107. }
  108. void encode_attributes_to_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes)
  109. {
  110. protobuf_attributes->set_flags(attributes->flags); // 64 bit
  111. protobuf_attributes->set_xfrm(attributes->xfrm); // 64 bit
  112. }
  113. void encode_report_to_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report)
  114. {
  115. printf("\n report \n key id \n");
  116. int counter; google::protobuf::uint32 temp32;
  117. for(counter=0;counter<SGX_KEYID_SIZE;counter++)
  118. {
  119. temp32=report->key_id.id[counter];
  120. protobuf_report->add_key_id(temp32);
  121. printf("%d ",temp32);
  122. }
  123. printf("\n mac \n");
  124. for(counter=0;counter<SGX_MAC_SIZE;counter++)
  125. {
  126. temp32=report->mac[counter];
  127. protobuf_report->add_mac(temp32);
  128. printf("%d ", temp32);
  129. }
  130. protobuf_report->mutable_body()->set_misc_select(report->body.misc_select); // 32 bit
  131. protobuf_report->mutable_body()->set_isv_svn(report->body.isv_svn); // 16 bit
  132. protobuf_report->mutable_body()->set_isv_prod_id(report->body.isv_prod_id); // 16 bit
  133. encode_attributes_to_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes));
  134. for(counter=0;counter<SGX_CPUSVN_SIZE;counter++)
  135. {
  136. temp32=report->body.cpu_svn.svn[counter];
  137. protobuf_report->mutable_body()->add_cpu_svn(temp32);
  138. }
  139. for(counter=0;counter<SGX_REPORT_BODY_RESERVED1;counter++)
  140. {
  141. temp32=report->body.reserved1[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
  142. protobuf_report->mutable_body()->add_reserved1(temp32);
  143. }
  144. for(counter=0;counter<SGX_REPORT_BODY_RESERVED2;counter++)
  145. {
  146. temp32=report->body.reserved2[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
  147. protobuf_report->mutable_body()->add_reserved2(temp32);
  148. }
  149. for(counter=0;counter<SGX_REPORT_BODY_RESERVED3;counter++)
  150. {
  151. temp32=report->body.reserved3[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
  152. protobuf_report->mutable_body()->add_reserved3(temp32);
  153. }
  154. for(counter=0;counter<SGX_REPORT_BODY_RESERVED4;counter++)
  155. {
  156. temp32=report->body.reserved4[counter]; // TODO: Could be optimized out - if these are determined to be 0s.
  157. protobuf_report->mutable_body()->add_reserved4(temp32);
  158. }
  159. printf("\nmr enclave\n");
  160. fflush(stdout);
  161. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  162. {
  163. temp32=report->body.mr_enclave.m[counter];
  164. protobuf_report->mutable_body()->add_mr_enclave(temp32);
  165. printf("%x ", temp32);
  166. }
  167. printf("\n mr signer\n"); fflush(stdout);
  168. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  169. {
  170. temp32=report->body.mr_signer.m[counter];
  171. protobuf_report->mutable_body()->add_mr_signer(temp32);
  172. printf("%x ", temp32);
  173. }
  174. for(counter=0;counter<SGX_REPORT_DATA_SIZE;counter++)
  175. {
  176. temp32=report->body.report_data.d[counter];
  177. protobuf_report->mutable_body()->add_report_data(temp32);
  178. }
  179. }
  180. int decode_attributes_from_protobuf(protobuf_sgx_attributes_t* protobuf_attributes, sgx_attributes_t* attributes)
  181. {
  182. attributes->flags = protobuf_attributes->flags();
  183. printf("\n flags %" PRIu64 " \n", attributes->flags);
  184. attributes->xfrm = protobuf_attributes->xfrm();
  185. printf("\n xfrm %" PRIu64 " \n", attributes->xfrm);
  186. return 0;
  187. }
  188. int decode_report_from_protobuf(protobuf_sgx_report_t* protobuf_report, sgx_report_t* report)
  189. {
  190. int counter; google::protobuf::uint32 temp32;
  191. printf("\n----------------------Decoding received msg3 ------------------------\n");
  192. printf("\nreport body keyid\n");
  193. for(counter=0;counter<SGX_KEYID_SIZE;counter++)
  194. {
  195. temp32=protobuf_report->key_id(counter);
  196. if(fit_32_into_uint8_t(temp32, &(report->key_id.id[counter]))!=0)
  197. return -1;
  198. printf("%d ", report->key_id.id[counter]);
  199. }
  200. printf("\nreport mac\n");
  201. for(counter=0;counter<SGX_MAC_SIZE;counter++)
  202. {
  203. temp32=protobuf_report->mac(counter);
  204. if(fit_32_into_uint8_t(temp32, &(report->mac[counter]))!=0)
  205. return -1;
  206. printf("%d ", report->mac[counter]);
  207. }
  208. report->body.misc_select=protobuf_report->mutable_body()->misc_select(); // 32 bit
  209. temp32=protobuf_report->mutable_body()->isv_svn();
  210. if(fit_32_into_uint16_t(temp32, &(report->body.isv_svn))!=0)
  211. return -1;
  212. printf("\nmisc select %d \n", report->body.misc_select);
  213. temp32=protobuf_report->mutable_body()->isv_prod_id();
  214. if(fit_32_into_uint16_t(temp32, &(report->body.isv_prod_id))!=0)
  215. return -1;
  216. printf("\nprod id %d \n", report->body.isv_prod_id);
  217. decode_attributes_from_protobuf(protobuf_report->mutable_body()->mutable_attributes(), &(report->body.attributes));
  218. printf("\n cpu svn\n");
  219. for(counter=0;counter<SGX_CPUSVN_SIZE;counter++)
  220. {
  221. temp32=protobuf_report->mutable_body()->cpu_svn(counter);
  222. if(fit_32_into_uint8_t(temp32, &(report->body.cpu_svn.svn[counter]))!=0)
  223. return -1;
  224. printf("%d ", report->body.cpu_svn.svn[counter]);
  225. }
  226. printf("\n reserved1 \n");
  227. for(counter=0;counter<SGX_REPORT_BODY_RESERVED1;counter++)
  228. {
  229. temp32=protobuf_report->mutable_body()->reserved1(counter);
  230. if(fit_32_into_uint8_t(temp32, &(report->body.reserved1[counter]))!=0)
  231. return -1;
  232. printf("%d ", report->body.reserved1[counter]);
  233. }
  234. printf("\n reserved2 \n");
  235. for(counter=0;counter<SGX_REPORT_BODY_RESERVED2;counter++)
  236. {
  237. temp32=protobuf_report->mutable_body()->reserved2(counter);
  238. if(fit_32_into_uint8_t(temp32, &(report->body.reserved2[counter]))!=0)
  239. return -1;
  240. printf("%d ", report->body.reserved2[counter]);
  241. }
  242. printf("\n reserved3 \n");
  243. for(counter=0;counter<SGX_REPORT_BODY_RESERVED3;counter++)
  244. {
  245. temp32=protobuf_report->mutable_body()->reserved3(counter);
  246. if(fit_32_into_uint8_t(temp32, &(report->body.reserved3[counter]))!=0)
  247. return -1;
  248. printf("%d ", report->body.reserved3[counter]);
  249. }
  250. printf("\n reserved4 \n");
  251. for(counter=0;counter<SGX_REPORT_BODY_RESERVED4;counter++)
  252. {
  253. temp32=protobuf_report->mutable_body()->reserved4(counter);
  254. if(fit_32_into_uint8_t(temp32, &(report->body.reserved4[counter]))!=0)
  255. return -1;
  256. printf("%d ", report->body.reserved4[counter]);
  257. }
  258. printf("\n mrenclave \n");
  259. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  260. {
  261. temp32=protobuf_report->mutable_body()->mr_enclave(counter);
  262. if(fit_32_into_uint8_t(temp32, &(report->body.mr_enclave.m[counter]))!=0)
  263. return -1;
  264. printf("%x ", report->body.mr_enclave.m[counter]);
  265. }
  266. printf("\n mrsigner \n");
  267. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  268. {
  269. temp32=protobuf_report->mutable_body()->mr_signer(counter);
  270. if(fit_32_into_uint8_t(temp32, &(report->body.mr_signer.m[counter]))!=0)
  271. return -1;
  272. printf("%x ", report->body.mr_signer.m[counter]);
  273. }
  274. printf("\n report data\n");
  275. for(counter=0;counter<SGX_REPORT_DATA_SIZE;counter++)
  276. {
  277. temp32=protobuf_report->mutable_body()->report_data(counter);
  278. if(fit_32_into_uint8_t(temp32, &(report->body.report_data.d[counter]))!=0)
  279. return -1;
  280. printf("%d ", report->body.report_data.d[counter]);
  281. }
  282. printf("\n------------------------ end of msg3 --------------------------\n");
  283. return 0;
  284. }
  285. int decode_msg1_from_protobuf( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1, sgx_dh_msg1_t* native_dhmsg1)
  286. {
  287. int counter; google::protobuf::uint32 temp32;// google::protobuf::uint64 temp64;
  288. for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
  289. {
  290. temp32 = protobuf_dhmsg1.mutable_g_a()->gx(counter);
  291. if(fit_32_into_uint8_t(temp32, &(native_dhmsg1->g_a.gx[counter]))!=0)
  292. return -1;
  293. temp32 = protobuf_dhmsg1.mutable_g_a()->gy(counter);
  294. if(fit_32_into_uint8_t(temp32, &(native_dhmsg1->g_a.gy[counter]))!=0)
  295. return -1;
  296. }
  297. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  298. {
  299. temp32 = protobuf_dhmsg1.mutable_target()->mr_enclave(counter);
  300. if(fit_32_into_uint8_t(temp32, &(native_dhmsg1->target.mr_enclave.m[counter]))!=0)
  301. return -1;
  302. }
  303. for(counter=0;counter<SGX_TARGET_INFO_RESERVED1_BYTES;counter++)
  304. {
  305. temp32 = protobuf_dhmsg1.mutable_target()->reserved1(counter);
  306. if(fit_32_into_uint8_t(temp32, &(native_dhmsg1->target.reserved1[counter]))!=0)
  307. return -1;
  308. }
  309. for(counter=0;counter<SGX_TARGET_INFO_RESERVED2_BYTES;counter++)
  310. {
  311. temp32 = protobuf_dhmsg1.mutable_target()->reserved2(counter);
  312. if(fit_32_into_uint8_t(temp32, &(native_dhmsg1->target.reserved2[counter]))!=0)
  313. return -1;
  314. }
  315. native_dhmsg1->target.attributes.flags = protobuf_dhmsg1.mutable_target()->mutable_attributes()->flags();
  316. native_dhmsg1->target.attributes.xfrm = protobuf_dhmsg1.mutable_target()->mutable_attributes()->xfrm();
  317. native_dhmsg1->target.misc_select = protobuf_dhmsg1.mutable_target()->misc_select();
  318. return 0;
  319. }
  320. int decode_msg3_from_protobuf(protobuf_sgx_dh_msg3_t& protobuf_dhmsg3, sgx_dh_msg3_t* native_dhmsg3)
  321. {
  322. int counter; google::protobuf::uint32 temp32;
  323. for(counter=0;counter<SGX_DH_MAC_SIZE;counter++)
  324. {
  325. temp32=protobuf_dhmsg3.cmac(counter);
  326. if(fit_32_into_uint8_t(temp32, &(native_dhmsg3->cmac[counter]))!=0)
  327. return -1;
  328. }
  329. if(decode_report_from_protobuf(protobuf_dhmsg3.mutable_msg3_body()->mutable_report(), &(native_dhmsg3->msg3_body.report))==-1)
  330. return -1;
  331. int max_counter=protobuf_dhmsg3.mutable_msg3_body()->additional_prop_size();
  332. native_dhmsg3->msg3_body.additional_prop_length=max_counter;
  333. // TODO: Need to assign a variable on the heap and then pass it as an argument to this function - set it to null if protobuf_dhmsg3.mutable_msg3_body()->additional_prop_size() is 0
  334. // TODO: And then free it in that function (create_session) when it is done. It is likely that it is 0 in the SGX SDK sample code. And SDK people probably didn't deserialize it - as it may contain a pointer in the general case - to the array of additional_properties.
  335. if(max_counter!=0)
  336. return -1;
  337. return 0;
  338. }
  339. int print_initialized_msg1( protobuf_sgx_dh_msg1_t& protobuf_dhmsg1 /*, sgx_dh_msg1_t* native_dhmsg1*/)
  340. {
  341. int counter;
  342. printf("gx\n");
  343. for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
  344. {
  345. printf("%d ", protobuf_dhmsg1.g_a().gx(counter));
  346. }
  347. printf("\ngy\n");
  348. for(counter=0;counter<SGX_ECP256_KEY_SIZE;counter++)
  349. {
  350. printf("%d ", protobuf_dhmsg1.g_a().gy(counter));
  351. }
  352. printf("\nmrenclave in target\n");
  353. for(counter=0;counter<SGX_HASH_SIZE;counter++)
  354. {
  355. printf("%" PRIu32 " ", protobuf_dhmsg1.target().mr_enclave(counter));
  356. }
  357. printf("\nreserved1 in target\n");
  358. for(counter=0;counter<SGX_TARGET_INFO_RESERVED1_BYTES;counter++)
  359. {
  360. printf("%" PRIu32 " ", protobuf_dhmsg1.target().reserved1(counter));
  361. }
  362. printf("\nreserved2 in target\n");
  363. for(counter=0;counter<SGX_TARGET_INFO_RESERVED2_BYTES;counter++)
  364. {
  365. printf("%" PRIu32 " ", protobuf_dhmsg1.target().reserved2(counter));
  366. }
  367. printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().flags());
  368. printf("\n %" PRIu64 "\n", protobuf_dhmsg1.target().attributes().xfrm());
  369. printf("\n %" PRIu32 "\n", protobuf_dhmsg1.target().misc_select());
  370. return 0;
  371. }
  372. void encode_msg2_to_protobuf( protobuf_sgx_dh_msg2_t& protobuf_dhmsg2, sgx_dh_msg2_t* native_dhmsg2)
  373. {
  374. int counter; google::protobuf::uint32 temp32; //google::protobuf::uint64 temp64;
  375. printf("\n msg2 cmac \n");
  376. for(counter=0;counter<SGX_DH_MAC_SIZE;counter++)
  377. {
  378. temp32=native_dhmsg2->cmac[counter];
  379. protobuf_dhmsg2.add_cmac(temp32);
  380. printf("%d ", temp32);
  381. }
  382. encode_ec256_public_key_to_protobuf(protobuf_dhmsg2.mutable_g_b(), &(native_dhmsg2->g_b));
  383. encode_report_to_protobuf(protobuf_dhmsg2.mutable_report(), &(native_dhmsg2->report));
  384. }
  385. // Got rid of the session ID - figure out its role.
  386. //message1 from the destination enclave through a socket set up before.
  387. // TODO: What do we do about session id?
  388. int session_request_call(int fd, sgx_dh_msg1_t* dh_msg1) //, uint32_t* session_id)
  389. {
  390. protobuf_sgx_dh_msg1_t protobuf_msg1;
  391. printf("reading msg1\n");
  392. fflush(stdout);
  393. if(read_protobuf_msg_from_fd(fd, protobuf_msg1)!=0)
  394. return -1;
  395. print_initialized_msg1(protobuf_msg1);
  396. printf("\n done reading msg1 --------------------\n");
  397. fflush(stdout);
  398. if(decode_msg1_from_protobuf(protobuf_msg1, dh_msg1)!=0)
  399. return -1;
  400. return 0;
  401. }
  402. // Source enclave for exchange_report_ocall (like other ocalls) will be the PHP enclave and the destination enclave will be the decryptor one.
  403. //Makes an sgx_ecall to the destination enclave sends message2 from the source enclave and gets message 3 from the destination enclave
  404. // TODO: What do we do about session id?
  405. int exchange_report_call(int fd, sgx_dh_msg2_t *dh_msg2, sgx_dh_msg3_t *dh_msg3) // , uint32_t* session_id)
  406. {
  407. protobuf_sgx_dh_msg2_t protobuf_msg2;
  408. protobuf_sgx_dh_msg3_t protobuf_msg3;
  409. printf("\n------------------------------------- generating msg2 --------\n");
  410. // Fill protobuf class for dhmsg2 with contents from its native C struct.
  411. encode_msg2_to_protobuf(protobuf_msg2, dh_msg2);
  412. // Write msg length and then write the raw msg.
  413. if(write_protobuf_msg_to_fd(fd, protobuf_msg2)!=0)
  414. return -1;
  415. printf("Wrote msg2 to protobuf ------------------------------------------\n");
  416. fflush(stdout);
  417. // Read from socket dh_msg3
  418. if(read_protobuf_msg_from_fd(fd, protobuf_msg3)!=0)
  419. return -1;
  420. // Decode msg3 from protobuf to native structs
  421. if(decode_msg3_from_protobuf(protobuf_msg3, dh_msg3)!=0)
  422. return -1;
  423. return 0;
  424. }
  425. //Make an sgx_ecall to the destination enclave to close the session
  426. int end_session_ocall()
  427. {
  428. return SGX_SUCCESS;
  429. }