Home | History | Annotate | Download | only in TcgStorageOpalLib
      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