VirtualBox

source: vbox/trunk/src/libs/libtpms-0.9.0/src/tpm2/Policy_spt.c@ 91612

最後變更 在這個檔案從91612是 91612,由 vboxsync 提交於 3 年 前

src/libs: Export libtpms-0.9.0, bugref:10078

檔案大小: 11.3 KB
 
1/********************************************************************************/
2/* */
3/* Policy Command Support */
4/* Written by Ken Goldman */
5/* IBM Thomas J. Watson Research Center */
6/* $Id: Policy_spt.c 1594 2020-03-26 22:15:48Z kgoldman $ */
7/* */
8/* Licenses and Notices */
9/* */
10/* 1. Copyright Licenses: */
11/* */
12/* - Trusted Computing Group (TCG) grants to the user of the source code in */
13/* this specification (the "Source Code") a worldwide, irrevocable, */
14/* nonexclusive, royalty free, copyright license to reproduce, create */
15/* derivative works, distribute, display and perform the Source Code and */
16/* derivative works thereof, and to grant others the rights granted herein. */
17/* */
18/* - The TCG grants to the user of the other parts of the specification */
19/* (other than the Source Code) the rights to reproduce, distribute, */
20/* display, and perform the specification solely for the purpose of */
21/* developing products based on such documents. */
22/* */
23/* 2. Source Code Distribution Conditions: */
24/* */
25/* - Redistributions of Source Code must retain the above copyright licenses, */
26/* this list of conditions and the following disclaimers. */
27/* */
28/* - Redistributions in binary form must reproduce the above copyright */
29/* licenses, this list of conditions and the following disclaimers in the */
30/* documentation and/or other materials provided with the distribution. */
31/* */
32/* 3. Disclaimers: */
33/* */
34/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
35/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
36/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
37/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
38/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
39/* information on specification licensing rights available through TCG */
40/* membership agreements. */
41/* */
42/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
43/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
44/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
45/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
46/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
47/* */
48/* - Without limitation, TCG and its members and licensors disclaim all */
49/* liability, including liability for infringement of any proprietary */
50/* rights, relating to use of information in this specification and to the */
51/* implementation of this specification, and TCG disclaims all liability for */
52/* cost of procurement of substitute goods or services, lost profits, loss */
53/* of use, loss of data or any incidental, consequential, direct, indirect, */
54/* or special damages, whether under contract, tort, warranty or otherwise, */
55/* arising in any way out of use or reliance upon this specification or any */
56/* information herein. */
57/* */
58/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
59/* */
60/********************************************************************************/
61
62/* 7.4 Policy Command Support (Policy_spt.c) */
63#include "Tpm.h"
64#include "Policy_spt_fp.h"
65#include "PolicySigned_fp.h"
66#include "PolicySecret_fp.h"
67#include "PolicyTicket_fp.h"
68/* 7.4.1 PolicyParameterChecks() */
69/* This function validates the common parameters of TPM2_PolicySiged() and TPM2_PolicySecret(). The
70 common parameters are nonceTPM, expiration, and cpHashA. */
71TPM_RC
72PolicyParameterChecks(
73 SESSION *session,
74 UINT64 authTimeout,
75 TPM2B_DIGEST *cpHashA,
76 TPM2B_NONCE *nonce,
77 TPM_RC blameNonce,
78 TPM_RC blameCpHash,
79 TPM_RC blameExpiration
80 )
81{
82 // Validate that input nonceTPM is correct if present
83 if(nonce != NULL && nonce->t.size != 0)
84 {
85 if(!MemoryEqual2B(&nonce->b, &session->nonceTPM.b))
86 return TPM_RCS_NONCE + blameNonce;
87 }
88 // If authTimeout is set (expiration != 0...
89 if(authTimeout != 0)
90 {
91 // Validate input expiration.
92 // Cannot compare time if clock stop advancing. A TPM_RC_NV_UNAVAILABLE
93 // or TPM_RC_NV_RATE error may be returned here.
94 RETURN_IF_NV_IS_NOT_AVAILABLE;
95 // if the time has already passed or the time epoch has changed then the
96 // time value is no longer good.
97 if((authTimeout < g_time)
98 || (session->epoch != g_timeEpoch))
99 return TPM_RCS_EXPIRED + blameExpiration;
100 }
101 // If the cpHash is present, then check it
102 if(cpHashA != NULL && cpHashA->t.size != 0)
103 {
104 // The cpHash input has to have the correct size
105 if(cpHashA->t.size != session->u2.policyDigest.t.size)
106 return TPM_RCS_SIZE + blameCpHash;
107 // If the cpHash has already been set, then this input value
108 // must match the current value.
109 if(session->u1.cpHash.b.size != 0
110 && !MemoryEqual2B(&cpHashA->b, &session->u1.cpHash.b))
111 return TPM_RC_CPHASH;
112 }
113 return TPM_RC_SUCCESS;
114}
115/* 7.4.2 PolicyContextUpdate() */
116/* Update policy hash Update the policyDigest in policy session by extending policyRef and
117 objectName to it. This will also update the cpHash if it is present. */
118void
119PolicyContextUpdate(
120 TPM_CC commandCode, // IN: command code
121 TPM2B_NAME *name, // IN: name of entity
122 TPM2B_NONCE *ref, // IN: the reference data
123 TPM2B_DIGEST *cpHash, // IN: the cpHash (optional)
124 UINT64 policyTimeout, // IN: the timeout value for the policy
125 SESSION *session // IN/OUT: policy session to be updated
126 )
127{
128 HASH_STATE hashState;
129 // Start hash
130 CryptHashStart(&hashState, session->authHashAlg);
131 // policyDigest size should always be the digest size of session hash algorithm.
132 pAssert(session->u2.policyDigest.t.size
133 == CryptHashGetDigestSize(session->authHashAlg));
134 // add old digest
135 CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
136 // add commandCode
137 CryptDigestUpdateInt(&hashState, sizeof(commandCode), commandCode);
138 // add name if applicable
139 if(name != NULL)
140 CryptDigestUpdate2B(&hashState, &name->b);
141 // Complete the digest and get the results
142 CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
143 // If the policy reference is not null, do a second update to the digest.
144 if(ref != NULL)
145 {
146 // Start second hash computation
147 CryptHashStart(&hashState, session->authHashAlg);
148 // add policyDigest
149 CryptDigestUpdate2B(&hashState, &session->u2.policyDigest.b);
150 // add policyRef
151 CryptDigestUpdate2B(&hashState, &ref->b);
152 // Complete second digest
153 CryptHashEnd2B(&hashState, &session->u2.policyDigest.b);
154 }
155 // Deal with the cpHash. If the cpHash value is present
156 // then it would have already been checked to make sure that
157 // it is compatible with the current value so all we need
158 // to do here is copy it and set the isCpHashDefined attribute
159 if(cpHash != NULL && cpHash->t.size != 0)
160 {
161 session->u1.cpHash = *cpHash;
162 session->attributes.isCpHashDefined = SET;
163 }
164 // update the timeout if it is specified
165 if(policyTimeout != 0)
166 {
167 // If the timeout has not been set, then set it to the new value
168 // than the current timeout then set it to the new value
169 if(session->timeout == 0 || session->timeout > policyTimeout)
170 session->timeout = policyTimeout;
171 }
172 return;
173}
174/* 7.4.2.1 ComputeAuthTimeout() */
175/* This function is used to determine what the authorization timeout value for the session should
176 be. */
177UINT64
178ComputeAuthTimeout(
179 SESSION *session, // IN: the session containing the time
180 // values
181 INT32 expiration, // IN: either the number of seconds from
182 // the start of the session or the
183 // time in g_timer;
184 TPM2B_NONCE *nonce // IN: indicator of the time base
185 )
186{
187 UINT64 policyTime;
188 // If no expiration, policy time is 0
189 if(expiration == 0)
190 policyTime = 0;
191 else
192 {
193 if(expiration < 0) {
194 if (expiration == (INT32)0x80000000) /* libtpms changed begin; ubsan */
195 expiration++; /* libtpms changed end */
196 expiration = -expiration;
197 }
198 if(nonce->t.size == 0)
199 // The input time is absolute Time (not Clock), but it is expressed
200 // in seconds. To make sure that we don't time out too early, take the
201 // current value of milliseconds in g_time and add that to the input
202 // seconds value.
203 policyTime = (((UINT64)expiration) * 1000) + g_time % 1000;
204 else
205 // The policy timeout is the absolute value of the expiration in seconds
206 // added to the start time of the policy.
207 policyTime = session->startTime + (((UINT64)expiration) * 1000);
208 }
209 return policyTime;
210}
211/* 7.4.2.2 PolicyDigestClear() */
212/* Function to reset the policyDigest of a session */
213void
214PolicyDigestClear(
215 SESSION *session
216 )
217{
218 session->u2.policyDigest.t.size = CryptHashGetDigestSize(session->authHashAlg);
219 MemorySet(session->u2.policyDigest.t.buffer, 0,
220 session->u2.policyDigest.t.size);
221}
222
223/* 7.4.2.5 PolicySptCheckCondition() */
224/* Checks to see if the condition in the policy is satisfied. */
225
226BOOL
227PolicySptCheckCondition(
228 TPM_EO operation,
229 BYTE *opA,
230 BYTE *opB,
231 UINT16 size
232 )
233{
234 // Arithmetic Comparison
235 switch(operation)
236 {
237 case TPM_EO_EQ:
238 // compare A = B
239 return (UnsignedCompareB(size, opA, size, opB) == 0);
240 break;
241 case TPM_EO_NEQ:
242 // compare A != B
243 return (UnsignedCompareB(size, opA, size, opB) != 0);
244 break;
245 case TPM_EO_SIGNED_GT:
246 // compare A > B signed
247 return (SignedCompareB(size, opA, size, opB) > 0);
248 break;
249 case TPM_EO_UNSIGNED_GT:
250 // compare A > B unsigned
251 return (UnsignedCompareB(size, opA, size, opB) > 0);
252 break;
253 case TPM_EO_SIGNED_LT:
254 // compare A < B signed
255 return (SignedCompareB(size, opA, size, opB) < 0);
256 break;
257 case TPM_EO_UNSIGNED_LT:
258 // compare A < B unsigned
259 return (UnsignedCompareB(size, opA, size, opB) < 0);
260 break;
261 case TPM_EO_SIGNED_GE:
262 // compare A >= B signed
263 return (SignedCompareB(size, opA, size, opB) >= 0);
264 break;
265 case TPM_EO_UNSIGNED_GE:
266 // compare A >= B unsigned
267 return (UnsignedCompareB(size, opA, size, opB) >= 0);
268 break;
269 case TPM_EO_SIGNED_LE:
270 // compare A <= B signed
271 return (SignedCompareB(size, opA, size, opB) <= 0);
272 break;
273 case TPM_EO_UNSIGNED_LE:
274 // compare A <= B unsigned
275 return (UnsignedCompareB(size, opA, size, opB) <= 0);
276 break;
277 case TPM_EO_BITSET:
278 // All bits SET in B are SET in A. ((A&B)=B)
279 {
280 UINT32 i;
281 for(i = 0; i < size; i++)
282 if((opA[i] & opB[i]) != opB[i])
283 return FALSE;
284 }
285 break;
286 case TPM_EO_BITCLEAR:
287 // All bits SET in B are CLEAR in A. ((A&B)=0)
288 {
289 UINT32 i;
290 for(i = 0; i < size; i++)
291 if((opA[i] & opB[i]) != 0)
292 return FALSE;
293 }
294 break;
295 default:
296 FAIL(FATAL_ERROR_INTERNAL);
297 break;
298 }
299 return TRUE;
300}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette