summaryrefslogtreecommitdiff
path: root/SecurityPkg/VariableAuthenticated/Pei
diff options
context:
space:
mode:
authorgdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-02 07:49:32 +0000
committergdong1 <gdong1@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-02 07:49:32 +0000
commit0c18794ea4289f03fefc7117b56740414cc0536c (patch)
tree4e51c5cc23c69a67cead8c58464da870daa4c029 /SecurityPkg/VariableAuthenticated/Pei
parent986d1dfb0813d6a7623531e85c2e2a7e1f956cf8 (diff)
downloadedk2-platforms-0c18794ea4289f03fefc7117b56740414cc0536c.tar.xz
Add security package to repository.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'SecurityPkg/VariableAuthenticated/Pei')
-rw-r--r--SecurityPkg/VariableAuthenticated/Pei/Variable.c671
-rw-r--r--SecurityPkg/VariableAuthenticated/Pei/Variable.h128
-rw-r--r--SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf64
3 files changed, 863 insertions, 0 deletions
diff --git a/SecurityPkg/VariableAuthenticated/Pei/Variable.c b/SecurityPkg/VariableAuthenticated/Pei/Variable.c
new file mode 100644
index 0000000000..1fd051b354
--- /dev/null
+++ b/SecurityPkg/VariableAuthenticated/Pei/Variable.c
@@ -0,0 +1,671 @@
+/** @file
+ Implement ReadOnly Variable Services required by PEIM and install PEI
+ ReadOnly Varaiable2 PPI. These services operates the non-volatile
+ storage space.
+
+Copyright (c) 2009 - 2011, 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 "Variable.h"
+
+//
+// Module globals
+//
+EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = {
+ PeiGetVariable,
+ PeiGetNextVariableName
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ &mVariablePpi
+};
+
+
+/**
+ Provide the functionality of the variable services.
+
+ @param FileHandle Handle of the file being invoked.
+ Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS If the interface could be successfully installed
+ @retval Others Returned from PeiServicesInstallPpi()
+
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeVariableServices (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+
+ //
+ // Check if this is recovery boot path. If no, publish the variable access capability
+ // to other modules. If yes, the content of variable area is not reliable. Therefore,
+ // in this case we should not provide variable service to other pei modules.
+ //
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return PeiServicesInstallPpi (&mPpiListVariable);
+
+}
+
+/**
+
+ Gets the pointer to the first variable header in given variable store area.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return Pointer to the first variable header
+
+**/
+VARIABLE_HEADER *
+GetStartPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
+}
+
+
+/**
+ This code gets the pointer to the last variable memory pointer byte.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @return VARIABLE_HEADER* pointer to last unavailable Variable Header.
+
+**/
+VARIABLE_HEADER *
+GetEndPointer (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+ //
+ // The end of variable store
+ //
+ return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);
+}
+
+
+/**
+ This code checks if variable header is valid or not.
+
+ @param Variable Pointer to the Variable Header.
+
+ @retval TRUE Variable header is valid.
+ @retval FALSE Variable header is not valid.
+
+**/
+BOOLEAN
+IsValidVariableHeader (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ This code gets the size of name of variable.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+UINTN
+NameSizeOfVariable (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->NameSize;
+}
+
+
+/**
+ This code gets the size of data of variable.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return Size of variable in bytes in type UINTN.
+
+**/
+UINTN
+DataSizeOfVariable (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+ if (Variable->State == (UINT8) (-1) ||
+ Variable->DataSize == (UINT32) (-1) ||
+ Variable->NameSize == (UINT32) (-1) ||
+ Variable->Attributes == (UINT32) (-1)) {
+ return 0;
+ }
+ return (UINTN) Variable->DataSize;
+}
+
+/**
+ This code gets the pointer to the variable name.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A CHAR16* pointer to Variable Name.
+
+**/
+CHAR16 *
+GetVariableNamePtr (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+
+ return (CHAR16 *) (Variable + 1);
+}
+
+
+/**
+ This code gets the pointer to the variable data.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A UINT8* pointer to Variable Data.
+
+**/
+UINT8 *
+GetVariableDataPtr (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+ UINTN Value;
+
+ //
+ // Be careful about pad size for alignment
+ //
+ Value = (UINTN) GetVariableNamePtr (Variable);
+ Value += NameSizeOfVariable (Variable);
+ Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
+
+ return (UINT8 *) Value;
+}
+
+
+/**
+ This code gets the pointer to the next variable header.
+
+ @param Variable Pointer to the Variable Header.
+
+ @return A VARIABLE_HEADER* pointer to next variable header.
+
+**/
+VARIABLE_HEADER *
+GetNextVariablePtr (
+ IN VARIABLE_HEADER *Variable
+ )
+{
+ UINTN Value;
+
+ if (!IsValidVariableHeader (Variable)) {
+ return NULL;
+ }
+
+ Value = (UINTN) GetVariableDataPtr (Variable);
+ Value += DataSizeOfVariable (Variable);
+ Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
+
+ //
+ // Be careful about pad size for alignment
+ //
+ return (VARIABLE_HEADER *) HEADER_ALIGN (Value);
+}
+
+/**
+ This code gets the pointer to the variable name.
+
+ @param VarStoreHeader Pointer to the Variable Store Header.
+
+ @retval EfiRaw Variable store is raw
+ @retval EfiValid Variable store is valid
+ @retval EfiInvalid Variable store is invalid
+
+**/
+VARIABLE_STORE_STATUS
+GetVariableStoreStatus (
+ IN VARIABLE_STORE_HEADER *VarStoreHeader
+ )
+{
+
+ if (CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) &&
+ VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
+ VarStoreHeader->State == VARIABLE_STORE_HEALTHY
+ ) {
+
+ return EfiValid;
+ }
+
+ if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&
+ ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&
+ ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&
+ ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&
+ VarStoreHeader->Size == 0xffffffff &&
+ VarStoreHeader->Format == 0xff &&
+ VarStoreHeader->State == 0xff
+ ) {
+
+ return EfiRaw;
+ } else {
+ return EfiInvalid;
+ }
+}
+
+
+/**
+ This function compares a variable with variable entries in database.
+
+ @param Variable Pointer to the variable in our database
+ @param VariableName Name of the variable to compare to 'Variable'
+ @param VendorGuid GUID of the variable to compare to 'Variable'
+ @param PtrTrack Variable Track Pointer structure that contains Variable Information.
+
+ @retval EFI_SUCCESS Found match variable
+ @retval EFI_NOT_FOUND Variable not found
+
+**/
+EFI_STATUS
+CompareWithValidVariable (
+ IN VARIABLE_HEADER *Variable,
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ OUT VARIABLE_POINTER_TRACK *PtrTrack
+ )
+{
+ VOID *Point;
+
+ if (VariableName[0] == 0) {
+ PtrTrack->CurrPtr = Variable;
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID a UINT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&
+ (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&
+ (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&
+ (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])
+ ) {
+ ASSERT (NameSizeOfVariable (Variable) != 0);
+ Point = (VOID *) GetVariableNamePtr (Variable);
+ if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) {
+ PtrTrack->CurrPtr = Variable;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ This code finds variable in storage blocks (Non-Volatile).
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param VariableName Name of the variable to be found
+ @param VendorGuid Vendor GUID to be found.
+ @param PtrTrack Variable Track Pointer structure that contains Variable Information.
+
+ @retval EFI_SUCCESS Variable found successfully
+ @retval EFI_NOT_FOUND Variable not found
+ @retval EFI_INVALID_PARAMETER Invalid variable name
+
+**/
+EFI_STATUS
+FindVariable (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VendorGuid,
+ OUT VARIABLE_POINTER_TRACK *PtrTrack
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_HEADER *Variable;
+ VARIABLE_HEADER *LastVariable;
+ VARIABLE_HEADER *MaxIndex;
+ VARIABLE_INDEX_TABLE *IndexTable;
+ UINT32 Count;
+ UINT32 Offset;
+ UINT8 *VariableBase;
+ BOOLEAN StopRecord;
+
+ if (VariableName[0] != 0 && VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // No Variable Address equals zero, so 0 as initial value is safe.
+ //
+ MaxIndex = 0;
+ StopRecord = FALSE;
+
+ GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid);
+ if (GuidHob == NULL) {
+ //
+ // If it's the first time to access variable region in flash, create a guid hob to record
+ // VAR_ADDED type variable info.
+ // Note that as the resource of PEI phase is limited, only store the number of
+ // VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.
+ //
+ IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
+ IndexTable->Length = 0;
+ IndexTable->StartPtr = NULL;
+ IndexTable->EndPtr = NULL;
+ IndexTable->GoneThrough = 0;
+ } else {
+ IndexTable = GET_GUID_HOB_DATA (GuidHob);
+ for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {
+ //
+ // traverse the variable info list to look for varible.
+ // The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.
+ //
+ ASSERT (Count < VARIABLE_INDEX_TABLE_VOLUME);
+ Offset += IndexTable->Index[Count];
+ MaxIndex = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);
+ if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
+ PtrTrack->StartPtr = IndexTable->StartPtr;
+ PtrTrack->EndPtr = IndexTable->EndPtr;
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ if (IndexTable->GoneThrough != 0) {
+ return EFI_NOT_FOUND;
+ }
+ }
+ //
+ // If not found in HOB, then let's start from the MaxIndex we've found.
+ //
+ if (MaxIndex != NULL) {
+ Variable = GetNextVariablePtr (MaxIndex);
+ LastVariable = MaxIndex;
+ } else {
+ if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {
+ Variable = IndexTable->StartPtr;
+ } else {
+ VariableBase = (UINT8 *) (UINTN) PcdGet64 (PcdFlashNvStorageVariableBase64);
+ if (VariableBase == NULL) {
+ VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);
+ }
+
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \
+ ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength);
+
+ if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (~VariableStoreHeader->Size == 0) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Find the variable by walk through non-volatile variable store
+ //
+ IndexTable->StartPtr = GetStartPointer (VariableStoreHeader);
+ IndexTable->EndPtr = GetEndPointer (VariableStoreHeader);
+
+ //
+ // Start Pointers for the variable.
+ // Actual Data Pointer where data can be written.
+ //
+ Variable = IndexTable->StartPtr;
+ }
+
+ LastVariable = IndexTable->StartPtr;
+ }
+ //
+ // Find the variable by walk through non-volatile variable store
+ //
+ PtrTrack->StartPtr = IndexTable->StartPtr;
+ PtrTrack->EndPtr = IndexTable->EndPtr;
+
+ while ((Variable < IndexTable->EndPtr) && IsValidVariableHeader (Variable)) {
+ if (Variable->State == VAR_ADDED) {
+ //
+ // Record Variable in VariableIndex HOB
+ //
+ if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && !StopRecord) {
+ Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);
+ //
+ // The distance of two neighbouring VAR_ADDED variable is larger than 2^16,
+ // which is beyond the allowable scope(UINT16) of record. In such case, need not to
+ // record the subsequent VAR_ADDED type variables again.
+ //
+ if ((Offset & 0xFFFF0000UL) != 0) {
+ StopRecord = TRUE;
+ }
+
+ if (!StopRecord) {
+ IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;
+ }
+ LastVariable = Variable;
+ }
+
+ if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ Variable = GetNextVariablePtr (Variable);
+ }
+ //
+ // If gone through the VariableStore, that means we never find in Firmware any more.
+ //
+ if ((IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) && (!StopRecord)) {
+ IndexTable->GoneThrough = 1;
+ }
+
+ PtrTrack->CurrPtr = NULL;
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This service retrieves a variable's value using its name and GUID.
+
+ Read the specified variable from the UEFI variable store. If the Data
+ buffer is too small to hold the contents of the variable, the error
+ EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer
+ size to obtain the data.
+
+ @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
+ @param VariableName A pointer to a null-terminated string that is the variable's name.
+ @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of
+ VariableGuid and VariableName must be unique.
+ @param Attributes If non-NULL, on return, points to the variable's attributes.
+ @param DataSize On entry, points to the size in bytes of the Data buffer.
+ On return, points to the size of the data returned in Data.
+ @param Data Points to the buffer which will hold the returned variable value.
+
+ @retval EFI_SUCCESS The variable was read successfully.
+ @retval EFI_NOT_FOUND The variable could not be found.
+ @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data.
+ DataSize is updated with the size required for
+ the specified variable.
+ @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetVariable (
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VariableGuid,
+ OUT UINT32 *Attributes,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ )
+{
+ VARIABLE_POINTER_TRACK Variable;
+ UINTN VarDataSize;
+ EFI_STATUS Status;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+ if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Find existing variable
+ //
+ Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
+ if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
+ return Status;
+ }
+ //
+ // Get data size
+ //
+ VarDataSize = DataSizeOfVariable (Variable.CurrPtr);
+ if (*DataSize >= VarDataSize) {
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
+
+ if (Attributes != NULL) {
+ *Attributes = Variable.CurrPtr->Attributes;
+ }
+
+ *DataSize = VarDataSize;
+ return EFI_SUCCESS;
+ } else {
+ *DataSize = VarDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+}
+
+/**
+ Return the next variable name and GUID.
+
+ This function is called multiple times to retrieve the VariableName
+ and VariableGuid of all variables currently available in the system.
+ On each call, the previous results are passed into the interface,
+ and, on return, the interface returns the data for the next
+ interface. When the entire variable list has been returned,
+ EFI_NOT_FOUND is returned.
+
+ @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
+
+ @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName.
+ On return, the size of the variable name buffer.
+ @param VariableName On entry, a pointer to a null-terminated string that is the variable's name.
+ On return, points to the next variable's null-terminated name string.
+ @param VariableGuid On entry, a pointer to an EFI_GUID that is the variable's GUID.
+ On return, a pointer to the next variable's GUID.
+
+ @retval EFI_SUCCESS The variable was read successfully.
+ @retval EFI_NOT_FOUND The variable could not be found.
+ @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting
+ data. VariableNameSize is updated with the size
+ required for the specified variable.
+ @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or
+ VariableNameSize is NULL.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetNextVariableName (
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VariableGuid
+ )
+{
+ VARIABLE_POINTER_TRACK Variable;
+ UINTN VarNameSize;
+ EFI_STATUS Status;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+ if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable);
+ if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ if (VariableName[0] != 0) {
+ //
+ // If variable name is not NULL, get next variable
+ //
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
+ }
+
+ while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) {
+ if (IsValidVariableHeader (Variable.CurrPtr)) {
+ if (Variable.CurrPtr->State == VAR_ADDED) {
+ ASSERT (NameSizeOfVariable (Variable.CurrPtr) != 0);
+
+ VarNameSize = (UINTN) NameSizeOfVariable (Variable.CurrPtr);
+ if (VarNameSize <= *VariableNameSize) {
+ CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);
+
+ CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID));
+
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *VariableNameSize = VarNameSize;
+ return Status;
+ //
+ // Variable is found
+ //
+ } else {
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
+ }
+ } else {
+ break;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/SecurityPkg/VariableAuthenticated/Pei/Variable.h b/SecurityPkg/VariableAuthenticated/Pei/Variable.h
new file mode 100644
index 0000000000..af22687fe8
--- /dev/null
+++ b/SecurityPkg/VariableAuthenticated/Pei/Variable.h
@@ -0,0 +1,128 @@
+/** @file
+ The internal header file includes the common header files, defines
+ internal structure and functions used by PeiVariable module.
+
+Copyright (c) 2009 - 2011, 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 _PEI_VARIABLE_H_
+#define _PEI_VARIABLE_H_
+
+#include <PiPei.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+
+#include <Guid/AuthenticatedVariableFormat.h>
+#include <Guid/VariableIndexTable.h>
+//
+// Functions
+//
+/**
+ Provide the functionality of the variable services.
+
+ @param FileHandle Handle of the file being invoked.
+ Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().
+ @param PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS If the interface could be successfully installed
+ @retval Others Returned from PeiServicesInstallPpi()
+
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeVariableServices (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This service retrieves a variable's value using its name and GUID.
+
+ Read the specified variable from the UEFI variable store. If the Data
+ buffer is too small to hold the contents of the variable, the error
+ EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer
+ size to obtain the data.
+
+ @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
+ @param VariableName A pointer to a null-terminated string that is the variable's name.
+ @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of
+ VariableGuid and VariableName must be unique.
+ @param Attributes If non-NULL, on return, points to the variable's attributes.
+ @param DataSize On entry, points to the size in bytes of the Data buffer.
+ On return, points to the size of the data returned in Data.
+ @param Data Points to the buffer which will hold the returned variable value.
+
+ @retval EFI_SUCCESS The variable was read successfully.
+ @retval EFI_NOT_FOUND The variable could not be found.
+ @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data.
+ DataSize is updated with the size required for
+ the specified variable.
+ @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetVariable (
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN CONST CHAR16 *VariableName,
+ IN CONST EFI_GUID *VariableGuid,
+ OUT UINT32 *Attributes,
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data
+ );
+
+/**
+ Return the next variable name and GUID.
+
+ This function is called multiple times to retrieve the VariableName
+ and VariableGuid of all variables currently available in the system.
+ On each call, the previous results are passed into the interface,
+ and, on return, the interface returns the data for the next
+ interface. When the entire variable list has been returned,
+ EFI_NOT_FOUND is returned.
+
+ @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI.
+
+ @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName.
+ @param VariableName On entry, a pointer to a null-terminated string that is the variable's name.
+ On return, points to the next variable's null-terminated name string.
+
+ @param VariableGuid On entry, a pointer to an UEFI _GUID that is the variable's GUID.
+ On return, a pointer to the next variable's GUID.
+
+ @retval EFI_SUCCESS The variable was read successfully.
+ @retval EFI_NOT_FOUND The variable could not be found.
+ @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting
+ data. VariableNameSize is updated with the size
+ required for the specified variable.
+ @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or
+ VariableNameSize is NULL.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiGetNextVariableName (
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VariableGuid
+ );
+
+#endif
diff --git a/SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf b/SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
new file mode 100644
index 0000000000..7863293ff8
--- /dev/null
+++ b/SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
@@ -0,0 +1,64 @@
+## @file
+# The component description for PEI variable driver.
+#
+# Copyright (c) 2009 - 2011, 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 = 0x00010005
+ BASE_NAME = PeiVariable
+ FILE_GUID = B1F7AF2F-2807-478c-A893-2BF4DDD1F62B
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimInitializeVariableServices
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ Variable.c
+ Variable.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ PcdLib
+ HobLib
+ PeimEntryPoint
+ DebugLib
+ PeiServicesTablePointerLib
+ PeiServicesLib
+
+[Guids]
+ gEfiAuthenticatedVariableGuid
+ gEfiVariableIndexTableGuid
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_PRODUCES (Not for boot mode RECOVERY)
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES
+
+[Depex]
+ TRUE
+
+#
+# [BootMode]
+# RECOVERY ## CONSUMES
+#
+