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