diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib')
5 files changed, 942 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c new file mode 100644 index 0000000..ffb8480 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.c @@ -0,0 +1,838 @@ +/** @file + This file is SampleCode for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#include "EdkIIGluePeim.h" +#include "CpuAccess.h" +#endif + +#include <EfiTpm.h> +#include "BootGuardTpmEventLogLib.h" + +// +// Data structure definition +// +#pragma pack (1) + +#define BASE_4GB 0x0000000100000000ULL +// +// FIT definition +// +#define FIT_TABLE_TYPE_HEADER 0x0 +#define FIT_TABLE_TYPE_MICROCODE 0x1 +#define FIT_TABLE_TYPE_STARTUP_ACM 0x2 +#define FIT_TABLE_TYPE_BIOS_MODULE 0x7 +#define FIT_TABLE_TYPE_KEY_MANIFEST 0xB +#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST 0xC + +typedef struct { + UINT64 Address; + UINT8 Size[3]; + UINT8 Reserved; + UINT16 Version; + UINT8 Type : 7; + UINT8 Cv : 1; + UINT8 Chksum; +} FIRMWARE_INTERFACE_TABLE_ENTRY; + +// +// ACM definition +// +#define MMIO_ACM_STATUS (TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_ACM_STATUS) +#define ACM_KEY_HASH_MMIO_ADDR_0 0xFED30400 +#define ACM_KEY_HASH_MMIO_ADDR_1 (ACM_KEY_HASH_MMIO_ADDR_0 + 8) +#define ACM_KEY_HASH_MMIO_ADDR_2 (ACM_KEY_HASH_MMIO_ADDR_0 + 16) +#define ACM_KEY_HASH_MMIO_ADDR_3 (ACM_KEY_HASH_MMIO_ADDR_0 + 24) +#define ACM_PKCS_1_5_RSA_SIGNATURE_SIZE 256 +#define ACM_HEADER_FLAG_DEBUG_SIGNED BIT15 +#define ACM_NPW_SVN 0x2 + +typedef struct { + UINT32 ModuleType; + UINT32 HeaderLen; + UINT32 HeaderVersion; + UINT16 ChipsetId; + UINT16 Flags; + UINT32 ModuleVendor; + UINT32 Date; + UINT32 Size; + UINT16 AcmSvn; + UINT16 Reserved1; + UINT32 CodeControl; + UINT32 ErrorEntryPoint; + UINT32 GdtLimit; + UINT32 GdtBasePtr; + UINT32 SegSel; + UINT32 EntryPoint; + UINT8 Reserved2[64]; + UINT32 KeySize; + UINT32 ScratchSize; + UINT8 RsaPubKey[64 * 4]; + UINT32 RsaPubExp; + UINT8 RsaSig[256]; +} ACM_FORMAT; + +// +// Manifest definition +// +#define SHA256_DIGEST_SIZE 32 + +typedef struct { + UINT16 HashAlg; + UINT16 Size; + UINT8 HashBuffer[SHA256_DIGEST_SIZE]; +} HASH_STRUCTURE; + +#define RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT (RSA_PUBLIC_KEY_STRUCT_KEY_SIZE_DEFAULT/8) + +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT32 Exponent; + UINT8 Modulus[RSA_PUBLIC_KEY_STRUCT_KEY_LEN_DEFAULT]; +} RSA_PUBLIC_KEY_STRUCT; + +#define RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT 2048 +#define RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT (RSASSA_SIGNATURE_STRUCT_KEY_SIZE_DEFAULT/8) +typedef struct { + UINT8 Version; + UINT16 KeySize; + UINT16 HashAlg; + UINT8 Signature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; +} RSASSA_SIGNATURE_STRUCT; + +typedef struct { + UINT8 Version; + UINT16 KeyAlg; + RSA_PUBLIC_KEY_STRUCT Key; + UINT16 SigScheme; + RSASSA_SIGNATURE_STRUCT Signature; +} KEY_SIGNATURE_STRUCT; + +#define BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID (*(UINT64 *)"__ACBP__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 HdrStructVersion; + UINT8 PMBPMVersion; + UINT8 BPSVN; + UINT8 ACMSVN; + UINT8 Reserved; + UINT16 NEMDataStack; +} BOOT_POLICY_MANIFEST_HEADER; + +#define IBB_SEGMENT_FLAG_IBB 0x0 +#define IBB_SEGMENT_FLAG_NON_IBB 0x1 +typedef struct { + UINT8 Reserved[2]; + UINT16 Flags; + UINT32 Base; + UINT32 Size; +} IBB_SEGMENT_ELEMENT; + +#define BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__IBBS__") +#define IBB_FLAG_AUTHORITY_MEASURE 0x4 + +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 Reserved1[2]; + UINT8 PbetValue; + UINT32 Flags; + UINT64 IbbMchBar; + UINT64 VtdBar; + UINT32 PmrlBase; + UINT32 PmrlLimit; + UINT64 Reserved2[2]; + HASH_STRUCTURE PostIbbHash; + UINT32 EntryPoint; + HASH_STRUCTURE Digest; + UINT8 SegmentCount; + IBB_SEGMENT_ELEMENT IbbSegment[1]; +} IBB_ELEMENT; + +#define BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMDA__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT16 PmDataSize; +} PLATFORM_MANUFACTURER_ELEMENT; + +#define BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID (*(UINT64 *)"__PMSG__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + KEY_SIGNATURE_STRUCT KeySignature; +} BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT; + +#define KEY_MANIFEST_STRUCTURE_ID (*(UINT64 *)"__KEYM__") +typedef struct { + UINT8 StructureId[8]; + UINT8 StructVersion; + UINT8 KeyManifestVersion; + UINT8 KmSvn; + UINT8 KeyManifestId; + HASH_STRUCTURE BpKey; + KEY_SIGNATURE_STRUCT KeyManifestSignature; +} KEY_MANIFEST_STRAUCTURE; + +// +// DetailPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmRsaSignature[ACM_PKCS_1_5_RSA_SIGNATURE_SIZE]; + UINT8 KmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 BpmRsaSignature[RSASSA_SIGNATURE_STRUCT_KEY_LEN_DEFAULT]; + UINT8 IbbHash[SHA256_DIGEST_SIZE]; +} DETAIL_PCR_DATA; + +// +// AuthorityPCR data +// +typedef struct { + UINT8 BpRstrLow; + UINT8 BpTypeLow; + UINT16 AcmSvn; + UINT8 AcmKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpKeyHash[SHA256_DIGEST_SIZE]; + UINT8 BpmKeyHashFromKm[SHA256_DIGEST_SIZE]; + UINT8 VerifiedBoot; +} AUTHORITY_PCR_DATA; + +// +// Boot Policy Restrictions definition +// +typedef union { + struct { + UINT8 Facb : 1; + UINT8 Dcd : 1; + UINT8 Dbi : 1; + UINT8 Pbe : 1; + UINT8 Bbp : 1; + UINT8 Reserved : 2; + UINT8 BpInvd : 1; + } Bits; + UINT8 Data; +} BP_RSTR_LOW; + +// +// Boot Policy Type definition +// +typedef union { + struct { + UINT8 MeasuredBoot : 1; + UINT8 VerifiedBoot : 1; + UINT8 Hap : 1; + UINT8 Reserved : 5; + } Bits; + UINT8 Data; +} BP_TYPE_LOW; + +#pragma pack () + +// +// OEM_IMPLEMENTATION_BEGIN +// +// SHA calculation and TPM functions are OEM Core/Platform code depended, +// OEM can customize these empty functions for their specific. +// +// For the detail of SHA algorithm, please refer to FIPS PUB 180-2. +// For TPM event log, please refer to TCG EFI Protocol Specification. +// + +// +// Null-defined macro for passing EDK build +// +#define SHA_INIT +#define SHA_UPDATE +#define SHA_FINAL + +/** + Calculate SHA-1 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA-1 digest value. +**/ +VOID +CreateSha1Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate SHA256 Hash + + @param[in] Data Data to be hashed. + @param[in] Size Size of data. + @param[out] Digest SHA256 digest value. +**/ +VOID +CreateSha256Hash ( + IN UINT8 *Data, + IN UINTN Size, + OUT UINT8 *Digest + ) +{ + VOID *Context; + + SHA_INIT (Context); + SHA_UPDATE (Context, Data, Size); + SHA_FINAL (Context, Digest); + + return; +} + +/** + Add a new entry to the Event Log. + + @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. + @param[in] NewEventData Pointer to the new event data. + + @retval EFI_SUCCESS The new event log entry was added. + @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. +**/ +EFI_STATUS +LogEvent ( + IN TCG_PCR_EVENT_HDR *NewEventHdr, + IN UINT8 *NewEventData + ) +{ + + return EFI_SUCCESS; +} +// +// OEM_IMPLEMENTATION_END +// + +/** + Find FIT Entry address data by type + + @param[in] Type FIT Entry type + + @return FIT entry address +**/ +VOID * +FindFitEntryData ( + IN UINT8 Type + ) +{ + FIRMWARE_INTERFACE_TABLE_ENTRY *FitEntry; + UINT32 EntryNum; + UINT64 FitTableOffset; + UINT32 Index; + + FitTableOffset = *(UINT64 *)(UINTN)(BASE_4GB - 0x40); + FitEntry = (FIRMWARE_INTERFACE_TABLE_ENTRY *)(UINTN)FitTableOffset; + if (FitEntry[0].Address != *(UINT64 *)"_FIT_ ") { + return NULL; + } + if (FitEntry[0].Type != FIT_TABLE_TYPE_HEADER) { + return NULL; + } + EntryNum = *(UINT32 *)(&FitEntry[0].Size[0]) & 0xFFFFFF; + for (Index = 0; Index < EntryNum; Index++) { + if (FitEntry[Index].Type == Type) { + return (VOID *)(UINTN)FitEntry[Index].Address; + } + } + + return NULL; +} + +/** + Find the address of ACM. + + @return A pointer to ACM. +**/ +VOID * +FindAcm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_STARTUP_ACM); +} + +/** + Find the address of Boot Policy Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindBpm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST); +} + +/** + Find the address of Key Manifest. + + @return A pointer to Key Manifest data structure. +**/ +VOID * +FindKm ( + VOID + ) +{ + return FindFitEntryData (FIT_TABLE_TYPE_KEY_MANIFEST); +} + +/** + Find BPM element by structureID + + @param[in] Bpm A pointer to BPM data structure. + @param[in] StructureId BPM element StructureID + + @return A pointer to BPM element data structure. +**/ +VOID * +FindBpmElement ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm, + IN UINT64 StructureId + ) +{ + BOOT_POLICY_MANIFEST_HEADER *BpmHeader; + IBB_ELEMENT *IbbElement; + PLATFORM_MANUFACTURER_ELEMENT *PmElement; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignatureElement; + UINT8 *Buffer; + + Buffer = (UINT8 *)Bpm; + + BpmHeader = (BOOT_POLICY_MANIFEST_HEADER *)Buffer; + if (*(UINT64 *)BpmHeader->StructureId != BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_HEADER_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(BOOT_POLICY_MANIFEST_HEADER); + + IbbElement = (IBB_ELEMENT *)Buffer; + if (*(UINT64 *)IbbElement->StructureId != BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(IBB_ELEMENT) + sizeof(IBB_SEGMENT_ELEMENT) * (IbbElement->SegmentCount - 1); + + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + while (*(UINT64 *)PmElement->StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + if (StructureId == BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + Buffer += sizeof(PLATFORM_MANUFACTURER_ELEMENT) + PmElement->PmDataSize; + PmElement = (PLATFORM_MANUFACTURER_ELEMENT *)Buffer; + } + + BpmSignatureElement = (BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *)Buffer; + if (*(UINT64 *)BpmSignatureElement->StructureId != BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return NULL; + } + if (StructureId == BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID) { + return Buffer; + } + return NULL; +} + +/** + Find BPM IBB element + + @param[in] Bpm A pointer to BPM data structure. + + @return A pointer to BPM IBB element data structure. +**/ +VOID * +FindBpmIbb ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_IBB_ELEMENT_STRUCTURE_ID); +} + +/** + Find BPM Signature element + + @param[in] Bpm BPM address + + @return BPM Signature element +**/ +VOID * +FindBpmSignature ( + IN BOOT_POLICY_MANIFEST_HEADER *Bpm + ) +{ + return FindBpmElement (Bpm, BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_STRUCTURE_ID); +} + +/** + Check if ACM is a NPW ACM. + + @retval TRUE It is a NPW ACM + @retval FALSE It is NOT a NPW ACM +**/ +BOOLEAN +IsNpwAcm ( + VOID + ) +{ + ACM_FORMAT *Acm; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + if (Acm == NULL) { + return FALSE; + } + + if (((Acm->Flags & ACM_HEADER_FLAG_DEBUG_SIGNED) == 0) && (Acm->AcmSvn < ACM_NPW_SVN)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard verifies the IBB. + + @retval TRUE It is VerifiedBoot + @retval FALSE It is NOT VerifiedBoot +**/ +BOOLEAN +IsVerifiedBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_VERIFIED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Check if Boot Guard measures IBB into TPM's PCRs. + + @retval TRUE It is MeasuredBoot + @retval FALSE It is NOT MeasuredBoot +**/ +BOOLEAN +IsMeasuredBoot ( + VOID + ) +{ + if ((AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO) & B_MEASURED) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Get the lower 8 bits of Boot Policy Restrictions + + @return The lower 8 bits of BP.RSTR +**/ +UINT8 +GetBpRstrLow ( + VOID + ) +{ + BP_RSTR_LOW BpRstr; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpRstr.Bits.Facb = (UINT8)((SacmInfo & BIT4) >> 4); + BpRstr.Bits.Dcd = (UINT8)((AcmStatus & BIT21) >> 21); + BpRstr.Bits.Dbi = (UINT8)((AcmStatus & BIT22) >> 22); + BpRstr.Bits.Pbe = (UINT8)((AcmStatus & BIT23) >> 23); + BpRstr.Bits.Bbp = (UINT8)((AcmStatus & BIT24) >> 24); + BpRstr.Bits.Reserved = 0; + BpRstr.Bits.BpInvd = 0; + + return BpRstr.Data; +} + +/** + Get the lower 8 bits of Boot Policy Type + + @return The lower 8 bits of BP.TYPE +**/ +UINT8 +GetBpTypeLow ( + VOID + ) +{ + BP_TYPE_LOW BpType; + UINT32 AcmStatus; + UINT64 SacmInfo; + + AcmStatus = MmioRead32 (MMIO_ACM_STATUS); + SacmInfo = AsmReadMsr64 (MSR_BOOT_GUARD_SACM_INFO); + + BpType.Bits.MeasuredBoot = (UINT8)((SacmInfo & BIT5) >> 5); + BpType.Bits.VerifiedBoot = (UINT8)((SacmInfo & BIT6) >> 6); + BpType.Bits.Hap = (UINT8)((AcmStatus & BIT20) >> 20); + BpType.Bits.Reserved = 0; + + return BpType.Data; +} + +/** + Calculate IBB Hash + + @param[in] BpmIbb A pointer to BPM IBB element data structure. + @param[out] Digest IBB digest value. +**/ +VOID +CreateIbbHash ( + IN IBB_ELEMENT *BpmIbb, + OUT UINT8 *Digest + ) +{ + VOID *Context; + UINTN Index; + + SHA_INIT (Context); + + for (Index = 0; Index < BpmIbb->SegmentCount; Index++) { + if (BpmIbb->IbbSegment[Index].Flags == IBB_SEGMENT_FLAG_IBB) { + SHA_UPDATE (Context, (VOID *)(UINTN)BpmIbb->IbbSegment[Index].Base, BpmIbb->IbbSegment[Index].Size); + } + } + + SHA_FINAL (Context, Digest); + + return; +} + +/** + Calculate DetailPCR extend value + + @param[out] Digest DetailPCR digest +**/ +VOID +CaculateDetailPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT *BpmSignature; + DETAIL_PCR_DATA DetailPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + BpmSignature = FindBpmSignature (Bpm); + ASSERT (BpmSignature != NULL); + + DetailPcrData.BpRstrLow = GetBpRstrLow (); + DetailPcrData.BpTypeLow = GetBpTypeLow (); + DetailPcrData.AcmSvn = Acm->AcmSvn; + CopyMem (&DetailPcrData.AcmRsaSignature, &Acm->RsaSig, sizeof(DetailPcrData.AcmRsaSignature)); + CopyMem (&DetailPcrData.KmRsaSignature, &Km->KeyManifestSignature.Signature.Signature, sizeof(DetailPcrData.KmRsaSignature)); + CopyMem (&DetailPcrData.BpmRsaSignature, &BpmSignature->KeySignature.Signature.Signature, sizeof(DetailPcrData.BpmRsaSignature)); + if (IsVerifiedBoot ()) { + CopyMem (&DetailPcrData.IbbHash, &BpmIbb->Digest.HashBuffer, sizeof(DetailPcrData.IbbHash)); + } else { + // + // Calculate IBB hash because it is NOT verified boot, the Digest from IBB can not be trust. + // + CreateIbbHash (BpmIbb, (UINT8 *)&DetailPcrData.IbbHash); + } + + CreateSha1Hash ((UINT8 *)&DetailPcrData, sizeof(DetailPcrData), (UINT8 *)Digest); +} + +/** + Calculate AuthorityPCR extend value + + @param[out] Digest AuthorityPCR digest +**/ +VOID +CaculateAuthorityPCRExtendValue ( + OUT TCG_DIGEST *Digest + ) +{ + ACM_FORMAT *Acm; + KEY_MANIFEST_STRAUCTURE *Km; + AUTHORITY_PCR_DATA AuthorityPcrData; + + Acm = FindAcm (); + ASSERT (Acm != NULL); + + Km = FindKm (); + ASSERT (Km != NULL); + + AuthorityPcrData.BpRstrLow = GetBpRstrLow (); + AuthorityPcrData.BpTypeLow = GetBpTypeLow (); + AuthorityPcrData.AcmSvn = Acm->AcmSvn; + + // + // Get ACM Key hash + // + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[0] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_0); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[8] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_1); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[16] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_2); + *(UINT64 *)&AuthorityPcrData.AcmKeyHash[24] = MmioRead64 (ACM_KEY_HASH_MMIO_ADDR_3); + + // + // Calculate BP Key hash + // + CreateSha256Hash ((UINT8 *)&Km->KeyManifestSignature.Key.Modulus, sizeof(Km->KeyManifestSignature.Key.Modulus), (UINT8 *)&AuthorityPcrData.BpKeyHash); + + CopyMem (&AuthorityPcrData.BpmKeyHashFromKm, &Km->BpKey.HashBuffer, sizeof(AuthorityPcrData.BpmKeyHashFromKm)); + if (IsVerifiedBoot ()) { + AuthorityPcrData.VerifiedBoot = 0; + } else { + AuthorityPcrData.VerifiedBoot = 1; + } + + CreateSha1Hash ((UINT8 *)&AuthorityPcrData, sizeof(AuthorityPcrData), (UINT8 *)Digest); +} + +/** + Check if we need AuthorityPCR measurement + + @retval TRUE Need AuthorityPCR measurement + @retval FALSE Do NOT need AuthorityPCR measurement +**/ +BOOLEAN +NeedAuthorityMeasure ( + VOID + ) +{ + BOOT_POLICY_MANIFEST_HEADER *Bpm; + IBB_ELEMENT *BpmIbb; + + Bpm = FindBpm (); + ASSERT (Bpm != NULL); + + BpmIbb = FindBpmIbb (Bpm); + ASSERT (BpmIbb != NULL); + + if ((BpmIbb->Flags & IBB_FLAG_AUTHORITY_MEASURE) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Create DetailPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateDetailPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + NewEventHdr.PCRIndex = 0; + NewEventHdr.EventType = EV_S_CRTM_CONTENTS; + CaculateDetailPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof ("Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof ("Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, "Boot Guard Measured S-CRTM"); + } +} + +/** + Create AuthorityPCR event log + + @param[in] TpmType TPM type +**/ +VOID +CreateAuthorityPcrEvent ( + IN TPM_TYPE TpmType + ) +{ + TCG_PCR_EVENT_HDR NewEventHdr; + + if (NeedAuthorityMeasure() && IsVerifiedBoot()) { + if (TpmType == dTpm12) { + NewEventHdr.PCRIndex = 6; + } else { + NewEventHdr.PCRIndex = 7; + } + NewEventHdr.EventType = EV_EFI_VARIABLE_DRIVER_CONFIG; + CaculateAuthorityPCRExtendValue (&NewEventHdr.Digest); + + if (IsNpwAcm()) { + NewEventHdr.EventSize = sizeof (L"Boot Guard Debug Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Debug Measured S-CRTM"); + } else { + NewEventHdr.EventSize = sizeof (L"Boot Guard Measured S-CRTM"); + LogEvent (&NewEventHdr, (UINT8 *)L"Boot Guard Measured S-CRTM"); + } + } +} + +/** + Create Boot Guard TPM event log + + @param[in] TpmType Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ) +{ + if (IsMeasuredBoot()) { + CreateDetailPcrEvent (TpmType); + CreateAuthorityPcrEvent (TpmType); + } +} diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif new file mode 100644 index 0000000..06d608a --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.cif @@ -0,0 +1,11 @@ +<component> + name = "BootGuardTpmEventLogLib" + category = ModulePart + LocalRoot = "ReferenceCode\Haswell\SampleCode\Library\BootGuardTpmEventLogLib" + RefName = "BootGuardTpmEventLogLib" +[files] +"BootGuardTpmEventLogLib.sdl" +"BootGuardTpmEventLogLib.mak" +"BootGuardTpmEventLogLib.c" +"BootGuardTpmEventLogLib.h" +<endComponent> diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h new file mode 100644 index 0000000..ca91990 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.h @@ -0,0 +1,33 @@ +/** @file + Header file for Boot Guard TPM event log. + +@copyright + Copyright (c) 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ +#define _BOOT_GUARD_TPM_EVENT_LOG_LIB_H_ + +#include EFI_PPI_DEFINITION (CpuPlatformPolicy) + +/** + Create Boot Guard TPM event log + + @param[in] TpmType - Which type of TPM is available on system. +**/ +VOID +CreateTpmEventLog ( + IN TPM_TYPE TpmType + ); + +#endif diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak new file mode 100644 index 0000000..47a3d87 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.mak @@ -0,0 +1,31 @@ +# MAK file for the ModulePart:AslUpdateLib +all : BootGuardTpmEventLogLib + +$(BUILD_DIR)\BootGuardTpmEventLogLib.lib : BootGuardTpmEventLogLib + +BootGuardTpmEventLogLib : $(BUILD_DIR)\BootGuardTpmEventLogLib.mak BootGuardTpmEventLogLibBin + +$(BUILD_DIR)\BootGuardTpmEventLogLib.mak : $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(BootGuardTpmEventLogLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(BootGuardTpmEventLogLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +BootGuardTpmEventLogLib_INCLUDES=\ + $(PROJECT_CPU_INCLUDES)\ + $(EdkIIGlueLib_INCLUDES)\ + $(iAMT_INCLUDES)\ + $(IndustryStandard_INCLUDES) + +BootGuardTpmEventLogLib_DEFINES=\ + $(MY_DEFINES)\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + +BootGuardTpmEventLogLib_LIBS=\ + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + +BootGuardTpmEventLogLibBin : + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\BootGuardTpmEventLogLib.mak all \ + "MY_INCLUDES=$(BootGuardTpmEventLogLib_INCLUDES)"\ + "MY_DEFINES=$(BootGuardTpmEventLogLib_DEFINES)"\ + TYPE=LIBRARY\
\ No newline at end of file diff --git a/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl new file mode 100644 index 0000000..37c7417 --- /dev/null +++ b/ReferenceCode/Haswell/SampleCode/Library/BootGuardTpmEventLogLib/BootGuardTpmEventLogLib.sdl @@ -0,0 +1,29 @@ +TOKEN + Name = BootGuardTpmEventLogLib_SUPPORT + Value = 1 + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable BootGuardTpmEventLogLib support in Project" +End + +MODULE + Help = "Includes BootGuardTpmEventLogLib.mak to Project" + File = "BootGuardTpmEventLogLib.mak" +End + +PATH + Name = "BootGuardTpmEventLogLib_DIR" +End + +ELINK + Name = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\BootGuardTpmEventLogLib.lib" + Parent = "BootGuardTpmEventLogLib_LIB" + InvokeOrder = AfterParent +End |