01/31/2018 OVMF Serial port Debugging on QEMU

It is a sunny day and it seems impossible for me to witness snowfall in Beijing this year anyway, even if almost every other place is reporting snow alerts recently... Another thing is that debug recording does improve my working efficiency, so I will insist anyway.

This passage main describes how I have tried to debug the TPM support issue. Here we are mainly focusing on the configuration of the development platform of TPM based Rmt-Attestation.


TPM Based Rmt-Attestation in UEFI System

(1) The DEBUG Macro and Usage of Serial Port Console

Reference from the links followed:

The debug info of tianocore will be dumped into debug.log by running

../vtpm-support/qemu-tpm/x86_64-softmmu/qemu-system-x86_64 -display sdl \
-m 2048 -serial file:/home/hecmay/debug.log -global isa-debugcon.iobase=0x402 -net none \
-boot c -bios Build/Ovmf3264/DEBUG_GCC5/FV/OVMF.fd -boot menu=on \
-tpmdev cuse-tpm,id=tpm0,path=/dev/vtpm0 -device tpm-tis,tpmdev=tpm0 Build/test.img

Example of the debug.log content:

SecCoreStartupWithStack(0xFFFCC000, 0x820000)
Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE
Install PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3
Install PPI: 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
The 0th FV start address is 0x00000820000, size is 0x000E0000, handle is 0x820000
Register PPI Notify: 49EDB1C1-BF21-4761-BB12-EB0031AABB39
Register PPI Notify: EA7CA24B-DED5-4DAD-A389-BF827E8F9B38
Install PPI: B9E0ABFE-5979-4914-977F-6DEE78C278A6
Install PPI: DBE23AA9-A345-4B97-85B6-B226F1617389
Loading PEIM at 0x0000082C100 EntryPoint=0x0000082CB42 PcdPeim.efi
Install PPI: 06E81C58-4AD7-44BC-8390-F10265F72480
Install PPI: 01F34D25-4DE2-23AD-3FF3-36353FF323F1
Install PPI: 4D8B155B-C059-4C8F-8926-06FD4331DB8A
Install PPI: A60C6B59-E459-425D-9C69-0BCC9CB27D81
Register PPI Notify: 605EA650-C65C-42E1-BA80-91A52AB618C6
Loading PEIM at 0x000008308C0 EntryPoint=0x00000831C7F ReportStatusCodeRouterPei.efi
Install PPI: 0065D394-9951-4144-82A3-0AFC8579C251
Install PPI: 229832D3-7A30-4B36-B827-F40CB7D45436
Loading PEIM at 0x00000832940 EntryPoint=0x00000832E48 StatusCodeHandlerPei.efi
Loading PEIM at 0x00000834AC0 EntryPoint=0x00000834D00 PlatformPei.efi
Select Item: 0x0
FW CFG Signature: 0x554D4551
Select Item: 0x1
FW CFG Revision: 0x1
QemuFwCfg interface (IO Port) is supported.
Platform PEIM Loaded
CMOS:
00: 39 00 26 00 06 00 02 29 01 18 26 02 00 80 00 00
10: 40 00 F0 00 07 80 02 FF FF 2F 00 08 02 10 FF FF
20: C8 08 02 3F 00 00 00 00 00 00 00 00 00 00 00 00
30: FF FF 20 00 00 7F 00 20 00 00 00 00 00 02 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

(2) The TPM support issues not mentioned in Tiano Guidance

From the log we locate the important pieces of info of TPM

Loading driver at 0x0007E913000 EntryPoint=0x0007E913A81 TcgConfigDxe.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7F198298
ProtectUefiImageCommon - 0x7F198040
  - 0x000000007E913000 - 0x0000000000004E00
Image type IA32 can't be started on X64 UEFI system.
//
// ........
//
Loading driver at 0x0007FAC7000 EntryPoint=0x0007FAC7240 TcgDxe.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7F1BCE98
ProtectUefiImageCommon - 0x7F1BCBC0
  - 0x000000007FAC7000 - 0x0000000000004BC0
No TPM12 instance required!
Error: Image at 0007FAC7000 start failed: Unsupported
//
// ..........
//
Found TCG support in Port 0 PortMultiplierPort 0

// Also note that the TcgPeo.efi was not loaded in the PEI phase

1.The TpmPei.efi was not loaded

// SecurityPkg/Tcg/TcgPei/TcgPei.inf
[Depex]
  gEfiPeiMasterBootModePpiGuid AND
  gEfiPeiReadOnlyVariable2PpiGuid AND
  gEfiTpmDeviceSelectedGuid

Check these three dependency expression independently referring to DEBUG log.

//MdePkg/Mdepkg.dec
[Ppis]
  ## Include/Ppi/MasterBootMode.h
  gEfiPeiMasterBootModePpiGuid = { 0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, \
0xc0, 0x92, 0xa4, 0x10 } }
// ..........
  ## Include/Ppi/ReadOnlyVariable2.h
  gEfiPeiReadOnlyVariable2PpiGuid = { 0x2ab86ef5, 0xecb5, 0x4134, { 0xb5, 0x56, 0x38, 0x54, \
0xca, 0x1f, 0xe1, 0xb4 } }
//...........
// SecurityPkg/SecurityPkg.dec
  ## GUID used to select supported TPM instance from UI.
  #  Include/Guid/TpmInstance.h
  gEfiTpmDeviceSelectedGuid          = { 0x7f4158d3, 0x74d, 0x456d, { 0x8c, 0xb2, 0x1, 0xf9, \
0xc8, 0xf7, 0x9d, 0xaa } }

The gEfiPeiMasterBootModePpi has been installed by certain PEIM referring to debug.log. But the gEfiPeiReadOnlyVariable2Ppi is not installed (gEfiTpmDeviceSelectedGuid should only be a GUID used for TPM device selection).

// MdeModulePkg/Universal/Variable/Pei/Variable.c
EFI_STATUS
EFIAPI
PeimInitializeVariableServices (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
{
  return PeiServicesInstallPpi (&mPpiListVariable);

// MdeModulePkg/Universal/Variable/Pei/PeiVariable.inf
// Implements ReadOnly Variable Services required by PEIM and installs PEI ReadOnly Varaiable2 PPI
[Depex]
  gEdkiiFaultTolerantWriteGuid

// MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
// This module installs gEdkiiFaultTolerantWriteGuid PPI to inform the check 
// for FTW last write data has been done. This PEIM is not loaded.
[Depex]
  TRUE

So the solution is to add FaultTolerantWritePei.inf and PeiVariable.inf to the Components of Ovmf.dsc Also comment the gEfiTpmDeviceSelectedGuid and make some further modification to Flash Non-Volatile Working Base Address. Details of which will be mentioned in Section (4)

With amendments showed above, we will run PEIM of TcgPei successfully:

Loading PEIM at 0x0007FEBE000 EntryPoint=0x0007FEBF18A TcgPei.efi
TPM12Startup: TPM_SUCCESS
Install PPI: E9DB0D58-D48D-47F6-9C6E-6F40E86C7B41
Install PPI: A030D115-54DD-447B-9064-F206883D7CCC

The Tpm12Startup Function in Tpm12CommandLib, which is called in the Entry Point Function of TcgPei:

// SecurityPkg/Library/Tpm12CommandLib/Tpm12Startup.c
EFI_STATUS
EFIAPI
Tpm12Startup (
  IN TPM_STARTUP_TYPE  TpmSt
  )
{
  EFI_STATUS           Status;
  TPM_CMD_START_UP     Command;
  TPM_RSP_COMMAND_HDR  Response;
  UINT32               Length;

  //
  // send Tpm command TPM_ORD_Startup
  //
  Command.Hdr.tag       = SwapBytes16 (TPM_TAG_RQU_COMMAND);
  Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
  Command.Hdr.ordinal   = SwapBytes32 (TPM_ORD_Startup);
  Command.TpmSt         = SwapBytes16 (TpmSt);
  Length = sizeof (Response);
  Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  switch (SwapBytes32(Response.returnCode)) {
  case TPM_SUCCESS:
    DEBUG ((DEBUG_INFO, "TPM12Startup: TPM_SUCCESS\n"));
    return EFI_SUCCESS;
  case TPM_INVALID_POSTINIT:
    // In warm reset, TPM may response TPM_INVALID_POSTINIT
    DEBUG ((DEBUG_INFO, "TPM12Startup: TPM_INVALID_POSTINIT\n"));
    return EFI_SUCCESS;
  default:
    return EFI_DEVICE_ERROR;
  }
}

2.The TPM 1.2 is not required
And in the SecurityPkg/Tcg/TcgDxe/TcgDxe.c driver:

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

The PcdGetPtr function will retrieve PCD value with the token passed in from the DEC file of the Pkg.
The PCD value should be set up in advance to pair with the TPM_DEVICE_INTERFACE_TPM12 or other macros.

// SecurityPkg/SecurityPkg.dec   
  ## GUID value used for PcdTpmInstanceGuid to indicate TPM 1.2 device is selected to support.
  #  Include/Guid/TpmInstance.h
  gEfiTpmDeviceInstanceTpm12Guid     = { 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, \
0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }
//
// ........
//
  ## Guid name to identify TPM instance.<BR><BR>
  #  TPM_DEVICE_INTERFACE_NONE means disable.<BR>
  #  TPM_DEVICE_INTERFACE_TPM12 means TPM 1.2 DTPM.<BR>
  #  TPM_DEVICE_INTERFACE_DTPM2 means TPM 2.0 DTPM.<BR>
  #  Other GUID value means other TPM 2.0 device.<BR>
  # @Prompt TPM device type identifier
  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid |{ 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0x0001000F

So the gEfiTpmDeviceInstanceTpm12Guid is the same GUID with TPM_DEVICE_INTERFACE_TPM12:

//SecurityPkg/Include/Guid/TpmInstance.h
#define TPM_DEVICE_INTERFACE_TPM12  \
  { 0x8b01e5b6, 0x4f19, 0x46e8, { 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc } }

However, simply setting the PcdTpmInstanceGuid to the GUID corresponding to TPM12 does not work
{ 0x8b, 0x01, 0xe5, 0xb6, 0x4f, 0x19, 0x46, 0xe8, 0xab, 0x93, 0x1c, 0x53, 0x67, 0x1b, 0x90, 0xcc }

The Pcd value obtained by PcdGetPtr is up-tail-down in position.

TpmInstanceguid:  B6E5018B-194F-E846-AB93-1C53671B90CC
Tpm12Guid:        8B01E5B6-4F19-46E8-AB93-1C53671B90CC

Even if we set the same GUID manually, there will still be other errors:

Loading driver at 0x0007FAC8000 EntryPoint=0x0007FAC8240 TcgDxe.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7F1BCF18
ProtectUefiImageCommon - 0x7F1BCBC0
  - 0x000000007FAC8000 - 0x0000000000004C00
Tpm12RequestUseTpm - TCG - Not Found
TPM not detected!

This can be strange for the Tpm12RequestUseTpm() has been used successfully in TcgPei when locating EFI_TCG_PROTOCOL. The calling convention in Entry Point Function of TcgPei PEIM:

  if (!mImageInMemory) {
    Status = Tpm12RequestUseTpm ();
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      goto Done;
    }

    if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm12Startup (TPM_ST_STATE);
      } else {
        Status = Tpm12Startup (TPM_ST_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        goto Done;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      Status = Tpm12ContinueSelfTest ();
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }

    //
    // Only intall TpmInitializedPpi on success
    //
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

So the TPM12 should have been detected and EFI_TCG_PROTOCOL actually existed in PEI phase. The details of Tpm12RequestUseTpm() in Tpm12DeviceLibTcg Library is like:

// SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.c
/**
  This service requests use TPM12.

  @retval EFI_SUCCESS      Get the control of TPM12 chip.
  @retval EFI_NOT_FOUND    TPM12 not found.
  @retval EFI_DEVICE_ERROR Unexpected device behaviour.
**/
EFI_STATUS
EFIAPI
Tpm12RequestUseTpm (
  VOID
  )
{
  EFI_STATUS   Status;

  if (mTcgProtocol == NULL) {
    Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &mTcgProtocol);
    if (EFI_ERROR (Status)) {
      //
      // TCG protocol is not installed. So, TPM12 is not present.
      //
      DEBUG ((EFI_D_ERROR, "Tpm12RequestUseTpm - TCG - %r\n", Status));
      return EFI_NOT_FOUND;
    }
  }
  //
  // Assume when TCG Protocol is ready, RequestUseTpm already done.
  //
  return EFI_SUCCESS;
}

3. The Image of TcgConfigDxe.efi type incompatibility
To declare one of my misunderstandings: OvmfIA32X64 is not for a specific architecture but a combination of IA32 and X64 in different phases:

// OvmfPkg/README
                             PEI arch   DXE arch   UEFI interfaces
* OvmfPkg/OvmfPkgIa32.dsc      IA32       IA32           IA32
* OvmfPkg/OvmfPkgIa32X64.dsc   IA32       X64            X64
* OvmfPkg/OvmfPkgX64.dsc       X64        X64            X64

So the TcgConfigDxe.efi can be compiled with IA32 target wrongly somehow. To avoid this, we use X64 Architecture as target for all phases.

(3) Details of Modification to Ovmf.dsc to enable TPM support

in the Vimdiff we can see the difference shown with the original and modified version.
Vimdiff showing modification

With knowledge from the analysis mentioned above, modify the DSC file further. In this part, we will describe explicitly how each part should be modified in OVMF.dsc and OVMF.dec.

Note that '*' means changing and "+" means adding.

1. Secure Boot Setting

  • Make sure the following lib instances exist in OVMF.dsc
    [LibraryClasses] IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
    [LibraryClasses] OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf *
  • Make sure BaseCrptolib instances exist in different [LibraryClasses.common.phase]
    For PEI driver: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +
    For DXE driver: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +
    For RUNTIME driver: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
    For SMM driver: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
  • Replace the Null Platform Security lib instance with
    [LibraryClasses] PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
  • Ensure DxeImageVerificationLib is added to module SecurityStubDxe in the platform DSC file
    MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
       <LibraryClasses>
          NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
    }
  • Add Authenticated Variable driver INF in OVMF.dsc
    SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf +
    SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf +
    SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +

Following steps are for OVMF.fdf or VarStore.fdf.inc configuration

  • Remove original variable driver INF from the platform FDF file
    INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
    INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf -
  • Add Authenticated Variable Driver INF to the platform FDF file
    INF SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf +
    INF SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf +
    INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +
  • Update Variable GUID value of VARIABLE_STORE_HEADER in VarStore.fdf.inc as
 #Signature: gEfiAuthenticatedVariableGuid =
    # {0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92}}
    0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
    0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,

Following steps are for PCD configuration in paltform DEC

  • Set gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize for certificate storage purpose
    gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400|UINT32|0x30000003
  • Set a platform policy of image verification by PCDs in [PcdsFixedAtBuild] of SecurityPkg.dec
    https://github.com/tianocore/tianocore.github.io/wiki/How-to-Enable-Security#How_to_add_Secure_Boot_to_DSC_and_FDF

Optional

  • Enable SMM authenticated variable
    [Components] SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf

2. TPM Support Setting in OVMF

  • Ensure OpensslLib library instance is defined in [LibraryClasses] of the platform DSC*
    [LibraryClasses] IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
    [LibraryClasses] OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
  • Ensure BaseCryptLib library instances in each phase are defined in the platfrom
    DSC

    PEI phase: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
    DXE phase: BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
  • Add TPM library instance in the platform DSC file
    TPM Command Lib
    SecurityPkg/Library/TpmCommLib/TpmCommLib.inf +
    TCG physical presence library
    SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf +
    TPM measure boot library
    SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +
  • ** Add TPM drivers to [Component] section of the platform DSC**
    SecurityPkg/Tcg/TcgPei/TcgPei.inf +
    SecurityPkg/Tcg/TcgDxe/TcgDxe.inf +
    SecurityPkg/Tcg/TcgSmm/TcgSmm.inf +
    SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf +
    SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf +
    SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf +

Configuration for platform FDF and PCD

  • Add TPM drivers to the platform FDF
    INF SecurityPkg/Tcg/TcgPei/TcgPei.inf +
    INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf +
    INF SecurityPkg/Tcg/TcgSmm/TcgSmm.inf +
    INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf +
    INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf +
    INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf +
  • Set the platform policy by PCDs
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass|0|UINT8|0x00000006
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport|FALSE|BOOLEAN|0x00000007

3. Amendments during building OVMF
For the guidance on the Tianocore Wiki is way too old, which is written for UDK2010, the newest EDKII will need further modification to the configuration in order to run Secure Boot and TPM Support.

  • Documnetation Compatibility
1. SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf  not existent ---> MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
2. Add MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
3. SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf not existent ---> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf (duplicated)
4. Duplicated document: SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
  • Library Issues:
1. Tpm12DeviceLib lib clasee for PEIM not found: SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf
2. Tpm12CommandLib for PEIM not found: SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
3. Tpm12DeviceLib for DXE Driver not found: SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
4. Tpm12CommandLib for DXE Driver not found: SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf
5. TcgPpVendorLib for SMM Driver not found: SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf

(4) Modification to Fault Tolerant Write PEIM

The result demonstrates the correctness of our hypothesis. But some novel bugs emerged.....

Install PPI: EE16160A-E8BE-47A6-820A-C6900DB0250A
Loading PEIM at 0x0007FEC7000 EntryPoint=0x0007FEC8469 FaultTolerantWritePei.efi
ASSERT [FaultTolerantWritePei] /home/hecmay/Desktop/Tiano/edk2/MdeModulePkg/Universal\
/FaultTolerantWritePei/FaultTolerantWritePei.c(241): (WorkSpaceAddress != 0) && (SpareAreaAddress != 0)

OK. Let us have a look where is wrong in the FaultTolerantWritePei.c

// MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.c
EFI_STATUS
EFIAPI
PeimFaultTolerantWriteInitialize (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS                                Status;
  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER   *FtwWorkingBlockHeader;
  EFI_FAULT_TOLERANT_WRITE_HEADER           *FtwLastWriteHeader;
  EFI_FAULT_TOLERANT_WRITE_RECORD           *FtwLastWriteRecord;
  EFI_PHYSICAL_ADDRESS                      WorkSpaceAddress;
  UINTN                                     WorkSpaceLength;
  EFI_PHYSICAL_ADDRESS                      SpareAreaAddress;
  UINTN                                     SpareAreaLength;
  EFI_PHYSICAL_ADDRESS                      WorkSpaceInSpareArea;
  FAULT_TOLERANT_WRITE_LAST_WRITE_DATA      FtwLastWrite;

  FtwWorkingBlockHeader = NULL;
  FtwLastWriteHeader = NULL;
  FtwLastWriteRecord = NULL;

  WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwWorkingBase64);
  if (WorkSpaceAddress == 0) {
    WorkSpaceAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwWorkingBase);
  }
  WorkSpaceLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwWorkingSize);

  SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageFtwSpareBase64);
  if (SpareAreaAddress == 0) {
    SpareAreaAddress = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageFtwSpareBase);
  }
  SpareAreaLength = (UINTN) PcdGet32 (PcdFlashNvStorageFtwSpareSize);

  //
  // The address of FTW working base and spare base must not be 0.
  //
  ASSERT ((WorkSpaceAddress != 0) && (SpareAreaAddress != 0));

the issue should be relevant to the PCD default setting in the configuration.

  • PcdFlashNvStorageFtwWorkingBase64 || PcdFlashNvStorageFtwWorkingBase
  • PcdFlashNvStorageFtwSpareBase64 || PcdFlashNvStorageFtwSpareBase
  • Size: PcdFlashNvStorageFtwWorkingSize || PcdFlashNvStorageFtwSpareSize

Reference:

I still cannot fully understand why the FTW working space base address should not be 0x0? it seems that the address is required to be aligned. if we comment the ASSERT, similar error will appear:

Loading PEIM at 0x0007FEC7000 EntryPoint=0x0007FEC8469 FaultTolerantWritePei.efi
ASSERT [FaultTolerantWritePei] /home/hecmay/Desktop/Tiano/edk2/MdePkg/Library/BaseLib/Unaligned.c(192): Buffer != ((void *) 0)

The difference between OVMF and physical machine is another possible reason:

// OvmfPkg/OvmfPkg.fdf.inc 
!if $(FD_SIZE_IN_KB) == 4096
DEFINE VARS_LIVE_SIZE    = 0x40000
DEFINE FW_BASE_ADDRESS   = 0xFFC00000

//
// ......
//

SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase = $(FW_BASE_ADDRESS)
SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = $(VARS_LIVE_SIZE)

SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase = \
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase + \
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZE)

SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = \
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + \
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(VARS_SPARE_SIZE)

The solution is to replace the PCD Token in the original PcdFlashNvStorageWorkingBase with PcdOvmfFlashNvStorageWorkingBase. Remenber to add OVMF platform DEC to [Packages] part of FTW PEIM INF and include the new PCD token in the [Pcd] part.

in my understanding, the FlashNvStorageWorking Base Address should be dependent to different firmware volume setting, and its value will be set dynamically. The default value is like a reminder, which is set to be 0x0 is to confirm whether the Base Address has been initialized by using ASSERT.

(5) Conclusion and Future Plans

We have demonstrated that TPM can be detected in UEFI PEI Phase. The PEIM named TcgPei.efi will initialize TPM by calling Tpm with Tpm12RequestUseTpm() and Startup TPM

  • Why the TPM DXE Driver failed to locate EFI_TCG_PROTOCOL when calling Tpm12RequestUseTpm() function, which has been successfully called by TPM PEI Driver in its Entry Point function?
  • What is the mechanism in UEFI to detect the type of TPM? Is the EFI_TCGPROTOCOL compatible with EFI_TCG_PROTOCOL? and how are they implemented?

(6) Update for Debugging on 02/02/2018:

The bug is finally resolved. Along with the procedures shown above, we should also be aware of the correctness of the Tpm12DeviceLib we are using.

Change the Tpm12DeviceLibTcg used in OVMF.dsc [LibraryClasses.common.DEX_DRIVER] to Tpm12DeviceLibDTpm should work. The first Lib will not install EFI_TCG_PROTOCOL and can only be used with a EFI_TCG_PROTOCOL installed.

Tpm12 PCR values

OK, we can go to the next stage of testing the Socket model in UEFI environment and build up the Remote-Attestation framework based on it.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容