diff options
Diffstat (limited to 'Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c')
-rw-r--r-- | Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c | 584 |
1 files changed, 584 insertions, 0 deletions
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c new file mode 100644 index 0000000..dd71a11 --- /dev/null +++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c @@ -0,0 +1,584 @@ +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c 2 4/21/14 3:17p Fredericko $ +// +// $Revision: 2 $ +// +// $Date: 4/21/14 3:17p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c $ +// +// 2 4/21/14 3:17p Fredericko +// +// 1 4/21/14 2:18p Fredericko +// +// 1 10/08/13 12:06p Fredericko +// Initial Check-In for Tpm-Next module +// +// 1 7/10/13 5:57p Fredericko +// [TAG] EIP120969 +// [Category] New Feature +// [Description] TCG (TPM20) +//********************************************************************** +//<AMI_FHDR_START> +//--------------------------------------------------------------------------- +// Name: +// +// +// +//--------------------------------------------------------------------------- +//<AMI_FHDR_END> +#include "TpmClearOnRollback.h" +#include "TpmClearOnRollbackWrapperLib.h" + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TpmRecoveryGetFidFromFv +// +// Description: +// Finds FID information in the Flash +// +// Input: +// +// +// Output: +// +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS TpmRecoveryGetFidFromFv( + OUT VOID *Fid +) +{ + static EFI_GUID FidFileName = FID_FFS_FILE_NAME_GUID; + EFI_STATUS Status; + EFI_HANDLE *FvHandle; + UINTN FvCount; + UINTN i; + UINTN BufferSize; + VOID *Buffer; + + Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvCount, &FvHandle); + if (EFI_ERROR(Status)) + return Status; + + for(i = 0; i < FvCount; i++) + { + EFI_FIRMWARE_VOLUME_PROTOCOL *Fv; + UINT32 AuthStatus; + Status = pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolume2ProtocolGuid, &Fv); + if (EFI_ERROR(Status)) + continue; + Buffer = 0; + BufferSize = 0; + Status = Fv->ReadSection(Fv, &FidFileName, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 0, &Buffer, &BufferSize, &AuthStatus); + TRACE((-1, "extracted section with guid %g\n", (EFI_GUID *)Buffer)); + if (!EFI_ERROR(Status)) { + (UINT8 *)Buffer += sizeof(EFI_GUID); + MemCpy(Fid, Buffer, sizeof(FW_VERSION)); + (UINT8 *)Buffer -= sizeof(EFI_GUID); + pBS->FreePool(Buffer); + return EFI_SUCCESS; + } + } + pBS->FreePool(FvHandle); + return EFI_NOT_FOUND; +} + + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: TpmGetFidFromBuffer +// +// Description: +// Finds FID information in provided buffer +// +// Input: +// +// +// Output: +// +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS TpmGetFidFromBuffer( + OUT VOID *Fid, + IN VOID *Buffer +) +{ + static EFI_GUID FidSectionGuid = FID_FFS_FILE_SECTION_GUID; + UINT32 Signature; + UINT32 *SearchPointer; + + SearchPointer = (UINT32 *)((UINT8 *)Buffer - sizeof(EFI_GUID) + FLASH_SIZE); + Signature = FidSectionGuid.Data1; + + do { + if(*SearchPointer == Signature) { + if(!guidcmp(&FidSectionGuid, (EFI_GUID *)SearchPointer)) { + (UINT8 *)SearchPointer += sizeof(EFI_GUID); + MemCpy(Fid, SearchPointer, sizeof(FW_VERSION)); + return EFI_SUCCESS; + } + } + } while(SearchPointer-- >= (UINT32 *)Buffer); + + return EFI_NOT_FOUND; +} + + + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SendTpmCommandRecovery +// +// Description: +// Generic send TPM Transaction +// +// Input: +// +// +// Output: +// +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SendTpmCommandRecovery(UINT8 *Cmd, UINTN CmdSize, + UINT8 *RetBuff, UINTN RetBuffSize) +{ + EFI_STATUS Status; + TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1]; + + InBuffer[0].Buffer = Cmd; + InBuffer[0].Size = CmdSize; + OutBuffer[0].Buffer = RetBuff; + OutBuffer[0].Size = RetBuffSize; + + Status = TpmLibPassThrough(((TPM_1_2_REGISTERS_PTR)(UINTN)TPM_BASE_ADDRESS), + sizeof (InBuffer)/sizeof (*InBuffer), + InBuffer, + sizeof (OutBuffer) / sizeof (*OutBuffer), + OutBuffer); + + return Status; + +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: RecoverySetPhysicalPresence +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS RecoverySetPhysicalPresence() +{ + EFI_STATUS Status; + PHYSICAL_PRESENCE_CMD PpCmd; + TPM_1_2_RET_HEADER retHeader; + + + PpCmd.Hdr.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + PpCmd.Hdr.ParamSize = TPM_H2NL( sizeof (PHYSICAL_PRESENCE_CMD)); + PpCmd.Hdr.Ordinal = TPM_H2NL( TSC_ORD_PhysicalPresence ); + PpCmd.Data = TPM_H2NS(TPM_PHYSICAL_PRESENCE_CMD_ENABLE ); + + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + Status = SendTpmCommandRecovery((UINT8 *)&PpCmd, sizeof(PHYSICAL_PRESENCE_CMD), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + //don't care about error case on setting physical presence CMD type + //care about actual physical presence failure + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + PpCmd.Data = TPM_H2NS(TPM_PHYSICAL_PRESENCE_PRESENT); + + Status = SendTpmCommandRecovery((UINT8 *)&PpCmd, sizeof(PHYSICAL_PRESENCE_CMD), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + if(retHeader.RetCode == 0) + { + return EFI_SUCCESS; + } + + return EFI_SECURITY_VIOLATION; + +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: RecoveryEnableActivate +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS RecoveryEnableActivate() +{ + EFI_STATUS Status; + DATA_CMD Command; + TPM_1_2_CMD_HEADER cmdEnable; + TPM_1_2_RET_HEADER retHeader; + + cmdEnable.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + cmdEnable.ParamSize = TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER)); + cmdEnable.Ordinal = TPM_H2NL( TPM_ORD_PhysicalEnable ); + + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + Status = SendTpmCommandRecovery((UINT8 *)&cmdEnable, sizeof(TPM_1_2_CMD_HEADER), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + if(!EFI_ERROR(Status) && retHeader.RetCode == 0){ + Command.Hdr.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + Command.Hdr.ParamSize = TPM_H2NL( sizeof (DATA_CMD)); + Command.Hdr.Ordinal = TPM_H2NL( TPM_ORD_PhysicalSetDeactivated ); + Command.Data = 0x0; + + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + Status = SendTpmCommandRecovery((UINT8 *)&Command, sizeof(DATA_CMD), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + if(retHeader.RetCode == 0) + { + return EFI_SUCCESS; + } + } + + return EFI_SECURITY_VIOLATION; + +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: RecoverySendClearCmd +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +UINT8 RecoverySendClearCmd() +{ + EFI_STATUS Status; + TPM_1_2_CMD_HEADER cmdClear; + TPM_1_2_RET_HEADER retHeader; + + cmdClear.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + cmdClear.ParamSize = TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER)); + cmdClear.Ordinal = TPM_H2NL( TPM_ORD_ForceClear ); + + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + Status = SendTpmCommandRecovery((UINT8 *)&cmdClear, sizeof(TPM_1_2_CMD_HEADER), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + if(retHeader.RetCode == 0) + { + return TPM_CLEAR_SUCCESSFUL; + }else if((retHeader.RetCode == TPM_H2NL(DISABLED))|| + (retHeader.RetCode == TPM_H2NL(DEACTIVATED))){ + //we need to send enable and activate command + //reset and then clear. + Status = RecoveryEnableActivate(); + + if(!EFI_ERROR(Status)){ + return TPM_CLEAR_RESET_REQUIRED; + } + } + + return TPM_FATAL_CONTINUE_FLASH; + +} + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: RecoverySendStartUpCmd +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS RecoverySendStartUpCmd() +{ + EFI_STATUS Status; + TPM_1_2_CMD_STARTUP cmdStartup; + TPM_1_2_RET_HEADER retHeader; + TPM_STARTUP_TYPE TpmSt = TPM_ST_CLEAR; + + cmdStartup.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + cmdStartup.Header.ParamSize = TPM_H2NL( sizeof (cmdStartup)); + cmdStartup.Header.Ordinal = TPM_H2NL( TPM_ORD_Startup ); + cmdStartup.StartupType = TPM_H2NS( TpmSt ); + + MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0); + + Status = SendTpmCommandRecovery((UINT8 *)&cmdStartup, sizeof(TPM_1_2_CMD_STARTUP), + (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER)); + + if(retHeader.RetCode == 0) + { + return EFI_SUCCESS; + } + + return EFI_DEVICE_ERROR; +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: GetCapabilityCmd +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS GetCapabilityCmd(TPM_Capabilities_PermanentFlag *PermFlags) +{ + EFI_STATUS Status = EFI_ABORTED; + BOOLEAN Support = FALSE; + TPM_GetCapabilities_Input cmdGetCap; + + cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap)); + + if(AutoSupportType()){ + //not supported + return EFI_SUCCESS; + }else{ + cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability ); + cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG ); + } + + cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long + cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_PERMANENT ); + + Status = SendTpmCommandRecovery((UINT8 *)&cmdGetCap, sizeof(TPM_GetCapabilities_Input), + (UINT8 *)PermFlags, sizeof(TPM_Capabilities_PermanentFlag)); + + if(PermFlags->RetCode == TPM_H2NL(INVALID_POSTINIT)) + { + return EFI_NOT_READY; + } + + if(PermFlags->RetCode == 0){ + return EFI_SUCCESS; + } + + return EFI_DEVICE_ERROR; +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: GetVolatileFlags +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +EFI_STATUS GetVolatileFlags(TPM_VOLATILE_FLAGS *VolatileFlags) +{ + EFI_STATUS Status = EFI_ABORTED; + BOOLEAN Support = FALSE; + TPM_GetCapabilities_Input cmdGetCap; + + cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND ); + cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap)); + + if(AutoSupportType()){ + return EFI_SUCCESS; + }else{ + cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability ); + cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG ); + } + + cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long + cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_VOLATILE ); + + Status = SendTpmCommandRecovery((UINT8 *)&cmdGetCap, sizeof(TPM_GetCapabilities_Input), + (UINT8 *)VolatileFlags, sizeof(TPM_VOLATILE_FLAGS)); + + if(VolatileFlags->RetCode == TPM_H2NL(INVALID_POSTINIT)) + { + return EFI_NOT_READY; + } + + if(VolatileFlags->RetCode == 0){ + return EFI_SUCCESS; + } + + return EFI_DEVICE_ERROR; +} + + + +//********************************************************************** +//<AMI_PHDR_START> +// +// Procedure: ClearTpmBeforeFlash +// +// Description: +// +// Input: +// +// Output: +// +// Modified: +// +// Referrals: +// +// Notes: +//<AMI_PHDR_END> +//********************************************************************** +UINT8 ClearTpmBeforeFlash() +{ + TPM_Capabilities_PermanentFlag PermFlags; + UINT8 Result=0; + EFI_STATUS Status; + TPM_VOLATILE_FLAGS TpmVolatileFlags; + + if(AutoSupportType())return TPM_CLEAR_SUCCESSFUL; + + Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS); + if(EFI_ERROR(Status)){ + return TPM_CLEAR_SUCCESSFUL; + } + + //else we have a TPM need to process to clear + TisRequestLocality((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS); + + Status = GetCapabilityCmd(&PermFlags); + if(Status == EFI_NOT_READY) + { + Status = RecoverySendStartUpCmd(); + if(EFI_ERROR(Status)) + { + return TPM_FATAL_CONTINUE_FLASH; + } + } + + if(EFI_ERROR(Status))return TPM_FATAL_CONTINUE_FLASH; + + Status = RecoverySetPhysicalPresence(); + if(!EFI_ERROR(Status)) + { + Status = GetVolatileFlags(&TpmVolatileFlags); + if(!EFI_ERROR(Status)){ + if(TpmVolatileFlags.physicalPresenceLock){ + //we need to go into manufacturing mode\special mode + //to skip physical presence lock; Return we failed + //to clear TPM and flashing should be discontinued. + return TPM_FATAL_DISCONTINUE_FLASH; + } + } + Result = RecoverySendClearCmd(); + }else{ + if(EFI_ERROR(Status))return TPM_FATAL_CONTINUE_FLASH; + } + + TisReleaseLocality((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS); + + return Result; +} +//************************************************************************* +//************************************************************************* +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//************************************************************************* +//************************************************************************* |