From nobody Tue Dec 24 13:26:30 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1511854094851152.5064467145629; Mon, 27 Nov 2017 23:28:14 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C3E782034A79C; Mon, 27 Nov 2017 23:23:50 -0800 (PST) Received: from mail-pf0-x242.google.com (mail-pf0-x242.google.com [IPv6:2607:f8b0:400e:c00::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C34F52034A78F for ; Mon, 27 Nov 2017 23:23:48 -0800 (PST) Received: by mail-pf0-x242.google.com with SMTP id t69so18589317pfg.4 for ; Mon, 27 Nov 2017 23:28:11 -0800 (PST) Received: from localhost.localdomain ([220.225.120.129]) by smtp.gmail.com with ESMTPSA id g127sm41643826pgc.29.2017.11.27.23.28.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 27 Nov 2017 23:28:08 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c00::242; helo=mail-pf0-x242.google.com; envelope-from=kalyankumar.nagabhirava@linaro.org; receiver=edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=vZa+PuHZda9ZzG+VRyJebiov8J182lVBHUN1pCHybWg=; b=TgS3r/SQ95XiKZFTiqr6KWG24aHXouPnoyRzs5TFy48bY8HJUxHxEcYl4i+Gpbbta9 bAAx1OKDoWSCEBTLesHnNPLOepl9AhBZxobPhYVJwwZ57Wu0uZjUKGE+DX0eOXZf9xsx 9Ffo/iGDx+9nbkq52sspn1Hc0uQCWohk2j+4U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=vZa+PuHZda9ZzG+VRyJebiov8J182lVBHUN1pCHybWg=; b=cnWZzCY16CqF4mmHIB+M4zkL4PY8S1Bhcc98EICJgx+YHjsNa5XAuuxCYGyYJwFNaq BhHpsWWqe9wvWdrcj37P9oeOFs4rtOd4YyvxNNezhQwEHDBUGJngDeEUMygARiPhUtEo 65ROkDxTgCCwQi0tWH8pV59l/N8XKnb+8eXcvyQv1NemkMAh4cSwMTdr5MlML27V3l2C eOtq99D2Er7My1tsp3/az/XtGsBHJWnPVFfh8QiELTthfVAo5JLIv5LYp2MFOF5DUqwf gDwd6q1aTozORXMO85CuoTXSpHrlb1N4BciyO5Q8ZrA/MWh4UvOMGPitua/RA1yd6IJH SQ8Q== X-Gm-Message-State: AJaThX6CJibh1/s5cTHaVO7RydGuFAQf4UEiQd7vTBuKyhwsz9ZjtvoU nJ7q3A81tFiwYuSdgubh1YlKWUscoRw= X-Google-Smtp-Source: AGs4zMYIO0KSdbVr1fwcCeZ7oO6wb9rrJXjADM9qNhx+0Qm8r+NewQAIde4ccOjyonJkgU7Q5vu+ww== X-Received: by 10.99.120.131 with SMTP id t125mr5212075pgc.83.1511854089200; Mon, 27 Nov 2017 23:28:09 -0800 (PST) From: kalyan-nagabhirava To: edk2-devel@lists.01.org, ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, mark.gregotski@linaro.org Date: Tue, 28 Nov 2017 12:57:58 +0530 Message-Id: <20171128072758.13509-1-kalyankumar.nagabhirava@linaro.org> X-Mailer: git-send-email 2.15.0 Subject: [edk2] [PATCH] [edk2 EmbeddedPkg]:Adding secure boot and HTTP image download (Disaster recovery image) Applications for Linux based platforms X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Linaro and RDK are working on standardizing the boot process for RDK STB = boxes using Uefi. Added applications are reference implementation of RDK STB boot process on = Arm platforms Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: kalyan-nagabhirava --- EmbeddedPkg/Application/Dri/Dri.c | 26 + EmbeddedPkg/Application/Dri/Dri.inf | 56 ++ .../Application/DriSecureBoot/DriSecureBoot.c | 32 ++ .../Application/DriSecureBoot/DriSecureBoot.inf | 57 ++ EmbeddedPkg/Application/SecureBoot/SecureBoot.c | 30 ++ EmbeddedPkg/Application/SecureBoot/SecureBoot.inf | 57 ++ EmbeddedPkg/Drivers/RdkDxe/RdkDxe.c | 97 ++++ EmbeddedPkg/Drivers/RdkDxe/RdkDxe.h | 14 + EmbeddedPkg/Drivers/RdkDxe/RdkDxe.inf | 45 ++ EmbeddedPkg/Library/RdkBootManagerLib/DiskIo.c | 536 +++++++++++++++++= ++ EmbeddedPkg/Library/RdkBootManagerLib/HttpBoot.c | 315 +++++++++++ .../Library/RdkBootManagerLib/Include/DiskIo.h | 20 + .../Library/RdkBootManagerLib/Include/HttpBoot.h | 7 + .../Library/RdkBootManagerLib/Include/List.h | 136 +++++ .../RdkBootManagerLib/Include/RdkBootManagerLib.h | 31 ++ .../Library/RdkBootManagerLib/Include/RdkFile.h | 20 + .../Library/RdkBootManagerLib/Include/SecureBoot.h | 40 ++ .../RdkBootManagerLib/RdkBootManagerLib.dec | 52 ++ .../RdkBootManagerLib/RdkBootManagerLib.inf | 81 +++ EmbeddedPkg/Library/RdkBootManagerLib/RdkFile.c | 259 +++++++++ EmbeddedPkg/Library/RdkBootManagerLib/SecureBoot.c | 577 +++++++++++++++++= ++++ 21 files changed, 2488 insertions(+) create mode 100644 EmbeddedPkg/Application/Dri/Dri.c create mode 100644 EmbeddedPkg/Application/Dri/Dri.inf create mode 100644 EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.c create mode 100644 EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.inf create mode 100644 EmbeddedPkg/Application/SecureBoot/SecureBoot.c create mode 100644 EmbeddedPkg/Application/SecureBoot/SecureBoot.inf create mode 100644 EmbeddedPkg/Drivers/RdkDxe/RdkDxe.c create mode 100644 EmbeddedPkg/Drivers/RdkDxe/RdkDxe.h create mode 100644 EmbeddedPkg/Drivers/RdkDxe/RdkDxe.inf create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/DiskIo.c create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/HttpBoot.c create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/DiskIo.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/HttpBoot.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/List.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkBootMa= nagerLib.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkFile.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/Include/SecureBoo= t.h create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib= .dec create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib= .inf create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/RdkFile.c create mode 100644 EmbeddedPkg/Library/RdkBootManagerLib/SecureBoot.c diff --git a/EmbeddedPkg/Application/Dri/Dri.c b/EmbeddedPkg/Application/Dr= i/Dri.c new file mode 100644 index 0000000000..affbac08b6 --- /dev/null +++ b/EmbeddedPkg/Application/Dri/Dri.c @@ -0,0 +1,26 @@ +/* +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + */ +#include + +EFI_STATUS +EFIAPI +DriEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D RdkHttpBoot (); + return Status; +} diff --git a/EmbeddedPkg/Application/Dri/Dri.inf b/EmbeddedPkg/Application/= Dri/Dri.inf new file mode 100644 index 0000000000..d6f24b48a6 --- /dev/null +++ b/EmbeddedPkg/Application/Dri/Dri.inf @@ -0,0 +1,56 @@ +# +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# Copyright (c) 2016-2017, comcast . All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RdkDriLoader + FILE_GUID =3D 081ba18a-d71e-40a7-99a9-cdb86463966d + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D DriEntryPoint + +[Sources] + Dri.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + NetworkPkg/NetworkPkg.dec + EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec + +[Guids] + gEfiCertX509Guid + gEfiCertPkcs7Guid + gEfiCustomModeEnableGuid + gEfiImageSecurityDatabaseGuid + gFdtTableGuid + +[LibraryClasses] + RdkBootManagerLib + UefiApplicationEntryPoint + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathToTextProtocolGuid diff --git a/EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.c b/Embedd= edPkg/Application/DriSecureBoot/DriSecureBoot.c new file mode 100644 index 0000000000..9a36075e85 --- /dev/null +++ b/EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.c @@ -0,0 +1,32 @@ +/* +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + */ +#include + +EFI_STATUS +EFIAPI +DriSecureBootEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D RdkHttpBoot (); + + Status =3D RdkSecureBoot( + ImageHandle, + SystemTable->BootServices + ); + + return Status; +} diff --git a/EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.inf b/Embe= ddedPkg/Application/DriSecureBoot/DriSecureBoot.inf new file mode 100644 index 0000000000..20a68aac4b --- /dev/null +++ b/EmbeddedPkg/Application/DriSecureBoot/DriSecureBoot.inf @@ -0,0 +1,57 @@ +# +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# Copyright (c) 2016-2017, comcast . All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RdkDriSecureLoader + FILE_GUID =3D dd52d1d7-0de2-4552-98e0-8dbee458a502 + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D DriSecureBootEntryPoint + +[Sources] + DriSecureBoot.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + NetworkPkg/NetworkPkg.dec + EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec + +[Guids] + gEfiCertX509Guid + gEfiCertPkcs7Guid + gEfiCustomModeEnableGuid + gEfiImageSecurityDatabaseGuid + gFdtTableGuid + +[LibraryClasses] + RdkBootManagerLib + UefiApplicationEntryPoint + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathToTextProtocolGuid + gEfiDevicePathFromTextProtocolGuid diff --git a/EmbeddedPkg/Application/SecureBoot/SecureBoot.c b/EmbeddedPkg/= Application/SecureBoot/SecureBoot.c new file mode 100644 index 0000000000..51ac75835f --- /dev/null +++ b/EmbeddedPkg/Application/SecureBoot/SecureBoot.c @@ -0,0 +1,30 @@ +/* +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + */ +#include + +EFI_STATUS +EFIAPI +SecureBootEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D RdkSecureBoot ( + ImageHandle, + SystemTable->BootServices + ); + + return Status; +} diff --git a/EmbeddedPkg/Application/SecureBoot/SecureBoot.inf b/EmbeddedPk= g/Application/SecureBoot/SecureBoot.inf new file mode 100644 index 0000000000..90d1ee677f --- /dev/null +++ b/EmbeddedPkg/Application/SecureBoot/SecureBoot.inf @@ -0,0 +1,57 @@ +# +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# Copyright (c) 2016-2017, comcast . All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RdkSecureLoader + FILE_GUID =3D b2c7930f-07ef-4305-ac4e-1ce2085a7031 + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D SecureBootEntryPoint + +[Sources] + SecureBoot.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + NetworkPkg/NetworkPkg.dec + EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec + +[Guids] + gEfiCertX509Guid + gEfiCertPkcs7Guid + gEfiCustomModeEnableGuid + gEfiImageSecurityDatabaseGuid + gFdtTableGuid + gRdkGlobalVariableGuid + +[LibraryClasses] + RdkBootManagerLib + UefiApplicationEntryPoint + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathToTextProtocolGuid diff --git a/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.c b/EmbeddedPkg/Drivers/RdkD= xe/RdkDxe.c new file mode 100644 index 0000000000..9b35fe1be2 --- /dev/null +++ b/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.c @@ -0,0 +1,97 @@ +/* +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# +*/ +#include "RdkDxe.h" + +STATIC +VOID +PlatformRegisterFvBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINT32 Attributes + ) +{ + EFI_STATUS Status; + INTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath =3D DevicePathFromHandle (LoadedImage->DeviceHandle); + ASSERT (DevicePath !=3D NULL); + DevicePath =3D AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + ASSERT (DevicePath !=3D NULL); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + + OptionIndex =3D EfiBootManagerFindLoadOption ( + &NewOption, BootOptions, BootOptionCount + ); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + +EFI_STATUS +EFIAPI +RdkDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdRdkSecureBootFile), L"Rdk Secure Boot", LOAD_OPTION_AC= TIVE + ); + + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdRdkDriFile), L"Rdk Dri", LOAD_OPTION_ACTIVE + ); + + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdRdkDriSecureBootFile), L"Rdk Secure Dri Boot", LOAD_OP= TION_ACTIVE + ); + + return EFI_SUCCESS; +} diff --git a/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.h b/EmbeddedPkg/Drivers/RdkD= xe/RdkDxe.h new file mode 100644 index 0000000000..d103341047 --- /dev/null +++ b/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.h @@ -0,0 +1,14 @@ +#ifndef __RDK_DRIVER_H__ +#define __RDK_DRIVER_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __RDK_DRIVER_H__ */ diff --git a/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.inf b/EmbeddedPkg/Drivers/Rd= kDxe/RdkDxe.inf new file mode 100644 index 0000000000..75e48684df --- /dev/null +++ b/EmbeddedPkg/Drivers/RdkDxe/RdkDxe.inf @@ -0,0 +1,45 @@ +# +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# Copyright (c) 2016-2017, comcast . All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RDKDriver + FILE_GUID =3D 305da1a1-cd7d-4d61-bf83-8e79a7839a33 + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 0.1 + ENTRY_POINT =3D RdkDriverEntryPoint + +[Sources] + RdkDxe.c + RdkDxe.h + +[Packages] + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec + +[LibraryClasses] + UefiBootManagerLib + UefiDriverEntryPoint + +[FixedPcd] + gRdkTokenSpaceGuid.PcdRdkDriFile + gRdkTokenSpaceGuid.PcdRdkSecureBootFile + gRdkTokenSpaceGuid.PcdRdkDriSecureBootFile diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/DiskIo.c b/EmbeddedPkg/L= ibrary/RdkBootManagerLib/DiskIo.c new file mode 100644 index 0000000000..204a139d9f --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/DiskIo.c @@ -0,0 +1,536 @@ +#include + +/* See sparse_format.h in AOSP */ +#define SPARSE_HEADER_MAGIC 0xed26ff3a +#define CHUNK_TYPE_RAW 0xCAC1 +#define CHUNK_TYPE_FILL 0xCAC2 +#define CHUNK_TYPE_DONT_CARE 0xCAC3 +#define CHUNK_TYPE_CRC32 0xCAC4 + +#define PARTITION_NAME_MAX_LENGTH 72/2 + +#define FLASH_DEVICE_PATH_SIZE(DevPath) ( GetDevicePathSize (DevPath) - \ + sizeof (EFI_DEVICE_PATH_PROTOCOL)) + +#define IS_ALPHA(Char) (((Char) <=3D L'z' && (Char) >=3D L'a') || \ + ((Char) <=3D L'Z' && (Char) >=3D L'Z')) + +typedef struct _DISKIO_PARTITION_LIST { + LIST_ENTRY Link; + CHAR16 PartitionName[PARTITION_NAME_MAX_LENGTH]; + EFI_HANDLE PartitionHandle; +} DISKIO_PARTITION_LIST; + +typedef struct _SPARSE_HEADER { + UINT32 Magic; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT16 FileHeaderSize; + UINT16 ChunkHeaderSize; + UINT32 BlockSize; + UINT32 TotalBlocks; + UINT32 TotalChunks; + UINT32 ImageChecksum; +} SPARSE_HEADER; + +typedef struct _CHUNK_HEADER { + UINT16 ChunkType; + UINT16 Reserved1; + UINT32 ChunkSize; + UINT32 TotalSize; +} CHUNK_HEADER; + +STATIC LIST_ENTRY mPartitionListHead; +STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut; +STATIC UINT8 PartitionInited =3D 0; + +/* + * Helper to free the partition list + */ +STATIC +VOID +FreePartitionList ( + VOID +) +{ + DISKIO_PARTITION_LIST *Entry; + DISKIO_PARTITION_LIST *NextEntry; + + Entry =3D (DISKIO_PARTITION_LIST *) GetFirstNode (&mPartitionListHead); + while (!IsNull (&mPartitionListHead, &Entry->Link)) { + NextEntry =3D (DISKIO_PARTITION_LIST *) GetNextNode (&mPartitionListHe= ad, &Entry->Link); + + RemoveEntryList (&Entry->Link); + FreePool (Entry); + + Entry =3D NextEntry; + } +} + +/* + * Read the PartitionName fields from the GPT partition entries, putting t= hem + * into an allocated array that should later be freed. + */ +STATIC +EFI_STATUS +ReadPartitionEntries ( + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + OUT EFI_PARTITION_ENTRY **PartitionEntries + ) +{ + UINTN EntrySize; + UINTN NumEntries; + UINTN BufferSize; + UINT32 MediaId; + EFI_PARTITION_TABLE_HEADER *GptHeader; + EFI_STATUS Status; + + MediaId =3D BlockIo->Media->MediaId; + + // + // Read size of Partition entry and number of entries from GPT header + // + GptHeader =3D AllocatePool (BlockIo->Media->BlockSize); + if (GptHeader =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D BlockIo->ReadBlocks (BlockIo, MediaId, 1, BlockIo->Media->Blo= ckSize, (VOID *) GptHeader); + if (EFI_ERROR (Status)) { + return Status; + } + + // Check there is a GPT on the media + if (GptHeader->Header.Signature !=3D EFI_PTAB_HEADER_ID || + GptHeader->MyLBA !=3D 1) { + DEBUG ((DEBUG_ERROR, + "Fastboot platform: No GPT on flash. " + "Fastboot on Versatile Express does not support MBR.\n" + )); + return EFI_DEVICE_ERROR; + } + + EntrySize =3D GptHeader->SizeOfPartitionEntry; + NumEntries =3D GptHeader->NumberOfPartitionEntries; + + FreePool (GptHeader); + + ASSERT (EntrySize !=3D 0); + ASSERT (NumEntries !=3D 0); + + BufferSize =3D ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media->Bloc= kSize); + *PartitionEntries =3D AllocatePool (BufferSize); + if (PartitionEntries =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status =3D BlockIo->ReadBlocks (BlockIo, MediaId, 2, BufferSize, (VOID *= ) *PartitionEntries); + if (EFI_ERROR (Status)) { + FreePool (PartitionEntries); + return Status; + } + + return Status; +} + +/* + * Initialise: Open the Android NVM device and find the partitions on it. = Save them in + * a list along with the "PartitionName" fields for their GPT entries. + * We will use these partition names as the key in + * FastbootPlatformFlashPartition. + */ +EFI_STATUS +InitDiskIo ( + VOID + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath; + EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *NextNode; + HARDDRIVE_DEVICE_PATH *PartitionNode; + UINTN NumHandles; + EFI_HANDLE *AllHandles; + UINTN LoopIndex; + EFI_HANDLE FlashHandle; + EFI_BLOCK_IO_PROTOCOL *FlashBlockIo; + EFI_PARTITION_ENTRY *PartitionEntries; + DISKIO_PARTITION_LIST *Entry; + + InitializeListHead (&mPartitionListHead); + + Status =3D gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (V= OID **) &mTextOut); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Sta= tus + )); + return Status; + } + + // + // Get EFI_HANDLES for all the partitions on the block devices pointed t= o by + // PcdFastbootFlashDevicePath, also saving their GPT partition labels. + // There's no way to find all of a device's children, so we get every ha= ndle + // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out on= es + // that don't represent partitions on the flash device. + // + + FlashDevicePath =3D ConvertTextToDevicePath ((CHAR16*)PcdGetPtr (PcdAndr= oidFastbootNvmDevicePath)); + + // + // Open the Disk IO protocol on the flash device - this will be used to = read + // partition names out of the GPT entries + // + // Create another device path pointer because LocateDevicePath will modi= fy it. + FlashDevicePathDup =3D FlashDevicePath; + Status =3D gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevice= PathDup, &FlashHandle); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Warning: Couldn't locate Android NVM device (stat= us: %r)\n", Status)); + // Failing to locate partitions should not prevent to do other Android= FastBoot actions + return EFI_SUCCESS; + } + + Status =3D gBS->OpenProtocol ( + FlashHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) &FlashBlockIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Fastboot platform: Couldn't open Android NVM devi= ce (status: %r)\n", Status)); + return EFI_DEVICE_ERROR; + } + + // Read the GPT partition entry array into memory so we can get the part= ition names + Status =3D ReadPartitionEntries (FlashBlockIo, &PartitionEntries); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "Warning: Failed to read partitions from Android N= VM device (status: %r)\n", Status)); + // Failing to locate partitions should not prevent to do other Android= FastBoot actions + return EFI_SUCCESS; + } + + // Get every Block IO protocol instance installed in the system + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &NumHandles, + &AllHandles + ); + ASSERT_EFI_ERROR (Status); + + // Filter out handles that aren't children of the flash device + for (LoopIndex =3D 0; LoopIndex < NumHandles; LoopIndex++) { + // Get the device path for the handle + Status =3D gBS->OpenProtocol ( + AllHandles[LoopIndex], + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + // Check if it is a sub-device of the flash device + if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (= FlashDevicePath))) { + // Device path starts with path of flash device. Check it isn't the = flash + // device itself. + NextNode =3D NextDevicePathNode (DevicePath); + if (IsDevicePathEndType (NextNode)) { + // Create entry + Entry =3D AllocatePool (sizeof (DISKIO_PARTITION_LIST)); + if (Entry =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + FreePartitionList (); + goto Exit; + } + + // Copy handle and partition name + Entry->PartitionHandle =3D AllHandles[LoopIndex]; + StrCpy (Entry->PartitionName, L"ptable"); + InsertTailList (&mPartitionListHead, &Entry->Link); + continue; + } + + // Assert that this device path node represents a partition. + ASSERT (NextNode->Type =3D=3D MEDIA_DEVICE_PATH && + NextNode->SubType =3D=3D MEDIA_HARDDRIVE_DP); + + PartitionNode =3D (HARDDRIVE_DEVICE_PATH *) NextNode; + + // Assert that the partition type is GPT. ReadPartitionEntries check= s for + // presence of a GPT, so we should never find MBR partitions. + // ("MBRType" is a misnomer - this field is actually called "Partiti= on + // Format") + ASSERT (PartitionNode->MBRType =3D=3D MBR_TYPE_EFI_PARTITION_TABLE_H= EADER); + + // The firmware may install a handle for "partition 0", representing= the + // whole device. Ignore it. + if (PartitionNode->PartitionNumber =3D=3D 0) { + continue; + } + + // + // Add the partition handle to the list + // + + // Create entry + Entry =3D AllocatePool (sizeof (DISKIO_PARTITION_LIST)); + if (Entry =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + FreePartitionList (); + goto Exit; + } + + // Copy handle and partition name + Entry->PartitionHandle =3D AllHandles[LoopIndex]; + StrnCpy ( + Entry->PartitionName, + PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionNa= me, // Partition numbers start from 1. + PARTITION_NAME_MAX_LENGTH + ); + InsertTailList (&mPartitionListHead, &Entry->Link); + + // Print a debug message if the partition label is empty or looks li= ke + // garbage. + if (!IS_ALPHA (Entry->PartitionName[0])) { + DEBUG ((DEBUG_WARN, + "Warning: Partition %d doesn't seem to have a GPT partition la= bel. " + "You won't be able to flash it with Fastboot.\n", + PartitionNode->PartitionNumber + )); + } + } + } + + Exit: + FreePool (PartitionEntries); + FreePool (FlashDevicePath); + FreePool (AllHandles); + return Status; + +} + +STATIC +EFI_STATUS +OpenPartition ( + IN CHAR8 *PartitionName, + IN VOID *Image, + IN UINTN Size, + OUT EFI_BLOCK_IO_PROTOCOL **BlockIo, + OUT EFI_DISK_IO_PROTOCOL **DiskIo + ) +{ + EFI_STATUS Status; + UINTN PartitionSize; + DISKIO_PARTITION_LIST *Entry; + CHAR16 PartitionNameUnicode[60]; + BOOLEAN PartitionFound; + SPARSE_HEADER *SparseHeader; + + if(!PartitionInited) + { + InitDiskIo(); + PartitionInited =3D 1; + } + + AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode); + + PartitionFound =3D FALSE; + Entry =3D (DISKIO_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); + while (!IsNull (&mPartitionListHead, &Entry->Link)) { + // Search the partition list for the partition named by PartitionName + if (StrCmp (Entry->PartitionName, PartitionNameUnicode) =3D=3D 0) { + PartitionFound =3D TRUE; + break; + } + + Entry =3D (DISKIO_PARTITION_LIST *) GetNextNode (&mPartitionListHead, = &(Entry)->Link); + } + if (!PartitionFound) { + Status =3D EFI_NOT_FOUND; + goto exit; + } + + Status =3D gBS->OpenProtocol ( + Entry->PartitionHandle, + &gEfiBlockIoProtocolGuid, + (VOID **) BlockIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to open Block IO protocol: %r\n", Status)= ); + Status =3D EFI_NOT_FOUND; + goto exit; + } + + SparseHeader=3D(SPARSE_HEADER *)Image; + + if (SparseHeader->Magic =3D=3D SPARSE_HEADER_MAGIC) { + DEBUG ((DEBUG_INFO, "Sparse Magic: 0x%x Major: %d Minor: %d fhs: %d ch= s: %d bs: %d tbs: %d tcs: %d checksum: %d \n", + SparseHeader->Magic, SparseHeader->MajorVersion, SparseHeader->Minor= Version, SparseHeader->FileHeaderSize, + SparseHeader->ChunkHeaderSize, SparseHeader->BlockSize, SparseHeader= ->TotalBlocks, + SparseHeader->TotalChunks, SparseHeader->ImageChecksum)); + + if (SparseHeader->MajorVersion !=3D 1) { + DEBUG ((DEBUG_ERROR, "Sparse image version %d.%d not supported.\n", + SparseHeader->MajorVersion, SparseHeader->MinorVersion)); + Status =3D EFI_INVALID_PARAMETER; + goto exit; + } + + Size =3D SparseHeader->BlockSize * SparseHeader->TotalBlocks; + } + + // Check image will fit on device + PartitionSize =3D (BlockIo[0]->Media->LastBlock + 1) * BlockIo[0]->Media= ->BlockSize; + if (PartitionSize < Size) { + DEBUG ((DEBUG_ERROR, "Partition not big enough.\n")); + DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", Parti= tionSize, Size)); + + Status =3D EFI_VOLUME_FULL; + goto exit; + } + + Status =3D gBS->OpenProtocol ( + Entry->PartitionHandle, + &gEfiDiskIoProtocolGuid, + (VOID **) DiskIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + +exit: + return Status; +} + +EFI_STATUS +PartitionRead ( + IN CHAR8 *PartitionName, + IN VOID *Image, + IN UINTN Size + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + UINT32 MediaId; + + Status =3D OpenPartition (PartitionName, Image, Size, &BlockIo, &DiskIo); + if (EFI_ERROR (Status)) { + goto exit; + } + + MediaId =3D BlockIo->Media->MediaId; + + Status =3D DiskIo->ReadDisk (DiskIo, MediaId, 0, Size, Image); + if (EFI_ERROR (Status)) { + goto exit; + } + + BlockIo->FlushBlocks(BlockIo); + +exit: + return Status; +} + + +EFI_STATUS +PartitionWrite ( + IN CHAR8 *PartitionName, + IN VOID *Image, + IN UINTN Size + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + UINT32 MediaId; + SPARSE_HEADER *SparseHeader; + CHUNK_HEADER *ChunkHeader; + UINT32 Chunk; + UINTN Offset; + + Status =3D OpenPartition (PartitionName, Image, Size, &BlockIo, &DiskIo); + if (EFI_ERROR (Status)) { + goto exit; + } + + Offset =3D 0; + MediaId =3D BlockIo->Media->MediaId; + SparseHeader =3D (SPARSE_HEADER *)Image; + + if (SparseHeader->Magic =3D=3D SPARSE_HEADER_MAGIC) { + CHAR16 OutputString[64]; + UINTN ChunkPrintDensity =3D + SparseHeader->TotalChunks > 1600 ? SparseHeader->TotalChunks / 200 := 32; + + Image +=3D SparseHeader->FileHeaderSize; + for (Chunk =3D 0; Chunk < SparseHeader->TotalChunks; Chunk++) { + UINTN WriteSize; + ChunkHeader =3D (CHUNK_HEADER *)Image; + + // Show progress. Don't do it for every packet as outputting text + // might be time consuming. ChunkPrintDensity is calculated to + // provide an update every half percent change for large + // downloads. + if (Chunk % ChunkPrintDensity =3D=3D 0) { + UnicodeSPrint(OutputString, sizeof(OutputString), + L"\r%5d / %5d chunks written (%d%%)", Chunk, + SparseHeader->TotalChunks, + (Chunk * 100) / SparseHeader->TotalChunks); + mTextOut->OutputString(mTextOut, OutputString); + } + + DEBUG ((DEBUG_INFO, "Chunk #%d - Type: 0x%x Size: %d TotalSize: %d O= ffset %d\n", + (Chunk+1), ChunkHeader->ChunkType, ChunkHeader->ChunkSize, + ChunkHeader->TotalSize, Offset)); + Image +=3D sizeof(CHUNK_HEADER); + WriteSize=3D(SparseHeader->BlockSize) * ChunkHeader->ChunkSize; + switch (ChunkHeader->ChunkType) { + case CHUNK_TYPE_RAW: + DEBUG ((DEBUG_INFO, "Writing %d at Offset %d\n", WriteSize, Offs= et)); + Status =3D DiskIo->WriteDisk (DiskIo, MediaId, Offset, WriteSize= , Image); + if (EFI_ERROR (Status)) { + goto exit; + } + Image+=3DWriteSize; + break; + case CHUNK_TYPE_DONT_CARE: + break; + case CHUNK_TYPE_CRC32: + break; + default: + DEBUG ((DEBUG_ERROR, "Unknown Chunk Type: 0x%x", ChunkHeader->Ch= unkType)); + Status =3D EFI_PROTOCOL_ERROR; + goto exit; + } + Offset +=3D WriteSize; + } + + UnicodeSPrint(OutputString, sizeof(OutputString), + L"\r%5d / %5d chunks written (100%%)\r\n", + SparseHeader->TotalChunks, SparseHeader->TotalChunks); + mTextOut->OutputString(mTextOut, OutputString); + + } else { + + Status =3D DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image); + if (EFI_ERROR (Status)) { + goto exit; + } + } + + BlockIo->FlushBlocks(BlockIo); + +exit: + return Status; +} diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/HttpBoot.c b/EmbeddedPkg= /Library/RdkBootManagerLib/HttpBoot.c new file mode 100644 index 0000000000..e89241c51b --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/HttpBoot.c @@ -0,0 +1,315 @@ +/* +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# +*/ +#include + +STATIC EFI_LOAD_FILE_PROTOCOL *LoadFile =3D NULL; +STATIC HTTP_BOOT_PRIVATE_DATA *Private =3D NULL; + +STATIC +VOID +HttpPrivateFromLoadFile ( + IN EFI_LOAD_FILE_PROTOCOL *LoadFile, + OUT HTTP_BOOT_PRIVATE_DATA **Private + ) +{ + HTTP_BOOT_VIRTUAL_NIC *Ip4Nic =3D NULL; + + INT64 Offset =3D (INT64)&Ip4Nic->LoadFile; + Ip4Nic =3D (VOID *)((char *)LoadFile - Offset); + ASSERT (Ip4Nic->Signature =3D=3D HTTP_BOOT_VIRTUAL_NIC_SIGNATURE); + *Private =3D Ip4Nic->Private; +} + +STATIC +VOID +HttpGetLoadFileHandle ( + OUT EFI_LOAD_FILE_PROTOCOL **LoadFile + ) +{ + EFI_STATUS Status; + UINTN LoopIndex; + UINTN NumHandles; + EFI_HANDLE *AllHandles; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; + UINT16 *DeviceFullPath; + + Status =3D gBS->LocateProtocol ( + &gEfiDevicePathToTextProtocolGuid, + NULL, + (VOID **) &DevPathToText + ); + ASSERT_EFI_ERROR (Status); + + // Get every LoadFile protocol instance installed in the system + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiLoadFileProtocolGuid, + NULL, + &NumHandles, + &AllHandles + ); + ASSERT_EFI_ERROR (Status); + + // Get HTTP driver handle from AllHandles + for (LoopIndex =3D 0; LoopIndex < NumHandles; LoopIndex++) { + + Handle =3D AllHandles[LoopIndex]; + + // Get the device path for the handle + Status =3D gBS->OpenProtocol ( + Handle, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + DeviceFullPath =3D DevPathToText->ConvertDevicePathToText ( + DevicePath, + FALSE, + TRUE + ); + + ASSERT(DeviceFullPath !=3D NULL); + + if(StrStr(DeviceFullPath, L"IPv4") !=3D NULL) { + + Status =3D gBS->OpenProtocol ( + Handle, + &gEfiLoadFileProtocolGuid, + (VOID **) LoadFile, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + ASSERT_EFI_ERROR (Status); + + FreePool (AllHandles); + break; + } + } + + ASSERT ( LoopIndex < NumHandles ); +} + +STATIC +EFI_STATUS +HttpUpdatePath ( + IN CHAR16 *Uri, + OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath + ) +{ + EFI_DEV_PATH *Node; + EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; + EFI_STATUS Status; + UINTN Index; + UINTN Length; + CHAR8 AsciiUri[URI_STR_MAX_SIZE]; + + Node =3D NULL; + TmpDevicePath =3D NULL; + Status =3D EFI_SUCCESS; + + // Convert the scheme to all lower case. + for (Index =3D 0; Index < StrLen (Uri); Index++) { + if (Uri[Index] =3D=3D L':') { + break; + } + if (Uri[Index] >=3D L'A' && Uri[Index] <=3D L'Z') { + Uri[Index] -=3D (CHAR16)(L'A' - L'a'); + } + } + + // Only accept empty URI, or http and https URI. + if ((StrLen (Uri) !=3D 0) && (StrnCmp (Uri, L"http://", 7) !=3D 0) && (S= trnCmp (Uri, L"https://", 8) !=3D 0)) { + return EFI_INVALID_PARAMETER; + } + + // Create a new device path by appending the IP node and URI node to + // the driver's parent device path + Node =3D AllocateZeroPool (sizeof (IPv4_DEVICE_PATH)); + if (Node =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + Node->Ipv4.Header.Type =3D MESSAGING_DEVICE_PATH; + Node->Ipv4.Header.SubType =3D MSG_IPv4_DP; + SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH)); + TmpDevicePath =3D AppendDevicePathNode (Private->ParentDevicePath, (EFI_= DEVICE_PATH_PROTOCOL*) Node); + FreePool (Node); + if (TmpDevicePath =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Update the URI node with the input boot file URI. + UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri)); + Length =3D sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri); + Node =3D AllocatePool (Length); + if (Node =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + FreePool (TmpDevicePath); + goto ON_EXIT; + } + Node->DevPath.Type =3D MESSAGING_DEVICE_PATH; + Node->DevPath.SubType =3D MSG_URI_DP; + SetDevicePathNodeLength (Node, Length); + CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, As= ciiStrSize (AsciiUri)); + *NewDevicePath =3D AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH= _PROTOCOL*) Node); + FreePool (Node); + FreePool (TmpDevicePath); + if (*NewDevicePath =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + +ON_EXIT: + + return Status; +} + +STATIC +EFI_STATUS +HttpGetImage ( + IN CHAR16 *Uri, + OUT UINT8 **FileBuffer, + OUT UINTN *FileSize + ) +{ + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_STATUS Status; + + *FileBuffer =3D NULL; + NewDevicePath =3D NULL; + *FileSize =3D 0; + + // Get the LoadFile Handle and + // Private structure of HTTP driver + if (LoadFile =3D=3D NULL) { + HttpGetLoadFileHandle (&LoadFile); + HttpPrivateFromLoadFile (LoadFile, &Private); + } + + // Update URI path + Status =3D HttpUpdatePath (Uri, &NewDevicePath); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // Get the HTTP image from server + Status =3D LoadFile->LoadFile (LoadFile, NewDevicePath, TRUE, FileSize, = *FileBuffer); + if((Status !=3D EFI_WARN_FILE_SYSTEM) && (Status !=3D EFI_BUFFER_TOO_SMA= LL)) { + goto ON_EXIT; + } + + *FileBuffer =3D AllocatePool (*FileSize); + if (*FileBuffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status =3D LoadFile->LoadFile (LoadFile, NewDevicePath, TRUE, FileSize, = *FileBuffer); + if (EFI_ERROR (Status)) { + FreePool (FileBuffer); + goto ON_EXIT; + } + +ON_EXIT: + + if (NewDevicePath !=3D NULL) { + FreePool (NewDevicePath); + } + + return Status; +} + +EFI_STATUS +RdkHttpBoot ( + VOID + ) +{ + EFI_STATUS Status; + VOID *FilePtr; + UINT8 *FileBuffer; + UINT16 *Uri; + UINTN FileSize; + UINTN LoopIndex; + UINTN Size; + CONST CHAR16 *DtbPath; + CONST CHAR16 *ImagePath; + CONST CHAR16 *ServerUrlPath; + + Status =3D GetRdkVariable(L"URL", &ServerUrlPath);=20 + ASSERT_EFI_ERROR (Status); + + // Get the Server name stored in file Server.url + Status =3D RdkReadFile(ServerUrlPath, (VOID **)&FileBuffer, &FileSize); + ASSERT_EFI_ERROR (Status); + + Uri =3D AllocateZeroPool (sizeof(*Uri) * (FileSize+1)); + if (Uri =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + } + + for(LoopIndex=3D0; LoopIndexSetWatchdogTimer (0, 0x10000, 0, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "HttpBoot: Couldn't disable watchdog timer: %r\n",= Status)); + } + + // Get the File from server using it's URI + Status =3D HttpGetImage (Uri, &FileBuffer, &FileSize); + ASSERT_EFI_ERROR (Status); + + // Write the received image to flash + FilePtr =3D FileBuffer; + Size =3D Str2Int(FilePtr); + FilePtr +=3D FILE_HDR_SIZE; + Status =3D PartitionWrite((CHAR8 *) FixedPcdGetPtr (PcdRdkSystemParti= tionName), FilePtr, Size); + ASSERT_EFI_ERROR (Status); + + FilePtr +=3D Size; + Size =3D Str2Int(FilePtr); + FilePtr +=3D FILE_HDR_SIZE; + Status =3D GetRdkVariable(L"IMAGE", &ImagePath);=20 + ASSERT_EFI_ERROR (Status); + Status =3D RdkWriteFile(ImagePath, &FilePtr, &Size); + ASSERT_EFI_ERROR (Status); + + FilePtr +=3D Size; + Size =3D Str2Int(FilePtr); + FilePtr +=3D FILE_HDR_SIZE; + Status =3D GetRdkVariable(L"DTB", &DtbPath);=20 + ASSERT_EFI_ERROR (Status); + Status =3D RdkWriteFile(DtbPath, &FilePtr, &Size); + ASSERT_EFI_ERROR (Status); + + FreePool (FileBuffer); + FreePool (Uri); + + return Status; +} diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/DiskIo.h b/Embed= dedPkg/Library/RdkBootManagerLib/Include/DiskIo.h new file mode 100644 index 0000000000..003df0c071 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/DiskIo.h @@ -0,0 +1,20 @@ +#ifndef _RDK_DISK_IO_H_ +#define _RDK_DISK_IO_H_ + +extern +EFI_STATUS +PartitionRead ( + IN CHAR8 *PartitionName, + IN VOID *Image, + IN UINTN Size + ); + +extern +EFI_STATUS +PartitionWrite ( + IN CHAR8 *PartitionName, + IN VOID *Image, + IN UINTN Size + ); + +#endif /* _RDK_DISK_IO_H_ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/HttpBoot.h b/Emb= eddedPkg/Library/RdkBootManagerLib/Include/HttpBoot.h new file mode 100644 index 0000000000..80f448ee41 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/HttpBoot.h @@ -0,0 +1,7 @@ +#ifndef _RDK_HTTP_BOOT_H_ +#define _RDK_HTTP_BOOT_H_ + +extern EFI_STATUS +RdkHttpBoot ( VOID ); + +#endif /* _RDK_HTTP_BOOT_H_ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/List.h b/Embedde= dPkg/Library/RdkBootManagerLib/Include/List.h new file mode 100644 index 0000000000..5f6bfac8cf --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/List.h @@ -0,0 +1,136 @@ +#ifndef __LIST_H__ +#define __LIST_H__ + +#define OFFSETOF(TYPE, MEMBER) ((long unsigned int) &((TYPE *)0)->MEMBER) + +/** + * container_of - cast a member of a structure out to the containing struc= ture + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define CONTAINER_OF(Ptr, Type, Member) ({ \ + const typeof( ((Type *)0)->Member ) *__Mptr =3D (Ptr); \ + (Type *)( (char *)__Mptr - OFFSETOF(Type,Member) );}) + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +typedef struct ListHead { + struct ListHead *Next, *Prev; +} LIST_HEAD; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +static inline void INIT_LIST_HEAD(LIST_HEAD *List) +{ + List->Next =3D List; + List->Prev =3D List; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __ListAdd(LIST_HEAD *New, + LIST_HEAD *Prev, + LIST_HEAD *Next) +{ + Next->Prev =3D New; + New->Next =3D Next; + New->Prev =3D Prev; + Prev->Next =3D New; +} + +/** + * ListAdd - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void ListAdd(LIST_HEAD *New, LIST_HEAD *Head) +{ + __ListAdd(New, Head, Head->Next); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __ListDel(LIST_HEAD *Prev, LIST_HEAD *Next) +{ + Next->Prev =3D Prev; + Prev->Next =3D Next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry = is + * in an undefined state. + */ +static inline void ListDel(LIST_HEAD *Entry) +{ + __ListDel(Entry->Prev, Entry->Next); + Entry->Next =3D NULL; + Entry->Prev =3D NULL; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int ListEmpty(const LIST_HEAD *Head) +{ + return Head->Next =3D=3D Head; +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &LIST_HEAD pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define LIST_ENTRY(Ptr, Type, Member) \ + CONTAINER_OF(Ptr, Type, Member) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define LIST_FOR_EACH_ENTRY(Pos, Head, Member) \ + for (Pos =3D LIST_ENTRY((Head)->Next, typeof(*Pos), Member); \ + &Pos->Member !=3D (Head); \ + Pos =3D LIST_ENTRY(Pos->Member.Next, typeof(*Pos), Member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against= removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define LIST_FOR_EACH_ENTRY_SAFE(Pos, N, Head, Member) \ + for (Pos =3D LIST_ENTRY((Head)->Next, typeof(*Pos), Member), \ + N =3D LIST_ENTRY(Pos->Member.Next, typeof(*Pos), Member); \ + &Pos->Member !=3D (Head); \ + Pos =3D N, N =3D LIST_ENTRY(N->Member.Next, typeof(*N), Member)) + +#endif /* __LIST_H__ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkBootManagerLi= b.h b/EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h new file mode 100644 index 0000000000..5b0b2b1afb --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h @@ -0,0 +1,31 @@ +#ifndef __RDK_BOOT_MANAGER_LIB_H__ +#define __RDK_BOOT_MANAGER_LIB_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SecureBoot.h" +#include "HttpBoot.h" +#include "RdkFile.h" +#include "DiskIo.h" + +#endif /* __RDK_BOOT_MANAGER_LIB_H__ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkFile.h b/Embe= ddedPkg/Library/RdkBootManagerLib/Include/RdkFile.h new file mode 100644 index 0000000000..52490c5a37 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/RdkFile.h @@ -0,0 +1,20 @@ +#ifndef __RDK_FILE_H__ +#define __RDK_FILE_H__ + +#include "List.h" + +#define ALLOCATE_STRING_MEM(X) AllocateZeroPool((X + 1) * sizeof(CHAR16)) +#define MAX_VAR 4 + +typedef struct { + CHAR16 *Name; + LIST_HEAD List; +} DIR_NODE; + +extern EFI_STATUS +GetRdkVariable ( + IN CONST CHAR16 *Name, + OUT CONST CHAR16 **Value + ); + +#endif /* __RDK_FILE_H__ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/Include/SecureBoot.h b/E= mbeddedPkg/Library/RdkBootManagerLib/Include/SecureBoot.h new file mode 100644 index 0000000000..3cfd687670 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/Include/SecureBoot.h @@ -0,0 +1,40 @@ +#ifndef _RDK_SECURE_BOOT_H_ +#define _RDK_SECURE_BOOT_H_ + +#define FILE_HDR_SIZE 16 + +extern UINTN Str2Int ( + VOID * Str +); + +extern EFI_STATUS RdkSecureBoot ( + EFI_HANDLE ImageHandle, + EFI_BOOT_SERVICES *BootServices); + +extern EFI_STATUS RdkReadFile ( + IN CONST CHAR16 *Path, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize + ); + +extern EFI_STATUS RdkWriteFile ( + IN CONST CHAR16 *Path, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize + ); + +extern EFI_STATUS GetFileHandler ( + OUT EFI_FILE_HANDLE *FileHandle, + IN CONST CHAR16 *Path, + IN UINT64 OpenMode +); + +typedef enum KEY +{ + PK_KEY=3D1, + KEK_KEY, + DB_KEY, + DBX_KEY +} eKey; + +#endif /* _RDK_SECURE_BOOT_H_ */ diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec b/= EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec new file mode 100644 index 0000000000..2f84d1c56d --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec @@ -0,0 +1,52 @@ +# +# Copyright (c) 2014-2017, Linaro Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +[Defines] + DEC_SPECIFICATION =3D 0x00010019 + PACKAGE_NAME =3D RdkPkg + PACKAGE_GUID =3D 2f1f2d5e-d9e1-4aa1-8eb9-fed94682e140 + PACKAGE_VERSION =3D 0.1 + +##########################################################################= ###### +# +# Include Section - list of Include Paths that are provided by this packag= e. +# Comments are used for Keywords and Module Types. +# +# Supported Module Types: +# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_D= RIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION +# +##########################################################################= ###### +[Includes.common] + Include # Root include for the package + +[Guids.common] + gRdkTokenSpaceGuid =3D { 0x408c1892, 0xf11a, 0x40c7, { 0xaa,= 0x5f, 0x0d, 0x16, 0xc8, 0xb2, 0x52, 0x59 } } + gRdkGlobalVariableGuid =3D { 0xc3253c90, 0xa24f, 0x4599, { 0xa6,= 0x64, 0x1f, 0x88, 0x13, 0x77, 0x8f, 0xc9 } } + +[PcdsFixedAtBuild.common] + # Rdk Library + gRdkTokenSpaceGuid.PcdRdkRsvdReadSize|0x2000|UINT32|0x02000001 + gRdkTokenSpaceGuid.PcdRdkRsvdPartitionName|""|VOID*|0x02000002 + gRdkTokenSpaceGuid.PcdRdkSystemPartitionName|""|VOID*|0x02000003 + gRdkTokenSpaceGuid.PcdRdkConfFileName|""|VOID*|0x02000004 + gRdkTokenSpaceGuid.PcdRdkCmdLineArgs|""|VOID*|0x02000013 + gRdkTokenSpaceGuid.PcdRdkConfFileDevicePath|L""|VOID*|0x02000014 + gRdkTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L""|VOID*|0x00300013 + + # GUID of RdkSecureBootLoader + gRdkTokenSpaceGuid.PcdRdkSecureBootFile|{ 0x0f, 0x93, 0xc7, 0xb2, 0xef, = 0x07, 0x05, 0x43, 0xac, 0x4e, 0x1c, 0xe2, 0x08, 0x5a, 0x70, 0x31 }|VOID*|0x= 00000100 + + # GUID of RdkDri + gRdkTokenSpaceGuid.PcdRdkDriFile|{ 0x8a, 0xa1, 0x1b, 0x08, 0x1e, 0xd7, 0= xa7, 0x40, 0x99, 0xa9, 0xcd, 0xb8, 0x64, 0x63, 0x96, 0x6d }|VOID*|0x00001000 + + # GUID of RdkDriSecureBootLoader + gRdkTokenSpaceGuid.PcdRdkDriSecureBootFile|{ 0xd7, 0xd1, 0x52, 0xdd, 0xe= 2, 0x0d, 0x52, 0x45, 0x98, 0xe0, 0x8d, 0xbe, 0xe4, 0x58, 0xa5, 0x02 }|VOID*= |0x00100000 diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.inf b/= EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.inf new file mode 100644 index 0000000000..aee849db23 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.inf @@ -0,0 +1,81 @@ +# +# Copyright (c) 2016-2017, Linaro Limited. All rights reserved. +# Copyright (c) 2016-2017, comcast . All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# + +##########################################################################= ###### +# +# Defines Section - statements that will be processed to create a Makefile. +# +##########################################################################= ###### + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D RdkBootManagerLib + FILE_GUID =3D 901f54f2-9d70-9b89-9c0a-d9ca25379059 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D RdkBootManagerLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI= _APPLICATION UEFI_DRIVER + +[Sources] + DiskIo.c + SecureBoot.c + HttpBoot.c + RdkFile.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + SecurityPkg/SecurityPkg.dec + CryptoPkg/CryptoPkg.dec + NetworkPkg/NetworkPkg.dec + EmbeddedPkg/Library/RdkBootManagerLib/RdkBootManagerLib.dec + +[Guids] + gEfiCertX509Guid + gEfiCertPkcs7Guid + gEfiCustomModeEnableGuid + gEfiImageSecurityDatabaseGuid + gFdtTableGuid + gRdkGlobalVariableGuid + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathToTextProtocolGuid + gEfiDevicePathFromTextProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiShellProtocolGuid + gEfiDiskIoProtocolGuid + gEfiLoadFileProtocolGuid + +[Pcd] + gRdkTokenSpaceGuid.PcdRdkCmdLineArgs + gRdkTokenSpaceGuid.PcdRdkRsvdReadSize + gRdkTokenSpaceGuid.PcdRdkRsvdPartitionName + gRdkTokenSpaceGuid.PcdRdkSystemPartitionName + gRdkTokenSpaceGuid.PcdRdkConfFileName + gRdkTokenSpaceGuid.PcdRdkConfFileDevicePath + gRdkTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath + +[LibraryClasses] + FileHandleLib + ArmLib + BaseLib + DebugLib + DevicePathLib + HobLib + PcdLib + NetLib + diff --git a/EmbeddedPkg/Library/RdkBootManagerLib/RdkFile.c b/EmbeddedPkg/= Library/RdkBootManagerLib/RdkFile.c new file mode 100644 index 0000000000..346056fcb2 --- /dev/null +++ b/EmbeddedPkg/Library/RdkBootManagerLib/RdkFile.c @@ -0,0 +1,259 @@ +#include + +STATIC UINT8 VarablesInitialzed =3D 0; +STATIC CHAR16 *VarResult[MAX_VAR][2]; + +STATIC +VOID +SaveString ( + OUT CHAR16 **Dest, + IN CHAR16 *String1, + IN CHAR16 *String2 + ) +{ + *Dest =3D ALLOCATE_STRING_MEM(StrLen(String1) + StrLen(String2)); + StrCat(*Dest, String1); + StrCat(*Dest, String2); +} + +STATIC +EFI_STATUS +LsFiles ( + IN CONST CHAR16 *DirPath, + IN CONST CHAR16 *TargetFile, + OUT CHAR16 **Result, + IN LIST_HEAD *Head + ) +{ + EFI_STATUS Status; + EFI_FILE_INFO *FileInfo; + EFI_FILE_PROTOCOL *FileHandle; + BOOLEAN NoFile; + CHAR16 *TempPath; + DIR_NODE *Node; + + NoFile =3D FALSE; + TempPath =3D ALLOCATE_STRING_MEM(StrLen(DirPath) + 1); + StrCat(TempPath, DirPath); + StrCat(TempPath, L"/"); + + Status =3D GetFileHandler(&FileHandle, DirPath, EFI_FILE_MODE_READ); + ASSERT_EFI_ERROR(Status); + + for ( Status =3D FileHandleFindFirstFile(FileHandle, &FileInfo) + ; !EFI_ERROR(Status) && !NoFile + ; Status =3D FileHandleFindNextFile(FileHandle, FileInfo, &NoFile) + ) { + if((FileInfo->Attribute & EFI_FILE_DIRECTORY) && + (StrCmp(FileInfo->FileName, L".") !=3D 0) && + (StrCmp(FileInfo->FileName, L"..") !=3D 0)) { + Node =3D AllocateZeroPool(sizeof (DIR_NODE)); + SaveString(&Node->Name, TempPath, FileInfo->FileName); + ListAdd(&Node->List, Head); + } + else if(StrCmp(FileInfo->FileName, TargetFile) =3D=3D 0) { + SaveString(Result, TempPath, FileInfo->FileName); + Status =3D EFI_SUCCESS; + goto ON_EXIT; + } + } + + Status =3D EFI_NOT_FOUND; + +ON_EXIT: + FreePool(TempPath); + return Status; +} + +STATIC +VOID +DelDirList ( + IN LIST_HEAD *Head + ) +{ + DIR_NODE *Node; + DIR_NODE *Temp; + + LIST_FOR_EACH_ENTRY_SAFE (Node, Temp, Head, List) { + ListDel(&Node->List); + FreePool(Node->Name); + FreePool(Node); + } +} + +STATIC +EFI_STATUS +FindFileInDir ( + IN CONST CHAR16 *DevPath, + IN CONST CHAR16 *TargetFile, + OUT CHAR16 **Result + ) +{ + UINT8 Current; + UINT8 Next; + DIR_NODE *Temp; + LIST_HEAD DirList[2]; + + *Result =3D NULL; + EFI_STATUS Status =3D EFI_NOT_FOUND; + + INIT_LIST_HEAD(&DirList[0]); + INIT_LIST_HEAD(&DirList[1]); + + for (Current =3D 0, LsFiles(DevPath, TargetFile, Result, &DirList[Curren= t]); + !ListEmpty(&DirList[Current]); + Current =3D Next) { + Next =3D Current ^ 1; + DelDirList(&DirList[Next]); + + LIST_FOR_EACH_ENTRY(Temp, &DirList[Current], List) { + Status =3D LsFiles(Temp->Name, TargetFile, Result, &DirList[Next]); + if(!EFI_ERROR(Status)) { + DelDirList(&DirList[Current]); + break; + } + } + } + + DelDirList(&DirList[Next]); + return Status; +} + +STATIC +UINTN +StrSpn ( + IN CHAR8 *String, + IN CHAR8 *CharSet + ) +{ + UINTN Count; + + for(Count=3D0; String[Count] && !(String[Count] =3D=3D CharSet[0]); Coun= t++); + return Count; +} + +STATIC +CHAR16 * +Ascii2Uefi ( + IN CHAR8 *String + ) +{ + CHAR16 *Result; + UINTN Size; + + Size =3D AsciiStrLen(String); + Result =3D ALLOCATE_STRING_MEM(Size); + + while(Size--) { + Result[Size] =3D String[Size]; + } + + return Result; +} + +STATIC +EFI_STATUS +InitVarList ( + IN CHAR8 *FileData, + IN UINTN FileSize + ) +{ + UINTN InnerLoopIndex; + UINTN OuterLoopIndex; + UINTN Current; + UINTN Next; + CHAR8 *VarDelimiter[2]; + EFI_STATUS Status; + + VarDelimiter[0] =3D "=3D"; + VarDelimiter[1] =3D "\""; + Status =3D EFI_SUCCESS; + + for(OuterLoopIndex=3D0, Next=3D0; OuterLoopIndex + +STATIC +EFI_STATUS +OpenFileByDevicePath( + IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes +) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol; + EFI_FILE_PROTOCOL *Handle1; + EFI_FILE_PROTOCOL *Handle2; + EFI_HANDLE DeviceHandle; + + //if ((FilePath =3D=3D NULL || FileHandle =3D=3D NULL)) { + if ((FilePath =3D=3D NULL )) { + return EFI_INVALID_PARAMETER; + } + + Status =3D gBS->LocateDevicePath ( + &gEfiSimpleFileSystemProtocolGuid, + FilePath, + &DeviceHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D gBS->OpenProtocol( + DeviceHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID**)&EfiSimpleFileSystemProtocol, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystem= Protocol, &Handle1); + if (EFI_ERROR (Status)) { + FileHandle =3D NULL; + return Status; + } + + // + // go down directories one node at a time. + // + while (!IsDevicePathEnd (*FilePath)) { + // + // For file system access each node should be a file path component + // + if (DevicePathType (*FilePath) !=3D MEDIA_DEVICE_PATH || + DevicePathSubType (*FilePath) !=3D MEDIA_FILEPATH_DP + ) { + FileHandle =3D NULL; + return (EFI_INVALID_PARAMETER); + } + // + // Open this file path node + // + Handle2 =3D Handle1; + Handle1 =3D NULL; + + // + // Try to test opening an existing file + // + Status =3D Handle2->Open ( + Handle2, + &Handle1, + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, + OpenMode &~EFI_FILE_MODE_CREATE, + 0 + ); + + // + // see if the error was that it needs to be created + // + if ((EFI_ERROR (Status)) && (OpenMode !=3D (OpenMode &~EFI_FILE_MO= DE_CREATE))) { + Status =3D Handle2->Open ( + Handle2, + &Handle1, + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, + OpenMode, + Attributes + ); + } + // + // Close the last node + // + Handle2->Close (Handle2); + + if (EFI_ERROR(Status)) { + return (Status); + } + + // + // Get the next node + // + *FilePath =3D NextDevicePathNode (*FilePath); + } + + // + // This is a weak spot since if the undefined SHELL_FILE_HANDLE format= changes this must change also! + // + *FileHandle =3D (VOID*)Handle1; + + return EFI_SUCCESS; +} + +EFI_STATUS +GetFileHandler ( + OUT EFI_FILE_HANDLE *FileHandle, + IN CONST CHAR16 *Path, + IN UINT64 OpenMode +) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *KeyFileDevicePath; + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevicePathFromTextProtocol; + + Status =3D EFI_SUCCESS; + KeyFileDevicePath =3D NULL; + + Status =3D gBS->LocateProtocol ( + &gEfiDevicePathFromTextProtocolGuid, + NULL, + (VOID**)&DevicePathFromTextProtocol + ); + ASSERT_EFI_ERROR(Status); + + // KeyFileDevicePath =3D gEfiShellProtocol->GetDevicePathFromFilePath= (Path); + KeyFileDevicePath =3D DevicePathFromTextProtocol->ConvertTextToDevice= Path(Path); + if(KeyFileDevicePath !=3D NULL) + { + Status =3D OpenFileByDevicePath(&KeyFileDevicePath,FileHandle,Open= Mode,0); + if(Status !=3D EFI_SUCCESS) + { + DEBUG ((DEBUG_INFO, "Getting FileHandle of %s Failed\n",Path)); + } + } + return Status; +} + +STATIC +EFI_STATUS +CreateTimeBasedPayload ( + IN OUT UINTN *DataSize, + IN OUT UINT8 **Data +) +{ + EFI_STATUS Status; + UINT8 *NewData; + UINT8 *Payload; + UINTN PayloadSize; + EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; + UINTN DescriptorSize; + EFI_TIME Time; + + if (Data =3D=3D NULL || DataSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // In Setup mode or Custom mode, the variable does not need to be sign= ed but the + // parameters to the SetVariable() call still need to be prepared as a= uthenticated + // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor with= out certificate + // data in it. + // + + Payload =3D *Data; + PayloadSize =3D *DataSize; + + DescriptorSize =3D OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthIn= fo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); + NewData =3D (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); + if (NewData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if ((Payload !=3D NULL) && (PayloadSize !=3D 0)) { + CopyMem (NewData + DescriptorSize, Payload, PayloadSize); + } + + DescriptorData =3D (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); + + ZeroMem (&Time, sizeof (EFI_TIME)); + Status =3D gRT->GetTime (&Time, NULL); + if (EFI_ERROR (Status)) { + FreePool(NewData); + return Status; + } + Time.Pad1 =3D 0; + Time.Nanosecond =3D 0; + Time.TimeZone =3D 0; + Time.Daylight =3D 0; + Time.Pad2 =3D 0; + CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME)); + + DescriptorData->AuthInfo.Hdr.dwLength =3D OFFSET_OF (WIN_CERTI= FICATE_UEFI_GUID, CertData); + DescriptorData->AuthInfo.Hdr.wRevision =3D 0x0200; + DescriptorData->AuthInfo.Hdr.wCertificateType =3D WIN_CERT_TYPE_EFI_GU= ID; + CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid); + + if (Payload !=3D NULL) { + FreePool(Payload); + } + + *DataSize =3D DescriptorSize + PayloadSize; + *Data =3D NewData; + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SetBootMode ( + IN UINT8 SecureBootMode +) +{ + return gRT->SetVariable ( + EFI_CUSTOM_MODE_NAME, + &gEfiCustomModeEnableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT8), + &SecureBootMode + ); +} + +STATIC +EFI_STATUS +SetVariable ( + IN EFI_SIGNATURE_LIST *PkCert, + IN UINTN DataSize, + IN eKey KeyType +) +{ + UINT32 Attr; + EFI_STATUS Status=3DEFI_SUCCESS ; + Attr =3D EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUT= HENTICATED_WRITE_ACCESS; + if(KeyType =3D=3D PK_KEY) + { + DEBUG ((DEBUG_INFO, "Setting PK Key\n")); + Status =3D gRT->SetVariable ( + EFI_PLATFORM_KEY_NAME, + &gEfiGlobalVariableGuid, + Attr, + DataSize, + PkCert + ); + } + else if( KeyType =3D=3D KEK_KEY) + { + DEBUG ((DEBUG_INFO, "Setting KEK Key\n")); + Status =3D gRT->SetVariable ( + EFI_KEY_EXCHANGE_KEY_NAME, + &gEfiGlobalVariableGuid, + Attr, + DataSize, + PkCert + ); + + Status =3D gRT->SetVariable ( + EFI_IMAGE_SECURITY_DATABASE, + &gEfiImageSecurityDatabaseGuid, + Attr, + DataSize, + PkCert + ); + } + else + { + ASSERT(FALSE); + } + return Status; + +} + +STATIC +VOID +PopulateCert ( + OUT EFI_SIGNATURE_LIST **Cert, + IN UINTN DataSize, + IN UINT8 *Data +) +{ + EFI_SIGNATURE_DATA *CertData =3D NULL; + + if( (*Cert) =3D=3D NULL) + { + (*Cert) =3D (EFI_SIGNATURE_LIST*) AllocateZeroPool ( sizeof(EFI_SI= GNATURE_LIST) + + sizeof(EFI_SIGNATURE_DATA) - 1 + + DataSize ); + + ASSERT ((*Cert) !=3D NULL); + } + (*Cert)->SignatureListSize =3D (UINT32) (sizeof(EFI_SIGNATURE_LIST) + + sizeof(EFI_SIGNATURE_DATA) - 1 + + DataSize); + (*Cert)->SignatureSize =3D (UINT32) (sizeof(EFI_SIGNATURE_DATA) = - 1 + DataSize); + (*Cert)->SignatureHeaderSize =3D 0; + CopyGuid (&(*Cert)->SignatureType, &gEfiCertX509Guid); + + + CertData =3D (EFI_SIGNATURE_DATA*) ((UINTN)(*Cert) + sizeof(EFI_SIGNAT= URE_LIST) + (*Cert)->SignatureHeaderSize); + ASSERT (CertData !=3D NULL); + + CopyGuid (&CertData->SignatureOwner, &gEfiGlobalVariableGuid); + CopyMem (&CertData->SignatureData, Data, DataSize); +} + +STATIC +EFI_STATUS +RegisterCert ( + IN UINT8 *KeyData, + IN UINTN KeySize, + IN eKey KeyType +) +{ + EFI_STATUS Status; + EFI_SIGNATURE_LIST *Cert =3D NULL; + + Status =3D SetBootMode(CUSTOM_SECURE_BOOT_MODE); + ASSERT_EFI_ERROR (Status); + + PopulateCert(&Cert, KeySize, KeyData); + + KeySize =3D Cert->SignatureListSize; + + Status =3D CreateTimeBasedPayload (&KeySize, (UINT8**) &Cert); + ASSERT_EFI_ERROR (Status); + + Status =3D SetVariable(Cert,KeySize,KeyType); + return Status; +} + +UINTN +Str2Int ( + VOID * Str +) +{ + UINTN i, Size; + UINT8 *Ptr =3D Str; + + for(i=3D0, Size=3D0; iSetVariable ( + L"RdkRootCertificate", + &gRdkGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_AC= CESS, + KekCrtSize, + KekCrtData + ); + ASSERT_EFI_ERROR(Status); + + /* Read PK and KEK keys from reserved partition */ + STATIC UINT8 *Buffer =3D NULL; + UINT32 RsvdReadSize =3D PcdGet32 (PcdRdkRsvdReadSize); + Buffer =3D AllocateZeroPool(RsvdReadSize); + PartitionRead((CHAR8 *)FixedPcdGetPtr (PcdRdkRsvdPartitionName), Buffe= r, RsvdReadSize); + + INT32 PkKeySize, KekKeySize; + + UINT8 * PkKey =3D Buffer; + PkKeySize =3D Str2Int (PkKey); + PkKey +=3D FILE_HDR_SIZE; + + UINT8 * KekKey =3D PkKey + PkKeySize; + KekKeySize =3D Str2Int (KekKey); + KekKey +=3D FILE_HDR_SIZE; + + INT8* SetupMode =3D NULL; + eKey KeyType; + + KeyType =3D PK_KEY; + Status =3D RegisterCert(PkKey,PkKeySize,KeyType); + GetEfiGlobalVariable2 (L"SetupMode", (VOID**)&SetupMode, NULL); + + if (*SetupMode =3D=3D 0) + { + DEBUG ((DEBUG_INFO, "PK Key Got Registered. Now System in User Mod= e\n")); + KeyType =3D KEK_KEY; + Status =3D RegisterCert(KekKey,KekKeySize,KeyType); + } + else if(*SetupMode =3D=3D 1) + { + DEBUG ((DEBUG_INFO, "System in Standard System Mode ::: Secure Boo= t Not enabled\n")); + ASSERT_EFI_ERROR(Status); + } + + FreePool(Buffer); +} + +EFI_STATUS +RdkReadFile ( + IN CONST CHAR16 *Path, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize +) +{ + UINTN BufferSize; + UINT64 SourceFileSize; + VOID *Buffer; + EFI_STATUS Status; + EFI_FILE_HANDLE FileHandle; + + Status =3D GetFileHandler(&FileHandle, Path, EFI_FILE_MODE_READ); + ASSERT_EFI_ERROR(Status); + + if (FileSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D NULL; + + // Get the file size + Status =3D FileHandle->SetPosition (FileHandle, (UINT64) -1); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status =3D FileHandle->GetPosition (FileHandle, &SourceFileSize); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status =3D FileHandle->SetPosition (FileHandle, 0); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + BufferSize =3D (UINTN) SourceFileSize; + Buffer =3D AllocateZeroPool(BufferSize); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BufferSize =3D (UINTN) SourceFileSize; + *FileSize =3D BufferSize; + + Status =3D FileHandle->Read (FileHandle, &BufferSize, Buffer); + if (EFI_ERROR (Status) || BufferSize !=3D *FileSize) { + FreePool (Buffer); + Buffer =3D NULL; + Status =3D EFI_BAD_BUFFER_SIZE; + goto ON_EXIT; + } + +ON_EXIT: + + *BufferPtr =3D Buffer; + return Status; +} + +EFI_STATUS +RdkWriteFile ( + IN CONST CHAR16 *Path, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize +) +{ + EFI_STATUS Status; + EFI_FILE_HANDLE FileHandle; + + if (FileSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Status =3D GetFileHandler(&FileHandle, Path, EFI_FILE_MODE_READ|EFI_FI= LE_MODE_WRITE|EFI_FILE_MODE_CREATE); + ASSERT_EFI_ERROR(Status); + + Status =3D FileHandle->Write (FileHandle, FileSize, *BufferPtr); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +EFI_STATUS +RdkSecureBoot ( + EFI_HANDLE ImageHandle, + EFI_BOOT_SERVICES *BootServices +) +{ + UINT8 *FdtData; + UINTN FdtDataSize; + UINTN *ExitDataSize; + CHAR16 **ExitData; + CHAR16 LoadOption[128]; + CONST CHAR8 *CmdLine; + CONST CHAR16 *ImagePath; + CONST CHAR16 *DtbPath; + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevicePathFromTextProtocol; + + FilePath =3D NULL; + ExitData =3D NULL; + ExitDataSize =3D NULL; + CmdLine =3D (CONST CHAR8 *)FixedPcdGetPtr (PcdRdkCmdLineArgs); + + Status =3D GetRdkVariable(L"DTB", &DtbPath);=20 + ASSERT_EFI_ERROR (Status); + + Status =3D RdkReadFile (DtbPath, (VOID**) &FdtData, &FdtDataSize); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->InstallConfigurationTable (&gFdtTableGuid,(VOID*)FdtDa= ta); + ASSERT_EFI_ERROR (Status); + + RdkSetVariable(); + + Status =3D GetRdkVariable(L"IMAGE", &ImagePath);=20 + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->LocateProtocol ( + &gEfiDevicePathFromTextProtocolGuid, + NULL, + (VOID**)&DevicePathFromTextProtocol + ); + ASSERT_EFI_ERROR(Status); + + FilePath =3D DevicePathFromTextProtocol->ConvertTextToDevicePath(Imag= ePath); + + Status =3D BootServices->LoadImage ( + TRUE, + ImageHandle, + FilePath, + NULL, + 0, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + UnicodeSPrintAsciiFormat (LoadOption, sizeof(LoadOption), CmdLine); + + Status =3D BootServices->HandleProtocol (Handle, &gEfiLoadedImageProto= colGuid, (VOID **) &ImageInfo); + ASSERT_EFI_ERROR (Status); + ImageInfo->LoadOptionsSize =3D sizeof(LoadOption); + ImageInfo->LoadOptions =3D LoadOption; + + Status =3D BootServices->StartImage (Handle, ExitDataSize, ExitData); + ASSERT_EFI_ERROR (Status); + + return Status; +} --=20 2.15.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel