1 /** @file 2 Implement TPM2 Hierarchy related command. 3 4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include <IndustryStandard/UefiTcgPlatform.h> 16 #include <Library/Tpm2CommandLib.h> 17 #include <Library/Tpm2DeviceLib.h> 18 #include <Library/BaseMemoryLib.h> 19 #include <Library/BaseLib.h> 20 #include <Library/DebugLib.h> 21 22 #pragma pack(1) 23 24 typedef struct { 25 TPM2_COMMAND_HEADER Header; 26 TPMI_RH_HIERARCHY_AUTH AuthHandle; 27 UINT32 AuthSessionSize; 28 TPMS_AUTH_COMMAND AuthSession; 29 TPM2B_DIGEST AuthPolicy; 30 TPMI_ALG_HASH HashAlg; 31 } TPM2_SET_PRIMARY_POLICY_COMMAND; 32 33 typedef struct { 34 TPM2_RESPONSE_HEADER Header; 35 UINT32 AuthSessionSize; 36 TPMS_AUTH_RESPONSE AuthSession; 37 } TPM2_SET_PRIMARY_POLICY_RESPONSE; 38 39 typedef struct { 40 TPM2_COMMAND_HEADER Header; 41 TPMI_RH_CLEAR AuthHandle; 42 UINT32 AuthorizationSize; 43 TPMS_AUTH_COMMAND AuthSession; 44 } TPM2_CLEAR_COMMAND; 45 46 typedef struct { 47 TPM2_RESPONSE_HEADER Header; 48 UINT32 ParameterSize; 49 TPMS_AUTH_RESPONSE AuthSession; 50 } TPM2_CLEAR_RESPONSE; 51 52 typedef struct { 53 TPM2_COMMAND_HEADER Header; 54 TPMI_RH_CLEAR AuthHandle; 55 UINT32 AuthorizationSize; 56 TPMS_AUTH_COMMAND AuthSession; 57 TPMI_YES_NO Disable; 58 } TPM2_CLEAR_CONTROL_COMMAND; 59 60 typedef struct { 61 TPM2_RESPONSE_HEADER Header; 62 UINT32 ParameterSize; 63 TPMS_AUTH_RESPONSE AuthSession; 64 } TPM2_CLEAR_CONTROL_RESPONSE; 65 66 typedef struct { 67 TPM2_COMMAND_HEADER Header; 68 TPMI_RH_HIERARCHY_AUTH AuthHandle; 69 UINT32 AuthorizationSize; 70 TPMS_AUTH_COMMAND AuthSession; 71 TPM2B_AUTH NewAuth; 72 } TPM2_HIERARCHY_CHANGE_AUTH_COMMAND; 73 74 typedef struct { 75 TPM2_RESPONSE_HEADER Header; 76 UINT32 ParameterSize; 77 TPMS_AUTH_RESPONSE AuthSession; 78 } TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE; 79 80 typedef struct { 81 TPM2_COMMAND_HEADER Header; 82 TPMI_RH_PLATFORM AuthHandle; 83 UINT32 AuthorizationSize; 84 TPMS_AUTH_COMMAND AuthSession; 85 } TPM2_CHANGE_EPS_COMMAND; 86 87 typedef struct { 88 TPM2_RESPONSE_HEADER Header; 89 UINT32 ParameterSize; 90 TPMS_AUTH_RESPONSE AuthSession; 91 } TPM2_CHANGE_EPS_RESPONSE; 92 93 typedef struct { 94 TPM2_COMMAND_HEADER Header; 95 TPMI_RH_PLATFORM AuthHandle; 96 UINT32 AuthorizationSize; 97 TPMS_AUTH_COMMAND AuthSession; 98 } TPM2_CHANGE_PPS_COMMAND; 99 100 typedef struct { 101 TPM2_RESPONSE_HEADER Header; 102 UINT32 ParameterSize; 103 TPMS_AUTH_RESPONSE AuthSession; 104 } TPM2_CHANGE_PPS_RESPONSE; 105 106 typedef struct { 107 TPM2_COMMAND_HEADER Header; 108 TPMI_RH_HIERARCHY AuthHandle; 109 UINT32 AuthorizationSize; 110 TPMS_AUTH_COMMAND AuthSession; 111 TPMI_RH_HIERARCHY Hierarchy; 112 TPMI_YES_NO State; 113 } TPM2_HIERARCHY_CONTROL_COMMAND; 114 115 typedef struct { 116 TPM2_RESPONSE_HEADER Header; 117 UINT32 ParameterSize; 118 TPMS_AUTH_RESPONSE AuthSession; 119 } TPM2_HIERARCHY_CONTROL_RESPONSE; 120 121 #pragma pack() 122 123 /** 124 This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the 125 storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy). 126 127 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated 128 @param[in] AuthSession Auth Session context 129 @param[in] AuthPolicy An authorization policy hash 130 @param[in] HashAlg The hash algorithm to use for the policy 131 132 @retval EFI_SUCCESS Operation completed successfully. 133 @retval EFI_DEVICE_ERROR Unexpected device behavior. 134 **/ 135 EFI_STATUS 136 EFIAPI 137 Tpm2SetPrimaryPolicy ( 138 IN TPMI_RH_HIERARCHY_AUTH AuthHandle, 139 IN TPMS_AUTH_COMMAND *AuthSession, 140 IN TPM2B_DIGEST *AuthPolicy, 141 IN TPMI_ALG_HASH HashAlg 142 ) 143 { 144 EFI_STATUS Status; 145 TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer; 146 TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer; 147 UINT32 SendBufferSize; 148 UINT32 RecvBufferSize; 149 UINT8 *Buffer; 150 UINT32 SessionInfoSize; 151 152 // 153 // Construct command 154 // 155 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 156 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetPrimaryPolicy); 157 158 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle); 159 160 // 161 // Add in Auth session 162 // 163 Buffer = (UINT8 *)&SendBuffer.AuthSession; 164 165 // sessionInfoSize 166 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 167 Buffer += SessionInfoSize; 168 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize); 169 170 // 171 // Real data 172 // 173 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(AuthPolicy->size)); 174 Buffer += sizeof(UINT16); 175 CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size); 176 Buffer += AuthPolicy->size; 177 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg)); 178 Buffer += sizeof(UINT16); 179 180 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer); 181 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize); 182 183 // 184 // send Tpm command 185 // 186 RecvBufferSize = sizeof (RecvBuffer); 187 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer); 188 if (EFI_ERROR (Status)) { 189 goto Done; 190 } 191 192 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) { 193 DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize)); 194 Status = EFI_DEVICE_ERROR; 195 goto Done; 196 } 197 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) { 198 DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode))); 199 Status = EFI_DEVICE_ERROR; 200 goto Done; 201 } 202 203 Done: 204 // 205 // Clear AuthSession Content 206 // 207 ZeroMem (&SendBuffer, sizeof(SendBuffer)); 208 ZeroMem (&RecvBuffer, sizeof(RecvBuffer)); 209 return Status; 210 } 211 212 /** 213 This command removes all TPM context associated with a specific Owner. 214 215 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP} 216 @param[in] AuthSession Auth Session context 217 218 @retval EFI_SUCCESS Operation completed successfully. 219 @retval EFI_DEVICE_ERROR Unexpected device behavior. 220 **/ 221 EFI_STATUS 222 EFIAPI 223 Tpm2Clear ( 224 IN TPMI_RH_CLEAR AuthHandle, 225 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL 226 ) 227 { 228 EFI_STATUS Status; 229 TPM2_CLEAR_COMMAND Cmd; 230 TPM2_CLEAR_RESPONSE Res; 231 UINT32 ResultBufSize; 232 UINT32 CmdSize; 233 UINT32 RespSize; 234 UINT8 *Buffer; 235 UINT32 SessionInfoSize; 236 237 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 238 Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear); 239 Cmd.AuthHandle = SwapBytes32(AuthHandle); 240 241 // 242 // Add in Auth session 243 // 244 Buffer = (UINT8 *)&Cmd.AuthSession; 245 246 // sessionInfoSize 247 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 248 Buffer += SessionInfoSize; 249 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 250 251 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 252 Cmd.Header.paramSize = SwapBytes32(CmdSize); 253 254 ResultBufSize = sizeof(Res); 255 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); 256 if (EFI_ERROR(Status)) { 257 goto Done; 258 } 259 260 if (ResultBufSize > sizeof(Res)) { 261 DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n")); 262 Status = EFI_BUFFER_TOO_SMALL; 263 goto Done; 264 } 265 266 // 267 // Validate response headers 268 // 269 RespSize = SwapBytes32(Res.Header.paramSize); 270 if (RespSize > sizeof(Res)) { 271 DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize)); 272 Status = EFI_BUFFER_TOO_SMALL; 273 goto Done; 274 } 275 276 // 277 // Fail if command failed 278 // 279 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 280 DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 281 Status = EFI_DEVICE_ERROR; 282 goto Done; 283 } 284 285 // 286 // Unmarshal the response 287 // 288 289 // None 290 Done: 291 // 292 // Clear AuthSession Content 293 // 294 ZeroMem (&Cmd, sizeof(Cmd)); 295 ZeroMem (&Res, sizeof(Res)); 296 return Status; 297 } 298 299 /** 300 Disables and enables the execution of TPM2_Clear(). 301 302 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP} 303 @param[in] AuthSession Auth Session context 304 @param[in] Disable YES if the disableOwnerClear flag is to be SET, 305 NO if the flag is to be CLEAR. 306 307 @retval EFI_SUCCESS Operation completed successfully. 308 @retval EFI_DEVICE_ERROR Unexpected device behavior. 309 **/ 310 EFI_STATUS 311 EFIAPI 312 Tpm2ClearControl ( 313 IN TPMI_RH_CLEAR AuthHandle, 314 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL 315 IN TPMI_YES_NO Disable 316 ) 317 { 318 EFI_STATUS Status; 319 TPM2_CLEAR_CONTROL_COMMAND Cmd; 320 TPM2_CLEAR_CONTROL_RESPONSE Res; 321 UINT32 ResultBufSize; 322 UINT32 CmdSize; 323 UINT32 RespSize; 324 UINT8 *Buffer; 325 UINT32 SessionInfoSize; 326 327 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 328 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl); 329 Cmd.AuthHandle = SwapBytes32(AuthHandle); 330 331 // 332 // Add in Auth session 333 // 334 Buffer = (UINT8 *)&Cmd.AuthSession; 335 336 // sessionInfoSize 337 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 338 Buffer += SessionInfoSize; 339 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 340 341 // disable 342 *(UINT8 *)Buffer = Disable; 343 Buffer++; 344 345 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 346 Cmd.Header.paramSize = SwapBytes32(CmdSize); 347 348 ResultBufSize = sizeof(Res); 349 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res); 350 if (EFI_ERROR(Status)) { 351 goto Done; 352 } 353 354 if (ResultBufSize > sizeof(Res)) { 355 DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n")); 356 Status = EFI_BUFFER_TOO_SMALL; 357 goto Done; 358 } 359 360 // 361 // Validate response headers 362 // 363 RespSize = SwapBytes32(Res.Header.paramSize); 364 if (RespSize > sizeof(Res)) { 365 DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize)); 366 Status = EFI_BUFFER_TOO_SMALL; 367 goto Done; 368 } 369 370 // 371 // Fail if command failed 372 // 373 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 374 DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 375 Status = EFI_DEVICE_ERROR; 376 goto Done; 377 } 378 379 // 380 // Unmarshal the response 381 // 382 383 // None 384 Done: 385 // 386 // Clear AuthSession Content 387 // 388 ZeroMem (&Cmd, sizeof(Cmd)); 389 ZeroMem (&Res, sizeof(Res)); 390 return Status; 391 } 392 393 /** 394 This command allows the authorization secret for a hierarchy or lockout to be changed using the current 395 authorization value as the command authorization. 396 397 @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} 398 @param[in] AuthSession Auth Session context 399 @param[in] NewAuth New authorization secret 400 401 @retval EFI_SUCCESS Operation completed successfully. 402 @retval EFI_DEVICE_ERROR Unexpected device behavior. 403 **/ 404 EFI_STATUS 405 EFIAPI 406 Tpm2HierarchyChangeAuth ( 407 IN TPMI_RH_HIERARCHY_AUTH AuthHandle, 408 IN TPMS_AUTH_COMMAND *AuthSession, 409 IN TPM2B_AUTH *NewAuth 410 ) 411 { 412 EFI_STATUS Status; 413 TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd; 414 TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res; 415 UINT32 CmdSize; 416 UINT32 RespSize; 417 UINT8 *Buffer; 418 UINT32 SessionInfoSize; 419 UINT8 *ResultBuf; 420 UINT32 ResultBufSize; 421 422 // 423 // Construct command 424 // 425 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 426 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 427 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyChangeAuth); 428 Cmd.AuthHandle = SwapBytes32(AuthHandle); 429 430 // 431 // Add in Auth session 432 // 433 Buffer = (UINT8 *)&Cmd.AuthSession; 434 435 // sessionInfoSize 436 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 437 Buffer += SessionInfoSize; 438 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 439 440 // New Authorization size 441 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size)); 442 Buffer += sizeof(UINT16); 443 444 // New Authorizeation 445 CopyMem(Buffer, NewAuth->buffer, NewAuth->size); 446 Buffer += NewAuth->size; 447 448 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 449 Cmd.Header.paramSize = SwapBytes32(CmdSize); 450 451 ResultBuf = (UINT8 *) &Res; 452 ResultBufSize = sizeof(Res); 453 454 // 455 // Call the TPM 456 // 457 Status = Tpm2SubmitCommand ( 458 CmdSize, 459 (UINT8 *)&Cmd, 460 &ResultBufSize, 461 ResultBuf 462 ); 463 if (EFI_ERROR(Status)) { 464 goto Done; 465 } 466 467 if (ResultBufSize > sizeof(Res)) { 468 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n")); 469 Status = EFI_BUFFER_TOO_SMALL; 470 goto Done; 471 } 472 473 // 474 // Validate response headers 475 // 476 RespSize = SwapBytes32(Res.Header.paramSize); 477 if (RespSize > sizeof(Res)) { 478 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize)); 479 Status = EFI_BUFFER_TOO_SMALL; 480 goto Done; 481 } 482 483 // 484 // Fail if command failed 485 // 486 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 487 DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 488 Status = EFI_DEVICE_ERROR; 489 goto Done; 490 } 491 492 Done: 493 // 494 // Clear AuthSession Content 495 // 496 ZeroMem (&Cmd, sizeof(Cmd)); 497 ZeroMem (&Res, sizeof(Res)); 498 return Status; 499 } 500 501 /** 502 This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to 503 their default initialization values. 504 505 @param[in] AuthHandle TPM_RH_PLATFORM+{PP} 506 @param[in] AuthSession Auth Session context 507 508 @retval EFI_SUCCESS Operation completed successfully. 509 @retval EFI_DEVICE_ERROR Unexpected device behavior. 510 **/ 511 EFI_STATUS 512 EFIAPI 513 Tpm2ChangeEPS ( 514 IN TPMI_RH_PLATFORM AuthHandle, 515 IN TPMS_AUTH_COMMAND *AuthSession 516 ) 517 { 518 EFI_STATUS Status; 519 TPM2_CHANGE_EPS_COMMAND Cmd; 520 TPM2_CHANGE_EPS_RESPONSE Res; 521 UINT32 CmdSize; 522 UINT32 RespSize; 523 UINT8 *Buffer; 524 UINT32 SessionInfoSize; 525 UINT8 *ResultBuf; 526 UINT32 ResultBufSize; 527 528 // 529 // Construct command 530 // 531 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 532 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 533 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangeEPS); 534 Cmd.AuthHandle = SwapBytes32(AuthHandle); 535 536 // 537 // Add in Auth session 538 // 539 Buffer = (UINT8 *)&Cmd.AuthSession; 540 541 // sessionInfoSize 542 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 543 Buffer += SessionInfoSize; 544 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 545 546 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 547 Cmd.Header.paramSize = SwapBytes32(CmdSize); 548 549 ResultBuf = (UINT8 *) &Res; 550 ResultBufSize = sizeof(Res); 551 552 // 553 // Call the TPM 554 // 555 Status = Tpm2SubmitCommand ( 556 CmdSize, 557 (UINT8 *)&Cmd, 558 &ResultBufSize, 559 ResultBuf 560 ); 561 if (EFI_ERROR(Status)) { 562 goto Done; 563 } 564 565 if (ResultBufSize > sizeof(Res)) { 566 DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n")); 567 Status = EFI_BUFFER_TOO_SMALL; 568 goto Done; 569 } 570 571 // 572 // Validate response headers 573 // 574 RespSize = SwapBytes32(Res.Header.paramSize); 575 if (RespSize > sizeof(Res)) { 576 DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize)); 577 Status = EFI_BUFFER_TOO_SMALL; 578 goto Done; 579 } 580 581 // 582 // Fail if command failed 583 // 584 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 585 DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 586 Status = EFI_DEVICE_ERROR; 587 goto Done; 588 } 589 590 Done: 591 // 592 // Clear AuthSession Content 593 // 594 ZeroMem (&Cmd, sizeof(Cmd)); 595 ZeroMem (&Res, sizeof(Res)); 596 return Status; 597 } 598 599 /** 600 This replaces the current PPS with a value from the RNG and sets platformPolicy to the default 601 initialization value (the Empty Buffer). 602 603 @param[in] AuthHandle TPM_RH_PLATFORM+{PP} 604 @param[in] AuthSession Auth Session context 605 606 @retval EFI_SUCCESS Operation completed successfully. 607 @retval EFI_DEVICE_ERROR Unexpected device behavior. 608 **/ 609 EFI_STATUS 610 EFIAPI 611 Tpm2ChangePPS ( 612 IN TPMI_RH_PLATFORM AuthHandle, 613 IN TPMS_AUTH_COMMAND *AuthSession 614 ) 615 { 616 EFI_STATUS Status; 617 TPM2_CHANGE_PPS_COMMAND Cmd; 618 TPM2_CHANGE_PPS_RESPONSE Res; 619 UINT32 CmdSize; 620 UINT32 RespSize; 621 UINT8 *Buffer; 622 UINT32 SessionInfoSize; 623 UINT8 *ResultBuf; 624 UINT32 ResultBufSize; 625 626 // 627 // Construct command 628 // 629 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 630 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 631 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangePPS); 632 Cmd.AuthHandle = SwapBytes32(AuthHandle); 633 634 // 635 // Add in Auth session 636 // 637 Buffer = (UINT8 *)&Cmd.AuthSession; 638 639 // sessionInfoSize 640 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 641 Buffer += SessionInfoSize; 642 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 643 644 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 645 Cmd.Header.paramSize = SwapBytes32(CmdSize); 646 647 ResultBuf = (UINT8 *) &Res; 648 ResultBufSize = sizeof(Res); 649 650 // 651 // Call the TPM 652 // 653 Status = Tpm2SubmitCommand ( 654 CmdSize, 655 (UINT8 *)&Cmd, 656 &ResultBufSize, 657 ResultBuf 658 ); 659 if (EFI_ERROR(Status)) { 660 goto Done; 661 } 662 663 if (ResultBufSize > sizeof(Res)) { 664 DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n")); 665 Status = EFI_BUFFER_TOO_SMALL; 666 goto Done; 667 } 668 669 // 670 // Validate response headers 671 // 672 RespSize = SwapBytes32(Res.Header.paramSize); 673 if (RespSize > sizeof(Res)) { 674 DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize)); 675 Status = EFI_BUFFER_TOO_SMALL; 676 goto Done; 677 } 678 679 // 680 // Fail if command failed 681 // 682 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 683 DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 684 Status = EFI_DEVICE_ERROR; 685 goto Done; 686 } 687 688 Done: 689 // 690 // Clear AuthSession Content 691 // 692 ZeroMem (&Cmd, sizeof(Cmd)); 693 ZeroMem (&Res, sizeof(Res)); 694 return Status; 695 } 696 697 /** 698 This command enables and disables use of a hierarchy. 699 700 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} 701 @param[in] AuthSession Auth Session context 702 @param[in] Hierarchy Hierarchy of the enable being modified 703 @param[in] State YES if the enable should be SET, 704 NO if the enable should be CLEAR 705 706 @retval EFI_SUCCESS Operation completed successfully. 707 @retval EFI_DEVICE_ERROR Unexpected device behavior. 708 **/ 709 EFI_STATUS 710 EFIAPI 711 Tpm2HierarchyControl ( 712 IN TPMI_RH_HIERARCHY AuthHandle, 713 IN TPMS_AUTH_COMMAND *AuthSession, 714 IN TPMI_RH_HIERARCHY Hierarchy, 715 IN TPMI_YES_NO State 716 ) 717 { 718 EFI_STATUS Status; 719 TPM2_HIERARCHY_CONTROL_COMMAND Cmd; 720 TPM2_HIERARCHY_CONTROL_RESPONSE Res; 721 UINT32 CmdSize; 722 UINT32 RespSize; 723 UINT8 *Buffer; 724 UINT32 SessionInfoSize; 725 UINT8 *ResultBuf; 726 UINT32 ResultBufSize; 727 728 // 729 // Construct command 730 // 731 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS); 732 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd)); 733 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyControl); 734 Cmd.AuthHandle = SwapBytes32(AuthHandle); 735 736 // 737 // Add in Auth session 738 // 739 Buffer = (UINT8 *)&Cmd.AuthSession; 740 741 // sessionInfoSize 742 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer); 743 Buffer += SessionInfoSize; 744 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize); 745 746 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy)); 747 Buffer += sizeof(UINT32); 748 749 *(UINT8 *)Buffer = State; 750 Buffer++; 751 752 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd); 753 Cmd.Header.paramSize = SwapBytes32(CmdSize); 754 755 ResultBuf = (UINT8 *) &Res; 756 ResultBufSize = sizeof(Res); 757 758 // 759 // Call the TPM 760 // 761 Status = Tpm2SubmitCommand ( 762 CmdSize, 763 (UINT8 *)&Cmd, 764 &ResultBufSize, 765 ResultBuf 766 ); 767 if (EFI_ERROR(Status)) { 768 goto Done; 769 } 770 771 if (ResultBufSize > sizeof(Res)) { 772 DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n")); 773 Status = EFI_BUFFER_TOO_SMALL; 774 goto Done; 775 } 776 777 // 778 // Validate response headers 779 // 780 RespSize = SwapBytes32(Res.Header.paramSize); 781 if (RespSize > sizeof(Res)) { 782 DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize)); 783 Status = EFI_BUFFER_TOO_SMALL; 784 goto Done; 785 } 786 787 // 788 // Fail if command failed 789 // 790 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) { 791 DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode))); 792 Status = EFI_DEVICE_ERROR; 793 goto Done; 794 } 795 796 Done: 797 // 798 // Clear AuthSession Content 799 // 800 ZeroMem (&Cmd, sizeof(Cmd)); 801 ZeroMem (&Res, sizeof(Res)); 802 return Status; 803 } 804