From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.136; helo=mga12.intel.com; envelope-from=hao.a.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 3C14E208D613B for ; Mon, 18 Feb 2019 18:52:26 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Feb 2019 18:52:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,385,1544515200"; d="scan'208";a="127484208" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by orsmga003.jf.intel.com with ESMTP; 18 Feb 2019 18:52:24 -0800 Received: from fmsmsx121.amr.corp.intel.com (10.18.125.36) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 18 Feb 2019 18:52:24 -0800 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx121.amr.corp.intel.com (10.18.125.36) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 18 Feb 2019 18:52:23 -0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.102]) by shsmsx102.ccr.corp.intel.com ([169.254.2.207]) with mapi id 14.03.0415.000; Tue, 19 Feb 2019 10:52:20 +0800 From: "Wu, Hao A" To: "Dong, Eric" , "edk2-devel@lists.01.org" CC: "Ni, Ray" , "Zhang, Chao B" , "Yao, Jiewen" Thread-Topic: [PATCH v1 1/1] SecurityPkg/HddPassword: Add Security feature set support for ATA dev Thread-Index: AQHUxNkaztKPwV+7LkOc2d+sPRSxkaXkrKeAgAHFaaA= Date: Tue, 19 Feb 2019 02:52:19 +0000 Message-ID: References: <20190215024911.7704-1-hao.a.wu@intel.com> <20190215024911.7704-2-hao.a.wu@intel.com> In-Reply-To: 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 v1 1/1] SecurityPkg/HddPassword: Add Security feature set support for ATA dev X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Feb 2019 02:52:26 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: Dong, Eric > Sent: Monday, February 18, 2019 3:48 PM > To: Wu, Hao A; edk2-devel@lists.01.org > Cc: Ni, Ray; Zhang, Chao B; Yao, Jiewen > Subject: RE: [PATCH v1 1/1] SecurityPkg/HddPassword: Add Security feature > set support for ATA dev >=20 > Hi Hao, >=20 > Only minor change request, remove below useless zero memory action. > ZeroMem (S3InitDevices, S3InitDevicesLength); Thanks Eric, I will also remove the line: ZeroMem (S3InitDevicesBak, GetDevicePathSize (S3InitDevicesBak)); which similarly clears the device path information in memory. Best Regards, Hao Wu >=20 > With this change, Reviewed-by: Eric Dong >=20 > Thanks, > Eric > > -----Original Message----- > > From: Wu, Hao A > > Sent: Friday, February 15, 2019 10:49 AM > > To: edk2-devel@lists.01.org > > Cc: Wu, Hao A ; Dong, Eric ; > Ni, > > Ray ; Zhang, Chao B ; Yao, > > Jiewen > > Subject: [PATCH v1 1/1] SecurityPkg/HddPassword: Add Security feature > set > > support for ATA dev > > > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1529 > > > > This commit will add the 'Security feature set' support for ATA devices= . > > > > According to the AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS) > > specification, the Security feature set is an optional feature. In > > summary, the feature is a password system that restricts access to user > > data stored on an ATA device. A more detailed introduction of this feat= ure > > can be referred from the ATA8-ACS spec. > > > > The HddPassword driver is composed of 2 parts: > > * A DXE driver and > > * A PEI driver > > > > The DXE driver consumes EFI_ATA_PASS_THRU_PROTOCOL instances and > > installs > > an HII GUI to manage the devices. If the managing device supports Secur= ity > > feature set, the HII page will provide the user with the ability to > > set/update/disable the password for this device. Also, if a password is > > being set via the Security feature set, a popup window will show during > > boot requesting the user to input password. > > > > Another feature supported by this driver is that for those managing > > devices with password set, they will be automatically unlocked during t= he > > S3 resume. This is done by the co-work of the DXE driver and the PEI > > driver: > > > > The DXE driver will save the password and the identication information = for > > these devices into a LockBox, which is only allowed to restore during S= 3 > > resume. > > > > The PEI driver, during S3 resume, will restore the content in the LockB= ox > > and will consume EDKII_PEI_ATA_PASS_THRU_PPI instances to unlock > > devices. > > > > Cc: Eric Dong > > Cc: Ray Ni > > Cc: Chao Zhang > > Cc: Jiewen Yao > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Hao Wu > > --- > > SecurityPkg/SecurityPkg.dsc | 6 + > > SecurityPkg/HddPassword/HddPasswordDxe.inf | 75 + > > SecurityPkg/HddPassword/HddPasswordPei.inf | 54 + > > SecurityPkg/HddPassword/HddPasswordCommon.h | 61 + > > SecurityPkg/HddPassword/HddPasswordDxe.h | 148 + > > SecurityPkg/HddPassword/HddPasswordHiiDataStruc.h | 63 + > > SecurityPkg/HddPassword/HddPasswordPei.h | 64 + > > SecurityPkg/HddPassword/HddPassword.vfr | 188 ++ > > SecurityPkg/HddPassword/HddPasswordDxe.c | 2816 > > ++++++++++++++++++++ > > SecurityPkg/HddPassword/HddPasswordPei.c | 461 ++++ > > SecurityPkg/HddPassword/HddPasswordStrings.uni | 48 + > > 11 files changed, 3984 insertions(+) > > > > diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc > > index ab887e8c4d..5577ff0687 100644 > > --- a/SecurityPkg/SecurityPkg.dsc > > +++ b/SecurityPkg/SecurityPkg.dsc > > @@ -287,6 +287,12 @@ > > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordDxe.inf > > SecurityPkg/Tcg/Opal/OpalPassword/OpalPasswordPei.inf > > > > + # > > + # HDD Password solution > > + # > > + SecurityPkg/HddPassword/HddPasswordDxe.inf > > + SecurityPkg/HddPassword/HddPasswordPei.inf > > + > > [BuildOptions] > > MSFT:*_*_IA32_DLINK_FLAGS =3D /ALIGN:256 > > INTEL:*_*_IA32_DLINK_FLAGS =3D /ALIGN:256 > > diff --git a/SecurityPkg/HddPassword/HddPasswordDxe.inf > > b/SecurityPkg/HddPassword/HddPasswordDxe.inf > > new file mode 100644 > > index 0000000000..7a3fc2f88c > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordDxe.inf > > @@ -0,0 +1,75 @@ > > +## @file > > +# HddPasswordDxe driver which is used to set/clear hdd password at > > attached harddisk > > +# devices. > > +# > > +# Copyright (c) 2019, Intel Corporation. All rights reserved.
> > +# > > +# This program and the accompanying materials > > +# are licensed and made available under the terms and conditions of t= he > > 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 IMPLIED. > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x00010005 > > + BASE_NAME =3D HddPasswordDxe > > + FILE_GUID =3D 9BD549CD-86D1-4925-9F7D-3686DDD87= 6FC > > + MODULE_TYPE =3D DXE_DRIVER > > + VERSION_STRING =3D 1.0 > > + ENTRY_POINT =3D HddPasswordDxeInit > > + > > +# > > +# The following information is for reference only and not required by = the > > build tools. > > +# > > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > > +# > > + > > +[Sources] > > + HddPasswordDxe.c > > + HddPasswordDxe.h > > + HddPasswordHiiDataStruc.h > > + HddPassword.vfr > > + HddPasswordStrings.uni > > + HddPasswordCommon.h > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + CryptoPkg/CryptoPkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + MemoryAllocationLib > > + UefiBootServicesTableLib > > + UefiDriverEntryPoint > > + UefiHiiServicesLib > > + UefiRuntimeServicesTableLib > > + DxeServicesTableLib > > + BaseMemoryLib > > + DebugLib > > + HiiLib > > + PrintLib > > + UefiLib > > + LockBoxLib > > + S3BootScriptLib > > + PciLib > > + BaseCryptLib > > + > > +[Guids] > > + gEfiIfrTianoGuid ## CONSUMES ## GUID > > + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event > > + gS3StorageDeviceInitListGuid ## SOMETIMES_PRODUCES = ## > > UNDEFINED > > + > > +[Protocols] > > + gEfiHiiConfigAccessProtocolGuid ## PRODUCES > > + gEfiAtaPassThruProtocolGuid ## CONSUMES > > + gEfiPciIoProtocolGuid ## CONSUMES > > + gEdkiiVariableLockProtocolGuid ## CONSUMES > > + > > +[Depex] > > + gEfiVariableWriteArchProtocolGuid > > + > > diff --git a/SecurityPkg/HddPassword/HddPasswordPei.inf > > b/SecurityPkg/HddPassword/HddPasswordPei.inf > > new file mode 100644 > > index 0000000000..d240cc1d07 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordPei.inf > > @@ -0,0 +1,54 @@ > > +## @file > > +# HddPassword PEI module which is used to unlock HDD password for S3. > > +# > > +# Copyright (c) 2019, Intel Corporation. All rights reserved.
> > +# > > +# This program and the accompanying materials > > +# are licensed and made available under the terms and conditions of t= he > > 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 IMPLIED. > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x00010005 > > + BASE_NAME =3D HddPasswordPei > > + FILE_GUID =3D 91AD7375-8E8E-49D2-A343-68BC78273= 955 > > + MODULE_TYPE =3D PEIM > > + VERSION_STRING =3D 1.0 > > + ENTRY_POINT =3D HddPasswordPeiInit > > + > > +# > > +# The following information is for reference only and not required by = the > > build tools. > > +# > > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > > +# > > + > > +[Sources] > > + HddPasswordPei.c > > + HddPasswordPei.h > > + HddPasswordCommon.h > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + > > +[LibraryClasses] > > + PeimEntryPoint > > + PeiServicesLib > > + DebugLib > > + BaseLib > > + BaseMemoryLib > > + MemoryAllocationLib > > + PciLib > > + LockBoxLib > > + > > +[Ppis] > > + gEdkiiPeiAtaPassThruPpiGuid ## NOTIFY > > + > > +[Depex] > > + gEfiPeiMasterBootModePpiGuid > > + > > diff --git a/SecurityPkg/HddPassword/HddPasswordCommon.h > > b/SecurityPkg/HddPassword/HddPasswordCommon.h > > new file mode 100644 > > index 0000000000..b904b7d39e > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordCommon.h > > @@ -0,0 +1,61 @@ > > +/** @file > > + HDD Password common header file. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#ifndef _HDD_PASSWORD_COMMON_H_ > > +#define _HDD_PASSWORD_COMMON_H_ > > + > > +// > > +// The payload length of HDD related ATA commands > > +// > > +#define HDD_PAYLOAD 512 > > + > > +#define ATA_SECURITY_SET_PASSWORD_CMD 0xF1 > > +#define ATA_SECURITY_UNLOCK_CMD 0xF2 > > +#define ATA_SECURITY_FREEZE_LOCK_CMD 0xF5 > > +#define ATA_SECURITY_DIS_PASSWORD_CMD 0xF6 > > + > > +// > > +// The max retry count specified in ATA 8 spec. > > +// > > +#define MAX_HDD_PASSWORD_RETRY_COUNT 5 > > + > > +// > > +// According to ATA spec, the max length of hdd password is 32 bytes > > +// > > +#define HDD_PASSWORD_MAX_LENGTH 32 > > + > > +#define HDD_PASSWORD_DEVICE_INFO_GUID { 0x96d877ad, 0x48af, > > 0x4b39, { 0x9b, 0x27, 0x4d, 0x97, 0x43, 0x9, 0xae, 0x47 } } > > + > > +typedef struct { > > + UINT8 Bus; > > + UINT8 Device; > > + UINT8 Function; > > + UINT8 Reserved; > > + UINT16 Port; > > + UINT16 PortMultiplierPort; > > +} HDD_PASSWORD_DEVICE; > > + > > +// > > +// It will be used to unlock HDD password for S3. > > +// > > +typedef struct { > > + HDD_PASSWORD_DEVICE Device; > > + CHAR8 Password[HDD_PASSWORD_MAX_LENGTH]; > > + UINT32 DevicePathLength; > > + EFI_DEVICE_PATH_PROTOCOL DevicePath[]; > > +} HDD_PASSWORD_DEVICE_INFO; > > + > > +#endif // _HDD_PASSWORD_COMMON_H_ > > diff --git a/SecurityPkg/HddPassword/HddPasswordDxe.h > > b/SecurityPkg/HddPassword/HddPasswordDxe.h > > new file mode 100644 > > index 0000000000..41db0554d5 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordDxe.h > > @@ -0,0 +1,148 @@ > > +/** @file > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#ifndef _HDD_PASSWORD_DXE_H_ > > +#define _HDD_PASSWORD_DXE_H_ > > + > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "HddPasswordCommon.h" > > +#include "HddPasswordHiiDataStruc.h" > > + > > +// > > +// This is the generated IFR binary data for each formset defined in V= FR. > > +// This data array is ready to be used as input of HiiAddPackages() to > > +// create a packagelist (which contains Form packages, String packages= , > etc). > > +// > > +extern UINT8 HddPasswordBin[]; > > + > > +// > > +// This is the generated String package data for all .UNI files. > > +// This data array is ready to be used as input of HiiAddPackages() to > > +// create a packagelist (which contains Form packages, String packages= , > etc). > > +// > > +extern UINT8 HddPasswordDxeStrings[]; > > + > > +#define HDD_PASSWORD_DXE_PRIVATE_SIGNATURE SIGNATURE_32 ('H', > > 'D', 'D', 'P') > > + > > +typedef struct _HDD_PASSWORD_CONFIG_FORM_ENTRY { > > + LIST_ENTRY Link; > > + EFI_HANDLE Controller; > > + UINTN Bus; > > + UINTN Device; > > + UINTN Function; > > + UINT16 Port; > > + UINT16 PortMultiplierPort; > > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > > + CHAR16 HddString[64]; > > + CHAR8 Password[HDD_PASSWORD_MAX_LENGTH]; > > + EFI_STRING_ID TitleToken; > > + EFI_STRING_ID TitleHelpToken; > > + > > + HDD_PASSWORD_CONFIG IfrData; > > + EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru; > > +} HDD_PASSWORD_CONFIG_FORM_ENTRY; > > + > > +typedef struct _HDD_PASSWORD_DXE_PRIVATE_DATA { > > + UINTN Signature; > > + EFI_HANDLE DriverHandle; > > + EFI_HII_HANDLE HiiHandle; > > + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *Current; > > +} HDD_PASSWORD_DXE_PRIVATE_DATA; > > + > > +#define HDD_PASSWORD_DXE_PRIVATE_FROM_THIS(a) CR (a, > > HDD_PASSWORD_DXE_PRIVATE_DATA, ConfigAccess, > > HDD_PASSWORD_DXE_PRIVATE_SIGNATURE) > > + > > +// > > +//Iterate through the doule linked list. NOT delete safe > > +// > > +#define EFI_LIST_FOR_EACH(Entry, ListHead) \ > > + for (Entry =3D (ListHead)->ForwardLink; Entry !=3D (ListHead); Entry= =3D Entry- > > >ForwardLink) > > + > > +#define PASSWORD_SALT_SIZE 32 > > + > > +#define HDD_PASSWORD_REQUEST_VARIABLE_NAME > > L"HddPasswordRequest" > > + > > +// > > +// It needs to be locked before EndOfDxe. > > +// > > +#define HDD_PASSWORD_VARIABLE_NAME L"HddPassword" > > + > > +#pragma pack(1) > > + > > +typedef struct { > > + HDD_PASSWORD_DEVICE Device; > > + HDD_PASSWORD_REQUEST Request; > > +} HDD_PASSWORD_REQUEST_VARIABLE; > > + > > +// > > +// It will be used to validate HDD password when the device is at froz= en > > state. > > +// > > +typedef struct { > > + HDD_PASSWORD_DEVICE Device; > > + UINT8 PasswordHash[SHA256_DIGEST_SIZE]; > > + UINT8 PasswordSalt[PASSWORD_SALT_SIZE]; > > +} HDD_PASSWORD_VARIABLE; > > + > > +/// > > +/// HII specific Vendor Device Path definition. > > +/// > > +typedef struct { > > + VENDOR_DEVICE_PATH VendorDevicePath; > > + EFI_DEVICE_PATH_PROTOCOL End; > > +} HII_VENDOR_DEVICE_PATH; > > + > > +#pragma pack() > > + > > +// > > +// Time out value for ATA pass through protocol > > +// > > +#define ATA_TIMEOUT EFI_TIMER_PERIOD_SECONDS (3) > > + > > +typedef struct { > > + UINT32 Address; > > + S3_BOOT_SCRIPT_LIB_WIDTH Width; > > +} HDD_HC_PCI_REGISTER_SAVE; > > + > > +#endif > > diff --git a/SecurityPkg/HddPassword/HddPasswordHiiDataStruc.h > > b/SecurityPkg/HddPassword/HddPasswordHiiDataStruc.h > > new file mode 100644 > > index 0000000000..608b92d797 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordHiiDataStruc.h > > @@ -0,0 +1,63 @@ > > +/** @file > > + HddPassword HII data structure used by the driver. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#ifndef _HDD_PASSWORD_HII_DATASTRUC_H_ > > +#define _HDD_PASSWORD_HII_DATASTRUC_H_ > > + > > +#include > > + > > +#define HDD_PASSWORD_CONFIG_GUID \ > > + { \ > > + 0x737cded7, 0x448b, 0x4801, { 0xb5, 0x7d, 0xb1, 0x94, 0x83, 0xec, = 0x60, > > 0x6f } \ > > + } > > + > > +#define FORMID_HDD_MAIN_FORM 1 > > +#define FORMID_HDD_DEVICE_FORM 2 > > + > > +#define HDD_DEVICE_ENTRY_LABEL 0x1234 > > +#define HDD_DEVICE_LABEL_END 0xffff > > + > > +#define KEY_HDD_DEVICE_ENTRY_BASE 0x1000 > > + > > +#define KEY_HDD_USER_PASSWORD 0x101 > > +#define KEY_HDD_MASTER_PASSWORD 0x102 > > + > > +#pragma pack(1) > > + > > +typedef struct { > > + UINT8 Supported:1; > > + UINT8 Enabled:1; > > + UINT8 Locked:1; > > + UINT8 Frozen:1; > > + UINT8 UserPasswordStatus:1; > > + UINT8 MasterPasswordStatus:1; > > + UINT8 Reserved:2; > > +} HDD_PASSWORD_SECURITY_STATUS; > > + > > +typedef struct { > > + UINT8 UserPassword:1; > > + UINT8 MasterPassword:1; > > + UINT8 Reserved:6; > > +} HDD_PASSWORD_REQUEST; > > + > > +typedef struct _HDD_PASSWORD_CONFIG { > > + HDD_PASSWORD_SECURITY_STATUS SecurityStatus; > > + HDD_PASSWORD_REQUEST Request; > > +} HDD_PASSWORD_CONFIG; > > + > > +#pragma pack() > > + > > +#endif > > diff --git a/SecurityPkg/HddPassword/HddPasswordPei.h > > b/SecurityPkg/HddPassword/HddPasswordPei.h > > new file mode 100644 > > index 0000000000..be5402ecfc > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordPei.h > > @@ -0,0 +1,64 @@ > > +/** @file > > + HddPassword PEI module which is used to unlock HDD password for S3. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#ifndef _HDD_PASSWORD_PEI_H_ > > +#define _HDD_PASSWORD_PEI_H_ > > + > > +#include > > +#include > > +//#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > + > > +#include "HddPasswordCommon.h" > > + > > +// > > +// The maximum number of ATA PassThru PPI instances supported by the > > driver > > +// > > +#define MAX_ATA_PASSTHRU_PPI 32 > > + > > +// > > +// Time out value for ATA PassThru PPI > > +// > > +#define ATA_TIMEOUT 30000000 > > + > > +// > > +// Private data structure for HddPassword PEI driver > > +// > > +#define HDD_PASSWORD_PEI_DRIVER_SIGNATURE SIGNATURE_32 ('h', > > 'd', 'r', 'i') > > + > > +typedef struct { > > + UINTN Signature; > > + EFI_PEI_NOTIFY_DESCRIPTOR AtaPassThruPpiNotifyList; > > + > > + UINTN AtaPassThruPpiInstanceNum; > > + UINTN AtaPassThruPpiInstances[MAX_ATA_PASSTHR= U_PPI]; > > +} HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA; > > + > > +#define HDD_PASSWORD_PEI_PRIVATE_DATA_FROM_THIS_NOTIFY(a) > \ > > + CR (a, HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA, > > AtaPassThruPpiNotifyList, HDD_PASSWORD_PEI_DRIVER_SIGNATURE) > > + > > +#endif > > + > > diff --git a/SecurityPkg/HddPassword/HddPassword.vfr > > b/SecurityPkg/HddPassword/HddPassword.vfr > > new file mode 100644 > > index 0000000000..2cd39523c7 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPassword.vfr > > @@ -0,0 +1,188 @@ > > +/** @file > > + HDD Password Configuration Formset. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > +**/ > > + > > +#include "HddPasswordHiiDataStruc.h" > > + > > +formset > > + guid =3D HDD_PASSWORD_CONFIG_GUID, > > + title =3D STRING_TOKEN(STR_HDD_SECURITY_CONFIG), > > + help =3D STRING_TOKEN(STR_HDD_SECURITY_CONFIG), > > + classguid =3D EFI_HII_PLATFORM_SETUP_FORMSET_GUID, > > + > > + varstore HDD_PASSWORD_CONFIG, > > + name =3D HDD_PASSWORD_CONFIG, > > + guid =3D HDD_PASSWORD_CONFIG_GUID; > > + > > + form formid =3D FORMID_HDD_MAIN_FORM, > > + title =3D STRING_TOKEN(STR_HDD_SECURITY_CONFIG); > > + > > + label HDD_DEVICE_ENTRY_LABEL; > > + label HDD_DEVICE_LABEL_END; > > + > > + endform; > > + > > + form > > + formid =3D FORMID_HDD_DEVICE_FORM, > > + title =3D STRING_TOKEN(STR_HDD_SECURITY_HD); > > + > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_PWD_DESC); > > + > > + subtitle text =3D STRING_TOKEN(STR_NULL); > > + > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_BANNER_ONE); > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_BANNER_TWO); > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_BANNER_THREE); > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_BANNER_FOUR); > > + subtitle text =3D STRING_TOKEN(STR_SECURITY_HDD_BANNER_FIVE); > > + > > + subtitle text =3D STRING_TOKEN(STR_NULL); > > + > > + subtitle text =3D STRING_TOKEN(STR_HDD_PASSWORD_CONFIG); > > + > > + subtitle text =3D STRING_TOKEN(STR_NULL); > > + > > + grayoutif TRUE; > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.Supported =3D=3D 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_SUPPORTED), > > + text =3D STRING_TOKEN(STR_YES), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.Supported =3D=3D 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_SUPPORTED), > > + text =3D STRING_TOKEN(STR_NO), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Enabled > > =3D=3D 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_ENABLED), > > + text =3D STRING_TOKEN(STR_YES), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Enabled > > =3D=3D 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_ENABLED), > > + text =3D STRING_TOKEN(STR_NO), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Locked > =3D=3D > > 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_LOCKED), > > + text =3D STRING_TOKEN(STR_YES), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Locked > =3D=3D > > 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_LOCKED), > > + text =3D STRING_TOKEN(STR_NO), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Frozen > =3D=3D > > 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_FROZEN), > > + text =3D STRING_TOKEN(STR_YES), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist HDD_PASSWORD_CONFIG.SecurityStatus.Frozen > =3D=3D > > 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_SEC_FROZEN), > > + text =3D STRING_TOKEN(STR_NO), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.UserPasswordStatus =3D=3D 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_HDD_USER_PASSWORD_STS), > > + text =3D STRING_TOKEN(STR_INSTALLED), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.UserPasswordStatus =3D=3D 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_HDD_USER_PASSWORD_STS), > > + text =3D STRING_TOKEN(STR_NOT_INSTALLED), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.MasterPasswordStatus =3D=3D 0; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_HDD_MASTER_PASSWORD_STS), > > + text =3D STRING_TOKEN(STR_INSTALLED), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + > > + suppressif ideqvallist > > HDD_PASSWORD_CONFIG.SecurityStatus.MasterPasswordStatus =3D=3D 1; > > + text > > + help =3D STRING_TOKEN(STR_EMPTY), > > + text =3D STRING_TOKEN(STR_HDD_MASTER_PASSWORD_STS), > > + text =3D STRING_TOKEN(STR_NOT_INSTALLED), > > + flags =3D 0, > > + key =3D 0; > > + endif; > > + endif; > > + > > + subtitle text =3D STRING_TOKEN(STR_NULL); > > + > > + grayoutif ideqval HDD_PASSWORD_CONFIG.SecurityStatus.Supported > =3D=3D > > 0; > > + checkbox varid =3D HDD_PASSWORD_CONFIG.Request.UserPassword, > > + prompt =3D STRING_TOKEN(STR_HDD_USER_PASSWORD), > > + help =3D STRING_TOKEN(STR_HDD_USER_PASSWORD_HELP), > > + flags =3D INTERACTIVE | RESET_REQUIRED, > > + key =3D KEY_HDD_USER_PASSWORD, > > + endcheckbox; > > + endif; > > + > > + grayoutif ideqval HDD_PASSWORD_CONFIG.SecurityStatus.Supported > =3D=3D > > 0; > > + checkbox varid =3D HDD_PASSWORD_CONFIG.Request.MasterPassword, > > + prompt =3D STRING_TOKEN(STR_HDD_MASTER_PASSWORD), > > + help =3D STRING_TOKEN(STR_HDD_MASTER_PASSWORD_HELP)= , > > + flags =3D INTERACTIVE | RESET_REQUIRED, > > + key =3D KEY_HDD_MASTER_PASSWORD, > > + endcheckbox; > > + endif; > > + endform; > > + > > +endformset; > > diff --git a/SecurityPkg/HddPassword/HddPasswordDxe.c > > b/SecurityPkg/HddPassword/HddPasswordDxe.c > > new file mode 100644 > > index 0000000000..c8198f9c78 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordDxe.c > > @@ -0,0 +1,2816 @@ > > +/** @file > > + HDD password driver which is used to support HDD security feature. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#include "HddPasswordDxe.h" > > + > > +EFI_GUID mHddPasswordVendorGuid =3D > > HDD_PASSWORD_CONFIG_GUID; > > +CHAR16 mHddPasswordVendorStorageName[] =3D > > L"HDD_PASSWORD_CONFIG"; > > +LIST_ENTRY mHddPasswordConfigFormList; > > +UINT32 mNumberOfHddDevices =3D 0; > > + > > +EFI_GUID mHddPasswordDeviceInfoGuid =3D > > HDD_PASSWORD_DEVICE_INFO_GUID; > > +BOOLEAN mHddPasswordEndOfDxe =3D FALSE; > > +HDD_PASSWORD_REQUEST_VARIABLE > *mHddPasswordRequestVariable > > =3D NULL; > > +UINTN mHddPasswordRequestVariableSize =3D 0; > > + > > +HII_VENDOR_DEVICE_PATH mHddPasswordHiiVendorDevicePath =3D { > > + { > > + { > > + HARDWARE_DEVICE_PATH, > > + HW_VENDOR_DP, > > + { > > + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), > > + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) > > + } > > + }, > > + HDD_PASSWORD_CONFIG_GUID > > + }, > > + { > > + END_DEVICE_PATH_TYPE, > > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > > + { > > + (UINT8) (END_DEVICE_PATH_LENGTH), > > + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) > > + } > > + } > > +}; > > + > > + > > +/** > > + Check if the password is full zero. > > + > > + @param[in] Password Points to the data buffer > > + > > + @retval TRUE This password string is full zero. > > + @retval FALSE This password string is not full zero. > > + > > +**/ > > +BOOLEAN > > +PasswordIsFullZero ( > > + IN CHAR8 *Password > > + ) > > +{ > > + UINTN Index; > > + > > + for (Index =3D 0; Index < HDD_PASSWORD_MAX_LENGTH; Index++) { > > + if (Password[Index] !=3D 0) { > > + return FALSE; > > + } > > + } > > + > > + return TRUE; > > +} > > + > > +/** > > + Save device info. > > + > > + @param[in] ConfigFormEntry Points to > > HDD_PASSWORD_CONFIG_FORM_ENTRY buffer > > + @param[in,out] TempDevInfo Points to > > HDD_PASSWORD_DEVICE_INFO buffer > > + > > +**/ > > +VOID > > +SaveDeviceInfo ( > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, > > + IN OUT HDD_PASSWORD_DEVICE_INFO *TempDevInfo > > + ) > > +{ > > + TempDevInfo->Device.Bus =3D (UINT8) ConfigFormEntry->= Bus; > > + TempDevInfo->Device.Device =3D (UINT8) ConfigFormEntry->= Device; > > + TempDevInfo->Device.Function =3D (UINT8) ConfigFormEntry- > > >Function; > > + TempDevInfo->Device.Port =3D ConfigFormEntry->Port; > > + TempDevInfo->Device.PortMultiplierPort =3D ConfigFormEntry- > > >PortMultiplierPort; > > + CopyMem (TempDevInfo->Password, ConfigFormEntry->Password, > > HDD_PASSWORD_MAX_LENGTH); > > + TempDevInfo->DevicePathLength =3D (UINT32) GetDevicePathSiz= e > > (ConfigFormEntry->DevicePath); > > + CopyMem (TempDevInfo->DevicePath, ConfigFormEntry->DevicePath, > > TempDevInfo->DevicePathLength); > > +} > > + > > +/** > > + Build HDD password device info and save them to LockBox. > > + > > + **/ > > +VOID > > +BuildHddPasswordDeviceInfo ( > > + VOID > > + ) > > +{ > > + EFI_STATUS Status; > > + LIST_ENTRY *Entry; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry; > > + HDD_PASSWORD_DEVICE_INFO *DevInfo; > > + HDD_PASSWORD_DEVICE_INFO *TempDevInfo; > > + UINTN DevInfoLength; > > + UINT8 DummyData; > > + BOOLEAN S3InitDevicesExist; > > + UINTN S3InitDevicesLength; > > + EFI_DEVICE_PATH_PROTOCOL *S3InitDevices; > > + EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak; > > + > > + // > > + // Build HDD password device info and save them to LockBox. > > + // > > + DevInfoLength =3D 0; > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + > > + // > > + // 1. Handle device which already set password. > > + // 2. When request to send freeze comamnd, driver also needs to > handle > > device > > + // which support security feature. > > + // > > + if ((!PasswordIsFullZero (ConfigFormEntry->Password)) || > > + ((ConfigFormEntry->IfrData.SecurityStatus.Supported !=3D 0) && > > + (ConfigFormEntry->IfrData.SecurityStatus.Enabled =3D=3D 0))) = { > > + DevInfoLength +=3D sizeof (HDD_PASSWORD_DEVICE_INFO) + > > + GetDevicePathSize (ConfigFormEntry->DevicePath)= ; > > + } > > + } > > + > > + if (DevInfoLength =3D=3D 0) { > > + return; > > + } > > + > > + S3InitDevicesLength =3D sizeof (DummyData); > > + Status =3D RestoreLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + &DummyData, > > + &S3InitDevicesLength > > + ); > > + ASSERT ((Status =3D=3D EFI_NOT_FOUND) || (Status =3D=3D > > EFI_BUFFER_TOO_SMALL)); > > + if (Status =3D=3D EFI_NOT_FOUND) { > > + S3InitDevices =3D NULL; > > + S3InitDevicesExist =3D FALSE; > > + } else if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > > + S3InitDevices =3D AllocatePool (S3InitDevicesLength); > > + ASSERT (S3InitDevices !=3D NULL); > > + > > + Status =3D RestoreLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + S3InitDevices, > > + &S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + S3InitDevicesExist =3D TRUE; > > + } else { > > + return; > > + } > > + > > + DevInfo =3D AllocateZeroPool (DevInfoLength); > > + ASSERT (DevInfo !=3D NULL); > > + > > + TempDevInfo =3D DevInfo; > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + > > + if ((!PasswordIsFullZero (ConfigFormEntry->Password)) || > > + ((ConfigFormEntry->IfrData.SecurityStatus.Supported !=3D 0) && > > + (ConfigFormEntry->IfrData.SecurityStatus.Enabled =3D=3D 0))) = { > > + SaveDeviceInfo (ConfigFormEntry, TempDevInfo); > > + > > + S3InitDevicesBak =3D S3InitDevices; > > + S3InitDevices =3D AppendDevicePathInstance ( > > + S3InitDevicesBak, > > + ConfigFormEntry->DevicePath > > + ); > > + if (S3InitDevicesBak !=3D NULL) { > > + ZeroMem (S3InitDevicesBak, GetDevicePathSize (S3InitDevicesBak= )); > > + FreePool (S3InitDevicesBak); > > + } > > + ASSERT (S3InitDevices !=3D NULL); > > + > > + TempDevInfo =3D (HDD_PASSWORD_DEVICE_INFO *) > > ((UINTN)TempDevInfo + > > + sizeof (HDD_PASSWORD= _DEVICE_INFO) + > > + TempDevInfo->DeviceP= athLength); > > + } > > + } > > + > > + Status =3D SaveLockBox ( > > + &mHddPasswordDeviceInfoGuid, > > + DevInfo, > > + DevInfoLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + Status =3D SetLockBoxAttributes ( > > + &mHddPasswordDeviceInfoGuid, > > + LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + S3InitDevicesLength =3D GetDevicePathSize (S3InitDevices); > > + if (S3InitDevicesExist) { > > + Status =3D UpdateLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + 0, > > + S3InitDevices, > > + S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } else { > > + Status =3D SaveLockBox ( > > + &gS3StorageDeviceInitListGuid, > > + S3InitDevices, > > + S3InitDevicesLength > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + Status =3D SetLockBoxAttributes ( > > + &gS3StorageDeviceInitListGuid, > > + LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } > > + > > + ZeroMem (DevInfo, DevInfoLength); > > + FreePool (DevInfo); > > + ZeroMem (S3InitDevices, S3InitDevicesLength); > > + FreePool (S3InitDevices); > > +} > > + > > +/** > > + Send freeze lock cmd through Ata Pass Thru Protocol. > > + > > + @param[in] AtaPassThru The pointer to the ATA_PASS_THRU > protocol. > > + @param[in] Port The port number of the ATA device to = send the > > command. > > + @param[in] PortMultiplierPort The port multiplier port number of th= e > ATA > > device to send the command. > > + If there is no port multiplier, then = specify 0xFFFF. > > + > > + @retval EFI_SUCCESS Successful to send freeze lock cmd. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to send freeze > > lock cmd. > > + @retval EFI_DEVICE_ERROR Can not send freeze lock cmd. > > + > > +**/ > > +EFI_STATUS > > +FreezeLockDevice ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + > > + if (AtaPassThru =3D=3D NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_FREEZE_LOCK_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet, > > + NULL > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Get attached harddisk identify data through Ata Pass Thru Protocol. > > + > > + @param[in] AtaPassThru The pointer to the ATA_PASS_THRU > protocol. > > + @param[in] Port The port number of the ATA device to = send the > > command. > > + @param[in] PortMultiplierPort The port multiplier port number of th= e > ATA > > device to send the command. > > + If there is no port multiplier, then = specify 0xFFFF. > > + @param[in] IdentifyData The buffer to store identify data. > > + > > + @retval EFI_SUCCESS Successful to get identify data. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to get identify > > data. > > + @retval EFI_DEVICE_ERROR Can not get identify data. > > + > > +**/ > > +EFI_STATUS > > +GetHddDeviceIdentifyData ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN ATA_IDENTIFY_DATA *IdentifyData > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + > > + if ((AtaPassThru =3D=3D NULL) || (IdentifyData =3D=3D NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_CMD_IDENTIFY_DRIVE; > > + Acb.AtaDeviceHead =3D (UINT8) (BIT7 | BIT6 | BIT5 | (PortMultiplierP= ort =3D=3D > > 0xFFFF ? 0 : (PortMultiplierPort << 4))); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_BYTES | > > EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + Packet.InDataBuffer =3D IdentifyData; > > + Packet.InTransferLength =3D sizeof (ATA_IDENTIFY_DATA); > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet, > > + NULL > > + ); > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + return Status; > > +} > > + > > +/** > > + Parse security status according to identify data. > > + > > + @param[in] IdentifyData The buffer to store identify data. > > + @param[in, out] IfrData IFR data to hold security status. > > + > > +**/ > > +VOID > > +GetHddPasswordSecurityStatus ( > > + IN ATA_IDENTIFY_DATA *IdentifyData, > > + IN OUT HDD_PASSWORD_CONFIG *IfrData > > + ) > > +{ > > + IfrData->SecurityStatus.Supported =3D (IdentifyData- > > >command_set_supported_82 & BIT1) ? 1 : 0; > > + IfrData->SecurityStatus.Enabled =3D (IdentifyData->security_status= & > BIT1) ? > > 1 : 0; > > + IfrData->SecurityStatus.Locked =3D (IdentifyData->security_status= & > BIT2) ? > > 1 : 0; > > + IfrData->SecurityStatus.Frozen =3D (IdentifyData->security_status= & > BIT3) ? > > 1 : 0; > > + IfrData->SecurityStatus.UserPasswordStatus =3D IfrData- > > >SecurityStatus.Enabled; > > + IfrData->SecurityStatus.MasterPasswordStatus =3D IfrData- > > >SecurityStatus.Supported; > > + > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Supported > =3D %x\n", > > IfrData->SecurityStatus.Supported)); > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Enabled = =3D %x\n", > > IfrData->SecurityStatus.Enabled)); > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Locked = =3D %x\n", > > IfrData->SecurityStatus.Locked)); > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Frozen = =3D %x\n", > > IfrData->SecurityStatus.Frozen)); > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.UserPasswordStatus > > =3D %x\n", IfrData->SecurityStatus.UserPasswordStatus)); > > + DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.MasterPasswordStatus > > =3D %x\n", IfrData->SecurityStatus.MasterPasswordStatus)); > > +} > > + > > +/** > > + Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event > > group. > > + > > + This is a notification function registered on > > EFI_END_OF_DXE_EVENT_GROUP_GUID event group. > > + > > + @param Event Event whose notification function is being invo= ked. > > + @param Context Pointer to the notification function's context. > > + > > +**/ > > +VOID > > +EFIAPI > > +HddPasswordEndOfDxeEventNotify ( > > + EFI_EVENT Event, > > + VOID *Context > > + ) > > +{ > > + LIST_ENTRY *Entry; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry; > > + EFI_STATUS Status; > > + ATA_IDENTIFY_DATA IdentifyData; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + mHddPasswordEndOfDxe =3D TRUE; > > + > > + if (mHddPasswordRequestVariable !=3D NULL) { > > + // > > + // Free the HDD password request variable buffer here > > + // as the HDD password requests should have been processed. > > + // > > + FreePool (mHddPasswordRequestVariable); > > + mHddPasswordRequestVariable =3D NULL; > > + mHddPasswordRequestVariableSize =3D 0; > > + } > > + > > + // > > + // If no any device, return directly. > > + // > > + if (IsListEmpty (&mHddPasswordConfigFormList)) { > > + gBS->CloseEvent (Event); > > + return; > > + } > > + > > + BuildHddPasswordDeviceInfo (); > > + > > + // > > + // Zero passsword and freeze lock device. > > + // > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + > > + ZeroMem (ConfigFormEntry->Password, > > HDD_PASSWORD_MAX_LENGTH); > > + > > + // > > + // Check whether need send freeze lock command. > > + // Below device will be froze: > > + // 1. Device not enable password. > > + // 2. Device enable password and unlocked. > > + // > > + if ((ConfigFormEntry->IfrData.SecurityStatus.Supported !=3D 0) && > > + (ConfigFormEntry->IfrData.SecurityStatus.Locked =3D=3D 0) && > > + (ConfigFormEntry->IfrData.SecurityStatus.Frozen =3D=3D 0)) { > > + Status =3D FreezeLockDevice (ConfigFormEntry->AtaPassThru, > > ConfigFormEntry->Port, ConfigFormEntry->PortMultiplierPort); > > + DEBUG ((DEBUG_INFO, "FreezeLockDevice return %r!\n", Status)); > > + Status =3D GetHddDeviceIdentifyData ( > > + ConfigFormEntry->AtaPassThru, > > + ConfigFormEntry->Port, > > + ConfigFormEntry->PortMultiplierPort, > > + &IdentifyData > > + ); > > + GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry- > > >IfrData); > > + } > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > + > > + gBS->CloseEvent (Event); > > +} > > + > > +/** > > + Generate Salt value. > > + > > + @param[in, out] SaltValue Points to the salt buffer, 32 = bytes > > + > > +**/ > > +VOID > > +GenSalt ( > > + IN OUT UINT8 *SaltValue > > + ) > > +{ > > + RandomSeed (NULL, 0); > > + RandomBytes (SaltValue, PASSWORD_SALT_SIZE); > > +} > > + > > +/** > > + Hash the data to get credential. > > + > > + @param[in] Buffer Points to the data buffer > > + @param[in] BufferSize Buffer size > > + @param[in] SaltValue Points to the salt buffer, 32 bytes > > + @param[out] Credential Points to the hashed result > > + > > + @retval TRUE Hash the data successfully. > > + @retval FALSE Failed to hash the data. > > + > > +**/ > > +BOOLEAN > > +GenerateCredential ( > > + IN UINT8 *Buffer, > > + IN UINTN BufferSize, > > + IN UINT8 *SaltValue, > > + OUT UINT8 *Credential > > + ) > > +{ > > + BOOLEAN Status; > > + UINTN HashSize; > > + VOID *Hash; > > + VOID *HashData; > > + > > + Hash =3D NULL; > > + HashData =3D NULL; > > + Status =3D FALSE; > > + > > + HashSize =3D Sha256GetContextSize (); > > + Hash =3D AllocateZeroPool (HashSize); > > + ASSERT (Hash !=3D NULL); > > + if (Hash =3D=3D NULL) { > > + goto Done; > > + } > > + > > + Status =3D Sha256Init (Hash); > > + if (!Status) { > > + goto Done; > > + } > > + > > + HashData =3D AllocateZeroPool (PASSWORD_SALT_SIZE + BufferSize); > > + ASSERT (HashData !=3D NULL); > > + if (HashData =3D=3D NULL) { > > + goto Done; > > + } > > + > > + CopyMem (HashData, SaltValue, PASSWORD_SALT_SIZE); > > + CopyMem ((UINT8 *) HashData + PASSWORD_SALT_SIZE, Buffer, > > BufferSize); > > + > > + Status =3D Sha256Update (Hash, HashData, PASSWORD_SALT_SIZE + > > BufferSize); > > + if (!Status) { > > + goto Done; > > + } > > + > > + Status =3D Sha256Final (Hash, Credential); > > + > > +Done: > > + if (Hash !=3D NULL) { > > + FreePool (Hash); > > + } > > + if (HashData !=3D NULL) { > > + ZeroMem (HashData, PASSWORD_SALT_SIZE + BufferSize); > > + FreePool (HashData); > > + } > > + return Status; > > +} > > + > > +/** > > + Save HDD password variable that will be used to validate HDD passwor= d > > + when the device is at frozen state. > > + > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + @param[in] Password The hdd password of attached ATA d= evice. > > + > > +**/ > > +VOID > > +SaveHddPasswordVariable ( > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_VARIABLE *TempVariable; > > + UINTN TempVariableSize; > > + HDD_PASSWORD_VARIABLE *NextNode; > > + HDD_PASSWORD_VARIABLE *Variable; > > + UINTN VariableSize; > > + HDD_PASSWORD_VARIABLE *NewVariable; > > + UINTN NewVariableSize; > > + BOOLEAN Delete; > > + BOOLEAN HashOk; > > + UINT8 HashData[SHA256_DIGEST_SIZE]; > > + UINT8 SaltData[PASSWORD_SALT_SIZE]; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + Delete =3D FALSE; > > + if (!PasswordIsFullZero (Password)) { > > + // > > + // It is Set/Update HDD Password. > > + // > > + ZeroMem (HashData, sizeof (HashData)); > > + ZeroMem (SaltData, sizeof (SaltData)); > > + GenSalt (SaltData); > > + HashOk =3D GenerateCredential ((UINT8 *) Password, > > HDD_PASSWORD_MAX_LENGTH, SaltData, HashData); > > + if (!HashOk) { > > + DEBUG ((DEBUG_INFO, "GenerateCredential failed\n")); > > + return; > > + } > > + } else { > > + // > > + // It is Disable HDD Password. > > + // Go to delete the variable node for the HDD password device. > > + // > > + Delete =3D TRUE; > > + } > > + > > + Variable =3D NULL; > > + VariableSize =3D 0; > > + NewVariable =3D NULL; > > + NewVariableSize =3D 0; > > + > > + Status =3D GetVariable2 ( > > + HDD_PASSWORD_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + (VOID **) &Variable, > > + &VariableSize > > + ); > > + if (Delete) { > > + if (!EFI_ERROR (Status) && (Variable !=3D NULL)) { > > + TempVariable =3D Variable; > > + TempVariableSize =3D VariableSize; > > + while (TempVariableSize >=3D sizeof (HDD_PASSWORD_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigForm= Entry->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigForm= Entry->Device) > > && > > + (TempVariable->Device.Function =3D=3D ConfigForm= Entry- > >Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigForm= Entry->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigForm= Entry- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // Delete the node. > > + // > > + NextNode =3D TempVariable + 1; > > + CopyMem (TempVariable, NextNode, (UINTN) Variable + > VariableSize > > - (UINTN) NextNode); > > + NewVariable =3D Variable; > > + NewVariableSize =3D VariableSize - sizeof > (HDD_PASSWORD_VARIABLE); > > + break; > > + } > > + TempVariableSize -=3D sizeof (HDD_PASSWORD_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + if (NewVariable =3D=3D NULL) { > > + DEBUG ((DEBUG_INFO, "The variable node for the HDD password > > device is not found\n")); > > + } > > + } else { > > + DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", > > Status)); > > + } > > + } else { > > + if (!EFI_ERROR (Status) && (Variable !=3D NULL)) { > > + TempVariable =3D Variable; > > + TempVariableSize =3D VariableSize; > > + while (TempVariableSize >=3D sizeof (HDD_PASSWORD_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigForm= Entry->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigForm= Entry->Device) > > && > > + (TempVariable->Device.Function =3D=3D ConfigForm= Entry- > >Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigForm= Entry->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigForm= Entry- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // Update the node. > > + // > > + CopyMem (TempVariable->PasswordHash, HashData, sizeof > > (HashData)); > > + CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltD= ata)); > > + NewVariable =3D Variable; > > + NewVariableSize =3D VariableSize; > > + break; > > + } > > + TempVariableSize -=3D sizeof (HDD_PASSWORD_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + if (NewVariable =3D=3D NULL) { > > + // > > + // The node for the HDD password device is not found. > > + // Create node for the HDD password device. > > + // > > + NewVariableSize =3D VariableSize + sizeof > (HDD_PASSWORD_VARIABLE); > > + NewVariable =3D AllocateZeroPool (NewVariableSize); > > + ASSERT (NewVariable !=3D NULL); > > + CopyMem (NewVariable, Variable, VariableSize); > > + TempVariable =3D (HDD_PASSWORD_VARIABLE *) ((UINTN) > NewVariable > > + VariableSize); > > + TempVariable->Device.Bus =3D (UINT8) ConfigForm= Entry->Bus; > > + TempVariable->Device.Device =3D (UINT8) ConfigForm= Entry- > > >Device; > > + TempVariable->Device.Function =3D (UINT8) ConfigForm= Entry- > > >Function; > > + TempVariable->Device.Port =3D ConfigFormEntry->P= ort; > > + TempVariable->Device.PortMultiplierPort =3D ConfigFormEntry- > > >PortMultiplierPort; > > + CopyMem (TempVariable->PasswordHash, HashData, sizeof > > (HashData)); > > + CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltDat= a)); > > + } > > + } else { > > + NewVariableSize =3D sizeof (HDD_PASSWORD_VARIABLE); > > + NewVariable =3D AllocateZeroPool (NewVariableSize); > > + ASSERT (NewVariable !=3D NULL); > > + NewVariable->Device.Bus =3D (UINT8) ConfigFormEnt= ry->Bus; > > + NewVariable->Device.Device =3D (UINT8) ConfigFormEnt= ry- > >Device; > > + NewVariable->Device.Function =3D (UINT8) ConfigFormEnt= ry- > > >Function; > > + NewVariable->Device.Port =3D ConfigFormEntry->Port= ; > > + NewVariable->Device.PortMultiplierPort =3D ConfigFormEntry- > > >PortMultiplierPort; > > + CopyMem (NewVariable->PasswordHash, HashData, sizeof > (HashData)); > > + CopyMem (NewVariable->PasswordSalt, SaltData, sizeof (SaltData))= ; > > + } > > + } > > + > > + if (NewVariable !=3D NULL) { > > + Status =3D gRT->SetVariable ( > > + HDD_PASSWORD_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + EFI_VARIABLE_NON_VOLATILE | > > EFI_VARIABLE_BOOTSERVICE_ACCESS, > > + NewVariableSize, > > + NewVariable > > + ); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_INFO, "HddPassword variable set failed (%r)\n", > > Status)); > > + } > > + } > > + > > + if (NewVariable !=3D Variable) { > > + FreePool (NewVariable); > > + } > > + if (Variable !=3D NULL) { > > + FreePool (Variable); > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > +} > > + > > +/** > > + Get saved HDD password variable that will be used to validate HDD > > password > > + when the device is at frozen state. > > + > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + @param[out] HddPasswordVariable The variable node for the HDD > > password device. > > + > > + @retval TRUE The variable node for the HDD password device is f= ound > > and returned. > > + @retval FALSE The variable node for the HDD password device is n= ot > > found. > > + > > +**/ > > +BOOLEAN > > +GetSavedHddPasswordVariable ( > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, > > + OUT HDD_PASSWORD_VARIABLE *HddPasswordVariable > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_VARIABLE *TempVariable; > > + HDD_PASSWORD_VARIABLE *Variable; > > + UINTN VariableSize; > > + BOOLEAN Found; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + Variable =3D NULL; > > + VariableSize =3D 0; > > + > > + Status =3D GetVariable2 ( > > + HDD_PASSWORD_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + (VOID **) &Variable, > > + &VariableSize > > + ); > > + if (EFI_ERROR (Status) || (Variable =3D=3D NULL)) { > > + DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", > > Status)); > > + return FALSE; > > + } > > + > > + Found =3D FALSE; > > + TempVariable =3D Variable; > > + while (VariableSize >=3D sizeof (HDD_PASSWORD_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigFormEntr= y->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigFormEntr= y->Device) > && > > + (TempVariable->Device.Function =3D=3D ConfigFormEntr= y->Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigFormEntr= y->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigFormEntr= y- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // Get the node. > > + // > > + CopyMem (HddPasswordVariable, TempVariable, sizeof > > (HDD_PASSWORD_VARIABLE)); > > + Found =3D TRUE; > > + break; > > + } > > + VariableSize -=3D sizeof (HDD_PASSWORD_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + > > + FreePool (Variable); > > + > > + if (!Found) { > > + DEBUG ((DEBUG_INFO, "The variable node for the HDD password > device > > is not found\n")); > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > + > > + return Found; > > +} > > + > > +/** > > + Use saved HDD password variable to validate HDD password > > + when the device is at frozen state. > > + > > + @param[in] ConfigFormEntry The HDD Password configuration form > > entry. > > + @param[in] Password The hdd password of attached ATA devic= e. > > + > > + @retval EFI_SUCCESS Pass to validate the HDD password. > > + @retval EFI_NOT_FOUND The variable node for the HDD password > > device is not found. > > + @retval EFI_DEVICE_ERROR Failed to generate credential for the = HDD > > password. > > + @retval EFI_INVALID_PARAMETER Failed to validate the HDD password. > > + > > +**/ > > +EFI_STATUS > > +ValidateHddPassword ( > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_VARIABLE HddPasswordVariable; > > + BOOLEAN HashOk; > > + UINT8 HashData[SHA256_DIGEST_SIZE]; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + if (!GetSavedHddPasswordVariable (ConfigFormEntry, > > &HddPasswordVariable)) { > > + DEBUG ((DEBUG_INFO, "GetSavedHddPasswordVariable failed\n")); > > + return EFI_NOT_FOUND; > > + } > > + > > + ZeroMem (HashData, sizeof (HashData)); > > + HashOk =3D GenerateCredential ((UINT8 *) Password, > > HDD_PASSWORD_MAX_LENGTH, HddPasswordVariable.PasswordSalt, > > HashData); > > + if (!HashOk) { > > + DEBUG ((DEBUG_INFO, "GenerateCredential failed\n")); > > + return EFI_DEVICE_ERROR; > > + } > > + > > + if (CompareMem (HddPasswordVariable.PasswordHash, HashData, > sizeof > > (HashData)) !=3D 0) { > > + Status =3D EFI_INVALID_PARAMETER; > > + } else { > > + Status =3D EFI_SUCCESS; > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit (%r)\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Send unlock hdd password cmd through Ata Pass Thru Protocol. > > + > > + @param[in] AtaPassThru The pointer to the ATA_PASS_THRU > protocol. > > + @param[in] Port The port number of the ATA device to = send the > > command. > > + @param[in] PortMultiplierPort The port multiplier port number of th= e > ATA > > device to send the command. > > + If there is no port multiplier, then = specify 0xFFFF. > > + @param[in] Identifier The identifier to set user or master = password. > > + @param[in] Password The hdd password of attached ATA devi= ce. > > + > > + @retval EFI_SUCCESS Successful to send unlock hdd passwor= d cmd. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to send unlock > > hdd password cmd. > > + @retval EFI_DEVICE_ERROR Can not send unlock hdd password cmd. > > + > > +**/ > > +EFI_STATUS > > +UnlockHddPassword ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN CHAR8 Identifier, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + UINT8 Buffer[HDD_PAYLOAD]; > > + > > + if ((AtaPassThru =3D=3D NULL) || (Password =3D=3D NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_UNLOCK_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_BYTES; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + > > + ((CHAR16 *) Buffer)[0] =3D Identifier & BIT0; > > + CopyMem (&((CHAR16 *) Buffer)[1], Password, > > HDD_PASSWORD_MAX_LENGTH); > > + > > + Packet.OutDataBuffer =3D Buffer; > > + Packet.OutTransferLength =3D sizeof (Buffer); > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet, > > + NULL > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + ZeroMem (Buffer, sizeof (Buffer)); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Send disable hdd password cmd through Ata Pass Thru Protocol. > > + > > + @param[in] AtaPassThru The pointer to the ATA_PASS_THRU > protocol. > > + @param[in] Port The port number of the ATA device to = send the > > command. > > + @param[in] PortMultiplierPort The port multiplier port number of th= e > ATA > > device to send the command. > > + If there is no port multiplier, then = specify 0xFFFF. > > + @param[in] Identifier The identifier to set user or master = password. > > + @param[in] Password The hdd password of attached ATA devi= ce. > > + > > + @retval EFI_SUCCESS Successful to disable hdd password cm= d. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to disable hdd > > password cmd. > > + @retval EFI_DEVICE_ERROR Can not disable hdd password cmd. > > + > > +**/ > > +EFI_STATUS > > +DisableHddPassword ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN CHAR8 Identifier, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + UINT8 Buffer[HDD_PAYLOAD]; > > + > > + if ((AtaPassThru =3D=3D NULL) || (Password =3D=3D NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_DIS_PASSWORD_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_BYTES; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + > > + ((CHAR16 *) Buffer)[0] =3D Identifier & BIT0; > > + CopyMem (&((CHAR16 *) Buffer)[1], Password, > > HDD_PASSWORD_MAX_LENGTH); > > + > > + Packet.OutDataBuffer =3D Buffer; > > + Packet.OutTransferLength =3D sizeof (Buffer); > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet, > > + NULL > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + ZeroMem (Buffer, sizeof (Buffer)); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Send set hdd password cmd through Ata Pass Thru Protocol. > > + > > + @param[in] AtaPassThru The pointer to the ATA_PASS_TH= RU > > protocol. > > + @param[in] Port The port number of the ATA dev= ice to send > > the command. > > + @param[in] PortMultiplierPort The port multiplier port numbe= r of > the > > ATA device to send the command. > > + If there is no port multiplier= , then specify 0xFFFF. > > + @param[in] Identifier The identifier to set user or = master > > password. > > + @param[in] SecurityLevel The security level to be set t= o device. > > + @param[in] MasterPasswordIdentifier The master password identifier > to > > be set to device. > > + @param[in] Password The hdd password of attached A= TA > device. > > + > > + @retval EFI_SUCCESS Successful to set hdd password cmd. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to set hdd > > password cmd. > > + @retval EFI_DEVICE_ERROR Can not set hdd password cmd. > > + > > +**/ > > +EFI_STATUS > > +SetHddPassword ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN CHAR8 Identifier, > > + IN CHAR8 SecurityLevel, > > + IN CHAR16 MasterPasswordIdentifier, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + UINT8 Buffer[HDD_PAYLOAD]; > > + > > + if ((AtaPassThru =3D=3D NULL) || (Password =3D=3D NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_SET_PASSWORD_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_BYTES; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + > > + ((CHAR16 *) Buffer)[0] =3D (Identifier | (UINT16)(SecurityLevel << 8= )) & > (BIT0 > > | BIT8); > > + CopyMem (&((CHAR16 *) Buffer)[1], Password, > > HDD_PASSWORD_MAX_LENGTH); > > + if ((Identifier & BIT0) !=3D 0) { > > + ((CHAR16 *) Buffer)[17] =3D MasterPasswordIdentifier; > > + } > > + > > + Packet.OutDataBuffer =3D Buffer; > > + Packet.OutTransferLength =3D sizeof (Buffer); > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet, > > + NULL > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + ZeroMem (Buffer, sizeof (Buffer)); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Get attached harddisk model number from identify data buffer. > > + > > + @param[in] IdentifyData Pointer to identify data buffer. > > + @param[in, out] String The buffer to store harddisk model number= . > > + > > +**/ > > +VOID > > +GetHddDeviceModelNumber ( > > + IN ATA_IDENTIFY_DATA *IdentifyData, > > + IN OUT CHAR16 *String > > + ) > > +{ > > + UINTN Index; > > + > > + // > > + // Swap the byte order in the original module name. > > + // From Ata spec, the maximum length is 40 bytes. > > + // > > + for (Index =3D 0; Index < 40; Index +=3D 2) { > > + String[Index] =3D IdentifyData->ModelName[Index + 1]; > > + String[Index + 1] =3D IdentifyData->ModelName[Index]; > > + } > > + > > + // > > + // Chap it off after 20 characters > > + // > > + String[20] =3D L'\0'; > > + > > + return ; > > +} > > + > > +/** > > + Get password input from the popup windows. > > + > > + @param[in] PopUpString1 Pop up string 1. > > + @param[in] PopUpString2 Pop up string 2. > > + @param[in, out] Password The buffer to hold the input password. > > + > > + @retval EFI_ABORTED It is given up by pressing 'ESC' key. > > + @retval EFI_SUCCESS Get password input successfully. > > + > > +**/ > > +EFI_STATUS > > +PopupHddPasswordInputWindows ( > > + IN CHAR16 *PopUpString1, > > + IN CHAR16 *PopUpString2, > > + IN OUT CHAR8 *Password > > + ) > > +{ > > + EFI_INPUT_KEY Key; > > + UINTN Length; > > + CHAR16 Mask[HDD_PASSWORD_MAX_LENGTH + 1]; > > + CHAR16 Unicode[HDD_PASSWORD_MAX_LENGTH + 1]; > > + CHAR8 Ascii[HDD_PASSWORD_MAX_LENGTH + 1]; > > + > > + ZeroMem (Unicode, sizeof (Unicode)); > > + ZeroMem (Ascii, sizeof (Ascii)); > > + ZeroMem (Mask, sizeof (Mask)); > > + > > + gST->ConOut->ClearScreen(gST->ConOut); > > + > > + Length =3D 0; > > + while (TRUE) { > > + Mask[Length] =3D L'_'; > > + if (PopUpString2 =3D=3D NULL) { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + PopUpString1, > > + L"---------------------", > > + Mask, > > + NULL > > + ); > > + } else { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + PopUpString1, > > + PopUpString2, > > + L"---------------------", > > + Mask, > > + NULL > > + ); > > + } > > + // > > + // Check key. > > + // > > + if (Key.ScanCode =3D=3D SCAN_NULL) { > > + if (Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) { > > + // > > + // Add the null terminator. > > + // > > + Unicode[Length] =3D 0; > > + break; > > + } else if ((Key.UnicodeChar =3D=3D CHAR_NULL) || > > + (Key.UnicodeChar =3D=3D CHAR_TAB) || > > + (Key.UnicodeChar =3D=3D CHAR_LINEFEED) > > + ) { > > + continue; > > + } else { > > + if (Key.UnicodeChar =3D=3D CHAR_BACKSPACE) { > > + if (Length > 0) { > > + Unicode[Length] =3D 0; > > + Mask[Length] =3D 0; > > + Length--; > > + } > > + } else { > > + Unicode[Length] =3D Key.UnicodeChar; > > + Mask[Length] =3D L'*'; > > + Length++; > > + if (Length =3D=3D HDD_PASSWORD_MAX_LENGTH) { > > + // > > + // Add the null terminator. > > + // > > + Unicode[Length] =3D 0; > > + Mask[Length] =3D 0; > > + break; > > + } > > + } > > + } > > + } > > + > > + if (Key.ScanCode =3D=3D SCAN_ESC) { > > + ZeroMem (Unicode, sizeof (Unicode)); > > + ZeroMem (Ascii, sizeof (Ascii)); > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return EFI_ABORTED; > > + } > > + } > > + > > + UnicodeStrToAsciiStrS (Unicode, Ascii, sizeof (Ascii)); > > + CopyMem (Password, Ascii, HDD_PASSWORD_MAX_LENGTH); > > + ZeroMem (Unicode, sizeof (Unicode)); > > + ZeroMem (Ascii, sizeof (Ascii)); > > + > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Check if disk is locked, show popup window and ask for password if i= t is. > > + > > + @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance. > > + @param[in] Port The port number of attached ATA de= vice. > > + @param[in] PortMultiplierPort The port number of port multiplier= of > > attached ATA device. > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + > > +**/ > > +VOID > > +HddPasswordRequestPassword ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + CHAR16 PopUpString[100]; > > + ATA_IDENTIFY_DATA IdentifyData; > > + EFI_INPUT_KEY Key; > > + UINT16 RetryCount; > > + CHAR8 Password[HDD_PASSWORD_MAX_LENGTH]; > > + > > + RetryCount =3D 0; > > + > > + DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__)); > > + > > + UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Unlock: %s", > > ConfigFormEntry->HddString); > > + > > + // > > + // Check the device security status. > > + // > > + if ((ConfigFormEntry->IfrData.SecurityStatus.Supported) && > > + (ConfigFormEntry->IfrData.SecurityStatus.Enabled)) { > > + // > > + // As soon as the HDD password is in enabled state, we pop up a > window > > to unlock hdd > > + // no matter it's really in locked or unlocked state. > > + // This way forces user to enter password every time to provide be= st > > safety. > > + // > > + while (TRUE) { > > + Status =3D PopupHddPasswordInputWindows (PopUpString, NULL, > > Password); > > + if (!EFI_ERROR (Status)) { > > + // > > + // The HDD is in locked state, unlock it by user input. > > + // > > + if (!PasswordIsFullZero (Password)) { > > + if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) { > > + Status =3D UnlockHddPassword (AtaPassThru, Port, PortMulti= plierPort, > > 0, Password); > > + } else { > > + // > > + // Use saved HDD password variable to validate HDD passwor= d > > + // when the device is at frozen state. > > + // > > + Status =3D ValidateHddPassword (ConfigFormEntry, Password)= ; > > + } > > + } else { > > + Status =3D EFI_INVALID_PARAMETER; > > + } > > + if (!EFI_ERROR (Status)) { > > + CopyMem (ConfigFormEntry->Password, Password, > > HDD_PASSWORD_MAX_LENGTH); > > + if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) { > > + SaveHddPasswordVariable (ConfigFormEntry, Password); > > + } > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + Status =3D GetHddDeviceIdentifyData (AtaPassThru, Port, > > PortMultiplierPort, &IdentifyData); > > + ASSERT_EFI_ERROR (Status); > > + > > + // > > + // Check the device security status again. > > + // > > + GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntr= y- > > >IfrData); > > + return; > > + } > > + > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + > > + if (EFI_ERROR (Status)) { > > + RetryCount ++; > > + if (RetryCount < MAX_HDD_PASSWORD_RETRY_COUNT) { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Invalid password.", > > + L"Press ENTER to retry", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + continue; > > + } else { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Hdd password retry count is expired. Please shutdown= the > > machine.", > > + L"Press ENTER to shutdown", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); > > + break; > > + } > > + } > > + } else if (Status =3D=3D EFI_ABORTED) { > > + if (ConfigFormEntry->IfrData.SecurityStatus.Locked) { > > + // > > + // Current device in the lock status and > > + // User not input password and press ESC, > > + // keep device in lock status and continue boot. > > + // > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Press ENTER to skip the request and continue boot,", > > + L"Press ESC to input password again", > > + NULL > > + ); > > + } while ((Key.ScanCode !=3D SCAN_ESC) && (Key.UnicodeChar != =3D > > CHAR_CARRIAGE_RETURN)); > > + > > + if (Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) { > > + gST->ConOut->ClearScreen(gST->ConOut); > > + // > > + // Keep lock and continue boot. > > + // > > + return; > > + } else { > > + // > > + // Let user input password again. > > + // > > + continue; > > + } > > + } else { > > + // > > + // Current device in the unlock status and > > + // User not input password and press ESC, > > + // Shutdown the device. > > + // > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Press ENTER to shutdown, Press ESC to input password a= gain", > > + NULL > > + ); > > + } while ((Key.ScanCode !=3D SCAN_ESC) && (Key.UnicodeChar != =3D > > CHAR_CARRIAGE_RETURN)); > > + > > + if (Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) { > > + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); > > + } else { > > + // > > + // Let user input password again. > > + // > > + continue; > > + } > > + } > > + } > > + } > > + } > > +} > > + > > +/** > > + Process Set User Pwd HDD password request. > > + > > + @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance. > > + @param[in] Port The port number of attached ATA de= vice. > > + @param[in] PortMultiplierPort The port number of port multiplier= of > > attached ATA device. > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + > > +**/ > > +VOID > > +ProcessHddPasswordRequestSetUserPwd ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + CHAR16 PopUpString[100]; > > + ATA_IDENTIFY_DATA IdentifyData; > > + EFI_INPUT_KEY Key; > > + UINT16 RetryCount; > > + CHAR8 Password[HDD_PASSWORD_MAX_LENGTH]; > > + CHAR8 > PasswordConfirm[HDD_PASSWORD_MAX_LENGTH]; > > + > > + RetryCount =3D 0; > > + > > + DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__)); > > + > > + if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) { > > + DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry- > > >HddString)); > > + return; > > + } > > + > > + if (ConfigFormEntry->IfrData.SecurityStatus.Locked) { > > + DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry- > > >HddString)); > > + return; > > + } > > + > > + UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set User Pwd: %s= ", > > ConfigFormEntry->HddString); > > + > > + // > > + // Check the device security status. > > + // > > + if (ConfigFormEntry->IfrData.SecurityStatus.Supported) { > > + while (TRUE) { > > + Status =3D PopupHddPasswordInputWindows (PopUpString, L"Please > type > > in your new password", Password); > > + if (!EFI_ERROR (Status)) { > > + Status =3D PopupHddPasswordInputWindows (PopUpString, L"Please > > confirm your new password", PasswordConfirm); > > + if (!EFI_ERROR (Status)) { > > + if (CompareMem (Password, PasswordConfirm, > > HDD_PASSWORD_MAX_LENGTH) =3D=3D 0) { > > + if (!PasswordIsFullZero (Password)) { > > + Status =3D SetHddPassword (AtaPassThru, Port, PortMultip= lierPort, 0, > 1, > > 0, Password); > > + } else { > > + if (ConfigFormEntry->IfrData.SecurityStatus.Enabled) { > > + Status =3D DisableHddPassword (AtaPassThru, Port, > > PortMultiplierPort, 0, ConfigFormEntry->Password); > > + } else { > > + Status =3D EFI_INVALID_PARAMETER; > > + } > > + } > > + if (!EFI_ERROR (Status)) { > > + CopyMem (ConfigFormEntry->Password, Password, > > HDD_PASSWORD_MAX_LENGTH); > > + SaveHddPasswordVariable (ConfigFormEntry, Password); > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH); > > + Status =3D GetHddDeviceIdentifyData (AtaPassThru, Port, > > PortMultiplierPort, &IdentifyData); > > + ASSERT_EFI_ERROR (Status); > > + > > + // > > + // Check the device security status again. > > + // > > + GetHddPasswordSecurityStatus (&IdentifyData, > &ConfigFormEntry- > > >IfrData); > > + return; > > + } else { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Set/Disable User Pwd failed or invalid password.", > > + L"Press ENTER to retry", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + } > > + } else { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Passwords are not the same.", > > + L"Press ENTER to retry", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + Status =3D EFI_INVALID_PARAMETER; > > + } > > + } > > + > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH); > > + > > + if (EFI_ERROR (Status)) { > > + RetryCount ++; > > + if (RetryCount >=3D MAX_HDD_PASSWORD_RETRY_COUNT) { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Hdd password retry count is expired.", > > + L"Press ENTER to skip the request and continue boot", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return; > > + } > > + } > > + } else if (Status =3D=3D EFI_ABORTED) { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Press ENTER to skip the request and continue boot,", > > + L"Press ESC to input password again", > > + NULL > > + ); > > + } while ((Key.ScanCode !=3D SCAN_ESC) && (Key.UnicodeChar !=3D > > CHAR_CARRIAGE_RETURN)); > > + > > + if (Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) { > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return; > > + } else { > > + // > > + // Let user input password again. > > + // > > + continue; > > + } > > + } > > + } > > + } > > +} > > + > > +/** > > + Process Set Master Pwd HDD password request. > > + > > + @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance. > > + @param[in] Port The port number of attached ATA de= vice. > > + @param[in] PortMultiplierPort The port number of port multiplier= of > > attached ATA device. > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + > > +**/ > > +VOID > > +ProcessHddPasswordRequestSetMasterPwd ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + CHAR16 PopUpString[100]; > > + EFI_INPUT_KEY Key; > > + UINT16 RetryCount; > > + CHAR8 Password[HDD_PASSWORD_MAX_LENGTH]; > > + CHAR8 > PasswordConfirm[HDD_PASSWORD_MAX_LENGTH]; > > + > > + RetryCount =3D 0; > > + > > + DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__)); > > + > > + if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) { > > + DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry- > > >HddString)); > > + return; > > + } > > + > > + if (ConfigFormEntry->IfrData.SecurityStatus.Locked) { > > + DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry- > > >HddString)); > > + return; > > + } > > + > > + UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set Master > Pwd: %s", > > ConfigFormEntry->HddString); > > + > > + // > > + // Check the device security status. > > + // > > + if (ConfigFormEntry->IfrData.SecurityStatus.Supported) { > > + while (TRUE) { > > + Status =3D PopupHddPasswordInputWindows (PopUpString, L"Please > type > > in your new password", Password); > > + if (!EFI_ERROR (Status)) { > > + Status =3D PopupHddPasswordInputWindows (PopUpString, L"Please > > confirm your new password", PasswordConfirm); > > + if (!EFI_ERROR (Status)) { > > + if (CompareMem (Password, PasswordConfirm, > > HDD_PASSWORD_MAX_LENGTH) =3D=3D 0) { > > + if (!PasswordIsFullZero (Password)) { > > + Status =3D SetHddPassword (AtaPassThru, Port, PortMultip= lierPort, 1, > 1, > > 1, Password); > > + } else { > > + Status =3D EFI_INVALID_PARAMETER; > > + } > > + if (!EFI_ERROR (Status)) { > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH); > > + return; > > + } else { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Set Master Pwd failed or invalid password.", > > + L"Press ENTER to retry", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + } > > + } else { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Passwords are not the same.", > > + L"Press ENTER to retry", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + Status =3D EFI_INVALID_PARAMETER; > > + } > > + } > > + > > + ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH); > > + ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH); > > + > > + if (EFI_ERROR (Status)) { > > + RetryCount ++; > > + if (RetryCount >=3D MAX_HDD_PASSWORD_RETRY_COUNT) { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Hdd password retry count is expired.", > > + L"Press ENTER to skip the request and continue boot", > > + NULL > > + ); > > + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return; > > + } > > + } > > + } else if (Status =3D=3D EFI_ABORTED) { > > + do { > > + CreatePopUp ( > > + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, > > + &Key, > > + L"Press ENTER to skip the request and continue boot,", > > + L"Press ESC to input password again", > > + NULL > > + ); > > + } while ((Key.ScanCode !=3D SCAN_ESC) && (Key.UnicodeChar !=3D > > CHAR_CARRIAGE_RETURN)); > > + > > + if (Key.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) { > > + gST->ConOut->ClearScreen(gST->ConOut); > > + return; > > + } else { > > + // > > + // Let user input password again. > > + // > > + continue; > > + } > > + } > > + } > > + } > > +} > > + > > +/** > > + Process HDD password request. > > + > > + @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance. > > + @param[in] Port The port number of attached ATA de= vice. > > + @param[in] PortMultiplierPort The port number of port multiplier= of > > attached ATA device. > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + > > +**/ > > +VOID > > +ProcessHddPasswordRequest ( > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_REQUEST_VARIABLE *TempVariable; > > + HDD_PASSWORD_REQUEST_VARIABLE *Variable; > > + UINTN VariableSize; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + if (mHddPasswordRequestVariable =3D=3D NULL) { > > + Status =3D GetVariable2 ( > > + HDD_PASSWORD_REQUEST_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + (VOID **) &Variable, > > + &VariableSize > > + ); > > + if (EFI_ERROR (Status) || (Variable =3D=3D NULL)) { > > + return; > > + } > > + mHddPasswordRequestVariable =3D Variable; > > + mHddPasswordRequestVariableSize =3D VariableSize; > > + > > + // > > + // Delete the HDD password request variable. > > + // > > + Status =3D gRT->SetVariable ( > > + HDD_PASSWORD_REQUEST_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + 0, > > + 0, > > + NULL > > + ); > > + ASSERT_EFI_ERROR (Status); > > + } else { > > + Variable =3D mHddPasswordRequestVariable; > > + VariableSize =3D mHddPasswordRequestVariableSize; > > + } > > + > > + // > > + // Process the HDD password requests. > > + // > > + TempVariable =3D Variable; > > + while (VariableSize >=3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigFormEntr= y->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigFormEntr= y->Device) > && > > + (TempVariable->Device.Function =3D=3D ConfigFormEntr= y->Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigFormEntr= y->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigFormEntr= y- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // > > + if (TempVariable->Request.UserPassword !=3D 0) { > > + ProcessHddPasswordRequestSetUserPwd (AtaPassThru, Port, > > PortMultiplierPort, ConfigFormEntry); > > + } > > + if (TempVariable->Request.MasterPassword !=3D 0) { > > + ProcessHddPasswordRequestSetMasterPwd (AtaPassThru, Port, > > PortMultiplierPort, ConfigFormEntry); > > + } > > + > > + break; > > + } > > + > > + VariableSize -=3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > +} > > + > > +/** > > + Get saved HDD password request. > > + > > + @param[in, out] ConfigFormEntry The HDD Password configuration > > form entry. > > + > > +**/ > > +VOID > > +GetSavedHddPasswordRequest ( > > + IN OUT HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_REQUEST_VARIABLE *TempVariable; > > + HDD_PASSWORD_REQUEST_VARIABLE *Variable; > > + UINTN VariableSize; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + Variable =3D NULL; > > + VariableSize =3D 0; > > + > > + Status =3D GetVariable2 ( > > + HDD_PASSWORD_REQUEST_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + (VOID **) &Variable, > > + &VariableSize > > + ); > > + if (EFI_ERROR (Status) || (Variable =3D=3D NULL)) { > > + return; > > + } > > + > > + TempVariable =3D Variable; > > + while (VariableSize >=3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigFormEntr= y->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigFormEntr= y->Device) > && > > + (TempVariable->Device.Function =3D=3D ConfigFormEntr= y->Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigFormEntr= y->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigFormEntr= y- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // Get the HDD password request. > > + // > > + CopyMem (&ConfigFormEntry->IfrData.Request, &TempVariable- > > >Request, sizeof (HDD_PASSWORD_REQUEST)); > > + DEBUG (( > > + DEBUG_INFO, > > + "HddPasswordRequest got: 0x%x\n", > > + ConfigFormEntry->IfrData.Request > > + )); > > + break; > > + } > > + VariableSize -=3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + > > + FreePool (Variable); > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > +} > > + > > +/** > > + Save HDD password request. > > + > > + @param[in] ConfigFormEntry The HDD Password configuration for= m > > entry. > > + > > +**/ > > +VOID > > +SaveHddPasswordRequest ( > > + IN HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_REQUEST_VARIABLE *TempVariable; > > + UINTN TempVariableSize; > > + HDD_PASSWORD_REQUEST_VARIABLE *Variable; > > + UINTN VariableSize; > > + HDD_PASSWORD_REQUEST_VARIABLE *NewVariable; > > + UINTN NewVariableSize; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); > > + > > + DEBUG (( > > + DEBUG_INFO, > > + "HddPasswordRequest to save: 0x%x\n", > > + ConfigFormEntry->IfrData.Request > > + )); > > + > > + Variable =3D NULL; > > + VariableSize =3D 0; > > + NewVariable =3D NULL; > > + NewVariableSize =3D 0; > > + > > + Status =3D GetVariable2 ( > > + HDD_PASSWORD_REQUEST_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + (VOID **) &Variable, > > + &VariableSize > > + ); > > + if (!EFI_ERROR (Status) && (Variable !=3D NULL)) { > > + TempVariable =3D Variable; > > + TempVariableSize =3D VariableSize; > > + while (TempVariableSize >=3D sizeof > > (HDD_PASSWORD_REQUEST_VARIABLE)) { > > + if ((TempVariable->Device.Bus =3D=3D ConfigFormEn= try->Bus) && > > + (TempVariable->Device.Device =3D=3D ConfigFormEn= try->Device) > && > > + (TempVariable->Device.Function =3D=3D ConfigFormEn= try- > >Function) > > && > > + (TempVariable->Device.Port =3D=3D ConfigFormEn= try->Port) && > > + (TempVariable->Device.PortMultiplierPort =3D=3D ConfigFormEn= try- > > >PortMultiplierPort)) { > > + // > > + // Found the node for the HDD password device. > > + // Update the HDD password request. > > + // > > + CopyMem (&TempVariable->Request, &ConfigFormEntry- > > >IfrData.Request, sizeof (HDD_PASSWORD_REQUEST)); > > + NewVariable =3D Variable; > > + NewVariableSize =3D VariableSize; > > + break; > > + } > > + TempVariableSize -=3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE); > > + TempVariable +=3D 1; > > + } > > + if (NewVariable =3D=3D NULL) { > > + // > > + // The node for the HDD password device is not found. > > + // Create node for the HDD password device. > > + // > > + NewVariableSize =3D VariableSize + sizeof > > (HDD_PASSWORD_REQUEST_VARIABLE); > > + NewVariable =3D AllocateZeroPool (NewVariableSize); > > + ASSERT (NewVariable !=3D NULL); > > + CopyMem (NewVariable, Variable, VariableSize); > > + TempVariable =3D (HDD_PASSWORD_REQUEST_VARIABLE *) ((UINTN) > > NewVariable + VariableSize); > > + TempVariable->Device.Bus =3D (UINT8) ConfigFormEn= try->Bus; > > + TempVariable->Device.Device =3D (UINT8) ConfigFormEn= try- > >Device; > > + TempVariable->Device.Function =3D (UINT8) ConfigFormEn= try- > > >Function; > > + TempVariable->Device.Port =3D ConfigFormEntry->Por= t; > > + TempVariable->Device.PortMultiplierPort =3D ConfigFormEntry- > > >PortMultiplierPort; > > + CopyMem (&TempVariable->Request, &ConfigFormEntry- > > >IfrData.Request, sizeof (HDD_PASSWORD_REQUEST)); > > + } > > + } else { > > + NewVariableSize =3D sizeof (HDD_PASSWORD_REQUEST_VARIABLE); > > + NewVariable =3D AllocateZeroPool (NewVariableSize); > > + ASSERT (NewVariable !=3D NULL); > > + NewVariable->Device.Bus =3D (UINT8) ConfigFormEntry= ->Bus; > > + NewVariable->Device.Device =3D (UINT8) ConfigFormEntry= ->Device; > > + NewVariable->Device.Function =3D (UINT8) ConfigFormEntry= - > > >Function; > > + NewVariable->Device.Port =3D ConfigFormEntry->Port; > > + NewVariable->Device.PortMultiplierPort =3D ConfigFormEntry- > > >PortMultiplierPort; > > + CopyMem (&NewVariable->Request, &ConfigFormEntry- > > >IfrData.Request, sizeof (HDD_PASSWORD_REQUEST)); > > + } > > + Status =3D gRT->SetVariable ( > > + HDD_PASSWORD_REQUEST_VARIABLE_NAME, > > + &mHddPasswordVendorGuid, > > + EFI_VARIABLE_NON_VOLATILE | > > EFI_VARIABLE_BOOTSERVICE_ACCESS, > > + NewVariableSize, > > + NewVariable > > + ); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_INFO, "HddPasswordRequest variable set failed > (%r)\n", > > Status)); > > + } > > + if (NewVariable !=3D Variable) { > > + FreePool (NewVariable); > > + } > > + if (Variable !=3D NULL) { > > + FreePool (Variable); > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); > > +} > > + > > +/** > > + Get the HDD Password configuration form entry by the index of the go= to > > opcode actived. > > + > > + @param[in] Index The 0-based index of the goto opcode actived. > > + > > + @return The HDD Password configuration form entry found. > > +**/ > > +HDD_PASSWORD_CONFIG_FORM_ENTRY * > > +HddPasswordGetConfigFormEntryByIndex ( > > + IN UINT32 Index > > + ) > > +{ > > + LIST_ENTRY *Entry; > > + UINT32 CurrentIndex; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry; > > + > > + CurrentIndex =3D 0; > > + ConfigFormEntry =3D NULL; > > + > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + if (CurrentIndex =3D=3D Index) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + break; > > + } > > + > > + CurrentIndex++; > > + } > > + > > + return ConfigFormEntry; > > +} > > + > > +/** > > + This function allows the caller to request the current > > + configuration for one or more named elements. The resulting > > + string is in format. Any and all alternative > > + configuration strings shall also be appended to the end of the > > + current configuration string. If they are, they must appear > > + after the current configuration. They must contain the same > > + routing (GUID, NAME, PATH) as the current configuration string. > > + They must have an additional description indicating the type of > > + alternative configuration the string represents, > > + "ALTCFG=3D". That (when > > + converted from Hex UNICODE to binary) is a reference to a > > + string in the associated string pack. > > + > > + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. > > + @param[in] Request A null-terminated Unicode string in > > + format. Note that this > > + includes the routing information as well as > > + the configurable name / value pairs. It is > > + invalid for this string to be in > > + format. > > + @param[out] Progress On return, points to a character in the > > + Request string. Points to the string's null > > + terminator if request was successful. Points > > + to the most recent "&" before the first > > + failing name / value pair (or the beginning > > + of the string if the failure is in the first > > + name / value pair) if the request was not > > + successful. > > + @param[out] Results A null-terminated Unicode string in > > + format which has all values > > + filled in for the names in the Request string. > > + String to be allocated by the called function. > > + > > + @retval EFI_SUCCESS The Results string is filled with th= e > > + values corresponding to all requeste= d > > + names. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the > > + parts of the results that must be > > + stored awaiting possible future > > + protocols. > > + @retval EFI_INVALID_PARAMETER For example, passing in a NULL > > + for the Request parameter > > + would result in this type of > > + error. In this case, the > > + Progress parameter would be > > + set to NULL. > > + @retval EFI_NOT_FOUND Routing data doesn't match any > > + known driver. Progress set to the > > + first character in the routing heade= r. > > + Note: There is no requirement that t= he > > + driver validate the routing data. It > > + must skip the in order t= o > > + process the names. > > + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set > > + to most recent & before the > > + error or the beginning of the > > + string. > > + @retval EFI_INVALID_PARAMETER Unknown name. Progress points > > + to the & before the name in > > + question.Currently not implemented. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordFormExtractConfig ( > > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > > + IN CONST EFI_STRING Request, > > + OUT EFI_STRING *Progress, > > + OUT EFI_STRING *Results > > + ) > > +{ > > + EFI_STATUS Status; > > + UINTN BufferSize; > > + HDD_PASSWORD_CONFIG *IfrData; > > + HDD_PASSWORD_DXE_PRIVATE_DATA *Private; > > + EFI_STRING ConfigRequestHdr; > > + EFI_STRING ConfigRequest; > > + BOOLEAN AllocatedRequest; > > + UINTN Size; > > + > > + if (Progress =3D=3D NULL || Results =3D=3D NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + *Progress =3D Request; > > + if ((Request !=3D NULL) && !HiiIsConfigHdrMatch (Request, > > &mHddPasswordVendorGuid, mHddPasswordVendorStorageName)) { > > + return EFI_NOT_FOUND; > > + } > > + > > + ConfigRequestHdr =3D NULL; > > + ConfigRequest =3D NULL; > > + AllocatedRequest =3D FALSE; > > + Size =3D 0; > > + > > + Private =3D HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This); > > + IfrData =3D AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG)); > > + ASSERT (IfrData !=3D NULL); > > + if (Private->Current !=3D NULL) { > > + CopyMem (IfrData, &Private->Current->IfrData, sizeof > > (HDD_PASSWORD_CONFIG)); > > + } > > + > > + // > > + // Convert buffer data to by helper function > BlockToConfig() > > + // > > + BufferSize =3D sizeof (HDD_PASSWORD_CONFIG); > > + ConfigRequest =3D Request; > > + if ((Request =3D=3D NULL) || (StrStr (Request, L"OFFSET") =3D=3D NUL= L)) { > > + // > > + // Request has no request element, construct full request string. > > + // Allocate and fill a buffer large enough to hold the > > template > > + // followed by > "&OFFSET=3D0&WIDTH=3DWWWWWWWWWWWWWWWW" > > followed by a Null-terminator > > + // > > + ConfigRequestHdr =3D HiiConstructConfigHdr > (&mHddPasswordVendorGuid, > > mHddPasswordVendorStorageName, Private->DriverHandle); > > + Size =3D (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); > > + ConfigRequest =3D AllocateZeroPool (Size); > > + ASSERT (ConfigRequest !=3D NULL); > > + AllocatedRequest =3D TRUE; > > + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=3D0&WIDTH=3D%016LX= ", > > ConfigRequestHdr, (UINT64)BufferSize); > > + FreePool (ConfigRequestHdr); > > + } > > + Status =3D gHiiConfigRouting->BlockToConfig ( > > + gHiiConfigRouting, > > + ConfigRequest, > > + (UINT8 *) IfrData, > > + BufferSize, > > + Results, > > + Progress > > + ); > > + FreePool (IfrData); > > + // > > + // Free the allocated config request string. > > + // > > + if (AllocatedRequest) { > > + FreePool (ConfigRequest); > > + ConfigRequest =3D NULL; > > + } > > + > > + // > > + // Set Progress string to the original request string. > > + // > > + if (Request =3D=3D NULL) { > > + *Progress =3D NULL; > > + } else if (StrStr (Request, L"OFFSET") =3D=3D NULL) { > > + *Progress =3D Request + StrLen (Request); > > + } > > + > > + return Status; > > +} > > + > > +/** > > + This function applies changes in a driver's configuration. > > + Input is a Configuration, which has the routing data for this > > + driver followed by name / value configuration pairs. The driver > > + must apply those pairs to its configurable storage. If the > > + driver's configuration is stored in a linear block of data > > + and the driver's name / value pairs are in > > + format, it may use the ConfigToBlock helper function (above) to > > + simplify the job. Currently not implemented. > > + > > + @param[in] This Points to the > EFI_HII_CONFIG_ACCESS_PROTOCOL. > > + @param[in] Configuration A null-terminated Unicode string in > > + format. > > + @param[out] Progress A pointer to a string filled in with the > > + offset of the most recent '&' before the > > + first failing name / value pair (or the > > + beginn ing of the string if the failure > > + is in the first name / value pair) or > > + the terminating NULL if all was > > + successful. > > + > > + @retval EFI_SUCCESS The results have been distributed or= are > > + awaiting distribution. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the > > + parts of the results that must be > > + stored awaiting possible future > > + protocols. > > + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the > > + Results parameter would result > > + in this type of error. > > + @retval EFI_NOT_FOUND Target for the specified routing dat= a > > + was not found. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordFormRouteConfig ( > > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > > + IN CONST EFI_STRING Configuration, > > + OUT EFI_STRING *Progress > > + ) > > +{ > > + if (Configuration =3D=3D NULL || Progress =3D=3D NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // Check routing data in . > > + // Note: if only one Storage is used, then this checking could be sk= ipped. > > + // > > + if (!HiiIsConfigHdrMatch (Configuration, &mHddPasswordVendorGuid, > > mHddPasswordVendorStorageName)) { > > + *Progress =3D Configuration; > > + return EFI_NOT_FOUND; > > + } > > + > > + *Progress =3D Configuration + StrLen (Configuration); > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + This function is called to provide results data to the driver. > > + This data consists of a unique key that is used to identify > > + which data is either being passed back or being asked for. > > + > > + @param[in] This Points to the > > EFI_HII_CONFIG_ACCESS_PROTOCOL. > > + @param[in] Action Specifies the type of action taken by= the > browser. > > + @param[in] QuestionId A unique value which is sent to the o= riginal > > + exporting driver so that it can ident= ify the type > > + of data to expect. The format of the = data tends to > > + vary based on the opcode that enerate= d the callback. > > + @param[in] Type The type of value for the question. > > + @param[in] Value A pointer to the data being sent to t= he original > > + exporting driver. > > + @param[out] ActionRequest On return, points to the action > requested > > by the > > + callback function. > > + > > + @retval EFI_SUCCESS The callback successfully handled the= action. > > + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to > hold > > the > > + variable and its data. > > + @retval EFI_DEVICE_ERROR The variable could not be saved. > > + @retval EFI_UNSUPPORTED The specified Action is not supported= by > > the > > + callback.Currently not implemented. > > + @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. > > + @retval Others Other errors as indicated. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordFormCallback ( > > + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, > > + IN EFI_BROWSER_ACTION Action, > > + IN EFI_QUESTION_ID QuestionId, > > + IN UINT8 Type, > > + IN EFI_IFR_TYPE_VALUE *Value, > > + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest > > + ) > > +{ > > + HDD_PASSWORD_DXE_PRIVATE_DATA *Private; > > + EFI_STRING_ID DeviceFormTitleToken; > > + HDD_PASSWORD_CONFIG *IfrData; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry; > > + > > + if (ActionRequest !=3D NULL) { > > + *ActionRequest =3D EFI_BROWSER_ACTION_REQUEST_NONE; > > + } else { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + if ((Action !=3D EFI_BROWSER_ACTION_CHANGING) && (Action !=3D > > EFI_BROWSER_ACTION_CHANGED)) { > > + // > > + // Do nothing for other UEFI Action. Only do call back when data i= s > > changing or changed. > > + // > > + return EFI_UNSUPPORTED; > > + } > > + > > + Private =3D HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This); > > + > > + // > > + // Retrive data from Browser > > + // > > + IfrData =3D AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG)); > > + ASSERT (IfrData !=3D NULL); > > + if (!HiiGetBrowserData (&mHddPasswordVendorGuid, > > mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), > > (UINT8 *) IfrData)) { > > + FreePool (IfrData); > > + return EFI_NOT_FOUND; > > + } > > + > > + switch (QuestionId) { > > + case KEY_HDD_USER_PASSWORD: > > + if (Action =3D=3D EFI_BROWSER_ACTION_CHANGED) { > > + DEBUG ((DEBUG_INFO, "KEY_HDD_USER_PASSWORD\n")); > > + ConfigFormEntry =3D Private->Current; > > + ConfigFormEntry->IfrData.Request.UserPassword =3D Value->b; > > + SaveHddPasswordRequest (ConfigFormEntry); > > + *ActionRequest =3D EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; > > + } > > + break; > > + case KEY_HDD_MASTER_PASSWORD: > > + if (Action =3D=3D EFI_BROWSER_ACTION_CHANGED) { > > + DEBUG ((DEBUG_INFO, "KEY_HDD_MASTER_PASSWORD\n")); > > + ConfigFormEntry =3D Private->Current; > > + ConfigFormEntry->IfrData.Request.MasterPassword =3D Value->b; > > + SaveHddPasswordRequest (ConfigFormEntry); > > + *ActionRequest =3D EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; > > + } > > + break; > > + > > + default: > > + if ((QuestionId >=3D KEY_HDD_DEVICE_ENTRY_BASE) && (QuestionId < > > (mNumberOfHddDevices + KEY_HDD_DEVICE_ENTRY_BASE))) { > > + if (Action =3D=3D EFI_BROWSER_ACTION_CHANGING) { > > + // > > + // In case goto the device configuration form, update the devi= ce form > > title. > > + // > > + ConfigFormEntry =3D HddPasswordGetConfigFormEntryByIndex > ((UINT32) > > (QuestionId - KEY_HDD_DEVICE_ENTRY_BASE)); > > + ASSERT (ConfigFormEntry !=3D NULL); > > + > > + DeviceFormTitleToken =3D (EFI_STRING_ID) STR_HDD_SECURITY_HD; > > + HiiSetString (Private->HiiHandle, DeviceFormTitleToken, > > ConfigFormEntry->HddString, NULL); > > + > > + Private->Current =3D ConfigFormEntry; > > + CopyMem (IfrData, &ConfigFormEntry->IfrData, sizeof > > (HDD_PASSWORD_CONFIG)); > > + } > > + } > > + > > + break; > > + } > > + > > + // > > + // Pass changed uncommitted data back to Form Browser > > + // > > + HiiSetBrowserData (&mHddPasswordVendorGuid, > > mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), > > (UINT8 *) IfrData, NULL); > > + > > + FreePool (IfrData); > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Updates the HDD Password configuration form to add an entry for the > > attached > > + ata harddisk device specified by the Controller. > > + > > + @param[in] HiiHandle The HII Handle associated with the > registered > > package list. > > + @param[in] AtaPassThru Pointer to ATA_PASSTHRU instance. > > + @param[in] PciIo Pointer to PCI_IO instance. > > + @param[in] Controller The controller handle of the attache= d ata > > controller. > > + @param[in] Bus The bus number of ATA controller. > > + @param[in] Device The device number of ATA controller. > > + @param[in] Function The function number of ATA controlle= r. > > + @param[in] Port The port number of attached ATA devi= ce. > > + @param[in] PortMultiplierPort The port number of port multiplier o= f > > attached ATA device. > > + > > + @retval EFI_SUCCESS The Hdd Password configuration form = is > > updated. > > + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. > > + @retval Others Other errors as indicated. > > + > > +**/ > > +EFI_STATUS > > +HddPasswordConfigUpdateForm ( > > + IN EFI_HII_HANDLE HiiHandle, > > + IN EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru, > > + IN EFI_PCI_IO_PROTOCOL *PciIo, > > + IN EFI_HANDLE Controller, > > + IN UINTN Bus, > > + IN UINTN Device, > > + IN UINTN Function, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort > > + ) > > +{ > > + LIST_ENTRY *Entry; > > + HDD_PASSWORD_CONFIG_FORM_ENTRY *ConfigFormEntry; > > + BOOLEAN EntryExisted; > > + EFI_STATUS Status; > > + VOID *StartOpCodeHandle; > > + VOID *EndOpCodeHandle; > > + EFI_IFR_GUID_LABEL *StartLabel; > > + EFI_IFR_GUID_LABEL *EndLabel; > > + CHAR16 HddString[40]; > > + ATA_IDENTIFY_DATA IdentifyData; > > + EFI_DEVICE_PATH_PROTOCOL *AtaDeviceNode; > > + > > + ConfigFormEntry =3D NULL; > > + EntryExisted =3D FALSE; > > + > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + > > + if ((ConfigFormEntry->Bus =3D=3D Bus) && > > + (ConfigFormEntry->Device =3D=3D Device) && > > + (ConfigFormEntry->Function =3D=3D Function) && > > + (ConfigFormEntry->Port =3D=3D Port) && > > + (ConfigFormEntry->PortMultiplierPort =3D=3D PortMultiplierPort= )) { > > + EntryExisted =3D TRUE; > > + break; > > + } > > + } > > + > > + if (!EntryExisted) { > > + // > > + // Add a new form. > > + // > > + ConfigFormEntry =3D AllocateZeroPool (sizeof > > (HDD_PASSWORD_CONFIG_FORM_ENTRY)); > > + if (ConfigFormEntry =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + InitializeListHead (&ConfigFormEntry->Link); > > + ConfigFormEntry->Controller =3D Controller; > > + ConfigFormEntry->Bus =3D Bus; > > + ConfigFormEntry->Device =3D Device; > > + ConfigFormEntry->Function =3D Function; > > + ConfigFormEntry->Port =3D Port; > > + ConfigFormEntry->PortMultiplierPort =3D PortMultiplierPort; > > + ConfigFormEntry->AtaPassThru =3D AtaPassThru; > > + > > + DEBUG ((DEBUG_INFO, "HddPasswordDxe: Create new form for > > device[%d][%d] at Bus 0x%x Dev 0x%x Func 0x%x\n", Port, > > PortMultiplierPort, Bus, Device, Function)); > > + > > + // > > + // Construct the device path for the HDD password device > > + // > > + Status =3D AtaPassThru->BuildDevicePath ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &AtaDeviceNode > > + ); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + ConfigFormEntry->DevicePath =3D AppendDevicePathNode > > (DevicePathFromHandle (Controller), AtaDeviceNode); > > + FreePool (AtaDeviceNode); > > + if (ConfigFormEntry->DevicePath =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Get attached harddisk model number > > + // > > + Status =3D GetHddDeviceIdentifyData (AtaPassThru, Port, > > PortMultiplierPort, &IdentifyData); > > + ASSERT_EFI_ERROR (Status); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + GetHddDeviceModelNumber (&IdentifyData, HddString); > > + // > > + // Compose the HDD title string and help string of this port and c= reate a > > new EFI_STRING_ID. > > + // > > + UnicodeSPrint (ConfigFormEntry->HddString, sizeof (ConfigFormEntry= - > > >HddString), L"HDD %d:%s", mNumberOfHddDevices, HddString); > > + ConfigFormEntry->TitleToken =3D HiiSetString (HiiHandle, 0, > > ConfigFormEntry->HddString, NULL); > > + ConfigFormEntry->TitleHelpToken =3D HiiSetString (HiiHandle, 0, > L"Request > > to set HDD Password", NULL); > > + > > + GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry- > > >IfrData); > > + > > + InsertTailList (&mHddPasswordConfigFormList, &ConfigFormEntry- > >Link); > > + > > + // > > + // Init OpCode Handle > > + // > > + StartOpCodeHandle =3D HiiAllocateOpCodeHandle (); > > + ASSERT (StartOpCodeHandle !=3D NULL); > > + > > + EndOpCodeHandle =3D HiiAllocateOpCodeHandle (); > > + ASSERT (EndOpCodeHandle !=3D NULL); > > + > > + // > > + // Create Hii Extend Label OpCode as the start opcode > > + // > > + StartLabel =3D (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode > > (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof > > (EFI_IFR_GUID_LABEL)); > > + StartLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; > > + StartLabel->Number =3D HDD_DEVICE_ENTRY_LABEL; > > + > > + // > > + // Create Hii Extend Label OpCode as the end opcode > > + // > > + EndLabel =3D (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode > > (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof > (EFI_IFR_GUID_LABEL)); > > + EndLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; > > + EndLabel->Number =3D HDD_DEVICE_LABEL_END; > > + > > + mNumberOfHddDevices =3D 0; > > + EFI_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) { > > + ConfigFormEntry =3D BASE_CR (Entry, > > HDD_PASSWORD_CONFIG_FORM_ENTRY, Link); > > + > > + HiiCreateGotoOpCode ( > > + StartOpCodeHandle, // Container= for dynamic created > > opcodes > > + FORMID_HDD_DEVICE_FORM, // Target Fo= rm ID > > + ConfigFormEntry->TitleToken, // Prompt te= xt > > + ConfigFormEntry->TitleHelpToken, // Help text > > + EFI_IFR_FLAG_CALLBACK, // Question = flag > > + (UINT16) (KEY_HDD_DEVICE_ENTRY_BASE + mNumberOfHddDevices) > > // Question ID > > + ); > > + > > + mNumberOfHddDevices++; > > + } > > + > > + HiiUpdateForm ( > > + HiiHandle, > > + &mHddPasswordVendorGuid, > > + FORMID_HDD_MAIN_FORM, > > + StartOpCodeHandle, > > + EndOpCodeHandle > > + ); > > + > > + HiiFreeOpCodeHandle (StartOpCodeHandle); > > + HiiFreeOpCodeHandle (EndOpCodeHandle); > > + > > + // > > + // Check if device is locked and prompt for password. > > + // > > + HddPasswordRequestPassword (AtaPassThru, Port, PortMultiplierPort, > > ConfigFormEntry); > > + > > + // > > + // Process HDD password request from last boot. > > + // > > + ProcessHddPasswordRequest (AtaPassThru, Port, PortMultiplierPort, > > ConfigFormEntry); > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Ata Pass Thru Protocol notification event handler. > > + > > + Check attached harddisk status to see if it's locked. If yes, then p= op up a > > password windows to require user input. > > + It also registers a form for user configuration on Hdd password > > configuration. > > + > > + @param[in] Event Event whose notification function is being invok= ed. > > + @param[in] Context Pointer to the notification function's context. > > + > > +**/ > > +VOID > > +EFIAPI > > +HddPasswordNotificationEvent ( > > + IN EFI_EVENT Event, > > + IN VOID *Context > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_DXE_PRIVATE_DATA *Private; > > + EFI_ATA_PASS_THRU_PROTOCOL *AtaPassThru; > > + UINT16 Port; > > + UINT16 PortMultiplierPort; > > + EFI_HANDLE Controller; > > + EFI_HANDLE *HandleBuffer; > > + UINTN HandleCount; > > + UINTN Index; > > + EFI_PCI_IO_PROTOCOL *PciIo; > > + UINTN SegNum; > > + UINTN BusNum; > > + UINTN DevNum; > > + UINTN FuncNum; > > + > > + if (mHddPasswordEndOfDxe) { > > + gBS->CloseEvent (Event); > > + return; > > + } > > + > > + Private =3D (HDD_PASSWORD_DXE_PRIVATE_DATA *)Context; > > + > > + // > > + // Locate all handles of AtaPassThru protocol > > + // > > + Status =3D gBS->LocateHandleBuffer ( > > + ByProtocol, > > + &gEfiAtaPassThruProtocolGuid, > > + NULL, > > + &HandleCount, > > + &HandleBuffer > > + ); > > + if (EFI_ERROR (Status)) { > > + return ; > > + } > > + > > + // > > + // Check attached hard disk status to see if it's locked > > + // > > + for (Index =3D 0; Index < HandleCount; Index +=3D 1) { > > + Controller =3D HandleBuffer[Index]; > > + Status =3D gBS->HandleProtocol ( > > + Controller, > > + &gEfiAtaPassThruProtocolGuid, > > + (VOID **) &AtaPassThru > > + ); > > + if (EFI_ERROR (Status)) { > > + break; > > + } > > + > > + // > > + // Ignore those logical ATA_PASS_THRU instance. > > + // > > + if ((AtaPassThru->Mode->Attributes & > > EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL) =3D=3D 0) { > > + continue; > > + } > > + > > + Status =3D gBS->HandleProtocol ( > > + Controller, > > + &gEfiPciIoProtocolGuid, > > + (VOID **) &PciIo > > + ); > > + ASSERT_EFI_ERROR (Status); > > + if (EFI_ERROR (Status)) { > > + break; > > + } > > + > > + Status =3D PciIo->GetLocation ( > > + PciIo, > > + &SegNum, > > + &BusNum, > > + &DevNum, > > + &FuncNum > > + ); > > + ASSERT_EFI_ERROR (Status); > > + if (EFI_ERROR (Status)) { > > + break; > > + } > > + > > + // > > + // Assume and only support Segment =3D=3D 0. > > + // > > + ASSERT (SegNum =3D=3D 0); > > + > > + // > > + // traverse all attached harddisk devices to update form and unloc= k it > > + // > > + Port =3D 0xFFFF; > > + > > + while (TRUE) { > > + Status =3D AtaPassThru->GetNextPort (AtaPassThru, &Port); > > + if (EFI_ERROR (Status)) { > > + // > > + // We cannot find more legal port then we are done. > > + // > > + break; > > + } > > + > > + PortMultiplierPort =3D 0xFFFF; > > + while (TRUE) { > > + Status =3D AtaPassThru->GetNextDevice (AtaPassThru, Port, > > &PortMultiplierPort); > > + if (EFI_ERROR (Status)) { > > + // > > + // We cannot find more legal port multiplier port number for= ATA > > device > > + // on the port, then we are done. > > + // > > + break; > > + } > > + // > > + // Find out the attached harddisk devices. > > + // Try to add a HDD Password configuration page for the attach= ed > > devices. > > + // > > + gBS->RestoreTPL (TPL_APPLICATION); > > + Status =3D HddPasswordConfigUpdateForm (Private->HiiHandle, > > AtaPassThru, PciIo, Controller, BusNum, DevNum, FuncNum, Port, > > PortMultiplierPort); > > + gBS->RaiseTPL (TPL_CALLBACK); > > + if (EFI_ERROR (Status)) { > > + break; > > + } > > + } > > + } > > + } > > + > > + FreePool (HandleBuffer); > > + return ; > > +} > > + > > +/** > > + Initialize the HDD Password configuration form. > > + > > + @param[out] Instance Pointer to private instance. > > + > > + @retval EFI_SUCCESS The HDD Password configuration form= is > > initialized. > > + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. > > + @retval Others Other errors as indicated. > > +**/ > > +EFI_STATUS > > +HddPasswordConfigFormInit ( > > + OUT HDD_PASSWORD_DXE_PRIVATE_DATA **Instance > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_DXE_PRIVATE_DATA *Private; > > + > > + InitializeListHead (&mHddPasswordConfigFormList); > > + > > + Private =3D AllocateZeroPool (sizeof > > (HDD_PASSWORD_DXE_PRIVATE_DATA)); > > + if (Private =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + Private->Signature =3D HDD_PASSWORD_DXE_PRIVATE_SIGNATURE; > > + > > + Private->ConfigAccess.ExtractConfig =3D HddPasswordFormExtractConfig= ; > > + Private->ConfigAccess.RouteConfig =3D HddPasswordFormRouteConfig; > > + Private->ConfigAccess.Callback =3D HddPasswordFormCallback; > > + > > + // > > + // Install Device Path Protocol and Config Access protocol to driver > handle > > + // > > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > > + &Private->DriverHandle, > > + &gEfiDevicePathProtocolGuid, > > + &mHddPasswordHiiVendorDevicePath, > > + &gEfiHiiConfigAccessProtocolGuid, > > + &Private->ConfigAccess, > > + NULL > > + ); > > + ASSERT_EFI_ERROR (Status); > > + if (EFI_ERROR (Status)) { > > + FreePool(Private); > > + return Status; > > + } > > + > > + // > > + // Publish our HII data > > + // > > + Private->HiiHandle =3D HiiAddPackages ( > > + &mHddPasswordVendorGuid, > > + Private->DriverHandle, > > + HddPasswordDxeStrings, > > + HddPasswordBin, > > + NULL > > + ); > > + if (Private->HiiHandle =3D=3D NULL) { > > + FreePool(Private); > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + *Instance =3D Private; > > + return Status; > > +} > > + > > +/** > > + Main entry for this driver. > > + > > + @param ImageHandle Image handle this driver. > > + @param SystemTable Pointer to SystemTable. > > + > > + @retval EFI_SUCESS This function always complete successfully. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordDxeInit ( > > + IN EFI_HANDLE ImageHandle, > > + IN EFI_SYSTEM_TABLE *SystemTable > > + ) > > +{ > > + EFI_STATUS Status; > > + HDD_PASSWORD_DXE_PRIVATE_DATA *Private; > > + EFI_EVENT Registration; > > + EFI_EVENT EndOfDxeEvent; > > + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; > > + > > + Private =3D NULL; > > + > > + // > > + // Initialize the configuration form of HDD Password. > > + // > > + Status =3D HddPasswordConfigFormInit (&Private); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + // > > + // Register HddPasswordNotificationEvent() notify function. > > + // > > + EfiCreateProtocolNotifyEvent ( > > + &gEfiAtaPassThruProtocolGuid, > > + TPL_CALLBACK, > > + HddPasswordNotificationEvent, > > + (VOID *)Private, > > + &Registration > > + ); > > + > > + Status =3D gBS->CreateEventEx ( > > + EVT_NOTIFY_SIGNAL, > > + TPL_CALLBACK, > > + HddPasswordEndOfDxeEventNotify, > > + NULL, > > + &gEfiEndOfDxeEventGroupGuid, > > + &EndOfDxeEvent > > + ); > > + ASSERT_EFI_ERROR (Status); > > + > > + // > > + // Make HDD_PASSWORD_VARIABLE_NAME varible read-only. > > + // > > + Status =3D gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NUL= L, > > (VOID **) &VariableLock); > > + if (!EFI_ERROR (Status)) { > > + Status =3D VariableLock->RequestToLock ( > > + VariableLock, > > + HDD_PASSWORD_VARIABLE_NAME, > > + &mHddPasswordVendorGuid > > + ); > > + DEBUG ((DEBUG_INFO, "%a(): Lock %s variable (%r)\n", > __FUNCTION__, > > HDD_PASSWORD_VARIABLE_NAME, Status)); > > + ASSERT_EFI_ERROR (Status); > > + } > > + > > + return Status; > > +} > > diff --git a/SecurityPkg/HddPassword/HddPasswordPei.c > > b/SecurityPkg/HddPassword/HddPasswordPei.c > > new file mode 100644 > > index 0000000000..3f04f03d0b > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordPei.c > > @@ -0,0 +1,461 @@ > > +/** @file > > + HddPassword PEI module which is used to unlock HDD password for S3. > > + > > + Copyright (c) 2019, 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 IMPLIED. > > + > > +**/ > > + > > +#include "HddPasswordPei.h" > > + > > +EFI_GUID mHddPasswordDeviceInfoGuid =3D > > HDD_PASSWORD_DEVICE_INFO_GUID; > > + > > +/** > > + Tell whether the input EDKII_PEI_ATA_PASS_THRU_PPI instance has > > already been > > + handled by the HddPassword PEI driver. > > + > > + @param[in] Private Pointer to the HddPassword PEI driver= private > > data. > > + @param[in] PassThruInstance Pointer to the > > EDKII_PEI_ATA_PASS_THRU_PPI. > > + > > + @retval TRUE The PPI instance has already been handled. > > + @retval FALSE The PPI instance has not been handled before. > > + > > +**/ > > +BOOLEAN > > +IsPassThruInstanceHandled ( > > + IN HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA *Private, > > + IN EDKII_PEI_ATA_PASS_THRU_PPI *PassThruInstance > > + ) > > +{ > > + UINTN Index; > > + > > + for (Index =3D 0; Index < Private->AtaPassThruPpiInstanceNum; Index+= +) { > > + if ((UINTN)PassThruInstance =3D=3D Private- > >AtaPassThruPpiInstances[Index]) > > { > > + return TRUE; > > + } > > + } > > + > > + return FALSE; > > +} > > + > > +/** > > + Send unlock hdd password cmd through ATA PassThru PPI. > > + > > + @param[in] AtaPassThru The pointer to the ATA PassThru PPI= . > > + @param[in] Port The port number of the ATA device. > > + @param[in] PortMultiplierPort The port multiplier port number of = the > > ATA device. > > + @param[in] Identifier The identifier to set user or maste= r password. > > + @param[in] Password The hdd password of attached ATA de= vice. > > + > > + @retval EFI_SUCCESS Successful to send unlock hdd passw= ord > cmd. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to send unlock > > hdd password cmd. > > + @retval EFI_DEVICE_ERROR Can not send unlock hdd password cm= d. > > + > > +**/ > > +EFI_STATUS > > +UnlockDevice ( > > + IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort, > > + IN CHAR8 Identifier, > > + IN CHAR8 *Password > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + UINT8 Buffer[HDD_PAYLOAD]; > > + > > + if ((AtaPassThru =3D=3D NULL) || (Password =3D=3D NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_UNLOCK_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_BYTES; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + > > + ((CHAR16 *) Buffer)[0] =3D Identifier & BIT0; > > + CopyMem (&((CHAR16 *) Buffer)[1], Password, > > HDD_PASSWORD_MAX_LENGTH); > > + > > + Packet.OutDataBuffer =3D Buffer; > > + Packet.OutTransferLength =3D sizeof (Buffer); > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + ZeroMem (Buffer, sizeof (Buffer)); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Send security freeze lock cmd through ATA PassThru PPI. > > + > > + @param[in] AtaPassThru The pointer to the ATA PassThru PPI= . > > + @param[in] Port The port number of the ATA device. > > + @param[in] PortMultiplierPort The port multiplier port number of = the > > ATA device. > > + > > + @retval EFI_SUCCESS Successful to send security freeze = lock cmd. > > + @retval EFI_INVALID_PARAMETER The parameter passed-in is invalid. > > + @retval EFI_OUT_OF_RESOURCES Not enough memory to send unlock > > hdd password cmd. > > + @retval EFI_DEVICE_ERROR Can not send security freeze lock c= md. > > + > > +**/ > > +EFI_STATUS > > +FreezeLockDevice ( > > + IN EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru, > > + IN UINT16 Port, > > + IN UINT16 PortMultiplierPort > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_ATA_COMMAND_BLOCK Acb; > > + EFI_ATA_STATUS_BLOCK *Asb; > > + EFI_ATA_PASS_THRU_COMMAND_PACKET Packet; > > + > > + if (AtaPassThru =3D=3D NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // > > + // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure)= in > > + // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned > > specified by > > + // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. > > Meanwhile, > > + // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 > fields, > > so it > > + // may not be aligned when allocated on stack for some compilers. > Hence, > > we > > + // use the API AllocateAlignedPages to ensure this structure is prop= erly > > + // aligned. > > + // > > + Asb =3D AllocateAlignedPages ( > > + EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)), > > + AtaPassThru->Mode->IoAlign > > + ); > > + if (Asb =3D=3D NULL) { > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + // > > + // Prepare for ATA command block. > > + // > > + ZeroMem (&Acb, sizeof (Acb)); > > + ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK)); > > + Acb.AtaCommand =3D ATA_SECURITY_FREEZE_LOCK_CMD; > > + Acb.AtaDeviceHead =3D (UINT8) (PortMultiplierPort =3D=3D 0xFFFF ? 0 = : > > (PortMultiplierPort << 4)); > > + > > + // > > + // Prepare for ATA pass through packet. > > + // > > + ZeroMem (&Packet, sizeof (Packet)); > > + Packet.Protocol =3D EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA; > > + Packet.Length =3D EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER; > > + Packet.Asb =3D Asb; > > + Packet.Acb =3D &Acb; > > + Packet.Timeout =3D ATA_TIMEOUT; > > + > > + Status =3D AtaPassThru->PassThru ( > > + AtaPassThru, > > + Port, > > + PortMultiplierPort, > > + &Packet > > + ); > > + if (!EFI_ERROR (Status) && > > + ((Asb->AtaStatus & ATA_STSREG_ERR) !=3D 0) && > > + ((Asb->AtaError & ATA_ERRREG_ABRT) !=3D 0)) { > > + Status =3D EFI_DEVICE_ERROR; > > + } > > + > > + FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof > > (EFI_ATA_STATUS_BLOCK))); > > + > > + DEBUG ((DEBUG_INFO, "%a() - %r\n", __FUNCTION__, Status)); > > + return Status; > > +} > > + > > +/** > > + Unlock HDD password for S3. > > + > > + @param[in] Private Pointer to the HddPassword PEI driver private = data. > > + > > +**/ > > +VOID > > +UnlockHddPassword ( > > + IN HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA *Private > > + ) > > +{ > > + EFI_STATUS Status; > > + VOID *Buffer; > > + UINTN Length; > > + UINT8 DummyData; > > + HDD_PASSWORD_DEVICE_INFO *DevInfo; > > + UINTN AtaPassThruInstance; > > + EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThruPpi; > > + UINT16 Port; > > + UINT16 PortMultiplierPort; > > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > > + UINTN DevicePathLength; > > + > > + // > > + // Get HDD password device info from LockBox. > > + // > > + Buffer =3D (VOID *) &DummyData; > > + Length =3D 1; > > + Status =3D RestoreLockBox (&mHddPasswordDeviceInfoGuid, Buffer, > > &Length); > > + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > > + Buffer =3D AllocatePages (EFI_SIZE_TO_PAGES (Length)); > > + if (Buffer !=3D NULL) { > > + Status =3D RestoreLockBox (&mHddPasswordDeviceInfoGuid, Buffer, > > &Length); > > + } > > + } > > + if ((Buffer =3D=3D NULL) || (Buffer =3D=3D (VOID *) &DummyData)) { > > + return; > > + } else if (EFI_ERROR (Status)) { > > + FreePages (Buffer, EFI_SIZE_TO_PAGES (Length)); > > + return; > > + } > > + > > + // > > + // Go through the ATA PassThru PPI instances within system. > > + // > > + for (AtaPassThruInstance =3D 0; > > + AtaPassThruInstance < MAX_ATA_PASSTHRU_PPI; > > + AtaPassThruInstance++) { > > + Status =3D PeiServicesLocatePpi ( > > + &gEdkiiPeiAtaPassThruPpiGuid, > > + AtaPassThruInstance, > > + NULL, > > + (VOID **) &AtaPassThruPpi > > + ); > > + if (EFI_ERROR (Status)) { > > + // > > + // No more EDKII_PEI_ATA_PASS_THRU_PPI instances. > > + // > > + break; > > + } > > + > > + // > > + // Check whether this PPI instance has been handled previously. > > + // > > + if (IsPassThruInstanceHandled (Private, AtaPassThruPpi)) { > > + DEBUG (( > > + DEBUG_INFO, "%a: ATA PassThru PPI instance (0x%p) already > > handled.\n", > > + __FUNCTION__, (UINTN)AtaPassThruPpi > > + )); > > + continue; > > + } else { > > + DEBUG (( > > + DEBUG_INFO, "%a: New ATA PassThru PPI instance (0x%p) found.\n= ", > > + __FUNCTION__, (UINTN)AtaPassThruPpi > > + )); > > + Private->AtaPassThruPpiInstances[Private- > > >AtaPassThruPpiInstanceNum] =3D (UINTN)AtaPassThruPpi; > > + Private->AtaPassThruPpiInstanceNum++; > > + } > > + > > + Status =3D AtaPassThruPpi->GetDevicePath (AtaPassThruPpi, > > &DevicePathLength, &DevicePath); > > + if (EFI_ERROR (Status) || (DevicePathLength <=3D sizeof > > (EFI_DEVICE_PATH_PROTOCOL))) { > > + continue; > > + } > > + > > + // > > + // Go through all the devices managed by this PPI instance. > > + // > > + Port =3D 0xFFFF; > > + while (TRUE) { > > + Status =3D AtaPassThruPpi->GetNextPort (AtaPassThruPpi, &Port); > > + if (EFI_ERROR (Status)) { > > + // > > + // We cannot find more legal port then we are done. > > + // > > + break; > > + } > > + > > + PortMultiplierPort =3D 0xFFFF; > > + while (TRUE) { > > + Status =3D AtaPassThruPpi->GetNextDevice (AtaPassThruPpi, Port= , > > &PortMultiplierPort); > > + if (EFI_ERROR (Status)) { > > + // > > + // We cannot find more legal port multiplier port number for= ATA > > device > > + // on the port, then we are done. > > + // > > + break; > > + } > > + > > + // > > + // Search the device in the restored LockBox. > > + // > > + DevInfo =3D (HDD_PASSWORD_DEVICE_INFO *) Buffer; > > + while ((UINTN) DevInfo < ((UINTN) Buffer + Length)) { > > + // > > + // Find the matching device. > > + // > > + if ((DevInfo->Device.Port =3D=3D Port) && > > + (DevInfo->Device.PortMultiplierPort =3D=3D PortMultiplie= rPort) && > > + (DevInfo->DevicePathLength >=3D DevicePathLength) && > > + (CompareMem ( > > + DevInfo->DevicePath, > > + DevicePath, > > + DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)) = =3D=3D 0)) > { > > + // > > + // If device locked, unlock first. > > + // > > + if (!IsZeroBuffer (DevInfo->Password, > > HDD_PASSWORD_MAX_LENGTH)) { > > + UnlockDevice (AtaPassThruPpi, Port, PortMultiplierPort, = 0, > DevInfo- > > >Password); > > + } > > + // > > + // Freeze lock the device. > > + // > > + FreezeLockDevice (AtaPassThruPpi, Port, PortMultiplierPort= ); > > + break; > > + } > > + > > + DevInfo =3D (HDD_PASSWORD_DEVICE_INFO *) > > + ((UINTN) DevInfo + sizeof (HDD_PASSWORD_DEVICE_INF= O) + > > DevInfo->DevicePathLength); > > + } > > + } > > + } > > + } > > + > > + ZeroMem (Buffer, Length); > > + FreePages (Buffer, EFI_SIZE_TO_PAGES (Length)); > > + > > +} > > + > > +/** > > + Entry point of the notification callback function itself within the = PEIM. > > + It is to unlock HDD password for S3. > > + > > + @param PeiServices Indirect reference to the PEI Services Tabl= e. > > + @param NotifyDescriptor Address of the notification descriptor data > > structure. > > + @param Ppi Address of the PPI that was installed. > > + > > + @return Status of the notification. > > + The status code returned from this function is ignored. > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordAtaPassThruNotify ( > > + IN EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, > > + IN VOID *Ppi > > + ) > > +{ > > + HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA *Private; > > + > > + DEBUG ((DEBUG_INFO, "%a() - enter at S3 resume\n", __FUNCTION__)); > > + > > + Private =3D HDD_PASSWORD_PEI_PRIVATE_DATA_FROM_THIS_NOTIFY > > (NotifyDesc); > > + UnlockHddPassword (Private); > > + > > + DEBUG ((DEBUG_INFO, "%a() - exit at S3 resume\n", __FUNCTION__)); > > + > > + return EFI_SUCCESS; > > +} > > + > > +HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA > > mHddPasswordPeiDriverPrivateTemplate =3D { > > + HDD_PASSWORD_PEI_DRIVER_SIGNATURE, // Signature > > + { // AtaPassThruPpiNotifyList > > + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > + &gEdkiiPeiAtaPassThruPpiGuid, > > + HddPasswordAtaPassThruNotify > > + }, > > + 0, // AtaPassThruPpiInstanceNum > > + {0} // AtaPassThruPpiInstances > > +}; > > + > > +/** > > + Main entry for this module. > > + > > + @param FileHandle Handle of the file being invoked. > > + @param PeiServices Pointer to PEI Services table. > > + > > + @return Status from PeiServicesNotifyPpi. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +HddPasswordPeiInit ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + IN CONST EFI_PEI_SERVICES **PeiServices > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_BOOT_MODE BootMode; > > + HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA *Private; > > + > > + Status =3D PeiServicesGetBootMode (&BootMode); > > + if ((EFI_ERROR (Status)) || (BootMode !=3D BOOT_ON_S3_RESUME)) { > > + return EFI_UNSUPPORTED; > > + } > > + > > + DEBUG ((DEBUG_INFO, "%a: Enters in S3 path.\n", __FUNCTION__)); > > + > > + Private =3D (HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA *) > > + AllocateCopyPool ( > > + sizeof (HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA), > > + &mHddPasswordPeiDriverPrivateTemplate > > + ); > > + if (Private =3D=3D NULL) { > > + DEBUG (( > > + DEBUG_ERROR, > > + "%a: Failed to allocate memory for > > HDD_PASSWORD_PEI_DRIVER_PRIVATE_DATA.\n", > > + __FUNCTION__ > > + )); > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + Status =3D PeiServicesNotifyPpi (&Private->AtaPassThruPpiNotifyList)= ; > > + ASSERT_EFI_ERROR (Status); > > + return Status; > > +} > > + > > diff --git a/SecurityPkg/HddPassword/HddPasswordStrings.uni > > b/SecurityPkg/HddPassword/HddPasswordStrings.uni > > new file mode 100644 > > index 0000000000..455ecfcd02 > > --- /dev/null > > +++ b/SecurityPkg/HddPassword/HddPasswordStrings.uni > > @@ -0,0 +1,48 @@ > > +// /** @file > > +// String definitions for HddPassword Setup Form. > > +// > > +// Copyright (c) 2019, 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 IMPLIED. > > +// > > +// **/ > > + > > +#langdef en-US "English" > > + > > +#string STR_HDD_SECURITY_CONFIG #language en-US "HDD > Security > > Configuration" > > + > > +#string STR_SECURITY_HDD_PWD_DESC #language en-US "HDD > > Password Description :" > > + > > +#string STR_SECURITY_HDD_BANNER_ONE #language en-US "Allows > > Access to Set, Modify and Clear HardDisk User and" > > +#string STR_SECURITY_HDD_BANNER_TWO #language en-US > "Master > > Passwords." > > +#string STR_SECURITY_HDD_BANNER_THREE #language en-US "User > > Password need to be installed for Enabling Security." > > +#string STR_SECURITY_HDD_BANNER_FOUR #language en-US > "Master > > Password can be modified only when succesfully" > > +#string STR_SECURITY_HDD_BANNER_FIVE #language en-US > "unlocked > > with User Password in POST." > > + > > +#string STR_HDD_SECURITY_HD #language en-US "HDD > Password" > > +#string STR_HDD_SECURITY_HELP #language en-US "Set HDD > > Password" > > +#string STR_HDD_PASSWORD_CONFIG #language en-US "HDD > > PASSWORD CONFIGURATION:" > > +#string STR_SEC_SUPPORTED #language en-US "Securit= y > > Supported :" > > +#string STR_SEC_ENABLED #language en-US "Securit= y > > Enabled :" > > +#string STR_SEC_LOCKED #language en-US "Securit= y > > Locked :" > > +#string STR_SEC_FROZEN #language en-US "Securit= y > > Frozen :" > > +#string STR_YES #language en-US "Yes" > > +#string STR_NO #language en-US "No" > > +#string STR_HDD_USER_PASSWORD #language en-US "Request > to > > set User Password" > > +#string STR_HDD_USER_PASSWORD_HELP #language en-US > "Request > > to set HDD User Password. \n*** Reset is required for the request to be > > processed in next boot *** \n*** G3 circle is required to disable freez= e > state > > when Security Frozen state is Yes, otherwise the request will be ignore= d. > *** > > " > > +#string STR_HDD_MASTER_PASSWORD #language en-US "Request > > to set Master Password" > > +#string STR_HDD_MASTER_PASSWORD_HELP #language en-US > > "Request to set HDD Master Password. \n*** Reset is required for the > > request to be processed in next boot *** \n*** G3 circle is required to > > disable freeze state when Security Frozen state is Yes, otherwise the > request > > will be ignored. *** " > > + > > +#string STR_INSTALLED #language en-US "INSTALL= ED" > > +#string STR_NOT_INSTALLED #language en-US "NOT > INSTALLED" > > +#string STR_HDD_USER_PASSWORD_STS #language en-US "HDD > User > > Password Status :" > > +#string STR_HDD_MASTER_PASSWORD_STS #language en-US "HDD > > Master Password Status:" > > +#string STR_NULL #language en-US "" > > +#string STR_EMPTY #language en-US "" > > -- > > 2.12.0.windows.1