blob: 7c2a98ae463ae465bdfbdf52f62885460db50278 [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
Etienne Carriere41343db2017-03-17 15:38:52 +010074struct tee_ctx {
75 TEEC_Context ctx;
76 TEEC_Session sess;
77};
78
Etienne Carriereb9a95822017-04-26 15:03:53 +020079int allocate_ion_buffer(size_t size, int heap_id, int verbosity)
Etienne Carriere41343db2017-03-17 15:38:52 +010080{
81 struct ion_allocation_data alloc_data;
82 struct ion_handle_data hdl_data;
83 struct ion_fd_data fd_data;
84 int ion;
85 int fd = -1;
86
87 ion = open("/dev/ion", O_RDWR);
88 if (ion < 0) {
89 fprintf(stderr, "Error; failed to open /dev/ion\n");
90 verbose("Seems no ION heap is available.\n");
91 verbose("To test ION allocation you can enable\n");
92 verbose("CONFIG_ION and CONFIG_ION_DUMMY in your\n");
93 verbose("linux kernel configuration.\n");
94 return fd;
95 }
96
97 if (heap_id < 0)
98 heap_id = DEFAULT_ION_HEAP_TYPE;
99
100 verbose("Allocate in ION heap '%s'\n",
101 heap_id == ION_HEAP_TYPE_SYSTEM ? "system" :
102 heap_id == ION_HEAP_TYPE_SYSTEM_CONTIG ? "system contig" :
103 heap_id == ION_HEAP_TYPE_CARVEOUT ? "carveout" :
104 heap_id == ION_HEAP_TYPE_CHUNK ? "chunk" :
105 heap_id == ION_HEAP_TYPE_DMA ? "dma" :
106 heap_id == ION_HEAP_TYPE_UNMAPPED ? "unmapped" :
107 "custom");
108
109 alloc_data.len = size;
110 alloc_data.align = 0;
111 alloc_data.flags = 0;
112 alloc_data.heap_id_mask = 1 << heap_id;
113 if (ioctl(ion, ION_IOC_ALLOC, &alloc_data) == -1)
114 goto out;
115
116 fd_data.handle = alloc_data.handle;
117 if (ioctl(ion, ION_IOC_SHARE, &fd_data) != -1)
118 fd = fd_data.fd;
119
120 hdl_data.handle = alloc_data.handle;
121 (void)ioctl(ion, ION_IOC_FREE, &hdl_data);
122out:
123 close(ion);
124 return fd;
125}
126
127static void finalize_tee_ctx(struct tee_ctx *ctx)
128{
129 if (!ctx)
130 return;
131
132 TEEC_CloseSession(&ctx->sess);
133 TEEC_FinalizeContext(&ctx->ctx);
134}
135
Etienne Carrierec45d9762017-03-21 15:45:13 +0100136static int create_tee_ctx(struct tee_ctx *ctx, enum test_target_ta target_ta)
Etienne Carriere41343db2017-03-17 15:38:52 +0100137{
138 TEEC_Result teerc;
Etienne Carriereb296a642017-03-29 15:23:56 +0200139 const TEEC_UUID *uuid;
Etienne Carriere41343db2017-03-17 15:38:52 +0100140 uint32_t err_origin;
141
Etienne Carrierec45d9762017-03-21 15:45:13 +0100142 switch (target_ta) {
143 case TEST_NS_TO_TA:
144 case TEST_TA_TO_TA:
145 case TEST_TA_TO_PTA:
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100146 uuid = &sdp_basic_ta_uuid;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100147 break;
148 case TEST_NS_TO_PTA:
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100149 uuid = &pta_invoke_tests_ta_uuid;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100150 break;
151 default:
152 return -1;
153 }
154
Etienne Carriere41343db2017-03-17 15:38:52 +0100155 teerc = TEEC_InitializeContext(NULL, &ctx->ctx);
156 if (teerc != TEEC_SUCCESS)
157 return -1;
158
Etienne Carrierec45d9762017-03-21 15:45:13 +0100159 teerc = TEEC_OpenSession(&ctx->ctx, &ctx->sess, uuid,
Etienne Carriere41343db2017-03-17 15:38:52 +0100160 TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
161 if (teerc != TEEC_SUCCESS)
Etienne Carrierec45d9762017-03-21 15:45:13 +0100162 fprintf(stderr, "Error: open session to target test %s failed %x %d\n",
163 (target_ta == TEST_NS_TO_PTA) ? "pTA" : "TA",
Etienne Carriere41343db2017-03-17 15:38:52 +0100164 teerc, err_origin);
165
166 return (teerc == TEEC_SUCCESS) ? 0 : -1;
167}
168
169static int tee_register_buffer(struct tee_ctx *ctx, void **shm_ref, int fd)
170{
171 TEEC_Result teerc;
172 TEEC_SharedMemory *shm;
173
174 shm = malloc(sizeof(*shm));
175 if (!shm)
176 return 1;
177
178 shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
179 teerc = TEEC_RegisterSharedMemoryFileDescriptor(&ctx->ctx, shm, fd);
180 if (teerc != TEEC_SUCCESS) {
181 fprintf(stderr, "Error: TEEC_RegisterMemoryFileDescriptor() failed %x\n",
182 teerc);
183 return 1;
184 }
185
186 *shm_ref = shm;
187 return 0;
188}
189
190static void tee_deregister_buffer(struct tee_ctx *ctx, void *shm_ref)
191{
192 (void)ctx;
193
194 if (!shm_ref)
195 return;
196
197 TEEC_ReleaseSharedMemory((TEEC_SharedMemory *)shm_ref);
198 free(shm_ref);
199}
200
201static int inject_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100202 void *in, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100203{
204 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
205 TEEC_Result teerc;
206 TEEC_Operation op;
207 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100208 unsigned cmd;
209
210 switch (ind) {
211 case TEST_NS_TO_TA:
212 cmd = TA_SDP_BASIC_CMD_INJECT;
213 break;
214 case TEST_TA_TO_TA:
215 cmd = TA_SDP_BASIC_CMD_INVOKE_INJECT;
216 break;
217 case TEST_TA_TO_PTA:
218 cmd = TA_SDP_BASIC_CMD_PTA_INJECT;
219 break;
220 case TEST_NS_TO_PTA:
221 cmd = PTA_INVOKE_TESTS_CMD_COPY_NSEC_TO_SEC;
222 break;
223 default:
224 return -1;
225 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100226
227 memset(&op, 0, sizeof(op));
228 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
229 TEEC_MEMREF_PARTIAL_OUTPUT,
230 TEEC_NONE, TEEC_NONE);
231
232 op.params[0].tmpref.buffer = in;
233 op.params[0].tmpref.size = len;
234
235 op.params[1].memref.parent = shm;
236 op.params[1].memref.size = len;
237 op.params[1].memref.offset = offset;
238
Etienne Carrieref690b912017-03-21 15:44:13 +0100239 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100240 if (teerc != TEEC_SUCCESS)
241 fprintf(stderr, "Error: invoke SDP test TA (inject) failed %x %d\n",
242 teerc, err_origin);
243
244 return (teerc == TEEC_SUCCESS) ? 0 : -1;
245}
246
247static int transform_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100248 size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100249{
250 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
251 TEEC_Result teerc;
252 TEEC_Operation op;
253 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100254 unsigned cmd;
255
256 switch (ind) {
257 case TEST_NS_TO_TA:
258 cmd = TA_SDP_BASIC_CMD_TRANSFORM;
259 break;
260 case TEST_TA_TO_TA:
261 cmd = TA_SDP_BASIC_CMD_INVOKE_TRANSFORM;
262 break;
263 case TEST_TA_TO_PTA:
264 cmd = TA_SDP_BASIC_CMD_PTA_TRANSFORM;
265 break;
266 case TEST_NS_TO_PTA:
267 cmd = PTA_INVOKE_TESTS_CMD_READ_MODIFY_SEC;
268 break;
269 default:
270 return -1;
271 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100272
273 memset(&op, 0, sizeof(op));
274 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
275 TEEC_NONE, TEEC_NONE, TEEC_NONE);
276 op.params[0].memref.parent = shm;
277 op.params[0].memref.size = len;
278 op.params[0].memref.offset = offset;
279
Etienne Carrieref690b912017-03-21 15:44:13 +0100280 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100281 if (teerc != TEEC_SUCCESS)
282 fprintf(stderr, "Error: invoke SDP test TA (transform) failed %x %d\n",
283 teerc, err_origin);
284
285 return (teerc == TEEC_SUCCESS) ? 0 : -1;
286}
287
288static int dump_sdp_data(struct tee_ctx *ctx,
Etienne Carrieref690b912017-03-21 15:44:13 +0100289 void *out, size_t offset, size_t len, void *shm_ref, int ind)
Etienne Carriere41343db2017-03-17 15:38:52 +0100290{
291 TEEC_SharedMemory *shm = (TEEC_SharedMemory *)shm_ref;
292 TEEC_Result teerc;
293 TEEC_Operation op;
294 uint32_t err_origin;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100295 unsigned cmd;
296
297 switch (ind) {
298 case TEST_NS_TO_TA:
299 cmd = TA_SDP_BASIC_CMD_DUMP;
300 break;
301 case TEST_TA_TO_TA:
302 cmd = TA_SDP_BASIC_CMD_INVOKE_DUMP;
303 break;
304 case TEST_TA_TO_PTA:
305 cmd = TA_SDP_BASIC_CMD_PTA_DUMP;
306 break;
307 case TEST_NS_TO_PTA:
308 cmd = PTA_INVOKE_TESTS_CMD_COPY_SEC_TO_NSEC;
309 break;
310 default:
311 return -1;
312 }
Etienne Carriere41343db2017-03-17 15:38:52 +0100313
314 memset(&op, 0, sizeof(op));
315 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
316 TEEC_MEMREF_TEMP_OUTPUT,
317 TEEC_NONE, TEEC_NONE);
318 op.params[0].memref.parent = shm;
319 op.params[0].memref.size = len;
320 op.params[0].memref.offset = offset;
321
322 op.params[1].tmpref.buffer = out;
323 op.params[1].tmpref.size = len;
324
Etienne Carrieref690b912017-03-21 15:44:13 +0100325 teerc = TEEC_InvokeCommand(&ctx->sess, cmd, &op, &err_origin);
Etienne Carriere41343db2017-03-17 15:38:52 +0100326 if (teerc != TEEC_SUCCESS)
327 fprintf(stderr, "Error: invoke SDP test TA (dump) failed %x %d\n",
328 teerc, err_origin);
329
330 return (teerc == TEEC_SUCCESS) ? 0 : -1;
331}
332
333static int check_sdp_dumped(struct tee_ctx *ctx, void *ref, size_t len,
334 void *out)
335{
336 char *bref = (char *)ref;
337 char *data = (char *)out;
338 int err = 0;
339
340 (void)ctx;
341
342 while(len--)
343 if (*data++ != (unsigned char)(~(*bref++) + 1))
344 err++;
345
346 return err;
347}
348
349/*
350 * Consider 32kByte + 1 of random data is sufficient for an accurate test
351 * whatever the test buffer size is. Random buffer is read as a ring buffer.
352 */
353#define RANDOM_BUFFER_SIZE (32 * 1024 + 1)
354static int get_random_bytes(char *out, size_t len)
355{
356 static char *rand_buf = NULL;
357 static size_t rand_idx = 0;
358 int rc;
359
360 if (!rand_buf) {
361 const char rand_dev[] = "/dev/urandom";
362 int fd;
363
364 rand_buf = malloc(RANDOM_BUFFER_SIZE);
365 if (!rand_buf) {
366 fprintf(stderr, "failed to random buffer memory (%d bytes)\n",
367 RANDOM_BUFFER_SIZE);
368 return -1;
369 }
370
371 fd = open(rand_dev, O_RDONLY);
372 if (fd < 0) {
373 fprintf(stderr, "failed to open %s\n", rand_dev);
374 return -1;
375 }
376
377 rc = read(fd, rand_buf, RANDOM_BUFFER_SIZE);
378 if (rc != RANDOM_BUFFER_SIZE) {
379 fprintf(stderr, "failed to read %d bytes from %s\n",
380 RANDOM_BUFFER_SIZE, rand_dev);
381 return -1;
382 }
383 close(fd);
384 }
385
386 while (len) {
387 size_t t_len = (RANDOM_BUFFER_SIZE < len) ? RANDOM_BUFFER_SIZE : len;
388
389 if ((rand_idx + t_len) > RANDOM_BUFFER_SIZE) {
390 int sz_end = RANDOM_BUFFER_SIZE - rand_idx;
391 int sz_beg = t_len - sz_end;
392
393 memcpy(out, rand_buf + rand_idx, sz_end);
394 memcpy(out + sz_end, rand_buf , sz_beg);
395 rand_idx = sz_beg;
396 } else {
397 memcpy(out, rand_buf + rand_idx, t_len);
398 rand_idx += t_len;
399 }
400 len -= t_len;
401 }
402 return 0;
403}
404
405
Etienne Carriere50abf9a2017-03-24 11:33:50 +0100406int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop,
Etienne Carriereb9a95822017-04-26 15:03:53 +0200407 int ion_heap, int rnd_offset, int verbosity)
Etienne Carriere41343db2017-03-17 15:38:52 +0100408{
409 struct tee_ctx *ctx = NULL;
410 unsigned char *test_buf = NULL;
411 unsigned char *ref_buf = NULL;
412 void *shm_ref = NULL;
413 unsigned int err = 1;
414 int fd = -1;
415 size_t sdp_size = size;
416 size_t offset;
Etienne Carrieref690b912017-03-21 15:44:13 +0100417 size_t loop_cnt;
Etienne Carriere41343db2017-03-17 15:38:52 +0100418
419 if (!loop) {
420 fprintf(stderr, "Error: null loop value\n");
421 return 1;
422 }
423
424 /* reduce size to enable offset tests (max offset is 255 bytes) */
425 if (rnd_offset)
426 size -= 255;
427
428 test_buf = malloc(size);
429 ref_buf = malloc(size);
430 if (!test_buf || !ref_buf) {
431 verbose("failed to allocate memory\n");
432 goto out;
433 }
434
Etienne Carriereb9a95822017-04-26 15:03:53 +0200435 fd = allocate_ion_buffer(sdp_size, ion_heap, verbosity);
Etienne Carriere41343db2017-03-17 15:38:52 +0100436 if (fd < 0) {
Etienne Carriere5fdf6352017-03-24 11:49:50 +0100437 verbose("Failed to allocate SDP buffer (%zu bytes) in ION heap %d: %d\n",
Etienne Carriere41343db2017-03-17 15:38:52 +0100438 sdp_size, ion_heap, fd);
439 goto out;
440 }
441
442 /* register secure buffer to TEE */
443 ctx = malloc(sizeof(*ctx));
444 if (!ctx)
445 goto out;
Etienne Carrierec45d9762017-03-21 15:45:13 +0100446 if (create_tee_ctx(ctx, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100447 goto out;
448 if (tee_register_buffer(ctx, &shm_ref, fd))
449 goto out;
450
451 /* release registered fd: tee should still hold refcount on resource */
452 close(fd);
453 fd = -1;
454
455 /* invoke trusted application with secure buffer as memref parameter */
Etienne Carrieref690b912017-03-21 15:44:13 +0100456 for (loop_cnt = loop; loop_cnt; loop_cnt--) {
Etienne Carriere41343db2017-03-17 15:38:52 +0100457 /* get an buffer of random-like values */
458 if (get_random_bytes((char *)ref_buf, size))
459 goto out;
460 memcpy(test_buf, ref_buf, size);
461 /* random offset [0 255] */
462 offset = (unsigned int)*ref_buf;
463
464 /* TA writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100465 if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100466 goto out;
467
468 /* TA reads/writes into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100469 if (transform_sdp_data(ctx, offset, size, shm_ref, ta))
Etienne Carriere41343db2017-03-17 15:38:52 +0100470 goto out;
471
472 /* TA reads into SDP buffer */
Etienne Carrierec45d9762017-03-21 15:45:13 +0100473 if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
Etienne Carrieref690b912017-03-21 15:44:13 +0100474 goto out;
475
476 /* check dumped data are the expected ones */
477 if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) {
478 fprintf(stderr, "check SDP data: %d errors\n", err);
479 goto out;
480 }
481 }
482
Etienne Carriere41343db2017-03-17 15:38:52 +0100483 err = 0;
Etienne Carriere41343db2017-03-17 15:38:52 +0100484out:
Etienne Carriere41343db2017-03-17 15:38:52 +0100485 if (fd >= 0)
486 close(fd);
487 if (shm_ref)
488 tee_deregister_buffer(ctx, shm_ref);
489 finalize_tee_ctx(ctx);
490 free(ctx);
491 free(ref_buf);
492 free(test_buf);
493 return err;
494}
495
496#define _TO_STR(x) #x
497#define TO_STR(x) _TO_STR(x)
498
499static void usage(const char *progname, size_t size, int loop, int ion_heap)
500{
501 fprintf(stderr, "Usage: %s [OPTION]\n", progname);
502 fprintf(stderr,
503 "Testing basic accesses to secure buffer (SDP) on OP-TEE.\n"
504 "Allocates a secure buffer and invoke a TA to access it.\n"
505 "TA is used to init/transform/dump the secure buffer.\n"
506 "CA check dumped content.\n\n");
507
508 fprintf(stderr, "Options:\n");
509 fprintf(stderr, " -h|--help Print this help and exit\n");
510 fprintf(stderr, " -v Be verbose\n");
511 fprintf(stderr, " -s SIZE SDP buffer byte size [%zu]\n", size);
512 fprintf(stderr, " -n LOOP Test loop iterations [%u]\n", loop);
513 fprintf(stderr, " --ion-heap ID Target ION heap ID [%d]\n", ion_heap);
514 fprintf(stderr, " --no-offset No random offset [0 255] in buffer\n");
515}
516
517#define NEXT_ARG(i) \
518 do { \
519 if (++i == argc) { \
520 fprintf(stderr, "%s: %s: missing argument\n", \
521 argv[0], argv[i-1]); \
522 return 1; \
523 } \
524 } while (0);
525
Jerome Forissiere1342522017-05-19 09:25:53 +0200526#define CHECK_RESULT(_res, _exp, _action) \
527 if ((_res) == (_exp)) { \
528 verbose("Test passed\n"); \
529 } else { \
530 verbose("Test failed!\n"); \
531 _action; \
532 }
533
Etienne Carriere41343db2017-03-17 15:38:52 +0100534int sdp_basic_runner_cmd_parser(int argc, char *argv[])
535{
536 size_t test_size = 5000;
537 size_t test_loop = 1000;
538 int ion_heap = DEFAULT_ION_HEAP_TYPE;
539 int rnd_offset = 1;
Etienne Carriereb9a95822017-04-26 15:03:53 +0200540 int verbosity = 1;
Jerome Forissiere1342522017-05-19 09:25:53 +0200541 int err;
Etienne Carriere41343db2017-03-17 15:38:52 +0100542 int i;
543
544 /* Parse command line */
545 for (i = 1; i < argc; i++) {
546 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
547 usage(argv[0], test_size, test_loop, ion_heap);
548 return 0;
549 }
550 }
551 for (i = 1; i < argc; i++) {
552 if (!strcmp(argv[i], "-v")) {
553 verbosity++;
554 } else if (!strcmp(argv[i], "-s")) {
555 NEXT_ARG(i);
556 test_size = atoi(argv[i]);
557 } else if (!strcmp(argv[i], "-n")) {
558 NEXT_ARG(i);
559 test_loop = atoi(argv[i]);
560 } else if (!strcmp(argv[i], "--ion-heap")) {
561 NEXT_ARG(i);
562 ion_heap = atoi(argv[i]);
563 } else if (!strcmp(argv[i], "--no-offset")) {
564 rnd_offset = 0;
565 } else {
566 fprintf(stderr, "%s: invalid argument: %s\n",
567 argv[0], argv[i]);
568 usage(argv[0], test_size, test_loop, ion_heap);
569 return 1;
570 }
571 }
572
Jerome Forissiere1342522017-05-19 09:25:53 +0200573 verbose("\nSecure Data Path basic access: "
574 "NS invokes SDP TA\n");
575 err = sdp_basic_test(TEST_NS_TO_TA, test_size, test_loop, ion_heap,
576 rnd_offset, verbosity);
577 CHECK_RESULT(err, 0, return 1);
Etienne Carriere41343db2017-03-17 15:38:52 +0100578
Jerome Forissiere1342522017-05-19 09:25:53 +0200579 verbose("\nSecure Data Path basic access: "
580 "SDP TA invokes SDP TA\n");
581 err = sdp_basic_test(TEST_TA_TO_TA, test_size, test_loop, ion_heap,
582 rnd_offset, verbosity);
583 CHECK_RESULT(err, 0, return 1);
Etienne Carrierec45d9762017-03-21 15:45:13 +0100584
Jerome Forissiere1342522017-05-19 09:25:53 +0200585 verbose("\nSecure Data Path basic access: "
586 "SDP TA invokes SDP pTA\n");
587 err = sdp_basic_test(TEST_TA_TO_PTA, test_size, test_loop, ion_heap,
588 rnd_offset, verbosity);
589 CHECK_RESULT(err, 0, return 1);
Etienne Carriere41343db2017-03-17 15:38:52 +0100590
Jerome Forissiere1342522017-05-19 09:25:53 +0200591 verbose("\nSecure Data Path basic access: "
592 "NS invokes SDP pTA (shall fail)\n");
593 err = sdp_basic_test(TEST_NS_TO_PTA, test_size, test_loop, ion_heap,
594 rnd_offset, verbosity);
595 CHECK_RESULT(err, 1, return 1);
Etienne Carriered1655822017-03-21 15:45:24 +0100596
Etienne Carriere41343db2017-03-17 15:38:52 +0100597 return 0;
598}