Home | History | Annotate | Download | only in tpm2
      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 //         PCRGetProperty()
     14 //
     15 //     This function accepts a property selection and, if so, sets value to the value of the property.
     16 //     All the fixed values are vendor dependent or determined by a platform-specific specification. The values
     17 //     in the table below are examples and should be changed by the vendor.
     18 //
     19 //     Return Value                      Meaning
     20 //
     21 //     TRUE                              referenced property exists and value set
     22 //     FALSE                             referenced property does not exist
     23 //
     24 static BOOL
     25 TPMPropertyIsDefined(
     26     TPM_PT               property,           // IN: property
     27     UINT32              *value               // OUT: property value
     28     )
     29 {
     30    switch(property)
     31    {
     32        case TPM_PT_FAMILY_INDICATOR:
     33            // from the title page of the specification
     34            // For this specification, the value is "2.0".
     35            *value = TPM_SPEC_FAMILY;
     36            break;
     37        case TPM_PT_LEVEL:
     38            // from the title page of the specification
     39            *value = TPM_SPEC_LEVEL;
     40            break;
     41        case TPM_PT_REVISION:
     42            // from the title page of the specification
     43            *value = TPM_SPEC_VERSION;
     44            break;
     45        case TPM_PT_DAY_OF_YEAR:
     46            // computed from the date value on the title page of the specification
     47            *value = TPM_SPEC_DAY_OF_YEAR;
     48            break;
     49        case TPM_PT_YEAR:
     50            // from the title page of the specification
     51            *value = TPM_SPEC_YEAR;
     52            break;
     53        case TPM_PT_MANUFACTURER:
     54            // vendor ID unique to each TPM manufacturer
     55            *value = BYTE_ARRAY_TO_UINT32(MANUFACTURER);
     56            break;
     57        case TPM_PT_VENDOR_STRING_1:
     58            // first four characters of the vendor ID string
     59            *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_1);
     60            break;
     61        case TPM_PT_VENDOR_STRING_2:
     62            // second four characters of the vendor ID string
     63 #ifdef VENDOR_STRING_2
     64            *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_2);
     65 #else
     66            *value = 0;
     67 #endif
     68            break;
     69        case TPM_PT_VENDOR_STRING_3:
     70            // third four characters of the vendor ID string
     71 #ifdef VENDOR_STRING_3
     72            *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_3);
     73 #else
     74            *value = 0;
     75 #endif
     76            break;
     77        case TPM_PT_VENDOR_STRING_4:
     78            // fourth four characters of the vendor ID string
     79 #ifdef VENDOR_STRING_4
     80            *value = BYTE_ARRAY_TO_UINT32(VENDOR_STRING_4);
     81 #else
     82            *value = 0;
     83 #endif
     84            break;
     85        case TPM_PT_VENDOR_TPM_TYPE:
     86            // vendor-defined value indicating the TPM model
     87            *value = 1;
     88            break;
     89        case TPM_PT_FIRMWARE_VERSION_1:
     90            // more significant 32-bits of a vendor-specific value
     91            *value = gp.firmwareV1;
     92            break;
     93        case TPM_PT_FIRMWARE_VERSION_2:
     94            // less significant 32-bits of a vendor-specific value
     95            *value = gp.firmwareV2;
     96            break;
     97        case TPM_PT_INPUT_BUFFER:
     98            // maximum size of TPM2B_MAX_BUFFER
     99            *value = MAX_DIGEST_BUFFER;
    100            break;
    101        case TPM_PT_HR_TRANSIENT_MIN:
    102            // minimum number of transient objects that can be held in TPM
    103            // RAM
    104            *value = MAX_LOADED_OBJECTS;
    105            break;
    106        case TPM_PT_HR_PERSISTENT_MIN:
    107            // minimum number of persistent objects that can be held in
    108            // TPM NV memory
    109            // In this implementation, there is no minimum number of
    110            // persistent objects.
    111            *value = MIN_EVICT_OBJECTS;
    112            break;
    113        case TPM_PT_HR_LOADED_MIN:
    114            // minimum number of authorization sessions that can be held in
    115            // TPM RAM
    116            *value = MAX_LOADED_SESSIONS;
    117            break;
    118        case TPM_PT_ACTIVE_SESSIONS_MAX:
    119            // number of authorization sessions that may be active at a time
    120            *value = MAX_ACTIVE_SESSIONS;
    121            break;
    122        case TPM_PT_PCR_COUNT:
    123            // number of PCR implemented
    124            *value = IMPLEMENTATION_PCR;
    125            break;
    126        case TPM_PT_PCR_SELECT_MIN:
    127            // minimum number of bytes in a TPMS_PCR_SELECT.sizeOfSelect
    128            *value = PCR_SELECT_MIN;
    129            break;
    130        case TPM_PT_CONTEXT_GAP_MAX:
    131            // maximum allowed difference (unsigned) between the contextID
    132            // values of two saved session contexts
    133            *value = (1 << (sizeof(CONTEXT_SLOT) * 8)) - 1;
    134             break;
    135         case TPM_PT_NV_COUNTERS_MAX:
    136             // maximum number of NV indexes that are allowed to have the
    137             // TPMA_NV_COUNTER attribute SET
    138             // In this implementation, there is no limitation on the number
    139             // of counters, except for the size of the NV Index memory.
    140             *value = 0;
    141             break;
    142         case TPM_PT_NV_INDEX_MAX:
    143             // maximum size of an NV index data area
    144             *value = MAX_NV_INDEX_SIZE;
    145             break;
    146         case TPM_PT_MEMORY:
    147             // a TPMA_MEMORY indicating the memory management method for the TPM
    148         {
    149             TPMA_MEMORY         attributes = {0};
    150             attributes.sharedNV = SET;
    151             attributes.objectCopiedToRam = SET;
    152              // Note: Different compilers may require a different method to cast
    153              // a bit field structure to a UINT32.
    154              memcpy(value, &attributes, sizeof(UINT32));
    155              break;
    156         }
    157         case TPM_PT_CLOCK_UPDATE:
    158             // interval, in seconds, between updates to the copy of
    159             // TPMS_TIME_INFO .clock in NV
    160             *value = (1 << NV_CLOCK_UPDATE_INTERVAL);
    161             break;
    162         case TPM_PT_CONTEXT_HASH:
    163             // algorithm used for the integrity hash on saved contexts and
    164             // for digesting the fuData of TPM2_FirmwareRead()
    165             *value = CONTEXT_INTEGRITY_HASH_ALG;
    166             break;
    167         case TPM_PT_CONTEXT_SYM:
    168             // algorithm used for encryption of saved contexts
    169             *value = CONTEXT_ENCRYPT_ALG;
    170             break;
    171         case TPM_PT_CONTEXT_SYM_SIZE:
    172             // size of the key used for encryption of saved contexts
    173             *value = CONTEXT_ENCRYPT_KEY_BITS;
    174             break;
    175         case TPM_PT_ORDERLY_COUNT:
    176             // maximum difference between the volatile and non-volatile
    177             // versions of TPMA_NV_COUNTER that have TPMA_NV_ORDERLY SET
    178             *value = MAX_ORDERLY_COUNT;
    179             break;
    180         case TPM_PT_MAX_COMMAND_SIZE:
    181             // maximum value for 'commandSize'
    182             *value = MAX_COMMAND_SIZE;
    183             break;
    184         case TPM_PT_MAX_RESPONSE_SIZE:
    185             // maximum value for 'responseSize'
    186             *value = MAX_RESPONSE_SIZE;
    187             break;
    188         case TPM_PT_MAX_DIGEST:
    189             // maximum size of a digest that can be produced by the TPM
    190             *value = sizeof(TPMU_HA);
    191             break;
    192         case TPM_PT_MAX_OBJECT_CONTEXT:
    193             // maximum size of a TPMS_CONTEXT that will be returned by
    194             // TPM2_ContextSave for object context
    195             *value = 0;
    196              // adding sequence, saved handle and hierarchy
    197              *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
    198                         sizeof(TPMI_RH_HIERARCHY);
    199               // add size field in TPM2B_CONTEXT
    200               *value += sizeof(UINT16);
    201               // add integrity hash size
    202               *value += sizeof(UINT16) +
    203                         CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
    204               // Add fingerprint size, which is the same as sequence size
    205               *value += sizeof(UINT64);
    206             // Add OBJECT structure size
    207             *value += sizeof(OBJECT);
    208             break;
    209         case TPM_PT_MAX_SESSION_CONTEXT:
    210             // the maximum size of a TPMS_CONTEXT that will be returned by
    211             // TPM2_ContextSave for object context
    212             *value = 0;
    213               // adding sequence, saved handle and hierarchy
    214               *value += sizeof(UINT64) + sizeof(TPMI_DH_CONTEXT) +
    215                         sizeof(TPMI_RH_HIERARCHY);
    216               // Add size field in TPM2B_CONTEXT
    217               *value += sizeof(UINT16);
    218               // Add integrity hash size
    219               *value += sizeof(UINT16) +
    220                         CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG);
    221               // Add fingerprint size, which is the same as sequence size
    222               *value += sizeof(UINT64);
    223            // Add SESSION structure size
    224            *value += sizeof(SESSION);
    225            break;
    226        case TPM_PT_PS_FAMILY_INDICATOR:
    227            // platform specific values for the TPM_PT_PS parameters from
    228            // the relevant platform-specific specification
    229            // In this reference implementation, all of these values are 0.
    230            *value = 0;
    231            break;
    232        case TPM_PT_PS_LEVEL:
    233            // level of the platform-specific specification
    234            *value = 0;
    235            break;
    236        case TPM_PT_PS_REVISION:
    237            // specification Revision times 100 for the platform-specific
    238            // specification
    239            *value = 0;
    240            break;
    241        case TPM_PT_PS_DAY_OF_YEAR:
    242            // platform-specific specification day of year using TCG calendar
    243            *value = 0;
    244            break;
    245        case TPM_PT_PS_YEAR:
    246            // platform-specific specification year using the CE
    247            *value = 0;
    248            break;
    249        case TPM_PT_SPLIT_MAX:
    250            // number of split signing operations supported by the TPM
    251            *value = 0;
    252    #ifdef TPM_ALG_ECC
    253            *value = sizeof(gr.commitArray) * 8;
    254    #endif
    255            break;
    256        case TPM_PT_TOTAL_COMMANDS:
    257            // total number of commands implemented in the TPM
    258              // Since the reference implementation does not have any
    259              // vendor-defined commands, this will be the same as the
    260              // number of library commands.
    261         {
    262              UINT32 i;
    263              *value = 0;
    264              // calculate implemented command numbers
    265              for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
    266              {
    267                  if(CommandIsImplemented(i)) (*value)++;
    268              }
    269              break;
    270         }
    271         case TPM_PT_LIBRARY_COMMANDS:
    272             // number of commands from the TPM library that are implemented
    273         {
    274             UINT32 i;
    275             *value = 0;
    276              // calculate implemented command numbers
    277              for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
    278              {
    279                  if(CommandIsImplemented(i)) (*value)++;
    280              }
    281              break;
    282         }
    283         case TPM_PT_VENDOR_COMMANDS:
    284             // number of vendor commands that are implemented
    285             *value = 0;
    286             break;
    287         case TPM_PT_PERMANENT:
    288             // TPMA_PERMANENT
    289         {
    290             TPMA_PERMANENT           flags = {0};
    291             if(gp.ownerAuth.t.size != 0)
    292                 flags.ownerAuthSet = SET;
    293             if(gp.endorsementAuth.t.size != 0)
    294                 flags.endorsementAuthSet = SET;
    295             if(gp.lockoutAuth.t.size != 0)
    296                 flags.lockoutAuthSet = SET;
    297             if(gp.disableClear)
    298                 flags.disableClear = SET;
    299             if(gp.failedTries >= gp.maxTries)
    300                 flags.inLockout = SET;
    301             // In this implementation, EPS is always generated by TPM
    302             flags.tpmGeneratedEPS = SET;
    303              // Note: Different compilers may require a different method to cast
    304              // a bit field structure to a UINT32.
    305              memcpy(value, &flags, sizeof(UINT32));
    306              break;
    307         }
    308         case TPM_PT_STARTUP_CLEAR:
    309             // TPMA_STARTUP_CLEAR
    310         {
    311             TPMA_STARTUP_CLEAR      flags = {0};
    312             if(g_phEnable)
    313                 flags.phEnable = SET;
    314             if(gc.shEnable)
    315                 flags.shEnable = SET;
    316             if(gc.ehEnable)
    317                 flags.ehEnable = SET;
    318             if(gc.phEnableNV)
    319                 flags.phEnableNV = SET;
    320             if(g_prevOrderlyState != SHUTDOWN_NONE)
    321                   flags.orderly = SET;
    322               // Note: Different compilers may require a different method to cast
    323               // a bit field structure to a UINT32.
    324               memcpy(value, &flags, sizeof(UINT32));
    325               break;
    326         }
    327         case TPM_PT_HR_NV_INDEX:
    328             // number of NV indexes currently defined
    329             *value = NvCapGetIndexNumber();
    330             break;
    331         case TPM_PT_HR_LOADED:
    332             // number of authorization sessions currently loaded into TPM
    333             // RAM
    334             *value = SessionCapGetLoadedNumber();
    335             break;
    336         case TPM_PT_HR_LOADED_AVAIL:
    337             // number of additional authorization sessions, of any type,
    338             // that could be loaded into TPM RAM
    339             *value = SessionCapGetLoadedAvail();
    340             break;
    341         case TPM_PT_HR_ACTIVE:
    342             // number of active authorization sessions currently being
    343             // tracked by the TPM
    344             *value = SessionCapGetActiveNumber();
    345             break;
    346         case TPM_PT_HR_ACTIVE_AVAIL:
    347             // number of additional authorization sessions, of any type,
    348             // that could be created
    349             *value = SessionCapGetActiveAvail();
    350             break;
    351         case TPM_PT_HR_TRANSIENT_AVAIL:
    352             // estimate of the number of additional transient objects that
    353             // could be loaded into TPM RAM
    354             *value = ObjectCapGetTransientAvail();
    355             break;
    356         case TPM_PT_HR_PERSISTENT:
    357             // number of persistent objects currently loaded into TPM
    358             // NV memory
    359             *value = NvCapGetPersistentNumber();
    360             break;
    361         case TPM_PT_HR_PERSISTENT_AVAIL:
    362             // number of additional persistent objects that could be loaded
    363             // into NV memory
    364             *value = NvCapGetPersistentAvail();
    365             break;
    366         case TPM_PT_NV_COUNTERS:
    367             // number of defined NV indexes that have NV TPMA_NV_COUNTER
    368             // attribute SET
    369             *value = NvCapGetCounterNumber();
    370             break;
    371         case TPM_PT_NV_COUNTERS_AVAIL:
    372             // number of additional NV indexes that can be defined with their
    373             // TPMA_NV_COUNTER attribute SET
    374             *value = NvCapGetCounterAvail();
    375             break;
    376         case TPM_PT_ALGORITHM_SET:
    377             // region code for the TPM
    378             *value = gp.algorithmSet;
    379             break;
    380        case TPM_PT_LOADED_CURVES:
    381    #ifdef TPM_ALG_ECC
    382            // number of loaded ECC curves
    383            *value = CryptCapGetEccCurveNumber();
    384    #else // TPM_ALG_ECC
    385              *value = 0;
    386      #endif // TPM_ALG_ECC
    387              break;
    388           case TPM_PT_LOCKOUT_COUNTER:
    389               // current value of the lockout counter
    390               *value = gp.failedTries;
    391               break;
    392           case TPM_PT_MAX_AUTH_FAIL:
    393               // number of authorization failures before DA lockout is invoked
    394               *value = gp.maxTries;
    395               break;
    396           case TPM_PT_LOCKOUT_INTERVAL:
    397               // number of seconds before the value reported by
    398               // TPM_PT_LOCKOUT_COUNTER is decremented
    399               *value = gp.recoveryTime;
    400               break;
    401           case TPM_PT_LOCKOUT_RECOVERY:
    402               // number of seconds after a lockoutAuth failure before use of
    403               // lockoutAuth may be attempted again
    404               *value = gp.lockoutRecovery;
    405               break;
    406           case TPM_PT_AUDIT_COUNTER_0:
    407               // high-order 32 bits of the command audit counter
    408               *value = (UINT32) (gp.auditCounter >> 32);
    409               break;
    410           case TPM_PT_AUDIT_COUNTER_1:
    411               // low-order 32 bits of the command audit counter
    412               *value = (UINT32) (gp.auditCounter);
    413               break;
    414           default:
    415               // property is not defined
    416               return FALSE;
    417               break;
    418      }
    419      return TRUE;
    420 }
    421 //
    422 //
    423 //           TPMCapGetProperties()
    424 //
    425 //      This function is used to get the TPM_PT values. The search of properties will start at property and
    426 //      continue until propertyList has as many values as will fit, or the last property has been reported, or the list
    427 //      has as many values as requested in count.
    428 //
    429 //      Return Value                      Meaning
    430 //
    431 //      YES                               more properties are available
    432 //      NO                                no more properties to be reported
    433 //
    434 TPMI_YES_NO
    435 TPMCapGetProperties(
    436      TPM_PT                              property,           // IN: the starting TPM property
    437      UINT32                              count,              // IN: maximum number of returned
    438                                                              //     propertie
    439      TPML_TAGGED_TPM_PROPERTY           *propertyList        // OUT: property list
    440      )
    441 {
    442      TPMI_YES_NO        more = NO;
    443      UINT32             i;
    444      // initialize output property list
    445      propertyList->count = 0;
    446       // maximum count of properties we may return is MAX_PCR_PROPERTIES
    447       if(count > MAX_TPM_PROPERTIES) count = MAX_TPM_PROPERTIES;
    448       // If property is less than PT_FIXED, start from PT_FIXED.
    449       if(property < PT_FIXED) property = PT_FIXED;
    450       // Scan through the TPM properties of the requested group.
    451       // The size of TPM property group is PT_GROUP * 2 for fix and
    452       // variable groups.
    453       for(i = property; i <= PT_FIXED + PT_GROUP * 2; i++)
    454       {
    455           UINT32          value;
    456           if(TPMPropertyIsDefined((TPM_PT) i, &value))
    457           {
    458               if(propertyList->count < count)
    459               {
    460                     // If the list is not full, add this property
    461                     propertyList->tpmProperty[propertyList->count].property =
    462                         (TPM_PT) i;
    463                     propertyList->tpmProperty[propertyList->count].value = value;
    464                     propertyList->count++;
    465               }
    466               else
    467               {
    468                   // If the return list is full but there are more properties
    469                   // available, set the indication and exit the loop.
    470                   more = YES;
    471                   break;
    472               }
    473           }
    474       }
    475       return more;
    476 }
    477