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