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