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