linux-coco.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
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



  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).