Trusted Execution Environment EFI Protocol

Licensing: Microsoft agrees to grant to you a no charge, royalty-free license to its Necessary Claims on reasonable and non-discriminatory terms solely to make, use, sell, offer for sale, import, or distribute any implementation of this specification. "Necessary Claims" are those claims of Microsoft-owned or Microsoft-controlled patents that are technically necessary to implement the required portions (which also include the required elements of optional portions) of this specification, where the functionality causing the infringement is described in detail and not merely referenced in this Specification.

1.0 Introduction

This document specifies an EFI protocol for interacting with a Trusted Execution Environment (TrEE), implementing TPM 2.0 functionality per a subset of a Trusted Computing Group (TCG) Trusted Platform Module 2.0 Library specification. This document also specifies platform firmware measurement requirements. The EFI protocol defined herein leverages to a large degree [TCG06a] and [TCG06b].

2.0 Data Structures and Acronyms

2.1 Data Structures

As in [TCG06a], all data values SHALL be represented in Little-Endian format. Strings SHALL be represented as an array of ASCII bytes with the left-most character placed in the lowest memory location.

2.2 Acronyms and Conventions

(For acronyms not defined herein, see [TCG06a])

TrEETrusted Execution Environment

Use of the terms "MUST" and "SHALL" in this document are to be interpreted in accordance with [RFC2119].

3.0 EFI TrEE Protocol

This section provides a detailed description of the EFI_TREE_PROTOCOL and the EFI_TREE_SERVICE_BINDING_PROTOCOL. The EFI TrEE Protocol is used to communicate with a TrEE.

3.1 TrEE EFI Service Binding Protocol

This section defines the TrEE EFI service binding protocol.

Summary - The EFI TrEE Service Binding Protocol is used to locate TrEE devices that are supported by an EFI TrEE Protocol driver and to create and destroy EFI TrEE protocol child driver instances that can use the underlying TrEE device.

GUID - #define EFI_TREE_SERVICE_BINDING_PROTOCOL_GUID \ {0x4cf01d0a, 0xc48c, 0x4271, 0xa2, 0x2a, 0xad, 0x8e, 0x55, 0x97,\ 0x81, 0x88}

DescriptionAn application (or driver) that requires TrEE services can use one of the protocol handler services, such as BS->LocateHandleBuffer(), to search for devices that publish an EFI TrEE Service Binding Protocol. Each device with a published the EFI TrEE Service Binding Protocol supports the EFI TrEE Protocol and may be available for use.

After a successful call to the EFI_TREE_SERVICE_BINDING_PROTOCOL.CreateChild() function, the child EFI TrEE Protocol driver instance is ready for use.

Before an EFI application or driver terminates execution, every successful call to the EFI_TREE_SERVICE_BINDING_PROTOCOL.CreateChild() function must be matched with a call to the EFI_TREE_SERVICE_BINDING_PROTOCOL.DestroyChild() function.

3.2 TrEE EFI Protocol

Summary - The EFI TrEE protocol is used to communicate with a TrEE - to send commands to a TrEE, use it for trusted execution operations and to provide access to the firmware log of measurements extended in the TrEE. The protocol maintains an Event Log of measurements recorded in the TrEE with a format identical to the TCG 1.2 TCG Event Log (see [TCG06b]); referred to as the TrEE Event Log Format TCG 1.2 Event Log in this specification. Implementers may create additional Event Logs with other formats, but this version of the protocol does not define a way to retrieve them.

GUID - #define EFI_TREE_PROTOCOL_GUID \ {0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2,\ 0x72, 0x0f}

Protocol Interface Structure -

typedef struct _EFI_TREE_PROTOCOL {
  EFI_TREE_GET_CAPABILITYGetCapability;
  EFI_TREE_GET_EVENT_LOGGetEventLog;
  EFI_TREE_HASH_LOG_EXTEND_EVENTHashLogExtendEvent;
  EFI_TREE_SUBMIT_COMMANDSubmitCommand;
} EFI_TREE_PROTOCOL;

Parameters

GetCapability

This service provides information about the TrEE and firmware capabilities

GetEventLog

Get a pointer to a firmware event log

HashLogExtendEvent

This service will cause the EFI TrEE driver to extend an event and (optionally) write the event to the TrEE log.

SubmitCommand

This service submits a command directly to the TrEE.

