aboutsummaryrefslogtreecommitdiff
path: root/components/service/secure_storage/provider/secure_flash_store/sfs_provider.c
blob: 76b6cbac165b8bb8641fc2f871aba4da08812810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "sfs_provider.h"
#include "secure_flash_store.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>

#include <stdio.h>

/* Handler mapping table for service */
static const struct service_handler handler_table[] = {
	{TS_SECURE_STORAGE_OPCODE_SET,	sfs_set_handler},
	{TS_SECURE_STORAGE_OPCODE_GET,	sfs_get_handler},
	{TS_SECURE_STORAGE_OPCODE_GET_INFO,	sfs_get_info_handler},
	{TS_SECURE_STORAGE_OPCODE_REMOVE,	sfs_remove_handler}
};

struct rpc_interface *sfs_provider_init(struct sfs_provider *context)
{
	struct rpc_interface *rpc_interface = NULL;

	if (context == NULL)
		goto out;

	if (sfs_init() != PSA_SUCCESS)
		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);

out:
	return rpc_interface;
}

rpc_status_t sfs_set_handler(void *context, struct call_req *req)
{
	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 = sfs_set(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;
}

rpc_status_t sfs_get_handler(void *context, struct call_req *req)
{
	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 = sfs_get(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;
}

rpc_status_t sfs_get_info_handler(void *context, struct call_req *req)
{
	struct secure_storage_request_get_info *request_desc;
	struct secure_storage_response_get_info *response_desc;
	struct secure_storage_response_get_info storage_info; //TODO: unnecessary?
	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 = sfs_get_info(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;
}

rpc_status_t sfs_remove_handler(void *context, struct call_req *req)
{
	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 = sfs_remove(req->caller_id, request_desc->uid);
	call_req_set_opstatus(req, psa_status);

	return TS_RPC_CALL_ACCEPTED;
}