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