blob: 3194951ab8efbac2b66a3cbf44e83cd261f5b786 [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 <err.h>
29#include <fcntl.h>
Etienne Carrierec45d9762017-03-21 15:45:13 +010030#include <pta_invoke_tests.h>
Etienne Carriere41343db2017-03-17 15:38:52 +010031#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <sys/ioctl.h>
35#include <sys/mman.h>
36#include <tee_client_api.h>
37#include <tee_client_api_extensions.h>
38#include <unistd.h>
39
Etienne Carriere41343db2017-03-17 15:38:52 +010040#include "crypto_common.h"
Etienne Carriere50abf9a2017-03-24 11:33:50 +010041#include "sdp_basic.h"
42#include "xtest_test.h"
Etienne Carriere41343db2017-03-17 15:38:52 +010043
44/*
45 * SDP basic test setup overview.
46 *
47 * - A dedicated trusted application (SDP basic TA) supports 3 commands:
48 * - 'inject' data from a nonsecure buffer into a secure buffer
49 * - 'transform' data inside a secure buffer (bitwise invert + unsigned incr)
50 * - 'dump' data from a secure buffer into a nonsecure buffer
51
52 * - This test client application (CA) invokes the TA for these 3 operations,
53 * inject random value, trasforming them then dump them.
54 *
55 * To do so, CA allocates a 'SDP secure buffer' and invoke the TA for these 3
56 * operations (inject then transform then dump) over the allocate buffer.
57 *
58 * The secure buffer is currently allocation through ION support adn
59 * registered to OP-TEE and as shared memory.
60 *
61 * To enhance test coverage against buffer alignement usecase, the CA invokes
62 * the TA with a variable offset inside the buffer. As CA injects random data
63 * into the buffer, the CA uses one of the random bytes to set the value of the
64 * offset in the accessed secure buffer.
65 *
66 * For debugging support, the CA may map (in nonsecure world) the secure
67 * buffer to read its content. As this is unsafe on a hardened platform, this
68 * operation is default disable. When enable, error only print out a warning
69 * trace but does not actually fail the test. This also give an easy way to
70 * check that some HW complains on access violation when nonsecure accesses
71 * secure data.
72 */
73
74static int verbosity = 1;
75
76struct tee_ctx {
77 TEEC_Context ctx;
78 TEEC_Session sess;
79};
80
Etienne Carriere41343db2017-03-17 15:38:52 +010081int allocate_ion_buffer(size_t size, int heap_id)
82{
83 struct ion_allocation_data alloc_data;
84 struct ion_handle_data hdl_data;
85 struct ion_fd_data fd_data;
86 int ion;
87 int fd = -1;
88
89 ion = open("/dev/ion", O_RDWR);
90 if (ion < 0) {
91 fprintf(stderr, "Error; failed to open /dev/ion\n");
92 verbose("Seems no ION heap is available.\n");
93 verbose("To test ION allocation you can enable\n");
94 verbose("CONFIG_ION and CONFIG_ION_DUMMY in your\n");
95 verbose("linux kernel configuration.\n");
96 return fd;
97 }
98
99 if (heap_id < 0)
100 heap_id = DEFAULT_ION_HEAP_TYPE;
101
102 verbose("Allocate in ION heap '%s'\n",
103 heap_id == ION_HEAP_TYPE_SYSTEM ? "system" :
104 heap_id == ION_HEAP_TYPE_SYSTEM_CONTIG ? "system contig" :
105 heap_id == ION_HEAP_TYPE_CARVEOUT ? "carveout" :
106 heap_id == ION_HEAP_TYPE_CHUNK ? "chunk" :
107 heap_id == ION_HEAP_TYPE_DMA ? "dma" :
108 heap_id == ION_HEAP_TYPE_UNMAPPED ? "unmapped" :
109 "custom");
110
111 alloc_data.len = size;
112 alloc_data.align = 0;
113 alloc_data.flags = 0;
114 alloc_data.heap_id_mask = 1 << heap_id;
115 if (ioctl(ion, ION_IOC_ALLOC, &alloc_data) == -1)
116 goto out;
117
118 fd_data.handle = alloc_data.handle;
119 if (ioctl(ion, ION_IOC_SHARE, &fd_data) != -1)
120 fd = fd_data.fd;
121
122 hdl_data.handle = alloc_data.handle;
123 (void)ioctl(ion, ION_IOC_FREE, &hdl_data);
124out:
125 close(ion);
126 return fd;
127}
128
129static void finalize_tee_ctx(struct tee_ctx *ctx)
130{
131 if (!ctx)
132 return;
133
134 TEEC_CloseSession(&ctx->sess);
135 TEEC_FinalizeContext(&ctx->ctx);
136}
137
Etienne Carrierec45d9762017-03-21 15:45:13 +0100138static int create_tee_ctx(struct tee_ctx *ctx, enum test_target_ta target_ta)
Etienne Carriere41343db2017-03-17 15:38:52 +0100139{
140 TEEC_Result teerc;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100141 TEEC_UUID *uuid;
Etienne Carriere41343db2017-03-17 15:38:52 +0100142 uint32_t err_origin;
143
Etienne Carrierec45d9762017-03-21 15:45:13 +0100144 switch (target_ta) {
145 case TEST_NS_TO_TA:
146 case TEST_TA_TO_TA:
147 case TEST_TA_TO_PTA:
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100148 uuid = &sdp_basic_ta_uuid;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100149 break;
150 case TEST_NS_TO_PTA:
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100151 uuid = &pta_invoke_tests_ta_uuid;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100152 break;
153 default:
154 return -1;
155 }
156
Etienne Carriere41343db2017-03-17 15:38:52 +0100157 teerc = TEEC_InitializeContext(NULL, &ctx->ctx);
158 if (teerc != TEEC_SUCCESS)
159 return -1;
160
Etienne Carrierec45d9762017-03-21 15:45:13 +0100161 teerc = TEEC_OpenSession(&ctx->ctx, &ctx->sess, uuid,
Etienne Carriere41343db2017-03-17 15:38:52 +0100162 TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
163 if (teerc != TEEC_SUCCESS)
Etienne Carrierec45d9762017-03-21 15:45:13 +0100164 fprintf(stderr, "Error: open session to target test %s failed %x %d\n",
165 (target_ta == TEST_NS_TO_PTA) ? "pTA" : "TA",
Etienne Carriere41343db2017-03-17 15:38:52 +0100166 teerc, err_origin);
167
168 return (teerc == TEEC_SUCCESS) ? 0 : -1;
169}
170
171static int tee_register_buffer(struct tee_ctx *ctx, void **shm_ref, int fd)
172{
173 TEEC_Result teerc;
174 TEEC_SharedMemory *shm;
175
176 shm = malloc(sizeof(*shm));
177 if (!shm)
178 return 1;
179
180 shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
181 teerc = TEEC_RegisterSharedMemoryFileDescriptor(&ctx->ctx, shm, fd);
182 if (teerc != TEEC_SUCCESS) {
183 fprintf(stderr, "Error: TEEC_RegisterMemoryFileDescriptor() failed %x\n",
184 teerc);
185 return 1;
186 }
187
188 *shm_ref = shm;
189 return 0;
190}
191
192static void tee_deregister_buffer(struct tee_ctx *ctx, void *shm_ref)
193{
194 (void)ctx;
195
196 if (!shm_ref)
197 return;
198
199 TEEC_ReleaseSharedMemory((TEEC_SharedMemory *)shm_ref);
200 free(shm_ref);
201}
202
203static int inject_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100204 void *in, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100205{
206 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
207 TEEC_Result teerc;
208 TEEC_Operation op;
209 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100210 unsigned cmd;
211
212 switch (ind) {
213 case TEST_NS_TO_TA:
214 cmd = TA_SDP_BASIC_CMD_INJECT;
215 break;
216 case TEST_TA_TO_TA:
217 cmd = TA_SDP_BASIC_CMD_INVOKE_INJECT;
218 break;
219 case TEST_TA_TO_PTA:
220 cmd = TA_SDP_BASIC_CMD_PTA_INJECT;
221 break;
222 case TEST_NS_TO_PTA:
223 cmd = PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC;
224 break;
225 default:
226 return -1;
227 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100228
229 memset(&op, 0, sizeof(op));
230 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
231 TEEC_MEMREF_PARTIAL_OUTPUT,
232 TEEC_NONE, TEEC_NONE);
233
234 op.params[0].tmpref.buffer = in;
235 op.params[0].tmpref.size = len;
236
237 op.params[1].memref.parent = shm;
238 op.params[1].memref.size = len;
239 op.params[1].memref.offset = offset;
240
Etienne Carrieref690b912017-03-21 15:44:13 +0100241 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100242 if (teerc != TEEC_SUCCESS)
243 fprintf(stderr, "Error: invoke SDP test TA (inject) failed %x %d\n",
244 teerc, err_origin);
245
246 return (teerc == TEEC_SUCCESS) ? 0 : -1;
247}
248
249static int transform_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100250 size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100251{
252 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
253 TEEC_Result teerc;
254 TEEC_Operation op;
255 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100256 unsigned cmd;
257
258 switch (ind) {
259 case TEST_NS_TO_TA:
260 cmd = TA_SDP_BASIC_CMD_TRANSFORM;
261 break;
262 case TEST_TA_TO_TA:
263 cmd = TA_SDP_BASIC_CMD_INVOKE_TRANSFORM;
264 break;
265 case TEST_TA_TO_PTA:
266 cmd = TA_SDP_BASIC_CMD_PTA_TRANSFORM;
267 break;
268 case TEST_NS_TO_PTA:
269 cmd = PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC;
270 break;
271 default:
272 return -1;
273 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100274
275 memset(&op, 0, sizeof(op));
276 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
277 TEEC_NONE, TEEC_NONE, TEEC_NONE);
278 op.params[0].memref.parent = shm;
279 op.params[0].memref.size = len;
280 op.params[0].memref.offset = offset;
281
Etienne Carrieref690b912017-03-21 15:44:13 +0100282 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100283 if (teerc != TEEC_SUCCESS)
284 fprintf(stderr, "Error: invoke SDP test TA (transform) failed %x %d\n",
285 teerc, err_origin);
286
287 return (teerc == TEEC_SUCCESS) ? 0 : -1;
288}
289
290static int dump_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100291 void *out, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100292{
293 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
294 TEEC_Result teerc;
295 TEEC_Operation op;
296 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100297 unsigned cmd;
298
299 switch (ind) {
300 case TEST_NS_TO_TA:
301 cmd = TA_SDP_BASIC_CMD_DUMP;
302 break;
303 case TEST_TA_TO_TA:
304 cmd = TA_SDP_BASIC_CMD_INVOKE_DUMP;
305 break;
306 case TEST_TA_TO_PTA:
307 cmd = TA_SDP_BASIC_CMD_PTA_DUMP;
308 break;
309 case TEST_NS_TO_PTA:
310 cmd = PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC;
311 break;
312 default:
313 return -1;
314 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100315
316 memset(&op, 0, sizeof(op));
317 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
318 TEEC_MEMREF_TEMP_OUTPUT,
319 TEEC_NONE, TEEC_NONE);
320 op.params[0].memref.parent = shm;
321 op.params[0].memref.size = len;
322 op.params[0].memref.offset = offset;
323
324 op.params[1].tmpref.buffer = out;
325 op.params[1].tmpref.size = len;
326
Etienne Carrieref690b912017-03-21 15:44:13 +0100327 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100328 if (teerc != TEEC_SUCCESS)
329 fprintf(stderr, "Error: invoke SDP test TA (dump) failed %x %d\n",
330 teerc, err_origin);
331
332 return (teerc == TEEC_SUCCESS) ? 0 : -1;
333}
334
335static int check_sdp_dumped(struct tee_ctx *ctx, void *ref, size_t len,
336 void *out)
337{
338 char *bref = (char *)ref;
339 char *data = (char *)out;
340 int err = 0;
341
342 (void)ctx;
343
344 while(len--)
345 if (*data++ != (unsigned char)(~(*bref++) + 1))
346 err++;
347
348 return err;
349}
350
351/*
352 * Consider 32kByte + 1 of random data is sufficient for an accurate test
353 * whatever the test buffer size is. Random buffer is read as a ring buffer.
354 */
355#define RANDOM_BUFFER_SIZE (32 * 1024 + 1)
356static int get_random_bytes(char *out, size_t len)
357{
358 static char *rand_buf = NULL;
359 static size_t rand_idx = 0;
360 int rc;
361
362 if (!rand_buf) {
363 const char rand_dev[] = "/dev/urandom";
364 int fd;
365
366 rand_buf = malloc(RANDOM_BUFFER_SIZE);
367 if (!rand_buf) {
368 fprintf(stderr, "failed to random buffer memory (%d bytes)\n",
369 RANDOM_BUFFER_SIZE);
370 return -1;
371 }
372
373 fd = open(rand_dev, O_RDONLY);
374 if (fd < 0) {
375 fprintf(stderr, "failed to open %s\n", rand_dev);
376 return -1;
377 }
378
379 rc = read(fd, rand_buf, RANDOM_BUFFER_SIZE);
380 if (rc != RANDOM_BUFFER_SIZE) {
381 fprintf(stderr, "failed to read %d bytes from %s\n",
382 RANDOM_BUFFER_SIZE, rand_dev);
383 return -1;
384 }
385 close(fd);
386 }
387
388 while (len) {
389 size_t t_len = (RANDOM_BUFFER_SIZE < len) ? RANDOM_BUFFER_SIZE : len;
390
391 if ((rand_idx + t_len) > RANDOM_BUFFER_SIZE) {
392 int sz_end = RANDOM_BUFFER_SIZE - rand_idx;
393 int sz_beg = t_len - sz_end;
394
395 memcpy(out, rand_buf + rand_idx, sz_end);
396 memcpy(out + sz_end, rand_buf , sz_beg);
397 rand_idx = sz_beg;
398 } else {
399 memcpy(out, rand_buf + rand_idx, t_len);
400 rand_idx += t_len;
401 }
402 len -= t_len;
403 }
404 return 0;
405}
406
407
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100408int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop,
409 int ion_heap, int rnd_offset)
Etienne Carriere41343db2017-03-17 15:38:52 +0100410{
411 struct tee_ctx *ctx = NULL;
412 unsigned char *test_buf = NULL;
413 unsigned char *ref_buf = NULL;
414 void *shm_ref = NULL;
415 unsigned int err = 1;
416 int fd = -1;
417 size_t sdp_size = size;
418 size_t offset;
Etienne Carrieref690b912017-03-21 15:44:13 +0100419 size_t loop_cnt;
Etienne Carriere41343db2017-03-17 15:38:52 +0100420
421 if (!loop) {
422 fprintf(stderr, "Error: null loop value\n");
423 return 1;
424 }
425
426 /* reduce size to enable offset tests (max offset is 255 bytes) */
427 if (rnd_offset)
428 size -= 255;
429
430 test_buf = malloc(size);
431 ref_buf = malloc(size);
432 if (!test_buf || !ref_buf) {
433 verbose("failed to allocate memory\n");
434 goto out;
435 }
436
437 fd = allocate_ion_buffer(sdp_size, ion_heap);
438 if (fd < 0) {
439 verbose("Failed to allocate SDP buffer (%lu bytes) in ION heap %d: %d\n",
440 sdp_size, ion_heap, fd);
441 goto out;
442 }
443
444 /* register secure buffer to TEE */
445 ctx = malloc(sizeof(*ctx));
446 if (!ctx)
447 goto out;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100448 if (create_tee_ctx(ctx, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100449 goto out;
450 if (tee_register_buffer(ctx, &shm_ref, fd))
451 goto out;
452
453 /* release registered fd: tee should still hold refcount on resource */
454 close(fd);
455 fd = -1;
456
457 /* invoke trusted application with secure buffer as memref parameter */
Etienne Carrieref690b912017-03-21 15:44:13 +0100458 for (loop_cnt = loop; loop_cnt; loop_cnt--) {
Etienne Carriere41343db2017-03-17 15:38:52 +0100459 /* get an buffer of random-like values */
460 if (get_random_bytes((char *)ref_buf, size))
461 goto out;
462 memcpy(test_buf, ref_buf, size);
463 /* random offset [0 255] */
464 offset = (unsigned int)*ref_buf;
465
466 /* TA writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100467 if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100468 goto out;
469
470 /* TA reads/writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100471 if (transform_sdp_data(ctx, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100472 goto out;
473
474 /* TA reads into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100475 if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carrieref690b912017-03-21 15:44:13 +0100476 goto out;
477
478 /* check dumped data are the expected ones */
479 if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) {
480 fprintf(stderr, "check SDP data: %d errors\n", err);
481 goto out;
482 }
483 }
484
Etienne Carriere41343db2017-03-17 15:38:52 +0100485 err = 0;
486 verbose("%s: successed\n", __func__);
487out:
488 if (err)
489 verbose("test failed\n");
490 if (fd >= 0)
491 close(fd);
492 if (shm_ref)
493 tee_deregister_buffer(ctx, shm_ref);
494 finalize_tee_ctx(ctx);
495 free(ctx);
496 free(ref_buf);
497 free(test_buf);
498 return err;
499}
500
501#define _TO_STR(x) #x
502#define TO_STR(x) _TO_STR(x)
503
504static void usage(const char *progname, size_t size, int loop, int ion_heap)
505{
506 fprintf(stderr, "Usage: %s [OPTION]\n", progname);
507 fprintf(stderr,
508 "Testing basic accesses to secure buffer (SDP) on OP-TEE.\n"
509 "Allocates a secure buffer and invoke a TA to access it.\n"
510 "TA is used to init/transform/dump the secure buffer.\n"
511 "CA check dumped content.\n\n");
512
513 fprintf(stderr, "Options:\n");
514 fprintf(stderr, " -h|--help Print this help and exit\n");
515 fprintf(stderr, " -v Be verbose\n");
516 fprintf(stderr, " -s SIZE SDP buffer byte size [%zu]\n", size);
517 fprintf(stderr, " -n LOOP Test loop iterations [%u]\n", loop);
518 fprintf(stderr, " --ion-heap ID Target ION heap ID [%d]\n", ion_heap);
519 fprintf(stderr, " --no-offset No random offset [0 255] in buffer\n");
520}
521
522#define NEXT_ARG(i) \
523 do { \
524 if (++i == argc) { \
525 fprintf(stderr, "%s: %s: missing argument\n", \
526 argv[0], argv[i-1]); \
527 return 1; \
528 } \
529 } while (0);
530
531int sdp_basic_runner_cmd_parser(int argc, char *argv[])
532{
533 size_t test_size = 5000;
534 size_t test_loop = 1000;
535 int ion_heap = DEFAULT_ION_HEAP_TYPE;
536 int rnd_offset = 1;
537 int i;
538
539 /* Parse command line */
540 for (i = 1; i < argc; i++) {
541 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
542 usage(argv[0], test_size, test_loop, ion_heap);
543 return 0;
544 }
545 }
546 for (i = 1; i < argc; i++) {
547 if (!strcmp(argv[i], "-v")) {
548 verbosity++;
549 } else if (!strcmp(argv[i], "-s")) {
550 NEXT_ARG(i);
551 test_size = atoi(argv[i]);
552 } else if (!strcmp(argv[i], "-n")) {
553 NEXT_ARG(i);
554 test_loop = atoi(argv[i]);
555 } else if (!strcmp(argv[i], "--ion-heap")) {
556 NEXT_ARG(i);
557 ion_heap = atoi(argv[i]);
558 } else if (!strcmp(argv[i], "--no-offset")) {
559 rnd_offset = 0;
560 } else {
561 fprintf(stderr, "%s: invalid argument: %s\n",
562 argv[0], argv[i]);
563 usage(argv[0], test_size, test_loop, ion_heap);
564 return 1;
565 }
566 }
567
Etienne Carrierec45d9762017-03-21 15:45:13 +0100568 verbose("\nSecure Data Path basic accesses: NS invokes SDP TA\n");
569 if (sdp_basic_test(TEST_NS_TO_TA,
570 test_size, test_loop, ion_heap, rnd_offset))
571 return 1;
Etienne Carriere41343db2017-03-17 15:38:52 +0100572
Etienne Carrierec45d9762017-03-21 15:45:13 +0100573 verbose("\nSecure Data Path basic accesses: SDP TA invokes SDP TA\n");
574 if (sdp_basic_test(TEST_TA_TO_TA,
575 test_size, test_loop, ion_heap, rnd_offset))
576 return 1;
577
578 verbose("\nSecure Data Path basic accesses: SDP TA invokes SDP pTA\n");
579 if (sdp_basic_test(TEST_TA_TO_PTA,
580 test_size, test_loop, ion_heap, rnd_offset))
Etienne Carriere41343db2017-03-17 15:38:52 +0100581 return 1;
582
Etienne Carriered1655822017-03-21 15:45:24 +0100583 verbose("\nSecure Data Path basic accesses: NS invokes SDP pTA (shall fail)\n");
584 if (sdp_basic_test(TEST_NS_TO_PTA,
585 test_size, test_loop, ion_heap, rnd_offset))
586 verbose("-> false negative: pTAs refuse SDP memref from NS clients.\n");
587
Etienne Carriere41343db2017-03-17 15:38:52 +0100588 return 0;
589}