1 // This file was extracted from the TCG Published
2 // Trusted Platform Module Library
3 // Part 4: Supporting Routines
4 // Family "2.0"
5 // Level 00 Revision 01.16
6 // October 30, 2014
7
8 #include "InternalRoutines.h"
9 #include "PP_fp.h"
10
11 //
12 //
13 // Functions
14 //
15 // PhysicalPresencePreInstall_Init()
16 //
17 // This function is used to initialize the array of commands that require confirmation with physical presence.
18 // The array is an array of bits that has a correspondence with the command code.
19 // This command should only ever be executable in a manufacturing setting or in a simulation.
20 //
21 void
PhysicalPresencePreInstall_Init(void)22 PhysicalPresencePreInstall_Init(
23 void
24 )
25 {
26 // Clear all the PP commands
27 MemorySet(&gp.ppList, 0,
28 //
29 ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8);
30 // TPM_CC_PP_Commands always requires PP
31 if(CommandIsImplemented(TPM_CC_PP_Commands))
32 PhysicalPresenceCommandSet(TPM_CC_PP_Commands);
33 // Write PP list to NV
34 NvWriteReserved(NV_PP_LIST, &gp.ppList);
35 return;
36 }
37 //
38 //
39 // PhysicalPresenceCommandSet()
40 //
41 // This function is used to indicate a command that requires PP confirmation.
42 //
43 void
PhysicalPresenceCommandSet(TPM_CC commandCode)44 PhysicalPresenceCommandSet(
45 TPM_CC commandCode // IN: command code
46 )
47 {
48 UINT32 bitPos;
49 // Assume command is implemented. It should be checked before this
50 // function is called
51 pAssert(CommandIsImplemented(commandCode));
52 // If the command is not a PP command, ignore it
53 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
54 return;
55 bitPos = commandCode - TPM_CC_PP_FIRST;
56 // Set bit
57 gp.ppList[bitPos/8] |= 1 << (bitPos % 8);
58 return;
59 }
60 //
61 //
62 // PhysicalPresenceCommandClear()
63 //
64 // This function is used to indicate a command that no longer requires PP confirmation.
65 //
66 void
PhysicalPresenceCommandClear(TPM_CC commandCode)67 PhysicalPresenceCommandClear(
68 TPM_CC commandCode // IN: command code
69 )
70 {
71 UINT32 bitPos;
72 // Assume command is implemented. It should be checked before this
73 // function is called
74 pAssert(CommandIsImplemented(commandCode));
75 // If the command is not a PP command, ignore it
76 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
77 return;
78 // if the input code is TPM_CC_PP_Commands, it can not be cleared
79 if(commandCode == TPM_CC_PP_Commands)
80 return;
81 bitPos = commandCode - TPM_CC_PP_FIRST;
82 // Set bit
83 gp.ppList[bitPos/8] |= (1 << (bitPos % 8));
84 // Flip it to off
85 gp.ppList[bitPos/8] ^= (1 << (bitPos % 8));
86 return;
87 }
88 //
89 //
90 // PhysicalPresenceIsRequired()
91 //
92 // This function indicates if PP confirmation is required for a command.
93 //
94 // Return Value Meaning
95 //
96 // TRUE if physical presence is required
97 // FALSE if physical presence is not required
98 //
99 BOOL
PhysicalPresenceIsRequired(TPM_CC commandCode)100 PhysicalPresenceIsRequired(
101 TPM_CC commandCode // IN: command code
102 )
103 {
104 UINT32 bitPos;
105 // if the input commandCode is not a PP command, return FALSE
106 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
107 return FALSE;
108 bitPos = commandCode - TPM_CC_PP_FIRST;
109 // Check the bit map. If the bit is SET, PP authorization is required
110 return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0);
111 }
112 //
113 //
114 // PhysicalPresenceCapGetCCList()
115 //
116 // This function returns a list of commands that require PP confirmation. The list starts from the first
117 // implemented command that has a command code that the same or greater than commandCode.
118 //
119 // Return Value Meaning
120 //
121 // YES if there are more command codes available
122 // NO all the available command codes have been returned
123 //
124 TPMI_YES_NO
PhysicalPresenceCapGetCCList(TPM_CC commandCode,UINT32 count,TPML_CC * commandList)125 PhysicalPresenceCapGetCCList(
126 TPM_CC commandCode, // IN: start command code
127 UINT32 count, // IN: count of returned TPM_CC
128 TPML_CC *commandList // OUT: list of TPM_CC
129 )
130 {
131 TPMI_YES_NO more = NO;
132 UINT32 i;
133 // Initialize output handle list
134 commandList->count = 0;
135 // The maximum count of command we may return is MAX_CAP_CC
136 if(count > MAX_CAP_CC) count = MAX_CAP_CC;
137 // Collect PP commands
138 for(i = commandCode; i <= TPM_CC_PP_LAST; i++)
139 {
140 if(PhysicalPresenceIsRequired(i))
141 {
142 if(commandList->count < count)
143 {
144 // If we have not filled up the return list, add this command
145 // code to it
146 commandList->commandCodes[commandList->count] = i;
147 commandList->count++;
148 }
149 else
150 {
151 // If the return list is full but we still have PP command
152 // available, report this and stop iterating
153 more = YES;
154 break;
155 }
156 }
157 }
158 return more;
159 }
160