From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 8235B941CF0 for ; Tue, 26 Mar 2024 13:57:57 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=HDFIu7OkFxoXwolrMSYFr4+bmW2Z2ULuPAnjXAUuwEg=; c=relaxed/simple; d=groups.io; h=From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type; s=20240206; t=1711461475; v=1; b=lZa05WfbHRxuCVG4ZERgsEQzEbGtHN1q6J2SiPoR0vDVpC2f4aATK+bLUfDSdEWbZI6R4586 TQ3zkg0IOI0FLd1/UplEcVr1UfGlG1WeCdigqmTDwEop4k4roXHe4rkOQ2LXIF/a0XZk8iG+gzB eyQzptsRTSt5v1cFH219y58LFEg7Nz14DeKMGALFDKEZAvharTTDIy6877QsPiH8FHHtjljO4uI GGedoFAhrwTsrRRvZUSYjTYZVLgsHBQusbgMZXAyxHz7ghhzmU5X+8ZBIs4lMY6XBd2PeMAOsIs iJQPdB0OgA/aNf/yIyufJKZGpyCgzddOELeHbdd+6cmwg== X-Received: by 127.0.0.2 with SMTP id UQJAYY7687511xKkI5sFqr33; Tue, 26 Mar 2024 06:57:55 -0700 X-Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.129]) by mx.groups.io with SMTP id smtpd.web10.9641.1711461474673542280 for ; Tue, 26 Mar 2024 06:57:55 -0700 X-Received: from MW4PR12MB7031.namprd12.prod.outlook.com (2603:10b6:303:1ef::6) by DM4PR12MB6661.namprd12.prod.outlook.com (2603:10b6:8:b7::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.32; Tue, 26 Mar 2024 13:57:49 +0000 X-Received: from MW4PR12MB7031.namprd12.prod.outlook.com ([fe80::fef9:2c9c:21b5:6f50]) by MW4PR12MB7031.namprd12.prod.outlook.com ([fe80::fef9:2c9c:21b5:6f50%2]) with mapi id 15.20.7409.031; Tue, 26 Mar 2024 13:57:48 +0000 From: "Nickle Wang via groups.io" To: Mike Maslenkin , "devel@edk2.groups.io" CC: Abner Chang , Igor Kulchytskyy , Nick Ramirez Subject: Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishClientPkg/Features: support Redfish Secure Boot Thread-Topic: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishClientPkg/Features: support Redfish Secure Boot Thread-Index: AQHadkczGthP6T46l0yZ9fRTb5QF9rFKHa/A Date: Tue, 26 Mar 2024 13:57:48 +0000 Message-ID: References: <20240314145300.153086-1-nicklew@nvidia.com> <517B1BB3-9433-4C68-80F3-46BBC1627671@gmail.com> In-Reply-To: <517B1BB3-9433-4C68-80F3-46BBC1627671@gmail.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MW4PR12MB7031:EE_|DM4PR12MB6661:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: T4uk6eYBIhr2TCxK7/GoYO55tHTz7pGzEpHeIUYMaqPFXblsqb0hGNA2ZbDqg2TEvAF+ryYLGWBd2WCRWCw2mlUsifekV93zbIps+OMIVUniFdoMmZYsR7r013gV1f/4h2kdDjjhPH56JW4wU3kwfWGlaCcUuoYOUq2wcHahHLvsQwSsbOAf/jiTSpAj1HP1hLc0A4hlIRwdR7BSmyKJSNs/uNwalukrUC/ctf3tWnntHbF/Le3Y7O8lZS6mxnuK0RRoxnX0EZBpjI94KNi0vN67b+42xKOSIMC0o8uMOBmjMjoeHFbWytzf0hmVnkmSvfg+Ejwj51uWrAKanekg+qlbbPXadaQntnnvCyN+3iMV165cGn0lQNPprsO0UiJjlQ/IMaUKQbUoZnoZC7broe0XImirWBiCxm/rKKQFUSbbh1970+1qUB1uVFYORiXh0Rs43Vpv9IWS2rjobgnxZKbtR/2kGX14o7r8SWe5eMgo/Ya5Dl0WqUOtrlXAz92ufODb4zyU8wWS2rGx39QIQlrtKIokQkaEM+Ooac8Rke26HUvqIg2Ko50Drv3jkBGusODmv83j+2YECleoq3K7Icu+/to4sefR9EWFSMwOJZQ= x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?46IY6WCpoY/8PYrhZYyV5dvlbt8+mf1PeLLoi7VY1XzOEuDQ6cf2AUXMGTUN?= =?us-ascii?Q?wScgERdNQKvCR16HC8CuH01h5Gn6h5Envk25gLknLe18YW2RC5IRgq5KPmCp?= =?us-ascii?Q?x7dTumxMYLzf/GYF4sT1pCyFX6haPse+e7Q8Q8fA9lOVQkiwyaYmvo1rDA5i?= =?us-ascii?Q?VIZjUKzkQkz8D89M9Wo3s9O0IGzUoC3KLfQAL8dm8lca+wcjEd2r68I9txZe?= =?us-ascii?Q?sOgNXBh1leYHmHXnli8RUBq7Y7iej4jqBpFOMrG/k1wwoBOBVduC4Di9/ftU?= =?us-ascii?Q?fjGkM1KmsXUB11A3J4kJRq5Zdl24ktLxI5qmhV9UN3Tqa75hz/wPZgxL/Ga6?= =?us-ascii?Q?YR+j16AvAU3TbXGN+3EtpmJXQlQvpFXCv5Y6dW2C7MWyzNviVSNmF7Po+cXR?= =?us-ascii?Q?FTR9AQ4IDVDMu04Rap7wxZxN7r4c97gqoZleNjiqlEXIgsV3RQXuzGMgubth?= =?us-ascii?Q?nWsrE804s/Ry9m5pOln1xPluQX9Z8GvsoSSHVS4Q+aM1eelUbwsrhd+gSCOc?= =?us-ascii?Q?txkY36PC1FktMcH9X0pKBl5yoeUbIlXsAJ5GLjMSTYyIEBXZp9RhE3hMRC+3?= =?us-ascii?Q?VN59+S158QA+r/MtQdw8Ol+y/kMuYNggw3slm9tBsqPTZLcUJB4MBuXw1cMQ?= =?us-ascii?Q?rFlnf88V5YoNXFfeXxmliecy5bDtvF9RL7Mfc9Tup2QYFkevabOf1uxP7FDg?= =?us-ascii?Q?GW38DvoEY5s63y/rJzBaGZSQJWGnwIcL0xp2e0wPdctS0CT9waRTUercSHmr?= =?us-ascii?Q?FdIjcqQT5LkGbTGQ3B+9X+Q9lL0X5dNzmwF795WuTCstkqBWbnaOZMD0DBKa?= =?us-ascii?Q?a8nNIDk5UCkDBFtasVe8x/THQJYuKCJlvRysJauczhlSravEHyuCUjCZIOek?= =?us-ascii?Q?i34peZ5d/ioVTPmyu/Dabjp1BuEo3Gqx1kYdclO6lJnBla5+10ZXOF3QFFec?= =?us-ascii?Q?RGOb8L9IuS18PRRy166oCQ09HMEh1DgD3xtlLYSYZbnj6chT4+oJad0x7SwN?= =?us-ascii?Q?t0SIM2Y2pXJR5aR9lTac35OlzQ2q9JW+QTMWRDPuiI4AWTDjXsUFA9fJg6eg?= =?us-ascii?Q?v/LFE9iTicZ1OQ2PAulzr9sTcY5iPjazYQqsLmDQIOQAklmPsdHMk3hiuhu+?= =?us-ascii?Q?eaWabQ0OvZQ1CaFaNEehA7zgBGXNUyOt7r/cN0JtjSDlaRTtbvy+4R8prri6?= =?us-ascii?Q?gvIazNTL+RKWroEsoeuyAS4KJtiDmpXsxICp4kNY49hCjT1mxiXRt+VlpBwZ?= =?us-ascii?Q?HdYztTypHD6yT73vNO4S8J4ERzaZTneFMNRPNEgjczvM5BwSzU2XnOrS6GiN?= =?us-ascii?Q?OGfzNooGH2OwapRCUOtD4jI/ygW33nZdFVc4WICfL43WRxO7KX/r0FmrRVt1?= =?us-ascii?Q?glyn2S4/7quBWqo9JTn0jqZgkmJAKfUUpKojIAXNVb5/FUgN2XtZDLpL0tmg?= =?us-ascii?Q?lB1PXmhPUrlmfiWDUNvSbYE//XzpaVkaDmintXlMb/pyw+MUoOhrQvGOGV0p?= =?us-ascii?Q?i2YFQmKpp4FaRinFMwYhMp6vteBO+g4U0BxLaGDTvS6TnSfVrCPN6B7crxMj?= =?us-ascii?Q?wNXNGTYa9GFSUHH2GDE=3D?= MIME-Version: 1.0 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MW4PR12MB7031.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6b8ce871-6362-4599-72b2-08dc4d9cb89e X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Mar 2024 13:57:48.6855 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: p0wH5JzJ4JcFCzKcZx5uMVOhSZO4pAMK5xJX09FW47a8lrvP9mwE7A+BReDSZWPXci7hsMyGuPYvzV+c4LZoOQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6661 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Tue, 26 Mar 2024 06:57:55 -0700 Reply-To: devel@edk2.groups.io,nicklew@nvidia.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: K1hrQpG5sh9wQ8X0x66efdohx7686176AA= Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_MW4PR12MB7031FBB03B6BF5921D54207AD9352MW4PR12MB7031namp_" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=lZa05Wfb; dmarc=pass (policy=none) header.from=groups.io; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io --_000_MW4PR12MB7031FBB03B6BF5921D54207AD9352MW4PR12MB7031namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Mike, Thanks for your review. I addressed your review comments in pull request: h= ttps://github.com/tianocore/edk2-redfish-client/pull/83 I am waiting for Abner's patch (PR#84) because I plan to incorporate Abner'= s changes into this driver. I will send version 2 patch series here for rev= iew later. Regards, Nickle From: Mike Maslenkin Sent: Friday, March 15, 2024 3:38 AM To: devel@edk2.groups.io; Nickle Wang Cc: Abner Chang ; Igor Kulchytskyy ; Ni= ck Ramirez Subject: Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishClientPkg= /Features: support Redfish Secure Boot External email: Use caution opening links or attachments Hi Nickle, please find my comments below On 14. 3. 2024., at 17:53, Nickle Wang via groups.io > wrote: Introduce SecureBoot driver to support /redfish/v1/Systems/SYS/SecureBoot resource. Signed-off-by: Nickle Wang > Cc: Abner Chang > Cc: Igor Kulchytskyy > Cc: Nick Ramirez > --- .../RedfishClientComponents.dsc.inc | 2 + RedfishClientPkg/RedfishClientLibs.dsc.inc | 4 + .../SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf | 60 ++ .../v1_1_0/Common/SecureBootCommon.h | 40 + .../v1_1_0/Common/SecureBootCommon.c | 756 ++++++++++++++++ .../SecureBoot/v1_1_0/Dxe/SecureBootDxe.c | 808 ++++++++++++++++++ RedfishClientPkg/RedfishClient.fdf.inc | 1 + 7 files changed, 1671 insertions(+) create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.inf create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.h create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.c create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.c diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc b/RedfishClie= ntPkg/RedfishClientComponents.dsc.inc index ae2a4b025..42fc0c299 100644 --- a/RedfishClientPkg/RedfishClientComponents.dsc.inc +++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc @@ -34,6 +34,7 @@ RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf RedfishClientPkg/Features/BootOptionCollection/BootOptionCollectionDxe.in= f RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.inf + RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf !include RedfishClientPkg/RedfishJsonStructureDxe.dsc.inc @@ -47,3 +48,4 @@ RedfishClientPkg/Converter/Bios/v1_0_9/RedfishBios_V1_0_9_Dxe.inf RedfishClientPkg/Converter/BootOptionCollection/RedfishBootOptionCollecti= on_Dxe.inf RedfishClientPkg/Converter/BootOption/v1_0_4/RedfishBootOption_V1_0_4_Dxe= .inf + RedfishClientPkg/Converter/SecureBoot/v1_1_0/RedfishSecureBoot_V1_1_0_Dx= e.inf diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/= RedfishClientLibs.dsc.inc index 6599926ab..9126465df 100644 --- a/RedfishClientPkg/RedfishClientLibs.dsc.inc +++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc @@ -25,6 +25,8 @@ BiosV1_0_9Lib|RedfishClientPkg/ConverterLib/edk2library/Bios/v1_0_9/Lib.i= nf BootOptionCollectionLib|RedfishClientPkg/ConverterLib/edk2library/BootOpt= ionCollection/Lib.inf BootOptionV1_0_4Lib|RedfishClientPkg/ConverterLib/edk2library/BootOption/= v1_0_4/Lib.inf + SecureBootV1_1_0Lib|RedfishClientPkg/ConverterLib/edk2library/SecureBoot= /v1_1_0/Lib.inf + # # Above modules should be pulled in by build tool. # @@ -42,3 +44,5 @@ RedfishAddendumLib|RedfishClientPkg/Library/RedfishAddendumLib/RedfishAdd= endumLib.inf RedfishDebugLib|RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf RedfishHttpLib|RedfishPkg/Library/RedfishHttpLib/RedfishHttpLib.inf + SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBo= otVariableLib.inf + PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPo= licy/PlatformPKProtectionLibVarPolicy.inf diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= inf b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf new file mode 100644 index 000000000..1ad8c623f --- /dev/null +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf @@ -0,0 +1,60 @@ +## @file +# +# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights re= served. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SecureBootDxe + FILE_GUID =3D 5E4025F8-DA42-468A-853E-6A1091D35052 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D RedfishResourceEntryPoint + UNLOAD_IMAGE =3D RedfishResourceUnload + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + RedfishPkg/RedfishPkg.dec + RedfishClientPkg/RedfishClientPkg.dec + +[Sources] + ../Common/SecureBootCommon.h + ../Common/SecureBootCommon.c + SecureBootDxe.c + +[LibraryClasses] + BaseMemoryLib + DebugLib + EdkIIRedfishResourceConfigLib + RedfishFeatureUtilityLib + RedfishVersionLib + RedfishResourceIdentifyLib + SecureBootVariableLib + UefiLib + UefiDriverEntryPoint + RedfishAddendumLib + UefiRuntimeServicesTableLib + +[Protocols] + gEdkIIRedfishConfigHandlerProtocolGuid ## PRODUCED + gEfiRestJsonStructureProtocolGuid ## CONSUMED + gEdkIIRedfishResourceConfigProtocolGuid ## PRODUCED + gEdkIIRedfishFeatureProtocolGuid ## CONSUMED + +[Guids] + gEfiSecureBootEnableDisableGuid ## CONSUMED + +[Pcd] + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize + gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize + gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootRequired + +[Depex] + TRUE diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.h b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.h new file mode 100644 index 000000000..0d1824160 --- /dev/null +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h @@ -0,0 +1,40 @@ +/** @file + + Redfish feature driver implementation - internal header file + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_SECUREBOOT_COMMON_H_ +#define EFI_REDFISH_SECUREBOOT_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Schema information. +// +#define REDFISH_MANAGED_URI L"Systems/{}/SecureBoot" +#define REDFISH_DUMMY_CONFIG_LANG L"Systems/{1}/SecureBoot" +#define MAX_URI_LENGTH 256 +#define RESOURCE_SCHEMA "SecureBoot" +#define RESOURCE_SCHEMA_MAJOR "1" +#define RESOURCE_SCHEMA_MINOR "1" +#define RESOURCE_SCHEMA_ERRATA "0" +#define RESOURCE_SCHEMA_VERSION "v1_1_0" +#define SECURE_BOOT_SETUP_MODE "SetupMode" +#define SECURE_BOOT_USER_MODE "UserMode" +#define SECURE_BOOT_ENABLED "Enabled" +#define SECURE_BOOT_DISABLED "Disabled" +#define SECURE_BOOT_MODE_STR_LEN 16 + +#endif diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.c new file mode 100644 index 000000000..56a45ee72 --- /dev/null +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c @@ -0,0 +1,756 @@ +/** @file + Redfish feature driver implementation - common functions + + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SecureBootCommon.h" + +CHAR8 SecureBootEmptyJson[] =3D "{\"@odata.id\": \"\", = \"@odata.type\": \"#SecureBoot.v1_1_0.SecureBoot\", \"Id\": \"\", \"Name\":= \"\", \"Attributes\":{}}"; + +REDFISH_RESOURCE_COMMON_PRIVATE *mRedfishResourcePrivate = =3D NULL; +EFI_HANDLE mRedfishResourceConfigProtocolHandle = =3D NULL; +CHAR16 *mSecureBootSupportedAttributes[SECURE_BO= OT_MODE_STR_LEN] =3D { + L"SecureBootCurrentBoot", + L"SecureBootEnable", + L"SecureBootMode" +}; + +/** + Read EFI_SECURE_BOOT_ENABLE_NAME variable and return its value to caller= . + + @retval BOOLEAN TRUE when EFI_SECURE_BOOT_ENABLE_NAME value is SECURE= _BOOT_ENABLE + FALSE when EFI_SECURE_BOOT_ENABLE_NAME value is SECUR= E_BOOT_DISABLE +**/ +BOOLEAN +RedfishReadSecureBootEnable ( + VOID + ) +{ + UINT8 *Buffer; + BOOLEAN SecureBootEnableValue; + + Buffer =3D NULL; + SecureBootEnableValue =3D FALSE; + + GetVariable2 ( + EFI_SECURE_BOOT_ENABLE_NAME, + &gEfiSecureBootEnableDisableGuid, + (VOID **)&Buffer, + NULL + ); + + if (Buffer !=3D NULL) { + if (*Buffer =3D=3D SECURE_BOOT_ENABLE) { + SecureBootEnableValue =3D TRUE; + } + + FreePool (Buffer); + } + + return SecureBootEnableValue; +} + +/** + Write EFI_SECURE_BOOT_ENABLE_NAME variable with given value. + + @param[in] SecureBootEnableValue Value to write. TRUE is SECURE_BOO= T_ENABLE. + FALSE is SECURE_BOOT_DISABLE. + + @retval EFI_SUCCESS Write value successfully. + @retval Others Some error happened. +**/ +EFI_STATUS +RedfishWriteSecureBootEnable ( + BOOLEAN SecureBootEnableValue + ) +{ + EFI_STATUS Status; + UINT8 VarValue; + + VarValue =3D (SecureBootEnableValue ? SECURE_BOOT_ENABLE : SECURE_BOOT_D= ISABLE); + Status =3D gRT->SetVariable ( + EFI_SECURE_BOOT_ENABLE_NAME, + &gEfiSecureBootEnableDisableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_A= CCESS, + sizeof (VarValue), + &VarValue + ); + + return Status; +} + +/** + Consume Redfish resource in given Json data. + + @param[in] This Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance. + @param[in] Json The JSON to consume. + @param[in] HeaderEtag The Etag string returned in HTTP header= . + + @retval EFI_SUCCESS Consume Redfish attribute successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +RedfishConsumeResourceCommon ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN CHAR8 *Json, + IN CHAR8 *HeaderEtag OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_REDFISH_SECUREBOOT_V1_1_0 *SecureBoot; + EFI_REDFISH_SECUREBOOT_V1_1_0_CS *SecureBootCs; + BOOLEAN SecureBootEnableDisable; + + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) { + return EFI_INVALID_PARAMETER; + } + + SecureBoot =3D NULL; + SecureBootCs =3D NULL; + SecureBootEnableDisable =3D RedfishReadSecureBootEnable (); + + Status =3D Private->JsonStructProtocol->ToStructure ( + Private->JsonStructProtocol, + NULL, + Json, + (EFI_REST_JSON_STRUCTURE_HEADER = **)&SecureBoot + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: ToStructure() failed: %r\n", __func__, Statu= s)); + return Status; + } + + SecureBootCs =3D SecureBoot->SecureBoot; + + // + // Check ETAG to see if we need to consume it + // + if (CheckEtag (Private->Uri, HeaderEtag, SecureBootCs->odata_etag)) { + // + // No change + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no change, ignore consu= me action\n", __func__, Private->Uri)); + Status =3D EFI_ALREADY_STARTED; + goto ON_RELEASE; + } + + // + // Secure boot enable + // + if (SecureBootCs->SecureBootEnable !=3D NULL) { + if (SecureBootEnableDisable !=3D *SecureBootCs->SecureBootEnable) { + // + // Write value to "SecureBootEnable" variable. AuthVariableLib will = enable or disable secure boot + // based on "SecureBootEnable" value. + // + Status =3D RedfishWriteSecureBootEnable (*SecureBootCs->SecureBootEn= able); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: write secure boot enable disable failed:= %r\n", __func__, Status)); + } else { + REDFISH_ENABLE_SYSTEM_REBOOT (); + } + } else { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: secure boot mode is not changed\n"= , __func__)); + } + } + +ON_RELEASE: + + // + // Release resource. + // + Private->JsonStructProtocol->DestoryStructure ( + Private->JsonStructProtocol, + (EFI_REST_JSON_STRUCTURE_HEADER *)SecureB= oot + ); + + return EFI_SUCCESS; +} + +/** + Provision Redfish resource. This function reads secure boot variable and= convert it + to Redfish attribute. + + @param[in] JsonStructProtocol Pointer to Json structure protocol. + @param[in] InputJson Jason data on input. + @param[in] ResourceId Resource ID. This is optional. + @param[in] ConfigureLang Configure language for this Redfish res= ource. + @param[in] ProvisionMode TRUE when this is to provision Redfish = attribute to + Redfish service. FALSE is to update Red= fish attribute + to Redfish service. + @param[out] ResultJson Json data on output. + + @retval EFI_SUCCESS Provision Redfish attribute successfull= y. + @retval Others Some error happened. + +**/ +EFI_STATUS +ProvisioningSecureBootProperties ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *JsonStructProtocol, + IN CHAR8 *InputJson, + IN CHAR8 *ResourceId OPTIONAL, + IN EFI_STRING ConfigureLang, + IN BOOLEAN ProvisionMode, + OUT CHAR8 **ResultJson + ) +{ + EFI_REDFISH_SECUREBOOT_V1_1_0 *SecureBoot; + EFI_REDFISH_SECUREBOOT_V1_1_0_CS *SecureBootCs; + EFI_STATUS Status; + BOOLEAN PropertyChanged; + CHAR8 *AsciiStringValue; + INT32 *IntegerValue; + UINT8 SetupMode; + BOOLEAN SecureBootEnabled; + BOOLEAN SecureBootEnableDisable; + + if ((JsonStructProtocol =3D=3D NULL) || (ResultJson =3D=3D NULL) || IS_E= MPTY_STRING (InputJson) || IS_EMPTY_STRING (ConfigureLang)) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s with: %s\n", __func__,= ConfigureLang, (ProvisionMode ? L"Provision resource" : L"Update resource"= ))); + + *ResultJson =3D NULL; + PropertyChanged =3D FALSE; + AsciiStringValue =3D NULL; + SecureBootEnableDisable =3D RedfishReadSecureBootEnable (); + SecureBootEnabled =3D IsSecureBootEnabled (); + + SecureBoot =3D NULL; + Status =3D JsonStructProtocol->ToStructure ( + JsonStructProtocol, + NULL, + InputJson, + (EFI_REST_JSON_STRUCTURE_HEADER **)&S= ecureBoot + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: ToStructure failure: %r\n", __func__, Status= )); + return Status; + } + + SecureBootCs =3D SecureBoot->SecureBoot; + + // + // ID + // + if (SecureBootCs->Id !=3D NULL) { + SecureBootCs->Id =3D NULL; + } + + // + // Name + // + if (SecureBootCs->Name !=3D NULL) { + SecureBootCs->Name =3D NULL; + } + + // + // Secure boot variables that we will handle here + // + // EFI_SETUP_MODE_NAME (gEfiGlobalVariableGuid) + // EFI_SECURE_BOOT_MODE_NAME (gEfiGlobalVariableGuid) + // EFI_SECURE_BOOT_ENABLE_NAME (gEfiSecureBootEnableDisableGuid) + // + + // + // Current Boot + // + if (PropertyChecker (SecureBootCs->SecureBootCurrentBoot, ProvisionMode)= ) { + AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN * size= of (CHAR8)); + if (AsciiStringValue !=3D NULL) { + AsciiSPrint (AsciiStringValue, SECURE_BOOT_MODE_STR_LEN, "%a", (Secu= reBootEnabled ? SECURE_BOOT_ENABLED : SECURE_BOOT_DISABLED)); + if (ProvisionMode || (AsciiStrCmp (SecureBootCs->SecureBootCurrentBo= ot, AsciiStringValue) !=3D 0)) { + SecureBootCs->SecureBootCurrentBoot =3D AsciiStringValue; + PropertyChanged =3D TRUE; + } + } else { + DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__)); + } + } + + // + // Secure boot enable + // + if (PropertyChecker (SecureBootCs->SecureBootEnable, ProvisionMode)) { + if (ProvisionMode || (*SecureBootCs->SecureBootEnable !=3D SecureBootE= nableDisable)) { + IntegerValue =3D AllocatePool (sizeof (*IntegerValue)); + if (IntegerValue !=3D NULL) { + *IntegerValue =3D (SecureBootEnableDisable ? 0x01= : 0x00); + SecureBootCs->SecureBootEnable =3D IntegerValue; + PropertyChanged =3D TRUE; + } else { + DEBUG ((DEBUG_ERROR, "%a: out of resource\n", __func__)); + } + } + } + + // + // Secure boot mode + // + if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode)) { + Status =3D GetSetupMode (&SetupMode); + if (!EFI_ERROR (Status)) { + AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE_STR_LEN *siz= eof (CHAR8)); + if (AsciiStringValue !=3D NULL) { + AsciiSPrint (AsciiStringValue, SECURE_BOOT_MODE_STR_LEN *sizeof (C= HAR8), "%a", (SetupMode =3D=3D USER_MODE ? SECURE_BOOT_USER_MODE : SECURE_B= OOT_SETUP_MODE)); + if (ProvisionMode || (AsciiStrCmp (SecureBootCs->SecureBootMode, A= sciiStringValue) !=3D 0)) { + SecureBootCs->SecureBootMode =3D AsciiStringValue; + PropertyChanged =3D TRUE; + } + } + } else { + DEBUG ((DEBUG_ERROR, "%a: cannot read setup mode: %r\n", __func__, S= tatus)); + } + } + + // + // Convert C structure back to JSON text. + // + Status =3D JsonStructProtocol->ToJson ( + JsonStructProtocol, + (EFI_REST_JSON_STRUCTURE_HEADER *)SecureB= oot, + ResultJson + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: ToJson() failed: %r\n", __func__, Status)); + return Status; SecureBoot structure leak. It is released below. + } + + // + // Release resource. + // + JsonStructProtocol->DestoryStructure ( + JsonStructProtocol, + (EFI_REST_JSON_STRUCTURE_HEADER *)SecureBoot + ); + + return (PropertyChanged ? EFI_SUCCESS : EFI_NOT_FOUND); +} + +/** + Provision Redfish resource and upload data to Redfish service. This func= tion + checks OEM data and platform addendum data before sending data to Redfis= h service. + + @param[in] Private Pointer to private data. + + @retval EFI_SUCCESS Provision Redfish resource successfully= . + @retval Others Some error happened. + +**/ +EFI_STATUS +ProvisioningSecureBootResource ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private + ) +{ + EFI_STATUS Status; + CHAR8 *Json; + CHAR8 *JsonWithAddendum; + REDFISH_RESPONSE Response; + + if (Private =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Json =3D NULL; + + Status =3D ProvisioningSecureBootProperties ( + Private->JsonStructProtocol, + SecureBootEmptyJson, + NULL, + REDFISH_DUMMY_CONFIG_LANG, + TRUE, + &Json + ); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resource for= %s ignored. Nothing changed\n", __func__, REDFISH_DUMMY_CONFIG_LANG)); + Status =3D EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, "%a: provisioning existing resource for %s fail= ed: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status)); + } + + goto ON_RELEASE; + } + + // + // Check and see if platform has OEM data or not + // + Status =3D RedfishGetOemData ( + Private->Uri, + RESOURCE_SCHEMA, + RESOURCE_SCHEMA_VERSION, + Json, + &JsonWithAddendum + ); + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { + FreePool (Json); + Json =3D JsonWithAddendum; + JsonWithAddendum =3D NULL; + } + + // + // Check and see if platform has addendum data or not + // + Status =3D RedfishGetAddendumData ( + Private->Uri, + RESOURCE_SCHEMA, + RESOURCE_SCHEMA_VERSION, + Json, + &JsonWithAddendum + ); + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { + FreePool (Json); + Json =3D JsonWithAddendum; + JsonWithAddendum =3D NULL; + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resource for %s\= n", __func__, REDFISH_DUMMY_CONFIG_LANG)); + + // + // PATCH back to instance + // + Status =3D RedfishHttpPatchResource (Private->RedfishService, Private->U= ri, Json, &Response); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: patch resource for %s failed: %r\n", __func_= _, REDFISH_DUMMY_CONFIG_LANG, Status)); + } + +ON_RELEASE: + + if (Json !=3D NULL) { + FreePool (Json); + } + + RedfishHttpFreeResponse (&Response); + + return Status; +} + +/** + Provisioning redfish resource to Redfish service. + + @param[in] Private Pointer to private data. + @param[in] ResourceExist TRUE if resource exists, PUT method wil= l be used. + FALSE if resource does not exist POST m= ethod is used. Actually ProvisioningSecureBootResource uses PATCH only. + + @retval EFI_SUCCESS Provision resource successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +RedfishProvisioningResourceCommon ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN BOOLEAN ResourceExist + ) +{ + if (Private =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + return ProvisioningSecureBootResource (Private); +} + +/** + Check resource from given Json data. + + @param[in] This Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance. + @param[in] Json The JSON data to check. + @param[in] HeaderEtag The Etag string returned in HTTP header= . + + @retval EFI_SUCCESS Check resource successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +RedfishCheckResourceCommon ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN CHAR8 *Json, + IN CHAR8 *HeaderEtag OPTIONAL + ) +{ + UINTN Index; + EFI_STATUS Status; + UINTN Count; + EFI_STRING Property; + + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check ETAG to see if we need to check it + // + if (CheckEtag (Private->Uri, HeaderEtag, NULL)) { + // + // No change + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no change, ignore check= action\n", __func__, Private->Uri)); + return EFI_SUCCESS; + } + + Count =3D sizeof (mSecureBootSupportedAttributes) / sizeof (mSecureBootS= upportedAttributes[0]); + if (Count =3D=3D 0) { + return EFI_UNSUPPORTED; + } + + Status =3D EFI_SUCCESS; + for (Index =3D 0; Index < Count; Index++) { + Property =3D mSecureBootSupportedAttributes[Index]; + if (Property =3D=3D NULL) { + continue; + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: [%d] check attribute for: %s\n", __f= unc__, Index, Property)); + if (!MatchPropertyWithJsonContext (Property, Json)) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: property is missing: %s\n", __func= __, Property)); + Status =3D EFI_NOT_FOUND; + } + } + + return Status; +} + +/** + Update resource to Redfish service. + + @param[in] Private Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance. + @param[in] Json The JSON data to be updated. + + @retval EFI_SUCCESS Update resource successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +RedfishUpdateResourceCommon ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN CHAR8 *InputJson + ) +{ + EFI_STATUS Status; + CHAR8 *Json; + CHAR8 *JsonWithAddendum; + REDFISH_RESPONSE Response; + + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (InputJson)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Json =3D NULL; + + Status =3D ProvisioningSecureBootProperties ( + Private->JsonStructProtocol, + SecureBootEmptyJson, + NULL, + REDFISH_DUMMY_CONFIG_LANG, + TRUE, + &Json + ); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s ignored. No= thing changed\n", __func__, REDFISH_DUMMY_CONFIG_LANG)); + Status =3D EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, "%a: update resource for %s failed: %r\n", __fu= nc__, REDFISH_DUMMY_CONFIG_LANG, Status)); + } + + goto ON_RELEASE; + } + + // + // Check and see if platform has OEM data or not + // + Status =3D RedfishGetOemData ( + Private->Uri, + RESOURCE_SCHEMA, + RESOURCE_SCHEMA_VERSION, + Json, + &JsonWithAddendum + ); + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { + FreePool (Json); + Json =3D JsonWithAddendum; + JsonWithAddendum =3D NULL; + } + + // + // Check and see if platform has addendum data or not + // + Status =3D RedfishGetAddendumData ( + Private->Uri, + RESOURCE_SCHEMA, + RESOURCE_SCHEMA_VERSION, + Json, + &JsonWithAddendum + ); + if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) { + FreePool (Json); + Json =3D JsonWithAddendum; + JsonWithAddendum =3D NULL; + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s\n", __func__, R= EDFISH_DUMMY_CONFIG_LANG)); + + // + // PATCH back to instance + // + Status =3D RedfishHttpPatchResource (Private->RedfishService, Private->U= ri, Json, &Response); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: patch resource for %s failed: %r\n", __func_= _, REDFISH_DUMMY_CONFIG_LANG, Status)); + } + +ON_RELEASE: + + if (Json !=3D NULL) { + FreePool (Json); + } + + RedfishHttpFreeResponse (&Response); + + return Status; +} + +/** + Identify resource in given Json data. + + @param[in] Private Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance. + @param[in] Json The JSON to be identified. + + @retval EFI_SUCCESS Identify resource successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +RedfishIdentifyResourceCommon ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN CHAR8 *Json + ) +{ + BOOLEAN Supported; + + Supported =3D RedfishIdentifyResource (Private->Uri, Private->Json); + if (Supported) { + // + // Keep URI and ConfigLang mapping + // + RedfishSetRedfishUri (REDFISH_DUMMY_CONFIG_LANG, Private->Uri); + } + + return (Supported ? EFI_SUCCESS : EFI_UNSUPPORTED); +} + +/** + Handle Redfish resource in Uri. + + @param[in] Private Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance. + @param[in] Uri URI to Redfish resource that we like to= process. + + @retval EFI_SUCCESS Handle resource successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +HandleResource ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN EFI_STRING Uri + ) +{ + EFI_STATUS Status; + REDFISH_SCHEMA_INFO SchemaInfo; + EFI_STRING ConfigLang; + + if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + // + // Resource match + // + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s\n", __func__,= Uri)); + + Status =3D GetRedfishSchemaInfo (Private->RedfishService, Private->JsonS= tructProtocol, Uri, NULL, &SchemaInfo); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to get schema information from: %s %r= \n", __func__, Uri, Status)); + return Status; + } + + // + // Check and see if this is target resource that we want to handle. + // Some resource is handled by other provider so we have to make sure th= is first. + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a: Identify for %s\n", __func__, Uri)); + ConfigLang =3D RedfishGetConfigLanguage (Uri); + if (ConfigLang =3D=3D NULL) { + Status =3D EdkIIRedfishResourceConfigIdentify (&SchemaInfo, Uri, NULL,= Private->InformationExchange); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_UNSUPPORTED) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" is not handled by us\n", = __func__, Uri)); + return EFI_SUCCESS; + } else if (Status =3D=3D EFI_NOT_FOUND) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" has nothing to handle\n",= __func__, Uri)); + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_ERROR, "%a: fail to identify resource: \"%s\": %r\n", = __func__, Uri, Status)); + return Status; + } + } else { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: history record found: %s\n", __func_= _, ConfigLang)); + FreePool (ConfigLang); + } + + // + // Check and see if target property exist or not even when collection me= mber exists. + // If not, we sill do provision. %s/sill/still + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a Check for %s\n", __func__, Uri)); + Status =3D EdkIIRedfishResourceConfigCheck (&SchemaInfo, Uri, NULL); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_UNSUPPORTED) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: \"%s\" is not handled by us\n", __= func__, Uri)); + return EFI_SUCCESS; + } + + // + // The target property does not exist, do the provision to create prop= erty. + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s\n", __func__, Uri)); + Status =3D EdkIIRedfishResourceConfigProvisioning (&SchemaInfo, Uri, N= ULL, Private->InformationExchange, FALSE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to provision with GET mode: %r\n", = __func__, Status)); + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s finished\n"= , __func__, Uri)); + + return Status; + } + + // + // Consume first. + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __func__, Uri)); + Status =3D EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to consume resource for: %s: %r\n", _= _func__, Uri, Status)); + } + + // + // Patch. + // + DEBUG ((REDFISH_DEBUG_TRACE, "%a update for %s\n", __func__, Uri)); + Status =3D EdkIIRedfishResourceConfigUpdate (&SchemaInfo, Uri, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to update resource for: %s: %r\n", __= func__, Uri, Status)); + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s finished\n", = __func__, Uri)); + + return Status; +} diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c new file mode 100644 index 000000000..a0f4f3d14 --- /dev/null +++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c @@ -0,0 +1,808 @@ +/** @file + Redfish feature driver implementation - SecureBoot + + (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved= . + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "../Common/SecureBootCommon.h" + +extern REDFISH_RESOURCE_COMMON_PRIVATE *mRedfishResourcePrivate; +extern EFI_HANDLE mRedfishResourceConfigProtocolHand= le; + +EFI_STATUS +HandleResource ( + IN REDFISH_RESOURCE_COMMON_PRIVATE *Private, + IN EFI_STRING Uri + ); + +/** + Provisioning redfish resource by given URI. + + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCOL = instance. + @param[in] Uri Target URI to create resource. + @param[in] PostMode TRUE if the resource does not exist, po= st method is used. + FALSE if the resource exist but propert= y is missing, put method is used. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceProvisioningResource ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + IN EFI_STRING Uri, + IN BOOLEAN PostMode + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STATUS Status; + REDFISH_RESPONSE Response; + + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning in %s mode\n", __func__, = (PostMode ? L"POST" : L"PATCH"))); This message conflicts with PostMode parameter description. + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCOL = (This); + + if (Private->RedfishService =3D=3D NULL) { + return EFI_NOT_READY; + } + + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, &= Response, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, U= ri)); + return Status; + } + + Private->Uri =3D Uri; + Private->Payload =3D Response.Payload; + ASSERT (Private->Payload !=3D NULL); + + Status =3D RedfishProvisioningResourceCommon (Private, !PostMode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to provision resource to: %s: %r\n", = __func__, Uri, Status)); + } else { + // + // Get latest ETag on URI and keep it in variable. + // + SetEtagFromUri (Private->RedfishService, Private->Uri, TRUE); + } + + // + // Release resource + // + RedfishHttpFreeResponse (&Response); + Private->Payload =3D NULL; + + return Status; +} + +/** + Consume resource from given URI. + + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCOL = instance. + @param[in] Uri The target URI to consume. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceConsumeResource ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + IN EFI_STRING Uri + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STATUS Status; + REDFISH_RESPONSE Response; + EFI_STRING PendingSettingUri; + REDFISH_RESPONSE PendingSettingResponse; + REDFISH_RESPONSE *ExpectedResponse; + CHAR8 *Etag; + + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + ZeroMem (&PendingSettingResponse, sizeof (REDFISH_RESPONSE)); + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCOL = (This); + + if (Private->RedfishService =3D=3D NULL) { + return EFI_NOT_READY; + } + + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, &= Response, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, U= ri)); + return Status; + } + + // + // Check and see if "@Redfish.Settings" exist or not. + // + PendingSettingUri =3D NULL; + Status =3D GetPendingSettings ( + Private->RedfishService, + Response.Payload, + &PendingSettingResponse, + &PendingSettingUri + ); + if (!EFI_ERROR (Status)) { + DEBUG ((REDFISH_DEBUG_TRACE, "%a: @Redfish.Settings found: %s\n", __fu= nc__, PendingSettingUri)); + Private->Uri =3D PendingSettingUri; + ExpectedResponse =3D &PendingSettingResponse; + } else { + Private->Uri =3D Uri; + ExpectedResponse =3D &Response; + } + + Private->Payload =3D ExpectedResponse->Payload; + ASSERT (Private->Payload !=3D NULL); + + Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private->Payload= ), EDKII_JSON_COMPACT); + ASSERT (Private->Json !=3D NULL); + + // + // Searching for etag in HTTP response header + // + Etag =3D NULL; + Status =3D GetHttpResponseEtag (ExpectedResponse, &Etag); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __fu= nc__)); + } + + Status =3D RedfishConsumeResourceCommon (Private, Private->Json, Etag); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to consume resource from: %s: %r\n", = __func__, Private->Uri, Status)); + } + + // + // Release resource + // + RedfishHttpFreeResponse (&Response); + RedfishHttpFreeResponse (&PendingSettingResponse); + Private->Payload =3D NULL; + + if (Private->Json !=3D NULL) { + FreePool (Private->Json); + Private->Json =3D NULL; + } + + if (Etag !=3D NULL) { + FreePool (Etag); + } + + if (PendingSettingUri !=3D NULL) { + FreePool (PendingSettingUri); + } + + return Status; +} + +/** + Get information about this protocol. + + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCOL = instance. + @param[out] Schema Supported schema. + @param[out] Major Supported major number. + @param[out] Minor Supported minor number. + @param[out] Errata Supported errata number. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceGetInfo ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + OUT REDFISH_SCHEMA_INFO *Info + ) +{ + if ((This =3D=3D NULL) || (Info =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + AsciiStrCpyS (Info->Schema, REDFISH_SCHEMA_STRING_SIZE, RESOURCE_SCHEMA)= ; + AsciiStrCpyS (Info->Major, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE_SCHEMA_= MAJOR); + AsciiStrCpyS (Info->Minor, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE_SCHEMA_= MINOR); + AsciiStrCpyS (Info->Errata, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE_SCHEMA= _ERRATA); + + return EFI_SUCCESS; +} + +/** + Update resource to given URI. + + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCOL = instance. + @param[in] Uri The target URI to consume. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceUpdate ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + IN EFI_STRING Uri + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STATUS Status; + REDFISH_RESPONSE Response; + + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCOL = (This); + + if (Private->RedfishService =3D=3D NULL) { + return EFI_NOT_READY; + } + + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, &= Response, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, U= ri)); + return Status; + } + + Private->Uri =3D Uri; + Private->Payload =3D Response.Payload; + ASSERT (Private->Payload !=3D NULL); + + Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private->Payload= ), EDKII_JSON_COMPACT); + ASSERT (Private->Json !=3D NULL); + + Status =3D RedfishUpdateResourceCommon (Private, Private->Json); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to update resource to: %s: %r\n", __f= unc__, Uri, Status)); + } else { + // + // Get latest ETag on URI and keep it in variable. + // + SetEtagFromUri (Private->RedfishService, Private->Uri, TRUE); + } + + // + // Release resource + // + RedfishHttpFreeResponse (&Response); + Private->Payload =3D NULL; + + if (Private->Json !=3D NULL) { + FreePool (Private->Json); + Private->Json =3D NULL; + } + + return Status; +} + +/** + Check resource on given URI. + + @param[in] This Pointer to EFI_HP_REDFISH_HII_PROTOCOL = instance. + @param[in] Uri The target URI to consume. + + @retval EFI_SUCCESS Value is returned successfully. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceCheck ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + IN EFI_STRING Uri + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STATUS Status; + REDFISH_RESPONSE Response; + CHAR8 *Etag; + + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCOL = (This); + + if (Private->RedfishService =3D=3D NULL) { + return EFI_NOT_READY; + } + + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, &= Response, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, U= ri)); + return Status; + } + + Private->Uri =3D Uri; + Private->Payload =3D Response.Payload; + ASSERT (Private->Payload !=3D NULL); + + Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private->Payload= ), EDKII_JSON_COMPACT); + ASSERT (Private->Json !=3D NULL); + + // + // Find etag in HTTP response header + // + Etag =3D NULL; + Status =3D GetHttpResponseEtag (&Response, &Etag); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __fu= nc__)); + } + + Status =3D RedfishCheckResourceCommon (Private, Private->Json, Etag); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to check resource from: %s: %r\n", __= func__, Uri, Status)); + } + + // + // Release resource + // + if (Etag !=3D NULL) { + FreePool (Etag); + } + + RedfishHttpFreeResponse (&Response); + Private->Payload =3D NULL; + + if (Private->Json !=3D NULL) { + FreePool (Private->Json); + Private->Json =3D NULL; + } + + return Status; +} + +/** + Identify resource on given URI. + + @param[in] This Pointer to EDKII_REDFISH_RESOURCE_CONFI= G_PROTOCOL instance. + @param[in] Uri The target URI to consume. + + @retval EFI_SUCCESS This is target resource which we want t= o handle. + @retval EFI_UNSUPPORTED This is not the target resource. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceIdentify ( + IN EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL *This, + IN EFI_STRING Uri + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STATUS Status; + REDFISH_RESPONSE Response; + + if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (&Response, sizeof (REDFISH_RESPONSE)); + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROTOCOL = (This); + + if (Private->RedfishService =3D=3D NULL) { + return EFI_NOT_READY; + } + + Status =3D RedfishHttpGetResource (Private->RedfishService, Uri, NULL, &= Response, TRUE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: get resource from: %s failed\n", __func__, U= ri)); + return Status; + } + + Private->Uri =3D Uri; + Private->Payload =3D Response.Payload; + ASSERT (Private->Payload !=3D NULL); + + Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private->Payload= ), EDKII_JSON_COMPACT); + ASSERT (Private->Json !=3D NULL); + + Status =3D RedfishIdentifyResourceCommon (Private, Private->Json); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: identify %s failed: %r\n", __func__, Uri, St= atus)); + } + + // + // Release resource + // + RedfishHttpFreeResponse (&Response); + Private->Payload =3D NULL; + + if (Private->Json !=3D NULL) { + FreePool (Private->Json); + Private->Json =3D NULL; + } + + return Status; +} + +EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL mRedfishResourceConfig =3D { + RedfishResourceProvisioningResource, + RedfishResourceConsumeResource, + RedfishResourceUpdate, + RedfishResourceCheck, + RedfishResourceIdentify, + RedfishResourceGetInfo +}; + +/** + Initialize a Redfish configure handler. + + This function will be called by the Redfish config driver to initialize = each Redfish configure + handler. + + @param[in] This Pointer to EDKII_REDFISH_CONFIG_HA= NDLER_PROTOCOL instance. + @param[in] RedfishConfigServiceInfo Redfish service information. + + @retval EFI_SUCCESS The handler has been initialized su= ccessfully. + @retval EFI_DEVICE_ERROR Failed to create or configure the R= EST EX protocol instance. + @retval EFI_ALREADY_STARTED This handler has already been initi= alized. + @retval Other Error happens during the initializa= tion. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceInit ( + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This, + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOCOL (T= his); + + Private->RedfishService =3D RedfishCreateService (RedfishConfigServiceIn= fo); + if (Private->RedfishService =3D=3D NULL) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Stop a Redfish configure handler. + + @param[in] This Pointer to EDKII_REDFISH_CONFIG_HANDLER= _PROTOCOL instance. + + @retval EFI_SUCCESS This handler has been stoped successful= ly. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceStop ( + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This + ) +{ + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + + Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOCOL (T= his); + + if (Private->Event !=3D NULL) { + gBS->CloseEvent (Private->Event); + Private->Event =3D NULL; + } + + if (Private->RedfishService !=3D NULL) { + RedfishCleanupService (Private->RedfishService); + Private->RedfishService =3D NULL; + } + + return EFI_SUCCESS; +} + +EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL mRedfishConfigHandler =3D { + RedfishResourceInit, + RedfishResourceStop +}; + +/** + Callback function when gEfiRestJsonStructureProtocolGuid is installed. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +EfiRestJsonStructureProtocolIsReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + if (mRedfishResourcePrivate =3D=3D NULL) { + return; + } + + if (mRedfishResourcePrivate->JsonStructProtocol !=3D NULL) { + return; + } + + Status =3D gBS->LocateProtocol ( + &gEfiRestJsonStructureProtocolGuid, + NULL, + (VOID **)&mRedfishResourcePrivate->JsonStructProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to locate gEfiRestJsonStructureProtoc= olGuid: %r\n", __func__, Status)); + } + + gBS->CloseEvent (Event); +} + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be unl= oaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +RedfishResourceUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; + + if (mRedfishResourcePrivate =3D=3D NULL) { + return EFI_NOT_READY; + } + + ConfigHandler =3D NULL; + + // + // Firstly, find ConfigHandler Protocol interface in this ImageHandle. + // + Status =3D gBS->OpenProtocol ( + ImageHandle, + &gEdkIIRedfishConfigHandlerProtocolGuid, + (VOID **)&ConfigHandler, + NULL, + NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + ); + if (EFI_ERROR (Status) || (ConfigHandler =3D=3D NULL)) { + return Status; + } + + ConfigHandler->Stop (ConfigHandler); + + // + // Last, uninstall ConfigHandler Protocol and resource protocol. + // + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEdkIIRedfishConfigHandlerProtocolGuid, + ConfigHandler, + &gEdkIIRedfishResourceConfigProtocolGuid, + &mRedfishResourcePrivate->RedfishResourceConfig, + NULL + ); + + FreePool (mRedfishResourcePrivate); + mRedfishResourcePrivate =3D NULL; + + return Status; +} + +/** + The callback function provided by Redfish Feature driver. + + @param[in] This Pointer to EDKII_REDFISH_FEATURE_PROT= OCOL instance. + @param[in] FeatureAction The action Redfish feature driver sho= uld take. + @param[in] Uri The collection URI. + @param[in] Context The context of Redfish feature driver= . + @param[in,out] InformationExchange The pointer to RESOURCE_INFORMATION_E= XCHANGE + + @retval EFI_SUCCESS Redfish feature driver callback is exec= uted successfully. + @retval Others Some errors happened. + + @retval EFI_SUCCESS Redfish feature driver callback is exec= uted successfully. + @retval Others Some errors happened. + +**/ +EFI_STATUS +EFIAPI +RedfishExternalResourceResourceFeatureCallback ( + IN EDKII_REDFISH_FEATURE_PROTOCOL *This, + IN FEATURE_CALLBACK_ACTION FeatureAction, + IN VOID *Context, + IN OUT RESOURCE_INFORMATION_EXCHANGE *InformationExchange + ) +{ + EFI_STATUS Status; + REDFISH_SERVICE RedfishService; + REDFISH_RESOURCE_COMMON_PRIVATE *Private; + EFI_STRING ResourceUri; + EFI_STRING SecureBootUri; + + if (FeatureAction !=3D CallbackActionStartOperation) { + return EFI_UNSUPPORTED; + } + + Private =3D (REDFISH_RESOURCE_COMMON_PRIVATE *)Context; + + RedfishService =3D Private->RedfishService; + if (RedfishService =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: no Redfish service configured\n", __func__))= ; + return EFI_NOT_READY; + } + + // + // Save in private structure. + // + Private->InformationExchange =3D InformationExchange; + + // + // Find Redfish version on Redfish ser + // + Private->RedfishVersion =3D RedfishGetVersion (RedfishService); + + // + // Create the full URI from Redfish service root. + // + ResourceUri =3D (EFI_STRING)AllocateZeroPool (MAX_URI_LENGTH * sizeof (C= HAR16)); + if (ResourceUri =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for full URI.\n", __= func__)); + return EFI_OUT_OF_RESOURCES; + } + + StrCatS (ResourceUri, MAX_URI_LENGTH, Private->RedfishVersion); + StrCatS (ResourceUri, MAX_URI_LENGTH, InformationExchange->SendInformati= on.FullUri); + + // + // Initialize collection path + // + SecureBootUri =3D RedfishGetUri (ResourceUri); + if (SecureBootUri =3D=3D NULL) { + ASSERT (FALSE); + FreePool (ResourceUri); + return EFI_OUT_OF_RESOURCES; + } + + Status =3D HandleResource (Private, SecureBootUri); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: process external resource: %s failed: %r\n",= __func__, SecureBootUri, Status)); + } + + FreePool (SecureBootUri); + FreePool (ResourceUri); + return Status; +} + +/** + Callback function when gEdkIIRedfishFeatureProtocolGuid is installed. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +EdkIIRedfishFeatureProtocolIsReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EDKII_REDFISH_FEATURE_PROTOCOL *FeatureProtocol; + + if (mRedfishResourcePrivate =3D=3D NULL) { + return; + } + + if (mRedfishResourcePrivate->FeatureProtocol !=3D NULL) { + return; + } + + Status =3D gBS->LocateProtocol ( + &gEdkIIRedfishFeatureProtocolGuid, + NULL, + (VOID **)&FeatureProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to locate gEdkIIRedfishFeatureProtoco= lGuid: %r\n", __func__, Status)); + gBS->CloseEvent (Event); + return; + } + + Status =3D FeatureProtocol->Register ( + FeatureProtocol, + REDFISH_MANAGED_URI, + RedfishExternalResourceResourceFeatureCallba= ck, + (VOID *)mRedfishResourcePrivate + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: failed to register %s: %r\n", __func__, REDF= ISH_MANAGED_URI, Status)); + } + + mRedfishResourcePrivate->FeatureProtocol =3D FeatureProtocol; + + gBS->CloseEvent (Event); +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers includ= ing + both device drivers and bus drivers. It initialize the global variables = and + publish the driver binding protocol. + + @param[in] ImageHandle The firmware allocated handle for the UEFI= image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_ACCESS_DENIED EFI_ISCSI_INITIATOR_NAME_PROTOCOL was inst= alled unexpectedly. + @retval Others Other errors as indicated. +**/ +EFI_STATUS +EFIAPI +RedfishResourceEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *Registration; + + if (mRedfishResourcePrivate !=3D NULL) { + return EFI_ALREADY_STARTED; + } + + mRedfishResourceConfigProtocolHandle =3D ImageHandle; + + mRedfishResourcePrivate =3D AllocateZeroPool (sizeof (REDFISH_RESOURCE_C= OMMON_PRIVATE)); + CopyMem (&mRedfishResourcePrivate->ConfigHandler, &mRedfishConfigHandler= , sizeof (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL)); + CopyMem (&mRedfishResourcePrivate->RedfishResourceConfig, &mRedfishResou= rceConfig, sizeof (EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL)); + + // + // Publish config handler protocol and resource protocol. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEdkIIRedfishConfigHandlerProtocolGuid, + &mRedfishResourcePrivate->ConfigHandler, + &gEdkIIRedfishResourceConfigProtocolGuid, + &mRedfishResourcePrivate->RedfishResourceConfig, + NULL + ); + + EfiCreateProtocolNotifyEvent ( + &gEfiRestJsonStructureProtocolGuid, + TPL_CALLBACK, + EfiRestJsonStructureProtocolIsReady, + NULL, + &Registration + ); + + EfiCreateProtocolNotifyEvent ( + &gEdkIIRedfishFeatureProtocolGuid, + TPL_CALLBACK, + EdkIIRedfishFeatureProtocolIsReady, + (VOID *)mRedfishResourcePrivate, + &Registration + ); + + return Status; +} diff --git a/RedfishClientPkg/RedfishClient.fdf.inc b/RedfishClientPkg/Redf= ishClient.fdf.inc index 59b8acba1..154f641b2 100644 --- a/RedfishClientPkg/RedfishClient.fdf.inc +++ b/RedfishClientPkg/RedfishClient.fdf.inc @@ -25,6 +25,7 @@ INF RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.inf INF RedfishClientPkg/Features/BootOptionCollection/BootOptionCollectionDx= e.inf INF RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.inf + INF RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf !include RedfishClientPkg/RedfishJsonStructureDxe.fdf.inc # -- 2.34.1 Regards, Mike -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117119): https://edk2.groups.io/g/devel/message/117119 Mute This Topic: https://groups.io/mt/104927848/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --_000_MW4PR12MB7031FBB03B6BF5921D54207AD9352MW4PR12MB7031namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hi Mike,

 

Thanks for your review. I addressed your review comm= ents in pull request: https:= //github.com/tianocore/edk2-redfish-client/pull/83

 

I am waiting for Abner’s patch (PR#84) because= I plan to incorporate Abner’s changes into this driver. I will send = version 2 patch series here for review later.

 

Regards,

Nickle

 

From: Mike Maslenkin <mike.maslenkin@gmail= .com>
Sent: Friday, March 15, 2024 3:38 AM
To: devel@edk2.groups.io; Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>; Igor Kulchytskyy <ig= ork@ami.com>; Nick Ramirez <nramirez@nvidia.com>
Subject: Re: [edk2-devel] [edk2-redfish-client][PATCH 1/2] RedfishCl= ientPkg/Features: support Redfish Secure Boot

 

External email: Use caution opening l= inks or attachments

 

Hi Nickle,

 

please find my comments below



On 14. 3. 2024., at 17:53, Nickle Wang via groups.io <nicklew=3Dnvidia.com@groups.io> wrote:

 

Introduce SecureBoot driver to support
/redfish/v1/Systems/SYS/SecureBoot resource.

Signed-off-by: Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Igor Kulchytskyy <igork@ami.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
---
.../RedfishClientComponents.dsc.inc       &nb= sp;   |   2 +
RedfishClientPkg/RedfishClientLibs.dsc.inc    |   = 4 +
.../SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf   |  60 ++
.../v1_1_0/Common/SecureBootCommon.h       &n= bsp;  |  40 +
.../v1_1_0/Common/SecureBootCommon.c       &n= bsp;  | 756 ++++++++++++++++
.../SecureBoot/v1_1_0/Dxe/SecureBootDxe.c     | 808 +++= +++++++++++++++
RedfishClientPkg/RedfishClient.fdf.inc       =  |   1 +
7 files changed, 1671 insertions(+)
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.inf
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.h
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/Secur= eBootCommon.c
create mode 100644 RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBo= otDxe.c

diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc b/RedfishClie= ntPkg/RedfishClientComponents.dsc.inc
index ae2a4b025..42fc0c299 100644
--- a/RedfishClientPkg/RedfishClientComponents.dsc.inc
+++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc
@@ -34,6 +34,7 @@
  RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.inf
  RedfishClientPkg/Features/BootOptionCollection/BootOptionCollec= tionDxe.inf
  RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.i= nf
+  RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
  !include RedfishClientPkg/RedfishJsonStructureDxe.dsc.inc

@@ -47,3 +48,4 @@
  RedfishClientPkg/Converter/Bios/v1_0_9/RedfishBios_V1_0_9_Dxe.i= nf
  RedfishClientPkg/Converter/BootOptionCollection/RedfishBootOpti= onCollection_Dxe.inf
  RedfishClientPkg/Converter/BootOption/v1_0_4/RedfishBootOption_= V1_0_4_Dxe.inf
+  RedfishClientPkg/Converter/SecureBoot/v1_1_0/RedfishSecureBoot_V1_1= _0_Dxe.inf
diff --git a/RedfishClientPkg/RedfishClientLibs.dsc.inc b/RedfishClientPkg/= RedfishClientLibs.dsc.inc
index 6599926ab..9126465df 100644
--- a/RedfishClientPkg/RedfishClientLibs.dsc.inc
+++ b/RedfishClientPkg/RedfishClientLibs.dsc.inc
@@ -25,6 +25,8 @@
  BiosV1_0_9Lib|RedfishClientPkg/ConverterLib/edk2library/Bios/v1= _0_9/Lib.inf
  BootOptionCollectionLib|RedfishClientPkg/ConverterLib/edk2libra= ry/BootOptionCollection/Lib.inf
  BootOptionV1_0_4Lib|RedfishClientPkg/ConverterLib/edk2library/B= ootOption/v1_0_4/Lib.inf
+  SecureBootV1_1_0Lib|RedfishClientPkg/ConverterLib/edk2library/Secur= eBoot/v1_1_0/Lib.inf
+
  #
  # Above modules should be pulled in by build tool.
  #
@@ -42,3 +44,5 @@
  RedfishAddendumLib|RedfishClientPkg/Library/RedfishAddendumLib/= RedfishAddendumLib.inf
  RedfishDebugLib|RedfishPkg/Library/RedfishDebugLib/RedfishDebug= Lib.inf
  RedfishHttpLib|RedfishPkg/Library/RedfishHttpLib/RedfishHttpLib= .inf
+  SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/Sec= ureBootVariableLib.inf
+  PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLib= VarPolicy/PlatformPKProtectionLibVarPolicy.inf
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= inf b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
new file mode 100644
index 000000000..1ad8c623f
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.inf
@@ -0,0 +1,60 @@
+## @file
+#
+#  (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&= lt;BR>
+#  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All = rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION          &= nbsp;    =3D 0x00010005
+  BASE_NAME          &nb= sp;      =3D SecureBootDxe
+  FILE_GUID          &nb= sp;      =3D 5E4025F8-DA42-468A-853E-6A1091D3= 5052
+  MODULE_TYPE          &= nbsp;    =3D DXE_DRIVER
+  VERSION_STRING         &nbs= p;  =3D 1.0
+  ENTRY_POINT          &= nbsp;    =3D RedfishResourceEntryPoint
+  UNLOAD_IMAGE          =     =3D RedfishResourceUnload
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  RedfishPkg/RedfishPkg.dec
+  RedfishClientPkg/RedfishClientPkg.dec
+
+[Sources]
+  ../Common/SecureBootCommon.h
+  ../Common/SecureBootCommon.c
+  SecureBootDxe.c
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  EdkIIRedfishResourceConfigLib
+  RedfishFeatureUtilityLib
+  RedfishVersionLib
+  RedfishResourceIdentifyLib
+  SecureBootVariableLib
+  UefiLib
+  UefiDriverEntryPoint
+  RedfishAddendumLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEdkIIRedfishConfigHandlerProtocolGuid     &nbs= p;    ## PRODUCED
+  gEfiRestJsonStructureProtocolGuid      &nb= sp;        ## CONSUMED
+  gEdkIIRedfishResourceConfigProtocolGuid     &nb= sp;   ## PRODUCED
+  gEdkIIRedfishFeatureProtocolGuid      &nbs= p;         ## CONSUMED
+
+[Guids]
+  gEfiSecureBootEnableDisableGuid       = ;          ## CONSUMED +
+[Pcd]
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize +  gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize +  gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootRequired +
+[Depex]
+  TRUE
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.h b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.h
new file mode 100644
index 000000000..0d1824160
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.h=
@@ -0,0 +1,40 @@
+/** @file
+
+  Redfish feature driver implementation - internal header file
+  (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+  Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All r= ights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EFI_REDFISH_SECUREBOOT_COMMON_H_
+#define EFI_REDFISH_SECUREBOOT_COMMON_H_
+
+#include <Guid/ImageAuthentication.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <RedfishJsonStructure/SecureBoot/v1_1_0/EfiSecureBootV1_1_0.h&= gt;
+#include <RedfishResourceCommon.h>
+#include <UefiSecureBoot.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SecureBootVariableLib.h>
+
+//
+// Schema information.
+//
+#define REDFISH_MANAGED_URI        L&qu= ot;Systems/{}/SecureBoot"
+#define REDFISH_DUMMY_CONFIG_LANG  L"Systems/{1}/SecureBoot"= ;
+#define MAX_URI_LENGTH         &nb= sp;   256
+#define RESOURCE_SCHEMA         &n= bsp;  "SecureBoot"
+#define RESOURCE_SCHEMA_MAJOR      "1"<= br> +#define RESOURCE_SCHEMA_MINOR      "1"<= br> +#define RESOURCE_SCHEMA_ERRATA     "0"
+#define RESOURCE_SCHEMA_VERSION    "v1_1_0"
+#define SECURE_BOOT_SETUP_MODE     "SetupMode&quo= t;
+#define SECURE_BOOT_USER_MODE      "UserMode= "
+#define SECURE_BOOT_ENABLED        &quo= t;Enabled"
+#define SECURE_BOOT_DISABLED       "Dis= abled"
+#define SECURE_BOOT_MODE_STR_LEN   16
+
+#endif
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootC= ommon.c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootComm= on.c
new file mode 100644
index 000000000..56a45ee72
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Common/SecureBootCommon.c=
@@ -0,0 +1,756 @@
+/** @file
+  Redfish feature driver implementation - common functions
+
+  (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+  Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All r= ights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecureBootCommon.h"
+
+CHAR8  SecureBootEmptyJson[] =3D "{\"@odata.id\": \"\", \"@odat= a.type\": \"#SecureBoot.v1_1_0.SecureBoot\", \"Id\"= ;: \"\", \"Name\": \"\", \"Attributes\&q= uot;:{}}";
+
+REDFISH_RESOURCE_COMMON_PRIVATE  *mRedfishResourcePrivate   = ;            &n= bsp;            = ;      =3D NULL;
+EFI_HANDLE           &nb= sp;           mRedfi= shResourceConfigProtocolHandle        &n= bsp;            = ; =3D NULL;
+CHAR16            &= nbsp;           &nbs= p;  *mSecureBootSupportedAttributes[SECURE_BOOT_MODE_STR_LEN] =3D= {
+  L"SecureBootCurrentBoot",
+  L"SecureBootEnable",
+  L"SecureBootMode"
+};
+
+/**
+  Read EFI_SECURE_BOOT_ENABLE_NAME variable and return its value to c= aller.
+
+  @retval BOOLEAN    TRUE when EFI_SECURE_BOOT_ENABLE_= NAME value is SECURE_BOOT_ENABLE
+             &= nbsp;       FALSE when EFI_SECURE_BOOT_E= NABLE_NAME value is SECURE_BOOT_DISABLE
+**/
+BOOLEAN
+RedfishReadSecureBootEnable (
+  VOID
+  )
+{
+  UINT8    *Buffer;
+  BOOLEAN  SecureBootEnableValue;
+
+  Buffer           =      =3D NULL;
+  SecureBootEnableValue =3D FALSE;
+
+  GetVariable2 (
+    EFI_SECURE_BOOT_ENABLE_NAME,
+    &gEfiSecureBootEnableDisableGuid,
+    (VOID **)&Buffer,
+    NULL
+    );
+
+  if (Buffer !=3D NULL) {
+    if (*Buffer =3D=3D SECURE_BOOT_ENABLE) {
+      SecureBootEnableValue =3D TRUE;
+    }
+
+    FreePool (Buffer);
+  }
+
+  return SecureBootEnableValue;
+}
+
+/**
+  Write EFI_SECURE_BOOT_ENABLE_NAME variable with given value.
+
+  @param[in]   SecureBootEnableValue    Valu= e to write. TRUE is SECURE_BOOT_ENABLE.
+             &= nbsp;           &nbs= p;            &= nbsp; FALSE is SECURE_BOOT_DISABLE.
+
+  @retval EFI_SUCCESS         = ;     Write value successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+**/
+EFI_STATUS
+RedfishWriteSecureBootEnable (
+  BOOLEAN  SecureBootEnableValue
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       VarValue;
+
+  VarValue =3D (SecureBootEnableValue ? SECURE_BOOT_ENABLE : SECURE_B= OOT_DISABLE);
+  Status   =3D gRT->SetVariable (
+             &= nbsp;      EFI_SECURE_BOOT_ENABLE_NAME,
+             &= nbsp;      &gEfiSecureBootEnableDisableGu= id,
+             &= nbsp;      EFI_VARIABLE_NON_VOLATILE | EFI_VA= RIABLE_BOOTSERVICE_ACCESS,
+             &= nbsp;      sizeof (VarValue),
+             &= nbsp;      &VarValue
+             &= nbsp;      );
+
+  return Status;
+}
+
+/**
+  Consume Redfish resource in given Json data.
+
+  @param[in]   This       &nb= sp;        Pointer to REDFISH_RESOU= RCE_COMMON_PRIVATE instance.
+  @param[in]   Json       &nb= sp;        The JSON to consume.
+  @param[in]   HeaderEtag      &nb= sp;   The Etag string returned in HTTP header.
+
+  @retval EFI_SUCCESS         = ;     Consume Redfish attribute successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+RedfishConsumeResourceCommon (
+  IN  REDFISH_RESOURCE_COMMON_PRIVATE  *Private,
+  IN  CHAR8         &nbs= p;            &= nbsp;     *Json,
+  IN  CHAR8         &nbs= p;            &= nbsp;     *HeaderEtag OPTIONAL
+  )
+{
+  EFI_STATUS          &n= bsp;            = ; Status;
+  EFI_REDFISH_SECUREBOOT_V1_1_0     *SecureBoot;<= br> +  EFI_REDFISH_SECUREBOOT_V1_1_0_CS  *SecureBootCs;
+  BOOLEAN           = ;            &n= bsp;   SecureBootEnableDisable;
+
+  if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SecureBoot          &n= bsp;   =3D NULL;
+  SecureBootCs          =   =3D NULL;
+  SecureBootEnableDisable =3D RedfishReadSecureBootEnable ();
+
+  Status =3D Private->JsonStructProtocol->ToStructure (
+             &= nbsp;           &nbs= p;            &= nbsp;   Private->JsonStructProtocol,
+             &= nbsp;           &nbs= p;            &= nbsp;   NULL,
+             &= nbsp;           &nbs= p;            &= nbsp;   Json,
+             &= nbsp;           &nbs= p;            &= nbsp;   (EFI_REST_JSON_STRUCTURE_HEADER **)&SecureBoot +             &= nbsp;           &nbs= p;            &= nbsp;   );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: ToStructure() failed: %r= \n", __func__, Status));
+    return Status;
+  }
+
+  SecureBootCs =3D SecureBoot->SecureBoot;
+
+  //
+  // Check ETAG to see if we need to consume it
+  //
+  if (CheckEtag (Private->Uri, HeaderEtag, SecureBootCs->odata_= etag)) {
+    //
+    // No change
+    //
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no = change, ignore consume action\n", __func__, Private->Uri));
+    Status =3D EFI_ALREADY_STARTED;
+    goto ON_RELEASE;
+  }
+
+  //
+  // Secure boot enable
+  //
+  if (SecureBootCs->SecureBootEnable !=3D NULL) {
+    if (SecureBootEnableDisable !=3D *SecureBootCs->Secu= reBootEnable) {
+      //
+      // Write value to "SecureBootEnable&qu= ot; variable. AuthVariableLib will enable or disable secure boot
+      // based on "SecureBootEnable" va= lue.
+      //
+      Status =3D RedfishWriteSecureBootEnable (*S= ecureBootCs->SecureBootEnable);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: = write secure boot enable disable failed: %r\n", __func__, Status)); +      } else {
+        REDFISH_ENABLE_SYSTEM_REBOOT ()= ;
+      }
+    } else {
+      DEBUG ((REDFISH_DEBUG_TRACE, "%a: secu= re boot mode is not changed\n", __func__));
+    }
+  }
+
+ON_RELEASE:
+
+  //
+  // Release resource.
+  //
+  Private->JsonStructProtocol->DestoryStructure (
+             &= nbsp;           &nbs= p;       Private->JsonStructProtocol,=
+             &= nbsp;           &nbs= p;       (EFI_REST_JSON_STRUCTURE_HEADER= *)SecureBoot
+             &= nbsp;           &nbs= p;       );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Provision Redfish resource. This function reads secure boot variabl= e and convert it
+  to Redfish attribute.
+
+  @param[in]   JsonStructProtocol  Pointer to Json str= ucture protocol.
+  @param[in]   InputJson      &nbs= p;    Jason data on input.
+  @param[in]   ResourceId      &nb= sp;   Resource ID. This is optional.
+  @param[in]   ConfigureLang      =  Configure language for this Redfish resource.
+  @param[in]   ProvisionMode      =  TRUE when this is to provision Redfish attribute to
+             &= nbsp;           &nbs= p;         Redfish service. FA= LSE is to update Redfish attribute
+             &= nbsp;           &nbs= p;         to Redfish service.=
+  @param[out]  ResultJson       &n= bsp;  Json data on output.
+
+  @retval EFI_SUCCESS         = ;     Provision Redfish attribute successfully. +  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+ProvisioningSecureBootProperties (
+  IN  EFI_REST_JSON_STRUCTURE_PROTOCOL  *JsonStructProtocol= ,
+  IN  CHAR8         &nbs= p;            &= nbsp;      *InputJson,
+  IN  CHAR8         &nbs= p;            &= nbsp;      *ResourceId OPTIONAL,
+  IN  EFI_STRING         = ;            &n= bsp;  ConfigureLang,
+  IN  BOOLEAN         &n= bsp;            = ;     ProvisionMode,
+  OUT CHAR8          &nb= sp;            =       **ResultJson
+  )
+{
+  EFI_REDFISH_SECUREBOOT_V1_1_0     *SecureBoot;<= br> +  EFI_REDFISH_SECUREBOOT_V1_1_0_CS  *SecureBootCs;
+  EFI_STATUS          &n= bsp;            = ; Status;
+  BOOLEAN           = ;            &n= bsp;   PropertyChanged;
+  CHAR8           &= nbsp;           &nbs= p;     *AsciiStringValue;
+  INT32           &= nbsp;           &nbs= p;     *IntegerValue;
+  UINT8           &= nbsp;           &nbs= p;     SetupMode;
+  BOOLEAN           = ;            &n= bsp;   SecureBootEnabled;
+  BOOLEAN           = ;            &n= bsp;   SecureBootEnableDisable;
+
+  if ((JsonStructProtocol =3D=3D NULL) || (ResultJson =3D=3D NULL) ||= IS_EMPTY_STRING (InputJson) || IS_EMPTY_STRING (ConfigureLang)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s with: %s\n&q= uot;, __func__, ConfigureLang, (ProvisionMode ? L"Provision resource&q= uot; : L"Update resource")));
+
+  *ResultJson          &= nbsp;  =3D NULL;
+  PropertyChanged         =3D= FALSE;
+  AsciiStringValue        =3D NULL= ;
+  SecureBootEnableDisable =3D RedfishReadSecureBootEnable ();
+  SecureBootEnabled       =3D IsSecureB= ootEnabled ();
+
+  SecureBoot =3D NULL;
+  Status     =3D JsonStructProtocol->ToStructu= re (
+             &= nbsp;           &nbs= p;           JsonStr= uctProtocol,
+             &= nbsp;           &nbs= p;           NULL, +             &= nbsp;           &nbs= p;           InputJs= on,
+             &= nbsp;           &nbs= p;           (EFI_RE= ST_JSON_STRUCTURE_HEADER **)&SecureBoot
+             &= nbsp;           &nbs= p;           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: ToStructure failure: %r\= n", __func__, Status));
+    return Status;
+  }
+
+  SecureBootCs =3D SecureBoot->SecureBoot;
+
+  //
+  // ID
+  //
+  if (SecureBootCs->Id !=3D NULL) {
+    SecureBootCs->Id =3D NULL;
+  }
+
+  //
+  // Name
+  //
+  if (SecureBootCs->Name !=3D NULL) {
+    SecureBootCs->Name =3D NULL;
+  }
+
+  //
+  // Secure boot variables that we will handle here
+  //
+  // EFI_SETUP_MODE_NAME (gEfiGlobalVariableGuid)
+  // EFI_SECURE_BOOT_MODE_NAME (gEfiGlobalVariableGuid)
+  // EFI_SECURE_BOOT_ENABLE_NAME (gEfiSecureBootEnableDisableGuid) +  //
+
+  //
+  // Current Boot
+  //
+  if (PropertyChecker (SecureBootCs->SecureBootCurrentBoot, Provis= ionMode)) {
+    AsciiStringValue =3D AllocateZeroPool (SECURE_BOOT_MODE= _STR_LEN * sizeof (CHAR8));
+    if (AsciiStringValue !=3D NULL) {
+      AsciiSPrint (AsciiStringValue, SECURE_BOOT_= MODE_STR_LEN, "%a", (SecureBootEnabled ? SECURE_BOOT_ENABLED : SE= CURE_BOOT_DISABLED));
+      if (ProvisionMode || (AsciiStrCmp (SecureBo= otCs->SecureBootCurrentBoot, AsciiStringValue) !=3D 0)) {
+        SecureBootCs->SecureBootCurr= entBoot =3D AsciiStringValue;
+        PropertyChanged   &nb= sp;            =      =3D TRUE;
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "%a: out of resou= rce\n", __func__));
+    }
+  }
+
+  //
+  // Secure boot enable
+  //
+  if (PropertyChecker (SecureBootCs->SecureBootEnable, ProvisionMo= de)) {
+    if (ProvisionMode || (*SecureBootCs->SecureBootEnabl= e !=3D SecureBootEnableDisable)) {
+      IntegerValue =3D AllocatePool (sizeof (*Int= egerValue));
+      if (IntegerValue !=3D NULL) {
+        *IntegerValue    = ;            &n= bsp; =3D (SecureBootEnableDisable ? 0x01 : 0x00);
+        SecureBootCs->SecureBootEnab= le =3D IntegerValue;
+        PropertyChanged   &nb= sp;            = =3D TRUE;
+      } else {
+        DEBUG ((DEBUG_ERROR, "%a: = out of resource\n", __func__));
+      }
+    }
+  }
+
+  //
+  // Secure boot mode
+  //
+  if (PropertyChecker (SecureBootCs->SecureBootMode, ProvisionMode= )) {
+    Status =3D GetSetupMode (&SetupMode);
+    if (!EFI_ERROR (Status)) {
+      AsciiStringValue =3D AllocateZeroPool (SECU= RE_BOOT_MODE_STR_LEN *sizeof (CHAR8));
+      if (AsciiStringValue !=3D NULL) {
+        AsciiSPrint (AsciiStringValue, = SECURE_BOOT_MODE_STR_LEN *sizeof (CHAR8), "%a", (SetupMode =3D=3D= USER_MODE ? SECURE_BOOT_USER_MODE : SECURE_BOOT_SETUP_MODE));
+        if (ProvisionMode || (AsciiStrC= mp (SecureBootCs->SecureBootMode, AsciiStringValue) !=3D 0)) {
+          SecureBootCs->Se= cureBootMode =3D AsciiStringValue;
+          PropertyChanged &nb= sp;            = =3D TRUE;
+        }
+      }
+    } else {
+      DEBUG ((DEBUG_ERROR, "%a: cannot read = setup mode: %r\n", __func__, Status));
+    }
+  }
+
+  //
+  // Convert C structure back to JSON text.
+  //
+  Status =3D JsonStructProtocol->ToJson (
+             &= nbsp;           &nbs= p;       JsonStructProtocol,
+             &= nbsp;           &nbs= p;       (EFI_REST_JSON_STRUCTURE_HEADER= *)SecureBoot,
+             &= nbsp;           &nbs= p;       ResultJson
+             &= nbsp;           &nbs= p;       );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: ToJson() failed: %r\n&qu= ot;, __func__, Status));
+    return Status;

 

 

 

  SecureBoot structure leak. It is released bel= ow.



+  }
+
+  //
+  // Release resource.
+  //
+  JsonStructProtocol->DestoryStructure (
+             &= nbsp;          JsonStruct= Protocol,
+             &= nbsp;          (EFI_REST_= JSON_STRUCTURE_HEADER *)SecureBoot
+             &= nbsp;          );
+
+  return (PropertyChanged ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
+/**
+  Provision Redfish resource and upload data to Redfish service. This= function
+  checks OEM data and platform addendum data before sending data to R= edfish service.
+
+  @param[in]   Private   Pointer to private data.=
+
+  @retval EFI_SUCCESS         = ;     Provision Redfish resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+ProvisioningSecureBootResource (
+  IN  REDFISH_RESOURCE_COMMON_PRIVATE  *Private
+  )
+{
+  EFI_STATUS        Status;
+  CHAR8           &= nbsp; *Json;
+  CHAR8           &= nbsp; *JsonWithAddendum;
+  REDFISH_RESPONSE  Response;
+
+  if (Private =3D=3D NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Json =3D NULL;
+
+  Status =3D ProvisioningSecureBootProperties (
+             P= rivate->JsonStructProtocol,
+             S= ecureBootEmptyJson,
+             N= ULL,
+             R= EDFISH_DUMMY_CONFIG_LANG,
+             T= RUE,
+             &= amp;Json
+             )= ;
+  if (EFI_ERROR (Status)) {
+    if (Status =3D=3D EFI_NOT_FOUND) {
+      DEBUG ((REDFISH_DEBUG_TRACE, "%a: prov= isioning existing resource for %s ignored. Nothing changed\n", __func_= _, REDFISH_DUMMY_CONFIG_LANG));
+      Status =3D EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_ERROR, "%a: provisioning= existing resource for %s failed: %r\n", __func__, REDFISH_DUMMY_CONFI= G_LANG, Status));
+    }
+
+    goto ON_RELEASE;
+  }
+
+  //
+  // Check and see if platform has OEM data or not
+  //
+  Status =3D RedfishGetOemData (
+             P= rivate->Uri,
+             R= ESOURCE_SCHEMA,
+             R= ESOURCE_SCHEMA_VERSION,
+             J= son,
+             &= amp;JsonWithAddendum
+             )= ;
+  if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> +    FreePool (Json);
+    Json         &n= bsp;   =3D JsonWithAddendum;
+    JsonWithAddendum =3D NULL;
+  }
+
+  //
+  // Check and see if platform has addendum data or not
+  //
+  Status =3D RedfishGetAddendumData (
+             P= rivate->Uri,
+             R= ESOURCE_SCHEMA,
+             R= ESOURCE_SCHEMA_VERSION,
+             J= son,
+             &= amp;JsonWithAddendum
+             )= ;
+  if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> +    FreePool (Json);
+    Json         &n= bsp;   =3D JsonWithAddendum;
+    JsonWithAddendum =3D NULL;
+  }
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning existing resour= ce for %s\n", __func__, REDFISH_DUMMY_CONFIG_LANG));
+
+  //
+  // PATCH back to instance
+  //
+  Status =3D RedfishHttpPatchResource (Private->RedfishService, Pr= ivate->Uri, Json, &Response);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: patch resource for %s fa= iled: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status));
+  }
+
+ON_RELEASE:
+
+  if (Json !=3D NULL) {
+    FreePool (Json);
+  }
+
+  RedfishHttpFreeResponse (&Response);
+
+  return Status;
+}
+
+/**
+  Provisioning redfish resource to Redfish service.
+
+  @param[in]   Private       =       Pointer to private data.
+  @param[in]   ResourceExist      =  TRUE if resource exists, PUT method will be used.
+             &= nbsp;           &nbs= p;         FALSE if resource d= oes not exist POST method is used.

 

 

Actually ProvisioningSecureBootResource uses PATCH o= nly.

 



+
+  @retval EFI_SUCCESS         = ;     Provision resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+RedfishProvisioningResourceCommon (
+  IN     REDFISH_RESOURCE_COMMON_PRIVATE  *P= rivate,
+  IN     BOOLEAN      &n= bsp;            = ;       ResourceExist
+  )
+{
+  if (Private =3D=3D NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return ProvisioningSecureBootResource (Private);
+}
+
+/**
+  Check resource from given Json data.
+
+  @param[in]   This       &nb= sp;        Pointer to REDFISH_RESOU= RCE_COMMON_PRIVATE instance.
+  @param[in]   Json       &nb= sp;        The JSON data to check.<= br> +  @param[in]   HeaderEtag      &nb= sp;   The Etag string returned in HTTP header.
+
+  @retval EFI_SUCCESS         = ;     Check resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+RedfishCheckResourceCommon (
+  IN     REDFISH_RESOURCE_COMMON_PRIVATE  *P= rivate,
+  IN     CHAR8      &nbs= p;            &= nbsp;        *Json,
+  IN     CHAR8      &nbs= p;            &= nbsp;        *HeaderEtag OPTIONAL +  )
+{
+  UINTN       Index;
+  EFI_STATUS  Status;
+  UINTN       Count;
+  EFI_STRING  Property;
+
+  if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Json)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check ETAG to see if we need to check it
+  //
+  if (CheckEtag (Private->Uri, HeaderEtag, NULL)) {
+    //
+    // No change
+    //
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: ETAG: %s has no = change, ignore check action\n", __func__, Private->Uri));
+    return EFI_SUCCESS;
+  }
+
+  Count =3D sizeof (mSecureBootSupportedAttributes) / sizeof (mSecure= BootSupportedAttributes[0]);
+  if (Count =3D=3D 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status =3D EFI_SUCCESS;
+  for (Index =3D 0; Index < Count; Index++) {
+    Property =3D mSecureBootSupportedAttributes[Index];
+    if (Property =3D=3D NULL) {
+      continue;
+    }
+
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: [%d] check attri= bute for: %s\n", __func__, Index, Property));
+    if (!MatchPropertyWithJsonContext (Property, Json)) { +      DEBUG ((REDFISH_DEBUG_TRACE, "%a: prop= erty is missing: %s\n", __func__, Property));
+      Status =3D EFI_NOT_FOUND;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Update resource to Redfish service.
+
+  @param[in]   Private       =       Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+  @param[in]   Json       &nb= sp;        The JSON data to be upda= ted.
+
+  @retval EFI_SUCCESS         = ;     Update resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+RedfishUpdateResourceCommon (
+  IN     REDFISH_RESOURCE_COMMON_PRIVATE  *P= rivate,
+  IN     CHAR8      &nbs= p;            &= nbsp;        *InputJson
+  )
+{
+  EFI_STATUS        Status;
+  CHAR8           &= nbsp; *Json;
+  CHAR8           &= nbsp; *JsonWithAddendum;
+  REDFISH_RESPONSE  Response;
+
+  if ((Private =3D=3D NULL) || IS_EMPTY_STRING (InputJson)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Json =3D NULL;
+
+  Status =3D ProvisioningSecureBootProperties (
+             P= rivate->JsonStructProtocol,
+             S= ecureBootEmptyJson,
+             N= ULL,
+             R= EDFISH_DUMMY_CONFIG_LANG,
+             T= RUE,
+             &= amp;Json
+             )= ;
+  if (EFI_ERROR (Status)) {
+    if (Status =3D=3D EFI_NOT_FOUND) {
+      DEBUG ((REDFISH_DEBUG_TRACE, "%a: upda= te resource for %s ignored. Nothing changed\n", __func__, REDFISH_DUMM= Y_CONFIG_LANG));
+      Status =3D EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_ERROR, "%a: update resou= rce for %s failed: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status)= );
+    }
+
+    goto ON_RELEASE;
+  }
+
+  //
+  // Check and see if platform has OEM data or not
+  //
+  Status =3D RedfishGetOemData (
+             P= rivate->Uri,
+             R= ESOURCE_SCHEMA,
+             R= ESOURCE_SCHEMA_VERSION,
+             J= son,
+             &= amp;JsonWithAddendum
+             )= ;
+  if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> +    FreePool (Json);
+    Json         &n= bsp;   =3D JsonWithAddendum;
+    JsonWithAddendum =3D NULL;
+  }
+
+  //
+  // Check and see if platform has addendum data or not
+  //
+  Status =3D RedfishGetAddendumData (
+             P= rivate->Uri,
+             R= ESOURCE_SCHEMA,
+             R= ESOURCE_SCHEMA_VERSION,
+             J= son,
+             &= amp;JsonWithAddendum
+             )= ;
+  if (!EFI_ERROR (Status) && (JsonWithAddendum !=3D NULL)) {<= br> +    FreePool (Json);
+    Json         &n= bsp;   =3D JsonWithAddendum;
+    JsonWithAddendum =3D NULL;
+  }
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: update resource for %s\n&quo= t;, __func__, REDFISH_DUMMY_CONFIG_LANG));
+
+  //
+  // PATCH back to instance
+  //
+  Status =3D RedfishHttpPatchResource (Private->RedfishService, Pr= ivate->Uri, Json, &Response);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: patch resource for %s fa= iled: %r\n", __func__, REDFISH_DUMMY_CONFIG_LANG, Status));
+  }
+
+ON_RELEASE:
+
+  if (Json !=3D NULL) {
+    FreePool (Json);
+  }
+
+  RedfishHttpFreeResponse (&Response);
+
+  return Status;
+}
+
+/**
+  Identify resource in given Json data.
+
+  @param[in]   Private       =       Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+  @param[in]   Json       &nb= sp;        The JSON to be identifie= d.
+
+  @retval EFI_SUCCESS         = ;     Identify resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+RedfishIdentifyResourceCommon (
+  IN     REDFISH_RESOURCE_COMMON_PRIVATE  *P= rivate,
+  IN     CHAR8      &nbs= p;            &= nbsp;        *Json
+  )
+{
+  BOOLEAN  Supported;
+
+  Supported =3D RedfishIdentifyResource (Private->Uri, Private->= ;Json);
+  if (Supported) {
+    //
+    // Keep URI and ConfigLang mapping
+    //
+    RedfishSetRedfishUri (REDFISH_DUMMY_CONFIG_LANG, Privat= e->Uri);
+  }
+
+  return (Supported ? EFI_SUCCESS : EFI_UNSUPPORTED);
+}
+
+/**
+  Handle Redfish resource in Uri.
+
+  @param[in]   Private       =       Pointer to REDFISH_RESOURCE_COMMON_PRIV= ATE instance.
+  @param[in]   Uri       &nbs= p;         URI to Redfish reso= urce that we like to process.
+
+  @retval EFI_SUCCESS         = ;     Handle resource successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+HandleResource (
+  IN  REDFISH_RESOURCE_COMMON_PRIVATE  *Private,
+  IN  EFI_STRING         = ;            &n= bsp; Uri
+  )
+{
+  EFI_STATUS          &n= bsp;Status;
+  REDFISH_SCHEMA_INFO  SchemaInfo;
+  EFI_STRING          &n= bsp;ConfigLang;
+
+  if ((Private =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Resource match
+  //
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s\n&q= uot;, __func__, Uri));
+
+  Status =3D GetRedfishSchemaInfo (Private->RedfishService, Privat= e->JsonStructProtocol, Uri, NULL, &SchemaInfo);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to get schema inf= ormation from: %s %r\n", __func__, Uri, Status));
+    return Status;
+  }
+
+  //
+  // Check and see if this is target resource that we want to handle.=
+  // Some resource is handled by other provider so we have to make su= re this first.
+  //
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: Identify for %s\n", __f= unc__, Uri));
+  ConfigLang =3D RedfishGetConfigLanguage (Uri);
+  if (ConfigLang =3D=3D NULL) {
+    Status =3D EdkIIRedfishResourceConfigIdentify (&Sch= emaInfo, Uri, NULL, Private->InformationExchange);
+    if (EFI_ERROR (Status)) {
+      if (Status =3D=3D EFI_UNSUPPORTED) {
+        DEBUG ((REDFISH_DEBUG_TRACE, &q= uot;%a: \"%s\" is not handled by us\n", __func__, Uri));
+        return EFI_SUCCESS;
+      } else if (Status =3D=3D EFI_NOT_FOUND) { +        DEBUG ((REDFISH_DEBUG_TRACE, &q= uot;%a: \"%s\" has nothing to handle\n", __func__, Uri)); +        return EFI_SUCCESS;
+      }
+
+      DEBUG ((DEBUG_ERROR, "%a: fail to iden= tify resource: \"%s\": %r\n", __func__, Uri, Status));
+      return Status;
+    }
+  } else {
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: history record f= ound: %s\n", __func__, ConfigLang));
+    FreePool (ConfigLang);
+  }
+
+  //
+  // Check and see if target property exist or not even when collecti= on member exists.
+  // If not, we sill do provision.

 

%s/sill/still



+  //
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a Check for %s\n", __func_= _, Uri));
+  Status =3D EdkIIRedfishResourceConfigCheck (&SchemaInfo, Uri, N= ULL);
+  if (EFI_ERROR (Status)) {
+    if (Status =3D=3D EFI_UNSUPPORTED) {
+      DEBUG ((REDFISH_DEBUG_TRACE, "%a: \&qu= ot;%s\" is not handled by us\n", __func__, Uri));
+      return EFI_SUCCESS;
+    }
+
+    //
+    // The target property does not exist, do the provision= to create property.
+    //
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a provision for %s\= n", __func__, Uri));
+    Status =3D EdkIIRedfishResourceConfigProvisioning (&= ;SchemaInfo, Uri, NULL, Private->InformationExchange, FALSE);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: failed to pr= ovision with GET mode: %r\n", __func__, Status));
+    }
+
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource= for: %s finished\n", __func__, Uri));
+
+    return Status;
+  }
+
+  //
+  // Consume first.
+  //
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __fun= c__, Uri));
+  Status =3D EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri,= NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to consume resour= ce for: %s: %r\n", __func__, Uri, Status));
+  }
+
+  //
+  // Patch.
+  //
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a update for %s\n", __func= __, Uri));
+  Status =3D EdkIIRedfishResourceConfigUpdate (&SchemaInfo, Uri, = NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to update resourc= e for: %s: %r\n", __func__, Uri, Status));
+  }
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: process resource for: %s fin= ished\n", __func__, Uri));
+
+  return Status;
+}
diff --git a/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.= c b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c
new file mode 100644
index 000000000..a0f4f3d14
--- /dev/null
+++ b/RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.c
@@ -0,0 +1,808 @@
+/** @file
+  Redfish feature driver implementation - SecureBoot
+
+  (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP&l= t;BR>
+  Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights= reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "../Common/SecureBootCommon.h"
+
+extern REDFISH_RESOURCE_COMMON_PRIVATE  *mRedfishResourcePrivate;
+extern EFI_HANDLE          &n= bsp;            = ;mRedfishResourceConfigProtocolHandle;
+
+EFI_STATUS
+HandleResource (
+  IN  REDFISH_RESOURCE_COMMON_PRIVATE  *Private,
+  IN  EFI_STRING         = ;            &n= bsp; Uri
+  );
+
+/**
+  Provisioning redfish resource by given URI.
+
+  @param[in]   This       &nb= sp;        Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+  @param[in]   Uri       &nbs= p;         Target URI to creat= e resource.
+  @param[in]   PostMode       = ;     TRUE if the resource does not exist, post me= thod is used.
+             &= nbsp;           &nbs= p;         FALSE if the resour= ce exist but property is missing, put method is used.
+
+  @retval EFI_SUCCESS         = ;     Value is returned successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceProvisioningResource (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  IN     EFI_STRING      = ;            &n= bsp;           Uri,<= br> +  IN     BOOLEAN      &n= bsp;            = ;            &n= bsp; PostMode
+  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_RESPONSE         &n= bsp;       Response;
+
+  if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((REDFISH_DEBUG_TRACE, "%a: provisioning in %s mode\n&qu= ot;, __func__, (PostMode ? L"POST" : L"PATCH")));<= /o:p>

 

 

This message conflicts with PostMode parameter descr= iption.

 



+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+    return Status;
+  }
+
+  Private->Uri     =3D Uri;
+  Private->Payload =3D Response.Payload;
+  ASSERT (Private->Payload !=3D NULL);
+
+  Status =3D RedfishProvisioningResourceCommon (Private, !PostMode);<= br> +  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to provision reso= urce to: %s: %r\n", __func__, Uri, Status));
+  } else {
+    //
+    // Get latest ETag on URI and keep it in variable.
+    //
+    SetEtagFromUri (Private->RedfishService, Private->= ;Uri, TRUE);
+  }
+
+  //
+  // Release resource
+  //
+  RedfishHttpFreeResponse (&Response);
+  Private->Payload =3D NULL;
+
+  return Status;
+}
+
+/**
+  Consume resource from given URI.
+
+  @param[in]   This       &nb= sp;        Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+  @param[in]   Uri       &nbs= p;         The target URI to c= onsume.
+
+  @retval EFI_SUCCESS         = ;     Value is returned successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceConsumeResource (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  IN     EFI_STRING      = ;            &n= bsp;           Uri +  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_RESPONSE         &n= bsp;       Response;
+  EFI_STRING          &n= bsp;            = ;PendingSettingUri;
+  REDFISH_RESPONSE         &n= bsp;       PendingSettingResponse;
+  REDFISH_RESPONSE         &n= bsp;       *ExpectedResponse;
+  CHAR8           &= nbsp;           &nbs= p;    *Etag;
+
+  if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  ZeroMem (&PendingSettingResponse, sizeof (REDFISH_RESPONSE)); +  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+    return Status;
+  }
+
+  //
+  // Check and see if "@Redfish.Settings" exist or not.
+  //
+  PendingSettingUri =3D NULL;
+  Status           =  =3D GetPendingSettings (
+             &= nbsp;          Private-&g= t;RedfishService,
+             &= nbsp;          Response.P= ayload,
+             &= nbsp;          &Pendi= ngSettingResponse,
+             &= nbsp;          &Pendi= ngSettingUri
+             &= nbsp;          );
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((REDFISH_DEBUG_TRACE, "%a: @Redfish.Setting= s found: %s\n", __func__, PendingSettingUri));
+    Private->Uri     =3D PendingSett= ingUri;
+    ExpectedResponse =3D &PendingSettingResponse;
+  } else {
+    Private->Uri     =3D Uri;
+    ExpectedResponse =3D &Response;
+  }
+
+  Private->Payload =3D ExpectedResponse->Payload;
+  ASSERT (Private->Payload !=3D NULL);
+
+  Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+  ASSERT (Private->Json !=3D NULL);
+
+  //
+  // Searching for etag in HTTP response header
+  //
+  Etag   =3D NULL;
+  Status =3D GetHttpResponseEtag (ExpectedResponse, &Etag);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from = HTTP header\n", __func__));
+  }
+
+  Status =3D RedfishConsumeResourceCommon (Private, Private->Json,= Etag);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to consume resour= ce from: %s: %r\n", __func__, Private->Uri, Status));
+  }
+
+  //
+  // Release resource
+  //
+  RedfishHttpFreeResponse (&Response);
+  RedfishHttpFreeResponse (&PendingSettingResponse);
+  Private->Payload =3D NULL;
+
+  if (Private->Json !=3D NULL) {
+    FreePool (Private->Json);
+    Private->Json =3D NULL;
+  }
+
+  if (Etag !=3D NULL) {
+    FreePool (Etag);
+  }
+
+  if (PendingSettingUri !=3D NULL) {
+    FreePool (PendingSettingUri);
+  }
+
+  return Status;
+}
+
+/**
+  Get information about this protocol.
+
+  @param[in]   This       &nb= sp;        Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+  @param[out]  Schema        =       Supported schema.
+  @param[out]  Major        &= nbsp;      Supported major number.
+  @param[out]  Minor        &= nbsp;      Supported minor number.
+  @param[out]  Errata        =       Supported errata number.
+
+  @retval EFI_SUCCESS         = ;     Value is returned successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceGetInfo (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  OUT    REDFISH_SCHEMA_INFO     &= nbsp;           &nbs= p;   *Info
+  )
+{
+  if ((This =3D=3D NULL) || (Info =3D=3D NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AsciiStrCpyS (Info->Schema, REDFISH_SCHEMA_STRING_SIZE, RESOURCE= _SCHEMA);
+  AsciiStrCpyS (Info->Major, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE= _SCHEMA_MAJOR);
+  AsciiStrCpyS (Info->Minor, REDFISH_SCHEMA_VERSION_SIZE, RESOURCE= _SCHEMA_MINOR);
+  AsciiStrCpyS (Info->Errata, REDFISH_SCHEMA_VERSION_SIZE, RESOURC= E_SCHEMA_ERRATA);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update resource to given URI.
+
+  @param[in]   This       &nb= sp;        Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+  @param[in]   Uri       &nbs= p;         The target URI to c= onsume.
+
+  @retval EFI_SUCCESS         = ;     Value is returned successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceUpdate (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  IN     EFI_STRING      = ;            &n= bsp;           Uri +  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_RESPONSE         &n= bsp;       Response;
+
+  if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+    return Status;
+  }
+
+  Private->Uri     =3D Uri;
+  Private->Payload =3D Response.Payload;
+  ASSERT (Private->Payload !=3D NULL);
+
+  Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+  ASSERT (Private->Json !=3D NULL);
+
+  Status =3D RedfishUpdateResourceCommon (Private, Private->Json);=
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to update resourc= e to: %s: %r\n", __func__, Uri, Status));
+  } else {
+    //
+    // Get latest ETag on URI and keep it in variable.
+    //
+    SetEtagFromUri (Private->RedfishService, Private->= ;Uri, TRUE);
+  }
+
+  //
+  // Release resource
+  //
+  RedfishHttpFreeResponse (&Response);
+  Private->Payload =3D NULL;
+
+  if (Private->Json !=3D NULL) {
+    FreePool (Private->Json);
+    Private->Json =3D NULL;
+  }
+
+  return Status;
+}
+
+/**
+  Check resource on given URI.
+
+  @param[in]   This       &nb= sp;        Pointer to EFI_HP_REDFIS= H_HII_PROTOCOL instance.
+  @param[in]   Uri       &nbs= p;         The target URI to c= onsume.
+
+  @retval EFI_SUCCESS         = ;     Value is returned successfully.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceCheck (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  IN     EFI_STRING      = ;            &n= bsp;           Uri +  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_RESPONSE         &n= bsp;       Response;
+  CHAR8           &= nbsp;           &nbs= p;    *Etag;
+
+  if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+    return Status;
+  }
+
+  Private->Uri     =3D Uri;
+  Private->Payload =3D Response.Payload;
+  ASSERT (Private->Payload !=3D NULL);
+
+  Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+  ASSERT (Private->Json !=3D NULL);
+
+  //
+  // Find etag in HTTP response header
+  //
+  Etag   =3D NULL;
+  Status =3D GetHttpResponseEtag (&Response, &Etag);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from = HTTP header\n", __func__));
+  }
+
+  Status =3D RedfishCheckResourceCommon (Private, Private->Json, E= tag);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to check resource= from: %s: %r\n", __func__, Uri, Status));
+  }
+
+  //
+  // Release resource
+  //
+  if (Etag !=3D NULL) {
+    FreePool (Etag);
+  }
+
+  RedfishHttpFreeResponse (&Response);
+  Private->Payload =3D NULL;
+
+  if (Private->Json !=3D NULL) {
+    FreePool (Private->Json);
+    Private->Json =3D NULL;
+  }
+
+  return Status;
+}
+
+/**
+  Identify resource on given URI.
+
+  @param[in]   This       &nb= sp;        Pointer to EDKII_REDFISH= _RESOURCE_CONFIG_PROTOCOL instance.
+  @param[in]   Uri       &nbs= p;         The target URI to c= onsume.
+
+  @retval EFI_SUCCESS         = ;     This is target resource which we want to han= dle.
+  @retval EFI_UNSUPPORTED        &= nbsp; This is not the target resource.
+  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceIdentify (
+  IN     EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL &= nbsp;*This,
+  IN     EFI_STRING      = ;            &n= bsp;           Uri +  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_RESPONSE         &n= bsp;       Response;
+
+  if ((This =3D=3D NULL) || IS_EMPTY_STRING (Uri)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_RESOURCE_PROT= OCOL (This);
+
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  Status =3D RedfishHttpGetResource (Private->RedfishService, Uri,= NULL, &Response, TRUE);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: get resource from: %s fa= iled\n", __func__, Uri));
+    return Status;
+  }
+
+  Private->Uri     =3D Uri;
+  Private->Payload =3D Response.Payload;
+  ASSERT (Private->Payload !=3D NULL);
+
+  Private->Json =3D JsonDumpString (RedfishJsonInPayload (Private-= >Payload), EDKII_JSON_COMPACT);
+  ASSERT (Private->Json !=3D NULL);
+
+  Status =3D RedfishIdentifyResourceCommon (Private, Private->Json= );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: identify %s failed: %r\n= ", __func__, Uri, Status));
+  }
+
+  //
+  // Release resource
+  //
+  RedfishHttpFreeResponse (&Response);
+  Private->Payload =3D NULL;
+
+  if (Private->Json !=3D NULL) {
+    FreePool (Private->Json);
+    Private->Json =3D NULL;
+  }
+
+  return Status;
+}
+
+EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL  mRedfishResourceConfig =3D {<= br> +  RedfishResourceProvisioningResource,
+  RedfishResourceConsumeResource,
+  RedfishResourceUpdate,
+  RedfishResourceCheck,
+  RedfishResourceIdentify,
+  RedfishResourceGetInfo
+};
+
+/**
+  Initialize a Redfish configure handler.
+
+  This function will be called by the Redfish config driver to initia= lize each Redfish configure
+  handler.
+
+  @param[in]   This       &nb= sp;            =  Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance.
+  @param[in]   RedfishConfigServiceInfo Redfish service inf= ormation.
+
+  @retval EFI_SUCCESS         = ;         The handler has been= initialized successfully.
+  @retval EFI_DEVICE_ERROR        =      Failed to create or configure the REST EX pro= tocol instance.
+  @retval EFI_ALREADY_STARTED       &nb= sp;  This handler has already been initialized.
+  @retval Other          = ;            &n= bsp; Error happens during the initialization.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceInit (
+  IN  EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  *This,
+  IN  REDFISH_CONFIG_SERVICE_INFORMATION     = ;*RedfishConfigServiceInfo
+  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOC= OL (This);
+
+  Private->RedfishService =3D RedfishCreateService (RedfishConfigS= erviceInfo);
+  if (Private->RedfishService =3D=3D NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Stop a Redfish configure handler.
+
+  @param[in]   This       &nb= sp;        Pointer to EDKII_REDFISH= _CONFIG_HANDLER_PROTOCOL instance.
+
+  @retval EFI_SUCCESS         = ;     This handler has been stoped successfully. +  @retval Others         &nbs= p;         Some error happened= .
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceStop (
+  IN  EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  *This
+  )
+{
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+
+  Private =3D REDFISH_RESOURCE_COMMON_PRIVATE_DATA_FROM_CONFIG_PROTOC= OL (This);
+
+  if (Private->Event !=3D NULL) {
+    gBS->CloseEvent (Private->Event);
+    Private->Event =3D NULL;
+  }
+
+  if (Private->RedfishService !=3D NULL) {
+    RedfishCleanupService (Private->RedfishService);
+    Private->RedfishService =3D NULL;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  mRedfishConfigHandler =3D { +  RedfishResourceInit,
+  RedfishResourceStop
+};
+
+/**
+  Callback function when gEfiRestJsonStructureProtocolGuid is install= ed.
+
+  @param[in] Event    Event whose notification functio= n is being invoked.
+  @param[in] Context  Pointer to the notification function's con= text.
+**/
+VOID
+EFIAPI
+EfiRestJsonStructureProtocolIsReady (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  if (mRedfishResourcePrivate =3D=3D NULL) {
+    return;
+  }
+
+  if (mRedfishResourcePrivate->JsonStructProtocol !=3D NULL) {
+    return;
+  }
+
+  Status =3D gBS->LocateProtocol (
+             &= nbsp;    &gEfiRestJsonStructureProtocolGuid,
+             &= nbsp;    NULL,
+             &= nbsp;    (VOID **)&mRedfishResourcePrivate->Json= StructProtocol
+             &= nbsp;    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to locate gEfiRes= tJsonStructureProtocolGuid: %r\n", __func__, Status));
+  }
+
+  gBS->CloseEvent (Event);
+}
+
+/**
+  Unloads an image.
+
+  @param  ImageHandle        =    Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS         = ;  The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image hand= le.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS          &n= bsp;            = ;      Status;
+  EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL  *ConfigHandler;
+
+  if (mRedfishResourcePrivate =3D=3D NULL) {
+    return EFI_NOT_READY;
+  }
+
+  ConfigHandler =3D NULL;
+
+  //
+  // Firstly, find ConfigHandler Protocol interface in this ImageHand= le.
+  //
+  Status =3D gBS->OpenProtocol (
+             &= nbsp;    ImageHandle,
+             &= nbsp;    &gEdkIIRedfishConfigHandlerProtocolGuid, +             &= nbsp;    (VOID **)&ConfigHandler,
+             &= nbsp;    NULL,
+             &= nbsp;    NULL,
+             &= nbsp;    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+             &= nbsp;    );
+  if (EFI_ERROR (Status) || (ConfigHandler =3D=3D NULL)) {
+    return Status;
+  }
+
+  ConfigHandler->Stop (ConfigHandler);
+
+  //
+  // Last, uninstall ConfigHandler Protocol and resource protocol. +  //
+  Status =3D gBS->UninstallMultipleProtocolInterfaces (
+             &= nbsp;    ImageHandle,
+             &= nbsp;    &gEdkIIRedfishConfigHandlerProtocolGuid, +             &= nbsp;    ConfigHandler,
+             &= nbsp;    &gEdkIIRedfishResourceConfigProtocolGuid,<= br> +             &= nbsp;    &mRedfishResourcePrivate->RedfishResour= ceConfig,
+             &= nbsp;    NULL
+             &= nbsp;    );
+
+  FreePool (mRedfishResourcePrivate);
+  mRedfishResourcePrivate =3D NULL;
+
+  return Status;
+}
+
+/**
+  The callback function provided by Redfish Feature driver.
+
+  @param[in]     This     &nb= sp;          Pointer to E= DKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]     FeatureAction    =    The action Redfish feature driver should take.
+  @param[in]     Uri     &nbs= p;           The col= lection URI.
+  @param[in]     Context     =         The context of Redfish feat= ure driver.
+  @param[in,out] InformationExchange The pointer to RESOURCE_INFORMAT= ION_EXCHANGE
+
+  @retval EFI_SUCCESS         = ;     Redfish feature driver callback is executed = successfully.
+  @retval Others         &nbs= p;         Some errors happene= d.
+
+  @retval EFI_SUCCESS         = ;     Redfish feature driver callback is executed = successfully.
+  @retval Others         &nbs= p;         Some errors happene= d.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishExternalResourceResourceFeatureCallback (
+  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *Th= is,
+  IN     FEATURE_CALLBACK_ACTION   &nbs= p;     FeatureAction,
+  IN     VOID       = ;            &n= bsp;        *Context,
+  IN OUT RESOURCE_INFORMATION_EXCHANGE   *InformationExchan= ge
+  )
+{
+  EFI_STATUS          &n= bsp;            = ;Status;
+  REDFISH_SERVICE         &nb= sp;        RedfishService;
+  REDFISH_RESOURCE_COMMON_PRIVATE  *Private;
+  EFI_STRING          &n= bsp;            = ;ResourceUri;
+  EFI_STRING          &n= bsp;            = ;SecureBootUri;
+
+  if (FeatureAction !=3D CallbackActionStartOperation) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Private =3D (REDFISH_RESOURCE_COMMON_PRIVATE *)Context;
+
+  RedfishService =3D Private->RedfishService;
+  if (RedfishService =3D=3D NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: no Redfish service confi= gured\n", __func__));
+    return EFI_NOT_READY;
+  }
+
+  //
+  // Save in private structure.
+  //
+  Private->InformationExchange =3D InformationExchange;
+
+  //
+  // Find Redfish version on Redfish ser
+  //
+  Private->RedfishVersion =3D RedfishGetVersion (RedfishService);<= br> +
+  //
+  // Create the full URI from Redfish service root.
+  //
+  ResourceUri =3D (EFI_STRING)AllocateZeroPool (MAX_URI_LENGTH * size= of (CHAR16));
+  if (ResourceUri =3D=3D NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory = for full URI.\n", __func__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  StrCatS (ResourceUri, MAX_URI_LENGTH, Private->RedfishVersion);<= br> +  StrCatS (ResourceUri, MAX_URI_LENGTH, InformationExchange->SendI= nformation.FullUri);
+
+  //
+  // Initialize collection path
+  //
+  SecureBootUri =3D RedfishGetUri (ResourceUri);
+  if (SecureBootUri =3D=3D NULL) {
+    ASSERT (FALSE);
+    FreePool (ResourceUri);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status =3D HandleResource (Private, SecureBootUri);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: process external resourc= e: %s failed: %r\n", __func__, SecureBootUri, Status));
+  }
+
+  FreePool (SecureBootUri);
+  FreePool (ResourceUri);
+  return Status;
+}
+
+/**
+  Callback function when gEdkIIRedfishFeatureProtocolGuid is installe= d.
+
+  @param[in] Event    Event whose notification functio= n is being invoked.
+  @param[in] Context  Pointer to the notification function's con= text.
+**/
+VOID
+EFIAPI
+EdkIIRedfishFeatureProtocolIsReady (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  )
+{
+  EFI_STATUS          &n= bsp;           Statu= s;
+  EDKII_REDFISH_FEATURE_PROTOCOL  *FeatureProtocol;
+
+  if (mRedfishResourcePrivate =3D=3D NULL) {
+    return;
+  }
+
+  if (mRedfishResourcePrivate->FeatureProtocol !=3D NULL) {
+    return;
+  }
+
+  Status =3D gBS->LocateProtocol (
+             &= nbsp;    &gEdkIIRedfishFeatureProtocolGuid,
+             &= nbsp;    NULL,
+             &= nbsp;    (VOID **)&FeatureProtocol
+             &= nbsp;    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to locate gEdkIIR= edfishFeatureProtocolGuid: %r\n", __func__, Status));
+    gBS->CloseEvent (Event);
+    return;
+  }
+
+  Status =3D FeatureProtocol->Register (
+             &= nbsp;           &nbs= p;    FeatureProtocol,
+             &= nbsp;           &nbs= p;    REDFISH_MANAGED_URI,
+             &= nbsp;           &nbs= p;    RedfishExternalResourceResourceFeatureCallback, +             &= nbsp;           &nbs= p;    (VOID *)mRedfishResourcePrivate
+             &= nbsp;           &nbs= p;    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to register %s: %= r\n", __func__, REDFISH_MANAGED_URI, Status));
+  }
+
+  mRedfishResourcePrivate->FeatureProtocol =3D FeatureProtocol; +
+  gBS->CloseEvent (Event);
+}
+
+/**
+  This is the declaration of an EFI image entry point. This entry poi= nt is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers i= ncluding
+  both device drivers and bus drivers. It initialize the global varia= bles and
+  publish the driver binding protocol.
+
+  @param[in]   ImageHandle      Th= e firmware allocated handle for the UEFI image.
+  @param[in]   SystemTable      A = pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS         = ;  The operation completed successfully.
+  @retval EFI_ACCESS_DENIED     EFI_ISCSI_INITIAT= OR_NAME_PROTOCOL was installed unexpectedly.
+  @retval Others         &nbs= p;      Other errors as indicated.
+**/
+EFI_STATUS
+EFIAPI
+RedfishResourceEntryPoint (
+  IN EFI_HANDLE        ImageHandle= ,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  VOID        *Registration;
+
+  if (mRedfishResourcePrivate !=3D NULL) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  mRedfishResourceConfigProtocolHandle =3D ImageHandle;
+
+  mRedfishResourcePrivate =3D AllocateZeroPool (sizeof (REDFISH_RESOU= RCE_COMMON_PRIVATE));
+  CopyMem (&mRedfishResourcePrivate->ConfigHandler, &mRedf= ishConfigHandler, sizeof (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL));
+  CopyMem (&mRedfishResourcePrivate->RedfishResourceConfig, &a= mp;mRedfishResourceConfig, sizeof (EDKII_REDFISH_RESOURCE_CONFIG_PROTOCOL))= ;
+
+  //
+  // Publish config handler protocol and resource protocol.
+  //
+  Status =3D gBS->InstallMultipleProtocolInterfaces (
+             &= nbsp;    &ImageHandle,
+             &= nbsp;    &gEdkIIRedfishConfigHandlerProtocolGuid, +             &= nbsp;    &mRedfishResourcePrivate->ConfigHandler= ,
+             &= nbsp;    &gEdkIIRedfishResourceConfigProtocolGuid,<= br> +             &= nbsp;    &mRedfishResourcePrivate->RedfishResour= ceConfig,
+             &= nbsp;    NULL
+             &= nbsp;    );
+
+  EfiCreateProtocolNotifyEvent (
+    &gEfiRestJsonStructureProtocolGuid,
+    TPL_CALLBACK,
+    EfiRestJsonStructureProtocolIsReady,
+    NULL,
+    &Registration
+    );
+
+  EfiCreateProtocolNotifyEvent (
+    &gEdkIIRedfishFeatureProtocolGuid,
+    TPL_CALLBACK,
+    EdkIIRedfishFeatureProtocolIsReady,
+    (VOID *)mRedfishResourcePrivate,
+    &Registration
+    );
+
+  return Status;
+}
diff --git a/RedfishClientPkg/RedfishClient.fdf.inc b/RedfishClientPkg/Redf= ishClient.fdf.inc
index 59b8acba1..154f641b2 100644
--- a/RedfishClientPkg/RedfishClient.fdf.inc
+++ b/RedfishClientPkg/RedfishClient.fdf.inc
@@ -25,6 +25,7 @@
  INF RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.in= f
  INF RedfishClientPkg/Features/BootOptionCollection/BootOptionCo= llectionDxe.inf
  INF RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionD= xe.inf
+  INF RedfishClientPkg/Features/SecureBoot/v1_1_0/Dxe/SecureBootDxe.i= nf

  !include RedfishClientPkg/RedfishJsonStructureDxe.fdf.inc
  #
--
2.34.1

 

 

 

Regards,

Mike

 

_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#117119) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--_000_MW4PR12MB7031FBB03B6BF5921D54207AD9352MW4PR12MB7031namp_--