Description - The EFI_TREE_PROTOCOL abstracts TrEE activity. This protocol instance provides a Boot Service and is instantiated as a Boot Service Driver.

Boot Service Drivers are terminated when ExitBootServices ( ) is called and all memory resources consumed by the Boot Services Drivers are released for use in the operating system environment.

This Boot Service must create an EVT_SIGNAL_EXIT_BOOT_SERVICES event. This event will be notified by the system when ExitBootServices ( ) is invoked.

EVT_SIGNAL_EXIT_BOOT_SERVICES is a synchronous event used to ensure that certain activities occur following a call to a specific interface function; in this case, that is the cleanup that needs to be done in response to the ExitBootServices ( ) function. ExitBootServices ( ) cannot clean up on behalf of drivers that have been loaded into the system. The drivers have to do that for themselves by creating an event whose type is EVT_SIGNAL_EXIT_BOOT_SERVICES and whose notification function is a function within the driver itself. Then, when ExitBootServices ( ) has finished its cleanup, it signals the event type EVT_SIGNAL_EXIT_BOOT_SERVICES.

For implementation details about how a Boot Service instantiated as an EFI Driver creates this required EVT_SIGNAL_EXIT_BOOT_SERVICES event, see Section 6.1 of [UEFI12].

3.3 EFI_TREE_PROTOCOL.GetCapability

The EFI_TREE_PROTOCOL GetCapability function call provides protocol capability information and state information about the TrEE.

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_GET_CAPABILITY) (
  IN EFI_TREE_PROTOCOL      *This,
  IN OUT TREE_BOOT_SERVICE_CAPABILITY*ProtocolCapability,
);

Parameters

This

Indicates the calling context.

ProtocolCapability

The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY structure and sets the size field to the size of the structure allocated. The callee fills in the fields with the EFI protocol capability information and the current TrEE state information up to the number of fields which fit within the size of the structure passed in.

Related Definitions

typedef struct _TREE_VERSION { 
  UINT8 Major; 
  UINT8 Minor; 
} TREE_VERSION;
typedef UINT64 EFI_PHYSICAL_ADDRESS;
typedef UINT32 TREE_EVENT_LOG_BITMAP;
typedef UINT32 TREE_EVENT_LOG_FORMAT;
#define TREE_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
typedef struct _TREE_BOOT_SERVICE_CAPABILITY { 
  UINT8 Size;
  TREE_VERSION StructureVersion; 
  TREE_VERSION ProtocolVersion;
  UINT32 HashAlgorithmBitmap;
  TREE_EVENT_LOG_BITMAPSupportedEventLogs;
  BOOLEAN TrEEPresentFlag;
  UINT16MaxCommandSize;
  UINT16MaxResponseSize;
  UINT32ManufacturerID;  
} TREE_BOOT_SERVICE_CAPABILITY;

#define TREE_BOOT_HASH_ALG_SHA1       0x00000001
#define TREE_BOOT_HASH_ALG_SHA256     0x00000002
#define TREE_BOOT_HASH_ALG_SHA384     0x00000004
#define TREE_BOOT_HASH_ALG_SHA512     0x00000008

Size

Allocated size of the structure passed in

StructureVersion

Version of the TREE_BOOT_SERVICE_CAPABILITY structure itself. For this version of the protocol, the Major version shall be set to 1 and the Minor version shall be set to 0.

ProtocolVersion

Version of the TrEE protocol. For this version of the protocol, the Major version shall be set to 1 and the Minor version shall be set to 0.

HashAlgorithmBitMap

Supported hash algorithms

SupportedEventLogs

Bitmap of supported event log formats (see above)

TrEEPresentFlag

False = TrEE not present

MaxCommandSize

Max size (in bytes) of a command that can be sent to the TrEE

MaxResponseSize

Max size (in bytes) of a response that can be provided by the TrEE

ManufacturerID

4-byte Vendor ID (see [TCG07], "TPM Capabilities Vendor ID" section)

Description

The EFI_TREE_PROTOCOL Get Capability function call provides EFI protocol version and capability information as well as state information about the TrEE. The caller must set the Size field of the TREE_BOOT_SERVICE_CAPABILITY structure allocated. It is expected future versions of this function call may add additional fields to the structure. The Size value passed in will enable the function to only populate fields the caller allocated memory for. For example:

ProtocolCapability.Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY);

