123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- /*
- * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include "type_length_value.h"
- #include "epid_utility.h"
- #include "aesm_xegd_blob.h"
- #include "aeerror.h"
- #include "PVEClass.h"
- #include "PCEClass.h"
- #include "aesm_rand.h"
- /**
- * File: epid_provision_msg2.cpp
- * Description: Provide the untrusted implementation of code to process ProvMsg2
- *
- * Untrusted Code for EPID Provision
- */
- #define MSG2_TOP_FIELDS_COUNT_WITH_SIGRL 4
- #define MSG2_TOP_FIELDS_COUNT_WITHOUT_SIGRL 3
- #define MSG2_TOP_FIELD_NONCE tlvs_msg2[0]
- #define MSG2_TOP_FIELD_DATA tlvs_msg2[1]
- #define MSG2_TOP_FIELD_MAC tlvs_msg2[2]
- #define MSG2_TOP_FIELD_SIGRL tlvs_msg2[3]
- #define MSG2_FIELD1_MAX_COUNT 6
- #define MSG2_FIELD1_MIN_COUNT 4
- #define MSG2_FIELD1_GROUP_CERT tlvs_field1[0]
- #define MSG2_FIELD1_NONCE tlvs_field1[2]
- #define MSG2_FIELD1_PSID tlvs_field1[1]
- #define MSG2_FIELD1_PREV_PI tlvs_field1[alt_index+1]
- #define PREV_GID_INDEX (alt_index+2)
- #define MSG2_FIELD1_PREV_GID tlvs_field1[PREV_GID_INDEX]
- #define MSG2_FIELD1_PLAT_INFO tlvs_field1[alt_index+3]
- //Function to verify that EPID SigRl type and version is correct for sigrl
- static ae_error_t verify_sigrl_cert_type_version(const se_sig_rl_t *sigrl_cert)
- {
- if(sigrl_cert->epid_identifier!=SE_EPID_SIG_RL_ID||
- sigrl_cert->protocol_version!=SE_EPID_SIG_RL_VERSION)
- return PVE_INTEGRITY_CHECK_ERROR;
- return AE_SUCCESS;
- }
- static ae_error_t msg2_integrity_checking(const TLVsMsg& tlvs_msg2)
- {
- uint32_t tlv_count = tlvs_msg2.get_tlv_count();
- if(tlv_count != MSG2_TOP_FIELDS_COUNT_WITH_SIGRL && tlv_count != MSG2_TOP_FIELDS_COUNT_WITHOUT_SIGRL)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_NONCE.type != TLV_NONCE || MSG2_TOP_FIELD_NONCE.size != NONCE_SIZE || MSG2_TOP_FIELD_NONCE.version != TLV_VERSION_1)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_NONCE.header_size != SMALL_TLV_HEADER_SIZE)//Requires NONCE to be small header size
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_DATA.type != TLV_BLOCK_CIPHER_TEXT || MSG2_TOP_FIELD_DATA.version != TLV_VERSION_1)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_MAC.type != TLV_MESSAGE_AUTHENTICATION_CODE || MSG2_TOP_FIELD_MAC.version != TLV_VERSION_1 || MSG2_TOP_FIELD_MAC.size != MAC_SIZE)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_MAC.header_size != SMALL_TLV_HEADER_SIZE)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(tlv_count == MSG2_TOP_FIELDS_COUNT_WITH_SIGRL){
- if(MSG2_TOP_FIELD_SIGRL.type != TLV_EPID_SIG_RL || MSG2_TOP_FIELD_SIGRL.version != TLV_VERSION_1)
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_SIGRL.size < 2*SE_ECDSA_SIGN_SIZE + sizeof(se_sig_rl_t))
- return PVE_INTEGRITY_CHECK_ERROR;
- if(MSG2_TOP_FIELD_SIGRL.header_size != LARGE_TLV_HEADER_SIZE)
- return PVE_INTEGRITY_CHECK_ERROR;
- return verify_sigrl_cert_type_version(reinterpret_cast<const se_sig_rl_t *>(MSG2_TOP_FIELD_SIGRL.payload));
- }
- return AE_SUCCESS;
- }
- //check the format of msg2_field1 and copy correspondent data to msg2_blob_input
- static ae_error_t msg2_field1_msg_check_copy(const TLVsMsg& tlvs_field1, proc_prov_msg2_blob_input_t& msg2_blob_input, const signed_pek_t& pek)
- {
- uint32_t tlv_count = tlvs_field1.get_tlv_count();
- uint32_t alt_index = 2;
- msg2_blob_input.is_previous_pi_provided = false;
- if(tlv_count == MSG2_FIELD1_MAX_COUNT){//EPID_PSVN TLV is available
- msg2_blob_input.is_previous_pi_provided = true;
- if(MSG2_FIELD1_PREV_PI.type != TLV_PLATFORM_INFO ||
- MSG2_FIELD1_PREV_PI.size != sizeof(bk_platform_info_t)){
- return PVE_MSG_ERROR;
- }
- if(MSG2_FIELD1_PREV_PI.version != TLV_VERSION_1){
- return PVE_MSG_ERROR;
- }
- if(MSG2_FIELD1_PREV_PI.header_size != SMALL_TLV_HEADER_SIZE){
- return PVE_MSG_ERROR;
- }
- if(MSG2_FIELD1_PREV_GID.type != TLV_EPID_GID ||
- MSG2_FIELD1_PREV_GID.size != sizeof(GroupId)){
- return PVE_MSG_ERROR;
- }
- if(MSG2_FIELD1_PREV_GID.version != TLV_VERSION_1){
- return PVE_MSG_ERROR;
- }
- if(MSG2_FIELD1_PREV_GID.header_size != SMALL_TLV_HEADER_SIZE){
- return PVE_MSG_ERROR;
- }
- if(0!=memcpy_s(&msg2_blob_input.previous_gid, sizeof(msg2_blob_input.previous_gid), MSG2_FIELD1_PREV_GID.payload, MSG2_FIELD1_PREV_GID.size)){
- return PVE_UNEXPECTED_ERROR;
- }
- if(0!=memcpy_s(&msg2_blob_input.previous_pi, sizeof(msg2_blob_input.previous_pi), MSG2_FIELD1_PREV_PI.payload, MSG2_FIELD1_PREV_PI.size)){
- return PVE_UNEXPECTED_ERROR;
- }
- }else if(tlv_count!=MSG2_FIELD1_MIN_COUNT){
- return PVE_MSG_ERROR;//make sure number of TLVs are correct
- }else{
- alt_index=0;
- }
- if(MSG2_FIELD1_GROUP_CERT.type != TLV_EPID_GROUP_CERT||
- MSG2_FIELD1_GROUP_CERT.version != TLV_VERSION_1 ||
- MSG2_FIELD1_GROUP_CERT.size != sizeof(signed_epid_group_cert_t)||
- MSG2_FIELD1_GROUP_CERT.header_size != SMALL_TLV_HEADER_SIZE)
- return PVE_MSG_ERROR;
- if(MSG2_FIELD1_PSID.type != TLV_PS_ID ||
- MSG2_FIELD1_PSID.version != TLV_VERSION_1 ||
- MSG2_FIELD1_PSID.size != sizeof(psid_t)||
- MSG2_FIELD1_PSID.header_size != SMALL_TLV_HEADER_SIZE)
- return PVE_MSG_ERROR;
- if(MSG2_FIELD1_NONCE.type != TLV_NONCE||
- MSG2_FIELD1_NONCE.version != TLV_VERSION_1 ||
- MSG2_FIELD1_NONCE.size != CHALLENGE_NONCE_SIZE||
- MSG2_FIELD1_NONCE.header_size != SMALL_TLV_HEADER_SIZE)
- return PVE_MSG_ERROR;
- if(MSG2_FIELD1_PLAT_INFO.type != TLV_PLATFORM_INFO ||
- MSG2_FIELD1_PLAT_INFO.version != TLV_VERSION_1 ||
- MSG2_FIELD1_PLAT_INFO.size != sizeof(bk_platform_info_t)||
- MSG2_FIELD1_PLAT_INFO.header_size != SMALL_TLV_HEADER_SIZE)
- return PVE_MSG_ERROR;
- sgx_sha256_hash_t psid_hash;
- ae_error_t ret = sgx_error_to_ae_error(sgx_sha256_msg(reinterpret_cast<const uint8_t *>(&pek.n), static_cast<uint32_t>(sizeof(pek.n)+sizeof(pek.e)), &psid_hash));
- if(AE_SUCCESS != ret)
- return ret;
- if(0!=memcmp(&psid_hash, MSG2_FIELD1_PSID.payload, sizeof(psid_hash)))//PSID does not match
- return PVE_MSG_ERROR;
- bk_platform_info_t *d2 = (bk_platform_info_t *)MSG2_FIELD1_PLAT_INFO.payload;
- if(0!=memcpy_s(&msg2_blob_input.group_cert, sizeof(msg2_blob_input.group_cert), MSG2_FIELD1_GROUP_CERT.payload, MSG2_FIELD1_GROUP_CERT.size)||
- 0!=memcpy_s(&msg2_blob_input.challenge_nonce, sizeof(msg2_blob_input.challenge_nonce), MSG2_FIELD1_NONCE.payload, MSG2_FIELD1_NONCE.size)||
- 0!=memcpy_s(&msg2_blob_input.equiv_pi, sizeof(msg2_blob_input.equiv_pi), d2,sizeof(*d2))){
- return PVE_UNEXPECTED_ERROR;
- }
- return AE_SUCCESS;
- }
- //Function to check message header of ProvMsg2 to determine whether it is valid
- //@msg2_header, input the message header of ProvMsg2
- //@msg2_size, size of ProvMsg2, in bytes
- //@return AE_SUCCESS if the message header is valid ProvMsg2 or error code if there're any problems
- static ae_error_t check_prov_msg2_header(const provision_response_header_t *msg2_header, uint32_t msg2_size)
- {
- if(msg2_header->protocol != SE_EPID_PROVISIONING || msg2_header->type != TYPE_PROV_MSG2 ||
- msg2_header->version != TLV_VERSION_2){
- return PVE_INTEGRITY_CHECK_ERROR;
- }
- uint32_t size_in_header = lv_ntohl(msg2_header->size);
- if(size_in_header + PROVISION_RESPONSE_HEADER_SIZE != msg2_size)
- return PVE_INTEGRITY_CHECK_ERROR;
- return AE_SUCCESS;
- }
- static uint32_t estimate_epid_sig_size(uint32_t sigrl_size)
- {
- uint32_t sigrl_body_size = 0;
- uint32_t sigrl_extra_size = static_cast<uint32_t>(sizeof(se_sig_rl_t)-sizeof(SigRlEntry)+2*ECDSA_SIGN_SIZE);
- if(sigrl_size ==sigrl_extra_size || sigrl_size == 0){//sigrl_size==0 is special cases that no sigrl provided
- //Add the TLV Header size
- return static_cast<uint32_t>(sizeof(EpidSignature)-sizeof(NrProof)+MAX_TLV_HEADER_SIZE);
- }else if (sigrl_size < sigrl_extra_size){
- //Invalid sigrl size
- return 0;
- }else{
- sigrl_body_size = sigrl_size - sigrl_extra_size;
- uint64_t entry_count = sigrl_body_size/sizeof(SigRlEntry);
- uint64_t total_size = sizeof(EpidSignature)-sizeof(NrProof)+sizeof(NrProof)*entry_count+MAX_TLV_HEADER_SIZE;
- if(total_size > UINT32_MAX){
- return 0;
- }
- return static_cast<uint32_t>(total_size);
- }
- }
- static ae_error_t gen_msg3_header(const gen_prov_msg3_output_t& msg3_output, const uint8_t xid[XID_SIZE], provision_request_header_t *msg3_header, uint32_t& msg3_size)
- {
- msg3_header->protocol = SE_EPID_PROVISIONING;
- msg3_header->version = TLV_VERSION_2;
- msg3_header->type = TYPE_PROV_MSG3;
- size_t field1_size = 0;
- if(msg3_output.is_join_proof_generated){
- field1_size = BLOCK_CIPHER_TEXT_TLV_SIZE(HARD_CODED_JOIN_PROOF_WITH_ESCROW_TLV_SIZE)+MAC_TLV_SIZE(MAC_SIZE);
- }else{
- // BLOCK_CIPHER_TEXT_TLV_SIZE(0) is needed because IV need to be included for the following MAC tlv
- field1_size = BLOCK_CIPHER_TEXT_TLV_SIZE(0)+MAC_TLV_SIZE(MAC_SIZE);
- }
- field1_size+=NONCE_TLV_SIZE(NONCE_2_SIZE)+CIPHER_TEXT_TLV_SIZE(RSA_3072_KEY_BYTES)+SE_REPORT_TLV_SIZE();
- size_t total_body_size = NONCE_TLV_SIZE(NONCE_SIZE) + BLOCK_CIPHER_TEXT_TLV_SIZE(field1_size)+MAC_TLV_SIZE(MAC_SIZE);
- if(msg3_output.is_epid_sig_generated){
- total_body_size += BLOCK_CIPHER_TEXT_TLV_SIZE(msg3_output.epid_sig_output_size)+MAC_TLV_SIZE(MAC_SIZE);
- }
- uint32_t size_in_net = _htonl(total_body_size);
- if(0!=memcpy_s(&msg3_header->size, sizeof(msg3_header->size), &size_in_net, sizeof(size_in_net)))
- return PVE_UNEXPECTED_ERROR;//size in Big Endian in message header of ProvMsg3
- if(total_body_size>msg3_size - PROVISION_REQUEST_HEADER_SIZE ){//make sure buffer size provided by user is large enough
- return PVE_INSUFFICIENT_MEMORY_ERROR;
- }
- if(0!=memcpy_s(msg3_header->xid, sizeof(msg3_header->xid), xid, XID_SIZE))
- return PVE_UNEXPECTED_ERROR; //copy transaction id of ProvMsg2
- msg3_size = static_cast<uint32_t>(total_body_size + PROVISION_REQUEST_HEADER_SIZE);
- return AE_SUCCESS;
- }
- //Function to decode ProvMsg2 and generate ProvMsg3
- //@data: global structure used to store pve relative data
- //@msg2: ProvMsg2
- //@msg2_size: size of ProvMsg2
- //@epid_blob: input an optional old epid data blob used to generate non-revoke proof if required
- //@blob_size: size of the epid blob
- //@msg3: output buffer for ProvMsg3
- //@msg3_size: input the size of buffer msg3, in byte
- //@return AE_SUCCESS on success and error code on failure
- uint32_t CPVEClass::proc_prov_msg2(
- pve_data_t &data,
- const uint8_t *msg2,
- uint32_t msg2_size,
- const uint8_t *epid_blob,
- uint32_t blob_size,
- uint8_t *msg3,
- uint32_t msg3_size)
- {
- ae_error_t ret = AE_SUCCESS;
- const se_sig_rl_t *sigrl = NULL;
- uint32_t sigrl_size = 0;
- uint8_t *epid_sig = NULL;
- uint8_t *decoded_msg2 = NULL;
- uint8_t *encrypted_field1 = NULL;
- sgx_status_t sgx_status;
- uint8_t aad[PROVISION_RESPONSE_HEADER_SIZE+sizeof(RLver_t)+sizeof(GroupId)];
- size_t aad_size = PROVISION_RESPONSE_HEADER_SIZE;
- const provision_response_header_t *msg2_header = reinterpret_cast<const provision_response_header_t *>(msg2);
- provision_request_header_t *msg3_header = reinterpret_cast<provision_request_header_t *>(msg3);
- if(msg2_size < PROVISION_RESPONSE_HEADER_SIZE){
- AESM_DBG_ERROR("ProvMsg2 size too small");
- return PVE_MSG_ERROR;
- }
- if (epid_blob != NULL && blob_size != SGX_TRUSTED_EPID_BLOB_SIZE_SDK){
- AESM_DBG_FATAL("epid blob size error");
- return PVE_UNEXPECTED_ERROR;
- }
- if(msg3_size <PROVISION_REQUEST_HEADER_SIZE){
- AESM_DBG_ERROR("Input ProvMsg3 buffer too small");
- return PVE_INSUFFICIENT_MEMORY_ERROR;
- }
- ret = check_prov_msg2_header(msg2_header, msg2_size);//process message header
- if( AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to decode ProvMsg2:(ae%d)",ret);
- return ret;
- }
- if ( 0!=memcmp(msg2_header->xid, data.xid, XID_SIZE) ){
- AESM_DBG_ERROR("unmatched xid in ProvMsg2 header");
- return AE_FAILURE;
- }
- ret = check_epid_pve_pg_status_before_mac_verification(msg2_header);
- if( AE_SUCCESS != ret){
- AESM_DBG_ERROR("Backend server reported error in ProvMsg2:(ae%d)",ret);
- return ret;
- }
- if( 0!=memcpy_s(aad, sizeof(aad), msg2_header, PROVISION_RESPONSE_HEADER_SIZE)){
- AESM_DBG_FATAL("memcpy error");
- return PVE_UNEXPECTED_ERROR;
- }
- do{
- TLVsMsg tlvs_msg2;
- tlv_status_t tlv_status;
- //decode TLV structure of message body
- tlv_status= tlvs_msg2.init_from_buffer(msg2+static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE), msg2_size - static_cast<uint32_t>(PROVISION_RESPONSE_HEADER_SIZE));
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS!=ret){
- AESM_DBG_ERROR("Fail to decode ProvMsg2:(ae%d)",ret);
- break;
- }
- ret = msg2_integrity_checking(tlvs_msg2);//checking and verifying that TLV structure is correct and version is supported
- if(AE_SUCCESS!=ret){
- AESM_DBG_ERROR("ProvMsg2 integrity checking error:(ae%d)",ret);
- break;
- }
- sgx_aes_gcm_128bit_key_t ek2;
- uint8_t temp[NONCE_SIZE+XID_SIZE];
- if(0!=memcpy_s(temp, sizeof(temp), data.xid, sizeof(data.xid))||
- 0!=memcpy_s(temp+XID_SIZE, sizeof(temp)-XID_SIZE, MSG2_TOP_FIELD_NONCE.payload, MSG2_TOP_FIELD_NONCE.size)){
- AESM_DBG_ERROR("memcpy error");
- ret = AE_FAILURE;
- break;
- }
- se_static_assert(sizeof(sgx_cmac_128bit_key_t)==SK_SIZE);
- if((sgx_status=sgx_rijndael128_cmac_msg(reinterpret_cast<const sgx_cmac_128bit_key_t *>(data.sk),
- temp, XID_SIZE+NONCE_SIZE, &ek2))!=SGX_SUCCESS){
- AESM_DBG_ERROR("Fail to generate ek2:(sgx 0x%x)",sgx_status);
- ret = AE_FAILURE;
- break;
- }
- if(tlvs_msg2.get_tlv_count() == MSG2_TOP_FIELDS_COUNT_WITH_SIGRL){//sigrl version and gid is added as part of AAD if available
- sigrl = reinterpret_cast<const se_sig_rl_t *>(MSG2_TOP_FIELD_SIGRL.payload);
- if(0!=memcpy_s(aad+PROVISION_RESPONSE_HEADER_SIZE, sizeof(RLver_t), &sigrl->sig_rl.version, sizeof(RLver_t))){
- AESM_DBG_FATAL("memcpy error");
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- if(0!=memcpy_s(aad+PROVISION_RESPONSE_HEADER_SIZE+sizeof(RLver_t), sizeof(aad)- PROVISION_RESPONSE_HEADER_SIZE-sizeof(RLver_t), &sigrl->sig_rl.gid, sizeof(sigrl->sig_rl.gid))){
- AESM_DBG_FATAL("memcpy error");
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- aad_size += sizeof(RLver_t)+sizeof(GroupId);
- sigrl_size = MSG2_TOP_FIELD_SIGRL.size;
- }
- se_static_assert(SK_SIZE==sizeof(sgx_aes_gcm_128bit_key_t));
- tlv_msg_t field1 = block_cipher_tlv_get_encrypted_text(MSG2_TOP_FIELD_DATA);
- decoded_msg2 = static_cast<uint8_t *>(malloc(field1.msg_size));
- if(NULL == decoded_msg2){
- AESM_DBG_ERROR("malloc error");
- ret= AE_OUT_OF_MEMORY_ERROR;
- break;
- }
- //decrypt ProvMsg2 by EK2
- sgx_status = sgx_rijndael128GCM_decrypt(&ek2,
- field1.msg_buf, field1.msg_size, decoded_msg2,
- reinterpret_cast<uint8_t *>(block_cipher_tlv_get_iv(MSG2_TOP_FIELD_DATA)), IV_SIZE,
- aad, static_cast<uint32_t>(aad_size), reinterpret_cast<const sgx_aes_gcm_128bit_tag_t *>(MSG2_TOP_FIELD_MAC.payload));
- if(SGX_ERROR_MAC_MISMATCH == sgx_status){
- AESM_DBG_ERROR("Fail to decrypt ProvMsg2 body by EK2 (sgx0x%x)",sgx_status);
- ret = PVE_INTEGRITY_CHECK_ERROR;
- break;
- }
- if( AE_SUCCESS != (ret = sgx_error_to_ae_error(sgx_status))){
- AESM_DBG_ERROR("error in decrypting ProvMsg2 body:(sgx0x%x)",sgx_status);
- break;
- }
- ret = check_epid_pve_pg_status_after_mac_verification(msg2_header);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Backend server reported error in ProvMsg2 passed MAC verification:(ae%d)",ret);
- break;
- }
- TLVsMsg tlvs_field1;
- tlv_status = tlvs_field1.init_from_buffer(decoded_msg2, field1.msg_size);//decode TLV structure of field1 of ProvMsg2
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS!=ret){
- AESM_DBG_ERROR("Fail to decode field1 of ProvMsg2:(ae%d)",ret);
- break;
- }
- proc_prov_msg2_blob_input_t msg2_blob_input;
- memset(&msg2_blob_input, 0, sizeof(msg2_blob_input));
- ret = CPCEClass::instance().load_enclave();//Load PCE enclave now
- if( ret != AE_SUCCESS){
- AESM_DBG_ERROR("Fail to load PCE enclave:(ae%d)\n",ret);
- break;
- }
- ret = (ae_error_t)CPCEClass::instance().get_pce_target(&msg2_blob_input.pce_target_info);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("fail to get PCE target info:(ae%d)\n",ret);
- break;
- }
- ret = msg2_field1_msg_check_copy(tlvs_field1, msg2_blob_input, data.pek);//version/type checking to verify message format
- if( AE_SUCCESS != ret){
- AESM_DBG_ERROR("field1 of ProvMsg2 checking error:( ae%d)",ret);
- break;
- }
- gen_prov_msg3_output_t msg3_fixed_output;
- memset(&msg3_fixed_output, 0, sizeof(msg3_fixed_output));
- //collect old epid blob
- if(epid_blob==NULL){
- memset(msg2_blob_input.old_epid_data_blob, 0, SGX_TRUSTED_EPID_BLOB_SIZE_SDK);
- }else{
- #ifdef DBG_LOG
- {
- char dbg_str[256];
- aesm_dbg_format_hex(epid_blob, blob_size, dbg_str, 256);
- AESM_DBG_TRACE("old epid blob=%s",dbg_str);
- }
- #endif
- if (0 != memcpy_s(msg2_blob_input.old_epid_data_blob, sizeof(msg2_blob_input.old_epid_data_blob), epid_blob, blob_size)){
- AESM_DBG_FATAL("memcpy error");
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- }
- if(0!=memcpy_s(&msg2_blob_input.pek,sizeof(msg2_blob_input.pek), &data.pek, sizeof(data.pek))){
- AESM_DBG_ERROR("memcpy error");
- ret = AE_FAILURE;
- break;
- }
- if (AE_SUCCESS != (ret = XEGDBlob::instance().read(msg2_blob_input.xegb))){
- AESM_DBG_ERROR("Fail to read extend epid group blob info ");
- return ret;
- }
- uint32_t epid_sig_output_size = estimate_epid_sig_size(sigrl_size);
- //estimate_epid_sig_size(sigrl_size)=0, which means the sigrl is invalid.
- if(epid_sig_output_size == 0){
- AESM_DBG_ERROR("Invalid SIGRL size %d", sigrl_size);
- ret = PVE_MSG_ERROR;
- break;
- }
- epid_sig = static_cast<uint8_t *>(malloc(epid_sig_output_size));
- if(NULL == epid_sig){
- AESM_DBG_ERROR("malloc error");
- ret = AE_OUT_OF_MEMORY_ERROR;
- break;
- }
- ret = CPVEClass::instance().load_enclave();//Load PvE enclave now
- if( ret != AE_SUCCESS){
- AESM_DBG_ERROR("Fail to load PvE enclave:(ae%d)\n",ret);
- break;
- }
- ret = (ae_error_t)proc_prov_msg2_data(&msg2_blob_input, data.is_performance_rekey, reinterpret_cast<const uint8_t *>(sigrl), sigrl_size,
- &msg3_fixed_output, epid_sig, epid_sig_output_size);//ecall to process msg2 data and generate msg3 data in PvE
- if( PVE_EPIDBLOB_ERROR == ret){
- if(0!=memcpy_s(&data.bpi, sizeof(data.bpi), &msg2_blob_input.previous_pi, sizeof(msg2_blob_input.previous_pi))){
- AESM_DBG_FATAL("memcpy error");
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- }
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("PvE report error (ae%d) in processing ProvMsg2",ret);
- break;
- }
- uint8_t ecdsa_sign[64];
- psvn_t psvn;
- memset(&psvn, 0, sizeof(psvn));
- if(0!=memcpy_s(&psvn.cpu_svn,sizeof(psvn.cpu_svn), &msg2_blob_input.equiv_pi.cpu_svn, sizeof(msg2_blob_input.equiv_pi.cpu_svn))||
- 0!=memcpy_s(&psvn.isv_svn, sizeof(psvn.isv_svn), &msg2_blob_input.equiv_pi.pce_svn, sizeof(msg2_blob_input.equiv_pi.pce_svn))){
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- ret = CPCEClass::instance().load_enclave();//Load PCE enclave now
- if( ret != AE_SUCCESS){
- AESM_DBG_ERROR("Fail to load PCE enclave:(ae%d)\n",ret);
- break;
- }
- ret = (ae_error_t)CPCEClass::instance().sign_report(psvn, msg3_fixed_output.pwk2_report, ecdsa_sign);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("PCE report error (ae%d) in sign report",ret);
- break;
- }
- CPCEClass::instance().unload_enclave();
- uint8_t iv[IV_SIZE];
- uint8_t mac[MAC_SIZE];
- uint8_t *payload_data=NULL;
- uint32_t payload_size = 0;
- ret = aesm_read_rand(iv, IV_SIZE);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("fail to generate random number:(ae%d)",ret);
- break;
- }
- //Now start to generate ProvMsg3
- ret = gen_msg3_header(msg3_fixed_output, data.xid, msg3_header,msg3_size);//first generate header
- if( AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate ProvMsg3 Header:(ae%d)",ret);
- break;
- }
- TLVsMsg tlvs_msg3;
- tlv_status = tlvs_msg3.add_nonce(MSG2_TOP_FIELD_NONCE.payload, NONCE_SIZE);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS!=ret){
- AESM_DBG_ERROR("Fail to generate Nonce TLV in ProvMsg3:(ae%d)",ret);
- break;
- }
- if(msg3_fixed_output.is_join_proof_generated){
- payload_data = msg3_fixed_output.field1_data;
- payload_size = static_cast<uint32_t>(HARD_CODED_JOIN_PROOF_WITH_ESCROW_TLV_SIZE);
- }
- TLVsMsg tlvs_m3field1;
- tlv_status = tlvs_m3field1.add_block_cipher_text(msg3_fixed_output.field1_iv, payload_data, payload_size);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate Field3.1 TLV in ProvMsg3:(ae%d)", ret);
- break;
- }
- tlv_status = tlvs_m3field1.add_mac(msg3_fixed_output.field1_mac);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate Field3.2 TLV in ProvMsg3:(ae%d)",ret);
- break;
- }
- tlv_status = tlvs_m3field1.add_nonce(msg3_fixed_output.n2, NONCE_2_SIZE);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate Field3.3 NONCE TLV N2 in ProvMsg3:(ae %d)",ret);
- break;
- }
- tlv_status = tlvs_m3field1.add_cipher_text(msg3_fixed_output.encrypted_pwk2, RSA_3072_KEY_BYTES, PEK_3072_PUB);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate Field3.4 SE Report TLV in ProvMsg3:(ae %d)",ret);
- break;
- }
- tlv_status = tlvs_m3field1.add_pce_report_sign(msg3_fixed_output.pwk2_report.body, ecdsa_sign);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to generate Field3.5 PCE Report Sign TLV in ProvMsg3:(ae %d)",ret);
- break;
- }
- encrypted_field1 = static_cast<uint8_t *>(malloc(tlvs_m3field1.get_tlv_msg_size()));
- if( NULL == encrypted_field1){
- AESM_DBG_ERROR("malloc error");
- ret = AE_OUT_OF_MEMORY_ERROR;
- break;
- }
- //encrypt field1 using ek2 as key
- sgx_status = sgx_rijndael128GCM_encrypt(&ek2,
- tlvs_m3field1.get_tlv_msg(), tlvs_m3field1.get_tlv_msg_size(), encrypted_field1,
- iv, IV_SIZE, reinterpret_cast<uint8_t *>(msg3_header), PROVISION_REQUEST_HEADER_SIZE,
- reinterpret_cast<sgx_aes_gcm_128bit_tag_t *>(mac));
- if(AE_SUCCESS != (ret = sgx_error_to_ae_error(sgx_status))){
- AESM_DBG_ERROR("fail to encrypt ProvMsg3 body by ek2:(sgx0x%x)",sgx_status);
- break;
- }
- tlv_status = tlvs_msg3.add_block_cipher_text(iv, encrypted_field1, tlvs_m3field1.get_tlv_msg_size());
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to create Field1 TLV of ProvMsg3:(ae%d)",ret);
- break;
- }
- ret = tlv_error_2_pve_error(tlvs_msg3.add_mac(mac));
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to create Field2 TLV of ProvMsg3:(ae%d)",ret);
- break;
- }
- if(msg3_fixed_output.is_epid_sig_generated){
- tlv_status = tlvs_msg3.add_block_cipher_text(msg3_fixed_output.epid_sig_iv, epid_sig, msg3_fixed_output.epid_sig_output_size);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to create Field3 TLV of ProvMsg3:(ae%d)",ret);
- break;
- }
- tlv_status = tlvs_msg3.add_mac(msg3_fixed_output.epid_sig_mac);
- ret = tlv_error_2_pve_error(tlv_status);
- if(AE_SUCCESS != ret){
- AESM_DBG_ERROR("Fail to create Field4 TLV of ProvMsg3:(ae%d)",ret);
- break;
- }
- }
- assert( tlvs_msg3.get_tlv_msg_size() <= msg3_size - PROVISION_REQUEST_HEADER_SIZE);//The checking should have been done in header generation
- if(0!=memcpy_s(msg3+PROVISION_REQUEST_HEADER_SIZE, msg3_size-PROVISION_REQUEST_HEADER_SIZE,
- tlvs_msg3.get_tlv_msg(), tlvs_msg3.get_tlv_msg_size())){
- AESM_DBG_FATAL("memcpy error");
- ret = PVE_UNEXPECTED_ERROR;
- break;
- }
- AESM_DBG_TRACE("ProvMsg3 generated successfully");
- ret = AE_SUCCESS;
- }while(0);
- if(decoded_msg2)free(decoded_msg2);
- if(encrypted_field1) free(encrypted_field1);
- if(epid_sig)free(epid_sig);
- return ret;
- }
|