On 8 January 2018 at 05:45, kalyan-nagabhirava <[email protected]> wrote: > Implemented features related to secure boot and DRI (downloading the image > and storing on flash), > library has utility of file read and write operations for fat and raw flash > partition, it reads file path > and load the file content using configuration file. >
Please limit lines to < 80 columns > Cc: Ard Biesheuvel <[email protected]> > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: kalyan-nagabhirava <[email protected]> > --- > Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.dec | 50 > ++ > Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.inf | 79 > +++ > Platform/Comcast/Library/RdkBootManagerLib/Include/DiskIo.h | 20 > + > Platform/Comcast/Library/RdkBootManagerLib/Include/HttpBoot.h | 7 > + > Platform/Comcast/Library/RdkBootManagerLib/Include/List.h | 52 > ++ > Platform/Comcast/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h | 31 > ++ > Platform/Comcast/Library/RdkBootManagerLib/Include/RdkFile.h | 20 > + > Platform/Comcast/Library/RdkBootManagerLib/Include/SecureBoot.h | 40 > ++ > Platform/Comcast/Library/RdkBootManagerLib/DiskIo.c | 358 > ++++++++++++++ > Platform/Comcast/Library/RdkBootManagerLib/HttpBoot.c | 323 > +++++++++++++ > Platform/Comcast/Library/RdkBootManagerLib/RdkFile.c | 345 > +++++++++++++ > Platform/Comcast/Library/RdkBootManagerLib/SecureBoot.c | 506 > ++++++++++++++++++++ > 12 files changed, 1831 insertions(+) > > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.dec > b/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.dec > new file mode 100644 > index 000000000000..3f3635592325 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.dec > @@ -0,0 +1,50 @@ > +# > +# 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 BSD > License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > + > +[Defines] > + DEC_SPECIFICATION = 0x00010019 > + PACKAGE_NAME = RdkPkg > + PACKAGE_GUID = 2f1f2d5e-d9e1-4aa1-8eb9-fed94682e140 > + PACKAGE_VERSION = 0.1 > + > +################################################################################ > +# > +# Include Section - list of Include Paths that are provided by this package. > +# 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_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION > +# > +################################################################################ > +[Includes.common] > + Include # Root include for the package > + > +[Guids.common] > + gRdkTokenSpaceGuid = { 0x408c1892, 0xf11a, 0x40c7, { 0xaa, > 0x5f, 0x0d, 0x16, 0xc8, 0xb2, 0x52, 0x59 } } > + gRdkGlobalVariableGuid = { 0xc3253c90, 0xa24f, 0x4599, { 0xa6, > 0x64, 0x1f, 0x88, 0x13, 0x77, 0x8f, 0xc9 } } > + > +[PcdsFixedAtBuild.common] > + # Rdk Library > + gRdkTokenSpaceGuid.PcdRdkSystemPartitionName|""|VOID*|0x02000003 > + gRdkTokenSpaceGuid.PcdRdkConfFileName|""|VOID*|0x02000004 > + gRdkTokenSpaceGuid.PcdRdkCmdLineArgs|""|VOID*|0x02000013 > + gRdkTokenSpaceGuid.PcdRdkConfFileDevicePath|L""|VOID*|0x02000014 > + gRdkTokenSpaceGuid.PcdDtbAvailable|FALSE|BOOLEAN|0x00300014 > + > + # GUID of RdkSecureBootLoader > + gRdkTokenSpaceGuid.PcdRdkSecureBootFile|{ 0x0f, 0x93, 0xc7, 0xb2, 0xef, > 0x07, 0x05, 0x43, 0xac, 0x4e, 0x1c, 0xe2, 0x08, 0x5a, 0x70, 0x31 > }|VOID*|0x00000100 > + > + # GUID of RdkDri > + gRdkTokenSpaceGuid.PcdRdkDriFile|{ 0x8a, 0xa1, 0x1b, 0x08, 0x1e, 0xd7, > 0xa7, 0x40, 0x99, 0xa9, 0xcd, 0xb8, 0x64, 0x63, 0x96, 0x6d }|VOID*|0x00001000 > + > + # GUID of RdkDriSecureBootLoader > + gRdkTokenSpaceGuid.PcdRdkDriSecureBootFile|{ 0xd7, 0xd1, 0x52, 0xdd, 0xe2, > 0x0d, 0x52, 0x45, 0x98, 0xe0, 0x8d, 0xbe, 0xe4, 0x58, 0xa5, 0x02 > }|VOID*|0x00100000 > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.inf > b/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.inf > new file mode 100644 > index 000000000000..ecd9f578a580 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.inf > @@ -0,0 +1,79 @@ > +# > +# 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 BSD > License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > + > +################################################################################ > +# > +# Defines Section - statements that will be processed to create a Makefile. > +# > +################################################################################ > + > +[Defines] > + INF_VERSION = 0x00010006 > + BASE_NAME = RdkBootManagerLib > + FILE_GUID = 901f54f2-9d70-9b89-9c0a-d9ca25379059 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = 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 > + Platform/Comcast/Library/RdkBootManagerLib/RdkBootManagerLib.dec Do you really use all these packages? > + > +[Guids] > + gEfiCertX509Guid > + gEfiCertPkcs7Guid > + gEfiCustomModeEnableGuid > + gEfiImageSecurityDatabaseGuid > + gFdtTableGuid > + gRdkGlobalVariableGuid > + > +[Protocols] > + gEfiBlockIoProtocolGuid > + gEfiDevicePathToTextProtocolGuid > + gEfiDevicePathFromTextProtocolGuid > + gEfiLoadedImageProtocolGuid > + gEfiShellProtocolGuid > + gEfiDiskIoProtocolGuid > + gEfiLoadFileProtocolGuid > + > +[Pcd] > + gRdkTokenSpaceGuid.PcdRdkCmdLineArgs > + gRdkTokenSpaceGuid.PcdRdkSystemPartitionName > + gRdkTokenSpaceGuid.PcdRdkConfFileName > + gRdkTokenSpaceGuid.PcdRdkConfFileDevicePath > + gRdkTokenSpaceGuid.PcdDtbAvailable > + > +[LibraryClasses] > + FileHandleLib > + ArmLib > + BaseLib > + DebugLib > + DevicePathLib > + HobLib > + PcdLib > + NetLib > + Please order all of these alphabetically > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/Include/DiskIo.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/DiskIo.h > new file mode 100644 > index 000000000000..003df0c0715c > --- /dev/null > +++ b/Platform/Comcast/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 > + ); > + Please use two spaces as indentation Also, please combine all local includes into a single Platform/Comcast/Library/RdkBootManagerLib.h and get rid of the additional Include/ directory > +#endif /* _RDK_DISK_IO_H_ */ > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/Include/HttpBoot.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/HttpBoot.h > new file mode 100644 > index 000000000000..80f448ee4140 > --- /dev/null > +++ b/Platform/Comcast/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/Platform/Comcast/Library/RdkBootManagerLib/Include/List.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/List.h > new file mode 100644 > index 000000000000..02a44f6699ac > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/Include/List.h Please don't reinvent list accessors, but use the existing ones instead. > @@ -0,0 +1,52 @@ > +#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 > structure > + * @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 = (Ptr); \ > + (Type *)( (char *)__Mptr - OFFSETOF(Type,Member) );}) > + Use BASE_CR() here > + > + > +/** > + * 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 = LIST_ENTRY((Head)->ForwardLink, typeof(*Pos), Member); > \ > + &Pos->Member != (Head); \ > + Pos = LIST_ENTRY(Pos->Member.ForwardLink, 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 = LIST_ENTRY((Head)->ForwardLink, typeof(*Pos), Member), > \ > + N = LIST_ENTRY(Pos->Member.ForwardLink, typeof(*Pos), > Member); \ > + &Pos->Member != (Head); \ > + Pos = N, N = LIST_ENTRY(N->Member.ForwardLink, typeof(*N), > Member)) > + > +#endif /* __LIST_H__ */ > diff --git > a/Platform/Comcast/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h > new file mode 100644 > index 000000000000..5b0b2b1afb79 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/Include/RdkBootManagerLib.h > @@ -0,0 +1,31 @@ > +#ifndef __RDK_BOOT_MANAGER_LIB_H__ > +#define __RDK_BOOT_MANAGER_LIB_H__ > + > +#include <Library/BdsLib.h> > +#include <Library/UefiLib.h> > +#include <Library/BaseLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PrintLib.h> > +#include <Library/ShellLib.h> > +#include <Library/DevicePathLib.h> > +#include <Library/FileHandleLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > +#include <Protocol/DiskIo.h> > +#include <Protocol/BlockIo.h> > +#include <Protocol/LoadFile.h> > +#include <Protocol/SimpleTextOut.h> > +#include <Protocol/DevicePathFromText.h> > +#include <Protocol/DevicePathToText.h> > +#include <Protocol/AndroidFastbootPlatform.h> > +#include <Guid/ImageAuthentication.h> > +#include <Guid/AuthenticatedVariableFormat.h> > +#include <HttpBootDxe/HttpBootDxe.h> > +#include <Include/Guid/AuthenticatedVariableFormat.h> > +#include "SecureBoot.h" > +#include "HttpBoot.h" > +#include "RdkFile.h" > +#include "DiskIo.h" > + > +#endif /* __RDK_BOOT_MANAGER_LIB_H__ */ > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/Include/RdkFile.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/RdkFile.h > new file mode 100644 > index 000000000000..c5b1d43d5f76 > --- /dev/null > +++ b/Platform/Comcast/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 6 > + > +typedef struct { > + CHAR16 *Name; > + LIST_ENTRY List; > +} DIR_NODE; > + > +extern EFI_STATUS > +GetRdkVariable ( > + IN CONST CHAR16 *Name, > + OUT CONST CHAR16 **Value > + ); > + > +#endif /* __RDK_FILE_H__ */ > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/Include/SecureBoot.h > b/Platform/Comcast/Library/RdkBootManagerLib/Include/SecureBoot.h > new file mode 100644 > index 000000000000..3cfd687670b5 > --- /dev/null > +++ b/Platform/Comcast/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=1, > + KEK_KEY, > + DB_KEY, > + DBX_KEY > +} eKey; > + > +#endif /* _RDK_SECURE_BOOT_H_ */ > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/DiskIo.c > b/Platform/Comcast/Library/RdkBootManagerLib/DiskIo.c > new file mode 100644 > index 000000000000..7d1952dbcca1 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/DiskIo.c > @@ -0,0 +1,358 @@ > +#include <RdkBootManagerLib.h> > + > +/* 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) <= L'z' && (Char) >= L'a') || \ > + ((Char) <= L'Z' && (Char) >= 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; > + > +/* > + * Helper to free the partition list > + */ > +STATIC > +VOID > +FreePartitionList ( > + VOID > +) > +{ > + DISKIO_PARTITION_LIST *Entry; > + DISKIO_PARTITION_LIST *NextEntry; > + > + Entry = (DISKIO_PARTITION_LIST *) GetFirstNode (&mPartitionListHead); > + while (!IsNull (&mPartitionListHead, &Entry->Link)) { > + NextEntry = (DISKIO_PARTITION_LIST *) GetNextNode (&mPartitionListHead, > &Entry->Link); > + > + RemoveEntryList (&Entry->Link); > + FreePool (Entry); > + > + Entry = NextEntry; > + } > +} > + > +/* > + * lists the available Block Io and adds handle of given dev path > + */ > +STATIC > +EFI_STATUS > +ListBlockIos ( > + IN CHAR16 *PartitionName > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE *AllHandles; > + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + UINTN LoopIndex; > + UINTN NumHandles; > + UINT16 *DeviceFullPath; > + DISKIO_PARTITION_LIST *Entry; > + > + InitializeListHead (&mPartitionListHead); > + > + Status = gBS->LocateProtocol ( > + &gEfiDevicePathToTextProtocolGuid, > + NULL, > + (VOID **) &DevPathToText > + ); > + ASSERT_EFI_ERROR (Status); > + > + // Get every Block IO protocol instance installed in the system > + Status = gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiBlockIoProtocolGuid, > + NULL, > + &NumHandles, > + &AllHandles > + ); > + ASSERT_EFI_ERROR (Status); > + DEBUG((DEBUG_INFO, "Block IO: %d handles \n", NumHandles)); > + > + // Get HTTP driver handle from AllHandles > + for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) { > + // Get the device path for the handle > + Status = gBS->OpenProtocol ( > + AllHandles[LoopIndex], > + &gEfiDevicePathProtocolGuid, > + (VOID **) &DevicePath, > + gImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + > + DeviceFullPath = DevPathToText->ConvertDevicePathToText ( > + DevicePath, > + FALSE, > + TRUE > + ); > + > + DEBUG((DEBUG_INFO,"Handle[%d] is %p, fullpath %s\n", LoopIndex, > AllHandles[LoopIndex], DeviceFullPath)); > + > + if ( 0 == StrCmp ( PartitionName, DeviceFullPath ) ) { I will mention it once here but it applies to all patches: please don't put spaces after ( or before ) please do put spaces before ( please don't use 'backward' (yoda style) comparisons So the line above becomes if (StrCmp (PartitionName, DeviceFullPath) == 0) { > + DEBUG((DEBUG_INFO, "rootfs partition path matched\n")); > + // > + // Add the partition handle to the list > + // > + // Create entry > + Entry = AllocatePool (sizeof (DISKIO_PARTITION_LIST)); > + if (Entry == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + goto Exit; > + } > + > + // Copy handle and partition name > + Entry->PartitionHandle = AllHandles[LoopIndex]; > + StrnCpy ( > + Entry->PartitionName, > + PartitionName, > + PARTITION_NAME_MAX_LENGTH Use two spaces indentation for continuations (above as well) > + ); > + InsertTailList (&mPartitionListHead, &Entry->Link); > + break; > + } > + } > + FreePool(AllHandles); > + ASSERT ( LoopIndex < NumHandles ); > +Exit: > + 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; > + SPARSE_HEADER *SparseHeader; > + UINT16 UnicodePartitionName[100]; > + > + AsciiStrToUnicodeStr ( PartitionName, UnicodePartitionName); > + DEBUG((DEBUG_INFO, "Unicode partition name %s\n", UnicodePartitionName)); > + > + Status = ListBlockIos (UnicodePartitionName); > + ASSERT_EFI_ERROR ( Status ); > + > + Entry = (DISKIO_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); > + ASSERT ( NULL != Entry ); no spaces inside ( ) > + > + Status = 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 = EFI_NOT_FOUND; > + goto exit; > + } > + > + SparseHeader=(SPARSE_HEADER *)Image; Spaces before and after = > + > + if (SparseHeader->Magic == SPARSE_HEADER_MAGIC) { > + DEBUG ((DEBUG_INFO, "Sparse Magic: 0x%x Major: %d Minor: %d fhs: %d chs: > %d bs: %d tbs: %d tcs: %d checksum: %d \n", > + SparseHeader->Magic, SparseHeader->MajorVersion, > SparseHeader->MinorVersion, SparseHeader->FileHeaderSize, Check line length please > + SparseHeader->ChunkHeaderSize, SparseHeader->BlockSize, > SparseHeader->TotalBlocks, > + SparseHeader->TotalChunks, SparseHeader->ImageChecksum)); > + > + if (SparseHeader->MajorVersion != 1) { > + DEBUG ((DEBUG_ERROR, "Sparse image version %d.%d not supported.\n", > + SparseHeader->MajorVersion, SparseHeader->MinorVersion)); > + Status = EFI_INVALID_PARAMETER; > + goto exit; > + } > + > + Size = SparseHeader->BlockSize * SparseHeader->TotalBlocks; > + } > + > + // Check image will fit on device > + PartitionSize = (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", > PartitionSize, Size)); > + > + Status = EFI_VOLUME_FULL; > + goto exit; > + } > + > + Status = gBS->OpenProtocol ( > + Entry->PartitionHandle, > + &gEfiDiskIoProtocolGuid, > + (VOID **) DiskIo, > + gImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + > +exit: Please use consistent label naming style. I have seen all lowercase, all uppercase and mixed case in the same patch > + FreePartitionList(); > + 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 = OpenPartition (PartitionName, Image, Size, &BlockIo, &DiskIo); > + if (EFI_ERROR (Status)) { > + goto exit; > + } > + > + MediaId = BlockIo->Media->MediaId; > + > + Status = DiskIo->ReadDisk (DiskIo, MediaId, 0, Size, Image); > + if (EFI_ERROR (Status)) { > + goto exit; > + } > + > + BlockIo->FlushBlocks(BlockIo); Space before ( > + > +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 = OpenPartition (PartitionName, Image, Size, &BlockIo, &DiskIo); > + if (EFI_ERROR (Status)) { > + goto exit; > + } > + > + Offset = 0; > + MediaId = BlockIo->Media->MediaId; > + SparseHeader = (SPARSE_HEADER *)Image; > + > + if (SparseHeader->Magic == SPARSE_HEADER_MAGIC) { > + CHAR16 OutputString[64]; > + UINTN ChunkPrintDensity = > + SparseHeader->TotalChunks > 1600 ? SparseHeader->TotalChunks / 200 : > 32; > + > + Image += SparseHeader->FileHeaderSize; > + for (Chunk = 0; Chunk < SparseHeader->TotalChunks; Chunk++) { > + UINTN WriteSize; > + ChunkHeader = (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 == 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 > Offset %d\n", > + (Chunk+1), ChunkHeader->ChunkType, ChunkHeader->ChunkSize, > + ChunkHeader->TotalSize, Offset)); > + Image += sizeof(CHUNK_HEADER); > + WriteSize=(SparseHeader->BlockSize) * ChunkHeader->ChunkSize; > + switch (ChunkHeader->ChunkType) { > + case CHUNK_TYPE_RAW: > + DEBUG ((DEBUG_INFO, "Writing %d at Offset %d\n", WriteSize, > Offset)); > + Status = DiskIo->WriteDisk (DiskIo, MediaId, Offset, WriteSize, > Image); > + if (EFI_ERROR (Status)) { > + goto exit; > + } > + Image+=WriteSize; > + break; > + case CHUNK_TYPE_DONT_CARE: > + break; > + case CHUNK_TYPE_CRC32: > + break; > + default: > + DEBUG ((DEBUG_ERROR, "Unknown Chunk Type: 0x%x", > ChunkHeader->ChunkType)); > + Status = EFI_PROTOCOL_ERROR; > + goto exit; > + } > + Offset += WriteSize; > + } > + > + UnicodeSPrint(OutputString, sizeof(OutputString), > + L"\r%5d / %5d chunks written (100%%)\r\n", > + SparseHeader->TotalChunks, SparseHeader->TotalChunks); > + mTextOut->OutputString(mTextOut, OutputString); > + > + } else { > + > + Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image); > + if (EFI_ERROR (Status)) { > + goto exit; > + } > + } > + > + BlockIo->FlushBlocks(BlockIo); > + > +exit: > + return Status; > +} > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/HttpBoot.c > b/Platform/Comcast/Library/RdkBootManagerLib/HttpBoot.c > new file mode 100644 > index 000000000000..f3298c149593 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/HttpBoot.c > @@ -0,0 +1,323 @@ > +/* > +# 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 BSD > License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > +*/ > +#include <RdkBootManagerLib.h> > + > +STATIC EFI_LOAD_FILE_PROTOCOL *LoadFile = NULL; > +STATIC HTTP_BOOT_PRIVATE_DATA *Private = NULL; > + > +STATIC > +VOID > +HttpPrivateFromLoadFile ( > + IN EFI_LOAD_FILE_PROTOCOL *LoadFile, > + OUT HTTP_BOOT_PRIVATE_DATA **Private > + ) > +{ > + HTTP_BOOT_VIRTUAL_NIC *Ip4Nic = NULL; > + > +#if defined (MDE_CPU_AARCH64) > + INT64 Offset = (INT64)&Ip4Nic->LoadFile; > +#else //if defined (MDE_CPU_ARM) > + INT32 Offset = (INT32)&Ip4Nic->LoadFile; > +#endif Just use UINTN here > + Ip4Nic = (VOID *)((char *)LoadFile - Offset); Use CHAR8 not char > + ASSERT (Ip4Nic->Signature == HTTP_BOOT_VIRTUAL_NIC_SIGNATURE); > + *Private = 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 = gBS->LocateProtocol ( > + &gEfiDevicePathToTextProtocolGuid, > + NULL, > + (VOID **) &DevPathToText > + ); Two spaces indentation > + ASSERT_EFI_ERROR (Status); > + > + // Get every LoadFile protocol instance installed in the system > + Status = gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiLoadFileProtocolGuid, > + NULL, > + &NumHandles, > + &AllHandles > + ); > + ASSERT_EFI_ERROR (Status); > + > + // Get HTTP driver handle from AllHandles > + for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) { > + > + Handle = AllHandles[LoopIndex]; > + > + // Get the device path for the handle > + Status = gBS->OpenProtocol ( > + Handle, > + &gEfiDevicePathProtocolGuid, > + (VOID **) &DevicePath, > + gImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + ASSERT_EFI_ERROR (Status); > + > + DeviceFullPath = DevPathToText->ConvertDevicePathToText ( > + DevicePath, > + FALSE, > + TRUE > + ); > + > + ASSERT(DeviceFullPath != NULL); > + > + if(StrStr(DeviceFullPath, L"IPv4") != NULL) { > + DEBUG((DEBUG_INFO, "IPv4 protocol found\n")); > + Status = gBS->OpenProtocol ( > + Handle, > + &gEfiLoadFileProtocolGuid, > + (VOID **) LoadFile, > + gImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + ASSERT_EFI_ERROR (Status); > + > + FreePool (AllHandles); > + break; > + } > + } > + > + ASSERT ( LoopIndex < NumHandles ); spaces inside ( ) > +} > + > +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 = NULL; > + TmpDevicePath = NULL; > + Status = EFI_SUCCESS; > + > + // Convert the scheme to all lower case. > + for (Index = 0; Index < StrLen (Uri); Index++) { > + if (Uri[Index] == L':') { > + break; > + } > + if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') { > + Uri[Index] -= (CHAR16)(L'A' - L'a'); > + } > + } > + > + // Only accept empty URI, or http and https URI. > + if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp > (Uri, L"https://", 8) != 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 = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH)); > + if (Node == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH; > + Node->Ipv4.Header.SubType = MSG_IPv4_DP; > + SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH)); > + TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, > (EFI_DEVICE_PATH_PROTOCOL*) Node); > + FreePool (Node); > + if (TmpDevicePath == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // Update the URI node with the input boot file URI. > + UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri)); > + Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri); > + Node = AllocatePool (Length); > + if (Node == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + FreePool (TmpDevicePath); > + goto ON_EXIT; > + } > + Node->DevPath.Type = MESSAGING_DEVICE_PATH; > + Node->DevPath.SubType = MSG_URI_DP; > + SetDevicePathNodeLength (Node, Length); > + CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, > AsciiStrSize (AsciiUri)); > + *NewDevicePath = AppendDevicePathNode (TmpDevicePath, > (EFI_DEVICE_PATH_PROTOCOL*) Node); > + FreePool (Node); > + FreePool (TmpDevicePath); > + if (*NewDevicePath == NULL) { > + Status = 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 = NULL; > + NewDevicePath = NULL; > + *FileSize = 0; > + > + // Get the LoadFile Handle and > + // Private structure of HTTP driver > + if (LoadFile == NULL) { > + HttpGetLoadFileHandle (&LoadFile); > + HttpPrivateFromLoadFile (LoadFile, &Private); > + } > + > + // Update URI path > + Status = HttpUpdatePath (Uri, &NewDevicePath); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + // Get the HTTP image from server > + Status = LoadFile->LoadFile (LoadFile, NewDevicePath, TRUE, FileSize, > *FileBuffer); > + if((Status != EFI_WARN_FILE_SYSTEM) && (Status != EFI_BUFFER_TOO_SMALL)) { > + goto ON_EXIT; > + } > + > + *FileBuffer = AllocatePool (*FileSize); > + if (*FileBuffer == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + Status = LoadFile->LoadFile (LoadFile, NewDevicePath, TRUE, FileSize, > *FileBuffer); > + if (EFI_ERROR (Status)) { > + FreePool (FileBuffer); > + goto ON_EXIT; > + } > + > +ON_EXIT: > + > + if (NewDevicePath != 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 = GetRdkVariable(L"URL", &ServerUrlPath); > + ASSERT_EFI_ERROR (Status); > + > + // Get the Server name stored in file Server.url > + Status = RdkReadFile(ServerUrlPath, (VOID **)&FileBuffer, &FileSize); > + ASSERT_EFI_ERROR (Status); > + > + Uri = AllocateZeroPool (sizeof(*Uri) * (FileSize+1)); > + if (Uri == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + ASSERT_EFI_ERROR (Status); > + } > + > + for(LoopIndex=0; LoopIndex<FileSize; LoopIndex++) { Spaces around = and < > + Uri[LoopIndex] = FileBuffer[LoopIndex]; > + } > + > + if(FileBuffer[FileSize-1] == '\n') { Space after if > + Uri[FileSize-1] = '\0'; > + } > + > + FreePool (FileBuffer); > + FileBuffer=NULL; > + > + // Disable watchdog > + Status = gBS->SetWatchdogTimer (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 = HttpGetImage (Uri, &FileBuffer, &FileSize); > + ASSERT_EFI_ERROR (Status); > + > + // Write the received image to flash > + FilePtr = FileBuffer; > + Size = Str2Int(FilePtr); > + FilePtr += FILE_HDR_SIZE; > + Status = PartitionWrite((CHAR8 *) FixedPcdGetPtr > (PcdRdkSystemPartitionName), FilePtr, Size); > + ASSERT_EFI_ERROR (Status); > + > + FilePtr += Size; > + Size = Str2Int(FilePtr); > + FilePtr += FILE_HDR_SIZE; > + Status = GetRdkVariable(L"IMAGE", &ImagePath); > + ASSERT_EFI_ERROR (Status); > + Status = RdkWriteFile(ImagePath, &FilePtr, &Size); > + ASSERT_EFI_ERROR (Status); > + > + if ( FixedPcdGetBool ( PcdDtbAvailable ) ) { No spaces inside ( ) > + FilePtr += Size; > + Size = Str2Int(FilePtr); > + FilePtr += FILE_HDR_SIZE; > + Status = GetRdkVariable(L"DTB", &DtbPath); > + ASSERT_EFI_ERROR (Status); > + Status = RdkWriteFile(DtbPath, &FilePtr, &Size); > + ASSERT_EFI_ERROR (Status); Indentation of the above > + } > + > + FreePool (FileBuffer); > + FreePool (Uri); > + > + return Status; > +} > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/RdkFile.c > b/Platform/Comcast/Library/RdkBootManagerLib/RdkFile.c > new file mode 100644 > index 000000000000..e590468b195d > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/RdkFile.c > @@ -0,0 +1,345 @@ > +#include <RdkBootManagerLib.h> > + > +STATIC UINT8 VarablesInitialzed = 0; > +STATIC CHAR16 *VarResult[MAX_VAR][2]; > + > +STATIC > +VOID > +SaveString ( > + OUT CHAR16 **Dest, > + IN CHAR16 *String1, > + IN CHAR16 *String2 > + ) > +{ > + *Dest = ALLOCATE_STRING_MEM(StrLen(String1) + StrLen(String2)); > + ASSERT( NULL != Dest ); > + StrCat(*Dest, String1); > + StrCat(*Dest, String2); > +} > + > +STATIC > +EFI_STATUS > +LsFiles ( > + IN CONST CHAR16 *DirPath, > + IN CONST CHAR16 *TargetFile, > + OUT CHAR16 **Result, > + IN LIST_ENTRY *Head > + ) > +{ > + EFI_STATUS Status; > + EFI_FILE_INFO *FileInfo; > + EFI_FILE_PROTOCOL *FileHandle; > + BOOLEAN NoFile; > + CHAR16 *TempPath; > + DIR_NODE *Node; > + > + NoFile = FALSE; > + TempPath = ALLOCATE_STRING_MEM(StrLen(DirPath) + 1); > + StrCat(TempPath, DirPath); > + StrCat(TempPath, L"/"); > + > + Status = GetFileHandler(&FileHandle, DirPath, EFI_FILE_MODE_READ); > + ASSERT_EFI_ERROR(Status); > + > + for ( Status = FileHandleFindFirstFile(FileHandle, &FileInfo) > + ; !EFI_ERROR(Status) && !NoFile > + ; Status = FileHandleFindNextFile(FileHandle, FileInfo, &NoFile) > + ) { Please put ; on the line before > + if((FileInfo->Attribute & EFI_FILE_DIRECTORY) && > + (StrCmp(FileInfo->FileName, L".") != 0) && > + (StrCmp(FileInfo->FileName, L"..") != 0)) { > + Node = AllocateZeroPool(sizeof (DIR_NODE)); > + SaveString(&Node->Name, TempPath, FileInfo->FileName); > + InsertHeadList(Head,&Node->List); > + } > + else if(StrCmp(FileInfo->FileName, TargetFile) == 0) { Please put else on the previous line > + SaveString(Result, TempPath, FileInfo->FileName); > + Status = EFI_SUCCESS; > + goto ON_EXIT; > + } > + } > + > + Status = EFI_NOT_FOUND; > + > +ON_EXIT: > + FreePool(TempPath); > + return Status; > +} > + > +STATIC > +VOID > +DelDirList ( > + IN LIST_ENTRY *Head > + ) > +{ > + DIR_NODE *Node; > + DIR_NODE *Temp; > + > + LIST_FOR_EACH_ENTRY_SAFE (Node, Temp, Head, List) { > + RemoveEntryList(&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_ENTRY DirList[2]; > + > + *Result = NULL; > + EFI_STATUS Status = EFI_NOT_FOUND; > + > + InitializeListHead(&DirList[0]); > + InitializeListHead(&DirList[1]); > + > + for (Current = Next = 0, Status=LsFiles(DevPath, TargetFile, Result, > &DirList[Current]); > + !IsListEmpty(&DirList[Current]); > + Current = Next) { Indentation > + Next = Current ^ 1; > + DelDirList(&DirList[Next]); > + > + LIST_FOR_EACH_ENTRY(Temp, &DirList[Current], List) { > + Status = LsFiles(Temp->Name, TargetFile, Result, &DirList[Next]); > + if(!EFI_ERROR(Status)) { Space after if + indentation > + DelDirList(&DirList[Current]); > + break; > + } > + } > + } > + > + DelDirList(&DirList[Next]); > + return Status; > +} > + > +STATIC > +UINTN > +StrSpn ( > + IN CHAR8 *String, > + IN CHAR8 *CharSet > + ) > +{ > + UINTN Count; > + > + for(Count=0; String[Count] && !(String[Count] == CharSet[0]); Count++); > + return Count; > +} > + > +STATIC > +CHAR16 * > +Ascii2Uefi ( > + IN CHAR8 *String > + ) > +{ > + CHAR16 *Result; > + UINTN Size; > + > + Size = AsciiStrLen(String); > + Result = ALLOCATE_STRING_MEM(Size); > + > + while(Size--) { > + Result[Size] = String[Size]; > + } > + > + return Result; > +} Please use existing routines for this > + > +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] = "="; > + VarDelimiter[1] = "\""; > + Status = EFI_SUCCESS; > + > + //Initialize to NULL Space after // > + for(OuterLoopIndex=0; OuterLoopIndex < MAX_VAR; OuterLoopIndex++) { Space after for > + VarResult[OuterLoopIndex][0] = VarResult[OuterLoopIndex][1] = NULL; > + } > + > + for(OuterLoopIndex=0, Next=0; OuterLoopIndex < MAX_VAR && Next < FileSize; > OuterLoopIndex++) { > + for(InnerLoopIndex=0; InnerLoopIndex < 2; InnerLoopIndex++) { > + Current = Next; > + Next += StrSpn(&FileData[Next], VarDelimiter[InnerLoopIndex]); > + FileData[Next] = '\0'; > + VarResult[OuterLoopIndex][InnerLoopIndex] = > Ascii2Uefi(&FileData[Current]); > + //skip new line > + Next += 2; > + } > + } > + OK, I am going to stop commenting on coding style issues, but you *really* need to go through these patches and fix the coding style everywhere. Please look at BaseTools/Scripts/PatchCheck.py > + return Status; > +} > + > +STATIC > +EFI_STATUS > +InitRdkVariables ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN RdkSize; > + UINT8 *RdkData; > + CHAR16 *Result; > + CONST CHAR16 *DevPath; > + CONST CHAR16 *RdkFileName; > + > + DevPath = (CONST CHAR16 *)FixedPcdGetPtr (PcdRdkConfFileDevicePath); > + RdkFileName = (CONST CHAR16 *)FixedPcdGetPtr (PcdRdkConfFileName); > + > + Status = FindFileInDir(DevPath, RdkFileName, &Result); > + if(EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "Failed to find file %s in %s\n", RdkFileName, > DevPath)); > + return Status; > + } > + > + Status = RdkReadFile ((CONST CHAR16 *)Result, (VOID**) &RdkData, &RdkSize); > + if(EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "Failed to read file %s\n", RdkFileName)); > + return Status; > + } > + > + Status = InitVarList ((CHAR8 *)RdkData, RdkSize); > + return Status; > +} > + > +STATIC > +EFI_STATUS > +GetVarValue ( > + IN CONST CHAR16 *Name, > + OUT CONST CHAR16 **Value > + ) > +{ > + UINTN Count; > + EFI_STATUS Status; > + > + if(!VarablesInitialzed) { > + Status = InitRdkVariables(); > + if(EFI_ERROR(Status)) { > + return Status; > + } > + > + VarablesInitialzed = 1; > + } > + > + //Initialize to NULL > + *Value = NULL; > + > + for(Count=0; Count<MAX_VAR; Count++) { > + if(NULL != VarResult[Count][0] && StrCmp(Name, VarResult[Count][0]) == > 0) { > + *Value = VarResult[Count][1]; > + return EFI_SUCCESS; > + } > + } > + > + return EFI_NOT_FOUND; > +} > + > +EFI_STATUS > +GetRdkVariable ( > + IN CONST CHAR16 *Name, > + OUT CONST CHAR16 **Value > + ) > +{ > + EFI_STATUS Status; > + > + Status = GetVarValue(Name, Value); > + return Status; > +} > + > +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 = GetFileHandler(&FileHandle, Path, EFI_FILE_MODE_READ); > + ASSERT_EFI_ERROR(Status); > + > + Buffer = NULL; > + > + // Get the file size > + Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + Status = FileHandle->SetPosition (FileHandle, 0); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + BufferSize = (UINTN) SourceFileSize; > + Buffer = AllocateZeroPool(BufferSize); > + if (Buffer == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + if (FileSize != NULL) *FileSize = BufferSize; > + > + Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); > + if (EFI_ERROR (Status) || BufferSize != SourceFileSize) { > + FreePool (Buffer); > + Buffer = NULL; > + Status = EFI_BAD_BUFFER_SIZE; > + goto ON_EXIT; > + } > + > +ON_EXIT: > + > + *BufferPtr = 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 == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = GetFileHandler(&FileHandle, Path, > EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE); > + ASSERT_EFI_ERROR(Status); > + > + Status = FileHandle->Write (FileHandle, FileSize, *BufferPtr); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} Could you explain the purpose of this file? Did you invent your own file based variable store? > diff --git a/Platform/Comcast/Library/RdkBootManagerLib/SecureBoot.c > b/Platform/Comcast/Library/RdkBootManagerLib/SecureBoot.c > new file mode 100644 > index 000000000000..3d593361e6e8 > --- /dev/null > +++ b/Platform/Comcast/Library/RdkBootManagerLib/SecureBoot.c > @@ -0,0 +1,506 @@ > +#include <RdkBootManagerLib.h> > + > +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 == NULL )) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = gBS->LocateDevicePath ( > + &gEfiSimpleFileSystemProtocolGuid, > + FilePath, > + &DeviceHandle > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = gBS->OpenProtocol( > + DeviceHandle, > + &gEfiSimpleFileSystemProtocolGuid, > + (VOID**)&EfiSimpleFileSystemProtocol, > + gImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = > EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, > &Handle1); > + if (EFI_ERROR (Status)) { > + FileHandle = 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) != MEDIA_DEVICE_PATH || > + DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP > + ) { > + FileHandle = NULL; > + return (EFI_INVALID_PARAMETER); > + } > + // > + // Open this file path node > + // > + Handle2 = Handle1; > + Handle1 = NULL; > + > + // > + // Try to test opening an existing file > + // > + Status = 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 != (OpenMode > &~EFI_FILE_MODE_CREATE))) { > + Status = 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 = NextDevicePathNode (*FilePath); > + } > + > + // > + // This is a weak spot since if the undefined SHELL_FILE_HANDLE format > changes this must change also! > + // > + *FileHandle = (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 = EFI_SUCCESS; > + KeyFileDevicePath = NULL; > + > + Status = gBS->LocateProtocol ( > + &gEfiDevicePathFromTextProtocolGuid, > + NULL, > + (VOID**)&DevicePathFromTextProtocol > + ); > + ASSERT_EFI_ERROR(Status); > + > + KeyFileDevicePath = > DevicePathFromTextProtocol->ConvertTextToDevicePath(Path); > + if(KeyFileDevicePath != NULL) > + { > + Status = > OpenFileByDevicePath(&KeyFileDevicePath,FileHandle,OpenMode,0); > + if(Status != EFI_SUCCESS) > + { > + DEBUG ((DEBUG_ERROR, "Getting FileHandle of %s Failed\n",Path)); > + } > + } > + return Status; > +} > + > +UINTN > +Str2Int ( > + VOID * Str > +) > +{ > + UINTN i, Size; > + UINT8 *Ptr = Str; > + > + for(i=0, Size=0; i<FILE_HDR_SIZE; i++) > + { > + Size = (Ptr[i] - '0') + (Size * 10); > + } > + > + return Size; > +} > + Please use existing routines for this > +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 == NULL || DataSize == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // In Setup mode or Custom mode, the variable does not need to be signed > but the > + // parameters to the SetVariable() call still need to be prepared as > authenticated > + // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor > without certificate > + // data in it. > + // > + > + Payload = *Data; > + PayloadSize = *DataSize; > + > + DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) > + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); Line length > + NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); > + if (NewData == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + if ((Payload != NULL) && (PayloadSize != 0)) { > + CopyMem (NewData + DescriptorSize, Payload, PayloadSize); > + } > + > + DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); > + > + ZeroMem (&Time, sizeof (EFI_TIME)); > + Status = gRT->GetTime (&Time, NULL); > + if (EFI_ERROR (Status)) { > + FreePool(NewData); > + return Status; > + } > + Time.Pad1 = 0; > + Time.Nanosecond = 0; > + Time.TimeZone = 0; > + Time.Daylight = 0; > + Time.Pad2 = 0; > + CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME)); > + > + DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF > (WIN_CERTIFICATE_UEFI_GUID, CertData); > + DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; > + DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; > + CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid); > + > + if (Payload != NULL) { > + FreePool(Payload); > + } > + > + *DataSize = DescriptorSize + PayloadSize; > + *Data = 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=EFI_SUCCESS ; Please don't use initializers but only assignments. > + Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS > + | EFI_VARIABLE_BOOTSERVICE_ACCESS | > EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; > + if(KeyType == PK_KEY) > + { > + DEBUG ((DEBUG_INFO, "Setting PK Key\n")); > + Status = gRT->SetVariable ( > + EFI_PLATFORM_KEY_NAME, > + &gEfiGlobalVariableGuid, > + Attr, > + DataSize, > + PkCert > + ); > + } > + else if( KeyType == KEK_KEY) > + { > + DEBUG ((DEBUG_INFO, "Setting KEK Key\n")); > + Status = gRT->SetVariable ( > + EFI_KEY_EXCHANGE_KEY_NAME, > + &gEfiGlobalVariableGuid, > + Attr, > + DataSize, > + PkCert > + ); > + > + Status = 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 = NULL; > + > + if( (*Cert) == NULL) > + { > + (*Cert) = (EFI_SIGNATURE_LIST*) AllocateZeroPool ( > sizeof(EFI_SIGNATURE_LIST) > + + sizeof(EFI_SIGNATURE_DATA) - 1 > + + DataSize ); > + > + ASSERT ((*Cert) != NULL); > + } > + (*Cert)->SignatureListSize = (UINT32) (sizeof(EFI_SIGNATURE_LIST) > + + sizeof(EFI_SIGNATURE_DATA) - 1 > + + DataSize); > + (*Cert)->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 > + DataSize); > + (*Cert)->SignatureHeaderSize = 0; > + CopyGuid (&(*Cert)->SignatureType, &gEfiCertX509Guid); > + > + > + CertData = (EFI_SIGNATURE_DATA*) ((UINTN)(*Cert) + > sizeof(EFI_SIGNATURE_LIST) + (*Cert)->SignatureHeaderSize); > + ASSERT (CertData != 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 = NULL; > + > + Status = SetBootMode(CUSTOM_SECURE_BOOT_MODE); > + ASSERT_EFI_ERROR (Status); > + > + PopulateCert(&Cert, KeySize, KeyData); > + > + KeySize = Cert->SignatureListSize; > + > + Status = CreateTimeBasedPayload (&KeySize, (UINT8**) &Cert); > + ASSERT_EFI_ERROR (Status); > + > + Status = SetVariable(Cert,KeySize,KeyType); > + return Status; > +} > + > +STATIC > +VOID > +RdkSetVariable ( > + VOID > +) > +{ > + CONST CHAR16 *KeyPath = NULL; > + EFI_STATUS Status; > + > + Status = GetRdkVariable(L"ROOTCERT", &KeyPath); > + > + //set only if the Kek Crt file mentioned in the configuration file > + if ( NULL != KeyPath ) { > + UINT8 *KekCrtData = NULL; > + UINTN KekCrtSize; > + > + Status = RdkReadFile ( > + KeyPath, > + (VOID **)&KekCrtData, > + &KekCrtSize > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status = gRT->SetVariable ( > + L"RdkRootCertificate", > + &gRdkGlobalVariableGuid, > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > EFI_VARIABLE_RUNTIME_ACCESS, > + KekCrtSize, > + KekCrtData > + ); > + ASSERT_EFI_ERROR(Status); > + > + if ( KekCrtData ) FreePool(KekCrtData); > + } > + > + Status = GetRdkVariable(L"KEKCERT", &KeyPath); > + ASSERT_EFI_ERROR (Status); > + > + UINT8 *KekKey = NULL; > + UINTN KekKeySize = 0; Don't declare variables in the middle of the code > + Status = RdkReadFile ( > + KeyPath, > + (VOID **)&KekKey, > + &KekKeySize > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status = GetRdkVariable(L"PKCERT", &KeyPath); > + ASSERT_EFI_ERROR (Status); > + > + UINT8 *PkKey = NULL; > + UINTN PkKeySize = 0; > + Status = RdkReadFile ( > + KeyPath, > + (VOID **)&PkKey, > + &PkKeySize > + ); > + ASSERT_EFI_ERROR (Status); > + > + INT8* SetupMode = NULL; > + eKey KeyType; > + KeyType = PK_KEY; > + Status = RegisterCert(PkKey,PkKeySize,KeyType); > + GetEfiGlobalVariable2 (L"SetupMode", (VOID**)&SetupMode, NULL); > + > + if (*SetupMode == 0) > + { > + DEBUG ((DEBUG_INFO, "PK Key Got Registered. Now System in User > Mode\n")); > + KeyType = KEK_KEY; > + Status = RegisterCert(KekKey,KekKeySize,KeyType); > + } > + else if(*SetupMode == 1) > + { > + DEBUG ((DEBUG_INFO, "System in Standard System Mode ::: Secure Boot > Not enabled\n")); > + ASSERT_EFI_ERROR(Status); > + } > + > + if ( PkKey ) FreePool(PkKey); > + if ( KekKey ) FreePool(KekKey); > +} > + > +EFI_STATUS > +RdkSecureBoot ( > + EFI_HANDLE ImageHandle, > + EFI_BOOT_SERVICES *BootServices > +) > +{ > + UINTN ExitDataSize; > + CHAR16 *ExitData; > + CHAR16 LoadOption[128]; > + CONST CHAR8 *CmdLine; > + CHAR16 *ImagePath; > + EFI_STATUS Status; > + EFI_HANDLE Handle; > + EFI_DEVICE_PATH_PROTOCOL *FilePath; > + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; > + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DevicePathFromTextProtocol; > + > + FilePath = NULL; > + ExitData = NULL; > + CmdLine = (CONST CHAR8 *)FixedPcdGetPtr (PcdRdkCmdLineArgs); > + > + if ( FixedPcdGetBool ( PcdDtbAvailable ) ) { > + UINT8 *FdtData = NULL; > + CONST CHAR16 *DtbPath = NULL; Declare at function scope only, and don't use initializers but assignments > + > + Status = GetRdkVariable(L"DTB", &DtbPath); > + ASSERT_EFI_ERROR (Status); > + > + Status = RdkReadFile (DtbPath, (VOID**) &FdtData, NULL); > + ASSERT_EFI_ERROR (Status); > + > + Status = gBS->InstallConfigurationTable > (&gFdtTableGuid,(VOID*)FdtData); > + ASSERT_EFI_ERROR (Status); > + } > + > + RdkSetVariable(); > + > + Status = GetRdkVariable(L"IMAGE", (CONST CHAR16**)&ImagePath); > + ASSERT_EFI_ERROR (Status); > + > + Status = gBS->LocateProtocol ( > + &gEfiDevicePathFromTextProtocolGuid, > + NULL, > + (VOID**)&DevicePathFromTextProtocol > + ); > + ASSERT_EFI_ERROR(Status); > + > + FilePath = > DevicePathFromTextProtocol->ConvertTextToDevicePath(ImagePath); > + ASSERT( NULL != FilePath); > + > + Status = BootServices->LoadImage ( > + TRUE, > + ImageHandle, > + FilePath, > + NULL, > + 0, > + &Handle > + ); > + ASSERT_EFI_ERROR (Status); > + > + UnicodeSPrintAsciiFormat (LoadOption, sizeof(LoadOption), CmdLine); > + > + Status = BootServices->HandleProtocol (Handle, > &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); > + ASSERT_EFI_ERROR (Status); > + ImageInfo->LoadOptionsSize = sizeof(LoadOption); > + ImageInfo->LoadOptions = LoadOption; > + > + Status = BootServices->StartImage (Handle, &ExitDataSize, &ExitData); > + ASSERT_EFI_ERROR (Status); > + > + return Status; The coding style in this last file is absolutely dreadful. Other than that, it looks reasonable, although you should not implement your own string routines. _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

