X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=SecurityPkg%2FLibrary%2FDxeTcgPhysicalPresenceLib%2FDxeTcgPhysicalPresenceLib.c;h=427cc8d66bcda4a5f0e67550f52c778c1bbf6e16;hb=ed094569d6a1248b1b6ca6d0439e5bdf0db36aa2;hp=3414cd2ea42559c11839f4f0d30f0c0e5ebc5ecf;hpb=db06c2d723ac981e4e54b5d6dd410cb23621517c;p=mirror_edk2.git diff --git a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c index 3414cd2ea4..427cc8d66b 100644 --- a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c +++ b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c @@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +#include #include #include #include @@ -909,12 +910,11 @@ UserConfirm ( BOOLEAN HaveValidTpmRequest ( IN EFI_PHYSICAL_PRESENCE *TcgPpData, + IN UINT8 Flags, OUT BOOLEAN *RequestConfirmed ) { - UINT8 Flags; - - Flags = TcgPpData->Flags; + *RequestConfirmed = FALSE; switch (TcgPpData->PPRequest) { @@ -1003,14 +1003,16 @@ HaveValidTpmRequest ( VOID ExecutePendingTpmRequest ( IN EFI_TCG_PROTOCOL *TcgProtocol, - IN EFI_PHYSICAL_PRESENCE *TcgPpData + IN EFI_PHYSICAL_PRESENCE *TcgPpData, + IN UINT8 Flags ) { EFI_STATUS Status; UINTN DataSize; BOOLEAN RequestConfirmed; + UINT8 NewFlags; - if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) { + if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) { // // Invalid operation request. // @@ -1039,14 +1041,29 @@ ExecutePendingTpmRequest ( // Execute requested physical presence command // TcgPpData->PPResponse = TPM_PP_USER_ABORT; + NewFlags = Flags; if (RequestConfirmed) { - TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags); + TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags); } + // + // Save the flags if it is updated. + // + if (Flags != NewFlags) { + Status = gRT->SetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (UINT8), + &NewFlags + ); + } + + // // Clear request // - if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) { + if ((NewFlags & FLAG_RESET_TRACK) == 0) { TcgPpData->LastPPRequest = TcgPpData->PPRequest; TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; } @@ -1123,11 +1140,56 @@ TcgPhysicalPresenceLibProcessRequest ( UINTN DataSize; EFI_PHYSICAL_PRESENCE TcgPpData; EFI_TCG_PROTOCOL *TcgProtocol; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; + UINT8 PpiFlags; Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); if (EFI_ERROR (Status)) { return ; } + + // + // Initialize physical presence flags. + // + DataSize = sizeof (UINT8); + Status = gRT->GetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + PpiFlags = FLAG_NO_PPI_PROVISION; + Status = gRT->SetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (UINT8), + &PpiFlags + ); + } + ASSERT_EFI_ERROR (Status); + } + DEBUG ((EFI_D_ERROR, "[TPM] PpiFlags = %x, Status = %r\n", PpiFlags, Status)); + + // + // This flags variable controls whether physical presence is required for TPM command. + // It should be protected from malicious software. We set it as read-only variable here. + // + Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol); + if (!EFI_ERROR (Status)) { + Status = VariableLockProtocol->RequestToLock ( + VariableLockProtocol, + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "[TPM] Error when lock variable %s, Status = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status)); + ASSERT_EFI_ERROR (Status); + } + } // // Initialize physical presence variable. @@ -1143,7 +1205,6 @@ TcgPhysicalPresenceLibProcessRequest ( if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND) { ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData)); - TcgPpData.Flags |= FLAG_NO_PPI_PROVISION; DataSize = sizeof (EFI_PHYSICAL_PRESENCE); Status = gRT->SetVariable ( PHYSICAL_PRESENCE_VARIABLE, @@ -1156,7 +1217,7 @@ TcgPhysicalPresenceLibProcessRequest ( ASSERT_EFI_ERROR (Status); } - DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest)); + DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags, TcgPpData.PPRequest)); if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) { // @@ -1191,7 +1252,7 @@ TcgPhysicalPresenceLibProcessRequest ( // // Execute pending TPM request. // - ExecutePendingTpmRequest (TcgProtocol, &TcgPpData); + ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags); DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse)); // @@ -1223,7 +1284,8 @@ TcgPhysicalPresenceLibNeedUserConfirm( BOOLEAN LifetimeLock; BOOLEAN CmdEnable; EFI_TCG_PROTOCOL *TcgProtocol; - + UINT8 PpiFlags; + Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); if (EFI_ERROR (Status)) { return FALSE; @@ -1244,6 +1306,18 @@ TcgPhysicalPresenceLibNeedUserConfirm( return FALSE; } + DataSize = sizeof (UINT8); + Status = gRT->GetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) { // // No operation request @@ -1251,7 +1325,7 @@ TcgPhysicalPresenceLibNeedUserConfirm( return FALSE; } - if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) { + if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) { // // Invalid operation request. //