Skip to content

Commit

Permalink
Fix support for TPM on Q35 (#633)
Browse files Browse the repository at this point in the history
## Description

Fixes issue related to enabling TPM for QEMU Q35.

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

Locally tested with Windows boot.

## Integration Instructions

N/A
  • Loading branch information
cfernald authored Jul 19, 2023
1 parent a467084 commit 7b1bfe2
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 10 deletions.
43 changes: 43 additions & 0 deletions Platforms/Docs/Q35/Features/feature_tpm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# TPM Emulation

For more information on QEMU tpm, see the [QEMU TPM Documentation](https://www.qemu.org/docs/master/specs/tpm.html#the-qemu-tpm-emulator-device).

The QEMU TPM relies on a seperate program to emulate the TPM. Currently, this is
only supported on Linux using the [swtpm program](https://github.com/stefanberger/swtpm).
Swtpm can be installed from the linux package managers.

```bash
sudo apt-get install swtpm
```

To start the TPM emulator, invoke swtpm with a state file location and character
device.

```bash
mkdir /tmp/mytpm1
swtpm socket --tpmstate dir=/tmp/mytpm1 \
--ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
--tpm2 \
--log level=20
```

To run Q35 using this TPM, build and run with the following options. `TPM_DEV` should
point to the path of the character device from the above swtpm command.

```bash
stuart_build -c Platforms/QemuQ35Pkg/PlatformBuild.py --flashrom TOOL_CHAIN_TAG=GCC5 BLD_*_TPM_ENABLE=TRUE TPM_DEV=/tmp/mytpm1/swtpm-sock
```

In the window running swtpm, there should be output from the TPM communication.

```txt
Ctrl Cmd: length 4
00 00 00 10
Ctrl Rsp: length 4
00 00 00 00
SWTPM_IO_Read: length 10
80 01 00 00 00 0A 00 00 01 81
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 01 01
...
```
11 changes: 9 additions & 2 deletions Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ def Runner(env):
args += " -m 8192"

file_extension = Path(path_to_os).suffix.lower().replace('"', '')

storage_rule = {
".vhd": f" -drive format=raw,index=0,media=disk,file=\"{path_to_os}\"",
".qcow2": f" -hda \"{path_to_os}\""
}.get(file_extension, None)

if storage_rule is None:
raise Exception("Unknown OS storage type: " + path_to_os)

args += storage_rule
else:
args += " -m 2048"
Expand Down Expand Up @@ -179,6 +179,13 @@ def Runner(env):
args += " -smbios type=1,manufacturer=Palindrome,product=MuQemuQ35,serial=42-42-42-42,uuid=9de555c0-05d7-4aa1-84ab-bb511e3a8bef"
args += f" -smbios type=3,manufacturer=Palindrome,serial=40-41-42-43{boot_selection}"

# TPM in Linux
tpm_dev = env.GetValue("TPM_DEV")
if tpm_dev is not None:
args += f" -chardev socket,id=chrtpm,path={tpm_dev}"
args += " -tpmdev emulator,id=tpm0,chardev=chrtpm"
args += " -device tpm-tis,tpmdev=tpm0"

if (env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
args += " -display none" # no graphics
else:
Expand Down
12 changes: 6 additions & 6 deletions Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
# -D FLAG=VALUE
#
DEFINE SOURCE_DEBUG_ENABLE = FALSE
!ifndef TPM_ENABLE
DEFINE TPM_ENABLE = FALSE
!endif
DEFINE TPM_CONFIG_ENABLE = FALSE
DEFINE OPT_INTO_MFCI_PRE_PRODUCTION = TRUE
DEFINE BUILD_UNIT_TESTS = TRUE
Expand Down Expand Up @@ -445,7 +447,7 @@
Tpm12DeviceLib |SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
Tpm2DeviceLib |SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
SourceDebugEnabledLib |SourceLevelDebugPkg/Library/SourceDebugEnabled/SourceDebugEnabledLib.inf
Tcg2PreUefiEventLogLib |SecurityPkg/Library/QemuQ35PkgPreUefiEventLogLib/QemuQ35PkgPreUefiEventLogLib.inf ## BRET - Do we have a null instance
Tcg2PreUefiEventLogLib |QemuPkg/Library/QemuPreUefiEventLogLibNull/QemuPreUefiEventLogLibNull.inf
!endif

[LibraryClasses.X64.PEIM]
Expand Down Expand Up @@ -855,6 +857,9 @@
gUefiQemuQ35PkgTokenSpaceGuid.PcdPciMmio64Base|0x0
gUefiQemuQ35PkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000

# Limit to SHA256 for now.
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0x00002

gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0

gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
Expand Down Expand Up @@ -973,7 +978,6 @@

!if $(TPM_ENABLE) == TRUE
QemuPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
SecurityPkg/Tcg/TcgPei/TcgPei.inf
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
<LibraryClasses>
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
Expand Down Expand Up @@ -1469,10 +1473,6 @@
NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
}
SecurityPkg/Tcg/TcgDxe/TcgDxe.inf {
<LibraryClasses>
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
}
!endif
!if $(TPM_CONFIG_ENABLE) == TRUE AND $(TPM_ENABLE) == TRUE
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
Expand Down
2 changes: 0 additions & 2 deletions Platforms/QemuQ35Pkg/QemuQ35Pkg.fdf
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf

!if $(TPM_ENABLE) == TRUE
INF QemuPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
INF SecurityPkg/Tcg/TcgPei/TcgPei.inf
INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
!endif

Expand Down Expand Up @@ -476,7 +475,6 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
# TPM support
#
!if $(TPM_ENABLE) == TRUE
INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
!if $(TPM_CONFIG_ENABLE) == TRUE
INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @file
NULL implementation of PreUefiEventLogLib for QEMU.
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/DebugLib.h>

/**
Create the event log entries, Nothing to do for QEMU.
**/
VOID
CreateTcg2PreUefiEventLogEntries (
VOID
)
{
return;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## @file
# NULL PreUefiEventLogLibNull library instance for QEMU
#
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = QemuPreUefiEventLogLibNull
FILE_GUID = A3E24CE0-4E7D-4164-9A5B-90DFBE2F5744
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = Tcg2PreUefiEventLogLib

[Sources]
QemuPreUefiEventLogLibNull.c

[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
1 change: 1 addition & 0 deletions QemuPkg/QemuPkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
QemuPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
QemuPkg/Library/VirtioLib/VirtioLib.inf
QemuPkg/Library/QemuFwCfgLib/QemuFwCfgLibNull.inf
QemuPkg/Library/QemuPreUefiEventLogLibNull/QemuPreUefiEventLogLibNull.inf
QemuPkg/Library/XenPlatformLib/XenPlatformLib.inf
QemuPkg/FrontPageButtons/FrontPageButtons.inf
QemuPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
Expand Down

0 comments on commit 7b1bfe2

Please sign in to comment.