1 /** @file
2 Implement TPM2 Integrity related command.
3
4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <IndustryStandard/UefiTcgPlatform.h>
16 #include <Library/Tpm2CommandLib.h>
17 #include <Library/Tpm2DeviceLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21
22 #pragma pack(1)
23
24 typedef struct {
25 TPM2_COMMAND_HEADER Header;
26 TPMI_DH_PCR PcrHandle;
27 UINT32 AuthorizationSize;
28 TPMS_AUTH_COMMAND AuthSessionPcr;
29 TPML_DIGEST_VALUES DigestValues;
30 } TPM2_PCR_EXTEND_COMMAND;
31
32 typedef struct {
33 TPM2_RESPONSE_HEADER Header;
34 UINT32 ParameterSize;
35 TPMS_AUTH_RESPONSE AuthSessionPcr;
36 } TPM2_PCR_EXTEND_RESPONSE;
37
38 typedef struct {
39 TPM2_COMMAND_HEADER Header;
40 TPMI_DH_PCR PcrHandle;
41 UINT32 AuthorizationSize;
42 TPMS_AUTH_COMMAND AuthSessionPcr;
43 TPM2B_EVENT EventData;
44 } TPM2_PCR_EVENT_COMMAND;
45
46 typedef struct {
47 TPM2_RESPONSE_HEADER Header;
48 UINT32 ParameterSize;
49 TPML_DIGEST_VALUES Digests;
50 TPMS_AUTH_RESPONSE AuthSessionPcr;
51 } TPM2_PCR_EVENT_RESPONSE;
52
53 typedef struct {
54 TPM2_COMMAND_HEADER Header;
55 TPML_PCR_SELECTION PcrSelectionIn;
56 } TPM2_PCR_READ_COMMAND;
57
58 typedef struct {
59 TPM2_RESPONSE_HEADER Header;
60 UINT32 PcrUpdateCounter;
61 TPML_PCR_SELECTION PcrSelectionOut;
62 TPML_DIGEST PcrValues;
63 } TPM2_PCR_READ_RESPONSE;
64
65 typedef struct {
66 TPM2_COMMAND_HEADER Header;
67 TPMI_RH_PLATFORM AuthHandle;
68 UINT32 AuthSessionSize;
69 TPMS_AUTH_COMMAND AuthSession;
70 TPML_PCR_SELECTION PcrAllocation;
71 } TPM2_PCR_ALLOCATE_COMMAND;
72
73 typedef struct {
74 TPM2_RESPONSE_HEADER Header;
75 UINT32 AuthSessionSize;
76 TPMI_YES_NO AllocationSuccess;
77 UINT32 MaxPCR;
78 UINT32 SizeNeeded;
79 UINT32 SizeAvailable;
80 TPMS_AUTH_RESPONSE AuthSession;
81 } TPM2_PCR_ALLOCATE_RESPONSE;
82
83 #pragma pack()
84
85 /**
86 This command is used to cause an update to the indicated PCR.
87 The digests parameter contains one or more tagged digest value identified by an algorithm ID.
88 For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).
89
90 @param[in] PcrHandle Handle of the PCR
91 @param[in] Digests List of tagged digest values to be extended
92
93 @retval EFI_SUCCESS Operation completed successfully.
94 @retval EFI_DEVICE_ERROR Unexpected device behavior.
95 **/
96 EFI_STATUS
97 EFIAPI
Tpm2PcrExtend(IN TPMI_DH_PCR PcrHandle,IN TPML_DIGEST_VALUES * Digests)98 Tpm2PcrExtend (
99 IN TPMI_DH_PCR PcrHandle,
100 IN TPML_DIGEST_VALUES *Digests
101 )
102 {
103 EFI_STATUS Status;
104 TPM2_PCR_EXTEND_COMMAND Cmd;
105 TPM2_PCR_EXTEND_RESPONSE Res;
106 UINT32 CmdSize;
107 UINT32 RespSize;
108 UINT32 ResultBufSize;
109 UINT8 *Buffer;
110 UINTN Index;
111 UINT32 SessionInfoSize;
112 UINT16 DigestSize;
113
114 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
115 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
116 Cmd.PcrHandle = SwapBytes32(PcrHandle);
117
118
119 //
120 // Add in Auth session
121 //
122 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
123
124 // sessionInfoSize
125 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
126 Buffer += SessionInfoSize;
127 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
128
129 //Digest Count
130 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));
131 Buffer += sizeof(UINT32);
132
133 //Digest
134 for (Index = 0; Index < Digests->count; Index++) {
135 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));
136 Buffer += sizeof(UINT16);
137 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
138 if (DigestSize == 0) {
139 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
140 return EFI_DEVICE_ERROR;
141 }
142 CopyMem(
143 Buffer,
144 &Digests->digests[Index].digest,
145 DigestSize
146 );
147 Buffer += DigestSize;
148 }
149
150 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
151 Cmd.Header.paramSize = SwapBytes32(CmdSize);
152
153 ResultBufSize = sizeof(Res);
154 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
155 if (EFI_ERROR(Status)) {
156 return Status;
157 }
158
159 if (ResultBufSize > sizeof(Res)) {
160 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
161 return EFI_BUFFER_TOO_SMALL;
162 }
163
164 //
165 // Validate response headers
166 //
167 RespSize = SwapBytes32(Res.Header.paramSize);
168 if (RespSize > sizeof(Res)) {
169 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
170 return EFI_BUFFER_TOO_SMALL;
171 }
172
173 //
174 // Fail if command failed
175 //
176 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
177 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
178 return EFI_DEVICE_ERROR;
179 }
180
181 //
182 // Unmarshal the response
183 //
184
185 // None
186
187 return EFI_SUCCESS;
188 }
189
190 /**
191 This command is used to cause an update to the indicated PCR.
192 The data in eventData is hashed using the hash algorithm associated with each bank in which the
193 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle
194 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in
195 TPM2_PCR_Extend().
196 A TPM shall support an Event.size of zero through 1,024 inclusive.
197
198 @param[in] PcrHandle Handle of the PCR
199 @param[in] EventData Event data in sized buffer
200 @param[out] Digests List of digest
201
202 @retval EFI_SUCCESS Operation completed successfully.
203 @retval EFI_DEVICE_ERROR Unexpected device behavior.
204 **/
205 EFI_STATUS
206 EFIAPI
Tpm2PcrEvent(IN TPMI_DH_PCR PcrHandle,IN TPM2B_EVENT * EventData,OUT TPML_DIGEST_VALUES * Digests)207 Tpm2PcrEvent (
208 IN TPMI_DH_PCR PcrHandle,
209 IN TPM2B_EVENT *EventData,
210 OUT TPML_DIGEST_VALUES *Digests
211 )
212 {
213 EFI_STATUS Status;
214 TPM2_PCR_EVENT_COMMAND Cmd;
215 TPM2_PCR_EVENT_RESPONSE Res;
216 UINT32 CmdSize;
217 UINT32 RespSize;
218 UINT32 ResultBufSize;
219 UINT8 *Buffer;
220 UINTN Index;
221 UINT32 SessionInfoSize;
222 UINT16 DigestSize;
223
224 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
225 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);
226 Cmd.PcrHandle = SwapBytes32(PcrHandle);
227
228 //
229 // Add in Auth session
230 //
231 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
232
233 // sessionInfoSize
234 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
235 Buffer += SessionInfoSize;
236 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
237
238 // Event
239 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));
240 Buffer += sizeof(UINT16);
241
242 CopyMem (Buffer, EventData->buffer, EventData->size);
243 Buffer += EventData->size;
244
245 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
246 Cmd.Header.paramSize = SwapBytes32(CmdSize);
247
248 ResultBufSize = sizeof(Res);
249 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
250 if (EFI_ERROR(Status)) {
251 return Status;
252 }
253
254 if (ResultBufSize > sizeof(Res)) {
255 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
256 return EFI_BUFFER_TOO_SMALL;
257 }
258
259 //
260 // Validate response headers
261 //
262 RespSize = SwapBytes32(Res.Header.paramSize);
263 if (RespSize > sizeof(Res)) {
264 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
265 return EFI_BUFFER_TOO_SMALL;
266 }
267
268 //
269 // Fail if command failed
270 //
271 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
272 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
273 return EFI_DEVICE_ERROR;
274 }
275
276 //
277 // Unmarshal the response
278 //
279 Buffer = (UINT8 *)&Res.Digests;
280
281 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
282 Buffer += sizeof(UINT32);
283 for (Index = 0; Index < Digests->count; Index++) {
284 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
285 Buffer += sizeof(UINT16);
286 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
287 if (DigestSize == 0) {
288 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
289 return EFI_DEVICE_ERROR;
290 }
291 CopyMem(
292 &Digests->digests[Index].digest,
293 Buffer,
294 DigestSize
295 );
296 Buffer += DigestSize;
297 }
298
299 return EFI_SUCCESS;
300 }
301
302 /**
303 This command returns the values of all PCR specified in pcrSelect.
304
305 @param[in] PcrSelectionIn The selection of PCR to read.
306 @param[out] PcrUpdateCounter The current value of the PCR update counter.
307 @param[out] PcrSelectionOut The PCR in the returned list.
308 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.
309
310 @retval EFI_SUCCESS Operation completed successfully.
311 @retval EFI_DEVICE_ERROR The command was unsuccessful.
312 **/
313 EFI_STATUS
314 EFIAPI
Tpm2PcrRead(IN TPML_PCR_SELECTION * PcrSelectionIn,OUT UINT32 * PcrUpdateCounter,OUT TPML_PCR_SELECTION * PcrSelectionOut,OUT TPML_DIGEST * PcrValues)315 Tpm2PcrRead (
316 IN TPML_PCR_SELECTION *PcrSelectionIn,
317 OUT UINT32 *PcrUpdateCounter,
318 OUT TPML_PCR_SELECTION *PcrSelectionOut,
319 OUT TPML_DIGEST *PcrValues
320 )
321 {
322 EFI_STATUS Status;
323 TPM2_PCR_READ_COMMAND SendBuffer;
324 TPM2_PCR_READ_RESPONSE RecvBuffer;
325 UINT32 SendBufferSize;
326 UINT32 RecvBufferSize;
327 UINTN Index;
328 TPML_DIGEST *PcrValuesOut;
329 TPM2B_DIGEST *Digests;
330
331 //
332 // Construct command
333 //
334 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
335 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);
336
337 SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);
338 for (Index = 0; Index < PcrSelectionIn->count; Index++) {
339 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);
340 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;
341 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);
342 }
343
344 SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;
345 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
346
347 //
348 // send Tpm command
349 //
350 RecvBufferSize = sizeof (RecvBuffer);
351 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
352 if (EFI_ERROR (Status)) {
353 return Status;
354 }
355
356 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
357 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
358 return EFI_DEVICE_ERROR;
359 }
360 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
361 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
362 return EFI_NOT_FOUND;
363 }
364
365 //
366 // Return the response
367 //
368
369 //
370 // PcrUpdateCounter
371 //
372 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {
373 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
374 return EFI_DEVICE_ERROR;
375 }
376 *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
377
378 //
379 // PcrSelectionOut
380 //
381 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {
382 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
383 return EFI_DEVICE_ERROR;
384 }
385 PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
386 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
387 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
388 return EFI_DEVICE_ERROR;
389 }
390 for (Index = 0; Index < PcrSelectionOut->count; Index++) {
391 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
392 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
393 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);
394 }
395
396 //
397 // PcrValues
398 //
399 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);
400 PcrValues->count = SwapBytes32(PcrValuesOut->count);
401 Digests = PcrValuesOut->digests;
402 for (Index = 0; Index < PcrValues->count; Index++) {
403 PcrValues->digests[Index].size = SwapBytes16(Digests->size);
404 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
405 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);
406 }
407
408 return EFI_SUCCESS;
409 }
410
411 /**
412 This command is used to set the desired PCR allocation of PCR and algorithms.
413
414 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
415 @param[in] AuthSession Auth Session context
416 @param[in] PcrAllocation The requested allocation
417 @param[out] AllocationSuccess YES if the allocation succeeded
418 @param[out] MaxPCR maximum number of PCR that may be in a bank
419 @param[out] SizeNeeded number of octets required to satisfy the request
420 @param[out] SizeAvailable Number of octets available. Computed before the allocation
421
422 @retval EFI_SUCCESS Operation completed successfully.
423 @retval EFI_DEVICE_ERROR The command was unsuccessful.
424 **/
425 EFI_STATUS
426 EFIAPI
Tpm2PcrAllocate(IN TPMI_RH_PLATFORM AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPML_PCR_SELECTION * PcrAllocation,OUT TPMI_YES_NO * AllocationSuccess,OUT UINT32 * MaxPCR,OUT UINT32 * SizeNeeded,OUT UINT32 * SizeAvailable)427 Tpm2PcrAllocate (
428 IN TPMI_RH_PLATFORM AuthHandle,
429 IN TPMS_AUTH_COMMAND *AuthSession,
430 IN TPML_PCR_SELECTION *PcrAllocation,
431 OUT TPMI_YES_NO *AllocationSuccess,
432 OUT UINT32 *MaxPCR,
433 OUT UINT32 *SizeNeeded,
434 OUT UINT32 *SizeAvailable
435 )
436 {
437 EFI_STATUS Status;
438 TPM2_PCR_ALLOCATE_COMMAND Cmd;
439 TPM2_PCR_ALLOCATE_RESPONSE Res;
440 UINT32 CmdSize;
441 UINT32 RespSize;
442 UINT8 *Buffer;
443 UINT32 SessionInfoSize;
444 UINT8 *ResultBuf;
445 UINT32 ResultBufSize;
446 UINTN Index;
447
448 //
449 // Construct command
450 //
451 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
452 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
453 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);
454 Cmd.AuthHandle = SwapBytes32(AuthHandle);
455
456 //
457 // Add in Auth session
458 //
459 Buffer = (UINT8 *)&Cmd.AuthSession;
460
461 // sessionInfoSize
462 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
463 Buffer += SessionInfoSize;
464 Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);
465
466 // Count
467 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));
468 Buffer += sizeof(UINT32);
469 for (Index = 0; Index < PcrAllocation->count; Index++) {
470 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));
471 Buffer += sizeof(UINT16);
472 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
473 Buffer++;
474 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
475 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
476 }
477
478 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
479 Cmd.Header.paramSize = SwapBytes32(CmdSize);
480
481 ResultBuf = (UINT8 *) &Res;
482 ResultBufSize = sizeof(Res);
483
484 //
485 // Call the TPM
486 //
487 Status = Tpm2SubmitCommand (
488 CmdSize,
489 (UINT8 *)&Cmd,
490 &ResultBufSize,
491 ResultBuf
492 );
493 if (EFI_ERROR(Status)) {
494 goto Done;
495 }
496
497 if (ResultBufSize > sizeof(Res)) {
498 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
499 Status = EFI_BUFFER_TOO_SMALL;
500 goto Done;
501 }
502
503 //
504 // Validate response headers
505 //
506 RespSize = SwapBytes32(Res.Header.paramSize);
507 if (RespSize > sizeof(Res)) {
508 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
509 Status = EFI_BUFFER_TOO_SMALL;
510 goto Done;
511 }
512
513 //
514 // Fail if command failed
515 //
516 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
517 DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
518 Status = EFI_DEVICE_ERROR;
519 goto Done;
520 }
521
522 //
523 // Return the response
524 //
525 *AllocationSuccess = Res.AllocationSuccess;
526 *MaxPCR = SwapBytes32(Res.MaxPCR);
527 *SizeNeeded = SwapBytes32(Res.SizeNeeded);
528 *SizeAvailable = SwapBytes32(Res.SizeAvailable);
529
530 Done:
531 //
532 // Clear AuthSession Content
533 //
534 ZeroMem (&Cmd, sizeof(Cmd));
535 ZeroMem (&Res, sizeof(Res));
536 return Status;
537 }
538
539 /**
540 Alloc PCR data.
541
542 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
543 @param[in] SupportedPCRBanks Supported PCR banks
544 @param[in] PCRBanks PCR banks
545
546 @retval EFI_SUCCESS Operation completed successfully.
547 **/
548 EFI_STATUS
549 EFIAPI
Tpm2PcrAllocateBanks(IN TPM2B_AUTH * PlatformAuth,OPTIONAL IN UINT32 SupportedPCRBanks,IN UINT32 PCRBanks)550 Tpm2PcrAllocateBanks (
551 IN TPM2B_AUTH *PlatformAuth, OPTIONAL
552 IN UINT32 SupportedPCRBanks,
553 IN UINT32 PCRBanks
554 )
555 {
556 EFI_STATUS Status;
557 TPMS_AUTH_COMMAND *AuthSession;
558 TPMS_AUTH_COMMAND LocalAuthSession;
559 TPML_PCR_SELECTION PcrAllocation;
560 TPMI_YES_NO AllocationSuccess;
561 UINT32 MaxPCR;
562 UINT32 SizeNeeded;
563 UINT32 SizeAvailable;
564
565 if (PlatformAuth == NULL) {
566 AuthSession = NULL;
567 } else {
568 AuthSession = &LocalAuthSession;
569 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));
570 LocalAuthSession.sessionHandle = TPM_RS_PW;
571 LocalAuthSession.hmac.size = PlatformAuth->size;
572 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
573 }
574
575 //
576 // Fill input
577 //
578 ZeroMem (&PcrAllocation, sizeof(PcrAllocation));
579 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
580 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;
581 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
582 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
583 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
584 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
585 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
586 } else {
587 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
588 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
589 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
590 }
591 PcrAllocation.count++;
592 }
593 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
594 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;
595 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
596 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {
597 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
598 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
599 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
600 } else {
601 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
602 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
603 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
604 }
605 PcrAllocation.count++;
606 }
607 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
608 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;
609 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
610 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
611 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
612 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
613 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
614 } else {
615 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
616 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
617 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
618 }
619 PcrAllocation.count++;
620 }
621 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
622 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;
623 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
624 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
625 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
626 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
627 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
628 } else {
629 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
630 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
631 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
632 }
633 PcrAllocation.count++;
634 }
635 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
636 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;
637 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
638 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {
639 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
640 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
641 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
642 } else {
643 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
644 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
645 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
646 }
647 PcrAllocation.count++;
648 }
649 Status = Tpm2PcrAllocate (
650 TPM_RH_PLATFORM,
651 AuthSession,
652 &PcrAllocation,
653 &AllocationSuccess,
654 &MaxPCR,
655 &SizeNeeded,
656 &SizeAvailable
657 );
658 DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
659 if (EFI_ERROR (Status)) {
660 goto Done;
661 }
662
663 DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
664 DEBUG ((EFI_D_INFO, "MaxPCR - %08x\n", MaxPCR));
665 DEBUG ((EFI_D_INFO, "SizeNeeded - %08x\n", SizeNeeded));
666 DEBUG ((EFI_D_INFO, "SizeAvailable - %08x\n", SizeAvailable));
667
668 Done:
669 ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));
670 return Status;
671 }