1 /*
2  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "secure_storage_provider.h"
8 #include "components/common/utils/include/util.h"
9 #include "components/rpc/common/endpoint/rpc_service_interface.h"
10 #include "protocols/service/secure_storage/packed-c/secure_storage_proto.h"
11 
set_handler(void * context,struct rpc_request * req)12 static rpc_status_t set_handler(void *context, struct rpc_request *req)
13 {
14 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
15 	struct secure_storage_request_set *request_desc = NULL;
16 	size_t request_length = 0;
17 
18 	/* Checking if the descriptor fits into the request buffer */
19 	if (req->request.data_length < sizeof(*request_desc))
20 		return RPC_ERROR_INVALID_REQUEST_BODY;
21 
22 	request_desc = (struct secure_storage_request_set *)(req->request.data);
23 
24 	/* Checking for overflow */
25 	if (ADD_OVERFLOW(sizeof(*request_desc), request_desc->data_length, &request_length))
26 		return RPC_ERROR_INVALID_REQUEST_BODY;
27 
28 	/* Checking if the request descriptor and the data fits into the request buffer */
29 	if (req->request.data_length < request_length)
30 		return RPC_ERROR_INVALID_REQUEST_BODY;
31 
32 	req->service_status = this_context->backend->interface->set(
33 		this_context->backend->context, req->source_id, request_desc->uid,
34 		request_desc->data_length, request_desc->p_data,
35 		request_desc->create_flags);
36 
37 	return RPC_SUCCESS;
38 }
39 
get_handler(void * context,struct rpc_request * req)40 static rpc_status_t get_handler(void *context, struct rpc_request *req)
41 {
42 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
43 	struct secure_storage_request_get *request_desc = NULL;
44 
45 	/* Checking if the request descriptor fits into the request buffer */
46 	if (req->request.data_length < sizeof(*request_desc))
47 		return RPC_ERROR_INVALID_REQUEST_BODY;
48 
49 	request_desc = (struct secure_storage_request_get *)(req->request.data);
50 
51 	/* Clip the requested data size if it's too big for the response buffer */
52 	size_t data_size = MIN(req->response.size, request_desc->data_size);
53 
54 	req->service_status = this_context->backend->interface->get(
55 		this_context->backend->context, req->source_id, request_desc->uid,
56 		request_desc->data_offset, data_size,
57 		req->response.data, &req->response.data_length);
58 
59 	return RPC_SUCCESS;
60 }
61 
get_info_handler(void * context,struct rpc_request * req)62 static rpc_status_t get_info_handler(void *context, struct rpc_request *req)
63 {
64 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
65 	struct secure_storage_request_get_info *request_desc = NULL;
66 	struct secure_storage_response_get_info *response_desc = NULL;
67 	struct psa_storage_info_t storage_info = { 0 };
68 
69 	/* Checking if the descriptor fits into the request buffer */
70 	if (req->request.data_length < sizeof(*request_desc))
71 		return RPC_ERROR_INVALID_REQUEST_BODY;
72 
73 	request_desc = (struct secure_storage_request_get_info *)(req->request.data);
74 
75 	/* Checking if the response structure would fit the response buffer */
76 	if (req->response.size < sizeof(*response_desc))
77 		return RPC_ERROR_INVALID_RESPONSE_BODY;
78 
79 	response_desc = (struct secure_storage_response_get_info *)(req->response.data);
80 
81 	req->service_status = this_context->backend->interface->get_info(
82 		this_context->backend->context, req->source_id, request_desc->uid, &storage_info);
83 
84 	if (req->service_status == PSA_SUCCESS) {
85 		response_desc->capacity = storage_info.capacity;
86 		response_desc->size = storage_info.size;
87 		response_desc->flags = storage_info.flags;
88 		req->response.data_length = sizeof(*response_desc);
89 	}
90 
91 	return RPC_SUCCESS;
92 }
93 
remove_handler(void * context,struct rpc_request * req)94 static rpc_status_t remove_handler(void *context, struct rpc_request *req)
95 {
96 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
97 	struct secure_storage_request_remove *request_desc = NULL;
98 
99 	/* Checking if the descriptor fits into the request buffer */
100 	if (req->request.data_length < sizeof(*request_desc))
101 		return RPC_ERROR_INVALID_REQUEST_BODY;
102 
103 	request_desc = (struct secure_storage_request_remove *)(req->request.data);
104 
105 	req->service_status = this_context->backend->interface->remove(
106 		this_context->backend->context, req->source_id, request_desc->uid);
107 
108 	return RPC_SUCCESS;
109 }
110 
create_handler(void * context,struct rpc_request * req)111 static rpc_status_t create_handler(void *context, struct rpc_request *req)
112 {
113 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
114 	struct secure_storage_request_create *request_desc = NULL;
115 
116 	/* Checking if the descriptor fits into the request buffer */
117 	if (req->request.data_length < sizeof(*request_desc))
118 		return RPC_ERROR_INVALID_REQUEST_BODY;
119 
120 	request_desc = (struct secure_storage_request_create *)(req->request.data);
121 
122 	req->service_status = this_context->backend->interface->create(
123 		this_context->backend->context, req->source_id, request_desc->uid,
124 		request_desc->capacity, request_desc->create_flags);
125 
126 	return RPC_SUCCESS;
127 }
128 
set_extended_handler(void * context,struct rpc_request * req)129 static rpc_status_t set_extended_handler(void *context, struct rpc_request *req)
130 {
131 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
132 	struct secure_storage_request_set_extended *request_desc = NULL;
133 	size_t request_length = 0;
134 
135 	/* Checking if the descriptor fits into the request buffer */
136 	if (req->request.data_length < sizeof(*request_desc))
137 		return RPC_ERROR_INVALID_REQUEST_BODY;
138 
139 	request_desc = (struct secure_storage_request_set_extended *)(req->request.data);
140 
141 	/* Checking for overflow */
142 	if (ADD_OVERFLOW(sizeof(*request_desc), request_desc->data_length, &request_length))
143 		return RPC_ERROR_INVALID_REQUEST_BODY;
144 
145 	/* Checking if the request descriptor and the data fits into the request buffer */
146 	if (req->request.data_length < request_length)
147 		return RPC_ERROR_INVALID_REQUEST_BODY;
148 
149 	req->service_status = this_context->backend->interface->set_extended(
150 		this_context->backend->context, req->source_id, request_desc->uid,
151 		request_desc->data_offset, request_desc->data_length, request_desc->p_data);
152 
153 	return RPC_SUCCESS;
154 }
155 
get_support_handler(void * context,struct rpc_request * req)156 static rpc_status_t get_support_handler(void *context, struct rpc_request *req)
157 {
158 	struct secure_storage_provider *this_context = (struct secure_storage_provider*)context;
159 	struct secure_storage_response_get_support *response_desc = NULL;
160 	uint32_t feature_map;
161 
162 	/* Checking if the response structure would fit the response buffer */
163 	if (req->response.size < sizeof(struct secure_storage_response_get_support))
164 		return RPC_ERROR_INVALID_RESPONSE_BODY;
165 
166 	response_desc = (struct secure_storage_response_get_support *)(req->response.data);
167 
168 	feature_map = this_context->backend->interface->get_support(this_context->backend->context,
169 				req->source_id);
170 
171 	req->service_status = PSA_SUCCESS;
172 	response_desc->support = feature_map;
173 	req->response.data_length = sizeof(struct secure_storage_response_get_support);
174 
175 	return RPC_SUCCESS;
176 }
177 
178 /* Handler mapping table for service */
179 static const struct service_handler handler_table[] = {
180 	{TS_SECURE_STORAGE_OPCODE_SET,	set_handler},
181 	{TS_SECURE_STORAGE_OPCODE_GET,	get_handler},
182 	{TS_SECURE_STORAGE_OPCODE_GET_INFO,	get_info_handler},
183 	{TS_SECURE_STORAGE_OPCODE_REMOVE,	remove_handler},
184 	{TS_SECURE_STORAGE_OPCODE_CREATE,	create_handler},
185 	{TS_SECURE_STORAGE_OPCODE_SET_EXTENDED,	set_extended_handler},
186 	{TS_SECURE_STORAGE_OPCODE_GET_SUPPORT,	get_support_handler}
187 };
188 
secure_storage_provider_init(struct secure_storage_provider * context,struct storage_backend * backend,const struct rpc_uuid * service_uuid)189 struct rpc_service_interface *secure_storage_provider_init(struct secure_storage_provider *context,
190 							   struct storage_backend *backend,
191 							   const struct rpc_uuid *service_uuid)
192 {
193 	struct rpc_service_interface *rpc_interface = NULL;
194 
195 	if (!context || !backend)
196 		return NULL;
197 
198 	service_provider_init(&context->base_provider, context, service_uuid, handler_table,
199 				  sizeof(handler_table) / sizeof(handler_table[0]));
200 
201 	rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
202 
203 	context->backend = backend;
204 
205 	return rpc_interface;
206 }
207 
secure_storage_provider_deinit(struct secure_storage_provider * context)208 void secure_storage_provider_deinit(struct secure_storage_provider *context)
209 {
210 	(void)context;
211 }
212