/src/libtpms/src/tpm2/Handle.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* fUnctions that return the type of a handle. */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* */ |
7 | | /* Licenses and Notices */ |
8 | | /* */ |
9 | | /* 1. Copyright Licenses: */ |
10 | | /* */ |
11 | | /* - Trusted Computing Group (TCG) grants to the user of the source code in */ |
12 | | /* this specification (the "Source Code") a worldwide, irrevocable, */ |
13 | | /* nonexclusive, royalty free, copyright license to reproduce, create */ |
14 | | /* derivative works, distribute, display and perform the Source Code and */ |
15 | | /* derivative works thereof, and to grant others the rights granted herein. */ |
16 | | /* */ |
17 | | /* - The TCG grants to the user of the other parts of the specification */ |
18 | | /* (other than the Source Code) the rights to reproduce, distribute, */ |
19 | | /* display, and perform the specification solely for the purpose of */ |
20 | | /* developing products based on such documents. */ |
21 | | /* */ |
22 | | /* 2. Source Code Distribution Conditions: */ |
23 | | /* */ |
24 | | /* - Redistributions of Source Code must retain the above copyright licenses, */ |
25 | | /* this list of conditions and the following disclaimers. */ |
26 | | /* */ |
27 | | /* - Redistributions in binary form must reproduce the above copyright */ |
28 | | /* licenses, this list of conditions and the following disclaimers in the */ |
29 | | /* documentation and/or other materials provided with the distribution. */ |
30 | | /* */ |
31 | | /* 3. Disclaimers: */ |
32 | | /* */ |
33 | | /* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */ |
34 | | /* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */ |
35 | | /* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */ |
36 | | /* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */ |
37 | | /* Contact TCG Administration (admin@trustedcomputinggroup.org) for */ |
38 | | /* information on specification licensing rights available through TCG */ |
39 | | /* membership agreements. */ |
40 | | /* */ |
41 | | /* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */ |
42 | | /* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */ |
43 | | /* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */ |
44 | | /* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */ |
45 | | /* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */ |
46 | | /* */ |
47 | | /* - Without limitation, TCG and its members and licensors disclaim all */ |
48 | | /* liability, including liability for infringement of any proprietary */ |
49 | | /* rights, relating to use of information in this specification and to the */ |
50 | | /* implementation of this specification, and TCG disclaims all liability for */ |
51 | | /* cost of procurement of substitute goods or services, lost profits, loss */ |
52 | | /* of use, loss of data or any incidental, consequential, direct, indirect, */ |
53 | | /* or special damages, whether under contract, tort, warranty or otherwise, */ |
54 | | /* arising in any way out of use or reliance upon this specification or any */ |
55 | | /* information herein. */ |
56 | | /* */ |
57 | | /* (c) Copyright IBM Corp. and others, 2016 - 2023 */ |
58 | | /* */ |
59 | | /********************************************************************************/ |
60 | | |
61 | | //** Description |
62 | | // This file contains the functions that return the type of a handle. |
63 | | |
64 | | //** Includes |
65 | | #include "Tpm.h" |
66 | | |
67 | | //** Functions |
68 | | |
69 | | //*** HandleGetType() |
70 | | // This function returns the type of a handle which is the MSO of the handle. |
71 | | TPM_HT |
72 | | HandleGetType(TPM_HANDLE handle // IN: a handle to be checked |
73 | | ) |
74 | 13.7k | { |
75 | | // return the upper bytes of input data |
76 | 13.7k | return (TPM_HT)((handle & HR_RANGE_MASK) >> HR_SHIFT); |
77 | 13.7k | } |
78 | | |
79 | | //*** NextPermanentHandle() |
80 | | // This function returns the permanent handle that is equal to the input value or |
81 | | // is the next higher value. If there is no handle with the input value and there |
82 | | // is no next higher value, it returns 0: |
83 | | TPM_HANDLE |
84 | | NextPermanentHandle(TPM_HANDLE inHandle // IN: the handle to check |
85 | | ) |
86 | 371 | { |
87 | | // If inHandle is below the start of the range of permanent handles |
88 | | // set it to the start and scan from there |
89 | 371 | if(inHandle < TPM_RH_FIRST) |
90 | 0 | inHandle = TPM_RH_FIRST; |
91 | | // scan from input value until we find an implemented permanent handle |
92 | | // or go out of range |
93 | 12.5k | for(; inHandle <= TPM_RH_LAST; inHandle++) |
94 | 12.3k | { |
95 | | // Skip over gaps in the reserved handle space. |
96 | 12.3k | if(inHandle > TPM_RH_FW_NULL && inHandle < SVN_OWNER_FIRST) |
97 | 77 | inHandle = SVN_OWNER_FIRST; |
98 | 12.3k | if(inHandle > SVN_OWNER_FIRST && inHandle <= SVN_OWNER_LAST) |
99 | 105 | inHandle = SVN_ENDORSEMENT_FIRST; |
100 | 12.3k | if(inHandle > SVN_ENDORSEMENT_FIRST && inHandle <= SVN_ENDORSEMENT_LAST) |
101 | 126 | inHandle = SVN_PLATFORM_FIRST; |
102 | 12.3k | if(inHandle > SVN_PLATFORM_FIRST && inHandle <= SVN_PLATFORM_LAST) |
103 | 156 | inHandle = SVN_NULL_FIRST; |
104 | 12.3k | if(inHandle > SVN_NULL_FIRST) |
105 | 190 | inHandle = TPM_RH_LAST; |
106 | | |
107 | 12.3k | switch(inHandle) |
108 | 12.3k | { |
109 | 6 | case TPM_RH_OWNER: |
110 | 28 | case TPM_RH_NULL: |
111 | 53 | case TPM_RS_PW: |
112 | 79 | case TPM_RH_LOCKOUT: |
113 | 104 | case TPM_RH_ENDORSEMENT: |
114 | 128 | case TPM_RH_PLATFORM: |
115 | 152 | case TPM_RH_PLATFORM_NV: |
116 | | #if FW_LIMITED_SUPPORT |
117 | | case TPM_RH_FW_OWNER: |
118 | | case TPM_RH_FW_ENDORSEMENT: |
119 | | case TPM_RH_FW_PLATFORM: |
120 | | case TPM_RH_FW_NULL: |
121 | | #endif |
122 | | #if SVN_LIMITED_SUPPORT |
123 | | case TPM_RH_SVN_OWNER_BASE: |
124 | | case TPM_RH_SVN_ENDORSEMENT_BASE: |
125 | | case TPM_RH_SVN_PLATFORM_BASE: |
126 | | case TPM_RH_SVN_NULL_BASE: |
127 | | #endif |
128 | | #if VENDOR_PERMANENT_AUTH_ENABLED == YES |
129 | | case VENDOR_PERMANENT_AUTH_HANDLE: |
130 | | #endif |
131 | | // Each of the implemented ACT |
132 | 152 | #define ACT_IMPLEMENTED_CASE(N) case TPM_RH_ACT_##N: |
133 | | |
134 | 152 | FOR_EACH_ACT(ACT_IMPLEMENTED_CASE) |
135 | | |
136 | 152 | return inHandle; |
137 | 0 | break; |
138 | 12.1k | default: |
139 | 12.1k | break; |
140 | 12.3k | } |
141 | 12.3k | } |
142 | | // Out of range on the top |
143 | 219 | return 0; |
144 | 371 | } |
145 | | |
146 | | //*** PermanentCapGetHandles() |
147 | | // This function returns a list of the permanent handles of PCR, started from |
148 | | // 'handle'. If 'handle' is larger than the largest permanent handle, an empty list |
149 | | // will be returned with 'more' set to NO. |
150 | | // Return Type: TPMI_YES_NO |
151 | | // YES if there are more handles available |
152 | | // NO all the available handles has been returned |
153 | | TPMI_YES_NO |
154 | | PermanentCapGetHandles(TPM_HANDLE handle, // IN: start handle |
155 | | UINT32 count, // IN: count of returned handles |
156 | | TPML_HANDLE* handleList // OUT: list of handle |
157 | | ) |
158 | 108 | { |
159 | 108 | TPMI_YES_NO more = NO; |
160 | 108 | UINT32 i; |
161 | | |
162 | 108 | pAssert(HandleGetType(handle) == TPM_HT_PERMANENT); |
163 | | |
164 | | // Initialize output handle list |
165 | 108 | handleList->count = 0; |
166 | | |
167 | | // The maximum count of handles we may return is MAX_CAP_HANDLES |
168 | 108 | if(count > MAX_CAP_HANDLES) |
169 | 99 | count = MAX_CAP_HANDLES; |
170 | | |
171 | | // Iterate permanent handle range |
172 | 173 | for(i = NextPermanentHandle(handle); i != 0; i = NextPermanentHandle(i + 1)) |
173 | 69 | { |
174 | 69 | if(handleList->count < count) |
175 | 65 | { |
176 | | // If we have not filled up the return list, add this permanent |
177 | | // handle to it |
178 | 65 | handleList->handle[handleList->count] = i; |
179 | 65 | handleList->count++; |
180 | 65 | } |
181 | 4 | else |
182 | 4 | { |
183 | | // If the return list is full but we still have permanent handle |
184 | | // available, report this and stop iterating |
185 | 4 | more = YES; |
186 | 4 | break; |
187 | 4 | } |
188 | 69 | } |
189 | 108 | return more; |
190 | 108 | } |
191 | | |
192 | | //*** PermanentCapGetOneHandle() |
193 | | // This function returns whether a permanent handle exists. |
194 | | BOOL PermanentCapGetOneHandle(TPM_HANDLE handle) // IN: handle |
195 | 0 | { |
196 | 0 | UINT32 i; |
197 | | |
198 | 0 | pAssert(HandleGetType(handle) == TPM_HT_PERMANENT); |
199 | | |
200 | | // Iterate permanent handle range |
201 | 0 | for(i = NextPermanentHandle(handle); i != 0; i = NextPermanentHandle(i + 1)) |
202 | 0 | { |
203 | 0 | if(i == handle) |
204 | 0 | { |
205 | 0 | return TRUE; |
206 | 0 | } |
207 | 0 | } |
208 | 0 | return FALSE; |
209 | 0 | } |
210 | | |
211 | | //*** PermanentHandleGetPolicy() |
212 | | // This function returns a list of the permanent handles of PCR, started from |
213 | | // 'handle'. If 'handle' is larger than the largest permanent handle, an empty list |
214 | | // will be returned with 'more' set to NO. |
215 | | // Return Type: TPMI_YES_NO |
216 | | // YES if there are more handles available |
217 | | // NO all the available handles has been returned |
218 | | TPMI_YES_NO |
219 | | PermanentHandleGetPolicy(TPM_HANDLE handle, // IN: start handle |
220 | | UINT32 count, // IN: max count of returned handles |
221 | | TPML_TAGGED_POLICY* policyList // OUT: list of handle |
222 | | ) |
223 | 120 | { |
224 | 120 | TPMI_YES_NO more = NO; |
225 | | |
226 | 120 | pAssert(HandleGetType(handle) == TPM_HT_PERMANENT); |
227 | | |
228 | | // Initialize output handle list |
229 | 120 | policyList->count = 0; |
230 | | |
231 | | // The maximum count of policies we may return is MAX_TAGGED_POLICIES |
232 | 120 | if(count > MAX_TAGGED_POLICIES) |
233 | 109 | count = MAX_TAGGED_POLICIES; |
234 | | |
235 | | // Iterate permanent handle range |
236 | 198 | for(handle = NextPermanentHandle(handle); handle != 0; |
237 | 120 | handle = NextPermanentHandle(handle + 1)) |
238 | 83 | { |
239 | 83 | TPM2B_DIGEST policyDigest; |
240 | 83 | TPM_ALG_ID policyAlg; |
241 | | // Check to see if this permanent handle has a policy |
242 | 83 | policyAlg = EntityGetAuthPolicy(handle, &policyDigest); |
243 | 83 | if(policyAlg == TPM_ALG_ERROR) |
244 | 38 | continue; |
245 | 45 | if(policyList->count < count) |
246 | 40 | { |
247 | | // If we have not filled up the return list, add this |
248 | | // policy to the list; |
249 | 40 | policyList->policies[policyList->count].handle = handle; |
250 | 40 | policyList->policies[policyList->count].policyHash.hashAlg = policyAlg; |
251 | 40 | MemoryCopy(&policyList->policies[policyList->count].policyHash.digest, |
252 | 40 | policyDigest.t.buffer, |
253 | 40 | policyDigest.t.size); |
254 | 40 | policyList->count++; |
255 | 40 | } |
256 | 5 | else |
257 | 5 | { |
258 | | // If the return list is full but we still have permanent handle |
259 | | // available, report this and stop iterating |
260 | 5 | more = YES; |
261 | 5 | break; |
262 | 5 | } |
263 | 45 | } |
264 | 120 | return more; |
265 | 120 | } |
266 | | |
267 | | //*** PermanentHandleGetOnePolicy() |
268 | | // This function returns a permanent handle's policy, if present. |
269 | | BOOL PermanentHandleGetOnePolicy(TPM_HANDLE handle, // IN: handle |
270 | | TPMS_TAGGED_POLICY* policy // OUT: tagged policy |
271 | | ) |
272 | 0 | { |
273 | 0 | pAssert(HandleGetType(handle) == TPM_HT_PERMANENT); |
274 | | |
275 | 0 | if(NextPermanentHandle(handle) == handle) |
276 | 0 | { |
277 | 0 | TPM2B_DIGEST policyDigest; |
278 | 0 | TPM_ALG_ID policyAlg; |
279 | | // Check to see if this permanent handle has a policy |
280 | 0 | policyAlg = EntityGetAuthPolicy(handle, &policyDigest); |
281 | 0 | if(policyAlg == TPM_ALG_ERROR) |
282 | 0 | { |
283 | 0 | return FALSE; |
284 | 0 | } |
285 | 0 | policy->handle = handle; |
286 | 0 | policy->policyHash.hashAlg = policyAlg; |
287 | 0 | MemoryCopy( |
288 | 0 | &policy->policyHash.digest, policyDigest.t.buffer, policyDigest.t.size); |
289 | 0 | return TRUE; |
290 | 0 | } |
291 | 0 | return FALSE; |
292 | 0 | } |