For this version of the specification:

  1. If the This or the ProtocolCapability parameters are NULL, the functional call will return EFI_INVALID_PARAMETER.

  2. If the input ProtocolCapability.Size < sizeof(TREE_BOOT_SERVICE_CAPABILITY) the function will set ProtocolCapability.Size equal to sizeof(TREE_BOOT_SERVICE_CAPABILITY) as defined in this specification and will return the error code EFI_BUFFER_TOO_SMALL, the values of the remaining fields will be undefined.

  3. The following return values MUST be set:

    ProtocolCapability.StructureVersion.Major = 1

    ProtocolCapability.StructureVersion.Minor = 0

    ProtocolCapability.ProtocolVersion.Major = 1

    ProtocolCapability.ProtocolVersion.Minor = 0

  4. If the platform does not have a TrEE then the following values MUST be returned:

    ProtocolCapability.SupportedEventLogs = 0

    ProtocolCapability.HashAlgorithmBitmap = 0

    ProtocolCapability.TrEEPresentFlag = FALSE

    ProtocolCapability.MaxCommandSize = 0

    ProtocolCapability.MaxResponseSize = 0

    ProtocolCapability.ManufacturerID = 0

  5. The minimum MaxCommandSize and MaxResponseSize MUST be 0x500 (or greater) for Windows.

Status Codes Returned

EFI_SUCCESS

Operation completed successfully.

EFI_DEVICE_ERROR

The command was unsuccessful. The ProtocolCapability variable will not be populated.

EFI_INVALID_PARAMETER

One or more of the parameters are incorrect. The ProtocolCapability variable will not be populated.

EFI_BUFFER_TOO_SMALL

The ProtocolCapability variable is too small to hold the full response. It will be partially populated (required Size field will be set).

3.4 EFI_TREE_PROTOCOL.GetEventLog

The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to retrieve the address of a given event log and its last entry.

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_GET_EVENT_LOG) (
  IN  EFI_TREE_PROTOCOL      *This,
  IN  TREE_EVENT_LOG_FORMATEventLogFormat,
  OUT EFI_PHYSICAL_ADDRESS*EventLogLocation,
  OUT EFI_PHYSICAL_ADDRESS*EventLogLastEntry,
  OUT BOOLEAN*EventLogTruncated
);

Parameters

EventLogFormat

The type of the event log for which the information is requested.

EventLogLocation

A pointer to the memory address of the event log.

EventLogLastEntry

If the Event Log contains more than one entry, this is a pointer to the address of the start of the last entry in the event log in memory. For information about what values are returned in this parameter in the special cases of an empty Event Log or an Event Log with only one entry, see the Description section below.

EventLogTruncated

If the Event Log is missing at least one entry because an event would have exceeded the area allocated for events, this value is set to TRUE. Otherwise, the value will be FALSE and the Event Log will be complete.

Description

The firmware manages an Event Log of the measurements recorded in the TrEE during the boot process. During the boot process, before UEFI platform initialization, an entry is made in the Event Log for each measurement extended in the TrEE. In the UEFI environment, each time a call is made to HashLogExtendEvent to extend a measurement in the TrEE, an event is generally recorded in the Event Log containing the extended measurement. If the area allocated by firmware for the Event Log was too small to hold all events added, the function call indicates the Event Log was truncated and has missing entries. This version of the specification only requires an Event Log of SHA1 measurements to be maintained. Future versions of this specification may maintain additional Event Logs supporting different hash algorithms.

The Event Log area returned by this function is released when ExitBootServices ( ) is called. Callers of this method MUST not access the area after ExitBootServices ( ) has been called.For this version of the specification:

  1. If EventLogFormat does not equal TREE_EVENT_LOG_FORMAT_TCG_1_2, the function call MUST return EFI_INVALID_PARAMETER.

  2. If no TrEE is present the function MUST set the following values and return EFI_SUCCESS:

    1. EventLogLocation = NULL

    2. EventLogLastEntry = NULL

    3. EventLogTruncated = FALSE

  3. The EventLogLocation value MUST be set to the start of the specified event log format in memory

  4. If the specified event log:

    1. does not contain any events then EventLogLastEntry MUST be set to 0

    2. contains exactly one entry then EventLogLastEntry MUST be set to the same value as EventLogLocation

    3. contains more than one event then EventLogLastEntry MUST be set to the start address of the last event of the specified Event Log

  5. If a prior call to EFI_TREE_PROTOCOL.HashLogExtendEvent returned EFI_VOLUME_FULL then EventLogTruncated MUST be set to TRUE, otherwise it MUST be set to FALSE.

