Julian Hall | cac3150 | 2021-12-15 17:35:25 +0000 | [diff] [blame] | 1 | UEFI SMM Services |
| 2 | ================= |
| 3 | The Trusted Services project provides support for UEFI System Management Mode (SMM) services via the |
| 4 | SMM Gateway secure partition. The SMM Gateway adopts the API Gateway design pattern, popular in |
| 5 | microservices architecture. The pattern decouples clients from backend service providers using an |
| 6 | API gateway that presents a domain specific interface to clients while delegating operations to a |
| 7 | set of backend microservices. An API gateway will typically use multiple backend services and may |
| 8 | perform protocol translation while presenting a single service entry point for clients. The SMM |
| 9 | Gateway works in a similar manner - clients access SMM services using standard SMM protocol messages, |
| 10 | carried by an RPC mechanism. Service requests are forwarded by the SMM Gateway to backend service |
| 11 | providers for operations such as secure persistent storage and signature verification. |
| 12 | |
| 13 | SMM Gateway is intended to be used on non-EDK2 platforms as an alternative to the EDK2 StandaloneMM |
| 14 | (StMM) component. The current SMM Gateway version only supports the SMM Variable service. Additional |
| 15 | SMM service providers may be added to SMM Gateway if required. By deliberately limiting functionality |
| 16 | and exploiting backend services, the SMM Gateway SP can be significantly lighter-weight than StMM. |
| 17 | This option is intended to be used on more resource constrained devices that tend to use u-boot. |
| 18 | There is of course the possibility that other SMM services will need to be supported in the future. |
| 19 | In such cases, a judgement should be made as to whether StMM should be used rather than extending the SP. |
| 20 | |
| 21 | .. uml:: uml/SmmGatewayOverview.puml |
| 22 | |
| 23 | SMM Variable Service |
| 24 | -------------------- |
| 25 | Overview |
| 26 | '''''''' |
| 27 | UEFI Variable support is provided by the *smm_variable* service provider component. This service provider |
| 28 | is structured in the same way as other service providers within the TS project. Features of this |
| 29 | component are: |
| 30 | |
| 31 | * Source file location: ``components/service/smm_variable`` |
| 32 | * Public interface definitions: ``protocols/service/smm_variable`` |
| 33 | * Can be used with any RPC layer - not tied to MM Communicate RPC. |
| 34 | * Volatile and non-volatile storage is accessed via instances of the common *storage_backend* interface. |
| 35 | |
| 36 | The *smm-gateway/opteesp* deployment integrates the *smm_variable* service provider with the following: |
| 37 | |
| 38 | * An MM Communicate based RPC endpoint. |
| 39 | * A *mock_store* instance for volatile variables. |
| 40 | * A *secure_storage_client* for non-volatile variables. |
| 41 | |
| 42 | During SP initialization, the *smm-gateway* uses pre-configured information to discover a backend secure |
| 43 | storage SP for NV storage. |
| 44 | |
| 45 | The following diagram illustrates how the *smm_variable* service provider is integrated into the *smm-gateway*. |
| 46 | |
| 47 | .. image:: image/smm-gateway-layers.svg |
| 48 | |
| 49 | Because the *smm_variable* service provider is independent of any particular environment, alternative deployments |
| 50 | are possible e.g. |
| 51 | |
| 52 | * *smm_variable* service provider running within a GP TA with storage off-loaded to the GP TEE Internal API. |
| 53 | * *smm_variable* service provider running within a secure enclave with its own internal flash storage. |
| 54 | |
| 55 | Supported Functions |
| 56 | ''''''''''''''''''' |
| 57 | The *smm_variable* service provider supports the following functions: |
| 58 | |
| 59 | .. list-table:: |
| 60 | :header-rows: 1 |
| 61 | |
| 62 | * - SMM Variable Function |
| 63 | - Purpose |
| 64 | - Backend service interaction |
| 65 | * - SMM_VARIABLE_FUNCTION_GET_VARIABLE |
| 66 | - Get variable data identified by GUID/name. |
| 67 | - Query index and get object from appropriate storage backend. |
| 68 | * - SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME |
| 69 | - Called multiple times to enumerate stored variables. |
| 70 | - Find variable in index and return next. |
| 71 | * - SMM_VARIABLE_FUNCTION_SET_VARIABLE |
| 72 | - Adds a new variable or updates an existing one. |
| 73 | - | Sets object in storage backend and if necessary, updates index |
| 74 | | and syncs to storage. |
| 75 | * - SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO |
| 76 | - Returns information about the variable store. |
| 77 | - Iterates over stored variables to determine space used. |
| 78 | * - SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE |
| 79 | - Called by OS when boot phase is complete. |
| 80 | - | Updates view of runtime state held by smm_variable service provider. |
| 81 | | State variable used when implementing state dependent access control. |
| 82 | * - SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET |
| 83 | - | Set constraints that are checked on the SetVariable operation. |
| 84 | | Allows a platform to set check policy. |
| 85 | - | Variable index holds variable check constraints object for each variable. |
| 86 | | This is updated by this function. |
| 87 | * - SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET |
| 88 | - Get the variable check constraints. |
| 89 | - Reads the variable check constraints object. |
| 90 | * - SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE |
| 91 | - | Returns the maximum variable data size, excluding any |
| 92 | | auth header. |
| 93 | - | Considers size constraints imposed by backend stores and RPC response |
| 94 | | payload constraints. |
| 95 | |
| 96 | Supported Variable Attributes |
| 97 | ''''''''''''''''''''''''''''' |
| 98 | The following variable attributes are supported: |
| 99 | |
| 100 | .. list-table:: |
| 101 | :widths: 3 1 3 |
| 102 | :header-rows: 1 |
| 103 | |
| 104 | * - SMM Variable Attribute |
| 105 | - Support |
| 106 | - Comment |
| 107 | * - EFI_VARIABLE_NON_VOLATILE |
| 108 | - yes |
| 109 | - Determines which storage backend is used. |
| 110 | * - EFI_VARIABLE_BOOTSERVICE_ACCESS |
| 111 | - yes |
| 112 | - Boot service access controlled by smm_variable service provider. |
| 113 | * - EFI_VARIABLE_RUNTIME_ACCESS |
| 114 | - yes |
| 115 | - Runtime access controlled by smm_variable service provider. |
| 116 | * - EFI_VARIABLE_HARDWARE_ERROR_RECORD |
| 117 | - no |
| 118 | - |
| 119 | * - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
| 120 | - no |
| 121 | - |
| 122 | * - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS |
| 123 | - not yet |
| 124 | - Will be needed for secure boot support |
| 125 | * - EFI_VARIABLE_APPEND_WRITE |
| 126 | - yes |
| 127 | - Implemented by overwriting entire variable data. |
| 128 | |
| 129 | SMM Variable Tests |
| 130 | '''''''''''''''''' |
| 131 | The following test components exist for the SMM Variable service: |
| 132 | |
| 133 | .. list-table:: |
| 134 | :header-rows: 1 |
| 135 | |
| 136 | * - Test Component |
| 137 | - Description |
| 138 | - Included in deployments |
| 139 | * - ``component/service/smm_variable/backend/test`` |
| 140 | - | Component tests for the variable_index and variable_store backend |
| 141 | | components. Can be run in a native PC environment. |
| 142 | - ``deployments/component-test/*`` |
| 143 | * - ``component/service/smm_variable/test/service`` |
| 144 | - | End-to-end service level tests that call service operations from |
| 145 | | the perspective of a client. Can be run in a native PC environment |
| 146 | | or on the Arm target platform. |
| 147 | - | ``deployments/ts-service-test/linux-pc`` |
| 148 | | ``deployments/uefi-test/arm-linux`` |
| 149 | |
| 150 | SMM Gateway Build Configuration |
| 151 | ------------------------------- |
| 152 | The smm-gateway SP image may be built using the default configuration parameters defined |
| 153 | within relevant source files. In practice, it is likely that at least some configuration |
| 154 | values will need to be overridden. The following table lists build-time configuration |
| 155 | parameters that may be overridden by global C pre-processor defines. |
| 156 | |
| 157 | .. list-table:: |
| 158 | :widths: 2 2 2 1 |
| 159 | :header-rows: 1 |
| 160 | |
| 161 | * - Config define |
| 162 | - Usage |
| 163 | - File |
| 164 | - Default value |
| 165 | * - SMM_GATEWAY_MAX_UEFI_VARIABLES |
| 166 | - Maximum number of variables |
| 167 | - ``deployments/smm-gateway/smm_gateway.c`` |
| 168 | - 40 |
| 169 | * - SMM_GATEWAY_NV_STORE_SN |
| 170 | - The service ID for the backend NV variable store |
| 171 | - ``deployments/smm-gateway/smm_gateway.c`` |
| 172 | - Protected Storage SP |
| 173 | |
| 174 | MM Communicate RPC Layer |
| 175 | ------------------------ |
| 176 | To maintain compatibility with existing SMM service clients, an MM Communicate based RPC |
| 177 | layer has been developed that uses the same 'carveout' buffer scheme as StMM. When SMM |
| 178 | Gateway is used instead of StMM, existing SMM variable clients should interoperate seamlessly. |
| 179 | The MM Communicate RPC components implement the standard TS RPC interfaces and can be used as |
| 180 | a general purpose RPC for calls from normal world to secure world. The following MM Communicate |
| 181 | RPC components have been added: |
| 182 | |
| 183 | * ``components/rpc/mm_communicate/endpoint/sp`` - an RPC endpoint that handles FFA direct |
| 184 | calls with MM Communicate and SMM message carried in a shared 'carveout' buffer. Call requests |
| 185 | are demultiplexed to the appropriate service interface based on the service GUID carried in |
| 186 | the MM Communicate header. Suitable for use in SP deployments. |
| 187 | * ``components/rpc/mm_communicate/caller/linux`` - an RPC caller that calls service operations |
| 188 | associated with the destination service interface from Linux user-space. Uses the MM Communicate |
| 189 | protocol, sent over FFA using the Debug FFA kernel driver. Service level tests that run against |
| 190 | the SMM Gateway use this RPC caller for invoking SMM service operations. |
| 191 | |
| 192 | The following register mapping is assumed for FFA based direct calls to an SP that handles the MM |
| 193 | Communicate RPC protocol: |
| 194 | |
| 195 | .. list-table:: |
| 196 | :widths: 1 2 2 2 |
| 197 | :header-rows: 1 |
| 198 | |
| 199 | * - Registers |
| 200 | - FF-A layer |
| 201 | - MM_COMMUNICATE Request |
| 202 | - MM_COMMUNICATE Response |
| 203 | * - W0 |
| 204 | - Function ID |
| 205 | - | FFA_MSG_SEND_DIRECT_REQ |
| 206 | | (0x8400006F/0xC400006F) |
| 207 | - | FFA_MSG_SEND_DIRECT_RESP |
| 208 | | (0x84000070/0xC4000070) |
| 209 | * - W1 |
| 210 | - Source/Destination ID |
| 211 | - Source/Destination ID |
| 212 | - Source/Destination ID |
| 213 | * - W2/X2 |
| 214 | - Reserved |
| 215 | - 0x00000000 |
| 216 | - 0x00000000 |
| 217 | * - W3/X3 |
| 218 | - Parameter[0] |
| 219 | - Address of the MM communication buffer |
| 220 | - | ARM_SVC_ID_SP_EVENT_COMPLETE |
| 221 | | (0x84000061/0xC4000061) |
| 222 | * - W4/X4 |
| 223 | - Parameter[1] |
| 224 | - Size of the MM communication buffer |
| 225 | - SUCCESS/[error code] |
| 226 | * - W5/X5 |
| 227 | - Parameter[2] |
| 228 | - 0x00000000 |
| 229 | - 0x00000000 |
| 230 | * - W6/X6 |
| 231 | - Parameter[3] |
| 232 | - 0x00000000 |
| 233 | - 0x00000000 |
| 234 | * - W7/X7 |
| 235 | - Parameter[4] |
| 236 | - 0x00000000 |
| 237 | - 0x00000000 |
| 238 | |
| 239 | -------------- |
| 240 | |
| 241 | *Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.* |
| 242 | |
| 243 | SPDX-License-Identifier: BSD-3-Clause |