UEFI SMM Services

The Trusted Services project provides support for UEFI System Management Mode (SMM) services via the SMM Gateway secure partition. The SMM Gateway adopts the API Gateway design pattern, popular in microservices architecture. The pattern decouples clients from backend service providers using an API gateway that presents a domain specific interface to clients while delegating operations to a set of backend microservices. An API gateway will typically use multiple backend services and may perform protocol translation while presenting a single service entry point for clients. The SMM Gateway works in a similar manner - clients access SMM services using standard SMM protocol messages, carried by an RPC mechanism. Service requests are forwarded by the SMM Gateway to backend service providers for operations such as secure persistent storage and signature verification.

SMM Gateway is intended to be used on non-EDK2 platforms as an alternative to the EDK2 StandaloneMM (StMM) component. The current SMM Gateway version only supports the SMM Variable service. Additional SMM service providers may be added to SMM Gateway if required. By deliberately limiting functionality and exploiting backend services, the SMM Gateway SP can be significantly lighter-weight than StMM. This option is intended to be used on more resource constrained devices that tend to use u-boot. There is of course the possibility that other SMM services will need to be supported in the future. In such cases, a judgement should be made as to whether StMM should be used rather than extending the SP.

'-------------------------------------------------------------------------------
' Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
'
' SPDX-License-Identifier: BSD-3-Clause
'
'-------------------------------------------------------------------------------

@startuml

[u-boot efi services] -down- [smm gateway]
[smm gateway] -down- [secure storage service]
[smm gateway] -down- [crypto service]

@enduml

SMM Variable Service

Overview

UEFI Variable support is provided by the smm_variable service provider component. This service provider is structured in the same way as other service providers within the TS project. Features of this component are:

  • Source file location: components/service/uefi/smm_variable

  • Public interface definitions: protocols/service/smm_variable

  • Can be used with any RPC layer - not tied to MM Communicate RPC.

  • Volatile and non-volatile storage is accessed via instances of the common storage_backend interface.

The smm-gateway/opteesp and smm-gateway/sp deployments integrate the smm_variable service provider with the following:

  • An MM Communicate based RPC endpoint.

  • A mock_store instance for volatile variables.

  • A secure_storage_client for non-volatile variables.

  • A crypto client for signature verification.

During SP initialization, the smm-gateway uses pre-configured information to discover a backend secure storage SP for NV storage and a crypto SP to verify signatures needed for UEFI variable authentication. Crypto SP is accessible only if UEFI_AUTH_VAR is enabled.

The following diagram illustrates how the smm_variable service provider is integrated into the smm-gateway.

../_images/smm-gateway-layers.svg

Because the smm_variable service provider is independent of any particular environment, alternative deployments are possible e.g.

  • smm_variable service provider running within a GP TA with storage off-loaded to the GP TEE Internal API.

  • smm_variable service provider running within a secure enclave with its own internal flash storage.

Supported Functions

The smm_variable service provider supports the following functions:

SMM Variable Function

Purpose

Backend service interaction

SMM_VARIABLE_FUNCTION_GET_VARIABLE

Get variable data identified by GUID/name.

Query index and get object from appropriate storage backend.

SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME

Called multiple times to enumerate stored variables.

Find variable in index and return next.

SMM_VARIABLE_FUNCTION_SET_VARIABLE

Adds a new variable or updates an existing one.

Sets object in storage backend and if necessary, updates index
and syncs to storage.

SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO

Returns information about the variable store.

Iterates over stored variables to determine space used.

SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE

Called by OS when boot phase is complete.

Updates view of runtime state held by smm_variable service provider.
State variable used when implementing state dependent access control.

SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET

Set constraints that are checked on the SetVariable operation.
Allows a platform to set check policy.
Variable index holds variable check constraints object for each variable.
This is updated by this function.

SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET

Get the variable check constraints.

Reads the variable check constraints object.

SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE

Returns the maximum variable data size, excluding any
auth header.
Considers size constraints imposed by backend stores and RPC response
payload constraints.

Supported Variable Attributes

The following variable attributes are supported:

SMM Variable Attribute

Support

Comment

EFI_VARIABLE_NON_VOLATILE

yes

Determines which storage backend is used.

EFI_VARIABLE_BOOTSERVICE_ACCESS

yes

Boot service access controlled by smm_variable service provider.

EFI_VARIABLE_RUNTIME_ACCESS

yes

Runtime access controlled by smm_variable service provider.

EFI_VARIABLE_HARDWARE_ERROR_RECORD

no

If the attribute contains this value, VariableName and VendorGuid must comply with the rules stated in Section 8.2.4.2 and Appendix P of the standard.

EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS

no

DEPRECATED

EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS

no

Authentication with EFI_VARIABLE_AUTHENTICATION_3 descriptor is enabled.

EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS

yes

Authentication with EFI_VARIABLE_AUTHENTICATION_2 descriptor is enabled.

EFI_VARIABLE_APPEND_WRITE

yes

Implemented by overwriting entire variable data.

Limitations

Description

Value

Maximum size of a single variable

4096 bytes

Supported type of signature list element

DER-encoded X.509 certificates

Supported type of public keys

DER-encoded SignedData structure per PKCS#7 version 1.5, with or without a DER-encoded ContentInfo structure per PKCS#7 version 1.5.

Variable authentication

UEFI variable authentication is a method to ensure that a UEFI variable can only be modified by those who has proper rights. This restricts only the writing of these variables, while reading is only limited by the state of the system (boot versus runtime access).

