1 /*
2 * Copyright (c) 2017, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <inttypes.h>
29 #include <secure_storage_ta.h>
30 #include <tee_internal_api.h>
31 #include <tee_internal_api_extensions.h>
32
delete_object(uint32_t param_types,TEE_Param params[4])33 static TEE_Result delete_object(uint32_t param_types, TEE_Param params[4])
34 {
35 const uint32_t exp_param_types =
36 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
37 TEE_PARAM_TYPE_NONE,
38 TEE_PARAM_TYPE_NONE,
39 TEE_PARAM_TYPE_NONE);
40 TEE_ObjectHandle object;
41 TEE_Result res;
42 char *obj_id;
43 size_t obj_id_sz;
44
45 /*
46 * Safely get the invocation parameters
47 */
48 if (param_types != exp_param_types)
49 return TEE_ERROR_BAD_PARAMETERS;
50
51 obj_id_sz = params[0].memref.size;
52 obj_id = TEE_Malloc(obj_id_sz, 0);
53 if (!obj_id)
54 return TEE_ERROR_OUT_OF_MEMORY;
55
56 TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
57
58 /*
59 * Check object exists and delete it
60 */
61 res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
62 obj_id, obj_id_sz,
63 TEE_DATA_FLAG_ACCESS_READ |
64 TEE_DATA_FLAG_ACCESS_WRITE_META, /* we must be allowed to delete it */
65 &object);
66 if (res != TEE_SUCCESS) {
67 EMSG("Failed to open persistent object, res=0x%08x", res);
68 TEE_Free(obj_id);
69 return res;
70 }
71
72 TEE_CloseAndDeletePersistentObject1(object);
73 TEE_Free(obj_id);
74
75 return res;
76 }
77
create_raw_object(uint32_t param_types,TEE_Param params[4])78 static TEE_Result create_raw_object(uint32_t param_types, TEE_Param params[4])
79 {
80 const uint32_t exp_param_types =
81 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
82 TEE_PARAM_TYPE_MEMREF_INPUT,
83 TEE_PARAM_TYPE_NONE,
84 TEE_PARAM_TYPE_NONE);
85 TEE_ObjectHandle object;
86 TEE_Result res;
87 char *obj_id;
88 size_t obj_id_sz;
89 char *data;
90 size_t data_sz;
91 uint32_t obj_data_flag;
92
93 /*
94 * Safely get the invocation parameters
95 */
96 if (param_types != exp_param_types)
97 return TEE_ERROR_BAD_PARAMETERS;
98
99 obj_id_sz = params[0].memref.size;
100 obj_id = TEE_Malloc(obj_id_sz, 0);
101 if (!obj_id)
102 return TEE_ERROR_OUT_OF_MEMORY;
103
104 TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
105
106 data_sz = params[1].memref.size;
107 data = TEE_Malloc(data_sz, 0);
108 if (!data)
109 return TEE_ERROR_OUT_OF_MEMORY;
110 TEE_MemMove(data, params[1].memref.buffer, data_sz);
111
112 /*
113 * Create object in secure storage and fill with data
114 */
115 obj_data_flag = TEE_DATA_FLAG_ACCESS_READ | /* we can later read the oject */
116 TEE_DATA_FLAG_ACCESS_WRITE | /* we can later write into the object */
117 TEE_DATA_FLAG_ACCESS_WRITE_META | /* we can later destroy or rename the object */
118 TEE_DATA_FLAG_OVERWRITE; /* destroy existing object of same ID */
119
120 res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
121 obj_id, obj_id_sz,
122 obj_data_flag,
123 TEE_HANDLE_NULL,
124 NULL, 0, /* we may not fill it right now */
125 &object);
126 if (res != TEE_SUCCESS) {
127 EMSG("TEE_CreatePersistentObject failed 0x%08x", res);
128 TEE_Free(obj_id);
129 TEE_Free(data);
130 return res;
131 }
132
133 res = TEE_WriteObjectData(object, data, data_sz);
134 if (res != TEE_SUCCESS) {
135 EMSG("TEE_WriteObjectData failed 0x%08x", res);
136 TEE_CloseAndDeletePersistentObject1(object);
137 } else {
138 TEE_CloseObject(object);
139 }
140 TEE_Free(obj_id);
141 TEE_Free(data);
142 return res;
143 }
144
read_raw_object(uint32_t param_types,TEE_Param params[4])145 static TEE_Result read_raw_object(uint32_t param_types, TEE_Param params[4])
146 {
147 const uint32_t exp_param_types =
148 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
149 TEE_PARAM_TYPE_MEMREF_OUTPUT,
150 TEE_PARAM_TYPE_NONE,
151 TEE_PARAM_TYPE_NONE);
152 TEE_ObjectHandle object;
153 TEE_ObjectInfo object_info;
154 TEE_Result res;
155 uint32_t read_bytes;
156 char *obj_id;
157 size_t obj_id_sz;
158 char *data;
159 size_t data_sz;
160
161 /*
162 * Safely get the invocation parameters
163 */
164 if (param_types != exp_param_types)
165 return TEE_ERROR_BAD_PARAMETERS;
166
167 obj_id_sz = params[0].memref.size;
168 obj_id = TEE_Malloc(obj_id_sz, 0);
169 if (!obj_id)
170 return TEE_ERROR_OUT_OF_MEMORY;
171
172 TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);
173
174 data_sz = params[1].memref.size;
175 data = TEE_Malloc(data_sz, 0);
176 if (!data)
177 return TEE_ERROR_OUT_OF_MEMORY;
178
179 /*
180 * Check the object exist and can be dumped into output buffer
181 * then dump it.
182 */
183 res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
184 obj_id, obj_id_sz,
185 TEE_DATA_FLAG_ACCESS_READ |
186 TEE_DATA_FLAG_SHARE_READ,
187 &object);
188 if (res != TEE_SUCCESS) {
189 EMSG("Failed to open persistent object, res=0x%08x", res);
190 TEE_Free(obj_id);
191 TEE_Free(data);
192 return res;
193 }
194
195 res = TEE_GetObjectInfo1(object, &object_info);
196 if (res != TEE_SUCCESS) {
197 EMSG("Failed to create persistent object, res=0x%08x", res);
198 goto exit;
199 }
200
201 if (object_info.dataSize > data_sz) {
202 /*
203 * Provided buffer is too short.
204 * Return the expected size together with status "short buffer"
205 */
206 params[1].memref.size = object_info.dataSize;
207 res = TEE_ERROR_SHORT_BUFFER;
208 goto exit;
209 }
210
211 res = TEE_ReadObjectData(object, data, object_info.dataSize,
212 &read_bytes);
213 if (res == TEE_SUCCESS)
214 TEE_MemMove(params[1].memref.buffer, data, read_bytes);
215 if (res != TEE_SUCCESS || read_bytes != object_info.dataSize) {
216 EMSG("TEE_ReadObjectData failed 0x%08x, read %" PRIu32 " over %u",
217 res, read_bytes, object_info.dataSize);
218 goto exit;
219 }
220
221 /* Return the number of byte effectively filled */
222 params[1].memref.size = read_bytes;
223 exit:
224 TEE_CloseObject(object);
225 TEE_Free(obj_id);
226 TEE_Free(data);
227 return res;
228 }
229
TA_CreateEntryPoint(void)230 TEE_Result TA_CreateEntryPoint(void)
231 {
232 /* Nothing to do */
233 return TEE_SUCCESS;
234 }
235
TA_DestroyEntryPoint(void)236 void TA_DestroyEntryPoint(void)
237 {
238 /* Nothing to do */
239 }
240
TA_OpenSessionEntryPoint(uint32_t __unused param_types,TEE_Param __unused params[4],void __unused ** session)241 TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused param_types,
242 TEE_Param __unused params[4],
243 void __unused **session)
244 {
245 /* Nothing to do */
246 return TEE_SUCCESS;
247 }
248
TA_CloseSessionEntryPoint(void __unused * session)249 void TA_CloseSessionEntryPoint(void __unused *session)
250 {
251 /* Nothing to do */
252 }
253
TA_InvokeCommandEntryPoint(void __unused * session,uint32_t command,uint32_t param_types,TEE_Param params[4])254 TEE_Result TA_InvokeCommandEntryPoint(void __unused *session,
255 uint32_t command,
256 uint32_t param_types,
257 TEE_Param params[4])
258 {
259 switch (command) {
260 case TA_SECURE_STORAGE_CMD_WRITE_RAW:
261 return create_raw_object(param_types, params);
262 case TA_SECURE_STORAGE_CMD_READ_RAW:
263 return read_raw_object(param_types, params);
264 case TA_SECURE_STORAGE_CMD_DELETE:
265 return delete_object(param_types, params);
266 default:
267 EMSG("Command ID 0x%x is not supported", command);
268 return TEE_ERROR_NOT_SUPPORTED;
269 }
270 }
271