X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=SecurityPkg%2FTcg%2FTcg2Dxe%2FTcg2Dxe.c;h=aa463b287e79819d1f20cdc9f0d27795b8cbd3c8;hb=4cecd19a44dca3b02f8cf7359420b6271518e7dc;hp=79d614ce52246a29d1be1e585660dce584089963;hpb=a2612cf7d82ba09772c27f502eab34c405f5d2d3;p=mirror_edk2.git diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index 79d614ce52..aa463b287e 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -1,14 +1,14 @@ /** @file This module implements Tcg2 Protocol. - -Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+ +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ @@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -115,7 +116,6 @@ VARIABLE_TYPE mVariableType[] = { {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid}, {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid}, {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid}, - {EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid}, }; EFI_HANDLE mImageHandle; @@ -372,11 +372,11 @@ GetProcessorsCpuLocation ( @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The command was unsuccessful. - The ProtocolCapability variable will not be populated. + The ProtocolCapability variable will not be populated. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. The ProtocolCapability variable will not be populated. @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response. - It will be partially populated (required Size field will be set). + It will be partially populated (required Size field will be set). **/ EFI_STATUS EFIAPI @@ -390,7 +390,7 @@ Tcg2GetCapability ( if ((This == NULL) || (ProtocolCapability == NULL)) { return EFI_INVALID_PARAMETER; } - + DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size)); DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0))); @@ -398,7 +398,7 @@ Tcg2GetCapability ( // // Handle the case that firmware support 1.1 but OS only support 1.0. // - if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || + if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) { if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) { CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)); @@ -563,7 +563,7 @@ DumpEvent2 ( /** This function returns size of TCG PCR event 2. - + @param[in] TcgPcrEvent2 TCG PCR event 2 structure. @return size of TCG PCR event 2. @@ -623,7 +623,7 @@ DumpEventLog ( UINTN NumberOfEvents; DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat)); - + switch (EventLogFormat) { case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation; @@ -647,7 +647,7 @@ DumpEventLog ( break; case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: // - // Dump first event + // Dump first event // EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation; DumpEvent (EventHdr); @@ -682,7 +682,7 @@ DumpEventLog ( /** The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to - retrieve the address of a given event log and its last entry. + retrieve the address of a given event log and its last entry. @param[in] This Indicates the calling context @param[in] EventLogFormat The type of the event log for which the information is requested. @@ -780,14 +780,14 @@ Tcg2GetEventLog ( /** Add a new entry to the Event Log. - @param[in, out] EventLogPtr Pointer to the Event Log data. - @param[in, out] LogSize Size of the Event Log. + @param[in, out] EventLogPtr Pointer to the Event Log data. + @param[in, out] LogSize Size of the Event Log. @param[in] MaxSize Maximum size of the Event Log. - @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. + @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. @param[in] NewEventHdrSize New event header size. - @param[in] NewEventData Pointer to the new event data. + @param[in] NewEventData Pointer to the new event data. @param[in] NewEventSize New event data size. - + @retval EFI_SUCCESS The new event log entry was added. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @@ -838,9 +838,9 @@ TcgCommLogEvent ( Add a new entry to the Event Log. @param[in] EventLogFormat The type of the event log for which the information is requested. - @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. + @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. @param[in] NewEventHdrSize New event header size. - @param[in] NewEventData Pointer to the new event data. + @param[in] NewEventData Pointer to the new event data. @param[in] NewEventSize New event data size. @retval EFI_SUCCESS The new event log entry was added. @@ -859,7 +859,7 @@ TcgDxeLogEvent ( EFI_STATUS Status; UINTN Index; TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct; - + for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) { break; @@ -889,7 +889,7 @@ TcgDxeLogEvent ( NewEventData, NewEventSize ); - + if (Status == EFI_OUT_OF_RESOURCES) { EventLogAreaStruct->EventLogTruncated = TRUE; return EFI_VOLUME_FULL; @@ -1122,11 +1122,11 @@ TcgDxeLogHashEvent ( and add an entry to the Event Log. @param[in] Flags Bitmap providing additional information. - @param[in] HashData Physical address of the start of the data buffer + @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, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. - @param[in] NewEventData Pointer to the new event data. + @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. + @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @@ -1176,13 +1176,13 @@ TcgDxeHashLogExtendEvent ( /** The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with an opportunity to extend and optionally log events without requiring - knowledge of actual TPM commands. + knowledge of actual TPM commands. The extend operation will occur even if this function cannot create an event - log entry (e.g. due to the event log being full). + log entry (e.g. due to the event log being full). @param[in] This Indicates the calling context @param[in] Flags Bitmap providing additional information. - @param[in] DataToHash Physical address of the start of the data buffer to be hashed. + @param[in] DataToHash Physical address of the start of the data buffer to be hashed. @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash. @param[in] Event Pointer to data buffer containing information about the event. @@ -1272,7 +1272,7 @@ Tcg2HashLogExtendEvent ( @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received. @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device. @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. - @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. **/ EFI_STATUS EFIAPI @@ -1322,7 +1322,7 @@ Tcg2SubmitCommand ( @param[out] ActivePcrBanks Pointer to the variable receiving the bitmap of currently active PCR banks. @retval EFI_SUCCESS The bitmap of active PCR banks was stored in the ActivePcrBanks parameter. - @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. + @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. **/ EFI_STATUS EFIAPI @@ -1412,7 +1412,7 @@ Tcg2GetResultOfSetActivePcrBanks ( if ((OperationPresent == NULL) || (Response == NULL)) { return EFI_INVALID_PARAMETER; } - + ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response); if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) { return EFI_SUCCESS; @@ -1485,7 +1485,7 @@ SetupEventLog ( mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa; mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen); // - // To initialize them as 0xFF is recommended + // To initialize them as 0xFF is recommended // because the OS can know the last entry for that. // SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF); @@ -1631,7 +1631,7 @@ SetupEventLog ( mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE; // - // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 + // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 // Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]); if (EFI_ERROR (Status)) { @@ -1652,7 +1652,7 @@ SetupEventLog ( } } } - + // // 3. Sync data from PEI to DXE // @@ -1661,7 +1661,7 @@ SetupEventLog ( if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { GuidHob.Raw = GetHobList (); Status = EFI_SUCCESS; - while (!EFI_ERROR (Status) && + while (!EFI_ERROR (Status) && (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) { TcgEvent = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid)); ASSERT (TcgEvent != NULL); @@ -1729,8 +1729,8 @@ SetupEventLog ( Measure and log an action string, and extend the measurement result into PCR[PCRIndex]. @param[in] PCRIndex PCRIndex to extend - @param[in] String A specific string that indicates an Action event. - + @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. @@ -1778,7 +1778,7 @@ MeasureHandoffTables ( if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) { // - // Tcg Server spec. + // Tcg Server spec. // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1] // Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum); @@ -1810,7 +1810,7 @@ MeasureHandoffTables ( /** Measure and log Separator event, and extend the measurement result into a specific PCR. - @param[in] PCRIndex PCR index. + @param[in] PCRIndex PCR index. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. @@ -1842,13 +1842,13 @@ MeasureSeparatorEvent ( /** 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] 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. - + @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. @@ -1928,13 +1928,13 @@ MeasureVariable ( /** Read then 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] 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[out] VarSize The size of the variable data. - @param[out] VarData Pointer to the content of the variable. - + @param[out] VarSize The size of the variable data. + @param[out] VarData Pointer to the content of the variable. + @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. @@ -1982,13 +1982,14 @@ ReadAndMeasureVariable ( } /** - Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5]. + Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1]. +according to TCG PC Client PFP spec 0021 Section 2.4.4.2 @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[out] VarSize The size of the variable data. - @param[out] VarData Pointer to the content of the variable. - + @param[out] VarSize The size of the variable data. + @param[out] VarData Pointer to the content of the variable. + @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. @@ -2003,7 +2004,7 @@ ReadAndMeasureBootVariable ( ) { return ReadAndMeasureVariable ( - 5, + 1, EV_EFI_VARIABLE_BOOT, VarName, VendorGuid, @@ -2017,9 +2018,9 @@ ReadAndMeasureBootVariable ( @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[out] VarSize The size of the variable data. - @param[out] VarData Pointer to the content of the variable. - + @param[out] VarSize The size of the variable data. + @param[out] VarData Pointer to the content of the variable. + @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES Out of memory. @retval EFI_DEVICE_ERROR The operation was unsuccessful. @@ -2136,6 +2137,24 @@ MeasureAllSecureVariables ( } } + // + // Measure DBT if present and not empty + // + Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize); + if (!EFI_ERROR(Status)) { + Status = MeasureVariable ( + 7, + EV_EFI_VARIABLE_DRIVER_CONFIG, + EFI_IMAGE_SECURITY_DATABASE2, + &gEfiImageSecurityDatabaseGuid, + Data, + DataSize + ); + FreePool(Data); + } else { + DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2)); + } + return EFI_SUCCESS; } @@ -2394,9 +2413,71 @@ OnExitBootServicesFailed ( } +/** + This routine is called to properly shutdown the TPM before system reset. + It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library + Part 1: Architecture, Revision 01.16. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or + EfiResetShutdown the data buffer starts with a Null-terminated + string, optionally followed by additional binary data. + The string is a description that the caller may use to further + indicate the reason for the system reset. ResetData is only + valid if ResetStatus is something other than EFI_SUCCESS + unless the ResetType is EfiResetPlatformSpecific + where a minimum amount of ResetData is always required. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. +**/ +VOID +EFIAPI +ShutdownTpmOnReset ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + EFI_STATUS Status; + Status = Tpm2Shutdown (TPM_SU_CLEAR); + DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status)); +} + +/** + Hook the system reset to properly shutdown TPM. + It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library + Part 1: Architecture, Revision 01.16. + + @param[in] Event Event whose notification function is being invoked + @param[in] Context Pointer to the notification function's context +**/ +VOID +EFIAPI +OnResetNotificationInstall ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify; + + Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify); + if (!EFI_ERROR (Status)) { + Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n")); + + gBS->CloseEvent (Event); + } +} + /** The function install Tcg2 protocol. - + @retval EFI_SUCCESS Tcg2 protocol is installed. @retval other Some error occurs. **/ @@ -2421,9 +2502,9 @@ InstallTcg2 ( /** The driver's entry point. It publishes EFI Tcg2 Protocol. - @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. - + @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ @@ -2448,7 +2529,7 @@ DriverEntry ( if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ - DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n")); + DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n")); return EFI_UNSUPPORTED; } @@ -2456,18 +2537,18 @@ DriverEntry ( DEBUG ((EFI_D_ERROR, "TPM2 error!\n")); return EFI_DEVICE_ERROR; } - + Status = Tpm2RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n")); return Status; } - + // // Fill information // ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0])); - + mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY); mTcgDxeData.BsCap.ProtocolVersion.Major = 1; mTcgDxeData.BsCap.ProtocolVersion.Minor = 1; @@ -2574,7 +2655,7 @@ DriverEntry ( ); // - // Measure Exit Boot Service failed + // Measure Exit Boot Service failed // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, @@ -2591,6 +2672,11 @@ DriverEntry ( // may update SecureBoot value based on last setting. // EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration); + + // + // Hook the system reset to properly shutdown TPM. + // + EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration); } //