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
5 changes: 5 additions & 0 deletions Maintainers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,11 @@ SecurityPkg: Tcg related modules
F: SecurityPkg/Tcg/
R: Rahul Kumar <[email protected]> [rahul1-kumar]

SecurityPkg: SVSM related modules
F: SecurityPkg/Library/Tpm2DeviceLibDTpm/*Svsm*
R: Oliver Steffen <[email protected]> [osteffenrh]
R: Tom Lendacky <[email protected]> [tlendacky]

osteffenrh marked this conversation as resolved.
Show resolved Hide resolved
ShellPkg
F: ShellPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/ShellPkg
Expand Down
25 changes: 25 additions & 0 deletions MdePkg/Include/Register/Amd/Svsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,29 @@ typedef union {
UINT64 Uint64;
} SVSM_FUNCTION;

/// SVSM Guest Protocols
/// @{
#define SVSM_PROTOCOL_CORE 0
#define SVSM_PROTOCOL_ATTESTATION 1
#define SVSM_PROTOCOL_VTPM 2
/// @}

/// SVSM Core Protocol calls
/// @{
#define SVSM_CORE_REMAP_CA 0
#define SVSM_CORE_PVALIDATE 1
#define SVSM_CORE_CREATE_VCPU 2
#define SVSM_CORE_DELETE_VCPU 3
#define SVSM_CORE_DEPOSIT_MEM 4
#define SVSM_CORE_WITHDRAW_MEM 5
#define SVSM_CORE_QUERY_PROTOCOL 6
#define SVSM_CORE_CONFIGURE_VTOM 7
/// @}

/// SVSM vTPM Protocol calls
/// @{
#define SVSM_VTPM_QUERY 0
#define SVSM_VTPM_CMD 1
/// @}

#endif
2 changes: 1 addition & 1 deletion OvmfPkg/Include/Dsc/OvmfTpmComponentsDxe.dsc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
<LibraryClasses>
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpmSvsm.inf
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
Expand Down
2 changes: 1 addition & 1 deletion OvmfPkg/Include/Dsc/OvmfTpmLibs.dsc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
!if $(TPM1_ENABLE) == TRUE
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
!endif
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmSvsm.inf
!endif

!if $(TPM2_ENABLE) == TRUE || $(CC_MEASUREMENT_ENABLE) == TRUE
Expand Down
103 changes: 98 additions & 5 deletions OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ SvsmPvalidate (
Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
ZeroMem (Caa->SvsmBuffer, sizeof (Caa->SvsmBuffer));

Function.Id.Protocol = 0;
Function.Id.CallId = 1;
Function.Id.Protocol = SVSM_PROTOCOL_CORE;
Function.Id.CallId = SVSM_CORE_PVALIDATE;

Request = (SVSM_PVALIDATE_REQUEST *)Caa->SvsmBuffer;
EntryLimit = ((sizeof (Caa->SvsmBuffer) - sizeof (*Request)) /
Expand Down Expand Up @@ -407,17 +407,17 @@ SvsmVmsaRmpAdjust (

SvsmCallData.Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();

Function.Id.Protocol = 0;
Function.Id.Protocol = SVSM_PROTOCOL_CORE;

if (SetVmsa) {
Function.Id.CallId = 2;
Function.Id.CallId = SVSM_CORE_CREATE_VCPU;

SvsmCallData.RaxIn = Function.Uint64;
SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
SvsmCallData.RdxIn = (UINT64)(UINTN)Vmsa + SIZE_4KB;
SvsmCallData.R8In = ApicId;
} else {
Function.Id.CallId = 3;
Function.Id.CallId = SVSM_CORE_DELETE_VCPU;

SvsmCallData.RaxIn = Function.Uint64;
SvsmCallData.RcxIn = (UINT64)(UINTN)Vmsa;
Expand Down Expand Up @@ -498,3 +498,96 @@ AmdSvsmSnpVmsaRmpAdjust (
return AmdSvsmIsSvsmPresent () ? SvsmVmsaRmpAdjust (Vmsa, ApicId, SetVmsa)
: BaseVmsaRmpAdjust (Vmsa, SetVmsa);
}

/**
Perform a SVSM_VTPM_QUERY operation

Query the support provided by the SVSM vTPM.

@param[out] PlatformCommands It will contain a bitmap indicating the
supported vTPM platform commands.
@param[out] Features It will contain a bitmap indicating the
supported vTPM features.

@retval TRUE The query was processed.
@retval FALSE The query was not processed.

**/
BOOLEAN
EFIAPI
AmdSvsmVtpmQuery (
OUT UINT64 *PlatformCommands,
OUT UINT64 *Features
)
{
SVSM_CALL_DATA SvsmCallData;
SVSM_FUNCTION Function;

if (!PlatformCommands && !Features) {
return FALSE;
}

if (!AmdSvsmIsSvsmPresent ()) {
return FALSE;
}

Function.Id.Protocol = SVSM_PROTOCOL_VTPM;
Function.Id.CallId = SVSM_VTPM_QUERY;

SvsmCallData.Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
SvsmCallData.RaxIn = Function.Uint64;

if (SvsmMsrProtocol (&SvsmCallData)) {
return FALSE;
}

if (PlatformCommands) {
*PlatformCommands = SvsmCallData.RcxOut;
}

if (Features) {
*Features = SvsmCallData.RdxOut;
}

return TRUE;
}

