/** @file\r
Public API for Opal Core library.\r
\r
-Copyright (c) 2016, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Library/DebugLib.h>\r
#include <Library/TcgStorageOpalLib.h>\r
\r
+#include "TcgStorageOpalLibInternal.h"\r
+\r
#pragma pack(1)\r
typedef struct {\r
UINT8 HardwareReset : 1;\r
@param[in] SpSpecific Security Protocol Specific\r
@param[in] Buffer Address of Data to transfer\r
@param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
+ @param[in] EstimateTimeCost Estimate the time needed.\r
\r
**/\r
TCG_RESULT\r
UINT8 SecurityProtocol,\r
UINT16 SpSpecific,\r
VOID *Buffer,\r
- UINTN BufferSize\r
+ UINTN BufferSize,\r
+ UINT32 EstimateTimeCost\r
)\r
{\r
-\r
UINTN TransferLength512;\r
UINT32 Tries;\r
TCG_COM_PACKET *ComPacket;\r
// so we need to retry the IF-RECV to get the actual Data.\r
// See TCG Core Spec v2 Table 45 IF-RECV ComPacket Field Values Summary\r
// This is an arbitrary number of retries, not from the spec.\r
- // have a max timeout of 10 seconds, 5000 tries * 2ms = 10s\r
//\r
- Tries = 5000;\r
+ // if user input estimate time cost(second level) value bigger than 10s, base on user input value to wait.\r
+ // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms = 10s\r
+ //\r
+ if (EstimateTimeCost > 10) {\r
+ Tries = EstimateTimeCost * 500; // 500 = 1000 * 1000 / 2000;\r
+ } else {\r
+ Tries = 5000;\r
+ }\r
while ((Tries--) > 0) {\r
ZeroMem( Buffer, BufferSize );\r
TransferSize = 0;\r
Buffer,\r
&TransferSize\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
return TcgResultFailure;\r
}\r
/**\r
The function performs send, recv, check comIDs, check method status action.\r
\r
- @param[in] Session OPAL_SESSION related to this method..\r
- @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512\r
- @param[in] Buffer Address of Data to transfer\r
- @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
- @param[in] ParseStruct Structure used to parse received TCG response.\r
- @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
-\r
+ @param[in] Session OPAL_SESSION related to this method..\r
+ @param[in] SendSize Transfer Length of Buffer (in bytes) - always a multiple of 512\r
+ @param[in] Buffer Address of Data to transfer\r
+ @param[in] BufferSize Full Size of Buffer, including space that may be used for padding.\r
+ @param[in] ParseStruct Structure used to parse received TCG response.\r
+ @param[in] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
+ @param[in] EstimateTimeCost Estimate the time need to for the method.\r
**/\r
TCG_RESULT\r
EFIAPI\r
-OpalPerformMethod(\r
+OpalPerformMethod (\r
OPAL_SESSION *Session,\r
UINT32 SendSize,\r
VOID *Buffer,\r
UINT32 BufferSize,\r
TCG_PARSE_STRUCT *ParseStruct,\r
- UINT8 *MethodStatus\r
+ UINT8 *MethodStatus,\r
+ UINT32 EstimateTimeCost\r
)\r
{\r
NULL_CHECK(Session);\r
TCG_OPAL_SECURITY_PROTOCOL_1,\r
Session->OpalBaseComId,\r
Buffer,\r
- BufferSize\r
+ BufferSize,\r
+ EstimateTimeCost\r
));\r
\r
ERROR_CHECK(TcgInitTcgParseStruct(ParseStruct, Buffer, BufferSize));\r
//\r
// Send Revert Method Call\r
//\r
- ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
+ METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
+\r
+ return TcgResultSuccess;\r
+}\r
+\r
+/**\r
+\r
+ Reverts device using Admin SP Revert method.\r
+\r
+ @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert.\r
+ @param[in] EstimateTimeCost Estimate the time needed.\r
+\r
+**/\r
+TCG_RESULT\r
+OpalPyrite2PsidRevert(\r
+ OPAL_SESSION *AdminSpSession,\r
+ UINT32 EstimateTimeCost\r
+ )\r
+{\r
+ //\r
+ // Now that base comid is known, start Session\r
+ // we'll attempt to start Session as PSID authority\r
+ // verify PSID Authority is defined in ADMIN SP authority table... is this possible?\r
+ //\r
+ TCG_CREATE_STRUCT CreateStruct;\r
+ TCG_PARSE_STRUCT ParseStruct;\r
+ UINT32 Size;\r
+ UINT8 Buffer[BUFFER_SIZE];\r
+ UINT8 MethodStatus;\r
+\r
+\r
+ NULL_CHECK(AdminSpSession);\r
+\r
+ //\r
+ // Send Revert action on Admin SP\r
+ //\r
+ ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
+ ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
+ ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
+ ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
+ ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_ADMIN_SP_REVERT_METHOD));\r
+ ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
+ ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
+ ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
+ ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
+\r
+ //\r
+ // Send Revert Method Call\r
+ //\r
+ ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, EstimateTimeCost));\r
METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
\r
return TcgResultSuccess;\r
TCG_OPAL_SECURITY_PROTOCOL_1, // SP\r
TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY, // SP_Specific\r
BuffAddress,\r
- BufferSize\r
+ BufferSize,\r
+ 0\r
));\r
}\r
\r
TCG_SECURITY_PROTOCOL_INFO, // SP\r
TCG_SP_SPECIFIC_PROTOCOL_LIST, // SP_Specific\r
BuffAddress,\r
- BufferSize\r
+ BufferSize,\r
+ 0\r
));\r
}\r
\r
HostChallenge,\r
HostSigningAuthority\r
));\r
- ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
return TcgResultSuccess; // return early if method failed - user must check MethodStatus\r
}\r
TCG_OPAL_SECURITY_PROTOCOL_1,\r
Session->OpalBaseComId,\r
Buffer,\r
- sizeof(Buffer)\r
+ sizeof(Buffer),\r
+ 0\r
));\r
\r
ERROR_CHECK(TcgInitTcgParseStruct(&ParseStruct, Buffer, sizeof(Buffer)));\r
//\r
// Send MSID Method Call\r
//\r
- ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
\r
ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
return TcgResultSuccess;\r
}\r
\r
+/**\r
+\r
+ The function retrieves the MSID from the device specified\r
+\r
+ @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY\r
+ @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism that the device will use for Revert/RevertSP calls.\r
+\r
+**/\r
+TCG_RESULT\r
+OpalPyrite2GetActiveDataRemovalMechanism (\r
+ IN OPAL_SESSION *AdminSpSession,\r
+ OUT UINT8 *ActiveDataRemovalMechanism\r
+ )\r
+{\r
+ TCG_CREATE_STRUCT CreateStruct;\r
+ TCG_PARSE_STRUCT ParseStruct;\r
+ UINT32 Size;\r
+ UINT8 MethodStatus;\r
+ UINT32 Col;\r
+ UINT8 RecvActiveDataRemovalMechanism;\r
+ UINT8 Buffer[BUFFER_SIZE];\r
+\r
+ NULL_CHECK(AdminSpSession);\r
+ NULL_CHECK(ActiveDataRemovalMechanism);\r
+\r
+ ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE));\r
+ ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseComId, AdminSpSession->ComIdExtension));\r
+ ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId, AdminSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
+ ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
+ ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP_DATA_REMOVAL_MECHANISM, TCG_UID_METHOD_GET));\r
+ ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
+ ERROR_CHECK(TcgAddStartList(&CreateStruct));\r
+ ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
+ ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME));\r
+ ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
+ ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
+ ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
+ ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME));\r
+ ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
+ ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
+ ERROR_CHECK(TcgAddEndList(&CreateStruct));\r
+ ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
+ ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
+ ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
+\r
+ //\r
+ // Send Get Active Data Removal Mechanism Method Call\r
+ //\r
+ ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE, &ParseStruct, &MethodStatus, 0));\r
+ METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
+\r
+ ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextStartName(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, &Col));\r
+ ERROR_CHECK(TcgGetNextUINT8(&ParseStruct, &RecvActiveDataRemovalMechanism));\r
+ ERROR_CHECK(TcgGetNextEndName(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextEndList(&ParseStruct));\r
+ ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct));\r
+\r
+ if (Col != OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL) {\r
+ DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL));\r
+ return TcgResultFailure;\r
+ }\r
+\r
+ if (RecvActiveDataRemovalMechanism >= ResearvedMechanism) {\r
+ return TcgResultFailure;\r
+ }\r
+\r
+ //\r
+ // Copy active data removal mechanism into Buffer\r
+ //\r
+ CopyMem(ActiveDataRemovalMechanism, &RecvActiveDataRemovalMechanism, sizeof(RecvActiveDataRemovalMechanism));\r
+ return TcgResultSuccess;\r
+}\r
+\r
/**\r
\r
The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter\r
//\r
// Send RevertSP method call\r
//\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
+\r
+ //\r
+ // Session is immediately ended by device after successful revertsp, so no need to end Session\r
+ //\r
+ if (*MethodStatus == TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+ //\r
+ // Caller should take ownership again\r
+ //\r
+ return TcgResultSuccess;\r
+ } else {\r
+ //\r
+ // End Session\r
+ //\r
+ METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus\r
+ }\r
+\r
+ return TcgResultSuccess;\r
+}\r
+\r
+\r
+/**\r
+\r
+ The function calls the Admin SP RevertSP method on the Locking SP. If KeepUserData is True, then the optional parameter\r
+ to keep the user Data is set to True, otherwise the optional parameter is not provided.\r
+\r
+ @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP\r
+ @param[in] KeepUserData Specifies whether or not to keep user Data when performing RevertSP action. True = keeps user Data.\r
+ @param[in/out] MethodStatus Method status of last action performed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS.\r
+ @param[in] EstimateTimeCost Estimate the time needed.\r
+\r
+**/\r
+TCG_RESULT\r
+OpalPyrite2AdminRevert(\r
+ OPAL_SESSION *LockingSpSession,\r
+ BOOLEAN KeepUserData,\r
+ UINT8 *MethodStatus,\r
+ UINT32 EstimateTimeCost\r
+ )\r
+{\r
+ UINT8 Buf[BUFFER_SIZE];\r
+ TCG_CREATE_STRUCT CreateStruct;\r
+ UINT32 Size;\r
+ TCG_PARSE_STRUCT ParseStruct;\r
+ TCG_RESULT Ret;\r
+\r
+ NULL_CHECK(LockingSpSession);\r
+ NULL_CHECK(MethodStatus);\r
+\r
+ //\r
+ // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee revertSP can keep user Data\r
+ //\r
+ if (KeepUserData) {\r
+ //\r
+ // set readlocked and writelocked to false\r
+ //\r
+ Ret = OpalUpdateGlobalLockingRange(\r
+ LockingSpSession,\r
+ FALSE,\r
+ FALSE,\r
+ MethodStatus);\r
+\r
+ if (Ret != TcgResultSuccess || *MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
+ //\r
+ // bail out\r
+ //\r
+ return Ret;\r
+ }\r
+ }\r
+\r
+ ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
+ ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseComId, LockingSpSession->ComIdExtension));\r
+ ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0));\r
+ ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0));\r
+ ERROR_CHECK(TcgStartMethodCall(&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCKING_SP_REVERTSP_METHOD));\r
+ ERROR_CHECK(TcgStartParameters(&CreateStruct));\r
+\r
+ if (KeepUserData) {\r
+ //\r
+ // optional parameter to keep Data after revert\r
+ //\r
+ ERROR_CHECK(TcgAddStartName(&CreateStruct));\r
+ ERROR_CHECK(TcgAddUINT32(&CreateStruct, 0x060000)); // weird Value but that's what spec says\r
+ ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, KeepUserData));\r
+ ERROR_CHECK(TcgAddEndName(&CreateStruct));\r
+ }\r
+\r
+ ERROR_CHECK(TcgEndParameters(&CreateStruct));\r
+ ERROR_CHECK(TcgEndMethodCall(&CreateStruct));\r
+ ERROR_CHECK(TcgEndSubPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
+ ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
+\r
+ //\r
+ // Send RevertSP method call\r
+ //\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, EstimateTimeCost));\r
\r
//\r
// Session is immediately ended by device after successful revertsp, so no need to end Session\r
//\r
// Send Activate method call\r
//\r
- ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with success on method failure - user must inspect MethodStatus\r
\r
return TcgResultSuccess;\r
NewPinLength\r
));\r
\r
- ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
// exit with success on method failure - user must inspect MethodStatus\r
METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
\r
AuthorityUid,\r
TRUE));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
DEBUG ((DEBUG_INFO, "Send Set Authority error\n"));\r
NewPin,\r
NewPinLength));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
//\r
// allow user1 to set global range to unlocked/locked by modifying ACE_Locking_GlobalRange_SetRdLocked/SetWrLocked\r
OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
DEBUG ((DEBUG_INFO, "Update ACE for RDLOCKED failed\n"));\r
OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
DEBUG ((DEBUG_INFO, "Update ACE for WRLOCKED failed\n"));\r
\r
ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf)));\r
ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession, &CreateStruct, &Size));\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
//\r
- // For Pyrite type SSC, it not supports Active Key. \r
+ // For Pyrite type SSC, it not supports Active Key.\r
// So here add check logic before enable it.\r
//\r
Ret = OpalParseRetrieveGlobalLockingRangeActiveKey(&ParseStruct, &ActiveKey);\r
OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
DEBUG ((DEBUG_INFO, "Update ACE for GLOBALRANGE_GENKEY failed\n"));\r
//\r
- // TODO do we want to disable user1 if all permissions are not granted\r
+ // Disable user1 if all permissions are not granted.\r
//\r
return TcgResultFailure;\r
}\r
OPAL_LOCKING_SP_ADMINS_AUTHORITY\r
));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
if (*MethodStatus != TCG_METHOD_STATUS_CODE_SUCCESS) {\r
DEBUG ((DEBUG_INFO, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBALRANGE_GET_ALL failed\n"));\r
OPAL_LOCKING_SP_USER1_AUTHORITY,\r
FALSE));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
return TcgResultSuccess;\r
}\r
// retrieve the activekey in order to know which globalrange key to generate\r
//\r
ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSession, &CreateStruct, &Size));\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
\r
ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
\r
return TcgResultSuccess;\r
}\r
/**\r
\r
The function updates the ReadLocked and WriteLocked columns of the Global Locking Range.\r
- This funciton is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns\r
+ This function is required for a user1 authority, since a user1 authority shall only have access to ReadLocked and WriteLocked columns\r
(not ReadLockEnabled and WriteLockEnabled columns).\r
\r
@param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_SP to generate key\r
ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
\r
return TcgResultSuccess;\r
ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, MethodStatus, 0));\r
// Exit with success on method failure - user must inspect MethodStatus\r
METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess);\r
\r
ERROR_CHECK(TcgEndPacket(&CreateStruct));\r
ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size));\r
\r
- ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, &MethodStatus));\r
+ ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), &ParseStruct, &MethodStatus, 0));\r
METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure);\r
\r
ERROR_CHECK(TcgGetNextStartList(&ParseStruct));\r
TCG_SUPPORTED_SECURITY_PROTOCOLS *SupportedProtocols;\r
TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;\r
OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;\r
+ OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat2;\r
UINTN Size;\r
+ UINTN Size2;\r
\r
NULL_CHECK(Session);\r
NULL_CHECK(SupportedAttributes);\r
}\r
}\r
\r
+ //\r
+ // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 feature data.\r
+ // so here try to get data from pyrite 2.0 feature data first.\r
+ //\r
Size = 0;\r
Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC, &Size);\r
- SupportedAttributes->PyriteSsc = (Feat != NULL);\r
- if (Feat != NULL && Size >= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR)) {\r
+ Size2 = 0;\r
+ Feat2 = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC_V2_0_0, &Size2);\r
+ if (Feat2 != NULL && Size2 >= sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTOR)) {\r
+ SupportedAttributes->PyriteSscV2 = TRUE;\r
if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
- *OpalBaseComId = SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE);\r
- SupportedAttributes->InitCpinIndicator = (Feat->PyriteSsc.InitialCPINSIDPIN == 0);\r
- SupportedAttributes->CpinUponRevert = (Feat->PyriteSsc.CPINSIDPINRevertBehavior == 0);\r
- DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",\r
+ *OpalBaseComId = SwapBytes16 (Feat2->PyriteSscV2.BaseComdIdBE);\r
+ SupportedAttributes->InitCpinIndicator = (Feat2->PyriteSscV2.InitialCPINSIDPIN == 0);\r
+ SupportedAttributes->CpinUponRevert = (Feat2->PyriteSscV2.CPINSIDPINRevertBehavior == 0);\r
+ DEBUG ((DEBUG_INFO, "Pyrite SSC V2 InitCpinIndicator %d CpinUponRevert %d \n",\r
SupportedAttributes->InitCpinIndicator,\r
SupportedAttributes->CpinUponRevert\r
));\r
}\r
+ } else {\r
+ SupportedAttributes->PyriteSsc = (Feat != NULL);\r
+ if (Feat != NULL && Size >= sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR)) {\r
+ if (*OpalBaseComId == TCG_RESERVED_COMID) {\r
+ *OpalBaseComId = SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE);\r
+ SupportedAttributes->InitCpinIndicator = (Feat->PyriteSsc.InitialCPINSIDPIN == 0);\r
+ SupportedAttributes->CpinUponRevert = (Feat->PyriteSsc.CPINSIDPINRevertBehavior == 0);\r
+ DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d CpinUponRevert %d \n",\r
+ SupportedAttributes->InitCpinIndicator,\r
+ SupportedAttributes->CpinUponRevert\r
+ ));\r
+ }\r
+ }\r
}\r
\r
Size = 0;\r
Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size);\r
if (Feat != NULL && Size >= sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR)) {\r
SupportedAttributes->MediaEncryption = Feat->Locking.MediaEncryption;\r
+ DEBUG ((DEBUG_INFO, "SupportedAttributes->MediaEncryption 0x%X \n", SupportedAttributes->MediaEncryption));\r
}\r
\r
Size = 0;\r
Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_BLOCK_SID, &Size);\r
if (Feat != NULL && Size >= sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR)) {\r
SupportedAttributes->BlockSid = TRUE;\r
+ DEBUG ((DEBUG_INFO, "BlockSid Supported!!! Current Status is 0x%X \n", Feat->BlockSid.SIDBlockedState));\r
+ } else {\r
+ DEBUG ((DEBUG_INFO, "BlockSid Unsupported!!!"));\r
}\r
\r
- DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId));\r
+ Size = 0;\r
+ Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, TCG_FEATURE_DATA_REMOVAL, &Size);\r
+ if (Feat != NULL && Size >= sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR)) {\r
+ SupportedAttributes->DataRemoval = TRUE;\r
+ DEBUG ((DEBUG_INFO, "DataRemoval Feature Supported!\n"));\r
+ DEBUG ((DEBUG_INFO, "Operation Processing = 0x%x\n", Feat->DataRemoval.OperationProcessing));\r
+ DEBUG ((DEBUG_INFO, "RemovalMechanism = 0x%x\n", Feat->DataRemoval.RemovalMechanism));\r
+ DEBUG ((DEBUG_INFO, "BIT0 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit0, SwapBytes16 (Feat->DataRemoval.TimeBit0)));\r
+ DEBUG ((DEBUG_INFO, "BIT1 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit1, SwapBytes16 (Feat->DataRemoval.TimeBit1)));\r
+ DEBUG ((DEBUG_INFO, "BIT2 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit2, SwapBytes16 (Feat->DataRemoval.TimeBit2)));\r
+ DEBUG ((DEBUG_INFO, "BIT3 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit3, SwapBytes16 (Feat->DataRemoval.TimeBit3)));\r
+ DEBUG ((DEBUG_INFO, "BIT4 :: Format = 0x%x, Time = 0x%x\n", Feat->DataRemoval.FormatBit4, SwapBytes16 (Feat->DataRemoval.TimeBit4)));\r
+ }\r
\r
+ DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId));\r
\r
return TcgResultSuccess;\r
}\r
return TcgResultSuccess;\r
}\r
\r
+/**\r
+\r
+ Get the descriptor for the specific feature code.\r
+\r
+ @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_SP to retrieve info.\r
+ @param[in] FeatureCode The feature code user request.\r
+ @param[in, out] DataSize The data size.\r
+ @param[out] Data The data buffer used to save the feature descriptor.\r
+\r
+**/\r
+TCG_RESULT\r
+OpalGetFeatureDescriptor (\r
+ IN OPAL_SESSION *Session,\r
+ IN UINT16 FeatureCode,\r
+ IN OUT UINTN *DataSize,\r
+ OUT VOID *Data\r
+ )\r
+{\r
+ UINT8 Buffer[BUFFER_SIZE];\r
+ TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader;\r
+ OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat;\r
+ UINTN Size;\r
+\r
+ NULL_CHECK(Session);\r
+ NULL_CHECK(DataSize);\r
+ NULL_CHECK(Data);\r
+\r
+ ZeroMem(Buffer, BUFFER_SIZE);\r
+ ASSERT(sizeof(Buffer) >= sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS));\r
+\r
+ if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) == TcgResultFailure) {\r
+ DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n"));\r
+ return TcgResultFailure;\r
+ }\r
+ DiscoveryHeader = (TCG_LEVEL0_DISCOVERY_HEADER*) Buffer;\r
+\r
+ Size = 0;\r
+ Feat = (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeader, FeatureCode, &Size);\r
+ if (Feat != NULL) {\r
+ if (Size > *DataSize) {\r
+ *DataSize = Size;\r
+ return TcgResultFailureBufferTooSmall;\r
+ }\r
+\r
+ *DataSize = Size;\r
+ CopyMem (Data, Feat, Size);\r
+ }\r
+\r
+ return TcgResultSuccess;\r
+}\r
+\r
/**\r
\r
The function determines whether or not all of the requirements for the Opal Feature (not full specification)\r
if (SupportedAttributes->OpalSscLite == 0 &&\r
SupportedAttributes->OpalSsc1 == 0 &&\r
SupportedAttributes->OpalSsc2 == 0 &&\r
- SupportedAttributes->PyriteSsc == 0\r
+ SupportedAttributes->PyriteSsc == 0 &&\r
+ SupportedAttributes->PyriteSscV2 == 0\r
) {\r
return FALSE;\r
}\r