Status Codes Returned

EFI_SUCCESS

Operation completed successfully.

EFI_INVALID_PARAMETER

One or more of the parameters are incorrect (e.g. asking for an event log whose format is not supported).

3.5 EFI_TREE_PROTOCOL.HashLogExtendEvent

The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with an opportunity to extend and optionally log events without requiring knowledge of actual TPM commands.The extend operation will occur even if this function cannot create an event log entry (e.g. due to the event log being full).

Prototype

typedef
EFI_STATUS
(EFIAPI * EFI_TREE_HASH_LOG_EXTEND_EVENT) (
  IN EFI_TREE_PROTOCOL*This,
  IN UINT64Flags,
  IN EFI_PHYSICAL_ADDRESSDataToHash,
  IN UINT64DataToHashLen,
  IN TrEE_EVENT*Event,
);

Parameters

This

Indicates the calling context.

Flags

Bitmap providing additional information (see below).

DataToHash

Physical address of the start of the data buffer to be

hashed.

DataToHashLen

The length in bytes of the buffer referenced by DataToHash.

Event

Pointer to data buffer containing information about the event.

Related Definitions

#pragma pack(1)
typedef struct _TrEE_EVENT {
  UINT32Size;            
  TrEE_EVENT_HEADERHeader;
  UINT8Event[ANYSIZE_ARRAY];
} TrEE_EVENT;
typedef struct _TrEE_EVENT_HEADER {
  UINT32HeaderSize;
  UINT16HeaderVersion;
  TrEE_PCRINDEXPCRIndex;
  TrEE_EVENTTYPEEventType;
} TrEE_EVENT_HEADER;
#pragma pack()
typedef UINT32 TrEE_PCRINDEX;
typedef UINT32 TrEE_EVENTTYPE;

Size

Total size of the event including the Size component, the header and the Event data.

HeaderSize

Size of the event header itself (sizeof(TrEE_EVENT_HEADER)).

HeaderVersion

Header version. For this version of this specification, the value shall be 1.

PCRIndex

Index of the PCR that shall be extended (0 - 23).

EventType

Type of the event that shall be extended (and optionally logged).

Flag Values

The Flags variable is a bitmap providing additional data as follows:

#define TREE_EXTEND_ONLY 0x0000000000000001

This bit is shall be set when an event shall be extended but not logged.

#define PE_COFF_IMAGE 0x0000000000000010

This bit shall be set when the intent is to measure a PE/COFF image.

Description

The EFI_TREE_PROTOCOL Hash Log Extend Event function call calculates the measurement of a data buffer (possibly containing a PE/COFF binary image) and causes the TrEE driver to extend the measurement. In addition, the service optionally creates an event log entry and appends it to the Event Log for each event log format supported by the service. The service allows a caller to make use of the TrEE without knowing anything about specific TrEE commands.

The use of this function to measure PE/COFF images must be done before relocations have been applied to the image. Note: Use caution using this method to measure PE/COFF images. Generally implementations that load PE/COFF images strip important data during the load process from the image and may change the image section alignment in memory. The net result is calculating the hash of an in-memory image does not match the actual measurement for the image as properly calculated when it is loaded from storage media.

