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

Add support for a SVSM vTPM #5770

Closed
wants to merge 3 commits into from
Closed

Conversation

cclaudio
Copy link

@cclaudio cclaudio commented Jun 13, 2024

Description

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?
    • Breaking change - Will this cause a break in build or boot behavior?
    • Examples: Add a new library class or move a module to a different repo.
  • [ x ] Impacts security?
    • Security - Does the change have a direct security impact?
    • Examples: Crypto algorithm change or buffer overflow fix.
  • Includes tests?
    • Tests - Does the change include any explicit test code?
    • Examples: Unit tests or integration tests.

How This Was Tested

This was tested with the latest COCONUT-SVSM upstream code (commit 75b83b3e1a5c860a84ccfe0e4b503e7efee5834f), 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.

[snip]

Creating MpInformation2 HOB...
Loading PEIM F12F698A-E506-4A1B-B32E-6920E55DA1C4
Loading PEIM at 0x0007FB89000 EntryPoint=0x0007FB8A5E4 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 0x0007F7FC000 EntryPoint=0x0007F7FD916 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 0x0007F7F7000 EntryPoint=0x0007F7F9E2F TcgPei.efi
No TPM12 instance required!
Loading PEIM A0C98B77-CBA5-4BB8-993B-4AF6CE33ECE4
Loading PEIM at 0x0007F7E9000 EntryPoint=0x0007F7F1FCC Tcg2Pei.efi

[snip]

EFI stub: Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path
ReadPcr - 09
Supported PCRs - Count = 00000003
GetSupportedAndActivePcrs - Count = 00000003
ReadPcr - HashAlg = 0x0004, Pcr[09], digest = 68 36 46 79 6E 8A 5E 5E 37 34 DB 36 A9 84 85 36 6F C9 BD 07 
ReadPcr - HashAlg = 0x000B, Pcr[09], digest = 12 10 49 80 43 DB 86 46 AD 0F CE 32 76 7B EE 87 5B 20 3B D9 14 93 EA F4 D8 8F E9 39 10 8B CA 3E 
ReadPcr - HashAlg = 0x000C, Pcr[09], digest = E2 54 A7 DD CA BF EA C8 B1 CD A2 12 D7 2A A7 A8 04 BE A9 9D 1F 88 7A D9 40 28 4C 79 C9 DB F8 0C A6 BE AD C0 E9 44 FE AD F7 7F 32 D1 65 80 A3 14 
SupportedEventLogs - 0x00000003
  LogFormat - 0x00000001
  LogFormat - 0x00000002
EFI stub: Measured initrd data into PCR 9
Tcg2GetEventLog ... (0x2)
Tcg2GetEventLog (EventLogLocation - 7E577000)
Tcg2GetEventLog (EventLogLastEntry - 7E577E14)
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 - 0x00000029
0000: 53706563204944204576656E7430330000000000000200020300000004001400
0020: 0B0020000C00300000
  TCG_EfiSpecIDEventStruct:
    signature          - 'Spec ID Event03 '
    platformClass      - 0x00000000
    specVersion        - 2.00
    uintnSize          - 0x02
    NumberOfAlgorithms - 0x00000003
    digest(0)
      algorithmId      - 0x0004
      digestSize       - 0x0014
    digest(1)
      algorithmId      - 0x000B
      digestSize       - 0x0020
    digest(2)
      algorithmId      - 0x000C
      digestSize       - 0x0030
    VendorInfoSize     - 0x00
    VendorInfo         - 
  Event:
    PCRIndex  - 0
    EventType - 0x00000008
    DigestCount: 0x00000003
      HashAlgo : 0x0004
      Digest(0): 14 89 F9 23 C4 DC A7 29 17 8B 3E 32 33 45 85 50 D8 DD DF 29 
      HashAlgo : 0x000B
      Digest(1): 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(2): 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
0000: 0000

[snip]

Integration Instructions

N/A

cclaudio and others added 3 commits June 13, 2024 16:45
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]>
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]>
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.

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.

Cc: Jiewen Yao <[email protected]>
Co-authored-by: James Bottomley <[email protected]>
Signed-off-by: Claudio Carvalho <[email protected]>
@github-actions github-actions bot added the impact:security This change has a direct security impact such as changing a crypto algorithm. label Jun 13, 2024
@cclaudio cclaudio marked this pull request as draft June 20, 2024 16:49
@@ -443,6 +443,11 @@ Tpm2GetPtpInterface (
return Tpm2PtpInterfaceMax;
}

if (Tpm2SvsmQueryTpmSendCmd ()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I recommend using NULL class registration for SVSM TPM.
Please don't touch the current PTP for the real platform BIOS.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @jyao1. Thanks for your feedback and I apologize for the delay.

The API used to communicate with the SVSM vTPM is already under a NULL class. Could you elaborate a little bit more on what other NULL classes could be created?

  • UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.c
  • OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c

Right, this patch series is failing the CI mostly because it is hooking into the PTP which is used by multiple platforms. The idea behind that was to register the SVSM vTPM as a platform driver, similar to what we are doing in the Linux kernel. If not the PTP, would you have any suggestion for places where we could add it? And could that also be enabled via "-D TPM2_ENABLE"?

Copy link
Contributor

Choose a reason for hiding this comment

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

What I expect is something like the DTpm NULL class, https://github.com/tianocore/edk2/blob/master/SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf

For example, you can have, something like: Tpm2InstallLibSvsmVTpm.

Then you can register it in the OVMF DSC file, without impacting other platform, where they can still use existing DTpm.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you.

I will create the new SecurityPkg/Library/Tpm2InstanceLibSvsmVTpm and have it implement https://github.com/tianocore/edk2/blob/master/SecurityPkg/Include/Library/Tpm2DeviceLib.h similar to how Tpm2InstanceLibDTpm does.

It is not super clear though how I should register it in the Ovmf DSC file. I think I could do something similar to AmdSvsmLib.inf or TdxLib.inf. Would you have any suggestion/preference?

Copy link
Member

Choose a reason for hiding this comment

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

I recommend using NULL class registration for SVSM TPM. Please don't touch the current PTP for the real platform BIOS.

Care to explain why adding the svsm vtpm as new PTP variant is a problem?

I like the approach because it allows for runtime detection of the (v)TPM, whereas a svsm-specific Tpm2DeviceLib implementation must be selected at compile time.

If you want be able to exclude the svsm support for physical platforms we can have a Tpm2Svsm.c and a Tpm2SvsmNull.c and two variants of the Tpm2InstanceLibDTpm.inf file, one using the NULL implementation (for physical platforms) and one using the real svsm implementation (for OVMF).

Copy link
Member

Choose a reason for hiding this comment

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

ping @jyao1 ^^^

Copy link

This PR has been automatically marked as stale because it has not had activity in 60 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions.

@github-actions github-actions bot added the stale Due to lack of updates, this item is pending deletion. label Sep 22, 2024
Copy link

This pull request has been automatically been closed because it did not have any activity in 60 days and no follow up within 7 days after being marked stale. Thank you for your contributions.

@github-actions github-actions bot closed this Sep 30, 2024
@kraxel kraxel reopened this Nov 6, 2024
@github-actions github-actions bot removed the stale Due to lack of updates, this item is pending deletion. label Nov 6, 2024
@osteffenrh
Copy link
Contributor

We can close this PR. Work will continue at #6527

@kraxel kraxel closed this Dec 12, 2024
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.

4 participants