From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=hao.a.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (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 58FED2094608B for ; Sun, 6 May 2018 20:08:34 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 May 2018 20:08:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,372,1520924400"; d="scan'208";a="197251175" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga004.jf.intel.com with ESMTP; 06 May 2018 20:08:33 -0700 Received: from fmsmsx152.amr.corp.intel.com (10.18.125.5) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 6 May 2018 20:08:33 -0700 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by FMSMSX152.amr.corp.intel.com (10.18.125.5) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 6 May 2018 20:08:32 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.240]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.179]) with mapi id 14.03.0319.002; Mon, 7 May 2018 11:08:30 +0800 From: "Wu, Hao A" To: "Dong, Eric" , "edk2-devel@lists.01.org" Thread-Topic: [Patch 2/3] SecurityPkg/TcgStorageOpalLib: Add supports for pyrite 2.0 spec. Thread-Index: AQHT4o1AeBbvrh5PwUCgNsn8mVC7WaQjl3UQ Date: Mon, 7 May 2018 03:08:30 +0000 Message-ID: References: <20180503031702.11296-1-eric.dong@intel.com> <20180503031702.11296-3-eric.dong@intel.com> In-Reply-To: <20180503031702.11296-3-eric.dong@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [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: , X-List-Received-Date: Mon, 07 May 2018 03:08:36 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Some minor comments: 1. In file TcgStorageOpalCore.c, the function description comment for OpalGetFeatureDescriptor() seems not matching the function itself. Please h= elp to update. 2. For file TcgStorageOpalUtil.c, the copyright year format seems not prope= r. Also, maybe double quotes can be used instead of brackets for: #include Other than the above comments, the patch is good to me. Reviewed-by: Hao Wu Best Regards, Hao Wu > -----Original Message----- > From: Dong, Eric > Sent: Thursday, May 03, 2018 11:17 AM > To: edk2-devel@lists.01.org; Wu, Hao A > Subject: [Patch 2/3] SecurityPkg/TcgStorageOpalLib: Add supports for pyri= te 2.0 > spec. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Eric Dong > --- > 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/TcgStorageOpalLibInternal.h >=20 > 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 - > supported) > + // > + 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 on= e opal device. > + @param[in] GeneratedSid Generated SID of disk > + @param[in] SidLength Length of generatedSid = in bytes > + @param[out] ActiveDataRemovalMechanism Return the active data > removal 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 on= e opal device. > + @param[out] RemovalMechanismLists Return the supported da= ta > 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/SecurityPkg/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 BS= D > License > which accompanies this distribution. The full text of the license may b= e 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 s= pace 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 Summar= y > // 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 10= s, base > on user input value to wait. > + // Else, Use a max timeout of 10 seconds to wait, 5000 tries * 2ms =3D= 10s > + // > + 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 ac= tion. >=20 > - @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] 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= that may > be used for padding. > + @param[in] ParseStruct Structure used to parse received TCG > response. > + @param[in] 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 need to for the me= thod. > **/ > 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 OPAL_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 = this > 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- > >OpalBaseComId, 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_ADMIN_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), > &ParseStruct, MethodStatus)); > + ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), > &ParseStruct, MethodStatus, 0)); > if (*MethodStatus !=3D TCG_METHOD_STATUS_CODE_SUCCESS) { > return TcgResultSuccess; // return early if method failed - user mus= t 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 that 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- > >OpalBaseComId, 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_REMOVAL_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, > &RecvActiveDataRemovalMechanism)); > + 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_ADMIN_SP_ACTIVE_DATA_REMOVAL_MECHANISM_COL)); > + return TcgResultFailure; > + } > + > + if (RecvActiveDataRemovalMechanism >=3D ResearvedMechanism) { > + return TcgResultFailure; > + } > + > + // > + // Copy active data removal mechanism into Buffer > + // > + CopyMem(ActiveDataRemovalMechanism, > &RecvActiveDataRemovalMechanism, > sizeof(RecvActiveDataRemovalMechanism)); > + return TcgResultSuccess; > +} > + > /** >=20 > The function calls the Admin SP RevertSP method on the Locking SP. If > KeepUserData 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, s= o 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); // > exit with success on method failure - user must inspect MethodStatus > + } > + > + return TcgResultSuccess; > +} > + > + > +/** > + > + The function calls the Admin SP RevertSP method on the Locking SP. If > KeepUserData is True, then the optional parameter > + to keep the user Data is set to True, otherwise the optional parameter= is not > provided. > + > + @param[in] LockingSpSession OPAL_SESSION with > OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to > revertSP > + @param[in] KeepUserData Specifies whether or not to keep u= ser > Data when performing RevertSP action. True =3D keeps user Data. > + @param[in/out] MethodStatus Method status of last action perfo= rmed. > 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 guarante= e > 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- > >OpalBaseComId, LockingSpSession->ComIdExtension)); > + ERROR_CHECK(TcgStartPacket(&CreateStruct, LockingSpSession- > >TperSessionId, LockingSpSession->HostSessionId, 0x0, 0x0, 0x0)); > + ERROR_CHECK(TcgStartSubPacket(&CreateStruct, 0x0)); > + ERROR_CHECK(TcgStartMethodCall(&CreateStruct, TCG_UID_THIS_SP, > OPAL_LOCKING_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 > Value 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, s= o no > need to end Session > @@ -729,7 +972,7 @@ OpalActivateLockingSp( > // > // Send Activate method call > // > - ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), > &ParseStruct, MethodStatus)); > + ERROR_CHECK(OpalPerformMethod(AdminSpSession, Size, Buf, sizeof(Buf), > &ParseStruct, 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), > &ParseStruct, MethodStatus)); > + ERROR_CHECK(OpalPerformMethod(Session, Size, Buf, sizeof(Buf), > &ParseStruct, MethodStatus, 0)); > // exit with success on method failure - user must inspect MethodStatu= s > 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_Locking_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))); >=20 > ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSes > sion, &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. > @@ -922,7 +1165,7 @@ OpalSetLockingSpAuthorityEnabledAndPin( > OPAL_LOCKING_SP_ADMINS_AUTHORITY > )); >=20 > - ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Bu= f), > &ParseStruct, MethodStatus)); > + ERROR_CHECK(OpalPerformMethod(LockingSpSession, Size, Buf, sizeof(Bu= f), > &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_GLOBALRANGE_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 ge= nerate > // >=20 > ERROR_CHECK(OpalCreateRetrieveGlobalLockingRangeActiveKey(LockingSpSes > sion, &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 MethodStatu= s > 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 fea= ture data. > + // so here try to get data from pyrite 2.0 feature data first. > + // > Size =3D 0; > Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature > (DiscoveryHeader, 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 > (DiscoveryHeader, TCG_FEATURE_PYRITE_SSC_V2_0_0, &Size2); > + if (Feat2 !=3D NULL && Size2 >=3D sizeof (PYRITE_SSCV2_FEATURE_DESCRIP= TOR)) > { > + SupportedAttributes->PyriteSscV2 =3D TRUE; > 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.CPINSIDPINRevertBehavior =3D=3D 0); > - DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d > CpinUponRevert %d \n", > + *OpalBaseComId =3D SwapBytes16 (Feat2->PyriteSscV2.BaseComdIdBE); > + SupportedAttributes->InitCpinIndicator =3D (Feat2- > >PyriteSscV2.InitialCPINSIDPIN =3D=3D 0); > + SupportedAttributes->CpinUponRevert =3D (Feat2- > >PyriteSscV2.CPINSIDPINRevertBehavior =3D=3D 0); > + DEBUG ((DEBUG_INFO, "Pyrite SSC V2 InitCpinIndicator %d > CpinUponRevert %d \n", > SupportedAttributes->InitCpinIndicator, > SupportedAttributes->CpinUponRevert > )); > } > + } else { > + SupportedAttributes->PyriteSsc =3D (Feat !=3D NULL); > + if (Feat !=3D NULL && Size >=3D sizeof (PYRITE_SSC_FEATURE_DESCRIPTO= R)) { > + if (*OpalBaseComId =3D=3D TCG_RESERVED_COMID) { > + *OpalBaseComId =3D SwapBytes16 (Feat->PyriteSsc.BaseComdIdBE); > + SupportedAttributes->InitCpinIndicator =3D (Feat- > >PyriteSsc.InitialCPINSIDPIN =3D=3D 0); > + SupportedAttributes->CpinUponRevert =3D (Feat- > >PyriteSsc.CPINSIDPINRevertBehavior =3D=3D 0); > + DEBUG ((DEBUG_INFO, "Pyrite SSC InitCpinIndicator %d > CpinUponRevert %d \n", > + SupportedAttributes->InitCpinIndicator, > + SupportedAttributes->CpinUponRevert > + )); > + } > + } > } >=20 > Size =3D 0; > @@ -1519,16 +1783,33 @@ OpalGetSupportedAttributesInfo( > Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature > (DiscoveryHeader, TCG_FEATURE_LOCKING, &Size); > if (Feat !=3D NULL && Size >=3D sizeof (TCG_LOCKING_FEATURE_DESCRIPTOR= )) { > SupportedAttributes->MediaEncryption =3D Feat->Locking.MediaEncrypti= on; > + DEBUG ((DEBUG_INFO, "SupportedAttributes->MediaEncryption 0x%X \n", > SupportedAttributes->MediaEncryption)); > } >=20 > Size =3D 0; > Feat =3D (OPAL_LEVEL0_FEATURE_DESCRIPTOR*) TcgGetFeature > (DiscoveryHeader, TCG_FEATURE_BLOCK_SID, &Size); > if (Feat !=3D NULL && Size >=3D sizeof (TCG_BLOCK_SID_FEATURE_DESCRIPT= OR)) > { > 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 > (DiscoveryHeader, TCG_FEATURE_DATA_REMOVAL, &Size); > + if (Feat !=3D NULL && Size >=3D sizeof (DATA_REMOVAL_FEATURE_DESCRIPTO= R)) > { > + SupportedAttributes->DataRemoval =3D TRUE; > + DEBUG ((DEBUG_INFO, "DataRemoval Feature Supported!\n")); > + DEBUG ((DEBUG_INFO, "Operation Processing =3D 0x%x\n", Feat- > >DataRemoval.OperationProcessing)); > + DEBUG ((DEBUG_INFO, "RemovalMechanism =3D 0x%x\n", Feat- > >DataRemoval.RemovalMechanism)); > + 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= _SP > 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 f= eature > 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 > (DiscoveryHeader, 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= Opal > 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/TcgStorageOpalLibInter= nal.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 BS= D > License > +which accompanies this distribution. The full text of the license may b= e 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 IMPLIED. > + > +**/ > + > +#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 that 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= _SP > 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 f= eature > 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= opal 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 OPAL_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 > KeepUserData is True, then the optional parameter > + to keep the user Data is set to True, otherwise the optional parameter= is not > provided. > + > + @param[in] LockingSpSession OPAL_SESSION with > OPAL_UID_LOCKING_SP as OPAL_LOCKING_SP_ADMIN1_AUTHORITY to > revertSP > + @param[in] KeepUserData Specifies whether or not to keep u= ser > Data when performing RevertSP action. True =3D keeps user Data. > + @param[in/out] MethodStatus Method status of last action perfo= rmed. > 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/SecurityPkg/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 BS= D > License > which accompanies this distribution. The full text of the license may b= e 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", > RemovalTimeOut)); > + > 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= only 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", > RemovalTimeOut)); > + > 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, > RemovalTimeOut); > if (Ret !=3D TcgResultSuccess || MethodStatus !=3D > TCG_METHOD_STATUS_CODE_SUCCESS) { > // > // Device ends the session on successful revert, so only call OpalEn= dSession > when fail. > @@ -912,3 +922,201 @@ OpalUtilAdminPasswordExists( > return (OwnerShip =3D=3D OpalOwnershipUnknown && LockingFeature- > >LockingEnabled); > } >=20 > +/** > + Get Active Data Removal Mechanism Value. > + > + @param[in] Session The session info for on= e opal device. > + @param[in] GeneratedSid Generated SID of disk > + @param[in] SidLength Length of generatedSid = in bytes > + @param[out] ActiveDataRemovalMechanism Return the active data > removal 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_CODE_SUCCESS) { > + DEBUG ((DEBUG_INFO, "Start session with admin SP as SID authority fa= iled: > 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= minute > 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 on= e opal device. > + @param[out] RemovalMechanismLists Return the supported da= ta > 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, > &DataSize, &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, > Index, Index); > + > + if (BitValue =3D=3D 0) { > + RemovalMechanismLists[Index] =3D 0; > + } else { > + RemovalMechanismLists[Index] =3D GetDataRemovalTime (Index, > &Descriptor); > + } > + } > + > + return TcgResultSuccess; > +} > + > +/** > + Get revert timeout value. > + > + @param[in] Session The session info for one= opal 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, &SupportedAttri= butes, > &BaseComId); > + if (TcgResult !=3D TcgResultSuccess || SupportedAttributes.DataRemoval= =3D=3D 0) > { > + return 0; > + } > + > + TcgResult =3D OpalUtilGetMsid (Session, Msid, OPAL_MSID_LENGHT, > &MsidLength); > + if (TcgResult !=3D TcgResultSuccess) { > + return 0; > + } > + > + TcgResult =3D OpalUtilGetDataRemovalMechanismLists (Session, > RemovalMechanishLists); > + if (TcgResult !=3D TcgResultSuccess) { > + return 0; > + } > + > + TcgResult =3D OpalUtilGetActiveDataRemovalMechanism (Session, Msid, > MsidLength, &ActiveDataRemovalMechanism); > + if (TcgResult !=3D TcgResultSuccess) { > + return 0; > + } > + > + return RemovalMechanishLists[ActiveDataRemovalMechanism]; > +} > -- > 2.15.0.windows.1