1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 3: Commands 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "InternalRoutines.h" 9 #include "ContextLoad_fp.h" 10 #include "Context_spt_fp.h" 11 // 12 // 13 // Error Returns Meaning 14 // 15 // TPM_RC_CONTEXT_GAP there is only one available slot and this is not the oldest saved 16 // session context 17 // TPM_RC_HANDLE 'context. savedHandle' does not reference a saved session 18 // TPM_RC_HIERARCHY 'context.hierarchy' is disabled 19 // TPM_RC_INTEGRITY context integrity check fail 20 // TPM_RC_OBJECT_MEMORY no free slot for an object 21 // TPM_RC_SESSION_MEMORY no free session slots 22 // TPM_RC_SIZE incorrect context blob size 23 // 24 TPM_RC 25 TPM2_ContextLoad( 26 ContextLoad_In *in, // IN: input parameter list 27 ContextLoad_Out *out // OUT: output parameter list 28 ) 29 { 30 // Local Variables 31 TPM_RC result = TPM_RC_SUCCESS; 32 33 TPM2B_DIGEST integrityToCompare; 34 TPM2B_DIGEST integrity; 35 UINT16 integritySize; 36 UINT64 fingerprint; 37 BYTE *buffer; 38 INT32 size; 39 40 TPM_HT handleType; 41 TPM2B_SYM_KEY symKey; 42 TPM2B_IV iv; 43 44 // Input Validation 45 46 // Check context blob size 47 handleType = HandleGetType(in->context.savedHandle); 48 49 // Check integrity 50 // In this implementation, the same routine is used for both sessions 51 // and objects. 52 integritySize = CryptGetHashDigestSize(CONTEXT_INTEGRITY_HASH_ALG); 53 54 // Get integrity from context blob 55 buffer = in->context.contextBlob.t.buffer; 56 size = (INT32) in->context.contextBlob.t.size; 57 result = TPM2B_DIGEST_Unmarshal(&integrity, &buffer, &size); 58 if(result != TPM_RC_SUCCESS) 59 return result; 60 if(integrity.t.size != integritySize) 61 return TPM_RC_SIZE; 62 63 integritySize += sizeof(integrity.t.size); 64 // 65 66 // Compute context integrity 67 ComputeContextIntegrity(&in->context, &integrityToCompare); 68 69 // Compare integrity 70 if(!Memory2BEqual(&integrity.b, &integrityToCompare.b)) 71 return TPM_RC_INTEGRITY + RC_ContextLoad_context; 72 73 // Compute context encryption key 74 ComputeContextProtectionKey(&in->context, &symKey, &iv); 75 76 // Decrypt context data in place 77 CryptSymmetricDecrypt(in->context.contextBlob.t.buffer + integritySize, 78 CONTEXT_ENCRYPT_ALG, CONTEXT_ENCRYPT_KEY_BITS, 79 TPM_ALG_CFB, symKey.t.buffer, &iv, 80 in->context.contextBlob.t.size - integritySize, 81 in->context.contextBlob.t.buffer + integritySize); 82 83 // Read the fingerprint value, skip the leading integrity size 84 MemoryCopy(&fingerprint, in->context.contextBlob.t.buffer + integritySize, 85 sizeof(fingerprint), sizeof(fingerprint)); 86 // Check fingerprint. If the check fails, TPM should be put to failure mode 87 if(fingerprint != in->context.sequence) 88 FAIL(FATAL_ERROR_INTERNAL); 89 90 // Perform object or session specific input check 91 switch(handleType) 92 { 93 case TPM_HT_TRANSIENT: 94 { 95 // Get a pointer to the object in the context blob 96 OBJECT *outObject = (OBJECT *)(in->context.contextBlob.t.buffer 97 + integritySize + sizeof(fingerprint)); 98 99 // Discard any changes to the handle that the TRM might have made 100 in->context.savedHandle = TRANSIENT_FIRST; 101 102 // If hierarchy is disabled, no object context can be loaded in this 103 // hierarchy 104 if(!HierarchyIsEnabled(in->context.hierarchy)) 105 return TPM_RC_HIERARCHY + RC_ContextLoad_context; 106 107 // Restore object. A TPM_RC_OBJECT_MEMORY error may be returned at 108 // this point 109 result = ObjectContextLoad(outObject, &out->loadedHandle); 110 if(result != TPM_RC_SUCCESS) 111 return result; 112 113 // If this is a sequence object, the crypto library may need to 114 // reformat the data into an internal format 115 if(ObjectIsSequence(outObject)) 116 SequenceDataImportExport(ObjectGet(out->loadedHandle), 117 outObject, IMPORT_STATE); 118 119 break; 120 } 121 case TPM_HT_POLICY_SESSION: 122 case TPM_HT_HMAC_SESSION: 123 { 124 125 SESSION *session = (SESSION *)(in->context.contextBlob.t.buffer 126 + integritySize + sizeof(fingerprint)); 127 128 // This command may cause the orderlyState to be cleared due to 129 // the update of state reset data. If this is the case, check if NV is 130 // available first 131 if(gp.orderlyState != SHUTDOWN_NONE) 132 { 133 // The command needs NV update. Check if NV is available. 134 // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned 135 // at this point 136 result = NvIsAvailable(); 137 if(result != TPM_RC_SUCCESS) 138 return result; 139 } 140 141 // Check if input handle points to a valid saved session 142 if(!SessionIsSaved(in->context.savedHandle)) 143 return TPM_RC_HANDLE + RC_ContextLoad_context; 144 145 // Restore session. A TPM_RC_SESSION_MEMORY, TPM_RC_CONTEXT_GAP error 146 // may be returned at this point 147 result = SessionContextLoad(session, &in->context.savedHandle); 148 if(result != TPM_RC_SUCCESS) 149 return result; 150 151 out->loadedHandle = in->context.savedHandle; 152 153 // orderly state should be cleared because of the update of state 154 // reset and state clear data 155 g_clearOrderly = TRUE; 156 157 break; 158 } 159 default: 160 // Context blob may only have an object handle or a session handle. 161 // All the other handle type should be filtered out at unmarshal 162 pAssert(FALSE); 163 break; 164 } 165 166 return TPM_RC_SUCCESS; 167 } 168