From nobody Sun Feb 8 07:07:29 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 152531743403454.292119108636484; Wed, 2 May 2018 20:17:14 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 9D7E62063E2F9; Wed, 2 May 2018 20:17:10 -0700 (PDT) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B3CA62063E2F4 for ; Wed, 2 May 2018 20:17:09 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 May 2018 20:17:09 -0700 Received: from ydong10-win10.ccr.corp.intel.com ([10.239.158.44]) by orsmga001.jf.intel.com with ESMTP; 02 May 2018 20:17:08 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.65; helo=mga03.intel.com; envelope-from=eric.dong@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,356,1520924400"; d="scan'208";a="52769867" From: Eric Dong To: edk2-devel@lists.01.org, hao.a.wu@intel.com Date: Thu, 3 May 2018 11:17:01 +0800 Message-Id: <20180503031702.11296-3-eric.dong@intel.com> X-Mailer: git-send-email 2.15.0.windows.1 In-Reply-To: <20180503031702.11296-1-eric.dong@intel.com> References: <20180503031702.11296-1-eric.dong@intel.com> Subject: [edk2] [Patch 2/3] SecurityPkg/TcgStorageOpalLib: Add supports for pyrite 2.0 spec. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Eric Dong Reviewed-by: Hao Wu --- SecurityPkg/Include/Library/TcgStorageOpalLib.h | 41 ++ .../Library/TcgStorageOpalLib/TcgStorageOpalCore.c | 426 +++++++++++++++++= +--- .../TcgStorageOpalLib/TcgStorageOpalLib.inf | 1 + .../TcgStorageOpalLib/TcgStorageOpalLibInternal.h | 98 +++++ .../Library/TcgStorageOpalLib/TcgStorageOpalUtil.c | 214 ++++++++++- 5 files changed, 731 insertions(+), 49 deletions(-) create mode 100644 SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib= Internal.h diff --git a/SecurityPkg/Include/Library/TcgStorageOpalLib.h b/SecurityPkg/= Include/Library/TcgStorageOpalLib.h index 9b64a8e5cd..2947c0eaf1 100644 --- a/SecurityPkg/Include/Library/TcgStorageOpalLib.h +++ b/SecurityPkg/Include/Library/TcgStorageOpalLib.h @@ -82,6 +82,15 @@ typedef struct { // UINT32 BlockSid : 1; =20 + // + // Pyrite SSC V2 support (0 - not supported, 1 - supported) + // + UINT32 PyriteSscV2 : 1; + + // + // Supported Data Removal Mechanism support (0 - not supported, 1 - s= upported) + // + UINT32 DataRemoval : 1; } OPAL_DISK_SUPPORT_ATTRIBUTE; =20 // @@ -834,4 +843,36 @@ OpalUtilAdminPasswordExists( IN TCG_LOCKING_FEATURE_DESCRIPTOR *LockingFeature ); =20 +/** + Get Active Data Removal Mechanism Value. + + @param[in] Session, The session info for one = opal device. + @param[in] GeneratedSid Generated SID of disk + @param[in] SidLength Length of generatedSid in= bytes + @param[out] ActiveDataRemovalMechanism Return the active data re= moval mechanism. + +**/ +TCG_RESULT +EFIAPI +OpalUtilGetActiveDataRemovalMechanism ( + OPAL_SESSION *Session, + const VOID *GeneratedSid, + UINT32 SidLength, + UINT8 *ActiveDataRemovalMechanism + ); + +/** + Get the supported Data Removal Mechanism list. + + @param[in] Session, The session info for one = opal device. + @param[out] RemovalMechanismLists Return the supported data= removal mechanism lists. + +**/ +TCG_RESULT +EFIAPI +OpalUtilGetDataRemovalMechanismLists ( + IN OPAL_SESSION *Session, + OUT UINT32 *RemovalMechanismLists + ); + #endif // _OPAL_CORE_H_ diff --git a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c b/S= ecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c index 90cc51a24c..d031ebe798 100644 --- a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c +++ b/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalCore.c @@ -1,7 +1,7 @@ /** @file Public API for Opal Core library. =20 -Copyright (c) 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD = License which accompanies this distribution. The full text of the license may be = found at @@ -19,6 +19,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER= EXPRESS OR IMPLIED. #include #include =20 +#include "TcgStorageOpalLibInternal.h" + #pragma pack(1) typedef struct { UINT8 HardwareReset : 1; @@ -89,6 +91,7 @@ OpalTrustedSend( @param[in] SpSpecific Security Protocol Specific @param[in] Buffer Address of Data to transfer @param[in] BufferSize Full Size of Buffer, including spa= ce that may be used for padding. + @param[in] EstimateTimeCost Estimate the time needed. =20 **/ TCG_RESULT @@ -98,10 +101,10 @@ OpalTrustedRecv( UINT8 SecurityProtocol, UINT16 SpSpecific, VOID *Buffer, - UINTN BufferSize + UINTN BufferSize, + UINT32 EstimateTimeCost ) { - UINTN TransferLength512; UINT32 Tries; TCG_COM_PACKET *ComPacket; @@ -129,9 +132,15 @@ OpalTrustedRecv( // so we need to retry the IF-RECV to get the actual Data. // See TCG Core Spec v2 Table 45 IF-RECV ComPacket Field Values Summary // This is an arbitrary number of retries, not from the spec. - // have a max timeout of 10 seconds, 5000 tries * 2ms =3D 10s // - Tries =3D 5000; + // if user input estimate time cost(second level) value bigger than 10s,= base on user input value to wait. + // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms =3D 1= 0s + // + if (EstimateTimeCost > 10) { + Tries =3D EstimateTimeCost * 500; // 500 =3D 1000 * 1000 / 2000; + } else { + Tries =3D 5000; + } while ((Tries--) > 0) { ZeroMem( Buffer, BufferSize ); TransferSize =3D 0; @@ -146,7 +155,6 @@ OpalTrustedRecv( Buffer, &TransferSize ); - if (EFI_ERROR (Status)) { return TcgResultFailure; } @@ -179,23 +187,24 @@ OpalTrustedRecv( /** The function performs send, recv, check comIDs, check method status acti= on. =20 - @param[in] Session OPAL_SESSION related to this method.. - @param[in] SendSize Transfer Length of Buffer (in bytes) - a= lways a multiple of 512 - @param[in] Buffer Address of Data to transfer - @param[in] BufferSize Full Size of Buffer, including space tha= t may be used for padding. - @param[in] ParseStruct Structure used to parse received TCG res= ponse. - @param[in] MethodStatus Method status of last action performed. = If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS. - + @param[in] Session OPAL_SESSION related to this method.. + @param[in] SendSize Transfer Length of Buffer (in bytes) -= always a multiple of 512 + @param[in] Buffer Address of Data to transfer + @param[in] BufferSize Full Size of Buffer, including space t= hat may be used for padding. + @param[in] ParseStruct Structure used to parse received TCG r= esponse. + @param[in] MethodStatus Method status of last action performed= . If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS. + @param[in] EstimateTimeCost Estimate the time need to for the meth= od. **/ TCG_RESULT EFIAPI -OpalPerformMethod( +OpalPerformMethod ( OPAL_SESSION *Session, UINT32 SendSize, VOID *Buffer, UINT32 BufferSize, TCG_PARSE_STRUCT *ParseStruct, - UINT8 *MethodStatus + UINT8 *MethodStatus, + UINT32 EstimateTimeCost ) { NULL_CHECK(Session); @@ -217,7 +226,8 @@ OpalPerformMethod( TCG_OPAL_SECURITY_PROTOCOL_1, Session->OpalBaseComId, Buffer, - BufferSize + BufferSize, + EstimateTimeCost )); =20 ERROR_CHECK(TcgInitTcgParseStruct(ParseStruct, Buffer, BufferSize)); @@ -309,7 +319,60 @@ OpalPsidRevert( // // Send Revert Method Call // - ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus)); + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus, 0)); + METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure); + + return TcgResultSuccess; +} + +/** + + Reverts device using Admin SP Revert method. + + @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as O= PAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert. + @param[in] EstimateTimeCost Estimate the time needed. + +**/ +TCG_RESULT +EFIAPI +OpalPyrite2PsidRevert( + OPAL_SESSION *AdminSpSession, + UINT32 EstimateTimeCost + ) +{ + // + // Now that base comid is known, start Session + // we'll attempt to start Session as PSID authority + // verify PSID Authority is defined in ADMIN SP authority table... is th= is possible? + // + TCG_CREATE_STRUCT CreateStruct; + TCG_PARSE_STRUCT ParseStruct; + UINT32 Size; + UINT8 Buffer[BUFFER_SIZE]; + UINT8 MethodStatus; + + + NULL_CHECK(AdminSpSession); + + // + // Send Revert action on Admin SP + // + ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE)); + ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseCom= Id, AdminSpSession->ComIdExtension)); + ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId,= AdminSpSession->HostSessionId, 0x0, 0x0, 0x0)); + ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0)); + ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP, OPAL_AD= MIN_SP_REVERT_METHOD)); + ERROR_CHECK(TcgStartParameters(&CreateStruct)); + ERROR_CHECK(TcgEndParameters(&CreateStruct)); + ERROR_CHECK(TcgEndMethodCall(&CreateStruct)); + ERROR_CHECK(TcgEndSubPacket(&CreateStruct)); + ERROR_CHECK(TcgEndPacket(&CreateStruct)); + ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); + + // + // Send Revert Method Call + // + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus, EstimateTimeCost)); METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure); =20 return TcgResultSuccess; @@ -339,7 +402,8 @@ OpalRetrieveLevel0DiscoveryHeader( TCG_OPAL_SECURITY_PROTOCOL_1, // SP TCG_SP_SPECIFIC_PROTOCOL_LEVEL0_DISCOVERY, // SP_Specific BuffAddress, - BufferSize + BufferSize, + 0 )); } =20 @@ -367,7 +431,8 @@ OpalRetrieveSupportedProtocolList( TCG_SECURITY_PROTOCOL_INFO, // SP TCG_SP_SPECIFIC_PROTOCOL_LIST, // SP_Specific BuffAddress, - BufferSize + BufferSize, + 0 )); } =20 @@ -430,7 +495,7 @@ OpalStartSession( HostChallenge, HostSigningAuthority )); - ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStr= uct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStr= uct, MethodStatus, 0)); if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { return TcgResultSuccess; // return early if method failed - user must = check MethodStatus } @@ -487,7 +552,8 @@ OpalEndSession( TCG_OPAL_SECURITY_PROTOCOL_1, Session->OpalBaseComId, Buffer, - sizeof(Buffer) + sizeof(Buffer), + 0 )); =20 ERROR_CHECK(TcgInitTcgParseStruct(&ParseStruct, Buffer, sizeof(Buffer))); @@ -558,7 +624,7 @@ OpalGetMsid( // // Send MSID Method Call // - ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus)); + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus, 0)); METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure); =20 ERROR_CHECK(TcgGetNextStartList(&ParseStruct)); @@ -592,6 +658,86 @@ OpalGetMsid( return TcgResultSuccess; } =20 +/** + + The function retrieves the MSID from the device specified + + @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN= _SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY + @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism th= at the device will use for Revert/RevertSP calls. + +**/ +TCG_RESULT +EFIAPI +OpalPyrite2GetActiveDataRemovalMechanism ( + IN OPAL_SESSION *AdminSpSession, + OUT UINT8 *ActiveDataRemovalMechanism + ) +{ + TCG_CREATE_STRUCT CreateStruct; + TCG_PARSE_STRUCT ParseStruct; + UINT32 Size; + UINT8 MethodStatus; + UINT32 Col; + UINT8 RecvActiveDataRemovalMechanism; + UINT8 Buffer[BUFFER_SIZE]; + + NULL_CHECK(AdminSpSession); + NULL_CHECK(ActiveDataRemovalMechanism); + + ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buffer, BUFFER_SIZE)); + ERROR_CHECK(TcgStartComPacket(&CreateStruct, AdminSpSession->OpalBaseCom= Id, AdminSpSession->ComIdExtension)); + ERROR_CHECK(TcgStartPacket(&CreateStruct, AdminSpSession->TperSessionId,= AdminSpSession->HostSessionId, 0x0, 0x0, 0x0)); + ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0)); + ERROR_CHECK(TcgStartMethodCall(&CreateStruct, OPAL_UID_ADMIN_SP_DATA_REM= OVAL_MECHANISM, TCG_UID_METHOD_GET)); + ERROR_CHECK(TcgStartParameters(&CreateStruct)); + ERROR_CHECK(TcgAddStartList(&CreateStruct)); + ERROR_CHECK(TcgAddStartName(&CreateStruct)); + ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_START_COLUMN_NAME)= ); + ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL= _MECHANISM_COL)); + ERROR_CHECK(TcgAddEndName(&CreateStruct)); + ERROR_CHECK(TcgAddStartName(&CreateStruct)); + ERROR_CHECK(TcgAddUINT8(&CreateStruct, TCG_CELL_BLOCK_END_COLUMN_NAME)); + ERROR_CHECK(TcgAddUINT8(&CreateStruct, OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL= _MECHANISM_COL)); + ERROR_CHECK(TcgAddEndName(&CreateStruct)); + ERROR_CHECK(TcgAddEndList(&CreateStruct)); + ERROR_CHECK(TcgEndParameters(&CreateStruct)); + ERROR_CHECK(TcgEndMethodCall(&CreateStruct)); + ERROR_CHECK(TcgEndSubPacket(&CreateStruct)); + ERROR_CHECK(TcgEndPacket(&CreateStruct)); + ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); + + // + // Send Get Active Data Removal Mechanism Method Call + // + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buffer, BUFFER_SIZE,= &ParseStruct, &MethodStatus, 0)); + METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure); + + ERROR_CHECK(TcgGetNextStartList(&ParseStruct)); + ERROR_CHECK(TcgGetNextStartList(&ParseStruct)); + ERROR_CHECK(TcgGetNextStartName(&ParseStruct)); + ERROR_CHECK(TcgGetNextUINT32(&ParseStruct, &Col)); + ERROR_CHECK(TcgGetNextUINT8(&ParseStruct, &RecvActiveDataRemovalMechanis= m)); + ERROR_CHECK(TcgGetNextEndName(&ParseStruct)); + ERROR_CHECK(TcgGetNextEndList(&ParseStruct)); + ERROR_CHECK(TcgGetNextEndList(&ParseStruct)); + ERROR_CHECK(TcgGetNextEndOfData(&ParseStruct)); + + if (Col !=3D OPAL_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL) { + DEBUG ((DEBUG_INFO, "ERROR: got col %u, expected %u\n", Col, OPAL_ADMI= N_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL)); + return TcgResultFailure; + } + + if (RecvActiveDataRemovalMechanism >=3D ResearvedMechanism) { + return TcgResultFailure; + } + + // + // Copy active data removal mechanism into Buffer + // + CopyMem(ActiveDataRemovalMechanism, &RecvActiveDataRemovalMechanism, siz= eof(RecvActiveDataRemovalMechanism)); + return TcgResultSuccess; +} + /** =20 The function calls the Admin SP RevertSP method on the Locking SP. If K= eepUserData is True, then the optional parameter @@ -666,7 +812,104 @@ OpalAdminRevert( // // Send RevertSP method call // - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); + + // + // Session is immediately ended by device after successful revertsp, so = no need to end Session + // + if (*MethodStatus =3D=3D TCG_METHOD_STATUS_CODE_SUCCESS) { + // + // Caller should take ownership again + // + return TcgResultSuccess; + } else { + // + // End Session + // + METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exi= t with success on method failure - user must inspect MethodStatus + } + + return TcgResultSuccess; +} + + +/** + + The function calls the Admin SP RevertSP method on the Locking SP. If K= eepUserData is True, then the optional parameter + to keep the user Data is set to True, otherwise the optional parameter i= s not provided. + + @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_S= P as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP + @param[in] KeepUserData Specifies whether or not to keep use= r Data when performing RevertSP action. True =3D keeps user Data. + @param[in/out] MethodStatus Method status of last action perform= ed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS. + @param[in] EstimateTimeCost Estimate the time needed. + +**/ +TCG_RESULT +EFIAPI +OpalPyrite2AdminRevert( + OPAL_SESSION *LockingSpSession, + BOOLEAN KeepUserData, + UINT8 *MethodStatus, + UINT32 EstimateTimeCost + ) +{ + UINT8 Buf[BUFFER_SIZE]; + TCG_CREATE_STRUCT CreateStruct; + UINT32 Size; + TCG_PARSE_STRUCT ParseStruct; + TCG_RESULT Ret; + + NULL_CHECK(LockingSpSession); + NULL_CHECK(MethodStatus); + + // + // ReadLocked or WriteLocked must be False (per Opal spec) to guarantee = revertSP can keep user Data + // + if (KeepUserData) { + // + // set readlocked and writelocked to false + // + Ret =3D OpalUpdateGlobalLockingRange( + LockingSpSession, + FALSE, + FALSE, + MethodStatus); + + if (Ret !=3D TcgResultSuccess || *MethodStatus !=3D TCG_METHOD_STATUS_= CODE_SUCCESS) { + // + // bail out + // + return Ret; + } + } + + ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf))); + ERROR_CHECK(TcgStartComPacket(&CreateStruct, LockingSpSession->OpalBaseC= omId, LockingSpSession->ComIdExtension)); + ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession->TperSessionI= d, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0)); + ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0)); + ERROR_CHECK(TcgStartMethodCall(&CreateStruct, TCG_UID_THIS_SP, OPAL_LOCK= ING_SP_REVERTSP_METHOD)); + ERROR_CHECK(TcgStartParameters(&CreateStruct)); + + if (KeepUserData) { + // + // optional parameter to keep Data after revert + // + ERROR_CHECK(TcgAddStartName(&CreateStruct)); + ERROR_CHECK(TcgAddUINT32(&CreateStruct, 0x060000)); // weird Valu= e but that's what spec says + ERROR_CHECK(TcgAddBOOLEAN(&CreateStruct, KeepUserData)); + ERROR_CHECK(TcgAddEndName(&CreateStruct)); + } + + ERROR_CHECK(TcgEndParameters(&CreateStruct)); + ERROR_CHECK(TcgEndMethodCall(&CreateStruct)); + ERROR_CHECK(TcgEndSubPacket(&CreateStruct)); + ERROR_CHECK(TcgEndPacket(&CreateStruct)); + ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); + + // + // Send RevertSP method call + // + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, EstimateTimeCost)); =20 // // Session is immediately ended by device after successful revertsp, so = no need to end Session @@ -729,7 +972,7 @@ OpalActivateLockingSp( // // Send Activate method call // - ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), &P= arseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), &P= arseStruct, MethodStatus, 0)); METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); // exit with= success on method failure - user must inspect MethodStatus =20 return TcgResultSuccess; @@ -778,7 +1021,7 @@ OpalSetPassword( NewPinLength )); =20 - ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStr= uct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), &ParseStr= uct, MethodStatus, 0)); // exit with success on method failure - user must inspect MethodStatus METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); =20 @@ -831,7 +1074,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( AuthorityUid, TRUE)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { DEBUG ((DEBUG_INFO, "Send Set Authority error\n")); @@ -851,7 +1094,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( NewPin, NewPinLength)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 // // allow user1 to set global range to unlocked/locked by modifying ACE_L= ocking_GlobalRange_SetRdLocked/SetWrLocked @@ -870,7 +1113,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( OPAL_LOCKING_SP_ADMINS_AUTHORITY )); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { DEBUG ((DEBUG_INFO, "Update ACE for RDLOCKED failed\n")); @@ -891,7 +1134,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( OPAL_LOCKING_SP_ADMINS_AUTHORITY )); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { DEBUG ((DEBUG_INFO, "Update ACE for WRLOCKED failed\n")); @@ -900,7 +1143,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( =20 ERROR_CHECK(TcgInitTcgCreateStruct(&CreateStruct, Buf, sizeof(Buf))); ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSessi= on, &CreateStruct, &Size)); - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 // // For Pyrite type SSC, it not supports Active Key.=20 @@ -922,7 +1165,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( OPAL_LOCKING_SP_ADMINS_AUTHORITY )); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf)= , &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf)= , &ParseStruct, MethodStatus, 0)); =20 if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { DEBUG ((DEBUG_INFO, "Update ACE for GLOBALRANGE_GENKEY failed\n")); @@ -947,7 +1190,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( OPAL_LOCKING_SP_ADMINS_AUTHORITY )); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { DEBUG ((DEBUG_INFO, "Update ACE for OPAL_LOCKING_SP_ACE_LOCKING_GLOBAL= RANGE_GET_ALL failed\n")); @@ -991,7 +1234,7 @@ OpalDisableUser( OPAL_LOCKING_SP_USER1_AUTHORITY, FALSE)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 return TcgResultSuccess; } @@ -1026,7 +1269,7 @@ OpalGlobalLockingRangeGenKey( // retrieve the activekey in order to know which globalrange key to gene= rate // ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSessi= on, &CreateStruct, &Size)); - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); =20 @@ -1047,7 +1290,7 @@ OpalGlobalLockingRangeGenKey( ERROR_CHECK(TcgEndPacket(&CreateStruct)); ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); =20 return TcgResultSuccess; } @@ -1113,7 +1356,7 @@ OpalUpdateGlobalLockingRange( ERROR_CHECK(TcgEndPacket(&CreateStruct)); ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); =20 return TcgResultSuccess; @@ -1214,7 +1457,7 @@ OpalSetLockingRange( ERROR_CHECK(TcgEndPacket(&CreateStruct)); ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, MethodStatus, 0)); // Exit with success on method failure - user must inspect MethodStatus METHOD_STATUS_ERROR_CHECK(*MethodStatus, TcgResultSuccess); =20 @@ -1362,7 +1605,7 @@ OpalGetTryLimit( ERROR_CHECK(TcgEndPacket(&CreateStruct)); ERROR_CHECK(TcgEndComPacket(&CreateStruct, &Size)); =20 - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, &MethodStatus)); + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Buf), = &ParseStruct, &MethodStatus, 0)); METHOD_STATUS_ERROR_CHECK(MethodStatus, TcgResultFailure); =20 ERROR_CHECK(TcgGetNextStartList(&ParseStruct)); @@ -1404,7 +1647,9 @@ OpalGetSupportedAttributesInfo( TCG_SUPPORTED_SECURITY_PROTOCOLS *SupportedProtocols; TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader; OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat; + OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat2; UINTN Size; + UINTN Size2; =20 NULL_CHECK(Session); NULL_CHECK(SupportedAttributes); @@ -1491,19 +1736,38 @@ OpalGetSupportedAttributesInfo( } } =20 + // + // For some pyrite 2.0 device, it contains both pyrite 1.0 and 2.0 featu= re data. + // so here try to get data from pyrite 2.0 feature data first. + // Size =3D 0; Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeade= r, TCG_FEATURE_PYRITE_SSC, &Size); - SupportedAttributes->PyriteSsc =3D (Feat !=3D NULL); - if (Feat !=3D NULL && Size >=3D sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR)) { + Size2 =3D 0; + Feat2 =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHead= er, TCG_FEATURE_PYRITE_SSC_V2_0_0, &Size2); + if (Feat2 !=3D NULL && Size2 >=3D sizeof (PYRITE_SSCV2_FEATURE_DESCRIPTO= R)) { + SupportedAttributes->PyriteSscV2 =3D TRUE; if (*OpalBaseComId =3D=3D TCG_RESERVED_COMID) { - *OpalBaseComId =3D SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE); - SupportedAttributes->InitCpinIndicator =3D (Feat->PyriteSsc.InitialC= PINSIDPIN =3D=3D 0); - SupportedAttributes->CpinUponRevert =3D (Feat->PyriteSsc.CPINSIDPINR= evertBehavior =3D=3D 0); - DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d CpinUponRevert= %d \n", + *OpalBaseComId =3D SwapBytes16 (Feat2->PyriteSscV2.BaseComdIdBE); + SupportedAttributes->InitCpinIndicator =3D (Feat2->PyriteSscV2.Initi= alCPINSIDPIN =3D=3D 0); + SupportedAttributes->CpinUponRevert =3D (Feat2->PyriteSscV2.CPINSIDP= INRevertBehavior =3D=3D 0); + DEBUG ((DEBUG_INFO, "Pyrite SSC V2 InitCpinIndicator %d CpinUponRev= ert %d \n", SupportedAttributes->InitCpinIndicator, SupportedAttributes->CpinUponRevert )); } + } else { + SupportedAttributes->PyriteSsc =3D (Feat !=3D NULL); + if (Feat !=3D NULL && Size >=3D sizeof (PYRITE_SSC_FEATURE_DESCRIPTOR)= ) { + if (*OpalBaseComId =3D=3D TCG_RESERVED_COMID) { + *OpalBaseComId =3D SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE); + SupportedAttributes->InitCpinIndicator =3D (Feat->PyriteSsc.Initia= lCPINSIDPIN =3D=3D 0); + SupportedAttributes->CpinUponRevert =3D (Feat->PyriteSsc.CPINSIDPI= NRevertBehavior =3D=3D 0); + DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d CpinUponReve= rt %d \n", + SupportedAttributes->InitCpinIndicator, + SupportedAttributes->CpinUponRevert + )); + } + } } =20 Size =3D 0; @@ -1519,16 +1783,33 @@ OpalGetSupportedAttributesInfo( Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeade= r, TCG_FEATURE_LOCKING, &Size); if (Feat !=3D NULL && Size >=3D sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR))= { SupportedAttributes->MediaEncryption =3D Feat->Locking.MediaEncryption; + DEBUG ((DEBUG_INFO, "SupportedAttributes->MediaEncryption 0x%X \n", Su= pportedAttributes->MediaEncryption)); } =20 Size =3D 0; Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeade= r, TCG_FEATURE_BLOCK_SID, &Size); if (Feat !=3D NULL && Size >=3D sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPTOR= )) { SupportedAttributes->BlockSid =3D TRUE; + DEBUG ((DEBUG_INFO, "BlockSid Supported!!! Current Status is 0x%X \n",= Feat->BlockSid.SIDBlockedState)); + } else { + DEBUG ((DEBUG_INFO, "BlockSid Unsupported!!!")); } =20 - DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId)); + Size =3D 0; + Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeade= r, TCG_FEATURE_DATA_REMOVAL, &Size); + if (Feat !=3D NULL && Size >=3D sizeof (DATA_REMOVAL_FEATURE_DESCRIPTOR)= ) { + SupportedAttributes->DataRemoval =3D TRUE; + DEBUG ((DEBUG_INFO, "DataRemoval Feature Supported!\n")); + DEBUG ((DEBUG_INFO, "Operation Processing =3D 0x%x\n", Feat->DataRemov= al.OperationProcessing)); + DEBUG ((DEBUG_INFO, "RemovalMechanism =3D 0x%x\n", Feat->DataRemoval.R= emovalMechanism)); + DEBUG ((DEBUG_INFO, "BIT0 :: Format =3D 0x%x, Time =3D 0x%x\n", Feat->= DataRemoval.FormatBit0, SwapBytes16 (Feat->DataRemoval.TimeBit0))); + DEBUG ((DEBUG_INFO, "BIT1 :: Format =3D 0x%x, Time =3D 0x%x\n", Feat->= DataRemoval.FormatBit1, SwapBytes16 (Feat->DataRemoval.TimeBit1))); + DEBUG ((DEBUG_INFO, "BIT2 :: Format =3D 0x%x, Time =3D 0x%x\n", Feat->= DataRemoval.FormatBit2, SwapBytes16 (Feat->DataRemoval.TimeBit2))); + DEBUG ((DEBUG_INFO, "BIT3 :: Format =3D 0x%x, Time =3D 0x%x\n", Feat->= DataRemoval.FormatBit3, SwapBytes16 (Feat->DataRemoval.TimeBit3))); + DEBUG ((DEBUG_INFO, "BIT4 :: Format =3D 0x%x, Time =3D 0x%x\n", Feat->= DataRemoval.FormatBit4, SwapBytes16 (Feat->DataRemoval.TimeBit4))); + } =20 + DEBUG ((DEBUG_INFO, "Base COMID 0x%04X \n", *OpalBaseComId)); =20 return TcgResultSuccess; } @@ -1574,6 +1855,58 @@ OpalGetLockingInfo( return TcgResultSuccess; } =20 +/** + + Get the support attribute info. + + @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_S= P to retrieve info. + @param[in] FeatureCode The feature code user request. + @param[in, out] DataSize The data size. + @param[out] Data The data buffer used to save the fea= ture descriptor. + +**/ +TCG_RESULT +EFIAPI +OpalGetFeatureDescriptor ( + IN OPAL_SESSION *Session, + IN UINT16 FeatureCode, + IN OUT UINTN *DataSize, + OUT VOID *Data + ) +{ + UINT8 Buffer[BUFFER_SIZE]; + TCG_LEVEL0_DISCOVERY_HEADER *DiscoveryHeader; + OPAL_LEVEL0_FEATURE_DESCRIPTOR *Feat; + UINTN Size; + + NULL_CHECK(Session); + NULL_CHECK(DataSize); + NULL_CHECK(Data); + + ZeroMem(Buffer, BUFFER_SIZE); + ASSERT(sizeof(Buffer) >=3D sizeof(TCG_SUPPORTED_SECURITY_PROTOCOLS)); + + if (OpalRetrieveLevel0DiscoveryHeader (Session, BUFFER_SIZE, Buffer) =3D= =3D TcgResultFailure) { + DEBUG ((DEBUG_INFO, "OpalRetrieveLevel0DiscoveryHeader failed\n")); + return TcgResultFailure; + } + DiscoveryHeader =3D (TCG_LEVEL0_DISCOVERY_HEADER*) Buffer; + + Size =3D 0; + Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature (DiscoveryHeade= r, FeatureCode, &Size); + if (Feat !=3D NULL) { + if (Size > *DataSize) { + *DataSize =3D Size; + return TcgResultFailureBufferTooSmall; + } + + *DataSize =3D Size; + CopyMem (Data, Feat, Size); + } + + return TcgResultSuccess; +} + /** =20 The function determines whether or not all of the requirements for the O= pal Feature (not full specification) @@ -1597,7 +1930,8 @@ OpalFeatureSupported( if (SupportedAttributes->OpalSscLite =3D=3D 0 && SupportedAttributes->OpalSsc1 =3D=3D 0 && SupportedAttributes->OpalSsc2 =3D=3D 0 && - SupportedAttributes->PyriteSsc =3D=3D 0 + SupportedAttributes->PyriteSsc =3D=3D 0 && + SupportedAttributes->PyriteSscV2 =3D=3D 0 ) { return FALSE; } diff --git a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf b/= SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf index 78e47387a9..70f54f7f8a 100644 --- a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf +++ b/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLib.inf @@ -29,6 +29,7 @@ [Sources] TcgStorageOpalCore.c TcgStorageOpalUtil.c + TcgStorageOpalLibInternal.h =20 [LibraryClasses] BaseLib diff --git a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLibInterna= l.h b/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLibInternal.h new file mode 100644 index 0000000000..cd16c51c3b --- /dev/null +++ b/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalLibInternal.h @@ -0,0 +1,98 @@ +/** @file + Internal functions for Opal Core library. + +Copyright (c) 2018, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD = License +which accompanies this distribution. The full text of the license may be = found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + +**/ + +#ifndef _OPAL_INTERNAL_H_ +#define _OPAL_INTERNAL_H_ + +#include + + +/** + + The function retrieves the MSID from the device specified + + @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN= _SP as OPAL_ADMIN_SP_ANYBODY_AUTHORITY + @param[out] ActiveDataRemovalMechanism Active Data Removal Mechanism th= at the device will use for Revert/RevertSP calls. + +**/ +TCG_RESULT +EFIAPI +OpalPyrite2GetActiveDataRemovalMechanism ( + OPAL_SESSION *AdminSpSession, + UINT8 *ActiveDataRemovalMechanism + ); + +/** + + Get the support attribute info. + + @param[in] Session OPAL_SESSION with OPAL_UID_LOCKING_S= P to retrieve info. + @param[in] FeatureCode The feature code user request. + @param[in, out] DataSize The data size. + @param[out] Data The data buffer used to save the fea= ture descriptor. + +**/ +TCG_RESULT +OpalGetFeatureDescriptor ( + IN OPAL_SESSION *Session, + IN UINT16 FeatureCode, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +/** + Get revert timeout value. + + @param[in] Session The session info for one o= pal device. + +**/ +UINT32 +GetRevertTimeOut ( + IN OPAL_SESSION *Session + ); + +/** + + Reverts device using Admin SP Revert method. + + @param[in] AdminSpSession OPAL_SESSION with OPAL_UID_ADMIN_SP as O= PAL_ADMIN_SP_PSID_AUTHORITY to perform PSID revert. + @param[in] EstimateTimeCost Input the timeout value. + +**/ +TCG_RESULT +OpalPyrite2PsidRevert( + OPAL_SESSION *AdminSpSession, + UINT32 EstimateTimeCost + ); + +/** + + The function calls the Admin SP RevertSP method on the Locking SP. If K= eepUserData is True, then the optional parameter + to keep the user Data is set to True, otherwise the optional parameter i= s not provided. + + @param[in] LockingSpSession OPAL_SESSION with OPAL_UID_LOCKING_S= P as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to revertSP + @param[in] KeepUserData Specifies whether or not to keep use= r Data when performing RevertSP action. True =3D keeps user Data. + @param[in/out] MethodStatus Method status of last action perform= ed. If action succeeded, it should be TCG_METHOD_STATUS_CODE_SUCCESS. + @param[in] EstimateTimeCost Input the timeout value. + +**/ +TCG_RESULT +OpalPyrite2AdminRevert( + OPAL_SESSION *LockingSpSession, + BOOLEAN KeepUserData, + UINT8 *MethodStatus, + UINT32 EstimateTimeCost + ); + +#endif // _OPAL_CORE_H_ diff --git a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c b/S= ecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c index f77fbe25c1..0a597a20be 100644 --- a/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c +++ b/SecurityPkg/Library/TcgStorageOpalLib/TcgStorageOpalUtil.c @@ -1,7 +1,7 @@ /** @file Public API for Opal Core library. =20 -Copyright (c) 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2016 ~ 2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD = License which accompanies this distribution. The full text of the license may be = found at @@ -15,7 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER= EXPRESS OR IMPLIED. #include #include #include +#include =20 +#define OPAL_MSID_LENGHT 128 =20 /** Creates a session with OPAL_UID_ADMIN_SP as OPAL_ADMIN_SP_PSID_AUTHORITY= , then reverts device using Admin SP Revert method. @@ -35,10 +37,14 @@ OpalUtilPsidRevert( { UINT8 MethodStatus; TCG_RESULT Ret; + UINT32 RemovalTimeOut; =20 NULL_CHECK(Session); NULL_CHECK(Psid); =20 + RemovalTimeOut =3D GetRevertTimeOut (Session); + DEBUG ((DEBUG_INFO, "OpalUtilPsidRevert: Timeout value =3D %d\n", Remova= lTimeOut)); + Ret =3D OpalStartSession( Session, OPAL_UID_ADMIN_SP, @@ -48,7 +54,7 @@ OpalUtilPsidRevert( OPAL_ADMIN_SP_PSID_AUTHORITY, &MethodStatus); if (Ret =3D=3D TcgResultSuccess && MethodStatus =3D=3D TCG_METHOD_STATUS= _CODE_SUCCESS) { - Ret =3D OpalPsidRevert(Session); + Ret =3D OpalPyrite2PsidRevert(Session, RemovalTimeOut); if (Ret !=3D TcgResultSuccess) { // // If revert was successful, session was already ended by TPer, so o= nly end session on failure @@ -599,12 +605,16 @@ OpalUtilRevert( { UINT8 MethodStatus; TCG_RESULT Ret; + UINT32 RemovalTimeOut; =20 NULL_CHECK(Session); NULL_CHECK(Msid); NULL_CHECK(Password); NULL_CHECK(PasswordFailed); =20 + RemovalTimeOut =3D GetRevertTimeOut (Session); + DEBUG ((DEBUG_INFO, "OpalUtilRevert: Timeout value =3D %d\n", RemovalTim= eOut)); + Ret =3D OpalStartSession( Session, OPAL_UID_LOCKING_SP, @@ -625,7 +635,7 @@ OpalUtilRevert( // // Try to revert with admin1 // - Ret =3D OpalAdminRevert(Session, KeepUserData, &MethodStatus); + Ret =3D OpalPyrite2AdminRevert(Session, KeepUserData, &MethodStatus, Rem= ovalTimeOut); if (Ret !=3D TcgResultSuccess || MethodStatus !=3D TCG_METHOD_STATUS_COD= E_SUCCESS) { // // Device ends the session on successful revert, so only call OpalEndS= ession when fail. @@ -912,3 +922,201 @@ OpalUtilAdminPasswordExists( return (OwnerShip =3D=3D OpalOwnershipUnknown && LockingFeature->Locking= Enabled); } =20 +/** + Get Active Data Removal Mechanism Value. + + @param[in] Session The session info for one = opal device. + @param[in] GeneratedSid Generated SID of disk + @param[in] SidLength Length of generatedSid in= bytes + @param[out] ActiveDataRemovalMechanism Return the active data re= moval mechanism. + +**/ +TCG_RESULT +EFIAPI +OpalUtilGetActiveDataRemovalMechanism ( + OPAL_SESSION *Session, + const VOID *GeneratedSid, + UINT32 SidLength, + UINT8 *ActiveDataRemovalMechanism + ) +{ + TCG_RESULT Ret; + UINT8 MethodStatus; + + NULL_CHECK(Session); + NULL_CHECK(GeneratedSid); + NULL_CHECK(ActiveDataRemovalMechanism); + + Ret =3D OpalStartSession( + Session, + OPAL_UID_ADMIN_SP, + TRUE, + SidLength, + GeneratedSid, + OPAL_ADMIN_SP_ANYBODY_AUTHORITY, + &MethodStatus + ); + if (Ret !=3D TcgResultSuccess || MethodStatus !=3D TCG_METHOD_STATUS_COD= E_SUCCESS) { + DEBUG ((DEBUG_INFO, "Start session with admin SP as SID authority fail= ed: Ret=3D%d MethodStatus=3D%u\n", Ret, MethodStatus)); + if (MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { + Ret =3D TcgResultFailure; + } + return Ret; + } + + Ret =3D OpalPyrite2GetActiveDataRemovalMechanism ( + Session, + ActiveDataRemovalMechanism + ); + + if (Ret !=3D TcgResultSuccess) { + DEBUG ((DEBUG_INFO, "Pyrite2 Get Active Data Removal Mechanism failed:= Ret=3D%d\n", Ret)); + } + + OpalEndSession(Session); + + return Ret; +} + +/** + Calculate the estimated time. + + @param[in] IsMinite Whether the input time value is m= inute type or second type. + @param[in] Time The input time value. + +**/ +UINT32 +CalculateDataRemovalTime ( + IN BOOLEAN IsMinute, + IN UINT16 Time + ) +{ + if (IsMinute) { + return Time * 2 * 60; + } else { + return Time * 2; + } +} + +/** + Return the estimated time for specific type. + + @param[in] Index The input data removal type. + @param[in] Descriptor DATA_REMOVAL_FEATURE_DESCRIPTOR + +**/ +UINT32 +GetDataRemovalTime ( + IN UINT8 Index, + IN DATA_REMOVAL_FEATURE_DESCRIPTOR *Descriptor + ) +{ + switch (Index) { + case OverwriteDataErase: + return CalculateDataRemovalTime (Descriptor->FormatBit0, SwapBytes16 (= Descriptor->TimeBit0)); + + case BlockErase: + return CalculateDataRemovalTime (Descriptor->FormatBit1, SwapBytes16 (= Descriptor->TimeBit1)); + + case CryptoErase: + return CalculateDataRemovalTime (Descriptor->FormatBit2, SwapBytes16 (= Descriptor->TimeBit2)); + + case Unmap: + return CalculateDataRemovalTime (Descriptor->FormatBit3, SwapBytes16 (= Descriptor->TimeBit3)); + + case ResetWritePointers: + return CalculateDataRemovalTime (Descriptor->FormatBit4, SwapBytes16 (= Descriptor->TimeBit4)); + + case VendorSpecificErase: + return CalculateDataRemovalTime (Descriptor->FormatBit5, SwapBytes16 (= Descriptor->TimeBit5)); + + default: + return 0; + } +} + +/** + Get the supported Data Removal Mechanism list. + + @param[in] Session The session info for one = opal device. + @param[out] RemovalMechanismLists Return the supported data= removal mechanism lists. + +**/ +TCG_RESULT +EFIAPI +OpalUtilGetDataRemovalMechanismLists ( + IN OPAL_SESSION *Session, + OUT UINT32 *RemovalMechanismLists + ) +{ + TCG_RESULT Ret; + UINTN DataSize; + DATA_REMOVAL_FEATURE_DESCRIPTOR Descriptor; + UINT8 Index; + UINT8 BitValue; + + NULL_CHECK(Session); + NULL_CHECK(RemovalMechanismLists); + + DataSize =3D sizeof (Descriptor); + Ret =3D OpalGetFeatureDescriptor (Session, TCG_FEATURE_DATA_REMOVAL, &Da= taSize, &Descriptor); + if (Ret !=3D TcgResultSuccess) { + return TcgResultFailure; + } + + ASSERT (Descriptor.RemovalMechanism !=3D 0); + + for (Index =3D 0; Index < ResearvedMechanism; Index ++) { + BitValue =3D (BOOLEAN) BitFieldRead8 (Descriptor.RemovalMechanism, Ind= ex, Index); + + if (BitValue =3D=3D 0) { + RemovalMechanismLists[Index] =3D 0; + } else { + RemovalMechanismLists[Index] =3D GetDataRemovalTime (Index, &Descrip= tor); + } + } + + return TcgResultSuccess; +} + +/** + Get revert timeout value. + + @param[in] Session The session info for one o= pal device. + +**/ +UINT32 +GetRevertTimeOut ( + IN OPAL_SESSION *Session + ) +{ + TCG_RESULT TcgResult; + OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes; + UINT16 BaseComId; + UINT32 MsidLength; + UINT8 Msid[OPAL_MSID_LENGHT]; + UINT32 RemovalMechanishLists[ResearvedMechanism]; + UINT8 ActiveDataRemovalMechanism; + + TcgResult =3D OpalGetSupportedAttributesInfo (Session, &SupportedAttribu= tes, &BaseComId); + if (TcgResult !=3D TcgResultSuccess || SupportedAttributes.DataRemoval = =3D=3D 0) { + return 0; + } + + TcgResult =3D OpalUtilGetMsid (Session, Msid, OPAL_MSID_LENGHT, &MsidLen= gth); + if (TcgResult !=3D TcgResultSuccess) { + return 0; + } + + TcgResult =3D OpalUtilGetDataRemovalMechanismLists (Session, RemovalMech= anishLists); + if (TcgResult !=3D TcgResultSuccess) { + return 0; + } + + TcgResult =3D OpalUtilGetActiveDataRemovalMechanism (Session, Msid, Msid= Length, &ActiveDataRemovalMechanism); + if (TcgResult !=3D TcgResultSuccess) { + return 0; + } + + return RemovalMechanishLists[ActiveDataRemovalMechanism]; +} --=20 2.15.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel