Sherry Zhang | 0b9738a | 2021-01-07 14:26:01 +0800 | [diff] [blame^] | 1 | ####################### |
| 2 | Firmware Update Service |
| 3 | ####################### |
| 4 | |
| 5 | :Author: Sherry Zhang |
| 6 | :Organization: Arm Limited |
| 7 | :Contact: Sherry Zhang <Sherry.Zhang2@arm.com> |
| 8 | :Status: Draft |
| 9 | |
| 10 | .. contents:: Table of Contents |
| 11 | |
| 12 | *************************************** |
| 13 | Introduction of Firmware Update service |
| 14 | *************************************** |
| 15 | The Firmware Update(FWU) service provides the functionality of updating firmware |
| 16 | images. It provides a standard interface for updating firmware and it is |
| 17 | platform independent. TF-M defines a shim layer to support cooperation between |
| 18 | bootloader and FWU service. |
| 19 | |
| 20 | This partition supports the following features: |
| 21 | |
| 22 | - Query image information |
| 23 | Fetch information about the firmware images on the device. This covers the |
| 24 | images in the running area and also the staging area. |
| 25 | - Store image |
| 26 | Write a candidate image to its staging area. |
| 27 | - Validate image |
| 28 | Starts the validation of the image. |
| 29 | - Trigger reboot |
| 30 | Trigger a reboot to restart the platform. |
| 31 | |
| 32 | ********** |
| 33 | Components |
| 34 | ********** |
| 35 | The structure of the TF-M Firmware Update service is listed below: |
| 36 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 37 | | **Component name** | **Description** | **Location** | |
| 38 | +=============================+===============================================================+==================================================================================+ |
| 39 | | SPE client API interface | This module exports the client API of PSA Firmware Update to | ``./secure_fw/partitions/firmware_update/tfm_fwu_secure_api.c`` | |
| 40 | | | the other services available in TF-M. | | |
| 41 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 42 | | NSPE client API interface | This module exports the client API of PSA Firmware Update to | ``./interface/src/tfm_firmware_update_func_api.c`` | |
| 43 | | | the NSPE(i.e. to the applications). | ``./interface/src/tfm_firmware_update_ipc_api.c`` | |
| 44 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 45 | | Manifest | The manifest file is a description of the service components | ``./secure_fw/partitions/firmware_update/tfm_firmware_update.yaml`` | |
| 46 | | | for both library mode and IPC mode. | | |
| 47 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 48 | | Secure functions and IPC | This module handles all the secure function requests in | ``./secure_fw/partitions/firmware_update/tfm_fwu_req_mngr.c`` | |
| 49 | | request handlers | library model and all the service requests in IPC model. | | |
| 50 | | | It maitains the image state context and calls the image ID | | |
| 51 | | | converter to achieve the firmware update functionalities. | | |
| 52 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 53 | | Image ID Converter | This module converts the image ID between psa_image_id_t, | ``./secure_fw/partitions/firmware_update/tfm_fwu_internal.c`` | |
| 54 | | | which is the image ID structure in user interfaces, and | | |
| 55 | | | bl_image_id_t which is the image ID structure in bootloader. | | |
| 56 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 57 | | Shim layer between FWU and | This module provides the APIs with the functionality of | ``./secure_fw/partitions/firmware_update/tfm_bootloader_fwu_abstraction.h`` | |
| 58 | | bootloader | operating the bootloader to cooperate with the Firmware Update| | |
| 59 | | | service | | |
| 60 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 61 | | Shim layer example based on | This module is the implementation of the shim layer between | ``./secure_fw/partitions/firmware_update/bootloader/mcuboot/tfm_mcuboot_fwu.c`` | |
| 62 | | MCUboot | FWU and bootloader based on MCUboot. | | |
| 63 | | | | | |
| 64 | +-----------------------------+---------------------------------------------------------------+----------------------------------------------------------------------------------+ |
| 65 | |
| 66 | *********************** |
| 67 | Service API description |
| 68 | *********************** |
| 69 | This service follows the `Firmware Update API <https://developer.arm.com/documentation/ihi0093/0000/>`_ spec of version 0.7. |
| 70 | It implements the mandatory interface functions listed in section 5.1 and the |
| 71 | optional interface ``psa_fwu_accept()``. Please refer to Firmware Update spec |
| 72 | for the detailed description. |
| 73 | |
| 74 | ************************************* |
| 75 | Shim Layer between FWU and bootloader |
| 76 | ************************************* |
| 77 | The firmware update operations are achieved by calling the shim layer APIs |
| 78 | between bootloader and FWU. |
| 79 | |
| 80 | Shim layer introduction |
| 81 | ======================= |
| 82 | This shim layer provides the APIs with the functionality of operating the |
| 83 | bootloader to cooperate with the Firmware Update service. This shim layer |
| 84 | is decoupled from bootloader implementation. Users can specify a specific |
| 85 | bootloader by setting ``TFM_FWU_BOOTLOADER_LIB`` build configuration and |
| 86 | adding the specific build scripts into that file. By default, the MCUboot |
| 87 | is chosen as the bootloader. |
| 88 | |
| 89 | Interfaces of the shim Layer |
| 90 | ============================ |
| 91 | |
| 92 | fwu_bootloader_init(function) |
| 93 | ----------------------------- |
| 94 | Prototype |
| 95 | ^^^^^^^^^ |
| 96 | .. code-block:: c |
| 97 | |
| 98 | psa_status_t fwu_bootloader_init(void); |
| 99 | |
| 100 | Description |
| 101 | ^^^^^^^^^^^ |
| 102 | Bootloader related initialization for the firmware update, such as reading |
| 103 | some necessary shared data from the memory if needed. |
| 104 | |
| 105 | Parameters |
| 106 | ^^^^^^^^^^ |
| 107 | N/A |
| 108 | |
| 109 | fwu_bootloader_staging_area_init(function) |
| 110 | ------------------------------------------ |
| 111 | Prototype |
| 112 | ^^^^^^^^^ |
| 113 | .. code-block:: c |
| 114 | |
| 115 | psa_status_t fwu_bootloader_staging_area_init(bl_image_id_t bootloader_image_id); |
| 116 | |
| 117 | Description |
| 118 | ^^^^^^^^^^^ |
| 119 | Prepare the staging area of the image with the given ID for image download. |
| 120 | For example, initialize the staging area, open the flash area, and so on. |
| 121 | The image will be written into the staging area later. |
| 122 | |
| 123 | Parameters |
| 124 | ^^^^^^^^^^ |
| 125 | - ``bootloader_image_id``: The identifier of the target image in bootloader. |
| 126 | |
| 127 | fwu_bootloader_load_image(function) |
| 128 | ----------------------------------- |
| 129 | Prototype |
| 130 | ^^^^^^^^^ |
| 131 | |
| 132 | .. code-block:: c |
| 133 | |
| 134 | psa_status_t fwu_bootloader_load_image(bl_image_id_t bootloader_image_id, |
| 135 | size_t image_offset, |
| 136 | const void *block, |
| 137 | size_t block_size); |
| 138 | |
| 139 | Description |
| 140 | ^^^^^^^^^^^ |
| 141 | Load the image to its staging area. |
| 142 | |
| 143 | Parameters |
| 144 | ^^^^^^^^^^ |
| 145 | - ``bootloader_image_id``: The identifier of the target image in bootloader. |
| 146 | - ``image_offset``: The offset of the image being passed into block, in bytes. |
| 147 | - ``block``: A buffer containing a block of image data. This might be a complete image or a subset. |
| 148 | - ``block_size``: Size of block. |
| 149 | |
| 150 | fwu_bootloader_install_image(function) |
| 151 | --------------------------------------------- |
| 152 | Prototype |
| 153 | ^^^^^^^^^ |
| 154 | .. code-block:: c |
| 155 | |
| 156 | psa_status_t fwu_bootloader_install_image(bl_image_id_t bootloader_image_id, |
| 157 | bl_image_id_t *dependency, |
| 158 | psa_image_version_t *dependency_version); |
| 159 | |
| 160 | Description |
| 161 | ^^^^^^^^^^^ |
| 162 | Check the authenticity and integrity of the image. If a reboot is required to |
| 163 | complete the check, then mark this image as a candidate so that the next time |
| 164 | bootloader runs it will take this image as a candidate one to bootup. Return |
| 165 | the error code PSA_SUCCESS_REBOOT. |
| 166 | |
| 167 | Parameters |
| 168 | ^^^^^^^^^^ |
| 169 | - ``bootloader_image_id``: The identifier of the target image in bootloader. |
| 170 | - ``dependency``: Bootloader image ID of dependency if needed. |
| 171 | - ``dependency_version``: Bootloader image version of dependency if needed. |
| 172 | |
| 173 | fwu_bootloader_mark_image_accepted(function) |
| 174 | -------------------------------------------- |
| 175 | Prototype |
| 176 | ^^^^^^^^^ |
| 177 | .. code-block:: c |
| 178 | |
| 179 | psa_status_t fwu_bootloader_mark_image_accepted(void); |
| 180 | |
| 181 | Description |
| 182 | ^^^^^^^^^^^ |
| 183 | Call this API to mark the running images as permanent/accepted to avoid |
| 184 | revert when next time bootup. Usually, this API is called after the running |
| 185 | images have been verified as valid. |
| 186 | |
| 187 | Parameters |
| 188 | ^^^^^^^^^^ |
| 189 | N/A |
| 190 | |
| 191 | fwu_bootloader_abort(function) |
| 192 | ------------------------------ |
| 193 | Prototype |
| 194 | ^^^^^^^^^ |
| 195 | .. code-block:: c |
| 196 | |
| 197 | psa_status_t fwu_bootloader_abort(void); |
| 198 | |
| 199 | Description |
| 200 | ^^^^^^^^^^^ |
| 201 | Abort the current image download process. |
| 202 | |
| 203 | Parameters |
| 204 | ^^^^^^^^^^ |
| 205 | N/A |
| 206 | |
| 207 | fwu_bootloader_get_image_info(function) |
| 208 | --------------------------------------- |
| 209 | Prototype |
| 210 | ^^^^^^^^^ |
| 211 | .. code-block:: c |
| 212 | |
| 213 | psa_status_t fwu_bootloader_get_image_info(bl_image_id_t bootloader_image_id, |
| 214 | bool staging_area, |
| 215 | tfm_image_info_t *info); |
| 216 | |
| 217 | Description |
| 218 | ^^^^^^^^^^^ |
| 219 | Get the image information of the given bootloader_image_id in the staging area |
| 220 | or the running area. |
| 221 | |
| 222 | Parameters |
| 223 | ^^^^^^^^^^ |
| 224 | - ``bootloader_image_id``: The identifier of the target image in bootloader. |
| 225 | - ``active_image``: Indicates image location. |
| 226 | |
| 227 | - ``True``: the running image. |
| 228 | - ``False``: the image in the passive(or staging) slot. |
| 229 | |
| 230 | - ``info``: Buffer containing the image information. |
| 231 | |
| 232 | ****************************************** |
| 233 | Additional shared data between BL2 and SPE |
| 234 | ****************************************** |
| 235 | An additional TLV area "image version" is added into the shared memory between |
| 236 | BL2 and TF-M. So that the firmware update partition can get the image version. |
| 237 | Even though the image version information is also included in the ``BOOT RECORD`` |
| 238 | TLV area which is encoded by CBOR, adding a dedicated ``image version`` TLV area |
| 239 | is preferred to avoid involving the CBOR encoder which can increase the code |
| 240 | size. The FWU partition will read the shared data at the partition |
| 241 | initialization. |
| 242 | |
| 243 | ****************** |
| 244 | Image ID structure |
| 245 | ****************** |
| 246 | The structure of image ID is: |
| 247 | image_id[7:0]: slot. |
| 248 | image_id[15:8]: image type. |
| 249 | image_id[31:16]: specific image ID. |
| 250 | |
| 251 | Three image types are defined in this partition. |
| 252 | - FWU_IMAGE_TYPE_NONSECURE: the non_secure image |
| 253 | - FWU_IMAGE_TYPE_SECURE: the secure image |
| 254 | - FWU_IMAGE_TYPE_FULL: the secure + non_secure image |
| 255 | |
| 256 | .. Note:: |
| 257 | |
| 258 | Currently, images update with dependency is not supported by FWU in multiple image boot. |
| 259 | |
| 260 | Macros **FWU_CALCULATE_IMAGE_ID**, **FWU_IMAGE_ID_GET_TYPE** and |
| 261 | **FWU_IMAGE_ID_GET_SLOT** are dedicated to converting the image id, type, and |
| 262 | slot. The service users can call these macros to get the image ID. |
| 263 | |
| 264 | .. Note:: |
| 265 | |
| 266 | The image ID structure, as well as the macros listed here, is TF-M specific implementation. |
| 267 | |
| 268 | *********************************** |
| 269 | Benefits Analysis on this Partition |
| 270 | *********************************** |
| 271 | |
| 272 | Implement the FWU functionality in the non-secure side |
| 273 | ====================================================== |
| 274 | The Firmware Update APIs listed in `User interfaces`_ can also be implemented |
| 275 | in the non-secure side. The library model implementation can be referred to for |
| 276 | the non-secure side implementation. |
| 277 | |
| 278 | Pros and Cons for Implementing FWU APIs in Secure Side |
| 279 | ====================================================== |
| 280 | |
| 281 | Pros |
| 282 | ---- |
| 283 | - It protects the image in the passive or staging area from being tampered with |
| 284 | by the NSPE. Otherwise, a malicious actor from NSPE can tamper the image |
| 285 | stored in the non-secure area to break image update. |
| 286 | |
| 287 | - It protects secure image information from disclosure. In some cases, the |
| 288 | non-secure side shall not be permitted to get secure image information. |
| 289 | |
| 290 | - It protects the active image from being manipulated by NSPE. Some bootloader |
| 291 | supports testing the image. After the image is successfully installed and |
| 292 | starts to run, the user should set the image as permanent image if the image |
| 293 | passes the test. To achieve this, the area of the active image needs to be |
| 294 | accessed. In this case, implementing FWU service in SPE can prevent NSPE |
| 295 | from manipulating the active image area. |
| 296 | |
| 297 | - On some devices, such as the Arm Musca-B1 board, the passive or staging area |
| 298 | is restricted as secure access only. In this case, the FWU partition should |
| 299 | be implemented in the secure side. |
| 300 | |
| 301 | Cons |
| 302 | ---- |
| 303 | - It increases the image size of the secure image. |
| 304 | - It increases the execution latency and footprint. Compared to implementing |
| 305 | FWU in NSPE directly, calling the Firmware Update APIs which are implemented |
| 306 | in the secure side increases the execution latency and footprint. |
| 307 | - It can increase the attack surface of the secure runtime. |
| 308 | |
| 309 | Users can decide whether to call the FWU service in TF-M directly or implement |
| 310 | the Firmware Update APIs in the non-secure side based on the pros and cons |
| 311 | analysis above. |
| 312 | |
| 313 | *Copyright (c) 2021, Arm Limited. All rights reserved.* |