blob: 1491d423d118e9df334ff3cc24f8a0b7836501e4 [file] [log] [blame]
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014
#include "InternalRoutines.h"
#include "PP_fp.h"
//
//
// Functions
//
// PhysicalPresencePreInstall_Init()
//
// This function is used to initialize the array of commands that require confirmation with physical presence.
// The array is an array of bits that has a correspondence with the command code.
// This command should only ever be executable in a manufacturing setting or in a simulation.
//
void
PhysicalPresencePreInstall_Init(
void
)
{
// Clear all the PP commands
MemorySet(&gp.ppList, 0,
//
((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8);
// TPM_CC_PP_Commands always requires PP
if(CommandIsImplemented(TPM_CC_PP_Commands))
PhysicalPresenceCommandSet(TPM_CC_PP_Commands);
// Write PP list to NV
NvWriteReserved(NV_PP_LIST, &gp.ppList);
return;
}
//
//
// PhysicalPresenceCommandSet()
//
// This function is used to indicate a command that requires PP confirmation.
//
void
PhysicalPresenceCommandSet(
TPM_CC commandCode // IN: command code
)
{
UINT32 bitPos;
// Assume command is implemented. It should be checked before this
// function is called
pAssert(CommandIsImplemented(commandCode));
// If the command is not a PP command, ignore it
if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
return;
bitPos = commandCode - TPM_CC_PP_FIRST;
// Set bit
gp.ppList[bitPos/8] |= 1 << (bitPos % 8);
return;
}
//
//
// PhysicalPresenceCommandClear()
//
// This function is used to indicate a command that no longer requires PP confirmation.
//
void
PhysicalPresenceCommandClear(
TPM_CC commandCode // IN: command code
)
{
UINT32 bitPos;
// Assume command is implemented. It should be checked before this
// function is called
pAssert(CommandIsImplemented(commandCode));
// If the command is not a PP command, ignore it
if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
return;
// if the input code is TPM_CC_PP_Commands, it can not be cleared
if(commandCode == TPM_CC_PP_Commands)
return;
bitPos = commandCode - TPM_CC_PP_FIRST;
// Set bit
gp.ppList[bitPos/8] |= (1 << (bitPos % 8));
// Flip it to off
gp.ppList[bitPos/8] ^= (1 << (bitPos % 8));
return;
}
//
//
// PhysicalPresenceIsRequired()
//
// This function indicates if PP confirmation is required for a command.
//
// Return Value Meaning
//
// TRUE if physical presence is required
// FALSE if physical presence is not required
//
BOOL
PhysicalPresenceIsRequired(
TPM_CC commandCode // IN: command code
)
{
UINT32 bitPos;
// if the input commandCode is not a PP command, return FALSE
if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
return FALSE;
bitPos = commandCode - TPM_CC_PP_FIRST;
// Check the bit map. If the bit is SET, PP authorization is required
return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0);
}
//
//
// PhysicalPresenceCapGetCCList()
//
// This function returns a list of commands that require PP confirmation. The list starts from the first
// implemented command that has a command code that the same or greater than commandCode.
//
// Return Value Meaning
//
// YES if there are more command codes available
// NO all the available command codes have been returned
//
TPMI_YES_NO
PhysicalPresenceCapGetCCList(
TPM_CC commandCode, // IN: start command code
UINT32 count, // IN: count of returned TPM_CC
TPML_CC *commandList // OUT: list of TPM_CC
)
{
TPMI_YES_NO more = NO;
UINT32 i;
// Initialize output handle list
commandList->count = 0;
// The maximum count of command we may return is MAX_CAP_CC
if(count > MAX_CAP_CC) count = MAX_CAP_CC;
// Collect PP commands
for(i = commandCode; i <= TPM_CC_PP_LAST; i++)
{
if(PhysicalPresenceIsRequired(i))
{
if(commandList->count < count)
{
// If we have not filled up the return list, add this command
// code to it
commandList->commandCodes[commandList->count] = i;
commandList->count++;
}
else
{
// If the return list is full but we still have PP command
// available, report this and stop iterating
more = YES;
break;
}
}
}
return more;
}