Key Store Variables

Key Store variables store authentication keys, and have predefined special names to specify the keys scope (area of effect). When a write access to a variable with an active EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is being made, the signature part of the write access will be verified against the appropriate key Store variable. Access will only be granted if the signature is valid.

The following table lists which Key Store variables defined by the UEFI standard are implemented.

Variable name

Description

Supported

Platform Key (PK)

Root of trust. If it is not set the authentication is disabled, all write requests are successful.

yes

Key Exchange Key Database (KEK)

Protects key store databases from unauthorized modifications.

yes

Signature Database (db)

If a variable write request is signed by the public key whose private pair is stored here the authentication will pass.

yes

Blacklist Signature Database (dbx)

Contains signatures of software that must not run on the platform.

no

Authorized Recovery Signature Database (dbr)

Contains signatures of software that can be run for recovery.

no

Timestamp Signature Database (dbt)

Same as db, but the timestamp of the certificate is also verified.

no

There is no support for initializing the values of the read-only global variables containing default values of the key store variables (e.g. PKDefault, KEKDefault, etc.).

The following diagram shows variable authentication hierarchy.

A → B means A has the right to verify write request to B

@startuml
[PK]  --> [PK]
[PK]  --> [KEK]
[PK]  --> [db]
[KEK] --> [db]
[db]  --> [Common Variable]
@enduml

Authenticated Variable Lifecycle

Variable structure

../_images/uefi-variable-structure.svg

  • The elements of the signature verification are stored in or calculated from the fields of the variables:
    1. Hash: Calculated on Name, GUID, Attributes, Timestamp, Payload fields of the write request

    2. Public Key: Extracted from the ‘Sign. Data’ element of the Signature List field in the Payload of the variable responsible for authenticating the request (e.g. in case of KEK request, it will be extracted from PK)

    3. Signature: Extracted from the ‘CertData’ field of the write request.

SMM Variable Tests

The following test components exist for the SMM Variable service:

Test Component

Description

Included in deployments

component/service/uefi/smm_variable/backend/test

Component tests for the variable_index and variable_store backend
components. Can be run in a native PC environment.

deployments/component-test/*

component/service/uefi/smm_variable/test/service

End-to-end service level tests that call service operations from
the perspective of a client.  Can be run in a native PC environment
or on the Arm target platform.
deployments/ts-service-test/*
deployments/uefi-test/*

SMM Gateway Build Configuration

The smm-gateway SP image may be built using the default configuration parameters defined within relevant source files. In practice, it is likely that at least some configuration values will need to be overridden. The following table lists build-time configuration parameters that may be overridden by global C pre-processor defines.

Config define

Usage

File

Default value

SMM_GATEWAY_MAX_UEFI_VARIABLES

Maximum number of variables

deployments/smm-gateway/common/smm_gateway.c

40

UEFI_MAX_VARIABLE_SIZE

Maximum size of the uefi variables in bytes

components/service/uefi/smm_variable/backend/uefi_variable_store.c

4096

SMM_GATEWAY_NV_STORE_SN

The service ID for the backend NV variable store

deployments/smm-gateway/common/smm_gateway.c

Protected Storage SP

SMM_GATEWAY_CRYPTO_SN

The service ID for the crypto backend

deployments/smm-gateway/common/smm_gateway.c

Crypto SP

UEFI_AUTH_VAR

Enables or disables UEFI variable authentication

components/service/uefi/smm_variable/backend/uefi_variable_store.c

OFF

MM Communicate RPC Layer

To maintain compatibility with existing SMM service clients, an MM Communicate based RPC layer has been developed that uses the same ‘carveout’ buffer scheme as StMM. When SMM Gateway is used instead of StMM, existing SMM variable clients should interoperate seamlessly. The MM Communicate RPC components implement the standard TS RPC interfaces and can be used as a general purpose RPC for calls from normal world to secure world. The following MM Communicate RPC components have been added:

  • components/rpc/mm_communicate/endpoint/sp - an RPC endpoint that handles FFA direct calls with MM Communicate and SMM message carried in a shared ‘carveout’ buffer. Call requests are demultiplexed to the appropriate service interface based on the service GUID carried in the MM Communicate header.  Suitable for use in SP deployments.

  • components/rpc/mm_communicate/caller/linux - an RPC caller that calls service operations associated with the destination service interface from Linux user-space. Uses the MM Communicate protocol, sent over FFA using the Debug FFA kernel driver.  Service level tests that run against the SMM Gateway use this RPC caller for invoking SMM service operations.

The following register mapping is assumed for FFA based direct calls to an SP that handles the MM Communicate RPC protocol:

Registers

FF-A layer

MM_COMMUNICATE Request

MM_COMMUNICATE Response

W0

Function ID

FFA_MSG_SEND_DIRECT_REQ
(0x8400006F/0xC400006F)
FFA_MSG_SEND_DIRECT_RESP
(0x84000070/0xC4000070)

W1

Source/Destination ID

Source/Destination ID

Source/Destination ID

W2/X2

Reserved

0x00000000

0x00000000

W3/X3

Parameter[0]

Data offset in the MM communication buffer

SUCCESS/[MM communicate error code]

W4/X4

Parameter[1]

0x00000000

0x00000000

W5/X5

Parameter[2]

0x00000000

0x00000000

W6/X6

Parameter[3]

0x00000000

0x00000000

W7/X7

Parameter[4]

0x00000000

0x00000000


Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.

SPDX-License-Identifier: BSD-3-Clause