Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] Add support for a SVSM vTPM #6527

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

osteffenrh
Copy link
Contributor

Description

This is version 2 of #5770.

This series adds a DTpm driver to communicate with a virtual TPM running in the Secure VM Service Module (SVSM), enabling OVMF to do measured boot in SEV-SNP confidential VMs.

SEV-SNP provides a feature known as VM Privilege Level (VMPL), which allows for services to be run in the guest at different privilege levels. By running at VMPL0 (most priviledged VM level), the SVSM can be used to provide privileged services, e.g. virtual TPM, for the guest rather than trust such services from the hypervisor.

As described in the SVSM specification, guest components can call to the SVSM vTPM through the vTPM protocol (protocol-id 2).

The vTPM protocol follows the Microsoft TPM Simulator interface (MSSIM) and it supports two services:

SVSM_VTPM_QUERY (call-id 0): query MSSIM commands and vTPM features supported
SVSM_VTPM_CMD (call-id 1): send a MSSIM command to be run by the vTPM and get the result

The SVSM vTPM protocol is also added in this series.

  • Breaking change?
  • Impacts security?
    • This PR touches existing TPM driver code and implements new TPM related functionality.
  • Includes tests?

How This Was Tested

This was tested with the latest COCONUT-SVSM upstream code (commit 0b8feaf9), which provides vTPM service. The instructions to build and run a guest under a SVSM can be found in the INSTALL.md.

The OVMF boot message log below shows that it was able to find the SVSM vTPM and also use it for measured boot.

[...]
Creating MpInformation2 HOB...
Loading PEIM F12F698A-E506-4A1B-B32E-6920E55DA1C4
Loading PEIM at 0x0007FB30000 EntryPoint=0x0007FB31399 TpmMmioSevDecryptPei.efi
TpmMmioSevDecryptPeimEntryPoint
TpmMmioSevDecryptPeimEntryPoint: mapping TPM MMIO address range unencrypted
Install PPI: 35C84FF2-7BFE-453D-845F-683A492CF7B7
Loading PEIM 8AD3148F-945F-46B4-8ACD-71469EA73945
Loading PEIM at 0x0007F7FD000 EntryPoint=0x0007F7FE684 Tcg2ConfigPei.efi
Found SVSM vTPM
Tcg2ConfigPeimEntryPoint
Tcg2ConfigPeimEntryPoint: TPM2 detected
Install PPI: 7F4158D3-074D-456D-8CB2-01F9C8F79DAA
Loading PEIM 2BE1E4A6-6505-43B3-9FFC-A3C8330E0432
Loading PEIM at 0x0007F7F8000 EntryPoint=0x0007F7FAA00 TcgPei.efi
No TPM12 instance required!
Loading PEIM A0C98B77-CBA5-4BB8-993B-4AF6CE33ECE4
Loading PEIM at 0x0007F7EB000 EntryPoint=0x0007F7F364B Tcg2Pei.efi
TPM2Startup: TPM_RC_SUCCESS

[...]

Tcg2GetEventLog ... (0x2)
Tcg2GetEventLog (EventLogLocation - 7E632000)
Tcg2GetEventLog (EventLogLastEntry - 7E635BFC)
Tcg2GetEventLog (EventLogTruncated - 0)
Tcg2GetEventLog - Success
EventLogFormat: (0x2)
  Event:
    PCRIndex  - 0
    EventType - 0x00000003
    Digest    - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    EventSize - 0x00000025
0000: 53706563204944204576656E743033000000000000020002020000000B002000
0020: 0C00300000
  TCG_EfiSpecIDEventStruct:
    signature          - 'Spec ID Event03 '
    platformClass      - 0x00000000
    specVersion        - 2.00
    uintnSize          - 0x02
    NumberOfAlgorithms - 0x00000002
    digest(0)
      algorithmId      - 0x000B
      digestSize       - 0x0020
    digest(1)
      algorithmId      - 0x000C
      digestSize       - 0x0030
    VendorInfoSize     - 0x00
    VendorInfo         - 
  Event:
    PCRIndex  - 0
    EventType - 0x00000008
    DigestCount: 0x00000002
      HashAlgo : 0x000B
      Digest(0): 96 A2 96 D2 24 F2 85 C6 7B EE 93 C3 0F 8A 30 91 57 F0 DA A3 5D C5 B8 7E 41 0B 78 63 0A 09 CF C7 
      HashAlgo : 0x000C
      Digest(1): 1D D6 F7 B4 57 AD 88 0D 84 0D 41 C9 61 28 3B AB 68 8E 94 E4 B5 93 59 EA 45 68 65 81 E9 0F EC CE A3 C6 24 B1 22 61 13 F8 24 F3 15 EB 60 AE 0A 7C 

    EventSize - 0x00000002

