From: zwei4 <david.wei@intel.com>
To: edk2-devel@lists.01.org
Cc: David Wei <david.wei@intel.com>,
Kelly Steele <kelly.steele@intel.com>,
Mike Wu <mike.wu@intel.com>, Mang Guo <mang.guo@intel.com>
Subject: [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 4/5] Common EEPROM library instance.
Date: Mon, 23 Jul 2018 10:39:18 +0800 [thread overview]
Message-ID: <20180723023919.19796-4-david.wei@intel.com> (raw)
In-Reply-To: <20180723023919.19796-1-david.wei@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Kelly Steele <kelly.steele@intel.com>
CC: Mike Wu <mike.wu@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
.../Common/Features/Eeprom/EepromLib/EepromLib.c | 1011 ++++++++++++++++++++
.../Common/Features/Eeprom/EepromLib/EepromLib.h | 76 ++
.../Common/Features/Eeprom/EepromLib/EepromLib.inf | 63 ++
.../Features/Eeprom/EepromLib/EepromNullLib.inf | 36 +
.../Features/Eeprom/EepromLib/EepromPeiLib.inf | 62 ++
.../Features/Eeprom/EepromLib/Null/EepromNullLib.c | 82 ++
.../Features/Eeprom/EepromLib/Null/EepromNullLib.h | 26 +
.../Eeprom/EepromLib/Pei/ValidateHashPei.c | 251 +++++
.../Features/Eeprom/EepromLib/ValidateHash.c | 399 ++++++++
9 files changed, 2006 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
new file mode 100644
index 0000000000..6ab06da2be
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.c
@@ -0,0 +1,1011 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+BOOLEAN *gImageValidFlag;
+UINT32 mCrcTable[256];
+BOOLEAN mCrcInitFlag = FALSE;
+BOOLEAN mEepromLibDebugFlag = TRUE;
+
+/**
+ This internal function reverses bits for 32bit data.
+
+ @param Value The data to be reversed.
+
+ @return Data reversed.
+
+**/
+UINT32
+EFIAPI
+ReverseBits (
+ UINT32 Value
+ )
+{
+ UINTN Index;
+ UINT32 NewValue;
+
+ NewValue = 0;
+ for (Index = 0; Index < 32; Index++) {
+ if ((Value & (1 << Index)) != 0) {
+ NewValue = NewValue | (1 << (31 - Index));
+ }
+ }
+
+ return NewValue;
+}
+
+/**
+ Initialize CRC32 table.
+
+**/
+VOID
+EFIAPI
+InitializeCrc32Table (
+ VOID
+ )
+{
+ UINTN TableEntry;
+ UINTN Index;
+ UINT32 Value;
+
+ for (TableEntry = 0; TableEntry < 256; TableEntry++) {
+ Value = ReverseBits ((UINT32) TableEntry);
+ for (Index = 0; Index < 8; Index++) {
+ if ((Value & 0x80000000) != 0) {
+ Value = (Value << 1) ^ 0x04C11DB7;
+ } else {
+ Value = Value << 1;
+ }
+ }
+
+ mCrcTable[TableEntry] = ReverseBits (Value);
+ }
+ mCrcInitFlag = TRUE;
+}
+
+/*++
+
+Routine Description:
+
+ The CalculateCrc32 routine.
+
+Arguments:
+
+ Data - The buffer contaning the data to be processed
+ DataSize - The size of data to be processed
+ CrcOut - A pointer to the caller allocated UINT32 that on
+ contains the CRC32 checksum of Data
+
+Returns:
+
+ EFI_SUCCESS - Calculation is successful.
+ EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0
+
+--*/
+EFI_STATUS
+EFIAPI
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ )
+{
+ UINT32 Crc;
+ UINTN Index;
+ UINT8 *Ptr;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ // Sanity checks
+ if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Table initialized?
+ if (!mCrcInitFlag) InitializeCrc32Table ();
+
+ Crc = 0xFFFFFFFF;
+ for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
+ Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
+ }
+
+ *CrcOut = Crc ^ 0xFFFFFFFF;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EepromLibNemToMemory (VOID)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ UINT8 *Buffer;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Size = sizeof (GENERIC_HEADER);
+ Buffer = EepromAllocatePool (Size);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Try to erase the first header, thereby invalidating the image.
+ //
+ Status = WriteEeprom (LibraryIndex, 0, &Size, Buffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed, so bail.
+ //
+ goto Exit;
+ }
+
+ //
+ // Clear the valid status for this image.
+ //
+ gImageValidFlag[LibraryIndex] = FALSE;
+
+Exit:
+ //
+ // Free resources
+ //
+ Buffer = EepromFreePool (Buffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT CHAR8 Signature[EEPROM_SIGNATURE_SIZE],
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ GENERIC_HEADER *EepromHeader;
+ UINT32 Index;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ EepromHeader = NULL;
+ Status = EFI_SUCCESS;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Signature pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Start at the beginning structure and loop thru the image looking for the requested structure
+ //
+ Index = 0;
+ while (!EFI_ERROR (Status)) {
+ //
+ // Make sure buffer is empty
+ //
+ *Buffer = EepromFreePool (*Buffer);
+ Status = GetNextEepromStructure (LibraryIndex, &Index, Buffer, Size);
+ if (*Size != 0) {
+ //
+ // The buffer isn't empty
+ //
+ EepromHeader = (GENERIC_HEADER *) *Buffer;
+ if (AsciiStrnCmp (EepromHeader->signature, Signature, AsciiStrLen (Signature)) == 0) {
+ //
+ // This is our structure. Bail.
+ //
+ goto Exit;
+ }
+ }
+ *Buffer = EepromFreePool (*Buffer);
+ }
+
+ //
+ // Didn't find it. Error out.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find %a structure!\n", __FUNCTION__, __LINE__, Signature));
+ Status = EFI_NOT_FOUND;
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ *Buffer = EepromFreePool (*Buffer);
+ *Size = 0;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ return Status;
+}
+
+UINT32
+EFIAPI
+GetImageSize (
+ IN UINT8 LibraryIndex
+ )
+{
+ EEPROM_HEADER EepromHeader;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Size = 0;
+ goto Exit;
+ }
+
+ //
+ // Grab $Eeprom$ structure which should be the first structure at offset 0
+ //
+ Size = sizeof (EEPROM_HEADER);
+ ZeroMem (&EepromHeader, Size);
+ Status = ReadEeprom (LibraryIndex, 0, &Size, (UINT8 *) &EepromHeader, &EepromInfo);
+ if (EFI_ERROR (Status) || (AsciiStrnCmp (EepromHeader.signature, "$Eeprom$", 8) != 0)) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find $Eeprom$ structure!\n", __FUNCTION__, __LINE__));
+ //
+ // Try ReadEeprom() method
+ //
+ Size = 0;
+ Status = ReadEeprom (LibraryIndex, 0, &Size, (UINT8 *) &EepromHeader, &EepromInfo);
+ if ((Status != EFI_BUFFER_TOO_SMALL) || (Status != EFI_SUCCESS)) {
+ //
+ // Didn't find size.
+ //
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+ }
+
+ //
+ // Return size
+ //
+ Size = EepromHeader.structlength;
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Image size = %08x\n", __FUNCTION__, __LINE__, Size));
+
+Exit:
+ return Size;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT UINT32 *Index,
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ CHAR8 *AsciiString;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT32 ImageSize;
+ UINT32 Offset;
+ EFI_STATUS Status;
+ GENERIC_HEADER Structure;
+ UINT8 *TempBuffer;
+ UINT32 TempSize;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Status = EFI_SUCCESS;
+ TempBuffer = NULL;
+ TempSize = 0;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Buffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Size == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Size pointer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Make sure the incoming buffer is empty
+ //
+ *Buffer = EepromFreePool (*Buffer);
+ *Size = 0;
+
+ //
+ // Grab the image size
+ //
+ ImageSize = GetImageSize (LibraryIndex);
+ if (ImageSize == 0) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get image size!\n", __FUNCTION__, __LINE__));
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ //
+ // Paragraph align offset
+ //
+ Offset = *Index + (*Index % 0x10);
+
+ //
+ // Sanity check to make sure we are still in the image
+ //
+ if (Offset >= ImageSize) {
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - WARNING: Went past the end of the image!\n", __FUNCTION__, __LINE__));
+ Status = EFI_END_OF_FILE;
+ goto Exit;
+ }
+
+ //
+ // Read in the next header
+ //
+ TempSize = sizeof (GENERIC_HEADER);
+ Status = ReadEeprom (LibraryIndex, Offset, &TempSize, (UINT8 *) &Structure, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Got an error!
+ //
+ goto Exit;
+ }
+ //
+ // Check to see if this is a valid structure
+ //
+ if (Structure.signature[0] != '$') {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find structure signature starting with $!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+
+ //
+ // This is our structure!
+ //
+ TempSize = Structure.length;
+ TempBuffer = EepromAllocatePool (TempSize);
+ if (TempBuffer == NULL) {
+ //
+ // Failed to allocate pool
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate pool for Buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Some debug info
+ //
+ AsciiString = Structure.signature;
+ AsciiString[sizeof (Structure.signature)] = 0;
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Structure[%04x] = %a\n", __FUNCTION__, __LINE__, Offset, AsciiString));
+
+ //
+ // Grab the structure
+ //
+ Status = ReadEeprom (LibraryIndex, Offset, &TempSize, TempBuffer, &EepromInfo);
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - ReadEeprom() -> %r\n", __FUNCTION__, __LINE__, Status));
+ if (!EFI_ERROR (Status)) {
+ //
+ // Got a valid structure. Point Index to end of the structure..
+ //
+ *Index = Offset + TempSize;
+ //
+ // Pass out data
+ //
+ *Buffer = TempBuffer;
+ *Size = TempSize;
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ TempBuffer = EepromFreePool (TempBuffer);
+ if (Status != EFI_END_OF_FILE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ }
+ }
+ return Status;
+}
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+ IN BOOLEAN CopyToMemory,
+ IN BOOLEAN MemoryInitialized
+ )
+{
+ UINT8 *EepromAutoList;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT8 FirstValidImage;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ UINT8 index;
+ UINT8 Library;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ EepromAutoList = (UINT8 *) PcdGetPtr (PcdEepromAutoPriority);
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ FirstValidImage = EEPROM_NULL;
+ ImageBuffer = NULL;
+
+ //
+ // Sanity checks
+ //
+ if (EepromAutoList == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: PCD PcdEepromAutoPriority is empty!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ goto Exit;
+ }
+
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+
+ //
+ // Loop thru PcdEepromAutoPriority looking for a validated image.
+ //
+ index = 0;
+ while (EepromAutoList[index] != 0xFF) {
+ Library = EepromAutoList[index];
+ if (Library >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ //
+ // We're in the weeds. Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: PCD PcdEepromAutoPriority contains invalid value!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ goto Exit;
+ }
+ if (gImageValidFlag[Library]) {
+ //
+ // This library is valid, bail.
+ //
+ FirstValidImage = Library;
+ break;
+ }
+ //
+ // Point to next library
+ //
+ index++;
+ }
+ //
+ // Check to see if we need to validate and copy into memory
+ //
+ if (!CopyToMemory) {
+ //
+ // Nope. Bail.
+ //
+ goto Exit;
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // If nothing is valid, try validating them all
+ //
+ if (FirstValidImage == EEPROM_NULL) {
+ //
+ // Couldn't find a validated image. Try validating them all.
+ //
+ index = 0;
+ while (EepromAutoList[index] != 0xFF) {
+ Library = EepromAutoList[index];
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Trying to validate library %a...\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ Status = ValidateEeprom (Library);
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Validating %a -> %r\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library], Status));
+ if (!EFI_ERROR (Status) || (Status == EFI_MEDIA_CHANGED)) {
+ //
+ // This one is valid. Bail.
+ //
+ if (FirstValidImage == EEPROM_NULL) {
+ FirstValidImage = Library;
+ }
+ }
+ //
+ // Point to next library
+ //
+ index++;
+ }
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // Determine which image to copy to memory
+ //
+ if (gImageValidFlag[EEPROM_MEMORY]) {
+ //
+ // Yep. Bail.
+ //
+ Library = EEPROM_MEMORY;
+ goto Exit;
+ }
+ if (gImageValidFlag[EEPROM_EEPROM]) {
+ Library = EEPROM_EEPROM;
+ }
+ if (gImageValidFlag[EEPROM_FV]) {
+ Library = EEPROM_FV;
+ }
+ if (gImageValidFlag[EEPROM_EEPROM] && gImageValidFlag[EEPROM_FV]) {
+ BOARD_INFO_TABLE *EepromBoardInfo;
+ BOARD_INFO_TABLE *FvBoardInfo;
+ EEPROM_HEADER *EepromEepromHeader;
+ EEPROM_HEADER *FvEepromHeader;
+ //
+ // Initialize variables
+ //
+ EepromBoardInfo = NULL;
+ EepromEepromHeader = NULL;
+ FvBoardInfo = NULL;
+ FvEepromHeader = NULL;
+ Library = EEPROM_NULL;
+ //
+ // Get BoardInfo records
+ //
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_EEPROM, "$BrdInfo", (UINT8 **) &EepromBoardInfo, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (EepromBoardInfo == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get EEPROM Board Info structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_FV;
+ } else {
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_FV, "$BrdInfo", (UINT8 **) &FvBoardInfo, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (FvBoardInfo == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get FV Board Info structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_EEPROM;
+ } else {
+ //
+ // Compare BoardInfo records
+ //
+ if ((CompareMem (EepromBoardInfo->manuname, FvBoardInfo->manuname, 16) == 0) &&
+ (CompareMem (EepromBoardInfo->brdname, FvBoardInfo->brdname, 16) == 0) &&
+ (EepromBoardInfo->boardid == FvBoardInfo->boardid) &&
+ (EepromBoardInfo->fabid == FvBoardInfo->fabid) &&
+ (EepromBoardInfo->ecid == FvBoardInfo->ecid) &&
+ (EepromBoardInfo->boardtype == FvBoardInfo->boardtype)) {
+ //
+ // Get EepromHeader records
+ //
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_EEPROM, "$Eeprom$", (UINT8 **) &EepromEepromHeader, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (EepromEepromHeader == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get EEPROM header structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_FV;
+ } else {
+ Size = 0;
+ Status = GetEepromStructure (EEPROM_FV, "$Eeprom$", (UINT8 **) &FvEepromHeader, &Size);
+ if (EFI_ERROR (Status) || (Size == 0) || (FvEepromHeader == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get FV header structure! (%r)\n", __FUNCTION__, __LINE__, Status));
+ Library = EEPROM_EEPROM;
+ } else {
+ //
+ // Compare image versions
+ //
+ if (EepromEepromHeader->version > FvEepromHeader->version) {
+ Library = EEPROM_EEPROM;
+ } else {
+ Library = EEPROM_FV;
+ }
+ }
+ }
+ } else {
+ //
+ // FV gets priority since BoardInfo data doesn't match
+ //
+ Library = EEPROM_FV;
+ }
+ }
+ }
+ //
+ // Free resources
+ //
+ EepromBoardInfo = EepromFreePool (EepromBoardInfo);
+ EepromEepromHeader = EepromFreePool (EepromEepromHeader);
+ FvBoardInfo = EepromFreePool (FvBoardInfo);
+ FvEepromHeader = EepromFreePool (FvEepromHeader);
+ }
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+ //
+ // If we don't have memory, then bail so we don't take up all of the stack space in NEM.
+ //
+ if (!MemoryInitialized) {
+ goto Exit;
+ }
+ //
+ // We have a validated image and it is not in memory. Copy it in.
+ // 1. Ask for the image size so we can allocate a large enough buffer.
+ // 2. Read the image into the buffer.
+ // 3. Write it to memory.
+ // 4. Validate the memory copy.
+ //
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - Copying %a to EEPROM_MEMORY\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ ImageSize = GetImageSize (Library);
+ if (ImageSize != 0) {
+ //
+ // Something to copy
+ //
+ ImageBuffer = EepromAllocatePool (ImageSize);
+ if (ImageBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate pool!\n", __FUNCTION__, __LINE__));
+ } else {
+ //
+ // Read in entire image
+ //
+ Status = ReadEeprom (Library, 0, &ImageSize, ImageBuffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Reading image from %a returned %r!\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library], Status));
+ } else {
+ //
+ // Got the image, write to memory
+ //
+ Status = WriteEeprom (EEPROM_MEMORY, 0, &ImageSize, ImageBuffer, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Writing image to %a returned %r!\n", __FUNCTION__, __LINE__, mEepromLibraryString[EEPROM_MEMORY], Status));
+ } else {
+ //
+ // Validate memory image
+ //
+ Status = ValidateEeprom (EEPROM_MEMORY);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Validating image returned %r!\n", __FUNCTION__, __LINE__, Status));
+ } else {
+ //
+ // Return EEPROM_MEMORY
+ //
+ Library = EEPROM_MEMORY;
+ }
+ }
+ }
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ ImageBuffer = EepromFreePool (ImageBuffer);
+ if (FirstValidImage == EEPROM_NULL) {
+ //
+ // Nothing is valid. Return default NULL.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to find a valid image in list PcdEepromAutoPriority!\n", __FUNCTION__, __LINE__));
+ Library = EEPROM_NULL;
+ }
+
+ //
+ // Display current stack pointer
+ //
+ DisplayStackPointer (__FUNCTION__, __LINE__);
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Returning library %a\n", __FUNCTION__, __LINE__, mEepromLibraryString[Library]));
+ return Library;
+}
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ UINT32 Count;
+ UINT32 Crc32;
+ UINT32 Crc32Size;
+ EEPROM_HEADER *EepromHeader;
+ EEPROM_FUNCTION_INFO EepromInfo;
+ UINT8 *Hash;
+ UINT32 HashSize;
+ UINT16 HashType;
+ UINT8 *ImageBuffer;
+ UINT32 ImageSize;
+ SIGNATURE_DATA *Signature;
+ UINT8 *SignedHash;
+ UINT32 SignedHashSize;
+ EFI_STATUS Status;
+ GENERIC_HEADER *Structure;
+ INTN Test;
+
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+
+ //
+ // Initialize variables
+ //
+ ZeroMem (&EepromInfo, sizeof (EEPROM_FUNCTION_INFO));
+ Crc32Size = 0;
+ EepromHeader = NULL;
+ EepromInfo.Bus = PcdGet8 (PcdEepromBus);
+ EepromInfo.Address = PcdGet8 (PcdEepromAddress);
+ EepromInfo.LibraryIndex = EEPROM_EEPROM;
+ Hash = NULL;
+ ImageBuffer = NULL;
+ SignedHash = NULL;
+ SignedHashSize = 0;
+ Status = EFI_SUCCESS;
+ Structure = NULL;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Get image size
+ //
+ ImageSize = GetImageSize (LibraryIndex);
+ if (ImageSize == 0) {
+ //
+ // Oops!
+ //
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+ //
+ // Get a buffer to hold the image
+ //
+ ImageBuffer = EepromAllocatePool (ImageSize);
+ if (ImageBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unable to allocate 0x%08x bytes for the image buffer!\n", __FUNCTION__, __LINE__, ImageSize));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+ //
+ // Read in the image
+ //
+ Status = ReadEeprom (LibraryIndex, 0, &ImageSize, ImageBuffer, &EepromInfo);
+ if (EFI_ERROR (Status)) {
+ //
+ // Oops!!!
+ //
+ goto Exit;
+ }
+ EepromHeader = (EEPROM_HEADER *) ImageBuffer;
+ //
+ // Verify structure order
+ //
+ Count = 0;
+ Structure = (GENERIC_HEADER *) ImageBuffer;
+ while ((UINT8 *) Structure < (UINT8 *) (ImageBuffer + ImageSize)) {
+ //
+ // Increment count
+ //
+ Count++;
+ //
+ // Sanity check header
+ //
+ if (Count == 1) {
+ //
+ // First structure must be $Eeprom$
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$Eeprom$", 8);
+ //
+ // Set CRC32 size
+ //
+ Crc32Size = EepromHeader->crclength;
+ } else if (Count == 2) {
+ //
+ // Second structure must be $EeprMap
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$EeprMap", 8);
+ } else if (Count == 3) {
+ //
+ // Third structure must be $BrdInfo
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$BrdInfo", 8);
+ } else {
+ //
+ // All header signatures begin with $
+ //
+ Test = AsciiStrnCmp (Structure->signature, "$", 0x01);
+ }
+ if (Test != 0) {
+ //
+ // Sanity check failed! Bail.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image is corrupted!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+ if (AsciiStrnCmp (Structure->signature, "$PromSig", 8) == 0) {
+ //
+ // Check if this is the last structure
+ //
+ Signature = (SIGNATURE_DATA *) Structure;
+ HashSize = Signature->length - sizeof (SIGNATURE_DATA);
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashType = Signature->hashtype;
+ if (((UINT8 *) Signature - ImageBuffer) + Signature->length + (Structure->length % 0x10) != ImageSize) {
+ //
+ // Oops! $PromSig is not the last structure.
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: $PromSig structure is not the last structure!\n", __FUNCTION__, __LINE__));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ }
+ }
+ //
+ // Get next structure on paragraph boundary
+ //
+ Structure = (GENERIC_HEADER *) ((UINT8 *) Structure + Structure->length + (Structure->length % 0x10));
+ }
+ //
+ // Verify CRC32
+ //
+ Crc32 = EepromHeader->crc32;
+ EepromHeader->crc32 = 0;
+ CalculateCrc32 (ImageBuffer, Crc32Size, &EepromHeader->crc32);
+ if (EepromHeader->crc32 != Crc32) {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: CRC32 check failed! [%08x:%08x]\n", __FUNCTION__, __LINE__, EepromHeader->crc32, Crc32));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ //
+ // Verify hash
+ //
+ Status = EFI_SUCCESS;
+ if (HashSize > 0) {
+ //
+ // Check hash
+ //
+ Status = SignedHashCheck (LibraryIndex, ImageBuffer, Crc32Size, Signature);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to verify the hash!\n", __FUNCTION__, __LINE__));
+ goto Exit;
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ ImageBuffer = EepromFreePool (ImageBuffer);
+ if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {
+ gImageValidFlag[LibraryIndex] = FALSE;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ } else {
+ //
+ // Might need to go to a bit flag here to indicate CRC32, hash, and signed hash pass. First round in PEI will only be
+ // able to get CRC32 pass since hash is supported by OpenSSL library and it is HUGE.
+ //
+ gImageValidFlag[LibraryIndex] = TRUE;
+ }
+ return Status;
+}
+
+//
+// Desc: Registers the raw data libraries
+// Variables: None
+// Return: EFI_SUCCESS, anything else will cause an ASSERT
+//
+EFI_STATUS
+EFIAPI
+EepromInitConstructor (VOID)
+{
+ if (mEepromLibDebugFlag) DEBUG ((DEBUG_INFO, "%a (#%4d) - Starting...\n", __FUNCTION__, __LINE__));
+ //
+ // Initiliaze CRC32 tables
+ //
+ if (!mCrcInitFlag) InitializeCrc32Table ();
+
+ //
+ // Initiliaze Library valid flags pointer from PCD. This uses the fact that the PCD library currently just passes out
+ // a pointer to it's internal DB. There is no need to update the PCD, since the pointer already points to the internal
+ // PCD copy. If the PCD library changes to include a CRC check of it's data, then we'll have to start using the PcdSetPtr()
+ // function to set the internal PCD value.
+ //
+ gImageValidFlag = PcdGetPtr (PcdEepromLibraryValid);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
new file mode 100644
index 0000000000..83871a4ddf
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.h
@@ -0,0 +1,76 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EEPROM_LIB_COMMON_
+#define _EEPROM_LIB_COMMON_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <Guid/EepromVariable.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/EepromLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+
+#include <EepromStruct.h>
+
+
+////
+//// Defines
+////
+#define HASH_SIGNED_FLAG (1 << 15)
+#define HASH_TYPE_MASK 0x00FF
+#define MAX_HASH_TYPE 5
+#define MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
+#define EFI_CERT_TYPE_RSA2048_SIZE 256
+
+////
+//// TypeDefs
+////
+
+////
+//// Structures
+////
+
+////
+//// Functions
+////
+EFI_STATUS
+EFIAPI
+CalculateCrc32 (
+ IN UINT8 *Data,
+ IN UINTN DataSize,
+ IN OUT UINT32 *CrcOut
+ );
+
+EFI_STATUS
+EFIAPI
+EepromLibNemToMemory (VOID);
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ );
+
+#endif // _EEPROM_LIB_COMMON_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
new file mode 100644
index 0000000000..b7ccb920aa
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromLib.inf
@@ -0,0 +1,63 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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]
+ INF_VERSION = 0x00010017
+ BASE_NAME = EepromLib
+ FILE_GUID = 20AF98D0-BE4F-44FB-8C60-CA992FA121D1
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromLib
+ CONSTRUCTOR = EepromInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseCryptLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ EepromDataLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ UefiRuntimeServicesTableLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority
+ gPlatformModuleTokenSpaceGuid.PcdEepromAddress
+ gPlatformModuleTokenSpaceGuid.PcdEepromBus
+ gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag
+ gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+ gPlatformModuleTokenSpaceGuid.PcdEepromPublicKeyFile
+
+[Sources]
+ EepromLib.c
+ EepromLib.h
+ ValidateHash.c
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
new file mode 100644
index 0000000000..0aa2137e1b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromNullLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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]
+ INF_VERSION = 0x00010017
+ BASE_NAME = EepromNullLib
+ FILE_GUID = E4E838B1-7D70-42C7-A531-9C8EF44FA748
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromNullLib
+
+[Depex]
+ TRUE
+
+[LibraryClasses]
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+
+[Sources]
+ Null/EepromNullLib.c
+ Null/EepromNullLib.h
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
new file mode 100644
index 0000000000..0f619fd2f5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/EepromPeiLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Library producing EEPROM structure data functionality.
+#
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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]
+ INF_VERSION = 0x00010017
+ BASE_NAME = EepromPeiLib
+ FILE_GUID = 2B91CA36-CDBC-4A3B-BDE7-404BA69C8C55
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = EepromPeiLib
+ CONSTRUCTOR = EepromInitConstructor
+
+[Depex]
+ TRUE
+
+[Guids]
+ gEepromVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ EepromDataLib
+ MemoryAllocationLib
+ PcdLib
+ PeiServicesLib
+ PrintLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority
+ gPlatformModuleTokenSpaceGuid.PcdEepromAddress
+ gPlatformModuleTokenSpaceGuid.PcdEepromBus
+ gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag
+ gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer
+ gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
+
+[Sources]
+ EepromLib.c
+ EepromLib.h
+ Pei/ValidateHashPei.c
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
new file mode 100644
index 0000000000..612408a0e0
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.c
@@ -0,0 +1,82 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromNullLib.h"
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT CHAR8 Signature[EEPROM_SIGNATURE_SIZE],
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+UINT32
+EFIAPI
+GetImageSize (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+ IN UINT8 LibraryIndex,
+ IN OUT UINT32 *Index,
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT32 *Size
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+ IN BOOLEAN CopyToMemory,
+ IN BOOLEAN MemoryInitialized
+ )
+{
+ return EEPROM_NULL;
+}
+
+VOID
+InitializeEepromPcds (VOID)
+{
+}
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+ IN UINT8 LibraryIndex
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
new file mode 100644
index 0000000000..3d576202b5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Null/EepromNullLib.h
@@ -0,0 +1,26 @@
+/** @file
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EEPROM_NULL_LIB_COMMON_
+#define _EEPROM_NULL_LIB_COMMON_
+////
+//// Header files
+////
+#include <Uefi.h>
+#include <EepromStruct.h>
+
+#include <Library/DebugLib.h>
+#include <Library/EepromDataLib.h>
+#include <Library/EepromLib.h>
+
+#endif // _EEPROM_NULL_LIB_COMMON_
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
new file mode 100644
index 0000000000..b039d9885b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/Pei/ValidateHashPei.c
@@ -0,0 +1,251 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+#include <PiPei.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+UINTN
+EFIAPI
+DisplayStackPointer (
+ IN CHAR8 *Function,
+ IN UINTN LineNumber
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ UINTN Temp;
+
+ Hob = GetHobList ();
+ Temp = 0;
+ if ((Hob != NULL) & (mEepromDataLibDebugFlag)) {
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeTop = %08x\n", __FUNCTION__, __LINE__, Hob->EfiFreeMemoryTop));
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeBottom = %08x\n", __FUNCTION__, __LINE__, Hob->EfiFreeMemoryBottom));
+ Temp = (UINTN) Hob->EfiFreeMemoryBottom;
+ }
+
+ return Temp;
+}
+
+EFI_STATUS
+EFIAPI
+GetEepromVariable (
+ IN UINT8 LibraryIndex,
+ OUT UINT8 **Buffer,
+ OUT UINT32 *BufferSize
+ )
+{
+ UINT32 Attributes;
+ UINT8 *Data;
+ EFI_STATUS Status;
+ CHAR16 VariableName[32];
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ UINTN VariableSize;
+
+ //
+ // Initialize variables
+ //
+ Attributes = 0;
+ Data = NULL;
+ Status = EFI_SUCCESS;
+ UnicodeSPrint (VariableName, 32, L"PromSig-%d", LibraryIndex);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((*Buffer != NULL) || (BufferSize == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Find variable services
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariableServices);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to locate Variable PPI! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Get variable size
+ //
+ VariableSize = 0;
+ Status = VariableServices->GetVariable (
+ VariableServices, // *This
+ VariableName, // Variable name in Unicode
+ &gEepromVariableGuid, // Variable GUID
+ NULL, // Attributes
+ &VariableSize, // Data size
+ NULL // Data
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // No variable to find
+ //
+ *Buffer = NULL;
+ *BufferSize = 0;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ } else {
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get size of variable! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+ }
+
+ //
+ // Allocate buffer
+ //
+ Data = EepromAllocatePool (VariableSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to allocate buffer! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Get variable
+ //
+ Status = VariableServices->GetVariable (
+ VariableServices, // *This
+ VariableName, // Variable name in Unicode
+ &gEepromVariableGuid, // Variable GUID
+ NULL, // Attributes
+ &VariableSize, // Data size
+ Data // Data
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed to get data
+ //
+ *Buffer = NULL;
+ *BufferSize = 0;
+ } else {
+ *Buffer = Data;
+ *BufferSize = VariableSize;
+ }
+
+Exit:
+ if (EFI_ERROR (Status)) {
+ Data = EepromFreePool (Data);
+ }
+ return Status;
+}
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID)
+{
+ return TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ )
+{
+ UINT8 *Hash;
+ UINT32 HashSize;
+ EFI_STATUS Status;
+ UINT8 *Variable;
+ UINT32 VariableSize;
+
+ //
+ // Initialize variables
+ //
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashSize = Signature->length - sizeof (SIGNATURE_DATA);
+ Status = EFI_UNSUPPORTED;
+ Variable = NULL;
+ VariableSize = 0;
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Signature->hashtype == 0) {
+ //
+ // Nothing to do. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+
+ //
+ // Get stored hash
+ //
+ Status = GetEepromVariable (LibraryIndex, &Variable, &VariableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to get variable! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Sanity checks
+ //
+ if (VariableSize == 0) {
+ //
+ // Nothing stored for this library. Bail.
+ //
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ if (VariableSize != HashSize) {
+ Status = EFI_MEDIA_CHANGED;
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Stored size doesn't match real size! [%r]\n", __FUNCTION__, __LINE__, Status));
+ goto Exit;
+ }
+
+ //
+ // Compare stored to real
+ //
+ if (CompareMem (Variable, Hash, HashSize) != 0) {
+ //
+ // Failed security match
+ //
+ Status = EFI_SECURITY_VIOLATION;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+Exit:
+ Variable = EepromFreePool (Variable);
+ return Status;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
new file mode 100644
index 0000000000..355033cbef
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/EepromLib/ValidateHash.c
@@ -0,0 +1,399 @@
+/** @file
+ Common EEPROM library instance.
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ 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 "EepromLib.h"
+
+#include <Library/BaseCryptLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+CONST UINT8 mRsaE[] = {0x01, 0x00, 0x01};
+CONST UINT8 mHashSizeLookup[] = {
+ 0x00,
+ MD5_DIGEST_SIZE,
+ SHA1_DIGEST_SIZE,
+ SHA256_DIGEST_SIZE,
+ SHA384_DIGEST_SIZE,
+ SHA512_DIGEST_SIZE
+ };
+
+UINTN
+EFIAPI
+DisplayStackPointer (
+ IN CHAR8 *Function,
+ IN UINTN LineNumber
+ )
+{
+ UINT8 *Temp;
+
+ Temp = AllocatePool (1);
+ if (mEepromDataLibDebugFlag) {
+ DEBUG ((DEBUG_INFO, "%a (#%4d) - INFO: FreeBottom = %08x\n", __FUNCTION__, __LINE__, Temp));
+ }
+
+ return (UINTN) Temp;
+}
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID)
+{
+ return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+SetEepromVariable (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *Buffer,
+ IN UINT32 BufferSize
+ )
+{
+ UINT32 Attributes;
+ EFI_STATUS Status;
+ CHAR16 VariableName[32];
+
+ //
+ // Initialize variables
+ //
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ Status = EFI_SUCCESS;
+ UnicodeSPrint (VariableName, 32, L"PromSig-%d", LibraryIndex);
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((Buffer == NULL) && (BufferSize > 0)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ //
+ // Set variable
+ //
+ Status = gRT->SetVariable (
+ VariableName, // Variable name in UniCode
+ &gEepromVariableGuid, // Variable GUID
+ Attributes, // Attributes
+ BufferSize, // Data size
+ Buffer // Data
+ );
+
+Exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SignedHashCheck (
+ IN UINT8 LibraryIndex,
+ IN UINT8 *ImageBuffer,
+ IN UINT32 Crc32Size,
+ IN SIGNATURE_DATA *Signature
+ )
+{
+ UINT8 Digest[MAX_DIGEST_SIZE];
+ FV_FUNCTION_INFO FvInfo;
+ EFI_GUID FvPublicKeyFile;
+ UINT8 *Hash;
+ UINT32 HashSize;
+ BOOLEAN HashStatus;
+ UINT16 HashType;
+ UINT8 *PublicKey;
+ UINT32 PublicKeySize;
+ VOID *Rsa;
+ BOOLEAN RsaStatus;
+ UINT8 *SignedHash;
+ UINT32 SignedHashSize;
+ EFI_STATUS Status;
+
+ //
+ // Initialize variables
+ //
+ CopyMem (&FvPublicKeyFile, PcdGetPtr (PcdEepromPublicKeyFile), sizeof (EFI_GUID));
+ ZeroMem (&FvInfo, sizeof (FV_FUNCTION_INFO));
+ FvInfo.LibraryIndex = EEPROM_FV;
+ FvInfo.FvFileGuid = &FvPublicKeyFile;
+ Hash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA);
+ HashType = Signature->hashtype;
+ HashSize = mHashSizeLookup[HashType & HASH_TYPE_MASK];
+ PublicKey = NULL;
+ PublicKeySize = 0;
+ Rsa = NULL;
+ SignedHash = NULL;
+ SignedHashSize = 0;
+ Status = EFI_UNSUPPORTED;
+ if (HashType & HASH_SIGNED_FLAG) {
+ SignedHash = ((UINT8 *) Signature) + sizeof (SIGNATURE_DATA) + HashSize;
+ SignedHashSize = Signature->length - sizeof (SIGNATURE_DATA) - HashSize;
+ }
+
+ //
+ // Sanity checks
+ //
+ if (LibraryIndex >= EEPROM_DATA_LIBRARY_INDEX_MAX) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Library index is larger than %d!\n", __FUNCTION__, __LINE__, EEPROM_DATA_LIBRARY_INDEX_MAX - 1));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if ((ImageBuffer == NULL) || (Signature == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (Crc32Size == 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer size is 0!\n", __FUNCTION__, __LINE__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ if (HashType == 0) {
+ //
+ // Nothing to do. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ if ((HashType & HASH_TYPE_MASK) > MAX_HASH_TYPE) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: HashType out of bounds! [%04x]\n", __FUNCTION__, __LINE__, HashType));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+ if ((Hash == NULL) || (HashSize == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Buffer or buffer size is NULL!\n", __FUNCTION__, __LINE__));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+ if ((SignedHashSize != 256) && (SignedHashSize != 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: SignedHashSize failed! [%02x]\n", __FUNCTION__, __LINE__, SignedHashSize));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+
+ //
+ // Clear existing NvStorage variable if it exists. gEepromVariableGuid:L"PromSig-#"
+ //
+ Status = SetEepromVariable (LibraryIndex, NULL, 0);
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to delete variable PromSig-%d! [%r]\n", __FUNCTION__, __LINE__, LibraryIndex, Status));
+ goto Exit;
+ }
+
+ //
+ // Figure out what hash is being used
+ //
+ switch (HashType & HASH_TYPE_MASK) {
+ case HASH_NONE:
+ //
+ // Nothing to do. Bail.
+ //
+ break;
+ case HASH_MD5:
+ //
+ // MD5 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Md5HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed MD5 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, MD5_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed MD5 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = MD5_DIGEST_SIZE;
+ break;
+ case HASH_SHA1:
+ //
+ // SHA1 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha1HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA1 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA1_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA1 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA1_DIGEST_SIZE;
+ break;
+ case HASH_SHA256:
+ //
+ // SHA256 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha256HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA256 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA256_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA256 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA256_DIGEST_SIZE;
+ break;
+ case HASH_SHA384:
+ //
+ // SHA384 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha384HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA384 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA384_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA384 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA384_DIGEST_SIZE;
+ break;
+ case HASH_SHA512:
+ //
+ // SHA512 hashing
+ //
+ ZeroMem (Digest, MAX_DIGEST_SIZE);
+ HashStatus = Sha512HashAll (ImageBuffer, Crc32Size, Digest);
+ if (!HashStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA512 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ if (CompareMem (Digest, Hash, SHA512_DIGEST_SIZE) != 0) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Image failed SHA512 hash check!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+ HashSize = SHA512_DIGEST_SIZE;
+ break;
+ default:
+ //
+ // Oops!
+ //
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Unknown hash type [%04x]!\n", __FUNCTION__, __LINE__, HashType));
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Exit;
+ break;
+ }
+
+ //
+ // Does this have a signed hash?
+ //
+ if ((HashType & HASH_SIGNED_FLAG) != HASH_SIGNED_FLAG) {
+ //
+ // Nope. Bail.
+ //
+ Status = EFI_SUCCESS;
+ goto
Exit;
+ }
+
+ //
+ // Get size of public key file in FV
+ //
+ PublicKey = EepromAllocatePool (2);
+ Status = ReadEeprom (EEPROM_FV, 0, &PublicKeySize, PublicKey, &FvInfo);
+ if ((Status != EFI_BUFFER_TOO_SMALL) || (PublicKeySize == 0)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Finding Public key file size returned with %r and a size of %08x\n", __FUNCTION__, __LINE__, Status, PublicKeySize));
+ Status = EFI_COMPROMISED_DATA;
+ goto Exit;
+ }
+
+ //
+ // Allocate buffer for public key
+ //
+ PublicKey = EepromFreePool (PublicKey);
+ PublicKey = EepromAllocatePool (PublicKeySize);
+ if (PublicKey == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Read in Public key from FV
+ //
+ Status = ReadEeprom (EEPROM_FV, 0, &PublicKeySize, PublicKey, &FvInfo);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Verify signature
+ //
+ Rsa = RsaNew ();
+ if (Rsa == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaNew() returned NULL buffer!\n", __FUNCTION__, __LINE__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Set RSA Key Components.
+ // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
+ //
+ RsaStatus = RsaSetKey (Rsa, RsaKeyN, PublicKey, EFI_CERT_TYPE_RSA2048_SIZE);
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaSetKey(RsaKeyN) failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_ABORTED;
+ goto Exit;
+ }
+
+ RsaStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaSetKey(RsaKeyE) failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_ABORTED;
+ goto Exit;
+ }
+
+ RsaStatus = RsaPkcs1Verify (Rsa, Hash, HashSize, SignedHash, SignedHashSize);
+ if (!RsaStatus) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - RsaPkcs1Verify() failed!\n", __FUNCTION__, __LINE__));
+ Status = EFI_SECURITY_VIOLATION;
+ goto Exit;
+ }
+
+Exit:
+ if (Rsa != NULL) {
+ RsaFree (Rsa);
+ }
+ PublicKey = EepromFreePool (PublicKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - Ending with %r\n", __FUNCTION__, __LINE__, Status));
+ } else if (HashType != 0) {
+ //
+ // This is where a copy of the $PromSig data is stored in NvStorage. gEepromVariableGuid:L"PromSig-#"
+ //
+ Status = SetEepromVariable (LibraryIndex, Hash, (HashSize + SignedHashSize));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (#%4d) - ERROR: Failed to delete variable PromSig-%d! [%r]\n", __FUNCTION__, __LINE__, LibraryIndex, Status));
+ }
+ }
+ return Status;
+}
+
--
2.14.1.windows.1
next prev parent reply other threads:[~2018-07-23 2:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-23 2:39 [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 1/5] Add EepromApp zwei4
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality zwei4
2018-07-23 2:39 ` zwei4 [this message]
2018-07-23 2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 5/5] EEPROM header files zwei4
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180723023919.19796-4-david.wei@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox