Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david....@intel.com>
CC: Kelly Steele <kelly.ste...@intel.com>
CC: Mike Wu  <mike...@intel.com>
CC: Mang Guo <mang....@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

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to