TianoCore EDK2 master
Loading...
Searching...
No Matches
Tpm2Integrity.c
Go to the documentation of this file.
1
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15
16#pragma pack(1)
17
18typedef struct {
20 TPMI_DH_PCR PcrHandle;
21 UINT32 AuthorizationSize;
22 TPMS_AUTH_COMMAND AuthSessionPcr;
23 TPML_DIGEST_VALUES DigestValues;
25
26typedef struct {
28 UINT32 ParameterSize;
29 TPMS_AUTH_RESPONSE AuthSessionPcr;
31
32typedef struct {
34 TPMI_DH_PCR PcrHandle;
35 UINT32 AuthorizationSize;
36 TPMS_AUTH_COMMAND AuthSessionPcr;
37 TPM2B_EVENT EventData;
39
40typedef struct {
42 UINT32 ParameterSize;
43 TPML_DIGEST_VALUES Digests;
44 TPMS_AUTH_RESPONSE AuthSessionPcr;
46
47typedef struct {
49 TPML_PCR_SELECTION PcrSelectionIn;
51
52typedef struct {
54 UINT32 PcrUpdateCounter;
55 TPML_PCR_SELECTION PcrSelectionOut;
56 TPML_DIGEST PcrValues;
58
59typedef struct {
61 TPMI_RH_PLATFORM AuthHandle;
62 UINT32 AuthSessionSize;
63 TPMS_AUTH_COMMAND AuthSession;
64 TPML_PCR_SELECTION PcrAllocation;
66
67typedef struct {
69 UINT32 AuthSessionSize;
70 TPMI_YES_NO AllocationSuccess;
71 UINT32 MaxPCR;
72 UINT32 SizeNeeded;
73 UINT32 SizeAvailable;
74 TPMS_AUTH_RESPONSE AuthSession;
76
77#pragma pack()
78
91EFIAPI
93 IN TPMI_DH_PCR PcrHandle,
94 IN TPML_DIGEST_VALUES *Digests
95 )
96{
97 EFI_STATUS Status;
100 UINT32 CmdSize;
101 UINT32 RespSize;
102 UINT32 ResultBufSize;
103 UINT8 *Buffer;
104 UINTN Index;
105 UINT32 SessionInfoSize;
106 UINT16 DigestSize;
107
108 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
109 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);
110 Cmd.PcrHandle = SwapBytes32 (PcrHandle);
111
112 //
113 // Add in Auth session
114 //
115 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
116
117 // sessionInfoSize
118 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
119 Buffer += SessionInfoSize;
120 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
121
122 // Digest Count
123 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));
124 Buffer += sizeof (UINT32);
125
126 // Digest
127 for (Index = 0; Index < Digests->count; Index++) {
128 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));
129 Buffer += sizeof (UINT16);
130 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
131 if (DigestSize == 0) {
132 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
133 return EFI_DEVICE_ERROR;
134 }
135
136 CopyMem (
137 Buffer,
138 &Digests->digests[Index].digest,
139 DigestSize
140 );
141
143 UINTN Index2;
144 DEBUG ((
145 DEBUG_VERBOSE,
146 "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",
147 Digests->digests[Index].hashAlg,
148 (UINT8)PcrHandle
149 ));
150
151 for (Index2 = 0; Index2 < DigestSize; Index2++) {
152 DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));
153 }
154
155 DEBUG ((DEBUG_VERBOSE, "\n"));
157
158 Buffer += DigestSize;
159 }
160
161 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
162 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
163
164 ResultBufSize = sizeof (Res);
165 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
166 if (EFI_ERROR (Status)) {
167 return Status;
168 }
169
170 if (ResultBufSize > sizeof (Res)) {
171 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
172 return EFI_BUFFER_TOO_SMALL;
173 }
174
175 //
176 // Validate response headers
177 //
178 RespSize = SwapBytes32 (Res.Header.paramSize);
179 if (RespSize > sizeof (Res)) {
180 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
181 return EFI_BUFFER_TOO_SMALL;
182 }
183
184 //
185 // Fail if command failed
186 //
187 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
188 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
189 return EFI_DEVICE_ERROR;
190 }
191
193 DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));
194 Tpm2PcrReadForActiveBank (PcrHandle, NULL);
196
197 //
198 // Unmarshal the response
199 //
200
201 // None
202
203 return EFI_SUCCESS;
204}
205
222EFIAPI
224 IN TPMI_DH_PCR PcrHandle,
225 IN TPM2B_EVENT *EventData,
226 OUT TPML_DIGEST_VALUES *Digests
227 )
228{
229 EFI_STATUS Status;
232 UINT32 CmdSize;
233 UINT32 RespSize;
234 UINT32 ResultBufSize;
235 UINT8 *Buffer;
236 UINTN Index;
237 UINT32 SessionInfoSize;
238 UINT16 DigestSize;
239
240 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
241 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);
242 Cmd.PcrHandle = SwapBytes32 (PcrHandle);
243
244 //
245 // Add in Auth session
246 //
247 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
248
249 // sessionInfoSize
250 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
251 Buffer += SessionInfoSize;
252 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
253
254 // Event
255 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));
256 Buffer += sizeof (UINT16);
257
258 CopyMem (Buffer, EventData->buffer, EventData->size);
259 Buffer += EventData->size;
260
261 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
262 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
263
264 ResultBufSize = sizeof (Res);
265 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
266 if (EFI_ERROR (Status)) {
267 return Status;
268 }
269
270 if (ResultBufSize > sizeof (Res)) {
271 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
272 return EFI_BUFFER_TOO_SMALL;
273 }
274
275 //
276 // Validate response headers
277 //
278 RespSize = SwapBytes32 (Res.Header.paramSize);
279 if (RespSize > sizeof (Res)) {
280 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
281 return EFI_BUFFER_TOO_SMALL;
282 }
283
284 //
285 // Fail if command failed
286 //
287 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
288 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
289 return EFI_DEVICE_ERROR;
290 }
291
292 //
293 // Unmarshal the response
294 //
295 Buffer = (UINT8 *)&Res.Digests;
296
297 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
298 if (Digests->count > HASH_COUNT) {
299 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));
300 return EFI_DEVICE_ERROR;
301 }
302
303 Buffer += sizeof (UINT32);
304 for (Index = 0; Index < Digests->count; Index++) {
305 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
306 Buffer += sizeof (UINT16);
307 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
308 if (DigestSize == 0) {
309 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
310 return EFI_DEVICE_ERROR;
311 }
312
313 CopyMem (
314 &Digests->digests[Index].digest,
315 Buffer,
316 DigestSize
317 );
318 Buffer += DigestSize;
319 }
320
321 return EFI_SUCCESS;
322}
323
336EFIAPI
338 IN TPML_PCR_SELECTION *PcrSelectionIn,
339 OUT UINT32 *PcrUpdateCounter,
340 OUT TPML_PCR_SELECTION *PcrSelectionOut,
341 OUT TPML_DIGEST *PcrValues
342 )
343{
344 EFI_STATUS Status;
345 TPM2_PCR_READ_COMMAND SendBuffer;
346 TPM2_PCR_READ_RESPONSE RecvBuffer;
347 UINT32 SendBufferSize;
348 UINT32 RecvBufferSize;
349 UINTN Index;
350 TPML_DIGEST *PcrValuesOut;
351 TPM2B_DIGEST *Digests;
352
353 //
354 // Construct command
355 //
356 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);
357 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);
358
359 SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);
360 for (Index = 0; Index < PcrSelectionIn->count; Index++) {
361 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);
362 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;
363 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);
364 }
365
366 SendBufferSize = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;
367 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
368
369 //
370 // send Tpm command
371 //
372 RecvBufferSize = sizeof (RecvBuffer);
373 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
374 if (EFI_ERROR (Status)) {
375 return Status;
376 }
377
378 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
379 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
380 return EFI_DEVICE_ERROR;
381 }
382
383 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
384 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
385 return EFI_NOT_FOUND;
386 }
387
388 //
389 // Return the response
390 //
391
392 //
393 // PcrUpdateCounter
394 //
395 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {
396 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
397 return EFI_DEVICE_ERROR;
398 }
399
400 *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);
401
402 //
403 // PcrSelectionOut
404 //
405 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {
406 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
407 return EFI_DEVICE_ERROR;
408 }
409
410 PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);
411 if (PcrSelectionOut->count > HASH_COUNT) {
412 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));
413 return EFI_DEVICE_ERROR;
414 }
415
416 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
417 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
418 return EFI_DEVICE_ERROR;
419 }
420
421 for (Index = 0; Index < PcrSelectionOut->count; Index++) {
422 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
423 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
424 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {
425 return EFI_DEVICE_ERROR;
426 }
427
428 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);
429 }
430
431 //
432 // PcrValues
433 //
434 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);
435 PcrValues->count = SwapBytes32 (PcrValuesOut->count);
436 //
437 // The number of digests in list is not greater than 8 per TPML_DIGEST definition
438 //
439 if (PcrValues->count > 8) {
440 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));
441 return EFI_DEVICE_ERROR;
442 }
443
444 Digests = PcrValuesOut->digests;
445 for (Index = 0; Index < PcrValues->count; Index++) {
446 PcrValues->digests[Index].size = SwapBytes16 (Digests->size);
447 if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {
448 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));
449 return EFI_DEVICE_ERROR;
450 }
451
452 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
453 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);
454 }
455
456 return EFI_SUCCESS;
457}
458
474EFIAPI
476 IN TPMI_RH_PLATFORM AuthHandle,
477 IN TPMS_AUTH_COMMAND *AuthSession,
478 IN TPML_PCR_SELECTION *PcrAllocation,
479 OUT TPMI_YES_NO *AllocationSuccess,
480 OUT UINT32 *MaxPCR,
481 OUT UINT32 *SizeNeeded,
482 OUT UINT32 *SizeAvailable
483 )
484{
485 EFI_STATUS Status;
488 UINT32 CmdSize;
489 UINT32 RespSize;
490 UINT8 *Buffer;
491 UINT32 SessionInfoSize;
492 UINT8 *ResultBuf;
493 UINT32 ResultBufSize;
494 UINTN Index;
495
496 //
497 // Construct command
498 //
499 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
500 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
501 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);
502 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
503
504 //
505 // Add in Auth session
506 //
507 Buffer = (UINT8 *)&Cmd.AuthSession;
508
509 // sessionInfoSize
510 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
511 Buffer += SessionInfoSize;
512 Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);
513
514 // Count
515 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));
516 Buffer += sizeof (UINT32);
517 for (Index = 0; Index < PcrAllocation->count; Index++) {
518 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));
519 Buffer += sizeof (UINT16);
520 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
521 Buffer++;
522 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
523 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
524 }
525
526 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
527 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
528
529 ResultBuf = (UINT8 *)&Res;
530 ResultBufSize = sizeof (Res);
531
532 //
533 // Call the TPM
534 //
535 Status = Tpm2SubmitCommand (
536 CmdSize,
537 (UINT8 *)&Cmd,
538 &ResultBufSize,
539 ResultBuf
540 );
541 if (EFI_ERROR (Status)) {
542 goto Done;
543 }
544
545 if (ResultBufSize > sizeof (Res)) {
546 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
547 Status = EFI_BUFFER_TOO_SMALL;
548 goto Done;
549 }
550
551 //
552 // Validate response headers
553 //
554 RespSize = SwapBytes32 (Res.Header.paramSize);
555 if (RespSize > sizeof (Res)) {
556 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
557 Status = EFI_BUFFER_TOO_SMALL;
558 goto Done;
559 }
560
561 //
562 // Fail if command failed
563 //
564 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
565 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
566 Status = EFI_DEVICE_ERROR;
567 goto Done;
568 }
569
570 //
571 // Return the response
572 //
573 *AllocationSuccess = Res.AllocationSuccess;
574 *MaxPCR = SwapBytes32 (Res.MaxPCR);
575 *SizeNeeded = SwapBytes32 (Res.SizeNeeded);
576 *SizeAvailable = SwapBytes32 (Res.SizeAvailable);
577
578Done:
579 //
580 // Clear AuthSession Content
581 //
582 ZeroMem (&Cmd, sizeof (Cmd));
583 ZeroMem (&Res, sizeof (Res));
584 return Status;
585}
586
597EFIAPI
599 IN TPM2B_AUTH *PlatformAuth OPTIONAL,
600 IN UINT32 SupportedPCRBanks,
601 IN UINT32 PCRBanks
602 )
603{
604 EFI_STATUS Status;
605 TPMS_AUTH_COMMAND *AuthSession;
606 TPMS_AUTH_COMMAND LocalAuthSession;
607 TPML_PCR_SELECTION PcrAllocation;
608 TPMI_YES_NO AllocationSuccess;
609 UINT32 MaxPCR;
610 UINT32 SizeNeeded;
611 UINT32 SizeAvailable;
612
613 if (PlatformAuth == NULL) {
614 AuthSession = NULL;
615 } else {
616 AuthSession = &LocalAuthSession;
617 ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
618 LocalAuthSession.sessionHandle = TPM_RS_PW;
619 LocalAuthSession.hmac.size = PlatformAuth->size;
620 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
621 }
622
623 //
624 // Fill input
625 //
626 ZeroMem (&PcrAllocation, sizeof (PcrAllocation));
627 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
628 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;
629 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
630 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
631 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
632 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
633 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
634 } else {
635 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
636 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
637 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
638 }
639
640 PcrAllocation.count++;
641 }
642
643 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
644 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;
645 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
646 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {
647 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
648 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
649 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
650 } else {
651 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
652 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
653 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
654 }
655
656 PcrAllocation.count++;
657 }
658
659 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
660 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;
661 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
662 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
663 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
664 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
665 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
666 } else {
667 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
668 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
669 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
670 }
671
672 PcrAllocation.count++;
673 }
674
675 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
676 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;
677 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
678 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
679 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
680 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
681 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
682 } else {
683 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
684 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
685 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
686 }
687
688 PcrAllocation.count++;
689 }
690
691 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
692 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;
693 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
694 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {
695 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
696 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
697 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
698 } else {
699 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
700 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
701 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
702 }
703
704 PcrAllocation.count++;
705 }
706
707 Status = Tpm2PcrAllocate (
708 TPM_RH_PLATFORM,
709 AuthSession,
710 &PcrAllocation,
711 &AllocationSuccess,
712 &MaxPCR,
713 &SizeNeeded,
714 &SizeAvailable
715 );
716 DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
717 if (EFI_ERROR (Status)) {
718 goto Done;
719 }
720
721 DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
722 DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));
723 DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));
724 DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));
725
726Done:
727 ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
728 return Status;
729}
730
742EFIAPI
744 IN TPMI_DH_PCR PcrHandle,
745 OUT TPML_DIGEST *HashList
746 )
747{
748 EFI_STATUS Status;
750 TPML_PCR_SELECTION PcrSelectionIn;
751 TPML_PCR_SELECTION PcrSelectionOut;
752 TPML_DIGEST PcrValues;
753 UINT32 PcrUpdateCounter;
754 UINT8 PcrIndex;
755 UINT32 TpmHashAlgorithmBitmap;
756 TPMI_ALG_HASH CurrentPcrBankHash;
757 UINT32 ActivePcrBanks;
758 UINT32 TcgRegistryHashAlg;
759 UINTN Index;
760 UINTN Index2;
761
762 PcrIndex = (UINT8)PcrHandle;
763
764 if ((PcrIndex < 0) ||
765 (PcrIndex >= IMPLEMENTATION_PCR))
766 {
767 return EFI_INVALID_PARAMETER;
768 }
769
770 ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));
771 ZeroMem (&PcrUpdateCounter, sizeof (UINT32));
772 ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));
773 ZeroMem (&PcrValues, sizeof (PcrValues));
774 ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));
775
776 DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
777
778 //
779 // Read TPM capabilities
780 //
781 Status = Tpm2GetCapabilityPcrs (&Pcrs);
782
783 if (EFI_ERROR (Status)) {
784 DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));
785 return EFI_DEVICE_ERROR;
786 }
787
788 //
789 // Get Active Pcrs
790 //
792 &TpmHashAlgorithmBitmap,
793 &ActivePcrBanks
794 );
795
796 if (EFI_ERROR (Status)) {
797 DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));
798 return EFI_DEVICE_ERROR;
799 }
800
801 //
802 // Select from Active PCRs
803 //
804 for (Index = 0; Index < Pcrs.count; Index++) {
805 CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;
806
807 switch (CurrentPcrBankHash) {
808 case TPM_ALG_SHA1:
809 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));
810 TcgRegistryHashAlg = HASH_ALG_SHA1;
811 break;
812 case TPM_ALG_SHA256:
813 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));
814 TcgRegistryHashAlg = HASH_ALG_SHA256;
815 break;
816 case TPM_ALG_SHA384:
817 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));
818 TcgRegistryHashAlg = HASH_ALG_SHA384;
819 break;
820 case TPM_ALG_SHA512:
821 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));
822 TcgRegistryHashAlg = HASH_ALG_SHA512;
823 break;
824 case TPM_ALG_SM3_256:
825 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));
826 TcgRegistryHashAlg = HASH_ALG_SM3_256;
827 break;
828 default:
829 //
830 // Unsupported algorithm
831 //
832 DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));
833 TcgRegistryHashAlg = 0;
834 break;
835 }
836
837 //
838 // Skip unsupported and inactive PCR banks
839 //
840 if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {
841 DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));
842 continue;
843 }
844
845 //
846 // Select PCR from current active bank
847 //
848 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash = Pcrs.pcrSelections[Index].hash;
849 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;
850 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;
851 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;
852 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;
853 PcrSelectionIn.count++;
854 }
855
856 //
857 // Read PCRs
858 //
859 Status = Tpm2PcrRead (
860 &PcrSelectionIn,
861 &PcrUpdateCounter,
862 &PcrSelectionOut,
863 &PcrValues
864 );
865
866 if (EFI_ERROR (Status)) {
867 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));
868 return EFI_DEVICE_ERROR;
869 }
870
871 for (Index = 0; Index < PcrValues.count; Index++) {
872 DEBUG ((
873 DEBUG_INFO,
874 "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
875 PcrSelectionOut.pcrSelections[Index].hash,
876 PcrIndex
877 ));
878
879 for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
880 DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
881 }
882
883 DEBUG ((DEBUG_INFO, "\n"));
884 }
885
886 if (HashList != NULL) {
887 CopyMem (
888 HashList,
889 &PcrValues,
890 sizeof (TPML_DIGEST)
891 );
892 }
893
894 return EFI_SUCCESS;
895}
UINT64 UINTN
UINT16 EFIAPI SwapBytes16(IN UINT16 Value)
Definition: SwapBytes16.c:25
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
Definition: Unaligned.c:29
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
Definition: Unaligned.c:61
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
UINT16 GetHashSizeFromAlgo(IN TPMI_ALG_HASH HashAlgo)
Definition: TdTcg2Dxe.c:152
EFI_STATUS EFIAPI Tpm2GetCapabilitySupportedAndActivePcrs(OUT UINT32 *TpmHashAlgorithmBitmap, OUT UINT32 *ActivePcrBanks)
UINT32 EFIAPI CopyAuthSessionCommand(IN TPMS_AUTH_COMMAND *AuthSessionIn OPTIONAL, OUT UINT8 *AuthSessionOut)
Definition: Tpm2Help.c:88
EFI_STATUS EFIAPI Tpm2GetCapabilityPcrs(OUT TPML_PCR_SELECTION *Pcrs)
EFI_STATUS EFIAPI Tpm2SubmitCommand(IN UINT32 InputParameterBlockSize, IN UINT8 *InputParameterBlock, IN OUT UINT32 *OutputParameterBlockSize, IN UINT8 *OutputParameterBlock)
EFI_STATUS EFIAPI Tpm2PcrEvent(IN TPMI_DH_PCR PcrHandle, IN TPM2B_EVENT *EventData, OUT TPML_DIGEST_VALUES *Digests)
EFI_STATUS 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)
EFI_STATUS EFIAPI Tpm2PcrAllocateBanks(IN TPM2B_AUTH *PlatformAuth OPTIONAL, IN UINT32 SupportedPCRBanks, IN UINT32 PCRBanks)
EFI_STATUS EFIAPI Tpm2PcrRead(IN TPML_PCR_SELECTION *PcrSelectionIn, OUT UINT32 *PcrUpdateCounter, OUT TPML_PCR_SELECTION *PcrSelectionOut, OUT TPML_DIGEST *PcrValues)
EFI_STATUS EFIAPI Tpm2PcrExtend(IN TPMI_DH_PCR PcrHandle, IN TPML_DIGEST_VALUES *Digests)
Definition: Tpm2Integrity.c:92
EFI_STATUS EFIAPI Tpm2PcrReadForActiveBank(IN TPMI_DH_PCR PcrHandle, OUT TPML_DIGEST *HashList)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Tpm20.h:905