summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch523
1 files changed, 523 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch
new file mode 100644
index 0000000000..cac43ec4bc
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-security/trusted-services/corstone1000/0006-Add-secure-storage-ipc-backend.patch
@@ -0,0 +1,523 @@
+From 0df82487a7a253c601ca20ca1bd64fbb9ed64230 Mon Sep 17 00:00:00 2001
+From: Vishnu Banavath <vishnu.banavath@arm.com>
+Date: Fri, 3 Dec 2021 19:19:24 +0000
+Subject: [PATCH 06/19] Add secure storage ipc backend
+
+Add secure storage ipc ff-m implementation which may use
+openamp as rpc to communicate with other processor.
+
+Upstream-Status: Pending
+Signed-off-by: Vishnu Banavath <vishnu.banavath@arm.com>
+Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
+---
+ .../service/common/psa_ipc/service_psa_ipc.c | 143 +++++++++++-
+ .../secure_storage_ipc/component.cmake | 14 ++
+ .../secure_storage_ipc/secure_storage_ipc.c | 214 ++++++++++++++++++
+ .../secure_storage_ipc/secure_storage_ipc.h | 52 +++++
+ deployments/se-proxy/se-proxy.cmake | 1 +
+ 5 files changed, 420 insertions(+), 4 deletions(-)
+ create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/component.cmake
+ create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+ create mode 100644 components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
+
+diff --git a/components/service/common/psa_ipc/service_psa_ipc.c b/components/service/common/psa_ipc/service_psa_ipc.c
+index e8093c20a523..95a07c135f31 100644
+--- a/components/service/common/psa_ipc/service_psa_ipc.c
++++ b/components/service/common/psa_ipc/service_psa_ipc.c
+@@ -16,6 +16,52 @@
+ #include <psa/client.h>
+ #include "service_psa_ipc_openamp_lib.h"
+
++static struct psa_invec *psa_call_in_vec_param(uint8_t *req)
++{
++ return (struct psa_invec *)(req + sizeof(struct ns_openamp_msg));
++}
++
++static struct psa_outvec *psa_call_out_vec_param(uint8_t *req, size_t in_len)
++{
++ return (struct psa_outvec *)(req + sizeof(struct ns_openamp_msg) +
++ (in_len * sizeof(struct psa_invec)));
++}
++
++static size_t psa_call_header_len(const struct psa_invec *in_vec, size_t in_len,
++ struct psa_outvec *out_vec, size_t out_len)
++{
++ return sizeof(struct ns_openamp_msg) + (in_len * sizeof(*in_vec)) +
++ (out_len * sizeof(*out_vec));
++}
++
++static size_t psa_call_in_vec_len(const struct psa_invec *in_vec, size_t in_len)
++{
++ size_t req_len = 0;
++ int i;
++
++ if (!in_vec || !in_len)
++ return 0;
++
++ for (i = 0; i < in_len; i++)
++ req_len += in_vec[i].len;
++
++ return req_len;
++}
++
++static size_t psa_call_out_vec_len(const struct psa_outvec *out_vec, size_t out_len)
++{
++ size_t resp_len = 0;
++ int i;
++
++ if (!out_vec || !out_len)
++ return 0;
++
++ for (i = 0; i < out_len; i++)
++ resp_len += out_vec[i].len;
++
++ return resp_len;
++}
++
+ psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+ uint32_t version)
+ {
+@@ -31,7 +77,7 @@ psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+ rpc_handle = rpc_caller_begin(caller, &req,
+ sizeof(struct ns_openamp_msg));
+ if (!rpc_handle) {
+- EMSG("psa_connect: could not get handle");
++ EMSG("psa_connect: could not get rpc handle");
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+@@ -56,14 +102,100 @@ psa_handle_t psa_connect(struct rpc_caller *caller, uint32_t sid,
+ return resp_msg ? (psa_handle_t)resp_msg->reply : PSA_NULL_HANDLE;
+ }
+
+-psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t handle,
++psa_status_t psa_call(struct rpc_caller *caller, psa_handle_t psa_handle,
+ int32_t type, const struct psa_invec *in_vec,
+ size_t in_len, struct psa_outvec *out_vec, size_t out_len)
+ {
++ psa_status_t psa_status = PSA_SUCCESS;
++ struct s_openamp_msg *resp_msg = NULL;
++ struct psa_outvec *out_vec_param;
++ struct psa_invec *in_vec_param;
++ struct ns_openamp_msg *req_msg;
++ rpc_call_handle rpc_handle;
++ size_t out_vec_len;
++ size_t in_vec_len;
++ size_t header_len;
++ uint8_t *payload;
++ size_t resp_len;
++ uint8_t *resp;
++ uint8_t *req;
++ int ret;
++ int i;
++
++ if ((psa_handle == PSA_NULL_HANDLE) || !caller)
++ return PSA_ERROR_INVALID_ARGUMENT;
++
++ header_len = psa_call_header_len(in_vec, in_len, out_vec, out_len);
++ in_vec_len = psa_call_in_vec_len(in_vec, in_len);
++ out_vec_len = psa_call_out_vec_len(out_vec, out_len);
+
++ rpc_handle = rpc_caller_begin(caller, &req, header_len + in_vec_len);
++ if (!rpc_handle) {
++ EMSG("psa_call: could not get handle");
++ return PSA_ERROR_GENERIC_ERROR;
++ }
++
++ payload = req + header_len;
++
++ out_vec_param = psa_call_out_vec_param(req, in_len);
++ in_vec_param = psa_call_in_vec_param(req);
++
++ req_msg = (struct ns_openamp_msg *)req;
++
++ req_msg->call_type = OPENAMP_PSA_CALL;
++ req_msg->request_id = 1234;
++ req_msg->params.psa_call_params.handle = psa_handle;
++ req_msg->params.psa_call_params.type = type;
++ req_msg->params.psa_call_params.in_len = in_len;
++ req_msg->params.psa_call_params.in_vec = rpc_caller_virt_to_phys(caller, in_vec_param);
++ req_msg->params.psa_call_params.out_len = out_len;
++ req_msg->params.psa_call_params.out_vec = rpc_caller_virt_to_phys(caller, out_vec_param);
++
++ for (i = 0; i < in_len; i++) {
++ in_vec_param[i].base = rpc_caller_virt_to_phys(caller, payload);
++ in_vec_param[i].len = in_vec[i].len;
++
++ memcpy(payload, in_vec[i].base, in_vec[i].len);
++ payload += in_vec[i].len;
++ }
++
++ for (i = 0; i < out_len; i++) {
++ out_vec_param[i].base = NULL;
++ out_vec_param[i].len = out_vec[i].len;
++ }
++
++ ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
++ &resp_len);
++ if (ret != TS_RPC_CALL_ACCEPTED) {
++ EMSG("psa_call: invoke failed: %d", ret);
++ return PSA_ERROR_GENERIC_ERROR;
++ }
++
++ if (psa_status != PSA_SUCCESS) {
++ EMSG("psa_call: psa_status invoke failed: %d", psa_status);
++ return PSA_ERROR_GENERIC_ERROR;
++ }
++
++ resp_msg = (struct s_openamp_msg *)resp;
++
++ if (!resp_msg || !out_len || resp_msg->reply != PSA_SUCCESS)
++ goto caller_end;
++
++ out_vec_param = (struct psa_outvec *)rpc_caller_phys_to_virt(caller,
++ resp_msg->params.out_vec);
++
++ for (i = 0; i < resp_msg->params.out_len; i++) {
++ memcpy(out_vec[i].base, rpc_caller_phys_to_virt(caller, out_vec_param[i].base),
++ out_vec[i].len);
++ }
++
++caller_end:
++ rpc_caller_end(caller, rpc_handle);
++
++ return resp_msg ? resp_msg->reply : PSA_ERROR_COMMUNICATION_FAILURE;
+ }
+
+-void psa_close(struct rpc_caller *caller, psa_handle_t handle)
++void psa_close(struct rpc_caller *caller, psa_handle_t psa_handle)
+ {
+ psa_status_t psa_status = PSA_SUCCESS;
+ struct s_openamp_msg *resp_msg = NULL;
+@@ -74,6 +206,9 @@ void psa_close(struct rpc_caller *caller, psa_handle_t handle)
+ uint8_t *req;
+ int ret;
+
++ if ((psa_handle == PSA_NULL_HANDLE) || !caller)
++ return;
++
+ rpc_handle = rpc_caller_begin(caller, &req,
+ sizeof(struct ns_openamp_msg));
+ if (!rpc_handle) {
+@@ -84,7 +219,7 @@ void psa_close(struct rpc_caller *caller, psa_handle_t handle)
+ req_msg = (struct ns_openamp_msg *)req;
+
+ req_msg->call_type = OPENAMP_PSA_CLOSE;
+- req_msg->params.psa_close_params.handle = handle;
++ req_msg->params.psa_close_params.handle = psa_handle;
+
+ ret = rpc_caller_invoke(caller, rpc_handle, 0, &psa_status, &resp,
+ &resp_len);
+diff --git a/components/service/secure_storage/backend/secure_storage_ipc/component.cmake b/components/service/secure_storage/backend/secure_storage_ipc/component.cmake
+new file mode 100644
+index 000000000000..5d8f6714e0bd
+--- /dev/null
++++ b/components/service/secure_storage/backend/secure_storage_ipc/component.cmake
+@@ -0,0 +1,14 @@
++#-------------------------------------------------------------------------------
++# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
++#
++# SPDX-License-Identifier: BSD-3-Clause
++#
++#-------------------------------------------------------------------------------
++if (NOT DEFINED TGT)
++ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
++endif()
++
++target_sources(${TGT} PRIVATE
++ "${CMAKE_CURRENT_LIST_DIR}/secure_storage_ipc.c"
++ )
++
+diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+new file mode 100644
+index 000000000000..9b55f77dd395
+--- /dev/null
++++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.c
+@@ -0,0 +1,214 @@
++/*
++ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#include <protocols/rpc/common/packed-c/status.h>
++#include "secure_storage_ipc.h"
++#include <psa/client.h>
++#include <psa/sid.h>
++#include <rpc_caller.h>
++#include <string.h>
++#include <trace.h>
++
++
++static psa_status_t secure_storage_ipc_set(void *context, uint32_t client_id,
++ psa_storage_uid_t uid, size_t data_length,
++ const void *p_data, psa_storage_create_flags_t create_flags)
++{
++ struct secure_storage_ipc *ipc = context;
++ struct rpc_caller *caller = ipc->client.caller;
++ psa_handle_t psa_handle;
++ psa_status_t psa_status;
++ struct psa_invec in_vec[] = {
++ { .base = &uid, .len = sizeof(uid) },
++ { .base = p_data, .len = data_length },
++ { .base = &create_flags, .len = sizeof(create_flags) },
++ };
++
++ (void)client_id;
++
++ ipc->client.rpc_status = TS_RPC_CALL_ACCEPTED;
++
++ /* Validating input parameters */
++ if (p_data == NULL)
++ return PSA_ERROR_INVALID_ARGUMENT;
++
++ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
++ TFM_PS_SET, in_vec, IOVEC_LEN(in_vec), NULL, 0);
++ if (psa_status < 0)
++ EMSG("ipc_set: psa_call failed: %d", psa_status);
++
++ return psa_status;
++}
++
++static psa_status_t secure_storage_ipc_get(void *context,
++ uint32_t client_id,
++ psa_storage_uid_t uid,
++ size_t data_offset,
++ size_t data_size,
++ void *p_data,
++ size_t *p_data_length)
++{
++ struct secure_storage_ipc *ipc = context;
++ struct rpc_caller *caller = ipc->client.caller;
++ psa_handle_t psa_handle;
++ psa_status_t psa_status;
++ uint32_t offset = (uint32_t)data_offset;
++ struct psa_invec in_vec[] = {
++ { .base = &uid, .len = sizeof(uid) },
++ { .base = &offset, .len = sizeof(offset) },
++ };
++ struct psa_outvec out_vec[] = {
++ { .base = p_data, .len = data_size },
++ };
++
++ if (!p_data_length) {
++ EMSG("ipc_get: p_data_length not defined");
++ return PSA_ERROR_INVALID_ARGUMENT;
++ }
++
++ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
++ TFM_PS_GET, in_vec, IOVEC_LEN(in_vec),
++ out_vec, IOVEC_LEN(out_vec));
++ if (psa_status == PSA_SUCCESS)
++ *p_data_length = out_vec[0].len;
++
++ return psa_status;
++}
++
++static psa_status_t secure_storage_ipc_get_info(void *context,
++ uint32_t client_id,
++ psa_storage_uid_t uid,
++ struct psa_storage_info_t *p_info)
++{
++ struct secure_storage_ipc *ipc = context;
++ struct rpc_caller *caller = ipc->client.caller;
++ psa_handle_t psa_handle;
++ psa_status_t psa_status;
++ struct psa_invec in_vec[] = {
++ { .base = &uid, .len = sizeof(uid) },
++ };
++ struct psa_outvec out_vec[] = {
++ { .base = p_info, .len = sizeof(*p_info) },
++ };
++
++ (void)client_id;
++
++ /* Validating input parameters */
++ if (!p_info)
++ return PSA_ERROR_INVALID_ARGUMENT;
++
++ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
++ TFM_PS_GET_INFO, in_vec,
++ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
++ if (psa_status != PSA_SUCCESS)
++ EMSG("ipc_get_info: failed to psa_call: %d", psa_status);
++
++ return psa_status;
++}
++
++static psa_status_t secure_storage_ipc_remove(void *context,
++ uint32_t client_id,
++ psa_storage_uid_t uid)
++{
++ struct secure_storage_ipc *ipc = context;
++ struct rpc_caller *caller = ipc->client.caller;
++ psa_handle_t psa_handle;
++ psa_status_t psa_status;
++ struct psa_invec in_vec[] = {
++ { .base = &uid, .len = sizeof(uid) },
++ };
++
++ (void)client_id;
++
++ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
++ TFM_PS_REMOVE, in_vec,
++ IOVEC_LEN(in_vec), NULL, 0);
++ if (psa_status != PSA_SUCCESS)
++ EMSG("ipc_remove: failed to psa_call: %d", psa_status);
++
++ return psa_status;
++}
++
++static psa_status_t secure_storage_ipc_create(void *context,
++ uint32_t client_id,
++ uint64_t uid,
++ size_t capacity,
++ uint32_t create_flags)
++{
++ (void)context;
++ (void)uid;
++ (void)client_id;
++ (void)capacity;
++ (void)create_flags;
++
++ return PSA_ERROR_NOT_SUPPORTED;
++}
++
++static psa_status_t secure_storage_set_extended(void *context,
++ uint32_t client_id,
++ uint64_t uid,
++ size_t data_offset,
++ size_t data_length,
++ const void *p_data)
++{
++ (void)context;
++ (void)uid;
++ (void)client_id;
++ (void)data_offset;
++ (void)data_length;
++ (void)p_data;
++
++ return PSA_ERROR_NOT_SUPPORTED;
++}
++
++static uint32_t secure_storage_get_support(void *context, uint32_t client_id)
++{
++ struct secure_storage_ipc *ipc = context;
++ struct rpc_caller *caller = ipc->client.caller;
++ psa_handle_t psa_handle;
++ psa_status_t psa_status;
++ uint32_t support_flags;
++ struct psa_outvec out_vec[] = {
++ { .base = &support_flags, .len = sizeof(support_flags) },
++ };
++
++ (void)client_id;
++
++ psa_status = psa_call(caller, TFM_PROTECTED_STORAGE_SERVICE_HANDLE,
++ TFM_PS_GET_SUPPORT, NULL, 0,
++ out_vec, IOVEC_LEN(out_vec));
++ if (psa_status != PSA_SUCCESS)
++ EMSG("ipc_get_support: failed to psa_call: %d", psa_status);
++
++ return psa_status;
++}
++
++struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
++ struct rpc_caller *caller)
++{
++ service_client_init(&context->client, caller);
++
++ static const struct storage_backend_interface interface =
++ {
++ .set = secure_storage_ipc_set,
++ .get = secure_storage_ipc_get,
++ .get_info = secure_storage_ipc_get_info,
++ .remove = secure_storage_ipc_remove,
++ .create = secure_storage_ipc_create,
++ .set_extended = secure_storage_set_extended,
++ .get_support = secure_storage_get_support,
++ };
++
++ context->backend.context = context;
++ context->backend.interface = &interface;
++
++ return &context->backend;
++}
++
++void secure_storage_ipc_deinit(struct secure_storage_ipc *context)
++{
++ service_client_deinit(&context->client);
++}
+diff --git a/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
+new file mode 100644
+index 000000000000..e8c1e8fd2f92
+--- /dev/null
++++ b/components/service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ */
++
++#ifndef SECURE_STORAGE_IPC_H
++#define SECURE_STORAGE_IPC_H
++
++#include <service/secure_storage/backend/storage_backend.h>
++#include <service/common/client/service_client.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/**
++ * @brief Secure storage ipc instance
++ */
++struct secure_storage_ipc
++{
++ struct storage_backend backend;
++ struct service_client client;
++};
++
++/**
++ * @brief Initialize a secure storage ipc client
++ *
++ * A secure storage client is a storage backend that makes RPC calls
++ * to a remote secure storage provider.
++ *
++ * @param[in] context Instance data
++ * @param[in] rpc_caller RPC caller instance
++ *
++ *
++ * @return Pointer to inialized storage backend or NULL on failure
++ */
++struct storage_backend *secure_storage_ipc_init(struct secure_storage_ipc *context,
++ struct rpc_caller *caller);
++
++/**
++ * @brief Deinitialize a secure storage ipc client
++ *
++ * @param[in] context Instance data
++ */
++void secure_storage_ipc_deinit(struct secure_storage_ipc *context);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* SECURE_STORAGE_IPC_H */
+diff --git a/deployments/se-proxy/se-proxy.cmake b/deployments/se-proxy/se-proxy.cmake
+index dd0c5d00c21e..cd51460406ca 100644
+--- a/deployments/se-proxy/se-proxy.cmake
++++ b/deployments/se-proxy/se-proxy.cmake
+@@ -45,6 +45,7 @@ add_components(TARGET "se-proxy"
+ "components/service/crypto/factory/full"
+ "components/service/secure_storage/include"
+ "components/service/secure_storage/frontend/secure_storage_provider"
++ "components/service/secure_storage/backend/secure_storage_ipc"
+ "components/service/attestation/include"
+ "components/service/attestation/provider"
+ "components/service/attestation/provider/serializer/packed-c"
+--
+2.38.0
+