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