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 "EventSequenceComplete_fp.h" 10 // 11 // 12 // Error Returns Meaning 13 // 14 // TPM_RC_LOCALITY PCR extension is not allowed at the current locality 15 // TPM_RC_MODE input handle is not a valid event sequence object 16 // 17 TPM_RC 18 TPM2_EventSequenceComplete( 19 EventSequenceComplete_In *in, // IN: input parameter list 20 EventSequenceComplete_Out *out // OUT: output parameter list 21 ) 22 { 23 TPM_RC result; 24 HASH_OBJECT *hashObject; 25 UINT32 i; 26 TPM_ALG_ID hashAlg; 27 28 // Input validation 29 30 // get the event sequence object pointer 31 hashObject = (HASH_OBJECT *)ObjectGet(in->sequenceHandle); 32 33 // input handle must reference an event sequence object 34 if(hashObject->attributes.eventSeq != SET) 35 return TPM_RC_MODE + RC_EventSequenceComplete_sequenceHandle; 36 37 // see if a PCR extend is requested in call 38 if(in->pcrHandle != TPM_RH_NULL) 39 { 40 // see if extend of the PCR is allowed at the locality of the command, 41 if(!PCRIsExtendAllowed(in->pcrHandle)) 42 return TPM_RC_LOCALITY; 43 // if an extend is going to take place, then check to see if there has 44 // been an orderly shutdown. If so, and the selected PCR is one of the 45 // state saved PCR, then the orderly state has to change. The orderly state 46 // does not change for PCR that are not preserved. 47 // NOTE: This doesn't just check for Shutdown(STATE) because the orderly 48 // state will have to change if this is a state-saved PCR regardless 49 // of the current state. This is because a subsequent Shutdown(STATE) will 50 // check to see if there was an orderly shutdown and not do anything if 51 // there was. So, this must indicate that a future Shutdown(STATE) has 52 // something to do. 53 if(gp.orderlyState != SHUTDOWN_NONE && PCRIsStateSaved(in->pcrHandle)) 54 { 55 result = NvIsAvailable(); 56 if(result != TPM_RC_SUCCESS) return result; 57 g_clearOrderly = TRUE; 58 } 59 } 60 61 // Command Output 62 63 out->results.count = 0; 64 65 for(i = 0; i < HASH_COUNT; i++) 66 { 67 hashAlg = CryptGetHashAlgByIndex(i); 68 // Update last piece of data 69 CryptUpdateDigest2B(&hashObject->state.hashState[i], &in->buffer.b); 70 // Complete hash 71 out->results.digests[out->results.count].hashAlg = hashAlg; 72 CryptCompleteHash(&hashObject->state.hashState[i], 73 CryptGetHashDigestSize(hashAlg), 74 (BYTE *) &out->results.digests[out->results.count].digest); 75 76 // Extend PCR 77 if(in->pcrHandle != TPM_RH_NULL) 78 PCRExtend(in->pcrHandle, hashAlg, 79 CryptGetHashDigestSize(hashAlg), 80 (BYTE *) &out->results.digests[out->results.count].digest); 81 out->results.count++; 82 } 83 84 // Internal Data Update 85 86 // mark sequence object as evict so it will be flushed on the way out 87 hashObject->attributes.evict = SET; 88 89 return TPM_RC_SUCCESS; 90 } 91