ae_error_t CertificateProvisioningProtocol::msg3_seq3_2_create_quote_signature_tlv(const upse::Buffer& quote, TLVsMsg& seq3_2_tlv_quote_signature) { ae_error_t status = AESM_PSE_PR_INTERNAL_ERROR; tlv_status_t tlv_status; do { if (sizeof(sgx_quote_t) > quote.getSize()) break; const sgx_quote_t* pQuote = (const sgx_quote_t*)quote.getData(); /* the QUOTE SIGNATURE TLV doesn't include Quote.signature_len */ uint32_t SigLen = pQuote->signature_len; if (sizeof(sgx_quote_t) + SigLen > quote.getSize()) break; const uint8_t *pSig = pQuote->signature; tlv_status = seq3_2_tlv_quote_signature.add_quote_signature(pSig, SigLen); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; status = AE_SUCCESS; } while (0); return status; }
static ae_error_t msg4_field1_msg_checking(const TLVsMsg& tlvs_field1) { uint32_t tlv_count = tlvs_field1.get_tlv_count(); if(tlv_count!=MSG4_FIELD1_COUNT) { return PVE_MSG_ERROR; } uint32_t i; for(i=0; i<tlv_count; ++i) if(tlvs_field1[i].version != TLV_VERSION_1) return PVE_MSG_ERROR; if(MSG4_FIELD1_Nonce2.type != TLV_NONCE || MSG4_FIELD1_Nonce2.size != NONCE_2_SIZE || MSG4_FIELD1_Nonce2.header_size != SMALL_TLV_HEADER_SIZE) return PVE_MSG_ERROR; if(MSG4_FIELD1_ENC_Axf.type != TLV_BLOCK_CIPHER_TEXT|| MSG4_FIELD1_ENC_Axf.size != BLOCK_CIPHER_TEXT_TLV_PAYLOAD_SIZE(HARD_CODED_EPID_MEMBER_WITH_ESCROW_TLV_SIZE)) return PVE_MSG_ERROR; if(MSG4_FIELD1_MAC_Axf.type != TLV_MESSAGE_AUTHENTICATION_CODE|| MSG4_FIELD1_MAC_Axf.size != MAC_SIZE|| MSG4_FIELD1_MAC_Axf.header_size != SMALL_TLV_HEADER_SIZE) return PVE_MSG_ERROR; if(MSG4_FIELD1_GROUP_CERT.type != TLV_EPID_GROUP_CERT|| MSG4_FIELD1_GROUP_CERT.size != sizeof(signed_epid_group_cert_t)|| MSG4_FIELD1_GROUP_CERT.header_size != SMALL_TLV_HEADER_SIZE) return PVE_MSG_ERROR; if (MSG4_FIELD1_PLATFORM_INFO.type != TLV_PLATFORM_INFO || MSG4_FIELD1_PLATFORM_INFO.size != sizeof(bk_platform_info_t) || MSG4_FIELD1_PLATFORM_INFO.header_size != SMALL_TLV_HEADER_SIZE) return PVE_MSG_ERROR; return AE_SUCCESS; }
ae_error_t CertificateProvisioningProtocol::msg1_create_seq3_0(const TLVsMsg& seq3_1_tlv_epid_gid, const provision_request_header_t& serializedHeader, const upse::Buffer& ek1, TLVsMsg& seq3_0_tlv_block_cipher_text, upse::Buffer& mac) { //* 3.0 Block Cipher Text TLV (TLV Type, Type, Version, Size, [IV, EncryptedPayload is 3.1]) ae_error_t status = AE_FAILURE; tlv_status_t tlv_status; do { status = get_random_value(IV_SIZE, M1IV); if (AE_FAILED(status)) break; upse::Buffer aad; status = aad.Alloc(sizeof(serializedHeader)); if (AE_FAILED(status)) break; upse::BufferWriter aadWriter(aad); status = aadWriter.writeRaw((const uint8_t*)&serializedHeader, sizeof(serializedHeader)); if (AE_FAILED(status)) break; upse::Buffer epidGid; status = epidGid.Alloc(seq3_1_tlv_epid_gid.get_tlv_msg(), seq3_1_tlv_epid_gid.get_tlv_msg_size()); if (AE_FAILED(status)) break; upse::Buffer encryptedPayload; status = aesGCMEncrypt(M1IV, ek1, epidGid, aad, encryptedPayload, mac); if (AE_FAILED(status)) break; tlv_status = seq3_0_tlv_block_cipher_text.add_block_cipher_text(M1IV.getData(), encryptedPayload.getData(), encryptedPayload.getSize()); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; status = AE_SUCCESS; } while (0); return status; }
static ae_error_t msg4_integrity_checking(const TLVsMsg& tlvs_msg4) { uint32_t tlv_count = tlvs_msg4.get_tlv_count(); if(tlv_count != MSG4_TOP_FIELDS_COUNT) return PVE_INTEGRITY_CHECK_ERROR; if(MSG4_TOP_FIELD_NONCE.type != TLV_NONCE || MSG4_TOP_FIELD_NONCE.size != NONCE_SIZE || MSG4_TOP_FIELD_NONCE.version != TLV_VERSION_1 || MSG4_TOP_FIELD_NONCE.header_size != SMALL_TLV_HEADER_SIZE) return PVE_INTEGRITY_CHECK_ERROR; if(MSG4_TOP_FIELD_DATA.type != TLV_BLOCK_CIPHER_TEXT || MSG4_TOP_FIELD_DATA.version != TLV_VERSION_1) return PVE_INTEGRITY_CHECK_ERROR; if(MSG4_TOP_FIELD_MAC.type != TLV_MESSAGE_AUTHENTICATION_CODE || MSG4_TOP_FIELD_MAC.version != TLV_VERSION_1 || MSG4_TOP_FIELD_MAC.size != MAC_SIZE || MSG4_TOP_FIELD_MAC.header_size != SMALL_TLV_HEADER_SIZE) return PVE_INTEGRITY_CHECK_ERROR; return AE_SUCCESS; }
ae_error_t CertificateProvisioningProtocol::msg1_create_seq2_0(const TLVsMsg& seq2_1_tlv_block_cipher_info, TLVsMsg& seq2_0_tlv_cipher_text) { //* 2.0 Cipher Text TLV (TLV Type, Type, Version, Size, [KeyID, EncryptedPayload is 2.1]) ae_error_t status = AE_FAILURE; tlv_status_t tlv_status; do { upse::Buffer seq2_1_encrypted_tlv; upse::Buffer encryptedBlockCipherInfo; const public_key_t& public_key = get_intel_pek(); // Encrypt TLV 2.1 upse::Buffer blockCipherInfo; status = blockCipherInfo.Alloc(seq2_1_tlv_block_cipher_info.get_tlv_msg(), seq2_1_tlv_block_cipher_info.get_tlv_msg_size()); if (AE_FAILED(status)) break; upse::BufferReader blockCipherInfoReader(blockCipherInfo); status = encryptRSA_OAEP_SHA256(public_key, blockCipherInfoReader, encryptedBlockCipherInfo); if (AE_FAILED(status)) break; tlv_status = seq2_0_tlv_cipher_text.add_cipher_text(encryptedBlockCipherInfo.getData(), encryptedBlockCipherInfo.getSize(), PEK_3072_PUB); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; status = AE_SUCCESS; } while (0); return status; }
ae_error_t CertificateProvisioningProtocol::msg3_seq3_1_create_quote_tlv(const upse::Buffer& quoteBuffer, TLVsMsg& quoteTLV) { ae_error_t status = AESM_PSE_PR_INTERNAL_ERROR; tlv_status_t tlv_status; do { if (sizeof(sgx_quote_t) > quoteBuffer.getSize()) break; const sgx_quote_t* pQuote = (const sgx_quote_t*)quoteBuffer.getData(); tlv_status = quoteTLV.add_quote((uint8_t*)pQuote, static_cast<uint32_t>(sizeof(sgx_quote_t)-sizeof(pQuote->signature_len))); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; } while (0); return status; }
ae_error_t CertificateProvisioningProtocol::msg1_create_seq2_1(TLVsMsg& seq2_1_tlv_block_cipher_info) { //* 2.1 Block Cipher Info TLV (TLV Type, Type, Version, Size, [SK]) ae_error_t status = AE_FAILURE; tlv_status_t tlv_status; do { status = get_random_value(SK_SIZE, M1SK); if (AE_FAILED(status)) break; tlv_status = seq2_1_tlv_block_cipher_info.add_block_cipher_info(M1SK.getData()); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; status = AE_SUCCESS; } while (0); return status; }
ae_error_t CertificateProvisioningProtocol::msg3_seq3_0_create_block_cipher_text_tlv(const TLVsMsg& quote, const TLVsMsg& epidSigTLV, const TLVsMsg& csrTLV, const TLVsMsg& nonceTLV, const provision_request_header_t& requestHeader, const upse::Buffer& ek2, TLVsMsg& blockCipherTextTLV, upse::Buffer& mac) { ae_error_t status = AE_FAILURE; tlv_status_t tlv_status; upse::Buffer plainText; upse::Buffer encryptedPayload; do { status = get_random_value(IV_SIZE, M3IV); if (AE_FAILED(status)) break; status = plainText.Alloc(quote.get_tlv_msg_size() + epidSigTLV.get_tlv_msg_size() + csrTLV.get_tlv_msg_size()); if (AE_FAILED(status)) break; upse::BufferWriter plainTextWriter(plainText); status = plainTextWriter.writeRaw(quote.get_tlv_msg(), quote.get_tlv_msg_size()); if (AE_FAILED(status)) break; status = plainTextWriter.writeRaw(epidSigTLV.get_tlv_msg(), epidSigTLV.get_tlv_msg_size()); if (AE_FAILED(status)) break; status = plainTextWriter.writeRaw(csrTLV.get_tlv_msg(), csrTLV.get_tlv_msg_size()); if (AE_FAILED(status)) break; uint32_t payloadSize = BLOCK_CIPHER_TEXT_TLV_PAYLOAD_SIZE(plainText.getSize()); uint32_t blockCipherTextHeaderSize = get_tlv_total_size(payloadSize) - payloadSize; // Calculate AAD (concatenation of Request header, Nonce, Block Cipher Text TLV header and IV from Block Cipher Text TLV) upse::Buffer aad; status = aad.Alloc(static_cast<uint32_t>(sizeof(requestHeader) + nonceTLV.get_tlv_msg_size() + blockCipherTextHeaderSize + M3IV.getSize())); if (AE_FAILED(status)) break; TLVsMsg tmpBlockCipherTextTLV; tlv_status = tmpBlockCipherTextTLV.add_block_cipher_text(M3IV.getData(), NULL, plainText.getSize()); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; upse::BufferWriter aadWriter(aad); status = aadWriter.writeRaw((const uint8_t*)&requestHeader, sizeof(requestHeader)); if (AE_FAILED(status)) break; status = aadWriter.writeRaw(nonceTLV.get_tlv_msg(), nonceTLV.get_tlv_msg_size()); if (AE_FAILED(status)) break; status = aadWriter.writeRaw(tmpBlockCipherTextTLV.get_tlv_msg(), blockCipherTextHeaderSize); if (AE_FAILED(status)) break; status = aadWriter.writeRaw(M3IV.getData(), M3IV.getSize()); if (AE_FAILED(status)) break; status = aesGCMEncrypt(M3IV, ek2, plainText, aad, encryptedPayload, mac); if (AE_FAILED(status)) break; tlv_status = blockCipherTextTLV.add_block_cipher_text(M3IV.getData(), encryptedPayload.getData(), encryptedPayload.getSize()); status = tlv_error_2_pve_error(tlv_status); if (AE_FAILED(status)) break; status = AE_SUCCESS; } while (0); return status; }