Coverage Report

Created: 2025-07-11 06:08

/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
}