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
TPM2_EventSequenceComplete(EventSequenceComplete_In * in,EventSequenceComplete_Out * out)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