Imre Kis | 0706b65 | 2024-08-08 16:42:02 +0200 | [diff] [blame] | 1 | Firmware update on A+M systems |
| 2 | ------------------------------ |
| 3 | |
| 4 | Concept |
| 5 | ''''''' |
| 6 | |
| 7 | Some platforms have both Cortex-A and Cortex-M subsystems and implement the PSA RoT on the M class core. On such systems |
| 8 | the firmware store is usually read-only or not accessible to the Cortex-A cores due to security reasons. In such cases |
| 9 | it may still be beneficial to implement the cloud update client on the Cortex-A subsystem, and a solution is needed to |
| 10 | bridge the Cortex-A and the Cortex-M firmware update implementations. For this purpose TS implements a special firmware |
| 11 | update agent which is documented below. |
| 12 | |
| 13 | .. figure:: ../image/psa-fwu-m-block.svg |
| 14 | |
| 15 | Components on an A+M system. |
| 16 | |
| 17 | Standards and specifications |
| 18 | '''''''''''''''''''''''''''' |
| 19 | |
| 20 | * `Platform Security Firmware Update for the A-profile Arm Architecture`_ (A class FWU specification) |
| 21 | * `PSA Certified Firmware Update API 1.0`_ (M class FWU specification) |
| 22 | * `Trusted Firmware-M FWU service`_ |
| 23 | |
| 24 | Update agent implementation |
| 25 | ''''''''''''''''''''''''''' |
| 26 | |
| 27 | The update agent implements the `Platform Security Firmware Update for the A-profile Arm Architecture`_ API (prefixed |
| 28 | with ``fwu_``) and acts as a `PSA Certified Firmware Update API 1.0`_ client (prefixed with ``psa_fwu_``). The update |
| 29 | agent has to align the slightly different APIs by maintaining an internal registry of image states and image handles. |
| 30 | The differences between the two firmware update protocols are: |
| 31 | |
| 32 | * `Platform Security Firmware Update for the A-profile Arm Architecture`_ identifies images by UUID while |
| 33 | `PSA Certified Firmware Update API 1.0`_ identifies component by an 8 bit component ID. |
| 34 | * Although similar calls are implemented, FWU-A operates on images, while FWU-M on the whole image set. |
| 35 | * There is no *image handle* concept in `PSA Certified Firmware Update API 1.0`_ |
| 36 | * Differences in the returned details of the image query functions |
| 37 | |
| 38 | The solutions to these differences: |
| 39 | |
| 40 | * A static UUID to component ID mapping is used. This has to be passed to the agent init function. |
| 41 | * Gathering per image based calls and then make the actual call to the M class side when the operation was called on |
| 42 | each image. |
| 43 | * Implement internal image handle registry. |
| 44 | * Convert the image query result returned by FWU-M to FWU-A format. There are similar field, but this imposes some |
| 45 | limitations. |
| 46 | |
| 47 | |
| 48 | ``fwu_discover()`` |
| 49 | `````````````````` |
| 50 | |
| 51 | This function returns the list of implemented features. |
| 52 | |
| 53 | ``fwu_begin_staging()`` |
| 54 | ``````````````````````` |
| 55 | |
| 56 | Clients can only write images in staging state. In order to switch to staging state, the client must call |
| 57 | ``fwu_begin_staging()``. This results in ``psa_fwu_start()`` calls on all selected images. The client can pass a list of |
| 58 | the selected image UUIDs or select all images for staging. |
| 59 | |
| 60 | If the agent is already in staging state when ``fwu_begin_staging()`` is called, then the agent first discards all |
| 61 | transient state by calling ``fwu_cancel_staging()`` and ``psa_fwu_clean()`` on all image. |
| 62 | |
| 63 | .. uml:: ../uml/psa_fwu_m_update_agent/fwu_begin_staging.puml |
| 64 | |
| 65 | ``fwu_end_staging()`` |
| 66 | ````````````````````` |
| 67 | |
| 68 | Finishes the staging state when all images that were selected for the update have been updated. If all selected images |
| 69 | are also accepted the agent switches to regular state and the update is completed. If there are not accepted images, the |
| 70 | agent switches to trial state, so the client can validate the new set of images and accept or reject them. |
| 71 | |
| 72 | On calling ``fwu_end_staging()`` the agent calls ``psa_fwu_finish()`` on each selected image, then calls |
| 73 | ``psa_fwu_install()``. If all images have been accepted (see ``fwu_commit()``) it also calls ``psa_fwu_accept()``. |
| 74 | |
| 75 | .. uml:: ../uml/psa_fwu_m_update_agent/fwu_end_staging.puml |
| 76 | |
| 77 | ``fwu_cancel_staging()`` |
| 78 | ```````````````````````` |
| 79 | |
| 80 | Cancels staging state and reverts to original regular state. The function calls ``psa_fwu_cancel()`` on each selected |
| 81 | image. |
| 82 | |
| 83 | .. uml:: ../uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml |
| 84 | |
| 85 | ``fwu_open()`` |
| 86 | `````````````` |
| 87 | |
| 88 | `Platform Security Firmware Update for the A-profile Arm Architecture`_ has a concept of image handles. An image can be |
| 89 | opened via ``fwu_open()``, then accessed by calling ``fwu_write_stream()`` or ``fwu_read_stream()``, and finally it can |
| 90 | be closed by invoking ``fwu_commit()``. However `PSA Certified Firmware Update API 1.0`_ does not have a similar concept |
| 91 | and once the staging process was started for an image by calling ``psa_fwu_start()``, the image can be written through |
| 92 | ``psa_fwu_write()``. |
| 93 | |
| 94 | The update agent provides an internal registry of opened images and their access rights so it can handle subsequent |
| 95 | calls on the image handle. The open call can open an image for either write or read operations but not for both. The |
| 96 | image is identified by its UUID. Only images which were selected for staging can be opened for write. |
| 97 | |
| 98 | There is no actual call made to the M class side on opening a image. |
| 99 | |
| 100 | `PSA Certified Firmware Update API 1.0`_ does not provide a function for reading images, so opening images will fail |
| 101 | except for opening the image directory. Only the image directory supports read operations. |
| 102 | |
| 103 | ``fwu_write_stream()`` |
| 104 | `````````````````````` |
| 105 | |
| 106 | This function writes data into the opened image. The image handle has to be opened for write operations. The agent calls |
| 107 | ``psa_fwu_write()`` for doing the actual write and the write offset is tracked internally. |
| 108 | |
| 109 | ``fwu_read_stream()`` |
| 110 | ````````````````````` |
| 111 | |
| 112 | This function read data from the opened image. The image handle has to be opened for read operations. |
| 113 | |
| 114 | This call is only implemented for the image directory which returns the available image list as specified in |
| 115 | `Platform Security Firmware Update for the A-profile Arm Architecture`_. It does not support the partial reading of the |
| 116 | image directory. |
| 117 | |
| 118 | ``fwu_commit()`` |
| 119 | ```````````````` |
| 120 | |
| 121 | The commit call closes the image handle. The client can also mark the image as accepted on commit and this the method |
| 122 | for accepting all images before calling ``fwu_end_staging()``. |
| 123 | |
| 124 | There is no actual call made to the M class side on comiting an image. |
| 125 | |
| 126 | ``fwu_accept_image()`` |
| 127 | `````````````````````` |
| 128 | |
| 129 | `PSA Certified Firmware Update API 1.0`_ only provides a ``psa_fwu_accept()`` function which accepts the whole set of |
| 130 | selected images. In order to align with the ``fwu_accept_image()`` API, it only marks the given image as accepted and |
| 131 | calls ``psa_fwu_accept()`` when all images have been accepted. This results in a state transition to regular state. |
| 132 | |
| 133 | .. uml:: ../uml/psa_fwu_m_update_agent/fwu_accept.puml |
| 134 | |
| 135 | ``fwu_select_previous()`` |
| 136 | ````````````````````````` |
| 137 | |
| 138 | Selects previous working state (i.e. rejects the firmware update) and transitions back to regular state after calling |
| 139 | ``psa_fwu_reject()``. |
| 140 | |
| 141 | .. uml:: ../uml/psa_fwu_m_update_agent/fwu_select_previous.puml |
| 142 | |
| 143 | Image directory |
| 144 | ''''''''''''''' |
| 145 | |
| 146 | The client can read the image directory by opening and reading an image with dedicated UUID |
| 147 | (``deee58d9-5147-4ad3-a290-77666e2341a5``). On image directory read, the agent will call ``psa_fwu_query()`` on each |
| 148 | image and convert the value of similar fields. |
| 149 | |
| 150 | * The UUID is based on the UUID - component ID mapping passed upon agent initialization. |
| 151 | * The images only support write operation due to FWU-M limitation. |
| 152 | * The image maximal size is copied from the component info structure. |
| 153 | * The lowest accepted version is set to 0. |
| 154 | * The image version is converted from the fields of the component info structure into a single 32 bit value. The build |
| 155 | field is dropped due to lack of space in the 32 bit field. |
| 156 | * The images is marked accepted if its state in the component info structure is ``PSA_FWU_UPDATED``. |
| 157 | |
| 158 | .. uml:: ../uml/psa_fwu_m_update_agent/image_directory.puml |
| 159 | |
| 160 | -------------- |
| 161 | |
| 162 | .. _`Platform Security Firmware Update for the A-profile Arm Architecture`: https://developer.arm.com/documentation/den0118/latest/ |
| 163 | .. _`PSA Certified Firmware Update API 1.0`: https://arm-software.github.io/psa-api/fwu/1.0/ |
| 164 | .. _`Trusted Firmware-M FWU service`: https://tf-m-user-guide.trustedfirmware.org/design_docs/services/tfm_fwu_service.html |
| 165 | |
| 166 | *Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.* |
| 167 | |
| 168 | SPDX-License-Identifier: BSD-3-Clause |