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 #define PCR_C
      9 #include "InternalRoutines.h"
     10 #include "Platform.h"
     11 //
     12 //      The initial value of PCR attributes. The value of these fields should be consistent with PC Client
     13 //      specification In this implementation, we assume the total number of implemented PCR is 24.
     14 //
     15 static const PCR_Attributes s_initAttributes[] =
     16 {
     17     // PCR    0 - 15, static RTM
     18     {1, 0,    0x1F}, {1, 0, 0x1F},     {1,   0,    0x1F},   {1,   0,   0x1F},
     19     {1, 0,    0x1F}, {1, 0, 0x1F},     {1,   0,    0x1F},   {1,   0,   0x1F},
     20     {1, 0,    0x1F}, {1, 0, 0x1F},     {1,   0,    0x1F},   {1,   0,   0x1F},
     21     {1, 0,    0x1F}, {1, 0, 0x1F},     {1,   0,    0x1F},   {1,   0,   0x1F},
     22     {0,   0x0F,   0x1F},         //   PCR    16,   Debug
     23     {0,   0x10,   0x1C},         //   PCR    17,   Locality 4
     24     {0,   0x10,   0x1C},         //   PCR    18,   Locality 3
     25     {0,   0x10,   0x0C},         //   PCR    19,   Locality 2
     26     {0,   0x1C,   0x0E},         //   PCR    20,   Locality 1
     27     {0,   0x1C,   0x04},         //   PCR    21,   Dynamic OS
     28     {0,   0x1C,   0x04},         //   PCR    22,   Dynamic OS
     29     {0,   0x0F,   0x1F},         //   PCR    23,   App specific
     30     {0,   0x0F,   0x1F}          //   PCR    24,   testing policy
     31 };
     32 //
     33 //
     34 //           Functions
     35 //
     36 //          PCRBelongsAuthGroup()
     37 //
     38 //     This function indicates if a PCR belongs to a group that requires an authValue in order to modify the
     39 //     PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the
     40 //     platform specification.
     41 //
     42 //     Return Value                    Meaning
     43 //
     44 //     TRUE:                           PCR belongs an auth group
     45 //     FALSE:                          PCR does not belong an auth group
     46 //
     47 BOOL
     48 PCRBelongsAuthGroup(
     49     TPMI_DH_PCR          handle,              // IN: handle of PCR
     50     UINT32              *groupIndex           // OUT: group index if PCR belongs a
     51                                               //      group that allows authValue. If PCR
     52                                               //      does not belong to an auth group,
     53                                               //      the value in this parameter is
     54                                               //      invalid
     55 )
     56 {
     57   // None of the PCRs belong to a group requiring an authValue, as defined in
     58   // Table 4 "PCR Attributes" of the "TCG PC Client Platform TPM Profile (TPT)
     59   // Specification Level 00 Revision 00.43".
     60   return FALSE;
     61 }
     62 //
     63 //
     64 //          PCRBelongsPolicyGroup()
     65 //
     66 //     This function indicates if a PCR belongs to a group that requires a policy authorization in order to modify
     67 //     the PCR. If it does, groupIndex is set to value of the group index. This feature of PCR is decided by the
     68 //     platform specification.
     69 //     Family "2.0"                                   TCG Published                                          Page 169
     70 //     Level 00 Revision 01.16                Copyright  TCG 2006-2014                             October 30, 2014
     71 //     Trusted Platform Module Library                                          Part 4: Supporting Routines
     73 //
     74 //
     75 //     Return Value                      Meaning
     76 //
     77 //     TRUE:                             PCR belongs a policy group
     78 //     FALSE:                            PCR does not belong a policy group
     79 //
     80 BOOL
     81 PCRBelongsPolicyGroup(
     82     TPMI_DH_PCR           handle,            // IN: handle of PCR
     83     UINT32               *groupIndex         // OUT: group index if PCR belongs a group that
     84                                              //     allows policy. If PCR does not belong to
     85                                              //     a policy group, the value in this
     86                                              //     parameter is invalid
     87    )
     88 {
     89   // None of the PCRs belong to the policy group, as defined in Table 4
     90   // "PCR Attributes" of the "TCG PC Client Platform TPM Profile (TPT)
     91   // Specification Level 00 Revision 00.43".
     92   return FALSE;
     93 }
     94 //
     95 //
     96 //           PCRBelongsTCBGroup()
     97 //
     98 //     This function indicates if a PCR belongs to the TCB group.
     99 //
    100 //     Return Value                      Meaning
    101 //
    102 //     TRUE:                             PCR belongs to TCB group
    103 //     FALSE:                            PCR does not belong to TCB group
    104 //
    105 static BOOL
    106 PCRBelongsTCBGroup(
    107     TPMI_DH_PCR           handle             // IN: handle of PCR
    108     )
    109 {
    110 #if ENABLE_PCR_NO_INCREMENT == YES
    111   // Platform specification decides if a PCR belongs to a TCB group. In this
    112   // implementation, we assume PCR[16, 21-23] belong to TCB group as defined
    113   // in Table 4. If the platform specification requires differently, the
    114   // implementation should be changed accordingly
    115   if(handle == 16 || (handle >= 21 && handle <= 23))
    116     return TRUE;
    117 #endif
    118    return FALSE;
    119 }
    120 //
    121 //
    122 //           PCRPolicyIsAvailable()
    123 //
    124 //     This function indicates if a policy is available for a PCR.
    125 //
    126 //
    127 //
    128 //
    129 //      Return Value                     Meaning
    130 //
    131 //      TRUE                             the PCR should be authorized by policy
    132 //      FALSE                            the PCR does not allow policy
    133 //
    134 BOOL
    135 PCRPolicyIsAvailable(
    136     TPMI_DH_PCR          handle             // IN: PCR handle
    137     )
    138 {
    139     UINT32              groupIndex;
    140     return PCRBelongsPolicyGroup(handle, &groupIndex);
    141 }
    142 //
    143 //
    144 //           PCRGetAuthValue()
    145 //
    146 //      This function is used to access the authValue of a PCR. If PCR does not belong to an authValue group,
    147 //      an Empty Auth will be returned.
    148 //
    149 void
    150 PCRGetAuthValue(
    151     TPMI_DH_PCR          handle,            // IN: PCR handle
    152     TPM2B_AUTH          *auth               // OUT: authValue of PCR
    153     )
    154 {
    155     UINT32         groupIndex;
    156     if(PCRBelongsAuthGroup(handle, &groupIndex))
    157     {
    158         *auth = gc.pcrAuthValues.auth[groupIndex];
    159     }
    160     else
    161     {
    162         auth->t.size = 0;
    163     }
    164     return;
    165 }
    166 //
    167 //
    168 //           PCRGetAuthPolicy()
    169 //
    170 //      This function is used to access the authorization policy of a PCR. It sets policy to the authorization policy
    171 //      and returns the hash algorithm for policy If the PCR does not allow a policy, TPM_ALG_NULL is returned.
    172 //
    173 TPMI_ALG_HASH
    174 PCRGetAuthPolicy(
    175     TPMI_DH_PCR          handle,            // IN: PCR handle
    176     TPM2B_DIGEST        *policy             // OUT: policy of PCR
    177     )
    178 {
    179     UINT32               groupIndex;
    180     if(PCRBelongsPolicyGroup(handle, &groupIndex))
    181     {
    182         *policy = gp.pcrPolicies.policy[groupIndex];
    183         return gp.pcrPolicies.hashAlg[groupIndex];
    184     }
    185     else
    186     {
    187         policy->t.size = 0;
    188           return TPM_ALG_NULL;
    189    }
    190 }
    191 //
    192 //
    193 //            PCRSimStart()
    194 //
    195 //      This function is used to initialize the policies when a TPM is manufactured. This function would only be
    196 //      called in a manufacturing environment or in a TPM simulator.
    197 //
    198 void
    199 PCRSimStart(
    200    void
    201    )
    202 {
    203    UINT32 i;
    204    for(i = 0; i < NUM_POLICY_PCR_GROUP; i++)
    205    {
    206        gp.pcrPolicies.hashAlg[i] = TPM_ALG_NULL;
    207        gp.pcrPolicies.policy[i].t.size = 0;
    208    }
    209    for(i = 0; i < NUM_AUTHVALUE_PCR_GROUP; i++)
    210    {
    211        gc.pcrAuthValues.auth[i].t.size = 0;
    212    }
    213    // We need to give an initial configuration on allocated PCR before
    214    // receiving any TPM2_PCR_Allocate command to change this configuration
    215    // When the simulation environment starts, we allocate all the PCRs
    216    for(gp.pcrAllocated.count = 0; gp.pcrAllocated.count < HASH_COUNT;
    217            gp.pcrAllocated.count++)
    218    {
    219        gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].hash
    220            = CryptGetHashAlgByIndex(gp.pcrAllocated.count);
    221           gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].sizeofSelect
    222               = PCR_SELECT_MAX;
    223           for(i = 0; i < PCR_SELECT_MAX; i++)
    224               gp.pcrAllocated.pcrSelections[gp.pcrAllocated.count].pcrSelect[i]
    225                   = 0xFF;
    226    }
    227    // Store the initial configuration to NV
    228    NvWriteReserved(NV_PCR_POLICIES, &gp.pcrPolicies);
    229    NvWriteReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated);
    230    return;
    231 }
    232 //
    233 //
    234 //            GetSavedPcrPointer()
    235 //
    236 //      This function returns the address of an array of state saved PCR based on the hash algorithm.
    237 //
    238 //      Return Value                      Meaning
    239 //
    240 //      NULL                              no such algorithm
    241 //      not NULL                          pointer to the 0th byte of the 0th PCR
    242 //
    243 static BYTE *
    244 GetSavedPcrPointer (
    245    TPM_ALG_ID           alg,                 // IN: algorithm for bank
    246    UINT32               pcrIndex             // IN: PCR index in PCR_SAVE
    247     )
    248 {
    249    switch(alg)
    250    {
    251 #ifdef TPM_ALG_SHA1
    252    case TPM_ALG_SHA1:
    253        return gc.pcrSave.sha1[pcrIndex];
    254        break;
    255 #endif
    256 #ifdef TPM_ALG_SHA256
    257    case TPM_ALG_SHA256:
    258        return gc.pcrSave.sha256[pcrIndex];
    259        break;
    260 #endif
    261 #ifdef TPM_ALG_SHA384
    262    case TPM_ALG_SHA384:
    263        return gc.pcrSave.sha384[pcrIndex];
    264        break;
    265 #endif
    266 #ifdef TPM_ALG_SHA512
    267    case TPM_ALG_SHA512:
    268        return gc.pcrSave.sha512[pcrIndex];
    269        break;
    270 #endif
    271 #ifdef TPM_ALG_SM3_256
    272    case TPM_ALG_SM3_256:
    273        return gc.pcrSave.sm3_256[pcrIndex];
    274        break;
    275 #endif
    276    default:
    277        FAIL(FATAL_ERROR_INTERNAL);
    278    }
    279    return NULL; // Never reached.
    280 }
    281 //
    282 //
    283 //           PcrIsAllocated()
    284 //
    285 //      This function indicates if a PCR number for the particular hash algorithm is allocated.
    286 //
    287 //      Return Value                     Meaning
    288 //
    289 //      FALSE                            PCR is not allocated
    290 //      TRUE                             PCR is allocated
    291 //
    292 BOOL
    293 PcrIsAllocated (
    294     UINT32               pcr,               // IN: The number of the PCR
    295     TPMI_ALG_HASH        hashAlg            // IN: The PCR algorithm
    296     )
    297 {
    298     UINT32                    i;
    299     BOOL                      allocated = FALSE;
    300     if(pcr < IMPLEMENTATION_PCR)
    301     {
    302          for(i = 0; i < gp.pcrAllocated.count; i++)
    303          {
    304              if(gp.pcrAllocated.pcrSelections[i].hash == hashAlg)
    305              {
    306                  if(((gp.pcrAllocated.pcrSelections[i].pcrSelect[pcr/8])
    307                          & (1 << (pcr % 8))) != 0)
    308 //
    309                         allocated = TRUE;
    310                     else
    311                         allocated = FALSE;
    312                     break;
    313                 }
    314           }
    315    }
    316    return allocated;
    317 }
    318 //
    319 //
    320 //             GetPcrPointer()
    321 //
    322 //      This function returns the address of an array of PCR based on the hash algorithm.
    323 //
    324 //      Return Value                      Meaning
    325 //
    326 //      NULL                              no such algorithm
    327 //      not NULL                          pointer to the 0th byte of the 0th PCR
    328 //
    329 static BYTE *
    330 GetPcrPointer (
    331    TPM_ALG_ID            alg,                // IN: algorithm for bank
    332    UINT32                pcrNumber           // IN: PCR number
    333    )
    334 {
    335    static BYTE          *pcr = NULL;
    336    if(!PcrIsAllocated(pcrNumber, alg))
    337        return NULL;
    338    switch(alg)
    339    {
    340 #ifdef TPM_ALG_SHA1
    341    case TPM_ALG_SHA1:
    342        pcr = s_pcrs[pcrNumber].sha1Pcr;
    343        break;
    344 #endif
    345 #ifdef TPM_ALG_SHA256
    346    case TPM_ALG_SHA256:
    347        pcr = s_pcrs[pcrNumber].sha256Pcr;
    348        break;
    349 #endif
    350 #ifdef TPM_ALG_SHA384
    351    case TPM_ALG_SHA384:
    352        pcr = s_pcrs[pcrNumber].sha384Pcr;
    353        break;
    354 #endif
    355 #ifdef TPM_ALG_SHA512
    356    case TPM_ALG_SHA512:
    357        pcr = s_pcrs[pcrNumber].sha512Pcr;
    358        break;
    359 #endif
    360 #ifdef TPM_ALG_SM3_256
    361    case TPM_ALG_SM3_256:
    362        pcr = s_pcrs[pcrNumber].sm3_256Pcr;
    363        break;
    364 #endif
    365    default:
    366        pAssert(FALSE);
    367        break;
    368    }
    369    return pcr;
    370 //
    371 }
    372 //
    373 //
    374 //          IsPcrSelected()
    375 //
    376 //      This function indicates if an indicated PCR number is selected by the bit map in selection.
    377 //
    378 //      Return Value                     Meaning
    379 //
    380 //      FALSE                            PCR is not selected
    381 //      TRUE                             PCR is selected
    382 //
    383 static BOOL
    384 IsPcrSelected (
    385    UINT32                     pcr,                // IN: The number of the PCR
    386    TPMS_PCR_SELECTION        *selection           // IN: The selection structure
    387    )
    388 {
    389    BOOL                 selected = FALSE;
    390    if(   pcr < IMPLEMENTATION_PCR
    391       && ((selection->pcrSelect[pcr/8]) & (1 << (pcr % 8))) != 0)
    392        selected = TRUE;
    393    return selected;
    394 }
    395 //
    396 //
    397 //          FilterPcr()
    398 //
    399 //      This function modifies a PCR selection array based on the implemented PCR.
    400 //
    401 static void
    402 FilterPcr(
    403    TPMS_PCR_SELECTION        *selection           // IN: input PCR selection
    404    )
    405 {
    406    UINT32     i;
    407    TPMS_PCR_SELECTION            *allocated = NULL;
    408    // If size of select is less than PCR_SELECT_MAX, zero the unspecified PCR
    409    for(i = selection->sizeofSelect; i < PCR_SELECT_MAX; i++)
    410        selection->pcrSelect[i] = 0;
    411    // Find the internal configuration for the bank
    412    for(i = 0; i < gp.pcrAllocated.count; i++)
    413    {
    414        if(gp.pcrAllocated.pcrSelections[i].hash == selection->hash)
    415        {
    416            allocated = &gp.pcrAllocated.pcrSelections[i];
    417            break;
    418        }
    419    }
    420    for (i = 0; i < selection->sizeofSelect; i++)
    421    {
    422        if(allocated == NULL)
    423        {
    424             // If the required bank does not exist, clear input selection
    425             selection->pcrSelect[i] = 0;
    426        }
    427        else
    428             selection->pcrSelect[i] &= allocated->pcrSelect[i];
    429    }
    430    return;
    431 }
    432 //
    433 //
    434 //           PcrDrtm()
    435 //
    436 //      This function does the DRTM and H-CRTM processing it is called from _TPM_Hash_End().
    437 //
    438 void
    439 PcrDrtm(
    440    const TPMI_DH_PCR              pcrHandle,       // IN: the index of the PCR to be
    441                                                    //     modified
    442    const TPMI_ALG_HASH            hash,            // IN: the bank identifier
    443    const TPM2B_DIGEST            *digest           // IN: the digest to modify the PCR
    444    )
    445 {
    446    BYTE           *pcrData = GetPcrPointer(hash, pcrHandle);
    447    if(pcrData != NULL)
    448    {
    449        // Rest the PCR to zeros
    450        MemorySet(pcrData, 0, digest->t.size);
    451           // if the TPM has not started, then set the PCR to 0...04 and then extend
    452           if(!TPMIsStarted())
    453           {
    454               pcrData[digest->t.size - 1] = 4;
    455           }
    456           // Now, extend the value
    457           PCRExtend(pcrHandle, hash, digest->t.size, (BYTE *)digest->t.buffer);
    458    }
    459 }
    460 //
    461 //
    462 //           PCRStartup()
    463 //
    464 //      This function initializes the PCR subsystem at TPM2_Startup().
    465 //
    466 void
    467 PCRStartup(
    468    STARTUP_TYPE         type,              // IN: startup type
    469    BYTE                 locality           // IN: startup locality
    470    )
    471 {
    472    UINT32                  pcr, j;
    473    UINT32                  saveIndex = 0;
    474    g_pcrReConfig = FALSE;
    475    if(type != SU_RESUME)
    476    {
    477        // PCR generation counter is cleared at TPM_RESET and TPM_RESTART
    478        gr.pcrCounter = 0;
    479    }
    480    // Initialize/Restore PCR values
    481    for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
    482    {
    483        // On resume, need to know if this PCR had its state saved or not
    484        UINT32      stateSaved =
    485            (type == SU_RESUME && s_initAttributes[pcr].stateSave == SET) ? 1 : 0;
    486           // If this is the H-CRTM PCR and we are not doing a resume and we
    487           // had an H-CRTM event, then we don't change this PCR
    488           if(pcr == HCRTM_PCR && type != SU_RESUME && g_DrtmPreStartup == TRUE)
    489               continue;
    490           // Iterate each hash algorithm bank
    491           for(j = 0; j < gp.pcrAllocated.count; j++)
    492           {
    493               TPMI_ALG_HASH    hash = gp.pcrAllocated.pcrSelections[j].hash;
    494               BYTE            *pcrData = GetPcrPointer(hash, pcr);
    495               UINT16           pcrSize = CryptGetHashDigestSize(hash);
    496               if(pcrData != NULL)
    497               {
    498                   // if state was saved
    499                   if(stateSaved == 1)
    500                   {
    501                       // Restore saved PCR value
    502                       BYTE     *pcrSavedData;
    503                       pcrSavedData = GetSavedPcrPointer(
    504                                           gp.pcrAllocated.pcrSelections[j].hash,
    505                                           saveIndex);
    506                       MemoryCopy(pcrData, pcrSavedData, pcrSize, pcrSize);
    507                   }
    508                   else
    509                       // PCR was not restored by state save
    510                   {
    511                       // If the reset locality of the PCR is 4, then
    512                       // the reset value is all one's, otherwise it is
    513                       // all zero.
    514                       if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
    515                            MemorySet(pcrData, 0xFF, pcrSize);
    516                       else
    517                       {
    518                            MemorySet(pcrData, 0, pcrSize);
    519                            if(pcr == HCRTM_PCR)
    520                                pcrData[pcrSize-1] = locality;
    521                       }
    522                   }
    523               }
    524           }
    525           saveIndex += stateSaved;
    526    }
    527    // Reset authValues
    528    if(type != SU_RESUME)
    529    {
    530        for(j = 0; j < NUM_AUTHVALUE_PCR_GROUP; j++)
    531        {
    532            gc.pcrAuthValues.auth[j].t.size = 0;
    533        }
    534    }
    535 }
    536 //
    537 //
    538 //           PCRStateSave()
    539 //
    540 //      This function is used to save the PCR values that will be restored on TPM Resume.
    541 //
    542 void
    543 PCRStateSave(
    544    TPM_SU                 type             // IN: startup type
    545    )
    546 {
    547    UINT32                 pcr, j;
    548    UINT32                 saveIndex = 0;
    549 //
    550    // if state save CLEAR, nothing to be done.            Return here
    551    if(type == TPM_SU_CLEAR) return;
    552    // Copy PCR values to the structure that should be saved to NV
    553    for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
    554    {
    555        UINT32 stateSaved = (s_initAttributes[pcr].stateSave == SET) ? 1 : 0;
    556           // Iterate each hash algorithm bank
    557           for(j = 0; j < gp.pcrAllocated.count; j++)
    558           {
    559               BYTE    *pcrData;
    560               UINT32 pcrSize;
    561               pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[j].hash, pcr);
    562               if(pcrData != NULL)
    563               {
    564                   pcrSize
    565                       = CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[j].hash);
    566                   if(stateSaved == 1)
    567                   {
    568                       // Restore saved PCR value
    569                       BYTE     *pcrSavedData;
    570                       pcrSavedData
    571                            = GetSavedPcrPointer(gp.pcrAllocated.pcrSelections[j].hash,
    572                                                 saveIndex);
    573                       MemoryCopy(pcrSavedData, pcrData, pcrSize, pcrSize);
    574                   }
    575               }
    576           }
    577           saveIndex += stateSaved;
    578    }
    579    return;
    580 }
    581 //
    582 //
    583 //           PCRIsStateSaved()
    584 //
    585 //      This function indicates if the selected PCR is a PCR that is state saved on TPM2_Shutdown(STATE). The
    586 //      return value is based on PCR attributes.
    587 //
    588 //      Return Value                      Meaning
    589 //
    590 //      TRUE                              PCR is state saved
    591 //      FALSE                             PCR is not state saved
    592 //
    593 BOOL
    594 PCRIsStateSaved(
    595    TPMI_DH_PCR         handle                // IN: PCR handle to be extended
    596    )
    597 {
    598    UINT32                  pcr = handle - PCR_FIRST;
    599    if(s_initAttributes[pcr].stateSave == SET)
    600        return TRUE;
    601    else
    602        return FALSE;
    603 }
    604 //
    605 //
    606 //
    607 //          PCRIsResetAllowed()
    608 //
    609 //      This function indicates if a PCR may be reset by the current command locality. The return value is based
    610 //      on PCR attributes, and not the PCR allocation.
    611 //
    612 //      Return Value                    Meaning
    613 //
    614 //      TRUE                            TPM2_PCR_Reset() is allowed
    615 //      FALSE                           TPM2_PCR_Reset() is not allowed
    616 //
    617 BOOL
    618 PCRIsResetAllowed(
    619    TPMI_DH_PCR          handle            // IN: PCR handle to be extended
    620    )
    621 {
    622    UINT8                     commandLocality;
    623    UINT8                     localityBits = 1;
    624    UINT32                    pcr = handle - PCR_FIRST;
    625    // Check for the locality
    626    commandLocality = _plat__LocalityGet();
    627 #ifdef DRTM_PCR
    628    // For a TPM that does DRTM, Reset is not allowed at locality 4
    629    if(commandLocality == 4)
    630        return FALSE;
    631 #endif
    632    localityBits = localityBits << commandLocality;
    633    if((localityBits & s_initAttributes[pcr].resetLocality) == 0)
    634        return FALSE;
    635    else
    636        return TRUE;
    637 }
    638 //
    639 //
    640 //          PCRChanged()
    641 //
    642 //      This function checks a PCR handle to see if the attributes for the PCR are set so that any change to the
    643 //      PCR causes an increment of the pcrCounter. If it does, then the function increments the counter.
    644 //
    645 void
    646 PCRChanged(
    647    TPM_HANDLE           pcrHandle         // IN: the handle of the PCR that changed.
    648    )
    649 {
    650    // For the reference implementation, the only change that does not cause
    651    // increment is a change to a PCR in the TCB group.
    652    if(!PCRBelongsTCBGroup(pcrHandle))
    653        gr.pcrCounter++;
    654 }
    655 //
    656 //
    657 //          PCRIsExtendAllowed()
    658 //
    659 //      This function indicates a PCR may be extended at the current command locality. The return value is
    660 //      based on PCR attributes, and not the PCR allocation.
    661 //
    662 //
    663 //
    664 //
    665 //      Return Value                      Meaning
    666 //
    667 //      TRUE                              extend is allowed
    668 //      FALSE                             extend is not allowed
    669 //
    670 BOOL
    671 PCRIsExtendAllowed(
    672    TPMI_DH_PCR          handle               // IN: PCR handle to be extended
    673    )
    674 {
    675    UINT8                    commandLocality;
    676    UINT8                    localityBits = 1;
    677    UINT32                   pcr = handle - PCR_FIRST;
    678    // Check for the locality
    679    commandLocality = _plat__LocalityGet();
    680    localityBits = localityBits << commandLocality;
    681    if((localityBits & s_initAttributes[pcr].extendLocality) == 0)
    682        return FALSE;
    683    else
    684        return TRUE;
    685 }
    686 //
    687 //
    688 //           PCRExtend()
    689 //
    690 //      This function is used to extend a PCR in a specific bank.
    691 //
    692 void
    693 PCRExtend(
    694    TPMI_DH_PCR          handle,              //   IN:    PCR handle to be extended
    695    TPMI_ALG_HASH        hash,                //   IN:    hash algorithm of PCR
    696    UINT32               size,                //   IN:    size of data to be extended
    697    BYTE                *data                 //   IN:    data to be extended
    698    )
    699 {
    700    UINT32                    pcr = handle - PCR_FIRST;
    701    BYTE                     *pcrData;
    702    HASH_STATE                hashState;
    703    UINT16                    pcrSize;
    704    pcrData = GetPcrPointer(hash, pcr);
    705    // Extend PCR if it is allocated
    706    if(pcrData != NULL)
    707    {
    708        pcrSize = CryptGetHashDigestSize(hash);
    709        CryptStartHash(hash, &hashState);
    710        CryptUpdateDigest(&hashState, pcrSize, pcrData);
    711        CryptUpdateDigest(&hashState, size, data);
    712        CryptCompleteHash(&hashState, pcrSize, pcrData);
    713           // If PCR does not belong to TCB group, increment PCR counter
    714           if(!PCRBelongsTCBGroup(handle))
    715               gr.pcrCounter++;
    716    }
    717    return;
    718 }
    719 //
    720 //
    721 //
    722 //          PCRComputeCurrentDigest()
    723 //
    724 //      This function computes the digest of the selected PCR.
    725 //      As a side-effect, selection is modified so that only the implemented PCR will have their bits still set.
    726 //
    727 void
    728 PCRComputeCurrentDigest(
    729     TPMI_ALG_HASH             hashAlg,            // IN: hash algorithm to compute digest
    730     TPML_PCR_SELECTION       *selection,          // IN/OUT: PCR selection (filtered on
    731                                                   //     output)
    732     TPM2B_DIGEST             *digest              // OUT: digest
    733     )
    734 {
    735     HASH_STATE                      hashState;
    736     TPMS_PCR_SELECTION             *select;
    737     BYTE                           *pcrData;   // will point to a digest
    738     UINT32                          pcrSize;
    739     UINT32                          pcr;
    740     UINT32                          i;
    741     // Initialize the hash
    742     digest->t.size = CryptStartHash(hashAlg, &hashState);
    743     pAssert(digest->t.size > 0 && digest->t.size < UINT16_MAX);
    744     // Iterate through the list of PCR selection structures
    745     for(i = 0; i < selection->count; i++)
    746     {
    747         // Point to the current selection
    748         select = &selection->pcrSelections[i]; // Point to the current selection
    749         FilterPcr(select);      // Clear out the bits for unimplemented PCR
    750           // Need the size of each digest
    751           pcrSize = CryptGetHashDigestSize(selection->pcrSelections[i].hash);
    752           // Iterate through the selection
    753           for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
    754           {
    755               if(IsPcrSelected(pcr, select))         // Is this PCR selected
    756               {
    757                   // Get pointer to the digest data for the bank
    758                   pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
    759                   pAssert(pcrData != NULL);
    760                   CryptUpdateDigest(&hashState, pcrSize, pcrData); // add to digest
    761               }
    762           }
    763     }
    764     // Complete hash stack
    765     CryptCompleteHash2B(&hashState, &digest->b);
    766     return;
    767 }
    768 //
    769 //
    770 //          PCRRead()
    771 //
    772 //      This function is used to read a list of selected PCR. If the requested PCR number exceeds the maximum
    773 //      number that can be output, the selection is adjusted to reflect the actual output PCR.
    774 //
    775 void
    776 PCRRead(
    777     TPML_PCR_SELECTION       *selection,          // IN/OUT: PCR selection (filtered on
    778                                                   //     output)
    779     TPML_DIGEST              *digest,             // OUT: digest
    780     UINT32                   *pcrCounter          // OUT: the current value of PCR generation
    781                                              //     number
    782    )
    783 {
    784    TPMS_PCR_SELECTION            *select;
    785    BYTE                          *pcrData;        // will point to a digest
    786    UINT32                         pcr;
    787    UINT32                         i;
    788    digest->count = 0;
    789    // Iterate through the list of PCR selection structures
    790    for(i = 0; i < selection->count; i++)
    791    {
    792        // Point to the current selection
    793        select = &selection->pcrSelections[i]; // Point to the current selection
    794        FilterPcr(select);      // Clear out the bits for unimplemented PCR
    795         // Iterate through the selection
    796         for (pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
    797         {
    798             if(IsPcrSelected(pcr, select))          // Is this PCR selected
    799             {
    800                 // Check if number of digest exceed upper bound
    801                 if(digest->count > 7)
    802                 {
    803                     // Clear rest of the current select bitmap
    804                     while(    pcr < IMPLEMENTATION_PCR
    805                               // do not round up!
    806                            && (pcr / 8) < select->sizeofSelect)
    807                     {
    808                         // do not round up!
    809                         select->pcrSelect[pcr/8] &= (BYTE) ~(1 << (pcr % 8));
    810                         pcr++;
    811                     }
    812                     // Exit inner loop
    813                     break;;
    814                 }
    815                 // Need the size of each digest
    816                 digest->digests[digest->count].t.size =
    817                     CryptGetHashDigestSize(selection->pcrSelections[i].hash);
    818                   // Get pointer to the digest data for the bank
    819                   pcrData = GetPcrPointer(selection->pcrSelections[i].hash, pcr);
    820                   pAssert(pcrData != NULL);
    821                   // Add to the data to digest
    822                   MemoryCopy(digest->digests[digest->count].t.buffer,
    823                              pcrData,
    824                              digest->digests[digest->count].t.size,
    825                              digest->digests[digest->count].t.size);
    826                   digest->count++;
    827             }
    828         }
    829         // If we exit inner loop because we have exceed the output upper bound
    830         if(digest->count > 7 && pcr < IMPLEMENTATION_PCR)
    831         {
    832             // Clear rest of the selection
    833             while(i < selection->count)
    834             {
    835                 MemorySet(selection->pcrSelections[i].pcrSelect, 0,
    836                           selection->pcrSelections[i].sizeofSelect);
    837                 i++;
    838             }
    839             // exit outer loop
    840             break;
    841         }
    842    }
    843    *pcrCounter = gr.pcrCounter;
    844    return;
    845 }
    846 //
    847 //
    848 //          PcrWrite()
    849 //
    850 //      This function is used by _TPM_Hash_End() to set a PCR to the computed hash of the H-CRTM event.
    851 //
    852 void
    853 PcrWrite(
    854    TPMI_DH_PCR           handle,            // IN: PCR handle to be extended
    855    TPMI_ALG_HASH         hash,              // IN: hash algorithm of PCR
    856    TPM2B_DIGEST         *digest             // IN: the new value
    857    )
    858 {
    859    UINT32                     pcr = handle - PCR_FIRST;
    860    BYTE                      *pcrData;
    861    // Copy value to the PCR if it is allocated
    862    pcrData = GetPcrPointer(hash, pcr);
    863    if(pcrData != NULL)
    864    {
    865        MemoryCopy(pcrData, digest->t.buffer, digest->t.size, digest->t.size); ;
    866    }
    867    return;
    868 }
    869 //
    870 //
    871 //          PCRAllocate()
    872 //
    873 //      This function is used to change the PCR allocation.
    874 //
    875 //      Error Returns                   Meaning
    876 //
    877 //      TPM_RC_SUCCESS                  allocate success
    878 //      TPM_RC_NO_RESULTS               allocate failed
    879 //      TPM_RC_PCR                      improper allocation
    880 //
    881 TPM_RC
    882 PCRAllocate(
    883    TPML_PCR_SELECTION        *allocate,           //   IN: required allocation
    884    UINT32                    *maxPCR,             //   OUT: Maximum number of PCR
    885    UINT32                    *sizeNeeded,         //   OUT: required space
    886    UINT32                    *sizeAvailable       //   OUT: available space
    887    )
    888 {
    889    UINT32                        i, j, k;
    890    TPML_PCR_SELECTION            newAllocate;
    891    // Initialize the flags       to indicate if HCRTM PCR and DRTM PCR are allocated.
    892    BOOL                          pcrHcrtm = FALSE;
    893    BOOL                          pcrDrtm = FALSE;
    894    // Create the expected new PCR allocation based on the existing allocation
    895    // and the new input:
    896    // 1. if a PCR bank does not appear in the new allocation, the existing
    897    //     allocation of this PCR bank will be preserved.
    898    // 2. if a PCR bank appears multiple times in the new allocation, only the
    899    //     last one will be in effect.
    900    newAllocate = gp.pcrAllocated;
    901    for(i = 0; i < allocate->count; i++)
    902    {
    903        for(j = 0; j < newAllocate.count; j++)
    904        {
    905            // If hash matches, the new allocation covers the old allocation
    906            // for this particular bank.
    907            // The assumption is the initial PCR allocation (from manufacture)
    908            // has all the supported hash algorithms with an assigned bank
    909            // (possibly empty). So there must be a match for any new bank
    910            // allocation from the input.
    911            if(newAllocate.pcrSelections[j].hash ==
    912                allocate->pcrSelections[i].hash)
    913            {
    914                newAllocate.pcrSelections[j] = allocate->pcrSelections[i];
    915                break;
    916            }
    917        }
    918        // The j loop must exit with a match.
    919        pAssert(j < newAllocate.count);
    920    }
    921    // Max PCR in a bank is MIN(implemented PCR, PCR with attributes defined)
    922    *maxPCR = sizeof(s_initAttributes) / sizeof(PCR_Attributes);
    923    if(*maxPCR > IMPLEMENTATION_PCR)
    924        *maxPCR = IMPLEMENTATION_PCR;
    925    // Compute required size for allocation
    926    *sizeNeeded = 0;
    927    for(i = 0; i < newAllocate.count; i++)
    928    {
    929        UINT32      digestSize
    930            = CryptGetHashDigestSize(newAllocate.pcrSelections[i].hash);
    931 #if defined(DRTM_PCR)
    932        // Make sure that we end up with at least one DRTM PCR
    933 #   define PCR_DRTM (PCR_FIRST + DRTM_PCR)     // for cosmetics
    934        pcrDrtm =    pcrDrtm || TEST_BIT(PCR_DRTM, newAllocate.pcrSelections[i]);
    935 #else   // if DRTM PCR is not required, indicate that the allocation is OK
    936        pcrDrtm = TRUE;
    937 #endif
    938 #if defined(HCRTM_PCR)
    939        // and one HCRTM PCR (since this is usually PCR 0...)
    940 #   define PCR_HCRTM (PCR_FIRST + HCRTM_PCR)
    941        pcrHcrtm =    pcrDrtm || TEST_BIT(PCR_HCRTM, newAllocate.pcrSelections[i]);
    942 #else
    943        pcrHcrtm = TRUE;
    944 #endif
    945        for(j = 0; j < newAllocate.pcrSelections[i].sizeofSelect; j++)
    946        {
    947            BYTE         mask = 1;
    948            for(k = 0; k < 8; k++)
    949            {
    950                if((newAllocate.pcrSelections[i].pcrSelect[j] & mask) != 0)
    951                    *sizeNeeded += digestSize;
    952                mask = mask << 1;
    953            }
    954        }
    955    }
    956    if(!pcrDrtm || !pcrHcrtm)
    957        return TPM_RC_PCR;
    958    // In this particular implementation, we always have enough space to
    959    // allocate PCR. Different implementation may return a sizeAvailable less
    960    // than the sizeNeed.
    961    *sizeAvailable = sizeof(s_pcrs);
    962     // Save the required allocation to NV. Note that after NV is written, the
    963     // PCR allocation in NV is no longer consistent with the RAM data
    964     // gp.pcrAllocated. The NV version reflect the allocate after next
    965     // TPM_RESET, while the RAM version reflects the current allocation
    966     NvWriteReserved(NV_PCR_ALLOCATED, &newAllocate);
    967     return TPM_RC_SUCCESS;
    968 }
    969 //
    970 //
    971 //             PCRSetValue()
    972 //
    973 //      This function is used to set the designated PCR in all banks to an initial value. The initial value is signed
    974 //      and will be sign extended into the entire PCR.
    975 //
    976 void
    977 PCRSetValue(
    978     TPM_HANDLE           handle,            // IN: the handle of the PCR to set
    979     INT8                 initialValue       // IN: the value to set
    980     )
    981 {
    982     int                  i;
    983     UINT32               pcr = handle - PCR_FIRST;
    984     TPMI_ALG_HASH        hash;
    985     UINT16               digestSize;
    986     BYTE                *pcrData;
    987     // Iterate supported PCR bank algorithms to reset
    988     for(i = 0; i < HASH_COUNT; i++)
    989     {
    990         hash = CryptGetHashAlgByIndex(i);
    991         // Prevent runaway
    992         if(hash == TPM_ALG_NULL)
    993             break;
    994           // Get a pointer to the data
    995           pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
    996           // If the PCR is allocated
    997           if(pcrData != NULL)
    998           {
    999               // And the size of the digest
   1000               digestSize = CryptGetHashDigestSize(hash);
   1001                // Set the LSO to the input value
   1002                pcrData[digestSize - 1] = initialValue;
   1003                // Sign extend
   1004                if(initialValue >= 0)
   1005                    MemorySet(pcrData, 0, digestSize - 1);
   1006                else
   1007                    MemorySet(pcrData, -1, digestSize - 1);
   1008           }
   1009     }
   1010 }
   1011 //
   1012 //
   1013 //             PCRResetDynamics
   1014 //
   1015 //      This function is used to reset a dynamic PCR to 0. This function is used in DRTM sequence.
   1016 //
   1017 void
   1018 PCRResetDynamics(
   1019       void
   1020       )
   1021 {
   1022       UINT32                  pcr, i;
   1023       // Initialize PCR values
   1024       for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
   1025       {
   1026           // Iterate each hash algorithm bank
   1027           for(i = 0; i < gp.pcrAllocated.count; i++)
   1028           {
   1029               BYTE    *pcrData;
   1030               UINT32 pcrSize;
   1031                 pcrData = GetPcrPointer(gp.pcrAllocated.pcrSelections[i].hash, pcr);
   1032                 if(pcrData != NULL)
   1033                 {
   1034                     pcrSize =
   1035                         CryptGetHashDigestSize(gp.pcrAllocated.pcrSelections[i].hash);
   1036                     // Reset PCR
   1037                     // Any PCR can be reset by locality 4 should be reset to 0
   1038                     if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
   1039                         MemorySet(pcrData, 0, pcrSize);
   1040                 }
   1041           }
   1042       }
   1043       return;
   1044 }
   1045 //
   1046 //
   1047 //             PCRCapGetAllocation()
   1048 //
   1049 //      This function is used to get the current allocation of PCR banks.
   1050 //
   1051 //      Return Value                      Meaning
   1052 //
   1053 //      YES:                              if the return count is 0
   1054 //      NO:                               if the return count is not 0
   1055 //
   1056 TPMI_YES_NO
   1057 PCRCapGetAllocation(
   1058       UINT32                   count,               // IN: count of return
   1059       TPML_PCR_SELECTION      *pcrSelection         // OUT: PCR allocation list
   1060       )
   1061 {
   1062       if(count == 0)
   1063       {
   1064           pcrSelection->count = 0;
   1065           return YES;
   1066       }
   1067       else
   1068       {
   1069           *pcrSelection = gp.pcrAllocated;
   1070           return NO;
   1071       }
   1072 }
   1073 //
   1074 //
   1075 //             PCRSetSelectBit()
   1076 //
   1077 //      This function sets a bit in a bitmap array.
   1078 //
   1079 static void
   1080 PCRSetSelectBit(
   1081    UINT32               pcr,               // IN: PCR number
   1082    BYTE                *bitmap             // OUT: bit map to be set
   1083    )
   1084 {
   1085    bitmap[pcr / 8] |= (1 << (pcr % 8));
   1086    return;
   1087 }
   1088 //
   1089 //
   1090 //          PCRGetProperty()
   1091 //
   1092 //      This function returns the selected PCR property.
   1093 //
   1094 //      Return Value                    Meaning
   1095 //
   1096 //      TRUE                            the property type is implemented
   1097 //      FALSE                           the property type is not implemented
   1098 //
   1099 static BOOL
   1100 PCRGetProperty(
   1101    TPM_PT_PCR                     property,
   1102    TPMS_TAGGED_PCR_SELECT        *select
   1103    )
   1104 {
   1105    UINT32                    pcr;
   1106    UINT32                    groupIndex;
   1107    select->tag = property;
   1108    // Always set the bitmap to be the size of all PCR
   1109    select->sizeofSelect = (IMPLEMENTATION_PCR + 7) / 8;
   1110    // Initialize bitmap
   1111    MemorySet(select->pcrSelect, 0, select->sizeofSelect);
   1112    // Collecting properties
   1113    for(pcr = 0; pcr < IMPLEMENTATION_PCR; pcr++)
   1114    {
   1115        switch(property)
   1116        {
   1117            case TPM_PT_PCR_SAVE:
   1118                if(s_initAttributes[pcr].stateSave == SET)
   1119                    PCRSetSelectBit(pcr, select->pcrSelect);
   1120                break;
   1121            case TPM_PT_PCR_EXTEND_L0:
   1122                if((s_initAttributes[pcr].extendLocality & 0x01) != 0)
   1123                    PCRSetSelectBit(pcr, select->pcrSelect);
   1124                break;
   1125            case TPM_PT_PCR_RESET_L0:
   1126                if((s_initAttributes[pcr].resetLocality & 0x01) != 0)
   1127                    PCRSetSelectBit(pcr, select->pcrSelect);
   1128                break;
   1129            case TPM_PT_PCR_EXTEND_L1:
   1130                if((s_initAttributes[pcr].extendLocality & 0x02) != 0)
   1131                    PCRSetSelectBit(pcr, select->pcrSelect);
   1132                break;
   1133            case TPM_PT_PCR_RESET_L1:
   1134                if((s_initAttributes[pcr].resetLocality & 0x02) != 0)
   1135                    PCRSetSelectBit(pcr, select->pcrSelect);
   1136                break;
   1137            case TPM_PT_PCR_EXTEND_L2:
   1138                if((s_initAttributes[pcr].extendLocality & 0x04) != 0)
   1139                    PCRSetSelectBit(pcr, select->pcrSelect);
   1140 //
   1141                break;
   1142            case TPM_PT_PCR_RESET_L2:
   1143                if((s_initAttributes[pcr].resetLocality & 0x04) != 0)
   1144                     PCRSetSelectBit(pcr, select->pcrSelect);
   1145                break;
   1146            case TPM_PT_PCR_EXTEND_L3:
   1147                if((s_initAttributes[pcr].extendLocality & 0x08) != 0)
   1148                     PCRSetSelectBit(pcr, select->pcrSelect);
   1149                break;
   1150            case TPM_PT_PCR_RESET_L3:
   1151                if((s_initAttributes[pcr].resetLocality & 0x08) != 0)
   1152                     PCRSetSelectBit(pcr, select->pcrSelect);
   1153                break;
   1154            case TPM_PT_PCR_EXTEND_L4:
   1155                if((s_initAttributes[pcr].extendLocality & 0x10) != 0)
   1156                     PCRSetSelectBit(pcr, select->pcrSelect);
   1157                break;
   1158            case TPM_PT_PCR_RESET_L4:
   1159                if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
   1160                     PCRSetSelectBit(pcr, select->pcrSelect);
   1161                break;
   1162            case TPM_PT_PCR_DRTM_RESET:
   1163                // DRTM reset PCRs are the PCR reset by locality 4
   1164                if((s_initAttributes[pcr].resetLocality & 0x10) != 0)
   1165                     PCRSetSelectBit(pcr, select->pcrSelect);
   1166                break;
   1167 #if NUM_POLICY_PCR_GROUP > 0
   1168            case TPM_PT_PCR_POLICY:
   1169                if(PCRBelongsPolicyGroup(pcr + PCR_FIRST, &groupIndex))
   1170                     PCRSetSelectBit(pcr, select->pcrSelect);
   1171                break;
   1172 #endif
   1173 #if NUM_AUTHVALUE_PCR_GROUP > 0
   1174            case TPM_PT_PCR_AUTH:
   1175                if(PCRBelongsAuthGroup(pcr + PCR_FIRST, &groupIndex))
   1176                     PCRSetSelectBit(pcr, select->pcrSelect);
   1177                break;
   1178 #endif
   1179 #if ENABLE_PCR_NO_INCREMENT == YES
   1180            case TPM_PT_PCR_NO_INCREMENT:
   1181                if(PCRBelongsTCBGroup(pcr + PCR_FIRST))
   1182                     PCRSetSelectBit(pcr, select->pcrSelect);
   1183                break;
   1184 #endif
   1185            default:
   1186                // If property is not supported, stop scanning PCR attributes
   1187                // and return.
   1188                return FALSE;
   1189                break;
   1190        }
   1191    }
   1192    return TRUE;
   1193 }
   1194 //
   1195 //
   1196 //           PCRCapGetProperties()
   1197 //
   1198 //       This function returns a list of PCR properties starting at property.
   1199 //
   1200 //
   1201 //
   1202 //
   1203 //       Return Value                    Meaning
   1204 //
   1205 //       YES:                            if no more property is available
   1206 //       NO:                             if there are more properties not reported
   1207 //
   1208 TPMI_YES_NO
   1209 PCRCapGetProperties(
   1210       TPM_PT_PCR                       property,             // IN: the starting PCR property
   1211       UINT32                           count,                // IN: count of returned propertie
   1212       TPML_TAGGED_PCR_PROPERTY        *select                // OUT: PCR select
   1213       )
   1214 {
   1215       TPMI_YES_NO      more = NO;
   1216       UINT32           i;
   1217       // Initialize output property list
   1218       select->count = 0;
   1219       // The maximum count of properties we may return is MAX_PCR_PROPERTIES
   1220       if(count > MAX_PCR_PROPERTIES) count = MAX_PCR_PROPERTIES;
   1221       // TPM_PT_PCR_FIRST is defined as 0 in spec. It ensures that property
   1222       // value would never be less than TPM_PT_PCR_FIRST
   1223       pAssert(TPM_PT_PCR_FIRST == 0);
   1224       // Iterate PCR properties. TPM_PT_PCR_LAST is the index of the last property
   1225       // implemented on the TPM.
   1226       for(i = property; i <= TPM_PT_PCR_LAST; i++)
   1227       {
   1228           if(select->count < count)
   1229           {
   1230                // If we have not filled up the return list, add more properties to it
   1231                if(PCRGetProperty(i, &select->pcrProperty[select->count]))
   1232                    // only increment if the property is implemented
   1233                select->count++;
   1234           }
   1235           else
   1236           {
   1237                // If the return list is full but we still have properties
   1238                // available, report this and stop iterating.
   1239                more = YES;
   1240                break;
   1241           }
   1242       }
   1243       return more;
   1244 }
   1245 //
   1246 //
   1247 //            PCRCapGetHandles()
   1248 //
   1249 //       This function is used to get a list of handles of PCR, started from handle. If handle exceeds the maximum
   1250 //       PCR handle range, an empty list will be returned and the return value will be NO.
   1251 //
   1252 //       Return Value                    Meaning
   1253 //
   1254 //       YES                             if there are more handles available
   1255 //       NO                              all the available handles has been returned
   1256 //
   1257 TPMI_YES_NO
   1258 PCRCapGetHandles(
   1259       TPMI_DH_PCR       handle,             // IN: start handle
   1260       UINT32            count,              // IN: count of returned handle
   1261       TPML_HANDLE      *handleList          // OUT: list of handle
   1262      )
   1263 {
   1264      TPMI_YES_NO         more = NO;
   1265      UINT32              i;
   1266      pAssert(HandleGetType(handle) == TPM_HT_PCR);
   1267      // Initialize output handle list
   1268      handleList->count = 0;
   1269      // The maximum count of handles we may return is MAX_CAP_HANDLES
   1270      if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
   1271      // Iterate PCR handle range
   1272      for(i = handle & HR_HANDLE_MASK; i <= PCR_LAST; i++)
   1273      {
   1274          if(handleList->count < count)
   1275          {
   1276               // If we have not filled up the return list, add this PCR
   1277               // handle to it
   1278               handleList->handle[handleList->count] = i + PCR_FIRST;
   1279               handleList->count++;
   1280          }
   1281          else
   1282          {
   1283               // If the return list is full but we still have PCR handle
   1284               // available, report this and stop iterating
   1285               more = YES;
   1286               break;
   1287          }
   1288      }
   1289      return more;
   1290 }
   1291