blob: ec4a4f6a2cb008c12b6ef4609f00b00ac9812cce [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 4: Supporting Routines
4// Family "2.0"
5// Level 00 Revision 01.16
6// October 30, 2014
7
8#include "InternalRoutines.h"
9//
10//
11// Functions
12//
13// CommandAuditPreInstall_Init()
14//
15// This function initializes the command audit list. This function is simulates the behavior of manufacturing. A
16// function is used instead of a structure definition because this is easier than figuring out the initialization
17// value for a bit array.
18// This function would not be implemented outside of a manufacturing or simulation environment.
19//
20void
21CommandAuditPreInstall_Init(
22 void
23 )
24{
25 // Clear all the audit commands
26 MemorySet(gp.auditComands, 0x00,
27 ((TPM_CC_LAST - TPM_CC_FIRST + 1) + 7) / 8);
28 // TPM_CC_SetCommandCodeAuditStatus always being audited
29 if(CommandIsImplemented(TPM_CC_SetCommandCodeAuditStatus))
30 CommandAuditSet(TPM_CC_SetCommandCodeAuditStatus);
31 // Set initial command audit hash algorithm to be context integrity hash
32 // algorithm
33 gp.auditHashAlg = CONTEXT_INTEGRITY_HASH_ALG;
34 // Set up audit counter to be 0
35 gp.auditCounter = 0;
36 // Write command audit persistent data to NV
37 NvWriteReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
38 NvWriteReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
39 NvWriteReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
40 return;
41}
42//
43//
44// CommandAuditStartup()
45//
46// This function clears the command audit digest on a TPM Reset.
47//
48void
49CommandAuditStartup(
50 STARTUP_TYPE type // IN: start up type
51 )
52{
53 if(type == SU_RESET)
54 {
55 // Reset the digest size to initialize the digest
56 gr.commandAuditDigest.t.size = 0;
57 }
58}
59//
60//
61// CommandAuditSet()
62//
63// This function will SET the audit flag for a command. This function will not SET the audit flag for a
64// command that is not implemented. This ensures that the audit status is not SET when
65// TPM2_GetCapability() is used to read the list of audited commands.
66// This function is only used by TPM2_SetCommandCodeAuditStatus().
67// The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
68// NV after it is setting and clearing bits.
69//
70// Return Value Meaning
71//
72// TRUE the command code audit status was changed
73// FALSE the command code audit status was not changed
74//
75BOOL
76CommandAuditSet(
77 TPM_CC commandCode // IN: command code
78 )
79{
80 UINT32 bitPos;
81 // Only SET a bit if the corresponding command is implemented
82 if(CommandIsImplemented(commandCode))
83 {
84 // Can't audit shutdown
85 if(commandCode != TPM_CC_Shutdown)
86 {
87 bitPos = commandCode - TPM_CC_FIRST;
88 if(!BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
89 {
90 // Set bit
91 BitSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
92 return TRUE;
93 }
94 }
95 }
96 // No change
97 return FALSE;
98}
99//
100//
101// CommandAuditClear()
102//
103// This function will CLEAR the audit flag for a command. It will not CLEAR the audit flag for
104// TPM_CC_SetCommandCodeAuditStatus().
105// This function is only used by TPM2_SetCommandCodeAuditStatus().
106// The actions in TPM2_SetCommandCodeAuditStatus() are expected to cause the changes to be saved to
107// NV after it is setting and clearing bits.
108//
109//
110//
111// Return Value Meaning
112//
113// TRUE the command code audit status was changed
114// FALSE the command code audit status was not changed
115//
116BOOL
117CommandAuditClear(
118 TPM_CC commandCode // IN: command code
119 )
120{
121 UINT32 bitPos;
122 // Do nothing if the command is not implemented
123 if(CommandIsImplemented(commandCode))
124 {
125 // The bit associated with TPM_CC_SetCommandCodeAuditStatus() cannot be
126 // cleared
127 if(commandCode != TPM_CC_SetCommandCodeAuditStatus)
128 {
129 bitPos = commandCode - TPM_CC_FIRST;
130 if(BitIsSet(bitPos, &gp.auditComands[0], sizeof(gp.auditComands)))
131 {
132 // Clear bit
133 BitClear(bitPos, &gp.auditComands[0], sizeof(gp.auditComands));
134 return TRUE;
135 }
136 }
137 }
138 // No change
139 return FALSE;
140}
141//
142//
143// CommandAuditIsRequired()
144//
145// This function indicates if the audit flag is SET for a command.
146//
147// Return Value Meaning
148//
149// TRUE if command is audited
150// FALSE if command is not audited
151//
152BOOL
153CommandAuditIsRequired(
154 TPM_CC commandCode // IN: command code
155 )
156{
157 UINT32 bitPos;
158 bitPos = commandCode - TPM_CC_FIRST;
159 // Check the bit map. If the bit is SET, command audit is required
160 if((gp.auditComands[bitPos/8] & (1 << (bitPos % 8))) != 0)
161 return TRUE;
162 else
163 return FALSE;
164}
165//
166//
167// CommandAuditCapGetCCList()
168//
169// This function returns a list of commands that have their audit bit SET.
170// Family "2.0" TCG Published Page 111
171// Level 00 Revision 01.16 Copyright © TCG 2006-2014 October 30, 2014
172// Trusted Platform Module Library Part 4: Supporting Routines
173//
174//
175// The list starts at the input commandCode.
176//
177// Return Value Meaning
178//
179// YES if there are more command code available
180// NO all the available command code has been returned
181//
182TPMI_YES_NO
183CommandAuditCapGetCCList(
184 TPM_CC commandCode, // IN: start command code
185 UINT32 count, // IN: count of returned TPM_CC
186 TPML_CC *commandList // OUT: list of TPM_CC
187 )
188{
189 TPMI_YES_NO more = NO;
190 UINT32 i;
191 // Initialize output handle list
192 commandList->count = 0;
193 // The maximum count of command we may return is MAX_CAP_CC
194 if(count > MAX_CAP_CC) count = MAX_CAP_CC;
195 // If the command code is smaller than TPM_CC_FIRST, start from TPM_CC_FIRST
196 if(commandCode < TPM_CC_FIRST) commandCode = TPM_CC_FIRST;
197 // Collect audit commands
198 for(i = commandCode; i <= TPM_CC_LAST; i++)
199 {
200 if(CommandAuditIsRequired(i))
201 {
202 if(commandList->count < count)
203 {
204 // If we have not filled up the return list, add this command
205 // code to it
206 commandList->commandCodes[commandList->count] = i;
207 commandList->count++;
208 }
209 else
210 {
211 // If the return list is full but we still have command
212 // available, report this and stop iterating
213 more = YES;
214 break;
215 }
216 }
217 }
218 return more;
219}
220//
221//
222// CommandAuditGetDigest
223//
224// This command is used to create a digest of the commands being audited. The commands are processed
225// in ascending numeric order with a list of TPM_CC being added to a hash. This operates as if all the
226// audited command codes were concatenated and then hashed.
227//
228void
229CommandAuditGetDigest(
230 TPM2B_DIGEST *digest // OUT: command digest
231 )
232{
233 TPM_CC i;
234 HASH_STATE hashState;
235 // Start hash
236 digest->t.size = CryptStartHash(gp.auditHashAlg, &hashState);
237 // Add command code
238 for(i = TPM_CC_FIRST; i <= TPM_CC_LAST; i++)
239 {
240 if(CommandAuditIsRequired(i))
241 {
242 CryptUpdateDigestInt(&hashState, sizeof(i), &i);
243 }
244 }
245 // Complete hash
246 CryptCompleteHash2B(&hashState, &digest->b);
247 return;
248}