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 "PolicyPCR_fp.h"
     10 //
     11 //
     12 //     Error Returns                     Meaning
     13 //
     14 //     TPM_RC_VALUE                      if provided, pcrDigest does not match the current PCR settings
     15 //     TPM_RC_PCR_CHANGED                a previous TPM2_PolicyPCR() set pcrCounter and it has changed
     16 //
     17 TPM_RC
     18 TPM2_PolicyPCR(
     19    PolicyPCR_In      *in                 // IN: input parameter list
     20    )
     21 {
     22    SESSION           *session;
     23    TPM2B_DIGEST       pcrDigest;
     24    BYTE               pcrs[sizeof(TPML_PCR_SELECTION)];
     25    UINT32             pcrSize;
     26    BYTE              *buffer;
     27    INT32              bufferSize;
     28    TPM_CC             commandCode = TPM_CC_PolicyPCR;
     29    HASH_STATE         hashState;
     30 
     31 // Input Validation
     32 
     33    // Get pointer to the session structure
     34    session = SessionGet(in->policySession);
     35 
     36    // Do validation for non trial session
     37    if(session->attributes.isTrialPolicy == CLEAR)
     38    {
     39        // Make sure that this is not going to invalidate a previous PCR check
     40        if(session->pcrCounter != 0 && session->pcrCounter != gr.pcrCounter)
     41            return TPM_RC_PCR_CHANGED;
     42 
     43        // Compute current PCR digest
     44        PCRComputeCurrentDigest(session->authHashAlg, &in->pcrs, &pcrDigest);
     45 
     46        // If the caller specified the PCR digest and it does not
     47        // match the current PCR settings, return an error..
     48        if(in->pcrDigest.t.size != 0)
     49        {
     50            if(!Memory2BEqual(&in->pcrDigest.b, &pcrDigest.b))
     51                return TPM_RC_VALUE + RC_PolicyPCR_pcrDigest;
     52        }
     53    }
     54    else
     55    {
     56        // For trial session, just use the input PCR digest
     57        pcrDigest = in->pcrDigest;
     58    }
     59 // Internal Data Update
     60 
     61    // Update policy hash
     62    // policyDigestnew = hash(   policyDigestold || TPM_CC_PolicyPCR
     63    //                      || pcrs || pcrDigest)
     64    // Start hash
     65    CryptStartHash(session->authHashAlg, &hashState);
     66 
     67    // add old digest
     68    CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b);
     69 
     70   // add commandCode
     71   CryptUpdateDigestInt(&hashState, sizeof(TPM_CC), &commandCode);
     72 
     73   // add PCRS
     74   buffer = pcrs;
     75   bufferSize = sizeof(TPML_PCR_SELECTION);
     76   pcrSize = TPML_PCR_SELECTION_Marshal(&in->pcrs, &buffer, &bufferSize);
     77   CryptUpdateDigest(&hashState, pcrSize, pcrs);
     78 
     79   // add PCR digest
     80   CryptUpdateDigest2B(&hashState, &pcrDigest.b);
     81 
     82   // complete the hash and get the results
     83   CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b);
     84 
     85   // update pcrCounter in session context for non trial session
     86   if(session->attributes.isTrialPolicy == CLEAR)
     87   {
     88       session->pcrCounter = gr.pcrCounter;
     89   }
     90 
     91    return TPM_RC_SUCCESS;
     92 }
     93