From nobody Mon Apr 29 02:21:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+72559+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72559+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1615259853; cv=none; d=zohomail.com; s=zohoarc; b=FpRSMSBpox6d61RYzqfJWY03HrHKm0VDy4HxQia3gQ+CiWlhKd7cyzv/zc2xI/AxBa4XuEf+Pq6eMZKkTYE4cFvZ6v6g1WHZQMDJFQ9o7/v0tmr4QgEtPohAiuKHQLaOLloK07aPdSvQMPtfna6C8IjQa5a8g8UUkTXLSy6Xzvw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615259853; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Y20du5yEDUtJcv7YsKQYjadoPPZl0/HHD2qfqLimWTA=; b=eWFHG3EhUg+OT1ZX6Q5/wPYHIcfelHyE8hKKB/qGAt/m63sFUjKtbBsdByytKkL0RyKBFvqDQnRHCR1QEqJ5zT2rRjjNk+07XHpjj3fPflF4nU4RF1imzr5H7ZEyUHu05aTwCRptITNaGcOSvMNVzFIPAtvMmbC1QZIjcyNVvo0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72559+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1615259853157285.974681677833; Mon, 8 Mar 2021 19:17:33 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id pE4RYY1788612xiU7TuzF8A4; Mon, 08 Mar 2021 19:17:32 -0800 X-Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web12.3824.1615259850916862319 for ; Mon, 08 Mar 2021 19:17:32 -0800 IronPort-SDR: O5JiF+6IDGZIZQoXPECod1AViFrLXzzXwI+SOuJ8rlResFoNq1CVgLJ2YrPL+stv7QdFDx0Y9o MyXZx19CCCvQ== X-IronPort-AV: E=McAfee;i="6000,8403,9917"; a="184786126" X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="184786126" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:31 -0800 IronPort-SDR: 0I97Ix6kJ/vF488SfPJXDVJ/lq/mJuw2umWWIxiQ7npR2Fq3emEIQN/bnizrVn/gOtqP7qj8XC kcVIWG/QsHng== X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="409555363" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.4.42]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:29 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Liming Gao , Zhiguang Liu , Jiewen Yao , Doug Reiland Subject: [edk2-devel] [PATCH V2 1/3] MdePkg: Add Tdx support lib Date: Tue, 9 Mar 2021 11:16:56 +0800 Message-Id: <3becb5a42c39003b9306338b41ca16f73f191701.1615257614.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: tQ2wKgR7jjymPR8oimTzP8Yhx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1615259852; bh=26a9jGXwotWCKtgC2em+z/ABbquD8L2+eZwQAKrxRX0=; h=Cc:Date:From:Reply-To:Subject:To; b=mLVp67LcxtAM5bn5t92qFfgOVfm2JlwDAZH6QtziV33sf3TgHvnAVfI9wRWfjZYdThY vaGAjskw/f8TrreDSeSVH+LFluI4ZXjt+DdAST2x7slCRrhyRkMqjyULYwl5adeJDzT0u nK9YvaPAz2MD6nCx53YjohTrCCq+W2dUkwM= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" Intel Trust Domain Extension (Intel TDX) refers to an Intel technology that extends Virtual Machines Extensions (VMX) and Multi-Key Total Memory Encryption (MKTME) with a new kind of virtual machine guest called a Trust Domain (TD). TdxLib is created with functions to perform the related Tdx operation. This includes functions for: - TdCall : to cause a VM exit to the Intel TDX module - TdVmCall : it is a leaf function 0 for TDCALL - TdVmCallCpuid : enable the TD guest to request VMM to emulate CPUID - TdReport : to retrieve TDREPORT_STRUCT - TdAcceptPages : to accept pending private pages - TdExtendRtmr : to extend one of the RTMR registers The base function in this dirver will not do anything and will return an error if a return value is required. It is expected that other packages (like OvmfPkg) will create a version of the library to fully support a TD guest. Cc: Liming Gao Cc: Zhiguang Liu Cc: Jiewen Yao Signed-off-by: Min Xu Signed-off-by: Doug Reiland --- MdePkg/Include/IndustryStandard/Tdx.h | 201 ++++++++++++++++++++++++++ MdePkg/Include/Library/TdxLib.h | 165 +++++++++++++++++++++ MdePkg/Include/Protocol/Tdx.h | 22 +++ MdePkg/Library/TdxLib/TdxLibNull.c | 155 ++++++++++++++++++++ MdePkg/Library/TdxLib/TdxLibNull.inf | 33 +++++ 5 files changed, 576 insertions(+) create mode 100644 MdePkg/Include/IndustryStandard/Tdx.h create mode 100644 MdePkg/Include/Library/TdxLib.h create mode 100644 MdePkg/Include/Protocol/Tdx.h create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.c create mode 100644 MdePkg/Library/TdxLib/TdxLibNull.inf diff --git a/MdePkg/Include/IndustryStandard/Tdx.h b/MdePkg/Include/Industr= yStandard/Tdx.h new file mode 100644 index 000000000000..dbcc31c26528 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/Tdx.h @@ -0,0 +1,201 @@ +/** @file + Intel Trust Domain Extension definitions + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#ifndef _TDX_H_ +#define _TDX_H_ + +#define EXIT_REASON_EXTERNAL_INTERRUPT 1 +#define EXIT_REASON_TRIPLE_FAULT 2 + +#define EXIT_REASON_PENDING_INTERRUPT 7 +#define EXIT_REASON_NMI_WINDOW 8 +#define EXIT_REASON_TASK_SWITCH 9 +#define EXIT_REASON_CPUID 10 +#define EXIT_REASON_HLT 12 +#define EXIT_REASON_INVD 13 +#define EXIT_REASON_INVLPG 14 +#define EXIT_REASON_RDPMC 15 +#define EXIT_REASON_RDTSC 16 +#define EXIT_REASON_VMCALL 18 +#define EXIT_REASON_VMCLEAR 19 +#define EXIT_REASON_VMLAUNCH 20 +#define EXIT_REASON_VMPTRLD 21 +#define EXIT_REASON_VMPTRST 22 +#define EXIT_REASON_VMREAD 23 +#define EXIT_REASON_VMRESUME 24 +#define EXIT_REASON_VMWRITE 25 +#define EXIT_REASON_VMOFF 26 +#define EXIT_REASON_VMON 27 +#define EXIT_REASON_CR_ACCESS 28 +#define EXIT_REASON_DR_ACCESS 29 +#define EXIT_REASON_IO_INSTRUCTION 30 +#define EXIT_REASON_MSR_READ 31 +#define EXIT_REASON_MSR_WRITE 32 +#define EXIT_REASON_INVALID_STATE 33 +#define EXIT_REASON_MSR_LOAD_FAIL 34 +#define EXIT_REASON_MWAIT_INSTRUCTION 36 +#define EXIT_REASON_MONITOR_TRAP_FLAG 37 +#define EXIT_REASON_MONITOR_INSTRUCTION 39 +#define EXIT_REASON_PAUSE_INSTRUCTION 40 +#define EXIT_REASON_MCE_DURING_VMENTRY 41 +#define EXIT_REASON_TPR_BELOW_THRESHOLD 43 +#define EXIT_REASON_APIC_ACCESS 44 +#define EXIT_REASON_EOI_INDUCED 45 +#define EXIT_REASON_GDTR_IDTR 46 +#define EXIT_REASON_LDTR_TR 47 +#define EXIT_REASON_EPT_VIOLATION 48 +#define EXIT_REASON_EPT_MISCONFIG 49 +#define EXIT_REASON_INVEPT 50 +#define EXIT_REASON_RDTSCP 51 +#define EXIT_REASON_PREEMPTION_TIMER 52 +#define EXIT_REASON_INVVPID 53 +#define EXIT_REASON_WBINVD 54 +#define EXIT_REASON_XSETBV 55 +#define EXIT_REASON_APIC_WRITE 56 +#define EXIT_REASON_RDRAND 57 +#define EXIT_REASON_INVPCID 58 +#define EXIT_REASON_VMFUNC 59 +#define EXIT_REASON_ENCLS 60 +#define EXIT_REASON_RDSEED 61 +#define EXIT_REASON_PML_FULL 62 +#define EXIT_REASON_XSAVES 63 +#define EXIT_REASON_XRSTORS 64 + +// TDCALL API Function Completion Status Codes +#define TDX_EXIT_REASON_SUCCESS 0x0000000000000000 +#define TDX_EXIT_REASON_PAGE_ALREADY_ACCEPTED 0x00000B0A00000000 +#define TDX_EXIT_REASON_OPERAND_INVALID 0xC000010000000000 +#define TDX_EXIT_REASON_OPERAND_BUSY 0x8000020000000000 + +#define TDCALL_TDVMCALL 0 +#define TDCALL_TDINFO 1 +#define TDCALL_TDEXTENDRTMR 2 +#define TDCALL_TDGETVEINFO 3 +#define TDCALL_TDREPORT 4 +#define TDCALL_TDSETCPUIDVE 5 +#define TDCALL_TDACCEPTPAGE 6 + +#define TDVMCALL_CPUID 0x0000a +#define TDVMCALL_HALT 0x0000c +#define TDVMCALL_IO 0x0001e +#define TDVMCALL_RDMSR 0x0001f +#define TDVMCALL_WRMSR 0x00020 +#define TDVMCALL_MMIO 0x00030 +#define TDVMCALL_PCONFIG 0x00041 + +#define TDVMCALL_GET_TDVMCALL_INFO 0x10000 +#define TDVMCALL_MAPGPA 0x10001 +#define TDVMCALL_GET_QUOTE 0x10002 +#define TDVMCALL_REPORT_FATAL_ERR 0x10003 +#define TDVMCALL_SETUP_EVENT_NOTIFY 0x10004 + +#pragma pack(1) +typedef struct { + UINT64 Data[6]; +} TDCALL_GENERIC_RETURN_DATA; + +typedef struct { + UINT64 Gpaw; + UINT64 Attributes; + UINT32 MaxVcpus; + UINT32 NumVcpus; + UINT64 Resv[3]; +} TDCALL_INFO_RETURN_DATA; + +typedef union { + UINT64 Val; + struct { + UINT32 Size:3; + UINT32 Direction:1; + UINT32 String:1; + UINT32 Rep:1; + UINT32 Encoding:1; + UINT32 Resv:9; + UINT32 Port:16; + UINT32 Resv2; + } Io; +} VMX_EXIT_QUALIFICATION; + +typedef struct { + UINT32 ExitReason; + UINT32 Resv; + VMX_EXIT_QUALIFICATION ExitQualification; + UINT64 GuestLA; + UINT64 GuestPA; + UINT32 ExitInstructionLength; + UINT32 ExitInstructionInfo; + UINT32 Resv1; +} TDCALL_VEINFO_RETURN_DATA; + +typedef union { + TDCALL_GENERIC_RETURN_DATA Generic; + TDCALL_INFO_RETURN_DATA TdInfo; + TDCALL_VEINFO_RETURN_DATA VeInfo; +} TD_RETURN_DATA; + +/* data structure used in TDREPORT_STRUCT */ +typedef struct{ + UINT8 Type; + UINT8 Subtype; + UINT8 Version; + UINT8 Rsvd; +}TD_REPORT_TYPE; + +typedef struct{ + TD_REPORT_TYPE ReportType; + UINT8 Rsvd1[12]; + UINT8 CpuSvn[16]; + UINT8 TeeTcbInfoHash[48]; + UINT8 TeeInfoHash[48]; + UINT8 ReportData[64]; + UINT8 Rsvd2[32]; + UINT8 Mac[32]; +}REPORTMACSTRUCT; + +typedef struct{ + UINT8 Seam[2]; + UINT8 Rsvd[14]; +}TEE_TCB_SVN; + +typedef struct{ + UINT8 Valid[8]; + TEE_TCB_SVN TeeTcbSvn; + UINT8 Mrseam[48]; + UINT8 Mrsignerseam[48]; + UINT8 Attributes[8]; + UINT8 Rsvd[111]; +}TEE_TCB_INFO; + +typedef struct{ + UINT8 Attributes[8]; + UINT8 Xfam[8]; + UINT8 Mrtd[48]; + UINT8 Mrconfigid[48]; + UINT8 Mrowner[48]; + UINT8 Mrownerconfig[48]; + UINT8 Rtmrs[4][48]; + UINT8 Rsvd[112]; +}TDINFO; + +typedef struct{ + REPORTMACSTRUCT ReportMacStruct; + TEE_TCB_INFO TeeTcbInfo; + UINT8 Rsvd[17]; + TDINFO Tdinfo; +}TDREPORT_STRUCT; + +#pragma pack() + +#endif + diff --git a/MdePkg/Include/Library/TdxLib.h b/MdePkg/Include/Library/TdxLi= b.h new file mode 100644 index 000000000000..5e8634c6df79 --- /dev/null +++ b/MdePkg/Include/Library/TdxLib.h @@ -0,0 +1,165 @@ +/** @file + TdxLib definitions + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#ifndef _TDX_LIB_H_ +#define _TDX_LIB_H_ + +#include +#include +#include +#include + +/** + This function retrieve TDREPORT_STRUCT structure from TDX. + The struct contains the measurements/configuration information of + the guest TD that called the function, measurements/configuratio + information of the TDX-SEAM module and a REPORTMACSTRUCT. + The REPORTMACSTRUCT is integrity protected with a MAC and + contains the hash of the measurements and configuration + as well as additional REPORTDATA provided by the TD software. + + AdditionalData, a 64-byte value, is provided by the guest TD + to be included in the TDREPORT + + @param[in,out] Report Holds the TEREPORT_STRUCT. + @param[in] ReportSize Size of the report. It must be + larger than 1024B. + @param[in] AdditionalData Point to the additional data. + @param[in] AdditionalDataSize Size of the additional data. + If AdditionalData !=3D NULL, then + this value must be 64B. + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdReport( + IN OUT UINT8 *Report, + IN UINT32 ReportSize, + IN UINT8 *AdditionalData, + IN UINT32 AdditionalDataSize +); + +/** + This function accept a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + @param[in] StartAddress Guest physical address of the private page + to accept. + @param[in] NumberOfPages Number of the pages to be accepted. + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages + ); + +/** + This function extends one of the RTMR measurement register + in TDCS with the provided extension data in memory. + RTMR extending supports SHA384 which length is 48 bytes. + + @param[in] Data Point to the data to be extended + @param[in] DataLen Length of the data. Must be 48 + @param[in] Index RTMR index + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdExtendRtmr( + IN UINT32 *Data, + IN UINT32 DataLen, + IN UINT8 PcrIndex + ); + +/** + The TDCALL instruction causes a VM exit to the Intel TDX module. It is + used to call guest-side Intel TDX functions, either local or a TD exit + to the host VMM, as selected by Leaf. + Leaf functions are described at + + @param[in] Leaf Leaf number of TDCALL instruction + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in,out] Results Returned result of the Leaf function + + @return EFI_SUCCESS + @return Other See individual leaf functions +**/ +EFI_STATUS +EFIAPI +TdCall( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN OUT VOID *Results + ); + +/** + TDVMALL is a leaf function 0 for TDCALL. It helps invoke services from t= he + host VMM to pass/receive information. + + @param[in] Leaf Number of sub-functions + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in] Arg4 Arg4 + @param[in,out] Results Returned result of the sub-function + + @return EFI_SUCCESS + @return Other See individual sub-functions + +**/ +EFI_STATUS +EFIAPI +TdVmCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN OUT VOID *Results + ); + +/** + This function enable the TD guest to request the VMM to emulate CPUID + operation, especially for non-architectural, CPUID leaves. + + @param[in] Eax Main leaf of the CPUID + @param[in] Ecx Sub-leaf of the CPUID + @param[out] Results Returned result of CPUID operation + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdVmCallCpuid ( + IN UINT64 Eax, + IN UINT64 Ecx, + OUT VOID *Results + ); +#endif diff --git a/MdePkg/Include/Protocol/Tdx.h b/MdePkg/Include/Protocol/Tdx.h new file mode 100644 index 000000000000..d3e1eae13559 --- /dev/null +++ b/MdePkg/Include/Protocol/Tdx.h @@ -0,0 +1,22 @@ +/** @file + Tcg for Intel TDX definitions. + +Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#ifndef __TCG_TDX_H__ +#define __TCG_TDX_H__ + +#include + +#define TCG_TDX_EVENT_DATA_SIGNATURE SIGNATURE_32 ('T', 'D', 'X', 'S') + +#define TD_TCG2_PROTOCOL_GUID \ + {0x96751a3d, 0x72f4, 0x41a6, { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae,= 0x6b }} +extern EFI_GUID gTdTcg2ProtocolGuid; + + +#endif diff --git a/MdePkg/Library/TdxLib/TdxLibNull.c b/MdePkg/Library/TdxLib/Tdx= LibNull.c new file mode 100644 index 000000000000..8d759e4d33a4 --- /dev/null +++ b/MdePkg/Library/TdxLib/TdxLibNull.c @@ -0,0 +1,155 @@ +/** @file + Null instance of TdxLib. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + + +#include +#include +#include +#include + +/** + This function retrieve TDREPORT_STRUCT structure from TDX. + The struct contains the measurements/configuration information of + the guest TD that called the function, measurements/configuratio + information of the TDX-SEAM module and a REPORTMACSTRUCT. + The REPORTMACSTRUCT is integrity protected with a MAC and + contains the hash of the measurements and configuration + as well as additional REPORTDATA provided by the TD software. + + AdditionalData, a 64-byte value, is provided by the guest TD + to be included in the TDREPORT + + @param[in,out] Report Holds the TEREPORT_STRUCT. + @param[in] ReportSize Size of the report. It must be + larger than 1024B. + @param[in] AdditionalData Point to the additional data. + @param[in] AdditionalDataSize Size of the additional data. + If AdditionalData !=3D NULL, then + this value must be 64B. + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdReport( + IN OUT UINT8 *Report, + IN UINT32 ReportSize, + IN UINT8 *AdditionalData, + IN UINT32 AdditionalDataSize + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function accept a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + @param[in] StartAddress Guest physical address of the private page + to accept. + @param[in] NumberOfPages Number of the pages to be accepted. + + @return EFI_UNSUPPORTED +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages + ) +{ + return EFI_UNSUPPORTED; +} + +/** + The TDCALL instruction causes a VM exit to the Intel TDX module. It is + used to call guest-side Intel TDX functions, either local or a TD exit + to the host VMM, as selected by Leaf. + Leaf functions are described at + + @param[in] Leaf Leaf number of TDCALL instruction + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in,out] Results Returned result of the Leaf function + + @return EFI_SUCCESS + @return Other See individual leaf functions +**/ +EFI_STATUS +EFIAPI +TdCall( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN OUT VOID *Results + ) +{ + return EFI_UNSUPPORTED; +} + +/** + TDVMALL is a leaf function 0 for TDCALL. It helps invoke services from t= he + host VMM to pass/receive information. + + @param[in] Leaf Number of sub-functions + @param[in] Arg1 Arg1 + @param[in] Arg2 Arg2 + @param[in] Arg3 Arg3 + @param[in] Arg4 Arg4 + @param[in,out] Results Returned result of the sub-function + + @return EFI_SUCCESS + @return Other See individual sub-functions + +**/ +EFI_STATUS +EFIAPI +TdVmCall ( + IN UINT64 Leaf, + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN OUT VOID *Results + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function enable the TD guest to request the VMM to emulate CPUID + operation, especially for non-architectural, CPUID leaves. + + @param[in] Eax Main leaf of the CPUID + @param[in] Ecx Sub-leaf of the CPUID + @param[in,out] Results Returned result of CPUID operation + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdVmCallCpuid ( + IN UINT64 Eax, + IN UINT64 Ecx, + IN OUT VOID *Results + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdePkg/Library/TdxLib/TdxLibNull.inf b/MdePkg/Library/TdxLib/T= dxLibNull.inf new file mode 100644 index 000000000000..0d07595a8c3e --- /dev/null +++ b/MdePkg/Library/TdxLib/TdxLibNull.inf @@ -0,0 +1,33 @@ +## @file +# Null Tdx library instance +# +# Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BS= D License +# which accompanies this distribution. The full text of the license may b= e found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TdxLibNull + FILE_GUID =3D 05C5E621-FC66-4420-9C80-F0DE9E5B95FF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TdxLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +[Sources] + TdxLibNull.c + +[Packages] + MdePkg/MdePkg.dec --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#72559): https://edk2.groups.io/g/devel/message/72559 Mute This Topic: https://groups.io/mt/81193345/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon Apr 29 02:21:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+72560+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72560+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1615259854; cv=none; d=zohomail.com; s=zohoarc; b=TLT0Yf/XlI9PZxp6R9ykGSC3ANC9sPhWYhZQj+SgFE9UK3ZNmodgrV1oqDugYqOd/Gsh9/hRFRgZXE3Ak7HHEIm6tThaHDKTyyzpOXwljOFs8R3je9iHKf2dpaAio7o846ea7LuUatLNgvnJ6I76EXRPVxX7BNsJFpZCFreel8U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615259854; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=cQV8Oo1GRoFtWddKKV9iG/1+fMQ9Jh7IaTRyutt4DKQ=; b=WAWwEfeOosF7iax2QNP8Jf2i2UvxAZ2oBPxdOF4j+t1wm6l13JgkfjpBJOXKtLU6PvOBWBChI/a4wKKO0XYPEDt+pYWu1bL4fAHGNWkX8hZxFG7coiUEmIBVlZr0Sg8qEkwGErOLzAtWAFVlOw7xme47nNTek+McADaswA7Adzw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72560+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 161525985462790.02342142155601; Mon, 8 Mar 2021 19:17:34 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id V6WMYY1788612x4w7P3uB38h; Mon, 08 Mar 2021 19:17:34 -0800 X-Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web12.3824.1615259850916862319 for ; Mon, 08 Mar 2021 19:17:33 -0800 IronPort-SDR: DSdYDUAEqQj/0mEFXa84fiqCf1Pv/Cj6V9RnSwldSxHXmjPqNwiCelVgcZpvIjKE7UfLuDrSi4 qahGvUDja2Ug== X-IronPort-AV: E=McAfee;i="6000,8403,9917"; a="184786132" X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="184786132" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:33 -0800 IronPort-SDR: TQYnXgX08tdNiX1Eugd+WKWIt31/RWbP4ZQZij0RMwCl26pIIlfC8Fmd8B1J1m1gXISWHSDko1 kzPnLisD8Fdg== X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="409555377" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.4.42]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:31 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Jordan Justen , Laszlo Ersek , Jiewen Yao , Doug Reiland Subject: [edk2-devel] [PATCH V2 2/3] OvmfPkg: Add PCDs for TdxLib Date: Tue, 9 Mar 2021 11:16:57 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: EGNrNRRP3nlS6nIQ0uFk2ZQCx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1615259854; bh=vxsAvSXcGGZ4ucwrY1zHuEmtf8NBzE02tfo9ca/hF7I=; h=Cc:Date:From:Reply-To:Subject:To; b=tm/chRAg9blkzuEkLKDjl62xT8X/kk9HrQVoIFVtf5t9g+171OQa39d6usLfM8Lf+g1 J5cms1P46zL2V2FFZo5CU/RGPUBvjX5khDDM496kTAqgDcfOHvHhtZD78b0lEGeuzleeb FYZgpz3C3gJmmKlNSqemo1dInbOurFFsgoI= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" TdxLib for OvmfPkg depends on the below PCDs - PcdUseTdxAcceptPage Indicate whether TdCall(AcceptPage) is used. - PcdUseTdxEmulation Indicate whether TdxEmulation is used. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Jiewen Yao Signed-off-by: Min Xu Signed-off-by: Doug Reiland --- OvmfPkg/OvmfPkg.dec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 4348bb45c64a..68b3fd86d516 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -317,6 +317,12 @@ gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretBase|0x0|UINT32|0x42 gUefiOvmfPkgTokenSpaceGuid.PcdSevLaunchSecretSize|0x0|UINT32|0x43 =20 + ## Indicate whether TdCall(AcceptPage) is used. + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage|TRUE|BOOLEAN|0x44 + ## Indicate whether TdxEmulation is used. + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation|0x1|UINT32|0x45 + + [PcdsDynamic, PcdsDynamicEx] gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10 --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#72560): https://edk2.groups.io/g/devel/message/72560 Mute This Topic: https://groups.io/mt/81193346/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Mon Apr 29 02:21:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+72561+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72561+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1615259861; cv=none; d=zohomail.com; s=zohoarc; b=nAMdwwDpeik10tEHOGrSlr+r3OTwP6ickRdoA/5ShbCAmgXq3B4Wkit2LIcqngmznFf9DYAO8oEyl/e+NOc1Zinl34qpcR/nvGwA4RZ31bwq0fuzaoynT8LzV+BnpxgwfGOnaCkbhlg0TohIv1wzZwgD+dpg0/RKMh8QyVyaoKA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615259861; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=7iaUUpRNgimhxYLBDE/gy2Qyi8znxzL+9U+HUIQedXQ=; b=ILFuGuFHJMEUdIPshEjp0f4QoGNIFAC3Wa9UtLDC9FZQ/ZLtbZn/yWUnfOxXEpQdmlz7RyYjGHe2ssBmCnok5cIl2Uf4/1DByWBGFSBfnrc1Z6DUnD3MCm0KmVHeiOleaXHcYU7hPk24sY6gyjtdqZP+q7kmXnH8RMhd8VY1WUg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+72561+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1615259861980280.60014883951624; Mon, 8 Mar 2021 19:17:41 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id RVnxYY1788612xZNVOysEs6n; Mon, 08 Mar 2021 19:17:41 -0800 X-Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web12.3824.1615259850916862319 for ; Mon, 08 Mar 2021 19:17:36 -0800 IronPort-SDR: hdWZOzjaMYAF6ECXvO2MFZVotVfZ3yBP/R3CHiFbaUHlRDYQoi6yoTjAyp4TSGcyoeXKzIP/fq 7m9wfYZMt5zQ== X-IronPort-AV: E=McAfee;i="6000,8403,9917"; a="184786138" X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="184786138" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:35 -0800 IronPort-SDR: njOB4chRGD2bOWOFNH4etRmFCsB3syhAjBaz7cB9At/pu2s724GAKVcrY5zPQQ17MewWQyALwf WL8w48aVqOkA== X-IronPort-AV: E=Sophos;i="5.81,234,1610438400"; d="scan'208";a="409555391" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.238.4.42]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2021 19:17:33 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Jordan Justen , Laszlo Ersek , Jiewen Yao , Doug Reiland Subject: [edk2-devel] [PATCH V2 3/3] OvmfPkg: Implement library support for TdxLib SEC and DXE on OVMF Date: Tue, 9 Mar 2021 11:16:58 +0800 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: yRWB4IoQ05tjkKe6la7QDHEwx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1615259861; bh=1tRGZBlXCd2PuCJVw/P1NZMf1t2KX1VF28JwlOUAPMo=; h=Cc:Date:From:Reply-To:Subject:To; b=UqbQnqhPNdaK3FJZ2l07S4blrgVVhTHLoEGH0o+5tbprKRBWHszOAbdysOrzBVMyZ0q 4Ebp/RWOgwOt1GM2mh08rygy0XnHImi0cWMnh5uzKNI6O+G95t+P246EtAoYm7bUwdLgQ /2h3/QMyKKyayIbaLgfUcNlVVGS0LI8udq4= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" The base TdxLib in MdePkg/Library provides a default limited interface. As it does not provide full support, create an OVMF version of this library to begin the process of providing full support of TDX in OVMF. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Jiewen Yao Signed-off-by: Min Xu Signed-off-by: Doug Reiland --- OvmfPkg/Library/TdxLib/AcceptPages.c | 68 ++++++++ OvmfPkg/Library/TdxLib/Rtmr.c | 80 +++++++++ OvmfPkg/Library/TdxLib/TdReport.c | 102 +++++++++++ OvmfPkg/Library/TdxLib/TdxLib.inf | 48 ++++++ OvmfPkg/Library/TdxLib/TdxLibSec.inf | 45 +++++ OvmfPkg/Library/TdxLib/X64/Tdcall.nasm | 125 ++++++++++++++ OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm | 211 +++++++++++++++++++++++ 7 files changed, 679 insertions(+) create mode 100644 OvmfPkg/Library/TdxLib/AcceptPages.c create mode 100644 OvmfPkg/Library/TdxLib/Rtmr.c create mode 100644 OvmfPkg/Library/TdxLib/TdReport.c create mode 100644 OvmfPkg/Library/TdxLib/TdxLib.inf create mode 100644 OvmfPkg/Library/TdxLib/TdxLibSec.inf create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdcall.nasm create mode 100644 OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm diff --git a/OvmfPkg/Library/TdxLib/AcceptPages.c b/OvmfPkg/Library/TdxLib/= AcceptPages.c new file mode 100644 index 000000000000..3848bb6a95a4 --- /dev/null +++ b/OvmfPkg/Library/TdxLib/AcceptPages.c @@ -0,0 +1,68 @@ +/** @file + + There are 4 defined types in TD memory. + Unaccepted memory is a special type of private memory. The OVMF must + invoke TDCALL [TDG.MEM.PAGE.ACCEPT] the unaccepted memory before use it. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +UINT64 mNumberOfDuplicatedAcceptedPages; + +/** + This function accept a pending private page, and initialize the page to + all-0 using the TD ephemeral private key. + + @param[in] StartAddress Guest physical address of the private + page to accept. + @param[in] NumberOfPages Number of the pages to be accepted. + + @return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +TdAcceptPages ( + IN UINT64 StartAddress, + IN UINT64 NumberOfPages + ) +{ + UINT64 Address; + UINT64 Status; + UINT64 Index; + + // + // Determine if we need to accept pages before use + // + if (FixedPcdGetBool(PcdUseTdxAcceptPage) =3D=3D FALSE) { + return EFI_SUCCESS; + } + + Address =3D StartAddress; + + for( Index =3D 0; Index < NumberOfPages; Index++) { + Status =3D TdCall(TDCALL_TDACCEPTPAGE,Address, 0, 0, 0); + if (Status !=3D TDX_EXIT_REASON_SUCCESS) { + if ((Status & ~0xFFULL) =3D=3D TDX_EXIT_REASON_PAGE_ALREADY_ACCEPT= ED) { + ++mNumberOfDuplicatedAcceptedPages; + DEBUG((DEBUG_VERBOSE, "Address %llx already accepted. Total numb= er of already accepted pages %ld\n", + Address, mNumberOfDuplicatedAcceptedPages)); + } else { + DEBUG((DEBUG_ERROR, "Address %llx failed to be accepted. Error = =3D %ld\n", + Address, Status)); + ASSERT(Status =3D=3D TDX_EXIT_REASON_SUCCESS); + } + } + Address +=3D EFI_PAGE_SIZE; + } + return EFI_SUCCESS; +} + diff --git a/OvmfPkg/Library/TdxLib/Rtmr.c b/OvmfPkg/Library/TdxLib/Rtmr.c new file mode 100644 index 000000000000..a4b36b6c4bef --- /dev/null +++ b/OvmfPkg/Library/TdxLib/Rtmr.c @@ -0,0 +1,80 @@ +/** @file + + Extends one of the RTMR measurement registers in TDCS with the provided + extension data in memory. + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTMR_COUNT 4 + +/** + This function extends one of the RTMR measurement register + in TDCS with the provided extension data in memory. + RTMR extending supports SHA384 which length is 48 bytes. + + @param[in] Data Point to the data to be extended + @param[in] DataLen Length of the data. Must be 48 + @param[in] Index RTMR index + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdExtendRtmr( + IN UINT32 *Data, + IN UINT32 DataLen, + IN UINT8 Index + ) +{ + EFI_STATUS Status; + UINT64 *Buffer; + UINT64 TdCallStatus; + + Status =3D EFI_SUCCESS; + + ASSERT(Index >=3D 0 && Index < RTMR_COUNT); + ASSERT(DataLen =3D=3D SHA384_DIGEST_SIZE); + + // + // Allocate 64B aligned mem to hold the sha384 hash value + // + Buffer =3D AllocateAlignedPages(EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE), 6= 4); + if(Data =3D=3D NULL){ + return EFI_OUT_OF_RESOURCES; + } + CopyMem(Buffer, Data, SHA384_DIGEST_SIZE); + + TdCallStatus =3D TdCall(TDCALL_TDEXTENDRTMR, (UINT64)Buffer, Index, 0, 0= ); + + if(TdCallStatus =3D=3D TDX_EXIT_REASON_SUCCESS){ + Status =3D EFI_SUCCESS; + }else if(TdCallStatus =3D=3D TDX_EXIT_REASON_OPERAND_INVALID){ + Status =3D EFI_INVALID_PARAMETER; + }else{ + Status =3D EFI_DEVICE_ERROR; + } + + if(Status !=3D EFI_SUCCESS){ + DEBUG((DEBUG_ERROR, "Error returned from TdExtendRtmr call - 0x%lx\n",= TdCallStatus)); + } + + FreeAlignedPages(Buffer, EFI_SIZE_TO_PAGES(SHA384_DIGEST_SIZE)); + + return Status; +} diff --git a/OvmfPkg/Library/TdxLib/TdReport.c b/OvmfPkg/Library/TdxLib/TdR= eport.c new file mode 100644 index 000000000000..ace213bcf467 --- /dev/null +++ b/OvmfPkg/Library/TdxLib/TdReport.c @@ -0,0 +1,102 @@ +/** @file + + Retrieve TDREPORT_STRUCT structure from TDX + + Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#define REPORT_STRUCT_SIZE 1024 +#define ADDITIONAL_DATA_SIZE 64 + +/** + This function retrieve TDREPORT_STRUCT structure from TDX. + The struct contains the measurements/configuration information of + the guest TD that called the function, measurements/configuratio + information of the TDX-SEAM module and a REPORTMACSTRUCT. + The REPORTMACSTRUCT is integrity protected with a MAC and + contains the hash of the measurements and configuration + as well as additional REPORTDATA provided by the TD software. + + AdditionalData, a 64-byte value, is provided by the guest TD + to be included in the TDREPORT + + @param[in,out] Report Holds the TEREPORT_STRUCT. + @param[in] ReportSize Size of the report. It must be + larger than 1024B. + @param[in] AdditionalData Point to the additional data. + @param[in] AdditionalDataSize Size of the additional data. + If AdditionalData !=3D NULL, then + this value must be 64B. + + @return EFI_SUCCESS + @return EFI_INVALID_PARAMETER + @return EFI_DEVICE_ERROR + +**/ +EFI_STATUS +EFIAPI +TdReport( + IN OUT UINT8 *Report, + IN UINT32 ReportSize, + IN UINT8 *AdditionalData, + IN UINT32 AdditionalDataSize + ) + +{ + EFI_STATUS Status; + UINT64 *Data; + UINT64 *Report_Struct; + UINT64 *Report_Data; + UINT64 TdCallStatus; + + if(ReportSize < REPORT_STRUCT_SIZE){ + return EFI_INVALID_PARAMETER; + } + + if(AdditionalData !=3D NULL && AdditionalDataSize !=3D ADDITIONAL_DATA_S= IZE){ + return EFI_INVALID_PARAMETER; + } + + Data =3D AllocatePages(EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE + ADDITIONAL= _DATA_SIZE)); + if(Data =3D=3D NULL){ + return EFI_OUT_OF_RESOURCES; + } + + Report_Struct =3D Data; + Report_Data =3D Data + REPORT_STRUCT_SIZE; + if(AdditionalData !=3D NULL){ + CopyMem(Report_Data, AdditionalData, ADDITIONAL_DATA_SIZE); + }else{ + ZeroMem(Report_Data, ADDITIONAL_DATA_SIZE); + } + + TdCallStatus =3D TdCall(TDCALL_TDREPORT, (UINT64)Report_Struct, (UINT64)= Report_Data, 0, 0); + + if(TdCallStatus =3D=3D TDX_EXIT_REASON_SUCCESS){ + Status =3D EFI_SUCCESS; + }else if(TdCallStatus =3D=3D TDX_EXIT_REASON_OPERAND_INVALID){ + Status =3D EFI_INVALID_PARAMETER; + }else{ + Status =3D EFI_DEVICE_ERROR; + } + + if(Status !=3D EFI_SUCCESS){ + DEBUG((DEBUG_ERROR, "Error returned from TdReport call - 0x%lx\n", TdC= allStatus)); + }else{ + CopyMem(Report, Data, REPORT_STRUCT_SIZE); + } + + FreePages(Data, EFI_SIZE_TO_PAGES(REPORT_STRUCT_SIZE + ADDITIONAL_DATA_S= IZE)); + + return Status; +} diff --git a/OvmfPkg/Library/TdxLib/TdxLib.inf b/OvmfPkg/Library/TdxLib/Tdx= Lib.inf new file mode 100644 index 000000000000..f642de9e3a5f --- /dev/null +++ b/OvmfPkg/Library/TdxLib/TdxLib.inf @@ -0,0 +1,48 @@ +## @file +# Tdx library +# +# Copyright (c) 2020- 2021, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BS= D License +# which accompanies this distribution. The full text of the license may b= e found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TdxLib + FILE_GUID =3D 032A8E0D-0C27-40C0-9CAA-23B731C1B223 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TdxLib|PEI_CORE PEIM DXE_CORE DXE_DRI= VER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +[Sources] + Rtmr.c + TdReport.c + AcceptPages.c + X64/Tdcall.nasm + X64/Tdvmcall.nasm + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation diff --git a/OvmfPkg/Library/TdxLib/TdxLibSec.inf b/OvmfPkg/Library/TdxLib/= TdxLibSec.inf new file mode 100644 index 000000000000..82ef4f08be8c --- /dev/null +++ b/OvmfPkg/Library/TdxLib/TdxLibSec.inf @@ -0,0 +1,45 @@ +## @file +# Tdx library for SEC phase. +# +# Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BS= D License +# which accompanies this distribution. The full text of the license may b= e found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TdxLibSec + FILE_GUID =3D 498E8E1E-5B11-41F3-9083-EEE3A32B009D + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TdxLib|SEC + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 +# + +[Sources] + AcceptPages.c + X64/Tdcall.nasm + X64/Tdvmcall.nasm + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxAcceptPage + gUefiOvmfPkgTokenSpaceGuid.PcdUseTdxEmulation diff --git a/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm b/OvmfPkg/Library/TdxLi= b/X64/Tdcall.nasm new file mode 100644 index 000000000000..d0d55e2a9443 --- /dev/null +++ b/OvmfPkg/Library/TdxLib/X64/Tdcall.nasm @@ -0,0 +1,125 @@ +;-------------------------------------------------------------------------= ----- +;* +;* Copyright (c) 2020, Intel Corporation. All rights reserved.
+;* This program and the accompanying materials +;* are licensed and made available under the terms and conditions of the= BSD License +;* which accompanies this distribution. The full text of the license ma= y be found at +;* http://opensource.org/licenses/bsd-license.php +;* +;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR = IMPLIED. +;* +;* +;-------------------------------------------------------------------------= ----- + +DEFAULT REL +SECTION .text + +%macro tdcall 0 +%if (FixedPcdGet32 (PcdUseTdxEmulation) !=3D 0) + vmcall +%else + db 0x66,0x0f,0x01,0xcc +%endif +%endmacro + +%macro tdcall_push_regs 0 + push rbp + mov rbp, rsp + push r15 + push r14 + push r13 + push r12 + push rbx + push rsi + push rdi +%endmacro + +%macro tdcall_pop_regs 0 + pop rdi + pop rsi + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + pop rbp +%endmacro + +%define number_of_regs_pushed 8 +%define number_of_parameters 4 + +; Keep these in sync for push_regs/pop_regs, code below uses them to find = 5th or greater parameters +%define first_variable_on_stack_offset (number_of_regs_pushed * 8) + (num= ber_of_parameters * 8) + 8 +%define second_variable_on_stack_offset (first_variable_on_stack_offset) += 8 + +%macro tdcall_regs_preamble 2 + mov rax, %1 + + mov ecx, %2 + + ; R10 =3D 0 (standard TDVMCALL) + + xor r10d, r10d + + ; Zero out unused (for standard TDVMCALL) registers to avoid leaking + ; secrets to the VMM. + + xor ebx, ebx + xor esi, esi + xor edi, edi + + xor edx, edx + xor ebp, ebp + xor r8d, r8d + xor r9d, r9d +%endmacro + +%macro tdcall_regs_postamble 0 + xor ebx, ebx + xor esi, esi + xor edi, edi + + xor ecx, ecx + xor edx, edx + xor r8d, r8d + xor r9d, r9d + xor r10d, r10d + xor r11d, r11d +%endmacro + +; TdCall ( +; UINT64 Leaf, // Rcx +; UINT64 P1, // Rdx +; UINT64 P2, // R8 +; UINT64 P3, // R9 +; UINT64 Results, // rsp + 0x28 +; ) +global ASM_PFX(TdCall) +ASM_PFX(TdCall): + tdcall_push_regs + + mov rax, rcx + mov rcx, rdx + mov rdx, r8 + mov r8, r9 + + tdcall + + ; exit if tdcall reports failure. + test rax, rax + jnz .exit + + ; test if caller wanted results + mov r12, [rsp + first_variable_on_stack_offset ] + test r12, r12 + jz .exit + mov [r12 + 0 ], rcx + mov [r12 + 8 ], rdx + mov [r12 + 16], r8 + mov [r12 + 24], r9 + mov [r12 + 32], r10 + mov [r12 + 40], r11 +.exit: + tdcall_pop_regs + ret diff --git a/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm b/OvmfPkg/Library/Tdx= Lib/X64/Tdvmcall.nasm new file mode 100644 index 000000000000..e1da9b4fbdd6 --- /dev/null +++ b/OvmfPkg/Library/TdxLib/X64/Tdvmcall.nasm @@ -0,0 +1,211 @@ +;-------------------------------------------------------------------------= ----- +;* +;* Copyright (c) 2020, Intel Corporation. All rights reserved.
+;* This program and the accompanying materials +;* are licensed and made available under the terms and conditions of the= BSD License +;* which accompanies this distribution. The full text of the license ma= y be found at +;* http://opensource.org/licenses/bsd-license.php +;* +;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR = IMPLIED. +;* +;* +;-------------------------------------------------------------------------= ----- + +DEFAULT REL +SECTION .text + +%define TDVMCALL_EXPOSE_REGS_MASK 0xffec +%define TDVMCALL 0x0 +%define EXIT_REASON_CPUID 0xa + +%macro tdcall 0 +%if (FixedPcdGet32 (PcdUseTdxEmulation) !=3D 0) + vmcall +%else + db 0x66,0x0f,0x01,0xcc +%endif +%endmacro + +%macro tdcall_push_regs 0 + push rbp + mov rbp, rsp + push r15 + push r14 + push r13 + push r12 + push rbx + push rsi + push rdi +%endmacro + +%macro tdcall_pop_regs 0 + pop rdi + pop rsi + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + pop rbp +%endmacro + +%define number_of_regs_pushed 8 +%define number_of_parameters 4 + +; Keep these in sync for push_regs/pop_regs, code below uses them to find = 5th or greater parameters +%define first_variable_on_stack_offset (number_of_regs_pushed * 8) + (num= ber_of_parameters * 8) + 8 +%define second_variable_on_stack_offset (first_variable_on_stack_offset) += 8 + +%macro tdcall_regs_preamble 2 + mov rax, %1 + + mov ecx, %2 + + ; R10 =3D 0 (standard TDVMCALL) + + xor r10d, r10d + + ; Zero out unused (for standard TDVMCALL) registers to avoid leaking + ; secrets to the VMM. + + xor ebx, ebx + xor esi, esi + xor edi, edi + + xor edx, edx + xor ebp, ebp + xor r8d, r8d + xor r9d, r9d +%endmacro + +%macro tdcall_regs_postamble 0 + xor ebx, ebx + xor esi, esi + xor edi, edi + + xor ecx, ecx + xor edx, edx + xor r8d, r8d + xor r9d, r9d + xor r10d, r10d + xor r11d, r11d +%endmacro + +;-------------------------------------------------------------------------= ----- +; 0 =3D> RAX =3D TDCALL leaf +; M =3D> RCX =3D TDVMCALL register behavior +; 1 =3D> R10 =3D standard vs. vendor +; RDI =3D> R11 =3D TDVMCALL function / nr +; RSI =3D R12 =3D p1 +; RDX =3D> R13 =3D p2 +; RCX =3D> R14 =3D p3 +; R8 =3D> R15 =3D p4 + +; UINT64 +; EFIAPI +; TdVmCall ( +; UINT64 Leaf, // Rcx +; UINT64 P1, // Rdx +; UINT64 P2, // R8 +; UINT64 P3, // R9 +; UINT64 P4, // rsp + 0x28 +; UINT64 *Val // rsp + 0x30 +; ) +global ASM_PFX(TdVmCall) +ASM_PFX(TdVmCall): + tdcall_push_regs + + mov r11, rcx + mov r12, rdx + mov r13, r8 + mov r14, r9 + mov r15, [rsp + first_variable_on_stack_offset ] + + tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK + + tdcall + + ; ignore return dataif TDCALL reports failure. + test rax, rax + jnz .no_return_data + + ; Propagate TDVMCALL success/failure to return value. + mov rax, r10 + + ; Retrieve the Val pointer. + mov r9, [rsp + second_variable_on_stack_offset ] + test r9, r9 + jz .no_return_data + + ; On success, propagate TDVMCALL output value to output param + test rax, rax + jnz .no_return_data + mov [r9], r11 +.no_return_data: + tdcall_regs_postamble + + tdcall_pop_regs + + ret + +;-------------------------------------------------------------------------= ----- +; 0 =3D> RAX =3D TDCALL leaf +; M =3D> RCX =3D TDVMCALL register behavior +; 1 =3D> R10 =3D standard vs. vendor +; RDI =3D> R11 =3D TDVMCALL function / nr +; RSI =3D R12 =3D p1 +; RDX =3D> R13 =3D p2 +; RCX =3D> R14 =3D p3 +; R8 =3D> R15 =3D p4 + +; UINT64 +; EFIAPI +; TdVmCallCpuid ( +; UINT64 EaxIn, // Rcx +; UINT64 EcxIn, // Rdx +; UINT64 *Results // R8 +; ) +global ASM_PFX(TdVmCallCpuid) +ASM_PFX(TdVmCallCpuid): + tdcall_push_regs + + mov r11, EXIT_REASON_CPUID + mov r12, rcx + mov r13, rdx + + tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK + + ; Save *results pointers + push r8 + + tdcall + + ; Panic if TDCALL reports failure. + test rax, rax + jnz .no_return_data + + ; Propagate TDVMCALL success/failure to return value. + mov rax, r10 + test rax, rax + jnz .no_return_data + + ; Retrieve *Results + pop r8 + test r8, r8 + jnz .no_return_data + ; Caller pass in buffer so store results r12-r15 contains eax-edx + mov [r8 + 0], r12 + mov [r8 + 8], r13 + mov [r8 + 16], r14 + mov [r8 + 24], r15 + +.no_return_data: + tdcall_regs_postamble + + tdcall_pop_regs + + ret + +.panic: + ud2 --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#72561): https://edk2.groups.io/g/devel/message/72561 Mute This Topic: https://groups.io/mt/81193347/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-