Untrusted.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /* Adapted from sample code SampleEnclave/App/App.cpp in the SGX SDK: */
  2. /*
  3. * Copyright (C) 2011-2021 Intel Corporation. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. * * Neither the name of Intel Corporation nor the names of its
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. */
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <assert.h>
  35. #include <time.h>
  36. # include <unistd.h>
  37. # include <pwd.h>
  38. # define MAX_PATH FILENAME_MAX
  39. #define ENCLAVE_FILENAME "enclave.signed.so"
  40. #include "sgx_error.h"
  41. #include "sgx_urts.h"
  42. #include "sgx_tcrypto.h"
  43. #include "sgx_tseal.h"
  44. #include "Untrusted.hpp"
  45. #include "Enclave_u.h"
  46. /* Global EID shared by multiple threads */
  47. sgx_enclave_id_t global_eid = 0;
  48. typedef struct _sgx_errlist_t {
  49. sgx_status_t err;
  50. const char *msg;
  51. const char *sug; /* Suggestion */
  52. } sgx_errlist_t;
  53. /* Error code returned by sgx_create_enclave */
  54. static sgx_errlist_t sgx_errlist[] = {
  55. {
  56. SGX_ERROR_UNEXPECTED,
  57. "Unexpected error occurred.",
  58. NULL
  59. },
  60. {
  61. SGX_ERROR_INVALID_PARAMETER,
  62. "Invalid parameter.",
  63. NULL
  64. },
  65. {
  66. SGX_ERROR_OUT_OF_MEMORY,
  67. "Out of memory.",
  68. NULL
  69. },
  70. {
  71. SGX_ERROR_ENCLAVE_LOST,
  72. "Power transition occurred.",
  73. "Please refer to the sample \"PowerTransition\" for details."
  74. },
  75. {
  76. SGX_ERROR_INVALID_ENCLAVE,
  77. "Invalid enclave image.",
  78. NULL
  79. },
  80. {
  81. SGX_ERROR_INVALID_ENCLAVE_ID,
  82. "Invalid enclave identification.",
  83. NULL
  84. },
  85. {
  86. SGX_ERROR_INVALID_SIGNATURE,
  87. "Invalid enclave signature.",
  88. NULL
  89. },
  90. {
  91. SGX_ERROR_OUT_OF_EPC,
  92. "Out of EPC memory.",
  93. NULL
  94. },
  95. {
  96. SGX_ERROR_NO_DEVICE,
  97. "Invalid SGX device.",
  98. "Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
  99. },
  100. {
  101. SGX_ERROR_MEMORY_MAP_CONFLICT,
  102. "Memory map conflicted.",
  103. NULL
  104. },
  105. {
  106. SGX_ERROR_INVALID_METADATA,
  107. "Invalid enclave metadata.",
  108. NULL
  109. },
  110. {
  111. SGX_ERROR_DEVICE_BUSY,
  112. "SGX device was busy.",
  113. NULL
  114. },
  115. {
  116. SGX_ERROR_INVALID_VERSION,
  117. "Enclave version was invalid.",
  118. NULL
  119. },
  120. {
  121. SGX_ERROR_INVALID_ATTRIBUTE,
  122. "Enclave was not authorized.",
  123. NULL
  124. },
  125. {
  126. SGX_ERROR_ENCLAVE_FILE_ACCESS,
  127. "Can't open enclave file.",
  128. NULL
  129. },
  130. {
  131. SGX_ERROR_MEMORY_MAP_FAILURE,
  132. "Failed to reserve memory for the enclave.",
  133. NULL
  134. },
  135. };
  136. /* Check error conditions for loading enclave */
  137. void print_error_message(sgx_status_t ret)
  138. {
  139. size_t idx = 0;
  140. size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
  141. for (idx = 0; idx < ttl; idx++) {
  142. if(ret == sgx_errlist[idx].err) {
  143. if(NULL != sgx_errlist[idx].sug)
  144. printf("Info: %s\n", sgx_errlist[idx].sug);
  145. printf("Error: %s\n", sgx_errlist[idx].msg);
  146. break;
  147. }
  148. }
  149. if (idx == ttl)
  150. printf("Error code is 0x%X. Please refer to the \"Intel SGX SDK Developer Reference\" for more details.\n", ret);
  151. }
  152. /* Initialize the enclave:
  153. * Call sgx_create_enclave to initialize an enclave instance
  154. */
  155. int initialize_enclave(void)
  156. {
  157. sgx_status_t ret = SGX_ERROR_UNEXPECTED;
  158. /* Call sgx_create_enclave to initialize an enclave instance */
  159. /* Debug Support: set 2nd parameter to 1 */
  160. ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, NULL, NULL, &global_eid, NULL);
  161. if (ret != SGX_SUCCESS) {
  162. print_error_message(ret);
  163. return -1;
  164. }
  165. return 0;
  166. }
  167. void ocall_print_string(const char *str) {
  168. printf("%s", str);
  169. }
  170. /* Print the given string, prefixed with the current time, and return the
  171. * current time. */
  172. unsigned long ocall_print_string_with_rtclock(const char *str) {
  173. struct timespec tp;
  174. clock_gettime(CLOCK_REALTIME_COARSE, &tp);
  175. unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000;
  176. printf("%lu.%06lu: %s", tp.tv_sec, tp.tv_nsec/1000, str);
  177. return now;
  178. }
  179. /* Print the given string, prefixed with the current time, and return the
  180. * current time. Also print the time difference to the provided time. */
  181. unsigned long ocall_print_string_with_rtclock_diff(const char *str,
  182. unsigned long before) {
  183. struct timespec tp;
  184. clock_gettime(CLOCK_REALTIME_COARSE, &tp);
  185. unsigned long now = tp.tv_sec * 1000000 + tp.tv_nsec/1000;
  186. unsigned long diff = now - before;
  187. printf("%lu.%06lu: (%lu.%06lu) %s", tp.tv_sec, tp.tv_nsec/1000,
  188. diff/1000000, diff%1000000, str);
  189. return now;
  190. }
  191. void ecall_identity_key_new(sgx_ec256_public_t* outpub,
  192. sgx_sealed_data_t* outsealedpriv)
  193. {
  194. ecall_identity_key_new(global_eid, outpub, outsealedpriv);
  195. }
  196. bool ecall_identity_key_load(sgx_ec256_public_t* outpub,
  197. const sgx_sealed_data_t* insealedpriv)
  198. {
  199. bool ret;
  200. ecall_identity_key_load(global_eid, &ret, outpub, insealedpriv);
  201. return ret;
  202. }
  203. bool ecall_config_load(threadid_t nthreads,
  204. struct EnclaveAPIParams *apiparams,
  205. struct EnclaveAPINodeConfig *apinodeconfigs,
  206. nodenum_t num_nodes, nodenum_t my_node_num)
  207. {
  208. bool ret;
  209. ecall_config_load(global_eid, &ret, nthreads, apiparams, apinodeconfigs,
  210. num_nodes, my_node_num);
  211. return ret;
  212. }
  213. void ecall_close()
  214. {
  215. ecall_close(global_eid);
  216. }
  217. bool ecall_comms_start(std::function<void(void)> cb)
  218. {
  219. std::function<void(void)> *p = new std::function<void(void)>;
  220. *p = cb;
  221. bool ret;
  222. ecall_comms_start(global_eid, &ret, p);
  223. return ret;
  224. }
  225. bool ecall_message(nodenum_t node_num, uint32_t message_len)
  226. {
  227. bool ret;
  228. ecall_message(global_eid, &ret, node_num, message_len);
  229. return ret;
  230. }
  231. bool ecall_chunk(nodenum_t node_num, const uint8_t *chunkdata,
  232. uint32_t chunklen)
  233. {
  234. bool ret;
  235. ecall_chunk(global_eid, &ret, node_num, chunkdata, chunklen);
  236. return ret;
  237. }
  238. size_t ecall_precompute_sort(int sizeidx)
  239. {
  240. size_t ret;
  241. ecall_precompute_sort(global_eid, &ret, sizeidx);
  242. return ret;
  243. }
  244. bool ecall_ingest_raw(uint8_t *msgs, uint32_t num_msgs)
  245. {
  246. bool ret;
  247. ecall_ingest_raw(global_eid, &ret, msgs, num_msgs);
  248. return ret;
  249. }
  250. void ecall_routing_proceed(std::function<void(uint32_t)> cb)
  251. {
  252. std::function<void(uint32_t)> *p = new std::function<void(uint32_t)>;
  253. *p = cb;
  254. ecall_routing_proceed(global_eid, p);
  255. }
  256. void ocall_comms_ready(void *cbpointer)
  257. {
  258. std::function<void(void)> *p =
  259. (std::function<void(void)> *)cbpointer;
  260. std::function<void(void)> f = *p;
  261. delete p;
  262. f();
  263. }
  264. void ocall_routing_round_complete(void *cbpointer, uint32_t round_num)
  265. {
  266. std::function<void(uint32_t)> *p =
  267. (std::function<void(uint32_t)> *)cbpointer;
  268. std::function<void(uint32_t)> f = *p;
  269. delete p;
  270. f(round_num);
  271. }
  272. bool ecall_ingest_msgbundle(clientid_t cid, unsigned char *msgbundle,
  273. uint32_t num_msgs)
  274. {
  275. bool ret;
  276. ecall_ingest_msgbundle(global_eid, &ret, cid, msgbundle, num_msgs);
  277. return ret;
  278. }
  279. bool ecall_ingestion_authenticate(clientid_t cid, unsigned char *auth_string)
  280. {
  281. bool ret;
  282. ecall_ingestion_authenticate(global_eid, &ret, cid, auth_string);
  283. return ret;
  284. }
  285. bool ecall_storage_authenticate(clientid_t cid, unsigned char *auth_string)
  286. {
  287. bool ret;
  288. ecall_storage_authenticate(global_eid, &ret, cid, auth_string);
  289. return ret;
  290. }
  291. void ecall_supply_storage_buffers(unsigned char *mailboxes,
  292. uint32_t mailboxes_size, unsigned char *tokens, uint32_t tokens_size)
  293. {
  294. ecall_supply_storage_buffers(global_eid, mailboxes, mailboxes_size,
  295. tokens, tokens_size);
  296. }