/src/libtpms/src/tpm12/tpm_audit.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************************/ |
2 | | /* */ |
3 | | /* Audit Handler */ |
4 | | /* Written by Ken Goldman */ |
5 | | /* IBM Thomas J. Watson Research Center */ |
6 | | /* $Id: tpm_audit.c 4438 2011-02-13 23:03:56Z kgoldman $ */ |
7 | | /* */ |
8 | | /* (c) Copyright IBM Corporation 2006, 2010. */ |
9 | | /* */ |
10 | | /* All rights reserved. */ |
11 | | /* */ |
12 | | /* Redistribution and use in source and binary forms, with or without */ |
13 | | /* modification, are permitted provided that the following conditions are */ |
14 | | /* met: */ |
15 | | /* */ |
16 | | /* Redistributions of source code must retain the above copyright notice, */ |
17 | | /* this list of conditions and the following disclaimer. */ |
18 | | /* */ |
19 | | /* Redistributions in binary form must reproduce the above copyright */ |
20 | | /* notice, this list of conditions and the following disclaimer in the */ |
21 | | /* documentation and/or other materials provided with the distribution. */ |
22 | | /* */ |
23 | | /* Neither the names of the IBM Corporation nor the names of its */ |
24 | | /* contributors may be used to endorse or promote products derived from */ |
25 | | /* this software without specific prior written permission. */ |
26 | | /* */ |
27 | | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ |
28 | | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ |
29 | | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ |
30 | | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ |
31 | | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ |
32 | | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ |
33 | | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ |
34 | | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ |
35 | | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ |
36 | | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ |
37 | | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
38 | | /********************************************************************************/ |
39 | | |
40 | | #include <stdio.h> |
41 | | #include <string.h> |
42 | | |
43 | | #include "tpm_auth.h" |
44 | | #include "tpm_counter.h" |
45 | | #include "tpm_cryptoh.h" |
46 | | #include "tpm_debug.h" |
47 | | #include "tpm_digest.h" |
48 | | #include "tpm_error.h" |
49 | | #include "tpm_global.h" |
50 | | #include "tpm_key.h" |
51 | | #include "tpm_nonce.h" |
52 | | #include "tpm_permanent.h" |
53 | | #include "tpm_process.h" |
54 | | |
55 | | #include "tpm_audit.h" |
56 | | |
57 | | /* |
58 | | TPM_AUDIT_EVENT_IN |
59 | | */ |
60 | | |
61 | | /* TPM_AuditEventIn_Init() |
62 | | |
63 | | sets members to default values |
64 | | sets all pointers to NULL and sizes to 0 |
65 | | always succeeds - no return code |
66 | | */ |
67 | | |
68 | | void TPM_AuditEventIn_Init(TPM_AUDIT_EVENT_IN *tpm_audit_event_in) |
69 | 0 | { |
70 | 0 | printf(" TPM_AuditEventIn_Init:\n"); |
71 | 0 | TPM_Digest_Init(tpm_audit_event_in->inputParms); |
72 | 0 | TPM_CounterValue_Init(&(tpm_audit_event_in->auditCount)); |
73 | 0 | return; |
74 | 0 | } |
75 | | |
76 | | /* TPM_AuditEventIn_Store() |
77 | | |
78 | | serialize the structure to a stream contained in 'sbuffer' |
79 | | returns 0 or error codes |
80 | | */ |
81 | | |
82 | | TPM_RESULT TPM_AuditEventIn_Store(TPM_STORE_BUFFER *sbuffer, |
83 | | const TPM_AUDIT_EVENT_IN *tpm_audit_event_in) |
84 | 0 | { |
85 | 0 | TPM_RESULT rc = 0; |
86 | |
|
87 | 0 | printf(" TPM_AuditEventIn_Store:\n"); |
88 | | /* store tag */ |
89 | 0 | if (rc == 0) { |
90 | 0 | rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_AUDIT_EVENT_IN); |
91 | 0 | } |
92 | | /* store inputParms */ |
93 | 0 | if (rc == 0) { |
94 | 0 | rc = TPM_Digest_Store(sbuffer, tpm_audit_event_in->inputParms); |
95 | 0 | } |
96 | | /* store auditCount */ |
97 | 0 | if (rc == 0) { |
98 | 0 | rc = TPM_CounterValue_StorePublic(sbuffer, &(tpm_audit_event_in->auditCount)); |
99 | 0 | } |
100 | 0 | return rc; |
101 | 0 | } |
102 | | |
103 | | /* TPM_AuditEventIn_Delete() |
104 | | |
105 | | No-OP if the parameter is NULL, else: |
106 | | frees memory allocated for the object |
107 | | sets pointers to NULL |
108 | | calls TPM_AuditEventIn_Init to set members back to default values |
109 | | The object itself is not freed |
110 | | */ |
111 | | |
112 | | void TPM_AuditEventIn_Delete(TPM_AUDIT_EVENT_IN *tpm_audit_event_in) |
113 | 0 | { |
114 | 0 | printf(" TPM_AuditEventIn_Delete:\n"); |
115 | 0 | if (tpm_audit_event_in != NULL) { |
116 | 0 | TPM_AuditEventIn_Init(tpm_audit_event_in); |
117 | 0 | } |
118 | 0 | return; |
119 | 0 | } |
120 | | |
121 | | /* |
122 | | TPM_AUDIT_EVENT_OUT |
123 | | */ |
124 | | |
125 | | /* TPM_AuditEventOut_Init() |
126 | | |
127 | | sets members to default values |
128 | | sets all pointers to NULL and sizes to 0 |
129 | | always succeeds - no return code |
130 | | */ |
131 | | |
132 | | void TPM_AuditEventOut_Init(TPM_AUDIT_EVENT_OUT *tpm_audit_event_out) |
133 | 0 | { |
134 | 0 | printf(" TPM_AuditEventOut_Init:\n"); |
135 | 0 | TPM_Digest_Init(tpm_audit_event_out->outputParms); |
136 | 0 | TPM_CounterValue_Init(&(tpm_audit_event_out->auditCount)); |
137 | 0 | return; |
138 | 0 | } |
139 | | |
140 | | /* TPM_AuditEventOut_Store() |
141 | | |
142 | | serialize the structure to a stream contained in 'sbuffer' |
143 | | returns 0 or error codes |
144 | | */ |
145 | | |
146 | | TPM_RESULT TPM_AuditEventOut_Store(TPM_STORE_BUFFER *sbuffer, |
147 | | const TPM_AUDIT_EVENT_OUT *tpm_audit_event_out) |
148 | 0 | { |
149 | 0 | TPM_RESULT rc = 0; |
150 | |
|
151 | 0 | printf(" TPM_AuditEventOut_Store:\n"); |
152 | | /* store tag */ |
153 | 0 | if (rc == 0) { |
154 | 0 | rc = TPM_Sbuffer_Append16(sbuffer, TPM_TAG_AUDIT_EVENT_OUT); |
155 | 0 | } |
156 | | /* store outputParms */ |
157 | 0 | if (rc == 0) { |
158 | 0 | rc = TPM_Digest_Store(sbuffer, tpm_audit_event_out->outputParms); |
159 | 0 | } |
160 | | /* store auditCount */ |
161 | 0 | if (rc == 0) { |
162 | 0 | rc = TPM_CounterValue_StorePublic(sbuffer, &(tpm_audit_event_out->auditCount)); |
163 | 0 | } |
164 | 0 | return rc; |
165 | 0 | } |
166 | | |
167 | | /* TPM_AuditEventOut_Delete() |
168 | | |
169 | | No-OP if the parameter is NULL, else: |
170 | | frees memory allocated for the object |
171 | | sets pointers to NULL |
172 | | calls TPM_AuditEventOut_Init to set members back to default values |
173 | | The object itself is not freed |
174 | | */ |
175 | | |
176 | | void TPM_AuditEventOut_Delete(TPM_AUDIT_EVENT_OUT *tpm_audit_event_out) |
177 | 0 | { |
178 | 0 | printf(" TPM_AuditEventOut_Delete:\n"); |
179 | 0 | if (tpm_audit_event_out != NULL) { |
180 | 0 | TPM_AuditEventOut_Init(tpm_audit_event_out); |
181 | 0 | } |
182 | 0 | return; |
183 | 0 | } |
184 | | |
185 | | /* |
186 | | ordinalAuditStatus Processing |
187 | | */ |
188 | | |
189 | | /* TPM_OrdinalAuditStatus_Init() initializes the TPM_PERMANENT_DATA 'ordinalAuditStatus' to the |
190 | | default |
191 | | |
192 | | The flags are stored as a bit map to conserve NVRAM. |
193 | | |
194 | | The array is not written back to NVRAM. |
195 | | */ |
196 | | |
197 | | TPM_RESULT TPM_OrdinalAuditStatus_Init(TPM_PERMANENT_DATA *tpm_permanent_data) |
198 | 0 | { |
199 | 0 | TPM_RESULT rc = 0; |
200 | 0 | TPM_COMMAND_CODE ord; /* iterate through all ordinals */ |
201 | 0 | TPM_BOOL auditDefault; /* result for an ordinal */ |
202 | 0 | TPM_BOOL altered; |
203 | | |
204 | 0 | printf(" TPM_OrdinalAuditStatus_Init:\n"); |
205 | |
|
206 | 0 | for (ord = 0 ; (rc == 0) && (ord < TPM_ORDINALS_MAX) ; ord++) { |
207 | | /* get the default audit state from the ordinals table */ |
208 | 0 | TPM_OrdinalTable_GetAuditDefault(&auditDefault, ord); |
209 | | /* write to the TPM_PERMANENT_DATA bit map */ |
210 | 0 | rc = TPM_OrdinalAuditStatus_SetAuditStatus(&altered, tpm_permanent_data, auditDefault, ord); |
211 | 0 | } |
212 | | /* hack for TSC ordinals */ |
213 | 0 | if (rc == 0) { |
214 | 0 | TPM_OrdinalTable_GetAuditDefault(&auditDefault, TSC_ORD_PhysicalPresence); |
215 | 0 | rc = TPM_OrdinalAuditStatus_SetAuditStatus(&altered, tpm_permanent_data, auditDefault, |
216 | 0 | TSC_ORD_PhysicalPresence); |
217 | 0 | } |
218 | 0 | if (rc == 0) { |
219 | 0 | TPM_OrdinalTable_GetAuditDefault(&auditDefault, TSC_ORD_ResetEstablishmentBit); |
220 | 0 | rc = TPM_OrdinalAuditStatus_SetAuditStatus(&altered, tpm_permanent_data, auditDefault, |
221 | 0 | TSC_ORD_ResetEstablishmentBit); |
222 | 0 | } |
223 | 0 | return rc; |
224 | 0 | } |
225 | | |
226 | | /* TPM_OrdinalAuditStatus_Store() stores a list of all ordinals being audited |
227 | | */ |
228 | | |
229 | | TPM_RESULT TPM_OrdinalAuditStatus_Store(TPM_SIZED_BUFFER *ordinalList, |
230 | | TPM_PERMANENT_DATA *tpm_permanent_data, |
231 | | TPM_COMMAND_CODE startOrdinal) |
232 | 0 | { |
233 | 0 | TPM_RESULT rc = 0; |
234 | 0 | TPM_STORE_BUFFER sbuffer; |
235 | 0 | TPM_COMMAND_CODE ord; |
236 | 0 | TPM_BOOL auditStatus; |
237 | | |
238 | 0 | printf(" TPM_OrdinalAuditStatus_Store\n"); |
239 | 0 | TPM_Sbuffer_Init(&sbuffer); /* freed @1 */ |
240 | | /* scan through the ordinals array */ |
241 | 0 | for (ord = startOrdinal ; (rc == 0) && (ord < TPM_ORDINALS_MAX) ; ord++ ) { |
242 | | /* determine if the ordinal being audited */ |
243 | 0 | if (rc == 0) { |
244 | 0 | rc = TPM_OrdinalAuditStatus_GetAuditStatus(&auditStatus, ord, tpm_permanent_data); |
245 | 0 | } |
246 | | /* if being audited */ |
247 | 0 | if ((rc == 0) && auditStatus) { |
248 | 0 | rc = TPM_Sbuffer_Append32(&sbuffer, ord); /* append ordinal to the list */ |
249 | 0 | } |
250 | 0 | } |
251 | | /* scan the TSC ordinals */ |
252 | 0 | if (rc == 0) { |
253 | 0 | if (rc == 0) { |
254 | 0 | rc = TPM_OrdinalAuditStatus_GetAuditStatus(&auditStatus, |
255 | 0 | TSC_ORD_PhysicalPresence, |
256 | 0 | tpm_permanent_data); |
257 | 0 | } |
258 | 0 | if ((rc == 0) && auditStatus) { |
259 | 0 | rc = TPM_Sbuffer_Append32(&sbuffer, TSC_ORD_PhysicalPresence); |
260 | 0 | } |
261 | 0 | if (rc == 0) { |
262 | 0 | rc = TPM_OrdinalAuditStatus_GetAuditStatus(&auditStatus, |
263 | 0 | TSC_ORD_ResetEstablishmentBit, |
264 | 0 | tpm_permanent_data); |
265 | 0 | } |
266 | | /* if being audited */ |
267 | 0 | if ((rc == 0) && auditStatus) { |
268 | 0 | rc = TPM_Sbuffer_Append32(&sbuffer, TSC_ORD_ResetEstablishmentBit); |
269 | 0 | } |
270 | 0 | } |
271 | | /* convert the list to a TPM_SIZED_BUFFER */ |
272 | 0 | if (rc == 0) { |
273 | 0 | rc = TPM_SizedBuffer_SetFromStore(ordinalList, &sbuffer); |
274 | 0 | } |
275 | 0 | TPM_Sbuffer_Delete(&sbuffer); /* @1 */ |
276 | 0 | return rc; |
277 | 0 | } |
278 | | |
279 | | /* TPM_OrdinalAuditStatus_GetAuditState() gets the audit state for the ordinal |
280 | | */ |
281 | | |
282 | | TPM_RESULT TPM_OrdinalAuditStatus_GetAuditStatus(TPM_BOOL *auditStatus, |
283 | | TPM_COMMAND_CODE ordinal, |
284 | | TPM_PERMANENT_DATA *tpm_permanent_data) |
285 | 0 | { |
286 | 0 | TPM_RESULT rc = 0; |
287 | 0 | size_t index; /* index of ordinal in array */ |
288 | 0 | unsigned int offset; /* bit position of ordinal in array */ |
289 | 0 | unsigned char bit; |
290 | |
|
291 | 0 | if (rc == 0) { |
292 | | /* handle the TPM ordinals */ |
293 | 0 | if (ordinal < TPM_ORDINALS_MAX) { |
294 | 0 | index = ordinal/CHAR_BIT; |
295 | 0 | offset = ordinal % CHAR_BIT; |
296 | 0 | bit = 0x01 << offset; |
297 | 0 | *auditStatus = tpm_permanent_data->ordinalAuditStatus[index] & bit; |
298 | 0 | } |
299 | | /* handle the TSC ordinals */ |
300 | 0 | else if (ordinal == TSC_ORD_PhysicalPresence) { |
301 | 0 | *auditStatus = tpm_permanent_data->tscOrdinalAuditStatus & TSC_PHYS_PRES_AUDIT; |
302 | 0 | } |
303 | 0 | else if (ordinal == TSC_ORD_ResetEstablishmentBit) { |
304 | 0 | *auditStatus = tpm_permanent_data->tscOrdinalAuditStatus & TSC_RESET_ESTAB_AUDIT; |
305 | 0 | } |
306 | 0 | else { |
307 | 0 | printf("TPM_OrdinalAuditStatus_GetAuditStatus: Error (fatal) " |
308 | 0 | "ordinal %08x out of range\n", ordinal); |
309 | 0 | rc = TPM_FAIL; /* should never occur, always called with ordinal processing */ |
310 | 0 | } |
311 | 0 | } |
312 | | /* trace the ordinals with auditing enabled */ |
313 | 0 | if ((rc == 0) && *auditStatus) { |
314 | 0 | printf(" TPM_OrdinalAuditStatus_GetAuditStatus: ordinal %08x status %02x\n", |
315 | 0 | ordinal, *auditStatus); |
316 | 0 | } |
317 | 0 | return rc; |
318 | 0 | } |
319 | | |
320 | | /* TPM_OrdinalAuditStatus_SetAuditStatus() sets the TPM_PERMANENT_DATA -> ordinalAuditStatus for the |
321 | | ordinal |
322 | | |
323 | | The flags are stored as a bit map to conserve NVRAM. |
324 | | |
325 | | The array is not written back to NVRAM. On error, TPM_PERMANENT_DATA is not changed. |
326 | | |
327 | | altered is TRUE if the bit was changed, |
328 | | */ |
329 | | |
330 | | TPM_RESULT TPM_OrdinalAuditStatus_SetAuditStatus(TPM_BOOL *altered, |
331 | | TPM_PERMANENT_DATA *tpm_permanent_data, |
332 | | TPM_BOOL auditStatus, |
333 | | TPM_COMMAND_CODE ordinal) |
334 | 0 | { |
335 | 0 | TPM_RESULT rc = 0; |
336 | 0 | TPM_BOOL auditable; /* TRUE if the ordinal is auditable by this TPM |
337 | | implementation */ |
338 | 0 | size_t index; /* index of ordinal in array */ |
339 | 0 | unsigned int offset; /* bit position of ordinal in array */ |
340 | 0 | unsigned char bit; |
341 | |
|
342 | 0 | *altered = FALSE; /* default, returned on error */ |
343 | | #if 0 |
344 | | printf(" TPM_OrdinalAuditStatus_SetAuditStatus: ordinal %08x status %02x\n", |
345 | | ordinal, auditStatus); |
346 | | #endif |
347 | | /* If trying to set, screen against the 'never audit' ordinal table */ |
348 | 0 | if ((rc == 0) && auditStatus) { |
349 | 0 | TPM_OrdinalTable_GetAuditable(&auditable, ordinal); |
350 | | /* if it is a 'never audit' ordinal, it can not be set */ |
351 | 0 | if (!auditable) { |
352 | 0 | printf("TPM_OrdinalAuditStatus_SetAuditStatus: " |
353 | 0 | "Error, cannot audit ordinal %08x\n", ordinal); |
354 | 0 | rc = TPM_BAD_PARAMETER; |
355 | 0 | } |
356 | 0 | } |
357 | 0 | if (rc == 0) { |
358 | | /* handle the TPM ordinals */ |
359 | 0 | if (ordinal < TPM_ORDINALS_MAX) { |
360 | 0 | index = ordinal/CHAR_BIT; |
361 | 0 | offset = ordinal % CHAR_BIT; |
362 | 0 | bit = 0x01 << offset; |
363 | | /* determine if the bit is to be altered */ |
364 | 0 | if (((tpm_permanent_data->ordinalAuditStatus[index] & bit) && !auditStatus) || |
365 | 0 | (!(tpm_permanent_data->ordinalAuditStatus[index] & bit) && auditStatus)) { |
366 | |
|
367 | 0 | *altered = TRUE; |
368 | 0 | } |
369 | 0 | if (auditStatus) { |
370 | | /* set the bit */ |
371 | 0 | tpm_permanent_data->ordinalAuditStatus[index] |= bit; |
372 | 0 | } |
373 | 0 | else { |
374 | | /* clear the bit */ |
375 | 0 | tpm_permanent_data->ordinalAuditStatus[index] &= ~bit; |
376 | 0 | } |
377 | 0 | } |
378 | | /* handle the TSC ordinals */ |
379 | 0 | else if (ordinal == TSC_ORD_PhysicalPresence) { |
380 | | /* determine if the bit is to be altered */ |
381 | 0 | if (((tpm_permanent_data->tscOrdinalAuditStatus & TSC_PHYS_PRES_AUDIT) |
382 | 0 | && !auditStatus) || |
383 | 0 | (!(tpm_permanent_data->tscOrdinalAuditStatus & TSC_PHYS_PRES_AUDIT) |
384 | 0 | && auditStatus)) { |
385 | |
|
386 | 0 | *altered = TRUE; |
387 | 0 | } |
388 | 0 | if (auditStatus) { |
389 | 0 | tpm_permanent_data->tscOrdinalAuditStatus |= TSC_PHYS_PRES_AUDIT; |
390 | 0 | } |
391 | 0 | else { |
392 | 0 | tpm_permanent_data->tscOrdinalAuditStatus &= ~TSC_PHYS_PRES_AUDIT; |
393 | 0 | } |
394 | 0 | } |
395 | 0 | else if (ordinal == TSC_ORD_ResetEstablishmentBit) { |
396 | 0 | if (auditStatus) { |
397 | | /* determine if the bit is to be altered */ |
398 | 0 | if (((tpm_permanent_data->tscOrdinalAuditStatus & TSC_RESET_ESTAB_AUDIT) |
399 | 0 | && !auditStatus) || |
400 | 0 | (!(tpm_permanent_data->tscOrdinalAuditStatus & TSC_RESET_ESTAB_AUDIT) |
401 | 0 | && auditStatus)) { |
402 | |
|
403 | 0 | *altered = TRUE; |
404 | 0 | } |
405 | 0 | tpm_permanent_data->tscOrdinalAuditStatus |= TSC_RESET_ESTAB_AUDIT; |
406 | 0 | } |
407 | 0 | else { |
408 | 0 | tpm_permanent_data->tscOrdinalAuditStatus &= ~TSC_RESET_ESTAB_AUDIT; |
409 | 0 | } |
410 | 0 | } |
411 | 0 | else { |
412 | 0 | printf("TPM_OrdinalAuditStatus_SetAuditStatus: Error ordinal %08x out of range\n", |
413 | 0 | ordinal); |
414 | 0 | rc = TPM_BADINDEX; |
415 | 0 | } |
416 | 0 | } |
417 | 0 | return rc; |
418 | 0 | } |
419 | | |
420 | | /* |
421 | | Common Processing Functions |
422 | | */ |
423 | | |
424 | | /* 8.1 Audit Generation rev 109 |
425 | | |
426 | | TPM_AuditDigest_ExtendIn() extends the audit digest with a digest of input parameters |
427 | | */ |
428 | | |
429 | | TPM_RESULT TPM_AuditDigest_ExtendIn(tpm_state_t *tpm_state, |
430 | | TPM_DIGEST inParamDigest) |
431 | 0 | { |
432 | 0 | TPM_RESULT rc = 0; |
433 | 0 | TPM_AUDIT_EVENT_IN tpm_audit_event_in; |
434 | 0 | TPM_STORE_BUFFER eventIn_sbuffer; |
435 | 0 | const unsigned char *eventIn_buffer; /* serialized buffer */ |
436 | 0 | uint32_t eventIn_length; /* serialization length */ |
437 | | |
438 | 0 | printf(" TPM_AuditDigest_ExtendIn:\n"); |
439 | 0 | TPM_AuditEventIn_Init(&tpm_audit_event_in); /* freed @1 */ |
440 | 0 | TPM_Sbuffer_Init(&eventIn_sbuffer); /* freed @2 */ |
441 | |
|
442 | 0 | if (rc == 0) { |
443 | | /* b. Create A1 a TPM_AUDIT_EVENT_IN structure */ |
444 | | /* NOTE Done by TPM_AuditEventIn_Init() */ |
445 | | /* i. Set A1 -> inputParms to the digest of the input parameters from the command */ |
446 | | /* (1) Digest value according to the HMAC digest rules of the "above the line" parameters |
447 | | (i.e. the first HMAC digest calculation). */ |
448 | 0 | TPM_Digest_Copy(tpm_audit_event_in.inputParms, inParamDigest); |
449 | | /* ii. Set A1 -> auditCount to TPM_PERMANENT_DATA -> auditMonotonicCounter */ |
450 | 0 | TPM_CounterValue_CopyPublic(&(tpm_audit_event_in.auditCount), |
451 | 0 | &(tpm_state->tpm_permanent_data.auditMonotonicCounter)); |
452 | | /* serialize the A1 TPM_AUDIT_EVENT_IN object */ |
453 | 0 | rc = TPM_AuditEventIn_Store(&eventIn_sbuffer, &tpm_audit_event_in); |
454 | |
|
455 | 0 | } |
456 | 0 | if (rc == 0) { |
457 | | /* get the serialization results */ |
458 | 0 | TPM_Sbuffer_Get(&eventIn_sbuffer, &eventIn_buffer, &eventIn_length); |
459 | | /* c. Set TPM_STANY_DATA -> auditDigest to SHA-1 (TPM_STANY_DATA -> auditDigest || A1) */ |
460 | 0 | TPM_PrintFour(" TPM_AuditDigest_ExtendIn: Previous digest", |
461 | 0 | tpm_state->tpm_stclear_data.auditDigest); |
462 | 0 | TPM_PrintAll(" TPM_AuditDigest_ExtendIn: TPM_AUDIT_EVENT_IN", eventIn_buffer, eventIn_length); |
463 | 0 | rc = TPM_SHA1(tpm_state->tpm_stclear_data.auditDigest, |
464 | 0 | TPM_DIGEST_SIZE, tpm_state->tpm_stclear_data.auditDigest, |
465 | 0 | eventIn_length, eventIn_buffer, |
466 | 0 | 0, NULL); |
467 | 0 | TPM_PrintFour(" TPM_AuditDigest_ExtendIn: Current digest (in)", |
468 | 0 | tpm_state->tpm_stclear_data.auditDigest); |
469 | 0 | } |
470 | 0 | TPM_AuditEventIn_Delete(&tpm_audit_event_in); /* @1 */ |
471 | 0 | TPM_Sbuffer_Delete(&eventIn_sbuffer); /* @2 */ |
472 | 0 | return rc; |
473 | 0 | } |
474 | | |
475 | | /* 8.1 Audit Generation rev 109 |
476 | | |
477 | | TPM_AuditDigest_ExtendOut() extends the audit digest with a digest of output parameters |
478 | | */ |
479 | | |
480 | | TPM_RESULT TPM_AuditDigest_ExtendOut(tpm_state_t *tpm_state, |
481 | | TPM_DIGEST outParamDigest) |
482 | 0 | { |
483 | 0 | TPM_RESULT rc = 0; |
484 | 0 | TPM_AUDIT_EVENT_OUT tpm_audit_event_out; |
485 | 0 | TPM_STORE_BUFFER eventOut_sbuffer; |
486 | 0 | const unsigned char *eventOut_buffer; /* serialized buffer */ |
487 | 0 | uint32_t eventOut_length; /* serialization length */ |
488 | | |
489 | 0 | printf(" TPM_AuditDigest_ExtendOut:\n"); |
490 | 0 | TPM_AuditEventOut_Init(&tpm_audit_event_out); /* freed @1 */ |
491 | 0 | TPM_Sbuffer_Init(&eventOut_sbuffer); /* freed @2 */ |
492 | |
|
493 | 0 | if (rc == 0) { |
494 | | /* d. Create A2 a TPM_AUDIT_EVENT_OUT structure */ |
495 | | /* NOTE Done by TPM_AuditEventOut_Init() */ |
496 | | /* i. Set A2 -> outputParms to the digest of the output parameters from the command */ |
497 | | /* (1). Digest value according to the HMAC digest rules of the "above the line" parameters |
498 | | (i.e. the first HMAC digest calculation). */ |
499 | 0 | TPM_Digest_Copy(tpm_audit_event_out.outputParms, outParamDigest); |
500 | | /* ii. Set A2 -> auditCount to TPM_PERMANENT_DATA -> auditMonotonicCounter */ |
501 | 0 | TPM_CounterValue_CopyPublic(&(tpm_audit_event_out.auditCount), |
502 | 0 | &(tpm_state->tpm_permanent_data.auditMonotonicCounter)); |
503 | | /* serialize the A2 TPM_AUDIT_EVENT_OUT object */ |
504 | 0 | rc = TPM_AuditEventOut_Store(&eventOut_sbuffer, &tpm_audit_event_out); |
505 | 0 | } |
506 | 0 | if (rc == 0) { |
507 | | /* get the serialization results */ |
508 | 0 | TPM_Sbuffer_Get(&eventOut_sbuffer, &eventOut_buffer, &eventOut_length); |
509 | | /* e. Set TPM_STANY_DATA -> auditDigest to SHA-1 (TPM_STANY_DATA -> auditDigest || A2) */ |
510 | 0 | TPM_PrintFour(" TPM_AuditDigest_ExtendOut: Previous digest", |
511 | 0 | tpm_state->tpm_stclear_data.auditDigest); |
512 | 0 | TPM_PrintAll(" TPM_AuditDigest_ExtendOut: TPM_AUDIT_EVENT_OUT", eventOut_buffer, eventOut_length); |
513 | 0 | rc = TPM_SHA1(tpm_state->tpm_stclear_data.auditDigest, |
514 | 0 | TPM_DIGEST_SIZE, tpm_state->tpm_stclear_data.auditDigest, |
515 | 0 | eventOut_length, eventOut_buffer, |
516 | 0 | 0, NULL); |
517 | 0 | TPM_PrintFour(" TPM_AuditDigest_ExtendOut: Current digest (out)", |
518 | 0 | tpm_state->tpm_stclear_data.auditDigest); |
519 | 0 | } |
520 | 0 | TPM_AuditEventOut_Delete(&tpm_audit_event_out); /* @1 */ |
521 | 0 | TPM_Sbuffer_Delete(&eventOut_sbuffer); /* @2 */ |
522 | 0 | return rc; |
523 | 0 | } |
524 | | |
525 | | /* |
526 | | Processing Functions |
527 | | */ |
528 | | |
529 | | /* The TPM generates an audit event in response to the TPM executing a command that has the audit |
530 | | flag set to TRUE for that command. |
531 | | |
532 | | The TPM maintains an extended value for all audited operations. |
533 | | */ |
534 | | |
535 | | /* 8.3 TPM_GetAuditDigest rev 87 |
536 | | |
537 | | This returns the current audit digest. The external audit log has the responsibility to track the |
538 | | parameters that constitute the audit digest. |
539 | | |
540 | | This value may be unique to an individual TPM. The value however will be changing at a rate set |
541 | | by the TPM Owner. Those attempting to use this value may find it changing without their |
542 | | knowledge. This value represents a very poor source of tracking uniqueness. |
543 | | */ |
544 | | |
545 | | TPM_RESULT TPM_Process_GetAuditDigest(tpm_state_t *tpm_state, |
546 | | TPM_STORE_BUFFER *response, |
547 | | TPM_TAG tag, |
548 | | uint32_t paramSize, |
549 | | TPM_COMMAND_CODE ordinal, |
550 | | unsigned char *command, |
551 | | TPM_TRANSPORT_INTERNAL *transportInternal) |
552 | 0 | { |
553 | 0 | TPM_RESULT rcf = 0; /* fatal error precluding response */ |
554 | 0 | TPM_RESULT returnCode = TPM_SUCCESS; /* command return code */ |
555 | | |
556 | | /* input parameters */ |
557 | 0 | uint32_t startOrdinal; /* The starting ordinal for the list of audited ordinals */ |
558 | | |
559 | | /* processing parameters */ |
560 | 0 | unsigned char * inParamStart; /* starting point of inParam's */ |
561 | 0 | unsigned char * inParamEnd; /* ending point of inParam's */ |
562 | 0 | TPM_DIGEST inParamDigest; |
563 | 0 | TPM_BOOL auditStatus; /* audit the ordinal */ |
564 | 0 | TPM_BOOL transportEncrypt; /* wrapped in encrypted transport session */ |
565 | | |
566 | | /* output parameters */ |
567 | 0 | uint32_t outParamStart; /* starting point of outParam's */ |
568 | 0 | uint32_t outParamEnd; /* ending point of outParam's */ |
569 | 0 | TPM_DIGEST outParamDigest; |
570 | 0 | TPM_DIGEST auditDigest; /* Log of all audited events */ |
571 | 0 | TPM_BOOL more; /* TRUE if the output does not contain a full list of |
572 | | audited ordinals */ |
573 | 0 | TPM_SIZED_BUFFER ordList; /* List of ordinals that are audited. */ |
574 | |
|
575 | 0 | printf("TPM_Process_GetAuditDigest: Ordinal Entry\n"); |
576 | 0 | TPM_SizedBuffer_Init(&ordList); /* freed @1 */ |
577 | | /* |
578 | | get inputs |
579 | | */ |
580 | | /* save the starting point of inParam's for authorization and auditing */ |
581 | 0 | inParamStart = command; |
582 | | /* get startOrdinal parameter */ |
583 | 0 | if (returnCode == TPM_SUCCESS) { |
584 | 0 | returnCode = TPM_Load32(&startOrdinal, &command, ¶mSize); |
585 | 0 | } |
586 | 0 | if (returnCode == TPM_SUCCESS) { |
587 | 0 | printf("TPM_Process_GetAuditDigest: startOrdinal %08x\n", startOrdinal); |
588 | 0 | } |
589 | | /* save the ending point of inParam's for authorization and auditing */ |
590 | 0 | inParamEnd = command; |
591 | | /* digest the input parameters */ |
592 | 0 | if (returnCode == TPM_SUCCESS) { |
593 | 0 | returnCode = TPM_GetInParamDigest(inParamDigest, /* output */ |
594 | 0 | &auditStatus, /* output */ |
595 | 0 | &transportEncrypt, /* output */ |
596 | 0 | tpm_state, |
597 | 0 | tag, |
598 | 0 | ordinal, |
599 | 0 | inParamStart, |
600 | 0 | inParamEnd, |
601 | 0 | transportInternal); |
602 | 0 | } |
603 | | /* check state */ |
604 | 0 | if (returnCode == TPM_SUCCESS) { |
605 | 0 | returnCode = TPM_CheckState(tpm_state, tag, TPM_CHECK_ALLOW_NO_OWNER); |
606 | 0 | } |
607 | | /* check tag */ |
608 | 0 | if (returnCode == TPM_SUCCESS) { |
609 | 0 | returnCode = TPM_CheckRequestTag0(tag); |
610 | 0 | } |
611 | 0 | if (returnCode == TPM_SUCCESS) { |
612 | 0 | if (paramSize != 0) { |
613 | 0 | printf("TPM_Process_GetAuditDigest: Error, command has %u extra bytes\n", |
614 | 0 | paramSize); |
615 | 0 | returnCode = TPM_BAD_PARAM_SIZE; |
616 | 0 | } |
617 | 0 | } |
618 | | /* |
619 | | Processing |
620 | | */ |
621 | 0 | if (returnCode == TPM_SUCCESS) { |
622 | | /* 1. The TPM sets auditDigest to TPM_STANY_DATA -> auditDigest */ |
623 | 0 | TPM_Digest_Copy(auditDigest, tpm_state->tpm_stclear_data.auditDigest); |
624 | | /* 2. The TPM sets counterValue to TPM_PERMANENT_DATA -> auditMonotonicCounter */ |
625 | | /* NOTE Since there is only one, use it directly on the output */ |
626 | 0 | printf("TPM_Process_GetAuditDigest: Counter value %08x\n", |
627 | 0 | tpm_state->tpm_permanent_data.auditMonotonicCounter.counter); |
628 | | /* 3. The TPM creates an ordered list of audited ordinals. The list starts at startOrdinal |
629 | | listing each ordinal that is audited. */ |
630 | | /* a. If startOrdinal is 0 then the first ordinal that could be audited would be TPM_OIAP |
631 | | (ordinal 0x0000000A) */ |
632 | | /* b. The next ordinal would be TPM_OSAP (ordinal 0x0000000B) */ |
633 | 0 | returnCode = TPM_OrdinalAuditStatus_Store(&ordList, |
634 | 0 | &(tpm_state->tpm_permanent_data), |
635 | 0 | startOrdinal); |
636 | 0 | } |
637 | 0 | if (returnCode == TPM_SUCCESS) { |
638 | 0 | printf("TPM_Process_GetAuditDigest: ordSize %u\n", ordList.size); |
639 | | /* 4. If the ordered list does not fit in the output buffer the TPM sets more to TRUE */ |
640 | 0 | more = FALSE; |
641 | 0 | } |
642 | | /* |
643 | | response |
644 | | */ |
645 | | /* standard response: tag, (dummy) paramSize, returnCode. Failure is fatal. */ |
646 | 0 | if (rcf == 0) { |
647 | 0 | printf("TPM_Process_GetAuditDigest: Ordinal returnCode %08x %u\n", |
648 | 0 | returnCode, returnCode); |
649 | 0 | rcf = TPM_Sbuffer_StoreInitialResponse(response, tag, returnCode); |
650 | 0 | } |
651 | | /* success response, append the rest of the parameters. */ |
652 | 0 | if (rcf == 0) { |
653 | | /* append counterValue */ |
654 | 0 | if (returnCode == TPM_SUCCESS) { |
655 | | /* checkpoint the beginning of the outParam's */ |
656 | 0 | outParamStart = response->buffer_current - response->buffer; |
657 | | /* append counterValue */ |
658 | 0 | returnCode = TPM_CounterValue_StorePublic |
659 | 0 | (response, |
660 | 0 | &(tpm_state->tpm_permanent_data.auditMonotonicCounter)); |
661 | 0 | } |
662 | | /* 5. Return TPM_STANY_DATA -> auditDigest as auditDigest */ |
663 | 0 | if (returnCode == TPM_SUCCESS) { |
664 | 0 | returnCode = TPM_Digest_Store(response, auditDigest); |
665 | 0 | } |
666 | | /* append more */ |
667 | 0 | if (returnCode == TPM_SUCCESS) { |
668 | 0 | returnCode = TPM_Sbuffer_Append(response, &more, sizeof(TPM_BOOL)); |
669 | 0 | } |
670 | | /* append ordList */ |
671 | 0 | if (returnCode == TPM_SUCCESS) { |
672 | 0 | returnCode = TPM_SizedBuffer_Store(response, &ordList); |
673 | | /* checkpoint the end of the outParam's */ |
674 | 0 | outParamEnd = response->buffer_current - response->buffer; |
675 | 0 | } |
676 | | /* digest the above the line output parameters */ |
677 | 0 | if (returnCode == TPM_SUCCESS) { |
678 | 0 | returnCode = TPM_GetOutParamDigest(outParamDigest, /* output */ |
679 | 0 | auditStatus, /* input audit status */ |
680 | 0 | transportEncrypt, |
681 | 0 | tag, |
682 | 0 | returnCode, |
683 | 0 | ordinal, /* command ordinal */ |
684 | 0 | response->buffer + outParamStart, /* start */ |
685 | 0 | outParamEnd - outParamStart); /* length */ |
686 | 0 | } |
687 | | /* audit if required */ |
688 | 0 | if ((returnCode == TPM_SUCCESS) && auditStatus) { |
689 | 0 | returnCode = TPM_ProcessAudit(tpm_state, |
690 | 0 | transportEncrypt, |
691 | 0 | inParamDigest, |
692 | 0 | outParamDigest, |
693 | 0 | ordinal); |
694 | 0 | } |
695 | | /* adjust the initial response */ |
696 | 0 | rcf = TPM_Sbuffer_StoreFinalResponse(response, returnCode, tpm_state); |
697 | 0 | } |
698 | | /* |
699 | | cleanup |
700 | | */ |
701 | 0 | TPM_SizedBuffer_Delete(&ordList); /* @1 */ |
702 | 0 | return rcf; |
703 | 0 | } |
704 | | |
705 | | /* 8.4 TPM_GetAuditDigestSigned rev 101 |
706 | | |
707 | | The signing of the audit log returns the entire digest value and the list of currently audited |
708 | | commands. |
709 | | |
710 | | The inclusion of the list of audited commands as an atomic operation is to tie the current digest |
711 | | value with the list of commands that are being audited. |
712 | | |
713 | | Note to future architects |
714 | | |
715 | | When auditing functionality is active in a TPM, it may seem logical to remove this ordinal from |
716 | | the active set of ordinals as the signing functionality of this command could be handled in a |
717 | | signed transport session. While true this command has a secondary affect also, resetting the |
718 | | audit log digest. As the reset requires TPM Owner authentication there must be some way in this |
719 | | command to reflect the TPM Owner wishes. By requiring that a TPM Identity key be the only key |
720 | | that can sign and reset the TPM Owners authentication is implicit in the execution of the command |
721 | | (TPM Identity Keys are created and controlled by the TPM Owner only). Hence while one might want |
722 | | to remove an ordinal this is not one that can be removed if auditing is functional. |
723 | | */ |
724 | | |
725 | | TPM_RESULT TPM_Process_GetAuditDigestSigned(tpm_state_t *tpm_state, |
726 | | TPM_STORE_BUFFER *response, |
727 | | TPM_TAG tag, |
728 | | uint32_t paramSize, |
729 | | TPM_COMMAND_CODE ordinal, |
730 | | unsigned char *command, |
731 | | TPM_TRANSPORT_INTERNAL *transportInternal) |
732 | 0 | { |
733 | 0 | TPM_RESULT rcf = 0; /* fatal error precluding response */ |
734 | 0 | TPM_RESULT returnCode = TPM_SUCCESS; /* command return code */ |
735 | | |
736 | | /* input parameters */ |
737 | 0 | TPM_KEY_HANDLE keyHandle; /* The handle of a loaded key that can perform digital |
738 | | signatures. */ |
739 | 0 | TPM_BOOL closeAudit; /* Indication if audit session should be closed */ |
740 | 0 | TPM_NONCE antiReplay; /* A nonce to prevent replay attacks */ |
741 | 0 | TPM_AUTHHANDLE authHandle; /* The authorization session handle used for key |
742 | | authentication. */ |
743 | 0 | TPM_NONCE nonceOdd; /* Nonce generated by system associated with authHandle */ |
744 | 0 | TPM_BOOL continueAuthSession; /* The continue use flag for the authorization session |
745 | | handle */ |
746 | 0 | TPM_AUTHDATA keyAuth; /* Authorization. HMAC key: key.usageAuth. */ |
747 | | |
748 | | /* processing parameters */ |
749 | 0 | unsigned char * inParamStart; /* starting point of inParam's */ |
750 | 0 | unsigned char * inParamEnd; /* ending point of inParam's */ |
751 | 0 | TPM_DIGEST inParamDigest; |
752 | 0 | TPM_BOOL auditStatus; /* audit the ordinal */ |
753 | 0 | TPM_BOOL transportEncrypt; /* wrapped in encrypted transport session */ |
754 | 0 | TPM_BOOL authHandleValid = FALSE; |
755 | 0 | TPM_SECRET *hmacKey; |
756 | 0 | TPM_KEY *sigKey = NULL; /* the key specified by keyHandle */ |
757 | 0 | TPM_SECRET *keyUsageAuth; |
758 | 0 | TPM_BOOL parentPCRStatus; |
759 | 0 | TPM_AUTH_SESSION_DATA *auth_session_data = NULL; /* session data for authHandle */ |
760 | 0 | TPM_SIGN_INFO d1SignInfo; |
761 | 0 | TPM_SIZED_BUFFER d3SizedBuffer; /* List of ordinals that are audited. */ |
762 | 0 | TPM_STORE_BUFFER d2Sbuffer; /* data to be signed */ |
763 | 0 | TPM_DIGEST h1; |
764 | | |
765 | | /* output parameters */ |
766 | 0 | uint32_t outParamStart; /* starting point of outParam's */ |
767 | 0 | uint32_t outParamEnd; /* ending point of outParam's */ |
768 | 0 | TPM_DIGEST outParamDigest; |
769 | 0 | TPM_DIGEST ordinalDigest; /* Digest of all audited ordinals */ |
770 | 0 | TPM_SIZED_BUFFER sig; /* The signature of the area */ |
771 | |
|
772 | 0 | printf("TPM_Process_GetAuditDigestSigned: Ordinal Entry\n"); |
773 | 0 | TPM_SignInfo_Init(&d1SignInfo); /* freed @1 */ |
774 | 0 | TPM_SizedBuffer_Init(&d3SizedBuffer); /* freed @2 */ |
775 | 0 | TPM_Sbuffer_Init(&d2Sbuffer); /* freed @3 */ |
776 | 0 | TPM_SizedBuffer_Init(&sig); /* freed @4 */ |
777 | | /* |
778 | | get inputs |
779 | | */ |
780 | | /* get keyHandle parameter */ |
781 | 0 | if (returnCode == TPM_SUCCESS) { |
782 | 0 | returnCode = TPM_Load32(&keyHandle, &command, ¶mSize); |
783 | 0 | } |
784 | | /* save the starting point of inParam's for authorization and auditing */ |
785 | 0 | inParamStart = command; |
786 | | /* get closeAudit parameter */ |
787 | 0 | if (returnCode == TPM_SUCCESS) { |
788 | 0 | printf("TPM_Process_GetAuditDigestSigned: keyHandle %08x\n", keyHandle); |
789 | 0 | returnCode = TPM_LoadBool(&closeAudit, &command, ¶mSize); |
790 | 0 | } |
791 | | /* get antiReplay parameter */ |
792 | 0 | if (returnCode == TPM_SUCCESS) { |
793 | 0 | returnCode = TPM_Digest_Load(antiReplay, &command, ¶mSize); |
794 | 0 | } |
795 | | /* save the ending point of inParam's for authorization and auditing */ |
796 | 0 | inParamEnd = command; |
797 | | /* digest the input parameters */ |
798 | 0 | if (returnCode == TPM_SUCCESS) { |
799 | 0 | returnCode = TPM_GetInParamDigest(inParamDigest, /* output */ |
800 | 0 | &auditStatus, /* output */ |
801 | 0 | &transportEncrypt, /* output */ |
802 | 0 | tpm_state, |
803 | 0 | tag, |
804 | 0 | ordinal, |
805 | 0 | inParamStart, |
806 | 0 | inParamEnd, |
807 | 0 | transportInternal); |
808 | 0 | } |
809 | | /* check state */ |
810 | 0 | if (returnCode == TPM_SUCCESS) { |
811 | 0 | returnCode = TPM_CheckState(tpm_state, tag, TPM_CHECK_ALL); |
812 | 0 | } |
813 | | /* check tag */ |
814 | 0 | if (returnCode == TPM_SUCCESS) { |
815 | 0 | returnCode = TPM_CheckRequestTag10(tag); |
816 | 0 | } |
817 | | /* get the optional 'below the line' authorization parameters */ |
818 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_AUTH1_COMMAND)) { |
819 | 0 | returnCode = TPM_AuthParams_Get(&authHandle, |
820 | 0 | &authHandleValid, |
821 | 0 | nonceOdd, |
822 | 0 | &continueAuthSession, |
823 | 0 | keyAuth, |
824 | 0 | &command, ¶mSize); |
825 | 0 | } |
826 | 0 | if (returnCode == TPM_SUCCESS) { |
827 | 0 | if (paramSize != 0) { |
828 | 0 | printf("TPM_Process_GetAuditDigestSigned: Error, command has %u extra bytes\n", |
829 | 0 | paramSize); |
830 | 0 | returnCode = TPM_BAD_PARAM_SIZE; |
831 | 0 | } |
832 | 0 | } |
833 | | /* do not terminate sessions if the command did not parse correctly */ |
834 | 0 | if (returnCode != TPM_SUCCESS) { |
835 | 0 | authHandleValid = FALSE; |
836 | 0 | } |
837 | | /* |
838 | | Processing |
839 | | */ |
840 | | /* 1. Validate the AuthData and parameters using keyAuth, return TPM_AUTHFAIL on error */ |
841 | | /* get the key corresponding to the keyHandle parameter */ |
842 | 0 | if (returnCode == TPM_SUCCESS) { |
843 | 0 | returnCode = TPM_KeyHandleEntries_GetKey(&sigKey, &parentPCRStatus, tpm_state, keyHandle, |
844 | 0 | FALSE, /* not read-only */ |
845 | 0 | FALSE, /* do not ignore PCRs */ |
846 | 0 | FALSE); /* cannot use EK */ |
847 | 0 | } |
848 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_COMMAND)){ |
849 | 0 | if (sigKey->authDataUsage != TPM_AUTH_NEVER) { |
850 | 0 | printf("TPM_Process_GetAuditDigestSigned: Error, authorization required\n"); |
851 | 0 | returnCode = TPM_AUTHFAIL; |
852 | 0 | } |
853 | 0 | } |
854 | | /* get keyHandle -> usageAuth */ |
855 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_AUTH1_COMMAND)) { |
856 | 0 | returnCode = TPM_Key_GetUsageAuth(&keyUsageAuth, sigKey); |
857 | 0 | } |
858 | | /* get the session data */ |
859 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_AUTH1_COMMAND)) { |
860 | 0 | returnCode = TPM_AuthSessions_GetData(&auth_session_data, |
861 | 0 | &hmacKey, |
862 | 0 | tpm_state, |
863 | 0 | authHandle, |
864 | 0 | TPM_PID_NONE, |
865 | 0 | TPM_ET_KEYHANDLE, |
866 | 0 | ordinal, |
867 | 0 | sigKey, |
868 | 0 | keyUsageAuth, /* OIAP */ |
869 | 0 | sigKey->tpm_store_asymkey->pubDataDigest); /* OSAP */ |
870 | 0 | } |
871 | | /* validate the authorization to use the key pointed to by keyHandle */ |
872 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_AUTH1_COMMAND)) { |
873 | 0 | returnCode = TPM_Authdata_Check(tpm_state, |
874 | 0 | *hmacKey, /* HMAC key */ |
875 | 0 | inParamDigest, |
876 | 0 | auth_session_data, /* authorization session */ |
877 | 0 | nonceOdd, /* Nonce generated by system |
878 | | associated with authHandle */ |
879 | 0 | continueAuthSession, |
880 | 0 | keyAuth); /* Authorization digest for input */ |
881 | 0 | } |
882 | | /* 2.Validate that keyHandle -> keyUsage is TPM_KEY_SIGNING, TPM_KEY_IDENTITY or TPM_KEY_LEGACY, |
883 | | if not return TPM_INVALID_KEYUSAGE */ |
884 | 0 | if (returnCode == TPM_SUCCESS) { |
885 | 0 | if ((sigKey->keyUsage != TPM_KEY_SIGNING) && |
886 | 0 | (sigKey->keyUsage != TPM_KEY_IDENTITY) && |
887 | 0 | (sigKey->keyUsage != TPM_KEY_LEGACY)) { |
888 | 0 | printf("TPM_Process_GetAuditDigestSigned: Error, keyUsage %04hx is invalid\n", |
889 | 0 | sigKey->keyUsage); |
890 | 0 | returnCode = TPM_INVALID_KEYUSAGE; |
891 | 0 | } |
892 | 0 | } |
893 | | /* 3. The TPM validates that the key pointed to by keyHandle has a signature scheme of |
894 | | TPM_SS_RSASSAPKCS1v15_SHA1 or TPM_SS_RSASSAPKCS1v15_INFO, return TPM_INVALID_KEYUSAGE on |
895 | | error */ |
896 | 0 | if (returnCode == TPM_SUCCESS) { |
897 | 0 | if ((sigKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_SHA1) && |
898 | 0 | (sigKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_INFO)) { |
899 | 0 | printf("TPM_Process_GetAuditDigestSigned: Error, invalid sigScheme %04hx\n", |
900 | 0 | sigKey->algorithmParms.sigScheme); |
901 | 0 | returnCode = TPM_INVALID_KEYUSAGE; |
902 | 0 | } |
903 | 0 | } |
904 | 0 | if (returnCode == TPM_SUCCESS) { |
905 | | /* 4. Create D1 a TPM_SIGN_INFO structure and set the structure defaults */ |
906 | | /* NOTE Done by TPM_SignInfo_Init() */ |
907 | | /* a. Set D1 -> fixed to "ADIG" */ |
908 | 0 | memcpy(d1SignInfo.fixed, "ADIG", TPM_SIGN_INFO_FIXED_SIZE); |
909 | | /* b. Set D1 -> replay to antiReplay */ |
910 | 0 | TPM_Nonce_Copy(d1SignInfo.replay, antiReplay); |
911 | | /* c. Create D3 a list of all audited ordinals as defined in the TPM_GetAuditDigest |
912 | | uint32_t[] ordList outgoing parameter */ |
913 | 0 | returnCode = TPM_OrdinalAuditStatus_Store(&d3SizedBuffer, |
914 | 0 | &(tpm_state->tpm_permanent_data), |
915 | 0 | 0); |
916 | 0 | } |
917 | | /* d. Create D4 (ordinalDigest outgoing parameter) the SHA-1 of D3 */ |
918 | 0 | if (returnCode == TPM_SUCCESS) { |
919 | 0 | returnCode = TPM_SHA1(ordinalDigest, |
920 | 0 | d3SizedBuffer.size, d3SizedBuffer.buffer, |
921 | 0 | 0, NULL); |
922 | 0 | } |
923 | 0 | if (returnCode == TPM_SUCCESS) { |
924 | | /* e. Set auditDigest to TPM_STANY_DATA -> auditDigest */ |
925 | | /* NOTE: Use it directly on the output */ |
926 | | /* f. Set counterValue to TPM_PERMANENT_DATA -> auditMonotonicCounter */ |
927 | | /* NOTE Since there is only one, use it directly on the output */ |
928 | | /* g. Create D2 the concatenation of auditDigest || counterValue || D4 */ |
929 | 0 | returnCode = TPM_Sbuffer_Append(&d2Sbuffer, |
930 | 0 | tpm_state->tpm_stclear_data.auditDigest, TPM_DIGEST_SIZE); |
931 | 0 | } |
932 | 0 | if (returnCode == TPM_SUCCESS) { |
933 | 0 | returnCode = |
934 | 0 | TPM_CounterValue_StorePublic(&d2Sbuffer, |
935 | 0 | &(tpm_state->tpm_permanent_data.auditMonotonicCounter)); |
936 | 0 | } |
937 | 0 | if (returnCode == TPM_SUCCESS) { |
938 | 0 | returnCode = TPM_Sbuffer_Append(&d2Sbuffer, |
939 | 0 | ordinalDigest, TPM_DIGEST_SIZE); |
940 | 0 | } |
941 | | /* h. Set D1 -> data to D2 */ |
942 | 0 | if (returnCode == TPM_SUCCESS) { |
943 | 0 | returnCode = TPM_SizedBuffer_SetFromStore(&(d1SignInfo.data), &d2Sbuffer); |
944 | 0 | } |
945 | | /* i. Create a digital signature of the SHA-1 of D1 by using the signature scheme for keyHandle |
946 | | */ |
947 | 0 | if (returnCode == TPM_SUCCESS) { |
948 | 0 | returnCode = TPM_SHA1_GenerateStructure(h1, &d1SignInfo, |
949 | 0 | (TPM_STORE_FUNCTION_T)TPM_SignInfo_Store); |
950 | 0 | } |
951 | 0 | if (returnCode == TPM_SUCCESS) { |
952 | 0 | returnCode = TPM_RSASignToSizedBuffer(&sig, /* signature */ |
953 | 0 | h1, /* message */ |
954 | 0 | TPM_DIGEST_SIZE, /* message size */ |
955 | 0 | sigKey); /* input, signing key */ |
956 | 0 | } |
957 | 0 | if (returnCode == TPM_SUCCESS) { |
958 | 0 | TPM_PrintFour("TPM_Process_GetAuditDigestSigned: auditDigest", |
959 | 0 | tpm_state->tpm_stclear_data.auditDigest); |
960 | 0 | TPM_PrintFour("TPM_Process_GetAuditDigestSigned: ordinalDigest", |
961 | 0 | ordinalDigest); |
962 | 0 | } |
963 | | /* j. Set ordinalDigest to D4 */ |
964 | | /* NOTE Created directly in ordinalDigest */ |
965 | | /* 5. If closeAudit == TRUE */ |
966 | 0 | if ((returnCode == TPM_SUCCESS) && closeAudit) { |
967 | | /* a. If keyHandle->keyUsage is TPM_KEY_IDENTITY */ |
968 | 0 | if (sigKey->keyUsage == TPM_KEY_IDENTITY) { |
969 | | /* i. TPM_STANY_DATA -> auditDigest MUST be set to all zeros. */ |
970 | 0 | TPM_Digest_Init(tpm_state->tpm_stclear_data.auditDigest); |
971 | 0 | } |
972 | | /* b. Else */ |
973 | 0 | else { |
974 | | /* i. Return TPM_INVALID_KEYUSAGE */ |
975 | 0 | printf("TPM_Process_GetAuditDigestSigned: Error, " |
976 | 0 | "cannot closeAudit with keyUsage %04hx\n", sigKey->keyUsage); |
977 | 0 | returnCode = TPM_INVALID_KEYUSAGE; |
978 | 0 | } |
979 | 0 | } |
980 | | /* |
981 | | response |
982 | | */ |
983 | | /* standard response: tag, (dummy) paramSize, returnCode. Failure is fatal. */ |
984 | 0 | if (rcf == 0) { |
985 | 0 | printf("TPM_Process_GetAuditDigestSigned: Ordinal returnCode %08x %u\n", |
986 | 0 | returnCode, returnCode); |
987 | 0 | rcf = TPM_Sbuffer_StoreInitialResponse(response, tag, returnCode); |
988 | 0 | } |
989 | | /* success response, append the rest of the parameters. */ |
990 | 0 | if (rcf == 0) { |
991 | 0 | if (returnCode == TPM_SUCCESS) { |
992 | | /* checkpoint the beginning of the outParam's */ |
993 | 0 | outParamStart = response->buffer_current - response->buffer; |
994 | | /* return counterValue */ |
995 | 0 | returnCode = TPM_CounterValue_StorePublic |
996 | 0 | (response, |
997 | 0 | &(tpm_state->tpm_permanent_data.auditMonotonicCounter)); |
998 | 0 | } |
999 | | /* return auditDigest */ |
1000 | 0 | if (returnCode == TPM_SUCCESS) { |
1001 | 0 | returnCode = TPM_Digest_Store(response, tpm_state->tpm_stclear_data.auditDigest); |
1002 | 0 | } |
1003 | | /* return ordinalDigest */ |
1004 | 0 | if (returnCode == TPM_SUCCESS) { |
1005 | 0 | returnCode = TPM_Digest_Store(response, ordinalDigest); |
1006 | 0 | } |
1007 | | /* return sig */ |
1008 | 0 | if (returnCode == TPM_SUCCESS) { |
1009 | 0 | returnCode = TPM_SizedBuffer_Store(response, &sig); |
1010 | | /* checkpoint the end of the outParam's */ |
1011 | 0 | outParamEnd = response->buffer_current - response->buffer; |
1012 | 0 | } |
1013 | | /* digest the above the line output parameters */ |
1014 | 0 | if (returnCode == TPM_SUCCESS) { |
1015 | 0 | returnCode = TPM_GetOutParamDigest(outParamDigest, /* output */ |
1016 | 0 | auditStatus, /* input audit status */ |
1017 | 0 | transportEncrypt, |
1018 | 0 | tag, |
1019 | 0 | returnCode, |
1020 | 0 | ordinal, /* command ordinal */ |
1021 | 0 | response->buffer + outParamStart, /* start */ |
1022 | 0 | outParamEnd - outParamStart); /* length */ |
1023 | 0 | } |
1024 | | /* calculate and set the below the line parameters */ |
1025 | 0 | if ((returnCode == TPM_SUCCESS) && (tag == TPM_TAG_RQU_AUTH1_COMMAND)) { |
1026 | 0 | returnCode = TPM_AuthParams_Set(response, |
1027 | 0 | *hmacKey, /* owner HMAC key */ |
1028 | 0 | auth_session_data, |
1029 | 0 | outParamDigest, |
1030 | 0 | nonceOdd, |
1031 | 0 | continueAuthSession); |
1032 | 0 | } |
1033 | | /* audit if required */ |
1034 | 0 | if ((returnCode == TPM_SUCCESS) && auditStatus) { |
1035 | 0 | returnCode = TPM_ProcessAudit(tpm_state, |
1036 | 0 | transportEncrypt, |
1037 | 0 | inParamDigest, |
1038 | 0 | outParamDigest, |
1039 | 0 | ordinal); |
1040 | 0 | } |
1041 | | /* adjust the initial response */ |
1042 | 0 | rcf = TPM_Sbuffer_StoreFinalResponse(response, returnCode, tpm_state); |
1043 | 0 | } |
1044 | | /* if there was an error, or continueAuthSession is FALSE, terminate the session */ |
1045 | 0 | if (((rcf != 0) || |
1046 | 0 | ((returnCode != TPM_SUCCESS) && (returnCode != TPM_DEFEND_LOCK_RUNNING)) || |
1047 | 0 | !continueAuthSession) && |
1048 | 0 | authHandleValid) { |
1049 | 0 | TPM_AuthSessions_TerminateHandle(tpm_state->tpm_stclear_data.authSessions, authHandle); |
1050 | 0 | } |
1051 | | /* |
1052 | | cleanup |
1053 | | */ |
1054 | 0 | TPM_SignInfo_Delete(&d1SignInfo); /* @1 */ |
1055 | 0 | TPM_SizedBuffer_Delete(&d3SizedBuffer); /* @2 */ |
1056 | 0 | TPM_Sbuffer_Delete(&d2Sbuffer); /* @3 */ |
1057 | 0 | TPM_SizedBuffer_Delete(&sig); /* @4 */ |
1058 | 0 | return rcf; |
1059 | 0 | } |
1060 | | |
1061 | | /* 8.5 TPM_SetOrdinalAuditStatus rev 109 |
1062 | | |
1063 | | Set the audit flag for a given ordinal. This command requires the authentication of the TPM |
1064 | | Owner. |
1065 | | */ |
1066 | | |
1067 | | TPM_RESULT TPM_Process_SetOrdinalAuditStatus(tpm_state_t *tpm_state, |
1068 | | TPM_STORE_BUFFER *response, |
1069 | | TPM_TAG tag, |
1070 | | uint32_t paramSize, |
1071 | | TPM_COMMAND_CODE ordinal, |
1072 | | unsigned char *command, |
1073 | | TPM_TRANSPORT_INTERNAL *transportInternal) |
1074 | 0 | { |
1075 | 0 | TPM_RESULT rcf = 0; /* fatal error precluding response */ |
1076 | 0 | TPM_RESULT returnCode = TPM_SUCCESS; /* command return code */ |
1077 | | |
1078 | | /* input parameters */ |
1079 | 0 | TPM_COMMAND_CODE ordinalToAudit; /* The ordinal whose audit flag is to be set */ |
1080 | 0 | TPM_BOOL auditState; /* Value for audit flag */ |
1081 | 0 | TPM_AUTHHANDLE authHandle; /* The authorization session handle used for owner |
1082 | | authentication. */ |
1083 | 0 | TPM_NONCE nonceOdd; /* Nonce generated by system associated with authHandle */ |
1084 | 0 | TPM_BOOL continueAuthSession = TRUE; /* The continue use flag for the authorization |
1085 | | session handle */ |
1086 | 0 | TPM_AUTHDATA ownerAuth; /* The authorization session digest for inputs and owner |
1087 | | authentication. HMAC key: ownerAuth. */ |
1088 | | |
1089 | | /* processing parameters */ |
1090 | 0 | unsigned char * inParamStart; /* starting point of inParam's */ |
1091 | 0 | unsigned char * inParamEnd; /* ending point of inParam's */ |
1092 | 0 | TPM_DIGEST inParamDigest; |
1093 | 0 | TPM_BOOL auditStatus; /* audit the ordinal */ |
1094 | 0 | TPM_BOOL altered; /* status is changing */ |
1095 | 0 | TPM_BOOL transportEncrypt; /* wrapped in encrypted transport session */ |
1096 | 0 | TPM_BOOL authHandleValid = FALSE; |
1097 | 0 | TPM_SECRET *hmacKey; |
1098 | 0 | TPM_AUTH_SESSION_DATA *auth_session_data = NULL; /* session data for authHandle */ |
1099 | | |
1100 | | /* output parameters */ |
1101 | 0 | uint32_t outParamStart; /* starting point of outParam's */ |
1102 | 0 | uint32_t outParamEnd; /* ending point of outParam's */ |
1103 | 0 | TPM_DIGEST outParamDigest; |
1104 | |
|
1105 | 0 | printf("TPM_Process_SetOrdinalAuditStatus: Ordinal Entry\n"); |
1106 | | /* |
1107 | | get inputs |
1108 | | */ |
1109 | | /* save the starting point of inParam's for authorization and auditing */ |
1110 | 0 | inParamStart = command; |
1111 | | /* get ordinalToAudit parameter */ |
1112 | 0 | if (returnCode == TPM_SUCCESS) { |
1113 | 0 | returnCode = TPM_Load32(&ordinalToAudit, &command, ¶mSize); |
1114 | 0 | } |
1115 | | /* get auditState parameter */ |
1116 | 0 | if (returnCode == TPM_SUCCESS) { |
1117 | 0 | returnCode = TPM_LoadBool(&auditState, &command, ¶mSize); |
1118 | 0 | } |
1119 | 0 | if (returnCode == TPM_SUCCESS) { |
1120 | 0 | printf("TPM_Process_SetOrdinalAuditStatus: ordinalToAudit %08x auditState %02x\n", |
1121 | 0 | ordinalToAudit, auditState); |
1122 | 0 | } |
1123 | | /* save the ending point of inParam's for authorization and auditing */ |
1124 | 0 | inParamEnd = command; |
1125 | | /* digest the input parameters */ |
1126 | 0 | if (returnCode == TPM_SUCCESS) { |
1127 | 0 | returnCode = TPM_GetInParamDigest(inParamDigest, /* output */ |
1128 | 0 | &auditStatus, /* output */ |
1129 | 0 | &transportEncrypt, /* output */ |
1130 | 0 | tpm_state, |
1131 | 0 | tag, |
1132 | 0 | ordinal, |
1133 | 0 | inParamStart, |
1134 | 0 | inParamEnd, |
1135 | 0 | transportInternal); |
1136 | 0 | } |
1137 | | /* check state */ |
1138 | 0 | if (returnCode == TPM_SUCCESS) { |
1139 | 0 | returnCode = TPM_CheckState(tpm_state, tag, TPM_CHECK_ALL); |
1140 | 0 | } |
1141 | | /* check tag */ |
1142 | 0 | if (returnCode == TPM_SUCCESS) { |
1143 | 0 | returnCode = TPM_CheckRequestTag1(tag); |
1144 | 0 | } |
1145 | | /* get the 'below the line' authorization parameters */ |
1146 | 0 | if (returnCode == TPM_SUCCESS) { |
1147 | 0 | returnCode = TPM_AuthParams_Get(&authHandle, |
1148 | 0 | &authHandleValid, |
1149 | 0 | nonceOdd, |
1150 | 0 | &continueAuthSession, |
1151 | 0 | ownerAuth, |
1152 | 0 | &command, ¶mSize); |
1153 | 0 | } |
1154 | 0 | if (returnCode == TPM_SUCCESS) { |
1155 | 0 | if (paramSize != 0) { |
1156 | 0 | printf("TPM_Process_SetOrdinalAuditStatus: Error, command has %u extra bytes\n", |
1157 | 0 | paramSize); |
1158 | 0 | returnCode = TPM_BAD_PARAM_SIZE; |
1159 | 0 | } |
1160 | 0 | } |
1161 | | /* do not terminate sessions if the command did not parse correctly */ |
1162 | 0 | if (returnCode != TPM_SUCCESS) { |
1163 | 0 | authHandleValid = FALSE; |
1164 | 0 | } |
1165 | | /* |
1166 | | Processing |
1167 | | */ |
1168 | | /* 1. Validate the AuthData to execute the command and the parameters */ |
1169 | 0 | if (returnCode == TPM_SUCCESS) { |
1170 | 0 | returnCode = TPM_AuthSessions_GetData(&auth_session_data, |
1171 | 0 | &hmacKey, |
1172 | 0 | tpm_state, |
1173 | 0 | authHandle, |
1174 | 0 | TPM_PID_NONE, |
1175 | 0 | TPM_ET_OWNER, |
1176 | 0 | ordinal, |
1177 | 0 | NULL, |
1178 | 0 | &(tpm_state->tpm_permanent_data.ownerAuth), /* OIAP */ |
1179 | 0 | tpm_state->tpm_permanent_data.ownerAuth); /* OSAP */ |
1180 | 0 | } |
1181 | | /* calculate and set the below the line parameters */ |
1182 | 0 | if (returnCode == TPM_SUCCESS) { |
1183 | 0 | returnCode = TPM_Authdata_Check(tpm_state, |
1184 | 0 | *hmacKey, /* HMAC key */ |
1185 | 0 | inParamDigest, |
1186 | 0 | auth_session_data, /* authorization session */ |
1187 | 0 | nonceOdd, /* Nonce generated by system |
1188 | | associated with authHandle */ |
1189 | 0 | continueAuthSession, |
1190 | 0 | ownerAuth); /* Authorization digest for input */ |
1191 | 0 | } |
1192 | | /* 2. Validate that the ordinal points to a valid TPM ordinal, return TPM_BADINDEX on error */ |
1193 | | /* a. Valid TPM ordinal means an ordinal that the TPM implementation supports */ |
1194 | | /* Done by TPM_OrdinalAuditStatus_SetAuditState() */ |
1195 | | /* 3. Set the non-volatile flag associated with ordinalToAudit to the value in auditState */ |
1196 | | /* NOTE: On error, TPM_PERMANENT_DATA is not changed */ |
1197 | 0 | if (returnCode == TPM_SUCCESS) { |
1198 | 0 | returnCode = |
1199 | 0 | TPM_OrdinalAuditStatus_SetAuditStatus(&altered, |
1200 | 0 | &(tpm_state->tpm_permanent_data), |
1201 | 0 | auditState, /* uninitialized */ |
1202 | 0 | ordinalToAudit); |
1203 | | /* It's not really uninitialized, but beam doesn't understand that TPM_GetInParamDigest() |
1204 | | can't turn a FALSE into a TRUE */ |
1205 | 0 | } |
1206 | | /* Store the permanent data back to NVRAM */ |
1207 | 0 | if (returnCode == TPM_SUCCESS) { |
1208 | 0 | returnCode = TPM_PermanentAll_NVStore(tpm_state, |
1209 | 0 | altered, |
1210 | 0 | returnCode); |
1211 | 0 | } |
1212 | | /* Audit Generation 3.b. Corner Cases: TPM_SetOrdinalAuditStatus: In the case where the |
1213 | | ordinalToAudit is TPM_ORD_SetOrdinalAuditStatus, audit is based on the initial state, not the |
1214 | | final state. */ |
1215 | | /* |
1216 | | response |
1217 | | */ |
1218 | | /* standard response: tag, (dummy) paramSize, returnCode. Failure is fatal. */ |
1219 | 0 | if (rcf == 0) { |
1220 | 0 | printf("TPM_Process_SetOrdinalAuditStatus: Ordinal returnCode %08x %u\n", |
1221 | 0 | returnCode, returnCode); |
1222 | 0 | rcf = TPM_Sbuffer_StoreInitialResponse(response, tag, returnCode); |
1223 | 0 | } |
1224 | | /* success response, append the rest of the parameters. */ |
1225 | 0 | if (rcf == 0) { |
1226 | 0 | if (returnCode == TPM_SUCCESS) { |
1227 | | /* checkpoint the beginning of the outParam's */ |
1228 | 0 | outParamStart = response->buffer_current - response->buffer; |
1229 | | /* checkpoint the end of the outParam's */ |
1230 | 0 | outParamEnd = response->buffer_current - response->buffer; |
1231 | 0 | } |
1232 | | /* digest the above the line output parameters */ |
1233 | 0 | if (returnCode == TPM_SUCCESS) { |
1234 | 0 | returnCode = TPM_GetOutParamDigest(outParamDigest, /* output */ |
1235 | 0 | auditStatus, /* input audit status */ |
1236 | 0 | transportEncrypt, |
1237 | 0 | tag, |
1238 | 0 | returnCode, |
1239 | 0 | ordinal, /* command ordinal */ |
1240 | 0 | response->buffer + outParamStart, /* start */ |
1241 | 0 | outParamEnd - outParamStart); /* length */ |
1242 | 0 | } |
1243 | | /* calculate and set the below the line parameters */ |
1244 | 0 | if (returnCode == TPM_SUCCESS) { |
1245 | 0 | returnCode = TPM_AuthParams_Set(response, |
1246 | 0 | *hmacKey, /* owner HMAC key */ |
1247 | 0 | auth_session_data, |
1248 | 0 | outParamDigest, |
1249 | 0 | nonceOdd, |
1250 | 0 | continueAuthSession); |
1251 | 0 | } |
1252 | | /* audit if required */ |
1253 | 0 | if ((returnCode == TPM_SUCCESS) && auditStatus) { |
1254 | 0 | returnCode = TPM_ProcessAudit(tpm_state, |
1255 | 0 | transportEncrypt, |
1256 | 0 | inParamDigest, |
1257 | 0 | outParamDigest, |
1258 | 0 | ordinal); |
1259 | 0 | } |
1260 | | /* adjust the initial response */ |
1261 | 0 | rcf = TPM_Sbuffer_StoreFinalResponse(response, returnCode, tpm_state); |
1262 | 0 | } |
1263 | | /* if there was an error, terminate the session. */ |
1264 | 0 | if (((rcf != 0) || |
1265 | 0 | ((returnCode != TPM_SUCCESS) && (returnCode != TPM_DEFEND_LOCK_RUNNING)) || |
1266 | 0 | !continueAuthSession) && |
1267 | 0 | authHandleValid) { |
1268 | 0 | TPM_AuthSessions_TerminateHandle(tpm_state->tpm_stclear_data.authSessions, authHandle); |
1269 | 0 | } |
1270 | 0 | return rcf; |
1271 | 0 | } |