110 lines
3.4 KiB
C
110 lines
3.4 KiB
C
// 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 "SequenceComplete_fp.h"
|
|
#include "Platform.h"
|
|
//
|
|
//
|
|
// Error Returns Meaning
|
|
//
|
|
// TPM_RC_TYPE sequenceHandle does not reference a hash or HMAC sequence
|
|
// object
|
|
//
|
|
TPM_RC
|
|
TPM2_SequenceComplete(
|
|
SequenceComplete_In *in, // IN: input parameter list
|
|
SequenceComplete_Out *out // OUT: output parameter list
|
|
)
|
|
{
|
|
OBJECT *object;
|
|
|
|
// Input validation
|
|
|
|
// Get hash object pointer
|
|
object = ObjectGet(in->sequenceHandle);
|
|
|
|
// input handle must be a hash or HMAC sequence object.
|
|
if( object->attributes.hashSeq == CLEAR
|
|
&& object->attributes.hmacSeq == CLEAR)
|
|
return TPM_RC_MODE + RC_SequenceComplete_sequenceHandle;
|
|
|
|
// Command Output
|
|
|
|
if(object->attributes.hashSeq == SET) // sequence object for hash
|
|
{
|
|
// Update last piece of data
|
|
HASH_OBJECT *hashObject = (HASH_OBJECT *)object;
|
|
|
|
// Get the hash algorithm before the algorithm is lost in CryptCompleteHash
|
|
TPM_ALG_ID hashAlg = hashObject->state.hashState[0].state.hashAlg;
|
|
|
|
CryptUpdateDigest2B(&hashObject->state.hashState[0], &in->buffer.b);
|
|
|
|
// Complete hash
|
|
out->result.t.size
|
|
= CryptGetHashDigestSize(
|
|
CryptGetContextAlg(&hashObject->state.hashState[0]));
|
|
|
|
CryptCompleteHash2B(&hashObject->state.hashState[0], &out->result.b);
|
|
|
|
// Check if the first block of the sequence has been received
|
|
if(hashObject->attributes.firstBlock == CLEAR)
|
|
{
|
|
// If not, then this is the first block so see if it is 'safe'
|
|
// to sign.
|
|
if(TicketIsSafe(&in->buffer.b))
|
|
hashObject->attributes.ticketSafe = SET;
|
|
}
|
|
|
|
// Output ticket
|
|
out->validation.tag = TPM_ST_HASHCHECK;
|
|
out->validation.hierarchy = in->hierarchy;
|
|
|
|
if(in->hierarchy == TPM_RH_NULL)
|
|
{
|
|
// Ticket is not required
|
|
out->validation.digest.t.size = 0;
|
|
}
|
|
else if(object->attributes.ticketSafe == CLEAR)
|
|
{
|
|
// Ticket is not safe to generate
|
|
out->validation.hierarchy = TPM_RH_NULL;
|
|
out->validation.digest.t.size = 0;
|
|
}
|
|
else
|
|
{
|
|
// Compute ticket
|
|
TicketComputeHashCheck(out->validation.hierarchy, hashAlg,
|
|
&out->result, &out->validation);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HASH_OBJECT *hashObject = (HASH_OBJECT *)object;
|
|
|
|
// Update last piece of data
|
|
CryptUpdateDigest2B(&hashObject->state.hmacState, &in->buffer.b);
|
|
// Complete hash/HMAC
|
|
out->result.t.size =
|
|
CryptGetHashDigestSize(
|
|
CryptGetContextAlg(&hashObject->state.hmacState.hashState));
|
|
CryptCompleteHMAC2B(&(hashObject->state.hmacState), &out->result.b);
|
|
|
|
// No ticket is generated for HMAC sequence
|
|
out->validation.tag = TPM_ST_HASHCHECK;
|
|
out->validation.hierarchy = TPM_RH_NULL;
|
|
out->validation.digest.t.size = 0;
|
|
}
|
|
|
|
// Internal Data Update
|
|
|
|
// mark sequence object as evict so it will be flushed on the way out
|
|
object->attributes.evict = SET;
|
|
|
|
return TPM_RC_SUCCESS;
|
|
}
|