]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c
SecurityPkg/TcgStorageOpalLib: Return AUTHORITY_LOCKED_OUT error.
[mirror_edk2.git] / SecurityPkg / Library / TcgStorageOpalLib / TcgStorageOpalUtil.c
index 2d3ecb474cfac4f7e5cfe73915c88d2b64f3f614..3c4a8e9001219d58ae176860330cfd1e7ce15a1f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Public API for Opal Core library.\r
 \r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -11,11 +11,13 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
-#include <uefi.h>\r
+#include <Uefi.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/TcgStorageOpalLib.h>\r
+#include "TcgStorageOpalLibInternal.h"\r
 \r
+#define OPAL_MSID_LENGHT        128\r
 \r
 /**\r
   Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY, then reverts device using Admin SP Revert method.\r
@@ -35,10 +37,14 @@ OpalUtilPsidRevert(
 {\r
   UINT8        MethodStatus;\r
   TCG_RESULT   Ret;\r
+  UINT32       RemovalTimeOut;\r
 \r
   NULL_CHECK(Session);\r
   NULL_CHECK(Psid);\r
 \r
+  RemovalTimeOut = GetRevertTimeOut (Session);\r
+  DEBUG ((DEBUG_INFO, "OpalUtilPsidRevert: Timeout value = %d\n", RemovalTimeOut));\r
+\r
   Ret = OpalStartSession(\r
                       Session,\r
                       OPAL_UID_ADMIN_SP,\r
@@ -48,7 +54,7 @@ OpalUtilPsidRevert(
                       OPAL_ADMIN_SP_PSID_AUTHORITY,\r
                       &MethodStatus);\r
   if (Ret == TcgResultSuccess && MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {\r
-    Ret = OpalPsidRevert(Session);\r
+    Ret = OpalPyrite2PsidRevert(Session, RemovalTimeOut);\r
     if (Ret != TcgResultSuccess) {\r
       //\r
       // If revert was successful, session was already ended by TPer, so only end session on failure\r
@@ -599,12 +605,16 @@ OpalUtilRevert(
 {\r
   UINT8        MethodStatus;\r
   TCG_RESULT   Ret;\r
+  UINT32       RemovalTimeOut;\r
 \r
   NULL_CHECK(Session);\r
   NULL_CHECK(Msid);\r
   NULL_CHECK(Password);\r
   NULL_CHECK(PasswordFailed);\r
 \r
+  RemovalTimeOut = GetRevertTimeOut (Session);\r
+  DEBUG ((DEBUG_INFO, "OpalUtilRevert: Timeout value = %d\n", RemovalTimeOut));\r
+\r
   Ret = OpalStartSession(\r
                    Session,\r
                    OPAL_UID_LOCKING_SP,\r
@@ -625,8 +635,8 @@ OpalUtilRevert(
   //\r
   // Try to revert with admin1\r
   //\r
-  Ret = OpalAdminRevert(Session, KeepUserData, &MethodStatus);\r
-  if (Ret != TcgResultSuccess || MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+  Ret = OpalPyrite2AdminRevert(Session, KeepUserData, &MethodStatus, RemovalTimeOut);\r
+  if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
     //\r
     // Device ends the session on successful revert, so only call OpalEndSession when fail.\r
     //\r
@@ -778,7 +788,15 @@ OpalUtilUpdateGlobalLockingRange(
 \r
 done:\r
   if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
-    Ret = TcgResultFailure;\r
+    if (MethodStatus == TCG_METHOD_STATUS_CODE_AUTHORITY_LOCKED_OUT) {\r
+      //\r
+      // Caller need to know this special error, but return status not has type for it.\r
+      // so here use TcgResultFailureInvalidType as an replacement.\r
+      //\r
+      Ret = TcgResultFailureInvalidType;\r
+    } else {\r
+      Ret = TcgResultFailure;\r
+    }\r
   }\r
   return Ret;\r
 }\r
@@ -853,8 +871,9 @@ OpalUtilDetermineOwnership(
   TCG_RESULT       Ret;\r
   OPAL_OWNER_SHIP  Owner;\r
 \r
-  NULL_CHECK(Session);\r
-  NULL_CHECK(Msid);\r
+  if ((Session == NULL) || (Msid == NULL)) {\r
+    return OpalOwnershipUnknown;\r
+  }\r
 \r
   Owner = OpalOwnershipUnknown;\r
   //\r
@@ -911,3 +930,201 @@ OpalUtilAdminPasswordExists(
   return (OwnerShip == OpalOwnershipUnknown && LockingFeature->LockingEnabled);\r
 }\r
 \r
+/**\r
+  Get Active Data Removal Mechanism Value.\r
+\r
+  @param[in]      Session                        The session info for one opal device.\r
+  @param[in]      GeneratedSid                   Generated SID of disk\r
+  @param[in]      SidLength                      Length of generatedSid in bytes\r
+  @param[out]     ActiveDataRemovalMechanism     Return the active data removal mechanism.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+OpalUtilGetActiveDataRemovalMechanism (\r
+  OPAL_SESSION      *Session,\r
+  const VOID        *GeneratedSid,\r
+  UINT32            SidLength,\r
+  UINT8             *ActiveDataRemovalMechanism\r
+  )\r
+{\r
+  TCG_RESULT   Ret;\r
+  UINT8        MethodStatus;\r
+\r
+  NULL_CHECK(Session);\r
+  NULL_CHECK(GeneratedSid);\r
+  NULL_CHECK(ActiveDataRemovalMechanism);\r
+\r
+  Ret = OpalStartSession(\r
+                    Session,\r
+                    OPAL_UID_ADMIN_SP,\r
+                    TRUE,\r
+                    SidLength,\r
+                    GeneratedSid,\r
+                    OPAL_ADMIN_SP_ANYBODY_AUTHORITY,\r
+                    &MethodStatus\r
+                    );\r
+  if (Ret != TcgResultSuccess || MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+    DEBUG ((DEBUG_INFO, "Start session with admin SP as SID authority failed: Ret=%d MethodStatus=%u\n", Ret, MethodStatus));\r
+    if (MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+      Ret = TcgResultFailure;\r
+    }\r
+    return Ret;\r
+  }\r
+\r
+  Ret = OpalPyrite2GetActiveDataRemovalMechanism (\r
+                    Session,\r
+                    ActiveDataRemovalMechanism\r
+                    );\r
+\r
+  if (Ret != TcgResultSuccess) {\r
+    DEBUG ((DEBUG_INFO, "Pyrite2 Get Active Data Removal Mechanism failed: Ret=%d\n", Ret));\r
+  }\r
+\r
+  OpalEndSession(Session);\r
+\r
+  return Ret;\r
+}\r
+\r
+/**\r
+  Calculate the estimated time.\r
+\r
+  @param[in]      IsMinute               Whether the input time value is minute type or second type.\r
+  @param[in]      Time                   The input time value.\r
+\r
+**/\r
+UINT32\r
+CalculateDataRemovalTime (\r
+  IN BOOLEAN               IsMinute,\r
+  IN UINT16                Time\r
+  )\r
+{\r
+  if (IsMinute) {\r
+    return Time * 2 * 60;\r
+  } else {\r
+    return Time * 2;\r
+  }\r
+}\r
+\r
+/**\r
+  Return the estimated time for specific type.\r
+\r
+  @param[in]      Index               The input data removal type.\r
+  @param[in]      Descriptor          DATA_REMOVAL_FEATURE_DESCRIPTOR\r
+\r
+**/\r
+UINT32\r
+GetDataRemovalTime (\r
+  IN  UINT8                            Index,\r
+  IN  DATA_REMOVAL_FEATURE_DESCRIPTOR  *Descriptor\r
+  )\r
+{\r
+  switch (Index) {\r
+  case OverwriteDataErase:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit0, SwapBytes16 (Descriptor->TimeBit0));\r
+\r
+  case BlockErase:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit1, SwapBytes16 (Descriptor->TimeBit1));\r
+\r
+  case CryptoErase:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit2, SwapBytes16 (Descriptor->TimeBit2));\r
+\r
+  case Unmap:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit3, SwapBytes16 (Descriptor->TimeBit3));\r
+\r
+  case ResetWritePointers:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit4, SwapBytes16 (Descriptor->TimeBit4));\r
+\r
+  case VendorSpecificErase:\r
+    return CalculateDataRemovalTime (Descriptor->FormatBit5, SwapBytes16 (Descriptor->TimeBit5));\r
+\r
+  default:\r
+    return 0;\r
+  }\r
+}\r
+\r
+/**\r
+  Get the supported Data Removal Mechanism list.\r
+\r
+  @param[in]      Session                        The session info for one opal device.\r
+  @param[out]     RemovalMechanismLists          Return the supported data removal mechanism lists.\r
+\r
+**/\r
+TCG_RESULT\r
+EFIAPI\r
+OpalUtilGetDataRemovalMechanismLists (\r
+  IN  OPAL_SESSION      *Session,\r
+  OUT UINT32            *RemovalMechanismLists\r
+  )\r
+{\r
+  TCG_RESULT                       Ret;\r
+  UINTN                            DataSize;\r
+  DATA_REMOVAL_FEATURE_DESCRIPTOR  Descriptor;\r
+  UINT8                            Index;\r
+  UINT8                            BitValue;\r
+\r
+  NULL_CHECK(Session);\r
+  NULL_CHECK(RemovalMechanismLists);\r
+\r
+  DataSize = sizeof (Descriptor);\r
+  Ret = OpalGetFeatureDescriptor (Session, TCG_FEATURE_DATA_REMOVAL, &DataSize, &Descriptor);\r
+  if (Ret != TcgResultSuccess) {\r
+    return TcgResultFailure;\r
+  }\r
+\r
+  ASSERT (Descriptor.RemovalMechanism != 0);\r
+\r
+  for (Index = 0; Index < ResearvedMechanism; Index ++) {\r
+    BitValue = (BOOLEAN) BitFieldRead8 (Descriptor.RemovalMechanism, Index, Index);\r
+\r
+    if (BitValue == 0) {\r
+      RemovalMechanismLists[Index] = 0;\r
+    } else {\r
+      RemovalMechanismLists[Index] = GetDataRemovalTime (Index, &Descriptor);\r
+    }\r
+  }\r
+\r
+  return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+  Get revert timeout value.\r
+\r
+  @param[in]      Session                       The session info for one opal device.\r
+\r
+**/\r
+UINT32\r
+GetRevertTimeOut (\r
+  IN OPAL_SESSION                *Session\r
+  )\r
+{\r
+  TCG_RESULT                   TcgResult;\r
+  OPAL_DISK_SUPPORT_ATTRIBUTE  SupportedAttributes;\r
+  UINT16                       BaseComId;\r
+  UINT32                       MsidLength;\r
+  UINT8                        Msid[OPAL_MSID_LENGHT];\r
+  UINT32                       RemovalMechanishLists[ResearvedMechanism];\r
+  UINT8                        ActiveDataRemovalMechanism;\r
+\r
+  TcgResult = OpalGetSupportedAttributesInfo (Session, &SupportedAttributes, &BaseComId);\r
+  if (TcgResult != TcgResultSuccess || SupportedAttributes.DataRemoval == 0) {\r
+    return 0;\r
+  }\r
+\r
+  TcgResult = OpalUtilGetMsid (Session, Msid, OPAL_MSID_LENGHT, &MsidLength);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return 0;\r
+  }\r
+\r
+  TcgResult = OpalUtilGetDataRemovalMechanismLists (Session, RemovalMechanishLists);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return 0;\r
+  }\r
+\r
+  TcgResult = OpalUtilGetActiveDataRemovalMechanism (Session, Msid, MsidLength, &ActiveDataRemovalMechanism);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return 0;\r
+  }\r
+\r
+  return RemovalMechanishLists[ActiveDataRemovalMechanism];\r
+}\r