Coverage Report

Created: 2025-08-03 06:18

/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 */