1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 //** Description
36 // This file contains the functions that return the type of a handle.
37
38 //** Includes
39 #include "Tpm.h"
40
41 //** Functions
42
43 //*** HandleGetType()
44 // This function returns the type of a handle which is the MSO of the handle.
45 TPM_HT
HandleGetType(TPM_HANDLE handle)46 HandleGetType(
47 TPM_HANDLE handle // IN: a handle to be checked
48 )
49 {
50 // return the upper bytes of input data
51 return (TPM_HT)((handle & HR_RANGE_MASK) >> HR_SHIFT);
52 }
53
54 //*** NextPermanentHandle()
55 // This function returns the permanent handle that is equal to the input value or
56 // is the next higher value. If there is no handle with the input value and there
57 // is no next higher value, it returns 0:
58 TPM_HANDLE
NextPermanentHandle(TPM_HANDLE inHandle)59 NextPermanentHandle(
60 TPM_HANDLE inHandle // IN: the handle to check
61 )
62 {
63 // If inHandle is below the start of the range of permanent handles
64 // set it to the start and scan from there
65 if(inHandle < TPM_RH_FIRST)
66 inHandle = TPM_RH_FIRST;
67 // scan from input value until we find an implemented permanent handle
68 // or go out of range
69 for(; inHandle <= TPM_RH_LAST; inHandle++)
70 {
71 switch(inHandle)
72 {
73 case TPM_RH_OWNER:
74 case TPM_RH_NULL:
75 case TPM_RS_PW:
76 case TPM_RH_LOCKOUT:
77 case TPM_RH_ENDORSEMENT:
78 case TPM_RH_PLATFORM:
79 case TPM_RH_PLATFORM_NV:
80 #ifdef VENDOR_PERMANENT
81 case VENDOR_PERMANENT:
82 #endif
83 // Each of the implemented ACT
84 #define ACT_IMPLEMENTED_CASE(N) \
85 case TPM_RH_ACT_##N:
86
87 FOR_EACH_ACT(ACT_IMPLEMENTED_CASE)
88
89 return inHandle;
90 break;
91 default:
92 break;
93 }
94 }
95 // Out of range on the top
96 return 0;
97 }
98
99 //*** PermanentCapGetHandles()
100 // This function returns a list of the permanent handles of PCR, started from
101 // 'handle'. If 'handle' is larger than the largest permanent handle, an empty list
102 // will be returned with 'more' set to NO.
103 // Return Type: TPMI_YES_NO
104 // YES if there are more handles available
105 // NO all the available handles has been returned
106 TPMI_YES_NO
PermanentCapGetHandles(TPM_HANDLE handle,UINT32 count,TPML_HANDLE * handleList)107 PermanentCapGetHandles(
108 TPM_HANDLE handle, // IN: start handle
109 UINT32 count, // IN: count of returned handles
110 TPML_HANDLE *handleList // OUT: list of handle
111 )
112 {
113 TPMI_YES_NO more = NO;
114 UINT32 i;
115
116 pAssert(HandleGetType(handle) == TPM_HT_PERMANENT);
117
118 // Initialize output handle list
119 handleList->count = 0;
120
121 // The maximum count of handles we may return is MAX_CAP_HANDLES
122 if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
123
124 // Iterate permanent handle range
125 for(i = NextPermanentHandle(handle);
126 i != 0; i = NextPermanentHandle(i + 1))
127 {
128 if(handleList->count < count)
129 {
130 // If we have not filled up the return list, add this permanent
131 // handle to it
132 handleList->handle[handleList->count] = i;
133 handleList->count++;
134 }
135 else
136 {
137 // If the return list is full but we still have permanent handle
138 // available, report this and stop iterating
139 more = YES;
140 break;
141 }
142 }
143 return more;
144 }
145
146 //*** PermanentHandleGetPolicy()
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
PermanentHandleGetPolicy(TPM_HANDLE handle,UINT32 count,TPML_TAGGED_POLICY * policyList)154 PermanentHandleGetPolicy(
155 TPM_HANDLE handle, // IN: start handle
156 UINT32 count, // IN: max count of returned handles
157 TPML_TAGGED_POLICY *policyList // OUT: list of handle
158 )
159 {
160 TPMI_YES_NO more = NO;
161
162 pAssert(HandleGetType(handle) == TPM_HT_PERMANENT);
163
164 // Initialize output handle list
165 policyList->count = 0;
166
167 // The maximum count of policies we may return is MAX_TAGGED_POLICIES
168 if(count > MAX_TAGGED_POLICIES)
169 count = MAX_TAGGED_POLICIES;
170
171 // Iterate permanent handle range
172 for(handle = NextPermanentHandle(handle);
173 handle != 0;
174 handle = NextPermanentHandle(handle + 1))
175 {
176 TPM2B_DIGEST policyDigest;
177 TPM_ALG_ID policyAlg;
178 // Check to see if this permanent handle has a policy
179 policyAlg = EntityGetAuthPolicy(handle, &policyDigest);
180 if(policyAlg == TPM_ALG_ERROR)
181 continue;
182 if(policyList->count < count)
183 {
184 // If we have not filled up the return list, add this
185 // policy to the list;
186 policyList->policies[policyList->count].handle = handle;
187 policyList->policies[policyList->count].policyHash.hashAlg = policyAlg;
188 MemoryCopy(&policyList->policies[policyList->count].policyHash.digest,
189 policyDigest.t.buffer, policyDigest.t.size);
190 policyList->count++;
191 }
192 else
193 {
194 // If the return list is full but we still have permanent handle
195 // available, report this and stop iterating
196 more = YES;
197 break;
198 }
199 }
200 return more;
201 }
202