It was checked that the existing TPM support still works by launching Ovmf (x64) in Qemu
with a regular software TPM.

Integration Instructions

N/A


Changes since v1:

  • Implemented comments from @kraxel, stubbing the SVSM vTPM functions for regular TPM libs
  • Use proper names for SVSM guest protocol call numbers
  • Applied formatting style (uncrustify)

Cc: @cclaudio

@github-actions github-actions bot added the impact:security This change has a direct security impact such as changing a crypto algorithm. label Dec 11, 2024
@osteffenrh osteffenrh mentioned this pull request Dec 11, 2024
2 tasks
@osteffenrh osteffenrh force-pushed the svsm-vtpm-ptp-variant branch from e98ebd4 to 1706e02 Compare December 11, 2024 13:19
@osteffenrh osteffenrh force-pushed the svsm-vtpm-ptp-variant branch 3 times, most recently from 6c2105e to ae3eb31 Compare December 11, 2024 18:02
@jyao1
Copy link
Contributor

jyao1 commented Dec 12, 2024

Thanks for the update. In general I am OK with this approach to use NULL file and another lib instance, if you do not like NULL instance.

However, the biggest problem of this patch is that the AMD SVSM vTPM is totally irrelevant to TCG defined PTP. Mixing SVSM and PTP will cause lots of confusing. It is also weird to me, because TCG PTP spec never defines SVSM.

Here is my suggestion:

  1. Do not touch anything related to PTP, because that is defined by TCG. For example, TPM2_PTP_INTERFACE_TYPE, or Tpm2Ptp.c

  2. Create another C file as a wrapper to switch between PTP and SVSM vTPM. The idea is:
    Instead of merging SVSM into TCG PTP like below,

DTpm2SubmitCommand ()
{
  switch (PtpInterface) {
    case Tpm2PtpInterfaceCrb:
        ...
    case Tpm2PtpInterfaceTis:
        ...
    case Tpm2PtpInterfaceSvsm:
        Tpm2SvsmTpmSendCommand ()
}

please using following code in a new C wrapper - Tpm2DeviceLibDTpmSvsm.c

Tpm2SubmitCommand()
{
    if (TCG PTP TPM) {
        DTpm2SubmitCommand ()
    }
    if (SVSM vTPM) {
        Tpm2SvsmTpmSendCommand ()
    }
}

I think the mail function Tpm2Svsm.c does not need to change. We only need move the caller to another place.
SVSM should be in the same level as PTP, instead of being a subset of PTP.
Do you think if that is feasible?

One more thing, if we finally really include SVSM into SecurityPkg. I recommend having one more reviewer to help me maintain the code. To achieve this, please consider adding following section in maintainers.txt

SecurityPkg: SVSM related modules
F: SecurityPkg/*Svsm*
R: <Some SVSM expert>

Thought?

@osteffenrh osteffenrh force-pushed the svsm-vtpm-ptp-variant branch from ae3eb31 to c26c6bc Compare December 12, 2024 16:21
/* Max req/resp buffer size */
#define TPM_PLATFORM_MAX_BUFFER 4096

STATIC UINT8 Tpm2SvsmBuffer[TPM_PLATFORM_MAX_BUFFER];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are commands sent prior to having access to dynamic memory allocation? This expands the flash description size another 4KiB and kicks over some limits we have.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a new issue? Does it work with one of the previous versions of these patches?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if we don't have to allocate a 4k buffer statically we should not do that, but go AllocatePool + FreePool instead.

One common trick which can be used to allocate memory in case the pool allocator is not up yet is to create a HOB instead. Drawback is that HOBs can't be freed, but it should be possible to have a small communication buffer to probe for the svsm vtpm protocol being present and only create a (larger) HOB in case we actually need it.

osteffenrh and others added 9 commits December 17, 2024 12:55
Add protocol and call numbers as defined in the "Secure VM Service
Module for SEV-SNP Guests" Publication # 58019 Revision: 1.00

https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/58019.pdf

Signed-off-by: Oliver Steffen <[email protected]>
Make use of the named protocol and call constants for SVSM
communication.

Signed-off-by: Oliver Steffen <[email protected]>
We need to stub the SVSM vTPM protocol in the UefiCpuPkg in order to
support a SEV-SNP guest running under a SVSM at VMPL1 or lower.

Cc: Ray Ni <[email protected]>
Cc: Rahul Kumar <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Cc: Jiaxin Wu <[email protected]>
Co-authored-by: James Bottomley <[email protected]>
Signed-off-by: Claudio Carvalho <[email protected]>
Signed-off-by: Oliver Steffen <[email protected]>
Add call numbers for the SVSM vTPM protocol, as defined in the "Secure
VM Service Module for SEV-SNP Guests" Publication # 58019 Revision: 1.00

Signed-off-by: Oliver Steffen <[email protected]>
As described in the SVSM specification, guest components can call to the
SVSM vTPM through the vTPM protocol (protocol-id 2).

The SVSM vTPM protocol follows the Microsoft TPM Simulator interface
(MSSIM) and supports two services:

- SVSM_VTPM_QUERY (call-id 0): query MSSIM commands and vTPM features
  supported.
- SVSM_VTPM_CMD (call-id 1): send a MSSIM command to be run by the vTPM
  and get the result.

This patch adds support for SVSM_VTPM_QUERY and SVSM_VTPM_CMD to invoke
a SVSM when the guest is running at VMPL0.

Cc: Ard Biesheuvel <[email protected]>
Cc: Jiewen Yao <[email protected]>
Cc: Gerd Hoffmann <[email protected]>
Co-authored-by: James Bottomley <[email protected]>
Signed-off-by: Claudio Carvalho <[email protected]>
Signed-off-by: Oliver Steffen <[email protected]>
A some of functions implemented in Tpm2Ptp.c are forward declared in a
couple of places. To clean this up, introduce a header that contains
these declarations in a central place and use it instead.

Signed-off-by: Oliver Steffen <[email protected]>
SEV-SNP provides a feature known as VM Privilege Level (VMPL), which
allows for services to be run in the guest at different privilege
levels. By running at VMPL0 (most privileged VM level), the SVSM can be
used to provide privileged services, e.g. a virtual TPM, for the guest
rather than trust such services from the hypervisor.

This patch adds a DTpm driver to communicate with a virtual TPM running
in the SVSM. The driver follows the vTPM protocol documented in the SVSM
specification.

SVSM vTPM functionality is available as new device and instance
libraries, which can be consumed optionally, keeping changes to the
regular TPM implementation minimal.

Cc: Jiewen Yao <[email protected]>
Co-authored-by: James Bottomley <[email protected]>
Signed-off-by: Claudio Carvalho <[email protected]>
Signed-off-by: Oliver Steffen <[email protected]>
Switch over to Tpm2InstanceLibDTpmSvsm as the Tpm2 implementation to
support vTPMs provided by an SVSM.

Signed-off-by: Oliver Steffen <[email protected]>
Add a reviewer for the TPM2 code under SecurityPkg/
related to SVSM vTPM.

Signed-off-by: Oliver Steffen <[email protected]>
@osteffenrh osteffenrh force-pushed the svsm-vtpm-ptp-variant branch from c26c6bc to 7c97b37 Compare December 17, 2024 12:02
SecurityPkg: SVSM related modules
F: SecurityPkg/Library/Tpm2DeviceLibDTpm/*Svsm*
R: Oliver Steffen <[email protected]> [osteffenrh]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tlendacky do you want to be listed here too?

Or anybody else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, should probably list me as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impact:security This change has a direct security impact such as changing a crypto algorithm.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants