summaryrefslogtreecommitdiff
path: root/Core/EM/TCG2/Common/xTcgDxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/TCG2/Common/xTcgDxe.c')
-rw-r--r--Core/EM/TCG2/Common/xTcgDxe.c1835
1 files changed, 1835 insertions, 0 deletions
diff --git a/Core/EM/TCG2/Common/xTcgDxe.c b/Core/EM/TCG2/Common/xTcgDxe.c
new file mode 100644
index 0000000..4e2d21f
--- /dev/null
+++ b/Core/EM/TCG2/Common/xTcgDxe.c
@@ -0,0 +1,1835 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/xTcgDxe.c 2 6/14/14 12:28a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:28a $
+//**********************************************************************
+// Revision History
+// ----------------\
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/xTcgDxe.c $
+//
+// 2 6/14/14 12:28a Fredericko
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 2 10/31/13 11:20a Fredericko
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 2:01p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 105 12/10/12 6:24p Fredericko
+//
+// 104 12/03/12 11:01p Fredericko
+// [TAG] EIP104961
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UEFI 2.3.1 SCT test failed in Generic\EfiCompliant case.
+// The VariableAttribute of SecureBoot is not correct.
+// [RootCause] Changes to Secureboot module
+// [Solution] Remove secureboot variable check in Tcg
+// [Files] AmiTcgPlatformDxe.c
+// xTcgdxe.c
+//
+// 103 10/30/12 11:31a Fredericko
+//
+// 102 9/13/12 5:09p Fredericko
+// [TAG] EIP96217
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AMIUEFI: Only one EV_EFI_VARIABLE_AUTHORITY event instead
+// of two when an EFI application or driver is not executed because of a
+// Secure Boot violation and then booted into Windows ( Winqual Bug ID :
+// 958465 )
+// [RootCause] Not measuring Subsequent Certificate Authority that can
+// be loaded after boot before ExitBootServices is called
+// [Solution] Measuring all Subsequent Certificate Authority that can be
+// loaded after boot before ExitBootServices is called
+// Also EIP [96218]: Measure Zero Events for when SecureBootSupport is
+// enabled but Keys are not installed
+// [Files] xTcgDxe.c
+// AmiTcgPlatformDxe.c
+//
+// 101 5/09/12 3:52p Fredericko
+// Changes for the measurement for Certificate Authority for secureboot.
+//
+// 100 4/28/12 3:28p Fredericko
+// Changed When gpt is measured as well as put Perf macro for DP
+// information.
+//
+// 99 4/19/12 5:57p Fredericko
+// EIP: 85771. Fixes for measurement of gpt partitions on EFI platform.
+// First boot scenario after flashing was failing sometimes.
+//
+// 97 3/19/12 6:32p Fredericko
+// [TAG] EIP82769
+// [Category] Improvement
+// [Description] Firmware updates disable the TPM when Firmware update
+// is done
+// [Files] xTcgPei.c, xTcgDxe.c, TcgDxe.c
+//
+// 96 12/15/11 3:25p Fredericko
+//
+// 95 12/12/11 3:37p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+// AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+// AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+// 94 11/17/11 2:31p Fredericko
+// Changes for AmiTcgSetup for cases when TPM is plug into board after
+// first boot.
+//
+// 93 10/26/11 3:15p Fredericko
+// Changes for First boot scenerio and when Tcg Support is enabled and
+// Disabled
+//
+// 92 10/10/11 12:06a Fredericko
+// [TAG] EIP70220
+// [Category] Improvement
+// [Description] Remove dependency on CSM
+// [Files] TcgLegacy.sdl
+// AmiTcgPlatformDxe.c
+// AmiTcgPlatformDxe.h
+// xTcgDxe.c
+//
+// 91 9/27/11 10:26p Fredericko
+// [TAG] EIP67286
+// [Category] Improvement
+// [Description] changes for Tcg Setup policy
+// [Files] Tcg.sdl
+// TcgPei.cif
+// TcgPei.mak
+// xtcgPei.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+// TcgDxe.cif
+// TcgDxe.mak
+// xTcgDxe.c
+// AmiTcgPlatformPeilib.c
+// AmiTcgPlatformDxelib.c
+//
+// 90 9/03/11 8:05p Fredericko
+//
+// 89 8/29/11 6:50p Fredericko
+// [TAG] EIP0000
+// [Category] Improvement
+// [Description] Tcg Setup improvement. Logic for when Tcgsupport is
+// enabled.
+// [Files] xtcgdxe.c
+//
+// 88 4/18/11 5:00p Fredericko
+//
+// 87 3/29/11 9:17p Fredericko
+// Don't install platform protocol if there is a TPM device error from
+// startup command or selftest
+//
+// 86 3/29/11 1:13p Fredericko
+//
+// 85 3/28/11 2:20p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 82 10/07/10 10:37a Fredericko
+// [TAG] EIP45667
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Fail to get AMITSEVar
+// [RootCause] Uninitialized variable
+// [Solution] Initialize Size variable in prompt_operation function
+// [Files] xtcgdxe.c
+//
+// 81 9/23/10 6:12p Fredericko
+// [TAG] EIP42580
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] TPM prompt message override on LOGO mode
+// [RootCause] Proper SDL token comparism
+// [Solution] Use proper SDL token comparism
+// [Files] xtcgdxe.c
+//
+// 80 8/31/10 2:18p Fredericko
+// Workaround TSE problem with using AMIpost Manager for string display.
+//
+// 79 8/19/10 5:28p Fredericko
+// Edit display string positions on screen.
+//
+// 78 8/13/10 11:06a Fredericko
+// [TAG] N\A
+// [Category] IMPROVEMENT
+// [Description] Support for core 4.6.4.x and UEFI 2.1 Specifications
+// [FILES] xTcgDxe.c, TPMPwd.c
+//
+// 77 8/10/10 6:11p Fredericko
+// String display operations changes.
+//
+// 76 8/09/10 3:49p Fredericko
+// UEFI 2.1 changes
+//
+// 75 8/09/10 2:23p Fredericko
+// UEFI 2.1 changes
+//
+// 74 8/04/10 5:18p Fredericko
+// Reset system after executing owner commands. Special case.
+//
+// 73 7/13/10 5:37p Fredericko
+//
+// 72 7/09/10 3:39p Fredericko
+// modified platform protocol
+//
+// 71 6/02/10 5:06p Fredericko
+// Do nothing on some TPM error scenerios. We were shutting down the
+// system before.
+//
+// 70 5/21/10 4:03p Fredericko
+// Hii String package changes
+//
+// 68 5/21/10 11:37a Rizwank
+// Changes to include proper strings token header when AMI_TCG_MESSAGE is
+// enabled
+// Use correct imagehandle name
+//
+// 67 5/20/10 5:37p Fredericko
+//
+//
+// 65 5/20/10 9:02a Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 64 4/30/10 5:01p Fredericko
+// EIP 36943: Was not writing TPM results and clearing TPM request on a
+// special case.
+//
+// 63 4/21/10 11:50a Fredericko
+// Removal of functions that are no needed anymore for multi language
+// support.
+//
+// 62 3/23/10 8:42p Fredericko
+// TcgLegacy event moved to subcomponent
+//
+// 61 3/19/10 4:20p Fredericko
+// modified for legacy IO interface support
+//
+// 60 1/14/10 11:57a Fredericko
+// Physical presence lifetime lock support added.
+//
+// 59 12/31/09 2:52p Fredericko
+// modified to allow the setting of lifetime lock on physical presence
+//
+// 58 11/17/09 5:53p Fredericko
+// Check-in changes for PPI request that was lost in label 32...
+//
+// 57 10/10/09 5:11p Fredericko
+//
+// 56 9/15/09 6:22p Fredericko
+// Changed to not use CMOS for the case when a deactivated for Enable,
+// Activate and allow owner command.
+//
+// 55 8/19/09 1:58p Fredericko
+//
+// 54 8/19/09 10:54a Fredericko
+// Support to measure CPU microcode in Nested firmware volume.
+//
+// 53 8/14/09 4:22p Fredericko
+// Changed flow with Authentication and Setup Confirmation to rid of extra
+// reset in the flow.
+//
+// 52 7/29/09 11:17a Fredericko
+// 1. Create ACPI table for all ACPI NVS. including ACPI3.0
+// 2. If Setup request fails full reset the platform and re-execute the
+// command on next boot.
+// 3. Minor Compiler problem with error checking fixed.
+//
+// 1 6/10/09 4:56p Fasihm
+// Added fix for TCG support. Remove after TCG label is updated with
+// changes generically incorporated.
+//
+// 51 6/02/09 4:49p Fredericko
+//
+// 50 6/02/09 1:12p Fredericko
+//
+// 49 6/01/09 4:18p Fredericko
+// Changes added for TCM_SUPPORT
+//
+// 48 4/30/09 6:18p Fredericko
+// Updated Header Date
+//
+// 47 4/30/09 5:36p Fredericko
+// AMI company Header Address changes, Fixes when AMI_TCG_MESSAGE is
+// enabled. Build and display Fixes.
+//
+// 46 4/13/09 4:39p Fredericko
+//
+// 45 4/03/09 6:14p Fredericko
+// #define changes and coding standard changes
+//
+// 43 3/05/09 3:15p Fredericko
+// Changes for CoreSources dependency
+//
+// 42 2/05/09 5:37p Fredericko
+// Lots of changes done in relation to removing dependencies on EDK
+//
+// 41 1/02/09 5:36p Fredericko
+// Moving Measurement of event Separators to EFI phase from legacy phase.
+//
+// 39 6/02/08 8:34p Fredericko
+// update Setup with no hardware if TPM does not respond properly to
+// commands.
+//
+// 38 4/10/08 6:02p Fredericko
+// Mor implemenation changes. Currently supports upto 4GB.
+//
+// 37 4/10/08 5:31p Fredericko
+// Generic Measurement changes and bug fixes
+//
+// 36 2/27/08 8:50p Fredericko
+//
+// 35 2/27/08 5:57p Fredericko
+// TCG specification changes and code clean up
+//
+// 34 2/06/08 9:01p Fredericko
+// Changes for DTM WLK 1.1 and Physical Presence Lock before booting.
+//
+// 33 1/18/08 8:23p Fredericko
+// Generic changes for Tcg EFI measurements specification requirements
+//
+// 32 11/09/07 6:44p Fasihm
+// Removed CONFIRM_SETUP_CHANGE around update_cmos() as it is not needed
+// now.
+//
+// 31 10/23/07 12:36p Fredericko
+// Setup PPI bug fixes
+//
+// 30 10/08/07 9:16a Fredericko
+//
+// 29 9/26/07 2:46p Fredericko
+// Build in TRACE "TRACE" bugs
+//
+// 28 9/04/07 6:09p Fredericko
+// Changes made for new compiler swtich "\W4" to work
+//
+// 27 9/04/07 10:22a Fredericko
+// Measuring Embedded PciROM fix
+//
+// 26 8/09/07 2:20p Pats
+// Removed unnecessary extern reference.
+//
+// 25 8/09/07 11:34a Pats
+// Modified to support password authentication and state change
+// confirmation.
+//
+// 24 7/13/07 2:54p Rameshraju
+// Added the TPM post message and SDL tokens for the TPM key's
+//
+// 23 6/13/07 5:26p Fredericko
+// Measuring PCI option ROM fixes
+//
+// 22 6/08/07 6:36p Fredericko
+// New TPM feature to allow disabling and enabling TPM support.
+//
+// 21 5/22/07 7:24p Fredericko
+//
+// 20 5/22/07 3:51p Fredericko
+// Added TPM feature to report TPM status and ownership in setup
+//
+// 19 3/23/07 3:34p Fredericko
+// Display Correction for PPI request
+//
+// 18 3/19/07 9:07a Fredericko
+// Build issue fix
+//
+// 17 3/14/07 5:14p Fredericko
+// PPI print change and PPI bug fixes
+//
+// 16 3/12/07 11:45a Fredericko
+// Allow execution of TCG command if Tcg_Setup_enable and
+// TCG_setup_operation is requested
+//
+// 15 3/07/07 3:10p Fredericko
+// TCG_PPI bug fixes
+//
+// 14 3/06/07 1:02p Fasihm
+// Added the support for the TCG PPI support to the TCG module.
+//
+// 13 3/01/07 8:00p Fasihm
+// Changes made for the new Edk in both structures and APIs.
+//
+// 12 12/11/06 1:56p Fasihm
+// Added code for controlling with the Setup question TCG_SETUP.
+//
+// 11 11/15/06 11:16a Radhikav
+//
+// 10 11/13/06 3:47p Radhikav
+//
+// 9 11/03/06 6:34p Andriyn
+//
+// 8 11/02/06 9:59a Andriyn
+// Change: new features (PPI and Setup questions) are conditional under
+// SDL flag
+//
+// 7 10/06/06 5:16p Andriyn
+//
+// 6 8/22/06 1:30p Andriyn
+// MOR related changes
+//
+// 5 8/18/06 9:02a Andriyn
+// Refactor code
+//
+// 4 8/15/06 9:28a Andriyn
+//
+// 3 6/22/06 3:03p Andriyn
+//
+// 2 6/20/06 7:13p Andriyn
+// Changes due to protocols moved to MiscFramework
+//--------------------------------------------------------------------------
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: xTcgDxe.c
+//
+// Description:
+// Most Tcg DXE initialization and measurements are done here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <EFI.h>
+#include <TcgCommon.h>
+#include <AmiLib.h>
+#include <token.h>
+
+#if SMBIOS_SUPPORT == 1
+ #include <SmBios.h>
+#endif
+
+#include <TcgMisc.h>
+#include "TcgPrivate.h"
+#include <AmiDxeLib.h>
+#include <TcgPrivate.h>
+#include <DiskIo.h>
+#include <BlockIo.h>
+#include "protocol\TcgService\TcgService.h"
+#include "protocol\TpmDevice\TpmDevice.h"
+#include "Protocol/CpuIo.h"
+#include "Protocol/FirmwareVolume.h"
+#include "Protocol/DevicePath.h"
+#include "Protocol/PciIo.h"
+#include "TcgPlatformSetupPolicy.h"
+#include <AmiTcgPlatformProtocol.h>
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+#include <ImageAuthentication.h>
+#endif
+
+
+//------------------------------------------------------------------------
+//Internal Structures
+//------------------------------------------------------------------------
+typedef struct _TCG_DXE_PRIVATE_DATA
+{
+ EFI_TCG_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCG_DXE_PRIVATE_DATA;
+
+EFI_STATUS
+__stdcall TcgDxeCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue );
+
+
+#define TCG_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCG_DXE_PRIVATE_DATA, TcgServiceProtocol )
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+#define GUID_VARIABLE_DECLARATION( Variable, Guid ) extern EFI_GUID Variable
+
+EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+EFI_GUID gDsdtGuidDxe = DSDT_GUID;
+EFI_GUID TcgEfiGlobalVariableGuid = TCG_EFI_GLOBAL_VARIABLE_GUID;
+EFI_GUID AmiTcgPlatformProtocolGuid = AMI_TCG_PLATFORM_PROTOCOL_GUID;
+EFI_GUID gEfiTcgPrivateInterfaceGuid = EFI_TCG_PRIVATE_INTERFACE_GUID;
+static BOOLEAN BootLaunchDone = FALSE;
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+
+#include <AcpiSupport.h>
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+EFI_STATUS EFIAPI TcgDxeHashLogExtendEvent (
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *evNum );
+
+EFI_STATUS
+EFIAPI
+TcgMeasureGptTable (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/////////////////////////////////////////////////
+#define AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID \
+ { 0x6683D10C, 0xCF6E, 0x4914, 0xB5, 0xB4, 0xAB, 0x8E, 0xD7, 0x37, 0x0E, 0xD7 }
+//
+//
+// Data Table definition
+//
+typedef struct _AMI_VALID_CERT_IN_SIG_DB {
+ UINT32 SigOffset;
+ UINT32 SigLength;
+} AMI_VALID_CERT_IN_SIG_DB;
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AppendDevicePath
+//
+// Description: Appends Two given Device Path
+//
+// Input: IN EFI_DEVICE_PATH_PROTOCOL *Path1
+// IN EFI_DEVICE_PATH_PROTOCOL *Path2
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+static
+EFI_DEVICE_PATH_PROTOCOL* TcgAppendDevicePath(
+ IN EFI_DEVICE_PATH_PROTOCOL *Path1,
+ IN EFI_DEVICE_PATH_PROTOCOL *Path2 )
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINTN PathSize1, PathSize2;
+
+ if ( !Path1 && !Path2 )
+ {
+ return NULL;
+ }
+
+ PathSize1 = DPLength( Path1 );
+ PathSize2 = DPLength( Path2 );
+
+ if ( PathSize1 && PathSize2 )
+ {
+ PathSize1 -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ }
+
+ pBS->AllocatePool( EfiBootServicesData,
+ PathSize1 + PathSize2,
+ (void**)&NewPath );
+
+ pBS->CopyMem( NewPath, Path1, PathSize1 );
+ pBS->CopyMem( (UINT8*)NewPath + PathSize1, Path2, PathSize2 );
+
+ return NewPath;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiLibAllocatePool
+//
+// Description: Allocate BootServicesData pool.
+//
+// Input: AllocationSize - The size to allocate
+//
+// Output: Pointer of the buffer allocated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *
+EfiLibAllocatePool (
+ IN UINTN AllocationSize
+)
+{
+ VOID *Memory;
+
+ Memory = NULL;
+ pBS->AllocatePool (EfiBootServicesData, AllocationSize, &Memory);
+ return Memory;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: TcgEfiLibAllocateZeroPool
+//
+// Description: Allocate BootServicesData pool and zero the pool.
+//
+// Input: AllocationSize - The size to allocate
+//
+// Output: Pointer of the buffer allocated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *
+TcgEfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ VOID *Memory;
+
+ Memory = EfiLibAllocatePool (AllocationSize);
+ if (Memory != NULL) {
+ pBS->SetMem (Memory, AllocationSize, 0);
+ }
+
+ return Memory;
+}
+
+
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+EFI_STATUS
+MeasureCertificate(UINTN sizeOfCertificate,
+ UINT8 *pterCertificate)
+{
+ EFI_STATUS Status;
+ TCG_PCR_EVENT *TcgEvent = NULL;
+ EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ TCG_EFI_VARIABLE_DATA *VarLog;
+ EFI_PHYSICAL_ADDRESS Last;
+ UINT32 evNum;
+ BOOLEAN AlreadyMeasuredCert = FALSE;
+ UINTN i=0;
+ UINTN VarNameLength;
+ static BOOLEAN initialized = 0;
+ static TPM_DIGEST digestTrackingArray[10];
+ static TPM_DIGEST zeroDigest;
+ UINT8 *tempDigest = NULL;
+ UINT64 HashedDataLen = 20;
+
+ if(!initialized)
+ {
+ for(i=0;i<5; i++)
+ {
+ MemSet(digestTrackingArray[i].digest,20,0);
+ }
+ MemSet(zeroDigest.digest,20,0);
+ initialized = TRUE;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiTcgProtocolGuid,
+ NULL, &tcgSvc );
+
+ if(EFI_ERROR(Status))return Status;
+
+ VarNameLength = Wcslen(L"db");
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE( TCG_PCR_EVENT,Event )
+ + (UINT32)(sizeof(TCG_EFI_VARIABLE_DATA) + (VarNameLength
+ * sizeof(CHAR16)) + sizeOfCertificate - 3),
+ &TcgEvent);
+
+ if(EFI_ERROR(Status))return Status;
+
+ TcgEvent->PCRIndex = 7;
+ TcgEvent->EventType = 0x800000E0;
+
+ TcgEvent->EventSize = (UINT32)( sizeof (*VarLog) + VarNameLength
+ * sizeof (CHAR16) + sizeOfCertificate) - 3;
+
+ pBS->AllocatePool( EfiBootServicesData, TcgEvent->EventSize, &VarLog );
+
+ if ( VarLog == NULL ){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ VarLog->VariableName = gEfiImageSecurityDatabaseGuid;
+ VarLog->UnicodeNameLength = VarNameLength;
+ VarLog->VariableDataLength = sizeOfCertificate;
+
+ pBS->CopyMem((CHAR16*)(VarLog->UnicodeName),
+ L"db",
+ VarNameLength * sizeof (CHAR16));
+
+ pBS->CopyMem((CHAR16*)(VarLog->UnicodeName) + VarNameLength,
+ pterCertificate,
+ sizeOfCertificate);
+
+ pBS->CopyMem( TcgEvent->Event,
+ VarLog,
+ TcgEvent->EventSize );
+
+ //before extending verify if we have already measured it.
+ tcgSvc->HashAll(tcgSvc,
+ (UINT8 *)VarLog,
+ TcgEvent->EventSize,
+ 4,
+ &HashedDataLen,
+ &tempDigest);
+
+ for(i=0; i<10; i++)
+ {
+ //tempDigest
+ if(!MemCmp(digestTrackingArray[i].digest, tempDigest, 20))
+ return EFI_SUCCESS; //already measured
+
+ if(!MemCmp(digestTrackingArray[i].digest, zeroDigest.digest, 20))
+ break; //we need to measure
+ }
+
+ pBS->CopyMem(digestTrackingArray[i].digest, tempDigest, 20);
+
+ Status = tcgSvc->HashLogExtendEvent(tcgSvc,
+ (EFI_PHYSICAL_ADDRESS)VarLog,
+ TcgEvent->EventSize,
+ 4,
+ TcgEvent,
+ &evNum,
+ &Last );
+
+ pBS->FreePool(TcgEvent);
+
+ return Status;
+}
+
+
+EFI_STATUS FindandMeasureSecureBootCertificate(BOOLEAN BootPolicy)
+{
+ EFI_STATUS Status;
+ UINTN VarSize = 0;
+ UINTN i=0;
+ UINT8 *SecureDBBuffer = NULL;
+ UINT8 *CertificateBuffer = NULL;
+ UINTN SizeofCertificate = 0;
+ EFI_GUID Certificateguid = AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID;
+ AMI_VALID_CERT_IN_SIG_DB *CertInfo;
+ UINT8 *CertOffsetPtr = NULL;
+ static BOOLEAN NullKeysMeasured = FALSE;
+
+
+ if(BootPolicy == FALSE && BootLaunchDone == FALSE) return EFI_SUCCESS;
+ if(NullKeysMeasured == TRUE)return EFI_SUCCESS;
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE)
+ {
+ Status = pRS->GetVariable(L"db",
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &VarSize,
+ NULL);
+
+ if ( Status == EFI_BUFFER_TOO_SMALL )
+ {
+ pBS->AllocatePool( EfiBootServicesData, VarSize, &SecureDBBuffer );
+
+ if ( SecureDBBuffer != NULL )
+ {
+ Status = pRS->GetVariable(L"db",
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &VarSize,
+ SecureDBBuffer);
+
+ if ( EFI_ERROR( Status ))
+ {
+ pBS->FreePool( SecureDBBuffer );
+ SecureDBBuffer = NULL;
+#if (defined(UnconfiguredSecureBootVariables) && (UnconfiguredSecureBootVariables == 0))
+ return EFI_NOT_FOUND;
+#endif
+ }
+ }
+
+ }else{
+#if (defined(UnconfiguredSecureBootVariables) && (UnconfiguredSecureBootVariables == 0))
+ return EFI_NOT_FOUND;
+#else
+ SecureDBBuffer = NULL;
+#endif
+ }
+ }
+
+ //we need to find the pointer in the EFI system table and work from
+ //there
+ CertInfo = NULL;
+ CertInfo = GetEfiConfigurationTable(pST, &Certificateguid);
+ if(CertInfo == NULL){
+ TRACE(( TRACE_ALWAYS,"db variable found SecCertificate Information not found in EFI System Table \n"));
+ }
+ if(CertInfo->SigLength == 0){
+ TRACE(( TRACE_ALWAYS,"SecCertificate Information found in EST but Information might be invalid \n"));
+ }
+
+ CertOffsetPtr = NULL;
+
+ if(CertInfo!=0)
+ {
+ CertOffsetPtr = (SecureDBBuffer + CertInfo->SigOffset);
+ SizeofCertificate = (UINTN)CertInfo->SigLength;
+ }else{
+ SizeofCertificate = 0;
+ }
+
+ if(SizeofCertificate == 0){
+ NullKeysMeasured = TRUE;
+ }
+
+ MeasureCertificate(SizeofCertificate,CertOffsetPtr);
+
+ if(SecureDBBuffer!=NULL){
+ pBS->FreePool( SecureDBBuffer );
+ }
+
+ return Status;
+}
+#endif
+
+
+
+
+//--------------------------------------------------------------------------------------------
+//Description: Measure a PE/COFF image into PCR 2 or 4 depending on Boot policy of 0 or 1
+//Arguments:
+// BootPolicy - Boolean value of 0 or 1 for PCR index 2 or 4.
+// ImageContext - Contains details about the image.
+// LinkTimeBase - Linking time Image Address
+// ImageType - EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, BOOT_SERVICE_DRIVER, EFI_RUNTIME_DRIVER
+// DeviceHandle - Device identification handle
+// FilePath - Device File path
+//Output: EFI_SUCCESS - Image Measured successfully.
+//---------------------------------------------------------------------------------------------
+
+EFI_STATUS
+EFIAPI
+TcgMeasurePeImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_PHYSICAL_ADDRESS ImageAddress,
+ IN UINTN ImageSize,
+ IN UINTN LinkTimeBase,
+ IN UINT16 ImageType,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+
+ EFI_STATUS Status;
+ TCG_PCR_EVENT_HDR TcgEvent;
+ TCG_PCR_EVENT *TcgEventlog = NULL;
+ EFI_IMAGE_LOAD_EVENT *ImageLoad;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FullPath;
+ UINT32 FullPathSize;
+ SHA1_CTX Sha1Ctx;
+ TCG_EFI_IMAGE_DOS_HEADER *DosHdr;
+ UINT32 PeCoffHeaderOffset;
+ TCG_EFI_IMAGE_NT_HEADERS *Hdr;
+ TCG_EFI_IMAGE_SECTION_HEADER *Section;
+ UINT8 *HashBase;
+ UINTN HashSize;
+ UINTN SumOfBytesHashed;
+ TCG_EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINTN Index, iPos;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmProtocol;
+ UINT32 EventNumber;
+ TCG_DIGEST *Sha1Digest = NULL;
+
+ ImageLoad = NULL;
+ FullPath = NULL;
+ SectionHeader = NULL;
+ FullPathSize = 0;
+
+ if(AutoSupportType()){
+ return EFI_SUCCESS;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTpmDeviceProtocolGuid, NULL, &TpmProtocol );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+
+ if (DeviceHandle != NULL) {
+ //
+ // Skip images loaded from FVs
+ //
+ Status = pBS->OpenProtocol (
+ DeviceHandle,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (Status == EFI_UNSUPPORTED);
+
+ //
+ // Get device path for the device handle
+ //
+ Status = pBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ FullPath = TcgAppendDevicePath (DevicePath, FilePath);
+ FullPathSize = (UINT32)DPLength (FullPath);
+ }
+
+ //Allocate Event log memory
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE( TCG_PCR_EVENT, Event )
+ + ((sizeof (*ImageLoad)
+ - sizeof (ImageLoad->DevicePath)) + FullPathSize),
+ &TcgEventlog );
+ //
+ // Determine destination PCR by BootPolicy
+ //
+ TcgEvent.PCRIndex = BootPolicy ? 4 : 2;
+ TcgEvent.EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath);
+ TcgEvent.EventSize += FullPathSize;
+
+ switch (ImageType) {
+ case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ TcgEvent.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ TcgEvent.EventType = EV_EFI_BOOT_SERVICES_DRIVER;
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ TcgEvent.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
+ break;
+ default:
+ TRACE(( TRACE_ALWAYS,
+ __FUNCTION__ ": Unknown subsystem type %d",
+ ImageType));
+
+ ASSERT (FALSE);
+ TcgEvent.EventType = ImageType;
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ //do measure images from ROM that call LoadImage themselves
+ // without the correct Devicepath
+ if(ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
+ && BootLaunchDone == FALSE){
+ return EFI_SUCCESS;
+ }
+
+
+ PERF_START(0,L"MeasurePeImg",NULL,0);
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ TcgEvent.EventSize,
+ &ImageLoad );
+
+ if (ImageLoad == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ ImageLoad->ImageLocationInMemory = ImageAddress;
+ ImageLoad->ImageLengthInMemory = ImageSize;
+ ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
+ ImageLoad->LengthOfDevicePath = FullPathSize;
+ pBS->CopyMem( ImageLoad->DevicePath, FullPath, FullPathSize );
+
+ //
+ // Check PE/COFF image
+ //
+ DosHdr = (TCG_EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
+ PeCoffHeaderOffset = 0;
+ if (DosHdr->e_magic == TCG_EFI_IMAGE_DOS_SIGNATURE) {
+ PeCoffHeaderOffset = DosHdr->e_lfanew;
+ }
+ if (((TCG_EFI_TE_IMAGE_HEADER *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset))->Signature
+ == TCG_EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ goto Done;
+ }
+
+ //
+ // PE/COFF Image Measurement
+ //
+ // NOTE: The following codes/steps are based upon the authenticode image hashing in
+ // PE/COFF Specification 8.0 Appendix A.
+ //
+ //
+
+ // 1. Load the image header into memory.
+
+ // 2. Initialize a SHA hash context.
+// Status = SHA1_init(TcgProtocol, &Sha1Ctx);
+ SHA1Init(&Sha1Ctx );
+
+ //
+ // Measuring PE/COFF Image Header;
+ // But CheckSum field and SECURITY data directory (certificate) are excluded
+ //
+ Hdr = (TCG_EFI_IMAGE_NT_HEADERS *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
+
+ //
+ // 3. Calculate the distance from the base of the image header to the image checksum address.
+ // 4. Hash the image header from its base to beginning of the image checksum.
+ //
+ HashBase = (UINT8 *)(UINTN)ImageAddress;
+ HashSize = (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.CheckSum) - HashBase);
+
+/*Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 5. Skip over the image checksum (it occupies a single ULONG).
+ // 6. Get the address of the beginning of the Cert Directory.
+ // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
+ //
+ HashBase = (UINT8 *) &Hdr->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
+
+/* Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
+ // 9. Hash everything from the end of the Cert Directory to the end of image header.
+ //
+ HashBase = (UINT8 *) &Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
+ HashSize = Hdr->OptionalHeader.SizeOfHeaders -
+ (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *)(UINTN)ImageAddress);
+
+/* Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 10. Set the SUM_OF_BYTES_HASHED to the size of the header
+ //
+ SumOfBytesHashed = Hdr->OptionalHeader.SizeOfHeaders;
+
+ //
+ // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
+ // structures in the image. The 'NumberOfSections' field of the image
+ // header indicates how big the table should be. Do not include any
+ // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
+ //
+
+ Status = pBS->AllocatePool (EfiBootServicesData, sizeof (TCG_EFI_IMAGE_SECTION_HEADER) * Hdr->FileHeader.NumberOfSections, &SectionHeader);
+ if(SectionHeader==NULL)return EFI_OUT_OF_RESOURCES;
+ pBS->SetMem (SectionHeader, sizeof (TCG_EFI_IMAGE_SECTION_HEADER) * Hdr->FileHeader.NumberOfSections , 0);
+
+ //
+ // 12. Using the 'PointerToRawData' in the referenced section headers as
+ // a key, arrange the elements in the table in ascending order. In other
+ // words, sort the section headers according to the disk-file offset of
+ // the section.
+ //
+ Section = (TCG_EFI_IMAGE_SECTION_HEADER *) (
+ (UINT8 *)(UINTN)ImageAddress +
+ PeCoffHeaderOffset +
+ sizeof(UINT32) +
+ sizeof(TCG_EFI_IMAGE_FILE_HEADER) +
+ Hdr->FileHeader.SizeOfOptionalHeader
+ );
+ for (Index = 0; Index < Hdr->FileHeader.NumberOfSections; Index++) {
+ iPos = Index;
+ while ((iPos > 0) && (Section->PointerToRawData < SectionHeader[iPos - 1].PointerToRawData)) {
+ MemCpy (&SectionHeader[iPos], &SectionHeader[iPos - 1], sizeof(TCG_EFI_IMAGE_SECTION_HEADER));
+ iPos--;
+ }
+ MemCpy( &SectionHeader[iPos], Section,
+ sizeof(TCG_EFI_IMAGE_SECTION_HEADER));
+ Section += 1;
+ }
+
+ //
+ // 13. Walk through the sorted table, bring the corresponding section
+ // into memory, and hash the entire section (using the 'SizeOfRawData'
+ // field in the section header to determine the amount of data to hash).
+ // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
+ // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
+ //
+ for (Index = 0; Index < Hdr->FileHeader.NumberOfSections; Index++) {
+ Section = (TCG_EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];
+ if (Section->SizeOfRawData == 0) {
+ continue;
+ }
+ HashBase = (UINT8 *)(UINTN)ImageAddress + Section->PointerToRawData;
+ HashSize = (UINTN) Section->SizeOfRawData;
+/*
+ Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ SumOfBytesHashed += HashSize;
+ }
+
+ //
+ // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
+ // data in the file that needs to be added to the hash. This data begins
+ // at file offset SUM_OF_BYTES_HASHED and its length is:
+ // FileSize - (CertDirectory->Size)
+ //
+ if (ImageSize > SumOfBytesHashed) {
+ HashBase = (UINT8 *)(UINTN)ImageAddress + SumOfBytesHashed;
+ HashSize = (UINTN)(ImageSize -
+ Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
+ SumOfBytesHashed);
+/*
+ Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+ }
+
+ //
+ // 17. Finalize the SHA hash.
+ //
+// Status = SHA1_final(TcgProtocol, &Sha1Ctx, &Sha1Digest);
+ SHA1Final((unsigned char *)&Sha1Digest->digest, &Sha1Ctx);
+
+ pBS->CopyMem (&TcgEvent.Digest.digest,Sha1Digest->digest, sizeof (TcgEvent.Digest.digest));
+
+ //
+ // HashLogExtendEvent
+ //
+
+ //hash has been generated so extend it
+ TpmProtocol->Init(TpmProtocol);
+
+ Status = TcgDxeCommonExtend (
+ (void *)TcgProtocol,
+ TcgEvent.PCRIndex,
+ &TcgEvent.Digest,
+ Sha1Digest
+ );
+
+ TpmProtocol->Close(TpmProtocol);
+
+ if (!EFI_ERROR (Status)) {
+
+ //Now log the event
+ TcgEventlog->PCRIndex = TcgEvent.PCRIndex;
+ TcgEventlog->EventType = TcgEvent.EventType;
+ TcgEventlog->EventSize = TcgEvent.EventSize;
+ MemCpy(&TcgEventlog->Digest, &TcgEvent.Digest, sizeof(TCG_DIGEST));
+ MemCpy(&TcgEventlog->Event, ImageLoad, TcgEvent.EventSize);
+ Status = TcgProtocol->LogEvent(TcgProtocol, TcgEventlog, &EventNumber,0x01);
+ }
+
+ PERF_END(0,L"MeasurePeImg",NULL,0);
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE){
+ PERF_START(0,L"MeasureGpt",NULL,0);
+ TcgMeasureGptTable(FullPath);
+ PERF_END(0,L"MeasureGpt",NULL,0);
+ }
+
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+ FindandMeasureSecureBootCertificate(BootPolicy);
+#endif
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE){
+ BootLaunchDone = TRUE;
+ }
+
+ TpmProtocol->Close(TpmProtocol);
+
+Done:
+ if (ImageLoad != NULL) {
+ pBS->FreePool (ImageLoad);
+ }
+
+ if (TcgEventlog != NULL )
+ {
+ pBS->FreePool( TcgEventlog );
+ }
+ if (FullPathSize > 0) {
+ pBS->FreePool (FullPath);
+ }
+ if (SectionHeader != NULL) {
+ pBS->FreePool (SectionHeader);
+ }
+ return Status;
+}
+
+
+
+
+
+
+EFI_STATUS
+EFIAPI
+GptDevicePathToHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT EFI_HANDLE *GptHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *PreDevicePathNode;
+ HARDDRIVE_DEVICE_PATH *HdDevicePath;
+ EFI_HANDLE Handle;
+ BOOLEAN GptDiskFound;
+
+ NewDevicePathNode = TcgEfiLibAllocateZeroPool (DPLength (DevicePath));
+ MemCpy (NewDevicePathNode, DevicePath, DPLength (DevicePath));
+ DevicePathNode = NewDevicePathNode;
+
+ //
+ // The device should support blockIO protocol. Check it.
+ //
+ Status = pBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Find the gpt partion on the given devicepath, if not, return.
+ //
+ GptDiskFound = FALSE;
+ PreDevicePathNode = NULL;
+ HdDevicePath = NULL;
+ DevicePathNode = NewDevicePathNode;
+ while (!IsDevicePathEnd (DevicePathNode)) {
+ //
+ // Find the Gpt partition
+ //
+ if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {
+ HdDevicePath = (HARDDRIVE_DEVICE_PATH *) DevicePathNode;
+ //
+ // Check whether it is a gpt partition or not
+ //
+ if (PreDevicePathNode != NULL &&
+ HdDevicePath->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER &&
+ HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
+ GptDiskFound = TRUE;
+ break;
+ }
+ }
+ PreDevicePathNode = DevicePathNode;
+ DevicePathNode = NextDevicePathNode (DevicePathNode);
+ }
+ if (!GptDiskFound) {
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Change the device path to the parent device path and get the handle.
+ //
+ DevicePathNode->Type = 0xFF;
+ DevicePathNode->SubType = 0xFF;
+ DevicePathNode = NewDevicePathNode;
+ Status = pBS->LocateDevicePath (
+ &gEfiDiskIoProtocolGuid,
+ &DevicePathNode,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (NewDevicePathNode);
+ return Status;
+ }
+ *GptHandle = Handle;
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+HandleBootDevicePath(
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Count, i;
+ EFI_DEVICE_PATH_PROTOCOL *FullDevicePath=NULL;
+ HARDDRIVE_DEVICE_PATH *BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)DevicePath;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return NULL;
+
+ for( i=0; i<Count; i++ )
+ {
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath, *TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiBlockIoProtocolGuid,&BlockIo);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition)
+ continue;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&PartitionDevicePath);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)PartitionDevicePath;
+
+ for( TmpDevicePath = PartitionDevicePath;
+ !IsDevicePathEndType(TmpDevicePath);
+ TmpDevicePath=NextDevicePathNode(TmpDevicePath) )
+ {
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ }
+
+ //Check if our partition matches Boot partition
+ if (PartitionNode->Header.Type!=MEDIA_DEVICE_PATH || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP)
+ continue;
+
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber &&
+ PartitionNode->SignatureType==BootParitionDevicePath->SignatureType &&
+ !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16) )
+ {
+ //Match found
+ FullDevicePath = TcgAppendDevicePath(PartitionDevicePath,NextDevicePathNode(DevicePath));
+ break;
+ }
+ }
+
+ pBS->FreePool(Handle);
+ return FullDevicePath;
+}
+
+
+EFI_STATUS
+EFIAPI
+TcgMeasureGptTable (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ TCG_EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
+ TCG_EFI_PARTITION_ENTRY *PartitionEntry;
+ UINT8 *EntryPtr;
+ UINTN NumberOfPartition;
+ UINT32 Index;
+ TCG_PCR_EVENT *TcgEvent;
+ TCG_EFI_GPT_DATA *GptData;
+ EFI_GUID NullGuid = EFI_NULL_GUID;
+ EFI_HANDLE Handle;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmProtocol;
+ UINT32 evNum;
+ EFI_PHYSICAL_ADDRESS Last;
+ UINTN GptIndex;
+
+ if(AutoSupportType()){
+ return EFI_SUCCESS;
+ }
+
+ Status = GptDevicePathToHandle (DevicePath, &Handle);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, &BlockIo);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->HandleProtocol (Handle, &gEfiDiskIoProtocolGuid, &DiskIo);
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTpmDeviceProtocolGuid, NULL, &TpmProtocol );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
+ // Read the EFI Partition Table Header
+ //
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize,
+ &PrimaryHeader );
+
+ if (PrimaryHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ 1 * BlockIo->Media->BlockSize,
+ BlockIo->Media->BlockSize,
+ (UINT8 *)PrimaryHeader
+ );
+
+ if (EFI_ERROR (Status)) {
+ TRACE ((TRACE_ALWAYS, "Failed to Read Partition Table Header!\n"));
+ pBS->FreePool (PrimaryHeader);
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Read the partition entry.
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
+ &EntryPtr );
+
+ if (EntryPtr == NULL) {
+ pBS->FreePool (PrimaryHeader);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ Mul64(PrimaryHeader->PartitionEntryLba, BlockIo->Media->BlockSize),
+ PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
+ EntryPtr);
+
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ return EFI_DEVICE_ERROR;
+ }
+
+
+ //
+ // Count the valid partition
+ //
+ PartitionEntry = (TCG_EFI_PARTITION_ENTRY *)EntryPtr;
+ NumberOfPartition = 0;
+ for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
+ if (MemCmp(&PartitionEntry->PartitionTypeGuid, &NullGuid, sizeof(EFI_GUID))) {
+ NumberOfPartition++;
+ }
+ PartitionEntry++;
+ }
+ //
+ // Parepare Data for Measurement
+ //
+
+ //allocate memory for TCG event
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(TCG_PCR_EVENT_HDR) + \
+ (UINT32)(sizeof (TCG_EFI_PARTITION_TABLE_HEADER) + sizeof(UINTN)\
+ + (NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry)),
+ &TcgEvent );
+
+ TcgEvent->PCRIndex = 5;
+ TcgEvent->EventType = EV_EFI_GPT_EVENT;
+ TcgEvent->EventSize = (UINT32)(sizeof (TCG_EFI_PARTITION_TABLE_HEADER) + sizeof(UINTN)\
+ + (NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry));
+
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ TcgEvent->EventSize,
+ &GptData );
+ if (GptData == NULL) {
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemSet(GptData, TcgEvent->EventSize, 0);
+ //
+ // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
+ //
+ MemCpy ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (TCG_EFI_PARTITION_TABLE_HEADER));
+ GptData->NumberOfPartitions = NumberOfPartition;
+ //
+ // Copy the valid partition entry
+ //
+
+ PartitionEntry = (TCG_EFI_PARTITION_ENTRY*)EntryPtr;
+ GptIndex = 0;
+ for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
+ if (MemCmp (&PartitionEntry->PartitionTypeGuid, &NullGuid, sizeof(EFI_GUID))) {
+ MemCpy (
+ (UINT8 *)&GptData->Partitions + (GptIndex * sizeof (TCG_EFI_PARTITION_ENTRY)),
+ (UINT8 *)PartitionEntry,
+ sizeof (TCG_EFI_PARTITION_ENTRY)
+ );
+ GptIndex+=1;
+ }
+ PartitionEntry++;
+ }
+ //
+ // Measure the GPT data
+ //
+
+ pBS->CopyMem (TcgEvent->Event,
+ GptData,
+ TcgEvent->EventSize);
+
+ TpmProtocol ->Init( TpmProtocol );
+
+ Status = TcgProtocol->HashLogExtendEvent(
+ TcgProtocol,
+ (EFI_PHYSICAL_ADDRESS)GptData,
+ TcgEvent->EventSize,
+ TCG_ALG_SHA,
+ TcgEvent,
+ &evNum,
+ &Last);
+
+
+ TpmProtocol ->Close( TpmProtocol );
+
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ pBS->FreePool (TcgEvent);
+ pBS->FreePool (GptData);
+
+ TRACE(( TRACE_ALWAYS,"GPT_EXIT"));
+ return Status;
+}
+
+
+
+EFI_STATUS
+TcgMeasureAction(
+ IN CHAR8 *String
+ )
+{
+
+ TCG_PCR_EVENT *TcgEvent = NULL;
+ EFI_PHYSICAL_ADDRESS Last;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ UINT32 evNum;
+ UINT32 Len;
+ EFI_STATUS Status;
+
+
+ Status = pBS->LocateProtocol (
+ &gEfiTcgProtocolGuid,
+ NULL,
+ &tcgSvc);
+
+ ASSERT(!EFI_ERROR(Status));
+
+ Len = (UINT32)Strlen(String);
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE (TCG_PCR_EVENT, Event) +
+ Len,
+ &TcgEvent);
+
+ ASSERT(!EFI_ERROR(Status));
+
+ TcgEvent->PCRIndex = 5;
+ TcgEvent->EventType = EV_EFI_ACTION;
+ TcgEvent->EventSize = Len;
+
+ pBS->CopyMem (TcgEvent->Event,
+ String,
+ Len);
+
+ Status = tcgSvc->HashLogExtendEvent (
+ tcgSvc,
+ (EFI_PHYSICAL_ADDRESS)String,
+ TcgEvent->EventSize,
+ TCG_ALG_SHA,
+ TcgEvent,
+ &evNum,
+ &Last);
+
+ if(TcgEvent!=NULL)
+ {
+ pBS->FreePool (TcgEvent);
+ }
+
+ return Status;
+}
+
+UINT8 GetPlatformSupportType()
+{
+ return (AutoSupportType());
+}
+
+
+static EFI_TCG_PLATFORM_PROTOCOL mTcgPlatformProtocol = {
+ TcgMeasurePeImage,
+ TcgMeasureAction,
+ TcgMeasureGptTable
+};
+
+
+static AMI_TCG_PLATFORM_PROTOCOL mAmiTcgPlatformProtocol = {
+ GetPlatformSupportType
+};
+
+
+EFI_STATUS EFIAPI TcmDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable);
+
+TpmDxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * SystemTable);
+
+
+
+EFI_STATUS
+EFIAPI TcgDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable );
+
+EFI_STATUS
+EFIAPI Tcg20DxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable );
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Procedure: CommonTcgDxEntryPoint
+//
+// Description: Common entry point for Tcgdxe
+//
+// Input: IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI CommonTcgDxEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ TCG_PLATFORM_SETUP_PROTOCOL *ProtocolInstance;
+ EFI_GUID Policyguid = TCG_PLATFORM_SETUP_POLICY_GUID;
+ BOOLEAN TpmInitError = FALSE;
+#if TCG_LEGACY == 1
+ BOOLEAN TpmLegBin = TRUE;
+#else
+ BOOLEAN TpmLegBin = FALSE;
+#endif
+ TCG_CONFIGURATION Config;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_GUID TcgFirstbootGuid = AMI_TCG_RESETVAR_HOB_GUID;
+ void ** DummyPtr;
+ BOOLEAN *ResetAllTcgVar = NULL;
+
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol (&Policyguid, NULL, &ProtocolInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MemCpy(&Config, &ProtocolInstance->ConfigFlags, sizeof(TCG_CONFIGURATION));
+
+ Config.TcgSupportEnabled = 0;
+
+ if((AutoSupportType()== TRUE) || (TpmLegBin == TRUE))
+ {
+ if( Config.TpmSupport != 0x00)
+ {
+#if TCG_LEGACY == 0
+ Config.TcmSupport = TRUE;
+ Status = TcmDxeEntry( ImageHandle, SystemTable );
+#else
+ Config.TcmSupport = FALSE;
+ Status = TpmDxeEntry( ImageHandle, SystemTable);
+#endif
+ if(Status){
+ Config.TpmHardware = TRUE;
+ TpmInitError = TRUE;
+ }
+ }
+ }else{
+ Config.TcmSupport = FALSE;
+ Status = TpmDxeEntry( ImageHandle, SystemTable );
+ if(Status){
+ Config.TpmHardware = TRUE;
+ TpmInitError = TRUE;
+ }else{
+ Config.TpmHardware = FALSE; //negative logic False means present
+ }
+ }
+
+ if(TpmInitError){
+ Config.Tpm20Device = 0;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }
+
+ Status = Tcg20DxeEntry( ImageHandle, SystemTable );
+ if(Status != EFI_UNSUPPORTED){
+ //all dependent components will depend on
+ //the TrEEProtocol installed above
+ return EFI_SUCCESS;
+ }
+
+ Status = TcgDxeEntry( ImageHandle, SystemTable );
+
+ if(EFI_ERROR(Status)){
+
+ //if Support was enabled don't change TPM state
+ if((ProtocolInstance->ConfigFlags.TcgSupportEnabled!=0 &&
+ ProtocolInstance->ConfigFlags.TpmSupport == 0) ||
+ (ProtocolInstance->ConfigFlags.TcgSupportEnabled!=0 &&
+ ProtocolInstance->ConfigFlags.TcmSupport == 0))
+ {
+ Config.TcgSupportEnabled = FALSE;
+ }
+ else{
+ Config.TpmEnable = 0;
+ Config.TpmOperation = 0;
+ Config.TpmEnaDisable = TRUE;
+ Config.TpmActDeact = TRUE;
+ Config.TpmOwnedUnowned = FALSE;
+ }
+
+ Config.PpiSetupSyncFlag = TRUE;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }else{
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ Config.TcgSupportEnabled = FALSE;
+ ResetAllTcgVar = (UINT8*)LocateATcgHob(
+ pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &TcgFirstbootGuid);
+
+ DummyPtr = &ResetAllTcgVar;
+ if ( *DummyPtr != NULL )
+ {
+ if ( *ResetAllTcgVar == TRUE )
+ {
+ Config.PpiSetupSyncFlag = TRUE;
+ }
+ }
+
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }
+
+ Config.Tpm20Device = 0;
+ Config.TcgSupportEnabled = TRUE;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ }
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &gEfiTcgPrivateInterfaceGuid,
+ EFI_NATIVE_INTERFACE,
+ &mTcgPlatformProtocol);
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &AmiTcgPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mAmiTcgPlatformProtocol);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************