Upon invocation, the function shall perform the following actions:

  1. If any of the parameters This, DataToHash, or Event are NULL, the function MUST return EFI_INVALID_PARAMETER.

  2. If the Event.Size is less than Event.Header.HeaderSize + sizeof(UINT32), the function MUST return EFI_INVALID_PARAMETER.

  3. If the Event.Header.PCRIndex is not 0 through 23, inclusive, the function MUST return EFI_INVALID_PARAMETER.

  4. If the Flags bitmap has the PE_COFF_IMAGE bit SET but the PE/COFF image is corrupt or not understood the function MUST return EFI_UNSUPPORTED.

  5. The function allows any value for the Event.Header.EventType parameter.

  6. The function MUST calculate the digest (measurement) of the data starting at DataToHash with a length of DataToHashLen. When the PE_COFF_IMAGE bit is set, the function MUST calculate the measurement of the PE/COFF image in accordance with "Measuring a PE/COFF image" in Appendix A below.

  7. The function MUST successfully send the TPM2_PCR_Extend command to the TrEE to extend the PCR indicated by Event.Header.PCRIndex with the measurement digest. If the command cannot be sent successfully, the function must return EFI_DEVICE_ERROR. If the firmware supports more algorithms than SHA1 it may calculate digests using other algorithms and extend them too.

  8. If a previous call to this function returned EFI_VOLUME_FULL and the TREE_EXTEND_ONLY bit is set in the Flags parameter, the function MUST return EFI_VOLUME_FULL. (No attempt is made to add the event log entry to the event log(s).)

  9. The function MUST build a TCG Event Log entry as follows: (Note: The TCG_PCR_EVENT structure is defined in [TCG06b] and shall be considered byte-aligned.)

    1. TCG_PCR_EVENT.PCRIndex = Event.Header.PCRIndex

    2. TCG_PCR_EVENT.EventType = Event.Header.EventType

    3. TCG_PCR_EVENT.Digest = <the SHA1 measurement digest calculated above>

    4. TCG_PCR_EVENT.EventSize = Event.Size - sizeof(UINT32) - Event.Header.HeaderSize

    5. TCG_PCR_EVENT.Event = Event.Event (Note: this is a memory copy of EventSize bytes)

  10. The function MAY build similar event log entries for other supported Event Log formats.

  11. If the TCG_PCR_EVENT Event Log entry created above does not fit in the area allocated for the TrEE Event Log Format TCG 1.2 Event Log, the function MUST return EFI_VOLUME_FULL.

  12. If the firmware supports additional Event Log formats and any of the events created for those event logs would exceed the area allocated for the Event Log, the function MUST return EFI_VOLUME_FULL.

  13. The function MUST append the events created to their corresponding event logs and the service MUST update its internal pointer to the start of the last event for each Event Log.

Status Codes Returned.

EFI_SUCCESS

Operation completed successfully.

EFI_DEVICE_ERROR

The command was unsuccessful.

EFI_VOLUME_FULL

The extend operation occurred, but the event could not be written to one or more event logs.

EFI_INVALID_PARAMETER

One or more of the parameters are incorrect.

EFI_UNSUPPORTED

The PE/COFF image type is not supported.

3.6 EFI_TREE_PROTOCOL.SubmitCommand

This service enables the sending of commands to the TrEE.

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_TREE_SUBMIT_COMMAND) (
  IN EFI_TREE_PROTOCOL*This,
  IN UINT32InputParameterBlockSize,
  IN UINT8*InputParameterBlock,
  IN UINT32OutputParameterBlockSize,
  IN UINT8*OutputParameterBlock 
);

Parameters

This

Indicates the calling context.

InputParameterBlockSize

Size of the TrEE input parameter block.

InputParameterBlock

Pointer to the TrEE input parameter block.

OutputParameterBlockSize

Size of the TrEE output parameter block.

OutputParameterBlock

Pointer to the TrEE output parameter block.

Description

The EFI_TREE_PROTOCOL Submit Command function call provides a pass-through capability from the caller to the system's TrEE.

The caller is responsible for building the command byte-stream to be sent to the TrEE and is also responsible for interpreting the resulting byte-stream returned by the TrEE. The TrEE in and out operands for each TrEE command are defined elsewhere.

Note that the returned status codes reflect the outcome of the function invocation and not the success (or failure) of the underlying TrEE command.

The TPM 2.0 MUST not return TPM2_RC_RETRY prior to the completion of the call to ExitBootServices(). (The reason for this requirement is the return code would block the boot process until the TPM command could be compeleted.)

The TPM 2.0 MUST have access to its persistent storage prior to the call to ExitBootServices completing. If TPM 2.0 implementation MAY not have access to persistent storage after the call to ExitBootServices, please contact Microsoft for additional requirements.

Status Codes Returned

EFI_SUCCESS

The command byte stream was successfully sent to the device and a response was successfully received.

EFI_DEVICE_ERROR

The command was not successfully sent to the device or a response was not successfully received from the device.

EFI_INVALID_PARAMETER

One or more of the parameters are incorrect.

EFI_BUFFER_TOO_SMALL

The output parameter block is too small.

References

[MSFT08]

Microsoft Corporation, "Windows Authenticode Portable Executable Signature Format," Version 1.0, March 21, 2008.

[RFC2119]

