blob: 5af0f1cde3c704ea672326c0540b5d7707005eac [file] [log] [blame]
/*
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef PSA_UPDATE_H
#define PSA_UPDATE_H
#include <stddef.h>
#include <stdint.h>
#include "psa/error.h"
#include "psa/fwu_config.h"
#include "tfm_fwu_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TFM_FWU_INVALID_IMAGE_ID 0
/* The maximum size of an image digest in bytes. This is dependent
* on the hash algorithm used.
*/
#define PSA_FWU_MAX_DIGEST_SIZE 32
#define TFM_IMAGE_INFO_INVALID_DIGEST 0xFF
/* The image ID macros. */
#define FWU_IMAGE_ID_SLOT_POSITION 0U
/* The area where the image is running. */
#define FWU_IMAGE_ID_SLOT_ACTIVE 0x01U
/* The area to stage the image. */
#define FWU_IMAGE_ID_SLOT_STAGE 0x02U
#define FWU_IMAGE_ID_SLOT_MASK 0x00FF
#define FWU_IMAGE_ID_TYPE_POSITION 8U
#define FWU_IMAGE_ID_SPECIFIC_ID_POSITION 16U
#define FWU_CALCULATE_IMAGE_ID(slot, type, specific_id) \
((slot & FWU_IMAGE_ID_SLOT_MASK) | \
(type << FWU_IMAGE_ID_TYPE_POSITION) | \
(specific_id << FWU_IMAGE_ID_SPECIFIC_ID_POSITION))
#define FWU_IMAGE_ID_GET_TYPE(image_id) (image_id >> FWU_IMAGE_ID_TYPE_POSITION)
#define FWU_IMAGE_ID_GET_SLOT(image_id) (image_id & FWU_IMAGE_ID_SLOT_MASK)
/* Image state macros. */
#define PSA_IMAGE_UNDEFINED 0
#define PSA_IMAGE_CANDIDATE 1
#define PSA_IMAGE_INSTALLED 2
#define PSA_IMAGE_REJECTED 3
#define PSA_IMAGE_PENDING_INSTALL 4
#define PSA_IMAGE_REBOOT_NEEDED 5
/*
* image_id[7:0]: slot.
* image_id[15:8]: image type.
* image_id[31:16]: specific image ID.
*/
typedef uint32_t psa_image_id_t;
typedef struct tfm_image_version_s {
uint8_t iv_major;
uint8_t iv_minor;
uint16_t iv_revision;
uint32_t iv_build_num;
} psa_image_version_t;
typedef struct tfm_image_info_s {
psa_image_version_t version;
uint8_t state;
uint8_t digest[PSA_FWU_MAX_DIGEST_SIZE];
} psa_image_info_t;
typedef struct psa_hash_s {
uint8_t value[PSA_FWU_MAX_DIGEST_SIZE];
} psa_hash_t;
/**
* \brief Writes an image to its staging area.
*
* Writes the image data 'block' with length 'block_size' to its staging area.
* If the image size is less than or equal to PSA_FWU_MAX_BLOCK_SIZE, the
* caller can send the entire image in one call.
* If the image size is greater than PSA_FWU_MAX_BLOCK_SIZE, the caller must
* send parts of the image by calling this API multiple times with different
* data blocks.
*
* \param[in] image_id The identifier of the image
* \param[in] block_offset The offset of the block being passed into block,
* in bytes
* \param[in] block A buffer containing a block of image data. This
* might be a complete image or a subset.
* \param[in] block_size Size of block. The size must not be greater than
* PSA_FWU_MAX_BLOCK_SIZE.
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The data in block has been
* successfully stored.
* \retval PSA_ERROR_INVALID_ARGUMENT One of the following error
* conditions occurred:
* The parameter size is greater than
* PSA_FWU_MAX_BLOCK_SIZE;
* The parameter size is 0;
* The combination of offset and size
* is out of bounds.
*
* \retval PSA_ERROR_INSUFFICIENT_MEMORY There is not enough memory to
* process the update
* \retval PSA_ERROR_INSUFFICIENT_STORAGE There is not enough storage to
* process the update
* \retval PSA_ERROR_GENERAL_ERROR A fatal error occurred
* \retval PSA_ERROR_CURRENTLY_INSTALLING The image is currently locked for
* writing.
*/
psa_status_t psa_fwu_write(psa_image_id_t image_id,
size_t block_offset,
const void *block,
size_t block_size);
/**
* \brief Starts the installation of an image.
*
* The authenticity and integrity of the image is checked during installation.
* If a reboot is required to complete installation then the implementation
* can choose to defer the authenticity checks to that point.
*
* \param[in] image_id The identifier of the image to install
* \param[out] dependency_uuid If PSA_ERROR_DEPENDENCY_NEEDED is returned,
* this parameter is filled with dependency
* information
* \param[out] dependency_version If PSA_ERROR_DEPENDENCY_NEEDED is returned,
* this parameter is filled with the minimum
* required version for the dependency
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The image was successfully
* installed. The platform does not
* require a reboot.
* \retval PSA_SUCCESS_REBOOT A system reboot is needed to finish
* installation.
* \retval PSA_ERROR_INVALID_ARGUMENT Bad input parameter
* \retval PSA_ERROR_INVALID_SIGNATURE The signature is incorrect
* \retval PSA_ERROR_GENERAL_ERROR A fatal error occurred
* \retval PSA_ERROR_DEPENDENCY_NEEDED A different image requires
* installation first
* \retval PSA_ERROR_STORAGE_FAILURE Some persistent storage could not be
* read or written by the
* implementation
*/
psa_status_t psa_fwu_install(psa_image_id_t image_id,
psa_image_id_t *dependency_uuid,
psa_image_version_t *dependency_version);
/**
* \brief Aborts an ongoing installation and erases the staging area of the
* image.
*
* \param[in] image_id The identifier of the image to abort installation
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS Installation of the provided image_id
* has been aborted
* \retval PSA_ERROR_INVALID_ARGUMENT No image with the provided image_id
* is currently being installed
* \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
* abort an installation
*/
psa_status_t psa_fwu_abort(psa_image_id_t image_id);
/**
* \brief Returns information for an image of a particular image_id.
*
* \param[in] image_id The image_id of the image to query
*
* \param[out] info Output parameter for image information
* related to the image_id
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS Image information has been returned
* \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
* access platform version information
*/
psa_status_t psa_fwu_query(psa_image_id_t image_id,
psa_image_info_t *info);
/**
* \brief Requests the platform to reboot. On success, the platform initiates
* a reboot, and might not return to the caller.
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The platform will reboot soon
* \retval PSA_ERROR_NOT_PERMITTED The caller is not authorized to
* reboot the platform
*/
psa_status_t psa_fwu_request_reboot(void);
/**
* \brief Indicates to the implementation that the upgrade was successful.
*
* \param[in] image_id The image_id of the image to query
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The image and its dependencies have
* transitioned into a PSA_IMAGE_INSTALLED
* state
* \retval PSA_ERROR_NOT_SUPPORTED The implementation does not support a
* PSA_IMAGE_PENDING_INSTALL state
* \retval PSA_ERROR_NOT_PERMITTED The caller is not permitted to make
* this call
*/
psa_status_t psa_fwu_accept(psa_image_id_t image_id);
/**
* \brief Stores a manifest object and associates it with a particular image ID.
*
* \param[in] image_id The identifier of the image
*
* \param[in] manifest A pointer to a buffer containing a manifest
* object
*
* \param[in] manifest_size The size of the manifest parameter
*
* \param[in] manifest_dependency Output parameter containing the hash of a
* required manifest when
* PSA_ERROR_DEPENDENCY_NEEDED is returned
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The manifest is persisted
* \retval PSA_ERROR_NOT_PERMITTED The manifest is too old to be
* installed
* \retval PSA_ERROR_WRONG_DEVICE The manifest is not intended for this
* device
* \retval PSA_ERROR_INVALID_SIGNATURE The manifest signature is not valid
* \retval PSA_ERROR_DEPENDENCY_NEEDED A different manifest is needed
* \retval PSA_ERROR_INVALID_ARGUMENT Parameter size is 0 or a pointer
* parameter is NULL
* \retval PSA_ERROR_COMMUNICATION_FAILURE The system could not communicate with
* the installer
* \retval PSA_ERROR_NOT_SUPPORTED This function is not implemented
* \retval PSA_ERROR_CURRENTLY_INSTALLING An existing manifest for image ID is
* currently being installed and is
* locked from writing
* \retval PSA_ERROR_GENERIC_ERROR A fatal error occurred
*/
psa_status_t psa_fwu_set_manifest(psa_image_id_t image_id,
const void *manifest,
size_t manifest_size,
psa_hash_t *manifest_dependency);
#ifdef __cplusplus
}
#endif
#endif /* PSA_UPDATE_H */