1 /*
2  * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 /* PSA Firmware Update API v1.0 Beta */
9 
10 #ifndef PSA_UPDATE_H
11 #define PSA_UPDATE_H
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include "psa/error.h"
17 #ifdef FWU_DEVICE_CONFIG_FILE
18 #include FWU_DEVICE_CONFIG_FILE
19 #else
20 #include "psa/fwu_config.h"
21 #endif
22 #include "tfm_fwu_defs.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /**
29  * @brief The major version of this implementation of the Firmware Update API.
30  */
31 #define PSA_FWU_API_VERSION_MAJOR 1
32 
33 /**
34  * @brief The minor version of this implementation of the Firmware Update API.
35  */
36 #define PSA_FWU_API_VERSION_MINOR 0
37 
38 /**
39  * @brief A status code that indicates that the firmware of another component
40  *        requires updating.
41  */
42 #define PSA_ERROR_DEPENDENCY_NEEDED ((psa_status_t)-156)
43 
44 /**
45  * @brief A status code that indicates that the system is limiting i/o
46  *        operations to avoid rapid flash exhaustion.
47  */
48 #define PSA_ERROR_FLASH_ABUSE ((psa_status_t)-160)
49 
50 /**
51  * @brief A status code that indicates that the system does not have enough
52  *        power to carry out the request.
53  */
54 #define PSA_ERROR_INSUFFICIENT_POWER ((psa_status_t)-161)
55 
56 /**
57  * @brief The action was completed successfully and requires a system reboot to
58  *        complete installation.
59  */
60 #define PSA_SUCCESS_REBOOT ((psa_status_t)+1)
61 
62 /**
63  * @brief The action was completed successfully and requires a restart of the
64  *        component to complete installation.
65  */
66 #define PSA_SUCCESS_RESTART ((psa_status_t)+2)
67 
68 /**
69  * @brief Firmware component type identifier.
70  */
71 typedef uint8_t psa_fwu_component_t;
72 
73 /**
74  * @brief Version information about a firmware image.
75  */
76 typedef struct psa_fwu_image_version_t {
77     /* The major version of an image. */
78     uint8_t major;
79     /* The minor version of an image. */
80     uint8_t minor;
81     /* The revision or patch version of an image. */
82     uint16_t patch;
83     /* The build number of an image. */
84     uint32_t build;
85 } psa_fwu_image_version_t;
86 
87 /**
88  * @brief The READY state: the component is ready to start another update.
89  */
90 #define PSA_FWU_READY 0u
91 
92 /**
93  * @brief The WRITING state: a new firmware image is being written to the
94  *        firmware store.
95  */
96 #define PSA_FWU_WRITING 1u
97 
98 /**
99  * @brief The CANDIDATE state: a new firmware image is ready for installation.
100  */
101 #define PSA_FWU_CANDIDATE 2u
102 
103 /**
104  * @brief The STAGED state: a new firmware image is queued for installation.
105  */
106 #define PSA_FWU_STAGED 3u
107 
108 /**
109  * @brief The FAILED state: a firmware update has been cancelled or has failed.
110  */
111 #define PSA_FWU_FAILED 4u
112 
113 /**
114  * @brief The TRIAL state: a new firmware image requires testing prior to
115  *        acceptance of the update.
116  */
117 #define PSA_FWU_TRIAL 5u
118 
119 /**
120  * @brief The REJECTED state: a new firmware image has been rejected after
121  *        testing.
122  */
123 #define PSA_FWU_REJECTED 6u
124 
125 /**
126  * @brief The UPDATED state: a firmware update has been successful, and the new
127  *        image is now active.
128  */
129 #define PSA_FWU_UPDATED 7u
130 
131 /**
132  * @brief Flag to indicate whether the image data in the component staging area
133  *        is discarded at system reset.
134  */
135 #define PSA_FWU_FLAG_VOLATILE_STAGING 0x00000001u
136 
137 /**
138  * @brief Flag to indicate whether a firmware component expects encrypted images
139  *        during an update.
140  */
141 #define PSA_FWU_FLAG_ENCRYPTION 0x00000002u
142 
143 /**
144  * @brief The implementation-specific data in the component information
145  *        structure.
146  */
147 typedef struct {
148     /* The digest of second image when store state is CANDIDATE. */
149     uint8_t candidate_digest[TFM_FWU_MAX_DIGEST_SIZE];
150  } psa_fwu_impl_info_t;
151 
152 /**
153  * @brief Information about the firmware store for a firmware component.
154  */
155 typedef struct psa_fwu_component_info_t {
156     /* State of the component. */
157     uint8_t state;
158     /* Error for second image when store state is REJECTED or FAILED. */
159     psa_status_t error;
160     /* Version of active image. */
161     psa_fwu_image_version_t version;
162     /* Maximum image size in bytes. */
163     uint32_t max_size;
164     /* Flags that describe extra information about the firmware component. */
165     uint32_t flags;
166     /* Implementation-defined image location. */
167     uint32_t location;
168     /* Reserved for implementation-specific usage. */
169     psa_fwu_impl_info_t impl;
170 } psa_fwu_component_info_t;
171 
172 /**
173  * @brief Retrieve the firmware store information for a specific firmware
174  *        component.
175  *
176  * @param component Firmware component for which information is requested.
177  * @param info      Output parameter for component information.
178  *
179  * @return Result status.
180  */
181 psa_status_t psa_fwu_query(psa_fwu_component_t component,
182                            psa_fwu_component_info_t *info);
183 
184 /**
185  * @brief Begin a firmware update operation for a specific firmware component.
186  *
187  * @param component     Identifier of the firmware component to be updated.
188  * @param manifest      A pointer to a buffer containing a detached manifest for
189  *                      the update.
190  * @param manifest_size The size of the detached manifest.
191  *
192  * @return Result status.
193  */
194 psa_status_t psa_fwu_start(psa_fwu_component_t component,
195                            const void *manifest,
196                            size_t manifest_size);
197 
198 /**
199  * @brief The maximum permitted size for block in psa_fwu_write(), in bytes.
200  */
201 #define PSA_FWU_MAX_WRITE_SIZE TFM_CONFIG_FWU_MAX_WRITE_SIZE
202 
203 /**
204  * @brief Write a firmware image, or part of a firmware image, to its staging
205  *        area.
206  *
207  * @param component    Identifier of the firmware component being updated.
208  * @param image_offset The offset of the data block in the whole image.
209  * @param block        A buffer containing a block of image data.
210  * @param block_size   Size of block, in bytes.
211  *
212  * @return Result status.
213  */
214 psa_status_t psa_fwu_write(psa_fwu_component_t component,
215                            size_t image_offset,
216                            const void *block,
217                            size_t block_size);
218 
219 /**
220  * @brief Mark a firmware image in the staging area as ready for installation.
221  *
222  * @param component Identifier of the firmware component to install.
223  *
224  * @return Result status.
225  */
226 psa_status_t psa_fwu_finish(psa_fwu_component_t component);
227 
228 /**
229  * @brief Abandon an update that is in WRITING or CANDIDATE state.
230  *
231  * @param component Identifier of the firmware component to be cancelled.
232  *
233  * @return Result status.
234  */
235 psa_status_t psa_fwu_cancel(psa_fwu_component_t component);
236 
237 /**
238  * @brief Prepare the component for another update.
239  *
240  * @param component Identifier of the firmware component to tidy up.
241  *
242  * @return Result status.
243  */
244 psa_status_t psa_fwu_clean(psa_fwu_component_t component);
245 
246 /**
247  * @brief Start the installation of all firmware images that have been prepared
248  *        for update.
249  *
250  * @return Result status.
251  */
252 psa_status_t psa_fwu_install(void);
253 
254 /**
255  * @brief Requests the platform to reboot.
256  *
257  * @return Result status.
258  */
259 psa_status_t psa_fwu_request_reboot(void);
260 
261 /**
262  * @brief Abandon an installation that is in STAGED or TRIAL state.
263  *
264  * @param error An application-specific error code chosen by the application.
265  *
266  * @return Result status.
267  */
268 psa_status_t psa_fwu_reject(psa_status_t error);
269 
270 /**
271  * @brief Accept a firmware update that is currently in TRIAL state.
272  *
273  * @return Result status.
274  */
275 psa_status_t psa_fwu_accept(void);
276 
277 #ifdef __cplusplus
278 }
279 #endif
280 
281 #endif /* PSA_UPDATE_H */
282