From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web10.445.1575417459945456390 for ; Tue, 03 Dec 2019 15:57:40 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: nathaniel.l.desimone@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Dec 2019 15:57:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,275,1571727600"; d="scan'208";a="223018389" Received: from orsmsx101.amr.corp.intel.com ([10.22.225.128]) by orsmga002.jf.intel.com with ESMTP; 03 Dec 2019 15:57:37 -0800 Received: from orsmsx113.amr.corp.intel.com (10.22.240.9) by ORSMSX101.amr.corp.intel.com (10.22.225.128) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 3 Dec 2019 15:57:37 -0800 Received: from orsmsx114.amr.corp.intel.com ([169.254.8.67]) by ORSMSX113.amr.corp.intel.com ([169.254.9.200]) with mapi id 14.03.0439.000; Tue, 3 Dec 2019 15:57:36 -0800 From: "Nate DeSimone" To: "devel@edk2.groups.io" , "Kubacki, Michael A" CC: "Bi, Dandan" , "Gao, Liming" Subject: Re: [edk2-devel] [edk2-platforms][PATCH V2 20/47] Features/Intel/UserAuthFeaturePkg: Add initial package Thread-Topic: [edk2-devel] [edk2-platforms][PATCH V2 20/47] Features/Intel/UserAuthFeaturePkg: Add initial package Thread-Index: AQHVpYhAX7zTodnkWkK2FKaTSKkTqKepHxQA Date: Tue, 3 Dec 2019 23:57:35 +0000 Message-ID: <02A34F284D1DA44BB705E61F7180EF0AB5C13E0C@ORSMSX114.amr.corp.intel.com> References: <20191128010614.43628-1-michael.a.kubacki@intel.com> <20191128010614.43628-21-michael.a.kubacki@intel.com> In-Reply-To: <20191128010614.43628-21-michael.a.kubacki@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMjhkZDFlZDgtOGM0MS00MjYwLTk2MzAtZWQxNzRiYWE2MzU2IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiNnhINEc5N1pcL2ZVbkhHcFFRK3JTQURyNGdkaHJucFNXVnl6eGg0K05DZmhNeVZWY3BEdndUOGtPUTY5VHlSMlEifQ== x-ctpclassification: CTP_NT x-originating-ip: [10.22.254.138] MIME-Version: 1.0 Return-Path: nathaniel.l.desimone@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Nate DeSimone -----Original Message----- From: devel@edk2.groups.io On Behalf Of Kubacki, Mi= chael A Sent: Wednesday, November 27, 2019 5:06 PM To: devel@edk2.groups.io Cc: Bi, Dandan ; Gao, Liming Subject: [edk2-devel] [edk2-platforms][PATCH V2 20/47] Features/Intel/User= AuthFeaturePkg: Add initial package Adds a new feature package for the User Authentication feature. Cc: Dandan Bi Cc: Liming Gao Signed-off-by: Michael Kubacki --- Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec = | 49 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Include/UserAuthFeature.d= sc | 141 ++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dsc = | 30 + Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PostMemory.fdf = | 12 + Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PreMemory.fdf = | 8 + Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPasswordL= ibNull/PlatformPasswordLibNull.inf | 38 + Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPasswordLib/U= serPasswordLib.inf | 37 + Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPasswordUiLib= /UserPasswordUiLib.inf | 41 + Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthentication2Dxe.inf | 52 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxe.inf | 62 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationSmm.inf | 53 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Guid/UserAuthenti= cation.h | 45 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/PlatformP= asswordLib.h | 48 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/UserPassw= ordLib.h | 70 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/UserPassw= ordUiLib.h | 37 + Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= KeyService.h | 88 +++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthentication2Dxe.h | 55 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxe.h | 138 ++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxeFormset.h | 23 + Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationSmm.h | 52 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxeVfr.vfr | 39 + Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPasswordL= ibNull/PlatformPasswordLibNull.c | 78 ++ Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPasswordLib/U= serPasswordLib.c | 274 +++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPasswordUiLib= /UserPasswordUiLib.c | 522 +++++++++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= KeyService.c | 133 ++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthentication2Dxe.c | 484 ++++++++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxe.c | 780 ++++++++++++++++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxePassword.c | 319 ++++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationSmm.c | 674 +++++++++++++++++ Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPasswordL= ibNull/PlatformPasswordLibNull.uni | 19 + Features/Intel/UserInterface/UserAuthFeaturePkg/Readme.md = | 90 +++ Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/= UserAuthenticationDxeStrings.uni | 30 + 32 files changed, 4521 insertions(+) diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeatu= rePkg.dec b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeature= Pkg.dec new file mode 100644 index 0000000000..a9174edd54 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.d= ec @@ -0,0 +1,49 @@ +## @file +# This package provides advanced feature functionality for User Authentic= ation support. +# This package should only depend on EDK II Core packages, IntelSiliconPk= g, and MinPlatformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION =3D 0x00010017 + PACKAGE_NAME =3D UserAuthFeaturePkg + PACKAGE_GUID =3D 08737161-3956-422A-9ABD-FCE3C8DBA3D4 + PACKAGE_VERSION =3D 0.1 + +[Includes] + Include + +[LibraryClasses] + ## @libraryclass Provides a platform-specific method to return the pa= ssword policy. + PlatformPasswordLib|Include/Library/PlatformPasswordLib.h + + ## @libraryclass Provides services to set/verify the password and ret= urn if the password is set. + UserPasswordLib|Include/Library/UserPasswordLib.h + + ## @libraryclass Provides services to perform password authentication= . + UserPasswordUiLib|Include/Library/UserPasswordUiLib.h + +[Guids] + gUserAuthFeaturePkgTokenSpaceGuid =3D {0xa2793a6e, 0x6af1, 0x45c4, {0= x88, 0x4d, 0x3d, 0x0c, 0x7a, 0xfe, 0x91, 0xc6}} + + ## Include Include/Guid/UserAuthentication.h + gUserAuthenticationGuid =3D { 0xee24a7f7, 0x606b, 0x4724, { 0xb3, 0xc9,= 0xf5, 0xae, 0x4a, 0x3b, 0x81, 0x65}} + +[PcdsFeatureFlag] + ## This PCD specifies whether StatusCode is reported via USB3 Serial po= rt. + gUserAuthFeaturePkgTokenSpaceGuid.PcdUserAuthenticationFeatureEnable|FA= LSE|BOOLEAN|0xA0000001 + +[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx] + ## Indicate whether the password is cleared. + # When it is configured to Dynamic or DynamicEx, it can be set through = detection using + # a platform-specific method (e.g. Board Jumper set) in a actual platfo= rm in early boot phase.

