Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include   "InternalRoutines.h"
      9 #include   "Policy_spt_fp.h"
     10 #include   "PolicySigned_fp.h"
     11 #include   "PolicySecret_fp.h"
     12 #include   "PolicyTicket_fp.h"
     13 //
     14 //
     15 //           PolicyParameterChecks()
     16 //
     17 //      This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The
     18 //      common parameters are nonceTPM, expiration, and cpHashA.
     19 //
     20 TPM_RC
     21 PolicyParameterChecks(
     22      SESSION          *session,
     23      UINT64            authTimeout,
     24      TPM2B_DIGEST     *cpHashA,
     25      TPM2B_NONCE      *nonce,
     26      TPM_RC            nonceParameterNumber,
     27      TPM_RC            cpHashParameterNumber,
     28      TPM_RC            expirationParameterNumber
     29      )
     30 {
     31      TPM_RC            result;
     32      // Validate that input nonceTPM is correct if present
     33      if(nonce != NULL && nonce->t.size != 0)
     34 //
     35    {
     36          if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b))
     37              return TPM_RC_NONCE + RC_PolicySigned_nonceTPM;
     38    }
     39    // If authTimeout is set (expiration != 0...
     40    if(authTimeout != 0)
     41    {
     42        // ...then nonce must be present
     43        // nonce present isn't checked in PolicyTicket
     44        if(nonce != NULL && nonce->t.size == 0)
     45            // This error says that the time has expired but it is pointing
     46            // at the nonceTPM value.
     47            return TPM_RC_EXPIRED + nonceParameterNumber;
     48          // Validate input expiration.
     49          // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE
     50          // or TPM_RC_NV_RATE error may be returned here.
     51          result = NvIsAvailable();
     52          if(result != TPM_RC_SUCCESS)
     53              return result;
     54          if(authTimeout < go.clock)
     55              return TPM_RC_EXPIRED + expirationParameterNumber;
     56    }
     57    // If the cpHash is present, then check it
     58    if(cpHashA != NULL && cpHashA->t.size != 0)
     59    {
     60        // The cpHash input has to have the correct size
     61        if(cpHashA->t.size != session->u2.policyDigest.t.size)
     62            return TPM_RC_SIZE + cpHashParameterNumber;
     63          // If the cpHash has already been set, then this input value
     64          // must match the current value.
     65          if(     session->u1.cpHash.b.size != 0
     66              && !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b))
     67                  return TPM_RC_CPHASH;
     68    }
     69    return TPM_RC_SUCCESS;
     70 }
     71 //
     72 //
     73 //          PolicyContextUpdate()
     74 //
     75 //     Update policy hash Update the policyDigest in policy session by extending policyRef and objectName to
     76 //     it. This will also update the cpHash if it is present.
     77 //
     78 void
     79 PolicyContextUpdate(
     80    TPM_CC              commandCode,     //   IN:   command code
     81    TPM2B_NAME         *name,            //   IN:   name of entity
     82    TPM2B_NONCE        *ref,             //   IN:   the reference data
     83    TPM2B_DIGEST       *cpHash,          //   IN:   the cpHash (optional)
     84    UINT64              policyTimeout,
     85    SESSION            *session          // IN/OUT: policy session to be updated
     86    )
     87 {
     88    HASH_STATE               hashState;
     89    UINT16                   policyDigestSize;
     90    // Start hash
     91    policyDigestSize = CryptStartHash(session->authHashAlg, &hashState);
     92    // policyDigest size should always be the digest size of session hash algorithm.
     93    pAssert(session->u2.policyDigest.t.size == policyDigestSize);
     94      // add old digest
     95      CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
     96      // add commandCode
     97      CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode);
     98      // add name if applicable
     99      if(name != NULL)
    100          CryptUpdateDigest2B(&hashState, &name->b);
    101      // Complete the digest and get the results
    102      CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
    103      // Start second hash computation
    104      CryptStartHash(session->authHashAlg, &hashState);
    105      // add policyDigest
    106      CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
    107      // add policyRef
    108      if(ref != NULL)
    109          CryptUpdateDigest2B(&hashState, &ref->b);
    110      // Complete second digest
    111      CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
    112      // Deal with the cpHash. If the cpHash value is present
    113      // then it would have already been checked to make sure that
    114      // it is compatible with the current value so all we need
    115      // to do here is copy it and set the iscoHashDefined attribute
    116      if(cpHash != NULL && cpHash->t.size != 0)
    117      {
    118          session->u1.cpHash = *cpHash;
    119          session->attributes.iscpHashDefined = SET;
    120      }
    121      // update the timeout if it is specified
    122      if(policyTimeout!= 0)
    123      {
    124      // If the timeout has not been set, then set it to the new value
    125          if(session->timeOut == 0)
    126              session->timeOut = policyTimeout;
    127          else if(session->timeOut > policyTimeout)
    128              session->timeOut = policyTimeout;
    129      }
    130      return;
    131 }
    132