248 lines
8.1 KiB
C
248 lines
8.1 KiB
C
// 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"
|
||
//
|
||
//
|
||
// Functions
|
||
//
|
||
// CommandAuditPreInstall_Init()
|
||
//
|
||
// This function initializes the command audit list. This function is simulates the behavior of manufacturing. A
|
||
// function is used instead of a structure definition because this is easier than figuring out the initialization
|
||
// value for a bit array.
|
||
// This function would not be implemented outside of a manufacturing or simulation environment.
|
||
//
|
||
void
|
||
CommandAuditPreInstall_Init(
|
||
void
|
||
)
|
||
{
|
||
// Clear all the audit commands
|
||
MemorySet(gp.auditComands, 0x00,
|
||
((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8);
|
||
// TPM_CC_SetCommandCodeAuditStatus always being audited
|
||
if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus))
|
||
CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
|
||
// Set initial command audit hash algorithm to be context integrity hash
|
||
// algorithm
|
||
gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
|
||
// Set up audit counter to be 0
|
||
gp.auditCounter = 0;
|
||
// Write command audit persistent data to NV
|
||
NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
|
||
NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
|
||
NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
|
||
return;
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditStartup()
|
||
//
|
||
// This function clears the command audit digest on a TPM Reset.
|
||
//
|
||
void
|
||
CommandAuditStartup(
|
||
STARTUP_TYPE type // IN: start up type
|
||
)
|
||
{
|
||
if(type == SU_RESET)
|
||
{
|
||
// Reset the digest size to initialize the digest
|
||
gr.commandAuditDigest.t.size = 0;
|
||
}
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditSet()
|
||
//
|
||
// This function will SET the audit flag for a command. This function will not SET the audit flag for a
|
||
// command that is not implemented. This ensures that the audit status is not SET when
|
||
// TPM2_GetCapability() is used to read the list of audited commands.
|
||
// This function is only used by TPM2_SetCommandCodeAuditStatus().
|
||
// The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
|
||
// NV after it is setting and clearing bits.
|
||
//
|
||
// Return Value Meaning
|
||
//
|
||
// TRUE the command code audit status was changed
|
||
// FALSE the command code audit status was not changed
|
||
//
|
||
BOOL
|
||
CommandAuditSet(
|
||
TPM_CC commandCode // IN: command code
|
||
)
|
||
{
|
||
UINT32 bitPos;
|
||
// Only SET a bit if the corresponding command is implemented
|
||
if(CommandIsImplemented(commandCode))
|
||
{
|
||
// Can't audit shutdown
|
||
if(commandCode != TPM_CC_Shutdown)
|
||
{
|
||
bitPos = commandCode - TPM_CC_FIRST;
|
||
if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
|
||
{
|
||
// Set bit
|
||
BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
// No change
|
||
return FALSE;
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditClear()
|
||
//
|
||
// This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
|
||
// TPM_CC_SetCommandCodeAuditStatus().
|
||
// This function is only used by TPM2_SetCommandCodeAuditStatus().
|
||
// The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
|
||
// NV after it is setting and clearing bits.
|
||
//
|
||
//
|
||
//
|
||
// Return Value Meaning
|
||
//
|
||
// TRUE the command code audit status was changed
|
||
// FALSE the command code audit status was not changed
|
||
//
|
||
BOOL
|
||
CommandAuditClear(
|
||
TPM_CC commandCode // IN: command code
|
||
)
|
||
{
|
||
UINT32 bitPos;
|
||
// Do nothing if the command is not implemented
|
||
if(CommandIsImplemented(commandCode))
|
||
{
|
||
// The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
|
||
// cleared
|
||
if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
|
||
{
|
||
bitPos = commandCode - TPM_CC_FIRST;
|
||
if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
|
||
{
|
||
// Clear bit
|
||
BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
// No change
|
||
return FALSE;
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditIsRequired()
|
||
//
|
||
// This function indicates if the audit flag is SET for a command.
|
||
//
|
||
// Return Value Meaning
|
||
//
|
||
// TRUE if command is audited
|
||
// FALSE if command is not audited
|
||
//
|
||
BOOL
|
||
CommandAuditIsRequired(
|
||
TPM_CC commandCode // IN: command code
|
||
)
|
||
{
|
||
UINT32 bitPos;
|
||
bitPos = commandCode - TPM_CC_FIRST;
|
||
// Check the bit map. If the bit is SET, command audit is required
|
||
if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0)
|
||
return TRUE;
|
||
else
|
||
return FALSE;
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditCapGetCCList()
|
||
//
|
||
// This function returns a list of commands that have their audit bit SET.
|
||
// Family "2.0" TCG Published Page 111
|
||
// Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
|
||
// Trusted Platform Module Library Part 4: Supporting Routines
|
||
//
|
||
//
|
||
// The list starts at the input commandCode.
|
||
//
|
||
// Return Value Meaning
|
||
//
|
||
// YES if there are more command code available
|
||
// NO all the available command code has been returned
|
||
//
|
||
TPMI_YES_NO
|
||
CommandAuditCapGetCCList(
|
||
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;
|
||
// If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
|
||
if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
|
||
// Collect audit commands
|
||
for(i = commandCode; i <= TPM_CC_LAST; i++)
|
||
{
|
||
if(CommandAuditIsRequired(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 command
|
||
// available, report this and stop iterating
|
||
more = YES;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return more;
|
||
}
|
||
//
|
||
//
|
||
// CommandAuditGetDigest
|
||
//
|
||
// This command is used to create a digest of the commands being audited. The commands are processed
|
||
// in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the
|
||
// audited command codes were concatenated and then hashed.
|
||
//
|
||
void
|
||
CommandAuditGetDigest(
|
||
TPM2B_DIGEST *digest // OUT: command digest
|
||
)
|
||
{
|
||
TPM_CC i;
|
||
HASH_STATE hashState;
|
||
// Start hash
|
||
digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState);
|
||
// Add command code
|
||
for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
|
||
{
|
||
if(CommandAuditIsRequired(i))
|
||
{
|
||
CryptUpdateDigestInt(&hashState, sizeof(i), &i);
|
||
}
|
||
}
|
||
// Complete hash
|
||
CryptCompleteHash2B(&hashState, &digest->b);
|
||
return;
|
||
}
|