Home | History | Annotate | Download | only in tpm2
      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