diff --git a/components/TARGET_PSA/TARGET_MBED_SPM/COMPONENT_SPE/psa_setup.c b/components/TARGET_PSA/TARGET_MBED_SPM/COMPONENT_SPE/psa_setup.c index 3738c7b8fc..da2b58ee71 100644 --- a/components/TARGET_PSA/TARGET_MBED_SPM/COMPONENT_SPE/psa_setup.c +++ b/components/TARGET_PSA/TARGET_MBED_SPM/COMPONENT_SPE/psa_setup.c @@ -395,6 +395,18 @@ spm_rot_service_t platform_rot_services[] = { .tail = NULL } }, + { + .sid = PSA_PLATFORM_IOCTL, + .mask = PSA_PLATFORM_IOCTL_MSK, + .partition = NULL, + .min_version = 1, + .min_version_policy = PSA_MINOR_VERSION_POLICY_RELAXED, + .allow_nspe = true, + .queue = { + .head = NULL, + .tail = NULL + } + }, }; /* External SIDs used by PLATFORM */ diff --git a/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_service_list.inc b/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_service_list.inc index 6373268cfe..1248107af7 100644 --- a/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_service_list.inc +++ b/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_service_list.inc @@ -45,6 +45,7 @@ {"PSA_PLATFORM_LC_GET", PLATFORM_ID, PSA_PLATFORM_LC_GET_MSK, 0x00011000, true, 1, TFM_VERSION_POLICY_RELAXED}, {"PSA_PLATFORM_LC_SET", PLATFORM_ID, PSA_PLATFORM_LC_SET_MSK, 0x00011001, true, 1, TFM_VERSION_POLICY_RELAXED}, {"PSA_PLATFORM_SYSTEM_RESET", PLATFORM_ID, PSA_PLATFORM_SYSTEM_RESET_MSK, 0x00011002, true, 1, TFM_VERSION_POLICY_RELAXED}, +{"PSA_PLATFORM_IOCTL", PLATFORM_ID, PSA_PLATFORM_IOCTL_MSK, 0x00011003, true, 1, TFM_VERSION_POLICY_RELAXED}, /* ----------------------------------------------------------------------------- * ITS Services diff --git a/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_spm_signal_defs.h b/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_spm_signal_defs.h index e41c52d073..be52471c55 100644 --- a/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_spm_signal_defs.h +++ b/components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/inc/tfm_spm_signal_defs.h @@ -62,6 +62,8 @@ #define PSA_PLATFORM_LC_SET_MSK (1UL << PSA_PLATFORM_LC_SET_MSK_POS) #define PSA_PLATFORM_SYSTEM_RESET_MSK_POS (6UL) #define PSA_PLATFORM_SYSTEM_RESET_MSK (1UL << PSA_PLATFORM_SYSTEM_RESET_MSK_POS) +#define PSA_PLATFORM_IOCTL_MSK_POS (7UL) +#define PSA_PLATFORM_IOCTL_MSK (1UL << PSA_PLATFORM_IOCTL_MSK_POS) /* ----------------------------------------------------------------------------- * ITS Signals diff --git a/components/TARGET_PSA/inc/psa/tfm_platform_api.h b/components/TARGET_PSA/inc/psa/tfm_platform_api.h new file mode 100644 index 0000000000..86be961268 --- /dev/null +++ b/components/TARGET_PSA/inc/psa/tfm_platform_api.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PLATFORM_API__ +#define __TFM_PLATFORM_API__ + +#include +#include +#include "psa/client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief TFM secure partition platform API version + */ +#define TFM_PLATFORM_API_VERSION_MAJOR (0) +#define TFM_PLATFORM_API_VERSION_MINOR (3) + +/*! + * \enum tfm_platform_err_t + * + * \brief Platform service error types + * + */ +enum tfm_platform_err_t { + TFM_PLATFORM_ERR_SUCCESS = 0, + TFM_PLATFORM_ERR_SYSTEM_ERROR, + TFM_PLATFORM_ERR_INVALID_PARAM, + TFM_PLATFORM_ERR_NOT_SUPPORTED, + + /* Following entry is only to ensure the error code of int size */ + TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX +}; + +typedef int32_t tfm_platform_ioctl_req_t; + +/*! + * \brief Performs a platform-specific service + * + * \param[in] request Request identifier (valid values vary + * based on the platform) + * \param[in] input Input buffer to the requested service (or NULL) + * \param[in,out] output Output buffer to the requested service (or NULL) + * + * \return Returns values as specified by the \ref tfm_platform_err_t + */ +enum tfm_platform_err_t tfm_platform_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *input, + psa_outvec *output); + + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PLATFORM_API__ */ diff --git a/components/TARGET_PSA/services/inc/autogen_sid.h b/components/TARGET_PSA/services/inc/autogen_sid.h index c4fecf5c93..d3440689c1 100644 --- a/components/TARGET_PSA/services/inc/autogen_sid.h +++ b/components/TARGET_PSA/services/inc/autogen_sid.h @@ -56,6 +56,7 @@ #define PSA_PLATFORM_LC_GET 0x00011000 #define PSA_PLATFORM_LC_SET 0x00011001 #define PSA_PLATFORM_SYSTEM_RESET 0x00011002 +#define PSA_PLATFORM_IOCTL 0x00011003 /* ----------------------------------------------------------------------------- * ITS Service IDs diff --git a/components/TARGET_PSA/services/inc/mbed_spm_partitions.h b/components/TARGET_PSA/services/inc/mbed_spm_partitions.h index 5d9c137f86..acf41223ef 100644 --- a/components/TARGET_PSA/services/inc/mbed_spm_partitions.h +++ b/components/TARGET_PSA/services/inc/mbed_spm_partitions.h @@ -115,7 +115,7 @@ * -------------------------------------------------------------------------- */ #define PLATFORM_ID 8 -#define PLATFORM_ROT_SRV_COUNT (3UL) +#define PLATFORM_ROT_SRV_COUNT (4UL) #define PLATFORM_EXT_ROT_SRV_COUNT (1UL) @@ -127,11 +127,14 @@ #define PSA_PLATFORM_LC_SET_MSK (1UL << PSA_PLATFORM_LC_SET_MSK_POS) #define PSA_PLATFORM_SYSTEM_RESET_MSK_POS (6UL) #define PSA_PLATFORM_SYSTEM_RESET_MSK (1UL << PSA_PLATFORM_SYSTEM_RESET_MSK_POS) +#define PSA_PLATFORM_IOCTL_MSK_POS (7UL) +#define PSA_PLATFORM_IOCTL_MSK (1UL << PSA_PLATFORM_IOCTL_MSK_POS) #define PLATFORM_WAIT_ANY_SID_MSK (\ PSA_PLATFORM_LC_GET_MSK | \ PSA_PLATFORM_LC_SET_MSK | \ - PSA_PLATFORM_SYSTEM_RESET_MSK) + PSA_PLATFORM_SYSTEM_RESET_MSK | \ + PSA_PLATFORM_IOCTL_MSK) /* ----------------------------------------------------------------------------- diff --git a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.c b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.c index 9bf5f90dcf..9854633232 100644 --- a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.c +++ b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019 ARM Limited +/* Copyright (c) 2019-2020 Arm Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -45,3 +45,12 @@ MBED_WEAK void mbed_psa_system_reset_impl(void) /* Reset the system */ NVIC_SystemReset(); } + +MBED_WEAK enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *in_vec, + psa_outvec *out_vec) +{ + (void)in_vec; + (void)out_vec; + return TFM_PLATFORM_ERR_NOT_SUPPORTED; +} diff --git a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.h b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.h index 4d4f062a27..29e704f2c3 100644 --- a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.h +++ b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IMPL/platform_srv_impl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019 ARM Limited +/* Copyright (c) 2019-2020 Arm Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -19,10 +19,25 @@ #define __PLATFROM_SRV_IMPL_H__ #include "psa/client.h" +#include "psa/lifecycle.h" #include "mbed_toolchain.h" +#include "tfm_platform_api.h" psa_status_t psa_platfrom_lifecycle_get_impl(uint32_t *lc_state); psa_status_t psa_platfrom_lifecycle_change_request_impl(uint32_t lc_state); MBED_NORETURN void mbed_psa_system_reset_impl(void); +/*! + * \brief Performs a platform-specific service + * + * \param[in] request Request identifier (valid values vary + * based on the platform) + * \param[in] in_vec Input buffer to the requested service (or NULL) + * \param[out] out_vec Output buffer to the requested service (or NULL) + * + * \return Returns values as specified by the \ref tfm_platform_err_t + */ +enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *in_vec, + psa_outvec *out_vec); #endif // __PLATFROM_SRV_IMPL_H__ diff --git a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IPC/platform_ipc.c b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IPC/platform_ipc.c index 61634817d8..92cf1cd868 100644 --- a/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IPC/platform_ipc.c +++ b/components/TARGET_PSA/services/platform/COMPONENT_PSA_SRV_IPC/platform_ipc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019 ARM Limited +/* Copyright (c) 2019-2020 Arm Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -20,6 +20,7 @@ #include "psa/client.h" #include "mbed_toolchain.h" #include "mbed_error.h" +#include "tfm_platform_api.h" uint32_t psa_security_lifecycle_state(void) { @@ -66,3 +67,52 @@ void mbed_psa_system_reset(void) } error("reset failed - cannot connect to service handle=%ld", conn); } + +enum tfm_platform_err_t +tfm_platform_ioctl(tfm_platform_ioctl_req_t request, + psa_invec *input, psa_outvec *output) { + tfm_platform_ioctl_req_t req = request; + struct psa_invec in_vec[2] = { {0} }; + size_t inlen, outlen; + psa_status_t status = PSA_ERROR_CONNECTION_REFUSED; + psa_handle_t handle = PSA_NULL_HANDLE; + + in_vec[0].base = &req; + in_vec[0].len = sizeof(req); + if (input != NULL) + { + in_vec[1].base = input->base; + in_vec[1].len = input->len; + inlen = 2; + } else + { + inlen = 1; + } + + if (output != NULL) + { + outlen = 1; + } else + { + outlen = 0; + } + + handle = psa_connect(PSA_PLATFORM_IOCTL, 1); + if (handle <= 0) + { + return TFM_PLATFORM_ERR_SYSTEM_ERROR; + } + + status = psa_call(handle, + in_vec, inlen, + output, outlen); + psa_close(handle); + + if (status < PSA_SUCCESS) + { + return TFM_PLATFORM_ERR_SYSTEM_ERROR; + } else + { + return (enum tfm_platform_err_t) status; + } +} diff --git a/components/TARGET_PSA/services/platform/COMPONENT_SPE/platform_partition.c b/components/TARGET_PSA/services/platform/COMPONENT_SPE/platform_partition.c index db47444a34..308b3a74c8 100644 --- a/components/TARGET_PSA/services/platform/COMPONENT_SPE/platform_partition.c +++ b/components/TARGET_PSA/services/platform/COMPONENT_SPE/platform_partition.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019 ARM Limited +/* Copyright (c) 2019-2020 Arm Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -17,9 +17,13 @@ #include "mbed_spm_partitions.h" #include "platform_srv_impl.h" +#include "psa/lifecycle.h" #include "psa/internal_trusted_storage.h" #include "psa/service.h" +#define INPUT_BUFFER_SIZE 64 +#define OUTPUT_BUFFER_SIZE 64 + typedef psa_status_t (*SignalHandler)(psa_msg_t *); static psa_status_t lifecycle_get(psa_msg_t *msg) @@ -58,6 +62,92 @@ static MBED_NORETURN psa_status_t system_reset_request(psa_msg_t *msg) mbed_psa_system_reset_impl(); } +static enum tfm_platform_err_t +platform_sp_ioctl_ipc(const psa_msg_t *msg) { + void *input = NULL; + void *output = NULL; + psa_invec invec = {0}; + psa_outvec outvec = {0}; + uint8_t input_buffer[INPUT_BUFFER_SIZE] = {0}; + uint8_t output_buffer[OUTPUT_BUFFER_SIZE] = {0}; + tfm_platform_ioctl_req_t request = 0; + enum tfm_platform_err_t ret = TFM_PLATFORM_ERR_SYSTEM_ERROR; + size_t num = 0; + uint32_t in_len = PSA_MAX_IOVEC; + uint32_t out_len = PSA_MAX_IOVEC; + + while ((in_len > 0) && (msg->in_size[in_len - 1] == 0)) + { + in_len--; + } + + while ((out_len > 0) && (msg->out_size[out_len - 1] == 0)) + { + out_len--; + } + + if ((in_len < 1) || (in_len > 2) || + (out_len > 1)) + { + return TFM_PLATFORM_ERR_SYSTEM_ERROR; + } + + num = psa_read(msg->handle, 0, &request, sizeof(request)); + if (num != sizeof(request)) + { + return PSA_ERROR_PROGRAMMER_ERROR; + } + + if (in_len > 1) + { + if (msg->in_size[1] > INPUT_BUFFER_SIZE) { + return PSA_ERROR_PROGRAMMER_ERROR; + } + num = psa_read(msg->handle, 1, &input_buffer, msg->in_size[1]); + if (num != msg->in_size[1]) { + return PSA_ERROR_PROGRAMMER_ERROR; + } + invec.base = input_buffer; + invec.len = msg->in_size[1]; + input = &invec; + } + + if (out_len > 0) + { + if (msg->out_size[0] > OUTPUT_BUFFER_SIZE) { + return PSA_ERROR_PROGRAMMER_ERROR; + } + outvec.base = output_buffer; + outvec.len = msg->out_size[0]; + output = &outvec; + } + + ret = tfm_platform_hal_ioctl(request, input, output); + + if (output != NULL) + { + psa_write(msg->handle, 0, outvec.base, outvec.len); + } + + return ret; +} + +static psa_status_t platform_ioctl(psa_msg_t *msg) +{ + /* platform_sp_ioctl_ipc returns either psa_status_t or one of the + * following errorcodes: + * enum tfm_platform_err_t { + * TFM_PLATFORM_ERR_SUCCESS = 0, + * TFM_PLATFORM_ERR_SYSTEM_ERROR, + * TFM_PLATFORM_ERR_INVALID_PARAM, + * TFM_PLATFORM_ERR_NOT_SUPPORTED, + * + * TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX + * }; + */ + return platform_sp_ioctl_ipc(msg); +} + static void message_handler(psa_msg_t *msg, SignalHandler handler) { psa_status_t status = PSA_SUCCESS; @@ -102,5 +192,11 @@ void platform_partition_entry(void *ptr) } message_handler(&msg, system_reset_request); } + if ((signals & PSA_PLATFORM_IOCTL_MSK) != 0) { + if (PSA_SUCCESS != psa_get(PSA_PLATFORM_IOCTL_MSK, &msg)) { + continue; + } + message_handler(&msg, platform_ioctl); + } } } diff --git a/components/TARGET_PSA/services/platform/platform_psa.json b/components/TARGET_PSA/services/platform/platform_psa.json index b519504cc5..13a4e6f3c6 100644 --- a/components/TARGET_PSA/services/platform/platform_psa.json +++ b/components/TARGET_PSA/services/platform/platform_psa.json @@ -29,6 +29,14 @@ "non_secure_clients": true, "minor_version": 1, "minor_policy": "RELAXED" + }, + { + "name": "PSA_PLATFORM_IOCTL", + "identifier": "0x00011003", + "signal": "PSA_PLATFORM_IOCTL_MSK", + "non_secure_clients": true, + "minor_version": 1, + "minor_policy": "RELAXED" } ], "extern_sids": [