|
|
// 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; |
|
|
}
|
|
|
|