PSEClass.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * Copyright (C) 2011-2018 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 "arch.h"
  32. #include "PSEClass.h"
  33. #include "pse_op_u.h"
  34. #include "pse_op_u.c"
  35. #include "pse_op_psda_ocall.cpp"
  36. #include "pse_op_vmc_sqlite_ocall.cpp"
  37. #include "sgx_tseal.h"
  38. #include "pairing_blob.h"
  39. #include "oal/oal.h"
  40. #include "byte_order.h"
  41. #include "LEClass.h"
  42. #include "ae_ipp.h"
  43. #include "PSDAService.h"
  44. #include "se_wrapper.h"
  45. #include "PSEPRClass.h"
  46. #include "sgx_profile.h"
  47. #include "sgx_uae_service.h"
  48. #include "aesm_pse_status.h"
  49. #include "interface_psda.h"
  50. #define PSDA_CAP_PRTC 0x1
  51. #define PSDA_CAP_RPDATA 0x8
  52. #define CHECK_ECALL_RET(status,ret) \
  53. if((status) == SGX_ERROR_ENCLAVE_LOST) \
  54. {retry++;continue;} \
  55. else if ((status) == SGX_ERROR_OUT_OF_MEMORY) { \
  56. (ret) = AE_OUT_OF_MEMORY_ERROR; break; } \
  57. else if ((status) != SGX_SUCCESS) { \
  58. (ret) = AE_FAILURE; break; } \
  59. else if ((ret) != 0) { break; }
  60. extern uint32_t upse_iclsInit();
  61. ae_error_t CPSEClass::init_ps(void)
  62. {
  63. // Try to establish PSDA session during startup
  64. PROFILE_START("PSDAService::start_service()");
  65. bool psda_started = PSDAService::instance().start_service();
  66. PROFILE_END("PSDAService::start_service()");
  67. if (!psda_started)
  68. {
  69. AESM_DBG_ERROR("Psda not available");
  70. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]);
  71. // This is logged as a WARNING here, since the system may not require PS capability
  72. AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]);
  73. // Set state to UNAVAILABLE
  74. m_status = PSE_STATUS_UNAVAILABLE;
  75. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_NOT_AVAILABLE);
  76. return AESM_PSDA_NOT_AVAILABLE;
  77. }
  78. //Logic here is that ME FW mode is used(Emulator is not running)
  79. //provisioning is attempted using iclsclient and the return code is not verified
  80. //In case of emulator the emulator provisioning tool is used to provision for epid 1.1 and if not long term pairing will return not provisioned error.
  81. // Always call upse_iclsInit because TCB recovery may occur
  82. // Ignore the return value because the ME may still be working
  83. uint32_t status_provision = upse_iclsInit();
  84. if (status_provision != 0)
  85. {
  86. // Provisioning failed , maybe caused by missing of iCls client, etc.
  87. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]);
  88. // This is logged as a WARNING here, since the system may not require PS capability
  89. AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]);
  90. }
  91. pse_pr_interface_psda* pPSDA = new(std::nothrow) pse_pr_interface_psda();
  92. if (pPSDA == NULL) {
  93. return AE_OUT_OF_MEMORY_ERROR;
  94. }
  95. // Will fail if CSME is not provisioned
  96. ae_error_t ret = pPSDA->get_csme_gid(&PSDAService::instance().csme_gid);
  97. delete pPSDA;
  98. pPSDA = NULL;
  99. if (ret != AE_SUCCESS)
  100. {
  101. // Failed to get CSME GID
  102. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]);
  103. // This is logged as a WARNING here, since the system may not require PS capability
  104. AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]);
  105. return ret;
  106. }
  107. // Set state to PROVISIONED
  108. m_status = PSE_STATUS_CSE_PROVISIONED;
  109. // Get platform service capbility
  110. PROFILE_START("get_ps_cap");
  111. ret = get_ps_cap(&m_ps_cap);
  112. PROFILE_END("get_ps_cap");
  113. if (ret != AE_SUCCESS){
  114. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]);
  115. // This is logged as a WARNING here, since the system may not require PS capability
  116. AESM_LOG_WARN_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_FAIL_DAL]);
  117. AESM_DBG_ERROR("get_ps_cap failed:%d",ret);
  118. return ret;
  119. }
  120. // Try to establish ephemeral session
  121. PROFILE_START("create_ephemeral_session_pse_cse");
  122. ret = create_ephemeral_session_pse_cse(false, false);
  123. PROFILE_END("create_ephemeral_session_pse_cse");
  124. if(ret != AE_SUCCESS)
  125. {
  126. AESM_DBG_ERROR("creatfe_ephemeral_session_pse_cse failed:%d", ret);
  127. if (ret == PSE_OP_LTPB_SEALING_OUT_OF_DATE)
  128. {
  129. AESM_DBG_ERROR("TCB update casued ephemeral session failure, reseal LTP blob now");
  130. // Try to reseal LTP blob
  131. bool is_new_pairing = false;
  132. ae_error_t ltpStatus = CPSEPRClass::instance().long_term_pairing(&is_new_pairing);
  133. if (ltpStatus == AE_SUCCESS)
  134. {
  135. AESM_DBG_INFO("Reseal LTP blob succeeded. Try ephermeal session again.");
  136. ret = create_ephemeral_session_pse_cse(is_new_pairing, false);
  137. if (ret != AE_SUCCESS){
  138. AESM_DBG_ERROR("creatfe_ephemeral_session_pse_cse after ltp blob resealing failed:%d", ret);
  139. }
  140. }
  141. }
  142. }
  143. else {
  144. // If this succeeds we should log PS Init start/success, simply because it won't be repeated and
  145. // logged later. We don't log the error flows here, because we don't consider this the "real"
  146. // PS Init. That will happen the first time create_session(), etc is invoked.
  147. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_START]);
  148. AESM_LOG_INFO_ADMIN("%s", g_admin_event_string_table[SGX_ADMIN_EVENT_PS_INIT_SUCCESS]);
  149. }
  150. return ret;
  151. }
  152. void CPSEClass::before_enclave_load() {
  153. // always unload pse_pr enclave before loading pse_op enclave
  154. CPSEPRClass::instance().unload_enclave();
  155. }
  156. ae_error_t CPSEClass::create_session(
  157. uint32_t* session_id,
  158. uint8_t* se_dh_msg1, uint32_t se_dh_msg1_size
  159. )
  160. {
  161. sgx_status_t status = SGX_SUCCESS;
  162. ae_error_t ret = AE_SUCCESS;
  163. ae_error_t ret2 = AE_SUCCESS;
  164. // check enclave ID
  165. if(!m_enclave_id)
  166. return AE_FAILURE;
  167. if(sizeof(pse_dh_msg1_t) != se_dh_msg1_size)
  168. return PSE_OP_PARAMETER_ERROR;
  169. uint64_t milliseconds = static_cast<uint64_t>(static_cast<double>(se_get_tick_count()) * 1000.0 / static_cast<double>(m_freq) + 0.5);
  170. status = create_session_wrapper(m_enclave_id,&ret,milliseconds,session_id,(pse_dh_msg1_t*)se_dh_msg1);
  171. if (status == SGX_ERROR_ENCLAVE_LOST)
  172. {
  173. // unload pse-op enclave
  174. unload_enclave();
  175. // Return PSE_OP_EPHEMERAL_SESSION_INVALID to trigger ephemeral session re-establishment
  176. return PSE_OP_EPHEMERAL_SESSION_INVALID;
  177. }
  178. if(AE_SUCCESS != (ret2=sgx_error_to_ae_error(status)))
  179. return ret2;
  180. return ret;
  181. }
  182. //if ok return 0
  183. ae_error_t CPSEClass::exchange_report(
  184. uint32_t session_id,
  185. uint8_t* se_dh_msg2, uint32_t se_dh_msg2_size,
  186. uint8_t* se_dh_msg3, uint32_t se_dh_msg3_size
  187. )
  188. {
  189. sgx_status_t status = SGX_SUCCESS;
  190. ae_error_t ret = AE_SUCCESS;
  191. ae_error_t ret2 = AE_SUCCESS;
  192. if(!m_enclave_id)
  193. return AE_FAILURE;
  194. if(sizeof(sgx_dh_msg2_t) != se_dh_msg2_size)
  195. return PSE_OP_PARAMETER_ERROR;
  196. if(sizeof(pse_dh_msg3_t) != se_dh_msg3_size)
  197. return PSE_OP_PARAMETER_ERROR;
  198. uint64_t sys_tick = se_get_tick_count();
  199. uint64_t milliseconds = static_cast<uint64_t>(static_cast<double>(sys_tick) * 1000.0 / static_cast<double>(m_freq) + 0.5);
  200. //ECall
  201. status = exchange_report_wrapper(m_enclave_id, &ret,
  202. milliseconds,
  203. session_id,
  204. (sgx_dh_msg2_t*)se_dh_msg2,
  205. (pse_dh_msg3_t*)se_dh_msg3);
  206. if (status == SGX_ERROR_ENCLAVE_LOST)
  207. {
  208. // unload pse-op enclave
  209. unload_enclave();
  210. // Return PSE_OP_EPHEMERAL_SESSION_INVALID to trigger ephemeral session re-establishment
  211. return PSE_OP_EPHEMERAL_SESSION_INVALID;
  212. }
  213. if(AE_SUCCESS != (ret2 = sgx_error_to_ae_error(status)))
  214. return ret2;
  215. return ret;
  216. }
  217. //if ok return 0
  218. ae_error_t CPSEClass::close_session(uint32_t session_id)
  219. {
  220. sgx_status_t status = SGX_SUCCESS;
  221. ae_error_t ret = AE_SUCCESS;
  222. ae_error_t ret2 = AE_SUCCESS;
  223. if(!m_enclave_id)
  224. return AE_FAILURE;
  225. // ECall
  226. status = close_session_wrapper(m_enclave_id,&ret,session_id);
  227. if (status == SGX_ERROR_ENCLAVE_LOST)
  228. {
  229. // unload pse-op enclave
  230. unload_enclave();
  231. // Return PSE_OP_EPHEMERAL_SESSION_INVALID to trigger ephemeral session re-establishment
  232. return PSE_OP_EPHEMERAL_SESSION_INVALID;
  233. }
  234. if(AE_SUCCESS != (ret2=sgx_error_to_ae_error(status)))
  235. return ret2;
  236. return ret;
  237. }
  238. //if ok return 0
  239. ae_error_t CPSEClass::invoke_service(
  240. uint8_t* pse_message_req, size_t pse_message_req_size,
  241. uint8_t* pse_message_resp, size_t pse_message_resp_size)
  242. {
  243. sgx_status_t status = SGX_SUCCESS;
  244. ae_error_t ret = AE_SUCCESS;
  245. ae_error_t ret2= AE_SUCCESS;
  246. if(!m_enclave_id)
  247. return AE_FAILURE;
  248. uint64_t sys_tick = se_get_tick_count();
  249. uint64_t milliseconds = static_cast<uint64_t>(static_cast<double>(sys_tick) * 1000.0 / static_cast<double>(m_freq) + 0.5);
  250. // ECall
  251. PROFILE_START("invoke_service_wrapper");
  252. status = invoke_service_wrapper(m_enclave_id,
  253. &ret,
  254. milliseconds,
  255. pse_message_req,
  256. (uint32_t)pse_message_req_size,
  257. pse_message_resp,
  258. (uint32_t)pse_message_resp_size);
  259. if (status == SGX_ERROR_ENCLAVE_LOST)
  260. {
  261. // unload pse-op enclave
  262. unload_enclave();
  263. // Return PSE_OP_EPHEMERAL_SESSION_INVALID to trigger ephemeral session re-establishment
  264. return PSE_OP_EPHEMERAL_SESSION_INVALID;
  265. }
  266. PROFILE_END("invoke_service_wrapper");
  267. if(AE_SUCCESS != (ret2=sgx_error_to_ae_error(status)))
  268. return ret2;
  269. return ret;
  270. }
  271. ae_error_t CPSEClass::get_ps_cap(uint64_t* ps_cap)
  272. {
  273. if (ps_cap == NULL)
  274. {
  275. AESM_DBG_ERROR("input ps_cap is NULL");
  276. return AE_FAILURE;
  277. }
  278. if (m_ps_cap != PS_CAP_NOT_AVAILABLE)
  279. {
  280. AESM_DBG_TRACE("ps_cap is available:%llu", m_ps_cap);
  281. *ps_cap = m_ps_cap;
  282. return AE_SUCCESS;
  283. }
  284. psda_info_query_msg_t psda_cap_query_msg;
  285. psda_cap_query_msg.msg_hdr.msg_type = _htonl(PSDA_MSG_TYPE_CAP_QUERY);
  286. psda_cap_query_msg.msg_hdr.msg_len = 0;
  287. psda_cap_result_msg_t psda_cap_result_msg;
  288. memset(&psda_cap_result_msg, 0, sizeof(psda_cap_result_msg_t));
  289. JVM_COMM_BUFFER commBuf;
  290. commBuf.TxBuf->buffer = &psda_cap_query_msg;
  291. commBuf.TxBuf->length = sizeof(psda_info_query_msg_t);
  292. commBuf.RxBuf->buffer = &psda_cap_result_msg;
  293. commBuf.RxBuf->length = sizeof(psda_cap_result_msg_t);
  294. int response_code;
  295. ae_error_t ret;
  296. ret = PSDAService::instance().send_and_recv(
  297. PSDA_COMMAND_INFO,
  298. &commBuf,
  299. &response_code,
  300. AUTO_RETRY_ON_SESSION_LOSS);
  301. if (ret != AE_SUCCESS)
  302. {
  303. AESM_DBG_ERROR("JHI_SendAndRecv2 returned (ae%d)",ret);
  304. AESM_LOG_ERROR_UNICODE("%s", g_event_string_table[SGX_EVENT_DAL_COMM_FAILURE]);
  305. return ret;
  306. }
  307. if (response_code != PSDA_SUCCESS)
  308. {
  309. AESM_DBG_ERROR("JHI_SendAndRecv2 response_code is %d", response_code);
  310. return AE_FAILURE;
  311. }
  312. if (_ntohl(psda_cap_result_msg.msg_hdr.msg_type) != PSDA_MSG_TYPE_CAP_RESULT
  313. || _ntohl(psda_cap_result_msg.msg_hdr.msg_len) != PSDA_CAP_RESULT_MSG_LEN) {
  314. AESM_DBG_ERROR("msg_type %d, msg_len %d while expected value type %d, len %d",
  315. _ntohl(psda_cap_result_msg.msg_hdr.msg_type), _ntohl(psda_cap_result_msg.msg_hdr.msg_len),
  316. PSDA_MSG_TYPE_CAP_RESULT, PSDA_CAP_RESULT_MSG_LEN);
  317. return AE_FAILURE;
  318. }
  319. if (_ntohl(psda_cap_result_msg.cap_descriptor_version) != 1)
  320. {
  321. return AE_FAILURE;
  322. }
  323. m_ps_cap = 0;
  324. uint32_t psda_cap0 = _ntohl(psda_cap_result_msg.cap_descriptor0);
  325. if (psda_cap0 & PSDA_CAP_PRTC)
  326. m_ps_cap |= PS_CAP_TRUSTED_TIME; // Trusted time service
  327. if (psda_cap0 & PSDA_CAP_RPDATA) // RPDATA capbility is available
  328. m_ps_cap |= PS_CAP_MONOTONIC_COUNTER; // Monotonic counter service
  329. *ps_cap = m_ps_cap;
  330. return AE_SUCCESS;
  331. }
  332. /**
  333. * @brief Establish an ephemeral session between PSE and CSE if not established yet.
  334. *
  335. * @param is_new_pairing
  336. * @param redo
  337. *
  338. * @return SGX_SUCCESS for success. Other values indicate an error.
  339. */
  340. ae_error_t CPSEClass::create_ephemeral_session_pse_cse(bool is_new_pairing, bool redo)
  341. {
  342. ae_error_t ret = AE_FAILURE;
  343. pse_cse_msg2_t msg2;
  344. pse_cse_msg3_t msg3;
  345. pse_cse_msg4_t msg4;
  346. uint32_t blob_size;
  347. uint8_t* p_sealed_buffer = NULL;
  348. sgx_status_t status = SGX_SUCCESS;
  349. sgx_status_t stat_initdb = SGX_SUCCESS;
  350. int retry = 0;
  351. if (m_status == PSE_STATUS_INIT ||
  352. m_status == PSE_STATUS_UNAVAILABLE)
  353. {
  354. // CSE provisioning failed during initialization.
  355. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_NOT_AVAILABLE);
  356. return AE_FAILURE;
  357. }
  358. if (!redo)
  359. {
  360. if (m_status == PSE_STATUS_SERVICE_READY) {
  361. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_READY);
  362. return AE_SUCCESS;
  363. }
  364. }
  365. else
  366. {
  367. // invalidate current session
  368. m_status = PSE_STATUS_CSE_PROVISIONED;
  369. }
  370. // Set to NOT_READY at the beginning.
  371. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_NOT_READY);
  372. do
  373. {
  374. AESM_DBG_INFO("PSDA started");
  375. // Check LT pairing blob first
  376. blob_size = sizeof(pairing_blob_t);
  377. p_sealed_buffer = (uint8_t*)malloc(blob_size);
  378. if (p_sealed_buffer == NULL)
  379. {
  380. return AE_FAILURE;
  381. }
  382. PROFILE_START("aesm_read_data");
  383. // read sealed blob from persistent storage
  384. ret = aesm_read_data(FT_PERSISTENT_STORAGE, PSE_PR_LT_PAIRING_FID, p_sealed_buffer, &blob_size);
  385. PROFILE_END("aesm_read_data");
  386. if (ret != AE_SUCCESS||blob_size!=sizeof(pairing_blob_t))
  387. {
  388. // Failed to load LT sealed blob
  389. ret = PSE_PAIRING_BLOB_INVALID_ERROR;
  390. // unload pse_op enclave
  391. unload_enclave();
  392. // load pse_pr enclave
  393. CPSEPRClass::instance().load_enclave();
  394. break;
  395. }
  396. AESM_DBG_INFO("LT Paring Blob read");
  397. // load pse-op enclave if it's not loaded yet
  398. if ((ret = load_enclave()) != AE_SUCCESS)
  399. break;
  400. do
  401. {
  402. // create PSDA session if not available
  403. if (!PSDAService::instance().start_service()) {
  404. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_NOT_AVAILABLE);
  405. ret = AE_FAILURE;
  406. break;
  407. }
  408. if(status == SGX_ERROR_ENCLAVE_LOST)
  409. {
  410. unload_enclave();
  411. // Reload an AE will not fail because of out of EPC, so AESM_AE_OUT_OF_EPC is not checked here
  412. if(AE_SUCCESS != load_enclave())
  413. {
  414. ret = AE_FAILURE;
  415. break;
  416. }
  417. }
  418. AESM_DBG_INFO("PSDA Start Ephemral Session");
  419. // PSE --- M1:StartSession ---> CSE
  420. memset(&msg2, 0, sizeof(msg2));
  421. PROFILE_START("psda_start_ephemeral_session");
  422. ret = psda_start_ephemeral_session(((pairing_blob_t*)p_sealed_buffer)->plaintext.pse_instance_id, &msg2);
  423. PROFILE_END("psda_start_ephemeral_session");
  424. if (ret != AE_SUCCESS)
  425. break;
  426. AESM_DBG_INFO("Ephemral Session M2/M3");
  427. // PSE <--- M2 --- CSE
  428. memset(&msg3, 0, sizeof(msg3));
  429. PROFILE_START("ephemeral_session_m2m3_wrapper");
  430. status = ephemeral_session_m2m3_wrapper(m_enclave_id, &ret, (pairing_blob_t*)p_sealed_buffer, &msg2, &msg3);
  431. PROFILE_END("ephemeral_session_m2m3_wrapper");
  432. CHECK_ECALL_RET(status, ret)
  433. AESM_DBG_INFO("PSDA Finalize Session");
  434. // PSE --- M3 ---> CSE
  435. memset(&msg4, 0, sizeof(msg4));
  436. PROFILE_START("psda_finalize_session");
  437. ret = psda_finalize_session(((pairing_blob_t*)p_sealed_buffer)->plaintext.pse_instance_id, &msg3, &msg4);
  438. PROFILE_END("psda_finalize_session");
  439. if (ret == AESM_PSDA_SESSION_LOST)
  440. {
  441. retry++;
  442. continue;
  443. }
  444. BREAK_IF_FAILED(ret);
  445. AESM_DBG_INFO("Ephemeral Session M4");
  446. // PSE <--- M4 --- CSE
  447. PROFILE_START("ephemeral_session_m4_wrapper");
  448. status = ephemeral_session_m4_wrapper(m_enclave_id, &ret, &msg4);
  449. PROFILE_END("ephemeral_session_m4_wrapper");
  450. CHECK_ECALL_RET(status, ret)
  451. /* the return value of initialize_sqlite_database_file_wrapper is ignored unless it's SGX_ERROR_ENCLAVE_LOST */
  452. AESM_DBG_INFO("initialize vmc database");
  453. PROFILE_START("initialize_sqlite_database_file_wrapper");
  454. ae_error_t ret2;
  455. stat_initdb = initialize_sqlite_database_file_wrapper(m_enclave_id, &ret2, is_new_pairing);
  456. PROFILE_END("initialize_sqlite_database_file_wrapper");
  457. if (stat_initdb == SGX_ERROR_ENCLAVE_LOST)
  458. {
  459. retry++;
  460. continue;
  461. }
  462. else break;
  463. }while(retry < AESM_RETRY_COUNT);
  464. if (status == SGX_ERROR_ENCLAVE_LOST)
  465. {
  466. AESM_DBG_INFO("Enclave Lost");
  467. // maximum retry times reached
  468. ret = AE_FAILURE;
  469. break;
  470. }
  471. else if(ret == AE_SUCCESS)
  472. {
  473. // Set status to READY
  474. m_status = PSE_STATUS_SERVICE_READY;
  475. // Successfully build the ephemeral session
  476. PlatformServiceStatus::instance().set_platform_service_status(PLATFORM_SERVICE_READY);
  477. }
  478. } while(0);
  479. free(p_sealed_buffer);
  480. return ret;
  481. }
  482. ae_error_t CPSEClass::psda_start_ephemeral_session(const uint8_t* pse_instance_id,
  483. pse_cse_msg2_t* cse_msg2)
  484. {
  485. assert(cse_msg2 != NULL);
  486. AESM_DBG_INFO("Enter psda_start_ephemeral_session ...");
  487. eph_session_m1_t eph_session_m1;
  488. memcpy_s(eph_session_m1.msg_hdr.pse_instance_id, SW_INSTANCE_ID_SIZE, pse_instance_id, SW_INSTANCE_ID_SIZE);
  489. eph_session_m1.msg_hdr.msg_type = _htonl(PSDA_MSG_TYPE_EP_M1);
  490. eph_session_m1.msg_hdr.msg_len = 0;
  491. eph_session_m2_t eph_session_m2;
  492. memset(&eph_session_m2, 0, sizeof(eph_session_m2));
  493. JVM_COMM_BUFFER commBuf;
  494. commBuf.TxBuf->buffer = &eph_session_m1;
  495. commBuf.TxBuf->length = sizeof(eph_session_m1_t);
  496. commBuf.RxBuf->buffer = &eph_session_m2;
  497. commBuf.RxBuf->length = sizeof(eph_session_m2_t);
  498. int response_code;
  499. ae_error_t ret;
  500. ret = PSDAService::instance().send_and_recv(
  501. PSDA_COMMAND_EP,
  502. &commBuf,
  503. &response_code,
  504. AUTO_RETRY_ON_SESSION_LOSS);
  505. if (ret != AE_SUCCESS ) {
  506. AESM_LOG_ERROR_UNICODE("%s", g_event_string_table[SGX_EVENT_DAL_COMM_FAILURE]);
  507. return ret;
  508. }
  509. if (response_code == PSDA_LT_PAIRING_NOT_EXIST
  510. || response_code == PSDA_INTEGRITY_ERROR)
  511. {
  512. return AESM_PSDA_NEED_REPAIRING;
  513. }
  514. else if (response_code != PSDA_SUCCESS
  515. || _ntohl(eph_session_m2.msg_hdr.msg_type) != PSDA_MSG_TYPE_EP_M2
  516. || _ntohl(eph_session_m2.msg_hdr.msg_len) != sizeof(pse_cse_msg2_t)) {
  517. AESM_DBG_ERROR("JHI_SendAndRecv2 response_code is %d", response_code);
  518. return AE_FAILURE;
  519. }
  520. memcpy_s(cse_msg2, sizeof(pse_cse_msg2_t), &eph_session_m2.msg2, sizeof(pse_cse_msg2_t));
  521. return AE_SUCCESS;
  522. }
  523. ae_error_t CPSEClass::psda_finalize_session(const uint8_t* pse_instance_id,
  524. const pse_cse_msg3_t* cse_msg3,
  525. pse_cse_msg4_t* cse_msg4)
  526. {
  527. assert(cse_msg3 != NULL && cse_msg4 != NULL);
  528. AESM_DBG_INFO("Enter psda_finalize_session ...");
  529. eph_session_m3_t eph_session_m3;
  530. memcpy_s(eph_session_m3.msg_hdr.pse_instance_id, SW_INSTANCE_ID_SIZE, pse_instance_id, SW_INSTANCE_ID_SIZE);
  531. eph_session_m3.msg_hdr.msg_type = _htonl(PSDA_MSG_TYPE_EP_M3);
  532. eph_session_m3.msg_hdr.msg_len = _htonl(sizeof(pse_cse_msg3_t));
  533. memcpy_s(&eph_session_m3.msg3, sizeof(eph_session_m3.msg3), cse_msg3, sizeof(pse_cse_msg3_t));
  534. eph_session_m4_t eph_session_m4;
  535. memset(&eph_session_m4, 0, sizeof(eph_session_m4));
  536. JVM_COMM_BUFFER commBuf;
  537. commBuf.TxBuf->buffer = &eph_session_m3;
  538. commBuf.TxBuf->length = sizeof(eph_session_m3_t);
  539. commBuf.RxBuf->buffer = &eph_session_m4;
  540. commBuf.RxBuf->length = sizeof(eph_session_m4_t);
  541. int response_code;
  542. ae_error_t ret;
  543. ret = PSDAService::instance().send_and_recv(
  544. PSDA_COMMAND_EP,
  545. &commBuf,
  546. &response_code,
  547. NO_RETRY_ON_SESSION_LOSS);
  548. if (ret != AE_SUCCESS)
  549. {
  550. AESM_LOG_ERROR_UNICODE("%s", g_event_string_table[SGX_EVENT_DAL_COMM_FAILURE]);
  551. return ret;
  552. }
  553. if (response_code == PSDA_INTEGRITY_ERROR)
  554. {
  555. return AESM_PSDA_NEED_REPAIRING;
  556. }
  557. else if (response_code != PSDA_SUCCESS
  558. || _ntohl(eph_session_m4.msg_hdr.msg_type) != PSDA_MSG_TYPE_EP_M4
  559. || _ntohl(eph_session_m4.msg_hdr.msg_len) != sizeof(pse_cse_msg4_t)) {
  560. AESM_DBG_ERROR("JHI_SendAndRecv2 response_code is %d", response_code);
  561. return AE_FAILURE;
  562. }
  563. memcpy_s(cse_msg4, sizeof(pse_cse_msg4_t), &eph_session_m4.msg4, sizeof(pse_cse_msg4_t));
  564. return AE_SUCCESS;
  565. }
  566. ae_error_t CPSEClass::psda_invoke_service(uint8_t* psda_req_msg, uint32_t psda_req_msg_size,
  567. uint8_t* psda_resp_msg, uint32_t psda_resp_msg_size)
  568. {
  569. AESM_DBG_INFO("Enter psda_invoke_service ...");
  570. JVM_COMM_BUFFER commBuf;
  571. commBuf.TxBuf->buffer = psda_req_msg;
  572. commBuf.TxBuf->length = psda_req_msg_size;
  573. commBuf.RxBuf->buffer = psda_resp_msg;
  574. commBuf.RxBuf->length = psda_resp_msg_size;
  575. int response_code;
  576. ae_error_t ret;
  577. PROFILE_START("JHI_SendAndRecv2");
  578. ret = PSDAService::instance().send_and_recv(
  579. PSDA_COMMAND_SERVICE,
  580. &commBuf,
  581. &response_code,
  582. NO_RETRY_ON_SESSION_LOSS);
  583. PROFILE_END("JHI_SendAndRecv2");
  584. if (ret != AE_SUCCESS) {
  585. AESM_LOG_ERROR_UNICODE("%s", g_event_string_table[SGX_EVENT_DAL_COMM_FAILURE]);
  586. return ret;
  587. }
  588. if (PSDA_SUCCESS != response_code) {
  589. AESM_LOG_ERROR_UNICODE("%s", g_event_string_table[SGX_EVENT_DAL_SERVICE_ERROR]);
  590. }
  591. AESM_DBG_INFO("JHI_SendAndRecv2 response_code is %d", response_code);
  592. switch (response_code)
  593. {
  594. case PSDA_SUCCESS: // SGX Platform Service Message form PSE processed successfully
  595. return AE_SUCCESS;
  596. case PSDA_INTERNAL_ERROR: // Internal error, possibly due to unexpected error of the system
  597. return AESM_PSDA_INTERNAL_ERROR;
  598. case PSDA_INVALID_SESSION_STATE: // SGX Platform Service ephemeral session state is invalid
  599. case PSDA_SEQNO_CHECK_FAIL: // SGX Platform Service secure channel message sequence number check failure
  600. case PSDA_INTEGRITY_ERROR: // SGX Platform Service message crypto verification failure
  601. case PSDA_LT_PAIRING_NOT_EXIST: // SGX Platform Service long term pairing session doesn't exist
  602. return AESM_PSDA_NEED_REPAIRING;
  603. case PSDA_INVALID_COMMAND: // SGX Platform Service PS_COMMAND_ID provided by the transport layer is not recognized
  604. case PSDA_BAD_PARAMETER: // SGX Platform Service Message format error detected
  605. default:
  606. return AE_FAILURE;
  607. }
  608. }