blob: 5af0f1cde3c704ea672326c0540b5d7707005eac [file] [log] [blame]
Sherry Zhang07b42412021-01-07 14:19:41 +08001/*
Sherry Zhang73126e52022-02-15 14:27:49 +08002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Sherry Zhang07b42412021-01-07 14:19:41 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#ifndef PSA_UPDATE_H
9#define PSA_UPDATE_H
10
11#include <stddef.h>
12#include <stdint.h>
13
14#include "psa/error.h"
Sherry Zhang73126e52022-02-15 14:27:49 +080015#include "psa/fwu_config.h"
Sherry Zhang07b42412021-01-07 14:19:41 +080016#include "tfm_fwu_defs.h"
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
Sherry Zhang07b42412021-01-07 14:19:41 +080022#define TFM_FWU_INVALID_IMAGE_ID 0
23
24/* The maximum size of an image digest in bytes. This is dependent
25 * on the hash algorithm used.
26 */
27#define PSA_FWU_MAX_DIGEST_SIZE 32
28#define TFM_IMAGE_INFO_INVALID_DIGEST 0xFF
29
30/* The image ID macros. */
31#define FWU_IMAGE_ID_SLOT_POSITION 0U
32
33/* The area where the image is running. */
34#define FWU_IMAGE_ID_SLOT_ACTIVE 0x01U
35
36/* The area to stage the image. */
37#define FWU_IMAGE_ID_SLOT_STAGE 0x02U
38#define FWU_IMAGE_ID_SLOT_MASK 0x00FF
39
40#define FWU_IMAGE_ID_TYPE_POSITION 8U
41#define FWU_IMAGE_ID_SPECIFIC_ID_POSITION 16U
42
43#define FWU_CALCULATE_IMAGE_ID(slot, type, specific_id) \
44 ((slot & FWU_IMAGE_ID_SLOT_MASK) | \
45 (type << FWU_IMAGE_ID_TYPE_POSITION) | \
46 (specific_id << FWU_IMAGE_ID_SPECIFIC_ID_POSITION))
47#define FWU_IMAGE_ID_GET_TYPE(image_id) (image_id >> FWU_IMAGE_ID_TYPE_POSITION)
48#define FWU_IMAGE_ID_GET_SLOT(image_id) (image_id & FWU_IMAGE_ID_SLOT_MASK)
49
50/* Image state macros. */
51#define PSA_IMAGE_UNDEFINED 0
52#define PSA_IMAGE_CANDIDATE 1
53#define PSA_IMAGE_INSTALLED 2
54#define PSA_IMAGE_REJECTED 3
55#define PSA_IMAGE_PENDING_INSTALL 4
56#define PSA_IMAGE_REBOOT_NEEDED 5
57
58/*
59 * image_id[7:0]: slot.
60 * image_id[15:8]: image type.
61 * image_id[31:16]: specific image ID.
62 */
63typedef uint32_t psa_image_id_t;
64
65typedef struct tfm_image_version_s {
66 uint8_t iv_major;
67 uint8_t iv_minor;
68 uint16_t iv_revision;
69 uint32_t iv_build_num;
70} psa_image_version_t;
71
72typedef struct tfm_image_info_s {
73 psa_image_version_t version;
74 uint8_t state;
75 uint8_t digest[PSA_FWU_MAX_DIGEST_SIZE];
76} psa_image_info_t;
77
78typedef struct psa_hash_s {
79 uint8_t value[PSA_FWU_MAX_DIGEST_SIZE];
80} psa_hash_t;
81
82/**
83 * \brief Writes an image to its staging area.
84 *
85 * Writes the image data 'block' with length 'block_size' to its staging area.
86 * If the image size is less than or equal to PSA_FWU_MAX_BLOCK_SIZE, the
87 * caller can send the entire image in one call.
88 * If the image size is greater than PSA_FWU_MAX_BLOCK_SIZE, the caller must
89 * send parts of the image by calling this API multiple times with different
90 * data blocks.
91 *
92 * \param[in] image_id The identifier of the image
93 * \param[in] block_offset The offset of the block being passed into block,
94 * in bytes
95 * \param[in] block A buffer containing a block of image data. This
96 * might be a complete image or a subset.
97 * \param[in] block_size Size of block. The size must not be greater than
98 * PSA_FWU_MAX_BLOCK_SIZE.
99 *
100 * \return A status indicating the success/failure of the operation
101 *
102 * \retval PSA_SUCCESS The data in block has been
103 * successfully stored.
104 * \retval PSA_ERROR_INVALID_ARGUMENT One of the following error
105 * conditions occurred:
106 * The parameter size is greater than
107 * PSA_FWU_MAX_BLOCK_SIZE;
108 * The parameter size is 0;
109 * The combination of offset and size
110 * is out of bounds.
111 *
112 * \retval PSA_ERROR_INSUFFICIENT_MEMORY There is not enough memory to
113 * process the update
114 * \retval PSA_ERROR_INSUFFICIENT_STORAGE There is not enough storage to
115 * process the update
116 * \retval PSA_ERROR_GENERAL_ERROR A fatal error occurred
117 * \retval PSA_ERROR_CURRENTLY_INSTALLING The image is currently locked for
118 * writing.
119 */
120psa_status_t psa_fwu_write(psa_image_id_t image_id,
121 size_t block_offset,
122 const void *block,
123 size_t block_size);
124
125
126/**
127 * \brief Starts the installation of an image.
128 *
129 * The authenticity and integrity of the image is checked during installation.
130 * If a reboot is required to complete installation then the implementation
131 * can choose to defer the authenticity checks to that point.
132 *
133 * \param[in] image_id The identifier of the image to install
134 * \param[out] dependency_uuid If PSA_ERROR_DEPENDENCY_NEEDED is returned,
135 * this parameter is filled with dependency
136 * information
137 * \param[out] dependency_version If PSA_ERROR_DEPENDENCY_NEEDED is returned,
138 * this parameter is filled with the minimum
139 * required version for the dependency
140 *
141 * \return A status indicating the success/failure of the operation
142 *
143 * \retval PSA_SUCCESS The image was successfully
144 * installed. The platform does not
145 * require a reboot.
146 * \retval PSA_SUCCESS_REBOOT A system reboot is needed to finish
147 * installation.
148 * \retval PSA_ERROR_INVALID_ARGUMENT Bad input parameter
149 * \retval PSA_ERROR_INVALID_SIGNATURE The signature is incorrect
150 * \retval PSA_ERROR_GENERAL_ERROR A fatal error occurred
151 * \retval PSA_ERROR_DEPENDENCY_NEEDED A different image requires
152 * installation first
153 * \retval PSA_ERROR_STORAGE_FAILURE Some persistent storage could not be
154 * read or written by the
155 * implementation
156 */
157psa_status_t psa_fwu_install(psa_image_id_t image_id,
158 psa_image_id_t *dependency_uuid,
159 psa_image_version_t *dependency_version);
160
161/**
162 * \brief Aborts an ongoing installation and erases the staging area of the
163 * image.
164 *
165 * \param[in] image_id The identifier of the image to abort installation
166 *
167 * \return A status indicating the success/failure of the operation
168 *
169 * \retval PSA_SUCCESS Installation of the provided image_id
170 * has been aborted
171 * \retval PSA_ERROR_INVALID_ARGUMENT No image with the provided image_id
172 * is currently being installed
173 * \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
174 * abort an installation
175 */
176psa_status_t psa_fwu_abort(psa_image_id_t image_id);
177
178/**
179 * \brief Returns information for an image of a particular image_id.
180 *
181 * \param[in] image_id The image_id of the image to query
182 *
183 * \param[out] info Output parameter for image information
184 * related to the image_id
185 *
186 * \return A status indicating the success/failure of the operation
187 *
188 * \retval PSA_SUCCESS Image information has been returned
189 * \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
190 * access platform version information
191 */
192psa_status_t psa_fwu_query(psa_image_id_t image_id,
193 psa_image_info_t *info);
194
195/**
196 * \brief Requests the platform to reboot. On success, the platform initiates
197 * a reboot, and might not return to the caller.
198 *
199 * \return A status indicating the success/failure of the operation
200 *
201 * \retval PSA_SUCCESS The platform will reboot soon
202 * \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
203 * reboot the platform
204 */
205psa_status_t psa_fwu_request_reboot(void);
206
207/**
208 * \brief Indicates to the implementation that the upgrade was successful.
209 *
Sherry Zhang2da977d2021-05-10 16:59:05 +0800210 * \param[in] image_id The image_id of the image to query
211 *
Sherry Zhang07b42412021-01-07 14:19:41 +0800212 * \return A status indicating the success/failure of the operation
213 *
214 * \retval PSA_SUCCESS The image and its dependencies have
215 * transitioned into a PSA_IMAGE_INSTALLED
216 * state
217 * \retval PSA_ERROR_NOT_SUPPORTED The implementation does not support a
218 * PSA_IMAGE_PENDING_INSTALL state
219 * \retval PSA_ERROR_NOT_PERMITTED The caller is not permitted to make
220 * this call
221 */
Sherry Zhang2da977d2021-05-10 16:59:05 +0800222psa_status_t psa_fwu_accept(psa_image_id_t image_id);
Sherry Zhang07b42412021-01-07 14:19:41 +0800223
224/**
225 * \brief Stores a manifest object and associates it with a particular image ID.
226 *
227 * \param[in] image_id The identifier of the image
228 *
229 * \param[in] manifest A pointer to a buffer containing a manifest
230 * object
231 *
232 * \param[in] manifest_size The size of the manifest parameter
233 *
234 * \param[in] manifest_dependency Output parameter containing the hash of a
235 * required manifest when
236 * PSA_ERROR_DEPENDENCY_NEEDED is returned
237 *
238 * \return A status indicating the success/failure of the operation
239 *
240 * \retval PSA_SUCCESS The manifest is persisted
241 * \retval PSA_ERROR_NOT_PERMITTED The manifest is too old to be
242 * installed
243 * \retval PSA_ERROR_WRONG_DEVICE The manifest is not intended for this
244 * device
245 * \retval PSA_ERROR_INVALID_SIGNATURE The manifest signature is not valid
246 * \retval PSA_ERROR_DEPENDENCY_NEEDED A different manifest is needed
247 * \retval PSA_ERROR_INVALID_ARGUMENT Parameter size is 0 or a pointer
248 * parameter is NULL
249 * \retval PSA_ERROR_COMMUNICATION_FAILURE The system could not communicate with
250 * the installer
251 * \retval PSA_ERROR_NOT_SUPPORTED This function is not implemented
252 * \retval PSA_ERROR_CURRENTLY_INSTALLING An existing manifest for image ID is
253 * currently being installed and is
254 * locked from writing
255 * \retval PSA_ERROR_GENERIC_ERROR A fatal error occurred
256 */
257psa_status_t psa_fwu_set_manifest(psa_image_id_t image_id,
258 const void *manifest,
259 size_t manifest_size,
260 psa_hash_t *manifest_dependency);
261
262
263#ifdef __cplusplus
264}
265#endif
266#endif /* PSA_UPDATE_H */