// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2014, STMicroelectronics International N.V. */ #include #include #include #include #include #include "xtest_test.h" #include "xtest_helpers.h" #include "tee_api_defines.h" #include "tee_client_api.h" #define OFFSET0 0 #define PARAM_0 0 #define PARAM_1 1 #define PARAM_2 2 #define PARAM_3 3 struct xtest_session { ADBG_Case_t *c; TEEC_Session session; TEEC_Context context; }; /* Compares two memories and checks if their length and content is the same */ #define EXPECT_SHARED_MEM_BUFFER(c, exp_buf, exp_blen, op, param_num, shrm) \ do { \ if ((exp_buf) == NULL) { \ ADBG_EXPECT((c), exp_blen, \ (op)->params[(param_num)].memref.size); \ } else { \ ADBG_EXPECT_COMPARE_POINTER((c), (shrm), ==, \ (op)->params[(param_num)].memref.parent); \ ADBG_EXPECT_BUFFER((c), (exp_buf), (exp_blen), \ (shrm)->buffer, \ (op)->params[(param_num)].memref.size); \ } \ } while (0) /* * Compares the content of the memory cells in OP with the expected value * contained. */ #define EXPECT_OP_TMP_MEM_BUFFER(c, exp_buf, exp_blen, op, param_num, buf) \ do { \ if ((exp_buf) == NULL) { \ ADBG_EXPECT((c), exp_blen, \ (op)->params[(param_num)].tmpref.size); \ } else { \ ADBG_EXPECT_COMPARE_POINTER((c), (buf), ==, \ (op)->params[(param_num)].tmpref.buffer); \ ADBG_EXPECT_BUFFER((c), (exp_buf), (exp_blen), \ (buf), \ (op)->params[(param_num)].memref.size); \ } \ } while (0) /* Registers the TEEC_SharedMemory to the TEE. */ static TEEC_Result RegisterSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm, size_t size, uint32_t flags) { shm->flags = flags; shm->size = size; return TEEC_RegisterSharedMemory(ctx, shm); } /* Allocates shared memory inside of the TEE. */ static TEEC_Result AllocateSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm, size_t size, uint32_t flags) { shm->flags = flags; shm->size = size; return TEEC_AllocateSharedMemory(ctx, shm); } static void CloseSession_null(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "CloseSession_null"); { /* In reality doesn't test anything. */ TEEC_CloseSession(NULL); } Do_ADBG_EndSubCase(cs->c, "CloseSession_null"); } static void Allocate_In(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Allocate_In"); { TEEC_SharedMemory shm = { }; size_t size = 1024; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, size, TEEC_MEM_INPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Allocate_In"); } static void Allocate_out_of_memory(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Allocate_out_of_memory"); { TEEC_SharedMemory shm = { }; size_t SIZE_OVER_MEMORY_CAPACITY = SIZE_MAX; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; ADBG_EXPECT_TEEC_RESULT(cs->c, TEEC_ERROR_OUT_OF_MEMORY, AllocateSharedMemory(&cs->context, &shm, SIZE_OVER_MEMORY_CAPACITY, TEEC_MEM_INPUT)); TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Allocate_out_of_memory"); } static void OpenSession_error_notExistingTA(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "OpenSession_error_notExistingTA"); { TEEC_UUID NONEXISTING_TA_UUID = { 0x534D1192, 0x6143, 0x234C, { 0x47, 0x55, 0x53, 0x52, 0x54, 0x4F, 0x4F, 0x59 } }; uint32_t ret_orig = 0; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_SUCCESS, !=, TEEC_OpenSession(&cs->context, &cs->session, &NONEXISTING_TA_UUID, TEEC_LOGIN_PUBLIC, NULL, NULL, &ret_orig)); ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_ORIGIN_TRUSTED_APP, !=, ret_orig); TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "OpenSession_error_notExistingTA"); } static void Allocate_InOut(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Allocate_InOut"); { TEEC_SharedMemory shm = { }; uint8_t val[] = { 54, 76, 98, 32 }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_INPUT | TEEC_MEM_OUTPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Allocate_InOut"); } static void Register_In(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Register_In"); { TEEC_SharedMemory shm = { }; uint8_t val[] = { 32, 65, 43, 21, 98 }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_INPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Register_In"); } static void Register_notZeroLength_Out(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Register_notZeroLength_Out"); { TEEC_SharedMemory shm = { }; uint8_t val[] = { 56, 67, 78, 99 }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_OUTPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Register_notZeroLength_Out"); } static void Register_InOut(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Register_InOut"); { TEEC_SharedMemory shm = { }; uint8_t val[] = { 54, 76, 23, 98, 255, 23, 86 }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_INPUT | TEEC_MEM_OUTPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Register_InOut"); } static void Register_zeroLength_Out(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Register_zeroLength_Out"); { uint8_t val[] = { 65, 76, 98, 32 }; TEEC_SharedMemory shm = { }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, 0, TEEC_MEM_OUTPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Register_zeroLength_Out"); } static void Allocate_Out(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Allocate_Out"); { TEEC_SharedMemory shm = { }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, 0, TEEC_MEM_OUTPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Allocate_Out"); } static void FinalizeContext_null(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "FinalizeContext_null"); { TEEC_FinalizeContext(NULL); } Do_ADBG_EndSubCase(cs->c, "FinalizeContext_null"); } static void InitializeContext_NotExistingTEE(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "InitializeContext_NotExistingTEE"); { if (!ADBG_EXPECT_COMPARE_UNSIGNED(cs->c, TEEC_SUCCESS, !=, TEEC_InitializeContext("Invalid TEE name", &cs->context))) TEEC_FinalizeContext(&cs->context); } Do_ADBG_EndSubCase(cs->c, "InitializeContext_NotExistingTEE"); } static void AllocateThenRegister_SameMemory(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "AllocateThenRegister_SameMemory"); { TEEC_SharedMemory shm = { }; size_t size_allocation = 32; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, size_allocation, TEEC_MEM_INPUT))) goto out_final; ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, size_allocation, TEEC_MEM_INPUT)); TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "AllocateThenRegister_SameMemory"); } static void AllocateSameMemory_twice(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "AllocateSameMemory_twice"); { TEEC_SharedMemory shm = { }; size_t size_allocation = 32; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, size_allocation, TEEC_MEM_INPUT))) goto out_final; ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, size_allocation, TEEC_MEM_INPUT)); TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "AllocateSameMemory_twice"); } static void RegisterSameMemory_twice(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "RegisterSameMemory_twice"); { uint8_t val[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; TEEC_SharedMemory shm = { }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_INPUT))) goto out_final; ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, sizeof(val), TEEC_MEM_INPUT)); TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "RegisterSameMemory_twice"); } #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif static void Allocate_sharedMemory_32k(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Allocate_sharedMemory_32k"); { size_t size = MIN(32 * 1024, TEEC_CONFIG_SHAREDMEM_MAX_SIZE); TEEC_SharedMemory shm = { }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, AllocateSharedMemory(&cs->context, &shm, size, TEEC_MEM_INPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Allocate_sharedMemory_32k"); } #define SHM_32K_SIZE MIN(32 * 1024, TEEC_CONFIG_SHAREDMEM_MAX_SIZE) static void Register_sharedMemory_32k(struct xtest_session *cs) { Do_ADBG_BeginSubCase(cs->c, "Register_sharedMemory_32k"); { uint8_t val[SHM_32K_SIZE] = { }; TEEC_SharedMemory shm = { }; if (!ADBG_EXPECT(cs->c, TEEC_SUCCESS, TEEC_InitializeContext(xtest_tee_name, &cs->context))) goto out; shm.buffer = val; if (!ADBG_EXPECT_TEEC_SUCCESS(cs->c, RegisterSharedMemory(&cs->context, &shm, SHM_32K_SIZE, TEEC_MEM_INPUT))) goto out_final; TEEC_ReleaseSharedMemory(&shm); out_final: TEEC_FinalizeContext(&cs->context); } out: Do_ADBG_EndSubCase(cs->c, "Register_sharedMemory_32k"); } static void xtest_teec_TEE(ADBG_Case_t *c) { struct xtest_session connection = { c }; CloseSession_null(&connection); Allocate_In(&connection); Allocate_out_of_memory(&connection); OpenSession_error_notExistingTA(&connection); Allocate_InOut(&connection); Register_In(&connection); Register_notZeroLength_Out(&connection); Register_InOut(&connection); Register_zeroLength_Out(&connection); Allocate_Out(&connection); FinalizeContext_null(&connection); InitializeContext_NotExistingTEE(&connection); AllocateThenRegister_SameMemory(&connection); AllocateSameMemory_twice(&connection); RegisterSameMemory_twice(&connection); Allocate_sharedMemory_32k(&connection); Register_sharedMemory_32k(&connection); } ADBG_CASE_DEFINE(regression, 5006, xtest_teec_TEE, "Tests for Global platform TEEC");