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