/** This service abstracts the capability to do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and add an entry to the Event Log @param[in] This Indicates the calling context @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation @param[in, out] TCGLogData The physical address of the start of the data buffer containing the TCG_PCR_EVENT data structure. @param[in, out] EventNumber The event number of the event just logged. @param[out] EventLogLastEntry Physical address of the first byte of the entry just placed in the Event Log. If the Event Log was empty when this function was called then this physical address will be the same as the physical address of the start of the Event Log. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA. @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI TcgDxeHashLogExtendEvent ( IN EFI_TCG_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS HashData, IN UINT64 HashDataLen, IN TPM_ALGORITHM_ID AlgorithmId, IN OUT TCG_PCR_EVENT *TCGLogData, IN OUT UINT32 *EventNumber, OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry ) { TCG_DXE_DATA *TcgData; TcgData = TCG_DXE_DATA_FROM_THIS (This); if (TcgData->BsCap.TPMDeactivatedFlag) { return EFI_DEVICE_ERROR; } if (AlgorithmId != TPM_ALG_SHA) { return EFI_UNSUPPORTED; } return TcgDxeHashLogExtendEventI ( TcgData, (UINT8 *) (UINTN) HashData, HashDataLen, (TCG_PCR_EVENT_HDR*)TCGLogData, TCGLogData->Event ); }
/** Measure and log an EFI variable, and extend the measurement result into a specific PCR. @param[in] PCRIndex PCR Index. @param[in] EventType Event type. @param[in] VarName A Null-terminated string that is the name of the vendor's variable. @param[in] VendorGuid A unique identifier for the vendor. @param[in] VarData The content of the variable data. @param[in] VarSize The size of the variable data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureVariable ( IN TPM_PCRINDEX PCRIndex, IN TCG_EVENTTYPE EventType, IN CHAR16 *VarName, IN EFI_GUID *VendorGuid, IN VOID *VarData, IN UINTN VarSize ) { EFI_STATUS Status; TCG_PCR_EVENT_HDR TcgEvent; UINTN VarNameLength; EFI_VARIABLE_DATA *VarLog; VarNameLength = StrLen (VarName); TcgEvent.PCRIndex = PCRIndex; TcgEvent.EventType = EventType; TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData)); VarLog = (EFI_VARIABLE_DATA*)AllocatePool (TcgEvent.EventSize); if (VarLog == NULL) { return EFI_OUT_OF_RESOURCES; } VarLog->VariableName = *VendorGuid; VarLog->UnicodeNameLength = VarNameLength; VarLog->VariableDataLength = VarSize; CopyMem ( VarLog->UnicodeName, VarName, VarNameLength * sizeof (*VarName) ); CopyMem ( (CHAR16 *)VarLog->UnicodeName + VarNameLength, VarData, VarSize ); Status = TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)VarLog, TcgEvent.EventSize, &TcgEvent, (UINT8*)VarLog ); FreePool (VarLog); return Status; }
/** This service abstracts the capability to do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and add an entry to the Event Log @param[in] This Indicates the calling context @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation @param[in, out] TCGLogData The physical address of the start of the data buffer containing the TCG_PCR_EVENT data structure. @param[in, out] EventNumber The event number of the event just logged. @param[out] EventLogLastEntry Physical address of the first byte of the entry just placed in the Event Log. If the Event Log was empty when this function was called then this physical address will be the same as the physical address of the start of the Event Log. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA. @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI TcgDxeHashLogExtendEvent ( IN EFI_TCG_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS HashData, IN UINT64 HashDataLen, IN TPM_ALGORITHM_ID AlgorithmId, IN OUT TCG_PCR_EVENT *TCGLogData, IN OUT UINT32 *EventNumber, OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry ) { TCG_DXE_DATA *TcgData; EFI_STATUS Status; if (TCGLogData == NULL || EventLogLastEntry == NULL){ return EFI_INVALID_PARAMETER; } TcgData = TCG_DXE_DATA_FROM_THIS (This); if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) { return EFI_DEVICE_ERROR; } if (AlgorithmId != TPM_ALG_SHA) { return EFI_UNSUPPORTED; } if (HashData == 0 && HashDataLen > 0) { return EFI_INVALID_PARAMETER; } Status = TcgDxeHashLogExtendEventI ( TcgData, (UINT8 *) (UINTN) HashData, HashDataLen, (TCG_PCR_EVENT_HDR*)TCGLogData, TCGLogData->Event ); if (!EFI_ERROR(Status)){ *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN) TcgData->LastEvent; } return Status; }
/** Measure and log EFI handoff tables, and extend the measurement result into PCR[1]. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureHandoffTables ( VOID ) { EFI_STATUS Status; TCG_PCR_EVENT_HDR TcgEvent; EFI_HANDOFF_TABLE_POINTERS HandoffTables; UINTN ProcessorNum; EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; ProcessorLocBuf = NULL; Status = EFI_SUCCESS; if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) { // // Tcg Server spec. // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1] // Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum); if (!EFI_ERROR(Status)){ TcgEvent.PCRIndex = 1; TcgEvent.EventType = EV_TABLE_OF_DEVICES; TcgEvent.EventSize = sizeof (HandoffTables); HandoffTables.NumberOfTables = 1; HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid; HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf; Status = TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)(UINTN)ProcessorLocBuf, sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, &TcgEvent, (UINT8*)&HandoffTables ); FreePool(ProcessorLocBuf); } } return Status; }
/** Measure and log an action string, and extend the measurement result into PCR[5]. @param[in] String A specific string that indicates an Action event. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI TcgMeasureAction ( IN CHAR8 *String ) { TCG_PCR_EVENT_HDR TcgEvent; TcgEvent.PCRIndex = 5; TcgEvent.EventType = EV_EFI_ACTION; TcgEvent.EventSize = (UINT32)AsciiStrLen (String); return TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)String, TcgEvent.EventSize, &TcgEvent, (UINT8 *) String ); }
/** Measure and log EFI handoff tables, and extend the measurement result into PCR[1]. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureHandoffTables ( VOID ) { EFI_STATUS Status; SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; TCG_PCR_EVENT_HDR TcgEvent; EFI_HANDOFF_TABLE_POINTERS HandoffTables; Status = EfiGetSystemConfigurationTable ( &gEfiSmbiosTableGuid, (VOID **) &SmbiosTable ); if (!EFI_ERROR (Status)) { ASSERT (SmbiosTable != NULL); TcgEvent.PCRIndex = 1; TcgEvent.EventType = EV_EFI_HANDOFF_TABLES; TcgEvent.EventSize = sizeof (HandoffTables); HandoffTables.NumberOfTables = 1; HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid; HandoffTables.TableEntry[0].VendorTable = SmbiosTable; DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress)); DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength)); Status = TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)(UINTN)SmbiosTable->TableAddress, SmbiosTable->TableLength, &TcgEvent, (UINT8*)&HandoffTables ); } return Status; }
/** Measure and log Separator event, and extend the measurement result into a specific PCR. @param[in] PCRIndex PCR index. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureSeparatorEvent ( IN TPM_PCRINDEX PCRIndex ) { TCG_PCR_EVENT_HDR TcgEvent; UINT32 EventData; EventData = 0; TcgEvent.PCRIndex = PCRIndex; TcgEvent.EventType = EV_SEPARATOR; TcgEvent.EventSize = (UINT32)sizeof (EventData); return TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8 *)&EventData, sizeof (EventData), &TcgEvent, (UINT8 *)&EventData ); }
/** Measure and log EFI handoff tables, and extend the measurement result into PCR[1]. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI MeasureHandoffTables ( VOID ) { EFI_STATUS Status; SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; TCG_PCR_EVENT_HDR TcgEvent; EFI_HANDOFF_TABLE_POINTERS HandoffTables; UINTN ProcessorNum; EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf; // // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1] // Status = EfiGetSystemConfigurationTable ( &gEfiSmbiosTableGuid, (VOID **) &SmbiosTable ); if (!EFI_ERROR (Status)) { ASSERT (SmbiosTable != NULL); TcgEvent.PCRIndex = 1; TcgEvent.EventType = EV_EFI_HANDOFF_TABLES; TcgEvent.EventSize = sizeof (HandoffTables); HandoffTables.NumberOfTables = 1; HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid; HandoffTables.TableEntry[0].VendorTable = SmbiosTable; DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress)); DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength)); Status = TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)(UINTN)SmbiosTable->TableAddress, SmbiosTable->TableLength, &TcgEvent, (UINT8*)&HandoffTables ); } if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) { // // Tcg Server spec. // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1] // Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum); if (!EFI_ERROR(Status)) { TcgEvent.PCRIndex = 1; TcgEvent.EventType = EV_TABLE_OF_DEVICES; TcgEvent.EventSize = sizeof (HandoffTables); HandoffTables.NumberOfTables = 1; HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid; HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf; Status = TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)(UINTN)ProcessorLocBuf, sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum, &TcgEvent, (UINT8*)&HandoffTables ); FreePool(ProcessorLocBuf); } } return Status; }