]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
8dde5f34a27338fa6245f09d4f7799a237c5f4a3
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
1 /** @file
2 Implement TPM2 Integrity related command.
3
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <IndustryStandard/UefiTcgPlatform.h>
10 #include <Library/Tpm2CommandLib.h>
11 #include <Library/Tpm2DeviceLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/BaseLib.h>
14 #include <Library/DebugLib.h>
15
16 #pragma pack(1)
17
18 typedef struct {
19 TPM2_COMMAND_HEADER Header;
20 TPMI_DH_PCR PcrHandle;
21 UINT32 AuthorizationSize;
22 TPMS_AUTH_COMMAND AuthSessionPcr;
23 TPML_DIGEST_VALUES DigestValues;
24 } TPM2_PCR_EXTEND_COMMAND;
25
26 typedef struct {
27 TPM2_RESPONSE_HEADER Header;
28 UINT32 ParameterSize;
29 TPMS_AUTH_RESPONSE AuthSessionPcr;
30 } TPM2_PCR_EXTEND_RESPONSE;
31
32 typedef struct {
33 TPM2_COMMAND_HEADER Header;
34 TPMI_DH_PCR PcrHandle;
35 UINT32 AuthorizationSize;
36 TPMS_AUTH_COMMAND AuthSessionPcr;
37 TPM2B_EVENT EventData;
38 } TPM2_PCR_EVENT_COMMAND;
39
40 typedef struct {
41 TPM2_RESPONSE_HEADER Header;
42 UINT32 ParameterSize;
43 TPML_DIGEST_VALUES Digests;
44 TPMS_AUTH_RESPONSE AuthSessionPcr;
45 } TPM2_PCR_EVENT_RESPONSE;
46
47 typedef struct {
48 TPM2_COMMAND_HEADER Header;
49 TPML_PCR_SELECTION PcrSelectionIn;
50 } TPM2_PCR_READ_COMMAND;
51
52 typedef struct {
53 TPM2_RESPONSE_HEADER Header;
54 UINT32 PcrUpdateCounter;
55 TPML_PCR_SELECTION PcrSelectionOut;
56 TPML_DIGEST PcrValues;
57 } TPM2_PCR_READ_RESPONSE;
58
59 typedef struct {
60 TPM2_COMMAND_HEADER Header;
61 TPMI_RH_PLATFORM AuthHandle;
62 UINT32 AuthSessionSize;
63 TPMS_AUTH_COMMAND AuthSession;
64 TPML_PCR_SELECTION PcrAllocation;
65 } TPM2_PCR_ALLOCATE_COMMAND;
66
67 typedef struct {
68 TPM2_RESPONSE_HEADER Header;
69 UINT32 AuthSessionSize;
70 TPMI_YES_NO AllocationSuccess;
71 UINT32 MaxPCR;
72 UINT32 SizeNeeded;
73 UINT32 SizeAvailable;
74 TPMS_AUTH_RESPONSE AuthSession;
75 } TPM2_PCR_ALLOCATE_RESPONSE;
76
77 #pragma pack()
78
79 /**
80 This command is used to cause an update to the indicated PCR.
81 The digests parameter contains one or more tagged digest value identified by an algorithm ID.
82 For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).
83
84 @param[in] PcrHandle Handle of the PCR
85 @param[in] Digests List of tagged digest values to be extended
86
87 @retval EFI_SUCCESS Operation completed successfully.
88 @retval EFI_DEVICE_ERROR Unexpected device behavior.
89 **/
90 EFI_STATUS
91 EFIAPI
92 Tpm2PcrExtend (
93 IN TPMI_DH_PCR PcrHandle,
94 IN TPML_DIGEST_VALUES *Digests
95 )
96 {
97 EFI_STATUS Status;
98 TPM2_PCR_EXTEND_COMMAND Cmd;
99 TPM2_PCR_EXTEND_RESPONSE Res;
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 Buffer += DigestSize;
142 }
143
144 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
145 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
146
147 ResultBufSize = sizeof (Res);
148 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
149 if (EFI_ERROR (Status)) {
150 return Status;
151 }
152
153 if (ResultBufSize > sizeof (Res)) {
154 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
155 return EFI_BUFFER_TOO_SMALL;
156 }
157
158 //
159 // Validate response headers
160 //
161 RespSize = SwapBytes32 (Res.Header.paramSize);
162 if (RespSize > sizeof (Res)) {
163 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
164 return EFI_BUFFER_TOO_SMALL;
165 }
166
167 //
168 // Fail if command failed
169 //
170 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
171 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
172 return EFI_DEVICE_ERROR;
173 }
174
175 //
176 // Unmarshal the response
177 //
178
179 // None
180
181 return EFI_SUCCESS;
182 }
183
184 /**
185 This command is used to cause an update to the indicated PCR.
186 The data in eventData is hashed using the hash algorithm associated with each bank in which the
187 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle
188 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in
189 TPM2_PCR_Extend().
190 A TPM shall support an Event.size of zero through 1,024 inclusive.
191
192 @param[in] PcrHandle Handle of the PCR
193 @param[in] EventData Event data in sized buffer
194 @param[out] Digests List of digest
195
196 @retval EFI_SUCCESS Operation completed successfully.
197 @retval EFI_DEVICE_ERROR Unexpected device behavior.
198 **/
199 EFI_STATUS
200 EFIAPI
201 Tpm2PcrEvent (
202 IN TPMI_DH_PCR PcrHandle,
203 IN TPM2B_EVENT *EventData,
204 OUT TPML_DIGEST_VALUES *Digests
205 )
206 {
207 EFI_STATUS Status;
208 TPM2_PCR_EVENT_COMMAND Cmd;
209 TPM2_PCR_EVENT_RESPONSE Res;
210 UINT32 CmdSize;
211 UINT32 RespSize;
212 UINT32 ResultBufSize;
213 UINT8 *Buffer;
214 UINTN Index;
215 UINT32 SessionInfoSize;
216 UINT16 DigestSize;
217
218 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
219 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);
220 Cmd.PcrHandle = SwapBytes32 (PcrHandle);
221
222 //
223 // Add in Auth session
224 //
225 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;
226
227 // sessionInfoSize
228 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);
229 Buffer += SessionInfoSize;
230 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
231
232 // Event
233 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));
234 Buffer += sizeof (UINT16);
235
236 CopyMem (Buffer, EventData->buffer, EventData->size);
237 Buffer += EventData->size;
238
239 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
240 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
241
242 ResultBufSize = sizeof (Res);
243 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
244 if (EFI_ERROR (Status)) {
245 return Status;
246 }
247
248 if (ResultBufSize > sizeof (Res)) {
249 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
250 return EFI_BUFFER_TOO_SMALL;
251 }
252
253 //
254 // Validate response headers
255 //
256 RespSize = SwapBytes32 (Res.Header.paramSize);
257 if (RespSize > sizeof (Res)) {
258 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
259 return EFI_BUFFER_TOO_SMALL;
260 }
261
262 //
263 // Fail if command failed
264 //
265 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
266 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
267 return EFI_DEVICE_ERROR;
268 }
269
270 //
271 // Unmarshal the response
272 //
273 Buffer = (UINT8 *)&Res.Digests;
274
275 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
276 if (Digests->count > HASH_COUNT) {
277 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));
278 return EFI_DEVICE_ERROR;
279 }
280
281 Buffer += sizeof (UINT32);
282 for (Index = 0; Index < Digests->count; Index++) {
283 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
284 Buffer += sizeof (UINT16);
285 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
286 if (DigestSize == 0) {
287 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
288 return EFI_DEVICE_ERROR;
289 }
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
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 ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
358 return EFI_DEVICE_ERROR;
359 }
360
361 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
362 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
363 return EFI_NOT_FOUND;
364 }
365
366 //
367 // Return the response
368 //
369
370 //
371 // PcrUpdateCounter
372 //
373 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {
374 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
375 return EFI_DEVICE_ERROR;
376 }
377
378 *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);
379
380 //
381 // PcrSelectionOut
382 //
383 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {
384 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
385 return EFI_DEVICE_ERROR;
386 }
387
388 PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);
389 if (PcrSelectionOut->count > HASH_COUNT) {
390 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));
391 return EFI_DEVICE_ERROR;
392 }
393
394 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
395 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
396 return EFI_DEVICE_ERROR;
397 }
398
399 for (Index = 0; Index < PcrSelectionOut->count; Index++) {
400 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
401 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
402 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {
403 return EFI_DEVICE_ERROR;
404 }
405
406 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);
407 }
408
409 //
410 // PcrValues
411 //
412 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);
413 PcrValues->count = SwapBytes32 (PcrValuesOut->count);
414 //
415 // The number of digests in list is not greater than 8 per TPML_DIGEST definition
416 //
417 if (PcrValues->count > 8) {
418 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));
419 return EFI_DEVICE_ERROR;
420 }
421
422 Digests = PcrValuesOut->digests;
423 for (Index = 0; Index < PcrValues->count; Index++) {
424 PcrValues->digests[Index].size = SwapBytes16 (Digests->size);
425 if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {
426 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));
427 return EFI_DEVICE_ERROR;
428 }
429
430 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
431 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);
432 }
433
434 return EFI_SUCCESS;
435 }
436
437 /**
438 This command is used to set the desired PCR allocation of PCR and algorithms.
439
440 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
441 @param[in] AuthSession Auth Session context
442 @param[in] PcrAllocation The requested allocation
443 @param[out] AllocationSuccess YES if the allocation succeeded
444 @param[out] MaxPCR maximum number of PCR that may be in a bank
445 @param[out] SizeNeeded number of octets required to satisfy the request
446 @param[out] SizeAvailable Number of octets available. Computed before the allocation
447
448 @retval EFI_SUCCESS Operation completed successfully.
449 @retval EFI_DEVICE_ERROR The command was unsuccessful.
450 **/
451 EFI_STATUS
452 EFIAPI
453 Tpm2PcrAllocate (
454 IN TPMI_RH_PLATFORM AuthHandle,
455 IN TPMS_AUTH_COMMAND *AuthSession,
456 IN TPML_PCR_SELECTION *PcrAllocation,
457 OUT TPMI_YES_NO *AllocationSuccess,
458 OUT UINT32 *MaxPCR,
459 OUT UINT32 *SizeNeeded,
460 OUT UINT32 *SizeAvailable
461 )
462 {
463 EFI_STATUS Status;
464 TPM2_PCR_ALLOCATE_COMMAND Cmd;
465 TPM2_PCR_ALLOCATE_RESPONSE Res;
466 UINT32 CmdSize;
467 UINT32 RespSize;
468 UINT8 *Buffer;
469 UINT32 SessionInfoSize;
470 UINT8 *ResultBuf;
471 UINT32 ResultBufSize;
472 UINTN Index;
473
474 //
475 // Construct command
476 //
477 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
478 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));
479 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);
480 Cmd.AuthHandle = SwapBytes32 (AuthHandle);
481
482 //
483 // Add in Auth session
484 //
485 Buffer = (UINT8 *)&Cmd.AuthSession;
486
487 // sessionInfoSize
488 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
489 Buffer += SessionInfoSize;
490 Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);
491
492 // Count
493 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));
494 Buffer += sizeof (UINT32);
495 for (Index = 0; Index < PcrAllocation->count; Index++) {
496 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));
497 Buffer += sizeof (UINT16);
498 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
499 Buffer++;
500 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
501 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
502 }
503
504 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
505 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
506
507 ResultBuf = (UINT8 *)&Res;
508 ResultBufSize = sizeof (Res);
509
510 //
511 // Call the TPM
512 //
513 Status = Tpm2SubmitCommand (
514 CmdSize,
515 (UINT8 *)&Cmd,
516 &ResultBufSize,
517 ResultBuf
518 );
519 if (EFI_ERROR (Status)) {
520 goto Done;
521 }
522
523 if (ResultBufSize > sizeof (Res)) {
524 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
525 Status = EFI_BUFFER_TOO_SMALL;
526 goto Done;
527 }
528
529 //
530 // Validate response headers
531 //
532 RespSize = SwapBytes32 (Res.Header.paramSize);
533 if (RespSize > sizeof (Res)) {
534 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
535 Status = EFI_BUFFER_TOO_SMALL;
536 goto Done;
537 }
538
539 //
540 // Fail if command failed
541 //
542 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
543 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
544 Status = EFI_DEVICE_ERROR;
545 goto Done;
546 }
547
548 //
549 // Return the response
550 //
551 *AllocationSuccess = Res.AllocationSuccess;
552 *MaxPCR = SwapBytes32 (Res.MaxPCR);
553 *SizeNeeded = SwapBytes32 (Res.SizeNeeded);
554 *SizeAvailable = SwapBytes32 (Res.SizeAvailable);
555
556 Done:
557 //
558 // Clear AuthSession Content
559 //
560 ZeroMem (&Cmd, sizeof (Cmd));
561 ZeroMem (&Res, sizeof (Res));
562 return Status;
563 }
564
565 /**
566 Alloc PCR data.
567
568 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
569 @param[in] SupportedPCRBanks Supported PCR banks
570 @param[in] PCRBanks PCR banks
571
572 @retval EFI_SUCCESS Operation completed successfully.
573 **/
574 EFI_STATUS
575 EFIAPI
576 Tpm2PcrAllocateBanks (
577 IN TPM2B_AUTH *PlatformAuth OPTIONAL,
578 IN UINT32 SupportedPCRBanks,
579 IN UINT32 PCRBanks
580 )
581 {
582 EFI_STATUS Status;
583 TPMS_AUTH_COMMAND *AuthSession;
584 TPMS_AUTH_COMMAND LocalAuthSession;
585 TPML_PCR_SELECTION PcrAllocation;
586 TPMI_YES_NO AllocationSuccess;
587 UINT32 MaxPCR;
588 UINT32 SizeNeeded;
589 UINT32 SizeAvailable;
590
591 if (PlatformAuth == NULL) {
592 AuthSession = NULL;
593 } else {
594 AuthSession = &LocalAuthSession;
595 ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
596 LocalAuthSession.sessionHandle = TPM_RS_PW;
597 LocalAuthSession.hmac.size = PlatformAuth->size;
598 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
599 }
600
601 //
602 // Fill input
603 //
604 ZeroMem (&PcrAllocation, sizeof (PcrAllocation));
605 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
606 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;
607 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
608 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
609 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
610 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
611 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
612 } else {
613 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
614 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
615 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
616 }
617
618 PcrAllocation.count++;
619 }
620
621 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
622 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;
623 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
624 if ((HASH_ALG_SHA256 & 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
634 PcrAllocation.count++;
635 }
636
637 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
638 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;
639 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
640 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
641 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
642 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
643 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
644 } else {
645 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
646 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
647 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
648 }
649
650 PcrAllocation.count++;
651 }
652
653 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
654 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;
655 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
656 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
657 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
658 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
659 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
660 } else {
661 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
662 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
663 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
664 }
665
666 PcrAllocation.count++;
667 }
668
669 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
670 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;
671 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
672 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {
673 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
674 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
675 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
676 } else {
677 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
678 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
679 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
680 }
681
682 PcrAllocation.count++;
683 }
684
685 Status = Tpm2PcrAllocate (
686 TPM_RH_PLATFORM,
687 AuthSession,
688 &PcrAllocation,
689 &AllocationSuccess,
690 &MaxPCR,
691 &SizeNeeded,
692 &SizeAvailable
693 );
694 DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
695 if (EFI_ERROR (Status)) {
696 goto Done;
697 }
698
699 DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
700 DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));
701 DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));
702 DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));
703
704 Done:
705 ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
706 return Status;
707 }