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