/** @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
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
{\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
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
{\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
//\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
\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
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
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