//********************************************************************* // Call quoting enclave to convert report to name-based quote //********************************************************************* static ae_error_t do_get_quote ( /*in */ upse::Buffer& reportBuffer, /*in */ upse::Buffer& sigRLBuffer, /*out*/ upse::Buffer& quoteBuffer ) { // Call QE to convert REPORT to a name-based QUOTE ae_error_t status = AE_FAILURE; ae_error_t tmp_status = AE_SUCCESS; do { #ifndef FAKE_QUOTE uint32_t nQuote; // in - Quote buffer size sgx_report_t enclaveReport; // in sgx_quote_sign_type_t quote_type; // in sgx_spid_t spid = {{0}}; // in uint8_t* pSigRL = NULL; // in uint32_t nSigRL = 0; // in - Sig RL buffer size memset(&enclaveReport, 0, sizeof(enclaveReport)); nSigRL = sigRLBuffer.getSize(); if (0 != nSigRL) pSigRL = const_cast<uint8_t*>(sigRLBuffer.getData()); if (SGX_SUCCESS != sgx_calc_quote_size(pSigRL, nSigRL, &nQuote)) break; tmp_status = quoteBuffer.Alloc(nQuote); if (AE_FAILED(tmp_status)) break; upse::BufferWriter bwQuote(quoteBuffer); uint8_t* pQuote; tmp_status = bwQuote.reserve(nQuote, &pQuote); // out if (AE_FAILED(tmp_status)) break; quote_type = SGX_UNLINKABLE_SIGNATURE; // or SGX_LINKABLE_SIGNATURE // LSB16(SHA256("SGX PSE PROVISIONING SERVER")) // const char* SPID_VALUE = "SGX PSE PROVISIONING SERVER"; // sgx_sha256_hash_t spid_hash; // sgx_sha256_msg((const uint8_t*)SPID_VALUE, strlen(SPID_VALUE), &spid_hash); // memcpy_s(spid.id, sizeof(spid.id), &spid_hash[0], 16); static uint8_t spid_hash[] = { 0x32, 0x81, 0xE5, 0x9E, 0xB1, 0x23, 0xFA, 0xCD, 0x56, 0xDB, 0x62, 0x1E, 0x3B, 0x37, 0xFB, 0xE2 }; memcpy_s(spid.id, sizeof(spid.id), spid_hash, sizeof(spid_hash)); if (reportBuffer.getSize() != sizeof(enclaveReport)) break; memcpy_s(&enclaveReport, reportBuffer.getSize(), reportBuffer.getData(), reportBuffer.getSize()); aesm_error_t result; result = AESMLogic::get_quote( (uint8_t*)&enclaveReport, sizeof(enclaveReport), quote_type, (uint8_t*)&spid, sizeof(spid), NULL, 0, pSigRL, nSigRL, NULL, 0, (uint8_t*)pQuote, nQuote); if (result == AESM_BUSY) { //EPID_PROVISION triggered, make sure previous EPID provision has finished ae_error_t temp_ret = wait_pve_thread(); BREAK_IF_TRUE(AE_SUCCESS != temp_ret , status, PSE_PR_PCH_EPID_UNKNOWN_ERROR); //redo get_quote result = AESMLogic::get_quote( (uint8_t*)&enclaveReport, sizeof(enclaveReport), quote_type, (uint8_t*)&spid, sizeof(spid), NULL, 0, pSigRL, nSigRL, NULL, 0, (uint8_t*)pQuote, nQuote); } BREAK_IF_TRUE(AESM_OUT_OF_EPC == result, status, AESM_AE_OUT_OF_EPC); BREAK_IF_TRUE(AESM_SUCCESS != result, status, AESM_PSE_PR_GET_QUOTE_ERROR); #else const uint16_t SIGNATURE_LENGTH = 32; tmp_status = quoteBuffer.Alloc(sizeof(sgx_quote_t) + SIGNATURE_LENGTH); if (AE_FAILED(tmp_status)) break; sgx_quote_t* pQuote; tmp_status = upse::BufferWriter(quoteBuffer).reserve(quoteBuffer.getSize(), (uint8_t**)&pQuote); if (AE_FAILED(tmp_status)) break; uint16_t CPUSVN = 1; pQuote->version = 1; memcpy_s(pQuote->epid_group_id, sizeof(pQuote->epid_group_id), &GID_TO_USE, sizeof(GID_TO_USE)); pQuote->report_body.isv_prod_id = 0x0002; //0x8086; pQuote->report_body.isv_svn = 1; memcpy_s(pQuote->report_body.cpu_svn, sizeof(pQuote->report_body.cpu_svn), &CPUSVN, sizeof(CPUSVN)); const sgx_report_t* pReport = (sgx_report_t*)reportBuffer.getData(); memcpy_s(pQuote->report_body.report_data, sizeof(pQuote->report_body.report_data), pReport->body.report_data, sizeof(pQuote->report_body.report_data)); pQuote->signature_len = SIGNATURE_LENGTH; //NOTE: The signature is not valid when doing a FAKE_QUOTE #endif status = AE_SUCCESS; } while (0); if ((AE_FAILURE == status) && AE_FAILED(tmp_status)) status = tmp_status; SGX_DBGPRINT_PRINT_FUNCTION_AND_RETURNVAL(__FUNCTION__, status); return status; }
sgx_status_t sgx_ra_proc_msg2( sgx_ra_context_t context, sgx_enclave_id_t eid, sgx_ecall_proc_msg2_trusted_t p_proc_msg2, sgx_ecall_get_msg3_trusted_t p_get_msg3, const sgx_ra_msg2_t *p_msg2, uint32_t msg2_size, sgx_ra_msg3_t **pp_msg3, uint32_t *p_msg3_size) { if(!p_msg2 || !p_proc_msg2 || !p_get_msg3 || !p_msg3_size || !pp_msg3) return SGX_ERROR_INVALID_PARAMETER; if(msg2_size != sizeof(sgx_ra_msg2_t) + p_msg2->sig_rl_size) return SGX_ERROR_INVALID_PARAMETER; sgx_status_t ret = SGX_ERROR_UNEXPECTED; sgx_report_t report; sgx_ra_msg3_t *p_msg3 = NULL; sgx_att_key_id_t empty_att_key_id; memset(&report, 0, sizeof(report)); memset(&empty_att_key_id, 0, sizeof(empty_att_key_id)); { sgx_quote_nonce_t nonce; sgx_report_t qe_report; sgx_target_info_t qe_target_info; memset(&nonce, 0, sizeof(nonce)); memset(&qe_report, 0, sizeof(qe_report)); sgx_status_t status; g_ukey_spin_lock.lock(); if(0 != memcmp(&g_att_key_id, &empty_att_key_id, sizeof(g_att_key_id))) { ret = SGX_ERROR_INVALID_STATE; g_ukey_spin_lock.unlock(); goto CLEANUP; } if(memcpy_s(&qe_target_info, sizeof(qe_target_info), &g_qe_target_info, sizeof(g_qe_target_info)) != 0) { ret = SGX_ERROR_UNEXPECTED; g_ukey_spin_lock.unlock(); goto CLEANUP; } g_ukey_spin_lock.unlock(); ret = p_proc_msg2(eid, &status, context, p_msg2, &qe_target_info, &report, &nonce); if(SGX_SUCCESS!=ret) { goto CLEANUP; } if(SGX_SUCCESS!=status) { ret = status; goto CLEANUP; } uint32_t quote_size = 0; ret = sgx_calc_quote_size(p_msg2->sig_rl_size ? const_cast<uint8_t *>(p_msg2->sig_rl):NULL, p_msg2->sig_rl_size, "e_size); if(SGX_SUCCESS!=ret) { goto CLEANUP; } //check integer overflow of quote_size if (UINT32_MAX - quote_size < sizeof(sgx_ra_msg3_t)) { ret = SGX_ERROR_UNEXPECTED; goto CLEANUP; } uint32_t msg3_size = static_cast<uint32_t>(sizeof(sgx_ra_msg3_t)) + quote_size; p_msg3 = (sgx_ra_msg3_t *)malloc(msg3_size); if(!p_msg3) { ret = SGX_ERROR_OUT_OF_MEMORY; goto CLEANUP; } memset(p_msg3, 0, msg3_size); ret = sgx_get_quote(&report, p_msg2->quote_type == SGX_UNLINKABLE_SIGNATURE ? SGX_UNLINKABLE_SIGNATURE : SGX_LINKABLE_SIGNATURE, const_cast<sgx_spid_t *>(&p_msg2->spid), &nonce, p_msg2->sig_rl_size ? const_cast<uint8_t *>(p_msg2->sig_rl):NULL, p_msg2->sig_rl_size, &qe_report, (sgx_quote_t *)p_msg3->quote, quote_size); if(SGX_SUCCESS!=ret) { goto CLEANUP; } ret = p_get_msg3(eid, &status, context, quote_size, &qe_report, p_msg3, msg3_size); if(SGX_SUCCESS!=ret) { goto CLEANUP; } if(SGX_SUCCESS!=status) { ret = status; goto CLEANUP; } *pp_msg3 = p_msg3; *p_msg3_size = msg3_size; } CLEANUP: if(ret) SAFE_FREE(p_msg3); return ret; }