/**
Perform a SVSM_VTPM_CMD operation

Send the specified vTPM platform command to the SVSM vTPM.

@param[in, out] Buffer It should contain the vTPM platform command
request. The respective response will be returned
in the same Buffer, but not all commands specify a
response.

@retval TRUE The command was processed.
@retval FALSE The command was not processed.

**/
BOOLEAN
EFIAPI
AmdSvsmVtpmCmd (
IN OUT UINT8 *Buffer
)
{
SVSM_CALL_DATA SvsmCallData;
SVSM_FUNCTION Function;
UINTN Ret;

if (!AmdSvsmIsSvsmPresent ()) {
return FALSE;
}

Function.Id.Protocol = SVSM_PROTOCOL_VTPM;
Function.Id.CallId = SVSM_VTPM_CMD;

SvsmCallData.Caa = (SVSM_CAA *)AmdSvsmSnpGetCaa ();
SvsmCallData.RaxIn = Function.Uint64;
SvsmCallData.RcxIn = (UINT64)(UINTN)Buffer;

Ret = SvsmMsrProtocol (&SvsmCallData);

return (Ret == 0) ? TRUE : FALSE;
}
35 changes: 1 addition & 34 deletions SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/Tpm2DeviceLib.h>
#include <Library/PcdLib.h>

#include "Tpm2Ptp.h"
#include "Tpm2DeviceLibDTpm.h"

/**
This service enables the sending of commands to the TPM2.

@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.

@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
**/
EFI_STATUS
EFIAPI
DTpm2SubmitCommand (
IN UINT32 InputParameterBlockSize,
IN UINT8 *InputParameterBlock,
IN OUT UINT32 *OutputParameterBlockSize,
IN UINT8 *OutputParameterBlock
);

/**
This service requests use TPM2.

@retval EFI_SUCCESS Get the control of TPM2 chip.
@retval EFI_NOT_FOUND TPM2 not found.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
EFIAPI
DTpm2RequestUseTpm (
VOID
);

/**
This service enables the sending of commands to the TPM2.

Expand Down
96 changes: 96 additions & 0 deletions SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmSvsm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/** @file
This library is a TPM2 DTPM instance, supporting SVSM based vTPMs and regular
TPM2s at the same time.
Choosing this library means platform uses and only uses DTPM device as TPM2 engine.

Copyright (c) 2024 Red Hat
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/BaseLib.h>
#include <Library/Tpm2DeviceLib.h>

#include "Tpm2DeviceLibDTpm.h"
#include "Tpm2PtpSvsmShim.h"

/**
This service enables the sending of commands to the TPM2.

@param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
@param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
@param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
@param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.

@retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
@retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
@retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
**/
EFI_STATUS
EFIAPI
Tpm2SubmitCommand (
IN UINT32 InputParameterBlockSize,
IN UINT8 *InputParameterBlock,
IN OUT UINT32 *OutputParameterBlockSize,
IN UINT8 *OutputParameterBlock
)
{
return SvsmDTpm2SubmitCommand (
InputParameterBlockSize,
InputParameterBlock,
OutputParameterBlockSize,
OutputParameterBlock
);
}

