/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014, STMicroelectronics International N.V. * Copyright (c) 2020, Linaro Limited */ #ifndef XML_COMMON_API_H_ #define XML_COMMON_API_H_ #include <adbg.h> #include <tee_client_api.h> #include "xtest_helpers.h" #include "xtest_test.h" #define BIT(n) (1ul << (n)) #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #define ALLOCATE_SHARED_MEMORY(context, sharedMemory, sharedMemorySize, \ memoryType, exit_label) \ res = AllocateSharedMemory(context, sharedMemory, sharedMemorySize, \ memoryType); \ if (!ADBG_EXPECT_TEEC_SUCCESS(c, res)) \ goto exit_label; \ memset(sharedMemory->buffer, 0, sharedMemorySize); #define ALLOCATE_AND_FILL_SHARED_MEMORY(context, sharedMemory, \ sharedMemorySize, \ memoryType, copySize, data, \ exit_label) \ res = AllocateSharedMemory(context, sharedMemory, sharedMemorySize, \ memoryType); \ if (!ADBG_EXPECT_TEEC_SUCCESS(c, res)) \ goto exit_label; \ memset(sharedMemory->buffer, 0, sharedMemorySize); \ if (data != NULL) { \ memcpy(sharedMemory->buffer, data, copySize); \ } #define ALLOCATE_AND_FILL_SHARED_MEMORY_6(a,b,c,d,e,f) \ ALLOCATE_AND_FILL_SHARED_MEMORY(a,b,c,d,c,e,f) #define SET_SHARED_MEMORY_OPERATION_PARAMETER(parameterNumber, \ sharedMemoryOffset, \ sharedMemory, \ sharedMemorySize) \ op.params[parameterNumber].memref.offset = sharedMemoryOffset; \ op.params[parameterNumber].memref.size = sharedMemorySize; \ op.params[parameterNumber].memref.parent = sharedMemory; /*Open session using TEEC_OpenSession and check the returned value and/or returned origin.*/ #define XML_OpenSession(c, context, session, destination, connectionMethod, \ connectionData, operation, returnOrigin, expected) \ do { \ uint32_t ret_orig = 0; \ \ XML_VERIFY(c, expected, \ TEEC_OpenSession(context, session, destination, \ connectionMethod, connectionData, \ operation, &ret_orig)); \ if (!(unsigned long)(returnOrigin) || \ (unsigned long)(returnOrigin) == \ TEEC_ORIGIN_ANY_NOT_TRUSTED_APP) \ ADBG_EXPECT_NOT(c, (unsigned long)returnOrigin, \ ret_orig); \ else \ ADBG_EXPECT(c, (unsigned long)returnOrigin, ret_orig); \ } while (0) /* XML_VERIFY macro define. * * Use ADBG_EXPECT or ADBG_EXPECT_NOT depending on the expected return value. * * ADBG_EXPECT() -> IF(EXP == GOT) RETURN TRUE * ADBG_EXPECT() -> IF(EXP != GOT) RETURN TRUE */ #define XML_VERIFY(c, exp, got) \ do { \ if (exp == TEEC_UNDEFINED_ERROR) \ ADBG_EXPECT_NOT(c, exp, got); \ else \ ADBG_EXPECT(c, exp, got); \ } while (0) /*Initialize context using TEEC_InitializeContext and check the returned value.*/ #define XML_InitializeContext(c, name, context, expected) \ XML_VERIFY(c, expected, TEEC_InitializeContext(name, context)) #define OPERATION_TEEC_PARAM_TYPES(op, p0, p1, p2, p3) \ do { \ op->paramTypes = TEEC_PARAM_TYPES(p0, p1, p2, p3); \ } while (0) /*dummy functions*/ #define TEEC_SetUp_TEE() /*do nothing for now*/ #define TEEC_TearDown_TEE(a) /*do nothing for now*/ #define TEEC_SelectApp(a, b) /*do nothing for now*/ #define TEEC_createThread(a, b) /*do nothing for now*/ struct attr_value { uint8_t buf[1024]; size_t buf_size; uint32_t attr_id; }; #define MAX_NUM_SAVED_ATTR_VALUES 8 static struct attr_value saved_attr[MAX_NUM_SAVED_ATTR_VALUES] __maybe_unused; static TEEC_Result __maybe_unused Invoke_Simple_Function(ADBG_Case_t *c __unused, TEEC_Session *sess, uint32_t cmdId) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; uint32_t org; return TEEC_InvokeCommand(sess, cmdId, &op, &org); } static TEEC_Result __maybe_unused Invoke_Simple_Function_v1(ADBG_Case_t *c __unused, TEEC_Session *sess, uint32_t cmd, uint32_t a, uint32_t b) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; uint32_t org; op.params[0].value.a = a; op.params[0].value.b = b; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); return TEEC_InvokeCommand(sess, cmd, &op, &org); } static TEEC_Result __maybe_unused Invoke_Simple_Function_v2(ADBG_Case_t *c __unused, TEEC_Session *sess, uint32_t cmd, uint32_t a0, uint32_t b0, uint32_t a1, uint32_t b1) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; uint32_t org; op.params[0].value.a = a0; op.params[0].value.b = b0; op.params[1].value.a = a1; op.params[1].value.b = b1; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE); return TEEC_InvokeCommand(sess, cmd, &op, &org); } static TEEC_Result __maybe_unused Invoke_Simple_Function_v3(ADBG_Case_t *c __unused, TEEC_Session *sess, uint32_t cmd, uint32_t a0, uint32_t b0, uint32_t a1, uint32_t b1, uint32_t a2, uint32_t b2) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; uint32_t org; op.params[0].value.a = a0; op.params[0].value.b = b0; op.params[1].value.a = a1; op.params[1].value.b = b1; op.params[2].value.a = a2; op.params[2].value.b = b2; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_NONE); return TEEC_InvokeCommand(sess, cmd, &op, &org); } static TEEC_Result __maybe_unused Invoke_Simple_Function_v4(ADBG_Case_t *c __unused, TEEC_Session *sess, uint32_t cmd, uint32_t a0, uint32_t b0, uint32_t a1, uint32_t b1, uint32_t a2, uint32_t b2, uint32_t a3, uint32_t b3) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; uint32_t org; op.params[0].value.a = a0; op.params[0].value.b = b0; op.params[1].value.a = a1; op.params[1].value.b = b1; op.params[2].value.a = a2; op.params[2].value.b = b2; op.params[3].value.a = a3; op.params[3].value.b = b3; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_VALUE_INPUT); return TEEC_InvokeCommand(sess, cmd, &op, &org); } static TEEC_Result __maybe_unused AllocateSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm, uint32_t size, uint32_t flags) { shm->flags = flags; shm->size = size; return TEEC_AllocateSharedMemory(ctx, shm); } static TEEC_Result GetObjectBufferAttribute_helper(ADBG_Case_t *c, TEEC_Session *sess, size_t n, uint32_t cmd, uint32_t obj, uint32_t attr_id, bool buffer_is_null, uint32_t buffer_size) { TEEC_Operation op = TEEC_OPERATION_INITIALIZER; TEEC_Result res = TEE_SUCCESS; uint32_t org = 0; static TEEC_SharedMemory shm = { }; uint32_t memref_type = TEEC_MEMREF_TEMP_OUTPUT; if (!ADBG_EXPECT_COMPARE_SIGNED(c, n, <, MAX_NUM_SAVED_ATTR_VALUES)) return TEEC_ERROR_BAD_PARAMETERS; if (!ADBG_EXPECT_COMPARE_SIGNED(c, buffer_size, <=, sizeof(saved_attr[n].buf))) return TEEC_ERROR_BAD_PARAMETERS; if (!buffer_is_null) { shm.size = buffer_size; shm.flags = TEEC_MEM_OUTPUT; res = TEEC_AllocateSharedMemory(sess->ctx, &shm); if (!ADBG_EXPECT_TEEC_SUCCESS(c, res)) return res; SET_SHARED_MEMORY_OPERATION_PARAMETER(1, 0, &shm, shm.size); memref_type = TEEC_MEMREF_PARTIAL_OUTPUT; } op.params[0].value.a = obj; op.params[0].value.b = attr_id; op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, memref_type, TEEC_NONE, TEEC_NONE); res = TEEC_InvokeCommand(sess, cmd, &op, &org); if (!buffer_is_null) { if (res) { memset(saved_attr + n, 0, sizeof(saved_attr[n])); } else { memcpy(saved_attr[n].buf, shm.buffer, sizeof(saved_attr[n].buf)); saved_attr[n].buf_size = op.params[1].memref.size; saved_attr[n].attr_id = attr_id; } TEEC_ReleaseSharedMemory(&shm); } return res; } static TEEC_Result __maybe_unused Invoke_GetObjectBufferAttribute(ADBG_Case_t *c, TEEC_Session *sess, uint32_t cmd, uint32_t obj, uint32_t attr_id, bool buffer_is_null, uint32_t buffer_size) { return GetObjectBufferAttribute_helper(c, sess, 0, cmd, obj, attr_id, buffer_is_null, buffer_size); } static TEEC_Result __maybe_unused Invoke_FreeTransientObject(ADBG_Case_t *c, TEEC_Session *sess, uint32_t cmd, uint32_t obj_handle) { return Invoke_Simple_Function_v1(c, sess, cmd, obj_handle, 0); } #endif /* XML_COMMON_API_H_ */