Add security package to repository.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
gdong1
2011-09-02 07:49:32 +00:00
parent 986d1dfb08
commit 0c18794ea4
102 changed files with 38487 additions and 0 deletions

View File

@ -0,0 +1,268 @@
/** @file
If the Variable services have PcdVariableCollectStatistics set to TRUE then
this utility will print out the statistics information. You can use console
redirection to capture the data.
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 <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Guid/AuthenticatedVariableFormat.h>
#include <Guid/SmmVariableCommon.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/SmmVariable.h>
#define EFI_VARIABLE_GUID \
{ 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } }
EFI_GUID mEfiVariableGuid = EFI_VARIABLE_GUID;
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
/**
This function get the variable statistics data from SMM variable driver.
@param[in, out] SmmCommunicateHeader In input, a pointer to a collection of data that will
be passed into an SMM environment. In output, a pointer
to a collection of data that comes from an SMM environment.
@param[in, out] SmmCommunicateSize The size of the SmmCommunicateHeader.
@retval EFI_SUCCESS Get the statistics data information.
@retval EFI_NOT_FOUND Not found.
@retval EFI_BUFFER_TO_SMALL DataSize is too small for the result.
**/
EFI_STATUS
EFIAPI
GetVariableStatisticsData (
IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader,
IN OUT UINTN *SmmCommunicateSize
)
{
EFI_STATUS Status;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);
SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) &SmmCommunicateHeader->Data[0];
SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS;
Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, SmmCommunicateSize);
ASSERT_EFI_ERROR (Status);
Status = SmmVariableFunctionHeader->ReturnStatus;
return Status;
}
/**
This function get and print the variable statistics data from SMM variable driver.
@retval EFI_SUCCESS Print the statistics information successfully.
@retval EFI_NOT_FOUND Not found the statistics information.
**/
EFI_STATUS
PrintInfoFromSmm (
VOID
)
{
EFI_STATUS Status;
VARIABLE_INFO_ENTRY *VariableInfo;
EFI_SMM_COMMUNICATE_HEADER *CommBuffer;
UINTN RealCommSize;
UINTN CommSize;
SMM_VARIABLE_COMMUNICATE_HEADER *FunctionHeader;
EFI_SMM_VARIABLE_PROTOCOL *Smmvariable;
Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **) &Smmvariable);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
if (EFI_ERROR (Status)) {
return Status;
}
CommSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
RealCommSize = CommSize;
CommBuffer = AllocateZeroPool (CommSize);
ASSERT (CommBuffer != NULL);
Print (L"Non-Volatile SMM Variables:\n");
do {
Status = GetVariableStatisticsData (CommBuffer, &CommSize);
if (Status == EFI_BUFFER_TOO_SMALL) {
FreePool (CommBuffer);
CommBuffer = AllocateZeroPool (CommSize);
ASSERT (CommBuffer != NULL);
RealCommSize = CommSize;
Status = GetVariableStatisticsData (CommBuffer, &CommSize);
}
if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {
break;
}
if (CommSize < RealCommSize) {
CommSize = RealCommSize;
}
FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;
VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;
if (!VariableInfo->Volatile) {
Print (
L"%g R%03d(%03d) W%03d D%03d:%s\n",
&VariableInfo->VendorGuid,
VariableInfo->ReadCount,
VariableInfo->CacheCount,
VariableInfo->WriteCount,
VariableInfo->DeleteCount,
(CHAR16 *)(VariableInfo + 1)
);
}
} while (TRUE);
Print (L"Volatile SMM Variables:\n");
ZeroMem (CommBuffer, CommSize);
do {
Status = GetVariableStatisticsData (CommBuffer, &CommSize);
if (Status == EFI_BUFFER_TOO_SMALL) {
FreePool (CommBuffer);
CommBuffer = AllocateZeroPool (CommSize);
ASSERT (CommBuffer != NULL);
RealCommSize = CommSize;
Status = GetVariableStatisticsData (CommBuffer, &CommSize);
}
if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {
break;
}
if (CommSize < RealCommSize) {
CommSize = RealCommSize;
}
FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;
VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;
if (VariableInfo->Volatile) {
Print (
L"%g R%03d(%03d) W%03d D%03d:%s\n",
&VariableInfo->VendorGuid,
VariableInfo->ReadCount,
VariableInfo->CacheCount,
VariableInfo->WriteCount,
VariableInfo->DeleteCount,
(CHAR16 *)(VariableInfo + 1)
);
}
} while (TRUE);
FreePool (CommBuffer);
return Status;
}
/**
The user Entry Point for Application. The user code starts with this function
as the real entry point for the image goes into a library that calls this
function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VARIABLE_INFO_ENTRY *VariableInfo;
VARIABLE_INFO_ENTRY *Entry;
Status = EfiGetSystemConfigurationTable (&mEfiVariableGuid, (VOID **)&Entry);
if (EFI_ERROR (Status) || (Entry == NULL)) {
Status = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry);
}
if (EFI_ERROR (Status) || (Entry == NULL)) {
Status = PrintInfoFromSmm ();
if (!EFI_ERROR (Status)) {
return Status;
}
}
if (!EFI_ERROR (Status) && (Entry != NULL)) {
Print (L"Non-Volatile EFI Variables:\n");
VariableInfo = Entry;
do {
if (!VariableInfo->Volatile) {
Print (
L"%g R%03d(%03d) W%03d D%03d:%s\n",
&VariableInfo->VendorGuid,
VariableInfo->ReadCount,
VariableInfo->CacheCount,
VariableInfo->WriteCount,
VariableInfo->DeleteCount,
VariableInfo->Name
);
}
VariableInfo = VariableInfo->Next;
} while (VariableInfo != NULL);
Print (L"Volatile EFI Variables:\n");
VariableInfo = Entry;
do {
if (VariableInfo->Volatile) {
Print (
L"%g R%03d(%03d) W%03d D%03d:%s\n",
&VariableInfo->VendorGuid,
VariableInfo->ReadCount,
VariableInfo->CacheCount,
VariableInfo->WriteCount,
VariableInfo->DeleteCount,
VariableInfo->Name
);
}
VariableInfo = VariableInfo->Next;
} while (VariableInfo != NULL);
} else {
Print (L"Warning: Variable Dxe driver doesn't enable the feature of statistical information!\n");
Print (L"If you want to see this info, please:\n");
Print (L" 1. Set PcdVariableCollectStatistics as TRUE\n");
Print (L" 2. Rebuild Variable Dxe driver\n");
Print (L" 3. Run \"VariableInfo\" cmd again\n");
}
return Status;
}

View File

@ -0,0 +1,54 @@
## @file
# This is a shell application that will display statistical information
# about variable usage.
# Note that if Variable Dxe driver doesn't enable the feature by setting
# PcdVariableCollectStatistics as TRUE, The application will not display
# variable statistical information.
#
# 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 = VariableInfo
FILE_GUID = B9EF901F-A2A2-4fc8-8D2B-3A2E07B301CC
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
VariableInfo.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
MemoryAllocationLib
[Protocols]
gEfiSmmCommunicationProtocolGuid
gEfiSmmVariableProtocolGuid
[Guids]
gEfiAuthenticatedVariableGuid ## CONSUMES ## Configuration Table Guid

View File

@ -0,0 +1,174 @@
/** @file
The variable data structures are related to EDKII-specific
implementation of UEFI authenticated variables.
AuthenticatedVariableFormat.h defines variable data headers
and variable storage region headers.
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 __AUTHENTICATED_VARIABLE_FORMAT_H__
#define __AUTHENTICATED_VARIABLE_FORMAT_H__
#define EFI_AUTHENTICATED_VARIABLE_GUID \
{ 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
extern EFI_GUID gEfiAuthenticatedVariableGuid;
///
/// Alignment of variable name and data, according to the architecture:
/// * For IA-32 and Intel(R) 64 architectures: 1.
/// * For IA-64 architecture: 8.
///
#if defined (MDE_CPU_IPF)
#define ALIGNMENT 8
#else
#define ALIGNMENT 1
#endif
//
// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
//
#if (ALIGNMENT == 1)
#define GET_PAD_SIZE(a) (0)
#else
#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
#endif
///
/// Alignment of Variable Data Header in Variable Store region.
///
#define HEADER_ALIGNMENT 4
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
///
/// Status of Variable Store Region.
///
typedef enum {
EfiRaw,
EfiValid,
EfiInvalid,
EfiUnknown
} VARIABLE_STORE_STATUS;
#pragma pack(1)
#define VARIABLE_STORE_SIGNATURE EFI_AUTHENTICATED_VARIABLE_GUID
///
/// Variable Store Header Format and State.
///
#define VARIABLE_STORE_FORMATTED 0x5a
#define VARIABLE_STORE_HEALTHY 0xfe
///
/// Variable Store region header.
///
typedef struct {
///
/// Variable store region signature.
///
EFI_GUID Signature;
///
/// Size of entire variable store,
/// including size of variable store header but not including the size of FvHeader.
///
UINT32 Size;
///
/// Variable region format state.
///
UINT8 Format;
///
/// Variable region healthy state.
///
UINT8 State;
UINT16 Reserved;
UINT32 Reserved1;
} VARIABLE_STORE_HEADER;
///
/// Variable data start flag.
///
#define VARIABLE_DATA 0x55AA
///
/// Variable State flags.
///
#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition.
#define VAR_DELETED 0xfd ///< Variable is obsolete.
#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid.
#define VAR_ADDED 0x3f ///< Variable has been completely added.
///
/// Single Variable Data Header Structure.
///
typedef struct {
///
/// Variable Data Start Flag.
///
UINT16 StartId;
///
/// Variable State defined above.
///
UINT8 State;
UINT8 Reserved;
///
/// Attributes of variable defined in UEFI specification.
///
UINT32 Attributes;
///
/// Associated monotonic count value against replay attack.
///
UINT64 MonotonicCount;
///
/// Associated TimeStamp value against replay attack.
///
EFI_TIME TimeStamp;
///
/// Index of associated public key in database.
///
UINT32 PubKeyIndex;
///
/// Size of variable null-terminated Unicode string name.
///
UINT32 NameSize;
///
/// Size of the variable data without this header.
///
UINT32 DataSize;
///
/// A unique identifier for the vendor that produces and consumes this varaible.
///
EFI_GUID VendorGuid;
} VARIABLE_HEADER;
#pragma pack()
typedef struct _VARIABLE_INFO_ENTRY VARIABLE_INFO_ENTRY;
///
/// This structure contains the variable list that is put in EFI system table.
/// The variable driver collects all variables that were used at boot service time and produces this list.
/// This is an optional feature to dump all used variables in shell environment.
///
struct _VARIABLE_INFO_ENTRY {
VARIABLE_INFO_ENTRY *Next; ///< Pointer to next entry.
EFI_GUID VendorGuid; ///< Guid of Variable.
CHAR16 *Name; ///< Name of Variable.
UINT32 Attributes; ///< Attributes of variable defined in UEFI spec.
UINT32 ReadCount; ///< Number of times to read this variable.
UINT32 WriteCount; ///< Number of times to write this variable.
UINT32 DeleteCount; ///< Number of times to delete this variable.
UINT32 CacheCount; ///< Number of times that cache hits this variable.
BOOLEAN Volatile; ///< TRUE if volatile, FALSE if non-volatile.
};
#endif // __AUTHENTICATED_VARIABLE_FORMAT_H__

View File

@ -0,0 +1,76 @@
/** @file
Define the variable data structures used for TCG physical presence.
The TPM request from firmware or OS is saved to variable. And it is
cleared after it is processed in the next boot cycle. The TPM response
is saved to variable.
Copyright (c) 2006 - 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 __PHYSICAL_PRESENCE_DATA_GUID_H__
#define __PHYSICAL_PRESENCE_DATA_GUID_H__
#define EFI_PHYSICAL_PRESENCE_DATA_GUID \
{ \
0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }\
}
#define PHYSICAL_PRESENCE_VARIABLE L"PhysicalPresence"
typedef struct {
UINT8 PPRequest; ///< Physical Presence request command.
UINT8 LastPPRequest;
UINT32 PPResponse;
UINT8 Flags;
} EFI_PHYSICAL_PRESENCE;
//
// The definition bit of the flags
//
#define FLAG_NO_PPI_PROVISION BIT0
#define FLAG_NO_PPI_CLEAR BIT1
#define FLAG_NO_PPI_MAINTENANCE BIT2
#define FLAG_RESET_TRACK BIT3
#define H2NS(x) ((((x) << 8) | ((x) >> 8)) & 0xffff)
#define H2NL(x) (H2NS ((x) >> 16) | (H2NS ((x) & 0xffff) << 16))
//
// The definition of physical presence operation actions
//
#define NO_ACTION 0
#define ENABLE 1
#define DISABLE 2
#define ACTIVATE 3
#define DEACTIVATE 4
#define CLEAR 5
#define ENABLE_ACTIVATE 6
#define DEACTIVATE_DISABLE 7
#define SET_OWNER_INSTALL_TRUE 8
#define SET_OWNER_INSTALL_FALSE 9
#define ENABLE_ACTIVATE_OWNER_TRUE 10
#define DEACTIVATE_DISABLE_OWNER_FALSE 11
#define DEFERRED_PP_UNOWNERED_FIELD_UPGRADE 12
#define SET_OPERATOR_AUTH 13
#define CLEAR_ENABLE_ACTIVATE 14
#define SET_NO_PPI_PROVISION_FALSE 15
#define SET_NO_PPI_PROVISION_TRUE 16
#define SET_NO_PPI_CLEAR_FALSE 17
#define SET_NO_PPI_CLEAR_TRUE 18
#define SET_NO_PPI_MAINTENANCE_FALSE 19
#define SET_NO_PPI_MAINTENANCE_TRUE 20
#define ENABLE_ACTIVATE_CLEAR 21
#define ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE 22
extern EFI_GUID gEfiPhysicalPresenceGuid;
#endif

View File

@ -0,0 +1,25 @@
/** @file
GUID for SecurityPkg PCD Token Space.
Copyright (c) 2009 - 2010, 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 _SECURITYPKG_TOKEN_SPACE_GUID_H_
#define _SECURITYPKG_TOKEN_SPACE_GUID_H_
#define SECURITYPKG_TOKEN_SPACE_GUID \
{ \
0xd3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba } \
}
extern EFI_GUID gEfiSecurityPkgTokenSpaceGuid;
#endif

View File

@ -0,0 +1,30 @@
/** @file
Defines the HOB GUID used to pass a TCG_PCR_EVENT from a TPM PEIM to
a TPM DXE Driver. A GUIDed HOB is generated for each measurement
made in the PEI Phase.
Copyright (c) 2007 - 2010, 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 _TCG_EVENT_HOB_H_
#define _TCG_EVENT_HOB_H_
///
/// The Global ID of a GUIDed HOB used to pass a TCG_PCR_EVENT from a TPM PEIM to a TPM DXE Driver.
///
#define EFI_TCG_EVENT_HOB_GUID \
{ \
0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 } \
}
extern EFI_GUID gTcgEventEntryHobGuid;
#endif

View File

@ -0,0 +1,42 @@
/** @file
Provides a secure platform-specific method to clear PK(Platform Key).
Copyright (c) 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 __PLATFORM_SECURE_LIB_H__
#define __PLATFORM_SECURE_LIB_H__
/**
This function detects whether a secure platform-specific method to clear PK(Platform Key)
is configured by platform owner. This method is provided for users force to clear PK
in case incorrect enrollment mis-haps.
UEFI231 spec chapter 27.5.2 stipulates: The platform key may also be cleared using
a secure platform-specific method. In this case, the global variable SetupMode
must also be updated to 1.
NOTE THAT: This function cannot depend on any EFI Variable Service since they are
not available when this function is called in AuthenticateVariable driver.
@retval TRUE The Platform owner wants to force clear PK.
@retval FALSE The Platform owner doesn't want to force clear PK.
**/
BOOLEAN
EFIAPI
ForceClearPK (
VOID
);
#endif

View File

@ -0,0 +1,286 @@
/** @file
Ihis library is only intended to be used by TPM modules.
It provides basic TPM Interface Specification (TIS) and Command functions.
Copyright (c) 2005 - 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 _TPM_COMM_LIB_H_
#define _TPM_COMM_LIB_H_
#include <IndustryStandard/Tpm12.h>
typedef EFI_HANDLE TIS_TPM_HANDLE;
///
/// TPM register base address.
///
#define TPM_BASE_ADDRESS 0xfed40000
//
// Set structure alignment to 1-byte
//
#pragma pack (1)
//
// Register set map as specified in TIS specification Chapter 10
//
typedef struct {
///
/// Used to gain ownership for this particular port.
///
UINT8 Access; // 0
UINT8 Reserved1[7]; // 1
///
/// Controls interrupts.
///
UINT32 IntEnable; // 8
///
/// SIRQ vector to be used by the TPM.
///
UINT8 IntVector; // 0ch
UINT8 Reserved2[3]; // 0dh
///
/// What caused interrupt.
///
UINT32 IntSts; // 10h
///
/// Shows which interrupts are supported by that particular TPM.
///
UINT32 IntfCapability; // 14h
///
/// Status Register. Provides status of the TPM.
///
UINT8 Status; // 18h
///
/// Number of consecutive writes that can be done to the TPM.
///
UINT16 BurstCount; // 19h
UINT8 Reserved3[9];
///
/// Read or write FIFO, depending on transaction.
///
UINT32 DataFifo; // 24
UINT8 Reserved4[0xed8]; // 28h
///
/// Vendor ID
///
UINT16 Vid; // 0f00h
///
/// Device ID
///
UINT16 Did; // 0f02h
///
/// Revision ID
///
UINT8 Rid; // 0f04h
///
/// TCG defined configuration registers.
///
UINT8 TcgDefined[0x7b]; // 0f05h
///
/// Alias to I/O legacy space.
///
UINT32 LegacyAddress1; // 0f80h
///
/// Additional 8 bits for I/O legacy space extension.
///
UINT32 LegacyAddress1Ex; // 0f84h
///
/// Alias to second I/O legacy space.
///
UINT32 LegacyAddress2; // 0f88h
///
/// Additional 8 bits for second I/O legacy space extension.
///
UINT32 LegacyAddress2Ex; // 0f8ch
///
/// Vendor-defined configuration registers.
///
UINT8 VendorDefined[0x70];// 0f90h
} TIS_PC_REGISTERS;
//
// Restore original structure alignment
//
#pragma pack ()
//
// Define pointer types used to access TIS registers on PC
//
typedef TIS_PC_REGISTERS *TIS_PC_REGISTERS_PTR;
//
// TCG Platform Type based on TCG ACPI Specification Version 1.00
//
#define TCG_PLATFORM_TYPE_CLIENT 0
#define TCG_PLATFORM_TYPE_SERVER 1
//
// Define bits of ACCESS and STATUS registers
//
///
/// This bit is a 1 to indicate that the other bits in this register are valid.
///
#define TIS_PC_VALID BIT7
///
/// Indicate that this locality is active.
///
#define TIS_PC_ACC_ACTIVE BIT5
///
/// Set to 1 to indicate that this locality had the TPM taken away while
/// this locality had the TIS_PC_ACC_ACTIVE bit set.
///
#define TIS_PC_ACC_SEIZED BIT4
///
/// Set to 1 to indicate that TPM MUST reset the
/// TIS_PC_ACC_ACTIVE bit and remove ownership for localities less than the
/// locality that is writing this bit.
///
#define TIS_PC_ACC_SEIZE BIT3
///
/// When this bit is 1, another locality is requesting usage of the TPM.
///
#define TIS_PC_ACC_PENDIND BIT2
///
/// Set to 1 to indicate that this locality is requesting to use TPM.
///
#define TIS_PC_ACC_RQUUSE BIT1
///
/// A value of 1 indicates that a T/OS has not been established on the platform
///
#define TIS_PC_ACC_ESTABLISH BIT0
///
/// When this bit is 1, TPM is in the Ready state,
/// indicating it is ready to receive a new command.
///
#define TIS_PC_STS_READY BIT6
///
/// Write a 1 to this bit to cause the TPM to execute that command.
///
#define TIS_PC_STS_GO BIT5
///
/// This bit indicates that the TPM has data available as a response.
///
#define TIS_PC_STS_DATA BIT4
///
/// The TPM sets this bit to a value of 1 when it expects another byte of data for a command.
///
#define TIS_PC_STS_EXPECT BIT3
///
/// Writes a 1 to this bit to force the TPM to re-send the response.
///
#define TIS_PC_STS_RETRY BIT1
//
// Default TimeOut value
//
#define TIS_TIMEOUT_B 2000 * 1000 // 2s
#define TIS_TIMEOUT_C 750 * 1000 // 750ms
#define TIS_TIMEOUT_D 750 * 1000 // 750ms
//
// Max TPM command/reponse length
//
#define TPMCMDBUFLENGTH 1024
/**
Check whether the value of a TPM chip register satisfies the input BIT setting.
@param[in] Register Address port of register to be checked.
@param[in] BitSet Check these data bits are set.
@param[in] BitClear Check these data bits are clear.
@param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
@retval EFI_SUCCESS The register satisfies the check bit.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
**/
EFI_STATUS
EFIAPI
TisPcWaitRegisterBits (
IN UINT8 *Register,
IN UINT8 BitSet,
IN UINT8 BitClear,
IN UINT32 TimeOut
);
/**
Get BurstCount by reading the burstCount field of a TIS regiger
in the time of default TIS_TIMEOUT_D.
@param[in] TisReg Pointer to TIS register.
@param[out] BurstCount Pointer to a buffer to store the got BurstConut.
@retval EFI_SUCCESS Get BurstCount.
@retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
@retval EFI_TIMEOUT BurstCount can't be got in time.
**/
EFI_STATUS
EFIAPI
TisPcReadBurstCount (
IN TIS_PC_REGISTERS_PTR TisReg,
OUT UINT16 *BurstCount
);
/**
Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
to Status Register in time.
@param[in] TisReg Pointer to TIS register.
@retval EFI_SUCCESS TPM chip enters into ready state.
@retval EFI_INVALID_PARAMETER TisReg is NULL.
@retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
**/
EFI_STATUS
EFIAPI
TisPcPrepareCommand (
IN TIS_PC_REGISTERS_PTR TisReg
);
/**
Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
to ACCESS Register in the time of default TIS_TIMEOUT_D.
@param[in] TisReg Pointer to TIS register.
@retval EFI_SUCCESS Get the control of TPM chip.
@retval EFI_INVALID_PARAMETER TisReg is NULL.
@retval EFI_NOT_FOUND TPM chip doesn't exit.
@retval EFI_TIMEOUT Can't get the TPM control in time.
**/
EFI_STATUS
EFIAPI
TisPcRequestUseTpm (
IN TIS_PC_REGISTERS_PTR TisReg
);
/**
Single function calculates SHA1 digest value for all raw data. It
combines Sha1Init(), Sha1Update() and Sha1Final().
@param[in] Data Raw data to be digested.
@param[in] DataLen Size of the raw data.
@param[out] Digest Pointer to a buffer that stores the final digest.
@retval EFI_SUCCESS Always successfully calculate the final digest.
**/
EFI_STATUS
EFIAPI
TpmCommHashAll (
IN CONST UINT8 *Data,
IN UINTN DataLen,
OUT TPM_DIGEST *Digest
);
#endif

View File

@ -0,0 +1,60 @@
/** @file
This file defines the lock physical Presence PPI. This PPI is
produced by a platform specific PEIM and consumed by the TPM
PEIM.
Copyright (c) 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_LOCK_PHYSICAL_PRESENCE_H__
#define __PEI_LOCK_PHYSICAL_PRESENCE_H__
///
/// Global ID for the PEI_LOCK_PHYSICAL_PRESENCE_PPI_GUID.
///
#define PEI_LOCK_PHYSICAL_PRESENCE_PPI_GUID \
{ \
0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0xd } \
}
///
/// Forward declaration for the PEI_LOCK_PHYSICAL_PRESENCE_PPI
///
typedef struct _PEI_LOCK_PHYSICAL_PRESENCE_PPI PEI_LOCK_PHYSICAL_PRESENCE_PPI;
/**
This interface returns whether TPM physical presence needs be locked.
@param[in] PeiServices The pointer to the PEI Services Table.
@retval TRUE The TPM physical presence should be locked.
@retval FALSE The TPM physical presence cannot be locked.
**/
typedef
BOOLEAN
(EFIAPI *PEI_LOCK_PHYSICAL_PRESENCE)(
IN CONST EFI_PEI_SERVICES **PeiServices
);
///
/// This service abstracts TPM physical presence lock interface. It is necessary for
/// safety to convey this information to the TPM driver so that TPM physical presence
/// can be locked as early as possible. This PPI is produced by a platform specific
/// PEIM and consumed by the TPM PEIM.
///
struct _PEI_LOCK_PHYSICAL_PRESENCE_PPI {
PEI_LOCK_PHYSICAL_PRESENCE LockPhysicalPresence;
};
extern EFI_GUID gPeiLockPhysicalPresencePpiGuid;
#endif // __PEI_LOCK_PHYSICAL_PRESENCE_H__

View File

@ -0,0 +1,30 @@
/** @file
Tag GUID that must be installed by the TPM PEIM after the TPM hardware is
initialized. PEIMs that must execute after TPM hardware initialization
may use this GUID in their dependency expressions.
Copyright (c) 2008 - 2010, 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_TPM_INITIALIZED_PPI_H_
#define _PEI_TPM_INITIALIZED_PPI_H_
///
/// Global ID for the PEI_TPM_INITIALIZED_PPI which always uses a NULL interface.
///
#define PEI_TPM_INITIALIZED_PPI_GUID \
{ \
0xe9db0d58, 0xd48d, 0x47f6, 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 \
}
extern EFI_GUID gPeiTpmInitializedPpiGuid;
#endif

View File

@ -0,0 +1,858 @@
/** @file
Implement defer image load services for user identification in UEFI2.2.
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 "DxeDeferImageLoadLib.h"
//
// Handle for the Deferred Image Load Protocol instance produced by this driver.
//
EFI_HANDLE mDeferredImageHandle = NULL;
BOOLEAN mIsProtocolInstalled = FALSE;
EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;
DEFERRED_IMAGE_TABLE mDeferredImage = {
0, // Deferred image count
NULL // The deferred image info
};
EFI_DEFERRED_IMAGE_LOAD_PROTOCOL gDeferredImageLoad = {
GetDefferedImageInfo
};
/**
Get the image type.
@param[in] File This is a pointer to the device path of the file
that is being dispatched.
@return UINT32 Image Type
**/
UINT32
GetFileType (
IN CONST EFI_DEVICE_PATH_PROTOCOL *File
)
{
EFI_STATUS Status;
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
//
// First check to see if File is from a Firmware Volume
//
DeviceHandle = NULL;
TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
Status = gBS->LocateDevicePath (
&gEfiFirmwareVolume2ProtocolGuid,
&TempDevicePath,
&DeviceHandle
);
if (!EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
DeviceHandle,
&gEfiFirmwareVolume2ProtocolGuid,
NULL,
NULL,
NULL,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
return IMAGE_FROM_FV;
}
}
//
// Next check to see if File is from a Block I/O device
//
DeviceHandle = NULL;
TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
Status = gBS->LocateDevicePath (
&gEfiBlockIoProtocolGuid,
&TempDevicePath,
&DeviceHandle
);
if (!EFI_ERROR (Status)) {
BlockIo = NULL;
Status = gBS->OpenProtocol (
DeviceHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status) && BlockIo != NULL) {
if (BlockIo->Media != NULL) {
if (BlockIo->Media->RemovableMedia) {
//
// Block I/O is present and specifies the media is removable
//
return IMAGE_FROM_REMOVABLE_MEDIA;
} else {
//
// Block I/O is present and specifies the media is not removable
//
return IMAGE_FROM_FIXED_MEDIA;
}
}
}
}
//
// File is not in a Firmware Volume or on a Block I/O device, so check to see if
// the device path supports the Simple File System Protocol.
//
DeviceHandle = NULL;
TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
Status = gBS->LocateDevicePath (
&gEfiSimpleFileSystemProtocolGuid,
&TempDevicePath,
&DeviceHandle
);
if (!EFI_ERROR (Status)) {
//
// Simple File System is present without Block I/O, so assume media is fixed.
//
return IMAGE_FROM_FIXED_MEDIA;
}
//
// File is not from an FV, Block I/O or Simple File System, so the only options
// left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.
//
TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
while (!IsDevicePathEndType (TempDevicePath)) {
switch (DevicePathType (TempDevicePath)) {
case MEDIA_DEVICE_PATH:
if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {
return IMAGE_FROM_OPTION_ROM;
}
break;
case MESSAGING_DEVICE_PATH:
if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {
return IMAGE_FROM_REMOVABLE_MEDIA;
}
break;
default:
break;
}
TempDevicePath = NextDevicePathNode (TempDevicePath);
}
return IMAGE_UNKNOWN;
}
/**
Get current user's access right.
@param[out] AccessControl Points to the user's access control data, the
caller should free data buffer.
@param[in] AccessType The type of user access control.
@retval EFI_SUCCESS Get current user access control successfully
@retval others Fail to get current user access control
**/
EFI_STATUS
GetAccessControl (
OUT EFI_USER_INFO_ACCESS_CONTROL **AccessControl,
IN UINT32 AccessType
)
{
EFI_STATUS Status;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_INFO *Info;
UINTN InfoSize;
EFI_USER_INFO_ACCESS_CONTROL *Access;
EFI_USER_PROFILE_HANDLE CurrentUser;
UINTN CheckLen;
EFI_USER_MANAGER_PROTOCOL *UserManager;
CurrentUser = NULL;
Status = gBS->LocateProtocol (
&gEfiUserManagerProtocolGuid,
NULL,
(VOID **) &UserManager
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Get current user access information.
//
UserManager->Current (UserManager, &CurrentUser);
UserInfo = NULL;
Info = NULL;
InfoSize = 0;
while (TRUE) {
//
// Get next user information.
//
Status = UserManager->GetNextInfo (UserManager, CurrentUser, &UserInfo);
if (EFI_ERROR (Status)) {
return Status;
}
Status = UserManager->GetInfo (
UserManager,
CurrentUser,
UserInfo,
Info,
&InfoSize
);
if (Status == EFI_BUFFER_TOO_SMALL) {
if (Info != NULL) {
FreePool (Info);
}
Info = AllocateZeroPool (InfoSize);
ASSERT (Info != NULL);
Status = UserManager->GetInfo (
UserManager,
CurrentUser,
UserInfo,
Info,
&InfoSize
);
}
if (EFI_ERROR (Status)) {
break;
}
ASSERT (Info != NULL);
if (Info->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD) {
continue;
}
//
// Get specified access information.
//
CheckLen = 0;
while (CheckLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {
Access = (EFI_USER_INFO_ACCESS_CONTROL *) ((UINT8 *) (Info + 1) + CheckLen);
if ((Access->Type == AccessType)) {
*AccessControl = AllocateZeroPool (Access->Size);
ASSERT (*AccessControl != NULL);
CopyMem (*AccessControl, Access, Access->Size);
FreePool (Info);
return EFI_SUCCESS;
}
CheckLen += Access->Size;
}
}
if (Info != NULL) {
FreePool (Info);
}
return EFI_NOT_FOUND;
}
/**
Convert the '/' to '\' in the specified string.
@param[in, out] Str Points to the string to convert.
**/
VOID
ConvertDPStr (
IN OUT EFI_STRING Str
)
{
INTN Count;
INTN Index;
Count = StrSize(Str) / 2 - 1;
if (Count < 4) {
return;
}
//
// Convert device path string.
//
Index = Count - 1;
while (Index > 0) {
//
// Find the last '/'.
//
for (Index = Count - 1; Index > 0; Index--) {
if (Str[Index] == L'/')
break;
}
//
// Check next char.
//
if (Str[Index + 1] == L'\\')
return;
Str[Index] = L'\\';
//
// Check previous char.
//
if ((Index > 0) && (Str[Index - 1] == L'\\')) {
CopyMem (&Str[Index - 1], &Str[Index], (UINTN) ((Count - Index + 1) * sizeof (CHAR16)));
return;
}
Index--;
}
}
/**
Check whether the DevicePath2 is identical with DevicePath1, or identical with
DevicePath1's child device path.
If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device
path, then TRUE returned. Otherwise, FALSE is returned.
If DevicePath1 is NULL, then ASSERT().
If DevicePath2 is NULL, then ASSERT().
@param[in] DevicePath1 A pointer to a device path.
@param[in] DevicePath2 A pointer to a device path.
@retval TRUE Two device paths are identical , or DevicePath2 is
DevicePath1's child device path.
@retval FALSE Two device paths are not identical, and DevicePath2
is not DevicePath1's child device path.
**/
BOOLEAN
CheckDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2
)
{
EFI_STATUS Status;
EFI_STRING DevicePathStr1;
EFI_STRING DevicePathStr2;
UINTN StrLen1;
UINTN StrLen2;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText;
BOOLEAN DevicePathEqual;
ASSERT (DevicePath1 != NULL);
ASSERT (DevicePath2 != NULL);
DevicePathEqual = FALSE;
DevicePathText = NULL;
Status = gBS->LocateProtocol (
&gEfiDevicePathToTextProtocolGuid,
NULL,
(VOID **) &DevicePathText
);
ASSERT (Status == EFI_SUCCESS);
//
// Get first device path string.
//
DevicePathStr1 = DevicePathText->ConvertDevicePathToText (DevicePath1, TRUE, TRUE);
ConvertDPStr (DevicePathStr1);
//
// Get second device path string.
//
DevicePathStr2 = DevicePathText->ConvertDevicePathToText (DevicePath2, TRUE, TRUE);
ConvertDPStr (DevicePathStr2);
//
// Compare device path string.
//
StrLen1 = StrSize (DevicePathStr1);
StrLen2 = StrSize (DevicePathStr2);
if (StrLen1 > StrLen2) {
DevicePathEqual = FALSE;
goto Done;
}
if (CompareMem (DevicePathStr1, DevicePathStr2, StrLen1) == 0) {
DevicePathEqual = TRUE;
}
Done:
FreePool (DevicePathStr1);
FreePool (DevicePathStr2);
return DevicePathEqual;
}
/**
Check whether the image pointed to by DevicePath is in the device path list
specified by AccessType.
@param[in] DevicePath Points to device path.
@param[in] AccessType The type of user access control.
@retval TURE The DevicePath is in the specified List.
@retval FALSE The DevicePath is not in the specified List.
**/
BOOLEAN
IsDevicePathInList (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN UINT32 AccessType
)
{
EFI_STATUS Status;
EFI_USER_INFO_ACCESS_CONTROL *Access;
EFI_DEVICE_PATH_PROTOCOL *Path;
UINTN OffSet;
Status = GetAccessControl (&Access, AccessType);
if (EFI_ERROR (Status)) {
return FALSE;
}
OffSet = 0;
while (OffSet < Access->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {
Path = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(Access + 1) + OffSet);
if (CheckDevicePath (Path, DevicePath)) {
//
// The device path is found in list.
//
FreePool (Access);
return TRUE;
}
OffSet += GetDevicePathSize (Path);
}
FreePool (Access);
return FALSE;
}
/**
Check whether the image pointed to by DevicePath is permitted to load.
@param[in] DevicePath Points to device path
@retval TURE The image pointed by DevicePath is permitted to load.
@retval FALSE The image pointed by DevicePath is forbidden to load.
**/
BOOLEAN
VerifyDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_PERMIT_LOAD)) {
//
// This access control overrides any restrictions put in place by the
// EFI_USER_INFO_ACCESS_FORBID_LOAD record.
//
return TRUE;
}
if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_FORBID_LOAD)) {
//
// The device path is found in the forbidden list.
//
return FALSE;
}
return TRUE;
}
/**
Check the image pointed by DevicePath is a boot option or not.
@param[in] DevicePath Points to device path.
@retval TURE The image pointed by DevicePath is a boot option.
@retval FALSE The image pointed by DevicePath is not a boot option.
**/
BOOLEAN
IsBootOption (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_STATUS Status;
UINT16 *BootOrderList;
UINTN BootOrderListSize;
UINTN Index;
CHAR16 StrTemp[20];
UINT8 *OptionBuffer;
UINT8 *OptionPtr;
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
//
// Get BootOrder
//
BootOrderListSize = 0;
BootOrderList = NULL;
Status = gRT->GetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
NULL,
&BootOrderListSize,
NULL
);
if (Status == EFI_BUFFER_TOO_SMALL) {
BootOrderList = AllocateZeroPool (BootOrderListSize);
ASSERT (BootOrderList != NULL);
Status = gRT->GetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
NULL,
&BootOrderListSize,
BootOrderList
);
}
if (EFI_ERROR (Status)) {
//
// No Boot option
//
return FALSE;
}
OptionBuffer = NULL;
for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {
//
// Try to find the DevicePath in BootOption
//
UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);
OptionBuffer = GetEfiGlobalVariable (StrTemp);
if (OptionBuffer == NULL) {
continue;
}
//
// Check whether the image is forbidden.
//
OptionPtr = OptionBuffer;
//
// Skip attribute.
//
OptionPtr += sizeof (UINT32);
//
// Skip device path length.
//
OptionPtr += sizeof (UINT16);
//
// Skip descript string
//
OptionPtr += StrSize ((UINT16 *) OptionPtr);
//
// Now OptionPtr points to Device Path.
//
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) OptionPtr;
if (CheckDevicePath (DevicePath, OptionDevicePath)) {
FreePool (OptionBuffer);
OptionBuffer = NULL;
return TRUE;
}
FreePool (OptionBuffer);
OptionBuffer = NULL;
}
if (BootOrderList != NULL) {
FreePool (BootOrderList);
}
return FALSE;
}
/**
Add the image info to a deferred image list.
@param[in] ImageDevicePath A pointer to the device path of a image.
@param[in] Image Points to the first byte of the image, or NULL if the
image is not available.
@param[in] ImageSize The size of the image, or 0 if the image is not available.
**/
VOID
PutDefferedImageInfo (
IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,
IN VOID *Image,
IN UINTN ImageSize
)
{
DEFERRED_IMAGE_INFO *CurImageInfo;
UINTN PathSize;
//
// Expand memory for the new deferred image.
//
if (mDeferredImage.Count == 0) {
mDeferredImage.ImageInfo = AllocatePool (sizeof (DEFERRED_IMAGE_INFO));
ASSERT (mDeferredImage.ImageInfo != NULL);
} else {
CurImageInfo = AllocatePool ((mDeferredImage.Count + 1) * sizeof (DEFERRED_IMAGE_INFO));
ASSERT (CurImageInfo != NULL);
CopyMem (
CurImageInfo,
mDeferredImage.ImageInfo,
mDeferredImage.Count * sizeof (DEFERRED_IMAGE_INFO)
);
FreePool (mDeferredImage.ImageInfo);
mDeferredImage.ImageInfo = CurImageInfo;
}
mDeferredImage.Count++;
//
// Save the deferred image information.
//
CurImageInfo = &mDeferredImage.ImageInfo[mDeferredImage.Count - 1];
PathSize = GetDevicePathSize (ImageDevicePath);
CurImageInfo->ImageDevicePath = AllocateZeroPool (PathSize);
ASSERT (CurImageInfo->ImageDevicePath != NULL);
CopyMem (CurImageInfo->ImageDevicePath, ImageDevicePath, PathSize);
CurImageInfo->Image = Image;
CurImageInfo->ImageSize = ImageSize;
CurImageInfo->BootOption = IsBootOption (ImageDevicePath);
}
/**
Returns information about a deferred image.
This function returns information about a single deferred image. The deferred images are
numbered consecutively, starting with 0. If there is no image which corresponds to
ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by
iteratively calling this function until EFI_NOT_FOUND is returned.
Image may be NULL and ImageSize set to 0 if the decision to defer execution was made
because of the location of the executable image, rather than its actual contents.
@param[in] This Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.
@param[in] ImageIndex Zero-based index of the deferred index.
@param[out] ImageDevicePath On return, points to a pointer to the device path of the image.
The device path should not be freed by the caller.
@param[out] Image On return, points to the first byte of the image or NULL if the
image is not available. The image should not be freed by the caller
unless LoadImage() has been successfully called.
@param[out] ImageSize On return, the size of the image, or 0 if the image is not available.
@param[out] BootOption On return, points to TRUE if the image was intended as a boot option
or FALSE if it was not intended as a boot option.
@retval EFI_SUCCESS Image information returned successfully.
@retval EFI_NOT_FOUND ImageIndex does not refer to a valid image.
@retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or
BootOption is NULL.
**/
EFI_STATUS
EFIAPI
GetDefferedImageInfo (
IN EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *This,
IN UINTN ImageIndex,
OUT EFI_DEVICE_PATH_PROTOCOL **ImageDevicePath,
OUT VOID **Image,
OUT UINTN *ImageSize,
OUT BOOLEAN *BootOption
)
{
DEFERRED_IMAGE_INFO *ReqImageInfo;
//
// Check the parameter.
//
if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((ImageDevicePath == NULL) || (BootOption == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (ImageIndex >= mDeferredImage.Count) {
return EFI_NOT_FOUND;
}
//
// Get the request deferred image.
//
ReqImageInfo = &mDeferredImage.ImageInfo[ImageIndex];
*ImageDevicePath = ReqImageInfo->ImageDevicePath;
*Image = ReqImageInfo->Image;
*ImageSize = ReqImageInfo->ImageSize;
*BootOption = ReqImageInfo->BootOption;
return EFI_SUCCESS;
}
/**
Provides the service of deferring image load based on platform policy control,
and installs Deferred Image Load Protocol.
@param[in] AuthenticationStatus This is the authentication status returned from the
security measurement services for the input file.
@param[in] File This is a pointer to the device path of the file that
is being dispatched. This will optionally be used for
logging.
@param[in] FileBuffer File buffer matches the input file device path.
@param[in] FileSize Size of File buffer matches the input file device path.
@retval EFI_SUCCESS The file specified by File did authenticate, and the
platform policy dictates that the DXE Core may use File.
@retval EFI_INVALID_PARAMETER File is NULL.
@retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and
the platform policy dictates that File should be placed
in the untrusted state. A file may be promoted from
the untrusted to the trusted state at a future time
with a call to the Trust() DXE Service.
@retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and
the platform policy dictates that File should not be
used for any purpose.
**/
EFI_STATUS
EFIAPI
DxeDeferImageLoadHandler (
IN UINT32 AuthenticationStatus,
IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
IN VOID *FileBuffer,
IN UINTN FileSize
)
{
EFI_STATUS Status;
EFI_USER_PROFILE_HANDLE CurrentUser;
UINT32 Policy;
UINT32 FileType;
if (File == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check whether user has a logon.
//
CurrentUser = NULL;
if (mUserManager != NULL) {
mUserManager->Current (mUserManager, &CurrentUser);
if (CurrentUser != NULL) {
//
// The user is logon; verify the FilePath by current user access policy.
//
if (!VerifyDevicePath (File)) {
DEBUG ((EFI_D_ERROR, "[Security] The image is forbidden to load!\n"));
return EFI_ACCESS_DENIED;
}
return EFI_SUCCESS;
}
}
//
// Still no user logon.
// Check the file type and get policy setting.
//
FileType = GetFileType (File);
Policy = PcdGet32 (PcdDeferImageLoadPolicy);
if ((Policy & FileType) == FileType) {
//
// This file type is secure to load.
//
return EFI_SUCCESS;
}
DEBUG ((EFI_D_ERROR, "[Security] No user identified, the image is deferred to load!\n"));
PutDefferedImageInfo (File, NULL, 0);
//
// Install the Deferred Image Load Protocol onto a new handle.
//
if (!mIsProtocolInstalled) {
Status = gBS->InstallMultipleProtocolInterfaces (
&mDeferredImageHandle,
&gEfiDeferredImageLoadProtocolGuid,
&gDeferredImageLoad,
NULL
);
ASSERT_EFI_ERROR (Status);
mIsProtocolInstalled = TRUE;
}
return EFI_ACCESS_DENIED;
}
/**
Locate user manager protocol when user manager is installed.
@param[in] Event The Event that is being processed, not used.
@param[in] Context Event Context, not used.
**/
VOID
EFIAPI
FindUserManagerProtocol (
IN EFI_EVENT Event,
IN VOID* Context
)
{
gBS->LocateProtocol (
&gEfiUserManagerProtocolGuid,
NULL,
(VOID **) &mUserManager
);
}
/**
Register security handler for deferred image load.
@param[in] ImageHandle ImageHandle of the loaded driver.
@param[in] SystemTable Pointer to the EFI System Table.
@retval EFI_SUCCESS The handlers were registered successfully.
**/
EFI_STATUS
EFIAPI
DxeDeferImageLoadLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
VOID *Registration;
//
// Register user manager notification function.
//
EfiCreateProtocolNotifyEvent (
&gEfiUserManagerProtocolGuid,
TPL_CALLBACK,
FindUserManagerProtocol,
NULL,
&Registration
);
return RegisterSecurityHandler (
DxeDeferImageLoadHandler,
EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD
);
}

View File

@ -0,0 +1,106 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by DeferImageLoadLib.
Copyright (c) 2009 - 2010, 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 __DEFER_IMAGE_LOAD_LIB_H__
#define __DEFER_IMAGE_LOAD_LIB_H__
#include <PiDxe.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SecurityManagementLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/BlockIo.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/DeferredImageLoad.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
#include <Protocol/DevicePathToText.h>
#include <Guid/GlobalVariable.h>
//
// Image type definitions.
//
#define IMAGE_UNKNOWN 0x00000001
#define IMAGE_FROM_FV 0x00000002
#define IMAGE_FROM_OPTION_ROM 0x00000004
#define IMAGE_FROM_REMOVABLE_MEDIA 0x00000008
#define IMAGE_FROM_FIXED_MEDIA 0x00000010
//
// The struct to save the deferred image information.
//
typedef struct {
EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
VOID *Image;
UINTN ImageSize;
BOOLEAN BootOption;
} DEFERRED_IMAGE_INFO;
//
// The table to save the deferred image item.
//
typedef struct {
UINTN Count; ///< deferred image count
DEFERRED_IMAGE_INFO *ImageInfo; ///< deferred image item
} DEFERRED_IMAGE_TABLE;
/**
Returns information about a deferred image.
This function returns information about a single deferred image. The deferred images are
numbered consecutively, starting with 0. If there is no image which corresponds to
ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by
iteratively calling this function until EFI_NOT_FOUND is returned.
Image may be NULL and ImageSize set to 0 if the decision to defer execution was made
because of the location of the executable image, rather than its actual contents.
@param[in] This Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.
@param[in] ImageIndex Zero-based index of the deferred index.
@param[out] ImageDevicePath On return, points to a pointer to the device path of the image.
The device path should not be freed by the caller.
@param[out] Image On return, points to the first byte of the image or NULL if the
image is not available. The image should not be freed by the caller
unless LoadImage() has been called successfully.
@param[out] ImageSize On return, the size of the image, or 0 if the image is not available.
@param[out] BootOption On return, points to TRUE if the image was intended as a boot option
or FALSE if it was not intended as a boot option.
@retval EFI_SUCCESS Image information returned successfully.
@retval EFI_NOT_FOUND ImageIndex does not refer to a valid image.
@retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or
BootOption is NULL.
**/
EFI_STATUS
EFIAPI
GetDefferedImageInfo (
IN EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *This,
IN UINTN ImageIndex,
OUT EFI_DEVICE_PATH_PROTOCOL **ImageDevicePath,
OUT VOID **Image,
OUT UINTN *ImageSize,
OUT BOOLEAN *BootOption
);
#endif

View File

@ -0,0 +1,62 @@
## @file
# The library instance provides security service of deferring image load.
#
# Copyright (c) 2009 - 2010, 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 = DxeDeferImageLoadLib
FILE_GUID = 5E2FAE1F-41DA-4fbd-BC81-603CE5CD8497
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
CONSTRUCTOR = DxeDeferImageLoadLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
DxeDeferImageLoadLib.c
DxeDeferImageLoadLib.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
SecurityManagementLib
MemoryAllocationLib
DevicePathLib
BaseMemoryLib
PrintLib
DebugLib
UefiLib
PcdLib
[Protocols]
gEfiFirmwareVolume2ProtocolGuid
gEfiBlockIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid
gEfiUserManagerProtocolGuid
gEfiDeferredImageLoadProtocolGuid
gEfiDevicePathToTextProtocolGuid
[Guids]
gEfiGlobalVariableGuid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdDeferImageLoadPolicy

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by ImageVerificationLib.
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 __IMAGEVERIFICATIONLIB_H__
#define __IMAGEVERIFICATIONLIB_H__
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/PcdLib.h>
#include <Library/DevicePathLib.h>
#include <Library/SecurityManagementLib.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/DevicePath.h>
#include <Protocol/BlockIo.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/VariableWrite.h>
#include <Guid/ImageAuthentication.h>
#include <IndustryStandard/PeImage.h>
#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
#define EFI_CERT_TYPE_RSA2048_SIZE 256
#define MAX_NOTIFY_STRING_LEN 64
//
// Image type definitions
//
#define IMAGE_UNKNOWN 0x00000000
#define IMAGE_FROM_FV 0x00000001
#define IMAGE_FROM_OPTION_ROM 0x00000002
#define IMAGE_FROM_REMOVABLE_MEDIA 0x00000003
#define IMAGE_FROM_FIXED_MEDIA 0x00000004
//
// Authorization policy bit definition
//
#define ALWAYS_EXECUTE 0x00000000
#define NEVER_EXECUTE 0x00000001
#define ALLOW_EXECUTE_ON_SECURITY_VIOLATION 0x00000002
#define DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
#define DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
#define QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
//
// Support hash types
//
#define HASHALG_SHA1 0x00000000
#define HASHALG_SHA224 0x00000001
#define HASHALG_SHA256 0x00000002
#define HASHALG_SHA384 0x00000003
#define HASHALG_SHA512 0x00000004
#define HASHALG_MAX 0x00000005
//
// Set max digest size as SHA256 Output (32 bytes) by far
//
#define MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
//
//
// PKCS7 Certificate definition
//
typedef struct {
WIN_CERTIFICATE Hdr;
UINT8 CertData[1];
} WIN_CERTIFICATE_EFI_PKCS;
/**
Retrieves the size, in bytes, of the context buffer required for hash operations.
@return The size, in bytes, of the context buffer required for hash operations.
**/
typedef
UINTN
(EFIAPI *HASH_GET_CONTEXT_SIZE)(
VOID
);
/**
Initializes user-supplied memory pointed by HashContext as hash context for
subsequent use.
If HashContext is NULL, then ASSERT().
@param[in, out] HashContext Pointer to Context being initialized.
@retval TRUE HASH context initialization succeeded.
@retval FALSE HASH context initialization failed.
**/
typedef
BOOLEAN
(EFIAPI *HASH_INIT)(
IN OUT VOID *HashContext
);
/**
Performs digest on a data buffer of the specified length. This function can
be called multiple times to compute the digest of long or discontinuous data streams.
If HashContext is NULL, then ASSERT().
@param[in, out] HashContext Pointer to the MD5 context.
@param[in] Data Pointer to the buffer containing the data to be hashed.
@param[in] DataLength Length of Data buffer in bytes.
@retval TRUE HASH data digest succeeded.
@retval FALSE Invalid HASH context. After HashFinal function has been called, the
HASH context cannot be reused.
**/
typedef
BOOLEAN
(EFIAPI *HASH_UPDATE)(
IN OUT VOID *HashContext,
IN CONST VOID *Data,
IN UINTN DataLength
);
/**
Completes hash computation and retrieves the digest value into the specified
memory. After this function has been called, the context cannot be used again.
If HashContext is NULL, then ASSERT().
If HashValue is NULL, then ASSERT().
@param[in, out] HashContext Pointer to the MD5 context
@param[out] HashValue Pointer to a buffer that receives the HASH digest
value.
@retval TRUE HASH digest computation succeeded.
@retval FALSE HASH digest computation failed.
**/
typedef
BOOLEAN
(EFIAPI *HASH_FINAL)(
IN OUT VOID *HashContext,
OUT UINT8 *HashValue
);
//
// Hash Algorithm Table
//
typedef struct {
//
// Name for Hash Algorithm
//
CHAR16 *Name;
//
// Digest Length
//
UINTN DigestLength;
//
// Hash Algorithm OID ASN.1 Value
//
UINT8 *OidValue;
//
// Length of Hash OID Value
//
UINTN OidLength;
//
// Pointer to Hash GetContentSize function
//
HASH_GET_CONTEXT_SIZE GetContextSize;
//
// Pointer to Hash Init function
//
HASH_INIT HashInit;
//
// Pointer to Hash Update function
//
HASH_UPDATE HashUpdate;
//
// Pointer to Hash Final function
//
HASH_FINAL HashFinal;
} HASH_TABLE;
#endif

View File

@ -0,0 +1,73 @@
## @file
# The library instance provides security service of image verification.
# Image verification Library module supports UEFI2.3.1
#
# 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 = DxeImageVerificationLib
FILE_GUID = 0CA970E1-43FA-4402-BC0A-81AF336BFFD6
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = DxeImageVerificationLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
DxeImageVerificationLib.c
DxeImageVerificationLib.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
UefiLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
BaseMemoryLib
DebugLib
DevicePathLib
BaseCryptLib
SecurityManagementLib
[Protocols]
gEfiFirmwareVolume2ProtocolGuid
gEfiBlockIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid
gEfiVariableWriteArchProtocolGuid
[Guids]
gEfiCertTypeRsa2048Sha256Guid
gEfiImageSecurityDatabaseGuid
gEfiCertSha1Guid
gEfiCertSha256Guid
gEfiCertX509Guid
gEfiCertRsa2048Guid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy

View File

@ -0,0 +1,830 @@
/** @file
The library instance provides security service of TPM measure boot.
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 <PiDxe.h>
#include <Protocol/TcgService.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
#include <Protocol/DevicePathToText.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/PeCoffLib.h>
#include <Library/SecurityManagementLib.h>
//
// Flag to check GPT partition. It only need be measured once.
//
BOOLEAN mMeasureGptTableFlag = FALSE;
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
UINTN mMeasureGptCount = 0;
/**
Reads contents of a PE/COFF image in memory buffer.
@param FileHandle Pointer to the file handle to read the PE/COFF image.
@param FileOffset Offset into the PE/COFF image to begin the read operation.
@param ReadSize On input, the size in bytes of the requested read operation.
On output, the number of bytes actually read.
@param Buffer Output buffer that contains the data read from the PE/COFF image.
@retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
**/
EFI_STATUS
EFIAPI
ImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
)
{
CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
return EFI_SUCCESS;
}
/**
Measure GPT table data into TPM log.
@param TcgProtocol Pointer to the located TCG protocol instance.
@param GptHandle Handle that GPT partition was installed.
@retval EFI_SUCCESS Successfully measure GPT table.
@retval EFI_UNSUPPORTED Not support GPT table on the given handle.
@retval EFI_DEVICE_ERROR Can't get GPT table because device error.
@retval EFI_OUT_OF_RESOURCES No enough resource to measure GPT table.
@retval other error value
**/
EFI_STATUS
EFIAPI
TcgMeasureGptTable (
IN EFI_TCG_PROTOCOL *TcgProtocol,
IN EFI_HANDLE GptHandle
)
{
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_DISK_IO_PROTOCOL *DiskIo;
EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
EFI_PARTITION_ENTRY *PartitionEntry;
UINT8 *EntryPtr;
UINTN NumberOfPartition;
UINT32 Index;
TCG_PCR_EVENT *TcgEvent;
EFI_GPT_DATA *GptData;
UINT32 EventSize;
UINT32 EventNumber;
EFI_PHYSICAL_ADDRESS EventLogLastEntry;
if (mMeasureGptCount > 0) {
return EFI_SUCCESS;
}
Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID**)&DiskIo);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// Read the EFI Partition Table Header
//
PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *) AllocatePool (BlockIo->Media->BlockSize);
if (PrimaryHeader == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
1 * BlockIo->Media->BlockSize,
BlockIo->Media->BlockSize,
(UINT8 *)PrimaryHeader
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Failed to Read Partition Table Header!\n"));
FreePool (PrimaryHeader);
return EFI_DEVICE_ERROR;
}
//
// Read the partition entry.
//
EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
if (EntryPtr == NULL) {
FreePool (PrimaryHeader);
return EFI_OUT_OF_RESOURCES;
}
Status = DiskIo->ReadDisk (
DiskIo,
BlockIo->Media->MediaId,
MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
EntryPtr
);
if (EFI_ERROR (Status)) {
FreePool (PrimaryHeader);
FreePool (EntryPtr);
return EFI_DEVICE_ERROR;
}
//
// Count the valid partition
//
PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
NumberOfPartition = 0;
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mZeroGuid)) {
NumberOfPartition++;
}
PartitionEntry++;
}
//
// Parepare Data for Measurement
//
EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions)
+ NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);
TcgEvent = (TCG_PCR_EVENT *) AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));
if (TcgEvent == NULL) {
FreePool (PrimaryHeader);
FreePool (EntryPtr);
return EFI_OUT_OF_RESOURCES;
}
TcgEvent->PCRIndex = 5;
TcgEvent->EventType = EV_EFI_GPT_EVENT;
TcgEvent->EventSize = EventSize;
GptData = (EFI_GPT_DATA *) TcgEvent->Event;
//
// Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
//
CopyMem ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
GptData->NumberOfPartitions = NumberOfPartition;
//
// Copy the valid partition entry
//
PartitionEntry = (EFI_PARTITION_ENTRY*)EntryPtr;
NumberOfPartition = 0;
for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
if (!CompareGuid (&PartitionEntry->PartitionTypeGUID, &mZeroGuid)) {
CopyMem (
(UINT8 *)&GptData->Partitions + NumberOfPartition * sizeof (EFI_PARTITION_ENTRY),
(UINT8 *)PartitionEntry,
sizeof (EFI_PARTITION_ENTRY)
);
NumberOfPartition++;
}
PartitionEntry++;
}
//
// Measure the GPT data
//
EventNumber = 1;
Status = TcgProtocol->HashLogExtendEvent (
TcgProtocol,
(EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) GptData,
(UINT64) TcgEvent->EventSize,
TPM_ALG_SHA,
TcgEvent,
&EventNumber,
&EventLogLastEntry
);
if (!EFI_ERROR (Status)) {
mMeasureGptCount++;
}
FreePool (PrimaryHeader);
FreePool (EntryPtr);
FreePool (TcgEvent);
return Status;
}
/**
Measure PE image into TPM log based on the authenticode image hashing in
PE/COFF Specification 8.0 Appendix A.
@param[in] TcgProtocol Pointer to the located TCG protocol instance.
@param[in] ImageAddress Start address of image buffer.
@param[in] ImageSize Image size
@param[in] LinkTimeBase Address that the image is loaded into memory.
@param[in] ImageType Image subsystem type.
@param[in] FilePath File path is corresponding to the input image.
@retval EFI_SUCCESS Successfully measure image.
@retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
@retval other error value
**/
EFI_STATUS
EFIAPI
TcgMeasurePeImage (
IN EFI_TCG_PROTOCOL *TcgProtocol,
IN EFI_PHYSICAL_ADDRESS ImageAddress,
IN UINTN ImageSize,
IN UINTN LinkTimeBase,
IN UINT16 ImageType,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
)
{
EFI_STATUS Status;
TCG_PCR_EVENT *TcgEvent;
EFI_IMAGE_LOAD_EVENT *ImageLoad;
UINT32 FilePathSize;
VOID *Sha1Ctx;
UINTN CtxSize;
EFI_IMAGE_DOS_HEADER *DosHdr;
UINT32 PeCoffHeaderOffset;
EFI_IMAGE_SECTION_HEADER *Section;
UINT8 *HashBase;
UINTN HashSize;
UINTN SumOfBytesHashed;
EFI_IMAGE_SECTION_HEADER *SectionHeader;
UINTN Index, Pos;
UINT16 Magic;
UINT32 EventSize;
UINT32 EventNumber;
EFI_PHYSICAL_ADDRESS EventLogLastEntry;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
Status = EFI_SUCCESS;
ImageLoad = NULL;
SectionHeader = NULL;
Sha1Ctx = NULL;
FilePathSize = (UINT32) GetDevicePathSize (FilePath);
//
// Determine destination PCR by BootPolicy
//
EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;
TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));
if (TcgEvent == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TcgEvent->EventSize = EventSize;
ImageLoad = (EFI_IMAGE_LOAD_EVENT *) TcgEvent->Event;
switch (ImageType) {
case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
TcgEvent->EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
TcgEvent->PCRIndex = 4;
break;
case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
TcgEvent->EventType = EV_EFI_BOOT_SERVICES_DRIVER;
TcgEvent->PCRIndex = 2;
break;
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
TcgEvent->EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
TcgEvent->PCRIndex = 2;
break;
default:
DEBUG ((
EFI_D_ERROR,
"TcgMeasurePeImage: Unknown subsystem type %d",
ImageType
));
ASSERT (FALSE);
TcgEvent->EventType = ImageType;
Status = EFI_UNSUPPORTED;
goto Finish;
}
ImageLoad->ImageLocationInMemory = ImageAddress;
ImageLoad->ImageLengthInMemory = ImageSize;
ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
ImageLoad->LengthOfDevicePath = FilePathSize;
CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
//
// Check PE/COFF image
//
DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;
PeCoffHeaderOffset = 0;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
PeCoffHeaderOffset = DosHdr->e_lfanew;
}
if (((EFI_TE_IMAGE_HEADER *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset))->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE) {
goto Finish;
}
//
// PE/COFF Image Measurement
//
// NOTE: The following codes/steps are based upon the authenticode image hashing in
// PE/COFF Specification 8.0 Appendix A.
//
//
// 1. Load the image header into memory.
// 2. Initialize a SHA hash context.
CtxSize = Sha1GetContextSize ();
Sha1Ctx = AllocatePool (CtxSize);
if (Sha1Ctx == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Finish;
}
Sha1Init (Sha1Ctx);
//
// Measuring PE/COFF Image Header;
// But CheckSum field and SECURITY data directory (certificate) are excluded
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);
Magic = Hdr.Pe32->OptionalHeader.Magic;
//
// 3. Calculate the distance from the base of the image header to the image checksum address.
// 4. Hash the image header from its base to beginning of the image checksum.
//
HashBase = (UINT8 *) (UINTN) ImageAddress;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase);
} else {
//
// Use PE32+ offset
//
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase);
}
Sha1Update (Sha1Ctx, HashBase, HashSize);
//
// 5. Skip over the image checksum (it occupies a single ULONG).
// 6. Get the address of the beginning of the Cert Directory.
// 7. Hash everything from the end of the checksum to the start of the Cert Directory.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
} else {
//
// Use PE32+ offset
//
HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
}
Sha1Update (Sha1Ctx, HashBase, HashSize);
//
// 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
// 9. Hash everything from the end of the Cert Directory to the end of image header.
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders -
(UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) (UINTN) ImageAddress);
} else {
//
// Use PE32+ offset
//
HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders -
(UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) (UINTN) ImageAddress);
}
Sha1Update (Sha1Ctx, HashBase, HashSize);
//
// 10. Set the SUM_OF_BYTES_HASHED to the size of the header
//
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
} else {
//
// Use PE32+ offset
//
SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
}
//
// 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
// structures in the image. The 'NumberOfSections' field of the image
// header indicates how big the table should be. Do not include any
// IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
//
SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);
if (SectionHeader == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Finish;
}
//
// 12. Using the 'PointerToRawData' in the referenced section headers as
// a key, arrange the elements in the table in ascending order. In other
// words, sort the section headers according to the disk-file offset of
// the section.
//
Section = (EFI_IMAGE_SECTION_HEADER *) (
(UINT8 *) (UINTN) ImageAddress +
PeCoffHeaderOffset +
sizeof(UINT32) +
sizeof(EFI_IMAGE_FILE_HEADER) +
Hdr.Pe32->FileHeader.SizeOfOptionalHeader
);
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
Pos = Index;
while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));
Pos--;
}
CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));
Section += 1;
}
//
// 13. Walk through the sorted table, bring the corresponding section
// into memory, and hash the entire section (using the 'SizeOfRawData'
// field in the section header to determine the amount of data to hash).
// 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
// 15. Repeat steps 13 and 14 for all the sections in the sorted table.
//
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
Section = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];
if (Section->SizeOfRawData == 0) {
continue;
}
HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;
HashSize = (UINTN) Section->SizeOfRawData;
Sha1Update (Sha1Ctx, HashBase, HashSize);
SumOfBytesHashed += HashSize;
}
//
// 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
// data in the file that needs to be added to the hash. This data begins
// at file offset SUM_OF_BYTES_HASHED and its length is:
// FileSize - (CertDirectory->Size)
//
if (ImageSize > SumOfBytesHashed) {
HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
//
HashSize = (UINTN)(ImageSize -
Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
SumOfBytesHashed);
} else {
//
// Use PE32+ offset
//
HashSize = (UINTN)(ImageSize -
Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
SumOfBytesHashed);
}
Sha1Update (Sha1Ctx, HashBase, HashSize);
}
//
// 17. Finalize the SHA hash.
//
Sha1Final (Sha1Ctx, (UINT8 *)&TcgEvent->Digest);
//
// Log the PE data
//
EventNumber = 1;
Status = TcgProtocol->HashLogExtendEvent (
TcgProtocol,
(EFI_PHYSICAL_ADDRESS) (UINTN) (VOID *) NULL,
0,
TPM_ALG_SHA,
TcgEvent,
&EventNumber,
&EventLogLastEntry
);
Finish:
FreePool (TcgEvent);
if (SectionHeader != NULL) {
FreePool (SectionHeader);
}
if (Sha1Ctx != NULL ) {
FreePool (Sha1Ctx);
}
return Status;
}
/**
The security handler is used to abstract platform-specific policy
from the DXE core response to an attempt to use a file that returns a
given status for the authentication check from the section extraction protocol.
The possible responses in a given SAP implementation may include locking
flash upon failure to authenticate, attestation logging for all signed drivers,
and other exception operations. The File parameter allows for possible logging
within the SAP of the driver.
If File is NULL, then EFI_INVALID_PARAMETER is returned.
If the file specified by File with an authentication status specified by
AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.
If the file specified by File with an authentication status specified by
AuthenticationStatus is not safe for the DXE Core to use under any circumstances,
then EFI_ACCESS_DENIED is returned.
If the file specified by File with an authentication status specified by
AuthenticationStatus is not safe for the DXE Core to use right now, but it
might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is
returned.
@param[in, out] AuthenticationStatus This is the authentication status returned
from the securitymeasurement services for the
input file.
@param[in] File This is a pointer to the device path of the file that is
being dispatched. This will optionally be used for logging.
@param[in] FileBuffer File buffer matches the input file device path.
@param[in] FileSize Size of File buffer matches the input file device path.
@retval EFI_SUCCESS The file specified by File did authenticate, and the
platform policy dictates that the DXE Core may use File.
@retval EFI_INVALID_PARAMETER File is NULL.
@retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and
the platform policy dictates that File should be placed
in the untrusted state. A file may be promoted from
the untrusted to the trusted state at a future time
with a call to the Trust() DXE Service.
@retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and
the platform policy dictates that File should not be
used for any purpose.
**/
EFI_STATUS
EFIAPI
DxeTpmMeasureBootHandler (
IN OUT UINT32 AuthenticationStatus,
IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
IN VOID *FileBuffer OPTIONAL,
IN UINTN FileSize OPTIONAL
)
{
EFI_TCG_PROTOCOL *TcgProtocol;
EFI_STATUS Status;
TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability;
UINT32 TCGFeatureFlags;
EFI_PHYSICAL_ADDRESS EventLogLocation;
EFI_PHYSICAL_ADDRESS EventLogLastEntry;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
EFI_HANDLE Handle;
BOOLEAN ApplicationRequired;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
if (File == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
if (EFI_ERROR (Status)) {
//
// TCG protocol is not installed. So, TPM is not present.
// Don't do any measurement, and directly return EFI_SUCCESS.
//
return EFI_SUCCESS;
}
ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);
Status = TcgProtocol->StatusCheck (
TcgProtocol,
&ProtocolCapability,
&TCGFeatureFlags,
&EventLogLocation,
&EventLogLastEntry
);
if (EFI_ERROR (Status) || ProtocolCapability.TPMDeactivatedFlag) {
//
// TPM device doesn't work or activate.
//
return EFI_SUCCESS;
}
//
// Copy File Device Path
//
OrigDevicePathNode = DuplicateDevicePath (File);
ASSERT (OrigDevicePathNode != NULL);
//
// 1. Check whether this device path support BlockIo protocol.
// Is so, this device path may be a GPT device path.
//
DevicePathNode = OrigDevicePathNode;
Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
if (!EFI_ERROR (Status) && !mMeasureGptTableFlag) {
//
// Find the gpt partion on the given devicepath
//
DevicePathNode = OrigDevicePathNode;
while (!IsDevicePathEnd (DevicePathNode)) {
//
// Find the Gpt partition
//
if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&
DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {
//
// Check whether it is a gpt partition or not
//
if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER &&
((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) {
//
// Change the partition device path to its parent device path (disk) and get the handle.
//
DevicePathNode->Type = END_DEVICE_PATH_TYPE;
DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
DevicePathNode = OrigDevicePathNode;
Status = gBS->LocateDevicePath (
&gEfiDiskIoProtocolGuid,
&DevicePathNode,
&Handle
);
if (!EFI_ERROR (Status)) {
//
// Measure GPT disk.
//
Status = TcgMeasureGptTable (TcgProtocol, Handle);
if (!EFI_ERROR (Status)) {
//
// GPT disk check done.
//
mMeasureGptTableFlag = TRUE;
}
}
FreePool (OrigDevicePathNode);
OrigDevicePathNode = DuplicateDevicePath (File);
ASSERT (OrigDevicePathNode != NULL);
break;
}
}
DevicePathNode = NextDevicePathNode (DevicePathNode);
}
}
//
// 2. Measure PE image.
//
ApplicationRequired = FALSE;
//
// Check whether this device path support FV2 protocol.
//
DevicePathNode = OrigDevicePathNode;
Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);
if (!EFI_ERROR (Status)) {
//
// Don't check FV image, and directly return EFI_SUCCESS.
// It can be extended to the specific FV authentication according to the different requirement.
//
if (IsDevicePathEnd (DevicePathNode)) {
return EFI_SUCCESS;
}
//
// The image from Firmware image will not be mearsured.
// Current policy doesn't measure PeImage from Firmware if it is driver
// If the got PeImage is application, it will be still be measured.
//
ApplicationRequired = TRUE;
}
//
// File is not found.
//
if (FileBuffer == NULL) {
Status = EFI_SECURITY_VIOLATION;
goto Finish;
}
//
// Measure PE Image
//
DevicePathNode = OrigDevicePathNode;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = (VOID *) FileBuffer;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) ImageRead;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
//
// The information can't be got from the invalid PeImage
//
goto Finish;
}
//
// Measure only application if Application flag is set
// Measure drivers and applications if Application flag is not set
//
if ((!ApplicationRequired) ||
(ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {
//
// Print the image path to be measured.
//
DEBUG_CODE_BEGIN ();
CHAR16 *ToText;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
Status = gBS->LocateProtocol (
&gEfiDevicePathToTextProtocolGuid,
NULL,
(VOID **) &DevPathToText
);
if (!EFI_ERROR (Status)) {
ToText = DevPathToText->ConvertDevicePathToText (
DevicePathNode,
FALSE,
TRUE
);
if (ToText != NULL) {
DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));
}
}
DEBUG_CODE_END ();
//
// Measure PE image into TPM log.
//
Status = TcgMeasurePeImage (
TcgProtocol,
(EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer,
FileSize,
(UINTN) ImageContext.ImageAddress,
ImageContext.ImageType,
DevicePathNode
);
}
//
// Done, free the allocated resource.
//
Finish:
FreePool (OrigDevicePathNode);
return Status;
}
/**
Register the security handler to provide TPM measure boot service.
@param ImageHandle ImageHandle of the loaded driver.
@param SystemTable Pointer to the EFI System Table.
@retval EFI_SUCCESS Register successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
**/
EFI_STATUS
EFIAPI
DxeTpmMeasureBootLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return RegisterSecurityHandler (
DxeTpmMeasureBootHandler,
EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED
);
}

View File

@ -0,0 +1,54 @@
## @file
# The library instance provides security service of TPM measure boot.
#
# Copyright (c) 2009 - 2010, 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 = DxeTpmMeasureBootLib
FILE_GUID = 6C60C7D0-922A-4b7c-87D7-E503EDD73BBF
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = DxeTpmMeasureBootLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
DxeTpmMeasureBootLib.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
CryptoPkg/CryptoPkg.dec
[LibraryClasses]
BaseMemoryLib
DebugLib
MemoryAllocationLib
DevicePathLib
UefiBootServicesTableLib
BaseCryptLib
PeCoffLib
BaseLib
SecurityManagementLib
[Protocols]
gEfiTcgProtocolGuid ## CONSUMES
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
gEfiBlockIoProtocolGuid ## CONSUMES
gEfiDiskIoProtocolGuid ## CONSUMES
gEfiDevicePathToTextProtocolGuid ## SOMETIMES_CONSUMES (Only used in debug mode)

View File

@ -0,0 +1,39 @@
/** @file
Provides a secure platform-specific method to clear PK(Platform Key).
Copyright (c) 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.
**/
/**
This function detects whether a secure platform-specific method to clear PK(Platform Key)
is configured by platform owner. This method is provided for users force to clear PK
in case incorrect enrollment mis-haps.
UEFI231 spec chapter 27.5.2 stipulates: The platform key may also be cleared using
a secure platform-specific method. In this case, the global variable SetupMode
must also be updated to 1.
NOTE THAT: This function cannot depend on any EFI Variable Service since they are
not available when this function is called in AuthenticateVariable driver.
@retval TRUE The Platform owner wants to force clear PK.
@retval FALSE The Platform owner doesn't want to force clear PK.
**/
BOOLEAN
EFIAPI
ForceClearPK (
VOID
)
{
return FALSE;
}

View File

@ -0,0 +1,33 @@
## @file
# Provides a secure platform-specific method to clear PK(Platform Key).
#
# Copyright (c) 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 = PlatformSecureLibNull
FILE_GUID = 7FA68D82-10A4-4e71-9524-D3D9500D3CDF
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = PlatformSecureLib|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
PlatformSecureLibNull.c
[Packages]
MdePkg/MdePkg.dec

View File

@ -0,0 +1,29 @@
/** @file
The intenal header file for TpmCommLib.
Copyright (c) 2006 - 2010, 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 _TPMCOMMLIB_COMMON_HEADER_H_
#define _TPMCOMMLIB_COMMON_HEADER_H_
#include <PiPei.h>
#include <IndustryStandard/Tpm12.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
#include <Library/TpmCommLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#endif

View File

@ -0,0 +1,180 @@
/** @file
Basic TIS (TPM Interface Specification) functions.
Copyright (c) 2005 - 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 "CommonHeader.h"
/**
Check whether TPM chip exist.
@param[in] TisReg Pointer to TIS register.
@retval TRUE TPM chip exists.
@retval FALSE TPM chip is not found.
**/
BOOLEAN
TisPcPresenceCheck (
IN TIS_PC_REGISTERS_PTR TisReg
)
{
UINT8 RegRead;
RegRead = MmioRead8 ((UINTN)&TisReg->Access);
return (BOOLEAN)(RegRead != (UINT8)-1);
}
/**
Check whether the value of a TPM chip register satisfies the input BIT setting.
@param[in] Register Address port of register to be checked.
@param[in] BitSet Check these data bits are set.
@param[in] BitClear Check these data bits are clear.
@param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
@retval EFI_SUCCESS The register satisfies the check bit.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
**/
EFI_STATUS
EFIAPI
TisPcWaitRegisterBits (
IN UINT8 *Register,
IN UINT8 BitSet,
IN UINT8 BitClear,
IN UINT32 TimeOut
)
{
UINT8 RegRead;
UINT32 WaitTime;
for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
RegRead = MmioRead8 ((UINTN)Register);
if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
return EFI_SUCCESS;
MicroSecondDelay (30);
}
return EFI_TIMEOUT;
}
/**
Get BurstCount by reading the burstCount field of a TIS regiger
in the time of default TIS_TIMEOUT_D.
@param[in] TisReg Pointer to TIS register.
@param[out] BurstCount Pointer to a buffer to store the got BurstConut.
@retval EFI_SUCCESS Get BurstCount.
@retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
@retval EFI_TIMEOUT BurstCount can't be got in time.
**/
EFI_STATUS
EFIAPI
TisPcReadBurstCount (
IN TIS_PC_REGISTERS_PTR TisReg,
OUT UINT16 *BurstCount
)
{
UINT32 WaitTime;
UINT8 DataByte0;
UINT8 DataByte1;
if (BurstCount == NULL || TisReg == NULL) {
return EFI_INVALID_PARAMETER;
}
WaitTime = 0;
do {
//
// TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
// so it needs to use MmioRead8 to read two times
//
DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
*BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
if (*BurstCount != 0) {
return EFI_SUCCESS;
}
MicroSecondDelay (30);
WaitTime += 30;
} while (WaitTime < TIS_TIMEOUT_D);
return EFI_TIMEOUT;
}
/**
Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
to Status Register in time.
@param[in] TisReg Pointer to TIS register.
@retval EFI_SUCCESS TPM chip enters into ready state.
@retval EFI_INVALID_PARAMETER TisReg is NULL.
@retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
**/
EFI_STATUS
EFIAPI
TisPcPrepareCommand (
IN TIS_PC_REGISTERS_PTR TisReg
)
{
EFI_STATUS Status;
if (TisReg == NULL) {
return EFI_INVALID_PARAMETER;
}
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
Status = TisPcWaitRegisterBits (
&TisReg->Status,
TIS_PC_STS_READY,
0,
TIS_TIMEOUT_B
);
return Status;
}
/**
Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
to ACCESS Register in the time of default TIS_TIMEOUT_D.
@param[in] TisReg Pointer to TIS register.
@retval EFI_SUCCESS Get the control of TPM chip.
@retval EFI_INVALID_PARAMETER TisReg is NULL.
@retval EFI_NOT_FOUND TPM chip doesn't exit.
@retval EFI_TIMEOUT Can't get the TPM control in time.
**/
EFI_STATUS
EFIAPI
TisPcRequestUseTpm (
IN TIS_PC_REGISTERS_PTR TisReg
)
{
EFI_STATUS Status;
if (TisReg == NULL) {
return EFI_INVALID_PARAMETER;
}
if (!TisPcPresenceCheck (TisReg)) {
return EFI_NOT_FOUND;
}
MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
Status = TisPcWaitRegisterBits (
&TisReg->Access,
(UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
0,
TIS_TIMEOUT_D
);
return Status;
}

View File

@ -0,0 +1,50 @@
/** @file
Basic TPM command functions.
Copyright (c) 2005 - 2010, 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 "CommonHeader.h"
/**
Single function calculates SHA1 digest value for all raw data. It
combines Sha1Init(), Sha1Update() and Sha1Final().
@param[in] Data Raw data to be digested.
@param[in] DataLen Size of the raw data.
@param[out] Digest Pointer to a buffer that stores the final digest.
@retval EFI_SUCCESS Always successfully calculate the final digest.
**/
EFI_STATUS
EFIAPI
TpmCommHashAll (
IN CONST UINT8 *Data,
IN UINTN DataLen,
OUT TPM_DIGEST *Digest
)
{
VOID *Sha1Ctx;
UINTN CtxSize;
CtxSize = Sha1GetContextSize ();
Sha1Ctx = AllocatePool (CtxSize);
ASSERT (Sha1Ctx != NULL);
Sha1Init (Sha1Ctx);
Sha1Update (Sha1Ctx, Data, DataLen);
Sha1Final (Sha1Ctx, (UINT8 *)Digest);
FreePool (Sha1Ctx);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,46 @@
## @file
# TpmCommLib instance implements basis TPM Interface Specification (TIS) and TPM command functions.
#
# Copyright (c) 2006 - 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 = TpmCommLib
FILE_GUID = 7d9fe32e-a6a9-4cdf-abff-10cc7f22e1c9
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = TpmCommLib|DXE_DRIVER UEFI_DRIVER PEIM DXE_SMM_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF
#
[Sources]
TisPc.c
TpmComm.c
CommonHeader.h
[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
CryptoPkg/CryptoPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
IoLib
TimerLib
BaseCryptLib
MemoryAllocationLib
DebugLib

122
SecurityPkg/SecurityPkg.dec Normal file
View File

@ -0,0 +1,122 @@
## @file SecurityPkg.dec
# This package includes the security drivers, defintions(including PPIs/PROTOCOLs/GUIDs
# and library classes) and libraries instances.
#
# 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]
DEC_SPECIFICATION = 0x00010005
PACKAGE_NAME = SecurityPkg
PACKAGE_GUID = 24369CAC-6AA6-4fb8-88DB-90BF061668AD
PACKAGE_VERSION = 0.91
[Includes]
Include
[LibraryClasses]
## @libraryclass Definitions for common TPM commands as library API for TPM
# module use.
TpmCommLib|Include/Library/TpmCommLib.h
[Guids]
## Security package token space guid
# Include/Guid/SecurityPkgTokenSpace.h
gEfiSecurityPkgTokenSpaceGuid = { 0xd3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba }}
## Guid acted as the authenticated variable store header's signature, and to specify the variable list entries put in the EFI system table.
# Include/Guid/AuthenticatedVariableFormat.h
gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
## Include/Guid/TcgEventHob.h
gTcgEventEntryHobGuid = { 0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 }}
## Include/Guid/PhysicalPresenceData.h
gEfiPhysicalPresenceGuid = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }}
[Ppis]
## Include/Ppi/LockPhysicalPresence.h
gPeiLockPhysicalPresencePpiGuid = { 0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0xd } }
## Include/Ppi/TpmInitialized.h
gPeiTpmInitializedPpiGuid = { 0xe9db0d58, 0xd48d, 0x47f6, { 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 }}
[PcdsFixedAtBuild]
## Pcd for OptionRom.
# Image verification policy settings:
# ALWAYS_EXECUTE 0x00000000
# NEVER_EXECUTE 0x00000001
# ALLOW_EXECUTE_ON_SECURITY_VIOLATION 0x00000002
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00|UINT32|0x00000001
## Pcd for removable media.
# Removable media include CD-ROM, Floppy, USB and network.
# Image verification policy settings:
# ALWAYS_EXECUTE 0x00000000
# NEVER_EXECUTE 0x00000001
# ALLOW_EXECUTE_ON_SECURITY_VIOLATION 0x00000002
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x05|UINT32|0x00000002
## Pcd for fixed media.
# Fixed media include hard disk.
# Image verification policy settings:
# ALWAYS_EXECUTE 0x00000000
# NEVER_EXECUTE 0x00000001
# ALLOW_EXECUTE_ON_SECURITY_VIOLATION 0x00000002
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x05|UINT32|0x00000003
## Defer Image Load policy settings.
# The policy is bitwise.
# If bit is set, the image from corresponding device will be trust when loading.
#
# IMAGE_UNKNOWN 0x00000001
# IMAGE_FROM_FV 0x00000002
# IMAGE_FROM_OPTION_ROM 0x00000004
# IMAGE_FROM_REMOVABLE_MEDIA 0x00000008
# IMAGE_FROM_FIXED_MEDIA 0x00000010
gEfiSecurityPkgTokenSpaceGuid.PcdDeferImageLoadPolicy|0x0000001F|UINT32|0x0000004
## The token file name used to save credential in USB credential provider driver.
# The specified file should be saved at the root directory of USB storage disk.
gEfiSecurityPkgTokenSpaceGuid.PcdFixedUsbCredentialProviderTokenFileName|L"Token.bin"|VOID*|0x00000005
## The size of Append variable buffer. This buffer is reserved for runtime use, OS can append data into one existing variable.
gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize|0x2000|UINT32|0x30000005
## This PCD specifies the type of TCG platform that contains TPM chip.
# This PCD is only avaiable when PcdTpmPhysicalPresence is TRUE.
# If 0, TCG platform type is PC client.
# If 1, TCG platform type is server.
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass|0|UINT8|0x00000006
## The PCD is used to control whether to support hiding the TPM.
# If TRUE, PcdHideTpm controls whether to hide the TPM.
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport|FALSE|BOOLEAN|0x00000007
[PcdsDynamic, PcdsDynamicEx]
## The PCD is used to control whether to hide the TPM.
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm|FALSE|BOOLEAN|0x00010002
## The PCD is used to specify whether or not MOR (MemoryOverwriteControl) feature is enabled.
gEfiSecurityPkgTokenSpaceGuid.PcdMorEnable|FALSE|BOOLEAN|0x00010000
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## This PCD indicates the presence or absence of the platform operator.
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence|TRUE|BOOLEAN|0x00010001

125
SecurityPkg/SecurityPkg.dsc Normal file
View File

@ -0,0 +1,125 @@
## @file
# Security Module Package for All Architectures.
#
# 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]
PLATFORM_NAME = SecurityPkg
PLATFORM_GUID = B2C4614D-AE76-47ba-B876-5988BFED064F
PLATFORM_VERSION = 0.91
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/SecurityPkg
SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
[LibraryClasses]
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf
PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
[LibraryClasses.common.DXE_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER,]
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
[LibraryClasses.IPF.DXE_SAL_DRIVER]
ExtendedSalLib|MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
[Components]
SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerDxe.inf
SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf
SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf
SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf
#
# Application
#
SecurityPkg/Application/VariableInfo/VariableInfo.inf
#
# TPM
#
SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
SecurityPkg/Tcg/TcgPei/TcgPei.inf
SecurityPkg/Tcg/TcgDxe/TcgDxe.inf
SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf
SecurityPkg/Tcg/PhysicalPresenceDxe/PhysicalPresenceDxe.inf
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf {
<LibraryClasses>
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
}
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
[Components.IA32, Components.X64]
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf {
<LibraryClasses>
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
}
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
[Components.IPF]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf
[Components.EBC]
# Build only
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
[BuildOptions]
MSFT:*_*_IA32_DLINK_FLAGS = /ALIGN:256
INTEL:*_*_IA32_DLINK_FLAGS = /ALIGN:256

View File

@ -0,0 +1,82 @@
/** @file
TCG MOR (Memory Overwrite Request) Control Driver.
This driver initilize MemoryOverwriteRequestControl variable. It
will clear MOR_CLEAR_MEMORY_BIT bit if it is set.
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 "TcgMor.h"
/**
Entry Point for TCG MOR Control driver.
@param[in] ImageHandle Image handle of this driver.
@param[in] SystemTable A Pointer to the EFI System Table.
@retval EFI_SUCEESS
@return Others Some error occurs.
**/
EFI_STATUS
EFIAPI
MorDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT8 MorControl;
UINTN DataSize;
///
/// The firmware is required to create the MemoryOverwriteRequestControl UEFI variable.
///
DataSize = sizeof (MorControl);
Status = gRT->GetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
NULL,
&DataSize,
&MorControl
);
if (EFI_ERROR (Status)) {
//
// Set default value to 0
//
MorControl = 0;
} else {
if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
//
// MorControl is expected, directly return to avoid unnecessary variable operation
//
return EFI_SUCCESS;
}
//
// Clear MOR_CLEAR_MEMORY_BIT
//
DEBUG ((EFI_D_INFO, "TcgMor: Clear MorClearMemory bit\n"));
MorControl &= 0xFE;
}
Status = gRT->SetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
DataSize,
&MorControl
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,27 @@
/** @file
The header file for TcgMor.
Copyright (c) 2009, 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 __TCG_MOR_H__
#define __TCG_MOR_H__
#include <PiDxe.h>
#include <Guid/MemoryOverwriteControl.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#endif

View File

@ -0,0 +1,50 @@
## @file
# Component description file for Memory Overwrite Control 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 = TcgMor
FILE_GUID = AD416CE3-A483-45b1-94C2-4B4E4D575562
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MorDriverEntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
TcgMor.c
TcgMor.h
[Packages]
MdePkg/MdePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
ReportStatusCodeLib
DebugLib
[Guids]
gEfiMemoryOverwriteControlDataGuid # GUID ALWAYS_CONSUMED
[Depex]
gEfiVariableArchProtocolGuid AND
gEfiVariableWriteArchProtocolGuid AND
gEfiTcgProtocolGuid

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
/** @file
The header file for TPM physical presence driver.
Copyright (c) 2006 - 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 __PHYSICAL_PRESENCE_H__
#define __PHYSICAL_PRESENCE_H__
#include <PiDxe.h>
#include <Protocol/TcgService.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Guid/EventGroup.h>
#include <Guid/PhysicalPresenceData.h>
#define TPM_PP_USER_ABORT ((TPM_RESULT)(-0x10))
#define TPM_PP_BIOS_FAILURE ((TPM_RESULT)(-0x0f))
#define CONFIRM_BUFFER_SIZE 4096
#endif

View File

@ -0,0 +1,61 @@
## @file
# Component file for PhysicalPresenceDxe driver.
#
# Copyright (c) 2006 - 2010, 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 = PhysicalPresenceDxe
FILE_GUID = D85A4A0C-2E73-4491-92E1-DCEFC3882A68
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = DriverEntry
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF
#
[Sources]
PhysicalPresence.c
PhysicalPresence.h
PhysicalPresenceStrings.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
MemoryAllocationLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
BaseMemoryLib
DebugLib
PrintLib
HiiLib
[Protocols]
gEfiTcgProtocolGuid
[Guids]
gEfiPhysicalPresenceGuid
[Depex]
gEfiTcgProtocolGuid AND
gEfiVariableArchProtocolGuid AND
gEfiVariableWriteArchProtocolGuid AND
gEfiResetArchProtocolGuid

View File

@ -0,0 +1,134 @@
/** @file
This driver produces PEI_LOCK_PHYSICAL_PRESENCE_PPI to indicate
whether TPM need be locked or not. It can be replaced by a platform
specific driver.
Copyright (c) 2005 - 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 <PiPei.h>
#include <Ppi/LockPhysicalPresence.h>
#include <Ppi/ReadOnlyVariable2.h>
#include <Guid/PhysicalPresenceData.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
/**
This interface returns whether TPM physical presence needs be locked or not.
@param[in] PeiServices The pointer to the PEI Services Table.
@retval TRUE The TPM physical presence should be locked.
@retval FALSE The TPM physical presence cannot be locked.
**/
BOOLEAN
EFIAPI
LockTpmPhysicalPresence (
IN CONST EFI_PEI_SERVICES **PeiServices
);
//
// Gobal defintions for lock physical presence PPI and its descriptor.
//
PEI_LOCK_PHYSICAL_PRESENCE_PPI mLockPhysicalPresencePpi = {
LockTpmPhysicalPresence
};
EFI_PEI_PPI_DESCRIPTOR mLockPhysicalPresencePpiList = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gPeiLockPhysicalPresencePpiGuid,
&mLockPhysicalPresencePpi
};
/**
This interface returns whether TPM physical presence needs be locked or not.
@param[in] PeiServices The pointer to the PEI Services Table.
@retval TRUE The TPM physical presence should be locked.
@retval FALSE The TPM physical presence cannot be locked.
**/
BOOLEAN
EFIAPI
LockTpmPhysicalPresence (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
UINTN DataSize;
EFI_PHYSICAL_PRESENCE TcgPpData;
//
// The CRTM has sensed the physical presence assertion of the user. For example,
// the user has pressed the startup button or inserted a USB dongle. The details
// of the implementation are vendor-specific. Here we read a PCD value to indicate
// whether operator physical presence.
//
if (!PcdGetBool (PcdTpmPhysicalPresence)) {
return TRUE;
}
//
// Check the pending TPM requests. Lock TPM physical presence if there is no TPM
// request.
//
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&Variable
);
if (!EFI_ERROR (Status)) {
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
Status = Variable->GetVariable (
Variable,
PHYSICAL_PRESENCE_VARIABLE,
&gEfiPhysicalPresenceGuid,
NULL,
&DataSize,
&TcgPpData
);
if (!EFI_ERROR (Status)) {
if (TcgPpData.PPRequest != 0) {
return FALSE;
}
}
}
//
// Lock TPM physical presence by default.
//
return TRUE;
}
/**
Entry point of this module.
It installs lock physical presence PPI.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@return Status of install lock physical presence PPI.
**/
EFI_STATUS
EFIAPI
PeimEntry (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
return PeiServicesInstallPpi (&mLockPhysicalPresencePpiList);
}

View File

@ -0,0 +1,55 @@
## @file
# Component description file for physical presence PEI module.
#
# Copyright (c) 2005 - 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 = PhysicalPresencePei
FILE_GUID = 4FE772E8-FE3E-4086-B638-8C493C490488
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimEntry
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF
#
[Sources]
PhysicalPresencePei.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
PeimEntryPoint
PeiServicesLib
[Ppis]
gPeiLockPhysicalPresencePpiGuid
gEfiPeiReadOnlyVariable2PpiGuid
[Guids]
gEfiPhysicalPresenceGuid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND
gEfiPeiReadOnlyVariable2PpiGuid AND
gPeiTpmInitializedPpiGuid

View File

@ -0,0 +1,114 @@
/** @file
VFR file used by the TCG configuration component.
Copyright (c) 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 "TcgConfigNvData.h"
formset
guid = TCG_CONFIG_PRIVATE_GUID,
title = STRING_TOKEN(STR_TPM_TITLE),
help = STRING_TOKEN(STR_TPM_HELP),
classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
varstore TCG_CONFIGURATION,
varid = TCG_CONFIGURATION_VARSTORE_ID,
name = TCG_CONFIGURATION,
guid = TCG_CONFIG_PRIVATE_GUID;
form formid = TCG_CONFIGURATION_FORM_ID,
title = STRING_TOKEN(STR_TPM_TITLE);
subtitle text = STRING_TOKEN(STR_NULL);
suppressif TRUE;
checkbox varid = TCG_CONFIGURATION.TpmEnable,
prompt = STRING_TOKEN(STR_NULL),
help = STRING_TOKEN(STR_NULL),
endcheckbox;
endif;
suppressif TRUE;
checkbox varid = TCG_CONFIGURATION.TpmActivate,
prompt = STRING_TOKEN(STR_NULL),
help = STRING_TOKEN(STR_NULL),
endcheckbox;
endif;
suppressif TRUE;
checkbox varid = TCG_CONFIGURATION.OriginalHideTpm,
prompt = STRING_TOKEN(STR_NULL),
help = STRING_TOKEN(STR_NULL),
endcheckbox;
endif;
text
help = STRING_TOKEN(STR_TPM_STATE_HELP),
text = STRING_TOKEN(STR_TPM_STATE_PROMPT),
text = STRING_TOKEN(STR_TPM_STATE_CONTENT);
subtitle text = STRING_TOKEN(STR_NULL);
label LABEL_TCG_CONFIGURATION_HIDETPM;
checkbox varid = TCG_CONFIGURATION.HideTpm,
questionid = KEY_HIDE_TPM,
prompt = STRING_TOKEN(STR_HIDE_TPM_PROMPT),
help = STRING_TOKEN(STR_HIDE_TPM_HELP),
flags = RESET_REQUIRED,
endcheckbox;
label LABEL_END;
grayoutif ideqval TCG_CONFIGURATION.OriginalHideTpm == 1;
oneof varid = TCG_CONFIGURATION.TpmOperation,
questionid = KEY_TPM_ACTION,
prompt = STRING_TOKEN(STR_TPM_OPERATION),
help = STRING_TOKEN(STR_TPM_OPERATION_HELP),
flags = INTERACTIVE,
//
// Disable (TPM_ORD_PhysicalDisable) command is not available when disabled.
// Activate/deactivate (TPM_ORD_physicalSetDeactivated) command is not available when disabled.
//
suppressif ideqval TCG_CONFIGURATION.TpmEnable == 0;
option text = STRING_TOKEN(STR_DISABLE), value = DISABLE, flags = 0;
option text = STRING_TOKEN(STR_TPM_ACTIVATE), value = ACTIVATE, flags = 0;
option text = STRING_TOKEN(STR_TPM_DEACTIVATE), value = DEACTIVATE, flags = 0;
option text = STRING_TOKEN(STR_TPM_DEACTIVATE_DISABLE), value = DEACTIVATE_DISABLE, flags = 0;
endif
//
// Clear (TPM_ORD_ForceClear) command is not available when disabled or deactivated.
//
suppressif ideqval TCG_CONFIGURATION.TpmEnable == 0 OR
ideqval TCG_CONFIGURATION.TpmActivate == 0;
option text = STRING_TOKEN(STR_TPM_CLEAR), value = CLEAR, flags = 0;
option text = STRING_TOKEN(STR_TPM_CLEAR_ENABLE_ACTIVATE), value = CLEAR_ENABLE_ACTIVATE, flags = 0;
endif
option text = STRING_TOKEN(STR_ENABLE), value = ENABLE, flags = 0;
option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE), value = ENABLE_ACTIVATE, flags = 0;
option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE_CLEAR), value = ENABLE_ACTIVATE_CLEAR, flags = 0;
option text = STRING_TOKEN(STR_TPM_ENABLE_ACTIVATE_CLEAR_E_A), value = ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE, flags = 0;
endoneof;
subtitle text = STRING_TOKEN(STR_NULL);
checkbox varid = TCG_CONFIGURATION.MorState,
questionid = KEY_TPM_MOR_ENABLE,
prompt = STRING_TOKEN(STR_MOR_PROMPT),
help = STRING_TOKEN(STR_MOR_HELP),
endcheckbox;
endif;
endform;
endformset;

View File

@ -0,0 +1,147 @@
/** @file
The module entry point for Tcg configuration module.
Copyright (c) 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 "TcgConfigImpl.h"
EFI_GUID gTcgConfigPrivateGuid = TCG_CONFIG_PRIVATE_GUID;
/**
The entry point for Tcg configuration driver.
@param[in] ImageHandle The image handle of the driver.
@param[in] SystemTable The system table.
@retval EFI_ALREADY_STARTED The driver already exists in system.
@retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources.
@retval EFI_SUCCES All the related protocols are installed on the driver.
@retval Others Fail to install protocols as indicated.
**/
EFI_STATUS
EFIAPI
TcgConfigDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
TCG_CONFIG_PRIVATE_DATA *PrivateData;
EFI_TCG_PROTOCOL *TcgProtocol;
Status = TisPcRequestUseTpm ((TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));
return Status;
}
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
if (EFI_ERROR (Status)) {
TcgProtocol = NULL;
}
Status = gBS->OpenProtocol (
ImageHandle,
&gTcgConfigPrivateGuid,
NULL,
ImageHandle,
ImageHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (!EFI_ERROR (Status)) {
return EFI_ALREADY_STARTED;
}
//
// Create a private data structure.
//
PrivateData = AllocateCopyPool (sizeof (TCG_CONFIG_PRIVATE_DATA), &mTcgConfigPrivateDateTemplate);
if (PrivateData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
PrivateData->TcgProtocol = TcgProtocol;
PrivateData->HideTpm = PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm);
//
// Install TCG configuration form
//
Status = InstallTcgConfigForm (PrivateData);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
//
// Install private GUID.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gTcgConfigPrivateGuid,
PrivateData,
NULL
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
return EFI_SUCCESS;
ErrorExit:
if (PrivateData != NULL) {
UninstallTcgConfigForm (PrivateData);
}
return Status;
}
/**
Unload the Tcg configuration form.
@param[in] ImageHandle The driver's image handle.
@retval EFI_SUCCESS The Tcg configuration form is unloaded.
@retval Others Failed to unload the form.
**/
EFI_STATUS
EFIAPI
TcgConfigDriverUnload (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
TCG_CONFIG_PRIVATE_DATA *PrivateData;
Status = gBS->HandleProtocol (
ImageHandle,
&gTcgConfigPrivateGuid,
(VOID **) &PrivateData
);
if (EFI_ERROR (Status)) {
return Status;
}
ASSERT (PrivateData->Signature == TCG_CONFIG_PRIVATE_DATA_SIGNATURE);
gBS->UninstallMultipleProtocolInterfaces (
&ImageHandle,
&gTcgConfigPrivateGuid,
PrivateData,
NULL
);
UninstallTcgConfigForm (PrivateData);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,75 @@
## @file
# Component name for Tcg configuration module.
#
# Copyright (c) 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 = TcgConfigDxe
FILE_GUID = 1FA4DAFE-FA5D-4d75-BEA6-5863862C520A
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = TcgConfigDriverEntryPoint
UNLOAD_IMAGE = TcgConfigDriverUnload
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
TcgConfigDriver.c
TcgConfigImpl.c
TcgConfigImpl.h
TcgConfig.vfr
TcgConfigStrings.uni
TcgConfigNvData.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
MemoryAllocationLib
UefiLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
UefiHiiServicesLib
DebugLib
HiiLib
PcdLib
PrintLib
TpmCommLib
[Guids]
gEfiPhysicalPresenceGuid
gEfiIfrTianoGuid
[Protocols]
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
gEfiTcgProtocolGuid ## CONSUMES
[FixedPcd]
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdMorEnable
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
[Depex]
gEfiHiiConfigRoutingProtocolGuid AND
gEfiHiiDatabaseProtocolGuid AND
gEfiVariableArchProtocolGuid AND
gEfiVariableWriteArchProtocolGuid

View File

@ -0,0 +1,555 @@
/** @file
HII Config Access protocol implementation of TCG configuration module.
Copyright (c) 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 "TcgConfigImpl.h"
EFI_GUID mTcgFormSetGuid = TCG_CONFIG_PRIVATE_GUID;
CHAR16 mTcgStorageName[] = L"TCG_CONFIGURATION";
TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate = {
TCG_CONFIG_PRIVATE_DATA_SIGNATURE,
{
TcgExtractConfig,
TcgRouteConfig,
TcgCallback
}
};
HII_VENDOR_DEVICE_PATH mTcgHiiVendorDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
TCG_CONFIG_PRIVATE_GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8) (END_DEVICE_PATH_LENGTH),
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
/**
Get current state of TPM device.
@param[in] TcgProtocol Point to EFI_TCG_PROTOCOL instance.
@param[out] TpmEnable Flag to indicate TPM is enabled or not.
@param[out] TpmActivate Flag to indicate TPM is activated or not.
@retval EFI_SUCCESS State is successfully returned.
@retval EFI_DEVICE_ERROR Failed to get TPM response.
@retval Others Other errors as indicated.
**/
EFI_STATUS
GetTpmState (
IN EFI_TCG_PROTOCOL *TcgProtocol,
OUT BOOLEAN *TpmEnable, OPTIONAL
OUT BOOLEAN *TpmActivate OPTIONAL
)
{
EFI_STATUS Status;
TPM_RSP_COMMAND_HDR *TpmRsp;
UINT32 TpmSendSize;
TPM_PERMANENT_FLAGS *TpmPermanentFlags;
UINT8 CmdBuf[64];
ASSERT (TcgProtocol != NULL);
//
// Get TPM Permanent flags (TpmEnable, TpmActivate)
//
if ((TpmEnable != NULL) || (TpmActivate != NULL)) {
TpmSendSize = sizeof (TPM_RQU_COMMAND_HDR) + sizeof (UINT32) * 3;
*(UINT16*)&CmdBuf[0] = H2NS (TPM_TAG_RQU_COMMAND);
*(UINT32*)&CmdBuf[2] = H2NL (TpmSendSize);
*(UINT32*)&CmdBuf[6] = H2NL (TPM_ORD_GetCapability);
*(UINT32*)&CmdBuf[10] = H2NL (TPM_CAP_FLAG);
*(UINT32*)&CmdBuf[14] = H2NL (sizeof (TPM_CAP_FLAG_PERMANENT));
*(UINT32*)&CmdBuf[18] = H2NL (TPM_CAP_FLAG_PERMANENT);
Status = TcgProtocol->PassThroughToTpm (
TcgProtocol,
TpmSendSize,
CmdBuf,
sizeof (CmdBuf),
CmdBuf
);
TpmRsp = (TPM_RSP_COMMAND_HDR *) &CmdBuf[0];
if (EFI_ERROR (Status) || (TpmRsp->tag != H2NS (TPM_TAG_RSP_COMMAND)) || (TpmRsp->returnCode != 0)) {
return EFI_DEVICE_ERROR;
}
TpmPermanentFlags = (TPM_PERMANENT_FLAGS *) &CmdBuf[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
if (TpmEnable != NULL) {
*TpmEnable = (BOOLEAN) !TpmPermanentFlags->disable;
}
if (TpmActivate != NULL) {
*TpmActivate = (BOOLEAN) !TpmPermanentFlags->deactivated;
}
}
return EFI_SUCCESS;
}
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Request A null-terminated Unicode string in
<ConfigRequest> format.
@param[out] Progress On return, points to a character in the Request
string. Points to the string's null terminator if
request was successful. Points to the most recent
'&' before the first failing name/value pair (or
the beginning of the string if the failure is in
the first name/value pair) if the request was not
successful.
@param[out] Results A null-terminated Unicode string in
<ConfigAltResp> format which has all values filled
in for the names in the Request string. String to
be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
TcgExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
)
{
EFI_STATUS Status;
UINTN BufferSize;
TCG_CONFIGURATION Configuration;
TCG_CONFIG_PRIVATE_DATA *PrivateData;
EFI_STRING ConfigRequestHdr;
EFI_STRING ConfigRequest;
BOOLEAN AllocatedRequest;
UINTN Size;
BOOLEAN TpmEnable;
BOOLEAN TpmActivate;
CHAR16 State[32];
if (Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
}
*Progress = Request;
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mTcgFormSetGuid, mTcgStorageName)) {
return EFI_NOT_FOUND;
}
ConfigRequestHdr = NULL;
ConfigRequest = NULL;
AllocatedRequest = FALSE;
Size = 0;
PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);
//
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
//
ZeroMem (&Configuration, sizeof (TCG_CONFIGURATION));
Configuration.MorState = PcdGetBool (PcdMorEnable);
Configuration.TpmOperation = ENABLE;
Configuration.HideTpm = PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm);
//
// Read the original value of HideTpm from PrivateData which won't be changed by Setup in this boot.
//
Configuration.OriginalHideTpm = PrivateData->HideTpm;
//
// Display current TPM state.
//
if (PrivateData->TcgProtocol != NULL) {
Status = GetTpmState (PrivateData->TcgProtocol, &TpmEnable, &TpmActivate);
if (EFI_ERROR (Status)) {
return Status;
}
UnicodeSPrint (
State,
sizeof (State),
L"%s, and %s",
TpmEnable ? L"Enabled" : L"Disabled",
TpmActivate ? L"Activated" : L"Deactivated"
);
Configuration.TpmEnable = TpmEnable;
Configuration.TpmActivate = TpmActivate;
HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM_STATE_CONTENT), State, NULL);
}
BufferSize = sizeof (Configuration);
ConfigRequest = Request;
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
//
// Request has no request element, construct full request string.
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
//
ConfigRequestHdr = HiiConstructConfigHdr (&mTcgFormSetGuid, mTcgStorageName, PrivateData->DriverHandle);
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
ConfigRequest = AllocateZeroPool (Size);
ASSERT (ConfigRequest != NULL);
AllocatedRequest = TRUE;
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
FreePool (ConfigRequestHdr);
}
Status = gHiiConfigRouting->BlockToConfig (
gHiiConfigRouting,
ConfigRequest,
(UINT8 *) &Configuration,
BufferSize,
Results,
Progress
);
//
// Free the allocated config request string.
//
if (AllocatedRequest) {
FreePool (ConfigRequest);
}
//
// Set Progress string to the original request string.
//
if (Request == NULL) {
*Progress = NULL;
} else if (StrStr (Request, L"OFFSET") == NULL) {
*Progress = Request + StrLen (Request);
}
return Status;
}
/**
This function processes the results of changes in configuration.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Configuration A null-terminated Unicode string in <ConfigResp>
format.
@param[out] Progress A pointer to a string filled in with the offset of
the most recent '&' before the first failing
name/value pair (or the beginning of the string if
the failure is in the first name/value pair) or
the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
TcgRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
)
{
EFI_STATUS Status;
UINTN BufferSize;
TCG_CONFIGURATION TcgConfiguration;
if (Configuration == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
}
*Progress = Configuration;
if (!HiiIsConfigHdrMatch (Configuration, &mTcgFormSetGuid, mTcgStorageName)) {
return EFI_NOT_FOUND;
}
//
// Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
//
BufferSize = sizeof (TCG_CONFIGURATION);
Status = gHiiConfigRouting->ConfigToBlock (
gHiiConfigRouting,
Configuration,
(UINT8 *) &TcgConfiguration,
&BufferSize,
Progress
);
if (EFI_ERROR (Status)) {
return Status;
}
PcdSetBool (PcdMorEnable, TcgConfiguration.MorState);
PcdSetBool (PcdHideTpm, TcgConfiguration.HideTpm);
return EFI_SUCCESS;
}
/**
Save TPM request to variable space.
@param[in] PpRequest Physical Presence request command.
@retval EFI_SUCCESS The operation is finished successfully.
@retval Others Other errors as indicated.
**/
EFI_STATUS
SavePpRequest (
IN UINT8 PpRequest
)
{
EFI_STATUS Status;
UINTN DataSize;
EFI_PHYSICAL_PRESENCE PpData;
//
// Save TPM command to variable.
//
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
Status = gRT->GetVariable (
PHYSICAL_PRESENCE_VARIABLE,
&gEfiPhysicalPresenceGuid,
NULL,
&DataSize,
&PpData
);
if (EFI_ERROR (Status)) {
return Status;
}
PpData.PPRequest = PpRequest;
Status = gRT->SetVariable (
PHYSICAL_PRESENCE_VARIABLE,
&gEfiPhysicalPresenceGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
DataSize,
&PpData
);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Reset system.
//
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
return EFI_SUCCESS;
}
/**
This function processes the results of changes in configuration.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Action Specifies the type of action taken by the browser.
@param[in] QuestionId A unique value which is sent to the original
exporting driver so that it can identify the type
of data to expect.
@param[in] Type The type of value for the question.
@param[in] Value A pointer to the data being sent to the original
exporting driver.
@param[out] ActionRequest On return, points to the action requested by the
callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the
callback.
**/
EFI_STATUS
EFIAPI
TcgCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((Action != EFI_BROWSER_ACTION_CHANGING) || (QuestionId != KEY_TPM_ACTION)) {
return EFI_UNSUPPORTED;
}
SavePpRequest (Value->u8);
ASSERT (FALSE);
return EFI_SUCCESS;
}
/**
This function publish the TCG configuration Form for TPM device.
@param[in, out] PrivateData Points to TCG configuration private data.
@retval EFI_SUCCESS HII Form is installed for this network device.
@retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
@retval Others Other errors as indicated.
**/
EFI_STATUS
InstallTcgConfigForm (
IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
)
{
EFI_STATUS Status;
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
VOID *StartOpCodeHandle;
VOID *EndOpCodeHandle;
EFI_IFR_GUID_LABEL *StartLabel;
EFI_IFR_GUID_LABEL *EndLabel;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
DriverHandle = NULL;
ConfigAccess = &PrivateData->ConfigAccess;
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverHandle,
&gEfiDevicePathProtocolGuid,
&mTcgHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
ConfigAccess,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
PrivateData->DriverHandle = DriverHandle;
//
// Publish the HII package list
//
HiiHandle = HiiAddPackages (
&mTcgFormSetGuid,
DriverHandle,
TcgConfigDxeStrings,
TcgConfigBin,
NULL
);
if (HiiHandle == NULL) {
gBS->UninstallMultipleProtocolInterfaces (
DriverHandle,
&gEfiDevicePathProtocolGuid,
&mTcgHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
ConfigAccess,
NULL
);
return EFI_OUT_OF_RESOURCES;
}
PrivateData->HiiHandle = HiiHandle;
//
// Remove the Hide TPM question from the IFR
//
if (!PcdGetBool (PcdHideTpmSupport)) {
//
// Allocate space for creation of UpdateData Buffer
//
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (StartOpCodeHandle != NULL);
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (EndOpCodeHandle != NULL);
//
// Create Hii Extend Label OpCode as the start opcode
//
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartLabel->Number = LABEL_TCG_CONFIGURATION_HIDETPM;
//
// Create Hii Extend Label OpCode as the end opcode
//
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
EndLabel->Number = LABEL_END;
HiiUpdateForm (HiiHandle, NULL, TCG_CONFIGURATION_FORM_ID, StartOpCodeHandle, EndOpCodeHandle);
HiiFreeOpCodeHandle (StartOpCodeHandle);
HiiFreeOpCodeHandle (EndOpCodeHandle);
}
return EFI_SUCCESS;
}
/**
This function removes TCG configuration Form.
@param[in, out] PrivateData Points to TCG configuration private data.
**/
VOID
UninstallTcgConfigForm (
IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
)
{
//
// Uninstall HII package list
//
if (PrivateData->HiiHandle != NULL) {
HiiRemovePackages (PrivateData->HiiHandle);
PrivateData->HiiHandle = NULL;
}
//
// Uninstall HII Config Access Protocol
//
if (PrivateData->DriverHandle != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
PrivateData->DriverHandle,
&gEfiDevicePathProtocolGuid,
&mTcgHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
&PrivateData->ConfigAccess,
NULL
);
PrivateData->DriverHandle = NULL;
}
FreePool (PrivateData);
}

View File

@ -0,0 +1,195 @@
/** @file
The header file of HII Config Access protocol implementation of TCG
configuration module.
Copyright (c) 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 __TCG_CONFIG_IMPL_H__
#define __TCG_CONFIG_IMPL_H__
#include <Uefi.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/TcgService.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiHiiServicesLib.h>
#include <Library/UefiLib.h>
#include <Library/HiiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/PrintLib.h>
#include <Library/TpmCommLib.h>
#include <Guid/MdeModuleHii.h>
#include "TcgConfigNvData.h"
//
// Tool generated IFR binary data and String package data
//
extern UINT8 TcgConfigBin[];
extern UINT8 TcgConfigDxeStrings[];
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
typedef struct {
UINTN Signature;
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
EFI_TCG_PROTOCOL *TcgProtocol;
BOOLEAN HideTpm;
} TCG_CONFIG_PRIVATE_DATA;
extern TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate;
#define TCG_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'C', 'G', 'D')
#define TCG_CONFIG_PRIVATE_DATA_FROM_THIS(a) CR (a, TCG_CONFIG_PRIVATE_DATA, ConfigAccess, TCG_CONFIG_PRIVATE_DATA_SIGNATURE)
/**
This function publish the TCG configuration Form for TPM device.
@param[in, out] PrivateData Points to TCG configuration private data.
@retval EFI_SUCCESS HII Form is installed for this network device.
@retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
@retval Others Other errors as indicated.
**/
EFI_STATUS
InstallTcgConfigForm (
IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
);
/**
This function removes TCG configuration Form.
@param[in, out] PrivateData Points to TCG configuration private data.
**/
VOID
UninstallTcgConfigForm (
IN OUT TCG_CONFIG_PRIVATE_DATA *PrivateData
);
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Request A null-terminated Unicode string in
<ConfigRequest> format.
@param[out] Progress On return, points to a character in the Request
string. Points to the string's null terminator if
request was successful. Points to the most recent
'&' before the first failing name/value pair (or
the beginning of the string if the failure is in
the first name/value pair) if the request was not
successful.
@param[out] Results A null-terminated Unicode string in
<ConfigAltResp> format which has all values filled
in for the names in the Request string. String to
be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
TcgExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
);
/**
This function processes the results of changes in configuration.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Configuration A null-terminated Unicode string in <ConfigResp>
format.
@param[out] Progress A pointer to a string filled in with the offset of
the most recent '&' before the first failing
name/value pair (or the beginning of the string if
the failure is in the first name/value pair) or
the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this
driver.
**/
EFI_STATUS
EFIAPI
TcgRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
);
/**
This function processes the results of changes in configuration.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Action Specifies the type of action taken by the browser.
@param[in] QuestionId A unique value which is sent to the original
exporting driver so that it can identify the type
of data to expect.
@param[in] Type The type of value for the question.
@param[in] Value A pointer to the data being sent to the original
exporting driver.
@param[out] ActionRequest On return, points to the action requested by the
callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the
callback.
**/
EFI_STATUS
EFIAPI
TcgCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
#endif

View File

@ -0,0 +1,48 @@
/** @file
Header file for NV data structure definition.
Copyright (c) 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 __TCG_CONFIG_NV_DATA_H__
#define __TCG_CONFIG_NV_DATA_H__
#include <Guid/HiiPlatformSetupFormset.h>
#include <Guid/PhysicalPresenceData.h>
#define TCG_CONFIG_PRIVATE_GUID \
{ \
0xb0f901e4, 0xc424, 0x45de, {0x90, 0x81, 0x95, 0xe2, 0xb, 0xde, 0x6f, 0xb5 } \
}
#define TCG_CONFIGURATION_VARSTORE_ID 0x0001
#define TCG_CONFIGURATION_FORM_ID 0x0001
#define KEY_HIDE_TPM 0x2000
#define KEY_TPM_ACTION 0x3000
#define KEY_TPM_MOR_ENABLE 0x4000
#define LABEL_TCG_CONFIGURATION_HIDETPM 0x0001
#define LABEL_END 0xffff
//
// Nv Data structure referenced by IFR
//
typedef struct {
BOOLEAN HideTpm;
BOOLEAN OriginalHideTpm;
BOOLEAN MorState;
UINT8 TpmOperation;
BOOLEAN TpmEnable;
BOOLEAN TpmActivate;
} TCG_CONFIGURATION;
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
## @file
# Component file for module TcgDxe.
# This module will produce TCG protocol and measure boot environment.
#
# Copyright (c) 2006 - 2010, 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 = TcgDxe
FILE_GUID = A5683620-7998-4bb2-A377-1C1E31E1E215
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = DriverEntry
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF
#
[Sources]
TcgDxe.c
TisDxe.c
TpmComm.c
TpmComm.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
UefiBootServicesTableLib
HobLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
BaseMemoryLib
DebugLib
TpmCommLib
PrintLib
UefiLib
[Guids]
gEfiSmbiosTableGuid # ALWAYS_CONSUMED
gEfiGlobalVariableGuid # ALWAYS_CONSUMED
gTcgEventEntryHobGuid
gEfiEventReadyToBootGuid
gEfiEventExitBootServicesGuid
[Protocols]
gEfiTcgProtocolGuid ## PRODUCES
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass
[Depex]
TRUE

View File

@ -0,0 +1,432 @@
/** @file
TIS (TPM Interface Specification) functions used by TPM Dxe driver.
Copyright (c) 2005 - 2010, 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 <IndustryStandard/Tpm12.h>
#include <Library/TimerLib.h>
#include <Library/TpmCommLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
STATIC UINT8 TpmCommandBuf[TPMCMDBUFLENGTH];
/**
Send command to TPM for execution.
@param[in] TisReg TPM register space base address.
@param[in] TpmBuffer Buffer for TPM command data.
@param[in] DataLength TPM command data length.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
**/
EFI_STATUS
TisPcSend (
IN TIS_PC_REGISTERS_PTR TisReg,
IN UINT8 *TpmBuffer,
IN UINT32 DataLength
)
{
UINT16 BurstCount;
UINT32 Index;
EFI_STATUS Status;
Status = TisPcPrepareCommand (TisReg);
if (EFI_ERROR (Status)){
DEBUG ((DEBUG_ERROR, "The Tpm not ready!\n"));
return Status;
}
Index = 0;
while (Index < DataLength) {
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status)) {
return EFI_TIMEOUT;
}
for (; BurstCount > 0 && Index < DataLength; BurstCount--) {
MmioWrite8 ((UINTN) &TisReg->DataFifo, *(TpmBuffer + Index));
Index++;
}
}
//
// Ensure the Tpm status STS_EXPECT change from 1 to 0
//
Status = TisPcWaitRegisterBits (
&TisReg->Status,
(UINT8) TIS_PC_VALID,
TIS_PC_STS_EXPECT,
TIS_TIMEOUT_C
);
return Status;
}
/**
Receive response data of last command from TPM.
@param[in] TisReg TPM register space base address.
@param[out] TpmBuffer Buffer for response data.
@param[out] RespSize Response data length.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_DEVICE_ERROR Unexpected device status.
@retval EFI_BUFFER_TOO_SMALL Response data is too long.
**/
EFI_STATUS
TisPcReceive (
IN TIS_PC_REGISTERS_PTR TisReg,
OUT UINT8 *TpmBuffer,
OUT UINT32 *RespSize
)
{
EFI_STATUS Status;
UINT16 BurstCount;
UINT32 Index;
UINT32 ResponseSize;
UINT32 Data32;
//
// Wait for the command completion
//
Status = TisPcWaitRegisterBits (
&TisReg->Status,
(UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
0,
TIS_TIMEOUT_B
);
if (EFI_ERROR (Status)) {
return EFI_TIMEOUT;
}
//
// Read the response data header and check it
//
Index = 0;
BurstCount = 0;
while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status)) {
return EFI_TIMEOUT;
}
for (; BurstCount > 0 ; BurstCount--) {
*(TpmBuffer + Index) = MmioRead8 ((UINTN) &TisReg->DataFifo);
Index++;
if (Index == sizeof (TPM_RSP_COMMAND_HDR))
break;
}
}
//
// Check the reponse data header (tag,parasize and returncode )
//
CopyMem (&Data32, (TpmBuffer + 2), sizeof (UINT32));
ResponseSize = SwapBytes32 (Data32);
*RespSize = ResponseSize;
if (ResponseSize == sizeof (TPM_RSP_COMMAND_HDR)) {
return EFI_SUCCESS;
}
if (ResponseSize < sizeof (TPM_RSP_COMMAND_HDR)) {
return EFI_DEVICE_ERROR;
}
if (ResponseSize > TPMCMDBUFLENGTH) {
return EFI_BUFFER_TOO_SMALL;
}
//
// Continue reading the remaining data
//
while (Index < ResponseSize) {
for (; BurstCount > 0 ; BurstCount--) {
*(TpmBuffer + Index) = MmioRead8 ((UINTN) &TisReg->DataFifo);
Index++;
if (Index == ResponseSize) {
return EFI_SUCCESS;
}
}
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status) && (Index < ResponseSize)) {
return EFI_DEVICE_ERROR;
}
}
return EFI_SUCCESS;
}
/**
Format TPM command data according to the format control character.
@param[in] FmtChar Format control character.
@param[in, out] ap List of arguments.
@param[in] TpmBuffer Buffer for TPM command data.
@param[out] DataLength TPM command data length.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_INVALID_PARAMETER Invalid format control character.
@retval EFI_BUFFER_TOO_SMALL Buffer too small for command data.
**/
EFI_STATUS
TisPcSendV (
IN UINT8 FmtChar,
IN OUT VA_LIST *ap,
UINT8 *TpmBuffer,
UINT32 *DataLength
)
{
UINT8 DataByte;
UINT16 DataWord;
UINT32 DataDword;
TPM_RQU_COMMAND_HDR TpmCmdHdr;
TPM_RQU_COMMAND_HDR *TpmCmdPtr;
UINTN Size;
UINT8 *Raw;
switch (FmtChar) {
case 'b':
DataByte = VA_ARG (*ap, UINT8);
Raw = &DataByte;
Size = sizeof (DataByte);
break;
case 'w':
DataWord = VA_ARG (*ap, UINT16);
DataWord = SwapBytes16 (DataWord);
Raw = (UINT8*)&DataWord;
Size = sizeof (DataWord);
break;
case 'd':
DataDword = VA_ARG (*ap, UINT32);
DataDword = SwapBytes32 (DataDword);
Raw = (UINT8*)&DataDword;
Size = sizeof (DataDword);
break;
case 'h':
TpmCmdPtr = VA_ARG (*ap, TPM_RQU_COMMAND_HDR*);
TpmCmdHdr.tag = SwapBytes16 (TpmCmdPtr->tag);
TpmCmdHdr.paramSize = SwapBytes32 (TpmCmdPtr->paramSize);
TpmCmdHdr.ordinal = SwapBytes32 (TpmCmdPtr->ordinal);
Raw = (UINT8*) &TpmCmdHdr;
Size = sizeof (TpmCmdHdr);
break;
case 'r':
Raw = VA_ARG (*ap, UINT8*);
Size = VA_ARG (*ap, UINTN);
break;
case '\0':
return EFI_INVALID_PARAMETER;
default:
return EFI_INVALID_PARAMETER;
}
if(*DataLength + (UINT32) Size > TPMCMDBUFLENGTH) {
return EFI_BUFFER_TOO_SMALL;
}
CopyMem (TpmBuffer + *DataLength, Raw, Size);
*DataLength += (UINT32) Size;
return EFI_SUCCESS;
}
/**
Format reponse data according to the format control character.
@param[in] FmtChar Format control character.
@param[in, out] ap List of arguments.
@param[out] TpmBuffer Buffer for reponse data.
@param[in, out] DataIndex Data offset in reponse data buffer.
@param[in] RespSize Response data length.
@param[out] DataFinished Reach the end of Response data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_INVALID_PARAMETER Invalid format control character.
@retval EFI_BUFFER_TOO_SMALL Buffer too small for command data.
**/
EFI_STATUS
TisPcReceiveV (
IN UINT8 FmtChar,
IN OUT VA_LIST *ap,
OUT UINT8 *TpmBuffer,
IN OUT UINT32 *DataIndex,
IN UINT32 RespSize,
OUT BOOLEAN *DataFinished
)
{
UINT8 *Raw;
TPM_RSP_COMMAND_HDR *TpmRspPtr;
UINTN Size;
Raw = VA_ARG (*ap, UINT8*);
switch (FmtChar) {
case 'b':
Size = sizeof (UINT8);
break;
case 'w':
Size = sizeof (UINT16);
break;
case 'd':
Size = sizeof (UINT32);
break;
case 'h':
Size = sizeof (*TpmRspPtr);
break;
case 'r':
Size = VA_ARG (*ap, UINTN);
if(*DataIndex + (UINT32) Size <= RespSize) {
break;
}
*DataFinished = TRUE;
if (*DataIndex >= RespSize) {
return EFI_SUCCESS;
}
CopyMem (Raw, TpmBuffer + *DataIndex, RespSize - *DataIndex);
*DataIndex += RespSize - *DataIndex;
return EFI_SUCCESS;
case '\0':
return EFI_INVALID_PARAMETER;
default:
return EFI_WARN_UNKNOWN_GLYPH;
}
if(*DataIndex + (UINT32) Size > RespSize) {
*DataFinished = TRUE;
return EFI_SUCCESS;
}
if( *DataIndex + (UINT32) Size > TPMCMDBUFLENGTH )
return EFI_BUFFER_TOO_SMALL;
CopyMem (Raw, TpmBuffer + *DataIndex, Size);
*DataIndex += (UINT32) Size;
switch (FmtChar) {
case 'w':
*(UINT16*)Raw = SwapBytes16 (*(UINT16*) Raw);
break;
case 'd':
*(UINT32*)Raw = SwapBytes32 (*(UINT32*) Raw);
break;
case 'h':
TpmRspPtr = (TPM_RSP_COMMAND_HDR*) Raw;
TpmRspPtr->tag = SwapBytes16 (TpmRspPtr->tag);
TpmRspPtr->paramSize = SwapBytes32 (TpmRspPtr->paramSize);
TpmRspPtr->returnCode = SwapBytes32 (TpmRspPtr->returnCode);
break;
}
return EFI_SUCCESS;
}
/**
Send formatted command to TPM for execution and return formatted data from response.
@param[in] TisReg TPM Handle.
@param[in] Fmt Format control string.
@param[in] ... The variable argument list.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
**/
EFI_STATUS
EFIAPI
TisPcExecute (
IN TIS_TPM_HANDLE TisReg,
IN CONST CHAR8 *Fmt,
...
)
{
EFI_STATUS Status;
VA_LIST Ap;
UINT32 BufSize;
UINT32 ResponseSize;
BOOLEAN DataFinished;
VA_START (Ap, Fmt);
//
// Put the formatted command to the TpmCommandBuf
//
BufSize = 0;
while (*Fmt != '\0') {
if (*Fmt == '%') Fmt++;
if (*Fmt == '/') break;
Status = TisPcSendV (*Fmt, &Ap, TpmCommandBuf, &BufSize);
if (EFI_ERROR( Status )) {
return Status;
}
Fmt++;
}
//
// Send the command to TPM
//
Status = TisPcSend (TisReg, TpmCommandBuf, BufSize);
if (EFI_ERROR (Status)) {
//
// Ensure the TPM state change from "Reception" to "Idle/Ready"
//
MmioWrite8 ((UINTN) &(((TIS_PC_REGISTERS_PTR) TisReg)->Status), TIS_PC_STS_READY);
return Status;
}
MmioWrite8 ((UINTN) &(((TIS_PC_REGISTERS_PTR) TisReg)->Status), TIS_PC_STS_GO);
Fmt++;
//
// Receive the response data from TPM
//
ZeroMem (TpmCommandBuf, TPMCMDBUFLENGTH);
Status = TisPcReceive (TisReg, TpmCommandBuf, &ResponseSize);
//
// Ensure the TPM state change from "Execution" or "Completion" to "Idle/Ready"
//
MmioWrite8 ((UINTN) &(((TIS_PC_REGISTERS_PTR) TisReg)->Status), TIS_PC_STS_READY);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the formatted data from the TpmCommandBuf.
//
BufSize =0;
DataFinished = FALSE;
while (*Fmt != '\0') {
if (*Fmt == '%') {
Fmt++;
}
Status = TisPcReceiveV (*Fmt, &Ap, TpmCommandBuf, &BufSize, ResponseSize, &DataFinished);
if (EFI_ERROR (Status)) {
return Status;
}
if (DataFinished) {
return EFI_SUCCESS;
}
Fmt++;
}
VA_END (Ap);
return Status;
}

View File

@ -0,0 +1,163 @@
/** @file
Utility functions used by TPM Dxe driver.
Copyright (c) 2005 - 2010, 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 <IndustryStandard/Tpm12.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/TpmCommLib.h>
#include <Library/BaseMemoryLib.h>
#include "TpmComm.h"
/**
Extend a TPM PCR.
@param[in] TpmHandle TPM handle.
@param[in] DigestToExtend The 160 bit value representing the event to be recorded.
@param[in] PcrIndex The PCR to be updated.
@param[out] NewPcrValue New PCR value after extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
TpmCommExtend (
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_DIGEST *DigestToExtend,
IN TPM_PCRINDEX PcrIndex,
OUT TPM_DIGEST *NewPcrValue
)
{
EFI_STATUS Status;
TPM_DIGEST NewValue;
TPM_RQU_COMMAND_HDR CmdHdr;
TPM_RSP_COMMAND_HDR RspHdr;
if (NewPcrValue == NULL) {
NewPcrValue = &NewValue;
}
CmdHdr.tag = TPM_TAG_RQU_COMMAND;
CmdHdr.paramSize =
sizeof (CmdHdr) + sizeof (PcrIndex) + sizeof (*DigestToExtend);
CmdHdr.ordinal = TPM_ORD_Extend;
Status = TisPcExecute (
TpmHandle,
"%h%d%r%/%h%r",
&CmdHdr,
PcrIndex,
DigestToExtend,
(UINTN)sizeof (*DigestToExtend),
&RspHdr,
NewPcrValue,
(UINTN)sizeof (*NewPcrValue)
);
if (EFI_ERROR (Status)) {
return Status;
}
if (RspHdr.returnCode != 0) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Get TPM capability flags.
@param[in] TpmHandle TPM handle.
@param[in] FlagSubcap Flag subcap.
@param[out] FlagBuffer Pointer to the buffer for returned flag structure.
@param[in] FlagSize Size of the buffer.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
TpmCommGetFlags (
IN TIS_TPM_HANDLE TpmHandle,
IN UINT32 FlagSubcap,
OUT VOID *FlagBuffer,
IN UINTN FlagSize
)
{
EFI_STATUS Status;
TPM_RQU_COMMAND_HDR CmdHdr;
TPM_RSP_COMMAND_HDR RspHdr;
UINT32 Size;
CmdHdr.tag = TPM_TAG_RQU_COMMAND;
CmdHdr.paramSize = sizeof (CmdHdr) + sizeof (UINT32) * 3;
CmdHdr.ordinal = TPM_ORD_GetCapability;
Status = TisPcExecute (
TpmHandle,
"%h%d%d%d%/%h%d%r",
&CmdHdr,
TPM_CAP_FLAG,
sizeof (FlagSubcap),
FlagSubcap,
&RspHdr,
&Size,
FlagBuffer,
FlagSize
);
if (EFI_ERROR (Status)) {
return Status;
}
if (RspHdr.returnCode != 0) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Add a new entry to the Event Log.
@param[in, out] EventLogPtr Pointer to the Event Log data.
@param[in, out] LogSize Size of the Event Log.
@param[in] MaxSize Maximum size of the Event Log.
@param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
@param[in] NewEventData Pointer to the new event data.
@retval EFI_SUCCESS The new event log entry was added.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
**/
EFI_STATUS
TpmCommLogEvent (
IN OUT UINT8 **EventLogPtr,
IN OUT UINTN *LogSize,
IN UINTN MaxSize,
IN TCG_PCR_EVENT_HDR *NewEventHdr,
IN UINT8 *NewEventData
)
{
UINT32 NewLogSize;
NewLogSize = sizeof (*NewEventHdr) + NewEventHdr->EventSize;
if (NewLogSize + *LogSize > MaxSize) {
return EFI_OUT_OF_RESOURCES;
}
*EventLogPtr += *LogSize;
*LogSize += NewLogSize;
CopyMem (*EventLogPtr, NewEventHdr, sizeof (*NewEventHdr));
CopyMem (
*EventLogPtr + sizeof (*NewEventHdr),
NewEventData,
NewEventHdr->EventSize
);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,99 @@
/** @file
Definitions and function prototypes used by TPM DXE driver.
Copyright (c) 2005 - 2010, 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 _TPM_COMM_H_
#define _TPM_COMM_H_
/**
Add a new entry to the Event Log.
@param[in, out] EventLogPtr Pointer to the Event Log data.
@param[in, out] LogSize Size of the Event Log.
@param[in] MaxSize Maximum size of the Event Log.
@param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
@param[in] NewEventData Pointer to the new event data.
@retval EFI_SUCCESS The new event log entry was added.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
**/
EFI_STATUS
TpmCommLogEvent (
IN OUT UINT8 **EventLogPtr,
IN OUT UINTN *LogSize,
IN UINTN MaxSize,
IN TCG_PCR_EVENT_HDR *NewEventHdr,
IN UINT8 *NewEventData
);
/**
Extend a TPM PCR.
@param[in] TpmHandle TPM handle.
@param[in] DigestToExtend The 160 bit value representing the event to be recorded.
@param[in] PcrIndex The PCR to be updated.
@param[out] NewPcrValue New PCR value after extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
TpmCommExtend (
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_DIGEST *DigestToExtend,
IN TPM_PCRINDEX PcrIndex,
OUT TPM_DIGEST *NewPcrValue
);
/**
Get TPM capability flags.
@param[in] TpmHandle TPM handle.
@param[in] FlagSubcap Flag subcap.
@param[out] FlagBuffer Pointer to the buffer for returned flag structure.
@param[in] FlagSize Size of the buffer.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
TpmCommGetFlags (
IN TIS_TPM_HANDLE TpmHandle,
IN UINT32 FlagSubcap,
OUT VOID *Buffer,
IN UINTN Size
);
/**
Send formatted command to TPM for execution and return formatted data from response.
@param[in] TisReg TPM Handle.
@param[in] Fmt Format control string.
@param[in] ... The variable argument list.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
**/
EFI_STATUS
EFIAPI
TisPcExecute (
IN TIS_TPM_HANDLE TisReg,
IN CONST CHAR8 *Fmt,
...
);
#endif // _TPM_COMM_H_

View File

@ -0,0 +1,593 @@
/** @file
Initialize TPM device and measure FVs before handing off control to DXE.
Copyright (c) 2005 - 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 <PiPei.h>
#include <IndustryStandard/Tpm12.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Ppi/FirmwareVolumeInfo.h>
#include <Ppi/LockPhysicalPresence.h>
#include <Ppi/TpmInitialized.h>
#include <Ppi/FirmwareVolume.h>
#include <Guid/TcgEventHob.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/TpmCommLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include "TpmComm.h"
BOOLEAN mImageInMemory = FALSE;
EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gPeiTpmInitializedPpiGuid,
NULL
};
/**
Lock physical presence if needed.
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS Operation completed successfully.
**/
EFI_STATUS
EFIAPI
PhysicalPresencePpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
/**
Measure and record the Firmware Volum Information once FvInfoPPI install.
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
@return Others Fail to measure FV.
**/
EFI_STATUS
EFIAPI
FirmwareVolmeInfoPpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
&gPeiLockPhysicalPresencePpiGuid,
PhysicalPresencePpiNotifyCallback
},
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiPeiFirmwareVolumeInfoPpiGuid,
FirmwareVolmeInfoPpiNotifyCallback
}
};
CHAR8 mSCrtmVersion[] = "{D20BC7C6-A1A5-415c-AE85-38290AB6BE04}";
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
UINT32 mMeasuredFvIndex = 0;
/**
Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
and build a GUIDed HOB recording the event which will be passed to the DXE phase and
added into the Event Log.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] HashData Physical address of the start of the data buffer
to be hashed, extended, and logged.
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
@param[in] TpmHandle TPM handle.
@param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
@param[in] NewEventData Pointer to the new event data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
HashLogExtendEvent (
IN EFI_PEI_SERVICES **PeiServices,
IN UINT8 *HashData,
IN UINTN HashDataLen,
IN TIS_TPM_HANDLE TpmHandle,
IN TCG_PCR_EVENT_HDR *NewEventHdr,
IN UINT8 *NewEventData
)
{
EFI_STATUS Status;
VOID *HobData;
HobData = NULL;
if (HashDataLen != 0) {
Status = TpmCommHashAll (
HashData,
HashDataLen,
&NewEventHdr->Digest
);
ASSERT_EFI_ERROR (Status);
}
Status = TpmCommExtend (
PeiServices,
TpmHandle,
&NewEventHdr->Digest,
NewEventHdr->PCRIndex,
NULL
);
ASSERT_EFI_ERROR (Status);
HobData = BuildGuidHob (
&gTcgEventEntryHobGuid,
sizeof (*NewEventHdr) + NewEventHdr->EventSize
);
if (HobData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
return EFI_SUCCESS;
}
/**
Measure CRTM version.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureCRTMVersion (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle
)
{
TCG_PCR_EVENT_HDR TcgEventHdr;
//
// Here, only a static GUID is measured instead of real CRTM version.
// OEMs should get real CRTM version string and measure it.
//
TcgEventHdr.PCRIndex = 0;
TcgEventHdr.EventType = EV_S_CRTM_VERSION;
TcgEventHdr.EventSize = sizeof (mSCrtmVersion);
return HashLogExtendEvent (
PeiServices,
(UINT8*)&mSCrtmVersion,
TcgEventHdr.EventSize,
TpmHandle,
&TcgEventHdr,
(UINT8*)&mSCrtmVersion
);
}
/**
Measure FV image.
Add it into the measured FV list after the FV is measured successfully.
@param[in] FvBase Base address of FV image.
@param[in] FvLength Length of FV image.
@retval EFI_SUCCESS Fv image is measured successfully
or it has been already measured.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureFvImage (
IN EFI_PHYSICAL_ADDRESS FvBase,
IN UINT64 FvLength
)
{
UINT32 Index;
EFI_STATUS Status;
EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
TCG_PCR_EVENT_HDR TcgEventHdr;
TIS_TPM_HANDLE TpmHandle;
TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
//
// Check whether FV is in the measured FV list.
//
for (Index = 0; Index < mMeasuredFvIndex; Index ++) {
if (mMeasuredFvInfo[Index].BlobBase == FvBase) {
return EFI_SUCCESS;
}
}
//
// Measure and record the FV to the TPM
//
FvBlob.BlobBase = FvBase;
FvBlob.BlobLength = FvLength;
DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));
DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob.BlobLength));
TcgEventHdr.PCRIndex = 0;
TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
TcgEventHdr.EventSize = sizeof (FvBlob);
Status = HashLogExtendEvent (
(EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
(UINT8*) (UINTN) FvBlob.BlobBase,
(UINTN) FvBlob.BlobLength,
TpmHandle,
&TcgEventHdr,
(UINT8*) &FvBlob
);
ASSERT_EFI_ERROR (Status);
//
// Add new FV into the measured FV list.
//
ASSERT (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
if (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
mMeasuredFvInfo[mMeasuredFvIndex].BlobBase = FvBase;
mMeasuredFvInfo[mMeasuredFvIndex++].BlobLength = FvLength;
}
return Status;
}
/**
Measure main BIOS.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureMainBios (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle
)
{
EFI_STATUS Status;
UINT32 FvInstances;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_FV_INFO VolumeInfo;
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
FvInstances = 0;
while (TRUE) {
//
// Traverse all firmware volume instances of Static Core Root of Trust for Measurement
// (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
// platform for special CRTM TPM measuring.
//
Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);
if (EFI_ERROR (Status)) {
break;
}
//
// Measure and record the firmware volume that is dispatched by PeiCore
//
Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
ASSERT_EFI_ERROR (Status);
//
// Locate the corresponding FV_PPI according to founded FV's format guid
//
Status = PeiServicesLocatePpi (
&VolumeInfo.FvFormat,
0,
NULL,
(VOID**)&FvPpi
);
if (!EFI_ERROR (Status)) {
MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
}
FvInstances++;
}
return EFI_SUCCESS;
}
/**
Measure and record the Firmware Volum Information once FvInfoPPI install.
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
@return Others Fail to measure FV.
**/
EFI_STATUS
EFIAPI
FirmwareVolmeInfoPpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
EFI_STATUS Status;
EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
//
// The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
//
Status = PeiServicesLocatePpi (
&Fv->FvFormat,
0,
NULL,
(VOID**)&FvPpi
);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
//
// This is an FV from an FFS file, and the parent FV must have already been measured,
// No need to measure twice, so just returns
//
if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
return EFI_SUCCESS;
}
return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
}
/**
Lock physical presence if needed.
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_ABORTED physicalPresenceCMDEnable is locked.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
PhysicalPresencePpiNotifyCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EFI_STATUS Status;
PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;
BOOLEAN LifetimeLock;
BOOLEAN CmdEnable;
TIS_TPM_HANDLE TpmHandle;
TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;
if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {
return EFI_SUCCESS;
}
//
// Lock TPM physical presence.
//
Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);
if (EFI_ERROR (Status)) {
return Status;
}
if (!CmdEnable) {
if (LifetimeLock) {
//
// physicalPresenceCMDEnable is locked, can't change.
//
return EFI_ABORTED;
}
//
// Enable physical presence command
// It is necessary in order to lock physical presence
//
Status = TpmCommPhysicalPresence (
PeiServices,
TpmHandle,
TPM_PHYSICAL_PRESENCE_CMD_ENABLE
);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Lock physical presence
//
Status = TpmCommPhysicalPresence (
PeiServices,
TpmHandle,
TPM_PHYSICAL_PRESENCE_LOCK
);
return Status;
}
/**
Check if TPM chip is activeated or not.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@retval TRUE TPM is activated.
@retval FALSE TPM is deactivated.
**/
BOOLEAN
EFIAPI
IsTpmUsable (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle
)
{
EFI_STATUS Status;
BOOLEAN Deactivated;
Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);
if (EFI_ERROR (Status)) {
return FALSE;
}
return (BOOLEAN)(!Deactivated);
}
/**
Do measurement after memory is ready.
@param[in] PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
PeimEntryMP (
IN EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
TIS_TPM_HANDLE TpmHandle;
TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
if (EFI_ERROR (Status)) {
return Status;
}
if (IsTpmUsable (PeiServices, TpmHandle)) {
Status = MeasureCRTMVersion (PeiServices, TpmHandle);
ASSERT_EFI_ERROR (Status);
Status = MeasureMainBios (PeiServices, TpmHandle);
}
//
// Post callbacks:
// 1). for the FvInfoPpi services to measure and record
// the additional Fvs to TPM
// 2). for the OperatorPresencePpi service to determine whether to
// lock the TPM
//
Status = PeiServicesNotifyPpi (&mNotifyList[0]);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Entry point of this module.
@param[in] FileHandle Handle of the file being invoked.
@param[in] PeiServices Describes the list of possible PEI Services.
@return Status.
**/
EFI_STATUS
EFIAPI
PeimEntryMA (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
TIS_TPM_HANDLE TpmHandle;
if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
return EFI_UNSUPPORTED;
}
Status = (**PeiServices).RegisterForShadow(FileHandle);
if (Status == EFI_ALREADY_STARTED) {
mImageInMemory = TRUE;
} else if (Status == EFI_NOT_FOUND) {
ASSERT_EFI_ERROR (Status);
}
if (!mImageInMemory) {
//
// Initialize TPM device
//
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
return Status;
}
Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
if (EFI_ERROR (Status) ) {
return Status;
}
Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
ASSERT_EFI_ERROR (Status);
}
if (mImageInMemory) {
Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
if (EFI_ERROR (Status)) {
return Status;
}
}
return Status;
}

View File

@ -0,0 +1,67 @@
## @file
# This module will initialize TPM device and measure FVs in PEI phase.
#
# Copyright (c) 2006 - 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 = TcgPei
FILE_GUID = 2BE1E4A6-6505-43b3-9FFC-A3C8330E0432
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimEntryMA
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
TcgPei.c
TisPei.c
TpmComm.c
TpmComm.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
HobLib
PeimEntryPoint
PeiServicesLib
BaseMemoryLib
DebugLib
TpmCommLib
TimerLib
IoLib
PeiServicesTablePointerLib
[Guids]
gTcgEventEntryHobGuid
[Ppis]
gPeiLockPhysicalPresencePpiGuid
gEfiPeiFirmwareVolumeInfoPpiGuid
gPeiTpmInitializedPpiGuid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
[FixedPcd]
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
[Depex]
gEfiPeiMasterBootModePpiGuid AND
gEfiPeiReadOnlyVariable2PpiGuid

View File

@ -0,0 +1,160 @@
/** @file
TIS (TPM Interface Specification) functions used by TPM PEI driver.
Copyright (c) 2005 - 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 <IndustryStandard/Tpm12.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/TpmCommLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <Library/BaseMemoryLib.h>
/**
Send a command to TPM for execution and return response data.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TisReg TPM register space base address.
@param[in] BufferIn Buffer for command data.
@param[in] SizeIn Size of command data.
@param[in, out] BufferOut Buffer for response data.
@param[in, out] SizeOut Size of response data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TisTpmCommand (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_PC_REGISTERS_PTR TisReg,
IN UINT8 *BufferIn,
IN UINT32 SizeIn,
IN OUT UINT8 *BufferOut,
IN OUT UINT32 *SizeOut
)
{
EFI_STATUS Status;
UINT16 BurstCount;
UINT32 Index;
UINT32 TpmOutSize;
UINT16 Data16;
UINT32 Data32;
Status = TisPcPrepareCommand (TisReg);
if (EFI_ERROR (Status)){
DEBUG ((DEBUG_ERROR, "Tpm is not ready for command!\n"));
return Status;
}
//
// Send the command data to Tpm
//
Index = 0;
while (Index < SizeIn) {
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status)) {
Status = EFI_TIMEOUT;
goto Exit;
}
for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {
MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
Index++;
}
}
//
// Check the Tpm status STS_EXPECT change from 1 to 0
//
Status = TisPcWaitRegisterBits (
&TisReg->Status,
(UINT8) TIS_PC_VALID,
TIS_PC_STS_EXPECT,
TIS_TIMEOUT_C
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "The send buffer too small!\n"));
Status = EFI_BUFFER_TOO_SMALL;
goto Exit;
}
//
// Executed the TPM command and waiting for the response data ready
//
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);
Status = TisPcWaitRegisterBits (
&TisReg->Status,
(UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
0,
TIS_TIMEOUT_B
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Wait for Tpm response data time out!!\n"));
Status = EFI_TIMEOUT;
goto Exit;
}
//
// Get response data header
//
Index = 0;
BurstCount = 0;
while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status)) {
Status = EFI_TIMEOUT;
goto Exit;
}
for (; BurstCount > 0; BurstCount--) {
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
Index++;
if (Index == sizeof (TPM_RSP_COMMAND_HDR)) break;
}
}
//
// Check the reponse data header (tag,parasize and returncode )
//
CopyMem (&Data16, BufferOut, sizeof (UINT16));
if (SwapBytes16 (Data16) != TPM_TAG_RSP_COMMAND ) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
TpmOutSize = SwapBytes32 (Data32);
if (*SizeOut < TpmOutSize) {
Status = EFI_BUFFER_TOO_SMALL;
goto Exit;
}
*SizeOut = TpmOutSize;
//
// Continue reading the remaining data
//
while ( Index < TpmOutSize ) {
for (; BurstCount > 0; BurstCount--) {
*(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
Index++;
if (Index == TpmOutSize) {
Status = EFI_SUCCESS;
goto Exit;
}
}
Status = TisPcReadBurstCount (TisReg, &BurstCount);
if (EFI_ERROR (Status)) {
Status = EFI_TIMEOUT;
goto Exit;
}
}
Exit:
MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
return Status;
}

View File

@ -0,0 +1,272 @@
/** @file
Utility functions used by TPM PEI driver.
Copyright (c) 2005 - 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 "TpmComm.h"
/**
Send a command to TPM for execution and return response data.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TisReg TPM register space base address.
@param[in] BufferIn Buffer for command data.
@param[in] SizeIn Size of command data.
@param[in, out] BufferOut Buffer for response data.
@param[in, out] SizeOut size of response data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TisTpmCommand (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_PC_REGISTERS_PTR TisReg,
IN UINT8 *BufferIn,
IN UINT32 SizeIn,
IN OUT UINT8 *BufferOut,
IN OUT UINT32 *SizeOut
);
/**
Send TPM_Startup command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] BootMode Boot mode.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommStartup (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN EFI_BOOT_MODE BootMode
)
{
EFI_STATUS Status;
TPM_STARTUP_TYPE TpmSt;
UINT32 TpmRecvSize;
UINT32 TpmSendSize;
TPM_CMD_START_UP SendBuffer;
UINT8 RecvBuffer[20];
TpmSt = TPM_ST_CLEAR;
if (BootMode == BOOT_ON_S3_RESUME) {
TpmSt = TPM_ST_STATE;
}
//
// send Tpm command TPM_ORD_Startup
//
TpmRecvSize = 20;
TpmSendSize = sizeof (TPM_CMD_START_UP);
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Startup);
SendBuffer.TpmSt = SwapBytes16 (TpmSt);
Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
return Status;
}
/**
Send TPM_ContinueSelfTest command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommContinueSelfTest (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle
)
{
EFI_STATUS Status;
UINT32 TpmRecvSize;
UINT32 TpmSendSize;
TPM_CMD_SELF_TEST SendBuffer;
UINT8 RecvBuffer[20];
//
// send Tpm command TPM_ORD_ContinueSelfTest
//
TpmRecvSize = 20;
TpmSendSize = sizeof (TPM_CMD_SELF_TEST);
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_ContinueSelfTest);
Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
return Status;
}
/**
Get TPM capability flags.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[out] Deactivated Returns deactivated flag.
@param[out] LifetimeLock Returns physicalPresenceLifetimeLock permanent flag.
@param[out] CmdEnable Returns physicalPresenceCMDEnable permanent flag.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommGetCapability (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
OUT BOOLEAN *Deactivated, OPTIONAL
OUT BOOLEAN *LifetimeLock, OPTIONAL
OUT BOOLEAN *CmdEnable OPTIONAL
)
{
EFI_STATUS Status;
UINT32 TpmRecvSize;
UINT32 TpmSendSize;
TPM_CMD_GET_CAPABILITY SendBuffer;
UINT8 RecvBuffer[40];
TPM_PERMANENT_FLAGS *TpmPermanentFlags;
//
// send Tpm command TPM_ORD_GetCapability
//
TpmRecvSize = 40;
TpmSendSize = sizeof (TPM_CMD_GET_CAPABILITY);
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_GetCapability);
SendBuffer.Capability = SwapBytes32 (TPM_CAP_FLAG);
SendBuffer.CapabilityFlagSize = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
SendBuffer.CapabilityFlag = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
if (EFI_ERROR (Status)) {
return Status;
}
TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
if (Deactivated != NULL) {
*Deactivated = TpmPermanentFlags->deactivated;
}
if (LifetimeLock != NULL) {
*LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;
}
if (CmdEnable != NULL) {
*CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;
}
return Status;
}
/**
Extend a TPM PCR.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] DigestToExtend The 160 bit value representing the event to be recorded.
@param[in] PcrIndex The PCR to be updated.
@param[out] NewPcrValue New PCR value after extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommExtend (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_DIGEST *DigestToExtend,
IN TPM_PCRINDEX PcrIndex,
OUT TPM_DIGEST *NewPcrValue
)
{
EFI_STATUS Status;
UINT32 TpmSendSize;
UINT32 TpmRecvSize;
TPM_CMD_EXTEND SendBuffer;
UINT8 RecvBuffer[10 + sizeof(TPM_DIGEST)];
//
// send Tpm command TPM_ORD_Extend
//
TpmRecvSize = sizeof (TPM_RSP_COMMAND_HDR) + sizeof (TPM_DIGEST);
TpmSendSize = sizeof (TPM_CMD_EXTEND);
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_Extend);
SendBuffer.PcrIndex = SwapBytes32 (PcrIndex);
CopyMem (&SendBuffer.TpmDigest, (UINT8 *)DigestToExtend, sizeof (TPM_DIGEST));
Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
ASSERT_EFI_ERROR (Status);
if(NewPcrValue != NULL) {
CopyMem ((UINT8*)NewPcrValue, &RecvBuffer[10], sizeof (TPM_DIGEST));
}
return Status;
}
/**
Send TSC_PhysicalPresence command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] PhysicalPresence The state to set the TPMs Physical Presence flags.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommPhysicalPresence (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_PHYSICAL_PRESENCE PhysicalPresence
)
{
EFI_STATUS Status;
UINT32 TpmSendSize;
UINT32 TpmRecvSize;
TPM_CMD_PHYSICAL_PRESENCE SendBuffer;
UINT8 RecvBuffer[10];
//
// send Tpm command TSC_ORD_PhysicalPresence
//
TpmRecvSize = 10;
TpmSendSize = sizeof (TPM_CMD_PHYSICAL_PRESENCE);
SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
SendBuffer.Hdr.paramSize = SwapBytes32 (TpmSendSize);
SendBuffer.Hdr.ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence);
SendBuffer.PhysicalPresence = SwapBytes16 (PhysicalPresence);
Status = TisTpmCommand (PeiServices, TpmHandle, (UINT8 *)&SendBuffer, TpmSendSize, RecvBuffer, &TpmRecvSize);
return Status;
}

View File

@ -0,0 +1,163 @@
/** @file
The header file for TPM PEI driver.
Copyright (c) 2005 - 2010, 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 _TPM_COMM_H_
#define _TPM_COMM_H_
#include <IndustryStandard/Tpm12.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/TpmCommLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#pragma pack(1)
typedef struct {
TPM_RQU_COMMAND_HDR Hdr;
TPM_STARTUP_TYPE TpmSt;
} TPM_CMD_START_UP;
typedef struct {
TPM_RQU_COMMAND_HDR Hdr;
} TPM_CMD_SELF_TEST;
typedef struct {
TPM_RQU_COMMAND_HDR Hdr;
UINT32 Capability;
UINT32 CapabilityFlagSize;
UINT32 CapabilityFlag;
} TPM_CMD_GET_CAPABILITY;
typedef struct {
TPM_RQU_COMMAND_HDR Hdr;
TPM_PCRINDEX PcrIndex;
TPM_DIGEST TpmDigest;
} TPM_CMD_EXTEND;
typedef struct {
TPM_RQU_COMMAND_HDR Hdr;
TPM_PHYSICAL_PRESENCE PhysicalPresence;
} TPM_CMD_PHYSICAL_PRESENCE;
#pragma pack()
/**
Send TPM_Startup command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] BootMode Boot mode.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommStartup (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN EFI_BOOT_MODE BootMode
);
/**
Send TPM_ContinueSelfTest command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommContinueSelfTest (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle
);
/**
Get TPM capability flags.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[out] Deactivated Returns deactivated flag.
@param[out] LifetimeLock Returns physicalPresenceLifetimeLock permanent flag.
@param[out] CmdEnable Returns physicalPresenceCMDEnable permanent flag.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommGetCapability (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
OUT BOOLEAN *Deactivated, OPTIONAL
OUT BOOLEAN *LifetimeLock, OPTIONAL
OUT BOOLEAN *CmdEnable OPTIONAL
);
/**
Extend a TPM PCR.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] DigestToExtend The 160 bit value representing the event to be recorded.
@param[in] PcrIndex The PCR to be updated.
@param[out] NewPcrValue New PCR value after extend.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommExtend (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_DIGEST *DigestToExtend,
IN TPM_PCRINDEX PcrIndex,
OUT TPM_DIGEST *NewPcrValue
);
/**
Send TSC_PhysicalPresence command to TPM.
@param[in] PeiServices Describes the list of possible PEI Services.
@param[in] TpmHandle TPM handle.
@param[in] PhysicalPresence The state to set the TPMs Physical Presence flags.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_TIMEOUT The register can't run into the expected status in time.
@retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
@retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
TpmCommPhysicalPresence (
IN EFI_PEI_SERVICES **PeiServices,
IN TIS_TPM_HANDLE TpmHandle,
IN TPM_PHYSICAL_PRESENCE PhysicalPresence
);
#endif // _TPM_COMM_H_

View File

@ -0,0 +1,455 @@
/** @file
It updates TPM items in ACPI table and registers SMI callback
functions for physical presence and ClearMemory.
Copyright (c) 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 <PiDxe.h>
#include <IndustryStandard/Acpi.h>
#include <Guid/PhysicalPresenceData.h>
#include <Guid/MemoryOverwriteControl.h>
#include <Protocol/SmmSwDispatch2.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/SmmVariable.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesLib.h>
//
// AML parsing definitions
//
#define AML_OPREGION_OP 0x80
#define AML_BYTE_PREFIX 0x0A
#define AML_DWORD_PREFIX 0x0C
#pragma pack(1)
typedef struct {
UINT8 SoftwareSmi;
UINT32 Parameter;
UINT32 Response;
UINT32 Request;
UINT32 LastRequest;
UINT32 ReturnCode;
} PHYSICAL_PRESENCE_NVS;
typedef struct {
UINT8 SoftwareSmi;
UINT32 Parameter;
UINT32 Request;
} MEMORY_CLEAR_NVS;
typedef struct {
PHYSICAL_PRESENCE_NVS PhysicalPresence;
MEMORY_CLEAR_NVS MemoryClear;
} TCG_NVS;
typedef struct {
UINT8 OpRegionOp;
UINT32 NameString;
UINT8 RegionSpace;
UINT8 DWordPrefix;
UINT32 RegionOffset;
UINT8 BytePrefix;
UINT8 RegionLen;
} AML_OP_REGION_32_8;
#pragma pack()
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
TCG_NVS *mTcgNvs;
/**
Software SMI callback for TPM physical presence which is called from ACPI method.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] Context Points to an optional handler context which was specified when the
handler was registered.
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
be conveyed from a non-SMM environment into an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
@retval EFI_SUCCESS The interrupt was handled successfully.
**/
EFI_STATUS
EFIAPI
PhysicalPresenceCallback (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommBufferSize
)
{
EFI_STATUS Status;
UINTN DataSize;
EFI_PHYSICAL_PRESENCE PpData;
UINT8 Flags;
BOOLEAN RequestConfirmed;
//
// Get the Physical Presence variable
//
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
Status = mSmmVariable->SmmGetVariable (
PHYSICAL_PRESENCE_VARIABLE,
&gEfiPhysicalPresenceGuid,
NULL,
&DataSize,
&PpData
);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
DEBUG ((EFI_D_INFO, "[TPM] PP callback, Parameter = %x\n", mTcgNvs->PhysicalPresence.Parameter));
if (mTcgNvs->PhysicalPresence.Parameter == 5) {
//
// Return TPM Operation Response to OS Environment
//
mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest;
mTcgNvs->PhysicalPresence.Response = PpData.PPResponse;
} else if ((mTcgNvs->PhysicalPresence.Parameter == 2) || (mTcgNvs->PhysicalPresence.Parameter == 7)) {
//
// Submit TPM Operation Request to Pre-OS Environment
//
if (mTcgNvs->PhysicalPresence.Request == SET_OPERATOR_AUTH) {
//
// This command requires UI to prompt user for Auth data, NOT implemented.
//
mTcgNvs->PhysicalPresence.ReturnCode = 1;
return EFI_SUCCESS;
}
if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) {
PpData.PPRequest = (UINT8) mTcgNvs->PhysicalPresence.Request;
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
Status = mSmmVariable->SmmSetVariable (
PHYSICAL_PRESENCE_VARIABLE,
&gEfiPhysicalPresenceGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
DataSize,
&PpData
);
}
if (EFI_ERROR (Status)) {
//
// General failure.
//
mTcgNvs->PhysicalPresence.ReturnCode = 2;
return EFI_SUCCESS;
}
mTcgNvs->PhysicalPresence.ReturnCode = 0;
} else if (mTcgNvs->PhysicalPresence.Parameter == 8) {
//
// Get User Confirmation Status for Operation
//
Flags = PpData.Flags;
RequestConfirmed = FALSE;
switch (mTcgNvs->PhysicalPresence.Request) {
case ENABLE:
case DISABLE:
case ACTIVATE:
case DEACTIVATE:
case ENABLE_ACTIVATE:
case DEACTIVATE_DISABLE:
case SET_OWNER_INSTALL_TRUE:
case SET_OWNER_INSTALL_FALSE:
case ENABLE_ACTIVATE_OWNER_TRUE:
case DEACTIVATE_DISABLE_OWNER_FALSE:
if ((Flags & FLAG_NO_PPI_PROVISION) != 0) {
RequestConfirmed = TRUE;
}
break;
case CLEAR:
case ENABLE_ACTIVATE_CLEAR:
if ((Flags & FLAG_NO_PPI_CLEAR) != 0) {
RequestConfirmed = TRUE;
}
break;
case DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) {
RequestConfirmed = TRUE;
}
break;
case ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
case CLEAR_ENABLE_ACTIVATE:
if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) {
RequestConfirmed = TRUE;
}
break;
case SET_NO_PPI_PROVISION_FALSE:
case SET_NO_PPI_CLEAR_FALSE:
case SET_NO_PPI_MAINTENANCE_FALSE:
case NO_ACTION:
RequestConfirmed = TRUE;
break;
case SET_OPERATOR_AUTH:
//
// This command requires UI to prompt user for Auth data
// Here it is NOT implemented
//
mTcgNvs->PhysicalPresence.ReturnCode = 0;
return EFI_SUCCESS;
}
if (RequestConfirmed) {
//
// Allowed and physically present user not required
//
mTcgNvs->PhysicalPresence.ReturnCode = 4;
} else {
//
// Allowed and physically present user required
//
mTcgNvs->PhysicalPresence.ReturnCode = 3;
}
}
return EFI_SUCCESS;
}
/**
Software SMI callback for MemoryClear which is called from ACPI method.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] Context Points to an optional handler context which was specified when the
handler was registered.
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
be conveyed from a non-SMM environment into an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
@retval EFI_SUCCESS The interrupt was handled successfully.
**/
EFI_STATUS
EFIAPI
MemoryClearCallback (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommBufferSize
)
{
EFI_STATUS Status;
UINTN DataSize;
UINT8 MorControl;
if (mTcgNvs->MemoryClear.Parameter == 1) {
//
// Called from ACPI _DSM method, save the MOR data to variable.
//
MorControl = (UINT8) mTcgNvs->MemoryClear.Request;
} else if (mTcgNvs->MemoryClear.Parameter == 2) {
//
// Called from ACPI _PTS method, setup ClearMemory flags if needed.
//
DataSize = sizeof (UINT8);
Status = mSmmVariable->SmmGetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
NULL,
&DataSize,
&MorControl
);
if (EFI_ERROR (Status)) {
ASSERT (Status == EFI_NOT_FOUND);
return EFI_SUCCESS;
}
if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
return EFI_SUCCESS;
}
MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;
}
DataSize = sizeof (UINT8);
Status = mSmmVariable->SmmSetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
DataSize,
&MorControl
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
Find the operation region in TCG ACPI table by given Name and Size,
and initialize it if the region is found.
@param[in, out] Table The TPM item in ACPI table.
@param[in] Name The name string to find in TPM table.
@param[in] Size The size of the region to find.
@return The allocated address for the found region.
**/
VOID *
AssignOpRegion (
EFI_ACPI_DESCRIPTION_HEADER *Table,
UINT32 Name,
UINT16 Size
)
{
EFI_STATUS Status;
AML_OP_REGION_32_8 *OpRegion;
EFI_PHYSICAL_ADDRESS MemoryAddress;
MemoryAddress = SIZE_4GB - 1;
//
// Patch some pointers for the ASL code before loading the SSDT.
//
for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1);
OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);
OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {
if ((OpRegion->OpRegionOp == AML_OPREGION_OP) &&
(OpRegion->NameString == Name) &&
(OpRegion->RegionLen == Size) &&
(OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
(OpRegion->BytePrefix == AML_BYTE_PREFIX)) {
Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);
ASSERT_EFI_ERROR (Status);
ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);
OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress;
break;
}
}
return (VOID *) (UINTN) MemoryAddress;
}
/**
Initialize and publish TPM items in ACPI table.
@retval EFI_SUCCESS The TCG ACPI table is published successfully.
@retval Others The TCG ACPI table is not published.
**/
EFI_STATUS
PublishAcpiTable (
VOID
)
{
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
UINTN TableKey;
EFI_ACPI_DESCRIPTION_HEADER *Table;
UINTN TableSize;
Status = GetSectionFromFv (
&gEfiCallerIdGuid,
EFI_SECTION_RAW,
0,
(VOID **) &Table,
&TableSize
);
ASSERT_EFI_ERROR (Status);
ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'c', 'g', 'T', 'a', 'b', 'l', 'e'));
mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), sizeof (TCG_NVS));
ASSERT (mTcgNvs != NULL);
//
// Publish the TPM ACPI table
//
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
ASSERT_EFI_ERROR (Status);
TableKey = 0;
Status = AcpiTable->InstallAcpiTable (
AcpiTable,
Table,
TableSize,
&TableKey
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
The driver's entry point.
It install callbacks for TPM physical presence and MemoryClear, and locate
SMM variable to be used in the callback function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval Others Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeTcgSmm (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
EFI_SMM_SW_REGISTER_CONTEXT SwContext;
EFI_HANDLE SwHandle;
Status = PublishAcpiTable ();
ASSERT_EFI_ERROR (Status);
//
// Get the Sw dispatch protocol and register SMI callback functions.
//
Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);
ASSERT_EFI_ERROR (Status);
SwContext.SwSmiInputValue = (UINTN) -1;
Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;
SwContext.SwSmiInputValue = (UINTN) -1;
Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;
//
// Locate SmmVariableProtocol.
//
Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,56 @@
## @file
# This driver implements TPM definition block in ACPI table and
# registers SMI callback functions for physical presence and
# MemoryClear to handle the requests from ACPI method.
#
# Copyright (c) 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 = TcgSmm
FILE_GUID = 42293093-76B9-4482-8C02-3BEFDEA9B35D
MODULE_TYPE = DXE_SMM_DRIVER
PI_SPECIFICATION_VERSION = 0x0001000A
VERSION_STRING = 1.0
ENTRY_POINT = InitializeTcgSmm
[Sources]
TcgSmm.c
Tpm.asl
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
UefiDriverEntryPoint
SmmServicesTableLib
UefiBootServicesTableLib
DebugLib
DxeServicesLib
[Guids]
gEfiPhysicalPresenceGuid
gEfiMemoryOverwriteControlDataGuid
[Protocols]
gEfiSmmSwDispatch2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSmmVariableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[Depex]
gEfiAcpiTableProtocolGuid AND
gEfiSmmSwDispatch2ProtocolGuid AND
gEfiSmmVariableProtocolGuid AND
gEfiTcgProtocolGuid

View File

@ -0,0 +1,354 @@
/** @file
The TPM definition block in ACPI table for physical presence
and MemoryClear.
Copyright (c) 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.
**/
DefinitionBlock (
"Tpm.aml",
"SSDT",
1,
"Intel_",
"TcgTable",
0x1000
)
{
Scope (\_SB)
{
Device (TPM)
{
//
// Define _HID, "PNP0C31" is defined in
// "Secure Startup-FVE and TPM Admin BIOS and Platform Requirements"
//
Name (_HID, EISAID ("PNP0C31"))
//
// Readable name of this device, don't know if this way is correct yet
//
Name (_STR, Unicode ("TPM 1.2 Device"))
//
// Return the resource consumed by TPM device
//
Name (_CRS, ResourceTemplate () {
Memory32Fixed (ReadOnly, 0xfed40000, 0x5000)
})
//
// Operational region for Smi port access
//
OperationRegion (SMIP, SystemIO, 0xB2, 1)
Field (SMIP, ByteAcc, NoLock, Preserve)
{
IOB2, 8
}
//
// Operational region for TPM access
//
OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000)
Field (TPMR, AnyAcc, NoLock, Preserve)
{
ACC0, 8,
}
//
// Operational region for TPM support, TPM Physical Presence and TPM Memory Clear
// Region Offset to be fixed at runtime
//
OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0x1E)
Field (TNVS, AnyAcc, NoLock, Preserve)
{
PPIN, 8, // Software SMI for Physical Presence Interface
PPIP, 32, // Used for save physical presence paramter
PPRP, 32, // Physical Presence request operation response
PPRQ, 32, // Physical Presence request operation
LPPR, 32, // Last Physical Presence request operation
FRET, 32, // Physical Presence function return code
MCIN, 8, // Software SMI for Memory Clear Interface
MCIP, 32, // Used for save the Mor paramter
MORD, 32 // Memory Overwrite Request Data
}
Method (PTS, 1, Serialized)
{
//
// Detect Sx state for MOR, only S4, S5 need to handle
//
If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))
{
//
// Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.
//
If (LNot (And (MORD, 0x10)))
{
//
// Triggle the SMI through ACPI _PTS method.
//
Store (0x02, MCIP)
//
// Triggle the SMI interrupt
//
Store (MCIN, IOB2)
}
}
Return (0)
}
Method (_STA, 0)
{
if (LEqual (ACC0, 0xff))
{
Return (0)
}
Return (0x0f)
}
//
// TCG Hardware Information
//
Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {IntObj, IntObj, PkgObj})
{
//
// Switch by function index
//
Switch (ToInteger(Arg1))
{
Case (0)
{
//
// Standard query
//
Return (Buffer () {0x03})
}
Case (1)
{
//
// Return failure if no TPM present
//
Name(TPMV, Package () {0x01, Package () {ToBCD (1), ToBCD (20)}})
if (LEqual (_STA (), 0x00))
{
Return (Package () {0x00})
}
//
// Return TPM version
//
Return (TPMV)
}
Default {BreakPoint}
}
Return (Buffer () {0})
}
Name(TPM2, Package (0x02){
Zero,
Zero
})
Name(TPM3, Package (0x03){
Zero,
Zero,
Zero
})
//
// TCG Physical Presence Interface
//
Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {IntObj, IntObj, PkgObj})
{
//
// Switch by function index
//
Switch (ToInteger(Arg1))
{
Case (0)
{
//
// Standard query, supports function 1-8
//
Return (Buffer () {0xFF, 0x01})
}
Case (1)
{
//
// a) Get Physical Presence Interface Version
//
Return ("1.2")
}
Case (2)
{
//
// b) Submit TPM Operation Request to Pre-OS Environment
//
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
Store (0x02, PPIP)
//
// Triggle the SMI interrupt
//
Store (PPIN, IOB2)
Return (FRET)
}
Case (3)
{
//
// c) Get Pending TPM Operation Requested By the OS
//
Store (PPRQ, Index (TPM2, 0x01))
Return (TPM2)
}
Case (4)
{
//
// d) Get Platform-Specific Action to Transition to Pre-OS Environment
//
Return (2)
}
Case (5)
{
//
// e) Return TPM Operation Response to OS Environment
//
Store (0x05, PPIP)
//
// Triggle the SMI interrupt
//
Store (PPIN, IOB2)
Store (LPPR, Index (TPM3, 0x01))
Store (PPRP, Index (TPM3, 0x02))
Return (TPM3)
}
Case (6)
{
//
// f) Submit preferred user language (Not implemented)
//
Return (3)
}
Case (7)
{
//
// g) Submit TPM Operation Request to Pre-OS Environment 2
//
Store (7, PPIP)
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
//
// Triggle the SMI interrupt
//
Store (PPIN, IOB2)
Return (FRET)
}
Case (8)
{
//
// e) Get User Confirmation Status for Operation
//
Store (8, PPIP)
Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
//
// Triggle the SMI interrupt
//
Store (PPIN, IOB2)
Return (FRET)
}
Default {BreakPoint}
}
Return (1)
}
Method (TMCI, 3, Serialized, 0, IntObj, {IntObj, IntObj, PkgObj})
{
//
// Switch by function index
//
Switch (ToInteger (Arg1))
{
Case (0)
{
//
// Standard query, supports function 1-1
//
Return (Buffer () {0x03})
}
Case (1)
{
//
// Save the Operation Value of the Request to MORD (reserved memory)
//
Store (DerefOf (Index (Arg2, 0x00)), MORD)
//
// Triggle the SMI through ACPI _DSM method.
//
Store (0x01, MCIP)
//
// Triggle the SMI interrupt
//
Store (MCIN, IOB2)
Return (0)
}
Default {BreakPoint}
}
Return (1)
}
Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
{
//
// TCG Hardware Information
//
If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))
{
Return (HINF (Arg1, Arg2, Arg3))
}
//
// TCG Physical Presence Interface
//
If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
{
Return (TPPI (Arg1, Arg2, Arg3))
}
//
// TCG Memory Clear Interface
//
If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))
{
Return (TMCI (Arg1, Arg2, Arg3))
}
Return (Buffer () {0})
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,354 @@
/** @file
Password Credential Provider driver header file.
Copyright (c) 2009 - 2010, 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 _PASSWORD_CREDENTIAL_PROVIDER_H_
#define _PASSWORD_CREDENTIAL_PROVIDER_H_
#include <Uefi.h>
#include <Guid/GlobalVariable.h>
#include <Guid/MdeModuleHii.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/BaseCryptLib.h>
#include "PwdCredentialProviderData.h"
extern UINT8 PwdCredentialProviderStrings[];
extern UINT8 PwdCredentialProviderVfrBin[];
#define PASSWORD_TABLE_INC 16
#define CREDENTIAL_LEN 20
//
// Password credential information.
//
typedef struct {
EFI_USER_INFO_IDENTIFIER UserId;
CHAR8 Password[CREDENTIAL_LEN];
} PASSWORD_INFO;
//
// Password credential table.
//
typedef struct {
UINTN Count;
UINTN MaxCount;
UINTN ValidIndex;
PASSWORD_INFO UserInfo[1];
} CREDENTIAL_TABLE;
//
// The user information on the password provider.
//
typedef struct {
UINTN Count;
EFI_USER_INFO *Info[1];
} PASSWORD_CREDENTIAL_INFO;
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
#define PWD_PROVIDER_SIGNATURE SIGNATURE_32 ('P', 'W', 'D', 'P')
typedef struct {
UINTN Signature;
EFI_HANDLE DriverHandle;
EFI_HII_HANDLE HiiHandle;
//
// Produced protocol.
//
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
} PWD_PROVIDER_CALLBACK_INFO;
/**
Enroll a user on a credential provider.
This function enrolls and deletes a user profile using this credential provider.
If a user profile is successfully enrolled, it calls the User Manager Protocol
function Notify() to notify the user manager driver that credential information
has changed. If an enrolled user does exist, delete the user on the credential
provider.
@param[in] This Points to this instance of EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] User The user profile to enroll.
@retval EFI_SUCCESS User profile was successfully enrolled.
@retval EFI_ACCESS_DENIED Current user profile does not permit enrollment on the
user profile handle. Either the user profile cannot enroll
on any user profile or cannot enroll on a user profile
other than the current user profile.
@retval EFI_UNSUPPORTED This credential provider does not support enrollment in
the pre-OS.
@retval EFI_DEVICE_ERROR The new credential could not be created because of a device
error.
@retval EFI_INVALID_PARAMETER User does not refer to a valid user profile handle.
**/
EFI_STATUS
EFIAPI
CredentialEnroll (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User
);
/**
Returns the user interface information used during user identification.
This function returns information about the form used when interacting with the
user during user identification. The form is the first enabled form in the form-set
class EFI_HII_USER_CREDENTIAL_FORMSET_GUID installed on the HII handle HiiHandle. If
the user credential provider does not require a form to identify the user, then this
function should return EFI_NOT_FOUND.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] Hii On return, holds the HII database handle.
@param[out] FormSetId On return, holds the identifier of the form set which contains
the form used during user identification.
@param[out] FormId On return, holds the identifier of the form used during user
identification.
@retval EFI_SUCCESS Form returned successfully.
@retval EFI_NOT_FOUND Form not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or FormSetId is NULL or FormId is NULL.
**/
EFI_STATUS
EFIAPI
CredentialForm (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_GUID *FormSetId,
OUT EFI_FORM_ID *FormId
);
/**
Returns bitmap used to describe the credential provider type.
This optional function returns a bitmap which is less than or equal to the number
of pixels specified by Width and Height. If no such bitmap exists, then EFI_NOT_FOUND
is returned.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in, out] Width On entry, points to the desired bitmap width. If NULL then no
bitmap information will be returned. On exit, points to the
width of the bitmap returned.
@param[in, out] Height On entry, points to the desired bitmap height. If NULL then no
bitmap information will be returned. On exit, points to the
height of the bitmap returned
@param[out] Hii On return, holds the HII database handle.
@param[out] Image On return, holds the HII image identifier.
@retval EFI_SUCCESS Image identifier returned successfully.
@retval EFI_NOT_FOUND Image identifier not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or Image is NULL.
**/
EFI_STATUS
EFIAPI
CredentialTile (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN OUT UINTN *Width,
IN OUT UINTN *Height,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_IMAGE_ID *Image
);
/**
Returns string used to describe the credential provider type.
This function returns a string which describes the credential provider. If no
such string exists, then EFI_NOT_FOUND is returned.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] Hii On return, holds the HII database handle.
@param[out] String On return, holds the HII string identifier.
@retval EFI_SUCCESS String identifier returned successfully.
@retval EFI_NOT_FOUND String identifier not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or String is NULL.
**/
EFI_STATUS
EFIAPI
CredentialTitle (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_STRING_ID *String
);
/**
Return the user identifier associated with the currently authenticated user.
This function returns the user identifier of the user authenticated by this credential
provider. This function is called after the credential-related information has been
submitted on a form OR after a call to Default() has returned that this credential is
ready to log on.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] User The user profile handle of the user profile currently being
considered by the user identity manager. If NULL, then no user
profile is currently under consideration.
@param[out] Identifier On return, points to the user identifier.
@retval EFI_SUCCESS User identifier returned successfully.
@retval EFI_NOT_READY No user identifier can be returned.
@retval EFI_ACCESS_DENIED The user has been locked out of this user credential.
@retval EFI_INVALID_PARAMETER This is NULL, or Identifier is NULL.
@retval EFI_NOT_FOUND User is not NULL, and the specified user handle can't be
found in user profile database
**/
EFI_STATUS
EFIAPI
CredentialUser (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
OUT EFI_USER_INFO_IDENTIFIER *Identifier
);
/**
Indicate that user interface interaction has begun for the specified credential.
This function is called when a credential provider is selected by the user. If
AutoLogon returns FALSE, then the user interface will be constructed by the User
Identity Manager.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] AutoLogon On return, points to the credential provider's capabilities
after the credential provider has been selected by the user.
@retval EFI_SUCCESS Credential provider successfully selected.
@retval EFI_INVALID_PARAMETER AutoLogon is NULL.
**/
EFI_STATUS
EFIAPI
CredentialSelect (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon
);
/**
Indicate that user interface interaction has ended for the specified credential.
This function is called when a credential provider is deselected by the user.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@retval EFI_SUCCESS Credential provider successfully deselected.
**/
EFI_STATUS
EFIAPI
CredentialDeselect (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This
);
/**
Return the default logon behavior for this user credential.
This function reports the default login behavior regarding this credential provider.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] AutoLogon On return, holds whether the credential provider should be used
by default to automatically log on the user.
@retval EFI_SUCCESS Default information successfully returned.
@retval EFI_INVALID_PARAMETER AutoLogon is NULL.
**/
EFI_STATUS
EFIAPI
CredentialDefault (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon
);
/**
Return information attached to the credential provider.
This function returns user information.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] UserInfo Handle of the user information data record.
@param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On
exit, holds the user information. If the buffer is too small
to hold the information, then EFI_BUFFER_TOO_SMALL is returned
and InfoSize is updated to contain the number of bytes actually
required.
@param[in, out] InfoSize On entry, points to the size of Info. On return, points to the
size of the user information.
@retval EFI_SUCCESS Information returned successfully.
@retval EFI_BUFFER_TOO_SMALL The size specified by InfoSize is too small to hold all of the
user information. The size required is returned in *InfoSize.
@retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.
@retval EFI_NOT_FOUND The specified UserInfo does not refer to a valid user info handle.
**/
EFI_STATUS
EFIAPI
CredentialGetInfo (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_INFO_HANDLE UserInfo,
OUT EFI_USER_INFO *Info,
IN OUT UINTN *InfoSize
);
/**
Enumerate all of the user informations on the credential provider.
This function returns the next user information record. To retrieve the first user
information record handle, point UserInfo at a NULL. Each subsequent call will retrieve
another user information record handle until there are no more, at which point UserInfo
will point to NULL.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in, out] UserInfo On entry, points to the previous user information handle or NULL
to start enumeration. On exit, points to the next user information
handle or NULL if there is no more user information.
@retval EFI_SUCCESS User information returned.
@retval EFI_NOT_FOUND No more user information found.
@retval EFI_INVALID_PARAMETER UserInfo is NULL.
**/
EFI_STATUS
EFIAPI
CredentialGetNextInfo (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN OUT EFI_USER_INFO_HANDLE *UserInfo
);
#endif

View File

@ -0,0 +1,33 @@
/** @file
Data structure used by the Password Credential Provider driver.
Copyright (c) 2009 - 2010, 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 _PWD_CREDENTIAL_PROVIDER_DATA_H_
#define _PWD_CREDENTIAL_PROVIDER_DATA_H_
#define PWD_CREDENTIAL_PROVIDER_GUID \
{ \
0x78b9ec8b, 0xc000, 0x46c5, { 0xac, 0x93, 0x24, 0xa0, 0xc1, 0xbb, 0x0, 0xce } \
}
//
// Forms definition
//
#define FORMID_GET_PASSWORD_FORM 1
//
// Key defination
//
#define KEY_GET_PASSWORD 0x1000
#endif

View File

@ -0,0 +1,53 @@
## @file
# Component description file for Password Credential Provider.
#
# 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 = PwdCredentialProvider
FILE_GUID = D6C589EA-DD29-49ef-97F6-1A9FE19A04E0
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = PasswordProviderInit
[Sources]
PwdCredentialProvider.c
PwdCredentialProvider.h
PwdCredentialProviderData.h
PwdCredentialProviderVfr.Vfr
PwdCredentialProviderStrings.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
UefiDriverEntryPoint
MemoryAllocationLib
BaseMemoryLib
DebugLib
HiiLib
UefiLib
BaseCryptLib
[Guids]
gEfiIfrTianoGuid ## CONSUMES ## Guid
gEfiUserCredentialClassPasswordGuid ## CONSUMES ## Guid
[Protocols]
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiConfigAccessProtocolGuid
gEfiUserCredentialProtocolGuid
gEfiUserManagerProtocolGuid

View File

@ -0,0 +1,35 @@
/** @file
Password Credential Provider formset.
Copyright (c) 2009 - 2010, 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 "PwdCredentialProviderData.h"
formset
guid = PWD_CREDENTIAL_PROVIDER_GUID,
title = STRING_TOKEN(STR_CREDENTIAL_TITLE),
help = STRING_TOKEN(STR_NULL_STRING),
classguid = PWD_CREDENTIAL_PROVIDER_GUID,
form formid = FORMID_GET_PASSWORD_FORM,
title = STRING_TOKEN(STR_FORM_TITLE);
text
help = STRING_TOKEN(STR_NULL_STRING),
text = STRING_TOKEN(STR_INPUT_PASSWORD),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = KEY_GET_PASSWORD;
endform;
endformset;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,354 @@
/** @file
Usb Credential Provider driver header file.
Copyright (c) 2009, 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 _USB_CREDENTIAL_PROVIDER_H_
#define _USB_CREDENTIAL_PROVIDER_H_
#include <Uefi.h>
#include <Guid/GlobalVariable.h>
#include <Guid/MdeModuleHii.h>
#include <Guid/FileInfo.h>
#include <Guid/SecurityPkgTokenSpace.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/BlockIo.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/PcdLib.h>
extern UINT8 UsbCredentialProviderStrings[];
extern UINT8 UsbCredentialProviderVfrBin[];
#define USB_TABLE_INC 16
#define HASHED_CREDENTIAL_LEN 20
#define USB_CREDENTIAL_PROVIDER_GUID \
{ \
0xd0849ed1, 0xa88c, 0x4ba6, { 0xb1, 0xd6, 0xab, 0x50, 0xe2, 0x80, 0xb7, 0xa9 }\
}
//
// Save the enroll user credential Information.
//
typedef struct {
EFI_USER_INFO_IDENTIFIER UserId;
UINT8 Token[HASHED_CREDENTIAL_LEN];
} USB_INFO;
//
// USB Credential Table.
//
typedef struct {
UINTN Count;
UINTN MaxCount;
USB_INFO UserInfo[1];
} CREDENTIAL_TABLE;
//
// The user information on the USB provider.
//
typedef struct {
UINTN Count;
EFI_USER_INFO *Info[1];
} USB_CREDENTIAL_INFO;
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
#define USB_PROVIDER_SIGNATURE SIGNATURE_32 ('U', 'S', 'B', 'P')
typedef struct {
UINTN Signature;
EFI_HANDLE DriverHandle;
EFI_HII_HANDLE HiiHandle;
} USB_PROVIDER_CALLBACK_INFO;
/**
Enroll a user on a credential provider.
This function enrolls and deletes a user profile using this credential provider.
If a user profile is successfully enrolled, it calls the User Manager Protocol
function Notify() to notify the user manager driver that credential information
has changed. If an enrolled user does exist, delete the user on the credential
provider.
@param[in] This Points to this instance of EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] User The user profile to enroll.
@retval EFI_SUCCESS User profile was successfully enrolled.
@retval EFI_ACCESS_DENIED Current user profile does not permit enrollment on the
user profile handle. Either the user profile cannot enroll
on any user profile or cannot enroll on a user profile
other than the current user profile.
@retval EFI_UNSUPPORTED This credential provider does not support enrollment in
the pre-OS.
@retval EFI_DEVICE_ERROR The new credential could not be created because of a device
error.
@retval EFI_INVALID_PARAMETER User does not refer to a valid user profile handle.
**/
EFI_STATUS
EFIAPI
CredentialEnroll (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User
);
/**
Returns the user interface information used during user identification.
This function returns information about the form used when interacting with the
user during user identification. The form is the first enabled form in the form-set
class EFI_HII_USER_CREDENTIAL_FORMSET_GUID installed on the HII handle HiiHandle. If
the user credential provider does not require a form to identify the user, then this
function should return EFI_NOT_FOUND.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] Hii On return, holds the HII database handle.
@param[out] FormSetId On return, holds the identifier of the form set which contains
the form used during user identification.
@param[out] FormId On return, holds the identifier of the form used during user
identification.
@retval EFI_SUCCESS Form returned successfully.
@retval EFI_NOT_FOUND Form not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or FormSetId is NULL or FormId is NULL.
**/
EFI_STATUS
EFIAPI
CredentialForm (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_GUID *FormSetId,
OUT EFI_FORM_ID *FormId
);
/**
Returns bitmap used to describe the credential provider type.
This optional function returns a bitmap which is less than or equal to the number
of pixels specified by Width and Height. If no such bitmap exists, then EFI_NOT_FOUND
is returned.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in, out] Width On entry, points to the desired bitmap width. If NULL then no
bitmap information will be returned. On exit, points to the
width of the bitmap returned.
@param[in, out] Height On entry, points to the desired bitmap height. If NULL then no
bitmap information will be returned. On exit, points to the
height of the bitmap returned.
@param[out] Hii On return, holds the HII database handle.
@param[out] Image On return, holds the HII image identifier.
@retval EFI_SUCCESS Image identifier returned successfully.
@retval EFI_NOT_FOUND Image identifier not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or Image is NULL.
**/
EFI_STATUS
EFIAPI
CredentialTile (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN OUT UINTN *Width,
IN OUT UINTN *Height,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_IMAGE_ID *Image
);
/**
Returns string used to describe the credential provider type.
This function returns a string which describes the credential provider. If no
such string exists, then EFI_NOT_FOUND is returned.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] Hii On return, holds the HII database handle.
@param[out] String On return, holds the HII string identifier.
@retval EFI_SUCCESS String identifier returned successfully.
@retval EFI_NOT_FOUND String identifier not returned.
@retval EFI_INVALID_PARAMETER Hii is NULL or String is NULL.
**/
EFI_STATUS
EFIAPI
CredentialTitle (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_HII_HANDLE *Hii,
OUT EFI_STRING_ID *String
);
/**
Return the user identifier associated with the currently authenticated user.
This function returns the user identifier of the user authenticated by this credential
provider. This function is called after the credential-related information has been
submitted on a form OR after a call to Default() has returned that this credential is
ready to log on.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] User The user profile handle of the user profile currently being
considered by the user identity manager. If NULL, then no user
profile is currently under consideration.
@param[out] Identifier On return, points to the user identifier.
@retval EFI_SUCCESS User identifier returned successfully.
@retval EFI_NOT_READY No user identifier can be returned.
@retval EFI_ACCESS_DENIED The user has been locked out of this user credential.
@retval EFI_INVALID_PARAMETER This is NULL, or Identifier is NULL.
@retval EFI_NOT_FOUND User is not NULL, and the specified user handle can't be
found in user profile database.
**/
EFI_STATUS
EFIAPI
CredentialUser (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
OUT EFI_USER_INFO_IDENTIFIER *Identifier
);
/**
Indicate that user interface interaction has begun for the specified credential.
This function is called when a credential provider is selected by the user. If
AutoLogon returns FALSE, then the user interface will be constructed by the User
Identity Manager.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] AutoLogon On return, points to the credential provider's capabilities
after the credential provider has been selected by the user.
@retval EFI_SUCCESS Credential provider successfully selected.
@retval EFI_INVALID_PARAMETER AutoLogon is NULL.
**/
EFI_STATUS
EFIAPI
CredentialSelect (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon
);
/**
Indicate that user interface interaction has ended for the specified credential.
This function is called when a credential provider is deselected by the user.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@retval EFI_SUCCESS Credential provider successfully deselected.
**/
EFI_STATUS
EFIAPI
CredentialDeselect (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This
);
/**
Return the default logon behavior for this user credential.
This function reports the default login behavior regarding this credential provider.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[out] AutoLogon On return, holds whether the credential provider should be used
by default to automatically log on the user.
@retval EFI_SUCCESS Default information successfully returned.
@retval EFI_INVALID_PARAMETER AutoLogon is NULL.
**/
EFI_STATUS
EFIAPI
CredentialDefault (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon
);
/**
Return information attached to the credential provider.
This function returns user information.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in] UserInfo Handle of the user information data record.
@param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On
exit, holds the user information. If the buffer is too small
to hold the information, then EFI_BUFFER_TOO_SMALL is returned
and InfoSize is updated to contain the number of bytes actually
required.
@param[in, out] InfoSize On entry, points to the size of Info. On return, points to the
size of the user information.
@retval EFI_SUCCESS Information returned successfully.
@retval EFI_BUFFER_TOO_SMALL The size specified by InfoSize is too small to hold all of the
user information. The size required is returned in *InfoSize.
@retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.
@retval EFI_NOT_FOUND The specified UserInfo does not refer to a valid user info handle.
**/
EFI_STATUS
EFIAPI
CredentialGetInfo (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN EFI_USER_INFO_HANDLE UserInfo,
OUT EFI_USER_INFO *Info,
IN OUT UINTN *InfoSize
);
/**
Enumerate all of the user informations on the credential provider.
This function returns the next user information record. To retrieve the first user
information record handle, point UserInfo at a NULL. Each subsequent call will retrieve
another user information record handle until there are no more, at which point UserInfo
will point to NULL.
@param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.
@param[in, out] UserInfo On entry, points to the previous user information handle or NULL
to start enumeration. On exit, points to the next user information
handle or NULL if there is no more user information.
@retval EFI_SUCCESS User information returned.
@retval EFI_NOT_FOUND No more user information found.
@retval EFI_INVALID_PARAMETER UserInfo is NULL.
**/
EFI_STATUS
EFIAPI
CredentialGetNextInfo (
IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,
IN OUT EFI_USER_INFO_HANDLE *UserInfo
);
#endif

View File

@ -0,0 +1,58 @@
## @file
# Component description file for USB Credential Provider.
#
# 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 = UsbCredentialProvider
FILE_GUID = 672A0C68-2BF0-46f9-93C3-C4E7DC0FA555
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = UsbProviderInit
[Sources]
UsbCredentialProvider.c
UsbCredentialProvider.h
UsbCredentialProviderStrings.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
UefiDriverEntryPoint
MemoryAllocationLib
BaseMemoryLib
DebugLib
HiiLib
UefiLib
BaseCryptLib
[Guids]
gEfiIfrTianoGuid ## CONSUMES ## Guid
gEfiFileInfoGuid ## CONSUMES ## Guid
gEfiUserCredentialClassSecureCardGuid ## CONSUMES ## Guid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdFixedUsbCredentialProviderTokenFileName
[Protocols]
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUserCredentialProtocolGuid
gEfiUserManagerProtocolGuid
gEfiBlockIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid

View File

@ -0,0 +1,148 @@
/** @file
Load the deferred images after user is identified.
Copyright (c) 2009 - 2010, 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 "UserIdentifyManager.h"
EFI_HANDLE mDeferredImageHandle;
/**
The function will load all the deferred images again. If the deferred image is loaded
successfully, try to start it.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context
**/
VOID
EFIAPI
LoadDeferredImage (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
UINTN HandleCount;
EFI_HANDLE *HandleBuf;
UINTN Index;
UINTN DriverIndex;
EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
VOID *DriverImage;
UINTN ImageSize;
BOOLEAN BootOption;
EFI_HANDLE ImageHandle;
UINTN ExitDataSize;
CHAR16 *ExitData;
//
// Find all the deferred image load protocols.
//
HandleCount = 0;
HandleBuf = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiDeferredImageLoadProtocolGuid,
NULL,
&HandleCount,
&HandleBuf
);
if (EFI_ERROR (Status)) {
return ;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuf[Index],
&gEfiDeferredImageLoadProtocolGuid,
(VOID **) &DeferredImage
);
if (EFI_ERROR (Status)) {
continue ;
}
DriverIndex = 0;
do {
//
// Load all the deferred images in this protocol instance.
//
Status = DeferredImage->GetImageInfo(
DeferredImage,
DriverIndex,
&ImageDevicePath,
(VOID **) &DriverImage,
&ImageSize,
&BootOption
);
if (EFI_ERROR (Status)) {
break;
}
//
// Load and start the image.
//
Status = gBS->LoadImage (
BootOption,
mDeferredImageHandle,
ImageDevicePath,
NULL,
0,
&ImageHandle
);
if (!EFI_ERROR (Status)) {
//
// Before calling the image, enable the Watchdog Timer for
// a 5 Minute period
//
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
//
// Clear the Watchdog Timer after the image returns.
//
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
}
DriverIndex++;
} while (TRUE);
}
FreePool (HandleBuf);
}
/**
Register an event notification function for user profile changed.
@param[in] ImageHandle Image handle this driver.
**/
VOID
LoadDeferredImageInit (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
EFI_EVENT Event;
mDeferredImageHandle = ImageHandle;
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
LoadDeferredImage,
NULL,
&gEfiEventUserProfileChangedGuid,
&Event
);
ASSERT (Status == EFI_SUCCESS);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,413 @@
/** @file
The header file for User identify Manager driver.
Copyright (c) 2009 - 2010, 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 _USER_IDENTIFY_MANAGER_H_
#define _USER_IDENTIFY_MANAGER_H_
#include <Uefi.h>
#include <Guid/GlobalVariable.h>
#include <Guid/MdeModuleHii.h>
#include <Protocol/FormBrowser2.h>
#include <Protocol/HiiDatabase.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiString.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
#include <Protocol/DeferredImageLoad.h>
#include <Protocol/SimpleTextOut.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include "UserIdentifyManagerData.h"
//
// This is the generated IFR binary data for each formset defined in VFR.
// This data array is ready to be used as input of HiiAddPackages() to
// create a packagelist.
//
extern UINT8 UserIdentifyManagerVfrBin[];
//
// This is the generated String package data for all .UNI files.
// This data array is ready to be used as input of HiiAddPackages() to
// create a packagelist.
//
extern UINT8 UserIdentifyManagerStrings[];
#define USER_NUMBER_INC 32
#define DEFAULT_PROFILE_SIZE 512
#define INFO_PAYLOAD_SIZE 64
//
// Credential Provider Information.
//
typedef struct {
UINTN Count;
EFI_USER_CREDENTIAL_PROTOCOL *Provider[1];
} CREDENTIAL_PROVIDER_INFO;
//
// Internal user profile entry.
//
typedef struct {
UINTN MaxProfileSize;
UINTN UserProfileSize;
CHAR16 UserVarName[9];
UINT8 *ProfileInfo;
} USER_PROFILE_ENTRY;
//
// Internal user profile database.
//
typedef struct {
UINTN UserProfileNum;
UINTN MaxProfileNum;
EFI_USER_PROFILE_HANDLE UserProfile[1];
} USER_PROFILE_DB;
#define USER_MANAGER_SIGNATURE SIGNATURE_32 ('U', 'I', 'M', 'S')
typedef struct {
UINTN Signature;
EFI_HANDLE DriverHandle;
EFI_HII_HANDLE HiiHandle;
//
// Consumed protocol.
//
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
EFI_HII_STRING_PROTOCOL *HiiString;
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
//
// Produced protocol.
//
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
} USER_MANAGER_CALLBACK_INFO;
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
/**
Register an event notification function for the user profile changed.
@param[in] ImageHandle Image handle this driver.
**/
VOID
LoadDeferredImageInit (
IN EFI_HANDLE ImageHandle
);
/**
This function creates a new user profile with only
a new user identifier attached and returns its handle.
The user profile is non-volatile, but the handle User
can change across reboots.
@param[in] This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param[out] User Handle of a new user profile.
@retval EFI_SUCCESS User profile was successfully created.
@retval EFI_ACCESS_DENIED Current user does not have sufficient permissions
to create a user profile.
@retval EFI_UNSUPPORTED Creation of new user profiles is not supported.
@retval EFI_INVALID_PARAMETER User is NULL.
**/
EFI_STATUS
EFIAPI
UserProfileCreate (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
OUT EFI_USER_PROFILE_HANDLE *User
);
/**
Delete an existing user profile.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param User User profile handle.
@retval EFI_SUCCESS User profile was successfully deleted.
@retval EFI_ACCESS_DENIED Current user does not have sufficient permissions
to delete a user profile or there is only one
user profile.
@retval EFI_UNSUPPORTED Deletion of new user profiles is not supported.
@retval EFI_INVALID_PARAMETER User does not refer to a valid user profile.
**/
EFI_STATUS
EFIAPI
UserProfileDelete (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User
);
/**
Get next user profile from the user profile database.
@param[in] This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param[in, out] User User profile handle.
@retval EFI_SUCCESS Next enrolled user profile successfully returned.
@retval EFI_INVALID_PARAMETER User is NULL.
**/
EFI_STATUS
EFIAPI
UserProfileGetNext (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN OUT EFI_USER_PROFILE_HANDLE *User
);
/**
This function returns the current user profile handle.
@param[in] This Protocol EFI_USER_MANAGER_PROTOCOL instance pointer.
@param[out] CurrentUser User profile handle.
@retval EFI_SUCCESS Current user profile handle returned successfully.
@retval EFI_INVALID_PARAMETER CurrentUser is NULL.
**/
EFI_STATUS
EFIAPI
UserProfileCurrent (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
OUT EFI_USER_PROFILE_HANDLE *CurrentUser
);
/**
Identify the user and, if authenticated, returns the user handle and changes
the current user profile.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance pointer.
@param CurrentUser User profile handle.
@retval EFI_SUCCESS User was successfully identified.
@retval EFI_INVALID_PARAMETER User is NULL.
@retval EFI_ACCESS_DENIED User was not successfully identified.
**/
EFI_STATUS
EFIAPI
UserProfileIdentify (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
OUT EFI_USER_PROFILE_HANDLE *User
);
/**
Find a user using a user information record.
This function searches all user profiles for the specified user information record.
The search starts with the user information record handle following UserInfo and
continues until either the information is found or there are no more user profiles.
A match occurs when the Info.InfoType field matches the user information record
type and the user information record data matches the portion of Info passed the
EFI_USER_INFO header.
@param[in] This Points to this instance of the EFI_USER_MANAGER_PROTOCOL.
@param[in, out] User On entry, points to the previously returned user profile
handle, or NULL to start searching with the first user profile.
On return, points to the user profile handle, or NULL if not
found.
@param[in, out] UserInfo On entry, points to the previously returned user information
handle, or NULL to start searching with the first. On return,
points to the user information handle of the user information
record, or NULL if not found. Can be NULL, in which case only
one user information record per user can be returned.
@param[in] Info Points to the buffer containing the user information to be
compared to the user information record. If NULL, then only
the user information record type is compared. If InfoSize is 0,
then the user information record must be empty.
@param[in] InfoSize The size of Info, in bytes.
@retval EFI_SUCCESS User information was found. User points to the user profile handle,
and UserInfo points to the user information handle.
@retval EFI_NOT_FOUND User information was not found. User points to NULL and UserInfo
points to NULL.
**/
EFI_STATUS
EFIAPI
UserProfileFind (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN OUT EFI_USER_PROFILE_HANDLE *User,
IN OUT EFI_USER_INFO_HANDLE *UserInfo OPTIONAL,
IN CONST EFI_USER_INFO *Info,
IN UINTN InfoSize
);
/**
This function returns user information.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param User Handle of the user whose profile will be
retrieved.
@param UserInfo Handle of the user information data record.
@param Info On entry, points to a buffer of at least
*InfoSize bytes. On exit, holds the user
information.
@param InfoSize On entry, points to the size of Info. On return,
points to the size of the user information.
@retval EFI_SUCCESS Information returned successfully.
@retval EFI_ACCESS_DENIED The information about the specified user cannot
be accessed by the current user.
EFI_BUFFER_TOO_SMALL- The number of bytes
specified by *InfoSize is too small to hold the
returned data.
**/
EFI_STATUS
EFIAPI
UserProfileGetInfo (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
IN EFI_USER_INFO_HANDLE UserInfo,
OUT EFI_USER_INFO *Info,
IN OUT UINTN *InfoSize
);
/**
This function changes user information.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param User Handle of the user whose profile will be
retrieved.
@param UserInfo Handle of the user information data record.
@param Info Points to the user information.
@param InfoSize The size of Info, in bytes.
@retval EFI_SUCCESS User profile information was successfully
changed/added.
@retval EFI_ACCESS_DENIED The record is exclusive.
@retval EFI_SECURITY_VIOLATION The current user does not have permission to
change the specified user profile or user
information record.
**/
EFI_STATUS
EFIAPI
UserProfileSetInfo (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
IN OUT EFI_USER_INFO_HANDLE *UserInfo,
IN CONST EFI_USER_INFO *Info,
IN UINTN InfoSize
);
/**
This function allows the credential provider to notify the User Identity Manager
when user status has changed while deselected.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance
pointer.
@param Changed Points to the instance of the
EFI_USER_CREDENTIAL_PROTOCOL where the user has
changed.
@retval EFI_SUCCESS The User Identity Manager has handled the
notification.
@retval EFI_NOT_READY The function was called while the specified
credential provider was not selected.
@retval EFI_UNSUPPORTED The User Identity Manager doesn't support
asynchronous notifications.
**/
EFI_STATUS
EFIAPI
UserProfileNotify (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_HANDLE Changed
);
/**
Delete the user information attached to the user profile specified by the UserInfo.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance pointer.
@param User Handle of the user whose profile will be retrieved.
@param UserInfo Handle of the user information data record.
@retval EFI_SUCCESS User information deleted successfully.
@retval EFI_ACCESS_DENIED The current user does not have permission to
delete this user in-formation.
@retval EFI_NOT_FOUND User information record UserInfo does not exist
in the user pro-file.
**/
EFI_STATUS
EFIAPI
UserProfileDeleteInfo (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
IN EFI_USER_INFO_HANDLE UserInfo
);
/**
This function returns the next user information record.
@param This Protocol EFI_USER_MANAGER_PROTOCOL instance pointer.
@param User Handle of the user whose profile will be retrieved.
@param UserInfo Handle of the user information data record.
@retval EFI_SUCCESS User information returned.
@retval EFI_NOT_FOUND No more user information found.
**/
EFI_STATUS
EFIAPI
UserProfileGetNextInfo (
IN CONST EFI_USER_MANAGER_PROTOCOL *This,
IN EFI_USER_PROFILE_HANDLE User,
IN OUT EFI_USER_INFO_HANDLE *UserInfo
);
#endif

View File

@ -0,0 +1,42 @@
/** @file
Data structure used by the user identify manager driver.
Copyright (c) 2009 - 2010, 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 _USER_IDENTIFY_MANAGER_DATA_H_
#define _USER_IDENTIFY_MANAGER_DATA_H_
#include "UserIdentifyManagerStrDefs.h"
//
// Guid used in user profile saving and in form browser.
//
#define USER_IDENTIFY_MANAGER_GUID \
{ \
0x3ccd3dd8, 0x8d45, 0x4fed, { 0x96, 0x2d, 0x2b, 0x38, 0xcd, 0x82, 0xb3, 0xc4 } \
}
//
// Forms definition.
//
#define FORMID_USER_FORM 1
#define FORMID_PROVIDER_FORM 2
//
// Labels definition.
//
#define LABEL_USER_NAME 0x1000
#define LABEL_PROVIDER_NAME 0x3000
#define LABEL_END 0xffff
#define FORM_OPEN_QUESTION_ID 0xfffe
#endif

View File

@ -0,0 +1,62 @@
## @file
# Component description file for user identify manager 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 = UserIdentifyManager
FILE_GUID = C5D3191B-27D5-4873-8DF2-628136991A21
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = UserIdentifyManagerInit
[sources]
UserIdentifyManager.c
LoadDeferredImage.c
UserIdentifyManager.h
UserIdentifyManagerData.h
UserIdentifyManagerStrings.uni
UserIdentifyManagerVfr.Vfr
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
UefiDriverEntryPoint
MemoryAllocationLib
BaseMemoryLib
DebugLib
HiiLib
UefiLib
[Guids]
gEfiIfrTianoGuid ## CONSUMES ## Guid
gEfiEventUserProfileChangedGuid ## CONSUMES ## Guid
[Protocols]
gEfiFormBrowser2ProtocolGuid ## CONSUMES
gEfiHiiDatabaseProtocolGuid ## CONSUMES
gEfiUserCredentialProtocolGuid ## CONSUMES
gEfiDeferredImageLoadProtocolGuid ## CONSUMES
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
gEfiUserManagerProtocolGuid ## PRODUCES
gEfiSimpleTextOutProtocolGuid
gEfiSimpleTextInProtocolGuid
gEfiSimpleTextInputExProtocolGuid
[Depex]
gEfiHiiDatabaseProtocolGuid AND
gEfiHiiStringProtocolGuid AND
gEfiFormBrowser2ProtocolGuid

View File

@ -0,0 +1,44 @@
/** @file
User identify manager formset.
Copyright (c) 2009 - 2010, 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 "UserIdentifyManagerData.h"
formset
guid = USER_IDENTIFY_MANAGER_GUID,
title = STRING_TOKEN(STR_TITLE),
help = STRING_TOKEN(STR_NULL_STRING),
classguid = USER_IDENTIFY_MANAGER_GUID,
form formid = FORMID_USER_FORM,
title = STRING_TOKEN(STR_USER_SELECT);
suppressif TRUE;
text
help = STRING_TOKEN(STR_NULL_STRING),
text = STRING_TOKEN(STR_NULL_STRING),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = FORM_OPEN_QUESTION_ID;
endif;
label LABEL_USER_NAME;
label LABEL_END;
endform;
form formid = FORMID_PROVIDER_FORM,
title = STRING_TOKEN(STR_PROVIDER_SELECT);
label LABEL_PROVIDER_NAME;
label LABEL_END;
endform;
endformset;

View File

@ -0,0 +1,372 @@
/** @file
The functions to add a user profile.
Copyright (c) 2009 - 2010, 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 "UserProfileManager.h"
/**
Get user name from the popup windows.
@param[in, out] UserNameLen On entry, point to UserName buffer lengh, in bytes.
On exit, point to input user name length, in bytes.
@param[out] UserName The buffer to hold the input user name.
@retval EFI_ABORTED It is given up by pressing 'ESC' key.
@retval EFI_NOT_READY Not a valid input at all.
@retval EFI_SUCCESS Get a user name successfully.
**/
EFI_STATUS
GetUserNameInput (
IN OUT UINTN *UserNameLen,
OUT CHAR16 *UserName
)
{
EFI_INPUT_KEY Key;
UINTN NameLen;
CHAR16 Name[USER_NAME_LENGTH];
NameLen = 0;
while (TRUE) {
Name[NameLen] = L'_';
Name[NameLen + 1] = L'\0';
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Input User Name",
L"---------------------",
Name,
NULL
);
//
// Check key.
//
if (Key.ScanCode == SCAN_NULL) {
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
//
// Add the null terminator.
//
Name[NameLen] = 0;
NameLen++;
break;
} else if ((Key.UnicodeChar == CHAR_NULL) ||
(Key.UnicodeChar == CHAR_TAB) ||
(Key.UnicodeChar == CHAR_LINEFEED)
) {
continue;
} else {
if (Key.UnicodeChar == CHAR_BACKSPACE) {
if (NameLen > 0) {
NameLen--;
}
} else {
Name[NameLen] = Key.UnicodeChar;
NameLen++;
if (NameLen + 1 == USER_NAME_LENGTH) {
//
// Add the null terminator.
//
Name[NameLen] = 0;
NameLen++;
break;
}
}
}
}
if (Key.ScanCode == SCAN_ESC) {
return EFI_ABORTED;
}
}
if (NameLen <= 1) {
return EFI_NOT_READY;
}
if (*UserNameLen < NameLen * sizeof (CHAR16)) {
return EFI_NOT_READY;
}
*UserNameLen = NameLen * sizeof (CHAR16);
CopyMem (UserName, Name, *UserNameLen);
return EFI_SUCCESS;
}
/**
Set a user's username.
@param[in] User Handle of a user profile .
@param[in] UserNameLen The lengh of UserName.
@param[in] UserName Point to the buffer of user name.
@retval EFI_NOT_READY The usernme in mAddUserName had been used.
@retval EFI_SUCCESS Change the user's username successfully with
username in mAddUserName.
**/
EFI_STATUS
SetUserName (
IN EFI_USER_PROFILE_HANDLE User,
IN UINTN UserNameLen,
IN CHAR16 *UserName
)
{
EFI_STATUS Status;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_PROFILE_HANDLE TempUser;
EFI_USER_INFO *NewUserInfo;
NewUserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + UserNameLen);
ASSERT (NewUserInfo != NULL);
NewUserInfo->InfoType = EFI_USER_INFO_NAME_RECORD;
NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
EFI_USER_INFO_PUBLIC |
EFI_USER_INFO_EXCLUSIVE;
NewUserInfo->InfoSize = (UINT32) (sizeof (EFI_USER_INFO) + UserNameLen);
CopyMem ((UINT8 *) (NewUserInfo + 1), UserName, UserNameLen);
TempUser = NULL;
Status = mUserManager->Find (
mUserManager,
&TempUser,
NULL,
NewUserInfo,
NewUserInfo->InfoSize
);
if (!EFI_ERROR (Status)) {
//
// The user name had been used, return error.
//
FreePool (NewUserInfo);
return EFI_NOT_READY;
}
UserInfo = NULL;
mUserManager->SetInfo (
mUserManager,
User,
&UserInfo,
NewUserInfo,
NewUserInfo->InfoSize
);
FreePool (NewUserInfo);
return EFI_SUCCESS;
}
/**
Set create date of the specified user.
@param[in] User Handle of a user profile.
**/
VOID
SetCreateDate (
IN EFI_USER_PROFILE_HANDLE User
)
{
EFI_STATUS Status;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_INFO_CREATE_DATE Date;
EFI_USER_INFO *NewUserInfo;
NewUserInfo = AllocateZeroPool (
sizeof (EFI_USER_INFO) +
sizeof (EFI_USER_INFO_CREATE_DATE)
);
ASSERT (NewUserInfo != NULL);
NewUserInfo->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD;
NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
EFI_USER_INFO_PUBLIC |
EFI_USER_INFO_EXCLUSIVE;
NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE);
Status = gRT->GetTime (&Date, NULL);
if (EFI_ERROR (Status)) {
FreePool (NewUserInfo);
return ;
}
CopyMem ((UINT8 *) (NewUserInfo + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE));
UserInfo = NULL;
mUserManager->SetInfo (
mUserManager,
User,
&UserInfo,
NewUserInfo,
NewUserInfo->InfoSize
);
FreePool (NewUserInfo);
}
/**
Set the default identity policy of the specified user.
@param[in] User Handle of a user profile.
**/
VOID
SetIdentityPolicy (
IN EFI_USER_PROFILE_HANDLE User
)
{
EFI_USER_INFO_IDENTITY_POLICY *Policy;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_INFO *NewUserInfo;
NewUserInfo = AllocateZeroPool (
sizeof (EFI_USER_INFO) +
sizeof (EFI_USER_INFO_IDENTITY_POLICY)
);
ASSERT (NewUserInfo != NULL);
Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewUserInfo + 1);
Policy->Type = EFI_USER_INFO_IDENTITY_TRUE;
Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
NewUserInfo->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD;
NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
EFI_USER_INFO_PRIVATE |
EFI_USER_INFO_EXCLUSIVE;
NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length;
UserInfo = NULL;
mUserManager->SetInfo (
mUserManager,
User,
&UserInfo,
NewUserInfo,
NewUserInfo->InfoSize
);
FreePool (NewUserInfo);
}
/**
Set the default access policy of the specified user.
@param[in] User Handle of a user profile.
**/
VOID
SetAccessPolicy (
IN EFI_USER_PROFILE_HANDLE User
)
{
EFI_USER_INFO_ACCESS_CONTROL *Control;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_INFO *NewUserInfo;
NewUserInfo = AllocateZeroPool (
sizeof (EFI_USER_INFO) +
sizeof (EFI_USER_INFO_ACCESS_CONTROL)
);
ASSERT (NewUserInfo != NULL);
Control = (EFI_USER_INFO_ACCESS_CONTROL *) (NewUserInfo + 1);
Control->Type = EFI_USER_INFO_ACCESS_ENROLL_SELF;
Control->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);
NewUserInfo->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD;
NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
EFI_USER_INFO_PUBLIC |
EFI_USER_INFO_EXCLUSIVE;
NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + Control->Size;
UserInfo = NULL;
mUserManager->SetInfo (
mUserManager,
User,
&UserInfo,
NewUserInfo,
NewUserInfo->InfoSize
);
FreePool (NewUserInfo);
}
/**
Add a new user profile into the user profile database.
**/
VOID
CallAddUser (
VOID
)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
EFI_USER_PROFILE_HANDLE User;
UINTN UserNameLen;
CHAR16 UserName[USER_NAME_LENGTH];
CHAR16 *QuestionStr;
CHAR16 *PromptStr;
QuestionStr = NULL;
PromptStr = NULL;
//
// Get user name to add.
//
UserNameLen = sizeof (UserName);
Status = GetUserNameInput (&UserNameLen, UserName);
if (EFI_ERROR (Status)) {
if (Status != EFI_ABORTED) {
QuestionStr = GetStringById (STRING_TOKEN (STR_GET_USERNAME_FAILED));
PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
goto Done;
}
return ;
}
//
// Create a new user profile.
//
User = NULL;
Status = mUserManager->Create (mUserManager, &User);
if (EFI_ERROR (Status)) {
QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_FAILED));
PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
} else {
//
// Add default user information.
//
Status = SetUserName (User, UserNameLen, UserName);
if (EFI_ERROR (Status)) {
QuestionStr = GetStringById (STRING_TOKEN (STR_USER_ALREADY_EXISTED));
PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
goto Done;
}
SetCreateDate (User);
SetIdentityPolicy (User);
SetAccessPolicy (User);
QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_SUCCESS));
PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE));
}
Done:
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
QuestionStr,
L"",
PromptStr,
NULL
);
FreePool (QuestionStr);
FreePool (PromptStr);
}

View File

@ -0,0 +1,314 @@
/** @file
The functions to delete a user profile.
Copyright (c) 2009 - 2010, 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 "UserProfileManager.h"
/**
Get the username from the specified user.
@param[in] User Handle of a user profile.
@retval EFI_STRING_ID The String Id of the user's username.
**/
EFI_STRING_ID
GetUserName (
IN EFI_USER_PROFILE_HANDLE User
)
{
EFI_STATUS Status;
EFI_USER_INFO_HANDLE UserInfo;
EFI_USER_INFO *Info;
UINTN InfoSize;
UINTN MemSize;
UINTN NameLen;
CHAR16 UserName[USER_NAME_LENGTH];
EFI_STRING_ID UserId;
//
// Allocate user information memory.
//
MemSize = sizeof (EFI_USER_INFO) + 63;
Info = AllocateZeroPool (MemSize);
ASSERT (Info != NULL);
//
// Get user name information.
//
UserInfo = NULL;
while (TRUE) {
InfoSize = MemSize;
//
// Get next user information.
//
Status = mUserManager->GetNextInfo (
mUserManager,
User,
&UserInfo
);
if (EFI_ERROR (Status)) {
break;
}
Status = mUserManager->GetInfo (
mUserManager,
User,
UserInfo,
Info,
&InfoSize
);
if (Status == EFI_BUFFER_TOO_SMALL) {
MemSize = InfoSize;
FreePool (Info);
Info = AllocateZeroPool (MemSize);
ASSERT (Info != NULL);
Status = mUserManager->GetInfo (
mUserManager,
User,
UserInfo,
Info,
&InfoSize
);
}
//
// Check user information.
//
if (Status == EFI_SUCCESS) {
if (Info->InfoType == EFI_USER_INFO_NAME_RECORD) {
NameLen = Info->InfoSize - sizeof (EFI_USER_INFO);
if (NameLen > USER_NAME_LENGTH * sizeof (CHAR16)) {
NameLen = USER_NAME_LENGTH * sizeof (CHAR16);
}
ASSERT (NameLen >= sizeof (CHAR16));
CopyMem (UserName, (UINT8 *) (Info + 1), NameLen);
UserName[NameLen / sizeof (CHAR16) - 1] = 0;
UserId = HiiSetString (
mCallbackInfo->HiiHandle,
0,
UserName,
NULL
);
if (UserId != 0) {
FreePool (Info);
return UserId;
}
}
}
}
FreePool (Info);
return 0;
}
/**
Add a username item in form.
@param[in] User Points to the user profile whose username is added.
@param[in] Index The index of the user in the user name list
@param[in] OpCodeHandle Points to container for dynamic created opcodes.
**/
VOID
AddUserToForm (
IN EFI_USER_PROFILE_HANDLE User,
IN UINT16 Index,
IN VOID *OpCodeHandle
)
{
EFI_STRING_ID NameId;
//
// Get user name
//
NameId = GetUserName (User);
if (NameId == 0) {
return ;
}
//
// Create user name option.
//
switch (Index & KEY_FIRST_FORM_MASK) {
case KEY_MODIFY_USER:
HiiCreateGotoOpCode (
OpCodeHandle, // Container for dynamic created opcodes
FORMID_USER_INFO, // Target Form ID
NameId, // Prompt text
STRING_TOKEN (STR_NULL_STRING), // Help text
EFI_IFR_FLAG_CALLBACK, // Question flag
Index // Question ID
);
break;
case KEY_DEL_USER:
HiiCreateActionOpCode (
OpCodeHandle, // Container for dynamic created opcodes
Index, // Question ID
NameId, // Prompt text
STRING_TOKEN (STR_NULL_STRING), // Help text
EFI_IFR_FLAG_CALLBACK, // Question flag
0 // Action String ID
);
break;
default:
break;
}
}
/**
Delete the user specified by UserIndex in user profile database.
@param[in] UserIndex The index of user in the user name list
to be deleted.
**/
VOID
DeleteUser (
IN UINT8 UserIndex
)
{
EFI_STATUS Status;
EFI_USER_PROFILE_HANDLE User;
EFI_INPUT_KEY Key;
//
// Find specified user profile and delete it.
//
User = NULL;
Status = mUserManager->GetNext (mUserManager, &User);
if (EFI_ERROR (Status)) {
goto Done;
}
while (UserIndex > 1) {
Status = mUserManager->GetNext (mUserManager, &User);
if (EFI_ERROR (Status)) {
goto Done;
}
UserIndex--;
}
if (UserIndex == 1) {
Status = mUserManager->Delete (mUserManager, User);
if (EFI_ERROR (Status)) {
goto Done;
}
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Delete User Succeed!",
L"",
L"Please Press Any Key to Continue ...",
NULL
);
return ;
}
Done:
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Delete User Failed!",
L"",
L"Please Press Any Key to Continue ...",
NULL
);
}
/**
Display user select form, cab select a user to delete.
**/
VOID
SelectUserToDelete (
VOID
)
{
EFI_STATUS Status;
UINT8 Index;
EFI_USER_PROFILE_HANDLE User;
EFI_USER_PROFILE_HANDLE CurrentUser;
VOID *StartOpCodeHandle;
VOID *EndOpCodeHandle;
EFI_IFR_GUID_LABEL *StartLabel;
EFI_IFR_GUID_LABEL *EndLabel;
//
// Initialize the container for dynamic opcodes.
//
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (StartOpCodeHandle != NULL);
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (EndOpCodeHandle != NULL);
//
// Create Hii Extend Label OpCode.
//
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
StartOpCodeHandle,
&gEfiIfrTianoGuid,
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartLabel->Number = LABEL_USER_DEL_FUNC;
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
EndOpCodeHandle,
&gEfiIfrTianoGuid,
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
EndLabel->Number = LABEL_END;
//
// Add each user can be deleted.
//
User = NULL;
Index = 1;
mUserManager->Current (mUserManager, &CurrentUser);
while (TRUE) {
Status = mUserManager->GetNext (mUserManager, &User);
if (EFI_ERROR (Status)) {
break;
}
if (User != CurrentUser) {
AddUserToForm (
User,
(UINT16)(KEY_DEL_USER | KEY_SELECT_USER | Index),
StartOpCodeHandle
);
}
Index++;
}
HiiUpdateForm (
mCallbackInfo->HiiHandle, // HII handle
&mUserProfileManagerGuid, // Formset GUID
FORMID_DEL_USER, // Form ID
StartOpCodeHandle, // Label for where to insert opcodes
EndOpCodeHandle // Replace data
);
HiiFreeOpCodeHandle (StartOpCodeHandle);
HiiFreeOpCodeHandle (EndOpCodeHandle);
}

View File

@ -0,0 +1,806 @@
/** @file
This driver is a configuration tool for adding, deleting or modifying user
profiles, including gathering the necessary information to ascertain their
identity in the future, updating user access policy and identification
policy, etc.
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 "UserProfileManager.h"
EFI_GUID mUserProfileManagerGuid = USER_PROFILE_MANAGER_GUID;
EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;
CREDENTIAL_PROVIDER_INFO *mProviderInfo = NULL;
UINT8 mProviderChoice;
UINT8 mConncetLogical;
USER_INFO_ACCESS mAccessInfo;
USER_INFO mUserInfo;
USER_PROFILE_MANAGER_CALLBACK_INFO *mCallbackInfo;
HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
{0xad2e3474, 0x93e6, 0x488b, {0x93, 0x19, 0x64, 0x88, 0xfc, 0x68, 0x1f, 0x16}}
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8) (END_DEVICE_PATH_LENGTH),
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
/**
Get string by string id from HII Interface.
@param[in] Id String ID to get the string from.
@retval CHAR16 * String from ID.
@retval NULL If error occurs.
**/
CHAR16 *
GetStringById (
IN EFI_STRING_ID Id
)
{
//
// Get the current string for the current Language.
//
return HiiGetString (mCallbackInfo->HiiHandle, Id, NULL);
}
/**
This function gets all the credential providers in the system and saved them
to mProviderInfo.
@retval EFI_SUCESS Init credential provider database successfully.
@retval Others Fail to init credential provider database.
**/
EFI_STATUS
InitProviderInfo (
VOID
)
{
EFI_STATUS Status;
UINTN HandleCount;
EFI_HANDLE *HandleBuf;
UINTN Index;
//
// Try to find all the user credential provider driver.
//
HandleCount = 0;
HandleBuf = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiUserCredentialProtocolGuid,
NULL,
&HandleCount,
&HandleBuf
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get provider infomation.
//
if (mProviderInfo != NULL) {
FreePool (mProviderInfo);
}
mProviderInfo = AllocateZeroPool (
sizeof (CREDENTIAL_PROVIDER_INFO) -
sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) +
HandleCount * sizeof (EFI_USER_CREDENTIAL_PROTOCOL *)
);
if (mProviderInfo == NULL) {
FreePool (HandleBuf);
return EFI_OUT_OF_RESOURCES;
}
mProviderInfo->Count = HandleCount;
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuf[Index],
&gEfiUserCredentialProtocolGuid,
(VOID **) &mProviderInfo->Provider[Index]
);
if (EFI_ERROR (Status)) {
FreePool (HandleBuf);
FreePool (mProviderInfo);
mProviderInfo = NULL;
return Status;
}
}
FreePool (HandleBuf);
return EFI_SUCCESS;
}
/**
This function processes changes in user profile configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Action Specifies the type of action taken by the browser.
@param QuestionId A unique value which is sent to the original
exporting driver so that it can identify the type
of data to expect.
@param Type The type of value for the question.
@param Value A pointer to the data being sent to the original
exporting driver.
@param ActionRequest On return, points to the action requested by the
callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval Others Fail to handle the action.
**/
EFI_STATUS
EFIAPI
UserProfileManagerCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID QuestionId,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
UINT32 CurrentAccessRight;
CHAR16 *QuestionStr;
CHAR16 *PromptStr;
VOID *StartOpCodeHandle;
VOID *EndOpCodeHandle;
EFI_IFR_GUID_LABEL *StartLabel;
EFI_IFR_GUID_LABEL *EndLabel;
EFI_USER_PROFILE_HANDLE CurrentUser;
Status = EFI_SUCCESS;
switch (Action) {
case EFI_BROWSER_ACTION_FORM_OPEN:
{
//
// Update user manage Form when user manage Form is opened.
// This will be done only in FORM_OPEN CallBack of question with QUESTIONID_USER_MANAGE from user manage Form.
//
if (QuestionId != QUESTIONID_USER_MANAGE) {
return EFI_SUCCESS;
}
//
// Get current user
//
CurrentUser = NULL;
mUserManager->Current (mUserManager, &CurrentUser);
if (CurrentUser == NULL) {
DEBUG ((DEBUG_ERROR, "Error: current user does not exist!\n"));
return EFI_NOT_READY;
}
//
// Get current user's right information.
//
Status = GetAccessRight (&CurrentAccessRight);
if (EFI_ERROR (Status)) {
CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
}
//
// Init credential provider information.
//
Status = InitProviderInfo ();
if (EFI_ERROR (Status)) {
return Status;
}
//
// Initialize the container for dynamic opcodes.
//
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (StartOpCodeHandle != NULL);
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
ASSERT (EndOpCodeHandle != NULL);
//
// Create Hii Extend Label OpCode.
//
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
StartOpCodeHandle,
&gEfiIfrTianoGuid,
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartLabel->Number = LABEL_USER_MANAGE_FUNC;
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
EndOpCodeHandle,
&gEfiIfrTianoGuid,
NULL,
sizeof (EFI_IFR_GUID_LABEL)
);
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
EndLabel->Number = LABEL_END;
//
// Add user profile option.
//
if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) ||
(CurrentAccessRight == EFI_USER_INFO_ACCESS_ENROLL_OTHERS)
) {
HiiCreateActionOpCode (
StartOpCodeHandle, // Container for dynamic created opcodes
KEY_ADD_USER, // Question ID
STRING_TOKEN (STR_ADD_USER_TITLE), // Prompt text
STRING_TOKEN (STR_ADD_USER_HELP), // Help text
EFI_IFR_FLAG_CALLBACK, // Question flag
0 // Action String ID
);
}
//
// Add modify user profile option.
//
HiiCreateGotoOpCode (
StartOpCodeHandle, // Container for dynamic created opcodes
FORMID_MODIFY_USER, // Target Form ID
STRING_TOKEN (STR_MODIFY_USER_TITLE), // Prompt text
STRING_TOKEN (STR_MODIFY_USER_HELP), // Help text
EFI_IFR_FLAG_CALLBACK, // Question flag
KEY_MODIFY_USER // Question ID
);
//
// Add delete user profile option
//
if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
HiiCreateGotoOpCode (
StartOpCodeHandle, // Container for dynamic created opcodes
FORMID_DEL_USER, // Target Form ID
STRING_TOKEN (STR_DELETE_USER_TITLE), // Prompt text
STRING_TOKEN (STR_DELETE_USER_HELP), // Help text
EFI_IFR_FLAG_CALLBACK, // Question flag
KEY_DEL_USER // Question ID
);
}
HiiUpdateForm (
mCallbackInfo->HiiHandle, // HII handle
&mUserProfileManagerGuid, // Formset GUID
FORMID_USER_MANAGE, // Form ID
StartOpCodeHandle, // Label for where to insert opcodes
EndOpCodeHandle // Replace data
);
HiiFreeOpCodeHandle (StartOpCodeHandle);
HiiFreeOpCodeHandle (EndOpCodeHandle);
return EFI_SUCCESS;
}
break;
case EFI_BROWSER_ACTION_FORM_CLOSE:
Status = EFI_SUCCESS;
break;
case EFI_BROWSER_ACTION_CHANGING:
{
//
// Handle the request from form.
//
if ((Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
//
// Judge first 2 bits.
//
switch (QuestionId & KEY_FIRST_FORM_MASK) {
//
// Add user profile operation.
//
case KEY_ADD_USER:
CallAddUser ();
break;
//
// Delete user profile operation.
//
case KEY_DEL_USER:
//
// Judge next 2 bits.
//
switch (QuestionId & KEY_SECOND_FORM_MASK) {
//
// Enter delete user profile form.
//
case KEY_ENTER_NEXT_FORM:
SelectUserToDelete ();
break;
//
// Delete specified user profile.
//
case KEY_SELECT_USER:
DeleteUser ((UINT8) QuestionId);
//
// Update select user form after delete a user.
//
SelectUserToDelete ();
break;
default:
break;
}
break;
//
// Modify user profile operation.
//
case KEY_MODIFY_USER:
//
// Judge next 2 bits.
//
switch (QuestionId & KEY_SECOND_FORM_MASK) {
//
// Enter modify user profile form.
//
case KEY_ENTER_NEXT_FORM:
SelectUserToModify ();
break;
//
// Enter user profile information form.
//
case KEY_SELECT_USER:
//
// Judge next 3 bits.
//
switch (QuestionId & KEY_MODIFY_INFO_MASK) {
//
// Display user information form.
//
case KEY_ENTER_NEXT_FORM:
ModifyUserInfo ((UINT8) QuestionId);
break;
//
// Modify user name.
//
case KEY_MODIFY_NAME:
ModifyUserName ();
//
// Update username in parent form.
//
SelectUserToModify ();
break;
//
// Modify identity policy.
//
case KEY_MODIFY_IP:
//
// Judge next 3 bits
//
switch (QuestionId & KEY_MODIFY_IP_MASK) {
//
// Display identity policy modify form.
//
case KEY_ENTER_NEXT_FORM:
ModifyIdentityPolicy ();
break;
//
// Change credential provider option.
//
case KEY_MODIFY_PROV:
mProviderChoice = Value->u8;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
//
// Change logical connector.
//
case KEY_MODIFY_CONN:
mConncetLogical = Value->u8;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
//
// Save option.
//
case KEY_ADD_IP_OP:
AddIdentityPolicyItem ();
break;
//
// Return to user profile information form.
//
case KEY_IP_RETURN_UIF:
SaveIdentityPolicy ();
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
default:
break;
}
break;
//
// Modify access policy.
//
case KEY_MODIFY_AP:
//
// Judge next 3 bits.
//
switch (QuestionId & KEY_MODIFY_AP_MASK) {
//
// Display access policy modify form.
//
case KEY_ENTER_NEXT_FORM:
ModidyAccessPolicy ();
break;
//
// Change access right choice.
//
case KEY_MODIFY_RIGHT:
mAccessInfo.AccessRight = Value->u8;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
//
// Change setup choice.
//
case KEY_MODIFY_SETUP:
mAccessInfo.AccessSetup= Value->u8;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
//
// Change boot order choice.
//
case KEY_MODIFY_BOOT:
mAccessInfo.AccessBootOrder = Value->u32;
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
//
// Load device path form.
//
case KEY_MODIFY_LOAD:
//
// Judge next 2 bits.
//
switch (QuestionId & KEY_DISPLAY_DP_MASK) {
//
// Permit load device path.
//
case KEY_PERMIT_MODIFY:
DisplayLoadPermit ();
break;
//
// Forbid load device path.
//
case KEY_FORBID_MODIFY:
DisplayLoadForbid ();
break;
default:
break;
}
break;
//
// Connect device path form.
//
case KEY_MODIFY_CONNECT:
//
// Judge next 2 bits.
//
switch (QuestionId & KEY_DISPLAY_DP_MASK) {
//
// Permit connect device path.
//
case KEY_PERMIT_MODIFY:
DisplayConnectPermit ();
break;
//
// Forbid connect device path.
//
case KEY_FORBID_MODIFY:
DisplayConnectForbid ();
break;
default:
break;
}
break;
//
// Return to user profile information form.
//
case KEY_AP_RETURN_UIF:
SaveAccessPolicy ();
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
break;
default:
break;
}
break;
default:
break;
}
break;
//
// Access policy device path modified.
//
case KEY_MODIFY_AP_DP:
//
// Judge next 2 bits.
//
switch (QuestionId & KEY_MODIFY_DP_MASK) {
//
// Load permit device path modified.
//
case KEY_LOAD_PERMIT_MODIFY:
QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_FORBID_LIST));
PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
QuestionStr,
L"",
PromptStr,
NULL
);
FreePool (QuestionStr);
FreePool (PromptStr);
if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {
break;
}
AddToForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));
DisplayLoadPermit ();
break;
//
// Load forbid device path modified.
//
case KEY_LOAD_FORBID_MODIFY:
QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_PERMIT_LIST));
PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE));
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
QuestionStr,
L"",
PromptStr,
NULL
);
FreePool (QuestionStr);
FreePool (PromptStr);
if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) {
break;
}
DeleteFromForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1)));
DisplayLoadForbid ();
break;
//
// Connect permit device path modified.
//
case KEY_CONNECT_PERMIT_MODIFY:
break;
//
// Connect forbid device path modified.
//
case KEY_CONNECT_FORBID_MODIFY:
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
}
}
break;
default:
//
// All other action return unsupported.
//
Status = EFI_UNSUPPORTED;
break;
}
return Status;
}
/**
This function allows a caller to extract the current configuration for one
or more named elements from the target driver.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Request A null-terminated Unicode string in <ConfigRequest> format.
@param Progress On return, points to a character in the Request string.
Points to the string's null terminator if request was successful.
Points to the most recent '&' before the first failing name/value
pair (or the beginning of the string if the failure is in the
first name/value pair) if the request was not successful.
@param Results A null-terminated Unicode string in <ConfigAltResp> format which
has all values filled in for the names in the Request string.
String to be allocated by the called function.
@retval EFI_SUCCESS The Results is filled with the requested values.
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
@retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeExtractConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Request,
OUT EFI_STRING *Progress,
OUT EFI_STRING *Results
)
{
if (Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
}
*Progress = Request;
return EFI_NOT_FOUND;
}
/**
This function processes the results of changes in configuration.
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param Configuration A null-terminated Unicode string in <ConfigResp> format.
@param Progress A pointer to a string filled in with the offset of the most
recent '&' before the first failing name/value pair (or the
beginning of the string if the failure is in the first
name/value pair) or the terminating NULL if all was successful.
@retval EFI_SUCCESS The Results is processed successfully.
@retval EFI_INVALID_PARAMETER Configuration is NULL.
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
**/
EFI_STATUS
EFIAPI
FakeRouteConfig (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN CONST EFI_STRING Configuration,
OUT EFI_STRING *Progress
)
{
if (Configuration == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
}
return EFI_NOT_FOUND;
}
/**
Main entry for this driver.
@param ImageHandle Image handle this driver.
@param SystemTable Pointer to SystemTable.
@retval EFI_SUCESS This function always complete successfully.
**/
EFI_STATUS
EFIAPI
UserProfileManagerInit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
USER_PROFILE_MANAGER_CALLBACK_INFO *CallbackInfo;
Status = gBS->LocateProtocol (
&gEfiUserManagerProtocolGuid,
NULL,
(VOID **) &mUserManager
);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
//
// Initialize driver private data.
//
ZeroMem (&mUserInfo, sizeof (mUserInfo));
ZeroMem (&mAccessInfo, sizeof (mAccessInfo));
CallbackInfo = AllocateZeroPool (sizeof (USER_PROFILE_MANAGER_CALLBACK_INFO));
ASSERT (CallbackInfo != NULL);
CallbackInfo->Signature = USER_PROFILE_MANAGER_SIGNATURE;
CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;
CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;
CallbackInfo->ConfigAccess.Callback = UserProfileManagerCallback;
CallbackInfo->DriverHandle = NULL;
//
// Install Device Path Protocol and Config Access protocol to driver handle.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&CallbackInfo->DriverHandle,
&gEfiDevicePathProtocolGuid,
&mHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
&CallbackInfo->ConfigAccess,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Publish HII data.
//
CallbackInfo->HiiHandle = HiiAddPackages (
&mUserProfileManagerGuid,
CallbackInfo->DriverHandle,
UserProfileManagerStrings,
UserProfileManagerVfrBin,
NULL
);
ASSERT (CallbackInfo->HiiHandle != NULL);
mCallbackInfo = CallbackInfo;
return Status;
}

View File

@ -0,0 +1,387 @@
/** @file
The header file for user profile manager driver.
Copyright (c) 2009 - 2010, 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 __EFI_USER_PROFILE_MANAGER_H__
#define __EFI_USER_PROFILE_MANAGER_H__
#include <Uefi.h>
#include <Guid/GlobalVariable.h>
#include <Guid/MdeModuleHii.h>
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include "UserProfileManagerData.h"
#define USER_NAME_LENGTH 17
//
// Credential Provider Information.
//
typedef struct {
UINTN Count;
EFI_USER_CREDENTIAL_PROTOCOL *Provider[1];
} CREDENTIAL_PROVIDER_INFO;
//
// User profile information structure.
//
typedef struct {
UINT64 UsageCount;
EFI_TIME CreateDate;
EFI_TIME UsageDate;
UINTN AccessPolicyLen;
UINTN IdentityPolicyLen;
UINTN NewIdentityPolicyLen;
UINT8 *AccessPolicy;
UINT8 *IdentityPolicy;
UINT8 *NewIdentityPolicy;
CHAR16 UserName[USER_NAME_LENGTH];
BOOLEAN CreateDateExist;
BOOLEAN UsageDateExist;
BOOLEAN AccessPolicyModified;
BOOLEAN IdentityPolicyModified;
BOOLEAN NewIdentityPolicyModified;
} USER_INFO;
//
// User access information structure.
//
typedef struct {
UINTN LoadPermitLen;
UINTN LoadForbidLen;
UINTN ConnectPermitLen;
UINTN ConnectForbidLen;
UINT8 *LoadPermit;
UINT8 *LoadForbid;
UINT8 *ConnectPermit;
UINT8 *ConnectForbid;
UINT32 AccessBootOrder;
UINT8 AccessRight;
UINT8 AccessSetup;
} USER_INFO_ACCESS;
#define USER_PROFILE_MANAGER_SIGNATURE SIGNATURE_32 ('U', 'P', 'M', 'S')
typedef struct {
UINTN Signature;
EFI_HANDLE DriverHandle;
EFI_HII_HANDLE HiiHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
} USER_PROFILE_MANAGER_CALLBACK_INFO;
//
// HII specific Vendor Device Path definition.
//
typedef struct {
VENDOR_DEVICE_PATH VendorDevicePath;
EFI_DEVICE_PATH_PROTOCOL End;
} HII_VENDOR_DEVICE_PATH;
//
// This is the generated IFR binary data for each formset defined in VFR.
//
extern UINT8 UserProfileManagerVfrBin[];
//
// This is the generated String package data for .UNI file.
//
extern UINT8 UserProfileManagerStrings[];
//
// Guid used in the form browse.
//
extern EFI_GUID mUserProfileManagerGuid;
//
// The user manager protocol, used in several function.
//
extern EFI_USER_MANAGER_PROTOCOL *mUserManager;
//
// The credential providers database in system.
//
extern CREDENTIAL_PROVIDER_INFO *mProviderInfo;
//
// The variables used to update identity policy.
//
extern UINT8 mProviderChoice;
extern UINT8 mConncetLogical;
//
// The variables used to update access policy.
//
extern USER_INFO_ACCESS mAccessInfo;
//
// The user information used to record all data in UI.
//
extern USER_INFO mUserInfo;
extern USER_PROFILE_MANAGER_CALLBACK_INFO *mCallbackInfo;
/**
Get string by string id from HII Interface.
@param[in] Id String ID to get the string from.
@retval CHAR16 * String from ID.
@retval NULL If error occurs.
**/
CHAR16 *
GetStringById (
IN EFI_STRING_ID Id
);
/**
Add a new user profile into the user profile database.
**/
VOID
CallAddUser (
VOID
);
/**
Display user select form; can select a user to modify.
**/
VOID
SelectUserToModify (
VOID
);
/**
Display user select form, cab select a user to delete.
**/
VOID
SelectUserToDelete (
VOID
);
/**
Delete the user specified by UserIndex in user profile database.
@param[in] UserIndex The index of user in the user name list to be deleted.
**/
VOID
DeleteUser (
IN UINT8 UserIndex
);
/**
Add a username item in form.
@param[in] User Points to the user profile whose username is added.
@param[in] Index The index of the user in the user name list.
@param[in] OpCodeHandle Points to container for dynamic created opcodes.
**/
VOID
AddUserToForm (
IN EFI_USER_PROFILE_HANDLE User,
IN UINT16 Index,
IN VOID *OpCodeHandle
);
/**
Display modify user information form
In this form, username, create Date, usage date, usage count, identity policy,
and access policy are displayed.
@param[in] UserIndex The index of the user in display list to modify.
**/
VOID
ModifyUserInfo (
IN UINT8 UserIndex
);
/**
Get the username from user input and update username string in Hii
database with it.
**/
VOID
ModifyUserName (
VOID
);
/**
Display the form of modifying user identity policy.
**/
VOID
ModifyIdentityPolicy (
VOID
);
/**
Update the mUserInfo.NewIdentityPolicy and UI when 'add option' is pressed.
**/
VOID
AddIdentityPolicyItem (
VOID
);
/**
Save the identity policy and update UI with it.
This funciton will verify the new identity policy, in current implementation,
the identity policy can be: T, P & P & P & ..., P | P | P | ...
Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or".
Other identity policies are not supported.
**/
VOID
SaveIdentityPolicy (
VOID
);
/**
Display modify user access policy form
In this form, access right, access setu,p and access boot order are dynamically
added. Load devicepath and connect devicepath are displayed too.
**/
VOID
ModidyAccessPolicy (
VOID
);
/**
Collect all the access policy data to mUserInfo.AccessPolicy,
and save it to user profile.
**/
VOID
SaveAccessPolicy (
VOID
);
/**
Get current user's access rights.
@param[out] AccessRight Points to the buffer used for user's access rights.
@retval EFI_SUCCESS Get current user access rights successfully.
@retval others Fail to get current user access rights.
**/
EFI_STATUS
GetAccessRight (
OUT UINT32 *AccessRight
);
/**
Display the permit load device path in the loadable device path list.
**/
VOID
DisplayLoadPermit(
VOID
);
/**
Display the forbid load device path list (mAccessInfo.LoadForbid).
**/
VOID
DisplayLoadForbid (
VOID
);
/**
Display the permit connect device path.
**/
VOID
DisplayConnectPermit (
VOID
);
/**
Display the forbid connect device path list.
**/
VOID
DisplayConnectForbid (
VOID
);
/**
Delete the specified device path by DriverIndex from the forbid device path
list (mAccessInfo.LoadForbid).
@param[in] DriverIndex The index of driver in a forbidden device path list.
**/
VOID
DeleteFromForbidLoad (
IN UINT16 DriverIndex
);
/**
Add the specified device path by DriverIndex to the forbid device path
list (mAccessInfo.LoadForbid).
@param[in] DriverIndex The index of driver saved in driver options.
**/
VOID
AddToForbidLoad (
IN UINT16 DriverIndex
);
/**
Get user name from the popup windows.
@param[in, out] UserNameLen On entry, point to the buffer lengh of UserName.
On exit, point to the input user name length.
@param[out] UserName The buffer to hold the input user name.
@retval EFI_ABORTED It is given up by pressing 'ESC' key.
@retval EFI_NOT_READY Not a valid input at all.
@retval EFI_SUCCESS Get a user name successfully.
**/
EFI_STATUS
GetUserNameInput (
IN OUT UINTN *UserNameLen,
OUT CHAR16 *UserName
);
#endif

View File

@ -0,0 +1,161 @@
/** @file
The form data for user profile manager driver.
Copyright (c) 2009 - 2010, 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 __USER_PROFILE_MANAGER_DATA_H__
#define __USER_PROFILE_MANAGER_DATA_H__
#define USER_PROFILE_MANAGER_GUID \
{ \
0xc35f272c, 0x97c2, 0x465a, { 0xa2, 0x16, 0x69, 0x6b, 0x66, 0x8a, 0x8c, 0xfe } \
}
//
// Form ID
//
#define FORMID_USER_MANAGE 0x0001
#define FORMID_MODIFY_USER 0x0002
#define FORMID_DEL_USER 0x0003
#define FORMID_USER_INFO 0x0004
#define FORMID_MODIFY_IP 0x0005
#define FORMID_MODIFY_AP 0x0006
#define FORMID_LOAD_DP 0x0007
#define FORMID_CONNECT_DP 0x0008
#define FORMID_PERMIT_LOAD_DP 0x0009
#define FORMID_FORBID_LOAD_DP 0x000A
#define FORMID_PERMIT_CONNECT_DP 0x000B
#define FORMID_FORBID_CONNECT_DP 0x000C
//
// Label ID
//
#define LABEL_USER_MANAGE_FUNC 0x0010
#define LABEL_USER_DEL_FUNC 0x0020
#define LABEL_USER_MOD_FUNC 0x0030
#define LABEL_USER_INFO_FUNC 0x0040
#define LABEL_IP_MOD_FUNC 0x0050
#define LABEL_AP_MOD_FUNC 0x0060
#define LABEL_PERMIT_LOAD_FUNC 0x0070
#define LABLE_FORBID_LOAD_FUNC 0x0080
#define LABEL_END 0x00F0
//
// First form key (Add/modify/del user profile).
// First 2 bits (bit 16~15).
//
#define KEY_MODIFY_USER 0x4000
#define KEY_DEL_USER 0x8000
#define KEY_ADD_USER 0xC000
#define KEY_FIRST_FORM_MASK 0xC000
//
// Second form key (Display new form /Select user / modify device path in access policy).
// Next 2 bits (bit 14~13).
//
#define KEY_ENTER_NEXT_FORM 0x0000
#define KEY_SELECT_USER 0x1000
#define KEY_MODIFY_AP_DP 0x2000
#define KEY_OPEN_CLOSE_FORM_ACTION 0x3000
#define KEY_SECOND_FORM_MASK 0x3000
//
// User profile information form key.
// Next 3 bits (bit 12~10).
//
#define KEY_MODIFY_NAME 0x0200
#define KEY_MODIFY_IP 0x0400
#define KEY_MODIFY_AP 0x0600
#define KEY_MODIFY_INFO_MASK 0x0E00
//
// Specified key, used in VFR (KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_NAME).
//
#define KEY_MODIFY_USER_NAME 0x5200
//
// Modify identity policy form key.
// Next 3 bits (bit 9~7).
//
#define KEY_MODIFY_PROV 0x0040
#define KEY_MODIFY_MTYPE 0x0080
#define KEY_MODIFY_CONN 0x00C0
#define KEY_ADD_IP_OP 0x0100
#define KEY_IP_RETURN_UIF 0x0140
#define KEY_MODIFY_IP_MASK 0x01C0
//
// Specified key.
//
#define KEY_ADD_LOGICAL_OP 0x5500
#define KEY_IP_RETURN 0x5540
//
// Modify access policy form key.
// Next 3 bits (bit 9~7).
//
#define KEY_MODIFY_RIGHT 0x0040
#define KEY_MODIFY_SETUP 0x0080
#define KEY_MODIFY_BOOT 0x00C0
#define KEY_MODIFY_LOAD 0x0100
#define KEY_MODIFY_CONNECT 0x0140
#define KEY_AP_RETURN_UIF 0x0180
#define KEY_MODIFY_AP_MASK 0x01C0
//
// Specified key.
//
#define KEY_LOAD_DP 0x5700
#define KEY_CONN_DP 0x5740
#define KEY_AP_RETURN 0x5780
//
// Device path form key.
// Next 2 bits (bit 6~5).
//
#define KEY_PERMIT_MODIFY 0x0010
#define KEY_FORBID_MODIFY 0x0020
#define KEY_DISPLAY_DP_MASK 0x0030
//
// Specified key.
//
#define KEY_LOAD_PERMIT 0x5710
#define KEY_LOAD_FORBID 0x5720
#define KEY_CONNECT_PERMIT 0x5750
#define KEY_CONNECT_FORBID 0x5760
//
// Device path modify key.
// 2 bits (bit 12~11).
//
#define KEY_LOAD_PERMIT_MODIFY 0x0000
#define KEY_LOAD_FORBID_MODIFY 0x0400
#define KEY_CONNECT_PERMIT_MODIFY 0x0800
#define KEY_CONNECT_FORBID_MODIFY 0x0C00
#define KEY_MODIFY_DP_MASK 0x0C00
//
// The permissions usable when configuring the platform.
//
#define ACCESS_SETUP_RESTRICTED 1
#define ACCESS_SETUP_NORMAL 2
#define ACCESS_SETUP_ADMIN 3
//
// Question ID for the question used in each form (KEY_OPEN_CLOSE_FORM_ACTION | FORMID_FORM_USER_MANAGE)
// This ID is used in FORM OPEN/CLOSE CallBack action.
//
#define QUESTIONID_USER_MANAGE 0x3001
#endif

View File

@ -0,0 +1,60 @@
## @file
# Component description file for user profile manager 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 = UserProfileManager
FILE_GUID = E38CB52D-A74D-45db-A8D0-290C9B21BBF2
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = UserProfileManagerInit
[Sources]
UserProfileManager.c
UserProfileManager.h
UserProfileAdd.c
UserProfileDelete.c
UserProfileModify.c
UserProfileManagerData.h
UserProfileManagerStrings.uni
UserProfileManagerVfr.Vfr
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
UefiDriverEntryPoint
MemoryAllocationLib
BaseMemoryLib
DebugLib
HiiLib
UefiLib
[Guids]
gEfiIfrTianoGuid ## CONSUMES ## Guid
gEfiUserInfoAccessSetupAdminGuid ## CONSUMES ## Guid
gEfiUserInfoAccessSetupNormalGuid ## CONSUMES ## Guid
gEfiUserInfoAccessSetupRestrictedGuid ## CONSUMES ## Guid
[Protocols]
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiHiiConfigAccessProtocolGuid
gEfiUserCredentialProtocolGuid
gEfiUserManagerProtocolGuid
gEfiDevicePathToTextProtocolGuid
[Depex]
gEfiUserManagerProtocolGuid

View File

@ -0,0 +1,247 @@
/** @file
User Profile Manager formset.
Copyright (c) 2009 - 2010, 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 "UserProfileManagerData.h"
#define USER_MANAGER_CLASS 0x00
#define USER_MANAGER_SUBCLASS 0x04
formset
guid = USER_PROFILE_MANAGER_GUID,
title = STRING_TOKEN(STR_FORMSET_TITLE),
help = STRING_TOKEN(STR_TITLE_HELP),
class = USER_MANAGER_CLASS,
subclass = USER_MANAGER_SUBCLASS,
// User manager form
form formid = FORMID_USER_MANAGE,
title = STRING_TOKEN(STR_USERMAN_TITLE);
label LABEL_USER_MANAGE_FUNC;
label LABEL_END;
suppressif TRUE;
text
help = STRING_TOKEN(STR_NULL_STRING),
text = STRING_TOKEN(STR_NULL_STRING),
text = STRING_TOKEN(STR_NULL_STRING),
flags = INTERACTIVE,
key = QUESTIONID_USER_MANAGE;
endif;
endform;
// Modify user profile form
form formid = FORMID_MODIFY_USER,
title = STRING_TOKEN(STR_MODIFY_USER_TITLE);
label LABEL_USER_MOD_FUNC;
label LABEL_END;
endform;
// Delete user profile form
form formid = FORMID_DEL_USER,
title = STRING_TOKEN(STR_DELETE_USER_TITLE);
label LABEL_USER_DEL_FUNC;
label LABEL_END;
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
endform;
//
// User profile information form
//
form formid = FORMID_USER_INFO,
title = STRING_TOKEN(STR_USER_INFO);
text
help = STRING_TOKEN(STR_USER_NAME_VAL),
text = STRING_TOKEN(STR_USER_NAME),
flags = INTERACTIVE,
key = KEY_MODIFY_USER_NAME;
text
help = STRING_TOKEN(STR_CREATE_DATE_VAL),
text = STRING_TOKEN(STR_CREATE_DATE);
text
help = STRING_TOKEN(STR_USAGE_DATE_VAL),
text = STRING_TOKEN(STR_USAGE_DATE);
text
help = STRING_TOKEN(STR_USAGE_COUNT_VAL),
text = STRING_TOKEN(STR_USAGE_COUNT);
label LABEL_USER_INFO_FUNC;
label LABEL_END;
endform;
//
// Identify policy modify form
//
form formid = FORMID_MODIFY_IP,
title = STRING_TOKEN(STR_IDENTIFY_POLICY);
text
help = STRING_TOKEN(STR_IDENTIFY_POLICY_HELP),
text = STRING_TOKEN(STR_IDENTIFY_POLICY),
text = STRING_TOKEN(STR_IDENTIFY_POLICY_VALUE);
label LABEL_IP_MOD_FUNC;
label LABEL_END;
text
help = STRING_TOKEN(STR_ADD_OPTION_HELP),
text = STRING_TOKEN(STR_ADD_OPTION),
flags = INTERACTIVE,
key = KEY_ADD_LOGICAL_OP;
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
goto FORMID_USER_INFO,
prompt = STRING_TOKEN(STR_SAVE),
help = STRING_TOKEN(STR_IDENTIFY_SAVE_HELP),
flags = INTERACTIVE,
key = KEY_IP_RETURN;
endform;
//
// Access policy modify form
//
form formid = FORMID_MODIFY_AP,
title = STRING_TOKEN(STR_ACCESS_POLICY);
label LABEL_AP_MOD_FUNC;
label LABEL_END;
goto FORMID_LOAD_DP,
prompt = STRING_TOKEN(STR_LOAD),
help = STRING_TOKEN(STR_LOAD_HELP),
flags = INTERACTIVE,
key = KEY_LOAD_DP;
goto FORMID_CONNECT_DP,
prompt = STRING_TOKEN(STR_CONNECT),
help = STRING_TOKEN(STR_CONNECT_HELP),
flags = INTERACTIVE,
key = KEY_CONN_DP;
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
goto FORMID_USER_INFO,
prompt = STRING_TOKEN(STR_SAVE),
help = STRING_TOKEN(STR_ACCESS_SAVE_HELP),
flags = INTERACTIVE,
key = KEY_AP_RETURN;
endform;
//
// Load device path form
//
form formid = FORMID_LOAD_DP,
title = STRING_TOKEN(STR_LOAD);
goto FORMID_PERMIT_LOAD_DP,
prompt = STRING_TOKEN(STR_LOAD_PERMIT),
help = STRING_TOKEN(STR_LOAD_PERMIT_HELP),
flags = INTERACTIVE,
key = KEY_LOAD_PERMIT;
goto FORMID_FORBID_LOAD_DP,
prompt = STRING_TOKEN(STR_LOAD_FORBID),
help = STRING_TOKEN(STR_LOAD_FORBID_HELP),
flags = INTERACTIVE,
key = KEY_LOAD_FORBID;
endform;
//
// Permit load device path form
//
form formid = FORMID_PERMIT_LOAD_DP,
title = STRING_TOKEN(STR_LOAD_PERMIT);
label LABEL_PERMIT_LOAD_FUNC;
label LABEL_END;
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
endform;
//
// Forbid load device path form
//
form formid = FORMID_FORBID_LOAD_DP,
title = STRING_TOKEN(STR_LOAD_FORBID);
label LABLE_FORBID_LOAD_FUNC;
label LABEL_END;
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
endform;
//
// Connect device path form
//
form formid = FORMID_CONNECT_DP,
title = STRING_TOKEN(STR_CONNECT);
goto FORMID_PERMIT_CONNECT_DP,
prompt = STRING_TOKEN(STR_CONNECT_PERMIT),
help = STRING_TOKEN(STR_CONNECT_PERMIT_HELP),
flags = INTERACTIVE,
key = KEY_CONNECT_PERMIT;
goto FORMID_FORBID_CONNECT_DP,
prompt = STRING_TOKEN(STR_CONNECT_FORBID),
help = STRING_TOKEN(STR_CONNECT_FORBID_HELP),
flags = INTERACTIVE,
key = KEY_CONNECT_FORBID;
endform;
//
// Permit connect device path form
//
form formid = FORMID_PERMIT_CONNECT_DP,
title = STRING_TOKEN(STR_CONNECT_PERMIT);
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
endform;
//
// Forbid connect device path form
//
form formid = FORMID_FORBID_CONNECT_DP,
title = STRING_TOKEN(STR_CONNECT_FORBID);
subtitle
text = STRING_TOKEN(STR_NULL_STRING);
endform;
endformset;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,882 @@
/** @file
Implement authentication services for the authenticated variable
service in UEFI2.2.
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"
#include "AuthService.h"
///
/// Global database array for scratch
///
UINT32 mPubKeyNumber;
UINT32 mPlatformMode;
EFI_GUID mSignatureSupport[SIGSUPPORT_NUM] = {EFI_CERT_RSA2048_SHA256_GUID, EFI_CERT_RSA2048_SHA1_GUID};
//
// Public Exponent of RSA Key.
//
CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
/**
Initializes for authenticated varibale service.
@retval EFI_SUCCESS The function successfully executed.
@retval EFI_OUT_OF_RESOURCES Failed to allocate enough memory resources.
**/
EFI_STATUS
AutenticatedVariableServiceInitialize (
VOID
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK Variable;
UINT8 VarValue;
UINT32 VarAttr;
UINTN DataSize;
UINTN CtxSize;
VARIABLE_HEADER VariableHeader;
BOOLEAN Valid;
mVariableModuleGlobal->AuthenticatedVariableGuid[Physical] = &gEfiAuthenticatedVariableGuid;
mVariableModuleGlobal->CertRsa2048Sha256Guid[Physical] = &gEfiCertRsa2048Sha256Guid;
mVariableModuleGlobal->ImageSecurityDatabaseGuid[Physical] = &gEfiImageSecurityDatabaseGuid;
//
// Initialize hash context.
//
CtxSize = Sha256GetContextSize ();
mVariableModuleGlobal->HashContext[Physical] = AllocateRuntimePool (CtxSize);
ASSERT (mVariableModuleGlobal->HashContext[Physical] != NULL);
//
// Check "AuthVarKeyDatabase" variable's existence.
// If it doesn't exist, create a new one with initial value of 0 and EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
//
Status = FindVariable (
mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB],
&gEfiAuthenticatedVariableGuid,
&Variable,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance
);
if (Variable.CurrPtr == 0x0) {
VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
VarValue = 0;
mPubKeyNumber = 0;
Status = UpdateVariable (
mVariableModuleGlobal->VariableName[Physical][VAR_AUTH_KEY_DB],
&gEfiAuthenticatedVariableGuid,
&VarValue,
sizeof(UINT8),
VarAttr,
0,
0,
FALSE,
mVariableModuleGlobal,
&Variable
);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
//
// Load database in global variable for cache.
//
Valid = IsValidVariableHeader (
Variable.CurrPtr,
Variable.Volatile,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance,
&VariableHeader
);
ASSERT (Valid);
DataSize = DataSizeOfVariable (&VariableHeader);
ASSERT (DataSize <= MAX_KEYDB_SIZE);
GetVariableDataPtr (
Variable.CurrPtr,
Variable.Volatile,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance,
(CHAR16 *) mVariableModuleGlobal->PubKeyStore
);
mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE);
}
//
// Check "SetupMode" variable's existence.
// If it doesn't exist, check PK database's existence to determine the value.
// Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
//
Status = FindVariable (
mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE],
&gEfiGlobalVariableGuid,
&Variable,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance
);
if (Variable.CurrPtr == 0x0) {
Status = FindVariable (
mVariableModuleGlobal->VariableName[Physical][VAR_PLATFORM_KEY],
&gEfiGlobalVariableGuid,
&Variable,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance
);
if (Variable.CurrPtr == 0x0) {
mPlatformMode = SETUP_MODE;
} else {
mPlatformMode = USER_MODE;
}
VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
Status = UpdateVariable (
mVariableModuleGlobal->VariableName[Physical][VAR_SETUP_MODE],
&gEfiGlobalVariableGuid,
&mPlatformMode,
sizeof(UINT8),
VarAttr,
0,
0,
FALSE,
mVariableModuleGlobal,
&Variable
);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
GetVariableDataPtr (
Variable.CurrPtr,
Variable.Volatile,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance,
(CHAR16 *) &mPlatformMode
);
}
//
// Check "SignatureSupport" variable's existence.
// If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
//
Status = FindVariable (
EFI_SIGNATURE_SUPPORT_NAME,
&gEfiGlobalVariableGuid,
&Variable,
&mVariableModuleGlobal->VariableGlobal[Physical],
mVariableModuleGlobal->FvbInstance
);
if (Variable.CurrPtr == 0x0) {
VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
Status = UpdateVariable (
EFI_SIGNATURE_SUPPORT_NAME,
&gEfiGlobalVariableGuid,
mSignatureSupport,
SIGSUPPORT_NUM * sizeof(EFI_GUID),
VarAttr,
0,
0,
FALSE,
mVariableModuleGlobal,
&Variable
);
}
return Status;
}
/**
Add public key in store and return its index.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] PubKey The input pointer to Public Key data.
@return The index of new added item.
**/
UINT32
AddPubKeyInStore (
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN UINT8 *PubKey
)
{
EFI_STATUS Status;
BOOLEAN IsFound;
UINT32 Index;
VARIABLE_POINTER_TRACK Variable;
UINT8 *Ptr;
if (PubKey == NULL) {
return 0;
}
Status = FindVariable (
Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB],
Global->AuthenticatedVariableGuid[VirtualMode],
&Variable,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance
);
ASSERT_EFI_ERROR (Status);
//
// Check whether the public key entry does exist.
//
IsFound = FALSE;
for (Ptr = Global->PubKeyStore, Index = 1; Index <= mPubKeyNumber; Index++) {
if (CompareMem (Ptr, PubKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {
IsFound = TRUE;
break;
}
Ptr += EFI_CERT_TYPE_RSA2048_SIZE;
}
if (!IsFound) {
//
// Add public key in database.
//
if (mPubKeyNumber == MAX_KEY_NUM) {
//
// Notes: Database is full, need enhancement here, currently just return 0.
//
return 0;
}
CopyMem (Global->PubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
Index = ++mPubKeyNumber;
//
// Update public key database variable.
//
Status = UpdateVariable (
Global->VariableName[VirtualMode][VAR_AUTH_KEY_DB],
Global->AuthenticatedVariableGuid[VirtualMode],
Global->PubKeyStore,
mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
0,
0,
VirtualMode,
Global,
&Variable
);
ASSERT_EFI_ERROR (Status);
}
return Index;
}
/**
Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.
Follow the steps in UEFI2.2.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Data The pointer to data with AuthInfo.
@param[in] DataSize The size of Data.
@param[in] PubKey The public key used for verification.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION Authentication failed.
@retval EFI_SUCCESS Authentication successful.
**/
EFI_STATUS
VerifyDataPayload (
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN UINT8 *Data,
IN UINTN DataSize,
IN UINT8 *PubKey
)
{
BOOLEAN Status;
EFI_VARIABLE_AUTHENTICATION *CertData;
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
UINT8 Digest[SHA256_DIGEST_SIZE];
VOID *Rsa;
VOID *HashContext;
Rsa = NULL;
CertData = NULL;
CertBlock = NULL;
if (Data == NULL || PubKey == NULL) {
return EFI_INVALID_PARAMETER;
}
CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
//
// wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
// Cert type should be EFI_CERT_TYPE_RSA2048_SHA256.
//
if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
!CompareGuid (&CertData->AuthInfo.CertType, Global->CertRsa2048Sha256Guid[VirtualMode])
) {
//
// Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
//
return EFI_SECURITY_VIOLATION;
}
//
// Hash data payload with SHA256.
//
ZeroMem (Digest, SHA256_DIGEST_SIZE);
HashContext = Global->HashContext[VirtualMode];
Status = Sha256Init (HashContext);
if (!Status) {
goto Done;
}
Status = Sha256Update (HashContext, Data + AUTHINFO_SIZE, (UINTN) (DataSize - AUTHINFO_SIZE));
if (!Status) {
goto Done;
}
//
// Hash Monotonic Count.
//
Status = Sha256Update (HashContext, &CertData->MonotonicCount, sizeof (UINT64));
if (!Status) {
goto Done;
}
Status = Sha256Final (HashContext, Digest);
if (!Status) {
goto Done;
}
//
// Generate & Initialize RSA Context.
//
Rsa = RsaNew ();
ASSERT (Rsa != NULL);
//
// Set RSA Key Components.
// NOTE: Only N and E are needed to be set as RSA public key for signature verification.
//
Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
if (!Status) {
goto Done;
}
Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
if (!Status) {
goto Done;
}
//
// Verify the signature.
//
Status = RsaPkcs1Verify (
Rsa,
Digest,
SHA256_DIGEST_SIZE,
CertBlock->Signature,
EFI_CERT_TYPE_RSA2048_SHA256_SIZE
);
Done:
if (Rsa != NULL) {
RsaFree (Rsa);
}
if (Status) {
return EFI_SUCCESS;
} else {
return EFI_SECURITY_VIOLATION;
}
}
/**
Update platform mode.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Mode SETUP_MODE or USER_MODE.
**/
VOID
UpdatePlatformMode (
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN UINT32 Mode
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK Variable;
UINT32 VarAttr;
Status = FindVariable (
Global->VariableName[VirtualMode][VAR_SETUP_MODE],
Global->GlobalVariableGuid[VirtualMode],
&Variable,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance
);
ASSERT_EFI_ERROR (Status);
mPlatformMode = Mode;
VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
Status = UpdateVariable (
Global->VariableName[VirtualMode][VAR_SETUP_MODE],
Global->GlobalVariableGuid[VirtualMode],
&mPlatformMode,
sizeof(UINT8),
VarAttr,
0,
0,
VirtualMode,
Global,
&Variable
);
ASSERT_EFI_ERROR (Status);
}
/**
Process variable with platform key for verification.
@param[in] VariableName The name of Variable to be found.
@param[in] VendorGuid The variable vendor GUID.
@param[in] Data The data pointer.
@param[in] DataSize The size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@param[in] IsPk Indicates whether to process pk.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithPk (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL,
IN BOOLEAN IsPk
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK PkVariable;
EFI_SIGNATURE_LIST *OldPkList;
EFI_SIGNATURE_DATA *OldPkData;
EFI_VARIABLE_AUTHENTICATION *CertData;
VARIABLE_HEADER VariableHeader;
BOOLEAN Valid;
OldPkList = NULL;
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
//
// PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
//
return EFI_INVALID_PARAMETER;
}
if (mPlatformMode == USER_MODE) {
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
//
// In user mode, PK and KEK should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.
//
return EFI_INVALID_PARAMETER;
}
CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
if (Variable->CurrPtr != 0x0) {
Valid = IsValidVariableHeader (
Variable->CurrPtr,
Variable->Volatile,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance,
&VariableHeader
);
ASSERT (Valid);
if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
//
// Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
//
return EFI_SECURITY_VIOLATION;
}
}
//
// Get platform key from variable.
//
Status = FindVariable (
Global->VariableName[VirtualMode][VAR_PLATFORM_KEY],
Global->GlobalVariableGuid[VirtualMode],
&PkVariable,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance
);
ASSERT_EFI_ERROR (Status);
ZeroMem (Global->KeyList, MAX_KEYDB_SIZE);
GetVariableDataPtr (
PkVariable.CurrPtr,
PkVariable.Volatile,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance,
(CHAR16 *) Global->KeyList
);
OldPkList = (EFI_SIGNATURE_LIST *) Global->KeyList;
OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);
Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, OldPkData->SignatureData);
if (!EFI_ERROR (Status)) {
Status = UpdateVariable (
VariableName,
VendorGuid,
(UINT8*)Data + AUTHINFO_SIZE,
DataSize - AUTHINFO_SIZE,
Attributes,
0,
CertData->MonotonicCount,
VirtualMode,
Global,
Variable
);
if (!EFI_ERROR (Status)) {
//
// If delete PK in user mode, need change to setup mode.
//
if ((DataSize == AUTHINFO_SIZE) && IsPk) {
UpdatePlatformMode (VirtualMode, Global, SETUP_MODE);
}
}
}
} else {
Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, 0, 0, VirtualMode, Global, Variable);
//
// If enroll PK in setup mode, need change to user mode.
//
if ((DataSize != 0) && IsPk) {
UpdatePlatformMode (VirtualMode, Global, USER_MODE);
}
}
return Status;
}
/**
Process variable with key exchange key for verification.
@param[in] VariableName The name of Variable to be found.
@param[in] VendorGuid The variable vendor GUID.
@param[in] Data The data pointer.
@param[in] DataSize The size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION The variable did NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithKek (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK KekVariable;
EFI_SIGNATURE_LIST *KekList;
EFI_SIGNATURE_DATA *KekItem;
UINT32 KekCount;
EFI_VARIABLE_AUTHENTICATION *CertData;
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
BOOLEAN IsFound;
UINT32 Index;
VARIABLE_HEADER VariableHeader;
BOOLEAN Valid;
KekList = NULL;
if (mPlatformMode == USER_MODE) {
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
//
// In user mode, should set EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute.
//
return EFI_INVALID_PARAMETER;
}
CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
if (Variable->CurrPtr != 0x0) {
Valid = IsValidVariableHeader (
Variable->CurrPtr,
Variable->Volatile,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance,
&VariableHeader
);
ASSERT (Valid);
if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
//
// Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
//
return EFI_SECURITY_VIOLATION;
}
}
//
// Get KEK database from variable.
//
Status = FindVariable (
Global->VariableName[VirtualMode][VAR_KEY_EXCHANGE_KEY],
Global->GlobalVariableGuid[VirtualMode],
&KekVariable,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance
);
ASSERT_EFI_ERROR (Status);
ZeroMem (Global->KeyList, MAX_KEYDB_SIZE);
GetVariableDataPtr (
KekVariable.CurrPtr,
KekVariable.Volatile,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance,
(CHAR16 *) Global->KeyList
);
//
// Enumerate all Kek items in this list to verify the variable certificate data.
// If anyone is authenticated successfully, it means the variable is correct!
//
KekList = (EFI_SIGNATURE_LIST *) Global->KeyList;
IsFound = FALSE;
KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;
KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);
for (Index = 0; Index < KekCount; Index++) {
if (CompareMem (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {
IsFound = TRUE;
break;
}
KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);
}
if (!IsFound) {
return EFI_SECURITY_VIOLATION;
}
Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, CertBlock->PublicKey);
if (!EFI_ERROR (Status)) {
Status = UpdateVariable (
VariableName,
VendorGuid,
(UINT8*)Data + AUTHINFO_SIZE,
DataSize - AUTHINFO_SIZE,
Attributes,
0,
CertData->MonotonicCount,
VirtualMode,
Global,
Variable
);
}
} else {
//
// If in setup mode, no authentication needed.
//
Status = UpdateVariable (
VariableName,
VendorGuid,
Data,
DataSize,
Attributes,
0,
0,
VirtualMode,
Global,
Variable
);
}
return Status;
}
/**
Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set, and return the index of associated public key.
@param[in] Data The data pointer.
@param[in] DataSize The size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@param[out] KeyIndex The output index of corresponding public key in database.
@param[out] MonotonicCount The output value of corresponding Monotonic Count.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_WRITE_PROTECTED The variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@retval EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable is not write-protected, or passed validation successfully.
**/
EFI_STATUS
VerifyVariable (
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL,
OUT UINT32 *KeyIndex OPTIONAL,
OUT UINT64 *MonotonicCount OPTIONAL
)
{
EFI_STATUS Status;
BOOLEAN IsDeletion;
BOOLEAN IsFirstTime;
UINT8 *PubKey;
EFI_VARIABLE_AUTHENTICATION *CertData;
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
VARIABLE_HEADER VariableHeader;
BOOLEAN Valid;
CertData = NULL;
CertBlock = NULL;
PubKey = NULL;
IsDeletion = FALSE;
Valid = FALSE;
if (KeyIndex != NULL) {
*KeyIndex = 0;
}
//
// Determine if first time SetVariable with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS.
//
ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER));
if (Variable->CurrPtr != 0x0) {
Valid = IsValidVariableHeader (
Variable->CurrPtr,
Variable->Volatile,
&Global->VariableGlobal[VirtualMode],
Global->FvbInstance,
&VariableHeader
);
ASSERT (Valid);
}
if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
if (KeyIndex == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Determine current operation type.
//
if (DataSize == AUTHINFO_SIZE) {
IsDeletion = TRUE;
}
//
// Determine whether this is the first time with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
//
if (Variable->CurrPtr == 0x0) {
IsFirstTime = TRUE;
} else if (Valid &&(VariableHeader.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0) {
IsFirstTime = TRUE;
} else {
*KeyIndex = VariableHeader.PubKeyIndex;
IsFirstTime = FALSE;
}
} else if (Valid && (VariableHeader.Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
//
// If the variable is already write-protected, it always needs authentication before update.
//
return EFI_WRITE_PROTECTED;
} else {
//
// If without EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, set and attributes collision.
// That means it is not authenticated variable, just return EFI_SUCCESS.
//
return EFI_SUCCESS;
}
//
// Get PubKey and check Monotonic Count value corresponding to the variable.
//
CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData);
PubKey = CertBlock->PublicKey;
if (MonotonicCount != NULL) {
//
// Update Monotonic Count value.
//
*MonotonicCount = CertData->MonotonicCount;
}
if (!IsFirstTime) {
//
// Check input PubKey.
//
if (CompareMem (PubKey, Global->PubKeyStore + (*KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) {
return EFI_SECURITY_VIOLATION;
}
//
// Compare the current monotonic count and ensure that it is greater than the last SetVariable
// operation with the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute set.
//
if (CertData->MonotonicCount <= VariableHeader.MonotonicCount) {
//
// Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
//
return EFI_SECURITY_VIOLATION;
}
}
//
// Verify the certificate in Data payload.
//
Status = VerifyDataPayload (VirtualMode, Global, Data, DataSize, PubKey);
if (!EFI_ERROR (Status)) {
//
// Now, the signature has been verified!
//
if (IsFirstTime && !IsDeletion) {
//
// Update public key database variable if need and return the index.
//
*KeyIndex = AddPubKeyInStore (VirtualMode, Global, PubKey);
}
}
return Status;
}

View File

@ -0,0 +1,151 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by AuthService 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 _AUTHSERVICE_H_
#define _AUTHSERVICE_H_
#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
#define EFI_CERT_TYPE_RSA2048_SIZE 256
///
/// Size of AuthInfo prior to the data payload
///
#define AUTHINFO_SIZE (((UINTN)(((EFI_VARIABLE_AUTHENTICATION *) 0)->AuthInfo.CertData)) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))
///
/// Item number of support signature types.
///
#define SIGSUPPORT_NUM 2
/**
Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set, and return the index of associated public key.
@param[in] Data The data pointer.
@param[in] DataSize The size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@param[out] KeyIndex The output index of corresponding public key in database.
@param[out] MonotonicCount The output value of corresponding Monotonic Count.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_WRITE_PROTECTED The variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@retval EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable is not write-protected, or passed validation successfully.
**/
EFI_STATUS
VerifyVariable (
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL,
OUT UINT32 *KeyIndex OPTIONAL,
OUT UINT64 *MonotonicCount OPTIONAL
);
/**
Initializes for authenticated varibale service.
@retval EFI_SUCCESS The function successfully executed.
@retval EFI_OUT_OF_RESOURCES Failed to allocate enough memory resources.
**/
EFI_STATUS
AutenticatedVariableServiceInitialize (
VOID
);
/**
Initializes for cryptlib service before use, include register algrithm and allocate scratch.
**/
VOID
CryptLibraryInitialize (
VOID
);
/**
Process variable with platform key for verification.
@param[in] VariableName The name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data The data pointer.
@param[in] DataSize The size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@param[in] IsPk Indicates whether to process pk.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithPk (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL,
IN BOOLEAN IsPk
);
/**
Process variable with key exchange key for verification.
@param[in] VariableName The name of Variable to be found.
@param[in] VendorGuid The variable vendor GUID.
@param[in] Data The data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes The attribute value of the variable.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@retval EFI_SUCCESS The variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithKek (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL
);
#endif

View File

@ -0,0 +1,85 @@
## @file
# Component description file for Extended SAL authentication variable
# service 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = EsalVariableDxeSal
FILE_GUID = 14610837-4E97-4427-96E0-21D9B2956996
MODULE_TYPE = DXE_SAL_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = VariableServiceInitialize
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IPF
#
# VIRTUAL_ADDRESS_MAP_CALLBACK = VariableClassAddressChangeEvent
#
[Sources.common]
InitVariable.c
Reclaim.c
Variable.c
Variable.h
AuthService.c
AuthService.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
SynchronizationLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
UefiRuntimeLib
DxeServicesTableLib
UefiDriverEntryPoint
PcdLib
ExtendedSalLib
BaseCryptLib
[Protocols]
gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
gEfiFaultTolerantWriteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
[Guids]
gEfiGlobalVariableGuid
gEfiAuthenticatedVariableGuid
gEfiEventVirtualAddressChangeGuid
gEfiCertRsa2048Sha256Guid
gEfiImageSecurityDatabaseGuid
[Pcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics
[Depex]
gEfiExtendedSalFvBlockServicesProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid

View File

@ -0,0 +1,245 @@
/** @file
Entrypoint of Extended SAL variable service 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.
**/
#include "Variable.h"
#include "AuthService.h"
//
// Don't use module globals after the SetVirtualAddress map is signaled
//
EFI_EVENT mEfiVirtualNotifyEvent;
/**
Common entry for Extended SAL Variable Services Class.
This is the common entry of all functions of Extended SAL Variable Services Class.
@param[in] FunctionId The Function ID of member function in Extended SAL Variable Services Class.
@param[in] Arg2 The 2nd parameter for SAL procedure call.
@param[in] Arg3 The 3rd parameter for SAL procedure call.
@param[in] Arg4 The 4th parameter for SAL procedure call.
@param[in] Arg5 The 5th parameter for SAL procedure call.
@param[in] Arg6 The 6th parameter for SAL procedure call.
@param[in] Arg7 The 7th parameter for SAL procedure call.
@param[in] Arg8 The 8th parameter for SAL procedure call.
@param[in] VirtualMode The current calling mode for this function.
@param[in] Global The context of this Extended SAL Variable Services Class call.
@return The register of SAL.
**/
SAL_RETURN_REGS
EFIAPI
EsalVariableCommonEntry (
IN UINT64 FunctionId,
IN UINT64 Arg2,
IN UINT64 Arg3,
IN UINT64 Arg4,
IN UINT64 Arg5,
IN UINT64 Arg6,
IN UINT64 Arg7,
IN UINT64 Arg8,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global
)
{
SAL_RETURN_REGS ReturnVal;
ReturnVal.r9 = 0;
ReturnVal.r10 = 0;
ReturnVal.r11 = 0;
switch (FunctionId) {
case EsalGetVariableFunctionId:
ReturnVal.Status = EsalGetVariable (
(CHAR16 *) Arg2,
(EFI_GUID *) Arg3,
(UINT32 *) Arg4,
(UINTN *) Arg5,
(VOID *) Arg6,
VirtualMode,
Global
);
return ReturnVal;
case EsalGetNextVariableNameFunctionId:
ReturnVal.Status = EsalGetNextVariableName (
(UINTN *) Arg2,
(CHAR16 *) Arg3,
(EFI_GUID *) Arg4,
VirtualMode,
Global
);
return ReturnVal;
case EsalSetVariableFunctionId:
ReturnVal.Status = EsalSetVariable (
(CHAR16 *) Arg2,
(EFI_GUID *) Arg3,
(UINT32) Arg4,
(UINTN) Arg5,
(VOID *) Arg6,
VirtualMode,
Global
);
return ReturnVal;
case EsalQueryVariableInfoFunctionId:
ReturnVal.Status = EsalQueryVariableInfo (
(UINT32) Arg2,
(UINT64 *) Arg3,
(UINT64 *) Arg4,
(UINT64 *) Arg5,
VirtualMode,
Global
);
return ReturnVal;
default:
ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;
return ReturnVal;
}
}
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param[in] Event The event whose notification function is being invoked.
@param[in] Context The pointer to the notification function's context.
**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
UINTN Index;
CopyMem (
&mVariableModuleGlobal->VariableGlobal[Virtual],
&mVariableModuleGlobal->VariableGlobal[Physical],
sizeof (VARIABLE_GLOBAL)
);
EfiConvertPointer (
0x0,
(VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].NonVolatileVariableBase
);
EfiConvertPointer (
0x0,
(VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].VolatileVariableBase
);
mVariableModuleGlobal->PlatformLangCodes[Virtual] = mVariableModuleGlobal->PlatformLangCodes[Physical];
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes[Virtual]);
mVariableModuleGlobal->LangCodes[Virtual] = mVariableModuleGlobal->LangCodes[Physical];
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes[Virtual]);
mVariableModuleGlobal->PlatformLang[Virtual] = mVariableModuleGlobal->PlatformLang[Physical];
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang[Virtual]);
CopyMem (
mVariableModuleGlobal->VariableName[Virtual],
mVariableModuleGlobal->VariableName[Physical],
sizeof (mVariableModuleGlobal->VariableName[Physical])
);
for (Index = 0; Index < NUM_VAR_NAME; Index++) {
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableName[Virtual][Index]);
}
mVariableModuleGlobal->GlobalVariableGuid[Virtual] = &gEfiGlobalVariableGuid;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->GlobalVariableGuid[Virtual]);
mVariableModuleGlobal->AuthenticatedVariableGuid[Virtual] = &gEfiAuthenticatedVariableGuid;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->AuthenticatedVariableGuid[Virtual]);
mVariableModuleGlobal->CertRsa2048Sha256Guid[Virtual] = &gEfiCertRsa2048Sha256Guid;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->CertRsa2048Sha256Guid[Virtual]);
mVariableModuleGlobal->ImageSecurityDatabaseGuid[Virtual] = &gEfiImageSecurityDatabaseGuid;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->ImageSecurityDatabaseGuid[Virtual]);
mVariableModuleGlobal->HashContext[Virtual] = mVariableModuleGlobal->HashContext[Physical];
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->HashContext[Virtual]);
}
/**
Entry point of Extended SAL Variable service module.
This function is the entry point of Extended SAL Variable service module.
It registers all functions of Extended SAL Variable class, initializes
variable store for non-volatile and volatile variables, and registers
notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The Image handle of this driver.
@param[in] SystemTable The pointer of EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Extended SAL Variable Services Class successfully registered.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VariableClassAddressChangeEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mEfiVirtualNotifyEvent
);
ASSERT_EFI_ERROR (Status);
Status = VariableCommonInitialize (ImageHandle, SystemTable);
ASSERT_EFI_ERROR (Status);
//
// Authenticated variable initialize
//
Status = AutenticatedVariableServiceInitialize ();
ASSERT_EFI_ERROR (Status);
//
// Register All the Functions with Extended SAL Variable Services Class
//
RegisterEsalClass (
EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID_LO,
EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID_HI,
mVariableModuleGlobal,
EsalVariableCommonEntry,
EsalGetVariableFunctionId,
EsalVariableCommonEntry,
EsalGetNextVariableNameFunctionId,
EsalVariableCommonEntry,
EsalSetVariableFunctionId,
EsalVariableCommonEntry,
EsalQueryVariableInfoFunctionId,
NULL
);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,262 @@
/** @file
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
Copyright (c) 2006 - 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"
/**
Gets firmware volume block handle by given address.
This function gets firmware volume block handle whose
address range contains the parameter Address.
@param[in] Address Address which should be contained
by returned FVB handle.
@param[out] FvbHandle Pointer to FVB handle for output.
@retval EFI_SUCCESS FVB handle successfully returned.
@retval EFI_NOT_FOUND Failed to find FVB handle by address.
**/
EFI_STATUS
GetFvbHandleByAddress (
IN EFI_PHYSICAL_ADDRESS Address,
OUT EFI_HANDLE *FvbHandle
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
*FvbHandle = NULL;
//
// Locate all handles with Firmware Volume Block protocol
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolumeBlockProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Traverse all the handles, searching for the one containing parameter Address
//
for (Index = 0; Index < HandleCount; Index += 1) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiFirmwareVolumeBlockProtocolGuid,
(VOID **) &Fvb
);
if (EFI_ERROR (Status)) {
Status = EFI_NOT_FOUND;
break;
}
//
// Checks if the address range of this handle contains parameter Address
//
Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
if (EFI_ERROR (Status)) {
continue;
}
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {
*FvbHandle = HandleBuffer[Index];
Status = EFI_SUCCESS;
break;
}
}
FreePool (HandleBuffer);
return Status;
}
/**
Gets LBA of block and offset by given address.
This function gets the Logical Block Address (LBA) of firmware
volume block containing the given address, and the offset of
address on the block.
@param[in] Address Address which should be contained
by returned FVB handle.
@param[out] Lba The pointer to LBA for output.
@param[out] Offset The pointer to offset for output.
@retval EFI_SUCCESS LBA and offset successfully returned.
@retval EFI_NOT_FOUND Failed to find FVB handle by address.
@retval EFI_ABORTED Failed to find valid LBA and offset.
**/
EFI_STATUS
GetLbaAndOffsetByAddress (
IN EFI_PHYSICAL_ADDRESS Address,
OUT EFI_LBA *Lba,
OUT UINTN *Offset
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;
UINT32 LbaIndex;
*Lba = (EFI_LBA) (-1);
*Offset = 0;
//
// Gets firmware volume block handle by given address.
//
Status = GetFvbHandleByAddress (Address, &FvbHandle);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->HandleProtocol (
FvbHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
(VOID **) &Fvb
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the Base Address of FV
//
Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
if (EFI_ERROR (Status)) {
return Status;
}
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
//
// Get the (LBA, Offset) of Address
//
if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) {
if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {
//
// BUGBUG: Assume one FV has one type of BlockLength
//
FvbMapEntry = &FwVolHeader->BlockMap[0];
for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) {
//
// Found the (Lba, Offset)
//
*Lba = LbaIndex - 1;
*Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1)));
return EFI_SUCCESS;
}
}
}
}
return EFI_ABORTED;
}
/**
Writes a buffer to variable storage space.
This function writes a buffer to variable storage space into firmware
volume block device. The destination is specified by parameter
VariableBase. Fault Tolerant Write protocol is used for writing.
@param[in] VariableBase The base address of the variable to write.
@param[in] Buffer Points to the data buffer.
@param[in] BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@retval Other The function could not complete successfully.
**/
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer,
IN UINTN BufferSize
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_LBA VarLba;
UINTN VarOffset;
UINT8 *FtwBuffer;
UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
//
// Locate Fault Tolerant Write protocol
//
Status = gBS->LocateProtocol (
&gEfiFaultTolerantWriteProtocolGuid,
NULL,
(VOID **) &FtwProtocol
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Gets firmware volume block handle by VariableBase.
//
Status = GetFvbHandleByAddress (VariableBase, &FvbHandle);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Gets LBA of block and offset by VariableBase.
//
Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
//
// Prepare for the variable data
//
FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
FtwBuffer = AllocatePool (FtwBufferSize);
if (FtwBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);
CopyMem (FtwBuffer, Buffer, BufferSize);
//
// FTW write record
//
Status = FtwProtocol->Write (
FtwProtocol,
VarLba, // LBA
VarOffset, // Offset
FtwBufferSize, // NumBytes,
NULL,
FvbHandle,
FtwBuffer
);
FreePool (FtwBuffer);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,496 @@
/** @file
Internal header file for Extended SAL variable service 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 _VARIABLE_H_
#define _VARIABLE_H_
#include <PiDxe.h>
#include <Protocol/VariableWrite.h>
#include <Protocol/FaultTolerantWrite.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/Variable.h>
#include <Protocol/ExtendedSalBootService.h>
#include <Protocol/ExtendedSalServiceClasses.h>
#include <Guid/GlobalVariable.h>
#include <Guid/AuthenticatedVariableFormat.h>
#include <Guid/ImageAuthentication.h>
#include <Guid/EventGroup.h>
#include <Library/PcdLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ExtendedSalLib.h>
#include <Library/BaseCryptLib.h>
#define MAX_NAME_SIZE 0x100
#define NUM_VAR_NAME 9 // Number of pre-defined variable name to be referenced
#define VAR_PLATFORM_LANG_CODES 0 // Index of "PlatformLangCodes" variable
#define VAR_LANG_CODES 1 // Index of "LangCodes" variable
#define VAR_PLATFORM_LANG 2 // Index of "PlatformLang" variable
#define VAR_LANG 3 // Index of "Lang" variable
#define VAR_HW_ERR_REC 4 // Index of "HwErrRecXXXX" variable
#define VAR_AUTH_KEY_DB 5 // Index of "AuthVarKeyDatabase" variable
#define VAR_SETUP_MODE 6 // Index of "SetupMode" variable
#define VAR_PLATFORM_KEY 7 // Index of "PK" variable
#define VAR_KEY_EXCHANGE_KEY 8 // Index of "KEK" variable
///
/// "AuthVarKeyDatabase" variable for the Public Key store.
///
#define AUTHVAR_KEYDB_NAME L"AuthVarKeyDatabase"
#define AUTHVAR_KEYDB_NAME_SIZE 38
///
/// The maximum size of the public key database, restricted by maximum individal EFI
/// varible size, and excluding the variable header and name size.
///
#define MAX_KEYDB_SIZE (FixedPcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - AUTHVAR_KEYDB_NAME_SIZE)
#define MAX_KEY_NUM (MAX_KEYDB_SIZE / EFI_CERT_TYPE_RSA2048_SIZE)
///
/// The size of a 3 character ISO639 language code.
///
#define ISO_639_2_ENTRY_SIZE 3
typedef enum {
Physical,
Virtual
} VARIABLE_POINTER_TYPE;
typedef struct {
EFI_PHYSICAL_ADDRESS CurrPtr;
EFI_PHYSICAL_ADDRESS EndPtr;
EFI_PHYSICAL_ADDRESS StartPtr;
BOOLEAN Volatile;
} VARIABLE_POINTER_TRACK;
typedef struct {
EFI_PHYSICAL_ADDRESS VolatileVariableBase;
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
EFI_LOCK VariableServicesLock;
} VARIABLE_GLOBAL;
typedef struct {
VARIABLE_GLOBAL VariableGlobal[2];
CHAR16 *VariableName[2][NUM_VAR_NAME];
EFI_GUID *GlobalVariableGuid[2];
UINTN VolatileLastVariableOffset;
UINTN NonVolatileLastVariableOffset;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
CHAR8 *PlatformLangCodes[2];
CHAR8 *LangCodes[2];
CHAR8 *PlatformLang[2];
CHAR8 Lang[ISO_639_2_ENTRY_SIZE + 1];
UINT32 FvbInstance;
UINT32 ReentrantState;
EFI_GUID *AuthenticatedVariableGuid[2];
EFI_GUID *CertRsa2048Sha256Guid[2];
EFI_GUID *ImageSecurityDatabaseGuid[2];
VOID *HashContext[2]; // Hash context pointer
UINT8 KeyList[MAX_KEYDB_SIZE]; // Cached Platform Key list
UINT8 PubKeyStore[MAX_KEYDB_SIZE]; // Cached Public Key list
} ESAL_VARIABLE_GLOBAL;
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
UINT32 Attributes;
UINTN DataSize;
VOID *Data;
} VARIABLE_CACHE_ENTRY;
extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
//
// Functions
//
/**
Initializes variable store area for non-volatile and volatile variable.
This function allocates and initializes memory space for global context of ESAL
variable service and variable store area for non-volatile and volatile variable.
@param[in] ImageHandle The Image handle of this driver.
@param[in] SystemTable The pointer of EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Function successfully executed.
@retval EFI_OUT_OF_RESOURCES Failed to allocate enough memory resource.
**/
EFI_STATUS
VariableCommonInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Entry point of Extended SAL Variable service module.
This function is the entry point of Extended SAL Variable service module.
It registers all functions of Extended SAL Variable class, initializes
variable store for non-volatile and volatile variables, and registers
notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The Image handle of this driver.
@param[in] SystemTable The pointer of EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Extended SAL Variable Services Class successfully registered.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param[in] Event The event whose notification function is being invoked.
@param[in] Context The pointer to the notification function's context.
**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Implements EsalGetVariable function of Extended SAL Variable Services Class.
This function implements EsalGetVariable function of Extended SAL Variable Services Class.
It is equivalent in functionality to the EFI Runtime Service GetVariable().
@param[in] VariableName A Null-terminated Unicode string that is the name of
the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
@param[out] Attributes If not NULL, a pointer to the memory location to return the
attributes bitmask for the variable.
@param[in, out] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[out] Data On input, the size in bytes of the return Data buffer.
On output, the size of data returned in Data.
@param[in] VirtualMode Current calling mode for this function.
@param[in] Global Context of this Extended SAL Variable Services Class call.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The variable was not found.
@retval EFI_BUFFER_TOO_SMALL DataSize is too small for the result. DataSize has
been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableName is NULL.
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
@retval EFI_INVALID_PARAMETER DataSize is NULL.
@retval EFI_INVALID_PARAMETER DataSize is not too small and Data is NULL.
@retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
@retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
**/
EFI_STATUS
EFIAPI
EsalGetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global
);
/**
Implements EsalGetNextVariableName function of Extended SAL Variable Services Class.
This function implements EsalGetNextVariableName function of Extended SAL Variable Services Class.
It is equivalent in functionality to the EFI Runtime Service GetNextVariableName().
@param[in, out] VariableNameSize Size of the variable
@param[in, out] VariableName On input, supplies the last VariableName that was returned by GetNextVariableName().
On output, returns the Null-terminated Unicode string of the current variable.
@param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by GetNextVariableName().
On output, returns the VendorGuid of the current variable.
@param[in] VirtualMode Current calling mode for this function.
@param[in] Global Context of this Extended SAL Variable Services Class call.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The next variable was not found.
@retval EFI_BUFFER_TOO_SMALL VariableNameSize is too small for the result.
VariableNameSize has been updated with the size needed to complete the request.
@retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
@retval EFI_INVALID_PARAMETER VariableName is NULL.
@retval EFI_INVALID_PARAMETER VendorGuid is NULL.
@retval EFI_DEVICE_ERROR The variable name could not be retrieved due to a hardware error.
**/
EFI_STATUS
EFIAPI
EsalGetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global
);
/**
Implements EsalSetVariable function of Extended SAL Variable Services Class.
This function implements EsalSetVariable function of Extended SAL Variable Services Class.
It is equivalent in functionality to the EFI Runtime Service SetVariable().
@param[in] VariableName A Null-terminated Unicode string that is the name of the vendor's
variable. Each VariableName is unique for each
VendorGuid. VariableName must contain 1 or more
Unicode characters. If VariableName is an empty Unicode
string, then EFI_INVALID_PARAMETER is returned.
@param[in] VendorGuid A unique identifier for the vendor.
@param[in] Attributes Attributes bitmask to set for the variable.
@param[in] DataSize The size in bytes of the Data buffer. A size of zero causes the
variable to be deleted.
@param[in] Data The contents for the variable.
@param[in] VirtualMode Current calling mode for this function.
@param[in] Global Context of this Extended SAL Variable Services Class call.
@retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
defined by the Attributes.
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied, or the
DataSize exceeds the maximum allowed.
@retval EFI_INVALID_PARAMETER VariableName is an empty Unicode string.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved due to a hardware failure.
@retval EFI_WRITE_PROTECTED The variable in question is read-only.
@retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
@retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
@retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
**/
EFI_STATUS
EFIAPI
EsalSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global
);
/**
Implements EsalQueryVariableInfo function of Extended SAL Variable Services Class.
This function implements EsalQueryVariableInfo function of Extended SAL Variable Services Class.
It is equivalent in functionality to the EFI Runtime Service QueryVariableInfo().
@param[in] Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param[out] MaximumVariableStorageSize On output the maximum size of the storage space available for
the EFI variables associated with the attributes specified.
@param[out] RemainingVariableStorageSize Returns the remaining size of the storage space available for EFI
variables associated with the attributes specified.
@param[out] MaximumVariableSize Returns the maximum size of an individual EFI variable
associated with the attributes specified.
@param[in] VirtualMode Current calling mode for this function
@param[in] Global Context of this Extended SAL Variable Services Class call
@retval EFI_SUCCESS Valid answer returned.
@retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the
MaximumVariableStorageSize, RemainingVariableStorageSize,
MaximumVariableSize are undefined.
**/
EFI_STATUS
EFIAPI
EsalQueryVariableInfo (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global
);
/**
Writes a buffer to variable storage space.
This function writes a buffer to variable storage space into firmware
volume block device. The destination is specified by parameter
VariableBase. Fault Tolerant Write protocol is used for writing.
@param[in] VariableBase The base address of the variable to write.
@param[in] Buffer Points to the data buffer.
@param[in] BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@retval Other The function could not complete successfully.
**/
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer,
IN UINTN BufferSize
);
/**
Finds variable in volatile and non-volatile storage areas.
This code finds variable in volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
Otherwise, VariableName and VendorGuid are compared.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Vendor GUID to be found.
@param[out] PtrTrack VARIABLE_POINTER_TRACK structure for output,
including the range searched and the target position.
@param[in] Global Pointer to VARIABLE_GLOBAL structure, including
base of volatile variable storage area, base of
NV variable storage area, and a lock.
@param[in] Instance Instance of FV Block services.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while
VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_INVALID_PARAMETER Variable not found.
**/
EFI_STATUS
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack,
IN VARIABLE_GLOBAL *Global,
IN UINTN Instance
);
/**
Gets the pointer to variable data area.
This function gets the pointer to variable data area.
The variable is specified by its variable header.
@param[in] VariableAddress Start address of variable header.
@param[in] Volatile TRUE - Variable is volatile.
FALSE - Variable is non-volatile.
@param[in] Global Pointer to VARAIBLE_GLOBAL structure.
@param[in] Instance Instance of FV Block services.
@param[out] VariableData Buffer to hold variable data for output.
**/
VOID
GetVariableDataPtr (
IN EFI_PHYSICAL_ADDRESS VariableAddress,
IN BOOLEAN Volatile,
IN VARIABLE_GLOBAL *Global,
IN UINTN Instance,
OUT CHAR16 *VariableData
);
/**
Gets the size of variable data area.
This function gets the size of variable data area.
The variable is specified by its variable header.
If variable header contains raw data, just return 0.
@param[in] Variable Pointer to the variable header.
@return Size of variable data area in bytes.
**/
UINTN
DataSizeOfVariable (
IN VARIABLE_HEADER *Variable
);
/**
Update the variable region with Variable information. These are the same
arguments as the EFI Variable services.
@param[in] VariableName Name of variable.
@param[in] VendorGuid Guid of variable.
@param[in] Data Variable data.
@param[in] DataSize Size of data. 0 means delete.
@param[in] Attributes Attributes of the variable.
@param[in] KeyIndex Index of associated public key.
@param[in] MonotonicCount Value of associated monotonic count.
@param[in] VirtualMode Current calling mode for this function.
@param[in] Global Context of this Extended SAL Variable Services Class call.
@param[in] Variable The variable information which is used to keep track of variable usage.
@retval EFI_SUCCESS The update operation is success.
@retval EFI_OUT_OF_RESOURCES Variable region is full, can not write other data into this region.
**/
EFI_STATUS
EFIAPI
UpdateVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes OPTIONAL,
IN UINT32 KeyIndex OPTIONAL,
IN UINT64 MonotonicCount OPTIONAL,
IN BOOLEAN VirtualMode,
IN ESAL_VARIABLE_GLOBAL *Global,
IN VARIABLE_POINTER_TRACK *Variable
);
/**
Checks variable header.
This function checks if variable header is valid or not.
@param[in] VariableAddress Start address of variable header.
@param[in] Volatile TRUE - Variable is volatile.
FALSE - Variable is non-volatile.
@param[in] Global Pointer to VARAIBLE_GLOBAL structure.
@param[in] Instance Instance of FV Block services.
@param[out] VariableHeader Pointer to VARIABLE_HEADER for output.
@retval TRUE Variable header is valid.
@retval FALSE Variable header is not valid.
**/
BOOLEAN
IsValidVariableHeader (
IN EFI_PHYSICAL_ADDRESS VariableAddress,
IN BOOLEAN Volatile,
IN VARIABLE_GLOBAL *Global,
IN UINTN Instance,
OUT VARIABLE_HEADER *VariableHeader OPTIONAL
);
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -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
#

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,209 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by AuthService 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 _AUTHSERVICE_H_
#define _AUTHSERVICE_H_
#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
#define EFI_CERT_TYPE_RSA2048_SIZE 256
///
/// Size of AuthInfo prior to the data payload
///
#define AUTHINFO_SIZE (((UINTN)(((EFI_VARIABLE_AUTHENTICATION *) 0)->AuthInfo.CertData)) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256))
///
/// "AuthVarKeyDatabase" variable for the Public Key store.
///
#define AUTHVAR_KEYDB_NAME L"AuthVarKeyDatabase"
#define AUTHVAR_KEYDB_NAME_SIZE 38
///
/// Max size of public key database, restricted by max individal EFI varible size, exclude variable header and name size.
///
#define MAX_KEYDB_SIZE (FixedPcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - AUTHVAR_KEYDB_NAME_SIZE)
#define MAX_KEY_NUM (MAX_KEYDB_SIZE / EFI_CERT_TYPE_RSA2048_SIZE)
///
/// Item number of support signature types.
///
#define SIGSUPPORT_NUM 2
/**
Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter
@return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
@return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
set, but the AuthInfo does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable is not write-protected, or passed validation successfully.
**/
EFI_STATUS
ProcessVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes
);
/**
Initializes for authenticated varibale service.
@retval EFI_SUCCESS Function successfully executed.
@retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
**/
EFI_STATUS
AutenticatedVariableServiceInitialize (
VOID
);
/**
Initializes for cryptlib service before use, include register algrithm and allocate scratch.
**/
VOID
CryptLibraryInitialize (
VOID
);
/**
Process variable with platform key for verification.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes Attribute value of the variable.
@param[in] IsPk Indicate whether it is to process pk.
@return EFI_INVALID_PARAMETER Invalid parameter
@return EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithPk (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL,
IN BOOLEAN IsPk
);
/**
Process variable with key exchange key for verification.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Variable The variable information that is used to keep track of variable usage.
@param[in] Attributes Attribute value of the variable.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@return EFI_SUCCESS Variable passed validation successfully.
**/
EFI_STATUS
ProcessVarWithKek (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes OPTIONAL
);
/**
Compare two EFI_TIME data.
@param FirstTime A pointer to the first EFI_TIME data.
@param SecondTime A pointer to the second EFI_TIME data.
@retval TRUE The FirstTime is not later than the SecondTime.
@retval FALSE The FirstTime is later than the SecondTime.
**/
BOOLEAN
CompareTimeStamp (
IN EFI_TIME *FirstTime,
IN EFI_TIME *SecondTime
);
/**
Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Data Data pointer.
@param[in] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[in] Variable The variable information which is used to keep track of variable usage.
@param[in] Attributes Attribute value of the variable.
@param[in] Pk Verify against PK or KEK database.
@param[out] VarDel Delete the variable or not.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SECURITY_VIOLATION The variable does NOT pass the validation
check carried out by the firmware.
@retval EFI_OUT_OF_RESOURCES Failed to process variable due to lack
of resources.
@retval EFI_SUCCESS Variable pass validation successfully.
**/
EFI_STATUS
VerifyTimeBasedPayload (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN VARIABLE_POINTER_TRACK *Variable,
IN UINT32 Attributes,
IN BOOLEAN Pk,
OUT BOOLEAN *VarDel
);
extern UINT8 mPubKeyStore[MAX_KEYDB_SIZE];
extern UINT32 mPubKeyNumber;
extern VOID *mHashCtx;
extern VOID *mStorageArea;
#endif

View File

@ -0,0 +1,172 @@
/** @file
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
Copyright (c) 2009 - 2010, 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"
/**
Gets LBA of block and offset by given address.
This function gets the Logical Block Address (LBA) of a firmware
volume block containing the given address, and the offset of the
address on the block.
@param Address Address which should be contained
by returned FVB handle.
@param Lba Pointer to LBA for output.
@param Offset Pointer to offset for output.
@retval EFI_SUCCESS LBA and offset successfully returned.
@retval EFI_NOT_FOUND Fail to find FVB handle by address.
@retval EFI_ABORTED Fail to find valid LBA and offset.
**/
EFI_STATUS
GetLbaAndOffsetByAddress (
IN EFI_PHYSICAL_ADDRESS Address,
OUT EFI_LBA *Lba,
OUT UINTN *Offset
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry;
UINT32 LbaIndex;
*Lba = (EFI_LBA) (-1);
*Offset = 0;
//
// Get the proper FVB protocol.
//
Status = GetFvbInfoByAddress (Address, NULL, &Fvb);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the Base Address of FV.
//
Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
if (EFI_ERROR (Status)) {
return Status;
}
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
//
// Get the (LBA, Offset) of Address.
//
if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) {
//
// BUGBUG: Assume one FV has one type of BlockLength.
//
FvbMapEntry = &FwVolHeader->BlockMap[0];
for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) {
//
// Found the (Lba, Offset).
//
*Lba = LbaIndex - 1;
*Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1)));
return EFI_SUCCESS;
}
}
}
return EFI_ABORTED;
}
/**
Writes a buffer to variable storage space, in the working block.
This function writes a buffer to variable storage space into a firmware
volume block device. The destination is specified by parameter
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write
@param Buffer Point to the data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@retval EFI_ABORTED The function could not complete successfully.
**/
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer,
IN UINTN BufferSize
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_LBA VarLba;
UINTN VarOffset;
UINT8 *FtwBuffer;
UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
//
// Locate fault tolerant write protocol.
//
Status = GetFtwProtocol((VOID **) &FtwProtocol);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// Locate Fvb handle by address.
//
Status = GetFvbInfoByAddress (VariableBase, &FvbHandle, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get LBA and Offset by address.
//
Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset);
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
//
// Prepare for the variable data.
//
FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
FtwBuffer = AllocatePool (FtwBufferSize);
if (FtwBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);
CopyMem (FtwBuffer, Buffer, BufferSize);
//
// FTW write record.
//
Status = FtwProtocol->Write (
FtwProtocol,
VarLba, // LBA
VarOffset, // Offset
FtwBufferSize, // NumBytes
NULL, // PrivateData NULL
FvbHandle, // Fvb Handle
FtwBuffer // write buffer
);
FreePool (FtwBuffer);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,491 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
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 _VARIABLE_H_
#define _VARIABLE_H_
#include <PiDxe.h>
#include <Protocol/VariableWrite.h>
#include <Protocol/FaultTolerantWrite.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/Variable.h>
#include <Library/PcdLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/PlatformSecureLib.h>
#include <Guid/GlobalVariable.h>
#include <Guid/EventGroup.h>
#include <Guid/AuthenticatedVariableFormat.h>
#include <Guid/ImageAuthentication.h>
#define VARIABLE_RECLAIM_THRESHOLD (1024)
///
/// The size of a 3 character ISO639 language code.
///
#define ISO_639_2_ENTRY_SIZE 3
typedef struct {
VARIABLE_HEADER *CurrPtr;
VARIABLE_HEADER *EndPtr;
VARIABLE_HEADER *StartPtr;
BOOLEAN Volatile;
} VARIABLE_POINTER_TRACK;
typedef struct {
EFI_PHYSICAL_ADDRESS VolatileVariableBase;
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
EFI_LOCK VariableServicesLock;
UINT32 ReentrantState;
} VARIABLE_GLOBAL;
typedef struct {
VARIABLE_GLOBAL VariableGlobal;
UINTN VolatileLastVariableOffset;
UINTN NonVolatileLastVariableOffset;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
CHAR8 *PlatformLangCodes;
CHAR8 *LangCodes;
CHAR8 *PlatformLang;
CHAR8 Lang[ISO_639_2_ENTRY_SIZE + 1];
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbInstance;
} VARIABLE_MODULE_GLOBAL;
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
UINT32 Attributes;
UINTN DataSize;
VOID *Data;
} VARIABLE_CACHE_ENTRY;
/**
Writes a buffer to variable storage space, in the working block.
This function writes a buffer to variable storage space into a firmware
volume block device. The destination is specified by the parameter
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write.
@param Buffer Point to the data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@retval EFI_ABORTED The function could not complete successfully.
**/
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer,
IN UINTN BufferSize
);
/**
Finds variable in storage blocks of volatile and non-volatile storage areas.
This code finds variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
Otherwise, VariableName and VendorGuid are compared.
@param VariableName Name of the variable to be found.
@param VendorGuid Vendor GUID to be found.
@param PtrTrack VARIABLE_POINTER_TRACK structure for output,
including the range searched and the target position.
@param Global Pointer to VARIABLE_GLOBAL structure, including
base of volatile variable storage area, base of
NV variable storage area, and a lock.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while
VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_INVALID_PARAMETER Variable not found.
**/
EFI_STATUS
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack,
IN VARIABLE_GLOBAL *Global
);
/**
This code gets the pointer to the variable data.
@param Variable Pointer to the Variable Header.
@return Pointer to Variable Data.
**/
UINT8 *
GetVariableDataPtr (
IN VARIABLE_HEADER *Variable
);
/**
This code gets the size of variable data.
@param Variable Pointer to the Variable Header.
@return Size of variable in bytes.
**/
UINTN
DataSizeOfVariable (
IN VARIABLE_HEADER *Variable
);
/**
Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,
index of associated public key is needed.
@param[in] VariableName Name of variable.
@param[in] VendorGuid Guid of variable.
@param[in] Data Variable data.
@param[in] DataSize Size of data. 0 means delete.
@param[in] Attributes Attributes of the variable.
@param[in] KeyIndex Index of associated public key.
@param[in] MonotonicCount Value of associated monotonic count.
@param[in] Variable The variable information that is used to keep track of variable usage.
@param[in] TimeStamp Value of associated TimeStamp.
@retval EFI_SUCCESS The update operation is success.
@retval EFI_OUT_OF_RESOURCES Variable region is full, cannot write other data into this region.
**/
EFI_STATUS
UpdateVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes OPTIONAL,
IN UINT32 KeyIndex OPTIONAL,
IN UINT64 MonotonicCount OPTIONAL,
IN VARIABLE_POINTER_TRACK *Variable,
IN EFI_TIME *TimeStamp OPTIONAL
);
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
AtRuntime (
VOID
);
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
If Priority is not a valid TPL value, then ASSERT().
@param Lock A pointer to the lock data structure to initialize.
@param Priority EFI TPL is associated with the lock.
@return The lock.
**/
EFI_LOCK *
InitializeLock (
IN OUT EFI_LOCK *Lock,
IN EFI_TPL Priority
);
/**
Acquires lock only at boot time. Simply returns at runtime.
This is a temperary function that will be removed when
EfiAcquireLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiAcquireLock() at boot time, and simply returns
at runtime.
@param Lock A pointer to the lock to acquire.
**/
VOID
AcquireLockOnlyAtBootTime (
IN EFI_LOCK *Lock
);
/**
Releases lock only at boot time. Simply returns at runtime.
This is a temperary function which will be removed when
EfiReleaseLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiReleaseLock() at boot time and simply returns
at runtime.
@param Lock A pointer to the lock to release.
**/
VOID
ReleaseLockOnlyAtBootTime (
IN EFI_LOCK *Lock
);
/**
Retrive the FVB protocol interface by HANDLE.
@param[in] FvBlockHandle The handle of FVB protocol that provides services for
reading, writing, and erasing the target block.
@param[out] FvBlock The interface of FVB protocol
@retval EFI_SUCCESS The interface information for the specified protocol was returned.
@retval EFI_UNSUPPORTED The device does not support the FVB protocol.
@retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
**/
EFI_STATUS
GetFvbByHandle (
IN EFI_HANDLE FvBlockHandle,
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
);
/**
Retrive the Swap Address Range protocol interface.
@param[out] SarProtocol The interface of SAR protocol
@retval EFI_SUCCESS The SAR protocol instance was found and returned in SarProtocol.
@retval EFI_NOT_FOUND The SAR protocol instance was not found.
@retval EFI_INVALID_PARAMETER SarProtocol is NULL.
**/
EFI_STATUS
GetSarProtocol (
OUT VOID **SarProtocol
);
/**
Function returns an array of handles that support the FVB protocol
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
array of handles that support FVB protocol.
@retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
handles in Buffer was returned in NumberHandles.
@retval EFI_NOT_FOUND No FVB handle was found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
@retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
**/
EFI_STATUS
GetFvbCountAndBuffer (
OUT UINTN *NumberHandles,
OUT EFI_HANDLE **Buffer
);
/**
Initializes variable store area for non-volatile and volatile variable.
@retval EFI_SUCCESS Function successfully executed.
@retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
**/
EFI_STATUS
VariableCommonInitialize (
VOID
);
/**
This function reclaims variable storage if free size is below the threshold.
**/
VOID
ReclaimForOS(
VOID
);
/**
Initializes variable write service after FVB was ready.
@retval EFI_SUCCESS Function successfully executed.
@retval Others Fail to initialize the variable service.
**/
EFI_STATUS
VariableWriteServiceInitialize (
VOID
);
/**
Retrive the SMM Fault Tolerent Write protocol interface.
@param[out] FtwProtocol The interface of SMM Ftw protocol
@retval EFI_SUCCESS The SMM SAR protocol instance was found and returned in SarProtocol.
@retval EFI_NOT_FOUND The SMM SAR protocol instance was not found.
@retval EFI_INVALID_PARAMETER SarProtocol is NULL.
**/
EFI_STATUS
GetFtwProtocol (
OUT VOID **FtwProtocol
);
/**
Get the proper fvb handle and/or fvb protocol by the given Flash address.
@param[in] Address The Flash address.
@param[out] FvbHandle In output, if it is not NULL, it points to the proper FVB handle.
@param[out] FvbProtocol In output, if it is not NULL, it points to the proper FVB protocol.
**/
EFI_STATUS
GetFvbInfoByAddress (
IN EFI_PHYSICAL_ADDRESS Address,
OUT EFI_HANDLE *FvbHandle OPTIONAL,
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL
);
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Attributes Attribute value of the variable found.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data Data pointer.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
**/
EFI_STATUS
EFIAPI
VariableServiceGetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
OUT VOID *Data
);
/**
This code Finds the Next available variable.
@param VariableNameSize Size of the variable name.
@param VariableName Pointer to variable name.
@param VendorGuid Variable Vendor Guid.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
@return EFI_BUFFER_TO_SMALL DataSize is too small for the result.
**/
EFI_STATUS
EFIAPI
VariableServiceGetNextVariableName (
IN OUT UINTN *VariableNameSize,
IN OUT CHAR16 *VariableName,
IN OUT EFI_GUID *VendorGuid
);
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Attributes Attribute value of the variable found
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data Data pointer.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Set successfully.
@return EFI_OUT_OF_RESOURCES Resource not enough to set variable.
@return EFI_NOT_FOUND Not found.
@return EFI_WRITE_PROTECTED Variable is read-only.
**/
EFI_STATUS
EFIAPI
VariableServiceSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
);
/**
This code returns information about the EFI variables.
@param Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
for the EFI variables associated with the attributes specified.
@param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
for EFI variables associated with the attributes specified.
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
VariableServiceQueryVariableInfo (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize
);
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
#endif

View File

@ -0,0 +1,433 @@
/** @file
Implement all four UEFI Runtime Variable services for the nonvolatile
and volatile storage space and install variable architecture protocol.
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"
#include "AuthService.h"
extern VARIABLE_STORE_HEADER *mNvVariableCache;
extern VARIABLE_INFO_ENTRY *gVariableInfo;
EFI_HANDLE mHandle = NULL;
EFI_EVENT mVirtualAddressChangeEvent = NULL;
EFI_EVENT mFtwRegistration = NULL;
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
AtRuntime (
VOID
)
{
return EfiAtRuntime ();
}
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
If Priority is not a valid TPL value, then ASSERT().
@param Lock A pointer to the lock data structure to initialize.
@param Priority EFI TPL is associated with the lock.
@return The lock.
**/
EFI_LOCK *
InitializeLock (
IN OUT EFI_LOCK *Lock,
IN EFI_TPL Priority
)
{
return EfiInitializeLock (Lock, Priority);
}
/**
Acquires lock only at boot time. Simply returns at runtime.
This is a temperary function that will be removed when
EfiAcquireLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiAcquireLock() at boot time, and simply returns
at runtime.
@param Lock A pointer to the lock to acquire.
**/
VOID
AcquireLockOnlyAtBootTime (
IN EFI_LOCK *Lock
)
{
if (!AtRuntime ()) {
EfiAcquireLock (Lock);
}
}
/**
Releases lock only at boot time. Simply returns at runtime.
This is a temperary function which will be removed when
EfiReleaseLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiReleaseLock() at boot time and simply returns
at runtime.
@param Lock A pointer to the lock to release.
**/
VOID
ReleaseLockOnlyAtBootTime (
IN EFI_LOCK *Lock
)
{
if (!AtRuntime ()) {
EfiReleaseLock (Lock);
}
}
/**
Retrive the Fault Tolerent Write protocol interface.
@param[out] FtwProtocol The interface of Ftw protocol
@retval EFI_SUCCESS The FTW protocol instance was found and returned in FtwProtocol.
@retval EFI_NOT_FOUND The FTW protocol instance was not found.
@retval EFI_INVALID_PARAMETER SarProtocol is NULL.
**/
EFI_STATUS
GetFtwProtocol (
OUT VOID **FtwProtocol
)
{
EFI_STATUS Status;
//
// Locate Fault Tolerent Write protocol
//
Status = gBS->LocateProtocol (
&gEfiFaultTolerantWriteProtocolGuid,
NULL,
FtwProtocol
);
return Status;
}
/**
Retrive the FVB protocol interface by HANDLE.
@param[in] FvBlockHandle The handle of FVB protocol that provides services for
reading, writing, and erasing the target block.
@param[out] FvBlock The interface of FVB protocol
@retval EFI_SUCCESS The interface information for the specified protocol was returned.
@retval EFI_UNSUPPORTED The device does not support the FVB protocol.
@retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
**/
EFI_STATUS
GetFvbByHandle (
IN EFI_HANDLE FvBlockHandle,
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
)
{
//
// To get the FVB protocol interface on the handle
//
return gBS->HandleProtocol (
FvBlockHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
(VOID **) FvBlock
);
}
/**
Function returns an array of handles that support the FVB protocol
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
array of handles that support FVB protocol.
@retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
handles in Buffer was returned in NumberHandles.
@retval EFI_NOT_FOUND No FVB handle was found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
@retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
**/
EFI_STATUS
GetFvbCountAndBuffer (
OUT UINTN *NumberHandles,
OUT EFI_HANDLE **Buffer
)
{
EFI_STATUS Status;
//
// Locate all handles of Fvb protocol
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolumeBlockProtocolGuid,
NULL,
NumberHandles,
Buffer
);
return Status;
}
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
VariableClassAddressChangeEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mHashCtx);
EfiConvertPointer (0x0, (VOID **) &mStorageArea);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
}
/**
Notification function of EVT_GROUP_READY_TO_BOOT event group.
This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
When the Boot Manager is about to load and execute a boot option, it reclaims variable
storage if free size is below the threshold.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
OnReadyToBoot (
EFI_EVENT Event,
VOID *Context
)
{
ReclaimForOS ();
if (FeaturePcdGet (PcdVariableCollectStatistics)) {
gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);
}
}
/**
Fault Tolerant Write protocol notification event handler.
Non-Volatile variable write may needs FTW protocol to reclaim when
writting variable.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
FtwNotificationEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINT64 Length;
EFI_PHYSICAL_ADDRESS VariableStoreBase;
UINT64 VariableStoreLength;
//
// Ensure FTW protocol is installed.
//
Status = GetFtwProtocol ((VOID**) &FtwProtocol);
if (EFI_ERROR (Status)) {
return ;
}
//
// Find the proper FVB protocol for variable.
//
NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
if (NvStorageVariableBase == 0) {
NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
}
Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
if (EFI_ERROR (Status)) {
return ;
}
mVariableModuleGlobal->FvbInstance = FvbProtocol;
//
// Mark the variable storage region of the FLASH as RUNTIME.
//
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size;
BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);
Length = VariableStoreLength + (VariableStoreBase - BaseAddress);
Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
} else {
Status = gDS->SetMemorySpaceAttributes (
BaseAddress,
Length,
GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
}
}
Status = VariableWriteServiceInitialize ();
ASSERT_EFI_ERROR (Status);
//
// Install the Variable Write Architectural protocol.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableWriteArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
//
gBS->CloseEvent (Event);
}
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
Status = VariableCommonInitialize ();
ASSERT_EFI_ERROR (Status);
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
//
// Now install the Variable Runtime Architectural protocol on a new handle.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Register FtwNotificationEvent () notify function.
//
EfiCreateProtocolNotifyEvent (
&gEfiFaultTolerantWriteProtocolGuid,
TPL_CALLBACK,
FtwNotificationEvent,
(VOID *)SystemTable,
&mFtwRegistration
);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VariableClassAddressChangeEvent,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&mVirtualAddressChangeEvent
);
ASSERT_EFI_ERROR (Status);
//
// Register the event handling function to reclaim variable for OS usage.
//
Status = EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
OnReadyToBoot,
NULL,
&ReadyToBootEvent
);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,98 @@
## @file
# Component description file for Authenticated Variable 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = VariableRuntimeDxe
FILE_GUID = 2226F30F-3D5B-402d-9936-A97184EB4516
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = VariableServiceInitialize
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
# VIRTUAL_ADDRESS_MAP_CALLBACK = VariableClassAddressChangeEvent
#
[Sources]
Reclaim.c
Variable.c
VariableDxe.c
Variable.h
AuthService.c
AuthService.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
SynchronizationLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
UefiRuntimeLib
DxeServicesTableLib
UefiDriverEntryPoint
PcdLib
BaseCryptLib
PlatformSecureLib
[Protocols]
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
[Guids]
gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration Table Guid
gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
gEfiCertRsa2048Sha256Guid
gEfiImageSecurityDatabaseGuid
gEfiCertX509Guid
gEfiCertPkcs7Guid
gEfiCertRsa2048Guid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
[Depex]
gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid
# [Event]
# ##
# # Event will be signaled for VIRTUAL_ADDRESS_CHANGE event.
# #
# EVENT_TYPE_NOTIFY_SIGNAL ## PRODUCES
#
#

View File

@ -0,0 +1,587 @@
/** @file
The sample implementation for SMM variable protocol. And this driver
implements an SMI handler to communicate with the DXE runtime driver
to provide variable services.
Copyright (c) 2010 - 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 <Protocol/SmmVariable.h>
#include <Protocol/SmmFirmwareVolumeBlock.h>
#include <Protocol/SmmFaultTolerantWrite.h>
#include <Library/SmmServicesTableLib.h>
#include <Guid/AuthenticatedVariableFormat.h>
#include <Guid/SmmVariableCommon.h>
#include "Variable.h"
extern VARIABLE_INFO_ENTRY *gVariableInfo;
EFI_HANDLE mSmmVariableHandle = NULL;
EFI_HANDLE mVariableHandle = NULL;
BOOLEAN mAtRuntime = FALSE;
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
VariableServiceGetVariable,
VariableServiceGetNextVariableName,
VariableServiceSetVariable,
VariableServiceQueryVariableInfo
};
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
AtRuntime (
VOID
)
{
return mAtRuntime;
}
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
If Priority is not a valid TPL value, then ASSERT().
@param Lock A pointer to the lock data structure to initialize.
@param Priority EFI TPL is associated with the lock.
@return The lock.
**/
EFI_LOCK *
InitializeLock (
IN OUT EFI_LOCK *Lock,
IN EFI_TPL Priority
)
{
return Lock;
}
/**
Acquires lock only at boot time. Simply returns at runtime.
This is a temperary function that will be removed when
EfiAcquireLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiAcquireLock() at boot time, and simply returns
at runtime.
@param Lock A pointer to the lock to acquire.
**/
VOID
AcquireLockOnlyAtBootTime (
IN EFI_LOCK *Lock
)
{
}
/**
Releases lock only at boot time. Simply returns at runtime.
This is a temperary function which will be removed when
EfiReleaseLock() in UefiLib can handle the call in UEFI
Runtimer driver in RT phase.
It calls EfiReleaseLock() at boot time and simply returns
at runtime.
@param Lock A pointer to the lock to release.
**/
VOID
ReleaseLockOnlyAtBootTime (
IN EFI_LOCK *Lock
)
{
}
/**
Retrive the SMM Fault Tolerent Write protocol interface.
@param[out] FtwProtocol The interface of SMM Ftw protocol
@retval EFI_SUCCESS The SMM FTW protocol instance was found and returned in FtwProtocol.
@retval EFI_NOT_FOUND The SMM FTW protocol instance was not found.
@retval EFI_INVALID_PARAMETER SarProtocol is NULL.
**/
EFI_STATUS
GetFtwProtocol (
OUT VOID **FtwProtocol
)
{
EFI_STATUS Status;
//
// Locate Smm Fault Tolerent Write protocol
//
Status = gSmst->SmmLocateProtocol (
&gEfiSmmFaultTolerantWriteProtocolGuid,
NULL,
FtwProtocol
);
return Status;
}
/**
Retrive the SMM FVB protocol interface by HANDLE.
@param[in] FvBlockHandle The handle of SMM FVB protocol that provides services for
reading, writing, and erasing the target block.
@param[out] FvBlock The interface of SMM FVB protocol
@retval EFI_SUCCESS The interface information for the specified protocol was returned.
@retval EFI_UNSUPPORTED The device does not support the SMM FVB protocol.
@retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
**/
EFI_STATUS
GetFvbByHandle (
IN EFI_HANDLE FvBlockHandle,
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
)
{
//
// To get the SMM FVB protocol interface on the handle
//
return gSmst->SmmHandleProtocol (
FvBlockHandle,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
(VOID **) FvBlock
);
}
/**
Function returns an array of handles that support the SMM FVB protocol
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
array of handles that support SMM FVB protocol.
@retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
handles in Buffer was returned in NumberHandles.
@retval EFI_NOT_FOUND No SMM FVB handle was found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
@retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
**/
EFI_STATUS
GetFvbCountAndBuffer (
OUT UINTN *NumberHandles,
OUT EFI_HANDLE **Buffer
)
{
EFI_STATUS Status;
UINTN BufferSize;
if ((NumberHandles == NULL) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
BufferSize = 0;
*NumberHandles = 0;
*Buffer = NULL;
Status = gSmst->SmmLocateHandle (
ByProtocol,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
NULL,
&BufferSize,
*Buffer
);
if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) {
return EFI_NOT_FOUND;
}
*Buffer = AllocatePool (BufferSize);
if (*Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = gSmst->SmmLocateHandle (
ByProtocol,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
NULL,
&BufferSize,
*Buffer
);
*NumberHandles = BufferSize / sizeof(EFI_HANDLE);
if (EFI_ERROR(Status)) {
*NumberHandles = 0;
}
return Status;
}
/**
Get the variable statistics information from the information buffer pointed by gVariableInfo.
@param[in, out] InfoEntry A pointer to the buffer of variable information entry.
On input, point to the variable information returned last time. if
InfoEntry->VendorGuid is zero, return the first information.
On output, point to the next variable information.
@param[in, out] InfoSize On input, the size of the variable information buffer.
On output, the returned variable information size.
@retval EFI_SUCCESS The variable information is found and returned successfully.
@retval EFI_UNSUPPORTED No variable inoformation exists in variable driver. The
PcdVariableCollectStatistics should be set TRUE to support it.
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the next variable information.
**/
EFI_STATUS
SmmVariableGetStatistics (
IN OUT VARIABLE_INFO_ENTRY *InfoEntry,
IN OUT UINTN *InfoSize
)
{
VARIABLE_INFO_ENTRY *VariableInfo;
UINTN NameLength;
UINTN StatisticsInfoSize;
CHAR16 *InfoName;
ASSERT (InfoEntry != NULL);
VariableInfo = gVariableInfo;
if (VariableInfo == NULL) {
return EFI_UNSUPPORTED;
}
StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + StrSize (VariableInfo->Name);
if (*InfoSize < sizeof (VARIABLE_INFO_ENTRY)) {
*InfoSize = StatisticsInfoSize;
return EFI_BUFFER_TOO_SMALL;
}
InfoName = (CHAR16 *)(InfoEntry + 1);
if (CompareGuid (&InfoEntry->VendorGuid, &mZeroGuid)) {
//
// Return the first variable info
//
CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY));
CopyMem (InfoName, VariableInfo->Name, StrSize (VariableInfo->Name));
*InfoSize = StatisticsInfoSize;
return EFI_SUCCESS;
}
//
// Get the next variable info
//
while (VariableInfo != NULL) {
if (CompareGuid (&VariableInfo->VendorGuid, &InfoEntry->VendorGuid)) {
NameLength = StrSize (VariableInfo->Name);
if (NameLength == StrSize (InfoName)) {
if (CompareMem (VariableInfo->Name, InfoName, NameLength) == 0) {
//
// Find the match one
//
VariableInfo = VariableInfo->Next;
break;
}
}
}
VariableInfo = VariableInfo->Next;
};
if (VariableInfo == NULL) {
*InfoSize = 0;
return EFI_SUCCESS;
}
//
// Output the new variable info
//
StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + StrSize (VariableInfo->Name);
if (*InfoSize < StatisticsInfoSize) {
*InfoSize = StatisticsInfoSize;
return EFI_BUFFER_TOO_SMALL;
}
CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY));
CopyMem (InfoName, VariableInfo->Name, StrSize (VariableInfo->Name));
*InfoSize = StatisticsInfoSize;
return EFI_SUCCESS;
}
/**
Communication service SMI Handler entry.
This SMI handler provides services for the variable wrapper driver.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@param[in] RegisterContext Points to an optional handler context which was specified when the
handler was registered.
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
be conveyed from a non-SMM environment into an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
@retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
should still be called.
@retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
still be called.
@retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
be called.
@retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
**/
EFI_STATUS
EFIAPI
SmmVariableHandler (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *RegisterContext,
IN OUT VOID *CommBuffer,
IN OUT UINTN *CommBufferSize
)
{
EFI_STATUS Status;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader;
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *GetNextVariableName;
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
VARIABLE_INFO_ENTRY *VariableInfo;
UINTN InfoSize;
ASSERT (CommBuffer != NULL);
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;
switch (SmmVariableFunctionHeader->Function) {
case SMM_VARIABLE_FUNCTION_GET_VARIABLE:
SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;
Status = VariableServiceGetVariable (
SmmVariableHeader->Name,
&SmmVariableHeader->Guid,
&SmmVariableHeader->Attributes,
&SmmVariableHeader->DataSize,
(UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
);
break;
case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:
GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) SmmVariableFunctionHeader->Data;
Status = VariableServiceGetNextVariableName (
&GetNextVariableName->NameSize,
GetNextVariableName->Name,
&GetNextVariableName->Guid
);
break;
case SMM_VARIABLE_FUNCTION_SET_VARIABLE:
SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data;
Status = VariableServiceSetVariable (
SmmVariableHeader->Name,
&SmmVariableHeader->Guid,
SmmVariableHeader->Attributes,
SmmVariableHeader->DataSize,
(UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
);
break;
case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:
QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data;
Status = VariableServiceQueryVariableInfo (
QueryVariableInfo->Attributes,
&QueryVariableInfo->MaximumVariableStorageSize,
&QueryVariableInfo->RemainingVariableStorageSize,
&QueryVariableInfo->MaximumVariableSize
);
break;
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
ReclaimForOS ();
Status = EFI_SUCCESS;
break;
case SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE:
mAtRuntime = TRUE;
Status = EFI_SUCCESS;
break;
case SMM_VARIABLE_FUNCTION_GET_STATISTICS:
VariableInfo = (VARIABLE_INFO_ENTRY *) SmmVariableFunctionHeader->Data;
InfoSize = *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
Status = SmmVariableGetStatistics (VariableInfo, &InfoSize);
*CommBufferSize = InfoSize + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
break;
default:
ASSERT (FALSE);
Status = EFI_UNSUPPORTED;
}
SmmVariableFunctionHeader->ReturnStatus = Status;
return EFI_SUCCESS;
}
/**
SMM Fault Tolerant Write protocol notification event handler.
Non-Volatile variable write may needs FTW protocol to reclaim when
writting variable.
@param Protocol Points to the protocol's unique identifier
@param Interface Points to the interface instance
@param Handle The handle on which the interface was installed
@retval EFI_SUCCESS SmmEventCallback runs successfully
@retval EFI_NOT_FOUND The Fvb protocol for variable is not found.
**/
EFI_STATUS
EFIAPI
SmmFtwNotificationEvent (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
if (mVariableModuleGlobal->FvbInstance != NULL) {
return EFI_SUCCESS;
}
//
// Ensure SMM FTW protocol is installed.
//
Status = GetFtwProtocol ((VOID **)&FtwProtocol);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Find the proper FVB protocol for variable.
//
NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
if (NvStorageVariableBase == 0) {
NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
}
Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
mVariableModuleGlobal->FvbInstance = FvbProtocol;
Status = VariableWriteServiceInitialize ();
ASSERT_EFI_ERROR (Status);
//
// Notify the variable wrapper driver the variable write service is ready
//
Status = gBS->InstallProtocolInterface (
&mSmmVariableHandle,
&gSmmVariableWriteGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
EFI_STATUS
EFIAPI
VariableServiceInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE VariableHandle;
VOID *SmmFtwRegistration;
//
// Variable initialize.
//
Status = VariableCommonInitialize ();
ASSERT_EFI_ERROR (Status);
//
// Install the Smm Variable Protocol on a new handle.
//
VariableHandle = NULL;
Status = gSmst->SmmInstallProtocolInterface (
&VariableHandle,
&gEfiSmmVariableProtocolGuid,
EFI_NATIVE_INTERFACE,
&gSmmVariable
);
ASSERT_EFI_ERROR (Status);
///
/// Register SMM variable SMI handler
///
VariableHandle = NULL;
Status = gSmst->SmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);
ASSERT_EFI_ERROR (Status);
//
// Notify the variable wrapper driver the variable service is ready
//
Status = SystemTable->BootServices->InstallProtocolInterface (
&mVariableHandle,
&gEfiSmmVariableProtocolGuid,
EFI_NATIVE_INTERFACE,
&gSmmVariable
);
ASSERT_EFI_ERROR (Status);
//
// Register FtwNotificationEvent () notify function.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmFaultTolerantWriteProtocolGuid,
SmmFtwNotificationEvent,
&SmmFtwRegistration
);
ASSERT_EFI_ERROR (Status);
SmmFtwNotificationEvent (NULL, NULL, NULL);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,96 @@
## @file
# Component description file for SMM Authenticated Variable module.
#
# This module installs SMM variable protocol into SMM protocol database,
# which can be used by SMM driver, and installs SMM variable protocol
# into BS protocol database, which can be used to notify the SMM Runtime
# Dxe driver that the SMM variable service is ready.
# This module should be used with SMM Runtime DXE module together. The
# SMM Runtime DXE module would install variable arch protocol and variable
# write arch protocol based on SMM variable module.
#
# Copyright (c) 2010 - 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 = VariableSmm
FILE_GUID = D34BDC5E-968A-40f5-A48C-E594F45AE211
MODULE_TYPE = DXE_SMM_DRIVER
VERSION_STRING = 1.0
PI_SPECIFICATION_VERSION = 0x0001000A
ENTRY_POINT = VariableServiceInitialize
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
Reclaim.c
Variable.c
VariableSmm.c
AuthService.c
Variable.h
AuthService.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
CryptoPkg/CryptoPkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
UefiDriverEntryPoint
MemoryAllocationLib
BaseLib
SynchronizationLib
UefiLib
SmmServicesTableLib
BaseMemoryLib
DebugLib
DxeServicesTableLib
BaseCryptLib
PlatformSecureLib
[Protocols]
gEfiSmmFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmVariableProtocolGuid ## ALWAYS_PRODUCES
gEfiSmmFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
[Guids]
gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration Table Guid
gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
gSmmVariableWriteGuid ## PRODUCES ## SMM Variable Write Guid
gEfiCertRsa2048Sha256Guid
gEfiImageSecurityDatabaseGuid
gEfiCertX509Guid
gEfiCertPkcs7Guid
gEfiCertRsa2048Guid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
gEfiSecurityPkgTokenSpaceGuid.PcdMaxAppendVariableSize
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
[Depex]
TRUE

Some files were not shown because too many files have changed in this diff Show More