Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
31 | 0 | TPM_RC result; |
32 | | // Validate that input nonceTPM is correct if present |
33 | 0 | if(nonce != NULL && nonce->t.size != 0) |
34 | | // |
35 | 0 | { |
36 | 0 | if(!Memory2BEqual(&nonce->b, &session->nonceTPM.b)) |
37 | 0 | return TPM_RC_NONCE + RC_PolicySigned_nonceTPM; |
38 | 0 | } |
39 | | // If authTimeout is set (expiration != 0... |
40 | 0 | if(authTimeout != 0) |
41 | 0 | { |
42 | | // ...then nonce must be present |
43 | | // nonce present isn't checked in PolicyTicket |
44 | 0 | 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 | 0 | 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 | 0 | result = NvIsAvailable(); |
52 | 0 | if(result != TPM_RC_SUCCESS) |
53 | 0 | return result; |
54 | 0 | if(authTimeout < go.clock) |
55 | 0 | return TPM_RC_EXPIRED + expirationParameterNumber; |
56 | 0 | } |
57 | | // If the cpHash is present, then check it |
58 | 0 | if(cpHashA != NULL && cpHashA->t.size != 0) |
59 | 0 | { |
60 | | // The cpHash input has to have the correct size |
61 | 0 | if(cpHashA->t.size != session->u2.policyDigest.t.size) |
62 | 0 | return TPM_RC_SIZE + cpHashParameterNumber; |
63 | | // If the cpHash has already been set, then this input value |
64 | | // must match the current value. |
65 | 0 | if( session->u1.cpHash.b.size != 0 |
66 | 0 | && !Memory2BEqual(&cpHashA->b, &session->u1.cpHash.b)) |
67 | 0 | return TPM_RC_CPHASH; |
68 | 0 | } |
69 | 0 | return TPM_RC_SUCCESS; |
70 | 0 | } |
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 | 0 | { |
88 | 0 | HASH_STATE hashState; |
89 | 0 | UINT16 policyDigestSize; |
90 | | // Start hash |
91 | 0 | policyDigestSize = CryptStartHash(session->authHashAlg, &hashState); |
92 | | // policyDigest size should always be the digest size of session hash algorithm. |
93 | 0 | pAssert(session->u2.policyDigest.t.size == policyDigestSize); |
94 | | // add old digest |
95 | 0 | CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); |
96 | | // add commandCode |
97 | 0 | CryptUpdateDigestInt(&hashState, sizeof(commandCode), &commandCode); |
98 | | // add name if applicable |
99 | 0 | if(name != NULL) |
100 | 0 | CryptUpdateDigest2B(&hashState, &name->b); |
101 | | // Complete the digest and get the results |
102 | 0 | CryptCompleteHash2B(&hashState, &session->u2.policyDigest.b); |
103 | | // Start second hash computation |
104 | 0 | CryptStartHash(session->authHashAlg, &hashState); |
105 | | // add policyDigest |
106 | 0 | CryptUpdateDigest2B(&hashState, &session->u2.policyDigest.b); |
107 | | // add policyRef |
108 | 0 | if(ref != NULL) |
109 | 0 | CryptUpdateDigest2B(&hashState, &ref->b); |
110 | | // Complete second digest |
111 | 0 | 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 | 0 | if(cpHash != NULL && cpHash->t.size != 0) |
117 | 0 | { |
118 | 0 | session->u1.cpHash = *cpHash; |
119 | 0 | session->attributes.iscpHashDefined = SET; |
120 | 0 | } |
121 | | // update the timeout if it is specified |
122 | 0 | if(policyTimeout!= 0) |
123 | 0 | { |
124 | | // If the timeout has not been set, then set it to the new value |
125 | 0 | if(session->timeOut == 0) |
126 | 0 | session->timeOut = policyTimeout; |
127 | 0 | else if(session->timeOut > policyTimeout) |
128 | 0 | session->timeOut = policyTimeout; |
129 | 0 | } |
130 | 0 | return; |
131 | 0 | } |