aboutsummaryrefslogtreecommitdiff
path: root/EventSequenceComplete.c
blob: 3e59052f4c69d63d4e3df144c47e8037550b7489 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 3: Commands
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
#include "EventSequenceComplete_fp.h"
//
//
//     Error Returns                 Meaning
//
//     TPM_RC_LOCALITY               PCR extension is not allowed at the current locality
//     TPM_RC_MODE                   input handle is not a valid event sequence object
//
TPM_RC
TPM2_EventSequenceComplete(
   EventSequenceComplete_In      *in,                // IN: input parameter list
   EventSequenceComplete_Out     *out                // OUT: output parameter list
   )
{
   TPM_RC              result;
   HASH_OBJECT        *hashObject;
   UINT32              i;
   TPM_ALG_ID          hashAlg;

// Input validation

   // get the event sequence object pointer
   hashObject = (HASH_OBJECT *)ObjectGet(in->sequenceHandle);

   // input handle must reference an event sequence object
   if(hashObject->attributes.eventSeq != SET)
       return TPM_RC_MODE + RC_EventSequenceComplete_sequenceHandle;

   // see if a PCR extend is requested in call
   if(in->pcrHandle != TPM_RH_NULL)
   {
       // see if extend of the PCR is allowed at the locality of the command,
       if(!PCRIsExtendAllowed(in->pcrHandle))
           return TPM_RC_LOCALITY;
       // if an extend is going to take place, then check to see if there has
       // been an orderly shutdown. If so, and the selected PCR is one of the
       // state saved PCR, then the orderly state has to change. The orderly state
       // does not change for PCR that are not preserved.
       // NOTE: This doesn't just check for Shutdown(STATE) because the orderly
       // state will have to change if this is a state-saved PCR regardless
       // of the current state. This is because a subsequent Shutdown(STATE) will
       // check to see if there was an orderly shutdown and not do anything if
       // there was. So, this must indicate that a future Shutdown(STATE) has
       // something to do.
       if(gp.orderlyState != SHUTDOWN_NONE && PCRIsStateSaved(in->pcrHandle))
       {
           result = NvIsAvailable();
           if(result != TPM_RC_SUCCESS) return result;
           g_clearOrderly = TRUE;
       }
   }

// Command Output

   out->results.count = 0;

   for(i = 0; i < HASH_COUNT; i++)
   {
       hashAlg = CryptGetHashAlgByIndex(i);
       // Update last piece of data
       CryptUpdateDigest2B(&hashObject->state.hashState[i], &in->buffer.b);
       // Complete hash
       out->results.digests[out->results.count].hashAlg = hashAlg;
       CryptCompleteHash(&hashObject->state.hashState[i],
                       CryptGetHashDigestSize(hashAlg),
                       (BYTE *) &out->results.digests[out->results.count].digest);

       // Extend PCR
       if(in->pcrHandle != TPM_RH_NULL)
           PCRExtend(in->pcrHandle, hashAlg,
                     CryptGetHashDigestSize(hashAlg),
                     (BYTE *) &out->results.digests[out->results.count].digest);
       out->results.count++;
   }

// Internal Data Update

   // mark sequence object as evict so it will be flushed on the way out
   hashObject->attributes.evict = SET;

   return TPM_RC_SUCCESS;
}