1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 4: Supporting Routines 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "InternalRoutines.h" 9 // 10 // 11 // Functions 12 // 13 // CommandAuditPreInstall_Init() 14 // 15 // This function initializes the command audit list. This function is simulates the behavior of manufacturing. A 16 // function is used instead of a structure definition because this is easier than figuring out the initialization 17 // value for a bit array. 18 // This function would not be implemented outside of a manufacturing or simulation environment. 19 // 20 void 21 CommandAuditPreInstall_Init( 22 void 23 ) 24 { 25 // Clear all the audit commands 26 MemorySet(gp.auditComands, 0x00, 27 ((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8); 28 // TPM_CC_SetCommandCodeAuditStatus always being audited 29 if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus)) 30 CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus); 31 // Set initial command audit hash algorithm to be context integrity hash 32 // algorithm 33 gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG; 34 // Set up audit counter to be 0 35 gp.auditCounter = 0; 36 // Write command audit persistent data to NV 37 NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands); 38 NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg); 39 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter); 40 return; 41 } 42 // 43 // 44 // CommandAuditStartup() 45 // 46 // This function clears the command audit digest on a TPM Reset. 47 // 48 void 49 CommandAuditStartup( 50 STARTUP_TYPE type // IN: start up type 51 ) 52 { 53 if(type == SU_RESET) 54 { 55 // Reset the digest size to initialize the digest 56 gr.commandAuditDigest.t.size = 0; 57 } 58 } 59 // 60 // 61 // CommandAuditSet() 62 // 63 // This function will SET the audit flag for a command. This function will not SET the audit flag for a 64 // command that is not implemented. This ensures that the audit status is not SET when 65 // TPM2_GetCapability() is used to read the list of audited commands. 66 // This function is only used by TPM2_SetCommandCodeAuditStatus(). 67 // The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to 68 // NV after it is setting and clearing bits. 69 // 70 // Return Value Meaning 71 // 72 // TRUE the command code audit status was changed 73 // FALSE the command code audit status was not changed 74 // 75 BOOL 76 CommandAuditSet( 77 TPM_CC commandCode // IN: command code 78 ) 79 { 80 UINT32 bitPos; 81 // Only SET a bit if the corresponding command is implemented 82 if(CommandIsImplemented(commandCode)) 83 { 84 // Can't audit shutdown 85 if(commandCode != TPM_CC_Shutdown) 86 { 87 bitPos = commandCode - TPM_CC_FIRST; 88 if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands))) 89 { 90 // Set bit 91 BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)); 92 return TRUE; 93 } 94 } 95 } 96 // No change 97 return FALSE; 98 } 99 // 100 // 101 // CommandAuditClear() 102 // 103 // This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for 104 // TPM_CC_SetCommandCodeAuditStatus(). 105 // This function is only used by TPM2_SetCommandCodeAuditStatus(). 106 // The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to 107 // NV after it is setting and clearing bits. 108 // 109 // 110 // 111 // Return Value Meaning 112 // 113 // TRUE the command code audit status was changed 114 // FALSE the command code audit status was not changed 115 // 116 BOOL 117 CommandAuditClear( 118 TPM_CC commandCode // IN: command code 119 ) 120 { 121 UINT32 bitPos; 122 // Do nothing if the command is not implemented 123 if(CommandIsImplemented(commandCode)) 124 { 125 // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be 126 // cleared 127 if(commandCode != TPM_CC_SetCommandCodeAuditStatus) 128 { 129 bitPos = commandCode - TPM_CC_FIRST; 130 if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands))) 131 { 132 // Clear bit 133 BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)); 134 return TRUE; 135 } 136 } 137 } 138 // No change 139 return FALSE; 140 } 141 // 142 // 143 // CommandAuditIsRequired() 144 // 145 // This function indicates if the audit flag is SET for a command. 146 // 147 // Return Value Meaning 148 // 149 // TRUE if command is audited 150 // FALSE if command is not audited 151 // 152 BOOL 153 CommandAuditIsRequired( 154 TPM_CC commandCode // IN: command code 155 ) 156 { 157 UINT32 bitPos; 158 bitPos = commandCode - TPM_CC_FIRST; 159 // Check the bit map. If the bit is SET, command audit is required 160 if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0) 161 return TRUE; 162 else 163 return FALSE; 164 } 165 // 166 // 167 // CommandAuditCapGetCCList() 168 // 169 // This function returns a list of commands that have their audit bit SET. 170 // Family "2.0" TCG Published Page 111 171 // Level 00 Revision 01.16 Copyright TCG 2006-2014 October 30, 2014 172 // Trusted Platform Module Library Part 4: Supporting Routines 174 // 175 // 176 // The list starts at the input commandCode. 177 // 178 // Return Value Meaning 179 // 180 // YES if there are more command code available 181 // NO all the available command code has been returned 182 // 183 TPMI_YES_NO 184 CommandAuditCapGetCCList( 185 TPM_CC commandCode, // IN: start command code 186 UINT32 count, // IN: count of returned TPM_CC 187 TPML_CC *commandList // OUT: list of TPM_CC 188 ) 189 { 190 TPMI_YES_NO more = NO; 191 UINT32 i; 192 // Initialize output handle list 193 commandList->count = 0; 194 // The maximum count of command we may return is MAX_CAP_CC 195 if(count > MAX_CAP_CC) count = MAX_CAP_CC; 196 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST 197 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST; 198 // Collect audit commands 199 for(i = commandCode; i <= TPM_CC_LAST; i++) 200 { 201 if(CommandAuditIsRequired(i)) 202 { 203 if(commandList->count < count) 204 { 205 // If we have not filled up the return list, add this command 206 // code to it 207 commandList->commandCodes[commandList->count] = i; 208 commandList->count++; 209 } 210 else 211 { 212 // If the return list is full but we still have command 213 // available, report this and stop iterating 214 more = YES; 215 break; 216 } 217 } 218 } 219 return more; 220 } 221 // 222 // 223 // CommandAuditGetDigest 224 // 225 // This command is used to create a digest of the commands being audited. The commands are processed 226 // in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the 227 // audited command codes were concatenated and then hashed. 228 // 229 void 230 CommandAuditGetDigest( 231 TPM2B_DIGEST *digest // OUT: command digest 232 ) 233 { 234 TPM_CC i; 235 HASH_STATE hashState; 236 // Start hash 237 digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState); 238 // Add command code 239 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++) 240 { 241 if(CommandAuditIsRequired(i)) 242 { 243 CryptUpdateDigestInt(&hashState, sizeof(i), &i); 244 } 245 } 246 // Complete hash 247 CryptCompleteHash2B(&hashState, &digest->b); 248 return; 249 } 250