• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
TPM2_PolicyPCR(PolicyPCR_In * in)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