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