From d5130d33d7447fcde022889ec02bdbaa066bd5bf Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Thu, 22 Jul 2021 15:58:03 +0800 Subject: [PATCH] TFM: Add missing IPC file for PSA Firmware Update On a target that doesn't support Firmware Update, compilation still works, and any attempt to call the Firmware Update API returns a runtime error which is good enough. --- .../TARGET_TFM_LATEST/CMakeLists.txt | 1 + .../src/tfm_firmware_update_ipc_api.c | 193 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt index d4e2c8c889..8e32e9212d 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/CMakeLists.txt @@ -34,6 +34,7 @@ target_sources(mbed-psa INTERFACE src/os_wrapper_cmsis_rtos_v2.c src/tfm_crypto_ipc_api.c + src/tfm_firmware_update_ipc_api.c src/tfm_initial_attestation_ipc_api.c src/tfm_its_ipc_api.c src/tfm_platform_ipc_api.c diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c new file mode 100644 index 0000000000..0118488f57 --- /dev/null +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/src/tfm_firmware_update_ipc_api.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "psa/update.h" +#include "tfm_api.h" + +#include "psa/client.h" +#include "psa_manifest/sid.h" + +#define IOVEC_LEN(x) (uint32_t)(sizeof(x)/sizeof(x[0])) + +psa_status_t psa_fwu_write(const psa_image_id_t image_id, + size_t block_offset, + const void *block, + size_t block_size) +{ + psa_status_t status; + psa_handle_t handle; + + psa_invec in_vec[] = { + { .base = &image_id, .len = sizeof(image_id) }, + { .base = &block_offset, .len = sizeof(block_offset) }, + { .base = block, .len = block_size } + }; + + handle = psa_connect(TFM_FWU_WRITE_SID, TFM_FWU_WRITE_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, + 0); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +psa_status_t psa_fwu_install(const psa_image_id_t image_id, + psa_image_id_t *dependency_uuid, + psa_image_version_t *dependency_version) +{ + psa_status_t status; + psa_handle_t handle; + + psa_invec in_vec[] = { + { .base = &image_id, .len = sizeof(image_id) } + }; + + psa_outvec out_vec[] = { + { .base = dependency_uuid, .len = sizeof(*dependency_uuid) }, + { .base = dependency_version, .len = sizeof(*dependency_version)} + }; + + if ((dependency_uuid == NULL) || (dependency_version == NULL)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + handle = psa_connect(TFM_FWU_INSTALL_SID, TFM_FWU_INSTALL_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), + out_vec, IOVEC_LEN(out_vec)); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +psa_status_t psa_fwu_abort(const psa_image_id_t image_id) +{ + psa_status_t status; + psa_handle_t handle; + + psa_invec in_vec[] = { + { .base = &image_id, .len = sizeof(image_id) } + }; + + handle = psa_connect(TFM_FWU_ABORT_SID, TFM_FWU_ABORT_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), NULL, + 0); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +psa_status_t psa_fwu_query(const psa_image_id_t image_id, psa_image_info_t *info) +{ + psa_status_t status; + psa_handle_t handle; + + psa_invec in_vec[] = { + { .base = &image_id, .len = sizeof(image_id) } + }; + psa_outvec out_vec[] = { + { .base = info, .len = sizeof(*info)} + }; + + handle = psa_connect(TFM_FWU_QUERY_SID, TFM_FWU_QUERY_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, in_vec, IOVEC_LEN(in_vec), out_vec, + IOVEC_LEN(out_vec)); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +psa_status_t psa_fwu_request_reboot(void) +{ + psa_handle_t handle; + psa_status_t status; + + handle = psa_connect(TFM_FWU_REQUEST_REBOOT_SID, + TFM_FWU_REQUEST_REBOOT_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +psa_status_t psa_fwu_accept(void) +{ + psa_handle_t handle; + psa_status_t status; + + handle = psa_connect(TFM_FWU_ACCEPT_SID, + TFM_FWU_ACCEPT_VERSION); + if (!PSA_HANDLE_IS_VALID(handle)) { + return PSA_ERROR_GENERIC_ERROR; + } + + status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0); + + psa_close(handle); + + if (status == (psa_status_t)TFM_ERROR_INVALID_PARAMETER) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + return status; +} + +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) +{ + psa_status_t status; + + status = PSA_ERROR_NOT_SUPPORTED; + + return status; +}