/src/libtpms/src/tpm2/CommandCodeAttributes.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Functions for testing various command properties */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* */ |
7 | | /* Licenses and Notices */ |
8 | | /* */ |
9 | | /* 1. Copyright Licenses: */ |
10 | | /* */ |
11 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
12 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
13 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
14 | | /* derivative works, distribute, display and perform the Source Code and */ |
15 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
16 | | /* */ |
17 | | /* - The TCG grants to the user of the other parts of the specification */ |
18 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
19 | | /* display, and perform the specification solely for the purpose of */ |
20 | | /* developing products based on such documents. */ |
21 | | /* */ |
22 | | /* 2. Source Code Distribution Conditions: */ |
23 | | /* */ |
24 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
25 | | /* this list of conditions and the following disclaimers. */ |
26 | | /* */ |
27 | | /* - Redistributions in binary form must reproduce the above copyright */ |
28 | | /* licenses, this list of conditions and the following disclaimers in the */ |
29 | | /* documentation and/or other materials provided with the distribution. */ |
30 | | /* */ |
31 | | /* 3. Disclaimers: */ |
32 | | /* */ |
33 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
34 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
35 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
36 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
37 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
38 | | /* information on specification licensing rights available through TCG */ |
39 | | /* membership agreements. */ |
40 | | /* */ |
41 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
42 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
43 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
44 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
45 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
46 | | /* */ |
47 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
48 | | /* liability, including liability for infringement of any proprietary */ |
49 | | /* rights, relating to use of information in this specification and to the */ |
50 | | /* implementation of this specification, and TCG disclaims all liability for */ |
51 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
52 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
53 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
54 | | /* arising in any way out of use or reliance upon this specification or any */ |
55 | | /* information herein. */ |
56 | | /* */ |
57 | | /* (c) Copyright IBM Corp. and others, 2016 - 2023 */ |
58 | | /* */ |
59 | | /********************************************************************************/ |
60 | | |
61 | | //** Introduction |
62 | | // This file contains the functions for testing various command properties. |
63 | | |
64 | | //** Includes and Defines |
65 | | |
66 | | #include "Tpm.h" |
67 | | #include "CommandCodeAttributes_fp.h" |
68 | | |
69 | | // Set the default value for CC_VEND if not already set |
70 | | #ifndef CC_VEND |
71 | | # define CC_VEND (TPM_CC)(0x20000000) |
72 | | #endif |
73 | | |
74 | | typedef UINT16 ATTRIBUTE_TYPE; |
75 | | |
76 | | // The following file is produced from the command tables in part 3 of the |
77 | | // specification. It defines the attributes for each of the commands. |
78 | | // NOTE: This file is currently produced by an automated process. Files |
79 | | // produced from Part 2 or Part 3 tables through automated processes are not |
80 | | // included in the specification so that their is no ambiguity about the |
81 | | // table containing the information being the normative definition. |
82 | | #define _COMMAND_CODE_ATTRIBUTES_ |
83 | | #include "CommandAttributeData.h" |
84 | | |
85 | | //** Command Attribute Functions |
86 | | |
87 | | //*** NextImplementedIndex() |
88 | | // This function is used when the lists are not compressed. In a compressed list, |
89 | | // only the implemented commands are present. So, a search might find a value |
90 | | // but that value may not be implemented. This function checks to see if the input |
91 | | // commandIndex points to an implemented command and, if not, it searches upwards |
92 | | // until it finds one. When the list is compressed, this function gets defined |
93 | | // as a no-op. |
94 | | // Return Type: COMMAND_INDEX |
95 | | // UNIMPLEMENTED_COMMAND_INDEX command is not implemented |
96 | | // other index of the command |
97 | | #if !COMPRESSED_LISTS |
98 | | static COMMAND_INDEX NextImplementedIndex(COMMAND_INDEX commandIndex) |
99 | 110 | { |
100 | 144 | for(; commandIndex < COMMAND_COUNT; commandIndex++) |
101 | 139 | { |
102 | 139 | if((s_commandAttributes[commandIndex] & IS_IMPLEMENTED) && // libtpms changed |
103 | 139 | RuntimeCommandsCheckEnabled(&g_RuntimeProfile.RuntimeCommands, // libtpms added begin |
104 | 115 | GET_ATTRIBUTE(s_ccAttr[commandIndex], |
105 | 115 | TPMA_CC, commandIndex))) // libtpms added end |
106 | 105 | return commandIndex; |
107 | 139 | } |
108 | 5 | return UNIMPLEMENTED_COMMAND_INDEX; |
109 | 110 | } |
110 | | #else |
111 | | # define NextImplementedIndex(x) (x) |
112 | | #endif |
113 | | |
114 | | //*** GetClosestCommandIndex() |
115 | | // This function returns the command index for the command with a value that is |
116 | | // equal to or greater than the input value |
117 | | // Return Type: COMMAND_INDEX |
118 | | // UNIMPLEMENTED_COMMAND_INDEX command is not implemented |
119 | | // other index of a command |
120 | | COMMAND_INDEX |
121 | | GetClosestCommandIndex(TPM_CC commandCode // IN: the command code to start at |
122 | | ) |
123 | 1.73k | { |
124 | 1.73k | BOOL vendor = (commandCode & CC_VEND) != 0; |
125 | 1.73k | COMMAND_INDEX searchIndex = (COMMAND_INDEX)commandCode; |
126 | | |
127 | | // The commandCode is a UINT32 and the search index is UINT16. We are going to |
128 | | // search for a match but need to make sure that the commandCode value is not |
129 | | // out of range. To do this, need to clear the vendor bit of the commandCode |
130 | | // (if set) and compare the result to the 16-bit searchIndex value. If it is |
131 | | // out of range, indicate that the command is not implemented |
132 | 1.73k | if((commandCode & ~CC_VEND) != searchIndex) |
133 | 1.55k | return UNIMPLEMENTED_COMMAND_INDEX; |
134 | | |
135 | | // if there is at least one vendor command, the last entry in the array will |
136 | | // have the v bit set. If the input commandCode is larger than the last |
137 | | // vendor-command, then it is out of range. |
138 | 178 | if(vendor) |
139 | 64 | { |
140 | | #if VENDOR_COMMAND_ARRAY_SIZE > 0 |
141 | | COMMAND_INDEX commandIndex; |
142 | | COMMAND_INDEX min; |
143 | | COMMAND_INDEX max; |
144 | | int diff; |
145 | | # if LIBRARY_COMMAND_ARRAY_SIZE == COMMAND_COUNT |
146 | | # error "Constants are not consistent." |
147 | | # endif |
148 | | // Check to see if the value is equal to or below the minimum |
149 | | // entry. |
150 | | // Note: Put this check first so that the typical case of only one vendor- |
151 | | // specific command doesn't waste any more time. |
152 | | if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE], TPMA_CC, commandIndex) |
153 | | >= searchIndex) |
154 | | { |
155 | | // the vendor array is always assumed to be packed so there is |
156 | | // no need to check to see if the command is implemented |
157 | | return LIBRARY_COMMAND_ARRAY_SIZE; |
158 | | } |
159 | | // See if this is out of range on the top |
160 | | if(GET_ATTRIBUTE(s_ccAttr[COMMAND_COUNT - 1], TPMA_CC, commandIndex) |
161 | | < searchIndex) |
162 | | { |
163 | | return UNIMPLEMENTED_COMMAND_INDEX; |
164 | | } |
165 | | commandIndex = UNIMPLEMENTED_COMMAND_INDEX; // Needs initialization to keep |
166 | | // compiler happy |
167 | | min = LIBRARY_COMMAND_ARRAY_SIZE; // first vendor command |
168 | | max = COMMAND_COUNT - 1; // last vendor command |
169 | | diff = 1; // needs initialization to keep |
170 | | // compiler happy |
171 | | while(min <= max) |
172 | | { |
173 | | commandIndex = (min + max + 1) / 2; |
174 | | diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex) |
175 | | - searchIndex; |
176 | | if(diff == 0) |
177 | | return commandIndex; |
178 | | if(diff > 0) |
179 | | max = commandIndex - 1; |
180 | | else |
181 | | min = commandIndex + 1; |
182 | | } |
183 | | // didn't find and exact match. commandIndex will be pointing at the last |
184 | | // item tested. If 'diff' is positive, then the last item tested was |
185 | | // larger index of the command code so it is the smallest value |
186 | | // larger than the requested value. |
187 | | if(diff > 0) |
188 | | return commandIndex; |
189 | | // if 'diff' is negative, then the value tested was smaller than |
190 | | // the commandCode index and the next higher value is the correct one. |
191 | | // Note: this will necessarily be in range because of the earlier check |
192 | | // that the index was within range. |
193 | | return commandIndex + 1; |
194 | | #else |
195 | | // If there are no vendor commands so anything with the vendor bit set is out |
196 | | // of range |
197 | 64 | return UNIMPLEMENTED_COMMAND_INDEX; |
198 | 64 | #endif |
199 | 64 | } |
200 | | // Get here if the V-Bit was not set in 'commandCode' |
201 | | |
202 | 114 | if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1], TPMA_CC, commandIndex) |
203 | 114 | < searchIndex) |
204 | 4 | { |
205 | | // requested index is out of the range to the top |
206 | | #if VENDOR_COMMAND_ARRAY_SIZE > 0 |
207 | | // If there are vendor commands, then the first vendor command |
208 | | // is the next value greater than the commandCode. |
209 | | // NOTE: we got here if the starting index did not have the V bit but we |
210 | | // reached the end of the array of library commands (non-vendor). Since |
211 | | // there is at least one vendor command, and vendor commands are always |
212 | | // in a compressed list that starts after the library list, the next |
213 | | // index value contains a valid vendor command. |
214 | | return LIBRARY_COMMAND_ARRAY_SIZE; |
215 | | #else |
216 | | // if there are no vendor commands, then this is out of range |
217 | 4 | return UNIMPLEMENTED_COMMAND_INDEX; |
218 | 4 | #endif |
219 | 4 | } |
220 | | // If the request is lower than any value in the array, then return |
221 | | // the lowest value (needs to be an index for an implemented command |
222 | 110 | if(GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex) >= searchIndex) |
223 | 67 | { |
224 | 67 | return NextImplementedIndex(0); |
225 | 67 | } |
226 | 43 | else |
227 | 43 | { |
228 | | #if COMPRESSED_LISTS |
229 | | COMMAND_INDEX commandIndex = UNIMPLEMENTED_COMMAND_INDEX; |
230 | | COMMAND_INDEX min = 0; |
231 | | COMMAND_INDEX max = LIBRARY_COMMAND_ARRAY_SIZE - 1; |
232 | | int diff = 1; |
233 | | # if LIBRARY_COMMAND_ARRAY_SIZE == 0 |
234 | | # error "Something is terribly wrong" |
235 | | # endif |
236 | | // The s_ccAttr array contains an extra entry at the end (a zero value). |
237 | | // Don't count this as an array entry. This means that max should start |
238 | | // out pointing to the last valid entry in the array which is - 2 |
239 | | pAssert( |
240 | | max |
241 | | == (sizeof(s_ccAttr) / sizeof(TPMA_CC) - VENDOR_COMMAND_ARRAY_SIZE - 2)); |
242 | | while(min <= max) |
243 | | { |
244 | | commandIndex = (min + max + 1) / 2; |
245 | | diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex) |
246 | | - searchIndex; |
247 | | if(diff == 0) |
248 | | return commandIndex; |
249 | | if(diff > 0) |
250 | | max = commandIndex - 1; |
251 | | else |
252 | | min = commandIndex + 1; |
253 | | } |
254 | | // didn't find and exact match. commandIndex will be pointing at the |
255 | | // last item tested. If diff is positive, then the last item tested was |
256 | | // larger index of the command code so it is the smallest value |
257 | | // larger than the requested value. |
258 | | if(diff > 0) |
259 | | return commandIndex; |
260 | | // if diff is negative, then the value tested was smaller than |
261 | | // the commandCode index and the next higher value is the correct one. |
262 | | // Note: this will necessarily be in range because of the earlier check |
263 | | // that the index was within range. |
264 | | return commandIndex + 1; |
265 | | #else |
266 | | // The list is not compressed so offset into the array by the command |
267 | | // code value of the first entry in the list. Then go find the first |
268 | | // implemented command. |
269 | 43 | return NextImplementedIndex( |
270 | 43 | searchIndex - (COMMAND_INDEX)GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex)); // libtpms changed |
271 | 43 | #endif |
272 | 43 | } |
273 | 110 | } |
274 | | |
275 | | //*** CommandCodeToComandIndex() |
276 | | // This function returns the index in the various attributes arrays of the |
277 | | // command. |
278 | | // Return Type: COMMAND_INDEX |
279 | | // UNIMPLEMENTED_COMMAND_INDEX command is not implemented |
280 | | // other index of the command |
281 | | COMMAND_INDEX |
282 | | CommandCodeToCommandIndex(TPM_CC commandCode // IN: the command code to look up |
283 | | ) |
284 | 29.2k | { |
285 | | // Extract the low 16-bits of the command code to get the starting search index |
286 | 29.2k | COMMAND_INDEX searchIndex = (COMMAND_INDEX)commandCode; |
287 | 29.2k | BOOL vendor = (commandCode & CC_VEND) != 0; |
288 | 29.2k | COMMAND_INDEX commandIndex; |
289 | 29.2k | #if !COMPRESSED_LISTS |
290 | 29.2k | if(!vendor) |
291 | 27.7k | { |
292 | 27.7k | commandIndex = searchIndex - (COMMAND_INDEX)GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex); // libtpms changed |
293 | | // Check for out of range or unimplemented. |
294 | | // Note, since a COMMAND_INDEX is unsigned, if searchIndex is smaller than |
295 | | // the lowest value of command, it will become a 'negative' number making |
296 | | // it look like a large unsigned number, this will cause it to fail |
297 | | // the unsigned check below. |
298 | 27.7k | if(commandIndex >= LIBRARY_COMMAND_ARRAY_SIZE |
299 | 27.7k | || (s_commandAttributes[commandIndex] & IS_IMPLEMENTED) == 0 |
300 | 27.7k | || !RuntimeCommandsCheckEnabled(&g_RuntimeProfile.RuntimeCommands, // libtpms added |
301 | 24.0k | commandCode)) // libtpms added |
302 | 4.01k | return UNIMPLEMENTED_COMMAND_INDEX; |
303 | 23.6k | return commandIndex; |
304 | 27.7k | } |
305 | 1.56k | #endif |
306 | | // Need this code for any vendor code lookup or for compressed lists |
307 | 1.56k | commandIndex = GetClosestCommandIndex(commandCode); |
308 | | |
309 | | // Look at the returned value from get closest. If it isn't the one that was |
310 | | // requested, then the command is not implemented. |
311 | | // libtpms: Or it may be runtime-disabled |
312 | 1.56k | if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX) |
313 | 0 | { |
314 | 0 | if((GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex) |
315 | 0 | != searchIndex) |
316 | 0 | || (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) != vendor |
317 | 0 | || !RuntimeCommandsCheckEnabled(&g_RuntimeProfile.RuntimeCommands, // libtpms added |
318 | 0 | commandCode)) // libtpms added |
319 | 0 | commandIndex = UNIMPLEMENTED_COMMAND_INDEX; |
320 | 0 | } |
321 | 1.56k | return commandIndex; |
322 | 29.2k | } |
323 | | |
324 | | //*** GetNextCommandIndex() |
325 | | // This function returns the index of the next implemented command. |
326 | | // Return Type: COMMAND_INDEX |
327 | | // UNIMPLEMENTED_COMMAND_INDEX no more implemented commands |
328 | | // other the index of the next implemented command |
329 | | COMMAND_INDEX |
330 | | GetNextCommandIndex(COMMAND_INDEX commandIndex // IN: the starting index |
331 | | ) |
332 | 7.29k | { |
333 | 8.76k | while(++commandIndex < COMMAND_COUNT) |
334 | 8.67k | { |
335 | 8.67k | if(!RuntimeCommandsCheckEnabled(&g_RuntimeProfile.RuntimeCommands, // libtpms added begin |
336 | 8.67k | GET_ATTRIBUTE(s_ccAttr[commandIndex], |
337 | 8.67k | TPMA_CC, commandIndex))) |
338 | 1.46k | continue; // libtpms added end |
339 | 7.20k | #if !COMPRESSED_LISTS |
340 | 7.20k | if(s_commandAttributes[commandIndex] & IS_IMPLEMENTED) |
341 | 7.20k | #endif |
342 | 7.20k | return commandIndex; |
343 | 7.20k | } |
344 | 88 | return UNIMPLEMENTED_COMMAND_INDEX; |
345 | 7.29k | } |
346 | | |
347 | | //*** GetCommandCode() |
348 | | // This function returns the commandCode associated with the command index |
349 | | TPM_CC |
350 | | GetCommandCode(COMMAND_INDEX commandIndex // IN: the command index |
351 | | ) |
352 | 10 | { |
353 | 10 | TPM_CC commandCode = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex); |
354 | 10 | if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) |
355 | 0 | commandCode += CC_VEND; |
356 | 10 | return commandCode; |
357 | 10 | } |
358 | | |
359 | | //*** CommandAuthRole() |
360 | | // |
361 | | // This function returns the authorization role required of a handle. |
362 | | // |
363 | | // Return Type: AUTH_ROLE |
364 | | // AUTH_NONE no authorization is required |
365 | | // AUTH_USER user role authorization is required |
366 | | // AUTH_ADMIN admin role authorization is required |
367 | | // AUTH_DUP duplication role authorization is required |
368 | | AUTH_ROLE |
369 | | CommandAuthRole(COMMAND_INDEX commandIndex, // IN: command index |
370 | | UINT32 handleIndex // IN: handle index (zero based) |
371 | | ) |
372 | 3.66k | { |
373 | 3.66k | if(0 == handleIndex) |
374 | 3.56k | { |
375 | | // Any authorization role set? |
376 | 3.56k | COMMAND_ATTRIBUTES properties = s_commandAttributes[commandIndex]; |
377 | | |
378 | 3.56k | if(properties & HANDLE_1_USER) |
379 | 3.50k | return AUTH_USER; |
380 | 59 | if(properties & HANDLE_1_ADMIN) |
381 | 0 | return AUTH_ADMIN; |
382 | 59 | if(properties & HANDLE_1_DUP) |
383 | 0 | return AUTH_DUP; |
384 | 59 | } |
385 | 97 | else if(1 == handleIndex) |
386 | 97 | { |
387 | 97 | if(s_commandAttributes[commandIndex] & HANDLE_2_USER) |
388 | 1 | return AUTH_USER; |
389 | 97 | } |
390 | 155 | return AUTH_NONE; |
391 | 3.66k | } |
392 | | |
393 | | //*** EncryptSize() |
394 | | // This function returns the size of the decrypt size field. This function returns |
395 | | // 0 if encryption is not allowed |
396 | | // Return Type: int |
397 | | // 0 encryption not allowed |
398 | | // 2 size field is two bytes |
399 | | // 4 size field is four bytes |
400 | | int EncryptSize(COMMAND_INDEX commandIndex // IN: command index |
401 | | ) |
402 | 0 | { |
403 | 0 | return ((s_commandAttributes[commandIndex] & ENCRYPT_2) ? 2 |
404 | 0 | : (s_commandAttributes[commandIndex] & ENCRYPT_4) ? 4 |
405 | 0 | : 0); |
406 | 0 | } |
407 | | |
408 | | //*** DecryptSize() |
409 | | // This function returns the size of the decrypt size field. This function returns |
410 | | // 0 if decryption is not allowed |
411 | | // Return Type: int |
412 | | // 0 encryption not allowed |
413 | | // 2 size field is two bytes |
414 | | // 4 size field is four bytes |
415 | | int DecryptSize(COMMAND_INDEX commandIndex // IN: command index |
416 | | ) |
417 | 0 | { |
418 | 0 | return ((s_commandAttributes[commandIndex] & DECRYPT_2) ? 2 |
419 | 0 | : (s_commandAttributes[commandIndex] & DECRYPT_4) ? 4 |
420 | 0 | : 0); |
421 | 0 | } |
422 | | |
423 | | //*** IsSessionAllowed() |
424 | | // |
425 | | // This function indicates if the command is allowed to have sessions. |
426 | | // |
427 | | // This function must not be called if the command is not known to be implemented. |
428 | | // |
429 | | // Return Type: BOOL |
430 | | // TRUE(1) session is allowed with this command |
431 | | // FALSE(0) session is not allowed with this command |
432 | | BOOL IsSessionAllowed(COMMAND_INDEX commandIndex // IN: the command to be checked |
433 | | ) |
434 | 11.8k | { |
435 | 11.8k | return ((s_commandAttributes[commandIndex] & NO_SESSIONS) == 0); |
436 | 11.8k | } |
437 | | |
438 | | //*** IsHandleInResponse() |
439 | | // This function determines if a command has a handle in the response |
440 | | BOOL IsHandleInResponse(COMMAND_INDEX commandIndex) |
441 | 12.3k | { |
442 | 12.3k | return ((s_commandAttributes[commandIndex] & R_HANDLE) != 0); |
443 | 12.3k | } |
444 | | |
445 | | //*** IsWriteOperation() |
446 | | // Checks to see if an operation will write to an NV Index and is subject to being |
447 | | // blocked by read-lock |
448 | | BOOL IsWriteOperation(COMMAND_INDEX commandIndex // IN: Command to check |
449 | | ) |
450 | 0 | { |
451 | | #ifdef WRITE_LOCK |
452 | | return ((s_commandAttributes[commandIndex] & WRITE_LOCK) != 0); |
453 | | #else |
454 | 0 | if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) |
455 | 0 | { |
456 | 0 | switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)) |
457 | 0 | { |
458 | 0 | case TPM_CC_NV_Write: |
459 | 0 | # if CC_NV_Increment |
460 | 0 | case TPM_CC_NV_Increment: |
461 | 0 | # endif |
462 | 0 | # if CC_NV_SetBits |
463 | 0 | case TPM_CC_NV_SetBits: |
464 | 0 | # endif |
465 | 0 | # if CC_NV_Extend |
466 | 0 | case TPM_CC_NV_Extend: |
467 | 0 | # endif |
468 | | # if CC_AC_Send |
469 | | case TPM_CC_AC_Send: |
470 | | # endif |
471 | | // NV write lock counts as a write operation for authorization purposes. |
472 | | // We check to see if the NV is write locked before we do the |
473 | | // authorization. If it is locked, we fail the command early. |
474 | 0 | case TPM_CC_NV_WriteLock: |
475 | 0 | return TRUE; |
476 | 0 | default: |
477 | 0 | break; |
478 | 0 | } |
479 | 0 | } |
480 | 0 | return FALSE; |
481 | 0 | #endif |
482 | 0 | } |
483 | | |
484 | | //*** IsReadOperation() |
485 | | // Checks to see if an operation will write to an NV Index and is |
486 | | // subject to being blocked by write-lock. |
487 | | BOOL IsReadOperation(COMMAND_INDEX commandIndex // IN: Command to check |
488 | | ) |
489 | 0 | { |
490 | | #ifdef READ_LOCK |
491 | | return ((s_commandAttributes[commandIndex] & READ_LOCK) != 0); |
492 | | #else |
493 | |
|
494 | 0 | if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) |
495 | 0 | { |
496 | 0 | switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)) |
497 | 0 | { |
498 | 0 | case TPM_CC_NV_Read: |
499 | 0 | case TPM_CC_PolicyNV: |
500 | 0 | case TPM_CC_NV_Certify: |
501 | | // NV read lock counts as a read operation for authorization purposes. |
502 | | // We check to see if the NV is read locked before we do the |
503 | | // authorization. If it is locked, we fail the command early. |
504 | 0 | case TPM_CC_NV_ReadLock: |
505 | 0 | return TRUE; |
506 | 0 | default: |
507 | 0 | break; |
508 | 0 | } |
509 | 0 | } |
510 | 0 | return FALSE; |
511 | 0 | #endif |
512 | 0 | } |
513 | | |
514 | | //*** CommandCapGetCCList() |
515 | | // This function returns a list of implemented commands and command attributes |
516 | | // starting from the command in 'commandCode'. |
517 | | // Return Type: TPMI_YES_NO |
518 | | // YES more command attributes are available |
519 | | // NO no more command attributes are available |
520 | | TPMI_YES_NO |
521 | | CommandCapGetCCList(TPM_CC commandCode, // IN: start command code |
522 | | UINT32 count, // IN: maximum count for number of entries in |
523 | | // 'commandList' |
524 | | TPML_CCA* commandList // OUT: list of TPMA_CC |
525 | | ) |
526 | 45 | { |
527 | 45 | TPMI_YES_NO more = NO; |
528 | 45 | COMMAND_INDEX commandIndex; |
529 | | |
530 | | // initialize output handle list count |
531 | 45 | commandList->count = 0; |
532 | | |
533 | 45 | for(commandIndex = GetClosestCommandIndex(commandCode); |
534 | 2.77k | commandIndex != UNIMPLEMENTED_COMMAND_INDEX; |
535 | 2.73k | commandIndex = GetNextCommandIndex(commandIndex)) |
536 | 2.74k | { |
537 | 2.74k | #if !COMPRESSED_LISTS |
538 | | // this check isn't needed for compressed lists. |
539 | 2.74k | if(!(s_commandAttributes[commandIndex] & IS_IMPLEMENTED)) |
540 | 0 | continue; |
541 | 2.74k | #endif |
542 | 2.74k | if (!RuntimeCommandsCheckEnabled(&g_RuntimeProfile.RuntimeCommands, // libtpms added begin |
543 | 2.74k | GET_ATTRIBUTE(s_ccAttr[commandIndex], |
544 | 2.74k | TPMA_CC, commandIndex))) |
545 | 0 | continue; // libtpms added end |
546 | 2.74k | if(commandList->count < count) |
547 | 2.73k | { |
548 | | // If the list is not full, add the attributes for this command. |
549 | 2.73k | commandList->commandAttributes[commandList->count] = |
550 | 2.73k | s_ccAttr[commandIndex]; |
551 | 2.73k | commandList->count++; |
552 | 2.73k | } |
553 | 13 | else |
554 | 13 | { |
555 | | // If the list is full but there are more commands to report, |
556 | | // indicate this and return. |
557 | 13 | more = YES; |
558 | 13 | break; |
559 | 13 | } |
560 | 2.74k | } |
561 | 45 | return more; |
562 | 45 | } |
563 | | |
564 | | //*** CommandCapGetOneCC() |
565 | | // This function checks whether a command is implemented, and returns its |
566 | | // attributes if so. |
567 | | BOOL CommandCapGetOneCC(TPM_CC commandCode, // IN: command code |
568 | | TPMA_CC* commandAttributes // OUT: command attributes |
569 | | ) |
570 | 0 | { |
571 | 0 | COMMAND_INDEX commandIndex = CommandCodeToCommandIndex(commandCode); |
572 | 0 | if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX) |
573 | 0 | { |
574 | 0 | *commandAttributes = s_ccAttr[commandIndex]; |
575 | 0 | return TRUE; |
576 | 0 | } |
577 | 0 | return FALSE; |
578 | 0 | } |
579 | | #if 0 /* libtpms added */ |
580 | | |
581 | | //*** IsVendorCommand() |
582 | | // Function indicates if a command index references a vendor command. |
583 | | // Return Type: BOOL |
584 | | // TRUE(1) command is a vendor command |
585 | | // FALSE(0) command is not a vendor command |
586 | | BOOL IsVendorCommand(COMMAND_INDEX commandIndex // IN: command index to check |
587 | | ) |
588 | | { |
589 | | return (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)); |
590 | | } |
591 | | #endif /* libtpms added */ |