sample.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include <string.h>
  2. #include <assert.h>
  3. #include <unistd.h>
  4. #include <pwd.h>
  5. #include <libgen.h>
  6. #include <stdlib.h>
  7. # define MAX_PATH FILENAME_MAX
  8. #include <sgx_urts.h>
  9. #include "sample.h"
  10. #include "$(enclaveName)_u.h"
  11. /* Global EID shared by multiple threads */
  12. sgx_enclave_id_t global_eid = 0;
  13. typedef struct _sgx_errlist_t {
  14. sgx_status_t err;
  15. const char *msg;
  16. const char *sug; /* Suggestion */
  17. } sgx_errlist_t;
  18. /* Error code returned by sgx_create_enclave */
  19. static sgx_errlist_t sgx_errlist[] = {
  20. {
  21. SGX_ERROR_UNEXPECTED,
  22. "Unexpected error occurred.",
  23. NULL
  24. },
  25. {
  26. SGX_ERROR_INVALID_PARAMETER,
  27. "Invalid parameter.",
  28. NULL
  29. },
  30. {
  31. SGX_ERROR_OUT_OF_MEMORY,
  32. "Out of memory.",
  33. NULL
  34. },
  35. {
  36. SGX_ERROR_ENCLAVE_LOST,
  37. "Power transition occurred.",
  38. "Please refer to the sample \"PowerTransition\" for details."
  39. },
  40. {
  41. SGX_ERROR_INVALID_ENCLAVE,
  42. "Invalid enclave image.",
  43. NULL
  44. },
  45. {
  46. SGX_ERROR_INVALID_ENCLAVE_ID,
  47. "Invalid enclave identification.",
  48. NULL
  49. },
  50. {
  51. SGX_ERROR_INVALID_SIGNATURE,
  52. "Invalid enclave signature.",
  53. NULL
  54. },
  55. {
  56. SGX_ERROR_OUT_OF_EPC,
  57. "Out of EPC memory.",
  58. NULL
  59. },
  60. {
  61. SGX_ERROR_NO_DEVICE,
  62. "Invalid Intel(R) SGX device.",
  63. "Please make sure Intel(R) SGX module is enabled in the BIOS, and install Intel(R) SGX driver afterwards."
  64. },
  65. {
  66. SGX_ERROR_MEMORY_MAP_CONFLICT,
  67. "Memory map conflicted.",
  68. NULL
  69. },
  70. {
  71. SGX_ERROR_INVALID_METADATA,
  72. "Invalid enclave metadata.",
  73. NULL
  74. },
  75. {
  76. SGX_ERROR_DEVICE_BUSY,
  77. "Intel(R) SGX device was busy.",
  78. NULL
  79. },
  80. {
  81. SGX_ERROR_INVALID_VERSION,
  82. "Enclave version was invalid.",
  83. NULL
  84. },
  85. {
  86. SGX_ERROR_INVALID_ATTRIBUTE,
  87. "Enclave was not authorized.",
  88. NULL
  89. },
  90. {
  91. SGX_ERROR_ENCLAVE_FILE_ACCESS,
  92. "Can't open enclave file.",
  93. NULL
  94. },
  95. };
  96. /* Check error conditions for loading enclave */
  97. void print_error_message(sgx_status_t ret)
  98. {
  99. size_t idx = 0;
  100. size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];
  101. for (idx = 0; idx < ttl; idx++) {
  102. if(ret == sgx_errlist[idx].err) {
  103. if(NULL != sgx_errlist[idx].sug)
  104. printf("Info: %s\n", sgx_errlist[idx].sug);
  105. printf("Error: %s\n", sgx_errlist[idx].msg);
  106. break;
  107. }
  108. }
  109. if (idx == ttl)
  110. printf("Error code is 0x%X. Please refer to the \"Intel SGX SDK Developer Reference\" for more details.\n", ret);
  111. }
  112. /* Initialize the enclave:
  113. * Step 1: retrive the launch token saved by last transaction
  114. * Step 2: call sgx_create_enclave to initialize an enclave instance
  115. * Step 3: save the launch token if it is updated
  116. */
  117. int initialize_enclave(void)
  118. {
  119. char token_path[MAX_PATH] = {'\0'};
  120. sgx_launch_token_t token = {0};
  121. sgx_status_t ret = SGX_ERROR_UNEXPECTED;
  122. int updated = 0;
  123. /* Step 1: retrive the launch token saved by last transaction */
  124. /* try to get the token saved in $HOME */
  125. const char *home_dir = getpwuid(getuid())->pw_dir;
  126. if (home_dir != NULL &&
  127. (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
  128. /* compose the token path */
  129. strncpy(token_path, home_dir, strlen(home_dir));
  130. strncat(token_path, "/", strlen("/"));
  131. strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
  132. } else {
  133. /* if token path is too long or $HOME is NULL */
  134. strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
  135. }
  136. FILE *fp = fopen(token_path, "rb");
  137. if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
  138. printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
  139. }
  140. printf("token_path: %s\n", token_path);
  141. if (fp != NULL) {
  142. /* read the token from saved file */
  143. size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
  144. if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
  145. /* if token is invalid, clear the buffer */
  146. memset(&token, 0x0, sizeof(sgx_launch_token_t));
  147. printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
  148. }
  149. }
  150. /* Step 2: call sgx_create_enclave to initialize an enclave instance */
  151. /* Debug Support: set 2nd parameter to 1 */
  152. ret = sgx_create_enclave($(ENCLAVENAME)_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
  153. if (ret != SGX_SUCCESS) {
  154. print_error_message(ret);
  155. if (fp != NULL) fclose(fp);
  156. return -1;
  157. }
  158. /* Step 3: save the launch token if it is updated */
  159. if (updated == FALSE || fp == NULL) {
  160. /* if the token is not updated, or file handler is invalid, do not perform saving */
  161. if (fp != NULL) fclose(fp);
  162. return 0;
  163. }
  164. /* reopen the file with write capablity */
  165. fp = freopen(token_path, "wb", fp);
  166. if (fp == NULL) return 0;
  167. size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
  168. if (write_num != sizeof(sgx_launch_token_t))
  169. printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
  170. fclose(fp);
  171. return 0;
  172. }
  173. /* OCall functions */
  174. void ocall_$(enclaveName)_sample(const char *str)
  175. {
  176. /* Proxy/Bridge will check the length and null-terminate
  177. * the input string to prevent buffer overflow.
  178. */
  179. printf("%s", str);
  180. }
  181. /* Application entry */
  182. int SGX_CDECL main(int argc, char *argv[])
  183. {
  184. (void)(argc);
  185. (void)(argv);
  186. /* Changing dir to where the executable is.*/
  187. char absolutePath [MAX_PATH];
  188. char *ptr = NULL;
  189. ptr = realpath(dirname(argv[0]),absolutePath);
  190. if( chdir(absolutePath) != 0)
  191. abort();
  192. /* Initialize the enclave */
  193. if(initialize_enclave() < 0){
  194. return -1;
  195. }
  196. sgx_status_t ret = SGX_ERROR_UNEXPECTED;
  197. int ecall_return = 0;
  198. ret = ecall_$(enclaveName)_sample(global_eid, &ecall_return);
  199. if (ret != SGX_SUCCESS)
  200. abort();
  201. if (ecall_return == 0) {
  202. printf("Application ran with success\n");
  203. }
  204. else
  205. {
  206. printf("Application failed %d \n", ecall_return);
  207. }
  208. sgx_destroy_enclave(global_eid);
  209. return ecall_return;
  210. }