]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
741fe031a98ce8be5b0a6adae04f260b83a045dc
[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 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
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
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 if (Digests->count > HASH_COUNT) {
283 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));
284 return EFI_DEVICE_ERROR;
285 }
286
287 Buffer += sizeof(UINT32);
288 for (Index = 0; Index < Digests->count; Index++) {
289 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
290 Buffer += sizeof(UINT16);
291 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
292 if (DigestSize == 0) {
293 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
294 return EFI_DEVICE_ERROR;
295 }
296 CopyMem(
297 &Digests->digests[Index].digest,
298 Buffer,
299 DigestSize
300 );
301 Buffer += DigestSize;
302 }
303
304 return EFI_SUCCESS;
305 }
306
307 /**
308 This command returns the values of all PCR specified in pcrSelect.
309
310 @param[in] PcrSelectionIn The selection of PCR to read.
311 @param[out] PcrUpdateCounter The current value of the PCR update counter.
312 @param[out] PcrSelectionOut The PCR in the returned list.
313 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.
314
315 @retval EFI_SUCCESS Operation completed successfully.
316 @retval EFI_DEVICE_ERROR The command was unsuccessful.
317 **/
318 EFI_STATUS
319 EFIAPI
320 Tpm2PcrRead (
321 IN TPML_PCR_SELECTION *PcrSelectionIn,
322 OUT UINT32 *PcrUpdateCounter,
323 OUT TPML_PCR_SELECTION *PcrSelectionOut,
324 OUT TPML_DIGEST *PcrValues
325 )
326 {
327 EFI_STATUS Status;
328 TPM2_PCR_READ_COMMAND SendBuffer;
329 TPM2_PCR_READ_RESPONSE RecvBuffer;
330 UINT32 SendBufferSize;
331 UINT32 RecvBufferSize;
332 UINTN Index;
333 TPML_DIGEST *PcrValuesOut;
334 TPM2B_DIGEST *Digests;
335
336 //
337 // Construct command
338 //
339 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
340 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);
341
342 SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);
343 for (Index = 0; Index < PcrSelectionIn->count; Index++) {
344 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);
345 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;
346 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);
347 }
348
349 SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;
350 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
351
352 //
353 // send Tpm command
354 //
355 RecvBufferSize = sizeof (RecvBuffer);
356 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
357 if (EFI_ERROR (Status)) {
358 return Status;
359 }
360
361 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
362 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
363 return EFI_DEVICE_ERROR;
364 }
365 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
366 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
367 return EFI_NOT_FOUND;
368 }
369
370 //
371 // Return the response
372 //
373
374 //
375 // PcrUpdateCounter
376 //
377 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {
378 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
379 return EFI_DEVICE_ERROR;
380 }
381 *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
382
383 //
384 // PcrSelectionOut
385 //
386 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {
387 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
388 return EFI_DEVICE_ERROR;
389 }
390 PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
391 if (PcrSelectionOut->count > HASH_COUNT) {
392 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));
393 return EFI_DEVICE_ERROR;
394 }
395
396 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
397 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
398 return EFI_DEVICE_ERROR;
399 }
400 for (Index = 0; Index < PcrSelectionOut->count; Index++) {
401 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
402 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
403 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {
404 return EFI_DEVICE_ERROR;
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 Digests = PcrValuesOut->digests;
422 for (Index = 0; Index < PcrValues->count; Index++) {
423 PcrValues->digests[Index].size = SwapBytes16(Digests->size);
424 if (PcrValues->digests[Index].size > sizeof(TPMU_HA)) {
425 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));
426 return EFI_DEVICE_ERROR;
427 }
428 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
429 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);
430 }
431
432 return EFI_SUCCESS;
433 }
434
435 /**
436 This command is used to set the desired PCR allocation of PCR and algorithms.
437
438 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
439 @param[in] AuthSession Auth Session context
440 @param[in] PcrAllocation The requested allocation
441 @param[out] AllocationSuccess YES if the allocation succeeded
442 @param[out] MaxPCR maximum number of PCR that may be in a bank
443 @param[out] SizeNeeded number of octets required to satisfy the request
444 @param[out] SizeAvailable Number of octets available. Computed before the allocation
445
446 @retval EFI_SUCCESS Operation completed successfully.
447 @retval EFI_DEVICE_ERROR The command was unsuccessful.
448 **/
449 EFI_STATUS
450 EFIAPI
451 Tpm2PcrAllocate (
452 IN TPMI_RH_PLATFORM AuthHandle,
453 IN TPMS_AUTH_COMMAND *AuthSession,
454 IN TPML_PCR_SELECTION *PcrAllocation,
455 OUT TPMI_YES_NO *AllocationSuccess,
456 OUT UINT32 *MaxPCR,
457 OUT UINT32 *SizeNeeded,
458 OUT UINT32 *SizeAvailable
459 )
460 {
461 EFI_STATUS Status;
462 TPM2_PCR_ALLOCATE_COMMAND Cmd;
463 TPM2_PCR_ALLOCATE_RESPONSE Res;
464 UINT32 CmdSize;
465 UINT32 RespSize;
466 UINT8 *Buffer;
467 UINT32 SessionInfoSize;
468 UINT8 *ResultBuf;
469 UINT32 ResultBufSize;
470 UINTN Index;
471
472 //
473 // Construct command
474 //
475 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
476 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
477 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);
478 Cmd.AuthHandle = SwapBytes32(AuthHandle);
479
480 //
481 // Add in Auth session
482 //
483 Buffer = (UINT8 *)&Cmd.AuthSession;
484
485 // sessionInfoSize
486 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
487 Buffer += SessionInfoSize;
488 Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);
489
490 // Count
491 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));
492 Buffer += sizeof(UINT32);
493 for (Index = 0; Index < PcrAllocation->count; Index++) {
494 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));
495 Buffer += sizeof(UINT16);
496 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
497 Buffer++;
498 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
499 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
500 }
501
502 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
503 Cmd.Header.paramSize = SwapBytes32(CmdSize);
504
505 ResultBuf = (UINT8 *) &Res;
506 ResultBufSize = sizeof(Res);
507
508 //
509 // Call the TPM
510 //
511 Status = Tpm2SubmitCommand (
512 CmdSize,
513 (UINT8 *)&Cmd,
514 &ResultBufSize,
515 ResultBuf
516 );
517 if (EFI_ERROR(Status)) {
518 goto Done;
519 }
520
521 if (ResultBufSize > sizeof(Res)) {
522 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
523 Status = EFI_BUFFER_TOO_SMALL;
524 goto Done;
525 }
526
527 //
528 // Validate response headers
529 //
530 RespSize = SwapBytes32(Res.Header.paramSize);
531 if (RespSize > sizeof(Res)) {
532 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
533 Status = EFI_BUFFER_TOO_SMALL;
534 goto Done;
535 }
536
537 //
538 // Fail if command failed
539 //
540 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
541 DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
542 Status = EFI_DEVICE_ERROR;
543 goto Done;
544 }
545
546 //
547 // Return the response
548 //
549 *AllocationSuccess = Res.AllocationSuccess;
550 *MaxPCR = SwapBytes32(Res.MaxPCR);
551 *SizeNeeded = SwapBytes32(Res.SizeNeeded);
552 *SizeAvailable = SwapBytes32(Res.SizeAvailable);
553
554 Done:
555 //
556 // Clear AuthSession Content
557 //
558 ZeroMem (&Cmd, sizeof(Cmd));
559 ZeroMem (&Res, sizeof(Res));
560 return Status;
561 }
562
563 /**
564 Alloc PCR data.
565
566 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
567 @param[in] SupportedPCRBanks Supported PCR banks
568 @param[in] PCRBanks PCR banks
569
570 @retval EFI_SUCCESS Operation completed successfully.
571 **/
572 EFI_STATUS
573 EFIAPI
574 Tpm2PcrAllocateBanks (
575 IN TPM2B_AUTH *PlatformAuth, OPTIONAL
576 IN UINT32 SupportedPCRBanks,
577 IN UINT32 PCRBanks
578 )
579 {
580 EFI_STATUS Status;
581 TPMS_AUTH_COMMAND *AuthSession;
582 TPMS_AUTH_COMMAND LocalAuthSession;
583 TPML_PCR_SELECTION PcrAllocation;
584 TPMI_YES_NO AllocationSuccess;
585 UINT32 MaxPCR;
586 UINT32 SizeNeeded;
587 UINT32 SizeAvailable;
588
589 if (PlatformAuth == NULL) {
590 AuthSession = NULL;
591 } else {
592 AuthSession = &LocalAuthSession;
593 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));
594 LocalAuthSession.sessionHandle = TPM_RS_PW;
595 LocalAuthSession.hmac.size = PlatformAuth->size;
596 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
597 }
598
599 //
600 // Fill input
601 //
602 ZeroMem (&PcrAllocation, sizeof(PcrAllocation));
603 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
604 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;
605 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
606 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
607 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
608 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
609 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
610 } else {
611 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
612 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
613 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
614 }
615 PcrAllocation.count++;
616 }
617 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
618 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;
619 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
620 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {
621 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
622 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
623 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
624 } else {
625 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
626 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
627 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
628 }
629 PcrAllocation.count++;
630 }
631 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
632 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;
633 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
634 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
635 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
636 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
637 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
638 } else {
639 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
640 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
641 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
642 }
643 PcrAllocation.count++;
644 }
645 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
646 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;
647 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
648 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
649 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
650 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
651 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
652 } else {
653 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
654 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
655 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
656 }
657 PcrAllocation.count++;
658 }
659 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
660 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;
661 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
662 if ((HASH_ALG_SM3_256 & 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 PcrAllocation.count++;
672 }
673 Status = Tpm2PcrAllocate (
674 TPM_RH_PLATFORM,
675 AuthSession,
676 &PcrAllocation,
677 &AllocationSuccess,
678 &MaxPCR,
679 &SizeNeeded,
680 &SizeAvailable
681 );
682 DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
683 if (EFI_ERROR (Status)) {
684 goto Done;
685 }
686
687 DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
688 DEBUG ((EFI_D_INFO, "MaxPCR - %08x\n", MaxPCR));
689 DEBUG ((EFI_D_INFO, "SizeNeeded - %08x\n", SizeNeeded));
690 DEBUG ((EFI_D_INFO, "SizeAvailable - %08x\n", SizeAvailable));
691
692 Done:
693 ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));
694 return Status;
695 }