|
@@ -34,6 +34,7 @@
|
|
|
#include "QEClass.h"
|
|
|
#include "LEClass.h"
|
|
|
#include "PVEClass.h"
|
|
|
+#include "PCEClass.h"
|
|
|
|
|
|
#include "arch.h"
|
|
|
#include "sgx_report.h"
|
|
@@ -46,6 +47,7 @@
|
|
|
#include "oal/aesm_thread.h"
|
|
|
#include "aesm_encode.h"
|
|
|
#include "aesm_epid_blob.h"
|
|
|
+#include "aesm_xegd_blob.h"
|
|
|
#include "aesm_logic.h"
|
|
|
#include "pve_logic.h"
|
|
|
#include "qe_logic.h"
|
|
@@ -64,6 +66,7 @@
|
|
|
#include "prof_fun.h"
|
|
|
#include "aesm_long_lived_thread.h"
|
|
|
#include "sgx_profile.h"
|
|
|
+#include "service_enclave_mrsigner.hh"
|
|
|
|
|
|
#define CHECK_SERVICE_STATUS if (!is_service_running()) return AESM_SERVICE_STOPPED;
|
|
|
#define CHECK_SGX_STATUS if (g_sgx_device_status != SGX_ENABLED) return AESM_SGX_DEVICE_NOT_AVAILABLE;
|
|
@@ -74,13 +77,60 @@ AESMLogicMutex AESMLogic::_le_mutex;
|
|
|
|
|
|
bool AESMLogic::_is_qe_psvn_set;
|
|
|
bool AESMLogic::_is_pse_psvn_set;
|
|
|
+bool AESMLogic::_is_pce_psvn_set;
|
|
|
psvn_t AESMLogic::_qe_psvn;
|
|
|
+psvn_t AESMLogic::_pce_psvn;
|
|
|
psvn_t AESMLogic::_pse_psvn;
|
|
|
|
|
|
+uint32_t AESMLogic::active_extended_epid_group_id;
|
|
|
+
|
|
|
+static ae_error_t read_global_extended_epid_group_id(uint32_t *xeg_id)
|
|
|
+{
|
|
|
+ char path_name[MAX_PATH];
|
|
|
+ ae_error_t ae_ret = aesm_get_pathname(FT_PERSISTENT_STORAGE, EXTENDED_EPID_GROUP_ID_FID, path_name, MAX_PATH);
|
|
|
+ if(AE_SUCCESS != ae_ret){
|
|
|
+ return ae_ret;
|
|
|
+ }
|
|
|
+ FILE * f = fopen(path_name, "r");
|
|
|
+ if( f == NULL){
|
|
|
+ return OAL_CONFIG_FILE_ERROR;
|
|
|
+ }
|
|
|
+ ae_ret = OAL_CONFIG_FILE_ERROR;
|
|
|
+ if(fscanf(f, "%u", xeg_id)==1){
|
|
|
+ ae_ret = AE_SUCCESS;
|
|
|
+ }
|
|
|
+ fclose(f);
|
|
|
+ return ae_ret;
|
|
|
+}
|
|
|
+static ae_error_t set_global_extended_epid_group_id(uint32_t xeg_id)
|
|
|
+{
|
|
|
+ char path_name[MAX_PATH];
|
|
|
+ ae_error_t ae_ret = aesm_get_pathname(FT_PERSISTENT_STORAGE, EXTENDED_EPID_GROUP_ID_FID, path_name, MAX_PATH);
|
|
|
+ if(AE_SUCCESS != ae_ret){
|
|
|
+ return ae_ret;
|
|
|
+ }
|
|
|
+ FILE *f = fopen(path_name, "w");
|
|
|
+ if(f == NULL){
|
|
|
+ return OAL_CONFIG_FILE_ERROR;
|
|
|
+ }
|
|
|
+ ae_ret = OAL_CONFIG_FILE_ERROR;
|
|
|
+ if(fprintf(f, "%u", xeg_id)>0){
|
|
|
+ ae_ret = AE_SUCCESS;
|
|
|
+ }
|
|
|
+ fclose(f);
|
|
|
+ return ae_ret;
|
|
|
+}
|
|
|
+
|
|
|
+uint32_t AESMLogic::get_active_extended_epid_group_id()
|
|
|
+{
|
|
|
+ return active_extended_epid_group_id;
|
|
|
+}
|
|
|
+
|
|
|
static ae_error_t thread_to_load_qe(aesm_thread_arg_type_t arg)
|
|
|
{
|
|
|
epid_blob_with_cur_psvn_t epid_data;
|
|
|
ae_error_t ae_ret = AE_FAILURE;
|
|
|
+ uint32_t epid_xeid = 0;
|
|
|
UNUSED(arg);
|
|
|
AESM_DBG_TRACE("start to load qe");
|
|
|
memset(&epid_data, 0, sizeof(epid_data));
|
|
@@ -94,7 +144,50 @@ static ae_error_t thread_to_load_qe(aesm_thread_arg_type_t arg)
|
|
|
AESM_DBG_WARN("fail to load QE: %d", ae_ret);
|
|
|
}else{
|
|
|
AESM_DBG_TRACE("QE loaded successfully");
|
|
|
+ bool resealed = false;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ae_ret = static_cast<ae_error_t>(CQEClass::instance().verify_blob(
|
|
|
+ epid_data.trusted_epid_blob,
|
|
|
+ SGX_TRUSTED_EPID_BLOB_SIZE_PAK,
|
|
|
+ &resealed));
|
|
|
+ if(AE_SUCCESS != ae_ret)
|
|
|
+ {
|
|
|
+ AESM_DBG_WARN("Failed to verify EPID blob: %d", ae_ret);
|
|
|
+
|
|
|
+ EPIDBlob::instance().remove();
|
|
|
+ }else{
|
|
|
+
|
|
|
+ if ((EPIDBlob::instance().get_extended_epid_group_id(&epid_xeid) == AE_SUCCESS) && (epid_xeid == AESMLogic::get_active_extended_epid_group_id())) {
|
|
|
+ AESM_DBG_TRACE("EPID blob Verified");
|
|
|
+
|
|
|
+ if (true == resealed)
|
|
|
+ {
|
|
|
+ AESM_DBG_TRACE("EPID blob is resealed");
|
|
|
+ if ((ae_ret = EPIDBlob::instance().write(epid_data))
|
|
|
+ != AE_SUCCESS)
|
|
|
+ {
|
|
|
+ AESM_DBG_WARN("Failed to update epid blob: %d", ae_ret);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ AESM_DBG_TRACE("XEGDID mismatch in EPIDBlob, loading PCE ...");
|
|
|
+ EPIDBlob::instance().remove();
|
|
|
+ ae_ret = CPCEClass::instance().load_enclave();
|
|
|
+ if (AE_SUCCESS != ae_ret)
|
|
|
+ {
|
|
|
+ AESM_DBG_WARN("fail to load PCE: %d", ae_ret);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ AESM_DBG_TRACE("PCE loaded successfully");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ }else{
|
|
|
+ AESM_DBG_TRACE("Fail to read EPID Blob");
|
|
|
}
|
|
|
AESM_DBG_TRACE("QE Thread finished succ");
|
|
|
return AE_SUCCESS;
|
|
@@ -110,6 +203,24 @@ ae_error_t AESMLogic::service_start()
|
|
|
|
|
|
|
|
|
AESM_DBG_INFO("aesm service is starting");
|
|
|
+
|
|
|
+
|
|
|
+ ae_ret = read_global_extended_epid_group_id(&AESMLogic::active_extended_epid_group_id);
|
|
|
+ if (AE_SUCCESS != ae_ret){
|
|
|
+ AESM_DBG_INFO("Fail to read extended epid group id, default extended epid group used");
|
|
|
+ AESMLogic::active_extended_epid_group_id = DEFAULT_EGID;
|
|
|
+
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ AESM_DBG_INFO("active extended group id %d used", AESMLogic::active_extended_epid_group_id);
|
|
|
+ }
|
|
|
+ extended_epid_group_blob_t xegb;
|
|
|
+ aesm_server_url_infos_t urls;
|
|
|
+ if (AE_SUCCESS != (XEGDBlob::verify_xegd_by_xgid(active_extended_epid_group_id)) ||
|
|
|
+ AE_SUCCESS != (EndpointSelectionInfo::verify_file_by_xgid(active_extended_epid_group_id))){
|
|
|
+ AESMLogic::active_extended_epid_group_id = DEFAULT_EGID;
|
|
|
+ }
|
|
|
+
|
|
|
ae_ret = CLEClass::instance().load_enclave();
|
|
|
if(AE_SUCCESS != ae_ret)
|
|
|
{
|
|
@@ -126,7 +237,8 @@ ae_error_t AESMLogic::service_start()
|
|
|
}else{
|
|
|
(void)aesm_free_thread(qe_thread);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ start_white_list_thread();
|
|
|
AESM_DBG_TRACE("aesm service is started");
|
|
|
|
|
|
return AE_SUCCESS;
|
|
@@ -134,7 +246,9 @@ ae_error_t AESMLogic::service_start()
|
|
|
|
|
|
void AESMLogic::service_stop()
|
|
|
{
|
|
|
+ stop_all_long_lived_threads();
|
|
|
CPVEClass::instance().unload_enclave();
|
|
|
+ CPCEClass::instance().unload_enclave();
|
|
|
CQEClass::instance().unload_enclave();
|
|
|
CLEClass::instance().unload_enclave();
|
|
|
stop_all_long_lived_threads();
|
|
@@ -234,16 +348,21 @@ aesm_error_t AESMLogic::get_launch_token(
|
|
|
return AESM_PARAMETER_ERROR;
|
|
|
}
|
|
|
ae_error_t ae_ret = CLEClass::instance().load_enclave();
|
|
|
- if(ae_ret == AE_SERVER_NOT_AVAILABLE)
|
|
|
+ if(ae_ret == AESM_AE_NO_DEVICE)
|
|
|
{
|
|
|
AESM_LOG_ERROR("%s", g_event_string_table[SGX_EVENT_SERVICE_UNAVAILABLE]);
|
|
|
AESM_DBG_FATAL("LE not loaded due to AE_SERVER_NOT_AVAILABLE, possible SGX Env Not Ready");
|
|
|
return AESM_NO_DEVICE_ERROR;
|
|
|
}
|
|
|
+ else if(ae_ret == AESM_AE_OUT_OF_EPC)
|
|
|
+ {
|
|
|
+ AESM_DBG_WARN("LE not loaded due to out of EPC", ae_ret);
|
|
|
+ return AESM_OUT_OF_EPC;
|
|
|
+ }
|
|
|
else if(AE_FAILED(ae_ret))
|
|
|
{
|
|
|
AESM_DBG_ERROR("LE not loaded:%d", ae_ret);
|
|
|
- return AESM_UNEXPECTED_ERROR;
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
}
|
|
|
ret_le = static_cast<ae_error_t>(CLEClass::instance().get_launch_token(
|
|
|
const_cast<uint8_t *>(mrenclave), mrenclave_size,
|
|
@@ -297,6 +416,24 @@ ae_error_t AESMLogic::get_qe_isv_svn(uint16_t& isv_svn)
|
|
|
return AE_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ae_error_t AESMLogic::get_pce_isv_svn(uint16_t& isv_svn)
|
|
|
+{
|
|
|
+ if(!_is_pce_psvn_set){
|
|
|
+ ae_error_t ae_err = CPCEClass::instance().load_enclave();
|
|
|
+ if(AE_SUCCESS != ae_err){
|
|
|
+ AESM_DBG_ERROR("Fail to load PCE Enclave:%d",ae_err);
|
|
|
+ return ae_err;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ assert(_is_pce_psvn_set);
|
|
|
+ if(0!=memcpy_s(&isv_svn, sizeof(isv_svn), &_pce_psvn.isv_svn, sizeof(_pce_psvn.isv_svn))){
|
|
|
+ AESM_DBG_ERROR("memcpy failed");
|
|
|
+ return AE_FAILURE;
|
|
|
+ }
|
|
|
+ return AE_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
ae_error_t AESMLogic::get_pse_isv_svn(uint16_t& isv_svn)
|
|
|
{
|
|
|
return AE_FAILURE;
|
|
@@ -321,41 +458,62 @@ ae_error_t AESMLogic::get_qe_cpu_svn(sgx_cpu_svn_t& cpu_svn)
|
|
|
|
|
|
|
|
|
|
|
|
-ae_error_t AESMLogic::set_psvn(uint16_t prod_id, uint16_t isv_svn, sgx_cpu_svn_t cpu_svn)
|
|
|
+ae_error_t AESMLogic::set_psvn(uint16_t prod_id, uint16_t isv_svn, sgx_cpu_svn_t cpu_svn, uint32_t mrsigner_index)
|
|
|
{
|
|
|
if(prod_id == QE_PROD_ID){
|
|
|
- if(_is_qe_psvn_set){
|
|
|
- if(0!=memcmp(&_qe_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
|
|
|
- 0!=memcmp(&_qe_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
- AESM_DBG_ERROR("PSVN unmatched for QE/PVE");
|
|
|
- return AE_PSVN_UNMATCHED_ERROR;
|
|
|
+ if(mrsigner_index == AE_MR_SIGNER){
|
|
|
+ if(_is_qe_psvn_set){
|
|
|
+ if(0!=memcmp(&_qe_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcmp(&_qe_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("PSVN unmatched for QE/PVE");
|
|
|
+ return AE_PSVN_UNMATCHED_ERROR;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(0!=memcpy_s(&_qe_psvn.isv_svn, sizeof(_qe_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcpy_s(&_qe_psvn.cpu_svn, sizeof(_qe_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("memcpy failed");
|
|
|
+ return AE_FAILURE;
|
|
|
+ }
|
|
|
+ AESM_DBG_TRACE("get QE or PvE isv_svn=%d",(int)isv_svn);
|
|
|
+ _is_qe_psvn_set = true;
|
|
|
+ return AE_SUCCESS;
|
|
|
}
|
|
|
- }else{
|
|
|
- if(0!=memcpy_s(&_qe_psvn.isv_svn, sizeof(_qe_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
|
|
|
- 0!=memcpy_s(&_qe_psvn.cpu_svn, sizeof(_qe_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
- AESM_DBG_ERROR("memcpy failed");
|
|
|
- return AE_FAILURE;
|
|
|
+ }else if(mrsigner_index==PCE_MR_SIGNER){
|
|
|
+ if(_is_pce_psvn_set){
|
|
|
+ if(0!=memcmp(&_pce_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcmp(&_pce_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("PSVN unmatched for PCE");
|
|
|
+ return AE_PSVN_UNMATCHED_ERROR;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(0!=memcpy_s(&_pce_psvn.isv_svn, sizeof(_pce_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcpy_s(&_pce_psvn.cpu_svn, sizeof(_pce_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("memcpy failed");
|
|
|
+ return AE_FAILURE;
|
|
|
+ }
|
|
|
+ AESM_DBG_TRACE("get PCE isv_svn=%d", (int)isv_svn);
|
|
|
+ _is_pce_psvn_set = true;
|
|
|
+ return AE_SUCCESS;
|
|
|
}
|
|
|
- AESM_DBG_TRACE("get QE or PvE isv_svn=%d",(int)isv_svn);
|
|
|
- _is_qe_psvn_set = true;
|
|
|
- return AE_SUCCESS;
|
|
|
}
|
|
|
}else if(prod_id == PSE_PROD_ID){
|
|
|
- if(_is_pse_psvn_set){
|
|
|
- if(0!=memcmp(&_pse_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
|
|
|
- 0!=memcmp(&_pse_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
- AESM_DBG_ERROR("PSVN unmatched for PSE");
|
|
|
- return AE_PSVN_UNMATCHED_ERROR;
|
|
|
+ if(mrsigner_index == AE_MR_SIGNER){
|
|
|
+ if(_is_pse_psvn_set){
|
|
|
+ if(0!=memcmp(&_pse_psvn.isv_svn, &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcmp(&_pse_psvn.cpu_svn, &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("PSVN unmatched for PSE");
|
|
|
+ return AE_PSVN_UNMATCHED_ERROR;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(0!=memcpy_s(&_pse_psvn.isv_svn, sizeof(_pse_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
|
|
|
+ 0!=memcpy_s(&_pse_psvn.cpu_svn, sizeof(_pse_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
+ AESM_DBG_ERROR("memcpy failed");
|
|
|
+ return AE_FAILURE;
|
|
|
+ }
|
|
|
+ AESM_DBG_TRACE("get PSE isv_svn=%d", (int)isv_svn);
|
|
|
+ _is_pse_psvn_set = true;
|
|
|
+ return AE_SUCCESS;
|
|
|
}
|
|
|
- }else{
|
|
|
- if(0!=memcpy_s(&_pse_psvn.isv_svn, sizeof(_pse_psvn.isv_svn), &isv_svn, sizeof(isv_svn))||
|
|
|
- 0!=memcpy_s(&_pse_psvn.cpu_svn, sizeof(_pse_psvn.cpu_svn), &cpu_svn, sizeof(sgx_cpu_svn_t))){
|
|
|
- AESM_DBG_ERROR("memcpy failed");
|
|
|
- return AE_FAILURE;
|
|
|
- }
|
|
|
- AESM_DBG_TRACE("get PSE isv_svn=%d", (int)isv_svn);
|
|
|
- _is_pse_psvn_set = true;
|
|
|
- return AE_SUCCESS;
|
|
|
}
|
|
|
}
|
|
|
return AE_SUCCESS;
|
|
@@ -369,16 +527,25 @@ sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature,
|
|
|
AESMLogicLock lock(_le_mutex);
|
|
|
|
|
|
ae_error_t ret_le = AE_SUCCESS;
|
|
|
+ uint32_t mrsigner_index = UINT32_MAX;
|
|
|
|
|
|
if((ret_le=CLEClass::instance().load_enclave()) != AE_SUCCESS)
|
|
|
{
|
|
|
- if(ret_le == AE_SERVER_NOT_AVAILABLE)
|
|
|
+ if(ret_le == AESM_AE_NO_DEVICE)
|
|
|
{
|
|
|
- AESM_DBG_FATAL("LE not loaded due to AE_SERVER_NOT_AVAILABLE, possible SGX Env Not Ready");
|
|
|
+ AESM_DBG_FATAL("LE not loaded due to no SGX device available, possible SGX Env Not Ready");
|
|
|
return SGX_ERROR_NO_DEVICE;
|
|
|
}
|
|
|
- AESM_DBG_FATAL("fail to load LE:%d",ret_le);
|
|
|
- return SGX_ERROR_UNEXPECTED;
|
|
|
+ else if(ret_le == AESM_AE_OUT_OF_EPC)
|
|
|
+ {
|
|
|
+ AESM_DBG_FATAL("LE not loaded due to out of EPC");
|
|
|
+ return SGX_ERROR_OUT_OF_EPC;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ AESM_DBG_FATAL("fail to load LE:%d",ret_le);
|
|
|
+ return SGX_ERROR_SERVICE_UNAVAILABLE;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -390,7 +557,8 @@ sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature,
|
|
|
const_cast<uint8_t*>(reinterpret_cast<const uint8_t *>(attribute)),
|
|
|
sizeof(sgx_attributes_t),
|
|
|
reinterpret_cast<uint8_t*>(launch_token),
|
|
|
- sizeof(token_t)));
|
|
|
+ sizeof(token_t),
|
|
|
+ &mrsigner_index));
|
|
|
switch (ret_le)
|
|
|
{
|
|
|
case AE_SUCCESS:
|
|
@@ -411,7 +579,7 @@ sgx_status_t AESMLogic::get_launch_token(const enclave_css_t* signature,
|
|
|
}
|
|
|
|
|
|
token_t *lt = reinterpret_cast<token_t *>(launch_token);
|
|
|
- ret_le = set_psvn(signature->body.isv_prod_id, signature->body.isv_svn, lt->cpu_svn_le);
|
|
|
+ ret_le = set_psvn(signature->body.isv_prod_id, signature->body.isv_svn, lt->cpu_svn_le, mrsigner_index);
|
|
|
if(AE_PSVN_UNMATCHED_ERROR == ret_le)
|
|
|
{
|
|
|
|
|
@@ -428,7 +596,7 @@ aesm_error_t AESMLogic::create_session(
|
|
|
uint32_t* session_id,
|
|
|
uint8_t* se_dh_msg1, uint32_t se_dh_msg1_size)
|
|
|
{
|
|
|
- return AESM_SERVICE_NOT_AVAILABLE;
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
}
|
|
|
|
|
|
aesm_error_t AESMLogic::exchange_report(
|
|
@@ -436,20 +604,20 @@ aesm_error_t AESMLogic::exchange_report(
|
|
|
const uint8_t* se_dh_msg2, uint32_t se_dh_msg2_size,
|
|
|
uint8_t* se_dh_msg3, uint32_t se_dh_msg3_size)
|
|
|
{
|
|
|
- return AESM_SERVICE_NOT_AVAILABLE;
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
}
|
|
|
|
|
|
aesm_error_t AESMLogic::close_session(
|
|
|
uint32_t session_id)
|
|
|
{
|
|
|
- return AESM_SERVICE_NOT_AVAILABLE;
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
}
|
|
|
|
|
|
aesm_error_t AESMLogic::invoke_service(
|
|
|
const uint8_t* pse_message_req, uint32_t pse_message_req_size,
|
|
|
uint8_t* pse_message_resp, uint32_t pse_message_resp_size)
|
|
|
{
|
|
|
- return AESM_SERVICE_NOT_AVAILABLE;;
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;;
|
|
|
}
|
|
|
|
|
|
aesm_error_t AESMLogic::get_ps_cap(
|
|
@@ -469,6 +637,7 @@ aesm_error_t AESMLogic::init_quote(
|
|
|
{
|
|
|
ae_error_t ret = AE_SUCCESS;
|
|
|
uint16_t qe_isv_svn = 0xFFFF;
|
|
|
+ uint16_t pce_isv_svn = 0xFFFF;
|
|
|
sgx_cpu_svn_t qe_cpu_svn;
|
|
|
memset(&qe_cpu_svn, 0, sizeof(qe_cpu_svn));
|
|
|
AESM_DBG_INFO("init_quote");
|
|
@@ -479,19 +648,42 @@ aesm_error_t AESMLogic::init_quote(
|
|
|
}
|
|
|
AESMLogicLock lock(_qe_pve_mutex);
|
|
|
CHECK_EPID_PROVISIONG_STATUS;
|
|
|
+ ret = get_pce_isv_svn(pce_isv_svn);
|
|
|
+ if(AE_SUCCESS != ret)
|
|
|
+ {
|
|
|
+ if(AESM_AE_OUT_OF_EPC == ret)
|
|
|
+ return AESM_OUT_OF_EPC;
|
|
|
+ else if(AESM_AE_NO_DEVICE == ret)
|
|
|
+ return AESM_NO_DEVICE_ERROR;
|
|
|
+ else if(AE_SERVER_NOT_AVAILABLE == ret)
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+ }
|
|
|
ret = get_qe_cpu_svn(qe_cpu_svn);
|
|
|
if(AE_SUCCESS != ret)
|
|
|
{
|
|
|
+ if(AESM_AE_OUT_OF_EPC == ret)
|
|
|
+ return AESM_OUT_OF_EPC;
|
|
|
+ else if(AESM_AE_NO_DEVICE == ret)
|
|
|
+ return AESM_NO_DEVICE_ERROR;
|
|
|
+ else if(AE_SERVER_NOT_AVAILABLE == ret)
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
return AESM_UNEXPECTED_ERROR;
|
|
|
}
|
|
|
ret = get_qe_isv_svn(qe_isv_svn);
|
|
|
if(AE_SUCCESS != ret)
|
|
|
{
|
|
|
+ if(AESM_AE_OUT_OF_EPC == ret)
|
|
|
+ return AESM_OUT_OF_EPC;
|
|
|
+ else if(AESM_AE_NO_DEVICE == ret)
|
|
|
+ return AESM_NO_DEVICE_ERROR;
|
|
|
+ else if(AE_SERVER_NOT_AVAILABLE == ret)
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
return AESM_UNEXPECTED_ERROR;
|
|
|
}
|
|
|
return QEAESMLogic::init_quote(
|
|
|
reinterpret_cast<sgx_target_info_t *>(target_info),
|
|
|
- gid, gid_size, qe_isv_svn, qe_cpu_svn);
|
|
|
+ gid, gid_size, pce_isv_svn, qe_isv_svn, qe_cpu_svn);
|
|
|
}
|
|
|
|
|
|
aesm_error_t AESMLogic::get_quote(const uint8_t *report, uint32_t report_size,
|
|
@@ -502,6 +694,8 @@ aesm_error_t AESMLogic::get_quote(const uint8_t *report, uint32_t report_size,
|
|
|
uint8_t *qe_report, uint32_t qe_report_size,
|
|
|
uint8_t *quote, uint32_t buf_size)
|
|
|
{
|
|
|
+ ae_error_t ret = AE_SUCCESS;
|
|
|
+ uint16_t pce_isv_svn = 0xFFFF;
|
|
|
AESM_DBG_INFO("get_quote");
|
|
|
if(sizeof(sgx_report_t) != report_size ||
|
|
|
sizeof(sgx_spid_t) != spid_size)
|
|
@@ -516,8 +710,19 @@ aesm_error_t AESMLogic::get_quote(const uint8_t *report, uint32_t report_size,
|
|
|
}
|
|
|
AESMLogicLock lock(_qe_pve_mutex);
|
|
|
CHECK_EPID_PROVISIONG_STATUS;
|
|
|
+ ret = get_pce_isv_svn(pce_isv_svn);
|
|
|
+ if(AE_SUCCESS != ret)
|
|
|
+ {
|
|
|
+ if(AESM_AE_OUT_OF_EPC == ret)
|
|
|
+ return AESM_OUT_OF_EPC;
|
|
|
+ else if(AESM_AE_NO_DEVICE == ret)
|
|
|
+ return AESM_NO_DEVICE_ERROR;
|
|
|
+ else if(AE_SERVER_NOT_AVAILABLE == ret)
|
|
|
+ return AESM_SERVICE_UNAVAILABLE;
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+ }
|
|
|
return QEAESMLogic::get_quote(report, quote_type, spid, nonce, sigrl,
|
|
|
- sigrl_size, qe_report, quote, buf_size);
|
|
|
+ sigrl_size, qe_report, quote, buf_size, pce_isv_svn);
|
|
|
}
|
|
|
|
|
|
uint32_t AESMLogic::endpoint_selection(endpoint_selection_infos_t& es_info)
|
|
@@ -538,6 +743,84 @@ aesm_error_t AESMLogic::report_attestation_status(
|
|
|
return PlatformInfoLogic::report_attestation_status(platform_info, platform_info_size, attestation_status, update_info, update_info_size);
|
|
|
}
|
|
|
|
|
|
+uint32_t AESMLogic::is_gid_matching_result_in_epid_blob(const GroupID& gid)
|
|
|
+{
|
|
|
+ AESMLogicLock lock(_qe_pve_mutex);
|
|
|
+ EPIDBlob& epid_blob = EPIDBlob::instance();
|
|
|
+ uint32_t le_gid;
|
|
|
+ if(epid_blob.get_sgx_gid(&le_gid)!=AE_SUCCESS){
|
|
|
+ return GIDMT_UNEXPECTED_ERROR;
|
|
|
+ }
|
|
|
+ le_gid=_htonl(le_gid);
|
|
|
+ se_static_assert(sizeof(le_gid)==sizeof(gid));
|
|
|
+ if(memcmp(&le_gid,&gid,sizeof(gid))!=0){
|
|
|
+ return GIDMT_UNMATCHED;
|
|
|
+ }
|
|
|
+ return GIDMT_MATCHED;
|
|
|
+}
|
|
|
+
|
|
|
+ae_error_t AESMLogic::get_white_list_size_without_lock(uint32_t *white_list_cert_size)
|
|
|
+{
|
|
|
+ uint32_t white_cert_size = 0;
|
|
|
+ ae_error_t ae_ret = aesm_query_data_size(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_FID, &white_cert_size);
|
|
|
+ if (AE_SUCCESS == ae_ret)
|
|
|
+ {
|
|
|
+ if (white_cert_size != 0){
|
|
|
+ *white_list_cert_size = white_cert_size;
|
|
|
+ return AE_SUCCESS;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return AE_FAILURE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return ae_ret;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+aesm_error_t AESMLogic::get_white_list_size(
|
|
|
+ uint32_t* white_list_cert_size)
|
|
|
+{
|
|
|
+ if (NULL == white_list_cert_size){
|
|
|
+ return AESM_PARAMETER_ERROR;
|
|
|
+ }
|
|
|
+ CHECK_SERVICE_STATUS;
|
|
|
+ AESMLogicLock lock(_le_mutex);
|
|
|
+ CHECK_SERVICE_STATUS;
|
|
|
+ ae_error_t ae_ret = get_white_list_size_without_lock(white_list_cert_size);
|
|
|
+ if (AE_SUCCESS == ae_ret)
|
|
|
+ return AESM_SUCCESS;
|
|
|
+ else
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+aesm_error_t AESMLogic::get_white_list(
|
|
|
+ uint8_t *white_list_cert, uint32_t buf_size)
|
|
|
+{
|
|
|
+ uint32_t white_cert_size=0;
|
|
|
+ if (NULL == white_list_cert){
|
|
|
+ return AESM_PARAMETER_ERROR;
|
|
|
+ }
|
|
|
+ CHECK_SERVICE_STATUS;
|
|
|
+ AESMLogicLock lock(_le_mutex);
|
|
|
+ CHECK_SERVICE_STATUS;
|
|
|
+ ae_error_t ae_ret = get_white_list_size_without_lock(&white_cert_size);
|
|
|
+ if (AE_SUCCESS != ae_ret)
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+ if (white_cert_size != buf_size)
|
|
|
+ {
|
|
|
+ return AESM_PARAMETER_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ ae_ret = aesm_read_data(FT_PERSISTENT_STORAGE, AESM_WHITE_LIST_CERT_FID, white_list_cert, &white_cert_size);
|
|
|
+ if (AE_SUCCESS != ae_ret){
|
|
|
+ AESM_DBG_WARN("Fail to read white cert list file");
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+ }
|
|
|
+ return AESM_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
ae_error_t sgx_error_to_ae_error(sgx_status_t status)
|
|
|
{
|
|
|
if(SGX_ERROR_OUT_OF_MEMORY == status)
|
|
@@ -547,3 +830,37 @@ ae_error_t sgx_error_to_ae_error(sgx_status_t status)
|
|
|
return AE_FAILURE;
|
|
|
}
|
|
|
|
|
|
+aesm_error_t AESMLogic::switch_extended_epid_group(
|
|
|
+ uint32_t extended_epid_group_id
|
|
|
+ )
|
|
|
+{
|
|
|
+ AESM_DBG_INFO("AESMLogic::switch_extended_epid_group");
|
|
|
+ ae_error_t ae_ret;
|
|
|
+ extended_epid_group_blob_t xegb;
|
|
|
+ aesm_server_url_infos_t urls;
|
|
|
+ if ((ae_ret = XEGDBlob::verify_xegd_by_xgid(extended_epid_group_id)) != AE_SUCCESS ||
|
|
|
+ (ae_ret = EndpointSelectionInfo::verify_file_by_xgid(extended_epid_group_id)) != AE_SUCCESS){
|
|
|
+ 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);
|
|
|
+ return AESM_PARAMETER_ERROR;
|
|
|
+ }
|
|
|
+ ae_ret = set_global_extended_epid_group_id(extended_epid_group_id);
|
|
|
+ if (ae_ret != AE_SUCCESS){
|
|
|
+ AESM_DBG_INFO("Fail to switch to extended epid group %d", extended_epid_group_id);
|
|
|
+ return AESM_UNEXPECTED_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ AESM_DBG_INFO("Succ to switch to extended epid group %d in data file, restart aesm required to use it", extended_epid_group_id);
|
|
|
+ return AESM_SUCCESS;
|
|
|
+}
|
|
|
+aesm_error_t AESMLogic::get_extended_epid_group_id(
|
|
|
+ uint32_t* extended_epid_group_id)
|
|
|
+{
|
|
|
+ AESM_DBG_INFO("AESMLogic::get_extended_epid_group");
|
|
|
+ if (NULL == extended_epid_group_id)
|
|
|
+ {
|
|
|
+ return AESM_PARAMETER_ERROR;
|
|
|
+ }
|
|
|
+ *extended_epid_group_id = get_active_extended_epid_group_id();
|
|
|
+ return AESM_SUCCESS;
|
|
|
+}
|
|
|
+
|