+ # @Prompt The password clear status + gUserAuthFeaturePkgTokenSpaceGuid.PcdPasswordCleared|FALSE|BOOLEAN|0xF0= 000001 diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/UserA= uthFeature.dsc b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Us= erAuthFeature.dsc new file mode 100644 index 0000000000..e8d9a639bc --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/UserAuthFeat= ure.dsc @@ -0,0 +1,141 @@ +## @file +# This is a build description file for the User Authentication advanced f= eature. +# This file should be included into another package DSC file to build thi= s feature. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +#########################################################################= ####### +# +# Defines Section - statements that will be processed to create a Makefil= e. +# +#########################################################################= ####### +[Defines] +!ifndef $(PEI_ARCH) + !error "PEI_ARCH must be specified to build this feature!" +!endif +!ifndef $(DXE_ARCH) + !error "DXE_ARCH must be specified to build this feature!" +!endif + +#########################################################################= ####### +# +# Library Class section - list of all Library Classes needed by this feat= ure. +# +#########################################################################= ####### +[LibraryClasses] + ####################################### + # Edk2 Packages + ####################################### + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTempla= te.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo= otServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntr= yPoint.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServi= cesLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/= UefiRuntimeServicesTableLib.inf + + ##################################### + # User Authentication Feature Package + ##################################### + PlatformPasswordLib|UserInterface/UserAuthFeaturePkg/Library/PlatformPa= sswordLibNull/PlatformPasswordLibNull.inf + UserPasswordLib|UserInterface/UserAuthFeaturePkg/Library/UserPasswordLi= b/UserPasswordLib.inf + +[LibraryClasses.common.DXE_DRIVER] + ####################################### + # Edk2 Packages + ####################################### + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAl= locationLib.inf + +[LibraryClasses.common.DXE_SMM_DRIVER] + ####################################### + # Edk2 Packages + ####################################### + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf + MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllo= cationLib.inf + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTable= Lib.inf + +#########################################################################= ########################## +# +# Components Section - list of the modules and components that will be pr= ocessed by compilation +# tools and the EDK II tools to generate PE32/PE32+/= Coff image files. +# +# Note: The EDK II DSC file is not used to specify how compiled binary im= ages get placed +# into firmware volume images. This section is just a list of modul= es to compile from +# source into UEFI-compliant binaries. +# It is the FDF file that contains information on combining binary = files into firmware +# volume images, whose concept is beyond UEFI and is described in P= I specification. +# Binary modules do not need to be listed in this section, as they = should be +# specified in the FDF file. For example: Shell binary (Shell_Full.= efi), FAT binary (Fat.efi), +# Logo (Logo.bmp), and etc. +# There may also be modules listed in this section that are not req= uired in the FDF file, +# When a module listed here is excluded from FDF file, then UEFI-co= mpliant binary will be +# generated for it, but the binary will not be put into any firmwar= e volume. +# +#########################################################################= ########################## +# +# Feature PEI Components +# + +# @todo: Change below line to [Components.$(PEI_ARCH)] after https://bugz= illa.tianocore.org/show_bug.cgi?id=3D2308 +# is completed. +[Components.IA32] + ##################################### + # User Authentication Feature Package + ##################################### + + # Add library instances here that are not included in package component= s and should be tested + # in the package build. + + # Add components here that should be included in the package build. + +# +# Feature DXE Components +# + +# @todo: Change below line to [Components.$(DXE_ARCH)] after https://bugz= illa.tianocore.org/show_bug.cgi?id=3D2308 +# is completed. +[Components.X64] + ##################################### + # User Authentication Feature Package + ##################################### + + # Add library instances here that are not included in package component= s and should be tested + # in the package build. + UserInterface/UserAuthFeaturePkg/Library/UserPasswordUiLib/UserPassword= UiLib.inf + + # Add components here that should be included in the package build. + UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthentic= ationDxe.inf + UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthentic= ation2Dxe.inf + UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthentic= ationSmm.inf + +#########################################################################= ########################## +# +# BuildOptions Section - Define the module specific tool chain flags that= should be used as +# the default flags for a module. These flags are = appended to any +# standard flags that are defined by the build pro= cess. They can be +# applied for any modules or only those modules wi= th the specific +# module style (EDK or EDKII) specified in [Compon= ents] section. +# +# For advanced features, it is recommended to enab= le [BuildOptions] in +# the applicable INF file so it does not affect th= e whole board package +# build when this DSC file is active. +# +#########################################################################= ########################## +[BuildOptions] diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeatu= rePkg.dsc b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeature= Pkg.dsc new file mode 100644 index 0000000000..74eb9213ce --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.d= sc @@ -0,0 +1,30 @@ +## @file +# This is a build description file for the User Authentication advanced f= eature. +# This package should only depend on EDK II Core packages, IntelSiliconPk= g, and MinPlatformPkg. +# +# The DEC files are used by the utilities that parse DSC and +# INF files to generate AutoGen.c and AutoGen.h files +# for the build infrastructure. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME =3D UserAuthFeaturePkg + PLATFORM_GUID =3D E859E721-41C7-46A9-98DE-8C2F29097880 + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES =3D IA32|X64 + BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER =3D DEFAULT + PEI_ARCH =3D IA32 + DXE_ARCH =3D X64 + +# +# This package always builds the feature. +# +!include Include/UserAuthFeature.dsc diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PostM= emory.fdf b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PostMem= ory.fdf new file mode 100644 index 0000000000..f0b33aa44c --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PostMemory.f= df @@ -0,0 +1,12 @@ +## @file +# FDF file for post-memory modules that enable User Authentication. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + INF UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthe= nticationDxe.inf + INF UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthe= ntication2Dxe.inf + INF UserInterface/UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthe= nticationSmm.inf diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PreMe= mory.fdf b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PreMemor= y.fdf new file mode 100644 index 0000000000..512d1a2673 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/PreMemory.fd= f @@ -0,0 +1,8 @@ +## @file +# FDF file for pre-memory modules that enable User Authentication. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/Platf= ormPasswordLibNull/PlatformPasswordLibNull.inf b/Features/Intel/UserInterfa= ce/UserAuthFeaturePkg/Library/PlatformPasswordLibNull/PlatformPasswordLibNu= ll.inf new file mode 100644 index 0000000000..00be14df8a --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPass= wordLibNull/PlatformPasswordLibNull.inf @@ -0,0 +1,38 @@ +## @file +# NULL platform password library instance that returns the password clea= r state based upon PCD. +# +# NULL PlatformPasswordLib instance does NOT really detect whether the p= assword is cleared +# but returns the PCD value directly. This instance can be used to verif= y security +# related features during platform enabling and development. It should b= e replaced +# by a platform-specific method(e.g. Button pressed) in a real platform = for product. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D PlatformPasswordLibNull + MODULE_UNI_FILE =3D PlatformPasswordLibNull.uni + FILE_GUID =3D 27417BCA-0CCD-4089-9711-AD069A33C555 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformPasswordLib|DXE_RUNTIME_DRIV= ER DXE_SMM_DRIVER DXE_DRIVER + CONSTRUCTOR =3D PlatformPasswordLibNullConstructor + +# +# The following information is for reference only and not required by the= build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + PlatformPasswordLibNull.c + +[Packages] + MdePkg/MdePkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[Pcd] + gUserAuthFeaturePkgTokenSpaceGuid.PcdPasswordCleared ## CONSUMES diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserP= asswordLib/UserPasswordLib.inf b/Features/Intel/UserInterface/UserAuthFeatu= rePkg/Library/UserPasswordLib/UserPasswordLib.inf new file mode 100644 index 0000000000..99d84ae637 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPassword= Lib/UserPasswordLib.inf @@ -0,0 +1,37 @@ +## @file +# UserPasswordLib instance provides services to set/verify password +# and return if the password is set. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UserPasswordLib + FILE_GUID =3D 422BA58A-F162-4ECC-BD9A-AD84FE940F37 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D UserPasswordLib|DXE_RUNTIME_DRIVER D= XE_SMM_DRIVER DXE_DRIVER UEFI_APPLICATION + +[Sources] + UserPasswordLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + DebugLib + UefiLib + BaseMemoryLib + +[Guids] + gUserAuthenticationGuid ## CONSUMES ## GUID + gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTab= le + +[Protocols] + gEfiSmmCommunicationProtocolGuid ## CONSUMES diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserP= asswordUiLib/UserPasswordUiLib.inf b/Features/Intel/UserInterface/UserAuthF= eaturePkg/Library/UserPasswordUiLib/UserPasswordUiLib.inf new file mode 100644 index 0000000000..9ab7d83319 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPassword= UiLib/UserPasswordUiLib.inf @@ -0,0 +1,41 @@ +## @file +# UserPasswordUiLib instance provides services to do password authentica= tion. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UserPasswordUiLib + FILE_GUID =3D E2E92636-F511-46BC-A08B-02F815AFA884 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D UserPasswordUiLib|DXE_RUNTIME_DRIVER= DXE_SMM_DRIVER DXE_DRIVER UEFI_APPLICATION + +[Sources] + UserPasswordUiLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + DebugLib + UefiLib + MemoryAllocationLib + BaseMemoryLib + PrintLib + PlatformPasswordLib + UserPasswordLib + +[Guids] + gUserAuthenticationGuid ## CONSUMES ## GUID + gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTab= le + +[Protocols] + gEfiSmmCommunicationProtocolGuid ## CONSUMES diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthentication2Dxe.inf b/Features/Intel/UserInterface/UserA= uthFeaturePkg/UserAuthenticationDxeSmm/UserAuthentication2Dxe.inf new file mode 100644 index 0000000000..2c6c3661fb --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthentication2Dxe.inf @@ -0,0 +1,52 @@ +## @file +# User Authentication 2 Dxe Driver. +# +# This Driver mainly provides Setup Form to change password. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UserAuthentication2Dxe + FILE_GUID =3D 4EF592F4-C716-40CC-8C07-1E4E3BD71F11 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 2.0 + ENTRY_POINT =3D UserAuthentication2Entry + UNLOAD_IMAGE =3D UserAuthentication2Unload +[Sources] + UserAuthentication2Dxe.c + UserAuthentication2Dxe.h + UserAuthenticationDxeFormset.h + UserAuthenticationDxeVfr.vfr + UserAuthenticationDxeStrings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + UefiLib + HiiLib + DevicePathLib + MemoryAllocationLib + UserPasswordLib + +[Protocols] + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + +[Depex] + gEfiSimpleTextOutProtocolGuid AND + gEfiSmmCommunicationProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxe.inf b/Features/Intel/UserInterface/UserAu= thFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxe.inf new file mode 100644 index 0000000000..58066b588c --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxe.inf @@ -0,0 +1,62 @@ +## @file +# User Authentication Dxe Driver. +# +# This Driver mainly provides Setup Form to change password and +# does user authentication before entering Setup. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UserAuthenticationDxe + FILE_GUID =3D 0683FB88-664C-4BA6-9ED4-1C0916EE43A4 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 2.0 + ENTRY_POINT =3D UserAuthenticationEntry + UNLOAD_IMAGE =3D UserAuthenticationUnload + +[Sources] + UserAuthenticationDxe.c + UserAuthenticationDxe.h + UserAuthenticationDxePassword.c + UserAuthenticationDxeFormset.h + UserAuthenticationDxeVfr.vfr + UserAuthenticationDxeStrings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + UefiLib + HiiLib + DevicePathLib + MemoryAllocationLib + PlatformPasswordLib + PrintLib + +[Guids] + gUserAuthenticationGuid ## CONSUMES ## GUID + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTab= le + +[Protocols] + gEfiRscHandlerProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiSmmCommunicationProtocolGuid ## CONSUMES + +[Depex] + gEfiSimpleTextOutProtocolGuid AND + gEfiSmmCommunicationProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationSmm.inf b/Features/Intel/UserInterface/UserAu= thFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationSmm.inf new file mode 100644 index 0000000000..0b33b194aa --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationSmm.inf @@ -0,0 +1,53 @@ +## @file +# User Authentication Smm Driver. +# +# This driver provides SMM services for DXE user authentication module. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D UserAuthenticationSmm + FILE_GUID =3D 8fc6aaaa-4561-4815-8cf7-b87312992dce + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x0001000A + ENTRY_POINT =3D PasswordSmmInit + +[Sources] + UserAuthenticationSmm.c + UserAuthenticationSmm.h + KeyService.c + KeyService.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + CryptoPkg/CryptoPkg.dec + UserInterface/UserAuthFeaturePkg/UserAuthFeaturePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + DebugLib + BaseLib + BaseMemoryLib + PrintLib + SmmServicesTableLib + MemoryAllocationLib + UefiLib + BaseCryptLib + PlatformPasswordLib + +[Guids] + gUserAuthenticationGuid ## CONSUMES ## GUID + +[Protocols] + gEdkiiVariableLockProtocolGuid ## CONSUMES + gEfiSmmVariableProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmVariableProtocolGuid AND gEfiVariableWriteArchProtocolGuid diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Guid/= UserAuthentication.h b/Features/Intel/UserInterface/UserAuthFeaturePkg/Incl= ude/Guid/UserAuthentication.h new file mode 100644 index 0000000000..2a41a46cdc --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Guid/UserAut= hentication.h @@ -0,0 +1,45 @@ +/** @file + GUID is for UserAuthentication SMM communication. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USER_AUTHENTICATION_GUID_H__ +#define __USER_AUTHENTICATION_GUID_H__ + +#define PASSWORD_MIN_SIZE 9 // MIN number of chars of password, inclu= ding NULL. +#define PASSWORD_MAX_SIZE 33 // MAX number of chars of password, inclu= ding NULL. + +#define USER_AUTHENTICATION_GUID \ + { 0xf06e3ea7, 0x611c, 0x4b6b, { 0xb4, 0x10, 0xc2, 0xbf, 0x94, 0x3f, 0x3= 8, 0xf2 } } + +extern EFI_GUID gUserAuthenticationGuid; + +typedef struct { + UINTN Function; + EFI_STATUS ReturnStatus; +} SMM_PASSWORD_COMMUNICATE_HEADER; + +#define SMM_PASSWORD_FUNCTION_IS_PASSWORD_SET 1 +#define SMM_PASSWORD_FUNCTION_SET_PASSWORD 2 +#define SMM_PASSWORD_FUNCTION_VERIFY_PASSWORD 3 +#define SMM_PASSWORD_FUNCTION_SET_VERIFY_POLICY 4 +#define SMM_PASSWORD_FUNCTION_GET_VERIFY_POLICY 5 +#define SMM_PASSWORD_FUNCTION_WAS_PASSWORD_VERIFIED 6 + +typedef struct { + CHAR8 NewPassword[PASSWORD_MAX_SIZE]; + CHAR8 OldPassword[PASSWORD_MAX_SIZE]; +} SMM_PASSWORD_COMMUNICATE_SET_PASSWORD; + +typedef struct { + CHAR8 Password[PASSWORD_MAX_SIZE]; +} SMM_PASSWORD_COMMUNICATE_VERIFY_PASSWORD; + +typedef struct { + BOOLEAN NeedReVerify; +} SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY; + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Libra= ry/PlatformPasswordLib.h b/Features/Intel/UserInterface/UserAuthFeaturePkg/= Include/Library/PlatformPasswordLib.h new file mode 100644 index 0000000000..ce27947f6d --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/Plat= formPasswordLib.h @@ -0,0 +1,48 @@ +/** @file + Provides a platform-specific method to return password policy. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PLATFORM_PASSWORD_LIB_H__ +#define __PLATFORM_PASSWORD_LIB_H__ + +/** + This function is called at password driver entrypoint. + This function should be called only once, to clear the password. + + This function provides a way to reset the password, just in case + the platform owner forgets the password. + The platform should provide a secure way to make sure + only the platform owner is allowed to clear password. + + Once the password is cleared, the platform should provide a way + to set a new password. + + @retval TRUE There is a platform request to clear the password. + @retval FALSE There is no platform request to clear the password. +**/ +BOOLEAN +EFIAPI +IsPasswordCleared ( + VOID + ); + +/** + This function is called if the password driver finds that the password = is not enrolled, + when the password is required to input. + + This function should return the action according to platform policy. + + @retval TRUE The caller should force the user to enroll the password. + @retval FALSE The caller may skip the password enroll. +**/ +BOOLEAN +EFIAPI +NeedEnrollPassword ( + VOID + ); + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Libra= ry/UserPasswordLib.h b/Features/Intel/UserInterface/UserAuthFeaturePkg/Incl= ude/Library/UserPasswordLib.h new file mode 100644 index 0000000000..b6aad224e9 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/User= PasswordLib.h @@ -0,0 +1,70 @@ +/** @file + Provides services to set/verify password and return if the password is = set. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USER_PASSWORD_LIB_H__ +#define __USER_PASSWORD_LIB_H__ + +/** + Validate if the password is correct. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval EFI_SUCCESS The password is correct. + @retval EFI_SECURITY_VIOLATION The password is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to verify the = password. + @retval EFI_ACCESS_DENIED Password retry count reach. +**/ +EFI_STATUS +EFIAPI +VerifyPassword ( + IN CHAR16 *Password, + IN UINTN PasswordSize + ); + +/** + Set a new password. + + @param[in] NewPassword The user input new password. + NULL means clear password. + @param[in] NewPasswordSize The size of NewPassword in byte. + @param[in] OldPassword The user input old password. + NULL means no old password. + @param[in] OldPasswordSize The size of OldPassword in byte. + + @retval EFI_SUCCESS The NewPassword is set successfully. + @retval EFI_SECURITY_VIOLATION The OldPassword is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set the pas= sword. + @retval EFI_ACCESS_DENIED Password retry count reach. + @retval EFI_UNSUPPORTED NewPassword is not strong enough. + @retval EFI_ALREADY_STARTED NewPassword is in history. +**/ +EFI_STATUS +EFIAPI +SetPassword ( + IN CHAR16 *NewPassword, OPTIONAL + IN UINTN NewPasswordSize, + IN CHAR16 *OldPassword, OPTIONAL + IN UINTN OldPasswordSize + ); + +/** + Return if the password is set. + + @retval TRUE The password is set. + @retval FALSE The password is not set. +**/ +BOOLEAN +EFIAPI +IsPasswordInstalled ( + VOID + ); + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Libra= ry/UserPasswordUiLib.h b/Features/Intel/UserInterface/UserAuthFeaturePkg/In= clude/Library/UserPasswordUiLib.h new file mode 100644 index 0000000000..117f480733 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Include/Library/User= PasswordUiLib.h @@ -0,0 +1,37 @@ +/** @file + Provides services to do password authentication. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USER_PASSWORD_UI_LIB_H__ +#define __USER_PASSWORD_UI_LIB_H__ + +/** + Do password authentication. + + @retval EFI_SUCCESS Password authentication pass. +**/ +EFI_STATUS +EFIAPI +UiDoPasswordAuthentication ( + VOID + ); + +/** + Set password verification policy. + + @param[in] NeedReVerify Need re-verify or not. + + @retval EFI_SUCCESS Set verification policy successfully. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set verific= ation policy. +**/ +EFI_STATUS +EFIAPI +UiSetPasswordVerificationPolicy ( + IN BOOLEAN NeedReVerify + ); + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/KeyService.h b/Features/Intel/UserInterface/UserAuthFeaturePkg/= UserAuthenticationDxeSmm/KeyService.h new file mode 100644 index 0000000000..d0b20851fa --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/KeyService.h @@ -0,0 +1,88 @@ +/** @file + Header file for key service. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __KEY_LIB_H__ +#define __KEY_LIB_H__ + +/** + Compares the contents of two buffers with slow algorithm + + This function compares Length bytes of SourceBuffer to Length bytes of = DestinationBuffer. + If all Length bytes of the two buffers are identical, then 0 is returne= d. Otherwise, the + value returned is the first mismatched byte in SourceBuffer subtracted = from the first + mismatched byte in DestinationBuffer. + + If Length > 0 and DestinationBuffer is NULL, then ASSERT(). + If Length > 0 and SourceBuffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then A= SSERT(). + If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT= (). + + @param DestinationBuffer The pointer to the destination buffer to comp= are. + @param SourceBuffer The pointer to the source buffer to compare. + @param Length The number of bytes to compare. + + @return 0 All Length bytes of the two buffers are ident= ical. + @retval -1 The SourceBuffer is not identical to Destinat= ionBuffer. + +**/ +INTN +EFIAPI +KeyLibSlowCompareMem ( + IN CONST VOID *DestinationBuffer, + IN CONST VOID *SourceBuffer, + IN UINTN Length + ); + +/** + Generate Salt value. + + @param[in, out] SaltValue Points to the salt buffer + @param[in] SaltSize Size of the salt buffer + + @retval TRUE Salt is generated. + @retval FALSE Salt is not generated. +**/ +BOOLEAN +EFIAPI +KeyLibGenerateSalt( + IN OUT UINT8 *SaltValue, + IN UINTN SaltSize + ); + +#define HASH_TYPE_SHA256 0x000B +#define DEFAULT_PBKDF2_ITERATION_COUNT 1000 + +/** + Hash the password with PBKDF2. + + @param[in] HashType Hash type + @param[in] Key Points to the key buffer + @param[in] KeySize Key buffer size + @param[in] SaltValue Points to the salt buffer + @param[in] SaltSize Size of the salt buffer + @param[out] KeyHash Points to the hashed result + @param[in] KeyHashSize Size of the hash buffer + + @retval TRUE Hash the data successfully. + @retval FALSE Failed to hash the data. + +**/ +BOOLEAN +EFIAPI +KeyLibGeneratePBKDF2Hash ( + IN UINT32 HashType, + IN VOID *Key, + IN UINTN KeySize, + IN UINT8 *SaltValue, + IN UINTN SaltSize, + OUT UINT8 *KeyHash, + IN UINTN KeyHashSize + ); + +#endif + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthentication2Dxe.h b/Features/Intel/UserInterface/UserAut= hFeaturePkg/UserAuthenticationDxeSmm/UserAuthentication2Dxe.h new file mode 100644 index 0000000000..3b7fba026d --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthentication2Dxe.h @@ -0,0 +1,55 @@ +/** @file + Header file for UserAuthentication2Dxe. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _USER_AUTHENTICATION_DXE_H_ +#define _USER_AUTHENTICATION_DXE_H_ + + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "UserAuthenticationDxeFormset.h" + +extern UINT8 UserAuthenticationDxeVfrBin[]; +extern UINT8 UserAuthentication2DxeStrings[]; + +typedef struct { + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + UINT8 PasswordState; + CHAR16 OldPassword[PASSWORD_MAX_SIZE]; +} USER_AUTHENTICATION_PRIVATE_DATA; + +#pragma pack(1) +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; +#pragma pack() + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxe.h b/Features/Intel/UserInterface/UserAuth= FeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxe.h new file mode 100644 index 0000000000..e183424f35 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxe.h @@ -0,0 +1,138 @@ +/** @file + Header file for UserAuthenticationDxe. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _USER_AUTHENTICATION_DXE_H_ +#define _USER_AUTHENTICATION_DXE_H_ + + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "UserAuthenticationDxeFormset.h" + +extern UINT8 UserAuthenticationDxeVfrBin[]; +extern UINT8 UserAuthenticationDxeStrings[]; +extern EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication; + +typedef struct { + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + UINT8 PasswordState; + CHAR16 OldPassword[PASSWORD_MAX_SIZE]; +} USER_AUTHENTICATION_PRIVATE_DATA; + +#pragma pack(1) +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; +#pragma pack() + +/** + Validate if the password is correct. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval EFI_SUCCESS The password is correct. + @retval EFI_SECURITY_VIOLATION The password is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to verify the = password. + @retval EFI_ACCESS_DENIED Password retry count reach. +**/ +EFI_STATUS +VerifyPassword ( + IN CHAR16 *Password, + IN UINTN PasswordSize + ); + +/** + Set a new password. + + @param[in] NewPassword The user input new password. + NULL means clear password. + @param[in] NewPasswordSize The size of NewPassword in byte. + @param[in] OldPassword The user input old password. + NULL means no old password. + @param[in] OldPasswordSize The size of OldPassword in byte. + + @retval EFI_SUCCESS The NewPassword is set successfully. + @retval EFI_SECURITY_VIOLATION The OldPassword is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set the pas= sword. + @retval EFI_ACCESS_DENIED Password retry count reach. + @retval EFI_UNSUPPORTED NewPassword is not strong enough. + @retval EFI_ALREADY_STARTED NewPassword is in history. +**/ +EFI_STATUS +SetPassword ( + IN CHAR16 *NewPassword, OPTIONAL + IN UINTN NewPasswordSize, + IN CHAR16 *OldPassword, OPTIONAL + IN UINTN OldPasswordSize + ); + +/** + Return if the password is set. + + @retval TRUE The password is set. + @retval FALSE The password is not set. +**/ +BOOLEAN +IsPasswordInstalled ( + VOID + ); + +/** + Get password verification policy. + + @param[out] VerifyPolicy Verification policy. + + @retval EFI_SUCCESS Get verification policy successfully. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to get verific= ation policy. +**/ +EFI_STATUS +GetPasswordVerificationPolicy ( + OUT SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *VerifyPolicy + ); + +/** + Return if the password was verified. + + @retval TRUE The password was verified. + @retval FALSE The password was not verified. +**/ +BOOLEAN +WasPasswordVerified ( + VOID + ); + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxeFormset.h b/Features/Intel/UserInterface/U= serAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxeFormset.h new file mode 100644 index 0000000000..581849b534 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxeFormset.h @@ -0,0 +1,23 @@ +/** @file + Header file for UserAuthentication formset. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _USER_AUTHENTICATION_DXE_FORMSET_H_ +#define _USER_AUTHENTICATION_DXE_FORMSET_H_ + +// +// Vendor GUID of the formset +// +#define USER_AUTHENTICATION_FORMSET_GUID \ + { 0x760e3022, 0xf149, 0x4560, {0x9c, 0x6f, 0x33, 0xaa, 0x7d, 0x48, 0x75= , 0xfa} } + +#define ADMIN_PASSWORD_KEY_ID 0x2001 + +#define MAX_PASSWORD_LEN 32 +#define MIN_PASSWORD_LEN 0 + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationSmm.h b/Features/Intel/UserInterface/UserAuth= FeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationSmm.h new file mode 100644 index 0000000000..47bb95529f --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationSmm.h @@ -0,0 +1,52 @@ +/** @file + Header file for UserAuthenticationSmm. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __USER_AUTHENTICATION_SMM_H__ +#define __USER_AUTHENTICATION_SMM_H__ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "KeyService.h" + +#define PASSWORD_SALT_SIZE 32 +#define PASSWORD_HASH_SIZE 32 // SHA256_DIGEST_SIZE + +#define PASSWORD_MAX_TRY_COUNT 3 +#define PASSWORD_HISTORY_CHECK_COUNT 5 + +// +// Name of the variable +// +#define USER_AUTHENTICATION_VAR_NAME L"Password" +#define USER_AUTHENTICATION_HISTORY_LAST_VAR_NAME L"PasswordLast" + +// +// Variable storage +// +typedef struct { + UINT8 PasswordHash[PASSWORD_HASH_SIZE]; + UINT8 PasswordSalt[PASSWORD_SALT_SIZE]; +} USER_PASSWORD_VAR_STRUCT; + +#endif diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxeVfr.vfr b/Features/Intel/UserInterface/Use= rAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxeVfr.vfr new file mode 100644 index 0000000000..ca1d5ddec1 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxeVfr.vfr @@ -0,0 +1,39 @@ +///** @file +// UserAuthentication formset. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//**/ + +#include +#include "UserAuthenticationDxeFormset.h" + +formset + guid =3D USER_AUTHENTICATION_FORMSET_GUID, + title =3D STRING_TOKEN(STR_FORM_SET_TITLE), + help =3D STRING_TOKEN(STR_FORM_SET_TITLE_HELP), + classguid =3D EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + form formid =3D 1, + title =3D STRING_TOKEN(STR_FORM_TITLE); + + grayoutif TRUE; + text + help =3D STRING_TOKEN(STR_ADMIN_PASSWORD_STS_HELP), + text =3D STRING_TOKEN(STR_ADMIN_PASSWORD_STS_PROMPT), + text =3D STRING_TOKEN(STR_ADMIN_PASSWORD_STS_CONTENT); + endif; + + password + prompt =3D STRING_TOKEN(STR_ADMIN_PASSWORD_PROMPT), + help =3D STRING_TOKEN(STR_ADMIN_PASSWORD_HELP), + flags =3D INTERACTIVE, + key =3D ADMIN_PASSWORD_KEY_ID, + minsize =3D MIN_PASSWORD_LEN, + maxsize =3D MAX_PASSWORD_LEN, + endpassword; + + endform; + +endformset; diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/Platf= ormPasswordLibNull/PlatformPasswordLibNull.c b/Features/Intel/UserInterface= /UserAuthFeaturePkg/Library/PlatformPasswordLibNull/PlatformPasswordLibNull= .c new file mode 100644 index 0000000000..08e081aa99 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPass= wordLibNull/PlatformPasswordLibNull.c @@ -0,0 +1,78 @@ +/** @file + NULL PlatformPasswordLib instance does NOT really detect whether the pa= ssword is cleared + but returns the PCD value directly. This instance can be used to verify= security + related features during platform enabling and development. It should be= replaced + by a platform-specific method(e.g. Button pressed) in a real platform f= or product. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +BOOLEAN mPasswordCleared =3D FALSE; + +/** + This function is called at password driver entrypoint. + This function should be called only once, to clear the password. + + This function provides a way to reset the password, just in case + the platform owner forgets the password. + The platform should provide a secure way to make sure + only the platform owner is allowed to clear password. + + Once the password is cleared, the platform should provide a way + to set a new password. + + @retval TRUE There is a platform request to clear the password. + @retval FALSE There is no platform request to clear the password. +**/ +BOOLEAN +EFIAPI +IsPasswordCleared ( + VOID + ) +{ + return mPasswordCleared; +} + +/** + This function is called if the password driver finds that the password = is not enrolled, + when the password is required to input. + + This function should return the action according to platform policy. + + @retval TRUE The caller should force the user to enroll the password. + @retval FALSE The caller may skip the password enroll. +**/ +BOOLEAN +EFIAPI +NeedEnrollPassword ( + VOID + ) +{ + return FALSE; +} + + +/** + Save password clear state from a PCD to mPasswordCleared. + + @param ImageHandle ImageHandle of the loaded driver. + @param SystemTable Pointer to the EFI System Table. + + @retval EFI_SUCCESS PcdPasswordCleared is got successfully. + +**/ +EFI_STATUS +EFIAPI +PlatformPasswordLibNullConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + mPasswordCleared =3D PcdGetBool(PcdPasswordCleared); + + return EFI_SUCCESS; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserP= asswordLib/UserPasswordLib.c b/Features/Intel/UserInterface/UserAuthFeature= Pkg/Library/UserPasswordLib/UserPasswordLib.c new file mode 100644 index 0000000000..cbaf572378 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPassword= Lib/UserPasswordLib.c @@ -0,0 +1,274 @@ +/** @file + UserPasswordLib instance implementation provides services to + set/verify password and return if the password is set. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +#include +#include +#include +#include + +/** + Initialize the communicate buffer using DataSize and Function. + + @param[out] DataPtr Points to the data in the communicate= buffer. + @param[in] DataSize The data size to send to SMM. + @param[in] Function The function number to initialize the= communicate header. + + @return Communicate buffer. +**/ +VOID* +UserPasswordLibInitCommunicateBuffer ( + OUT VOID **DataPtr OPTIONAL, + IN UINTN DataSize, + IN UINTN Function + ) +{ + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + VOID *Buffer; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable; + EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion; + UINTN Index; + UINTN Size; + EFI_STATUS Status; + + Buffer =3D NULL; + Status =3D EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &SmmCommRegionTable + ); + if (EFI_ERROR (Status)) { + return NULL; + } + ASSERT (SmmCommRegionTable !=3D NULL); + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) (SmmCommRegionTable + 1)= ; + Size =3D 0; + for (Index =3D 0; Index < SmmCommRegionTable->NumberOfEntries; Index++)= { + if (SmmCommMemRegion->Type =3D=3D EfiConventionalMemory) { + Size =3D EFI_PAGES_TO_SIZE ((UINTN) SmmCommMemRegion->NumberOfPages= ); + if (Size >=3D (DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Da= ta) + sizeof (SMM_PASSWORD_COMMUNICATE_HEADER))) { + break; + } + } + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) SmmCommMemR= egion + SmmCommRegionTable->DescriptorSize); + } + ASSERT (Index < SmmCommRegionTable->NumberOfEntries); + + Buffer =3D (VOID*)(UINTN)SmmCommMemRegion->PhysicalStart; + ASSERT (Buffer !=3D NULL); + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gUserAuthenticationGuid); + SmmCommunicateHeader->MessageLength =3D DataSize + sizeof (SMM_PASSWORD= _COMMUNICATE_HEADER); + + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *) SmmCo= mmunicateHeader->Data; + ZeroMem (SmmPasswordFunctionHeader, DataSize + sizeof (SMM_PASSWORD_COM= MUNICATE_HEADER)); + SmmPasswordFunctionHeader->Function =3D Function; + if (DataPtr !=3D NULL) { + *DataPtr =3D SmmPasswordFunctionHeader + 1; + } + + return Buffer; +} + +/** + Send the data in communicate buffer to SMM. + + @param[in] Buffer Points to the data in the communica= te buffer. + @param[in] DataSize The data size to send to SMM. + + @retval EFI_SUCCESS Success is returned from the functi= on in SMM. + @retval Others Failure is returned from the functi= on in SMM. + +**/ +EFI_STATUS +UserPasswordLibSendCommunicateBuffer ( + IN VOID *Buffer, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + UINTN CommSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; + + // + // Locates SMM Communication protocol. + // + Status =3D gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL= , (VOID **) &SmmCommunication); + ASSERT_EFI_ERROR (Status); + + CommSize =3D DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + = sizeof (SMM_PASSWORD_COMMUNICATE_HEADER); + + Status =3D SmmCommunication->Communicate (SmmCommunication, Buffer, &Co= mmSize); + ASSERT_EFI_ERROR (Status); + + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *)SmmCom= municateHeader->Data; + return SmmPasswordFunctionHeader->ReturnStatus; +} + +/** + Validate if the password is correct. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval EFI_SUCCESS The password is correct. + @retval EFI_SECURITY_VIOLATION The password is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to verify the = password. + @retval EFI_ACCESS_DENIED Password retry count reach. +**/ +EFI_STATUS +EFIAPI +VerifyPassword ( + IN CHAR16 *Password, + IN UINTN PasswordSize + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_VERIFY_PASSWORD *VerifyPassword; + + ASSERT (Password !=3D NULL); + + if (PasswordSize > sizeof(VerifyPassword->Password) * sizeof(CHAR16)) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D UserPasswordLibInitCommunicateBuffer ( + (VOID**)&VerifyPassword, + sizeof(*VerifyPassword), + SMM_PASSWORD_FUNCTION_VERIFY_PASSWORD + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D UnicodeStrToAsciiStrS (Password, VerifyPassword->Password, s= izeof(VerifyPassword->Password)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + + Status =3D UserPasswordLibSendCommunicateBuffer (Buffer, sizeof(*Verify= Password)); + +EXIT: + ZeroMem (VerifyPassword, sizeof(*VerifyPassword)); + return Status; +} + +/** + Set a new password. + + @param[in] NewPassword The user input new password. + NULL means clear password. + @param[in] NewPasswordSize The size of NewPassword in byte. + @param[in] OldPassword The user input old password. + NULL means no old password. + @param[in] OldPasswordSize The size of OldPassword in byte. + + @retval EFI_SUCCESS The NewPassword is set successfully. + @retval EFI_SECURITY_VIOLATION The OldPassword is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set the pas= sword. + @retval EFI_ACCESS_DENIED Password retry count reach. + @retval EFI_UNSUPPORTED NewPassword is not strong enough. + @retval EFI_ALREADY_STARTED NewPassword is in history. +**/ +EFI_STATUS +EFIAPI +SetPassword ( + IN CHAR16 *NewPassword, OPTIONAL + IN UINTN NewPasswordSize, + IN CHAR16 *OldPassword, OPTIONAL + IN UINTN OldPasswordSize + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_SET_PASSWORD *SetPassword; + + if (NewPasswordSize > sizeof(SetPassword->NewPassword) * sizeof(CHAR16)= ) { + return EFI_INVALID_PARAMETER; + } + if (OldPasswordSize > sizeof(SetPassword->OldPassword) * sizeof(CHAR16)= ) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D UserPasswordLibInitCommunicateBuffer ( + (VOID**)&SetPassword, + sizeof(*SetPassword), + SMM_PASSWORD_FUNCTION_SET_PASSWORD + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (NewPassword !=3D NULL) { + Status =3D UnicodeStrToAsciiStrS (NewPassword, SetPassword->NewPasswo= rd, sizeof(SetPassword->NewPassword)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } else { + SetPassword->NewPassword[0] =3D 0; + } + + if (OldPassword !=3D NULL) { + Status =3D UnicodeStrToAsciiStrS (OldPassword, SetPassword->OldPasswo= rd, sizeof(SetPassword->OldPassword)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } else { + SetPassword->OldPassword[0] =3D 0; + } + + Status =3D UserPasswordLibSendCommunicateBuffer (Buffer, sizeof(*SetPas= sword)); + +EXIT: + ZeroMem (SetPassword, sizeof(*SetPassword)); + return Status; +} + +/** + Return if the password is set. + + @retval TRUE The password is set. + @retval FALSE The password is not set. +**/ +BOOLEAN +EFIAPI +IsPasswordInstalled ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + Buffer =3D UserPasswordLibInitCommunicateBuffer ( + NULL, + 0, + SMM_PASSWORD_FUNCTION_IS_PASSWORD_SET + ); + if (Buffer =3D=3D NULL) { + return FALSE; + } + + Status =3D UserPasswordLibSendCommunicateBuffer (Buffer, 0); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserP= asswordUiLib/UserPasswordUiLib.c b/Features/Intel/UserInterface/UserAuthFea= turePkg/Library/UserPasswordUiLib/UserPasswordUiLib.c new file mode 100644 index 0000000000..050bfda63a --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/UserPassword= UiLib/UserPasswordUiLib.c @@ -0,0 +1,522 @@ +/** @file + UserPasswordUiLib instance provides services to do password authenticat= ion. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Initialize the communicate buffer using DataSize and Function. + + @param[out] DataPtr Points to the data in the communicate= buffer. + @param[in] DataSize The data size to send to SMM. + @param[in] Function The function number to initialize the= communicate header. + + @return Communicate buffer. +**/ +VOID* +UserPasswordUiLibInitCommunicateBuffer ( + OUT VOID **DataPtr OPTIONAL, + IN UINTN DataSize, + IN UINTN Function + ) +{ + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + VOID *Buffer; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable; + EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion; + UINTN Index; + UINTN Size; + EFI_STATUS Status; + + Buffer =3D NULL; + Status =3D EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &SmmCommRegionTable + ); + if (EFI_ERROR (Status)) { + return NULL; + } + ASSERT (SmmCommRegionTable !=3D NULL); + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) (SmmCommRegionTable + 1)= ; + Size =3D 0; + for (Index =3D 0; Index < SmmCommRegionTable->NumberOfEntries; Index++)= { + if (SmmCommMemRegion->Type =3D=3D EfiConventionalMemory) { + Size =3D EFI_PAGES_TO_SIZE ((UINTN) SmmCommMemRegion->NumberOfPages= ); + if (Size >=3D (DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Da= ta) + sizeof (SMM_PASSWORD_COMMUNICATE_HEADER))) { + break; + } + } + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) SmmCommMemR= egion + SmmCommRegionTable->DescriptorSize); + } + ASSERT (Index < SmmCommRegionTable->NumberOfEntries); + + Buffer =3D (VOID*)(UINTN)SmmCommMemRegion->PhysicalStart; + ASSERT (Buffer !=3D NULL); + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gUserAuthenticationGuid); + SmmCommunicateHeader->MessageLength =3D DataSize + sizeof (SMM_PASSWORD= _COMMUNICATE_HEADER); + + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *) SmmCo= mmunicateHeader->Data; + ZeroMem (SmmPasswordFunctionHeader, DataSize + sizeof (SMM_PASSWORD_COM= MUNICATE_HEADER)); + SmmPasswordFunctionHeader->Function =3D Function; + if (DataPtr !=3D NULL) { + *DataPtr =3D SmmPasswordFunctionHeader + 1; + } + + return Buffer; +} + +/** + Send the data in communicate buffer to SMM. + + @param[in] Buffer Points to the data in the communica= te buffer. + @param[in] DataSize The data size to send to SMM. + + @retval EFI_SUCCESS Success is returned from the functi= on in SMM. + @retval Others Failure is returned from the functi= on in SMM. + +**/ +EFI_STATUS +UserPasswordUiLibSendCommunicateBuffer ( + IN VOID *Buffer, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + UINTN CommSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; + + // + // Locates SMM Communication protocol. + // + Status =3D gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL= , (VOID **) &SmmCommunication); + ASSERT_EFI_ERROR (Status); + + CommSize =3D DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + = sizeof (SMM_PASSWORD_COMMUNICATE_HEADER); + + Status =3D SmmCommunication->Communicate (SmmCommunication, Buffer, &Co= mmSize); + ASSERT_EFI_ERROR (Status); + + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *)SmmCom= municateHeader->Data; + return SmmPasswordFunctionHeader->ReturnStatus; +} + +/** + Set password verification policy. + + @param[in] NeedReVerify Need re-verify or not. + + @retval EFI_SUCCESS Set verification policy successfully. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set verific= ation policy. +**/ +EFI_STATUS +EFIAPI +UiSetPasswordVerificationPolicy ( + IN BOOLEAN NeedReVerify + ) +{ + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *SetVerifyPolicy; + + Buffer =3D UserPasswordUiLibInitCommunicateBuffer ( + (VOID**)&SetVerifyPolicy, + sizeof(*SetVerifyPolicy), + SMM_PASSWORD_FUNCTION_SET_VERIFY_POLICY + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetVerifyPolicy->NeedReVerify =3D NeedReVerify; + + return UserPasswordUiLibSendCommunicateBuffer (Buffer, sizeof(*SetVerif= yPolicy)); +} + +/** + Get a user input string. + + @param[in] PopUpString A popup string to inform user. + @param[in, out] UserInput The user input string + @param[in] UserInputMaxLen The max unicode count of the UserInpu= t without NULL terminator. +**/ +EFI_STATUS +GetUserInput ( + IN CHAR16 *PopUpString, + IN OUT CHAR16 *UserInput, + IN UINTN UserInputMaxLen + ) +{ + EFI_INPUT_KEY InputKey; + UINTN InputLength; + CHAR16 *Mask; + + UserInput[0] =3D 0; + Mask =3D AllocateZeroPool ((UserInputMaxLen + 1) * sizeof(CHAR16)); + if (Mask =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InputLength =3D 0; + + while (TRUE) { + if (InputLength < UserInputMaxLen) { + Mask[InputLength] =3D L'_'; + } + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + L"--------------------------------", + Mask, + NULL + ); + if (InputKey.ScanCode =3D=3D SCAN_NULL) { + // + // Check whether finish inputing password. + // + if (InputKey.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN && InputLength= > 0) { + // + // Add the null terminator. + // + UserInput[InputLength] =3D 0; + break; + } else if ((InputKey.UnicodeChar =3D=3D CHAR_NULL) || + (InputKey.UnicodeChar =3D=3D CHAR_LINEFEED) || + (InputKey.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) + ) { + continue; + } else { + // + // delete last key entered + // + if (InputKey.UnicodeChar =3D=3D CHAR_BACKSPACE) { + if (InputLength > 0) { + UserInput[InputLength] =3D 0; + Mask[InputLength] =3D 0; + InputLength--; + } + } else { + if (InputLength =3D=3D UserInputMaxLen) { + Mask[InputLength] =3D 0; + continue; + } + // + // add Next key entry + // + UserInput[InputLength] =3D InputKey.UnicodeChar; + Mask[InputLength] =3D L'*'; + InputLength++; + } + } + } + } + FreePool (Mask); + return EFI_SUCCESS; +} + +/** + Display a message box to end user. + + @param[in] DisplayString The string in message box. +**/ +VOID +MessageBox ( + IN CHAR16 *DisplayString + ) +{ + EFI_INPUT_KEY Key; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); +} + +/** + Force system reset. +**/ +VOID +ForceSystemReset ( + VOID + ) +{ + MessageBox (L"Password retry count reach, reset system!"); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + CpuDeadLoop(); +} + +/** + Display message for set password. + + @param[in] ReturnStatus The return status for set password. +**/ +VOID +PrintSetPasswordStatus ( + IN EFI_STATUS ReturnStatus + ) +{ + CHAR16 *DisplayString; + CHAR16 *DisplayString2; + + EFI_INPUT_KEY Key; + + if (ReturnStatus =3D=3D EFI_UNSUPPORTED) { + DisplayString =3D L"New password is not strong enough!"; + DisplayString2 =3D L"Password must at least 8 chars and include lower= case, uppercase alphabetic, number and symbol"; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + DisplayString2, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } else { + if (ReturnStatus =3D=3D EFI_SUCCESS) { + DisplayString =3D L"New password is updated successfully!"; + } else if (ReturnStatus =3D=3D EFI_ALREADY_STARTED) { + DisplayString =3D L"New password is found in the history passwords!= "; + } else { + DisplayString =3D L"New password update fails!"; + } + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } +} + +/** + Get password verification policy. + + @param[out] VerifyPolicy Verification policy. + + @retval EFI_SUCCESS Get verification policy successfully. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to get verific= ation policy. +**/ +EFI_STATUS +GetPasswordVerificationPolicy ( + OUT SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *VerifyPolicy + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *TempVerifyPolicy; + + Buffer =3D UserPasswordUiLibInitCommunicateBuffer ( + (VOID**)&TempVerifyPolicy, + sizeof(*TempVerifyPolicy), + SMM_PASSWORD_FUNCTION_GET_VERIFY_POLICY + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D UserPasswordUiLibSendCommunicateBuffer (Buffer, sizeof(*Temp= VerifyPolicy)); + if (!EFI_ERROR (Status)) { + CopyMem (VerifyPolicy, TempVerifyPolicy, sizeof (SMM_PASSWORD_COMMUNI= CATE_VERIFY_POLICY)); + } + + return Status; +} + +/** + Return if the password was verified. + + @retval TRUE The password was verified. + @retval FALSE The password was not verified. +**/ +BOOLEAN +WasPasswordVerified ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + Buffer =3D UserPasswordUiLibInitCommunicateBuffer ( + NULL, + 0, + SMM_PASSWORD_FUNCTION_WAS_PASSWORD_VERIFIED + ); + if (Buffer =3D=3D NULL) { + return FALSE; + } + + Status =3D UserPasswordUiLibSendCommunicateBuffer (Buffer, 0); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Require user input password. + + @retval TRUE User input correct password successfully. + @retval FALSE The password is not set. +**/ +BOOLEAN +RequireUserPassword ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 UserInputPw[PASSWORD_MAX_SIZE= ]; + CHAR16 *PopUpString; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY VerifyPolicy; + + Status =3D EFI_SUCCESS; + ZeroMem(UserInputPw, sizeof(UserInputPw)); + + if (!IsPasswordInstalled ()) { + return FALSE; + } + + Status =3D GetPasswordVerificationPolicy (&VerifyPolicy); + if (!EFI_ERROR (Status)) { + if (WasPasswordVerified() && (!VerifyPolicy.NeedReVerify)) { + DEBUG ((DEBUG_INFO, "Password was verified and Re-verify is not nee= ded\n")); + return TRUE; + } + } + + PopUpString =3D L"Please input admin password"; + + while (TRUE) { + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString, UserInputPw, PASSWORD_MAX_SIZE - 1); + + Status =3D VerifyPassword (UserInputPw, StrSize(UserInputPw)); + if (!EFI_ERROR(Status)) { + break; + } + if (Status =3D=3D EFI_ACCESS_DENIED) { + // + // Password retry count reach. + // + ForceSystemReset (); + } + MessageBox (L"Incorrect password!"); + } + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + + gST->ConOut->ClearScreen(gST->ConOut); + + return TRUE; +} + +/** + Set user password. + +**/ +VOID +SetUserPassword ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 UserInputPw[PASSWORD_MAX_SIZE]; + CHAR16 TmpPassword[PASSWORD_MAX_SIZE]; + CHAR16 *PopUpString; + CHAR16 *PopUpString2; + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + ZeroMem(TmpPassword, sizeof(TmpPassword)); + + PopUpString =3D L"Please set admin password"; + + while (TRUE) { + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString, UserInputPw, PASSWORD_MAX_SIZE - 1); + + PopUpString2 =3D L"Please confirm your new password"; + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString2, TmpPassword, PASSWORD_MAX_SIZE - 1); + if (StrCmp (TmpPassword, UserInputPw) !=3D 0) { + MessageBox (L"Password are not the same!"); + continue; + } + + Status =3D SetPassword (UserInputPw, StrSize(UserInputPw), NULL, 0); + PrintSetPasswordStatus (Status); + if (!EFI_ERROR(Status)) { + break; + } + } + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + ZeroMem(TmpPassword, sizeof(TmpPassword)); + + gST->ConOut->ClearScreen(gST->ConOut); +} + +/** + Do password authentication. + + @retval EFI_SUCCESS Password authentication pass. +**/ +EFI_STATUS +EFIAPI +UiDoPasswordAuthentication ( + VOID + ) +{ + BOOLEAN PasswordSet; + + PasswordSet =3D RequireUserPassword (); + if (PasswordSet) { + DEBUG ((DEBUG_INFO, "Welcome Admin!\n")); + } else { + DEBUG ((DEBUG_INFO, "Admin password is not set!\n")); + if (NeedEnrollPassword()) { + SetUserPassword (); + } + } + + return EFI_SUCCESS; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/KeyService.c b/Features/Intel/UserInterface/UserAuthFeaturePkg/= UserAuthenticationDxeSmm/KeyService.c new file mode 100644 index 0000000000..8b06e58ca5 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/KeyService.c @@ -0,0 +1,133 @@ +/** @file + Password key service. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include "KeyService.h" + +/** + Compares the contents of two buffers with slow algorithm + + This function compares Length bytes of SourceBuffer to Length bytes of = DestinationBuffer. + If all Length bytes of the two buffers are identical, then 0 is returne= d. Otherwise, the + value returned is the first mismatched byte in SourceBuffer subtracted = from the first + mismatched byte in DestinationBuffer. + + If Length > 0 and DestinationBuffer is NULL, then ASSERT(). + If Length > 0 and SourceBuffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then A= SSERT(). + If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT= (). + + @param DestinationBuffer The pointer to the destination buffer to comp= are. + @param SourceBuffer The pointer to the source buffer to compare. + @param Length The number of bytes to compare. + + @return 0 All Length bytes of the two buffers are ident= ical. + @retval -1 The SourceBuffer is not identical to Destinat= ionBuffer. + +**/ +INTN +EFIAPI +KeyLibSlowCompareMem ( + IN CONST VOID *DestinationBuffer, + IN CONST VOID *SourceBuffer, + IN UINTN Length + ) +{ + UINT8 Delta; + UINTN Index; + UINT8 *Destination; + UINT8 *Source; + + Destination =3D (UINT8 *)DestinationBuffer; + Source =3D (UINT8 *)SourceBuffer; + Delta =3D 0; + for (Index =3D 0; Index < Length; Index++) { + Delta |=3D Destination[Index] ^ Source[Index]; + } + if (Delta =3D=3D 0) { + return 0; + } else { + return -1; + } +} + +/** + Generate Salt value. + + @param[in, out] SaltValue Points to the salt buffer + @param[in] SaltSize Size of the salt buffer + + @retval TRUE Salt is generated. + @retval FALSE Salt is not generated. +**/ +BOOLEAN +EFIAPI +KeyLibGenerateSalt ( + IN OUT UINT8 *SaltValue, + IN UINTN SaltSize + ) +{ + if (SaltValue =3D=3D NULL) { + return FALSE; + } + RandomSeed(NULL, 0); + RandomBytes(SaltValue, SaltSize); + return TRUE; +} + +/** + Hash the password with PBKDF2. + + @param[in] HashType Hash type + @param[in] Key Points to the key buffer + @param[in] KeySize Key buffer size + @param[in] SaltValue Points to the salt buffer + @param[in] SaltSize Size of the salt buffer + @param[out] KeyHash Points to the hashed result + @param[in] KeyHashSize Size of the hash buffer + + @retval TRUE Hash the data successfully. + @retval FALSE Failed to hash the data. + +**/ +BOOLEAN +EFIAPI +KeyLibGeneratePBKDF2Hash ( + IN UINT32 HashType, + IN VOID *Key, + IN UINTN KeySize, + IN UINT8 *SaltValue, + IN UINTN SaltSize, + OUT UINT8 *KeyHash, + IN UINTN KeyHashSize + ) +{ + BOOLEAN Result; + + if (HashType !=3D HASH_TYPE_SHA256) { + return FALSE; + } + if (KeyHashSize !=3D SHA256_DIGEST_SIZE) { + return FALSE; + } + + Result =3D Pkcs5HashPassword ( + KeySize, + Key, + SaltSize, + SaltValue, + DEFAULT_PBKDF2_ITERATION_COUNT, + SHA256_DIGEST_SIZE, + KeyHashSize, + KeyHash + ); + return Result; +} diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthentication2Dxe.c b/Features/Intel/UserInterface/UserAut= hFeaturePkg/UserAuthenticationDxeSmm/UserAuthentication2Dxe.c new file mode 100644 index 0000000000..b4326d380f --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthentication2Dxe.c @@ -0,0 +1,484 @@ +/** @file + This Driver mainly provides Setup Form to change password. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UserAuthentication2Dxe.h" + +USER_AUTHENTICATION_PRIVATE_DATA *mUserAuthenticationData =3D NULL; + +EFI_GUID mUserAuthenticationVendorGuid =3D USER_AUTHENTICATION_FORMSET_GU= ID; +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath =3D { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + USER_AUTHENTICATION_FORMSET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + Display a message box to end user. + + @param[in] DisplayString The string in message box. +**/ +VOID +MessageBox ( + IN CHAR16 *DisplayString + ) +{ + EFI_INPUT_KEY Key; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); +} + +/** + Force system reset. +**/ +VOID +ForceSystemReset ( + VOID + ) +{ + MessageBox (L"Password retry count reach, reset system!"); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + CpuDeadLoop(); +} + +/** + Display message for set password. + + @param[in] ReturnStatus The return status for set password. +**/ +VOID +PrintSetPasswordStatus ( + IN EFI_STATUS ReturnStatus + ) +{ + CHAR16 *DisplayString; + CHAR16 *DisplayString2; + + EFI_INPUT_KEY Key; + + if (ReturnStatus =3D=3D EFI_UNSUPPORTED) { + DisplayString =3D L"New password is not strong enough!"; + DisplayString2 =3D L"Password must at least 8 chars and include lower= case, uppercase alphabetic, number and symbol"; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + DisplayString2, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } else { + if (ReturnStatus =3D=3D EFI_SUCCESS) { + DisplayString =3D L"New password is updated successfully!"; + } else if (ReturnStatus =3D=3D EFI_ALREADY_STARTED) { + DisplayString =3D L"New password is found in the history passwords!= "; + } else { + DisplayString =3D L"New password update fails!"; + } + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } +} + +/** + This function allows a caller to extract the current configuration for = one + or more named elements from the target driver. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Request A null-terminated Unicode string in + format. + @param Progress On return, points to a character in the = Request + string. Points to the string's null term= inator if + request was successful. Points to the mo= st recent + '&' before the first failing name/value = pair (or + the beginning of the string if the failu= re is in + the first name/value pair) if the reques= t was not + successful. + @param Results A null-terminated Unicode string in + format which has all val= ues filled + in for the names in the Request string. = String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested= values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown na= me. + @retval EFI_NOT_FOUND Routing data doesn't match any storage i= n this + driver. + +**/ +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if (Progress =3D=3D NULL || Results =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress =3D Request; + return EFI_NOT_FOUND; +} + + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Configuration A null-terminated Unicode string in + format. + @param Progress A pointer to a string filled in with the= offset of + the most recent '&' before the first fai= ling + name/value pair (or the beginning of the= string if + the failure is in the first name/value p= air) or + the terminating NULL if all was successf= ul. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage i= n this + driver. + +**/ +EFI_STATUS +EFIAPI +RouteConfig ( + 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; + } + + *Progress =3D Configuration; + + return EFI_NOT_FOUND; +} + +/** + HII update Admin Password status. + +**/ +VOID +HiiUpdateAdminPasswordStatus ( + VOID + ) +{ + if (IsPasswordInstalled ()) { + HiiSetString ( + mUserAuthenticationData->HiiHandle, + STRING_TOKEN (STR_ADMIN_PASSWORD_STS_CONTENT), + L"Installed", + NULL + ); + } else { + HiiSetString ( + mUserAuthenticationData->HiiHandle, + STRING_TOKEN (STR_ADMIN_PASSWORD_STS_CONTENT), + L"Not Installed", + NULL + ); + } +} + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Action Specifies the type of action taken by th= e browser. + @param QuestionId A unique value which is sent to the orig= inal + exporting driver so that it can identify= the type + of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the = original + exporting driver. + @param ActionRequest On return, points to the action requeste= d by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the ac= tion. + @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. + +**/ +EFI_STATUS +EFIAPI +UserAuthenticationCallback ( + 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 + ) +{ + EFI_STATUS Status; + CHAR16 *UserInputPassword; + + Status =3D EFI_SUCCESS; + + if (((Value =3D=3D NULL) && (Action !=3D EFI_BROWSER_ACTION_FORM_OPEN) = && (Action !=3D EFI_BROWSER_ACTION_FORM_CLOSE)) || + (ActionRequest =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + { + switch (QuestionId) { + case ADMIN_PASSWORD_KEY_ID: + HiiUpdateAdminPasswordStatus (); + default: + break; + } + } + break; + case EFI_BROWSER_ACTION_CHANGING: + { + switch (QuestionId) { + case ADMIN_PASSWORD_KEY_ID: + if ((Type =3D=3D EFI_IFR_TYPE_STRING) && (Value->string =3D=3D 0)= && + (mUserAuthenticationData->PasswordState =3D=3D BROWSER_STATE_= SET_PASSWORD)) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDA= TE_PASSWORD; + ZeroMem (mUserAuthenticationData->OldPassword, sizeof(mUserAuth= enticationData->OldPassword)); + return EFI_INVALID_PARAMETER; + } + // + // The Callback is responsible for validating old password input = by user, + // If Callback return EFI_SUCCESS, it indicates validation pass. + // + switch (mUserAuthenticationData->PasswordState) { + case BROWSER_STATE_VALIDATE_PASSWORD: + UserInputPassword =3D HiiGetString (mUserAuthenticationData->Hi= iHandle, Value->string, NULL); + if (UserInputPassword =3D=3D NULL) { + return EFI_UNSUPPORTED; + } + if ((StrLen (UserInputPassword) >=3D PASSWORD_MAX_SIZE)) { + Status =3D EFI_NOT_READY; + break; + } + if (UserInputPassword[0] =3D=3D 0) { + // + // Setup will use an empty password to check whether the old = password is set, + // If the validation is successful, means there is no old pas= sword, return + // success to set the new password. Or need to return EFI_NOT= _READY to + // let user input the old password. + // + Status =3D VerifyPassword (UserInputPassword, StrSize (UserIn= putPassword)); + if (Status =3D=3D EFI_SUCCESS) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_SE= T_PASSWORD; + } else { + Status =3D EFI_NOT_READY; + } + break; + } + Status =3D VerifyPassword (UserInputPassword, StrSize (UserInpu= tPassword)); + if (Status =3D=3D EFI_SUCCESS) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_SET_= PASSWORD; + StrCpyS ( + mUserAuthenticationData->OldPassword, + sizeof(mUserAuthenticationData->OldPassword)/sizeof(CHAR16)= , + UserInputPassword + ); + } else { + // + // Old password mismatch, return EFI_NOT_READY to prompt for = error message. + // + if (Status =3D=3D EFI_ACCESS_DENIED) { + // + // Password retry count reach. + // + ForceSystemReset (); + } + Status =3D EFI_NOT_READY; + } + break; + + case BROWSER_STATE_SET_PASSWORD: + UserInputPassword =3D HiiGetString (mUserAuthenticationData->Hi= iHandle, Value->string, NULL); + if (UserInputPassword =3D=3D NULL) { + return EFI_UNSUPPORTED; + } + if ((StrLen (UserInputPassword) >=3D PASSWORD_MAX_SIZE)) { + Status =3D EFI_NOT_READY; + break; + } + Status =3D SetPassword (UserInputPassword, StrSize (UserInputPa= ssword), mUserAuthenticationData->OldPassword, StrSize(mUserAuthenticationD= ata->OldPassword)); + PrintSetPasswordStatus (Status); + ZeroMem (mUserAuthenticationData->OldPassword, sizeof(mUserAuth= enticationData->OldPassword)); + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDA= TE_PASSWORD; + HiiUpdateAdminPasswordStatus (); + break; + + default: + break; + } + default: + break; + } + } + break; + default: + break; + } + return Status; +} + +/** + User Authentication entry point. + + @param ImageHandle The image handle. + @param SystemTable The system table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @return other Contain some other errors. + +**/ +EFI_STATUS +EFIAPI +UserAuthentication2Entry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + + DriverHandle =3D NULL; + + mUserAuthenticationData =3D AllocateZeroPool (sizeof (USER_AUTHENTICATI= ON_PRIVATE_DATA)); + if (mUserAuthenticationData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mUserAuthenticationData->ConfigAccess.ExtractConfig =3D ExtractConfig; + mUserAuthenticationData->ConfigAccess.RouteConfig =3D RouteConfig; + mUserAuthenticationData->ConfigAccess.Callback =3D UserAuthenticationCa= llback; + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDATE_PASSW= ORD; + + // + // Install Config Access protocol to driver handle. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mUserAuthenticationData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + mUserAuthenticationData->DriverHandle =3D DriverHandle; + + // + // Add HII data to database. + // + HiiHandle =3D HiiAddPackages ( + &mUserAuthenticationVendorGuid, + DriverHandle, + UserAuthentication2DxeStrings, + UserAuthenticationDxeVfrBin, + NULL + ); + if (HiiHandle =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + mUserAuthenticationData->HiiHandle =3D HiiHandle; + + return EFI_SUCCESS; +} + +/** + Unloads the application and its installed protocol. + + @param[in] ImageHandle Handle that identifies the image to be un= loaded. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +UserAuthentication2Unload ( + IN EFI_HANDLE ImageHandle + ) +{ + ASSERT (mUserAuthenticationData !=3D NULL); + + // + // Uninstall Config Access Protocol. + // + if (mUserAuthenticationData->DriverHandle !=3D NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + mUserAuthenticationData->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mUserAuthenticationData->ConfigAccess, + NULL + ); + mUserAuthenticationData->DriverHandle =3D NULL; + } + + // + // Remove Hii Data. + // + if (mUserAuthenticationData->HiiHandle !=3D NULL) { + HiiRemovePackages (mUserAuthenticationData->HiiHandle); + } + + FreePool (mUserAuthenticationData); + mUserAuthenticationData =3D NULL; + + return EFI_SUCCESS; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxe.c b/Features/Intel/UserInterface/UserAuth= FeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxe.c new file mode 100644 index 0000000000..bba2057a96 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxe.c @@ -0,0 +1,780 @@ +/** @file + This Driver mainly provides Setup Form to change password and + does user authentication before entering Setup. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UserAuthenticationDxe.h" + +EFI_EVENT mExitBootServicesEvent =3D NULL; +EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol =3D NULL; +USER_AUTHENTICATION_PRIVATE_DATA *mUserAuthenticationData =3D NULL; +EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication =3D NULL; + +EFI_GUID mUserAuthenticationVendorGuid =3D USER_AUTHENTICATION_FORMSET_GU= ID; +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath =3D { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + USER_AUTHENTICATION_FORMSET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + Get a user input string. + + @param[in] PopUpString A popup string to inform user. + @param[in, out] UserInput The user input string + @param[in] UserInputMaxLen The max unicode count of the UserInpu= t without NULL terminator. +**/ +EFI_STATUS +GetUserInput ( + IN CHAR16 *PopUpString, + IN OUT CHAR16 *UserInput, + IN UINTN UserInputMaxLen + ) +{ + EFI_INPUT_KEY InputKey; + UINTN InputLength; + CHAR16 *Mask; + + UserInput[0] =3D 0; + Mask =3D AllocateZeroPool ((UserInputMaxLen + 1) * sizeof(CHAR16)); + if (Mask =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InputLength =3D 0; + + while (TRUE) { + if (InputLength < UserInputMaxLen) { + Mask[InputLength] =3D L'_'; + } + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + L"--------------------------------", + Mask, + NULL + ); + if (InputKey.ScanCode =3D=3D SCAN_NULL) { + // + // Check whether finish inputing password. + // + if (InputKey.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN && InputLength= > 0) { + // + // Add the null terminator. + // + UserInput[InputLength] =3D 0; + break; + } else if ((InputKey.UnicodeChar =3D=3D CHAR_NULL) || + (InputKey.UnicodeChar =3D=3D CHAR_LINEFEED) || + (InputKey.UnicodeChar =3D=3D CHAR_CARRIAGE_RETURN) + ) { + continue; + } else { + // + // delete last key entered + // + if (InputKey.UnicodeChar =3D=3D CHAR_BACKSPACE) { + if (InputLength > 0) { + UserInput[InputLength] =3D 0; + Mask[InputLength] =3D 0; + InputLength--; + } + } else { + if (InputLength =3D=3D UserInputMaxLen) { + Mask[InputLength] =3D 0; + continue; + } + // + // add Next key entry + // + UserInput[InputLength] =3D InputKey.UnicodeChar; + Mask[InputLength] =3D L'*'; + InputLength++; + } + } + } + } + FreePool (Mask); + return EFI_SUCCESS; +} + +/** + Display a message box to end user. + + @param[in] DisplayString The string in message box. +**/ +VOID +MessageBox ( + IN CHAR16 *DisplayString + ) +{ + EFI_INPUT_KEY Key; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); +} + +/** + Force system reset. +**/ +VOID +ForceSystemReset ( + VOID + ) +{ + MessageBox (L"Password retry count reach, reset system!"); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + CpuDeadLoop(); +} + +/** + Display message for set password. + + @param[in] ReturnStatus The return status for set password. +**/ +VOID +PrintSetPasswordStatus ( + IN EFI_STATUS ReturnStatus + ) +{ + CHAR16 *DisplayString; + CHAR16 *DisplayString2; + + EFI_INPUT_KEY Key; + + if (ReturnStatus =3D=3D EFI_UNSUPPORTED) { + DisplayString =3D L"New password is not strong enough!"; + DisplayString2 =3D L"Password must at least 8 chars and include lower= case, uppercase alphabetic, number and symbol"; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + DisplayString2, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } else { + if (ReturnStatus =3D=3D EFI_SUCCESS) { + DisplayString =3D L"New password is updated successfully!"; + } else if (ReturnStatus =3D=3D EFI_ALREADY_STARTED) { + DisplayString =3D L"New password is found in the history passwords!= "; + } else { + DisplayString =3D L"New password update fails!"; + } + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + DisplayString, + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar !=3D CHAR_CARRIAGE_RETURN); + } +} + +/** + Require user input password. + + @retval TRUE User input correct password successfully. + @retval FALSE The password is not set. +**/ +BOOLEAN +RequireUserPassword ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 UserInputPw[PASSWORD_MAX_= SIZE]; + CHAR16 *PopUpString; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY VerifyPolicy; + + Status =3D EFI_SUCCESS; + ZeroMem(UserInputPw, sizeof(UserInputPw)); + + if (!IsPasswordInstalled ()) { + return FALSE; + } + + Status =3D GetPasswordVerificationPolicy (&VerifyPolicy); + if (!EFI_ERROR (Status)) { + if (WasPasswordVerified() && (!VerifyPolicy.NeedReVerify)) { + DEBUG ((DEBUG_INFO, "Password was verified and Re-verify is not nee= ded\n")); + return TRUE; + } + } + + PopUpString =3D L"Please input admin password"; + + while (TRUE) { + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString, UserInputPw, PASSWORD_MAX_SIZE - 1); + + Status =3D VerifyPassword (UserInputPw, StrSize(UserInputPw)); + if (!EFI_ERROR(Status)) { + break; + } + if (Status =3D=3D EFI_ACCESS_DENIED) { + // + // Password retry count reach. + // + ForceSystemReset (); + } + MessageBox (L"Incorrect password!"); + } + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + + gST->ConOut->ClearScreen(gST->ConOut); + + return TRUE; +} + +/** + Set user password. + +**/ +VOID +SetUserPassword ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 UserInputPw[PASSWORD_MAX_SIZE]; + CHAR16 TmpPassword[PASSWORD_MAX_SIZE]; + CHAR16 *PopUpString; + CHAR16 *PopUpString2; + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + ZeroMem(TmpPassword, sizeof(TmpPassword)); + + PopUpString =3D L"Please set admin password"; + + while (TRUE) { + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString, UserInputPw, PASSWORD_MAX_SIZE - 1); + + PopUpString2 =3D L"Please confirm your new password"; + gST->ConOut->ClearScreen(gST->ConOut); + GetUserInput (PopUpString2, TmpPassword, PASSWORD_MAX_SIZE - 1); + if (StrCmp (TmpPassword, UserInputPw) !=3D 0) { + MessageBox (L"Password are not the same!"); + continue; + } + + Status =3D SetPassword (UserInputPw, StrSize(UserInputPw), NULL, 0); + PrintSetPasswordStatus (Status); + if (!EFI_ERROR(Status)) { + break; + } + } + + ZeroMem(UserInputPw, sizeof(UserInputPw)); + ZeroMem(TmpPassword, sizeof(TmpPassword)); + + gST->ConOut->ClearScreen(gST->ConOut); +} + +/** + Check password before entering into setup. + + @param CodeType Indicates the type of status code being reported.= Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below. + + @param Value Describes the current status of a hardware or sof= tware entity. + This included information about the class and sub= class that is used to classify the entity + as well as an operation. For progress codes, the= operation is the current activity. + For error codes, it is the exception. For debug = codes, it is not defined at this time. + Type EFI_STATUS_CODE_VALUE is defined in "Related= Definitions" below. + Specific values are discussed in the Intel? Platf= orm Innovation Framework for EFI Status Code Specification. + + @param Instance The enumeration of a hardware or software entity = within the system. + A system may contain multiple entities that match= a class/subclass pairing. + The instance differentiates between them. An ins= tance of 0 indicates that instance information is unavailable, + not meaningful, or not relevant. Valid instance = numbers start with 1. + + + @param CallerId This optional parameter may be used to identify t= he caller. + This parameter allows the status code driver to a= pply different rules to different callers. + Type EFI_GUID is defined in InstallProtocolInterf= ace() in the UEFI 2.0 Specification. + + + @param Data This optional parameter may be used to pass addit= ional data + + @retval EFI_SUCCESS Status code is what we expected. + @retval EFI_UNSUPPORTED Status code not supported. + +**/ +EFI_STATUS +EFIAPI +CheckForPassword ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId, OPTIONAL + IN EFI_STATUS_CODE_DATA *Data OPTIONAL + ) +{ + BOOLEAN PasswordSet; + + if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) =3D=3D EFI_PROGRESS_CODE) &= & + (Value =3D=3D (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)))= { + // + // Check whether enter setup page. + // + PasswordSet =3D RequireUserPassword (); + if (PasswordSet) { + DEBUG ((DEBUG_INFO, "Welcome Admin!\n")); + } else { + DEBUG ((DEBUG_INFO, "Admin password is not set!\n")); + if (NeedEnrollPassword()) { + SetUserPassword (); + } + } + + return EFI_SUCCESS; + } else{ + return EFI_UNSUPPORTED; + } +} + +/** + This function allows a caller to extract the current configuration for = one + or more named elements from the target driver. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Request A null-terminated Unicode string in + format. + @param Progress On return, points to a character in the = Request + string. Points to the string's null term= inator if + request was successful. Points to the mo= st recent + '&' before the first failing name/value = pair (or + the beginning of the string if the failu= re is in + the first name/value pair) if the reques= t was not + successful. + @param Results A null-terminated Unicode string in + format which has all val= ues filled + in for the names in the Request string. = String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested= values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown na= me. + @retval EFI_NOT_FOUND Routing data doesn't match any storage i= n this + driver. + +**/ +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if (Progress =3D=3D NULL || Results =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress =3D Request; + return EFI_NOT_FOUND; +} + + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Configuration A null-terminated Unicode string in + format. + @param Progress A pointer to a string filled in with the= offset of + the most recent '&' before the first fai= ling + name/value pair (or the beginning of the= string if + the failure is in the first name/value p= air) or + the terminating NULL if all was successf= ul. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage i= n this + driver. + +**/ +EFI_STATUS +EFIAPI +RouteConfig ( + 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; + } + + *Progress =3D Configuration; + + return EFI_NOT_FOUND; +} + +/** + HII update Admin Password status. + +**/ +VOID +HiiUpdateAdminPasswordStatus ( + VOID + ) +{ + if (IsPasswordInstalled ()) { + HiiSetString ( + mUserAuthenticationData->HiiHandle, + STRING_TOKEN (STR_ADMIN_PASSWORD_STS_CONTENT), + L"Installed", + NULL + ); + } else { + HiiSetString ( + mUserAuthenticationData->HiiHandle, + STRING_TOKEN (STR_ADMIN_PASSWORD_STS_CONTENT), + L"Not Installed", + NULL + ); + } +} + +/** + This function processes the results of changes in configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROT= OCOL. + @param Action Specifies the type of action taken by th= e browser. + @param QuestionId A unique value which is sent to the orig= inal + exporting driver so that it can identify= the type + of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the = original + exporting driver. + @param ActionRequest On return, points to the action requeste= d by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the ac= tion. + @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. + +**/ +EFI_STATUS +EFIAPI +UserAuthenticationCallback ( + 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 + ) +{ + EFI_STATUS Status; + CHAR16 *UserInputPassword; + + Status =3D EFI_SUCCESS; + + if (((Value =3D=3D NULL) && (Action !=3D EFI_BROWSER_ACTION_FORM_OPEN) = && (Action !=3D EFI_BROWSER_ACTION_FORM_CLOSE)) || + (ActionRequest =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + { + switch (QuestionId) { + case ADMIN_PASSWORD_KEY_ID: + HiiUpdateAdminPasswordStatus (); + default: + break; + } + } + break; + case EFI_BROWSER_ACTION_CHANGING: + { + switch (QuestionId) { + case ADMIN_PASSWORD_KEY_ID: + if ((Type =3D=3D EFI_IFR_TYPE_STRING) && (Value->string =3D=3D 0)= && + (mUserAuthenticationData->PasswordState =3D=3D BROWSER_STATE_= SET_PASSWORD)) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDA= TE_PASSWORD; + ZeroMem (mUserAuthenticationData->OldPassword, sizeof(mUserAuth= enticationData->OldPassword)); + return EFI_INVALID_PARAMETER; + } + // + // The Callback is responsible for validating old password input = by user, + // If Callback return EFI_SUCCESS, it indicates validation pass. + // + switch (mUserAuthenticationData->PasswordState) { + case BROWSER_STATE_VALIDATE_PASSWORD: + UserInputPassword =3D HiiGetString (mUserAuthenticationData->Hi= iHandle, Value->string, NULL); + if ((StrLen (UserInputPassword) >=3D PASSWORD_MAX_SIZE)) { + Status =3D EFI_NOT_READY; + break; + } + if (UserInputPassword[0] =3D=3D 0) { + // + // Setup will use a NULL password to check whether the old pa= ssword is set, + // If the validation is successful, means there is no old pas= sword, return + // success to set the new password. Or need to return EFI_NOT= _READY to + // let user input the old password. + // + Status =3D VerifyPassword (UserInputPassword, StrSize (UserIn= putPassword)); + if (Status =3D=3D EFI_SUCCESS) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_SE= T_PASSWORD; + } else { + Status =3D EFI_NOT_READY; + } + break; + } + Status =3D VerifyPassword (UserInputPassword, StrSize (UserInpu= tPassword)); + if (Status =3D=3D EFI_SUCCESS) { + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_SET_= PASSWORD; + StrCpyS ( + mUserAuthenticationData->OldPassword, + sizeof(mUserAuthenticationData->OldPassword)/sizeof(CHAR16)= , + UserInputPassword + ); + } else { + // + // Old password mismatch, return EFI_NOT_READY to prompt for = error message. + // + if (Status =3D=3D EFI_ACCESS_DENIED) { + // + // Password retry count reach. + // + ForceSystemReset (); + } + Status =3D EFI_NOT_READY; + } + break; + + case BROWSER_STATE_SET_PASSWORD: + UserInputPassword =3D HiiGetString (mUserAuthenticationData->Hi= iHandle, Value->string, NULL); + if ((StrLen (UserInputPassword) >=3D PASSWORD_MAX_SIZE)) { + Status =3D EFI_NOT_READY; + break; + } + Status =3D SetPassword (UserInputPassword, StrSize (UserInputPa= ssword), mUserAuthenticationData->OldPassword, StrSize(mUserAuthenticationD= ata->OldPassword)); + PrintSetPasswordStatus (Status); + ZeroMem (mUserAuthenticationData->OldPassword, sizeof(mUserAuth= enticationData->OldPassword)); + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDA= TE_PASSWORD; + HiiUpdateAdminPasswordStatus (); + break; + + default: + break; + } + default: + break; + } + } + break; + default: + break; + } + return Status; +} + +/** + Unregister status code callback functions. + + @param Event Event whose notification function is being invoke= d. + @param Context Pointer to the notification function's context, w= hich is + always zero in current implementation. + +**/ +VOID +EFIAPI +UnregisterBootTimeHandlers ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + mRscHandlerProtocol->Unregister (CheckForPassword); +} + +/** + User Authentication entry point. + + @param ImageHandle The image handle. + @param SystemTable The system table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @return other Contain some other errors. + +**/ +EFI_STATUS +EFIAPI +UserAuthenticationEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + + DriverHandle =3D NULL; + + mUserAuthenticationData =3D AllocateZeroPool (sizeof (USER_AUTHENTICATI= ON_PRIVATE_DATA)); + if (mUserAuthenticationData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mUserAuthenticationData->ConfigAccess.ExtractConfig =3D ExtractConfig; + mUserAuthenticationData->ConfigAccess.RouteConfig =3D RouteConfig; + mUserAuthenticationData->ConfigAccess.Callback =3D UserAuthenticationCa= llback; + mUserAuthenticationData->PasswordState =3D BROWSER_STATE_VALIDATE_PASSW= ORD; + + // + // Install Config Access protocol to driver handle. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mUserAuthenticationData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + mUserAuthenticationData->DriverHandle =3D DriverHandle; + + // + // Add HII data to database. + // + HiiHandle =3D HiiAddPackages ( + &mUserAuthenticationVendorGuid, + DriverHandle, + UserAuthenticationDxeStrings, + UserAuthenticationDxeVfrBin, + NULL + ); + if (HiiHandle =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + mUserAuthenticationData->HiiHandle =3D HiiHandle; + + // + // Locate report status code protocol. + // + Status =3D gBS->LocateProtocol ( + &gEfiRscHandlerProtocolGuid, + NULL, + (VOID **) &mRscHandlerProtocol + ); + ASSERT_EFI_ERROR (Status); + + // + //Register the callback function for ReportStatusCode() notification. + // + mRscHandlerProtocol->Register (CheckForPassword, TPL_HIGH_LEVEL); + + // + // Unregister boot time report status code listener at ExitBootService = Event. + // + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + UnregisterBootTimeHandlers, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Locates SMM Communication protocol. + // + Status =3D gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL= , (VOID **) &mSmmCommunication); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +/** + Unloads the application and its installed protocol. + + @param[in] ImageHandle Handle that identifies the image to be un= loaded. + + @retval EFI_SUCCESS The image has been unloaded. +**/ +EFI_STATUS +EFIAPI +UserAuthenticationUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + ASSERT (mUserAuthenticationData !=3D NULL); + + // + // Uninstall Config Access Protocol. + // + if (mUserAuthenticationData->DriverHandle !=3D NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + mUserAuthenticationData->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mUserAuthenticationData->ConfigAccess, + NULL + ); + mUserAuthenticationData->DriverHandle =3D NULL; + } + + // + // Remove Hii Data. + // + if (mUserAuthenticationData->HiiHandle !=3D NULL) { + HiiRemovePackages (mUserAuthenticationData->HiiHandle); + } + + FreePool (mUserAuthenticationData); + mUserAuthenticationData =3D NULL; + + return EFI_SUCCESS; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxePassword.c b/Features/Intel/UserInterface/= UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxePassword.c new file mode 100644 index 0000000000..6e1fedfab7 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxePassword.c @@ -0,0 +1,319 @@ +/** @file + UserAuthentication DXE password wrapper. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UserAuthenticationDxe.h" + +/** + Initialize the communicate buffer using DataSize and Function. + + @param[out] DataPtr Points to the data in the communicate= buffer. + @param[in] DataSize The data size to send to SMM. + @param[in] Function The function number to initialize the= communicate header. + + @return Communicate buffer. +**/ +VOID* +InitCommunicateBuffer ( + OUT VOID **DataPtr OPTIONAL, + IN UINTN DataSize, + IN UINTN Function + ) +{ + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + VOID *Buffer; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *SmmCommRegionTable; + EFI_MEMORY_DESCRIPTOR *SmmCommMemRegion; + UINTN Index; + UINTN Size; + EFI_STATUS Status; + + Buffer =3D NULL; + Status =3D EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &SmmCommRegionTable + ); + if (EFI_ERROR (Status)) { + return NULL; + } + ASSERT (SmmCommRegionTable !=3D NULL); + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) (SmmCommRegionTable + 1)= ; + Size =3D 0; + for (Index =3D 0; Index < SmmCommRegionTable->NumberOfEntries; Index++)= { + if (SmmCommMemRegion->Type =3D=3D EfiConventionalMemory) { + Size =3D EFI_PAGES_TO_SIZE ((UINTN) SmmCommMemRegion->NumberOfPages= ); + if (Size >=3D (DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Da= ta) + sizeof (SMM_PASSWORD_COMMUNICATE_HEADER))) { + break; + } + } + SmmCommMemRegion =3D (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) SmmCommMemR= egion + SmmCommRegionTable->DescriptorSize); + } + ASSERT (Index < SmmCommRegionTable->NumberOfEntries); + + Buffer =3D (VOID*)(UINTN)SmmCommMemRegion->PhysicalStart; + ASSERT (Buffer !=3D NULL); + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gUserAuthenticationGuid); + SmmCommunicateHeader->MessageLength =3D DataSize + sizeof (SMM_PASSWORD= _COMMUNICATE_HEADER); + + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *) SmmCo= mmunicateHeader->Data; + ZeroMem (SmmPasswordFunctionHeader, DataSize + sizeof (SMM_PASSWORD_COM= MUNICATE_HEADER)); + SmmPasswordFunctionHeader->Function =3D Function; + if (DataPtr !=3D NULL) { + *DataPtr =3D SmmPasswordFunctionHeader + 1; + } + + return Buffer; +} + +/** + Send the data in communicate buffer to SMM. + + @param[in] Buffer Points to the data in the communica= te buffer. + @param[in] DataSize The data size to send to SMM. + + @retval EFI_SUCCESS Success is returned from the functi= on in SMM. + @retval Others Failure is returned from the functi= on in SMM. + +**/ +EFI_STATUS +SendCommunicateBuffer ( + IN VOID *Buffer, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + UINTN CommSize; + EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmPasswordFunctionHeader; + + CommSize =3D DataSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + = sizeof (SMM_PASSWORD_COMMUNICATE_HEADER); + + Status =3D mSmmCommunication->Communicate (mSmmCommunication, Buffer, &= CommSize); + ASSERT_EFI_ERROR (Status); + + SmmCommunicateHeader =3D (EFI_SMM_COMMUNICATE_HEADER *) Buffer; + SmmPasswordFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *)SmmCom= municateHeader->Data; + return SmmPasswordFunctionHeader->ReturnStatus; +} + +/** + Validate if the password is correct. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval EFI_SUCCESS The password is correct. + @retval EFI_SECURITY_VIOLATION The password is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to verify the = password. + @retval EFI_ACCESS_DENIED Password retry count reach. +**/ +EFI_STATUS +VerifyPassword ( + IN CHAR16 *Password, + IN UINTN PasswordSize + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_VERIFY_PASSWORD *VerifyPassword; + + ASSERT (Password !=3D NULL); + + if (PasswordSize > sizeof(VerifyPassword->Password) * sizeof(CHAR16)) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D InitCommunicateBuffer ( + (VOID**)&VerifyPassword, + sizeof(*VerifyPassword), + SMM_PASSWORD_FUNCTION_VERIFY_PASSWORD + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D UnicodeStrToAsciiStrS (Password, VerifyPassword->Password, s= izeof(VerifyPassword->Password)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + + Status =3D SendCommunicateBuffer (Buffer, sizeof(*VerifyPassword)); + +EXIT: + ZeroMem (VerifyPassword, sizeof(*VerifyPassword)); + return Status; +} + +/** + Set a new password. + + @param[in] NewPassword The user input new password. + NULL means clear password. + @param[in] NewPasswordSize The size of NewPassword in byte. + @param[in] OldPassword The user input old password. + NULL means no old password. + @param[in] OldPasswordSize The size of OldPassword in byte. + + @retval EFI_SUCCESS The NewPassword is set successfully. + @retval EFI_SECURITY_VIOLATION The OldPassword is incorrect. + @retval EFI_INVALID_PARAMETER The password or size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to set the pas= sword. + @retval EFI_ACCESS_DENIED Password retry count reach. + @retval EFI_UNSUPPORTED NewPassword is not strong enough. + @retval EFI_ALREADY_STARTED NewPassword is in history. +**/ +EFI_STATUS +SetPassword ( + IN CHAR16 *NewPassword, OPTIONAL + IN UINTN NewPasswordSize, + IN CHAR16 *OldPassword, OPTIONAL + IN UINTN OldPasswordSize + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_SET_PASSWORD *SetPassword; + + if (NewPasswordSize > sizeof(SetPassword->NewPassword) * sizeof(CHAR16)= ) { + return EFI_INVALID_PARAMETER; + } + if (OldPasswordSize > sizeof(SetPassword->OldPassword) * sizeof(CHAR16)= ) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D InitCommunicateBuffer ( + (VOID**)&SetPassword, + sizeof(*SetPassword), + SMM_PASSWORD_FUNCTION_SET_PASSWORD + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (NewPassword !=3D NULL) { + Status =3D UnicodeStrToAsciiStrS (NewPassword, SetPassword->NewPasswo= rd, sizeof(SetPassword->NewPassword)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } else { + SetPassword->NewPassword[0] =3D 0; + } + + if (OldPassword !=3D NULL) { + Status =3D UnicodeStrToAsciiStrS (OldPassword, SetPassword->OldPasswo= rd, sizeof(SetPassword->OldPassword)); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } else { + SetPassword->OldPassword[0] =3D 0; + } + + Status =3D SendCommunicateBuffer (Buffer, sizeof(*SetPassword)); + +EXIT: + ZeroMem (SetPassword, sizeof(*SetPassword)); + return Status; +} + +/** + Return if the password is set. + + @retval TRUE The password is set. + @retval FALSE The password is not set. +**/ +BOOLEAN +IsPasswordInstalled ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + Buffer =3D InitCommunicateBuffer ( + NULL, + 0, + SMM_PASSWORD_FUNCTION_IS_PASSWORD_SET + ); + if (Buffer =3D=3D NULL) { + return FALSE; + } + + Status =3D SendCommunicateBuffer (Buffer, 0); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Get password verification policy. + + @param[out] VerifyPolicy Verification policy. + + @retval EFI_SUCCESS Get verification policy successfully. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to get verific= ation policy. +**/ +EFI_STATUS +GetPasswordVerificationPolicy ( + OUT SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *VerifyPolicy + ) +{ + EFI_STATUS Status; + VOID *Buffer; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *GetVerifyPolicy; + + Buffer =3D InitCommunicateBuffer ( + (VOID**)&GetVerifyPolicy, + sizeof(*GetVerifyPolicy), + SMM_PASSWORD_FUNCTION_GET_VERIFY_POLICY + ); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D SendCommunicateBuffer (Buffer, sizeof(*GetVerifyPolicy)); + if (!EFI_ERROR (Status)) { + CopyMem (VerifyPolicy, GetVerifyPolicy, sizeof (SMM_PASSWORD_COMMUNIC= ATE_VERIFY_POLICY)); + } + + return Status; +} + +/** + Return if the password was verified. + + @retval TRUE The password was verified. + @retval FALSE The password was not verified. +**/ +BOOLEAN +WasPasswordVerified ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Buffer; + + Buffer =3D InitCommunicateBuffer ( + NULL, + 0, + SMM_PASSWORD_FUNCTION_WAS_PASSWORD_VERIFIED + ); + if (Buffer =3D=3D NULL) { + return FALSE; + } + + Status =3D SendCommunicateBuffer (Buffer, 0); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationSmm.c b/Features/Intel/UserInterface/UserAuth= FeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationSmm.c new file mode 100644 index 0000000000..07e834ebfa --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationSmm.c @@ -0,0 +1,674 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UserAuthenticationSmm.h" + +EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; + +UINTN mAdminPasswordTryCount =3D 0; + +BOOLEAN mNeedReVerify =3D TRUE; +BOOLEAN mPasswordVerified =3D FALSE; + +/** + Verify if the password is correct. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + @param[in] UserPasswordVarStruct The storage of password in variable. + + @retval EFI_SUCCESS The password is correct. + @retval EFI_SECURITY_VIOLATION The password is incorrect. +**/ +EFI_STATUS +VerifyPassword ( + IN CHAR8 *Password, + IN UINTN PasswordSize, + IN USER_PASSWORD_VAR_STRUCT *UserPasswordVarStruct + ) +{ + BOOLEAN HashOk; + UINT8 HashData[PASSWORD_HASH_SIZE]; + + HashOk =3D KeyLibGeneratePBKDF2Hash ( + HASH_TYPE_SHA256, + (UINT8 *)Password, + PasswordSize, + UserPasswordVarStruct->PasswordSalt, + sizeof(UserPasswordVarStruct->PasswordSalt), + HashData, + sizeof(HashData) + ); + if (!HashOk) { + return EFI_DEVICE_ERROR; + } + if (KeyLibSlowCompareMem (UserPasswordVarStruct->PasswordHash, HashData= , PASSWORD_HASH_SIZE) =3D=3D 0) { + return EFI_SUCCESS; + } else { + return EFI_SECURITY_VIOLATION; + } +} + +/** + Get hash data of password from non-volatile variable region. + + @param[in] UserGuid The user GUID of the password varia= ble. + @param[in] Index The index of the password. + 0 means current password. + Non-0 means the password history. + @param[out] UserPasswordVarStruct The storage of password in variable= . + + @retval EFI_SUCCESS The password hash is returned successfu= lly. + @retval EFI_NOT_FOUND The password hash is not found. +**/ +EFI_STATUS +GetPasswordHashFromVariable ( + IN EFI_GUID *UserGuid, + IN UINTN Index, + OUT USER_PASSWORD_VAR_STRUCT *UserPasswordVarStruct + ) +{ + UINTN DataSize; + CHAR16 PasswordName[sizeof(USER_AUTHENTICATI= ON_VAR_NAME)/sizeof(CHAR16) + 5]; + + if (Index !=3D 0) { + UnicodeSPrint (PasswordName, sizeof (PasswordName), L"%s%04x", USER_A= UTHENTICATION_VAR_NAME, Index); + } else { + UnicodeSPrint (PasswordName, sizeof (PasswordName), L"%s", USER_AUTHE= NTICATION_VAR_NAME); + } + + DataSize =3D sizeof(*UserPasswordVarStruct); + return mSmmVariable->SmmGetVariable ( + PasswordName, + UserGuid, + NULL, + &DataSize, + UserPasswordVarStruct + ); +} + +/** + Save password hash data to non-volatile variable region. + + @param[in] UserGuid The user GUID of the password varia= ble. + @param[in] UserPasswordVarStruct The storage of password in variable= . + + @retval EFI_SUCCESS The password hash is saved successfully= . + @retval EFI_OUT_OF_RESOURCES Insufficient resources to save the pass= word hash. +**/ +EFI_STATUS +SavePasswordHashToVariable ( + IN EFI_GUID *UserGuid, + IN USER_PASSWORD_VAR_STRUCT *UserPasswordVarStruct + ) +{ + EFI_STATUS Status; + + if (UserPasswordVarStruct =3D=3D NULL) { + Status =3D mSmmVariable->SmmSetVariable ( + USER_AUTHENTICATION_VAR_NAME, + UserGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE, + 0, + NULL + ); + } else { + Status =3D mSmmVariable->SmmSetVariable ( + USER_AUTHENTICATION_VAR_NAME, + UserGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE, + sizeof(*UserPasswordVarStruct), + UserPasswordVarStruct + ); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SavePasswordHashToVariable fails with %r\n", St= atus)); + } + + return Status; +} + +/** + Save old password hash data to non-volatile variable region as history. + + The number of password history variable is limited. + If all the password history variables are used, the new password histor= y + will override the oldest one. + + @param[in] UserGuid The user GUID of the password varia= ble. + @param[in] UserPasswordVarStruct The storage of password in variable= . + + @retval EFI_SUCCESS The password hash is saved successfully= . + @retval EFI_OUT_OF_RESOURCES Insufficient resources to save the pass= word hash. +**/ +EFI_STATUS +SaveOldPasswordToHistory ( + IN EFI_GUID *UserGuid, + IN USER_PASSWORD_VAR_STRUCT *UserPasswordVarStruct + ) +{ + EFI_STATUS Status; + UINTN DataSize; + UINT32 LastIndex; + CHAR16 PasswordName[sizeof(USER_AUTHENTICATI= ON_VAR_NAME)/sizeof(CHAR16) + 5]; + + DEBUG ((DEBUG_INFO, "SaveOldPasswordToHistory\n")); + + DataSize =3D sizeof(LastIndex); + Status =3D mSmmVariable->SmmGetVariable ( + USER_AUTHENTICATION_HISTORY_LAST_VAR_NAME, + UserGuid, + NULL, + &DataSize, + &LastIndex + ); + if (EFI_ERROR(Status)) { + LastIndex =3D 0; + } + if (LastIndex >=3D PASSWORD_HISTORY_CHECK_COUNT) { + LastIndex =3D 0; + } + + LastIndex ++; + UnicodeSPrint (PasswordName, sizeof (PasswordName), L"%s%04x", USER_AUT= HENTICATION_VAR_NAME, LastIndex); + + + Status =3D mSmmVariable->SmmSetVariable ( + PasswordName, + UserGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE= _NON_VOLATILE, + sizeof(*UserPasswordVarStruct), + UserPasswordVarStruct + ); + DEBUG ((DEBUG_INFO, " -- to %s, %r\n", PasswordName, Status)); + if (!EFI_ERROR(Status)) { + Status =3D mSmmVariable->SmmSetVariable ( + USER_AUTHENTICATION_HISTORY_LAST_VAR_NAME, + UserGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE, + sizeof(LastIndex), + &LastIndex + ); + DEBUG ((DEBUG_INFO, " LastIndex - 0x%04x, %r\n", LastIndex, Status)); + } + + return Status; +} + +/** + Calculate password hash data and save it to non-volatile variable regio= n. + + @param[in] UserGuid The user GUID of the password variab= le. + @param[in] Password The user input password. + NULL means delete the password varia= ble. + @param[in] PasswordSize The size of Password in byte. + + @retval EFI_SUCCESS The password hash is calculated and sav= ed. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to save the pass= word hash. +**/ +EFI_STATUS +SavePasswordToVariable ( + IN EFI_GUID *UserGuid, + IN CHAR8 *Password, OPTIONAL + IN UINTN PasswordSize + ) +{ + EFI_STATUS Status; + USER_PASSWORD_VAR_STRUCT UserPasswordVarStruct; + BOOLEAN HashOk; + + // + // If password is NULL, it means we want to clean password field saved = in variable region. + // + if (Password !=3D NULL) { + KeyLibGenerateSalt (UserPasswordVarStruct.PasswordSalt, sizeof(UserPa= sswordVarStruct.PasswordSalt)); + HashOk =3D KeyLibGeneratePBKDF2Hash ( + HASH_TYPE_SHA256, + (UINT8 *)Password, + PasswordSize, + UserPasswordVarStruct.PasswordSalt, + sizeof(UserPasswordVarStruct.PasswordSalt), + UserPasswordVarStruct.PasswordHash, + sizeof(UserPasswordVarStruct.PasswordHash) + ); + if (!HashOk) { + return EFI_DEVICE_ERROR; + } + Status =3D SavePasswordHashToVariable (UserGuid, &UserPasswordVarStru= ct); + // + // Save Password data to history variable + // + if (!EFI_ERROR(Status)) { + SaveOldPasswordToHistory (UserGuid, &UserPasswordVarStruct); + } + } else { + Status =3D SavePasswordHashToVariable (UserGuid, NULL); + } + + return Status; +} + +/** + Verify the password. + If the password variable does not exist, it passes the verification. + If the password variable exists, it does verification based upon passwo= rd variable. + + @param[in] UserGuid The user GUID of the password variab= le. + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval TRUE The verification passes. + @retval FALSE The verification fails. +**/ +BOOLEAN +IsPasswordVerified ( + IN EFI_GUID *UserGuid, + IN CHAR8 *Password, + IN UINTN PasswordSize + ) +{ + USER_PASSWORD_VAR_STRUCT UserPasswordVarStruct; + EFI_STATUS Status; + UINTN *PasswordTryCount; + + PasswordTryCount =3D &mAdminPasswordTryCount; + + Status =3D GetPasswordHashFromVariable (UserGuid, 0, &UserPasswordVarSt= ruct); + if (EFI_ERROR(Status)) { + return TRUE; + } + + // + // Old password exists + // + Status =3D VerifyPassword (Password, PasswordSize, &UserPasswordVarStru= ct); + if (EFI_ERROR(Status)) { + if (Password[0] !=3D 0) { + *PasswordTryCount =3D *PasswordTryCount + 1; + } + return FALSE; + } + + return TRUE; +} + +/** + Return if the password is set. + + @param[in] UserGuid The user GUID of the password variab= le. + + @retval TRUE The password is set. + @retval FALSE The password is not set. +**/ +BOOLEAN +IsPasswordSet ( + IN EFI_GUID *UserGuid + ) +{ + USER_PASSWORD_VAR_STRUCT UserPasswordVarStruct; + EFI_STATUS Status; + + Status =3D GetPasswordHashFromVariable(UserGuid, 0, &UserPasswordVarStr= uct); + if (EFI_ERROR(Status)) { + return FALSE; + } + return TRUE; +} + +/** + Return if the password is strong. + Criteria: + 1) length >=3D PASSWORD_MIN_SIZE + 2) include lower case, upper case, number, symbol. + + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval TRUE The password is strong. + @retval FALSE The password is weak. +**/ +BOOLEAN +IsPasswordStrong ( + IN CHAR8 *Password, + IN UINTN PasswordSize + ) +{ + UINTN Index; + BOOLEAN HasLowerCase; + BOOLEAN HasUpperCase; + BOOLEAN HasNumber; + BOOLEAN HasSymbol; + + if (PasswordSize < PASSWORD_MIN_SIZE) { + return FALSE; + } + + HasLowerCase =3D FALSE; + HasUpperCase =3D FALSE; + HasNumber =3D FALSE; + HasSymbol =3D FALSE; + for (Index =3D 0; Index < PasswordSize - 1; Index++) { + if (Password[Index] >=3D 'a' && Password[Index] <=3D 'z') { + HasLowerCase =3D TRUE; + } else if (Password[Index] >=3D 'A' && Password[Index] <=3D 'Z') { + HasUpperCase =3D TRUE; + } else if (Password[Index] >=3D '0' && Password[Index] <=3D '9') { + HasNumber =3D TRUE; + } else { + HasSymbol =3D TRUE; + } + } + if ((!HasLowerCase) || (!HasUpperCase) || (!HasNumber) || (!HasSymbol))= { + return FALSE; + } + return TRUE; +} + +/** + Return if the password is set before in PASSWORD_HISTORY_CHECK_COUNT. + + @param[in] UserGuid The user GUID of the password variab= le. + @param[in] Password The user input password. + @param[in] PasswordSize The size of Password in byte. + + @retval TRUE The password is set before. + @retval FALSE The password is not set before. +**/ +BOOLEAN +IsPasswordInHistory ( + IN EFI_GUID *UserGuid, + IN CHAR8 *Password, + IN UINTN PasswordSize + ) +{ + EFI_STATUS Status; + USER_PASSWORD_VAR_STRUCT UserPasswordVarStruct; + UINTN Index; + + for (Index =3D 1; Index <=3D PASSWORD_HISTORY_CHECK_COUNT; Index++) { + Status =3D GetPasswordHashFromVariable (UserGuid, Index, &UserPasswor= dVarStruct); + if (!EFI_ERROR(Status)) { + Status =3D VerifyPassword (Password, PasswordSize, &UserPasswordVar= Struct); + if (!EFI_ERROR(Status)) { + return TRUE; + } + } + } + + return FALSE; +} + +/** + Communication service SMI Handler entry. + + This SMI handler provides services for password management. + + @param[in] DispatchHandle The unique handle assigned to this handl= er by SmiHandlerRegister(). + @param[in] RegisterContext Points to an optional handler context wh= ich was specified when the + handler was registered. + @param[in, out] CommBuffer A pointer to a collection of data in mem= ory that will + be conveyed from a non-SMM environment i= nto an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS The interrupt was handled a= nd quiesced. No other handlers + should still be called. + @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quie= sced but other handlers should + still be called. + @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pend= ing and other handlers should still + be called. + @retval EFI_INTERRUPT_PENDING The interrupt could not be = quiesced. +**/ +EFI_STATUS +EFIAPI +SmmPasswordHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *RegisterContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + EFI_STATUS Status; + SMM_PASSWORD_COMMUNICATE_HEADER *SmmFunctionHeader; + UINTN CommBufferPayloadSize; + UINTN TempCommBufferSize; + SMM_PASSWORD_COMMUNICATE_SET_PASSWORD SmmCommunicateSetPassword; + SMM_PASSWORD_COMMUNICATE_VERIFY_PASSWORD SmmCommunicateVerifyPassword; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY SmmCommunicateSetVerifyPolicy= ; + SMM_PASSWORD_COMMUNICATE_VERIFY_POLICY *SmmCommunicateGetVerifyPolic= y; + UINTN PasswordLen; + EFI_GUID *UserGuid; + UINTN *PasswordTryCount; + + // + // If input is invalid, stop processing this SMI + // + if (CommBuffer =3D=3D NULL || CommBufferSize =3D=3D NULL) { + return EFI_SUCCESS; + } + + TempCommBufferSize =3D *CommBufferSize; + PasswordLen =3D 0; + + if (TempCommBufferSize < sizeof (SMM_PASSWORD_COMMUNICATE_HEADER)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: SMM communication buffer si= ze invalid!\n")); + return EFI_SUCCESS; + } + + CommBufferPayloadSize =3D TempCommBufferSize - sizeof (SMM_PASSWORD_COM= MUNICATE_HEADER); + + Status =3D EFI_SUCCESS; + SmmFunctionHeader =3D (SMM_PASSWORD_COMMUNICATE_HEADER *)CommBuffer; + + UserGuid =3D &gUserAuthenticationGuid; + PasswordTryCount =3D &mAdminPasswordTryCount; + + switch (SmmFunctionHeader->Function) { + case SMM_PASSWORD_FUNCTION_IS_PASSWORD_SET: + PasswordTryCount =3D NULL; + if (CommBufferPayloadSize !=3D 0) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: IS_PASSWORD_SET payload b= uffer invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + if (IsPasswordSet(UserGuid)) { + Status =3D EFI_SUCCESS; + } else { + Status =3D EFI_NOT_FOUND; + } + break; + case SMM_PASSWORD_FUNCTION_SET_PASSWORD: + if (*PasswordTryCount >=3D PASSWORD_MAX_TRY_COUNT) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: SET_PASSWORD try count re= ach!\n")); + PasswordTryCount =3D NULL; + Status =3D EFI_ACCESS_DENIED; + goto EXIT; + } + if (CommBufferPayloadSize !=3D sizeof(SMM_PASSWORD_COMMUNICATE_SET_PA= SSWORD)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: SET_PASSWORD payload buff= er invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + CopyMem (&SmmCommunicateSetPassword, SmmFunctionHeader + 1, sizeof(Sm= mCommunicateSetPassword)); + + PasswordLen =3D AsciiStrnLenS(SmmCommunicateSetPassword.OldPassword, = sizeof(SmmCommunicateSetPassword.OldPassword)); + if (PasswordLen =3D=3D sizeof(SmmCommunicateSetPassword.OldPassword))= { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: OldPassword invalid!\n"))= ; + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + + if (!IsPasswordVerified (UserGuid, SmmCommunicateSetPassword.OldPassw= ord, PasswordLen + 1)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: PasswordVerify - FAIL\n")= ); + Status =3D EFI_SECURITY_VIOLATION; + goto EXIT; + } + + PasswordLen =3D AsciiStrnLenS(SmmCommunicateSetPassword.NewPassword, = sizeof(SmmCommunicateSetPassword.NewPassword)); + if (PasswordLen =3D=3D sizeof(SmmCommunicateSetPassword.NewPassword))= { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: NewPassword invalid!\n"))= ; + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + if (PasswordLen !=3D 0 && !IsPasswordStrong (SmmCommunicateSetPasswor= d.NewPassword, PasswordLen + 1)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: NewPassword too weak!\n")= ); + Status =3D EFI_UNSUPPORTED; + goto EXIT; + } + if (PasswordLen !=3D 0 && IsPasswordInHistory (UserGuid, SmmCommunica= teSetPassword.NewPassword, PasswordLen + 1)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: NewPassword in history!\n= ")); + Status =3D EFI_ALREADY_STARTED; + goto EXIT; + } + + if (PasswordLen =3D=3D 0) { + Status =3D SavePasswordToVariable (UserGuid, NULL, 0); + } else { + Status =3D SavePasswordToVariable (UserGuid, SmmCommunicateSetPassw= ord.NewPassword, PasswordLen + 1); + } + break; + + case SMM_PASSWORD_FUNCTION_VERIFY_PASSWORD: + if (*PasswordTryCount >=3D PASSWORD_MAX_TRY_COUNT) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: VERIFY_PASSWORD try count= reach!\n")); + PasswordTryCount =3D NULL; + Status =3D EFI_ACCESS_DENIED; + goto EXIT; + } + if (CommBufferPayloadSize !=3D sizeof(SMM_PASSWORD_COMMUNICATE_VERIFY= _PASSWORD)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: VERIFY_PASSWORD payload b= uffer invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + CopyMem (&SmmCommunicateVerifyPassword, SmmFunctionHeader + 1, sizeof= (SmmCommunicateVerifyPassword)); + + PasswordLen =3D AsciiStrnLenS(SmmCommunicateVerifyPassword.Password, = sizeof(SmmCommunicateVerifyPassword.Password)); + if (PasswordLen =3D=3D sizeof(SmmCommunicateVerifyPassword.Password))= { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: Password invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + if (!IsPasswordVerified (UserGuid, SmmCommunicateVerifyPassword.Passw= ord, PasswordLen + 1)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: PasswordVerify - FAIL\n")= ); + Status =3D EFI_SECURITY_VIOLATION; + goto EXIT; + } + mPasswordVerified =3D TRUE; + Status =3D EFI_SUCCESS; + break; + + case SMM_PASSWORD_FUNCTION_SET_VERIFY_POLICY: + PasswordTryCount =3D NULL; + if (CommBufferPayloadSize !=3D sizeof(SMM_PASSWORD_COMMUNICATE_VERIFY= _POLICY)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: SET_VERIFY_POLICY payload= buffer invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + CopyMem (&SmmCommunicateSetVerifyPolicy, SmmFunctionHeader + 1, sizeo= f(SmmCommunicateSetVerifyPolicy)); + mNeedReVerify =3D SmmCommunicateSetVerifyPolicy.NeedReVerify; + break; + + case SMM_PASSWORD_FUNCTION_GET_VERIFY_POLICY: + PasswordTryCount =3D NULL; + if (CommBufferPayloadSize !=3D sizeof(SMM_PASSWORD_COMMUNICATE_VERIFY= _POLICY)) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: GET_VERIFY_POLICY payload= buffer invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + SmmCommunicateGetVerifyPolicy =3D (SMM_PASSWORD_COMMUNICATE_VERIFY_PO= LICY *) (SmmFunctionHeader + 1); + SmmCommunicateGetVerifyPolicy->NeedReVerify =3D mNeedReVerify; + break; + case SMM_PASSWORD_FUNCTION_WAS_PASSWORD_VERIFIED: + PasswordTryCount =3D NULL; + if (CommBufferPayloadSize !=3D 0) { + DEBUG ((DEBUG_ERROR, "SmmPasswordHandler: WAS_PASSWORD_VERIFIED pay= load buffer invalid!\n")); + Status =3D EFI_INVALID_PARAMETER; + goto EXIT; + } + if (mPasswordVerified) { + Status =3D EFI_SUCCESS; + } else { + Status =3D EFI_NOT_STARTED; + } + break; + + default: + PasswordTryCount =3D NULL; + Status =3D EFI_UNSUPPORTED; + break; + } + +EXIT: + if (PasswordTryCount !=3D NULL) { + if (Status =3D=3D EFI_SUCCESS) { + *PasswordTryCount =3D 0; + } + } + SmmFunctionHeader->ReturnStatus =3D Status; + + return EFI_SUCCESS; +} + +/** + 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 +PasswordSmmInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE SmmHandle; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; + CHAR16 PasswordHistoryName[sizeof(USER_A= UTHENTICATION_VAR_NAME)/sizeof(CHAR16) + 5]; + UINTN Index; + + ASSERT (PASSWORD_HASH_SIZE =3D=3D SHA256_DIGEST_SIZE); + ASSERT (PASSWORD_HISTORY_CHECK_COUNT < 0xFFFF); + + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL= , (VOID**)&mSmmVariable); + ASSERT_EFI_ERROR (Status); + + // + // Make password variables read-only for DXE driver for security concer= n. + // + Status =3D gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, = (VOID **) &VariableLock); + if (!EFI_ERROR (Status)) { + Status =3D VariableLock->RequestToLock (VariableLock, USER_AUTHENTICA= TION_VAR_NAME, &gUserAuthenticationGuid); + ASSERT_EFI_ERROR (Status); + + for (Index =3D 1; Index <=3D PASSWORD_HISTORY_CHECK_COUNT; Index++) { + UnicodeSPrint (PasswordHistoryName, sizeof (PasswordHistoryName), L= "%s%04x", USER_AUTHENTICATION_VAR_NAME, Index); + Status =3D VariableLock->RequestToLock (VariableLock, PasswordHisto= ryName, &gUserAuthenticationGuid); + ASSERT_EFI_ERROR (Status); + } + Status =3D VariableLock->RequestToLock (VariableLock, USER_AUTHENTICA= TION_HISTORY_LAST_VAR_NAME, &gUserAuthenticationGuid); + ASSERT_EFI_ERROR (Status); + } + + SmmHandle =3D NULL; + Status =3D gSmst->SmiHandlerRegister (SmmPasswordHandler, &gUserAuth= enticationGuid, &SmmHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + if (IsPasswordCleared()) { + DEBUG ((DEBUG_INFO, "IsPasswordCleared\n")); + SavePasswordToVariable (&gUserAuthenticationGuid, NULL, 0); + } + + return EFI_SUCCESS; +} + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/Platf= ormPasswordLibNull/PlatformPasswordLibNull.uni b/Features/Intel/UserInterfa= ce/UserAuthFeaturePkg/Library/PlatformPasswordLibNull/PlatformPasswordLibNu= ll.uni new file mode 100644 index 0000000000..b0255889e0 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Library/PlatformPass= wordLibNull/PlatformPasswordLibNull.uni @@ -0,0 +1,19 @@ +// /** @file +// NULL platform password library instance that returns the password clea= r state based upon PCD. +// +// NULL PlatformPasswordLib instance does NOT really detect whether the p= assword is cleared +// but returns the PCD value directly. This instance can be used to verif= y security +// related features during platform enabling and development. It should b= e replaced +// by a platform-specific method(e.g. Button pressed) in a real platform = for product. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "NULL platform pa= ssword library instance that returns the password clear state based upon PC= D." + +#string STR_MODULE_DESCRIPTION #language en-US "NULL PlatformPas= swordLib instance does NOT really detect whether the password is cleared bu= t returns the PCD value directly. This instance can be used to verify secur= ity related features during platform enabling and development. It should be= replaced by a platform-specific method(e.g. Button pressed) in a real plat= form for product." + diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/Readme.md b/F= eatures/Intel/UserInterface/UserAuthFeaturePkg/Readme.md new file mode 100644 index 0000000000..46049ea02e --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/Readme.md @@ -0,0 +1,90 @@ +# Overview +* **Feature Name:** User Authentication +* **PI Phase(s) Supported:** DXE +* **SMM Required?** Yes + +## Purpose +This feature provides a user authentication service which includes: +1. An HII form to present a user password prompt. +2. A DXE driver to manage the state of the UI and use the SMM Communicate= protocol to manage password data with + the SMM driver. +3. A SMM driver to perform password authentication in an isolated executi= on environment and manage the password hash + on non-volatile storage in the form of a UEFI variable. + +# High-Level Theory of Operation +*_TODO_* +A description of how the device works at a high-level. + +The description should not be constrained to implementation details but p= rovide a simple mental model of how the +feature is supposed to work. + +## Firmware Volumes +*_TODO_* +A bulleted list of the firmware volumes that feature module(s) are placed= in. + +## Modules +*_TODO_* +A bulleted list of the modules that make up the feature. + +## +*_TODO_* +Each module in the feature should have a section that describes the modul= e in a level of detail that is useful +to better understand the module source code. + +## +*_TODO_* +Each library in the feature should have a section that describes the libr= ary in a level of detail that is useful +to better understand the library source code. + +## Key Functions +*_TODO_* +A bulleted list of key functions for interacting with the feature. + +Not all features need to be listed. Only functions exposed through extern= al interfaces that are important for feature +users to be aware of. + +## Configuration +*_TODO_* +Information that is useful for configuring the feature. + +Not all configuration options need to be listed. This section is used to = provide more background on configuration +options than possible elsewhere. + +## Data Flows +*_TODO_* +Architecturally defined data structures and flows for the feature. + +## Control Flows +*_TODO_* +Key control flows for the feature. + +## Build Flows +*_TODO_* +Any special build flows should be described in this section. + +This is particularly useful for features that use custom build tools or r= equire non-standard tool configuration. If the +standard flow in the feature package template is used, this section may b= e empty. + +## Test Point Results +*_TODO_* +The test(s) that can verify porting is complete for the feature. + +Each feature must describe at least one test point to verify the feature = is successful. If the test point is not +implemented, this should be stated. + +## Functional Exit Criteria +*_TODO_* +The testable functionality for the feature. + +This section should provide an ordered list of criteria that a board inte= grator can reference to ensure the feature is +functional on their board. + +## Feature Enabling Checklist +*_TODO_* +An ordered list of required activities to achieve desired functionality f= or the feature. + +## Common Optimizations +*_TODO_* +Common size or performance tuning options for this feature. + +This section is recommended but not required. If not used, the contents s= hould be left empty. diff --git a/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthentic= ationDxeSmm/UserAuthenticationDxeStrings.uni b/Features/Intel/UserInterface= /UserAuthFeaturePkg/UserAuthenticationDxeSmm/UserAuthenticationDxeStrings.u= ni new file mode 100644 index 0000000000..1e3a179677 --- /dev/null +++ b/Features/Intel/UserInterface/UserAuthFeaturePkg/UserAuthenticationDx= eSmm/UserAuthenticationDxeStrings.uni @@ -0,0 +1,30 @@ +/** @file +// String definitions for User Authentication formset. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +**/ + +#langdef en-US "English" +#langdef fr-FR "Francais" + + +#string STR_FORM_SET_TITLE #language en-US "User Password Man= agement" + #language fr-FR "User Password Man= agement" +#string STR_FORM_SET_TITLE_HELP #language en-US "This Driver mainl= y handle user's password" + #language fr-FR "This Driver mainl= y handle user's password" +#string STR_FORM_TITLE #language en-US "Password Manageme= nt Form" + #language fr-FR "Password Manageme= nt Form" +#string STR_ADMIN_PASSWORD_PROMPT #language en-US "Change Admin Pass= word" + #language fr-FR "Change Admin Pass= word" +#string STR_ADMIN_PASSWORD_HELP #language en-US "Input old admin p= assword if it was set, then you can change the password to a new one. After= the change action, you may need input the new password when you enter UI. = The new password must be between 8 and 32 chars include lowercase, uppercas= e alphabetic, number, and symbol. Input an empty password can clean old adm= in password, then no need input password to enter UI." + #language fr-FR "Input old admin p= assword if it was set, then you can change the password to a new one. After= the change action, you may need input the new password when you enter UI. = The new password must be between 8 and 32 chars include lowercase, uppercas= e alphabetic, number, and symbol. Input an empty password can clean old adm= in password, then no need input password to enter UI." +#string STR_ADMIN_PASSWORD_STS_HELP #language en-US "Current Admin Pas= sword status: Installed or Not Installed." + #language fr-FR "Current Admin Pas= sword status: Installed or Not Installed." +#string STR_ADMIN_PASSWORD_STS_PROMPT #language en-US "Admin Password St= atus" + #language fr-FR "Admin Password St= atus" +#string STR_ADMIN_PASSWORD_STS_CONTENT #language en-US "" + #language fr-FR "" + --=20 2.16.2.windows.1