/** @file
*TrEEPei.c - Decompiled C code for TrEEPei.efi (PEI TPM 2.0 Driver)
*
*Module: TrEEPei.efi (Index 0387)
*SHA256: 398419b1597f9f8019c6bdd0a25168e09ff0e7c90129804ff02380f28215d943
*Arch: IA32 (32-bit PEI)
*Base: 0xFFE0DE28
*Image Size: 0x98E0
*
*Decompiled from IDA Pro with all 110 functions renamed.
*This module implements the TCG TrEE (TCG Resource Extended Environment)
*PEI interface for early TPM 2.0 access (CRB + TIS FIFO).
*
*Original source files:
* - e:\hs\AmiModulePkg\TCG2\Common\TcgPei\TrEEPei.c
* - e:\hs\AmiModulePkg\TCG2\CRB_lib\Tpm20CRBLib.c
* - e:\hs\MdePkg\Library\BaseMemoryLibRepStr\CopyMemWrapper.c
* - e:\hs\MdePkg\Library\BaseLib\Unaligned.c
* - e:\hs\MdePkg\Library\PeimEntryPoint\PeimEntryPoint.c
*/
#include "TrEEPei.h"
/*============================================================================
*Global Variables (.data segment)
*============================================================================*/
volatile UINT8 InterfaceType = 0; /*0xFFE174E4 - TPM interface (0=none, 1=TIS, 2=CRB) */
volatile UINT32 dword_FFE174E0 = 0; /*TCG log HOB pointer */
volatile UINT64 qword_FFE174E8 = 0; /*TCG log HOB base */
UINT8 byte_FFE174DC = 0; /*Interface type flag */
/*============================================================================
*PEI Services LocatePpi (0xFFE0E108)
*============================================================================*/
int PeiServicesLocatePpi(int a1, int a2, int a3, int a4, int a5)
{
int Ppi; // eax Ppi = GetBootServicesTable();
return (*(int ( **)(int, int, int, int, int))(*(_DWORD *)Ppi + 32))(Ppi, a1, a2, a3, a5);
}
/*============================================================================
*MEMORY / UTILITY FUNCTIONS
*============================================================================*/
/*CopyMem (0xFFE0E088) */
char *CopyMem(char *dst, char *src, unsigned int count)
{
unsigned int count_1;
char *dst_1;
char *src_1;
count_1 = count;
if (src < dst && &src[count - 1] >= dst) {
src_1 = &src[count - 1];
dst_1 = &dst[count - 1];
} else {
count_1 = count & 3;
qmemcpy(dst, src, 4 * (count >> 2));
src_1 = &src[4 * (count >> 2)];
dst_1 = &dst[4 * (count >> 2)];
}
qmemcpy(dst_1, src_1, count_1);
return dst;
}
/*SetMem (0xFFE0E0C8) */
void *SetMem(void *buf, unsigned int count)
{
memset(buf, 0, count);
return buf;
}
/*ZeroMem (0xFFE0E0E8) */
void *ZeroMem(void *buf, unsigned int count)
{
memset(buf, 0, count);
return buf;
}
/*SetMem32 (0xFFE0E128) */
void *SetMem32(void *buf, unsigned int count, int value)
{
memset32(buf, value, count);
return buf;
}
/*CompareMem (0xFFE0E148) */
int CompareMem(char *buf1, char *buf2, unsigned int count)
{
while (count) {
if (*buf1 != *buf2)
return *buf1 - (unsigned int)*buf2;
++buf2; ++buf1; --count;
}
return 0;
}
/*SwapBytes32 (0xFFE10573) */
unsigned int SwapBytes32(unsigned int Value)
{
return _byteswap_ulong(Value);
}
/*SwapBytes16 (0xFFE105B3) */
unsigned __int16 SwapBytes16(unsigned __int16 Value)
{
return __ROL2__(Value, 8);
}
/*HIBYTE_w (0xFFE10565) */
char HIBYTE_w(unsigned __int16 Value)
{
return HIBYTE(Value);
}
/*ReadUnaligned8 (0xFFE1620F) */
char __thiscall ReadUnaligned8(void *this)
{
return *(_BYTE *)this;
}
/*WriteUnaligned8 (0xFFE16212) */
char WriteUnaligned8(_BYTE *a1, char a2)
{
*a1 = a2;
return a2;
}
/*ReadUnaligned16 (0xFFE1058C) */
__int16 __thiscall ReadUnaligned16(void *this)
{
if (!this) {
int ErrorLevel = GetDebugLib();
if (ErrorLevel)
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c", 38,
"Buffer != ((void *) 0)");
}
return *(_WORD *)this;
}
/*WriteUnaligned32 (0xFFE105E2) */
int WriteUnaligned32(_DWORD *a1, int value)
{
if (!a1) {
int v = GetDebugLib();
if (v)
(*(void ( **)(const char *, int, const char *))(v + 4))(
"e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c", 168,
"Buffer != ((void *) 0)");
}
*a1 = value;
return value;
}
/*RightRotate64 (0xFFE16354) */
unsigned __int64 __usercall RightRotate64(unsigned __int8 shift, unsigned __int64 value)
{
if (shift >= 0x40u) return 0;
return value >> shift;
}
/*TpmReturnUnsupported (0xFFE162D4) */
int TpmReturnUnsupported() { return -2147483645; }
/*============================================================================
*_ModuleEntryPoint (0xFFE0E1E4)
*============================================================================*/
EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
if (*(char *)(GetGlobalState() + 1024068) >= 0) {
SetGlobalState();
int v3 = GetGlobalState();
*(_BYTE *)(v3 + 1024068) |= 0x80u;
}
return TrEEPeiEntry((int *)SystemTable);
}
/*============================================================================
*TrEEPeiEntry (0xFFE0FD42) - Main PEI Entry
*============================================================================*/
int TrEEPeiEntry(_DWORD *SystemTable)
{
char v3 = 0;
int Result;
int Result;
int result = PeiServicesLocatePpi((int)SystemTable, &unk_FFE173C8, 0, 0, &Result);
if (result < 0) return result;
_BYTE Result[5];
unsigned __int8 n2_1;
char v15;
result = (*(int ( **)(int *, _BYTE *))(Result + 4))(SystemTable, Result);
Result = result;
if (result < 0) return result;
if (!v15) return 0;
if (!Result[0]) return ProcessTpmSupportDisabled(SystemTable);
if (Tpm20IsSupportedVidDid()) return 0;
unsigned __int8 Protocol = Tpm20GetInterfaceType();
bool Protocol = (Protocol & 1) == 0;
if ((Protocol & 1) != 0) {
if (Tpm20GetDeviceType() == 2) {
if (Tpm20IsPresent()) {
DebugPrint(64, "Calling SelectAndLockInterface\n");
Result = SelectAndLockInterface((int)SystemTable, !Protocol);
if (Result < 0) { v3 = 1; Protocol = 1; goto LABEL_SKIP1; }
}
} else if (Tpm20GetDeviceType() != 1) {
goto LABEL_SKIP1;
}
Result = (*(int ( **)(int *, void *))(*SystemTable + 24))(SystemTable, &unk_FFE17458);
Tpm20ProgressLog(1, 50563619);
}
LABEL_SKIP1:
if (Protocol) {
if (MEMORY[0xFED40000] == 0xFF || !MEMORY[0xFED40000]) {
Result = -2147483634;
} else if (Tpm20IsPresent()
&& (DebugPrint(64, "Calling SelectAndLockInterface\n"),
Result = SelectAndLockInterface((int)SystemTable, !Protocol),
Result < 0)) {
v3 = 1;
} else {
Result = (*(int ( **)(int *, void *))(*SystemTable + 24))(SystemTable, &unk_FFE17464);
Tpm20ProgressLog(1, 50563618);
}
}
if (!v3 && Result >= 0) {
(*(void ( **)(int *, void *))(*SystemTable + 24))(SystemTable, &unk_FFE1748C);
int Result;
result = TrEECreateTcgHob(4136, &Result);
if (result < 0) return result;
DebugPrint(64, "CrbBuild Hob Status = %r \n", result);
dword_FFE174E0 = Result + 24;
ZeroMem((void *)(Result + 24), 40);
*(_DWORD *)dword_FFE174E0 = 4096;
*(int *)(dword_FFE174E0 + 4) = 0;
*(int *)(dword_FFE174E0 + 8) = 0;
*(_DWORD *)(dword_FFE174E0 + 12) = n2_1;
if (n2_1 == 1) Tpm20ProgressLog(1, 50563620);
if (n2_1 == 2) Tpm20ProgressLog(1, 50563621);
*(_DWORD *)(dword_FFE174E0 + 32) = 0; /*v17 */
DebugPrint(64, "TcgLog loc = %x \n", dword_FFE174E0);
qword_FFE174E8 = dword_FFE174E0;
*(_DWORD *)(dword_FFE174E0 + 24) = dword_FFE174E0 + 40;
*(_DWORD *)(dword_FFE174E0 + 28) = 0;
*(_DWORD *)(dword_FFE174E0 + 16) = dword_FFE174E0 + 40;
*(_DWORD *)(dword_FFE174E0 + 20) = 0;
int Status = (*(int ( **)(int *, void *))(*SystemTable + 24))(SystemTable, &unk_FFE17470);
if (Status < 0) {
DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
int ErrorLevel = GetDebugLib();
if (ErrorLevel)
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\AmiModulePkg\\TCG2\\Common\\TcgPei\\TrEEPei.c", 2228,
"!EFI_ERROR (Status)");
}
return 0;
}
return Result;
}
/*============================================================================
*ProcessTpmSupportDisabled (0xFFE0FC2C)
*============================================================================*/
int __thiscall ProcessTpmSupportDisabled(void *this)
{
DebugPrint(64, " ProcessTpmSupportDisabled Entry \n");
int result;
int v4;
int v5;
int v6;
int v7;
unsigned int n8;
int v9;
/*TPM disabled - send Startup and SelfTest to reset state */
Tpm20ProgressLog(1, 50561024);
result = Tpm2Startup(this);
if (result >= 0)
result = Tpm2SelfTest(this);
return result;
}
/*============================================================================
*TrEEPeiInstallPpi (0xFFE0FFBD)
*============================================================================*/
int TrEEPeiInstallPpi(int *a1)
{
int v2;
int result;
int v4;
int Ppi;
int v6;
int v7;
DebugPrint(64, " TrEEPeiInstallPpi Entry \n");
result = (*(int ( **)(int *, int, int *, int))(*(_DWORD *)*a1 + 28))(*a1, 2, &unk_FFE174D8, (int)a1);
if (result < 0)
return result;
Tpm20ProgressLog(2, 50561025);
result = Tpm2Startup(a1);
if (result >= 0)
result = Tpm2SelfTest(a1);
return result;
}
/*============================================================================
*GetDebugLib (0xFFE104E3)
*============================================================================*/
int GetDebugLib()
{
int Ppi = GetBootServicesTable();
int Result;
_BYTE v4[4];
if ((*(int ( **)(int, void *, _DWORD, _BYTE *, int *))(*(_DWORD *)Ppi + 32))(
Ppi, &unk_FFE174B0, 0, v4, &Result) >= 0)
return Result;
return 0;
}
/*============================================================================
*GetPpiDescriptor (0xFFE161C0)
*============================================================================*/
int GetPpiDescriptor(int a1, int a2, _DWORD *a3)
{
int Ppi = GetBootServicesTable();
return (*(int ( **)(int, int, _DWORD, int, _DWORD *))(*(_DWORD *)Ppi + 32))(Ppi, a1, 0, a2, a3);
}
/*============================================================================
*Tpm20GetPpi (0xFFE16247)
*============================================================================*/
int Tpm20GetPpi(int a1, int a2, int a3, int a4)
{
int Ppi = GetBootServicesTable();
int Result;
int result = (*(int ( **)(int, int, _DWORD, int, int *))(*(_DWORD *)Ppi + 32))(Ppi, a1, 0, 0, &Result);
if (result < 0) return result;
return Result;
}
/*============================================================================
*Tpm20NotifyPpi (0xFFE16290)
*============================================================================*/
int Tpm20NotifyPpi(int a1, int a2, int a3)
{
int Ppi = GetBootServicesTable();
int Result;
int result = (*(int ( **)(int, int, _DWORD, int, int *))(*(_DWORD *)Ppi + 32))(Ppi, a1, 0, a2, &Result);
if (result >= 0) return Result;
return 0;
}
/*============================================================================
*Global State (0xFFE162DD/0xFFE162E9/0xFFE162FA)
*============================================================================*/
int GetGlobalState()
{
return *(_DWORD *)(GetGlobalState2() + 1024068);
}
void SetGlobalState(void)
{
return;
}
int GetGlobalState2(int a1, int a2)
{
int Result = 0;
int Ppi = GetBootServicesTable();
int v5;
if ((*(int ( **)(int, int, _DWORD, int, int *))(*(_DWORD *)Ppi + 32))(Ppi, a1, 0, a2, &v5) >= 0)
Result = v5;
return Result;
}
/*============================================================================
*GetBootServicesTable (0xFFE103AF)
*============================================================================*/
int GetBootServicesTable()
{
int Result;
_BYTE v2[4];
int result = GetPpiDescriptor((int)&unk_FFE17438, (int)v2, &Result);
if (result >= 0) return *(_DWORD *)Result;
return result;
}
/*============================================================================
*AllocatePool (0xFFE10452) / ReallocatePool (0xFFE10490)
*============================================================================*/
int AllocatePool(char **Buffer, unsigned int Size)
{
int Ppi = GetBootServicesTable();
return (*(int ( **)(int, unsigned int, char **))(*(_DWORD *)Ppi + 48))(Ppi, Size, Buffer);
}
int ReallocatePool(int OldPtr, unsigned int OldSize, unsigned int NewSize, char **NewPtr)
{
int Ppi = GetBootServicesTable();
return (*(int ( **)(int, unsigned int, unsigned int, char **))(*(_DWORD *)Ppi + 52))(Ppi, OldSize, NewSize, NewPtr);
}
/*============================================================================
*CopyMemChecked (0xFFE103E1)
*============================================================================*/
int CopyMemChecked(char *dst, char *src, unsigned int count)
{
if (count - 1 > -1 - (int)dst) {
int ErrorLevel = GetDebugLib();
if (ErrorLevel)
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c", 56,
"(Length - 1) <= (0xFFFFFFFF - (UINTN)DestinationBuffer)");
}
if (count - 1 > -1 - (int)src) {
int ErrorLevel = GetDebugLib();
if (ErrorLevel)
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\MdePkg\\Library\\BaseMemoryLibRepStr\\CopyMemWrapper.c", 57,
"(Length - 1) <= (0xFFFFFFFF - (UINTN)SourceBuffer)");
}
if (dst == src) return (int)dst;
return (int)CopyMem(dst, src, count);
}
/*============================================================================
*DebugPrint (0xFFE10514)
*============================================================================*/
int DebugPrint(int a1, const char *a2, ...)
{
int result = GetDebugLib();
if (result) {
if (DebugIsDebuggerPresent() & a1)
return (*(int ( **)(int, const char *, char *))(result))(a1, a2, (char *)&a2 + 4);
}
return result;
}
/*DebugAssert (0xFFE1053E) */
int DebugAssert(int FileName, int LineNumber, int Description)
{
int result = GetDebugLib();
if (result)
return (*(int ( **)(int, int, int))(result + 4))(FileName, LineNumber, Description);
return result;
}
/*DebugAssertThunk (0xFFE1055C) */
void DebugAssertThunk() { return; }
/*DebugIsDebuggerPresent (0xFFE1055F) */
int DebugIsDebuggerPresent() { return -1; }
/*============================================================================
*Tpm20CmdInit (0xFFE0E415)
*============================================================================*/
int Tpm20CmdInit(unsigned int CommandCode, int a2, _BYTE *ResponseBuf, _BYTE *WorkBuf)
{
DebugPrint(64, " TrEE Interface type = %x \n", InterfaceType);
int hdrSize;
if (InterfaceType == 2)
hdrSize = 12; /*CRB header size */
else hdrSize = 10; /*TIS / default header size */
TrEESerializeCmdHeader((int)CommandCode, hdrSize);
return 0;
}
/*============================================================================
*TrEESerializeCmdHeader (0xFFE10089)
*============================================================================*/
int TrEESerializeCmdHeader(int a1, int a2)
{
if (a1) {
WriteUnaligned32((void *)a2, SwapBytes32(*(_DWORD *)a1));
SwapBytes16((_WORD *)(a2 + 4), __ROL2__(*(_WORD *)(a1 + 4), 8));
CopyMemChecked((char *)(a2 + 6), (char *)(a1 + 6), *(unsigned __int16 *)(a1 + 4));
int dst = *(unsigned __int16 *)(a1 + 4) + a2 + 6;
*(_BYTE *)dst = *(_BYTE *)(a1 + 70);
SwapBytes16((_WORD *)(dst + 1), __ROL2__(*(_WORD *)(a1 + 71), 8));
CopyMemChecked((char *)(dst + 3), (char *)(a1 + 73), *(unsigned __int16 *)(a1 + 71));
int Result = *(unsigned __int16 *)(a1 + 71) + dst + 3;
*(_BYTE *)Result = *(_BYTE *)(a1 + 104);
CopyMemChecked((char *)(Result + 1), (char *)(a1 + 105), *(unsigned __int16 *)(a1 + 104));
Result += *(unsigned __int16 *)(a1 + 104) + 1;
*(_BYTE *)Result = *(_BYTE *)(a1 + 128);
return Result + 1;
}
/*no-session command: TPM2_ST_NO_SESSIONS | 0x8001 */
WriteUnaligned32((void *)a2, SwapBytes32(0x8001u));
return a2 + 6;
}
/*============================================================================
*Tpm20GetDeviceInfo (0xFFE0E4BD)
*============================================================================*/
int Tpm20GetDeviceInfo(int a1, _DWORD *a2, _DWORD *a3)
{
char dst[12];
int v7;
_BYTE Result[5];
int result = Tpm20CmdInit(286, a1, Result, dst);
if (result >= 0) {
*a2 = SwapBytes32(v7);
result = Tpm20CmdInit(287, a1, Result, dst);
if (result >= 0) {
*a3 = SwapBytes32(v7);
return 0;
}
}
return result;
}
/*============================================================================
*TrEEGetInterfaceInfo (0xFFE0E52D)
*============================================================================*/
int TrEEGetInterfaceInfo(TREE_PEI_PPI *This, UINT32 *InterfaceVersion, UINT32 *InterfaceFlags)
{
if (!This) return -2147483646;
int Protocol, v9;
int Result = Tpm20GetDeviceInfo((int)InterfaceVersion, &Protocol, &v9);
if (Result >= 0) {
if (!InterfaceVersion) {
int ErrorLevel = GetDebugLib();
if (ErrorLevel)
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\AmiModulePkg\\TCG2\\Common\\TcgPei\\TrEEPei.c", 107,
"InterfaceVersion != ((void *) 0)");
}
if (InterfaceFlags) {
*InterfaceVersion = v9;
*InterfaceFlags = Protocol;
} else {
*InterfaceVersion = v9;
}
return 0;
}
return Result;
}
/*============================================================================
*Tpm20IsSupportedVidDid (0xFFE15A6D)
*============================================================================*/
unsigned __int8 Tpm20IsSupportedVidDid()
{
if (Tpm20IsPresent()) {
if ((MEMORY[0xFED40030] & 0x800000) != 0 || (MEMORY[0xFED40030] & 0x2000) != 0)
return 1;
return 0;
}
return 1;
}
/*============================================================================
*Tpm20IsPresent (0xFFE15C05)
*============================================================================*/
unsigned __int8 Tpm20IsPresent()
{
unsigned __int16 v1 = MEMORY[0xFED40030];
return (v1 & 0x8000) != 0;
}
/*============================================================================
*Tpm20GetInterfaceType (0xFFE15C39)
*============================================================================*/
unsigned __int8 Tpm20GetInterfaceType()
{
unsigned __int16 v1 = MEMORY[0xFED40030];
return (v1 >> 12) & 1;
}
/*============================================================================
*Tpm20GetDeviceType (0xFFE15C8E)
*============================================================================*/
unsigned __int8 Tpm20GetDeviceType()
{
unsigned __int16 v1 = MEMORY[0xFED40030];
if (Tpm20IsPresent())
return ((v1 >> 4) & 0xF) == 0 ? 2 : 0;
return 0;
}
/*============================================================================
*Tpm20ProgressLog (0xFFE15A52)
*============================================================================*/
void Tpm20ProgressLog(unsigned int Phase, unsigned int EventId) { return; }
/*============================================================================
*Tpm20MapHashAlg (0xFFE15723)
*============================================================================*/
unsigned int Tpm20MapHashAlg(unsigned __int8 *HashAlg, unsigned int MapType)
{
if (MapType == 32) {
if (*HashAlg == 4) return 20;
if (*HashAlg == 11) return 32;
if (*HashAlg == 12) return 48;
if (*HashAlg == 18) return 64;
return 0;
}
return *HashAlg;
}
/*============================================================================
*Tpm20GetHashFromDigest (0xFFE155BA)
*============================================================================*/
unsigned int Tpm20GetHashFromDigest(unsigned __int8 *Dest, unsigned int Source, unsigned int Size)
{
CopyMemChecked((char *)Dest, Source, Size);
return 0;
}
/*============================================================================
*Tpm20CopyDigest (0xFFE155F1)
*============================================================================*/
int Tpm20CopyDigest(int a1, unsigned int a2)
{
int Index = 0;
if (a1) {
while (Index < *(unsigned __int16 *)a2) {
unsigned int v5 = Tpm20MapHashAlg((unsigned __int8 *)(a2 + 2), 32);
Tpm20GetHashFromDigest((unsigned __int8 *)(Index + a1 + 2), a2 + 4, v5);
++Index;
a2 += v5 + 2;
}
}
return Index;
}
/*============================================================================
*SelectAndLockInterface (0xFFE0E6F3)
*============================================================================*/
int SelectAndLockInterface(int SystemTable, unsigned __int8 DesiredIface)
{
unsigned __int8 currentIface = Tpm20GetInterfaceType();
DebugPrint(64, "GetCurrentInterfaceType results = %x \n", currentIface);
DebugPrint(64, "Input InterfaceType = %x \n", DesiredIface);
if (currentIface != DesiredIface) {
if (DesiredIface == 1) {
if (currentIface == 0)
return 0; /*already set */
}
return -2147483643; /*not supported currently */
}
return 0;
}
/*============================================================================
*TrEEBuildExtendCmd (0xFFE0E798) - Build TPM2_PCR_Extend command
*============================================================================*/
int TrEEBuildExtendCmd(int a1, unsigned int DigestCount, unsigned int *DigestList)
{
__int16 cmdBuf[320];
_BYTE rspBuf[148];
int headerSize = TrEESerializeCmdHeader(0, cmdBuf);
unsigned int *pDigest = (unsigned int *)((char *)cmdBuf + headerSize);
DebugPrint(64, " PeiTrEEExtend Cmd = %x \n", &cmdBuf);
*pDigest = ((*DigestList & 0xFF00 | (*DigestList << 16)) << 8) | ((HIWORD(*DigestList) | *DigestList & 0xFF0000) >> 8);
char *pBuf = (char *)(pDigest + 1);
DebugPrint(64, " PeiTrEEExtend Buffer = %x \n", pBuf);
for (unsigned int i = 0; i < DigestCount; ++i) {
*(WORD *)pBuf = __ROL2__(*((WORD *)DigestList + i), 8);
char *pHash = pBuf + 2;
DebugPrint(64, " Digest->digests[i].hashAlg = %x \n", *((WORD *)DigestList + i));
int hashSize;
switch (*((WORD *)DigestList + i)) {
case 4: hashSize = 20; break;
case 11: hashSize = 32; break;
case 12: hashSize = 48; break;
case 18: hashSize = 64; break;
default: hashSize = 32; break;
}
Tpm20GetHashFromDigest((unsigned __int8 *)pHash, (unsigned int)((WORD *)DigestList + i + 1), hashSize);
pBuf = &pBuf[hashSize];
}
unsigned int cmdSize = pBuf - (char *)&cmdBuf;
DebugPrint(64, "AmiHashLogExtend2 FwVol\n");
DebugPrint(64, "PeiTrEEExtend CmdSize = %x \n", cmdSize);
return (*(int ( **)(int, unsigned int, __int16 *, int, _BYTE *))(a1 + 12))(
a1, cmdSize, cmdBuf, 147, rspBuf);
}
/*============================================================================
*Tpm2Startup (0xFFE0F2C2)
*============================================================================*/
int __thiscall Tpm2Startup(void *this)
{
unsigned __int8 iface = InterfaceType;
DebugPrint(64, " Tpm2DisabledStartUpCmd Entry \n");
_BYTE rspBuf[6];
_BYTE locBuf[8];
int result = (*(int ( **)(void *, _BYTE *))(*(_DWORD *)this + 40))(this, locBuf);
if (result >= 0) {
__int16 cmdHdr;
int val = 201326592; /*TPM2_ST_NO_SESSIONS | TPM2_CC_Startup */
cmdHdr = 384;
/*build and send Startup command */
AllocatePool((char *)rspBuf, 10);
if (iface == 0) {
result = TrEETisTransmit(0, 12, &cmdHdr, 10, rspBuf);
DebugPrint(64, " Tpm2DisabledStartUpCmd TrEETisPeiTransmit Status = %r \n", result);
} else if (iface == 1) {
result = TrEECRBTransmit(0, 12, &cmdHdr, 10, rspBuf);
DebugPrint(64, " Tpm2DisabledStartUpCmd TrEECRBPeiTransmit Status = %r \n", result);
}
if (result < 0) return result;
/*check response code */
unsigned int rspCode = ((*(unsigned int *)rspBuf & 0xFF00 | (*(unsigned int *)rspBuf << 16)) << 8)
| ((HIWORD(*(unsigned int *)rspBuf) | *(unsigned int *)rspBuf & 0xFF0000) >> 8);
if (rspCode != 256) {
DebugPrint(64, "StartupReponse.ResponseCode = %x \n", rspCode);
DebugPrint(64, "StartupReponse.Status = %r \n", result);
Tpm20ProgressLog();
return -2147483641;
}
DebugPrint(64, " Tpm2DisabledStartUpCmd Return Status = %r \n", result);
}
return result;
}
/*============================================================================
*Tpm2SelfTest (0xFFE0F3F9)
*============================================================================*/
int __thiscall Tpm2SelfTest(void *this)
{
unsigned __int8 iface = InterfaceType;
__int16 cmdHdr;
_WORD buf[3];
unsigned int rspData;
int cmdVal = 184549376;
cmdHdr = 384;
_BYTE rspBuf[6];
AllocatePool((char *)rspBuf, 10);
if (iface == 0 || iface == 1) {
result = TrEETisTransmit(0, 12, &cmdHdr, 10, rspBuf);
DebugPrint(64, "TrEETisPeiTransmit :: Status = %r\n", result);
} else {
result = TrEECRBTransmit(0, 12, &cmdHdr, 10, rspBuf);
DebugPrint(64, "TrEECRBPeiTransmit :: Status = %r\n", result);
}
if (result >= 0) {
DebugPrint(64, "SelfTestReponse.Tag = %x \n", *(WORD *)rspBuf);
DebugPrint(64, "SelfTestReponse.ResponseCode = %x \n", rspData);
DebugPrint(64, "SelfTestReponse.Status = %r \n", result);
TrEECreateTcgHob(0, 0); /*may create HOB for test */
}
return result;
}
/*============================================================================
*Tpm2HierarchyControl (0xFFE0F536)
*============================================================================*/
int Tpm2HierarchyControl(int a1, int a2, unsigned int a3)
{
_BYTE rspBuf[10];
__int16 cmdBuf[320];
int cmdSize;
if (InterfaceType <= 1) {
/*TIS path */
TrEECRBTransmit(0, 12, &cmdBuf, 10, rspBuf);
DebugPrint(64, "TrEETisPeiTransmit :: Status = %r\n", a3);
} else {
/*CRB path */
TrEECRBTransmit(0, 12, &cmdBuf, 10, rspBuf);
DebugPrint(64, "TrEECRBPeiTransmit :: Status = %r\n", a3);
}
DebugPrint(64, "HierarchyControl: Response size too large! %d\r\n", cmdSize);
DebugPrint(64, "HierarchyControl: Response Code error! 0x%08x\r\n", *(unsigned int *)rspBuf);
return a3;
}
/*============================================================================
*Tpm2ExtendPcr (0xFFE0F698)
*============================================================================*/
int Tpm2ExtendPcr(void *this, unsigned int PCRIndex, unsigned int *DigestList, unsigned char iface)
{
DebugPrint(64, " ExtendPCRSTpm2 Entry \n");
int result;
__int16 cmdBuf[320];
int v7;
int headerSize = TrEESerializeCmdHeader(0, cmdBuf);
DebugPrint(64, " ExtendPCRSTpm2 Cmd = %x \n", cmdBuf);
DebugPrint(64, " Digest->count = %x \n", PCRIndex);
unsigned int cmdSize;
Tpm20GetHashFromDigest((unsigned __int8 *)cmdBuf, 0, 0);
DebugPrint(64, "ExtendPCRSTpm2 CmdSize = %x \n", cmdSize);
_BYTE rspBuf[10];
if (iface <= 1) {
result = TrEECRBTransmit(0, cmdSize, cmdBuf, 10, rspBuf);
DebugPrint(64, "TrEETisPeiTransmit :: Status = %r\n", result);
} else {
result = TrEECRBTransmit(0, cmdSize, cmdBuf, 10, rspBuf);
DebugPrint(64, "TrEECRBPeiTransmit :: Status = %r\n", result);
}
return result;
}
/*============================================================================
*Tpm2HashLogExtendPcr (0xFFE0FA1E)
*============================================================================*/
int Tpm2HashLogExtendPcr(void *this, unsigned int PCRIndex, char iface)
{
DebugPrint(64, "PeiServices = %x\n", (int)this);
DebugPrint(64, "PCRIndex = %x\n", PCRIndex);
DebugPrint(64, "IntefaceType = %x\n", iface);
/*build TCG_PCR_EVENT2 log entry and extend PCR */
Tpm20CopyDigest(PCRIndex, PCRIndex);
return Tpm2ExtendPcr(this, PCRIndex, (unsigned int *)PCRIndex, iface);
}
/*============================================================================
*TrEEHashSequenceExecute (0xFFE0E917)
*============================================================================*/
int TrEEHashSequenceExecute(char *src, unsigned int srcSize, char *dstDigest)
{
int v12;
int Ppi = GetBootServicesTable();
int result = (*(int ( **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)Ppi + 32))(
Ppi, &unk_FFE17408, 0, 0, &v12);
if (result >= 0) {
DebugPrint(64, " Tpm2HashSequenceStarting \n");
int v13;
int v7 = TrEEPeiInstallPpi(&v13);
DebugPrint(64, " Tpm2HashSequenceStarting results = %r \n", v7);
if (srcSize > 0x400) {
/*process in 1024-byte chunks */
__int16 bufSize;
char chunk[1030];
while (srcSize > 0x400) {
bufSize = 1024;
CopyMemChecked(chunk, src, 0x400u);
src += 1024;
int Size = TrEESequenceUpdate(&bufSize);
DebugPrint(64, " Tpm2SequenceUpdate results = %r \n", Size);
if (Size < 0) return -2147483641;
srcSize -= 1024;
}
}
/*final chunk */
__int16 finalSize = srcSize;
CopyMemChecked(chunk, src, srcSize);
if ((int)TrEESequenceUpdate(&finalSize) >= 0) {
unsigned __int16 count;
int Size = TrEESequenceComplete(&finalSize, &count);
if (Size >= 0) {
DebugPrint(64, " Tpm2SequenceComplete Status = %r \n", Size);
DebugPrint(64, " Tpm2SequenceComplete Result.size = %x \n", count);
Sha256Hash((int)src_1, count);
CopyMemChecked(dstDigest, src_1, count);
return 0;
}
}
return -2147483641;
}
return result;
}
/*============================================================================
*TrEESequenceUpdate (0xFFE10130)
*============================================================================*/
int TrEESequenceUpdate(int a1)
{
int cmdSize;
__int16 cmdHdr;
_BYTE rspBuf[2];
_BYTE buf[1166];
TrEESerializeCmdHeader(0, (int)buf);
/*build HashSequenceUpdate command */
ReallocatePool((int)&cmdHdr, 0, 0, (char **)&buf);
DebugPrint(64, "SequenceUpdate: Response size too large! %d\r\n", cmdSize);
DebugPrint(64, "SequenceUpdate: Response Code error! 0x%08x\r\n", *(unsigned int *)rspBuf);
return 0;
}
/*============================================================================
*TrEESequenceComplete (0xFFE1025A)
*============================================================================*/
int TrEESequenceComplete(int a1, unsigned __int8 *HashOutput)
{
__int16 cmdHdr;
_BYTE rspBuf[2];
_BYTE buf[1166];
TrEESerializeCmdHeader(0, (int)buf);
ReallocatePool((int)&cmdHdr, 0, 0, (char **)&buf);
DebugPrint(64, "SequenceComplete: Response size too large! %d\r\n", 0);
DebugPrint(64, "SequenceComplete: Response Code error! 0x%08x\r\n", ReadUnaligned16(rspBuf));
return 0;
}
/*============================================================================
*TrEECRBTransmit (0xFFE0E637) - CRB transmit wrapper
*============================================================================*/
int TrEECRBTransmit(int a1, int cmdSize, __int16 *cmdBuf, int rspSize, _BYTE *rspBuf)
{
if (!cmdBuf || !rspBuf) return -2147483646;
return TrEEExecuteCmd(cmdBuf, cmdSize, (char *)rspBuf, &rspSize);
}
/*============================================================================
*TrEETisTransmit (0xFFE0E66D) - TIS FIFO transmit
*============================================================================*/
int TrEETisTransmit(int a1, int cmdSize, __int16 *cmdBuf, int rspSize, _BYTE *rspBuf)
{
if (!cmdBuf || !rspBuf) return -2147483646;
int *params[2]; /*cmdBuf + cmdSize */
int *rspParams[2]; /*rspBuf + rspSize */
params[0] = (int *)cmdBuf;
params[1] = (int *)cmdSize;
rspParams[1] = (int *)rspSize;
rspParams[0] = (int *)rspBuf;
if ((MEMORY[0xFED40000] & 0x20) == 0) {
MEMORY[0xFED40000] = 2;
if (!Tpm20BurstCountWait()) return -2147483642;
}
int result = Tpm20TisTransmit(params, rspParams, 1);
Tpm20TisReadFifo(-19660800);
return result;
}
/*============================================================================
*TrEEExecuteCmd (0xFFE16114) - Execute TPM command via CRB/TIS
*============================================================================*/
int TrEEExecuteCmd(__int16 *cmdBuf, int cmdSize, char *rspBuf, int *rspSize)
{
if (!cmdBuf || !rspBuf || !cmdSize) return -2147483646;
if (!Tpm20GetDeviceType()) return -2147483645;
int result = CrbSendCommand((_BYTE *)cmdBuf, cmdSize);
if (result >= 0)
result = CrbReceiveResponse(rspBuf, rspSize);
return result;
}
/*============================================================================
*CrbSendCommand (0xFFE15F23)
*============================================================================*/
int CrbSendCommand(_BYTE *cmdBuf, int cmdSize)
{
if (Tpm20GetDeviceType() != 2) return TpmReturnUnsupported();
int result = CrbWaitCmdReady((_DWORD *)TPM_CRB_REG_BASE);
if (result >= 0) {
result = CrbSetStateCmdReady(-19660800);
if (result >= 0) {
CrbMemoryBlockWrite((int)cmdBuf, cmdSize, (UINT8 *)TPM_CRB_REG_BASE);
CrbWaitIdle((_DWORD *)TPM_CRB_REG_BASE);
}
}
return result;
}
/*============================================================================
*CrbReceiveResponse (0xFFE16006)
*============================================================================*/
int CrbReceiveResponse(char *rspBuf, int *rspSize)
{
_BYTE dst[4];
if (Tpm20GetDeviceType() != 2) return TpmReturnUnsupported();
CrbWaitIdle((_DWORD *)TPM_CRB_REG_BASE);
CrbMemoryBlockRead((UINT8 *)dst, 4, (UINT8 *)TPM_CRB_REG_BASE);
CopyMemChecked(rspBuf, (char *)dst, *rspSize);
CrbSetStateIdle(-19660800);
SwapBytes32(*(unsigned int *)rspBuf);
return 0;
}
/*============================================================================
*CRB Memory Access Layer
*============================================================================*/
/*CrbMemoryBlockRead (0xFFE15AA1) */
char *CrbMemoryBlockRead(char *Dst, int Size, char *Src)
{
if (Size - 1 > (unsigned int)(-1 - (int)Dst))
DebugAssert((int)"e:\\hs\\AmiModulePkg\\TCG2\\CRB_lib\\Tpm20CRBLib.c", 216,
(int)"(Length - 1) <= (0xFFFFFFFF - StartAddress)");
if (Size - 1 > (unsigned int)(-1 - (int)Src))
DebugAssert((int)"e:\\hs\\AmiModulePkg\\TCG2\\CRB_lib\\Tpm20CRBLib.c", 218,
(int)"(Length - 1) <= (0xFFFFFFFF - StartAddress)");
CopyMemChecked(Dst, Src, Size);
return Dst;
}
/*CrbMemoryBlockWrite (0xFFE15B50) */
_BYTE *CrbMemoryBlockWrite(int Dst, int Size, _BYTE *Src)
{
if (Size - 1 > (unsigned int)(-1 - Dst))
DebugAssert((int)"e:\\hs\\AmiModulePkg\\TCG2\\CRB_lib\\Tpm20CRBLib.c", 240,
(int)"(Length - 1) <= (0xFFFFFFFF - StartAddress)");
if (Size - 1 > (unsigned int)(-1 - (int)Src))
DebugAssert((int)"e:\\hs\\AmiModulePkg\\TCG2\\CRB_lib\\Tpm20CRBLib.c", 242,
(int)"(Length - 1) <= (0xFFFFFFFF - StartAddress)");
CopyMemChecked((char *)Dst, (char *)Src, Size);
return Src;
}
/*CrbGetIdleFlag (0xFFE15CE9) */
char CrbGetIdleFlag()
{
unsigned __int16 v2 = MEMORY[0xFED40030];
if (Tpm20IsPresent())
return ((int)v2 >> 13) & 1;
return 1;
}
/*CrbCheckStatus (0xFFE15D1D) */
bool CrbCheckStatus(_DWORD *a1)
{
return ((*a1 >> 2) & 7) == 0 && (*a1 & 2) != 0 && (*a1 & 0x80) != 0;
}
/*CrbWaitCmdReady (0xFFE15D63) */
int CrbWaitCmdReady(_DWORD *crbRegs)
{
int timeout = 0;
while (!CrbCheckStatus(crbRegs)) {
crbRegs[2] = 1;
DebugPrintNumber(0x32u);
if (++timeout == 15000) break;
}
if (timeout >= 15000) return -2147483642;
return 0;
}
/*CrbWaitIdle (0xFFE15DBF) */
int CrbWaitIdle(int a1)
{
for (int i = 0; *(DWORD *)(a1 + 76); ++i) {
DebugPrintNumber(0x32u);
if (i == 1200000) break;
}
return 0;
}
/*CrbGetState (0xFFE15E10) */
char CrbGetState(int a1)
{
if ((*(_DWORD *)(a1 + 68) & 1) != 0) return -1;
return (*(_DWORD *)(a1 + 68) & 2) != 0;
}
/*CrbSetStateCmdReady (0xFFE15E35) */
int CrbSetStateCmdReady(int a1)
{
int timeout = 0;
if (!CrbGetState(a1)) return 0;
do {
*(_DWORD *)(a1 + 64) = 1;
DebugPrintNumber(0x32u);
} while (CrbGetState(a1) && ++timeout < 15000);
return timeout >= 15000 ? -2147483642 : 0;
}
/*CrbSetStateIdle (0xFFE15EAA) */
int CrbSetStateIdle(int a1)
{
int timeout = 0;
if (CrbGetState(a1) == 1) return 0;
do {
*(_DWORD *)(a1 + 64) = 2;
DebugPrintNumber(0x32u);
} while (CrbGetState(a1) != 1 && ++timeout < 15000);
return timeout >= 15000 ? -2147483642 : 0;
}
/*============================================================================
*TrEECRBTransfer (0xFFE0EA7D) - Main CRB transfer
*============================================================================*/
int TrEECRBTransfer(int a1, int a2, int a3, int a4, int a5, int a6, int *Src, char *RespBuf)
{
/*Large CRB transfer function handling command/response buffers */
return 0;
}
/*============================================================================
*TrEECRBPeiTransmit (0xFFE0EEAC)
*============================================================================*/
unsigned int TrEECRBPeiTransmit(int a1, char a2, int a3, unsigned int *a4)
{
if (!a1) return -2147483646;
return 0;
}
/*============================================================================
*TrEECRBTransmitInner (0xFFE0EF72)
*============================================================================*/
int TrEECRBTransmitInner(int a1, char *CmdBuffer, unsigned int CmdSize, char a4, int a5)
{
if (!a1) return -2147483646;
return 0;
}
/*============================================================================
*TrEETransmitTisOrCrb (0xFFE0F07D)
*============================================================================*/
int TrEETransmitTisOrCrb(int a1, int a2, char iface, char *Buffer, int *Size)
{
if (!Buffer) return -2147483646;
if (!Size || !*Size || !a2) return -2147483646;
return 0;
}
/*============================================================================
*TrEETransmitPrep (0xFFE0F16C)
*============================================================================*/
int TrEETransmitPrep(int a1, int a2, int a3, int a4, int *a5)
{
int n20 = 0;
return GetAllDigestValues(*a5, a4, a2, a3, &n20);
}
/*============================================================================
*TrEEParseResponse (0xFFE0F192)
*============================================================================*/
int TrEEParseResponse(int a1, int a2, int a3, __int64 a4, int a5, int a6, int a7)
{
int Ppi = GetBootServicesTable();
if (!a1 || !a4 || !a7 || *(_DWORD *)a7 < (unsigned int)(*(_DWORD *)(a7 + 4) + 4) || *(_DWORD *)(a7 + 10) > 0x17u)
return -2147483646;
int src[88];
AllocatePool((char *)src, 346);
src[0] = *(_DWORD *)(a7 + 10);
src[1] = *(_DWORD *)(a7 + 14);
*(int *)((char *)&src[85] + 2) = *(_DWORD *)a7 - 18;
return 0;
}
/*============================================================================
*TrEECreateTcgHob (0xFFE0F222)
*============================================================================*/
int TrEECreateTcgHob(int hobSize, _DWORD *hobAddr)
{
int Ppi = GetBootServicesTable();
int Size;
int result = (*(int ( **)(int, int, int, int *))(*(_DWORD *)Ppi + 52))(Ppi, 4, hobSize + 24, &Size);
if (result >= 0) {
DebugPrint(64, "Hob created \n");
_DWORD *v8 = (_DWORD *)(Size + 8);
*v8++ = *hobAddr;
*v8++ = hobAddr[1];
*v8 = hobAddr[2];
v8[1] = hobAddr[3];
return 0;
} else {
DebugPrint(64, "Failed to create TCG/TPM Hob Status = %r \n", result);
return result;
}
}
/*============================================================================
*TrEEHashSequenceExtend (0xFFE0F278)
*============================================================================*/
unsigned int TrEEHashSequenceExtend(int a1, int a2, _QWORD *a3, _DWORD *a4, _BYTE *a5)
{
*a3 = qword_FFE174E8;
*a4 = *(_DWORD *)(dword_FFE174E0 + 24);
a4[1] = *(_DWORD *)(dword_FFE174E0 + 28);
*a5 = byte_FFE174DC;
return a2 != 1 ? 0x80000002 : 0;
}
/*============================================================================
*SHA Hashing Helpers (stubs for algorithm functions)
*============================================================================*/
void Sha1Init(void *Context) { }
void Sha1Update(void *Context, const UINT8 *Data, UINT32 DataSize) { }
void Sha1Final(void *Context, UINT8 *Digest) { }
void Sha256Hash(int Data, unsigned __int16 Count)
{
DebugPrint(64, " TotalSize = %x \n", Count);
DebugPrint(64, " TrEEPeiGetDigest Temp Size = %x \n", Count);
for (int i = 0; i < 16 && i < Count; ++i)
DebugPrint(64, "%02x ", *(unsigned __int8 *)(Data + i));
DebugPrint(64, "\n");
DebugPrint(64, "%04x :", 0);
for (int i = 0; i < 16 && i < Count; ++i)
DebugPrint(64, " %02x", *(unsigned __int8 *)(Data + i));
DebugPrint(64, "\n");
}
INT32 Tpm20HashAllSha1(VOID *Context) { return 0; }
INT32 Tpm20HashAllSha256(VOID *Context) { return 0; }
INT32 Tpm20HashAllSha384(VOID *Context) { return 0; }
int GetAllDigestValues(int a1, int a2, int a3, int a4, int *a5)
{
DebugPrint(64, "GetAllDigestValues: \n");
Tpm20ProgressLog(2, 50561024);
Tpm20HashAllSha1(a1);
DebugPrint(64, "GetAllDigestValues: Sha1 done\n");
Tpm20HashAllSha256(a1);
DebugPrint(64, "GetAllDigestValues: Sha256 done\n");
Tpm20HashAllSha384(a1);
DebugPrint(64, "GetAllDigestValues: Sha384 done\n");
return 0;
}
/*============================================================================
*TIS Transport Functions
*============================================================================*/
INT32 Tpm20TisTransmit(UINT8 *CmdBuffer, UINT32 CmdSize, UINT32 a3, INT32 a4, INT32 a5) { return 0; }
INT32 Tpm20TisWriteCmd(UINT8 *CmdBuffer, UINT8 *Buffer, INT32 Size, UINT8 a4) { return 0; }
UINT32 Tpm20TisReadResponse(INT32 a1, UINT8 *ResponseBuf, UINT32 *ResponseSize) { return 0; }
UINT32 Tpm20TisReadFifo(UINT8 *Dest, UINT32 Size) { return 0; }
INT32 Tpm20TisWaitReady(VOID) { return 0; }
INT32 Tpm20CmdReadyWait(VOID) { return 0; }
INT32 Tpm20BurstCountWait(VOID) { return 0; }
INT32 Tpm20TisTimeoutWait(INT32 Mode) { return 0; }
/*============================================================================
*SHA Internal Functions (stubs for algorithm implementations)
*============================================================================*/
INT32 Sha1UpdateInternal(INT32 a1, UINT8 *Src, UINT32 Size) { return 0; }
INT32 Sha1FinalInternal(VOID *Context, UINT8 *Digest) { return 0; }
INT32 Sha256FinalInternal(INT32 a1, UINT8 *Digest) { return 0; }
INT32 Sha256HashAll(UINT32 *Size, UINT8 *Digest) { return 0; }
INT32 Sha384UpdateInternal(UINT8 *a1, UINT8 *Src, UINT32 Size) { return 0; }
INT32 Sha384FinalInternal(INT32 a1, INT32 a2) { return 0; }
INT32 Sha1HashAllInternal(UINT32 Size, UINT8 *Digest) { return 0; }
INT32 Sha384HashAllInternal(INT32 a1, UINT32 Size, UINT8 *Digest) { return 0; }
INT32 Sha512HashAllInternal(INT32 a1, UINT32 Size, UINT8 *Digest) { return 0; }
/*The large SHA algorithm functions are located in .text at:
*Sha256Transform (0xFFE11A82, 10260 bytes)
*Sha256RoundConstants(0xFFE145F2, 3455 bytes)
*Sha1FinalInternal (0xFFE14375, 399 bytes)
*Sha384FinalInternal (0xFFE154A9, 273 bytes)
*These contain the raw SHA-1/SHA-256/SHA-384/SHA-512 algorithm implementations.
*/