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 //
     12 //          Functions
     13 //
     14 //          EntityGetLoadStatus()
     15 //
     16 //     This function will indicate if the entity associated with a handle is present in TPM memory. If the handle is
     17 //     a persistent object handle, and the object exists, the persistent object is moved from NV memory into a
     18 //     RAM object slot and the persistent handle is replaced with the transient object handle for the slot.
     19 //
     20 //     Error Returns                     Meaning
     21 //
     22 //     TPM_RC_HANDLE                     handle type does not match
     23 //     TPM_RC_REFERENCE_H0               entity is not present
     24 //     TPM_RC_HIERARCHY                  entity belongs to a disabled hierarchy
     25 //     TPM_RC_OBJECT_MEMORY              handle is an evict object but there is no space to load it to RAM
     26 //
     27 TPM_RC
     28 EntityGetLoadStatus(
     29     TPM_HANDLE          *handle,              // IN/OUT: handle of the entity
     30     TPM_CC               commandCode          // IN: the commmandCode
     31     )
     32 {
     33     TPM_RC              result = TPM_RC_SUCCESS;
     34     switch(HandleGetType(*handle))
     35     {
     36         // For handles associated with hierarchies, the entity is present
     37         // only if the associated enable is SET.
     38         case TPM_HT_PERMANENT:
     39             switch(*handle)
     40             {
     41                 case TPM_RH_OWNER:
     42                     if(!gc.shEnable)
     43                         result = TPM_RC_HIERARCHY;
     44                     break;
     45 #ifdef    VENDOR_PERMANENT
     46                  case VENDOR_PERMANENT:
     47 #endif
     48                    case TPM_RH_ENDORSEMENT:
     49                        if(!gc.ehEnable)
     50                             result = TPM_RC_HIERARCHY;
     51                        break;
     52                    case TPM_RH_PLATFORM:
     53                        if(!g_phEnable)
     54                             result = TPM_RC_HIERARCHY;
     55                        break;
     56                        // null handle, PW session handle and lockout
     57                        // handle are always available
     58                    case TPM_RH_NULL:
     59                    case TPM_RS_PW:
     60                    case TPM_RH_LOCKOUT:
     61                        break;
     62                    default:
     63                        // handling of the manufacture_specific handles
     64                        if(      ((TPM_RH)*handle >= TPM_RH_FIRST)
     65                             && ((TPM_RH)*handle <= TPM_RH_LAST))
     66                             // use the value that would have been returned from
     67                             // unmarshaling if it did the handle filtering
     68                                 result = TPM_RC_VALUE;
     69                        else
     70                             pAssert(FALSE);
     71                        break;
     72             }
     73             break;
     74         case TPM_HT_TRANSIENT:
     75             // For a transient object, check if the handle is associated
     76             // with a loaded object.
     77             if(!ObjectIsPresent(*handle))
     78                  result = TPM_RC_REFERENCE_H0;
     79             break;
     80         case TPM_HT_PERSISTENT:
     81             // Persistent object
     82             // Copy the persistent object to RAM and replace the handle with the
     83             // handle of the assigned slot. A TPM_RC_OBJECT_MEMORY,
     84             // TPM_RC_HIERARCHY or TPM_RC_REFERENCE_H0 error may be returned by
     85             // ObjectLoadEvict()
     86             result = ObjectLoadEvict(handle, commandCode);
     87             break;
     88         case TPM_HT_HMAC_SESSION:
     89             // For an HMAC session, see if the session is loaded
     90             // and if the session in the session slot is actually
     91             // an HMAC session.
     92             if(SessionIsLoaded(*handle))
     93             {
     94                  SESSION             *session;
     95                  session = SessionGet(*handle);
     96                  // Check if the session is a HMAC session
     97                  if(session->attributes.isPolicy == SET)
     98                      result = TPM_RC_HANDLE;
     99             }
    100             else
    101                  result = TPM_RC_REFERENCE_H0;
    102             break;
    103         case TPM_HT_POLICY_SESSION:
    104             // For a policy session, see if the session is loaded
    105             // and if the session in the session slot is actually
    106             // a policy session.
    107             if(SessionIsLoaded(*handle))
    108             {
    109                  SESSION             *session;
    110                  session = SessionGet(*handle);
    111                  // Check if the session is a policy session
    112                  if(session->attributes.isPolicy == CLEAR)
    113                      result = TPM_RC_HANDLE;
    114             }
    115             else
    116                  result = TPM_RC_REFERENCE_H0;
    117             break;
    118         case TPM_HT_NV_INDEX:
    119             // For an NV Index, use the platform-specific routine
    120             // to search the IN Index space.
    121             result = NvIndexIsAccessible(*handle, commandCode);
    122             break;
    123         case TPM_HT_PCR:
    124             // Any PCR handle that is unmarshaled successfully referenced
    125             // a PCR that is defined.
    126             break;
    127         default:
    128             // Any other handle type is a defect in the unmarshaling code.
    129             pAssert(FALSE);
    130             break;
    131    }
    132    return result;
    133 }
    134 //
    135 //
    136 //
    137 //           EntityGetAuthValue()
    138 //
    139 //      This function is used to access the authValue associated with a handle. This function assumes that the
    140 //      handle references an entity that is accessible and the handle is not for a persistent objects. That is
    141 //      EntityGetLoadStatus() should have been called. Also, the accessibility of the authValue should have been
    142 //      verified by IsAuthValueAvailable().
    143 //      This function copies the authorization value of the entity to auth.
    144 //      Return value is the number of octets copied to auth.
    145 //
    146 UINT16
    147 EntityGetAuthValue(
    148     TPMI_DH_ENTITY       handle,             // IN: handle of entity
    149     AUTH_VALUE          *auth                // OUT: authValue of the entity
    150     )
    151 {
    152     TPM2B_AUTH           authValue = {};
    153    switch(HandleGetType(handle))
    154    {
    155        case TPM_HT_PERMANENT:
    156            switch(handle)
    157            {
    158                case TPM_RH_OWNER:
    159                    // ownerAuth for TPM_RH_OWNER
    160                    authValue = gp.ownerAuth;
    161                    break;
    162                case TPM_RH_ENDORSEMENT:
    163                    // endorsementAuth for TPM_RH_ENDORSEMENT
    164                    authValue = gp.endorsementAuth;
    165                    break;
    166                case TPM_RH_PLATFORM:
    167                    // platformAuth for TPM_RH_PLATFORM
    168                    authValue = gc.platformAuth;
    169                    break;
    170                case TPM_RH_LOCKOUT:
    171                    // lockoutAuth for TPM_RH_LOCKOUT
    172                    authValue = gp.lockoutAuth;
    173                    break;
    174                case TPM_RH_NULL:
    175                    // nullAuth for TPM_RH_NULL. Return 0 directly here
    176                    return 0;
    177                    break;
    178 #ifdef VENDOR_PERMANENT
    179                case VENDOR_PERMANENT:
    180                    // vendor auth value
    181                    authValue = g_platformUniqueDetails;
    182 #endif
    183                default:
    184                    // If any other permanent handle is present it is
    185                    // a code defect.
    186                    pAssert(FALSE);
    187                    break;
    188            }
    189            break;
    190        case TPM_HT_TRANSIENT:
    191            // authValue for an object
    192            // A persistent object would have been copied into RAM
    193            // and would have an transient object handle here.
    194            {
    195                OBJECT          *object;
    196                object = ObjectGet(handle);
    197                // special handling if this is a sequence object
    198                if(ObjectIsSequence(object))
    199                    {
    200                        authValue = ((HASH_OBJECT *)object)->auth;
    201                    }
    202                    else
    203                    {
    204                        // Auth value is available only when the private portion of
    205                        // the object is loaded. The check should be made before
    206                        // this function is called
    207                        pAssert(object->attributes.publicOnly == CLEAR);
    208                        authValue = object->sensitive.authValue;
    209                    }
    210              }
    211              break;
    212          case TPM_HT_NV_INDEX:
    213              // authValue for an NV index
    214              {
    215                   NV_INDEX        nvIndex;
    216                   NvGetIndexInfo(handle, &nvIndex);
    217                   authValue = nvIndex.authValue;
    218              }
    219              break;
    220          case TPM_HT_PCR:
    221              // authValue for PCR
    222              PCRGetAuthValue(handle, &authValue);
    223              break;
    224          default:
    225              // If any other handle type is present here, then there is a defect
    226              // in the unmarshaling code.
    227              pAssert(FALSE);
    228              break;
    229     }
    230     // Copy the authValue
    231     pAssert(authValue.t.size <= sizeof(authValue.t.buffer));
    232     MemoryCopy(auth, authValue.t.buffer, authValue.t.size, sizeof(TPMU_HA));
    233     return authValue.t.size;
    234 }
    235 //
    236 //
    237 //           EntityGetAuthPolicy()
    238 //
    239 //      This function is used to access the authPolicy associated with a handle. This function assumes that the
    240 //      handle references an entity that is accessible and the handle is not for a persistent objects. That is
    241 //      EntityGetLoadStatus() should have been called. Also, the accessibility of the authPolicy should have
    242 //      been verified by IsAuthPolicyAvailable().
    243 //      This function copies the authorization policy of the entity to authPolicy.
    244 //      The return value is the hash algorithm for the policy.
    245 //
    246 TPMI_ALG_HASH
    247 EntityGetAuthPolicy(
    248     TPMI_DH_ENTITY       handle,             // IN: handle of entity
    249     TPM2B_DIGEST        *authPolicy          // OUT: authPolicy of the entity
    250     )
    251 {
    252     TPMI_ALG_HASH            hashAlg = TPM_ALG_NULL;
    253     switch(HandleGetType(handle))
    254     {
    255         case TPM_HT_PERMANENT:
    256             switch(handle)
    257             {
    258                 case TPM_RH_OWNER:
    259 //
    260                       // ownerPolicy for TPM_RH_OWNER
    261                       *authPolicy = gp.ownerPolicy;
    262                       hashAlg = gp.ownerAlg;
    263                       break;
    264                   case TPM_RH_ENDORSEMENT:
    265                       // endorsementPolicy for TPM_RH_ENDORSEMENT
    266                       *authPolicy = gp.endorsementPolicy;
    267                       hashAlg = gp.endorsementAlg;
    268                       break;
    269                   case TPM_RH_PLATFORM:
    270                       // platformPolicy for TPM_RH_PLATFORM
    271                       *authPolicy = gc.platformPolicy;
    272                       hashAlg = gc.platformAlg;
    273                       break;
    274                   case TPM_RH_LOCKOUT:
    275                       // lockoutPolicy for TPM_RH_LOCKOUT
    276                       *authPolicy = gp.lockoutPolicy;
    277                       hashAlg = gp.lockoutAlg;
    278                       break;
    279                   default:
    280                       // If any other permanent handle is present it is
    281                       // a code defect.
    282                       pAssert(FALSE);
    283                       break;
    284              }
    285              break;
    286          case TPM_HT_TRANSIENT:
    287              // authPolicy for an object
    288              {
    289                   OBJECT *object = ObjectGet(handle);
    290                   *authPolicy = object->publicArea.authPolicy;
    291                   hashAlg = object->publicArea.nameAlg;
    292              }
    293              break;
    294          case TPM_HT_NV_INDEX:
    295              // authPolicy for a NV index
    296              {
    297                   NV_INDEX        nvIndex;
    298                   NvGetIndexInfo(handle, &nvIndex);
    299                   *authPolicy = nvIndex.publicArea.authPolicy;
    300                   hashAlg = nvIndex.publicArea.nameAlg;
    301              }
    302              break;
    303          case TPM_HT_PCR:
    304              // authPolicy for a PCR
    305              hashAlg = PCRGetAuthPolicy(handle, authPolicy);
    306              break;
    307          default:
    308              // If any other handle type is present it is a code defect.
    309              pAssert(FALSE);
    310              break;
    311    }
    312    return hashAlg;
    313 }
    314 //
    315 //
    316 //           EntityGetName()
    317 //
    318 //      This function returns the Name associated with a handle. It will set name to the Name and return the size
    319 //      of the Name string.
    320 //
    321 UINT16
    322 EntityGetName(
    323    TPMI_DH_ENTITY       handle,           // IN: handle of entity
    324    NAME                *name              // OUT: name of entity
    325     )
    326 {
    327     UINT16              nameSize;
    328     INT32 bufferSize = sizeof(TPM_HANDLE);
    329     switch(HandleGetType(handle))
    330     {
    331         case TPM_HT_TRANSIENT:
    332             // Name for an object
    333             nameSize = ObjectGetName(handle, name);
    334             break;
    335         case TPM_HT_NV_INDEX:
    336             // Name for a NV index
    337             nameSize = NvGetName(handle, name);
    338             break;
    339         default:
    340             // For all other types, the handle is the Name
    341             nameSize = TPM_HANDLE_Marshal(&handle, (BYTE **)&name, &bufferSize);
    342             break;
    343     }
    344     return nameSize;
    345 }
    346 //
    347 //
    348 //           EntityGetHierarchy()
    349 //
    350 //      This function returns the hierarchy handle associated with an entity.
    351 //      a) A handle that is a hierarchy handle is associated with itself.
    352 //      b) An NV index belongs to TPM_RH_PLATFORM if TPMA_NV_PLATFORMCREATE, is SET,
    353 //         otherwise it belongs to TPM_RH_OWNER
    354 //      c) An object handle belongs to its hierarchy. All other handles belong to the platform hierarchy. or an NV
    355 //         Index.
    356 //
    357 TPMI_RH_HIERARCHY
    358 EntityGetHierarchy(
    359     TPMI_DH_ENTITY       handle             // IN :handle of entity
    360     )
    361 {
    362     TPMI_RH_HIERARCHY             hierarcy = TPM_RH_NULL;
    363     switch(HandleGetType(handle))
    364     {
    365         case TPM_HT_PERMANENT:
    366             // hierarchy for a permanent handle
    367             switch(handle)
    368             {
    369                 case TPM_RH_PLATFORM:
    370                 case TPM_RH_ENDORSEMENT:
    371                 case TPM_RH_NULL:
    372                     hierarcy = handle;
    373                     break;
    374                 // all other permanent handles are associated with the owner
    375                 // hierarchy. (should only be TPM_RH_OWNER and TPM_RH_LOCKOUT)
    376                 default:
    377                     hierarcy = TPM_RH_OWNER;
    378                     break;
    379             }
    380             break;
    381         case TPM_HT_NV_INDEX:
    382             // hierarchy for NV index
    383             {
    384                 NV_INDEX        nvIndex;
    385                 NvGetIndexInfo(handle, &nvIndex);
    386                 // If only the platform can delete the index, then it is
    387                   // considered to be in the platform hierarchy, otherwise it
    388                   // is in the owner hierarchy.
    389                   if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == SET)
    390                       hierarcy = TPM_RH_PLATFORM;
    391                   else
    392                       hierarcy = TPM_RH_OWNER;
    393              }
    394              break;
    395          case TPM_HT_TRANSIENT:
    396              // hierarchy for an object
    397              {
    398                  OBJECT          *object;
    399                  object = ObjectGet(handle);
    400                  if(object->attributes.ppsHierarchy)
    401                  {
    402                      hierarcy = TPM_RH_PLATFORM;
    403                  }
    404                  else if(object->attributes.epsHierarchy)
    405                  {
    406                      hierarcy = TPM_RH_ENDORSEMENT;
    407                  }
    408                  else if(object->attributes.spsHierarchy)
    409                  {
    410                      hierarcy = TPM_RH_OWNER;
    411                  }
    412              }
    413              break;
    414          case TPM_HT_PCR:
    415              hierarcy = TPM_RH_OWNER;
    416              break;
    417          default:
    418              pAssert(0);
    419              break;
    420      }
    421      // this is unreachable but it provides a return value for the default
    422      // case which makes the complier happy
    423      return hierarcy;
    424 }
    425