From: James Bottomley <jejb@linux.ibm.com>
To: linux-coco@lists.linux.dev
Subject: [RFC 3/3] edk2: Add SVSM based vTPM
Date: Tue, 03 Jan 2023 16:05:11 -0500 [thread overview]
Message-ID: <20c7dda843f93b22f6c6afca3820a53d669503bf.camel@linux.ibm.com> (raw)
In-Reply-To: <acb06bc7f329dfee21afa1b2ff080fe29b799021.camel@linux.ibm.com>
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Add this as a new device in TPM2DeviceLibDTpm. The SVSM vTPM has no
physical presence interface, so handle detecing this device before
that check. The detection is done by sending all zeros to the SVSM
for the VTPM function (8) and seeing if success is returned.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
.../Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf | 3 +
.../Tpm2DeviceLibDTpmStandaloneMm.inf | 3 +
.../Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf | 3 +
SecurityPkg/Include/Library/Tpm2DeviceLib.h | 1 +
.../Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.h | 33 +++++++
UefiCpuPkg/Include/Library/VmgExitLib.h | 6 ++
OvmfPkg/Library/VmgExitLib/VmgExitSvsm.c | 36 +++++++
.../Library/Tpm2DeviceLibDTpm/Tpm2Ptp.c | 14 +++
.../Library/Tpm2DeviceLibDTpm/Tpm2Svsm.c | 96 +++++++++++++++++++
.../Library/VmgExitLibNull/VmgExitLibNull.c | 23 +++++
10 files changed, 218 insertions(+)
create mode 100644 SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Svsm.c
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
index be3a0053ccce..2cd5216a0d42 100644
--- a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
@@ -33,6 +33,7 @@ [Defines]
[Sources]
Tpm2Tis.c
+ Tpm2Svsm.c
Tpm2Ptp.c
Tpm2DeviceLibDTpm.c
Tpm2DeviceLibDTpmBase.c
@@ -41,6 +42,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
BaseLib
@@ -49,6 +51,7 @@ [LibraryClasses]
TimerLib
DebugLib
PcdLib
+ VmgExitLib
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmStandaloneMm.inf b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmStandaloneMm.inf
index 18c08ad8bdcc..99b140be1c54 100644
--- a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmStandaloneMm.inf
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmStandaloneMm.inf
@@ -33,6 +33,7 @@ [Defines]
[Sources]
Tpm2Tis.c
+ Tpm2Svsm.c
Tpm2Ptp.c
Tpm2DeviceLibDTpm.c
Tpm2DeviceLibDTpmStandaloneMm.c
@@ -41,6 +42,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
BaseLib
@@ -49,6 +51,7 @@ [LibraryClasses]
TimerLib
DebugLib
PcdLib
+ VmgExitLib
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
index 31113d93ee41..7c41ab0a8531 100644
--- a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
@@ -29,6 +29,7 @@ [Defines]
[Sources]
Tpm2Tis.c
+ Tpm2Svsm.c
Tpm2Ptp.c
Tpm2InstanceLibDTpm.c
Tpm2DeviceLibDTpmBase.c
@@ -37,6 +38,7 @@ [Sources]
[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
BaseLib
@@ -45,6 +47,7 @@ [LibraryClasses]
TimerLib
DebugLib
PcdLib
+ VmgExitLib
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES
diff --git a/SecurityPkg/Include/Library/Tpm2DeviceLib.h b/SecurityPkg/Include/Library/Tpm2DeviceLib.h
index 783bfa533394..b45ea0d07eb4 100644
--- a/SecurityPkg/Include/Library/Tpm2DeviceLib.h
+++ b/SecurityPkg/Include/Library/Tpm2DeviceLib.h
@@ -18,6 +18,7 @@ typedef enum {
Tpm2PtpInterfaceTis,
Tpm2PtpInterfaceFifo,
Tpm2PtpInterfaceCrb,
+ Tpm2PtpInterfaceSvsm,
Tpm2PtpInterfaceMax,
} TPM2_PTP_INTERFACE_TYPE;
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.h b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.h
index d703f15a2fbb..8af67e31a757 100644
--- a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.h
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.h
@@ -64,4 +64,37 @@ InternalTpm2DeviceLibDTpmCommonConstructor (
VOID
);
+/**
+ Check if an SVSM based TPM is present
+
+ @retval TRUE SVSM TPM is present
+ @retval FALSE no SVSM TPM is present
+**/
+BOOLEAN
+Tpm2IsSvsm (
+ VOID
+ );
+
+/**
+ Send a command to TPM for execution and return response data.
+
+ @param[in] BufferIn Buffer for command data.
+ @param[in] SizeIn Size of command data.
+ @param[in, out] BufferOut Buffer for response data.
+ @param[in, out] SizeOut Size of response data.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+ @retval EFI_UNSUPPORTED Unsupported TPM version
+
+**/
+EFI_STATUS
+Tpm2SvsmTpmCommand (
+ IN UINT8 *BufferIn,
+ IN UINT32 SizeIn,
+ IN OUT UINT8 *BufferOut,
+ IN OUT UINT32 *SizeOut
+ );
+
#endif // _TPM2_DEVICE_LIB_DTPM_H_
diff --git a/UefiCpuPkg/Include/Library/VmgExitLib.h b/UefiCpuPkg/Include/Library/VmgExitLib.h
index f32938e8f262..4b65bcba780c 100644
--- a/UefiCpuPkg/Include/Library/VmgExitLib.h
+++ b/UefiCpuPkg/Include/Library/VmgExitLib.h
@@ -242,4 +242,10 @@ VmgExitVmsaRmpAdjust (
IN BOOLEAN SetVmsa
);
+BOOLEAN
+EFIAPI
+VmgExitVTPM (
+ IN OUT UINT8 *Buffer
+ );
+
#endif
diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitSvsm.c b/OvmfPkg/Library/VmgExitLib/VmgExitSvsm.c
index bbf8e5591a92..f3b169c4cba3 100644
--- a/OvmfPkg/Library/VmgExitLib/VmgExitSvsm.c
+++ b/OvmfPkg/Library/VmgExitLib/VmgExitSvsm.c
@@ -476,3 +476,39 @@ VmgExitVmsaRmpAdjust (
return VmgExitSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
: BaseVmsaRmpAdjust (Vmsa, ApicId, SetVmsa);
}
+
+
+/**
+ Tries to perform a SVSM call to the vTPM.
+
+ The buffer should contain a marshalled TPM command and will return a
+ marshalled TPM response. Sending down a NULL buffer will do nothing but
+ can be used to probe for the existence of the SVSM vTPM (will return
+ non zero if no vTPM is present)
+
+ @param Buffer A pointer to the input command and output response
+
+ @retval TRUE The Command is processed (or the vTPM is present)
+ @retval FALSE The vTPM is not present
+
+**/
+BOOLEAN
+EFIAPI
+VmgExitVTPM (
+ IN OUT UINT8 *Buffer
+ )
+{
+ SVSM_CAA *Caa;
+ SVSM_FUNCTION Function;
+ UINTN Ret;
+
+ if (!VmgExitSvsmPresent ())
+ return FALSE;
+
+ Caa = SvsmGetCaa ();
+ Function.Protocol = 0;
+ Function.CallId = 8;
+
+ Ret = SvsmMsrProtocol (Caa, Function.Uint64, (UINT64)Buffer, 0, 0);
+ return (Ret == 0) ? TRUE : FALSE;
+}
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Ptp.c b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Ptp.c
index 1d99beaa101f..19e4ddf3e09c 100644
--- a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Ptp.c
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Ptp.c
@@ -422,6 +422,11 @@ Tpm2GetPtpInterface (
PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;
+ if (Tpm2IsSvsm ()) {
+ DEBUG((DEBUG_INFO, "Found SVSM TPM\n"));
+ return Tpm2PtpInterfaceSvsm;
+ }
+
if (!Tpm2IsPtpPresence (Register)) {
return Tpm2PtpInterfaceMax;
}
@@ -595,6 +600,13 @@ DTpm2SubmitCommand (
OutputParameterBlock,
OutputParameterBlockSize
);
+ case Tpm2PtpInterfaceSvsm:
+ return Tpm2SvsmTpmCommand (
+ InputParameterBlock,
+ InputParameterBlockSize,
+ OutputParameterBlock,
+ OutputParameterBlockSize
+ );
default:
return EFI_NOT_FOUND;
}
@@ -622,6 +634,8 @@ DTpm2RequestUseTpm (
case Tpm2PtpInterfaceFifo:
case Tpm2PtpInterfaceTis:
return TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)(UINTN)PcdGet64 (PcdTpmBaseAddress));
+ case Tpm2PtpInterfaceSvsm:
+ return EFI_SUCCESS;
default:
return EFI_NOT_FOUND;
}
diff --git a/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Svsm.c b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Svsm.c
new file mode 100644
index 000000000000..ce0f162b9e01
--- /dev/null
+++ b/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2Svsm.c
@@ -0,0 +1,96 @@
+/** @file
+ SVSM TPM communication
+
+Copyright (c) 2023 James.Bottomley@HansenPartnership.com
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/PcdLib.h>
+#include <Library/VmgExitLib.h>
+
+#include "Tpm2DeviceLibDTpm.h"
+
+#pragma pack(1)
+typedef struct Tpm2SendCmdReq {
+ UINT32 Cmd;
+ UINT8 Locality;
+ UINT32 BufSize;
+ UINT8 Buf[];
+} Tpm2SendCmdReq;
+typedef struct Tpm2SendCmdResp {
+ INT32 Size;
+ UINT8 Buf[];
+} Tpm2SendCmdResp;
+#pragma pack()
+
+/* These defines come from the TPM platform interface */
+#define TPM_SEND_COMMAND 8
+#define TPM_PLATFORM_MAX_BUFFER 4096 /* max req/resp buffer size */
+
+STATIC UINT8 Tpm2SvsmBuffer[TPM_PLATFORM_MAX_BUFFER];
+
+/**
+ Send a command to TPM for execution and return response data.
+
+ @param[in] BufferIn Buffer for command data.
+ @param[in] SizeIn Size of command data.
+ @param[in, out] BufferOut Buffer for response data.
+ @param[in, out] SizeOut Size of response data.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+ @retval EFI_UNSUPPORTED Unsupported TPM version
+
+**/
+EFI_STATUS
+Tpm2SvsmTpmCommand (
+ IN UINT8 *BufferIn,
+ IN UINT32 SizeIn,
+ IN OUT UINT8 *BufferOut,
+ IN OUT UINT32 *SizeOut
+ )
+{
+ Tpm2SendCmdReq *req = (Tpm2SendCmdReq *)Tpm2SvsmBuffer;
+ Tpm2SendCmdResp *resp = (Tpm2SendCmdResp *)Tpm2SvsmBuffer;
+
+ if (SizeIn > sizeof (Tpm2SvsmBuffer) - sizeof (*req)) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ req->Cmd = TPM_SEND_COMMAND;
+ req->Locality = 0;
+ req->BufSize = SizeIn;
+ CopyMem (req->Buf, BufferIn, SizeIn);
+ if (!VmgExitVTPM (Tpm2SvsmBuffer)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *SizeOut = resp->Size;
+ CopyMem (BufferOut, resp->Buf, *SizeOut);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check if an SVSM based TPM is present
+
+ @retval TRUE SVSM TPM is present
+ @retval FALSE no SVSM TPM is present
+**/
+BOOLEAN
+Tpm2IsSvsm (
+ VOID
+ )
+{
+ BOOLEAN ret;
+ ret = VmgExitVTPM(NULL);
+ DEBUG((DEBUG_INFO, "Tpm2IsSvsm return %d\n", ret));
+ return ret;
+}
diff --git a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
index 02d72adab2b2..fd2b332980d9 100644
--- a/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
+++ b/UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.c
@@ -246,3 +246,26 @@ VmgExitVmsaRmpAdjust (
{
return EFI_UNSUPPORTED;
}
+
+/**
+ Tries to perform a SVSM call to the vTPM.
+
+ The buffer should contain a marshalled TPM command and will return a
+ marshalled TPM response. Sending down a NULL buffer will do nothing but
+ can be used to probe for the existence of the SVSM vTPM (will return
+ non zero if no vTPM is present)
+
+ @param Buffer A pointer to the input command and output response
+
+ @retval TRUE The Command is processed (or the vTPM is present)
+ @retval FALSE The vTPM is not present
+
+**/
+BOOLEAN
+EFIAPI
+VmgExitVTPM (
+ IN OUT UINT8 *Buffer
+ )
+{
+ return FALSE;
+}
--
2.35.3
next prev parent reply other threads:[~2023-01-03 21:05 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-03 21:01 [RFC 0/3] Enlightened vTPM support for SVSM on SEV-SNP James Bottomley
2023-01-03 21:02 ` [RFC 1/3] tpm: add generic platform device James Bottomley
2023-01-05 8:08 ` Dov Murik
2023-01-05 12:28 ` James Bottomley
2023-01-03 21:04 ` [RFC 2/2] x86/sev: add a SVSM vTPM " James Bottomley
2023-01-03 21:05 ` James Bottomley [this message]
2023-01-04 22:44 ` [RFC 0/3] Enlightened vTPM support for SVSM on SEV-SNP Tom Lendacky
2023-01-04 22:59 ` James Bottomley
2024-11-06 11:19 ` Stefano Garzarella
2024-11-06 14:54 ` James Bottomley
2024-11-06 15:33 ` Stefano Garzarella
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20c7dda843f93b22f6c6afca3820a53d669503bf.camel@linux.ibm.com \
--to=jejb@linux.ibm.com \
--cc=linux-coco@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).