aesm_util.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. //#include "memset_s.h"
  32. #include "persistent_storage_info.h"
  33. #include "oal/aesm_persistent_storage.h"
  34. #include "internal/se_stdio.h"
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <sys/stat.h>
  39. #include <unistd.h>
  40. #include <errno.h>
  41. #include <dlfcn.h>
  42. static ae_error_t aesm_get_path(
  43. const char *p_file_name,
  44. char *p_file_path,
  45. size_t buf_size)
  46. {
  47. if(!p_file_name || !p_file_path)
  48. return OAL_PARAMETER_ERROR;
  49. Dl_info dl_info;
  50. if(0==dladdr(__builtin_return_address(0), &dl_info)||
  51. NULL==dl_info.dli_fname)
  52. return AE_FAILURE;
  53. if(strnlen(dl_info.dli_fname,buf_size)>=buf_size)
  54. return OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  55. (void)strncpy(p_file_path,dl_info.dli_fname,buf_size);
  56. char* p_last_slash = strrchr(p_file_path, '/' );
  57. if ( p_last_slash != NULL )
  58. {
  59. p_last_slash++; //increment beyond the last slash
  60. *p_last_slash = '\0'; //null terminate the string
  61. }
  62. else p_file_path[0] = '\0';
  63. if(strnlen(p_file_path,buf_size)+strnlen(p_file_name,buf_size)+sizeof(char)>buf_size)
  64. return OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  65. (void)strncat(p_file_path,p_file_name, strnlen(p_file_name,buf_size));
  66. return AE_SUCCESS;
  67. }
  68. #define AESM_DATA_FOLDER "/var/opt/aesmd/data/"
  69. static ae_error_t aesm_get_data_path(
  70. const char *p_file_name,
  71. char *p_file_path,
  72. size_t buf_size)
  73. {
  74. if(!p_file_name || !p_file_path)
  75. return OAL_PARAMETER_ERROR;
  76. if(strlen(AESM_DATA_FOLDER)+strnlen(p_file_name,buf_size)+sizeof(char)>buf_size)
  77. return OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  78. (void)strcpy(p_file_path, AESM_DATA_FOLDER);
  79. (void)strncat(p_file_path,p_file_name, strnlen(p_file_name,buf_size));
  80. return AE_SUCCESS;
  81. }
  82. static ae_error_t aesm_write_file(
  83. const uint8_t *p_buf,
  84. uint32_t buf_size,
  85. char *p_file_name,
  86. bool is_full_path)
  87. {
  88. ae_error_t ret = AE_FAILURE;
  89. uint32_t write_length = 0;
  90. FILE* p_file = NULL;
  91. char p_full_path[MAX_PATH]= {0};
  92. if(is_full_path){
  93. if(strnlen(p_file_name,MAX_PATH)>=MAX_PATH){
  94. ret = OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  95. goto CLEANUP;
  96. }
  97. (void)strcpy(p_full_path, p_file_name);
  98. }else{
  99. if((ret=aesm_get_data_path(p_file_name, p_full_path, MAX_PATH)) != AE_SUCCESS)
  100. goto CLEANUP;
  101. }
  102. if(NULL == (p_file = fopen(p_full_path, "wb"))){
  103. ret = OAL_FILE_ACCESS_ERROR;
  104. goto CLEANUP;
  105. }
  106. write_length = (uint32_t)fwrite(p_buf, 1, buf_size, p_file);
  107. if(buf_size != write_length){
  108. ret = OAL_FILE_ACCESS_ERROR;
  109. goto CLEANUP;
  110. }
  111. ret = AE_SUCCESS;
  112. CLEANUP:
  113. if(p_file)
  114. fclose(p_file);
  115. return ret;
  116. }
  117. static ae_error_t aesm_read_file(
  118. uint8_t *p_buf,
  119. uint32_t& buf_size,
  120. char *p_file_name,
  121. bool is_full_path)
  122. {
  123. ae_error_t ret = AE_FAILURE;
  124. FILE* p_file = NULL;
  125. char p_full_path[MAX_PATH]= {0};
  126. if(is_full_path){
  127. if(strnlen(p_file_name,MAX_PATH)>=MAX_PATH){
  128. ret = OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  129. goto CLEANUP;
  130. }
  131. (void)strcpy(p_full_path, p_file_name);
  132. }else{
  133. if((ret=aesm_get_data_path(p_file_name, p_full_path, MAX_PATH)) != AE_SUCCESS)
  134. goto CLEANUP;
  135. }
  136. if(NULL == (p_file = fopen(p_full_path, "rb"))){
  137. ret = OAL_FILE_ACCESS_ERROR;
  138. goto CLEANUP;
  139. }
  140. buf_size = (uint32_t)fread(p_buf, 1, buf_size, p_file);
  141. ret = AE_SUCCESS;
  142. CLEANUP:
  143. if(p_file)
  144. fclose(p_file);
  145. return ret;
  146. }
  147. static ae_error_t aesm_remove_file(
  148. const char *p_file_name,
  149. bool is_full_path)
  150. {
  151. ae_error_t ae_err = AE_FAILURE;
  152. char p_full_path[MAX_PATH] = { 0 };
  153. if (is_full_path){
  154. if(strnlen(p_file_name,MAX_PATH)>=MAX_PATH){
  155. ae_err = OAL_PATHNAME_BUFFER_OVERFLOW_ERROR;
  156. goto CLEANUP;
  157. }
  158. (void)strcpy(p_full_path, p_file_name);
  159. }
  160. else{
  161. if ((ae_err = aesm_get_data_path(p_file_name, p_full_path, MAX_PATH)) != AE_SUCCESS)
  162. goto CLEANUP;
  163. }
  164. if (remove(p_full_path)){
  165. if (errno == ENOENT)
  166. ae_err = AE_SUCCESS;
  167. else
  168. ae_err = OAL_FILE_ACCESS_ERROR;
  169. goto CLEANUP;
  170. }
  171. ae_err = AE_SUCCESS;
  172. CLEANUP:
  173. return ae_err;
  174. }
  175. #define UPBOUND_OF_FORMAT 40
  176. ae_error_t aesm_get_pathname(aesm_data_type_t type, aesm_data_id_t id, char *buf, uint32_t buf_size, uint32_t xgid)
  177. {
  178. const persistent_storage_info_t *info = get_persistent_storage_info(id);
  179. int num_bytes = 0;
  180. if(info == NULL)
  181. return OAL_PARAMETER_ERROR;
  182. if(info->type != type)
  183. return OAL_PARAMETER_ERROR;
  184. if(info->type == FT_ENCLAVE_NAME){
  185. char local_info_name[MAX_PATH];
  186. if (xgid != INVALID_EGID){
  187. return AE_FAILURE;
  188. }
  189. if(strnlen(info->name, MAX_PATH)>=MAX_PATH-UPBOUND_OF_FORMAT){
  190. return AE_FAILURE;//info->name is a constant string and the length of it should not be too long so that the defense in depth codition here should never be triggered.
  191. }
  192. num_bytes = snprintf(local_info_name,MAX_PATH, "libsgx_%s.signed.so",info->name);
  193. if(num_bytes<0||num_bytes>=MAX_PATH){
  194. return AE_FAILURE;
  195. }
  196. return aesm_get_path(local_info_name, buf, buf_size);
  197. }else if(info->loc == AESM_LOCATION_DATA){
  198. if (xgid != INVALID_EGID){
  199. return AE_FAILURE;
  200. }
  201. return aesm_get_data_path(info->name, buf, buf_size);
  202. }
  203. else if (info->loc == AESM_LOCATION_MULTI_EXTENDED_EPID_GROUP_DATA){
  204. char name[MAX_PATH];
  205. ae_error_t ae_err;
  206. if (xgid == INVALID_EGID){//INVALID_EGID should not be used for file to support multi extended_epid_group
  207. return AE_FAILURE;
  208. }
  209. if(strnlen(info->name,MAX_PATH)>=MAX_PATH-UPBOUND_OF_FORMAT){
  210. return AE_FAILURE;//defense in depth. info->name is a constant string and its size should be small
  211. }
  212. if ((num_bytes=snprintf(name, MAX_PATH, "%s.%08X", info->name, xgid)) < 0|| num_bytes>=MAX_PATH){
  213. return AE_FAILURE;
  214. }
  215. if ((ae_err = aesm_get_data_path(name, buf, buf_size)) != AE_SUCCESS)
  216. return ae_err;
  217. return AE_SUCCESS;
  218. }else{//info->loc == AESM_LOCATION_EXE_FOLDER
  219. if (xgid != INVALID_EGID){
  220. return AE_FAILURE;
  221. }
  222. return aesm_get_path(info->name, buf, buf_size);
  223. }
  224. }
  225. //alias function for aesm_get_pathname
  226. ae_error_t aesm_get_cpathname(aesm_data_type_t type, aesm_data_id_t id, char *buf, uint32_t buf_size, uint32_t xgid)
  227. {
  228. return aesm_get_pathname(type, id, buf, buf_size, xgid);
  229. }
  230. ae_error_t aesm_query_data_size(aesm_data_type_t type, aesm_data_id_t data_id, uint32_t *p_size, uint32_t xgid)
  231. {
  232. char pathname[MAX_PATH];
  233. ae_error_t ret = AE_SUCCESS;
  234. const persistent_storage_info_t *info = get_persistent_storage_info(data_id);
  235. if(info == NULL)
  236. return OAL_PARAMETER_ERROR;
  237. if(info->access == AESM_FILE_ACCESS_PATH_ONLY)
  238. return OAL_PARAMETER_ERROR;
  239. ret = aesm_get_pathname(type, data_id, pathname, MAX_PATH, xgid);//currently all in file
  240. if(ret != AE_SUCCESS)
  241. return ret;
  242. struct stat stat_info;
  243. if(stat(pathname, &stat_info)!=0){//Maybe file has not been created
  244. *p_size = 0;
  245. return AE_SUCCESS;
  246. }
  247. *p_size = (uint32_t)stat_info.st_size;
  248. return AE_SUCCESS;
  249. }
  250. ae_error_t aesm_read_data(aesm_data_type_t type, aesm_data_id_t data_id, uint8_t *buf, uint32_t *p_size, uint32_t xgid)
  251. {
  252. char pathname[MAX_PATH];
  253. ae_error_t ret = AE_SUCCESS;
  254. const persistent_storage_info_t *info = get_persistent_storage_info(data_id);
  255. if(info == NULL)
  256. return OAL_PARAMETER_ERROR;
  257. if(info->access == AESM_FILE_ACCESS_PATH_ONLY)
  258. return OAL_PARAMETER_ERROR;
  259. ret = aesm_get_pathname(type, data_id, pathname, MAX_PATH, xgid);//currently all in file
  260. if(ret != AE_SUCCESS)
  261. return ret;
  262. if((ret=aesm_read_file(buf, *p_size, pathname, true))!=AE_SUCCESS)
  263. return ret;
  264. return AE_SUCCESS;
  265. }
  266. ae_error_t aesm_write_data(aesm_data_type_t type, aesm_data_id_t data_id, const uint8_t *buf, uint32_t size, uint32_t xgid)
  267. {
  268. char pathname[MAX_PATH];
  269. ae_error_t ret = AE_SUCCESS;
  270. const persistent_storage_info_t *info = get_persistent_storage_info(data_id);
  271. if(info == NULL)
  272. return OAL_PARAMETER_ERROR;
  273. if(info->access != AESM_FILE_ACCESS_ALL)
  274. return OAL_PARAMETER_ERROR;
  275. ret = aesm_get_pathname(type, data_id, pathname, MAX_PATH, xgid);//currently all in file
  276. if(ret != AE_SUCCESS)
  277. return ret;
  278. if((ret=aesm_write_file(buf, size, pathname, true))!=AE_SUCCESS)
  279. return ret;
  280. return AE_SUCCESS;
  281. }
  282. ae_error_t aesm_remove_data(aesm_data_type_t type, aesm_data_id_t data_id, uint32_t xgid)
  283. {
  284. char pathname[MAX_PATH];
  285. ae_error_t ret = AE_SUCCESS;
  286. const persistent_storage_info_t *info = get_persistent_storage_info(data_id);
  287. if (info == NULL)
  288. return OAL_PARAMETER_ERROR;
  289. if (info->access != AESM_FILE_ACCESS_ALL)
  290. return OAL_PARAMETER_ERROR;
  291. ret = aesm_get_pathname(type, data_id, pathname, MAX_PATH, xgid);//currently all in file
  292. if (ret != AE_SUCCESS){
  293. return ret;
  294. }
  295. if ((ret = aesm_remove_file(pathname, true)) != AE_SUCCESS)
  296. return ret;
  297. return AE_SUCCESS;
  298. }