Bradner, S., "Keywords for Use in RFCs to Indicate Requirement Levels," IETF RFC 2119, March 1997.

[TCG06a]

Trusted Computing Group, "TCG EFI Protocol," Version 1.20 Revision 1.00, June 9, 2006.

[TCG06b]

Trusted Computing Group, "TCG EFI Platform Specification," Version 1.20 Revision 1.0, June 7, 2006.

[TCG07]

Trusted Computing Group, "TCG Vendor ID Registry," Version 1.0, Revision 0.1, August 31, 2007.

[UEFI12]

UEFI, "Unified Extensible Firmware Interface Specification," Version 2.3.1 Errata C,

June 2012.

Appendix A: Static Root of Trust Measurements

Important

Appendix A implementation of PCR[7] measurements is mandatory for InstantGo systems.

At a high level, firmware is responsible for measuring the following components during boot:

  • Platform firmware that contains or measures the UEFI Boot Services and UEFI Runtime Services

  • Security relevant variables associated with platform firmware

  • UEFI drivers or boot applications loaded separately

  • Variables associated with separately loaded UEFI Drivers or UEFI Boot applications

The above measurements are defined by the TCG EFI Platform specification [TCG06b] Sections 5.1 - 5.5 and are not referred to further herein. Measurements into PCR[1] and PCR[3] are optional depending on platform configuration.

For Windows, PCR[7] is used to reflect the UEFI 2.3.1 Secure Boot policy. This policy relies on the firmware authenticating all boot components launched prior to the UEFI environment and the UEFI platform initialization code (or earlier firmware code) invariantly recording the Secure Boot policy information into PCR[7].

Platform firmware adhering to the policy must therefore measure the following values into PCR[7]:

  1. The contents of the PK variable

  2. The contents of the KEK variable

  3. The contents of the EFI_IMAGE_SECURITY_DATABASE variable

  4. The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable

  5. Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path

  6. The contents of the SecureBoot variable

Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE, EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].

In addition, if the platform provides a firmware debugger which may be launched prior to the UEFI environment, it MUST record this fact in PCR[7]. Likewise, if the platform provides a debugger for the UEFI environment, launch of the debugger MUST be recorded in PCR[7].

Implementation Note

The UEFI LoadImage function MUST record measurements in PCR[2] or PCR[4] per events described in [TCG06b] and also PCR[7] per events described in the section "Measuring UEFI Configuration into PCR[7]" below. To determine whether an image measurement applies to PCR[2] or PCR[4], LoadImage MUST examine the Subsystem field in the PE/COFF image. The values IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER and IMAGE_SUBSYSTEM_EFI_ROM correspond to PCR[2]. The value IMAGE_SUBSYSTEM_EFI_APPLICATION corresponds to PCR[4]. If the loaded image is some other type, it MUST be recorded in PCR[4]. Images that LoadImage fails to load due to (a) signature verification failure or (b) because the image does not comply with currently enforced UEFI 2.3.1 Secure Boot policy do not need to be measured in a PCR.

****Related Definitions

#define EV_EFI_VARIABLE_DRIVER_CONFIG \
                                  0x80000001 /* Defined in [TCG06b] */
#define EV_EFI_ACTION             0x80000007 /* Defined in [TCG06b] */
#define EV_EFI_VARIABLE_AUTHORITY 0x800000E0

This specification requires a modified TCG structure definition for EFI_VARIABLE_DATA.  The revised structure is:
typedef struct {
  EFI_GUIDVariableName;
  UINT64        UnicodeNameLength;    // The TCG Defintion used UINTN
  UINT64        VariableDataLength;   // The TCG Defintion used UINTN
  CHAR16       UnicodeName[1];
  INT8         VariableData[1];   
} EFI_VARIABLE_DATA;

Measuring a PE/COFF Image

When measuring a PE/COFF image, the EventType shall be as defined in [TCG06b] (for example, when measuring an EFI Boot Application, the EventType shall be EV_EFI_BOOT_SERVICES_APPLICATION) and the Event value shall be the value of the EFI_IMAGE_LOAD_EVENT structure defined in [TCG06b].

The HashLogExtendEvent service MUST hash the PE/COFF image in accordance with the procedure specified in "Calculating the PE Image Hash" section of [MSFT08].

Measuring UEFI Configuration into PCR[7]

