aboutsummaryrefslogtreecommitdiff
path: root/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c')
-rw-r--r--components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
new file mode 100644
index 000000000..11d61e82a
--- /dev/null
+++ b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "secure_storage_provider.h"
+#include <protocols/service/secure_storage/packed-c/secure_storage_proto.h>
+#include <protocols/service/psa/packed-c/status.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <components/rpc/common/endpoint/rpc_interface.h>
+
+
+static rpc_status_t set_handler(void *context, struct call_req *req)
+{
+ struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
+ struct secure_storage_request_set *request_desc;
+ psa_status_t psa_status;
+
+ /* Checking if the descriptor fits into the request buffer */
+ if (req->req_buf.data_len < sizeof(struct secure_storage_request_set))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ request_desc = (struct secure_storage_request_set *)(req->req_buf.data);
+
+ /* Checking for overflow */
+ if (sizeof(struct secure_storage_request_set) + request_desc->data_length < request_desc->data_length)
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ /* Checking if descriptor and data fits into the request buffer */
+ if (req->req_buf.data_len < sizeof(struct secure_storage_request_set) + request_desc->data_length)
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ psa_status = this_context->backend->interface->set(this_context->backend->context,
+ req->caller_id,
+ request_desc->uid,
+ request_desc->data_length,
+ request_desc->p_data,
+ request_desc->create_flags);
+ call_req_set_opstatus(req, psa_status);
+
+ return TS_RPC_CALL_ACCEPTED;
+}
+
+static rpc_status_t get_handler(void *context, struct call_req *req)
+{
+ struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
+ struct secure_storage_request_get *request_desc;
+ psa_status_t psa_status;
+
+ /* Checking if the descriptor fits into the request buffer */
+ if (req->req_buf.data_len < sizeof(struct secure_storage_request_get))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ request_desc = (struct secure_storage_request_get *)(req->req_buf.data);
+
+ /* Check if the requested data would fit into the response buffer. */
+ if (req->resp_buf.size < request_desc->data_size)
+ return TS_RPC_ERROR_INVALID_RESP_BODY;
+
+ psa_status = this_context->backend->interface->get(this_context->backend->context,
+ req->caller_id, request_desc->uid,
+ request_desc->data_offset,
+ request_desc->data_size,
+ req->resp_buf.data, &req->resp_buf.data_len);
+ call_req_set_opstatus(req, psa_status);
+
+ return TS_RPC_CALL_ACCEPTED;
+}
+
+static rpc_status_t get_info_handler(void *context, struct call_req *req)
+{
+ struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
+ struct secure_storage_request_get_info *request_desc;
+ struct secure_storage_response_get_info *response_desc;
+ struct psa_storage_info_t storage_info;
+ psa_status_t psa_status;
+
+ /* Checking if the descriptor fits into the request buffer */
+ if (req->req_buf.data_len < sizeof(struct secure_storage_request_get_info))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ request_desc = (struct secure_storage_request_get_info *)(req->req_buf.data);
+
+ /* Checking if the response structure would fit the response buffer */
+ if (req->resp_buf.size < sizeof(struct secure_storage_response_get_info))
+ return TS_RPC_ERROR_INVALID_RESP_BODY;
+
+ response_desc = (struct secure_storage_response_get_info *)(req->resp_buf.data);
+
+ psa_status = this_context->backend->interface->get_info(this_context->backend->context,
+ req->caller_id,
+ request_desc->uid,
+ &storage_info);
+ call_req_set_opstatus(req, psa_status);
+
+ if (psa_status != PSA_SUCCESS) {
+ req->resp_buf.data_len = 0;
+ }
+ else {
+ response_desc->capacity = storage_info.capacity;
+ response_desc->size = storage_info.size;
+ response_desc->flags = storage_info.flags;
+
+ req->resp_buf.data_len = sizeof(struct secure_storage_response_get_info);
+ }
+
+ return TS_RPC_CALL_ACCEPTED;
+}
+
+static rpc_status_t remove_handler(void *context, struct call_req *req)
+{
+ struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
+ struct secure_storage_request_remove *request_desc;
+ psa_status_t psa_status;
+
+ /* Checking if the descriptor fits into the request buffer */
+ if (req->req_buf.data_len < sizeof(struct secure_storage_request_remove))
+ return TS_RPC_ERROR_INVALID_REQ_BODY;
+
+ request_desc = (struct secure_storage_request_remove *)(req->req_buf.data);
+
+ psa_status = this_context->backend->interface->remove(this_context->backend->context,
+ req->caller_id,
+ request_desc->uid);
+ call_req_set_opstatus(req, psa_status);
+
+ return TS_RPC_CALL_ACCEPTED;
+}
+
+/* Handler mapping table for service */
+static const struct service_handler handler_table[] = {
+ {TS_SECURE_STORAGE_OPCODE_SET, set_handler},
+ {TS_SECURE_STORAGE_OPCODE_GET, get_handler},
+ {TS_SECURE_STORAGE_OPCODE_GET_INFO, get_info_handler},
+ {TS_SECURE_STORAGE_OPCODE_REMOVE, remove_handler}
+};
+
+struct rpc_interface *secure_storage_provider_init(struct secure_storage_provider *context,
+ struct storage_backend *backend)
+{
+ struct rpc_interface *rpc_interface = NULL;
+
+ if (context == NULL)
+ goto out;
+
+ if (backend == NULL)
+ goto out;
+
+ service_provider_init(&context->base_provider, context, handler_table,
+ sizeof(handler_table) / sizeof(handler_table[0]));
+
+ rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
+
+ context->backend = backend;
+
+out:
+ return rpc_interface;
+}
+
+void secure_storage_provider_deinit(struct secure_storage_provider *context)
+{
+ (void)context;
+}