aesm_logic.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  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. #include "QEClass.h"
  32. #include "LEClass.h"
  33. #include "PVEClass.h"
  34. #include "PCEClass.h"
  35. #include "arch.h"
  36. #include "sgx_report.h"
  37. #include "sgx_tseal.h"
  38. #include "epid_pve_type.h"
  39. #include "util.h"
  40. #include <assert.h>
  41. #include <time.h>
  42. #include "oal/oal.h"
  43. #include "oal/aesm_thread.h"
  44. #include "aesm_encode.h"
  45. #include "aesm_epid_blob.h"
  46. #include "aesm_xegd_blob.h"
  47. #include "aesm_logic.h"
  48. #include "pve_logic.h"
  49. #include "qe_logic.h"
  50. #include "platform_info_logic.h"
  51. #include "prov_msg_size.h"
  52. #include "se_sig_rl.h"
  53. #include "se_quote_internal.h"
  54. #include "endpoint_select_info.h"
  55. #include "se_wrapper.h"
  56. #include "ippcp.h"
  57. #include "ippcore.h"
  58. #include <time.h>
  59. #include <string>
  60. #include "ippcp.h"
  61. #include "ippcore.h"
  62. #include "prof_fun.h"
  63. #include "aesm_long_lived_thread.h"
  64. #include "sgx_profile.h"
  65. #include "service_enclave_mrsigner.hh"
  66. #define CHECK_SERVICE_STATUS if (!is_service_running()) return AESM_SERVICE_STOPPED;
  67. #define CHECK_SGX_STATUS if (g_sgx_device_status != SGX_ENABLED) return AESM_SGX_DEVICE_NOT_AVAILABLE;
  68. AESMLogicMutex AESMLogic::_qe_pve_mutex;
  69. AESMLogicMutex AESMLogic::_pse_mutex;
  70. AESMLogicMutex AESMLogic::_le_mutex;
  71. bool AESMLogic::_is_qe_psvn_set;
  72. bool AESMLogic::_is_pse_psvn_set;
  73. bool AESMLogic::_is_pce_psvn_set;
  74. psvn_t AESMLogic::_qe_psvn;
  75. psvn_t AESMLogic::_pce_psvn;
  76. psvn_t AESMLogic::_pse_psvn;
  77. uint32_t AESMLogic::active_extended_epid_group_id;
  78. static ae_error_t read_global_extended_epid_group_id(uint32_t *xeg_id)
  79. {
  80. char path_name[MAX_PATH];
  81. ae_error_t ae_ret = aesm_get_pathname(FT_PERSISTENT_STORAGE, EXTENDED_EPID_GROUP_ID_FID, path_name, MAX_PATH);
  82. if(AE_SUCCESS != ae_ret){
  83. return ae_ret;
  84. }
  85. FILE * f = fopen(path_name, "r");
  86. if( f == NULL){
  87. return OAL_CONFIG_FILE_ERROR;
  88. }
  89. ae_ret = OAL_CONFIG_FILE_ERROR;
  90. if(fscanf(f, "%u", xeg_id)==1){
  91. ae_ret = AE_SUCCESS;
  92. }
  93. fclose(f);
  94. return ae_ret;
  95. }
  96. static ae_error_t set_global_extended_epid_group_id(uint32_t xeg_id)
  97. {
  98. char path_name[MAX_PATH];
  99. ae_error_t ae_ret = aesm_get_pathname(FT_PERSISTENT_STORAGE, EXTENDED_EPID_GROUP_ID_FID, path_name, MAX_PATH);
  100. if(AE_SUCCESS != ae_ret){
  101. return ae_ret;
  102. }
  103. FILE *f = fopen(path_name, "w");
  104. if(f == NULL){
  105. return OAL_CONFIG_FILE_ERROR;
  106. }
  107. ae_ret = OAL_CONFIG_FILE_ERROR;
  108. if(fprintf(f, "%u", xeg_id)>0){
  109. ae_ret = AE_SUCCESS;
  110. }
  111. fclose(f);
  112. return ae_ret;
  113. }
  114. uint32_t AESMLogic::get_active_extended_epid_group_id()
  115. {
  116. return active_extended_epid_group_id;
  117. }
  118. static ae_error_t thread_to_load_qe(aesm_thread_arg_type_t arg)
  119. {
  120. epid_blob_with_cur_psvn_t epid_data;
  121. ae_error_t ae_ret = AE_FAILURE;
  122. uint32_t epid_xeid = 0;
  123. UNUSED(arg);
  124. AESM_DBG_TRACE("start to load qe");
  125. memset(&epid_data, 0, sizeof(epid_data));
  126. AESMLogicLock lock(AESMLogic::_qe_pve_mutex);
  127. if((ae_ret = EPIDBlob::instance().read(epid_data)) == AE_SUCCESS)
  128. {
  129. AESM_DBG_TRACE("EPID blob is read successfully, loading QE ...");
  130. ae_ret = CQEClass::instance().load_enclave();
  131. if(AE_SUCCESS != ae_ret)
  132. {
  133. AESM_DBG_WARN("fail to load QE: %d", ae_ret);
  134. }else{
  135. AESM_DBG_TRACE("QE loaded successfully");
  136. bool resealed = false;
  137. // Just take this chance to reseal EPID blob in case TCB is
  138. // upgraded, return value is ignored and no provisioning is
  139. // triggered.
  140. ae_ret = static_cast<ae_error_t>(CQEClass::instance().verify_blob(
  141. epid_data.trusted_epid_blob,
  142. SGX_TRUSTED_EPID_BLOB_SIZE_PAK,
  143. &resealed));
  144. if(AE_SUCCESS != ae_ret)
  145. {
  146. AESM_DBG_WARN("Failed to verify EPID blob: %d", ae_ret);
  147. // The EPID blob is invalid.
  148. EPIDBlob::instance().remove();
  149. }else{
  150. // Check whether EPID blob XEGDID is aligned with active extended group id if it exists.
  151. if ((EPIDBlob::instance().get_extended_epid_group_id(&epid_xeid) == AE_SUCCESS) && (epid_xeid == AESMLogic::get_active_extended_epid_group_id())) {
  152. AESM_DBG_TRACE("EPID blob Verified");
  153. // XEGDID is aligned
  154. if (true == resealed)
  155. {
  156. AESM_DBG_TRACE("EPID blob is resealed");
  157. if ((ae_ret = EPIDBlob::instance().write(epid_data))
  158. != AE_SUCCESS)
  159. {
  160. AESM_DBG_WARN("Failed to update epid blob: %d", ae_ret);
  161. }
  162. }
  163. }
  164. else { // XEGDID is NOT aligned
  165. AESM_DBG_TRACE("XEGDID mismatch in EPIDBlob, loading PCE ...");
  166. EPIDBlob::instance().remove();
  167. ae_ret = CPCEClass::instance().load_enclave();
  168. if (AE_SUCCESS != ae_ret)
  169. {
  170. AESM_DBG_WARN("fail to load PCE: %d", ae_ret);
  171. }
  172. else{
  173. AESM_DBG_TRACE("PCE loaded successfully");
  174. }
  175. }
  176. }
  177. }
  178. }else{
  179. AESM_DBG_TRACE("Fail to read EPID Blob");
  180. }
  181. AESM_DBG_TRACE("QE Thread finished succ");
  182. return AE_SUCCESS;
  183. }
  184. // Must be called when AESM starts
  185. ae_error_t AESMLogic::service_start()
  186. {
  187. AESM_PROFILE_INIT;
  188. ae_error_t ae_ret = AE_SUCCESS;
  189. AESM_LOG_INIT();
  190. //ippInit();//no ippInit available for c version ipp
  191. AESM_DBG_INFO("aesm service is starting");
  192. //Try to read current active extended epid group id
  193. ae_ret = read_global_extended_epid_group_id(&AESMLogic::active_extended_epid_group_id);
  194. if (AE_SUCCESS != ae_ret){
  195. AESM_DBG_INFO("Fail to read extended epid group id, default extended epid group used");
  196. AESMLogic::active_extended_epid_group_id = DEFAULT_EGID; //use default extended epid group id 0 if it is not available from data file
  197. }
  198. else{
  199. AESM_DBG_INFO("active extended group id %d used", AESMLogic::active_extended_epid_group_id);
  200. }
  201. extended_epid_group_blob_t xegb;
  202. aesm_server_url_infos_t urls;
  203. if (AE_SUCCESS != (XEGDBlob::verify_xegd_by_xgid(active_extended_epid_group_id)) ||
  204. AE_SUCCESS != (EndpointSelectionInfo::verify_file_by_xgid(active_extended_epid_group_id))){//try to load XEGD and URL file to make sure it is valid
  205. AESMLogic::active_extended_epid_group_id = DEFAULT_EGID;//If the active extended epid group id read from data file is not valid, switch to default extended epid group id
  206. }
  207. ae_ret = CLEClass::instance().load_enclave();
  208. if(AE_SUCCESS != ae_ret)
  209. {
  210. AESM_DBG_INFO("fail to load LE: %d", ae_ret);
  211. AESM_LOG_FATAL("%s", g_event_string_table[SGX_EVENT_SERVICE_UNAVAILABLE]);
  212. return ae_ret;
  213. }
  214. aesm_thread_t qe_thread=NULL;
  215. ae_error_t aesm_ret1 = aesm_create_thread(thread_to_load_qe, 0,&qe_thread);
  216. if(AE_SUCCESS != aesm_ret1 ){
  217. AESM_DBG_WARN("Fail to create thread to preload QE:%d",aesm_ret1);
  218. }else{
  219. (void)aesm_free_thread(qe_thread);//release thread handle to free memory
  220. }
  221. start_white_list_thread();
  222. AESM_DBG_TRACE("aesm service is started");
  223. return AE_SUCCESS;
  224. }
  225. void AESMLogic::service_stop()
  226. {
  227. stop_all_long_lived_threads();//waiting for pending threads util timeout
  228. CPVEClass::instance().unload_enclave();
  229. CPCEClass::instance().unload_enclave();
  230. CQEClass::instance().unload_enclave();
  231. CLEClass::instance().unload_enclave();
  232. stop_all_long_lived_threads();
  233. AESM_DBG_INFO("aesm service down");
  234. AESM_LOG_FINI();
  235. AESM_PROFILE_OUTPUT;
  236. }
  237. bool AESMLogic::is_service_running()
  238. {
  239. return true;
  240. }
  241. ae_error_t AESMLogic::save_unverified_white_list(const uint8_t *white_list_cert, uint32_t white_list_cert_size)
  242. {
  243. wl_cert_chain_t old_cert;
  244. const wl_cert_chain_t *p_new_cert = reinterpret_cast<const wl_cert_chain_t *>(white_list_cert);
  245. uint32_t old_cert_size = sizeof(old_cert);
  246. memset(&old_cert, 0, sizeof(old_cert));
  247. if((aesm_read_data(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_TO_BE_VERIFY_FID, reinterpret_cast<uint8_t *>(&old_cert), &old_cert_size) == AE_SUCCESS)
  248. && (old_cert_size == sizeof(old_cert)) && (white_list_cert_size >= sizeof(wl_cert_chain_t)))
  249. {
  250. if(_ntohl(p_new_cert->wl_cert.wl_version) <= _ntohl(old_cert.wl_cert.wl_version))
  251. {
  252. AESM_DBG_WARN("White list version downgraded! current version is %d, new version is %d",
  253. _ntohl(old_cert.wl_cert.wl_version), _ntohl(p_new_cert->wl_cert.wl_version));
  254. return OAL_PARAMETER_ERROR; // OAL_PARAMETER_ERROR used here is to indicate the white list is incorrect
  255. }
  256. }
  257. return aesm_write_data(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_TO_BE_VERIFY_FID, white_list_cert, white_list_cert_size);
  258. }
  259. aesm_error_t AESMLogic::white_list_register(
  260. const uint8_t *white_list_cert, uint32_t white_list_cert_size)
  261. {
  262. AESM_DBG_INFO("enter function");
  263. CHECK_SERVICE_STATUS;
  264. AESMLogicLock lock(_le_mutex);
  265. CHECK_SERVICE_STATUS;
  266. ae_error_t ret_le = AE_SUCCESS;
  267. if (NULL == white_list_cert||0==white_list_cert_size){
  268. AESM_DBG_TRACE("Invalid parameter");
  269. return AESM_PARAMETER_ERROR;
  270. }
  271. ae_error_t ae_ret = CLEClass::instance().load_enclave();
  272. if(ae_ret == AE_SERVER_NOT_AVAILABLE)
  273. {
  274. AESM_DBG_WARN("LE not loaded due to AE_SERVER_NOT_AVAILABLE, possible SGX Env Not Ready");
  275. ret_le = save_unverified_white_list(white_list_cert, white_list_cert_size);
  276. }
  277. else if(AE_FAILED(ae_ret))
  278. {
  279. AESM_DBG_ERROR("LE not loaded:%d", ae_ret);
  280. return AESM_UNEXPECTED_ERROR;
  281. }else{
  282. ret_le = static_cast<ae_error_t>(CLEClass::instance().white_list_register(
  283. white_list_cert, white_list_cert_size));
  284. }
  285. switch (ret_le)
  286. {
  287. case AE_SUCCESS:
  288. return AESM_SUCCESS;
  289. case LE_INVALID_PARAMETER:
  290. AESM_DBG_TRACE("Invalid parameter");
  291. return AESM_PARAMETER_ERROR;
  292. case LE_INVALID_ATTRIBUTE:
  293. AESM_DBG_TRACE("Launch token error");
  294. return AESM_GET_LICENSETOKEN_ERROR;
  295. default:
  296. AESM_DBG_WARN("unexpeted error %d", ret_le);
  297. return AESM_UNEXPECTED_ERROR;
  298. }
  299. }
  300. aesm_error_t AESMLogic::get_launch_token(
  301. const uint8_t * mrenclave, uint32_t mrenclave_size,
  302. const uint8_t *public_key, uint32_t public_key_size,
  303. const uint8_t *se_attributes, uint32_t se_attributes_size,
  304. uint8_t * lictoken, uint32_t lictoken_size)
  305. {
  306. AESM_DBG_INFO("enter function");
  307. CHECK_SERVICE_STATUS;
  308. AESMLogicLock lock(_le_mutex);
  309. CHECK_SERVICE_STATUS;
  310. ae_error_t ret_le = AE_SUCCESS;
  311. if (NULL == mrenclave ||
  312. NULL == public_key ||
  313. NULL == se_attributes ||
  314. NULL == lictoken)
  315. {
  316. //sizes are checked in CLEClass::get_launch_token()
  317. AESM_DBG_TRACE("Invalid parameter");
  318. return AESM_PARAMETER_ERROR;
  319. }
  320. ae_error_t ae_ret = CLEClass::instance().load_enclave();
  321. if(ae_ret == AESM_AE_NO_DEVICE)
  322. {
  323. AESM_LOG_ERROR("%s", g_event_string_table[SGX_EVENT_SERVICE_UNAVAILABLE]);
  324. AESM_DBG_FATAL("LE not loaded due to AE_SERVER_NOT_AVAILABLE, possible SGX Env Not Ready");
  325. return AESM_NO_DEVICE_ERROR;
  326. }
  327. else if(ae_ret == AESM_AE_OUT_OF_EPC)
  328. {
  329. AESM_DBG_WARN("LE not loaded due to out of EPC", ae_ret);
  330. return AESM_OUT_OF_EPC;
  331. }
  332. else if(AE_FAILED(ae_ret))
  333. {
  334. AESM_DBG_ERROR("LE not loaded:%d", ae_ret);
  335. return AESM_SERVICE_UNAVAILABLE;
  336. }
  337. ret_le = static_cast<ae_error_t>(CLEClass::instance().get_launch_token(
  338. const_cast<uint8_t *>(mrenclave), mrenclave_size,
  339. const_cast<uint8_t *>(public_key), public_key_size,
  340. const_cast<uint8_t *>(se_attributes), se_attributes_size,
  341. lictoken, lictoken_size));
  342. switch (ret_le)
  343. {
  344. case AE_SUCCESS:
  345. return AESM_SUCCESS;
  346. case LE_INVALID_PARAMETER:
  347. AESM_DBG_TRACE("Invalid parameter");
  348. return AESM_PARAMETER_ERROR;
  349. case LE_INVALID_ATTRIBUTE:
  350. case LE_INVALID_PRIVILEGE_ERROR:
  351. AESM_DBG_TRACE("Launch token error");
  352. return AESM_GET_LICENSETOKEN_ERROR;
  353. case LE_WHITELIST_UNINITIALIZED_ERROR:
  354. AESM_DBG_TRACE("LE whitelist uninitialized error");
  355. return AESM_UNEXPECTED_ERROR;
  356. default:
  357. AESM_DBG_WARN("unexpeted error %d", ret_le);
  358. return AESM_UNEXPECTED_ERROR;
  359. }
  360. }
  361. /* This function will be called outside aesm(from urts_internal) */
  362. extern "C" sgx_status_t get_launch_token(const enclave_css_t* signature,
  363. const sgx_attributes_t* attribute,
  364. sgx_launch_token_t* launch_token)
  365. {
  366. AESM_DBG_INFO("enter function");
  367. return AESMLogic::get_launch_token(signature, attribute, launch_token);
  368. }
  369. ae_error_t AESMLogic::get_qe_isv_svn(uint16_t& isv_svn)
  370. {
  371. if(!_is_qe_psvn_set){
  372. ae_error_t ae_err = CQEClass::instance().load_enclave();
  373. if(AE_SUCCESS != ae_err){
  374. AESM_DBG_ERROR("Fail to load QE Enclave:%d",ae_err);
  375. return ae_err;
  376. }
  377. }
  378. assert(_is_qe_psvn_set);
  379. if(0!=memcpy_s(&isv_svn, sizeof(isv_svn), &_qe_psvn.isv_svn, sizeof(_qe_psvn.isv_svn))){
  380. AESM_DBG_ERROR("memcpy failed");
  381. return AE_FAILURE;
  382. }
  383. return AE_SUCCESS;
  384. }
  385. ae_error_t AESMLogic::get_pce_isv_svn(uint16_t& isv_svn)
  386. {
  387. if(!_is_pce_psvn_set){
  388. ae_error_t ae_err = CPCEClass::instance().load_enclave();
  389. if(AE_SUCCESS != ae_err){
  390. AESM_DBG_ERROR("Fail to load PCE Enclave:%d",ae_err);
  391. return ae_err;
  392. }
  393. }
  394. assert(_is_pce_psvn_set);
  395. if(0!=memcpy_s(&isv_svn, sizeof(isv_svn), &_pce_psvn.isv_svn, sizeof(_pce_psvn.isv_svn))){
  396. AESM_DBG_ERROR("memcpy failed");
  397. return AE_FAILURE;
  398. }
  399. return AE_SUCCESS;
  400. }
  401. ae_error_t AESMLogic::get_pse_isv_svn(uint16_t& isv_svn)
  402. {
  403. return AE_FAILURE;
  404. }
  405. ae_error_t AESMLogic::get_qe_cpu_svn(sgx_cpu_svn_t& cpu_svn)
  406. {
  407. if(!_is_qe_psvn_set){
  408. ae_error_t ae_err = CQEClass::instance().load_enclave();
  409. if(AE_SUCCESS != ae_err){
  410. AESM_DBG_ERROR("Fail to load QE Enclave:%d",ae_err);
  411. return ae_err;
  412. }
  413. }
  414. assert(_is_qe_psvn_set);
  415. if(0!=memcpy_s(&cpu_svn, sizeof(sgx_cpu_svn_t), &_qe_psvn.cpu_svn, sizeof(_qe_psvn.cpu_svn))){
  416. AESM_DBG_ERROR("memcpy failed");
  417. return AE_FAILURE;
  418. }
  419. return AE_SUCCESS;
  420. }
  421. ae_error_t AESMLogic::set_psvn(uint16_t prod_id, uint16_t isv_svn, sgx_cpu_svn_t cpu_svn, uint32_t mrsigner_index)
  422. {
  423. if(prod_id == QE_PROD_ID){
  424. if(mrsigner_index == AE_MR_SIGNER){
  425. if(_is_qe_psvn_set){
  426. if(0!=memcmp(&_qe_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
  427. 0!=memcmp(&_qe_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
  428. AESM_DBG_ERROR("PSVN unmatched for QE/PVE");
  429. return AE_PSVN_UNMATCHED_ERROR;
  430. }
  431. }else{
  432. if(0!=memcpy_s(&_qe_psvn.isv_svn, sizeof(_qe_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
  433. 0!=memcpy_s(&_qe_psvn.cpu_svn, sizeof(_qe_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
  434. AESM_DBG_ERROR("memcpy failed");
  435. return AE_FAILURE;
  436. }
  437. AESM_DBG_TRACE("get QE or PvE isv_svn=%d",(int)isv_svn);
  438. _is_qe_psvn_set = true;
  439. return AE_SUCCESS;
  440. }
  441. }else if(mrsigner_index==PCE_MR_SIGNER){
  442. if(_is_pce_psvn_set){
  443. if(0!=memcmp(&_pce_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
  444. 0!=memcmp(&_pce_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
  445. AESM_DBG_ERROR("PSVN unmatched for PCE");
  446. return AE_PSVN_UNMATCHED_ERROR;
  447. }
  448. }else{
  449. if(0!=memcpy_s(&_pce_psvn.isv_svn, sizeof(_pce_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
  450. 0!=memcpy_s(&_pce_psvn.cpu_svn, sizeof(_pce_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
  451. AESM_DBG_ERROR("memcpy failed");
  452. return AE_FAILURE;
  453. }
  454. AESM_DBG_TRACE("get PCE isv_svn=%d", (int)isv_svn);
  455. _is_pce_psvn_set = true;
  456. return AE_SUCCESS;
  457. }
  458. }
  459. }else if(prod_id == PSE_PROD_ID){
  460. if(mrsigner_index == AE_MR_SIGNER){
  461. if(_is_pse_psvn_set){
  462. if(0!=memcmp(&_pse_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
  463. 0!=memcmp(&_pse_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
  464. AESM_DBG_ERROR("PSVN unmatched for PSE");
  465. return AE_PSVN_UNMATCHED_ERROR;
  466. }
  467. }else{
  468. if(0!=memcpy_s(&_pse_psvn.isv_svn, sizeof(_pse_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
  469. 0!=memcpy_s(&_pse_psvn.cpu_svn, sizeof(_pse_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
  470. AESM_DBG_ERROR("memcpy failed");
  471. return AE_FAILURE;
  472. }
  473. AESM_DBG_TRACE("get PSE isv_svn=%d", (int)isv_svn);
  474. _is_pse_psvn_set = true;
  475. return AE_SUCCESS;
  476. }
  477. }
  478. }
  479. return AE_SUCCESS;
  480. }
  481. sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature,
  482. const sgx_attributes_t* attribute,
  483. sgx_launch_token_t* launch_token)
  484. {
  485. AESM_DBG_INFO("enter function");
  486. AESMLogicLock lock(_le_mutex);
  487. ae_error_t ret_le = AE_SUCCESS;
  488. uint32_t mrsigner_index = UINT32_MAX;
  489. // load LE to get launch token
  490. if((ret_le=CLEClass::instance().load_enclave()) != AE_SUCCESS)
  491. {
  492. if(ret_le == AESM_AE_NO_DEVICE)
  493. {
  494. AESM_DBG_FATAL("LE not loaded due to no SGX device available, possible SGX Env Not Ready");
  495. return SGX_ERROR_NO_DEVICE;
  496. }
  497. else if(ret_le == AESM_AE_OUT_OF_EPC)
  498. {
  499. AESM_DBG_FATAL("LE not loaded due to out of EPC");
  500. return SGX_ERROR_OUT_OF_EPC;
  501. }
  502. else
  503. {
  504. AESM_DBG_FATAL("fail to load LE:%d",ret_le);
  505. return SGX_ERROR_SERVICE_UNAVAILABLE;
  506. }
  507. }
  508. ret_le = static_cast<ae_error_t>(CLEClass::instance().get_launch_token(
  509. const_cast<uint8_t*>(reinterpret_cast<const uint8_t *>(&signature->body.enclave_hash)),
  510. sizeof(sgx_measurement_t),
  511. const_cast<uint8_t*>(reinterpret_cast<const uint8_t *>(&signature->key.modulus)),
  512. sizeof(signature->key.modulus),
  513. const_cast<uint8_t*>(reinterpret_cast<const uint8_t *>(attribute)),
  514. sizeof(sgx_attributes_t),
  515. reinterpret_cast<uint8_t*>(launch_token),
  516. sizeof(token_t),
  517. &mrsigner_index));
  518. switch (ret_le)
  519. {
  520. case AE_SUCCESS:
  521. break;
  522. case LE_INVALID_PARAMETER:
  523. AESM_DBG_TRACE("Invalid parameter");
  524. return SGX_ERROR_INVALID_PARAMETER;
  525. case LE_INVALID_ATTRIBUTE:
  526. case LE_INVALID_PRIVILEGE_ERROR:
  527. AESM_DBG_TRACE("Launch token error");
  528. return SGX_ERROR_SERVICE_INVALID_PRIVILEGE;
  529. case LE_WHITELIST_UNINITIALIZED_ERROR:
  530. AESM_DBG_TRACE("LE whitelist uninitialized error");
  531. return SGX_ERROR_UNEXPECTED;
  532. default:
  533. AESM_DBG_WARN("unexpeted error %d", ret_le);
  534. return SGX_ERROR_UNEXPECTED;
  535. }
  536. token_t *lt = reinterpret_cast<token_t *>(launch_token);
  537. ret_le = set_psvn(signature->body.isv_prod_id, signature->body.isv_svn, lt->cpu_svn_le, mrsigner_index);
  538. if(AE_PSVN_UNMATCHED_ERROR == ret_le)
  539. {
  540. //QE or PSE has been changed, but AESM doesn't restart. Will not provide service.
  541. return SGX_ERROR_SERVICE_UNAVAILABLE;
  542. }else if(AE_SUCCESS != ret_le) {
  543. AESM_DBG_ERROR("fail to save psvn:%d", ret_le);
  544. return SGX_ERROR_UNEXPECTED;
  545. }
  546. return SGX_SUCCESS;
  547. }
  548. aesm_error_t AESMLogic::create_session(
  549. uint32_t* session_id,
  550. uint8_t* se_dh_msg1, uint32_t se_dh_msg1_size)
  551. {
  552. return AESM_SERVICE_UNAVAILABLE;
  553. }
  554. aesm_error_t AESMLogic::exchange_report(
  555. uint32_t session_id,
  556. const uint8_t* se_dh_msg2, uint32_t se_dh_msg2_size,
  557. uint8_t* se_dh_msg3, uint32_t se_dh_msg3_size)
  558. {
  559. return AESM_SERVICE_UNAVAILABLE;
  560. }
  561. aesm_error_t AESMLogic::close_session(
  562. uint32_t session_id)
  563. {
  564. return AESM_SERVICE_UNAVAILABLE;
  565. }
  566. aesm_error_t AESMLogic::invoke_service(
  567. const uint8_t* pse_message_req, uint32_t pse_message_req_size,
  568. uint8_t* pse_message_resp, uint32_t pse_message_resp_size)
  569. {
  570. return AESM_SERVICE_UNAVAILABLE;;
  571. }
  572. aesm_error_t AESMLogic::get_ps_cap(
  573. uint64_t* ps_cap)
  574. {
  575. return AESM_PSDA_UNAVAILABLE;
  576. }
  577. #define CHECK_EPID_PROVISIONG_STATUS \
  578. if(!query_pve_thread_status()){\
  579. return AESM_BUSY;\
  580. }
  581. aesm_error_t AESMLogic::init_quote(
  582. uint8_t *target_info, uint32_t target_info_size,
  583. uint8_t *gid, uint32_t gid_size)
  584. {
  585. ae_error_t ret = AE_SUCCESS;
  586. uint16_t qe_isv_svn = 0xFFFF;
  587. uint16_t pce_isv_svn = 0xFFFF;
  588. sgx_cpu_svn_t qe_cpu_svn;
  589. memset(&qe_cpu_svn, 0, sizeof(qe_cpu_svn));
  590. AESM_DBG_INFO("init_quote");
  591. if(sizeof(sgx_target_info_t) != target_info_size ||
  592. sizeof(sgx_epid_group_id_t) != gid_size)
  593. {
  594. return AESM_PARAMETER_ERROR;
  595. }
  596. AESMLogicLock lock(_qe_pve_mutex);
  597. CHECK_EPID_PROVISIONG_STATUS;
  598. ret = get_pce_isv_svn(pce_isv_svn);
  599. if(AE_SUCCESS != ret)
  600. {
  601. if(AESM_AE_OUT_OF_EPC == ret)
  602. return AESM_OUT_OF_EPC;
  603. else if(AESM_AE_NO_DEVICE == ret)
  604. return AESM_NO_DEVICE_ERROR;
  605. else if(AE_SERVER_NOT_AVAILABLE == ret)
  606. return AESM_SERVICE_UNAVAILABLE;
  607. return AESM_UNEXPECTED_ERROR;
  608. }
  609. ret = get_qe_cpu_svn(qe_cpu_svn);
  610. if(AE_SUCCESS != ret)
  611. {
  612. if(AESM_AE_OUT_OF_EPC == ret)
  613. return AESM_OUT_OF_EPC;
  614. else if(AESM_AE_NO_DEVICE == ret)
  615. return AESM_NO_DEVICE_ERROR;
  616. else if(AE_SERVER_NOT_AVAILABLE == ret)
  617. return AESM_SERVICE_UNAVAILABLE;
  618. return AESM_UNEXPECTED_ERROR;
  619. }
  620. ret = get_qe_isv_svn(qe_isv_svn);
  621. if(AE_SUCCESS != ret)
  622. {
  623. if(AESM_AE_OUT_OF_EPC == ret)
  624. return AESM_OUT_OF_EPC;
  625. else if(AESM_AE_NO_DEVICE == ret)
  626. return AESM_NO_DEVICE_ERROR;
  627. else if(AE_SERVER_NOT_AVAILABLE == ret)
  628. return AESM_SERVICE_UNAVAILABLE;
  629. return AESM_UNEXPECTED_ERROR;
  630. }
  631. return QEAESMLogic::init_quote(
  632. reinterpret_cast<sgx_target_info_t *>(target_info),
  633. gid, gid_size, pce_isv_svn, qe_isv_svn, qe_cpu_svn);
  634. }
  635. aesm_error_t AESMLogic::get_quote(const uint8_t *report, uint32_t report_size,
  636. uint32_t quote_type,
  637. const uint8_t *spid, uint32_t spid_size,
  638. const uint8_t *nonce, uint32_t nonce_size,
  639. const uint8_t *sigrl, uint32_t sigrl_size,
  640. uint8_t *qe_report, uint32_t qe_report_size,
  641. uint8_t *quote, uint32_t buf_size)
  642. {
  643. ae_error_t ret = AE_SUCCESS;
  644. uint16_t pce_isv_svn = 0xFFFF;
  645. AESM_DBG_INFO("get_quote");
  646. if(sizeof(sgx_report_t) != report_size ||
  647. sizeof(sgx_spid_t) != spid_size)
  648. {
  649. return AESM_PARAMETER_ERROR;
  650. }
  651. if((nonce && sizeof(sgx_quote_nonce_t) != nonce_size)
  652. || (qe_report && sizeof(sgx_report_t) != qe_report_size))
  653. {
  654. return AESM_PARAMETER_ERROR;
  655. }
  656. AESMLogicLock lock(_qe_pve_mutex);
  657. CHECK_EPID_PROVISIONG_STATUS;
  658. ret = get_pce_isv_svn(pce_isv_svn);
  659. if(AE_SUCCESS != ret)
  660. {
  661. if(AESM_AE_OUT_OF_EPC == ret)
  662. return AESM_OUT_OF_EPC;
  663. else if(AESM_AE_NO_DEVICE == ret)
  664. return AESM_NO_DEVICE_ERROR;
  665. else if(AE_SERVER_NOT_AVAILABLE == ret)
  666. return AESM_SERVICE_UNAVAILABLE;
  667. return AESM_UNEXPECTED_ERROR;
  668. }
  669. return QEAESMLogic::get_quote(report, quote_type, spid, nonce, sigrl,
  670. sigrl_size, qe_report, quote, buf_size, pce_isv_svn);
  671. }
  672. uint32_t AESMLogic::endpoint_selection(endpoint_selection_infos_t& es_info)
  673. {
  674. AESMLogicLock lock(_qe_pve_mutex);
  675. SGX_DBGPRINT_ONE_STRING_TWO_INTS_ENDPOINT_SELECTION(__FUNCTION__" (line, 0)", __LINE__, 0);
  676. return EndpointSelectionInfo::instance().start_protocol(es_info);
  677. }
  678. aesm_error_t AESMLogic::report_attestation_status(
  679. uint8_t* platform_info, uint32_t platform_info_size,
  680. uint32_t attestation_status,
  681. uint8_t* update_info, uint32_t update_info_size)
  682. {
  683. AESM_DBG_INFO("report_attestation_status");
  684. AESMLogicLock lock(_pse_mutex);
  685. return PlatformInfoLogic::report_attestation_status(platform_info, platform_info_size, attestation_status, update_info, update_info_size);
  686. }
  687. uint32_t AESMLogic::is_gid_matching_result_in_epid_blob(const GroupID& gid)
  688. {
  689. AESMLogicLock lock(_qe_pve_mutex);
  690. EPIDBlob& epid_blob = EPIDBlob::instance();
  691. uint32_t le_gid;
  692. if(epid_blob.get_sgx_gid(&le_gid)!=AE_SUCCESS){//get littlen endian gid
  693. return GIDMT_UNEXPECTED_ERROR;
  694. }
  695. le_gid=_htonl(le_gid);//use bigendian gid
  696. se_static_assert(sizeof(le_gid)==sizeof(gid));
  697. if(memcmp(&le_gid,&gid,sizeof(gid))!=0){
  698. return GIDMT_UNMATCHED;
  699. }
  700. return GIDMT_MATCHED;
  701. }
  702. ae_error_t AESMLogic::get_white_list_size_without_lock(uint32_t *white_list_cert_size)
  703. {
  704. uint32_t white_cert_size = 0;
  705. ae_error_t ae_ret = aesm_query_data_size(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_FID, &white_cert_size);
  706. if (AE_SUCCESS == ae_ret)
  707. {
  708. if (white_cert_size != 0){//file existing and not 0 size
  709. *white_list_cert_size = white_cert_size;
  710. return AE_SUCCESS;
  711. }
  712. else
  713. return AE_FAILURE;
  714. }
  715. else
  716. {
  717. return ae_ret;
  718. }
  719. }
  720. aesm_error_t AESMLogic::get_white_list_size(
  721. uint32_t* white_list_cert_size)
  722. {
  723. if (NULL == white_list_cert_size){
  724. return AESM_PARAMETER_ERROR;
  725. }
  726. CHECK_SERVICE_STATUS;
  727. AESMLogicLock lock(_le_mutex);
  728. CHECK_SERVICE_STATUS;
  729. ae_error_t ae_ret = get_white_list_size_without_lock(white_list_cert_size);
  730. if (AE_SUCCESS == ae_ret)
  731. return AESM_SUCCESS;
  732. else
  733. return AESM_UNEXPECTED_ERROR;
  734. }
  735. aesm_error_t AESMLogic::get_white_list(
  736. uint8_t *white_list_cert, uint32_t buf_size)
  737. {
  738. uint32_t white_cert_size=0;
  739. if (NULL == white_list_cert){
  740. return AESM_PARAMETER_ERROR;
  741. }
  742. CHECK_SERVICE_STATUS;
  743. AESMLogicLock lock(_le_mutex);
  744. CHECK_SERVICE_STATUS;
  745. ae_error_t ae_ret = get_white_list_size_without_lock(&white_cert_size);
  746. if (AE_SUCCESS != ae_ret)
  747. return AESM_UNEXPECTED_ERROR;
  748. if (white_cert_size != buf_size)
  749. {
  750. return AESM_PARAMETER_ERROR;
  751. }
  752. ae_ret = aesm_read_data(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_FID, white_list_cert, &white_cert_size);
  753. if (AE_SUCCESS != ae_ret){
  754. AESM_DBG_WARN("Fail to read white cert list file");
  755. return AESM_UNEXPECTED_ERROR;
  756. }
  757. return AESM_SUCCESS;
  758. }
  759. ae_error_t sgx_error_to_ae_error(sgx_status_t status)
  760. {
  761. if(SGX_ERROR_OUT_OF_MEMORY == status)
  762. return AE_OUT_OF_MEMORY_ERROR;
  763. if(SGX_SUCCESS == status)
  764. return AE_SUCCESS;
  765. return AE_FAILURE;
  766. }
  767. aesm_error_t AESMLogic::switch_extended_epid_group(
  768. uint32_t extended_epid_group_id
  769. )
  770. {
  771. AESM_DBG_INFO("AESMLogic::switch_extended_epid_group");
  772. ae_error_t ae_ret;
  773. extended_epid_group_blob_t xegb;
  774. aesm_server_url_infos_t urls;
  775. if ((ae_ret = XEGDBlob::verify_xegd_by_xgid(extended_epid_group_id)) != AE_SUCCESS ||
  776. (ae_ret = EndpointSelectionInfo::verify_file_by_xgid(extended_epid_group_id)) != AE_SUCCESS){
  777. AESM_DBG_INFO("Fail to switch to extended epid group to %d due to XEGD blob for URL blob not available", extended_epid_group_id);
  778. return AESM_PARAMETER_ERROR;
  779. }
  780. ae_ret = set_global_extended_epid_group_id(extended_epid_group_id);
  781. if (ae_ret != AE_SUCCESS){
  782. AESM_DBG_INFO("Fail to switch to extended epid group %d", extended_epid_group_id);
  783. return AESM_UNEXPECTED_ERROR;
  784. }
  785. AESM_DBG_INFO("Succ to switch to extended epid group %d in data file, restart aesm required to use it", extended_epid_group_id);
  786. return AESM_SUCCESS;
  787. }
  788. aesm_error_t AESMLogic::get_extended_epid_group_id(
  789. uint32_t* extended_epid_group_id)
  790. {
  791. AESM_DBG_INFO("AESMLogic::get_extended_epid_group");
  792. if (NULL == extended_epid_group_id)
  793. {
  794. return AESM_PARAMETER_ERROR;
  795. }
  796. *extended_epid_group_id = get_active_extended_epid_group_id();
  797. return AESM_SUCCESS;
  798. }