Coverage Report

Created: 2025-07-11 06:15

/src/tpm2/HierarchyControl.c
Line
Count
Source (jump to first uncovered line)
1
// This file was extracted from the TCG Published
2
// Trusted Platform Module Library
3
// Part 3: Commands
4
// Family "2.0"
5
// Level 00 Revision 01.16
6
// October 30, 2014
7
8
#include "InternalRoutines.h"
9
#include "HierarchyControl_fp.h"
10
//
11
//
12
//     Error Returns               Meaning
13
//
14
//     TPM_RC_AUTH_TYPE            authHandle is not applicable to hierarchy in its current state
15
//
16
TPM_RC
17
TPM2_HierarchyControl(
18
   HierarchyControl_In    *in                 // IN: input parameter list
19
   )
20
0
{
21
0
   TPM_RC      result;
22
0
   BOOL        select = (in->state == YES);
23
0
   BOOL        *selected = NULL;
24
25
// Input Validation
26
0
   switch(in->enable)
27
0
   {
28
       // Platform hierarchy has to be disabled by platform auth
29
       // If the platform hierarchy has already been disabled, only a reboot
30
       // can enable it again
31
0
       case TPM_RH_PLATFORM:
32
0
       case TPM_RH_PLATFORM_NV:
33
0
           if(in->authHandle != TPM_RH_PLATFORM)
34
0
               return TPM_RC_AUTH_TYPE;
35
0
           break;
36
37
       // ShEnable may be disabled if PlatformAuth/PlatformPolicy or
38
       // OwnerAuth/OwnerPolicy is provided. If ShEnable is disabled, then it
39
       // may only be enabled if PlatformAuth/PlatformPolicy is provided.
40
0
       case TPM_RH_OWNER:
41
0
           if(   in->authHandle != TPM_RH_PLATFORM
42
0
              && in->authHandle != TPM_RH_OWNER)
43
0
               return TPM_RC_AUTH_TYPE;
44
0
           if(   gc.shEnable == FALSE && in->state == YES
45
0
              && in->authHandle != TPM_RH_PLATFORM)
46
0
               return TPM_RC_AUTH_TYPE;
47
0
           break;
48
49
       // EhEnable may be disabled if either PlatformAuth/PlatformPolicy or
50
       // EndosementAuth/EndorsementPolicy is provided. If EhEnable is disabled,
51
       // then it may only be enabled if PlatformAuth/PlatformPolicy is
52
       // provided.
53
0
       case TPM_RH_ENDORSEMENT:
54
0
           if(   in->authHandle != TPM_RH_PLATFORM
55
0
              && in->authHandle != TPM_RH_ENDORSEMENT)
56
0
               return TPM_RC_AUTH_TYPE;
57
0
           if(   gc.ehEnable == FALSE && in->state == YES
58
0
              && in->authHandle != TPM_RH_PLATFORM)
59
0
               return TPM_RC_AUTH_TYPE;
60
0
           break;
61
0
       default:
62
0
           pAssert(FALSE);
63
0
           break;
64
0
   }
65
66
// Internal Data Update
67
68
   // Enable or disable the selected hierarchy
69
   // Note: the authorization processing for this command may keep these
70
   // command actions from being executed. For example, if phEnable is
71
   // CLEAR, then platformAuth cannot be used for authorization. This
72
   // means that would not be possible to use platformAuth to change the
73
   // state of phEnable from CLEAR to SET.
74
   // If it is decided that platformPolicy can still be used when phEnable
75
   // is CLEAR, then this code could SET phEnable when proper platform
76
   // policy is provided.
77
0
   switch(in->enable)
78
0
   {
79
0
       case TPM_RH_OWNER:
80
0
           selected = &gc.shEnable;
81
0
           break;
82
0
       case TPM_RH_ENDORSEMENT:
83
0
           selected = &gc.ehEnable;
84
0
           break;
85
0
       case TPM_RH_PLATFORM:
86
0
           selected = &g_phEnable;
87
0
           break;
88
0
       case TPM_RH_PLATFORM_NV:
89
0
           selected = &gc.phEnableNV;
90
0
           break;
91
0
       default:
92
0
           pAssert(FALSE);
93
0
           break;
94
0
   }
95
0
   if(selected != NULL && *selected != select)
96
0
   {
97
       // Before changing the internal state, make sure that NV is available.
98
       // Only need to update NV if changing the orderly state
99
0
       if(gp.orderlyState != SHUTDOWN_NONE)
100
0
       {
101
           // The command needs NV update. Check if NV is available.
102
           // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
103
           // this point
104
0
           result = NvIsAvailable();
105
0
           if(result != TPM_RC_SUCCESS)
106
0
               return result;
107
0
       }
108
       // state is changing and NV is available so modify
109
0
       *selected = select;
110
       // If a hierarchy was just disabled, flush it
111
0
       if(select == CLEAR && in->enable != TPM_RH_PLATFORM_NV)
112
       // Flush hierarchy
113
0
           ObjectFlushHierarchy(in->enable);
114
115
       // orderly state should be cleared because of the update to state clear data
116
       // This gets processed in ExecuteCommand() on the way out.
117
0
       g_clearOrderly = TRUE;
118
0
   }
119
0
   return TPM_RC_SUCCESS;
120
0
}