blob: 7df0d22aa9005361f40a43e6e34a067b891e8c1c [file] [log] [blame]
Etienne Carriere41343db2017-03-17 15:38:52 +01001/*
2 * Copyright (c) 2016, 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 <string.h>
29#include <tee_api.h>
30#include <tee_internal_api_extensions.h>
31#include <tee_internal_api.h>
32#include <tee_ta_api.h>
33#include <trace.h>
34
35#include <ta_sdp_basic.h>
36
37/*
38 * Basic Secure Data Path access test commands:
39 * - command INJECT: copy from non secure input into secure output.
40 * - command TRANSFROM: read, transform and write from/to secure in/out.
41 * - command DUMP: copy from secure input into non secure output.
42 */
43
44static TEE_Result cmd_inject(uint32_t types,
45 TEE_Param params[TEE_NUM_PARAMS])
46{
47 TEE_Result rc;
48 const int sec_idx = 1; /* highlight secure buffer index */
49 const int ns_idx = 0; /* highlight nonsecure buffer index */
50
51 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
52 TEE_PARAM_TYPE_MEMREF_OUTPUT,
53 TEE_PARAM_TYPE_NONE,
54 TEE_PARAM_TYPE_NONE)) {
55 EMSG("bad parameters %x", (unsigned)types);
56 return TEE_ERROR_BAD_PARAMETERS;
57 }
58
59 if (params[sec_idx].memref.size < params[ns_idx].memref.size)
60 return TEE_ERROR_SHORT_BUFFER;
61
62 /*
63 * We could rely on the TEE to provide consistent buffer/size values
64 * to reference a buffer with a unique and consistent secure attribute
65 * value. Hence it is safe enough (and more optimal) to test only the
66 * secure attribute of a single byte of it. Yet, since the current
67 * test does not deal with performance, let check the secure attribute
68 * of each byte of the buffer.
69 */
70 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
71 TEE_MEMORY_ACCESS_READ |
72 TEE_MEMORY_ACCESS_NONSECURE,
73 params[ns_idx].memref.buffer,
74 params[ns_idx].memref.size);
75 if (rc != TEE_SUCCESS) {
76 EMSG("TEE_CheckMemoryAccessRights(nsec) failed %x", rc);
77 return rc;
78 }
79
80 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
81 TEE_MEMORY_ACCESS_WRITE |
82 TEE_MEMORY_ACCESS_SECURE,
83 params[sec_idx].memref.buffer,
84 params[sec_idx].memref.size);
85 if (rc != TEE_SUCCESS) {
86 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
87 return rc;
88 }
89
90
91#ifdef CFG_CACHE_API
92 /*
93 * we should invalidate cache (here we assume buffer were not
94 * filled through cpu core caches. We flush buffers so that
95 * cache is not corrupted in cache target buffer not aligned
96 * on cache line size.
97 */
98 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
99 params[sec_idx].memref.size);
100 if (rc != TEE_SUCCESS) {
101 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
102 params[sec_idx].memref.buffer,
103 params[sec_idx].memref.size, rc);
104 return rc;
105 }
106#endif /* CFG_CACHE_API */
107
108 /* inject data */
109 TEE_MemMove(params[sec_idx].memref.buffer,
110 params[ns_idx].memref.buffer,
111 params[sec_idx].memref.size);
112
113#ifdef CFG_CACHE_API
114 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
115 params[sec_idx].memref.size);
116 if (rc != TEE_SUCCESS) {
117 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
118 params[sec_idx].memref.buffer,
119 params[sec_idx].memref.size, rc);
120 return rc;
121 }
122#endif /* CFG_CACHE_API */
123
124 return rc;
125}
126
127static TEE_Result cmd_transform(uint32_t types,
128 TEE_Param params[TEE_NUM_PARAMS])
129{
130 TEE_Result rc;
131 unsigned char *p;
132 size_t sz;
133
134 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
135 TEE_PARAM_TYPE_NONE,
136 TEE_PARAM_TYPE_NONE,
137 TEE_PARAM_TYPE_NONE))
138 return TEE_ERROR_BAD_PARAMETERS;
139
140 /*
141 * We could rely on the TEE to provide consistent buffer/size values
142 * to reference a buffer with a unique and consistent secure attribute
143 * value. Hence it is safe enough (and more optimal) to test only the
144 * secure attribute of a single byte of it. Yet, since the current
145 * test does not deal with performance, let check the secure attribute
146 * of each byte of the buffer.
147 */
148 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
149 TEE_MEMORY_ACCESS_READ |
150 TEE_MEMORY_ACCESS_WRITE |
151 TEE_MEMORY_ACCESS_SECURE,
152 params[0].memref.buffer,
153 params[0].memref.size);
154 if (rc != TEE_SUCCESS) {
155 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
156 return rc;
157 }
158
159
160#ifdef CFG_CACHE_API
161 /*
162 * we should invalidate cache (here we assume buffer were not
163 * filled through cpu core caches. We flush buffers so that
164 * cache is not corrupted in cache target buffer not aligned
165 * on cache line size.
166 */
167 rc = TEE_CacheFlush(params[0].memref.buffer,
168 params[0].memref.size);
169 if (rc != TEE_SUCCESS) {
170 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
171 params[0].memref.buffer,
172 params[0].memref.size, rc);
173 return rc;
174 }
175#endif /* CFG_CACHE_API */
176
177 /* transform the data */
178 p = (unsigned char *)params[0].memref.buffer;
179 sz = params[0].memref.size;
180 for (; sz; sz--, p++)
181 *p = ~(*p) + 1;
182
183#ifdef CFG_CACHE_API
184 rc = TEE_CacheFlush(params[0].memref.buffer,
185 params[0].memref.size);
186 if (rc != TEE_SUCCESS) {
187 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
188 params[0].memref.buffer,
189 params[0].memref.size, rc);
190 return rc;
191 }
192#endif /* CFG_CACHE_API */
193
194 return rc;
195}
196
197static TEE_Result cmd_dump(uint32_t types,
198 TEE_Param params[TEE_NUM_PARAMS])
199{
200 TEE_Result rc;
201 const int sec_idx = 0; /* highlight secure buffer index */
202 const int ns_idx = 1; /* highlight nonsecure buffer index */
203
204 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
205 TEE_PARAM_TYPE_MEMREF_OUTPUT,
206 TEE_PARAM_TYPE_NONE,
207 TEE_PARAM_TYPE_NONE))
208 return TEE_ERROR_BAD_PARAMETERS;
209
210 if (params[ns_idx].memref.size < params[sec_idx].memref.size)
211 return TEE_ERROR_SHORT_BUFFER;
212
213 /*
214 * We could rely on the TEE to provide consistent buffer/size values
215 * to reference a buffer with a unique and consistent secure attribute
216 * value. Hence it is safe enough (and more optimal) to test only the
217 * secure attribute of a single byte of it. Yet, since the current
218 * test does not deal with performance, let check the secure attribute
219 * of each byte of the buffer.
220 */
221 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
222 TEE_MEMORY_ACCESS_WRITE |
223 TEE_MEMORY_ACCESS_NONSECURE,
224 params[ns_idx].memref.buffer,
225 params[ns_idx].memref.size);
226 if (rc != TEE_SUCCESS) {
227 EMSG("TEE_CheckMemoryAccessRights(nsec) failed %x", rc);
228 return rc;
229 }
230
231 rc = TEE_CheckMemoryAccessRights(TEE_MEMORY_ACCESS_ANY_OWNER |
232 TEE_MEMORY_ACCESS_READ |
233 TEE_MEMORY_ACCESS_SECURE,
234 params[sec_idx].memref.buffer,
235 params[sec_idx].memref.size);
236 if (rc != TEE_SUCCESS) {
237 EMSG("TEE_CheckMemoryAccessRights(secure) failed %x", rc);
238 return rc;
239 }
240
241#ifdef CFG_CACHE_API
242 /*
243 * we should invalidate cache (here we assume buffer were not
244 * filled through cpu core caches. We flush buffers so that
245 * cache is not corrupted in cache target buffer not aligned
246 * on cache line size.
247 */
248 rc = TEE_CacheFlush(params[sec_idx].memref.buffer,
249 params[sec_idx].memref.size);
250 if (rc != TEE_SUCCESS) {
251 EMSG("TEE_CacheFlush(%p, %x) failed: 0x%x",
252 params[sec_idx].memref.buffer,
253 params[sec_idx].memref.size, rc);
254 return rc;
255 }
256#endif /* CFG_CACHE_API */
257
258 /* dump the data */
259 TEE_MemMove(params[ns_idx].memref.buffer,
260 params[sec_idx].memref.buffer,
261 params[sec_idx].memref.size);
262
263 return rc;
264}
265
Etienne Carrieref690b912017-03-21 15:44:13 +0100266static TEE_Result cmd_invoke(uint32_t nParamTypes,
267 TEE_Param pParams[TEE_NUM_PARAMS],
268 uint32_t nCommandID)
269{
270 const TEE_UUID uuid = TA_SDP_BASIC_UUID;
271 static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
272 uint32_t ret_orig;
273 TEE_Result res;
274
275 if (sess == TEE_HANDLE_NULL) {
276 res = TEE_OpenTASession(&uuid, 0, 0, NULL, &sess, &ret_orig);
277 if (res != TEE_SUCCESS) {
278 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED \n");
279 goto cleanup_return;
280 }
281
282 }
283
284 res = TEE_InvokeTACommand(sess, 0, nCommandID, nParamTypes, pParams, &ret_orig);
285 if (res != TEE_SUCCESS) {
286 EMSG("SDP basic test TA: TEE_OpenTASession() FAILED %x/%d\n",
287 res, ret_orig);
288 }
289
290cleanup_return:
291 if (res != TEE_SUCCESS) {
292 TEE_CloseTASession(sess);
293 sess = TEE_HANDLE_NULL;
294 }
295 return res;
296}
297
Etienne Carriere41343db2017-03-17 15:38:52 +0100298TEE_Result TA_CreateEntryPoint(void)
299{
300 return TEE_SUCCESS;
301}
302
303void TA_DestroyEntryPoint(void)
304{
305}
306
307TEE_Result TA_OpenSessionEntryPoint(uint32_t nParamTypes,
308 TEE_Param pParams[TEE_NUM_PARAMS],
309 void **ppSessionContext)
310{
311 (void)nParamTypes;
312 (void)pParams;
313 (void)ppSessionContext;
314 return TEE_SUCCESS;
315}
316
317void TA_CloseSessionEntryPoint(void *pSessionContext)
318{
319 (void)pSessionContext;
320}
321
322TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext,
323 uint32_t nCommandID, uint32_t nParamTypes,
324 TEE_Param pParams[TEE_NUM_PARAMS])
325{
326 (void)pSessionContext;
327
328 switch (nCommandID) {
329 case TA_SDP_BASIC_CMD_INJECT:
330 return cmd_inject(nParamTypes, pParams);
331 case TA_SDP_BASIC_CMD_TRANSFORM:
332 return cmd_transform(nParamTypes, pParams);
333 case TA_SDP_BASIC_CMD_DUMP:
334 return cmd_dump(nParamTypes, pParams);
Etienne Carrieref690b912017-03-21 15:44:13 +0100335
336 case TA_SDP_BASIC_CMD_INVOKE_INJECT:
337 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_INJECT);
338 case TA_SDP_BASIC_CMD_INVOKE_TRANSFORM:
339 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_TRANSFORM);
340 case TA_SDP_BASIC_CMD_INVOKE_DUMP:
341 return cmd_invoke(nParamTypes, pParams, TA_SDP_BASIC_CMD_DUMP);
342
Etienne Carriere41343db2017-03-17 15:38:52 +0100343 default:
344 return TEE_ERROR_BAD_PARAMETERS;
345 }
346}