blob: 95307004009e92bd6d86f22373d9226af7e4c3ac [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
20TPM_RC
21PolicyParameterChecks(
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//
78void
79PolicyContextUpdate(
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}