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
PolicyParameterChecks(SESSION * session,UINT64 authTimeout,TPM2B_DIGEST * cpHashA,TPM2B_NONCE * nonce,TPM_RC nonceParameterNumber,TPM_RC cpHashParameterNumber,TPM_RC expirationParameterNumber)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
PolicyContextUpdate(TPM_CC commandCode,TPM2B_NAME * name,TPM2B_NONCE * ref,TPM2B_DIGEST * cpHash,UINT64 policyTimeout,SESSION * session)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