For all EFI variable value events, the EventType shall be EV_EFI_VARIABLE_DRIVER_CONFIG defined above and the Event value shall be the value of the EFI_VARIABLE_DATA structure defined above in this specification (this structure shall be considered byte-aligned). The measurement digest shall be the SHA-1 hash of the event data which is the EFI_VARIABLE_DATA structure. (Note: This is a different digest than the one specified by [TCG06b].) The EFI_VARIABLE_DATA.UnicodeNameLength value is the number of CHAR16 characters (not the number of bytes). The EFI_VARIABLE_DATA.UnicodeName contents MUST NOT include a null terminator. If reading the EFI variable returns EFI_NOT_FOUND, the EFI_VARIABLE_DATA.VariableDataLength field MUST be set to zero and EFI_VARIABLE_DATA.VariableData field will have a size of zero.

  1. If the platform provides a firmware debugger mode which may be used prior to the UEFI environment or if the platform provides a debugger for the UEFI environment, then the platform SHALL extend an EV_EFI_ACTION event as specified in [TCG06b] into PCR[7] before allowing use of the debugger. The event string shall be "UEFI Debug Mode". Further, the platform MUST create a TCG Event Log entry as follows:

    1. TCG_PCR_EVENT.PCRIndex = 7

    2. TCG_PCR_EVENT.EventType = EV_EFI_ACTION

    3. TCG_PCR_EVENT.Digest = <the SHA-1 digest of the string value "UEFI Debug Mode" without the terminating NULL character>

    4. TCG_PCR_EVENT.EventSize = strlen("UEFI Debug Mode")

    5. TCG_PCR_EVENT.Event = "UEFI Debug Mode"

    The platform MAY build similar event log entries for other supported Event Log formats.

  2. Before executing any code not cryptographically authenticated as being provided by the Platform Manufacturer, the Platform Manufacturer firmware MUST measure the following values in the order listed using the EV_EFI_VARIABLE_DRIVER_CONFIG event type to PCR[7]:

    1. SecureBoot variable value

    2. The PK variable value

    3. The KEK variable value

    4. The EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE variable value

    5. The EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE1 variable value

  3. If the platform supports changing any of the following UEFI policy variables after they are initially measured in PCR[7] and before ExitBootServices ( ) has completed without unconditionally restarting the platform, it MUST measure the variable again immediately upon change. Additionally the normal update process for setting any of the UEFI variables below MUST occur before the initial measurement in PCR[7] or after the call to ExitBootServices() has completed.

    1. SecureBoot variable value

    2. The PK variable value

    3. The KEK variable value

    4. The EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE variable value

    5. The EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE1 variable value

  4. The system SHALL measure the EV_SEPARATOR event in PCR[7]. (This occurs at the same time the separator is measured to PCR[0] through PCR[7].)

  5. Before launching an EFI Driver or an EFI Boot Application (and regardless of whether the launch is due to the EFI Boot Manager picking an image from the DriverOrder or BootOrder UEFI variables or an already launched image calling the UEFI LoadImage() function), the UEFI firmware SHALL measure the entry in the EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE variable that was used to validate the EFI image into PCR[7]. The measurement SHALL occur in conjunction with image load. For this event, the EventType shall be EV_EFI_VARIABLE_AUTHORITY and the Event value shall be the value of the EFI_VARIABLE_DATA structure (the structure is defined above in this specification with a different definition than the TCG specification). The EFI_VARIABLE_DATA.VariableData value shall be the EFI_SIGNATURE_DATA value from the EFI_SIGNATURE_LIST that contained the authority that was used to validate the image and the EFI_VARIABLE_DATA.VariableName shall be set to EFI_IMAGE_SECURITY_DATABASE_GUID. The EFI_VARIABLE_DATA.UnicodeName shall be set to the value of EFI_IMAGE_SECURITY_DATABASE. The value shall not include the terminating NULL character.

  6. Before launching any additional EFI Drivers or EFI Boot Applications, the UEFI firmware SHALL check if the entry in the EFI_IMAGE_SECURITY_DATABASE_GUID/EFI_IMAGE_SECURITY_DATABASE variable which validates the EFI image has previously been measured with the EV_EFI_VARIABLE_AUTHORITY event type in PCR[7]. If it has not been, it MUST be measured as described in the previous step. If it has been measured previously, it MUST NOT be measured again.

Note

A measurement example for PCR[7] measurements is available upon request from Microsoft.