1 /** @file 2 Public API for Opal Core library. 3 4 Copyright (c) 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 #include <Uefi.h> 15 #include <Library/BaseLib.h> 16 #include <Library/DebugLib.h> 17 #include <Library/TcgStorageOpalLib.h> 18 19 20 /** 21 Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method. 22 23 @param[in] Session, The session info for one opal device. 24 @param[in] Psid PSID of device to revert. 25 @param[in] PsidLength Length of PSID in bytes. 26 27 **/ 28 TCG_RESULT 29 EFIAPI 30 OpalUtilPsidRevert( 31 OPAL_SESSION *Session, 32 const VOID *Psid, 33 UINT32 PsidLength 34 ) 35 { 36 UINT8 MethodStatus; 37 TCG_RESULT Ret; 38 39 NULL_CHECK(Session); 40 NULL_CHECK(Psid); 41 42 Ret = OpalStartSession( 43 Session, 44 OPAL_UID_ADMIN_SP, 45 TRUE, 46 PsidLength, 47 Psid, 48 OPAL_ADMIN_SP_PSID_AUTHORITY, 49 &MethodStatus); 50 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 51 Ret = OpalPsidRevert(Session); 52 if (Ret != TcgResultSuccess) { 53 // 54 // If revert was successful, session was already ended by TPer, so only end session on failure 55 // 56 OpalEndSession(Session); 57 } 58 } 59 60 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 61 Ret = TcgResultFailure; 62 } 63 64 return Ret; 65 } 66 67 /** 68 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY, 69 sets the OPAL_UID_ADMIN_SP_C_PIN_SID column with the new password, 70 and activates the locking SP to copy SID PIN to Admin1 Locking SP PIN 71 72 @param[in] Session, The session info for one opal device. 73 @param[in] GeneratedSid Generated SID of disk 74 @param[in] SidLength Length of generatedSid in bytes 75 @param[in] Password New admin password to set 76 @param[in] PassLength Length of password in bytes 77 78 **/ 79 TCG_RESULT 80 EFIAPI 81 OpalUtilSetAdminPasswordAsSid( 82 OPAL_SESSION *Session, 83 const VOID *GeneratedSid, 84 UINT32 SidLength, 85 const VOID *Password, 86 UINT32 PassLength 87 ) 88 { 89 UINT8 MethodStatus; 90 TCG_RESULT Ret; 91 92 NULL_CHECK(Session); 93 NULL_CHECK(GeneratedSid); 94 NULL_CHECK(Password); 95 96 Ret = OpalStartSession( 97 Session, 98 OPAL_UID_ADMIN_SP, 99 TRUE, 100 SidLength, 101 GeneratedSid, 102 OPAL_ADMIN_SP_SID_AUTHORITY, 103 &MethodStatus 104 ); 105 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 106 DEBUG ((DEBUG_INFO, "start session with admin SP as SID authority failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus)); 107 goto done; 108 } 109 110 // 111 // 1. Update SID = new Password 112 // 113 Ret = OpalSetPassword( 114 Session, 115 OPAL_UID_ADMIN_SP_C_PIN_SID, 116 Password, 117 PassLength, 118 &MethodStatus 119 ); 120 121 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 122 OpalEndSession(Session); 123 DEBUG ((DEBUG_INFO, "set Password failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus)); 124 goto done; 125 } 126 127 // 128 // 2. Activate locking SP 129 // 130 Ret = OpalActivateLockingSp(Session, &MethodStatus); 131 OpalEndSession(Session); 132 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 133 DEBUG ((DEBUG_INFO, "activate locking SP failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus)); 134 goto done; 135 } 136 137 done: 138 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 139 Ret = TcgResultFailure; 140 } 141 return Ret; 142 } 143 144 /** 145 146 Opens a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 147 and updates the specified locking range with the provided column values 148 149 @param[in] Session, The session info for one opal device. 150 @param[in] Password New admin password to set 151 @param[in] PassLength Length of password in bytes 152 @param[in] LockingRangeUid Locking range UID to set values 153 @param[in] RangeStart Value to set RangeStart column for Locking Range 154 @param[in] RangeLength Value to set RangeLength column for Locking Range 155 @param[in] ReadLockEnabled Value to set readLockEnabled column for Locking Range 156 @param[in] WriteLockEnabled Value to set writeLockEnabled column for Locking Range 157 @param[in] ReadLocked Value to set ReadLocked column for Locking Range 158 @param[in] WriteLocked Value to set WriteLocked column for Locking Range 159 160 **/ 161 TCG_RESULT 162 EFIAPI 163 OpalUtilSetOpalLockingRange( 164 OPAL_SESSION *Session, 165 const VOID *Password, 166 UINT32 PassLength, 167 TCG_UID LockingRangeUid, 168 UINT64 RangeStart, 169 UINT64 RangeLength, 170 BOOLEAN ReadLockEnabled, 171 BOOLEAN WriteLockEnabled, 172 BOOLEAN ReadLocked, 173 BOOLEAN WriteLocked 174 ) 175 { 176 UINT8 MethodStatus; 177 TCG_RESULT Ret; 178 179 NULL_CHECK(Session); 180 NULL_CHECK(Password); 181 182 // 183 // Start session with Locking SP using current admin Password 184 // 185 Ret = OpalStartSession( 186 Session, 187 OPAL_UID_LOCKING_SP, 188 TRUE, 189 PassLength, 190 Password, 191 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 192 &MethodStatus); 193 if ((Ret != TcgResultSuccess) || (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS)) { 194 DEBUG ((DEBUG_INFO, "start session with locking SP failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus)); 195 goto done; 196 } 197 198 // 199 // Enable locking range 200 // 201 Ret = OpalSetLockingRange( 202 Session, 203 LockingRangeUid, 204 RangeStart, 205 RangeLength, 206 ReadLockEnabled, 207 WriteLockEnabled, 208 ReadLocked, 209 WriteLocked, 210 &MethodStatus); 211 212 OpalEndSession(Session); 213 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 214 DEBUG ((DEBUG_INFO, "set locking range failed: Ret=%d MethodStatus=0x%x\n", Ret, MethodStatus)); 215 } 216 217 done: 218 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 219 Ret = TcgResultFailure; 220 } 221 return Ret; 222 } 223 224 /** 225 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_SID_AUTHORITY, 226 sets OPAL_UID_ADMIN_SP_C_PIN_SID with the new password, 227 and sets OPAL_LOCKING_SP_C_PIN_ADMIN1 with the new password. 228 229 @param[in] Session, The session info for one opal device. 230 @param[in] OldPassword Current admin password 231 @param[in] OldPasswordLength Length of current admin password in bytes 232 @param[in] NewPassword New admin password to set 233 @param[in] NewPasswordLength Length of new password in bytes 234 235 **/ 236 TCG_RESULT 237 EFIAPI 238 OpalUtilSetAdminPassword( 239 OPAL_SESSION *Session, 240 const VOID *OldPassword, 241 UINT32 OldPasswordLength, 242 const VOID *NewPassword, 243 UINT32 NewPasswordLength 244 ) 245 { 246 TCG_RESULT Ret; 247 UINT8 MethodStatus; 248 249 NULL_CHECK(Session); 250 NULL_CHECK(OldPassword); 251 NULL_CHECK(NewPassword); 252 253 // 254 // Unknown ownership 255 // 256 Ret = OpalStartSession( 257 Session, 258 OPAL_UID_ADMIN_SP, 259 TRUE, 260 OldPasswordLength, 261 OldPassword, 262 OPAL_ADMIN_SP_SID_AUTHORITY, 263 &MethodStatus 264 ); 265 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 266 DEBUG ((DEBUG_INFO, "start session with admin SP using old Password failed\n")); 267 goto done; 268 } 269 270 // 271 // Update SID = new pw 272 // 273 Ret = OpalSetPassword(Session, OPAL_UID_ADMIN_SP_C_PIN_SID, NewPassword, NewPasswordLength, &MethodStatus); 274 OpalEndSession(Session); 275 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 276 DEBUG ((DEBUG_INFO, "set new admin SP Password failed\n")); 277 goto done; 278 } 279 280 Ret = OpalStartSession( 281 Session, 282 OPAL_UID_LOCKING_SP, 283 TRUE, 284 OldPasswordLength, 285 OldPassword, 286 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 287 &MethodStatus 288 ); 289 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 290 DEBUG ((DEBUG_INFO, "start session with locking SP using old Password failed\n")); 291 goto done; 292 } 293 294 // 295 // Update admin locking SP to new pw 296 // 297 Ret = OpalSetPassword(Session, OPAL_LOCKING_SP_C_PIN_ADMIN1, NewPassword, NewPasswordLength, &MethodStatus); 298 OpalEndSession(Session); 299 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 300 DEBUG ((DEBUG_INFO, "set new locking SP Password failed\n")); 301 goto done; 302 } 303 304 done: 305 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 306 Ret = TcgResultFailure; 307 } 308 return Ret; 309 } 310 311 /** 312 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY 313 and sets the User1 SP authority to enabled and sets the User1 password. 314 315 @param[in] Session, The session info for one opal device. 316 @param[in] OldPassword Current admin password 317 @param[in] OldPasswordLength Length of current admin password in bytes 318 @param[in] NewPassword New admin password to set 319 @param[in] NewPasswordLength Length of new password in bytes 320 321 **/ 322 TCG_RESULT 323 EFIAPI 324 OpalUtilSetUserPassword( 325 OPAL_SESSION *Session, 326 const VOID *OldPassword, 327 UINT32 OldPasswordLength, 328 const VOID *NewPassword, 329 UINT32 NewPasswordLength 330 ) 331 { 332 UINT8 MethodStatus; 333 TCG_RESULT Ret; 334 335 NULL_CHECK(Session); 336 NULL_CHECK(OldPassword); 337 NULL_CHECK(NewPassword); 338 339 // 340 // See if updating user1 authority 341 // 342 Ret = OpalStartSession( 343 Session, 344 OPAL_UID_LOCKING_SP, 345 TRUE, 346 OldPasswordLength, 347 OldPassword, 348 OPAL_LOCKING_SP_USER1_AUTHORITY, 349 &MethodStatus 350 ); 351 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 352 Ret = OpalSetPassword( 353 Session, 354 OPAL_LOCKING_SP_C_PIN_USER1, 355 NewPassword, 356 NewPasswordLength, 357 &MethodStatus 358 ); 359 OpalEndSession(Session); 360 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 361 return Ret; 362 } 363 } 364 365 // 366 // Setting Password for first time or setting Password as admin 367 // 368 369 // 370 // Start session with Locking SP using current admin Password 371 // 372 Ret = OpalStartSession( 373 Session, 374 OPAL_UID_LOCKING_SP, 375 TRUE, 376 OldPasswordLength, 377 OldPassword, 378 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 379 &MethodStatus 380 ); 381 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 382 DEBUG ((DEBUG_INFO, "StartSession with locking SP as admin1 authority failed\n")); 383 goto done; 384 } 385 386 // 387 // Enable User1 and set its PIN 388 // 389 Ret = OpalSetLockingSpAuthorityEnabledAndPin( 390 Session, 391 OPAL_LOCKING_SP_C_PIN_USER1, 392 OPAL_LOCKING_SP_USER1_AUTHORITY, 393 NewPassword, 394 NewPasswordLength, 395 &MethodStatus 396 ); 397 OpalEndSession(Session); 398 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 399 DEBUG ((DEBUG_INFO, "OpalSetLockingSpAuthorityEnabledAndPin failed\n")); 400 goto done; 401 } 402 403 done: 404 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 405 Ret = TcgResultFailure; 406 } 407 return Ret; 408 } 409 410 /** 411 Verify whether user input the correct password. 412 413 @param[in] Session, The session info for one opal device. 414 @param[in] Password Admin password 415 @param[in] PasswordLength Length of password in bytes 416 @param[in/out] HostSigningAuthority Use the Host signing authority type. 417 418 **/ 419 TCG_RESULT 420 EFIAPI 421 OpalUtilVerifyPassword ( 422 OPAL_SESSION *Session, 423 const VOID *Password, 424 UINT32 PasswordLength, 425 TCG_UID HostSigningAuthority 426 ) 427 { 428 TCG_RESULT Ret; 429 UINT8 MethodStatus; 430 431 NULL_CHECK(Session); 432 NULL_CHECK(Password); 433 434 Ret = OpalStartSession( 435 Session, 436 OPAL_UID_LOCKING_SP, 437 TRUE, 438 PasswordLength, 439 Password, 440 HostSigningAuthority, 441 &MethodStatus); 442 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 443 OpalEndSession(Session); 444 return TcgResultSuccess; 445 } 446 447 return TcgResultFailure; 448 } 449 450 /** 451 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_USER1_AUTHORITY or OPAL_LOCKING_SP_ADMIN1_AUTHORITY 452 and generates a new global locking range key to erase the Data. 453 454 @param[in] Session, The session info for one opal device. 455 @param[in] Password Admin or user password 456 @param[in] PasswordLength Length of password in bytes 457 @param[in/out] PasswordFailed indicates if password failed (start session didn't work) 458 459 **/ 460 TCG_RESULT 461 EFIAPI 462 OpalUtilSecureErase( 463 OPAL_SESSION *Session, 464 const VOID *Password, 465 UINT32 PasswordLength, 466 BOOLEAN *PasswordFailed 467 ) 468 { 469 UINT8 MethodStatus; 470 TCG_RESULT Ret; 471 472 NULL_CHECK(Session); 473 NULL_CHECK(Password); 474 NULL_CHECK(PasswordFailed); 475 476 // 477 // Try to generate a new key with admin1 478 // 479 Ret = OpalStartSession( 480 Session, 481 OPAL_UID_LOCKING_SP, 482 TRUE, 483 PasswordLength, 484 Password, 485 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 486 &MethodStatus 487 ); 488 489 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 490 Ret = OpalGlobalLockingRangeGenKey(Session, &MethodStatus); 491 *PasswordFailed = FALSE; 492 OpalEndSession(Session); 493 } else { 494 // 495 // Try to generate a new key with user1 496 // 497 Ret = OpalStartSession( 498 Session, 499 OPAL_UID_LOCKING_SP, 500 TRUE, 501 PasswordLength, 502 Password, 503 OPAL_LOCKING_SP_USER1_AUTHORITY, 504 &MethodStatus 505 ); 506 507 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 508 Ret = OpalGlobalLockingRangeGenKey(Session, &MethodStatus); 509 *PasswordFailed = FALSE; 510 OpalEndSession(Session); 511 } else { 512 *PasswordFailed = TRUE; 513 } 514 } 515 516 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 517 Ret = TcgResultFailure; 518 } 519 return Ret; 520 } 521 522 /** 523 Starts a session with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY and disables the User1 authority. 524 525 @param[in] Session, The session info for one opal device. 526 @param[in] Password Admin password 527 @param[in] PasswordLength Length of password in bytes 528 @param[in/out] PasswordFailed indicates if password failed (start session didn't work) 529 530 **/ 531 TCG_RESULT 532 EFIAPI 533 OpalUtilDisableUser( 534 OPAL_SESSION *Session, 535 const VOID *Password, 536 UINT32 PasswordLength, 537 BOOLEAN *PasswordFailed 538 ) 539 { 540 UINT8 MethodStatus; 541 TCG_RESULT Ret; 542 543 NULL_CHECK(Session); 544 NULL_CHECK(Password); 545 NULL_CHECK(PasswordFailed); 546 547 // 548 // Start session with Locking SP using current admin Password 549 // 550 Ret = OpalStartSession( 551 Session, 552 OPAL_UID_LOCKING_SP, 553 TRUE, 554 PasswordLength, 555 Password, 556 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 557 &MethodStatus 558 ); 559 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 560 DEBUG ((DEBUG_INFO, "StartSession with Locking SP as Admin1 failed\n")); 561 *PasswordFailed = TRUE; 562 goto done; 563 } 564 565 *PasswordFailed = FALSE; 566 Ret = OpalDisableUser(Session, &MethodStatus); 567 OpalEndSession(Session); 568 569 done: 570 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 571 Ret = TcgResultFailure; 572 } 573 return Ret; 574 } 575 576 /** 577 Opens a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts the device using the RevertSP method. 578 579 @param[in] Session, The session info for one opal device. 580 @param[in] KeepUserData TRUE to keep existing Data on the disk, or FALSE to erase it 581 @param[in] Password Admin password 582 @param[in] PasswordLength Length of password in bytes 583 @param[in/out] PasswordFailed indicates if password failed (start session didn't work) 584 @param[in] Msid Msid info. 585 @param[in] MsidLength Msid data length. 586 587 **/ 588 TCG_RESULT 589 EFIAPI 590 OpalUtilRevert( 591 OPAL_SESSION *Session, 592 BOOLEAN KeepUserData, 593 const VOID *Password, 594 UINT32 PasswordLength, 595 BOOLEAN *PasswordFailed, 596 UINT8 *Msid, 597 UINT32 MsidLength 598 ) 599 { 600 UINT8 MethodStatus; 601 TCG_RESULT Ret; 602 603 NULL_CHECK(Session); 604 NULL_CHECK(Msid); 605 NULL_CHECK(Password); 606 NULL_CHECK(PasswordFailed); 607 608 Ret = OpalStartSession( 609 Session, 610 OPAL_UID_LOCKING_SP, 611 TRUE, 612 PasswordLength, 613 Password, 614 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 615 &MethodStatus 616 ); 617 618 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 619 DEBUG ((DEBUG_INFO, "error starting session: Ret=%d, MethodStatus=%u\n", Ret, MethodStatus)); 620 *PasswordFailed = TRUE; 621 goto done; 622 } 623 624 *PasswordFailed = FALSE; 625 // 626 // Try to revert with admin1 627 // 628 Ret = OpalAdminRevert(Session, KeepUserData, &MethodStatus); 629 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 630 // 631 // Device ends the session on successful revert, so only call OpalEndSession when fail. 632 // 633 DEBUG ((DEBUG_INFO, "OpalAdminRevert as admin failed\n")); 634 OpalEndSession(Session); 635 } 636 637 Ret = OpalUtilSetSIDtoMSID (Session, Password, PasswordLength, Msid, MsidLength); 638 639 done: 640 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 641 Ret = TcgResultFailure; 642 } 643 return Ret; 644 } 645 646 /** 647 After revert success, set SID to MSID. 648 649 @param Session, The session info for one opal device. 650 @param Password, Input password info. 651 @param PasswordLength, Input password length. 652 @param Msid Msid info. 653 @param MsidLength Msid data length. 654 655 **/ 656 TCG_RESULT 657 EFIAPI 658 OpalUtilSetSIDtoMSID ( 659 OPAL_SESSION *Session, 660 const VOID *Password, 661 UINT32 PasswordLength, 662 UINT8 *Msid, 663 UINT32 MsidLength 664 ) 665 { 666 TCG_RESULT Ret; 667 UINT8 MethodStatus; 668 669 NULL_CHECK(Session); 670 NULL_CHECK(Msid); 671 NULL_CHECK(Password); 672 673 // 674 // Start session with admin sp to update SID to MSID 675 // 676 Ret = OpalStartSession( 677 Session, 678 OPAL_UID_ADMIN_SP, 679 TRUE, 680 PasswordLength, 681 Password, 682 OPAL_ADMIN_SP_SID_AUTHORITY, 683 &MethodStatus 684 ); 685 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 686 goto done; 687 } 688 689 // 690 // Update SID pin 691 // 692 Ret = OpalSetPassword(Session, OPAL_UID_ADMIN_SP_C_PIN_SID, Msid, MsidLength, &MethodStatus); 693 OpalEndSession(Session); 694 695 done: 696 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 697 Ret = TcgResultFailure; 698 } 699 700 return Ret; 701 } 702 703 /** 704 Update global locking range. 705 706 @param Session, The session info for one opal device. 707 @param Password, Input password info. 708 @param PasswordLength, Input password length. 709 @param ReadLocked, Read lock info. 710 @param WriteLocked write lock info. 711 712 **/ 713 TCG_RESULT 714 EFIAPI 715 OpalUtilUpdateGlobalLockingRange( 716 OPAL_SESSION *Session, 717 const VOID *Password, 718 UINT32 PasswordLength, 719 BOOLEAN ReadLocked, 720 BOOLEAN WriteLocked 721 ) 722 { 723 UINT8 MethodStatus; 724 TCG_RESULT Ret; 725 726 NULL_CHECK(Session); 727 NULL_CHECK(Password); 728 729 // 730 // Try to start session with Locking SP as admin1 authority 731 // 732 Ret = OpalStartSession( 733 Session, 734 OPAL_UID_LOCKING_SP, 735 TRUE, 736 PasswordLength, 737 Password, 738 OPAL_LOCKING_SP_ADMIN1_AUTHORITY, 739 &MethodStatus 740 ); 741 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 742 Ret = OpalUpdateGlobalLockingRange( 743 Session, 744 ReadLocked, 745 WriteLocked, 746 &MethodStatus 747 ); 748 OpalEndSession(Session); 749 if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) { 750 goto done; 751 } 752 } 753 754 if (MethodStatus == TCG_METHOD_STATUS_CODE_AUTHORITY_LOCKED_OUT) { 755 DEBUG ((DEBUG_INFO, "unlock as admin failed with AUTHORITY_LOCKED_OUT\n")); 756 goto done; 757 } 758 759 // 760 // Try user1 authority 761 // 762 Ret = OpalStartSession( 763 Session, 764 OPAL_UID_LOCKING_SP, 765 TRUE, 766 PasswordLength, 767 Password, 768 OPAL_LOCKING_SP_USER1_AUTHORITY, 769 &MethodStatus 770 ); 771 if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 772 DEBUG ((DEBUG_INFO, "StartSession with Locking SP as User1 failed\n")); 773 goto done; 774 } 775 776 Ret = OpalUpdateGlobalLockingRange(Session, ReadLocked, WriteLocked, &MethodStatus); 777 OpalEndSession(Session); 778 779 done: 780 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 781 Ret = TcgResultFailure; 782 } 783 return Ret; 784 } 785 786 /** 787 Update global locking range. 788 789 @param Session, The session info for one opal device. 790 @param Msid, The data buffer to save Msid info. 791 @param MsidBufferLength, The data buffer length for Msid. 792 @param MsidLength, The actual data length for Msid. 793 794 **/ 795 TCG_RESULT 796 EFIAPI 797 OpalUtilGetMsid( 798 OPAL_SESSION *Session, 799 UINT8 *Msid, 800 UINT32 MsidBufferLength, 801 UINT32 *MsidLength 802 ) 803 { 804 UINT8 MethodStatus; 805 TCG_RESULT Ret; 806 807 NULL_CHECK(Session); 808 NULL_CHECK(Msid); 809 NULL_CHECK(MsidLength); 810 811 Ret = OpalStartSession( 812 Session, 813 OPAL_UID_ADMIN_SP, 814 TRUE, 815 0, 816 NULL, 817 TCG_UID_NULL, 818 &MethodStatus 819 ); 820 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) { 821 Ret = OpalGetMsid (Session, MsidBufferLength, Msid, MsidLength); 822 OpalEndSession (Session); 823 } 824 825 if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) { 826 Ret = TcgResultFailure; 827 } 828 829 return Ret; 830 } 831 832 /** 833 834 The function determines who owns the device by attempting to start a session with different credentials. 835 If the SID PIN matches the MSID PIN, the no one owns the device. 836 If the SID PIN matches the ourSidPin, then "Us" owns the device. Otherwise it is unknown. 837 838 839 @param[in] Session The session info for one opal device. 840 @param Msid, The Msid info. 841 @param MsidLength, The data length for Msid. 842 843 **/ 844 OPAL_OWNER_SHIP 845 EFIAPI 846 OpalUtilDetermineOwnership( 847 OPAL_SESSION *Session, 848 UINT8 *Msid, 849 UINT32 MsidLength 850 ) 851 { 852 UINT8 MethodStatus; 853 TCG_RESULT Ret; 854 OPAL_OWNER_SHIP Owner; 855 856 if ((Session == NULL) || (Msid == NULL)) { 857 return OpalOwnershipUnknown; 858 } 859 860 Owner = OpalOwnershipUnknown; 861 // 862 // Start Session as SID_UID with ADMIN_SP using MSID PIN 863 // 864 Ret = OpalStartSession( 865 Session, 866 OPAL_UID_ADMIN_SP, 867 TRUE, 868 MsidLength, 869 Msid, 870 OPAL_ADMIN_SP_SID_AUTHORITY, 871 &MethodStatus); 872 if ((Ret == TcgResultSuccess) && (MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS)) { 873 // 874 // now we know that SID PIN == MSID PIN 875 // 876 Owner = OpalOwnershipNobody; 877 878 OpalEndSession(Session); 879 } 880 881 return Owner; 882 } 883 884 /** 885 886 The function returns if admin password exists. 887 888 @param[in] OwnerShip The owner ship of the opal device. 889 @param[in] LockingFeature The locking info of the opal device. 890 891 @retval TRUE Admin password existed. 892 @retval FALSE Admin password not existed. 893 894 **/ 895 BOOLEAN 896 EFIAPI 897 OpalUtilAdminPasswordExists( 898 IN UINT16 OwnerShip, 899 IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature 900 ) 901 { 902 NULL_CHECK(LockingFeature); 903 904 // if it is Unknown who owns the device 905 // then someone has set password previously through our UI 906 // because the SID would no longer match the generated SID (ownership us) 907 // or someone has set password using 3rd party software 908 909 // 910 // Locking sp enabled is checked b/c it must be enabled to change the PIN of the Admin1. 911 // 912 return (OwnerShip == OpalOwnershipUnknown && LockingFeature->LockingEnabled); 913 } 914 915