blob: cf41f7e1d909eb78533d9398e4e8106e8e2aba21 [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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//
16TPM_RC
17TPM2_HierarchyControl(
18 HierarchyControl_In *in // IN: input parameter list
19 )
20{
21 TPM_RC result;
22 BOOL select = (in->state == YES);
23 BOOL *selected = NULL;
24
25// Input Validation
26 switch(in->enable)
27 {
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 case TPM_RH_PLATFORM:
32 case TPM_RH_PLATFORM_NV:
33 if(in->authHandle != TPM_RH_PLATFORM)
34 return TPM_RC_AUTH_TYPE;
35 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 case TPM_RH_OWNER:
41 if( in->authHandle != TPM_RH_PLATFORM
42 && in->authHandle != TPM_RH_OWNER)
43 return TPM_RC_AUTH_TYPE;
44 if( gc.shEnable == FALSE && in->state == YES
45 && in->authHandle != TPM_RH_PLATFORM)
46 return TPM_RC_AUTH_TYPE;
47 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 case TPM_RH_ENDORSEMENT:
54 if( in->authHandle != TPM_RH_PLATFORM
55 && in->authHandle != TPM_RH_ENDORSEMENT)
56 return TPM_RC_AUTH_TYPE;
57 if( gc.ehEnable == FALSE && in->state == YES
58 && in->authHandle != TPM_RH_PLATFORM)
59 return TPM_RC_AUTH_TYPE;
60 break;
61 default:
62 pAssert(FALSE);
63 break;
64 }
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 switch(in->enable)
78 {
79 case TPM_RH_OWNER:
80 selected = &gc.shEnable;
81 break;
82 case TPM_RH_ENDORSEMENT:
83 selected = &gc.ehEnable;
84 break;
85 case TPM_RH_PLATFORM:
86 selected = &g_phEnable;
87 break;
88 case TPM_RH_PLATFORM_NV:
89 selected = &gc.phEnableNV;
90 break;
91 default:
92 pAssert(FALSE);
93 break;
94 }
95 if(selected != NULL && *selected != select)
96 {
97 // Before changing the internal state, make sure that NV is available.
98 // Only need to update NV if changing the orderly state
99 if(gp.orderlyState != SHUTDOWN_NONE)
100 {
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 result = NvIsAvailable();
105 if(result != TPM_RC_SUCCESS)
106 return result;
107 }
108 // state is changing and NV is available so modify
109 *selected = select;
110 // If a hierarchy was just disabled, flush it
111 if(select == CLEAR && in->enable != TPM_RH_PLATFORM_NV)
112 // Flush hierarchy
113 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 g_clearOrderly = TRUE;
118 }
119 return TPM_RC_SUCCESS;
120}