/**
This service requests use TPM2.

@retval EFI_SUCCESS Get the control of TPM2 chip.
@retval EFI_NOT_FOUND TPM2 not found.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
EFIAPI
Tpm2RequestUseTpm (
VOID
)
{
return SvsmDTpm2RequestUseTpm ();
}

/**
This service register TPM2 device.

@param Tpm2Device TPM2 device

@retval EFI_SUCCESS This TPM2 device is registered successfully.
@retval EFI_UNSUPPORTED System does not support register this TPM2 device.
@retval EFI_ALREADY_STARTED System already register this TPM2 device.
**/
EFI_STATUS
EFIAPI
Tpm2RegisterTpm2DeviceLib (
IN TPM2_DEVICE_INTERFACE *Tpm2Device
)
{
return EFI_UNSUPPORTED;
}

/**
The function caches current active TPM interface type.

@retval EFI_SUCCESS DTPM2.0 instance is registered, or system does not support register DTPM2.0 instance
**/
EFI_STATUS
EFIAPI
Tpm2DeviceLibConstructorSvsm (
VOID
)
{
if (TryUseSvsmVTpm ()) {
return EFI_SUCCESS;
} else {
return InternalTpm2DeviceLibDTpmCommonConstructor ();
}
}
66 changes: 66 additions & 0 deletions SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpmSvsm.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## @file
# Provides SVSM based vTPM and regular TPM 2.0 TIS/PTP functions for DTPM
#
# Spec Compliance Info:
# "TCG PC Client Platform TPM Profile(PTP) Specification Family 2.0 Level 00 Revision 00.43"
# "TCG PC Client Specific TPM Interface Specification(TIS) Version 1.3"
#
# This library implements TIS (TPM Interface Specification) and
# PTP (Platform TPM Profile) functions which is
# used for every TPM 2.0 command. Choosing this library means platform uses and
# only uses TPM 2.0 DTPM device.
#
# This version of the library additionally supports SVSM based vTPMs for confidential
# virtual machines under AMD-SEV SNP.
#
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.
# Copyright (c) 2024 Red Hat
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = Tpm2DeviceLibDTpmSvsm
MODULE_UNI_FILE = Tpm2DeviceLibDTpm.uni
FILE_GUID = EE79D4E4-8538-4FE6-A7EF-4095CB6B38E7
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = Tpm2DeviceLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = Tpm2DeviceLibConstructorSvsm
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = X64
#

[Sources]
Tpm2Tis.c
Tpm2Svsm.c
Tpm2PtpSvsmShim.c
Tpm2Ptp.c
Tpm2DeviceLibDTpmSvsm.c
Tpm2DeviceLibDTpmBase.c
Tpm2DeviceLibDTpm.h

[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
UefiCpuPkg/UefiCpuPkg.dec

[LibraryClasses]
BaseLib
BaseMemoryLib
IoLib
TimerLib
DebugLib
PcdLib
AmdSvsmLib

[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES
gEfiSecurityPkgTokenSpaceGuid.PcdActiveTpmInterfaceType ## PRODUCES
gEfiSecurityPkgTokenSpaceGuid.PcdCRBIdleByPass ## PRODUCES
gEfiSecurityPkgTokenSpaceGuid.PcdSvsmVTpmPresence ## PRODUCES
gEfiSecurityPkgTokenSpaceGuid.PcdSvsmVTpmBufferPtr ## PRODUCES
Loading
Loading