Vadim Bendebury | 5679752 | 2015-05-20 10:32:25 -0700 | [diff] [blame] | 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 | } |