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